+% -------------= Simple planner for situation calculus =---------------
+%
+% Executes an iterative deepening search, by default limited to a depth
+% of 15 levels
+%
+% plan. will search for a plan of maximum length
+% plan(M). will search for a plan of maximum length up to M
+% plan(N,M). will search for a plan of mimimum length N and maximum
+% length M
+%
+%
+% Checklist for the definition of a domain and problem:
+%
+% - initial state initialize fluents in s0
+%
+% - possibility axioms poss( <action>(...), S ) :- <precond>
+%
+% - successor-state axioms <fluent>( ..., result(A,S) ) :-
+% <some events made it true>; % or
+% <it was true all along>, % and
+% not(<some events made it false>).
+%
+% - goal predicate goal(S) :- <goal conditions>
+%
+
+% --------------------------= High Level =-----------------------------
+
+% default number of iterations (15)
+plan :- plan(0, 15).
+
+% given max number of iterations
+plan(MaxDepth) :- plan(0, MaxDepth).
+
+% given min and max number of iterations
+plan(MinDepth, MaxDepth) :-
+ M is MaxDepth+1, write('Trying plans of length: '),
+ plan(Plan, MinDepth, M), nl, nl, writePlan(Plan).
+
+
+
+% same as above, to be called from shell; include additional output
+% messages and halt to quit pl
+planner :- planner(0, 15).
+planner(MaxDepth) :- planner(0, MaxDepth).
+planner(MinDepth, MaxDepth) :-
+ nl, plan(MinDepth, MaxDepth), nl, halt;
+ write('\n\nNo plan has been found!'), nl, nl, halt.
+
+
+
+% ---------------------------= Low Level =-----------------------------
+
+% start from depth N, up to M
+
+plan(P, N, M) :-
+ N < M,
+ debugoutput(write('\n\nPlans of length ')),
+ writef('%w %f',[N]),
+ seqplan(P, N, s0), !.
+
+plan(P, N, M) :- N < M, O is N+1, plan(P, O, M).
+
+seqplan( [], N, S ) :- N = 0, debugoutput(writeSituation(S)), goal(S).
+seqplan( [A|L], N, S) :- N > 0, M is N-1, result(A,S,S1), seqplan(L, M, S1).
+
+result(E,S,result(E,S)) :- primitive_action(E), poss(E,S).
+
+% -----------------------= Support Function =--------------------------
+
+% debugoutput will be printed only if debug(on) is defined in the KB
+:- dynamic debug/1.
+:- multifile debug/1.
+
+debug(on).
+debugoutput(A) :- debug(on), A, !; true.
+
+
+% prints a situation as a sequence of actions, starting from s0
+writeSituation(s0) :- write('\n s0').
+writeSituation(result(A,S)) :- writeSituation(S), writef(" > %w", [A]).
+
+% prints a plan as a list of actions, numbered
+
+writePlan(List) :-
+ debugoutput(write('\nA plan has been found:\n\n')),
+ writePlan(List,1).
+
+writePlan([],_) :-
+ nl.
+
+writePlan([Action|List], Counter) :-
+ writef('%3R %w\n',[Counter,Action]),
+ Next is Counter+1,
+ writePlan(List,Next).
+
+
+% hides some (unimportant) warnings from the pl interpreter
+:- style_check([-discontiguous, -singleton]).
+
+
+
+% ---------------------------------------------------------------------
+% ---------------------------------------------------------------------