这就是该条款的样子
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
我的问题是,我不明白分裂是如何运作的。我为上述案例写了下来,但我还是不知道。如果有人能解释我,我将不胜感激。
答案 0 :(得分:2)
为了更好地理解,首先尝试使用一些更具描述性(或至少是传统的)变量名称:
splits(L, ([], L)).
splits([Head|Tail], ([Head|Tail2], Remainder)):-
splits(Tail, (Tail2, Remainder)).
所以,你的第一个版本的Res
,它在第0个元素之前分割,应该是显而易见的:它是一个空列表和整个列表,它匹配第一个子句。
对于后续结果,Prolog会回溯,直到找到之前未采用的替代路线。鉴于[1,2,3]
是具有头部和尾部的列表,它与另一个子句中的[Head|Tail]
匹配。 Head
为1
,Tail
为[2,3]
。
所以我们现在再次绕过序列,但这一次,[2,3]
作为第一个参数。在第一个实例中,将(Tail2, Reminder)
绑定到([], [2,3])
,意味着([Head|Tail2], Remainder)
(即Res
,在您的查询中),因此绑定到([1 | []],[2,3])
。 [1|[]]
只是[1]
。所以你得到第二个回应。
然后以相同的方式导出后续结果,每次回溯发生时选择不同的子句。