% A reconstruction of simple version of Cohen's planning program% Based on Gazdar and Mellish% Christopher Manning May 1999%%% ----- The initial states and goals%%% ----- These are given a number, so that we can refer to multiple%%% ----- scenarios in one program.  They can be tested out by%%% ----- trying: test(number).%%% ----- You need that full stop at the end!%%% ----- An inital state is an id number followed by a list of true things%%% ----- A goal is an ID, whose goal it is, and then what the goal isinitial(1, [at(alan,inside), door(inside, outside, open)]).goal(1, alan, at(alan,outside)).initial(2, [at(alan,room1),	door(room1,room2,open),	door(room2,room3,open),	door(room3,room4,open)]).goal(2, alan, at(alan,room4)).initial(3, 	[at(alan,inside), at(sue,inside),	 cando(alan,move(alan,inside,outside)),	 believes(sue,cando(alan,move(alan,inside,outside))),	 door(inside, outside, open)]).goal(3, sue, at(alan,outside)).initial(4, [at(john, r1), at(mary, r2),	door(r1, r2, closed), bolt(door, back)]).goal(4, john, at(john, r2)).initial(5, [at(john, r1), at(mary, r2), cando(john, talkto(john, mary)),	cando(mary, move(mary, bolt)),	believes(john, cando(mary, move(mary, bolt))),	door(r1, r2, closed), bolt(door, across)]).goal(5, john, bolt(door, back)).initial(7, [cando(ann, talkto(ann, sandra)),    cando(sandra, talkto(sandra, ann)),    knows(sandra, safecombination)]).goal(7, ann, knows(ann, safecombination)).%%% ----- Information about possible actions and plans for achieving them%%% ----- Actions have four arguments:%%% ----- 1. The action predicate%%% ----- 2. A list of preconditions for being able to do the action%%% ----- 3. A list of things that become true as a result of doing the action%%% ----- 4. A list of things that cease to become true as a resultaction(request(P1, P2, Act),	% action	[cando(P1, talkto(P1, P2)), 	 believes(P1, cando(P2, Act))],		% preconditions	[believes(P2, wants(P1, Act))],		% becomes true	[]).			% no longer trueaction(move(Agent, Source, Destination),	[at(Agent, Source), wants(Agent, move(Agent, Source, Destination)),	 door(Source, Destination, open)],	[at(Agent, Destination)],	[at(Agent, Source)]).action(cause_to_want(Speaker, Addressee, Action),	% action	[cando(Addressee, Action),			% preconditions	 believes(Addressee, wants(Speaker, Action))],	[wants(Addressee, Action)],	[]).action(pushopen(P, door),	[door(Source, Destination, closed), 	 bolt(door, back),	 at(P, Source)],	[door(Source, Destination, open)],	[door(Source, Destination, closed)]).action(move(P, bolt),	[at(P, r2), wants(P, move(P, bolt))],	% can take out want	[bolt(door, back)],	[bolt(door, across)]).%%% ----- below here is the planner used.  You shouldn't need to look at%%% ----- or touch anything below here.% The length of a list -- used in generation mode for iterative deepeninglistlen(List, Length) :- lenacc(List, 0, Length).lenacc([], Length, Length).lenacc([_Head|Tail], A, Length) :- A1 is A + 1, lenacc(Tail, A1, Length).member(X, [X|_]).member(X, [_|Y]) :- member(X, Y).setdifference([], _, []).setdifference([A|T], B, R) :- member(A,B), !, setdifference(T, B, R).setdifference([A|T], B, [A|R]) :- setdifference(T, B, R).% planner(Id, Actions) :-	initial(Id, World),	goal(Id, Agent, Goal),	plan(Agent, Goal, World, Actions, [], _Done),	write_acts(Actions), nl.% Plan to achieve a single goal% plan(Agent, Goal, World, ActionsDiff1, ActionsDiff2, DoneFlag).plan(A, Goal, _W, _, _, _) :- write([goal,for,A,is,Goal]), nl, fail.% If a goal is commonknowledge, everyone believes it% plan(Agent, believes(_, Goal), World, Actions1, Actions2, Done) :-%	commonknowledge(Goal), !,%	plan(Agent, Goal, World, Actions1, Actions2, Done).% if it's something in the world, then we are doneplan(_Agent, Goal, World, Actions, Actions, _Done) :-	groundstate(Goal, State),	member(Goal, World),	write([it,is,true,that,Goal]), nl,	((State=ground,!); true).% Agents want things for themselvesplan(Agent, wants(Agent, _Want), _World, Actions, Actions, _Done).% Agents believe things providing they are true in the worldplan(Agent, believes(Agent, Goal), World, Actions1, Actions2, Done) :-	plan(Agent, Goal, World, Actions1, Actions2, Done).% the general recursive caseplan(Agent, Goal, World, [Action|Actions0], Actions2, Done) :- 	action(Action, Precond, Effect, NegEffect),%	write([testing,Goal,in,Effect]), nl,	member(Goal, Effect),	write([trying, operator, Action]), nl,	allplan(Agent, Precond, World, Actions0, Actions2, Done),%	allplan(Agent, Want, World, Actions1, Actions2, Done),%	this part is a noop at present	setdifference(World, NegEffect, _World2),	Done = yes.% Plan a set of goalsallplan(_Agent, [], _World, Actions, Actions, _Done).allplan(Agent, [Goal|Goals], World, Actions0, Actions2, Done) :-% 	var(Done), !,	plan(Agent, Goal, World, Actions0, Actions1, Done),	allplan(Agent, Goals, World, Actions1, Actions2, Done).% allplan(_Agent, _Goals, _World, Actions, Actions, _Done).groundstate(Goal, nonground) :- \+ ground(Goal), !.groundstate(_Goal, ground).write_acts([]) :- !,	nl, write('*** Plan is: '), nl.write_acts([Act|Acts]) :-	write_acts(Acts),	write(Act), nl.test(Id) :- listlen(Actions, Length),	( Length =< 8 -> 	   write('Trying plan of length '), write(Length), nl,	   planner(Id, Actions) 	;	   nl, 	   write('*** It doesn''t seem possible to solve that plan!'), nl,	   write('*** Aborting...'), nl,	   true	).