10:- lib(fd).
15:- lib(chr).
20:- chr('fluent'). 21
22
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
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
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
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)