我正在尝试了解 Prolog 递归是如何工作的。由于某种原因,在达到基本情况后,它会将所有结果展开回来。这是代码:
makeMove([0 | Tail], List).
makeMove([Head | Tail], List) :-
Head1 is Head - 1,
makeMove([Head1 | Tail], [[Head1 | Tail] | List]).
move(InputList, Output) :-
makeMove(InputList, Output).
我在这里想做的是生成一个列表列表,该列表可以通过从输入列表的第一个元素中减去 1 直到它为 0 来形成。 这是堆栈跟踪:
[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
最佳答案
最里面的调用中Output的值是前一个调用的值加上一些东西,但是Prolog变量是不可变的。你所拥有的是中间状态。要从最后的结果中获取它,您需要第三个参数:
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).
这不是您唯一的问题,但这应该可以帮助您克服困难。
关于recursion - 达到基本情况后无法从 Prolog 中的递归中获取结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47025100/