24% 
   25flux_version(2.0).
   26
   27%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   28%%
   29%% Libraries
   30%%
   31%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   37:- use_module( library(terms)).
   43:- use_module( library(lists)).
   49:- use_module( library('clp/clpfd')).
   55:- use_module( library(chr)).
   61:- ensure_loaded(fluent2).   62
   63%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   64%%
   65%% State Specifications and Update
   66%%
   67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   68
   69holds(F,Z):-fluent_holds_in_state(F,Z).
   75fluent_holds_in_state(F, [F|_]).
   76fluent_holds_in_state(F, Z) :- nonvar(Z), Z=[F1|Z1], F\==F1, fluent_holds_in_state(F, Z1).
   85fluent_holds_in_state(F, [F|Z], Z).
   86fluent_holds_in_state(F, Z, [F1|Zp]) :- nonvar(Z), Z=[F1|Z1], F\==F1, fluent_holds_in_state(F, Z1, Zp).
   94cancel(F,Z1,Z2) :-
   95   var(Z1)    -> cancel(F,Z1), cancelled(F,Z1), Z2=Z1 ;
   96   Z1 = [G|Z] -> ( F\=G -> cancel(F,Z,Z3), Z2=[G|Z3]
   97                         ; cancel(F,Z,Z2) ) ;
   98   Z1 = []    -> Z2 = [].
  105minus_(Z, [], Z).
  106minus_(Z, [F|Fs], Zp) :-
  107   ( \+ not_holds(F, Z) -> fluent_holds_in_state(F, Z, Z1) ;
  108     \+ fluent_holds_in_state(F, Z)     -> Z1 = Z
  109                         ; cancel(F, Z, Z1), not_holds(F, Z1) ),
  110   minus_(Z1, Fs, Zp).
  117plus_(Z, [], Z).
  118plus_(Z, [F|Fs], Zp) :-
  119   ( \+ fluent_holds_in_state(F, Z)     -> Z1=[F|Z] ;
  120     \+ not_holds(F, Z) -> Z1=Z
  121                         ; cancel(F, Z, Z2), not_holds(F, Z2), Z1=[F|Z2] ),
  122   plus_(Z1, Fs, Zp).
  130update(Z1, ThetaP, ThetaN, Z2) :-
  131   minus_(Z1, ThetaN, Z), plus_(Z, ThetaP, Z2).
  132
  133
  134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  135%%
  136%% State Knowledge
  137%%
  138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  145knows(F, Z) :- \+ not_holds(F, Z).
  152knows_not(F, Z) :- \+ fluent_holds_in_state(F, Z).
  168knows_val(X, F, Z) :- k_holds(F, Z), knows_val(X).
  169
  170k_holds(F, Z) :- nonvar(Z), Z=[F1|Z1],
  171                 ( instance1(F1, F), F=F1 ; k_holds(F, Z1) ).
  172
  173:- dynamic known_val/1.  174
  175knows_val(X) :- dom(X), \+ nonground(X), ambiguous(X) -> false.
  176knows_val(X) :- retract(known_val(X)).
  177
  178dom([]).
  179dom([X|Xs]) :- dom(Xs), ( is_domain(X) -> indomain(X)
  180                                        ; true ).
  181
  182ambiguous(X) :- retract(known_val(_)) -> true
  183                ;
  184                assertz(known_val(X)), false.
  185
  186
  187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  188%%
  189%% Execution
  190%%
  191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  224execute(A,Z1,Z2) :-
  225   current_predicate(perform/2),
  226   perform(A,Y)    -> ( current_predicate(ab_state_update/4)
  227                        ->
  228                           ( Z1=[sit(S)|Z], ! ; S=[], Z=Z1 ),
  229                           ( state_update(Z,A,Z3,Y)
  230                             ; ab_res([[A,Y]|S],Z3) ),
  231                           !, Z2=[sit([[A,Y]|S])|Z3]
  232                        ;
  233                        state_update(Z1,A,Z2,Y) ) ;
  234
  235   current_predicate(perform/3),
  236   perform(A,Y,E)  -> ( current_predicate(ab_state_update/4)
  237                        ->
  238                           ( Z1=[sit(S)|Z], ! ; S=[], Z=Z1 ),
  239                           ( state_update(Z,A,Z3,Y), state_updates(Z3,E,Z4)
  240                             ; ab_res([[A,Y,E]|S],Z4) ),
  241                           !, Z2=[sit([[A,Y,E]|S])|Z4]
  242                        ;
  243                        state_update(Z1,A,Z,Y), state_updates(Z,E,Z2) ) ;
  244
  245   A = [A1|A2]     ->
  246                      execute(A1,Z1,Z), execute(A2,Z,Z2) ;
  247
  248   A = if(F,A1,A2) ->
  249                      (fluent_holds_in_state(F,Z1) -> execute(A1,Z1,Z2)
  250                                    ; execute(A2,Z1,Z2)) ;
  251
  252   A = []          ->
  253                      Z1=Z2 ;
  254
  255   complex_action(A,Z1,Z2).
  256
  257ab_res([],Z) :- init(Z).
  258ab_res([S1|S],Z) :-
  259   ab_res(S,Z1),
  260   ( S1=[A,Y] -> ( state_update(Z1,A,Z,Y) ; ab_state_update(Z1,A,Z,Y) )
  261     ;
  262     S1=[A,Y,E], ( state_update(Z1,A,Z2,Y) ; ab_state_update(Z1,A,Z2,Y) ),
  263                 state_updates(Z2, E, Z) ).
  264
  265state_updates(Z, [], Z).
  266state_updates(Z1, [A|S], Z2) :-
  267   state_update(Z1, A, Z), state_updates(Z, S, Z2).
  268
  269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  270%%
  271%% Planning
  272%%
  273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  295:- dynamic plan_search_best/2.  296
  297plan(Problem, Z, P) :-
  298   assertz(plan_search_best(_,-1)),
  299   plan_search(Problem, Z),
  300   retract(plan_search_best(P,C)),
  301   C =\= -1.
  302
  303plan_search(Problem, Z) :-
  304   current_predicate(Problem/2) ->
  305      ( PlanningProblem =.. [Problem,Z,P],
  306        call(PlanningProblem),
  307        plan_cost(Problem, P, C),
  308        plan_search_best(_,C1),
  309        ( C1 =< C, C1 =\= -1 -> fail
  310                              ; retract(plan_search_best(_,C1)),
  311                                assertz(plan_search_best(P,C)), fail )
  312        ;
  313        true ) ;
  314   PlanningProblem =.. [Problem,Z,P,Zn],
  315   call(PlanningProblem),
  316   plan_cost(Problem, P, Zn, C),
  317   plan_search_best(_,C1),
  318   ( C1 =< C, C1 =\= -1 -> fail
  319                         ; retract(plan_search_best(_,C1)),
  320                           assertz(plan_search_best(P,C)), fail )
  321   ;
  322   true.
  333knows(F, S, Z0) :- \+ ( res(S, Z0, Z), not_holds(F, Z) ).
  340knows_not(F, S, Z0) :- \+ ( res(S, Z0, Z), fluent_holds_in_state(F, Z) ).
  348knows_val(X, F, S, Z0) :-
  349   res(S, Z0, Z) -> findall(X, knows_val(X,F,Z), T),
  350                    assertz(known_val(T)),
  351                    false.
  352knows_val(X, F, S, Z0) :-
  353   known_val(T), retract(known_val(T)), member(X, T),
  354   \+ ( res(S, Z0, Z), not_holds_all(F, Z) ).
  355
  356res([], Z0, Z0).
  357res(do(A,S), Z0, Z) :-
  358   A = if_true(F)  -> res(S, Z0, Z), fluent_holds_in_state(F, Z) ;
  359   A = if_false(F) -> res(S, Z0, Z), not_holds(F, Z) ;
  360   res(S, Z0, Z1), state_update(Z1, A, Z, _).
  361
  362
  363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  364%%
  365%% Ramification Problem
  366%%
  367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  381causes_f2(Z,P,N,Z2) :-
  382   causes_f2(Z,P,N,Z1,P1,N1) -> causes_f2(Z1,P1,N1,Z2)
  383                           ; Z2=Z.
  392ramify(Z1,ThetaP,ThetaN,Z2) :-
  393   update(Z1,ThetaP,ThetaN,Z), causes_f2(Z,ThetaP,ThetaN,Z2).
  398nonground(X):- \+ ground(X).
  399
  400instance1(X,Y):- subsumes_chk(Y,X)