Prolog如何评估此条款?

时间:2015-04-04 21:02:37

标签: prolog

这就是该条款的样子

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

拆分应该在每个可能的点上将列表L分成两部分,并且应该返回所有可能性。 可能的查询是
分裂([1,2,3],Res)

结果是

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

我的问题是,我不明白分裂是如何运作的。我为上述案例写了下来,但我还是不知道。如果有人能解释我,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

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

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

所以,你的第一个版本的Res,它在第0个元素之前分割,应该是显而易见的:它是一个空列表和整个列表,它匹配第一个子句。

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

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

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