2015-04-04 127 views
2

这是第看起来像Prolog如何评估此条款?

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

分裂应该在每一个可能的点分成两个部分列表L,而应返回做好一切准备。 可能的查询是
split([1,2,3],Res)

结果是

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

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

+0

什么是你不明白? – 2015-04-04 21:10:59

+0

@PaulButcher:我不明白的是,它一般如何工作。我一步一步写下来,但我不知道* Res *是如何产生的。 – tumbler 2015-04-04 21:24:30

+0

@PaulButcher:对于S和E的例子相当混乱。 – tumbler 2015-04-04 21:26:47

回答

2

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

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

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

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

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

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