Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 列表合并代码澄清_Prolog - Fatal编程技术网

Prolog 列表合并代码澄清

Prolog 列表合并代码澄清,prolog,Prolog,在下面的代码中,我不确定前三行是做什么的?我知道第四行递归地去掉了列表1和列表2的开头,但是为什么需要上面的规则呢 interweave([],[],[]). interweave([X],[],[X]). interweave([],[Y],[Y]). interweave([X|List1],[Y|List2],[X,Y|Result]) :- interweave(List1,List2,Result). 在Prolog中,您可以回答这些问题,而无需查看实际代码!只需提出最一般的问

在下面的代码中,我不确定前三行是做什么的?我知道第四行递归地去掉了列表1和列表2的开头,但是为什么需要上面的规则呢

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

在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] ? 

因此,这些情况都包括在内:如果两个列表都是空的,或者如果其中恰好有一个包含恰好一个元素。

在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] ? 

因此,这些情况都包括在内:如果两个列表都是空的,或者如果其中恰好有一个包含恰好一个元素。

当您编写递归过程时,您通常指定所谓的“基本情况”,即当不再需要或可能再次调用该过程时,应该做什么

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

interweaveList1、List2、Result:Result按顺序放置List1和List2的所有元素。列表1和列表2的长度不得超过1


在编写递归过程的代码时,通常指定所谓的“基本情况”,即当不再需要或不可能再次调用该过程时应该做什么

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

interweaveList1、List2、Result:Result按顺序放置List1和List2的所有元素。列表1和列表2的长度不得超过1


正如其他人所指出的,当您有一个递归谓词子句时,例如:

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交织[]、[]、[]。当两个原始输入列表长度相同时启用成功

2交织[X],[X],[X]。当第一个列表比第二个列表多出一个元素时,启用成功

3交织[],[Y],[Y]。当第二个列表比第一个列表多出一个元素时,启用成功

@卡佩里克在他的回答中指出了影响。因此,在您展示的当前实现中,在三种基本情况下,以下几点将会成功:

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([], L, L).
interweave(L, [], L) :- L = [_|_].  % Only true for non-empty list L

正如其他人所指出的,当您有一个递归谓词子句时,例如:

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交织[]、[]、[]。当两个原始输入列表长度相同时启用成功

2交织[X],[X],[X]。当第一个列表比第二个列表多出一个元素时,启用成功

3交织[],[Y],[Y]。当第二个列表比第一个列表多出一个元素时,启用成功

@卡佩里克在他的回答中指出了影响。因此,在您展示的当前实现中,在三种基本情况下,以下几点将会成功:

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([], L, L).
interweave(L, [], L) :- L = [_|_].  % Only true for non-empty list L
... 你甚至可以剪下额外的尾巴,用交织[X | |,],[X]。交织[],[X | |,[X]…-一个完整而彻底的答案,零次投票!。。。你甚至可以剪下额外的尾巴,用交织[X | |,],[X]。交织[],[X | |,[X]…-一个完整而彻底的答案,零次投票!