@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
@prefix graph: <http://www.w3.org/2000/10/swap/graph#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix : <http://example.org/ns#>.

# sample data from RubenD
[] :data {
    [] :package {
        [] :content {
            :a :b _:c.
            [] :package {
                [] :content {
                    :u :v _:c.
                    [] :package {
                        [] :content {
                            :x :y _:c.
                        }; :usable_until :yesterday.
                    }; :tag :invalid.
                }; :usable_until :tomorrow; :p :o.
            }; :tag :valid.
        }; :usable_until :next_week.
    }; :tag :valid.
}.

# unpack the triples that are usable in the future
{
    ?b :data ?g.
    ?g graph:list ?l.
    ?l :unpack ?m.
    ?m graph:union ?h.
} => ?h.

# the logic for unpack using backward rules
{
    () :unpack ().
} <= true.

{
    ?g :unpack ?h.
} <= {
    ?g list:firstRest (?f ?r).
    ?h list:firstRest (?a ?b).
    ?f :unpack ?a.
    ?r :unpack ?b.
}.

{
    {
        ?b :package ?p.
    } :unpack ?f.
} <= {
    ?p log:includes {
        ?a :content ?c.
        ?a :usable_until ?t.
    }.
    (:tomorrow :next_week) list:member ?t.
    ?c graph:list ?l.
    ?l :unpack ?m.
    ?m graph:union ?f.
}.

{
    {
        ?b :package ?p.
    } :unpack true.
} <= {
    ?p log:includes {
        ?a :content ?c.
        ?a :usable_until ?t.
    }.
    (:yesterday :last_week) list:member ?t.
    ?c graph:list ?l.
    ?l :unpack ?m.
    ?m graph:union ?f.
}.

{
    {
        ?b :tag ?p.
    } :unpack true.
} <= true.

{
    ?g :unpack ?g.
} <= {
    ?g log:rawType ?r.
    ?r log:notEqualTo rdf:List.
    ?g log:notIncludes {
        ?a :package ?p.
    }.
    ?g log:notIncludes {
        ?b :tag ?q.
    }.
}.
