1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2%%
    3%% Libraries
    4%%
    5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10:- lib(fd).
   15:- lib(chr).
   20:- chr('fluent').   21
   22
   23%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   24%%
   25%% State Specifications and Update
   26%%
   27%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   34holds(F, [F|_]).
   35holds(F, Z) :- nonvar(Z), Z=[F1|Z1], F\==F1, holds(F, Z1).
   44holds(F, [F|Z], Z).
   45holds(F, Z, [F1|Zp]) :- nonvar(Z), Z=[F1|Z1], F\==F1, holds(F, Z1, Zp).
   53cancel(F,Z1,Z2) :-
   54   var(Z1)    -> cancel(F,Z1), cancelled(F,Z1), Z2=Z1 ;
   55   Z1 = [G|Z] -> ( F\=G -> cancel(F,Z,Z3), Z2=[G|Z3]
   56                         ; cancel(F,Z,Z2) ) ;
   57   Z1 = []    -> Z2 = [].
   64minus_(Z, [], Z).
   65minus_(Z, [F|Fs], Zp) :-
   66   ( \+ not_holds(F, Z) -> holds(F, Z, Z1) ;
   67     \+ holds(F, Z)     -> Z1 = Z
   68                         ; cancel(F, Z, Z1), not_holds(F, Z1) ),
   69   minus_(Z1, Fs, Zp).
   76plus_(Z, [], Z).
   77plus_(Z, [F|Fs], Zp) :-
   78   ( \+ holds(F, Z)     -> Z1=[F|Z] ;
   79     \+ not_holds(F, Z) -> Z1=Z
   80                         ; cancel(F, Z, Z2), not_holds(F, Z2), Z1=[F|Z2] ),
   81   plus_(Z1, Fs, Zp).
   89update(Z1, ThetaP, ThetaN, Z2) :-
   90   minus_(Z1, ThetaN, Z), plus_(Z, ThetaP, Z2).
   91
   92
   93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   94%%
   95%% State Knowledge
   96%%
   97%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  104knows(F, Z) :- \+ not_holds(F, Z).
  111knows_not(F, Z) :- \+ holds(F, Z).
  127knows_val(X, F, Z) :- k_holds(F, Z), knows_val(X).
  128
  129k_holds(F, Z) :- nonvar(Z), Z=[F1|Z1],
  130                 ( instance(F1, F), F=F1 ; k_holds(F, Z1) ).
  131
  132:-local variable(known_val).
  133:-setval(known_val,nil).  134
  135knows_val(X) :- dom(X), \+ nonground(X), ambiguous(X) -> false.
  136knows_val(X) :- getval(known_val,X), X \== nil, setval(known_val, nil).
  137
  138dom([]).
  139dom([X|Xs]) :- dom(Xs), ( is_domain(X) -> indomain(X)
  140                                        ; true ).
  141
  142ambiguous(X) :- 
  143   ( getval(known_val, Val), 
  144     Val \== nil -> setval(known_val, nil)
  145   ;
  146                    setval(known_val, X), 
  147                    false
  148   ).
  149
  150%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  151%%
  152%% Execution
  153%%
  154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  187execute(A,Z1,Z2) :-
  188   is_predicate(perform/2),
  189   perform(A,Y)    -> ( is_predicate(ab_state_update/4) ->
  190                           ( Z1=[sit(S)|Z], ! ; S=[], Z=Z1 ),
  191                           ( state_update(Z,A,Z3,Y)
  192                             ; ab_res([[A,Y]|S],Z3) ),
  193                           !, Z2=[sit([[A,Y]|S])|Z3]
  194                        ;
  195			state_update(Z1,A,Z2,Y) ) ;
  196
  197   is_predicate(perform/3),
  198   perform(A,Y,E)  -> ( is_predicate(ab_state_update/4) ->
  199                           ( Z1=[sit(S)|Z], ! ; S=[], Z=Z1 ),
  200                           ( state_update(Z,A,Z3,Y), state_updates(Z3,E,Z4)
  201                             ; ab_res([[A,Y,E]|S],Z4) ),
  202                           !, Z2=[sit([[A,Y,E]|S])|Z4]
  203                        ;
  204			state_update(Z1,A,Z,Y), state_updates(Z,E,Z2) ) ;
  205
  206   A = [A1|A2]     ->
  207                      execute(A1,Z1,Z), execute(A2,Z,Z2) ;
  208
  209   A = if(F,A1,A2) ->
  210                      (holds(F,Z1) -> execute(A1,Z1,Z2)
  211                                    ; execute(A2,Z1,Z2)) ;
  212
  213   A = []          ->
  214                      Z1=Z2 ;
  215
  216   complex_action(A,Z1,Z2).
  217
  218ab_res([],Z) :- init(Z).
  219ab_res([S1|S],Z) :-
  220   ab_res(S,Z1),
  221   ( S1=[A,Y] -> ( state_update(Z1,A,Z,Y) ; ab_state_update(Z1,A,Z,Y) )
  222     ;
  223     S1=[A,Y,E], ( state_update(Z1,A,Z2,Y) ; ab_state_update(Z1,A,Z2,Y) ),
  224                 state_updates(Z2, E, Z) ).
  225
  226state_updates(Z, [], Z).
  227state_updates(Z1, [A|S], Z2) :-
  228   state_update(Z1, A, Z), state_updates(Z, S, Z2).
  229
  230%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  231%%
  232%% Planning
  233%%
  234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  235
  236%%
  237%% plan(PlanningProblemName,Z,P)
  238%%
  239%% P is an optimal plan for PlanningProblemName with starting state Z
  240%%
  241%% It assumes the definition of a predicate PlanningProblemName(Z0,P,Z)
  242%% describing the search space such that plan P executed in starting
  243%% state Z0 results in state Z which satisfies the planning goal,
  244%% and the definition of plan_cost(PlanningProblemName,P,Z,C) such that
  245%% C is the cost of plan P resulting in state Z; or
  246%%
  247%% the definition of a predicate is PlanningProblemName(Z0,P)
  248%% describing the search space such that conditional plan P executed in
  249%% starting state Z0 necessarily results in a state in which the planning
  250%% goal is satisfied, and the definition of plan_cost(PlanningProblemName,P,C)
  251%% such that C is the cost of plan P.
  252%%
  253%% For the definition of the search space, the predicates for knowledge
  254%% described below can be used.
  255%%
  256
  257:-local variable(plan_search_best).
  258
  259plan(Problem, Z, P) :-
  260   setval(plan_search_best(_: -1)),
  261   plan_search(Problem, Z),
  262   getval(plan_search_best,P:C),
  263   C =\= -1.
  264
  265plan_search(Problem, Z) :-
  266    is_predicate(Problem/2) ->
  267       ( PlanningProblem =.. [Problem,Z,P],
  268         call(PlanningProblem),
  269         plan_cost(Problem, P, C),
  270         getval(plan_search_best,_:C1),
  271         ( C1 =< C, C1 =\= -1 -> false
  272                               ;
  273                               setval(plan_search_best,P:C), false )
  274         ;
  275         true ) ;
  276    PlanningProblem =.. [Problem,Z,P,Zn],
  277    call(PlanningProblem),
  278    plan_cost(Problem, P, Zn, C),
  279    getval(plan_search_best,_:C1),
  280    ( C1 =< C, C1 =\= -1 -> false
  281                              ;
  282                            setval(plan_search_best,P:C),
  283                            false
  284    )
  285    ;
  286    true.
  298knows(F, S, Z0) :- \+ ( res(S, Z0, Z), not_holds(F, Z) ).
  305knows_not(F, S, Z0) :- \+ ( res(S, Z0, Z), holds(F, Z) ).
  306
  307%%
  308%% knows_val(X,F,S,Z0)
  309%%
  310%% there is an instance of the variables in X for which
  311%% non-ground fluent F is known to hold after doing S in state Z0
  312%%
  313
  314:-local variable(known_vals).
  315
  316knows_val(X, F, S, Z0) :-
  317   setval(known_vals,nil),
  318   res(S, Z0, Z),
  319   findall(X, knows_val(X,F,Z), T),
  320   getval(known_vals,T1),
  321   ( T1=nil -> T2=T ; intersection(T,T1,T2) ),
  322   setval(known_vals, T2),
  323   false.
  324knows_val(X, _, _, _) :-
  325   getval(known_vals, T), 
  326   member(X, T),
  327   setval(known_vals, nil).
  328
  329
  330res([], Z0, Z0).
  331res(do(A,S), Z0, Z) :-
  332   ( A = if_true(F)  -> res(S, Z0, Z), holds(F, Z) 
  333   ;
  334                        ( A = if_false(F) -> res(S, Z0, Z),
  335                                             not_holds(F, Z) 
  336                        ;
  337                                             res(S, Z0, Z1),
  338                                             state_update(Z1, A, Z, _)
  339                        )
  340   ).
  341
  342
  343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  344%%
  345%% Ramification Problem
  346%%
  347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  361causes(Z,P,N,Z2) :-
  362   causes(Z,P,N,Z1,P1,N1) -> causes(Z1,P1,N1,Z2)
  363                           ; Z2=Z.
  372ramify(Z1,ThetaP,ThetaN,Z2) :-
  373   update(Z1,ThetaP,ThetaN,Z), causes(Z,ThetaP,ThetaN,Z2)