```
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)
```