Prolog 如何评估这个子句?

How does Prolog evaluate this clause?

子句是这样的

splits(L, ([],L)).
splits([X|L],([X|S],E)):- splits(L, (S,E)).

splits 应该在每个可能的点将列表 L 分成两部分,并且应该 return 所有的可能性。 一个可能的查询是
splits([1,2,3], Res).

结果是

Res = ([], [1,2,3]);
Res = ([1], [2,3]);
Res = ([1,2], [3]);
Res = ([1,2,3], []);
No

我的问题是,我不明白拆分是如何工作的。我为上述情况写下了它,但我仍然不知道。如果有人能向我解释一下,我将不胜感激。

为了更好地理解,首先尝试使用一些更具描述性(或至少是常规的)变量名称:

splits(L, ([], L)).
splits([Head|Tail], ([Head|Tail2], Remainder)):- 
   splits(Tail, (Tail2, Remainder)).

因此,您的 Res 的第一个版本在第零个元素之前拆分,应该很明显:它是一个空列表和整个列表,并且与第一个子句匹配。

对于后续结果,Prolog 会回溯,直到找到之前未采用的替代路线。假设 [1,2,3] 是一个有头有尾的列表,它匹配 other 子句中的 [Head|Tail]Head1Tail[2,3]

所以我们现在再次遍历序​​列,但这一次,[2,3] 作为第一个参数。在第一个实例中,将 (Tail2, Reminder) 绑定到 ([], [2,3]),这意味着 ([Head|Tail2], Remainder)(即您的查询中的 Res)因此绑定到 ([1 | []],[2,3])[1|[]] 就是 [1]。所以你得到了你的第二个回应。

随后的结果以相同的方式导出,每次回溯时选择不同的子句。