
:- [golog_swi].
:- discontiguous proc/2.
:- multifile restoreSitArg/3.

%  Implementation of a depth-first planner.

plandf(N) :- do(wspdf(N),s0,_), askForMore.

proc(wspdf(N),
     ?(initializeSitCount) : ?(initializeCPU) : plans(N)).

proc(plans(N),   
     ?(goal) : ?(info) : ?(prettyPrintSituation) #
     ?(N > 0) : pi(a,?(primitive_action(a)) : a) : 
     ?(-badSituation) : ?(incrementSitCount) : 
     pi(n1, ?(n1 is N - 1) : plans(n1))).

% ---------------------------------------------------------------
   %   Implementation of World's Simplest Breadth-First Planner

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

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))).

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

/* ----------------------------------------------- */

info :- nl, cputime(T), write('  CPU time (sec): '), 
     getval(cpu,T1), T2 is T - T1, write(T2), getval(sitCount,C), 
     write('  Good situations: '), write(C), nl.
 
initializeSitCount :- setval(sitCount,0).

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

incrementSitCount :- incval(sitCount).

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).
