12:-include(swi_fd). 13
14flux_version(3.1).
19:- use_module(library(chr)).
23:- ensure_loaded('fluent3.chr'). 24
25:- tell('fluent3.pl'),listing,told. 26
27
39holds(F, [F|_]).
40holds(F, Z) :- nonvar(Z), Z=[F1|Z1], F\==F1, holds(F, Z1).
49holds(F, [F|Z], Z).
50holds(F, Z, [F1|Zp]) :- nonvar(Z), Z=[F1|Z1], F\==F1, holds(F, Z1, Zp).
58cancel(F,Z1,Z2) :-
59 var(Z1) -> cancel(F,Z1), cancelled(F,Z1), Z2=Z1 ;
60 Z1 = [G|Z] -> ( F\=G -> cancel(F,Z,Z3), Z2=[G|Z3]
61 ; cancel(F,Z,Z2) ) ;
62 Z1 = [] -> Z2 = [].
69minus_(Z, [], Z).
70minus_(Z, [F|Fs], Zp) :-
71 ( \+ not_holds(F, Z) -> holds(F, Z, Z1) ;
72 \+ holds(F, Z) -> Z1 = Z
73 ; cancel(F, Z, Z1), not_holds(F, Z1) ),
74 minus_(Z1, Fs, Zp).
81plus_(Z, [], Z).
82plus_(Z, [F|Fs], Zp) :-
83 ( \+ holds(F, Z) -> Z1=[F|Z] ;
84 \+ not_holds(F, Z) -> Z1=Z
85 ; cancel(F, Z, Z2), not_holds(F, Z2), Z1=[F|Z2] ),
86 plus_(Z1, Fs, Zp).
94update(Z1, ThetaP, ThetaN, Z2) :-
95 minus_(Z1, ThetaN, Z), plus_(Z, ThetaP, Z2).
96
97
109knows(F, Z) :- \+ not_holds(F, Z).
116knows_not(F, Z) :- \+ holds(F, Z).
132knows_val(X, F, Z) :- k_holds(F, Z), knows_val(X).
133
134k_holds(F, Z) :- nonvar(Z), Z=[F1|Z1],
135 ( instance(F1, F), F=F1 ; k_holds(F, Z1) ).
136
137:-local variable(known_val).
138:-setval(known_val,[]). 139
140knows_val(X) :- dom(X), \+ nonground(X), ambiguous(X) -> false.
141knows_val(X) :- getval(known_val,X), X \== [], setval(known_val, []).
142
143dom([]).
144dom([X|Xs]) :- dom(Xs), ( is_domain(X) -> indomain(X)
145 ; true ).
146
147ambiguous(X) :-
148 ( getval(known_val, Val),
149 Val \== [] -> setval(known_val, [])
150 ;
151 setval(known_val, X),
152 false
153 ).
154
192execute(A,Z1,Z2) :-
193 is_predicate(perform/2),
194 perform(A,Y) -> ( is_predicate(ab_state_update/4) ->
195 ( Z1=[sit(S)|Z], ! ; S=[], Z=Z1 ),
196 ( state_update(Z,A,Z3,Y)
197 ; ab_res([[A,Y]|S],Z3) ),
198 !, Z2=[sit([[A,Y]|S])|Z3]
199 ;
200 state_update(Z1,A,Z2,Y) ) ;
201
202 is_predicate(perform/3),
203 perform(A,Y,E) -> ( is_predicate(ab_state_update/4) ->
204 ( Z1=[sit(S)|Z], ! ; S=[], Z=Z1 ),
205 ( state_update(Z,A,Z3,Y), state_updates(Z3,E,Z4)
206 ; ab_res([[A,Y,E]|S],Z4) ),
207 !, Z2=[sit([[A,Y,E]|S])|Z4]
208 ;
209 state_update(Z1,A,Z,Y), state_updates(Z,E,Z2) ) ;
210
211 A = [A1|A2] ->
212 execute(A1,Z1,Z), execute(A2,Z,Z2) ;
213
214 A = if(F,A1,A2) ->
215 (holds(F,Z1) -> execute(A1,Z1,Z2)
216 ; execute(A2,Z1,Z2)) ;
217
218 A = [] ->
219 Z1=Z2 ;
220
221 complex_action(A,Z1,Z2).
222
223ab_res([],Z) :- init(Z).
224ab_res([S1|S],Z) :-
225 ab_res(S,Z1),
226 ( S1=[A,Y] -> ( state_update(Z1,A,Z,Y) ; ab_state_update(Z1,A,Z,Y) )
227 ;
228 S1=[A,Y,E], ( state_update(Z1,A,Z2,Y) ; ab_state_update(Z1,A,Z2,Y) ),
229 state_updates(Z2, E, Z) ).
230
231state_updates(Z, [], Z).
232state_updates(Z1, [A|S], Z2) :-
233 state_update(Z1, A, Z), state_updates(Z, S, Z2).
234
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236%%
237%% Planning
238%%
239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240
241%%
242%% plan(PlanningProblemName,Z,P)
243%%
244%% P is an optimal plan for PlanningProblemName with starting state Z
245%%
246%% It assumes the definition of a predicate PlanningProblemName(Z0,P,Z)
247%% describing the search space such that plan P executed in starting
248%% state Z0 results in state Z which satisfies the planning goal,
249%% and the definition of plan_cost(PlanningProblemName,P,Z,C) such that
250%% C is the cost of plan P resulting in state Z; or
251%%
252%% the definition of a predicate is PlanningProblemName(Z0,P)
253%% describing the search space such that conditional plan P executed in
254%% starting state Z0 necessarily results in a state in which the planning
255%% goal is satisfied, and the definition of plan_cost(PlanningProblemName,P,C)
256%% such that C is the cost of plan P.
257%%
258%% For the definition of the search space, the predicates for knowledge
259%% described below can be used.
260%%
261
262:- local variable(plan_search_best).
263
264plan(Problem, Z, P) :-
265 setval(plan_search_best(_ : -1)),
266 plan_search(Problem, Z),
267 getval(plan_search_best,P:C),
268 C =\= -1.
269
270plan_search(Problem, Z) :-
271 is_predicate(Problem/2) ->
272 ( PlanningProblem =.. [Problem,Z,P],
273 call(PlanningProblem),
274 plan_cost(Problem, P, C),
275 getval(plan_search_best,_:C1),
276 ( C1 =< C, C1 =\= -1 -> false
277 ;
278 setval(plan_search_best,P:C), false )
279 ;
280 true ) ;
281 PlanningProblem =.. [Problem,Z,P,Zn],
282 call(PlanningProblem),
283 plan_cost(Problem, P, Zn, C),
284 getval(plan_search_best,_:C1),
285 ( C1 =< C, C1 =\= -1 -> false
286 ;
287 setval(plan_search_best,P:C),
288 false
289 )
290 ;
291 true.
303knows(F, S, Z0) :- \+ ( res(S, Z0, Z), not_holds(F, Z) ).
310knows_not(F, S, Z0) :- \+ ( res(S, Z0, Z), holds(F, Z) ).
311
312%%
313%% knows_val(X,F,S,Z0)
314%%
315%% there is an instance of the variables in X for which
316%% non-ground fluent F is known to hold after doing S in state Z0
317%%
318
319:-local variable(known_vals).
320
321knows_val(X, F, S, Z0) :-
322 setval(known_vals,[]),
323 res(S, Z0, Z),
324 findall(X, knows_val(X,F,Z), T),
325 getval(known_vals,T1),
326 ( T1=[] -> T2=T ; intersection(T,T1,T2) ),
327 setval(known_vals, T2),
328 false.
329knows_val(X, _, _, _) :-
330 getval(known_vals, T),
331 member(X, T),
332 setval(known_vals, []).
333
334
335res([], Z0, Z0).
336res(do(A,S), Z0, Z) :-
337 ( A = if_true(F) -> res(S, Z0, Z), holds(F, Z)
338 ;
339 ( A = if_false(F) -> res(S, Z0, Z),
340 not_holds(F, Z)
341 ;
342 res(S, Z0, Z1),
343 state_update(Z1, A, Z, _)
344 )
345 ).
346
347
366causes(Z,P,N,Z2) :-
367 causes(Z,P,N,Z1,P1,N1) -> causes(Z1,P1,N1,Z2)
368 ; Z2=Z.
377ramify(Z1,ThetaP,ThetaN,Z2) :-
378 update(Z1,ThetaP,ThetaN,Z), causes(Z,ThetaP,ThetaN,Z2)