下面的prolog代码是做什么的?

下面的prolog代码是做什么的?,prolog,Prolog,我无法理解下面的代码。 如果我有以下输入,有人能一步一步地解释发生了什么吗 append([1,2,3], Lst). 事实上,我不知道;t获取如何将1和2作为结果附加到列表Lst append([_], []). append([H|T], [H|N]) :- append(T,N). 听起来你对序言还不熟悉。如果是,欢迎!让我们分析一下 此命名函数有两个子句。Prolog查看这些子句,以确定哪一个适用。当它找到一个匹配的,它会尝试执行它。如果执行过程中出现故障,它将备份并尝试下一

我无法理解下面的代码。
如果我有以下输入,有人能一步一步地解释发生了什么吗

append([1,2,3], Lst).
事实上,我不知道;t获取如何将1和2作为结果附加到列表Lst

append([_], []).    
append([H|T], [H|N]) :- append(T,N).

听起来你对序言还不熟悉。如果是,欢迎!让我们分析一下

此命名函数有两个子句。Prolog查看这些子句,以确定哪一个适用。当它找到一个匹配的,它会尝试执行它。如果执行过程中出现故障,它将备份并尝试下一个选项。具体而言,这些选择点因项目而异;在这个程序中,只有一个在子句级别,决定使用哪个规则

查看第一条规则的一种方式是,它说“一个包含一个元素的列表,无论该元素是什么,都与空列表相关。”查看
append([\u],])
,如果我们有
X=[foo]
Y=[]
,它将保持不变,因为
[foo]
是一项列表,而
[]
是空列表。这个规则是很好的Prolog风格,因为不管实例化如何,它都能工作:我们可以提供左边或右边,也可以两者都不提供,这无关紧要

第二条也很简单。它说如果左参数和右参数都以相同的项开始,并且如果列表的其余部分也由相同的谓词关联,则左参数和右参数是相关的。换句话说,如果我有两个列表
X
Y
,使得
append(X,Y)
是真的,那么
append([H | X],[H | Y])
也是真的。H是什么并不重要,X和Y是什么也不重要,除非
append/2
暗示了这一点

从逻辑上考虑,如果我知道任何一个项目列表都与空列表相关,并且任何列表都与以相同项目开头的列表相关,否则是相同的,那么唯一可以如此相关的列表类型是每个项目都相同的列表,除了左边列表的末尾还有一个项目,而右边没有。因此[1,2,3,4]与[1,2,3]相关,但[1,2,3,foo]和[1,2,3]也是如此

从程序上讲,让我们看看使用这组参数处理该谓词时会发生什么:

append([1,2,3], X).
第一条规则在[1,2,3]上不匹配。因此,我们必须看看第二条规则:

append([1|[2,3]], [1|X]) :- append([2,3], X).
我们可以重复:

append([2|[3]], [2|Y]) :- append([3], Y).
现在,第一条规则不匹配:

因此,把所有这些放在一起:

append([1,2,3], [1|X]) implies
  append([2,3], X=[2|Y]) implies
    append([3], Y=[])
  so Y = []
so X = [2]
so the right side is [1,2].
Prolog跟踪将向您显示基本相同的信息:

?- trace, append([1,2,3], X).
   Call: (7) append([1, 2, 3], _G1633) ? creep
   Call: (8) append([2, 3], _G1752) ? creep
   Call: (9) append([3], _G1755) ? creep
   Exit: (9) append([3], []) ? creep
   Exit: (8) append([2, 3], [2]) ? creep
   Exit: (7) append([1, 2, 3], [1, 2]) ? creep
这段Prolog代码让人困惑的是,它看起来并没有告诉Prolog如何做任何事情。这是真的,你没有,但是通过在逻辑上指定什么是真的,Prolog能够自己找到答案。这是非常聪明的代码。如果这是Haskell,我们将讨论内置函数
init
,它返回除最后一项之外的所有列表

希望这有帮助

?- trace, append([1,2,3], X).
   Call: (7) append([1, 2, 3], _G1633) ? creep
   Call: (8) append([2, 3], _G1752) ? creep
   Call: (9) append([3], _G1755) ? creep
   Exit: (9) append([3], []) ? creep
   Exit: (8) append([2, 3], [2]) ? creep
   Exit: (7) append([1, 2, 3], [1, 2]) ? creep