Home > Enterprise >  Prolog: recursion is not working properly
Prolog: recursion is not working properly

Time:12-17

I want to write change_state( L1, L2, -L3).

L1 contains states e.g: [milled, burned] L2 contains predicates e.g: [del(milled), add(shifted)] And L3 is the return list.

Example:

L1 = [milled, burned]
L2 = [del(burned), add(shifted)]
L3 = [milled, shifted]

So L1 is my start list and depending on the predicates in L2 I change the state of L1.

This is my solution with recursion:

change_state([], [], []).

change_state(X, [], []).

change_state(State, [H|T], NewState) :-
    functor(H, N, 1),
    arg(1, H, A),
    (    N = del 
    ->   remove_from_list(A, State, NewState)
    ;    arg(1, H, A),
         add_to_list(A, State, NewState) ),
    print(NewState),
    change_state(NewState, T, X),
    print(NewState).

I also put some prints into the function for debugging.

Now the problem:

If I call the function with

change_state([milled, burned], [del(burned), add(lol), add(hi)], L).

I get as an result

L = [milled].

So only the first predicate in L2 worked.

But the prints show me:

[milled][lol,milled][hi,lol,milled][hi,lol,milled][lol,milled][milled].

So it actually worked, but because of the recursion it goes back to the first state.

Any idea how to fix this?

CodePudding user response:

Although your code is already working correctly with the modifications that were indicated in the comments, I think a clearer implementation would be as follows:

change_state(State, Changes, NewState) :-
    change_state_loop(Changes, State, NewState).

% Reverse the order of the first two arguments to avoid choice points.

change_state_loop([], State, State).
change_state_loop([Change|Changes], State, NewState) :-
    do(Change, State, PartiallyUpdatedState),
    change_state_loop(Changes, PartiallyUpdatedState, NewState).

% Use unification to choose the correct operation to perform.

do(del(Fluent), State, NewState) :- subtract(State, [Fluent], NewState).
do(add(Fluent), State, NewState) :- union(State, [Fluent], NewState).
  • Related