# Goal driven Parallel Sequences -- Jos De Roo

# Inspired by https://www.cs.cmu.edu/~fp/courses/15816-s12/lectures/01-inference.pdf

# "In linear logic we are instead concerned with the change of truth with a
# change of state. We model this in a very simple way: when an inference rule
# is applied we consume the propositions used as premises and produce the
# propositions in the conclusions, thereby effecting an overall change in state."

@prefix math: <http://www.w3.org/2000/10/swap/math#>.
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix gps: <http://eyereasoner.github.io/eye/reasoning/gps/gps-schema#>.
@prefix : <urn:example:>.

# declare components
gps:findpath a log:Component.
gps:findpaths a log:Component.
gps:stagecount a log:Component.

# find paths in the state space from initial state to goal state within limits
(_:SCOPE _:Goal _:Path _:Duration _:Cost _:Belief _:Comfort _:MaxDuration _:MaxCost _:MinBelief _:MinComfort) log:onNegativeSurface {
    () log:onNegativeSurface {
        _:SCOPE gps:findpath (_:Goal _:Path _:Duration _:Cost _:Belief _:Comfort (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort)).
    }.
    _:SCOPE gps:findpaths (() _:Goal () 0.0 0.0 1.0 1.0 _:Path _:Duration _:Cost _:Belief _:Comfort
        (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort 1)).
}.

(_:SCOPE _:Goal _:Path _:Duration _:Cost _:Belief _:Comfort _:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount) log:onNegativeSurface {
    () log:onNegativeSurface {
        _:SCOPE gps:findpath (_:Goal _:Path _:Duration _:Cost _:Belief _:Comfort (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount)).
    }.
    _:SCOPE gps:findpaths (() _:Goal () 0.0 0.0 1.0 1.0 _:Path _:Duration _:Cost _:Belief _:Comfort
        (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount)).
}.

(_:SCOPE _:Maps _:Goal _:Path _:Duration _:Cost _:Belief _:Comfort _:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount) log:onNegativeSurface {
    () log:onNegativeSurface {
        _:SCOPE gps:findpaths (_:Maps _:Goal _:Path _:Duration _:Cost _:Belief _:Comfort _:Path _:Duration _:Cost _:Belief _:Comfort
            (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount)).
    }.
    _:Goal log:callWithCleanup true.
}.

(_:SCOPE _:Maps_s _:Goal _:Path_s _:Duration_s _:Cost_s _:Belief_s _:Comfort_s _:Path
 _:Duration _:Cost _:Belief _:Comfort _:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount
 _:From _:Transition _:To _:Action _:Duration_n _:Cost_n _:Belief_n _:Comfort_n _:Map _:Maps_t _:Stagecount
 _:Duration_t _:Cost_t _:Belief_t _:Comfort_t _:Path_t) log:onNegativeSurface {
    () log:onNegativeSurface {
        _:SCOPE gps:findpaths (_:Maps_s _:Goal _:Path_s _:Duration_s _:Cost_s _:Belief_s _:Comfort_s _:Path _:Duration _:Cost _:Belief _:Comfort
            (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount)).
    }.
    _:Map gps:description (_:From _:Transition _:To _:Action _:Duration_n _:Cost_n _:Belief_n _:Comfort_n).
    (_:Maps_s (_:Map)) list:append _:Maps_t.
    _:Maps_t gps:stagecount _:Stagecount.
    _:Stagecount math:notGreaterThan _:MaxStagecount.
    (_:Duration_s _:Duration_n) math:sum _:Duration_t.
    _:Duration_t math:notGreaterThan _:MaxDuration.
    (_:Cost_s _:Cost_n) math:sum _:Cost_t.
    _:Cost_t math:notGreaterThan _:MaxCost.
    (_:Belief_s _:Belief_n) math:product _:Belief_t.
    _:Belief_t math:notLessThan _:MinBelief.
    (_:Comfort_s _:Comfort_n) math:product _:Comfort_t.
    _:Comfort_t math:notLessThan _:MinComfort.
    (_:Path_s (_:Action)) list:append _:Path_t.
    _:From log:becomes _:To.
    {_:SCOPE gps:findpaths (_:Maps_t _:Goal _:Path_t _:Duration_t _:Cost_t _:Belief_t _:Comfort_t _:Path _:Duration _:Cost _:Belief _:Comfort
        (_:MaxDuration _:MaxCost _:MinBelief _:MinComfort _:MaxStagecount))} log:callWithCleanup {_:To log:becomes _:From}.
}.

# counting the number of stages (a stage is a sequence of steps in the same map)
() log:onNegativeSurface {
    () log:onNegativeSurface {
        () gps:stagecount 1.
    }.
}.

(_:A _:B _:C _:D _:E _:F _:G) log:onNegativeSurface {
    () log:onNegativeSurface {
        _:A gps:stagecount _:B.
    }.
    _:A list:firstRest (_:C _:D).
    _:D list:firstRest (_:E _:F).
    _:C log:notEqualTo _:E.
    _:D gps:stagecount _:G.
    (_:G 1) math:sum _:B.
}.

(_:A _:B _:C _:D) log:onNegativeSurface {
    () log:onNegativeSurface {
        _:A gps:stagecount _:B.
    }.
    _:A list:firstRest (_:C _:D).
    _:D gps:stagecount _:B.
}.

# current state
:i1 :location :Gent.

# map of Belgium
(_:S _:L) log:onNegativeSurface {
    () log:onNegativeSurface {
        :map-BE gps:description ({_:S :location :Gent} true {_:S :location :Brugge} :drive_gent_brugge 1500.0 0.006 0.96 0.99).
    }.
    _:S :location _:L.
}.

(_:S _:L) log:onNegativeSurface {
    () log:onNegativeSurface {
        :map-BE gps:description ({_:S :location :Gent} true {_:S :location :Kortrijk} :drive_gent_kortrijk 1600.0 0.007 0.96 0.99).
    }.
    _:S :location _:L.
}.

(_:S _:L) log:onNegativeSurface {
    () log:onNegativeSurface {
        :map-BE gps:description ({_:S :location :Kortrijk} true {_:S :location :Brugge} :drive_kortrijk_brugge 1600.0 0.007 0.96 0.99).
    }.
    _:S :location _:L.
}.

(_:S _:L) log:onNegativeSurface {
    () log:onNegativeSurface {
        :map-BE gps:description ({_:S :location :Brugge} true {_:S :location :Oostende} :drive_brugge_oostende 900.0 0.004 0.98 1.0).
    }.
    _:S :location _:L.
}.

# query
(_:SCOPE _:SUBJECT _:PATH _:DURATION _:COST _:BELIEF _:COMFORT) log:onNegativeSurface {
    _:SCOPE gps:findpath ({_:SUBJECT :location :Oostende} _:PATH _:DURATION _:COST _:BELIEF _:COMFORT (5000.0 5.0 0.2 0.4 1)).
    () log:onNegativeAnswerSurface {
        _:SUBJECT gps:path (_:PATH _:DURATION _:COST _:BELIEF _:COMFORT).
    }.
}.
