2
votes

I am trying to implement a kind of planner that to a given integer N generates X possible plans with N actions. A action has conditions and restrictions that must be fulfilled, and a list of effects that will be applied to the current state. I implemented the predicates that check the restrictions and conditions and the one that applies the effects. This method that i created already generates a plan with the N actions, but when i press ";" in swi-prolog to see other results, i get the following error:

ERROR: Out of local stack

This is my code:

makePlan(0,_,List):- List = [].
makePlan(N,I,R):- makeSinglePlan(N,I,R).

makeSinglePlan(0, _ ,_).
makeSinglePlan(N,I,[X|LIST]):- 
accao(nome : X, condicoes : Y, efeitos : Z, restricoes : W),
    checkAllConditions(Y, I),
    checkRestrictions(W), 
    applyEffects(I, Z, Current), 
    decrement(N, B), 
    list_to_set(Current, NC),
    makeSinglePlan(B,NC,LIST).


decrement(N,B):- B is N-1.

This is how i call the predicate from the console, the first param is the integer N that represents the number of actions that the plans should have, the second is the initial state, and third the return value:

makePlan(2, [clear(b),on(b,a),on(a,mesa),clear(d),on(d,c),on(c,mesa)], R).´

Example of an action:

accao(nome : putOn(X,Y), %name 
 condicoes : [on(X,Z),clear(X),clear(Y)], %conditions
   efeitos : [clear(Z),on(X,Y),-on(X,Z),clear(b)], %effects
restricoes : [(Y\==mesa),(X\==Y),(X\==Z),(Y\==Z)]) %restrictions

Auxiliar Predicates:

     % 1 - conditions to be checked 2 - current state
    checkAllConditions([],_).
    checkAllConditions([X|T],L):- checkCond(X,L) , checkAllConditions(T,L) .

    checkCond(X,[X|_]).
    checkCond(X,[_|T]):-checkCond(X,T).

      % 1 - restrictions to be checked
    checkRestrictions([]).
    checkRestrictions([X|T]):- X, checkRestrictions(T).

      % 1 -current state 2 - effects to be applied 3 - result
    applyEffects(L,[],L).
    applyEffects(L, [-X|YTail], A):- ! ,remove(X, L, B), applyEffects(B,YTail, A).
    applyEffects(L, [Y|YTail], A):- insert(Y, L, B), applyEffects(B,YTail, A).

    insert(E, L1, [E|L1] ).

    remove(_,[],[]).
    remove(X, [X|L1], A):- !, remove(X,L1,A).
    remove(X, [Y|L1], [Y|A]):- remove(X,L1,A).
1
@false i added the auxiliar predicatesMiguel Morujão
@false i updated all the code, now with 0 warningsMiguel Morujão

1 Answers

3
votes

Two changes are necessary:

makeSinglePlan(0, _ ,[]).
makeSinglePlan(N,I,[X|LIST]):-
    N > 0,
    ....

The list of actions should end with [], and the rule only applies for N > 0.

?- makePlan(2, [clear(b),on(b,a),on(a,mesa),clear(d),on(d,c),on(c,mesa)], R).
R = [putOn(b, d), putOn(b, a)] ;
R = [putOn(b, d), putOn(a, b)] ;
R = [putOn(b, d), putOn(a, d)] ;
R = [putOn(b, d), putOn(d, b)] ;
R = [putOn(b, d), putOn(d, a)] ;
R = [putOn(d, b), putOn(d, c)] ;
R = [putOn(d, b), putOn(b, c)] ;
R = [putOn(d, b), putOn(b, d)] ;
R = [putOn(d, b), putOn(c, b)] ;
R = [putOn(d, b), putOn(c, d)] ;
false.