Search code examples
prologdeclarative-programming

Reasoning in prolog issue


foo([], Res).
foo([schedule(_, X)|Tail], Res) :- append(Res, X, Res2), 
                                   foo(Tail, Res2).  

Expected result:

X is a list of values, Res is where the result should be stored.

Imagine that I call:

foo([schedule(c1,[t1,t2]),schedule(c2,[t3,t4])], X).

What the result should be is:

X = [t1,t2,t3,t4].

But the result is:

X = [] ;
X = [_G6951] ;
X = [_G6951,_G6957] ;
X = [_G6951,_G6957,_G6963] ;
X = [_G6951,_G6957,_G6963,_G6969] ;
X = [_G6951,_G6957,_G6963,_G6969,_G6975] ;
X = [_G6951,_G6957,_G6963,_G6969,_G6975,_G6981] ;
X = [_G6951,_G6957,_G6963,_G6969,_G6975,_G6981,_G6987] ;

and so on...

What is wrong in my code and reasoning, so that I understand what goes wrong?


Solution

  • For the first clause, the result for an empty list of schedules should be an empty list of values:

    foo([], []).
    

    You put the arguments for append/3 in wrong order (Res should be the concatenation of X and Res2):

    foo([schedule(_, X)|Tail], Res) :-
        append(Res2, X, Res), 
        foo(Tail, Res2).
    

    Now, in order to avoid Prolog do an infinite search for further solutions, change the order of the subgoals in the second clause:

    foo([schedule(_, X)|Tail], Res) :-
        foo(Tail, Res2),
        append(Res2, X, Res).