Search code examples
recursionprologreportingread-eval-print-loop

Can't get my results back from recursion in Prolog after reaching base case


I'm trying to get how Prolog recursion works. For some reason after reaching base case it unwinds all the results back. Here is the code:

makeMove([0 | Tail], List).
makeMove([Head | Tail], List) :-
    Head1 is Head - 1,
    makeMove([Head1 | Tail], [[Head1 | Tail] | List]).

move(InputList, Output) :-
    makeMove(InputList, Output).

What I'm trying to do here is to generate the list of lists that can be formed by subtracting 1 from the first element of the input List until it's 0. Here's the stack trace:

[trace]  ?- 
|    move([3,4,5], X).
   Call: (8) move([3, 4, 5], _23538) ? creep
   Call: (9) makeMove([3, 4, 5], _23538) ? creep
   Call: (10) _23792 is 3+ -1 ? creep
   Exit: (10) 2 is 3+ -1 ? creep
   Call: (10) makeMove([2, 4, 5], [[2, 4, 5]|_23538]) ? creep
   Call: (11) _23816 is 2+ -1 ? creep
   Exit: (11) 1 is 2+ -1 ? creep
   Call: (11) makeMove([1, 4, 5], [[1, 4, 5], [2, 4, 5]|_23538]) ? creep
   Call: (12) _23840 is 1+ -1 ? creep
   Exit: (12) 0 is 1+ -1 ? creep
   Call: (12) makeMove([0, 4, 5], [[0, 4, 5], [1, 4, 5], [2, 4, 5]|_23538]) ? creep
   Exit: (12) makeMove([0, 4, 5], [[0, 4, 5], [1, 4, 5], [2, 4, 5]|_23538]) ? creep
   Exit: (11) makeMove([1, 4, 5], [[1, 4, 5], [2, 4, 5]|_23538]) ? creep
   Exit: (10) makeMove([2, 4, 5], [[2, 4, 5]|_23538]) ? creep
   Exit: (9) makeMove([3, 4, 5], _23538) ? creep
   Exit: (8) move([3, 4, 5], _23538) ? creep
true 

Solution

  • The value of Output in the innermost call is the value of the previous call with some stuff put on it, but Prolog variables are not mutable. What you have is an intermediate state. To obtain it from the last result, you need a third parameter:

    makeMove([0 | Tail], Result, Result).
    
    makeMove([Head | Tail], List, Result) :-
        Head1 is Head - 1,
        makeMove([Head1 | Tail], [[Head1 | Tail] | List], Result).
    
    move(InputList, Output) :-
        makeMove(InputList, [], Output).
    

    This is not your only issue, but this should get you over the hump.