
   %   Implementation of World's Simplest Breadth-First Planner


:- multifile restoreSitArg/3, proc/2.

proc(wspbf(N), ?(initializeSitCount) : ?(initializeCPU) : plans(0,N)).

proc(plans(M,N),
          ?(M =< N) :
          (actionSequence(M) : ?(goal) :
           ?(reportSuccess) : ?(prettyPrintSituation) #
           pi(m1, ?(m1 is M + 1) :
           ?(reportLevel(m1)) : plans(m1,N)))).

proc(actionSequence(N),
        ?(N = 0) #
        ?(N > 0) : pi(a,?(primitive_action(a)) : a) :
        ?(-badSituation) : ?(incrementSitCount) :
        pi(n1, ?(n1 is N - 1) : actionSequence(n1))).

planbf(N) :- do(wspbf(N),s0,S), askForMore.

reportLevel(N) :- write('Starting level '), write(N),
                  reportCPUtime, write('  Good situations: '),
                  getval(sitCount,C), write(C), nl.

initializeSitCount :- setval(sitCount,0). /* Eclipse Prolog provides
                                             global variables.  */

initializeCPU :- cputime(T), setval(cpu,T).

incrementSitCount :- incval(sitCount).  % Increment global variable.

reportCPUtime :- cputime(T),  write('  CPU time (sec): '),
                 getval(cpu,T2), T1 is T - T2, write(T1).

reportSuccess :- nl, write('Success.'), reportCPUtime,
    write('  Good situations: '), getval(sitCount,C), write(C), nl.

prettyPrintSituation(S) :- makeActionList(S,Alist), nl, write(Alist), nl.

makeActionList(s0,[]).
makeActionList(do(A,S),L) :- makeActionList(S,L1), append(L1,[A],L).

restoreSitArg(prettyPrintSituation,S,prettyPrintSituation(S)).
restoreSitArg(badSituation,S,badSituation(S)).
restoreSitArg(goal,S,goal(S)).

askForMore :- write('More? '), read(n).

/* =============================================== */
/* gestione di predicati non predefiniti in SWI-prolog */

/* setval(Name,Value), incval(Name), getval(Name,Val) */

:- dynamic(counter_value).

setval(Name,Value) :-
	retractall(counter_value(Name,_)),
	assert(counter_value(Name,Value)).
incval(Name) :-
	retract(counter_value(Name,Value)),
	NewValue is Value + 1,
	assert(counter_value(Name,NewValue)).
getval(Name,Value) :-
	counter_value(Name,Value).

/* cputime(T) */

cputime(T) :- get_time(T).

