列出合并代码说明

时间:2014-09-07 04:05:06

标签: prolog

在下面的代码中,我不确定前三行是做什么的?我理解第四行递归地取消了List 1和List2,但为什么需要上面的规则呢?

interweave([],[],[]).
interweave([X],[],[X]).
interweave([],[Y],[Y]).
interweave([X|List1],[Y|List2],[X,Y|Result]) :-
   interweave(List1,List2,Result).

3 个答案:

答案 0 :(得分:2)

在Prolog中,您可以在不查看实际代码的情况下回答这些问题!只需询问最常见的查询:

| ?- interweave(Xs,Ys,Zs).
Xs = [],
Ys = [],
Zs = [] ? ;
Xs = [_A],
Ys = [],
Zs = [_A] ? ;
Xs = [],
Ys = [_A],
Zs = [_A] ? ;
Xs = [_A],
Ys = [_B],
Zs = [_A,_B] ? 

所以这些案例都包含在内:如果两个列表都是空的,或者其中只有一个列表只包含一个元素。

答案 1 :(得分:2)

正如其他人所指出的,当你有一个递归谓词条款,如:

interweave([X|List1], [Y|List2], [X,Y|Result]) :-
   interweave(List1, List2, Result).

您需要终止案例。否则,逻辑在哪里结束?在这种情况下,只要前两个参数都是至少一个元素的列表(或者可以有效地实例化),第三个参数是至少两个元素的列表(或者可以实例化) ,然后会发生递归。

当您为前两个参数传递列表并期望第三个参数中的结果时,最终您将遇到下列情况之一,这将使上述谓词子句失败:

1. interweave([], List2, Result), where List2 has at least one element
2. interweave(List1, [], Result), where List1 has at least one element
3. interweave([], [], Result)

由于[X|T]无法与[]统一,因此所有这三种情况都会使上述谓词条款失败。它必然是至少一个元素的列表。因此,如果没有基本情况,如果任何参数被完全实例化,则整个谓词都会失败,或者如果它们都没有,则会无限递归。

因此,您需要至少一个基本案例才能成功。但基本情况应该是什么?这取决于你对谓词的期望。在原始实现的情况下,基本案例会给您以下行为:

1)当两个原始输入列表的长度相同时,interweave([], [], []).会成功。

2)interweave([X], [], [X]).在第一个列表只有一个元素而不是第二个列表时启用成功。

3)interweave([], [Y], [Y]).在第二个列表中只有一个元素而不是第一个列表时启用成功。

@papelliC在他的回答中指出了这些影响。因此,在您显示的当前实现中,通过三个基本情况,以下内容将成功:

interweave([1,2,3], [a,b,c], R).  % R = [1,a,2,b,3,c]
interweave([1,2,3], [a,b], R).  % R = [1,a,2,b,3]
interweave([1,2], [a,b,c], R).  % R = [1,a,2,b,c]

但是,以下情况会失败:

interweave([1,2,3], [a], R).
interweave([1], [a,b,c], R).
etc

您可以通过多种方式更改此行为。例如,如果要求两个输入列表的长度相同,则省略基本情况#2和#3。如果您希望将任何长度的列表“编织”在一起并且只是追加额外的元素,那么您可以将基本案例更改为:

interweave([], L, L).
interweave(L, [], L).

这些说与另一个列表L编织在一起的空列表是列表L 。由于[]是一个列表,因此您可以interweave([], [], [])成功,而无需明确说明。但是,对于interweave([], [], []).,它将成功两次,因此在某些情况下会产生一些重复的结果。为避免这种情况,您可以将这些基本案例定义为:

interweave([], L, L).
interweave(L, [], L) :- L = [_|_].  % Only true for non-empty list L

答案 2 :(得分:1)

当您编写递归过程时,通常会指定所谓的“基本案例”,即当不再需要或可能再次调用该过程时该怎么做。

因此,这3条规则指定了交织/ 3的基本情况。整个过程的高级描述可以读取(但事实上,我发现Prolog代码更清晰:)

  

交织(List1,List2,Result):结果按顺序放置List1和List2的所有元素。 List1和List2 的长度必须最多为1。