PageRenderTime 68ms CodeModel.GetById 13ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 0ms

/graphplan.pl

http://github.com/Mortimerp9/Prolog-Graphplan
Perl | 328 lines | 240 code | 88 blank | 0 comment | 3 complexity | dd3ea5ae5b04972884c10fb9ac926538 MD5 | raw file
  1%    This file is part of the Prolog Graplan project.
  2%
  3%    The Prolog Graplan project is free software: you can redistribute it and/or modify
  4%    it under the terms of the GNU General Public License as published by
  5%    the Free Software Foundation, either version 3 of the License, or
  6%    (at your option) any later version.
  7%
  8%    The Prolog Graplan project is distributed in the hope that it will be useful,
  9%    but WITHOUT ANY WARRANTY; without even the implied warranty of
 10%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11%    GNU General Public License for more details.
 12%
 13%    You should have received a copy of the GNU General Public License
 14%    along with the Prolog Graplan project.  If not, see <http://www.gnu.org/licenses/>.
 15
 16% (C) 2011 Suresh Manandhar, Pierre Andrews
 17
 18% Graphplan Planner based on Blum & Furst 1997. Journal of AI, 90:281-300.
 19%  Pierre Andrews and Suresh Manandhar Nov 2006
 20%
 21
 22:- dynamic no_op_count/1.
 23:- dynamic mutex_action/3.
 24:- dynamic mutex_condition/3.
 25
 26:- dynamic plan_graph_del/3.
 27:- dynamic plan_graph_add/3.
 28:- dynamic plan_graph_pre/3.
 29
 30plan(InitialState, FinalState, Domain, Plan):-
 31	retractall(no_op_count(_)),
 32	retractall(mutex_action(_, _, _)),
 33	retractall(mutex_condition(_, _, _)),
 34
 35	retractall(plan_graph_del(_, _, _)),
 36	retractall(plan_graph_add(_, _, _)),
 37	retractall(plan_graph_pre(_, _, _)),
 38
 39	assert(no_op_count(0)),
 40	add_initial_conditions(InitialState),
 41	generate_graph_nodes(1, FinalState, FinalLevel, Domain),
 42	find_plan(FinalLevel, FinalState, InitialState, [], PlanT),
 43	remove_no_ops(PlanT, Plan),
 44	nl, nl, write_plan(Plan), nl.
 45
 46
 47find_plan(0, CurrentState, InitialState, Plan, Plan):-
 48	subset(CurrentState, InitialState).
 49
 50find_plan(N, CurrentState, InitialState, PrevActions, Plan):-
 51	N > 0,
 52	find_current_level_actions(N, CurrentState,  [], CurLevelNActions, []),
 53	
 54	findall(Cond,(member(Action,CurLevelNActions), plan_graph(N, pre, Cond, Action)), PreConds),
 55	list_to_set(PreConds, MidState),
 56
 57%	nl, write(' Level  '), write(N),
 58%	nl, write('Actions : '), nl, write(CurLevelNActions),
 59%	nl, write('State   : '), nl, write(CurrentState), nl,nl,
 60
 61	N1 is N-1,
 62	find_plan(N1, MidState, InitialState, [CurLevelNActions|PrevActions], Plan).
 63
 64
 65find_current_level_actions(_, [], Actions, Actions, _).
 66find_current_level_actions(N, CurrentState, CurActions, Actions, CurAdds):-
 67	member(Pred, CurrentState),
 68	choose_action_to_achieve_pred(N, Pred, Action),
 69
 70	not( (member(OtherAction,CurActions), mutex_action(N, Action, OtherAction)) ),
 71
 72	findall(Cond, plan_graph(N, add, Cond, Action), AddCondsL),
 73	list_to_set(AddCondsL, AddConds),
 74
 75	%% Plan minimality (as described in the paper) is equivalent to redundancy check
 76	%% There is no other action which has the same effect i.e. same add conditions
 77	not( (member(OtherAdds,CurAdds), subset(AddConds,OtherAdds), subset(OtherAdds,AddConds)) ),
 78
 79	subtract(CurrentState, AddConds, CurrentStateMod),
 80	find_current_level_actions(N, CurrentStateMod, [Action|CurActions], Actions, [AddConds|CurAdds]).
 81
 82
 83
 84choose_action_to_achieve_pred(N, Pred, no_op(X)):-  %% Generate shorter plans using the following strategy
 85	plan_graph(N, add, Pred, no_op(X)).                   %% Be lazy: prefer no ops
 86
 87choose_action_to_achieve_pred(N, Pred, OtherAction):-    %% Choose real actions only if no ops fail
 88	plan_graph(N, add, Pred, OtherAction),
 89	OtherAction \= no_op(_).
 90
 91
 92
 93
 94
 95add_initial_conditions([]).
 96add_initial_conditions([Pred|Conditions]):-
 97	add_plan_graph(0, add, Pred, start),
 98	add_initial_conditions(Conditions).
 99
100
101generate_graph_nodes( N, _, _, _Domain):-
102	N > 30,   %% The program is probably too slow beyond this point
103	!,
104	nl, nl, write('Bound reached'),
105	nl, write('Terminating.....'),
106	fail.
107
108generate_graph_nodes( N, FinalState, N1, _Domain):-
109	N1 is N-1,
110	%% Check if FinalState Conditions have been satisfied 
111        %%    and no mutual exclusion conditions have been violated
112	get_nonmutex_addconds(FinalState, N1, []),
113	nl, write('Feasible Plan found at level '), write(N1),
114	!.
115
116generate_graph_nodes(N, _, _, _Domain):-
117
118	% Add no-ops
119	add_no_op_nodes(N),
120
121	fail.
122
123
124generate_graph_nodes(N, _, _, Domain):-
125	can(Action, PreConditions, Domain),
126	NPrev is N-1,
127	get_nonmutex_addconds(PreConditions, NPrev, []),	
128	
129	deletes(Action, DelPreConditions, Domain),
130	%% Instantiation Check
131	( ground(DelPreConditions) 
132           -> true
133            ; ( 
134	        nl, 
135		write('Action not fully instantiated '), write(Action),
136		nl,
137		write('Del Conditions: '), write(DelPreConditions), nl
138	    )
139	),
140
141	
142	adds(Action, AddConditions, _, Domain),
143	%% Instantiation Check
144	( ground(AddConditions) 
145           -> true
146            ; ( 
147	        nl, 
148		write('Action not fully instantiated '), write(Action),
149		nl,
150		write('Add Conditions: '), write(AddConditions), nl
151	    )
152	),
153
154
155	add_graph_nodes(PreConditions, Action, N, pre),
156
157	add_graph_nodes(DelPreConditions, Action, N, del),
158	add_graph_nodes(AddConditions, Action, N, add),
159
160%	nl, write("Added Action: "), write(Action),
161%	nl,
162
163	fail.
164
165generate_graph_nodes(N, FinalState, FinalLevel, Domain):-
166
167	% Propagate mutual exclusions
168	mutex(N),
169
170	N1 is N+1,
171	!,
172	generate_graph_nodes(N1, FinalState, FinalLevel, Domain),
173	!.
174
175
176get_nonmutex_addconds([], _, _).
177get_nonmutex_addconds([Pred|Conditions], N, PrePreds):-
178	plan_graph(N, add, Pred, _),
179	check_mutex(PrePreds, Pred, N),
180	get_nonmutex_addconds(Conditions, N, [Pred|PrePreds]).
181	
182check_mutex([], _, _).
183check_mutex([OtherPred|Others], Pred, N):-
184	not(mutex_condition(N, Pred, OtherPred)),
185	check_mutex(Others, Pred, N).
186
187
188
189
190mutex(N):-
191	mutex_add_del_conflict(N),
192	mutex_precond_conflict(N),
193	mutex_add_add_conflict(N).
194
195
196mutex_add_del_conflict(N):-
197	plan_graph(N, del, Pred, Action2),
198	( plan_graph(N, add, Pred, Action1); plan_graph(N, pre, Pred, Action1) ),
199	Action1 \= Action2,
200	insert_action_conflict(N, Action1, Action2),
201	fail.
202mutex_add_del_conflict(_).
203
204
205insert_action_conflict(N, Action1, Action2):-
206	add_to_db(mutex_action(N, Action1, Action2)),
207	add_to_db(mutex_action(N, Action2, Action1)).
208
209
210
211mutex_add_add_conflict(N):-
212	mutex_action(N, Action1, Action2),
213	plan_graph(N, add, Pred1, Action1),
214	plan_graph(N, add, Pred2, Action2),
215
216	Action1 \= Action2,
217	Pred1 \= Pred2,
218	not(mutex_condition(N, Pred1, Pred2)),
219	not( (
220	       plan_graph(N, add, Pred1, Action11),
221	       plan_graph(N, add, Pred2, Action22),
222	       Action11 \= Action22,
223	       not(mutex_action(N, Action11, Action22))
224	      )
225           ),
226	add_to_db(mutex_condition(N, Pred1, Pred2)),
227	add_to_db(mutex_condition(N, Pred2, Pred1)),
228	fail.
229mutex_add_add_conflict(_).
230
231
232mutex_precond_conflict(N):-
233	N1 is N-1,
234	mutex_condition(N1, Pred1, Pred2),
235	plan_graph(N, pre, Pred1, Action1),
236	plan_graph(N, pre, Pred2, Action2),
237	Action1 \= Action2,
238	insert_action_conflict(N, Action1, Action2),
239	fail.
240mutex_precond_conflict(_).
241	
242
243plan_graph(N, del, Pred, Action):-
244	plan_graph_del(N, Pred, Action).
245	
246plan_graph(N, pre, Pred, Action):-
247	plan_graph_pre(N, Pred, Action).
248	
249plan_graph(N, add, Pred, Action):-
250	plan_graph_add(N, Pred, Action).
251
252
253add_plan_graph(N, del, Pred, Action):-
254	plan_graph_del(N, Pred, Action),
255	!.
256add_plan_graph(N, del, Pred, Action):-
257	assert(plan_graph_del(N, Pred, Action)).
258add_plan_graph(N, pre, Pred, Action):-
259	plan_graph_pre(N, Pred, Action),
260	!.
261add_plan_graph(N, pre, Pred, Action):-
262	assert(plan_graph_pre(N, Pred, Action)).
263add_plan_graph(N, add, Pred, Action):-
264	plan_graph_add(N, Pred, Action),
265	!.
266add_plan_graph(N, add, Pred, Action):-
267	assert(plan_graph_add(N, Pred, Action)).
268
269
270
271
272add_graph_nodes([], _, _, _).
273add_graph_nodes([Pred|Conditions], Action, N, Type):-
274	add_plan_graph(N, Type, Pred, Action),
275	add_graph_nodes(Conditions, Action, N, Type).
276
277add_no_op_nodes(N):-
278	NPrev is N-1,
279	plan_graph(NPrev, add, Pred, _),
280	add_no_op_node(Pred, N),
281	fail.
282add_no_op_nodes(_).
283
284
285add_no_op_node(Pred, N):-
286	not((plan_graph(N, add, Pred, no_op(C)), plan_graph(N, pre, Pred, no_op(C)))),
287	new_no_op_count(Count),
288	add_plan_graph(N, add, Pred, no_op(Count)),
289	add_plan_graph(N, pre, Pred, no_op(Count)).
290
291
292
293new_no_op_count(N):-
294	retract(no_op_count(N)),
295	N1 is N+1,
296	assert(no_op_count(N1)).
297
298
299
300add_to_db(Clause):-
301	call(Clause),
302	!.
303add_to_db(Clause):-
304	assert(Clause).
305
306
307write_plan(Plan):- write_plan(Plan,1). 
308
309write_plan([], _):- nl.
310write_plan([Actions|Rest], N):-
311	nl, write('Step '), write(N), write(:), nl,
312	write_list(Actions),
313	N1 is N+1,
314	write_plan(Rest, N1).
315	
316write_list([]).
317write_list([no_op(_)|L]):- !, write_list(L).
318write_list([X|L]):-  write('        '), write(X), nl, write_list(L).
319
320remove_no_ops([],[]).
321remove_no_ops([no_op(_)|L],R):-
322	!,
323	remove_no_ops(L,R).
324remove_no_ops([X|L],[X1|R]):-
325	!,
326	remove_no_ops(X,X1),
327	remove_no_ops(L,R).
328remove_no_ops(X,X).