2016-12-30 93 views
1

下面是递归添加元素X到列表末尾的代码。Prolog递归追加列表

app(X, [], [X]). 
app(X, [Y | S], [Y | S2]) :- app(X, S, S2). 

任何人都可以解释我是如何工作的?退货声明在哪里,究竟是什么app(X, S, S2)[Y | S], [Y | S2]

回答

2

你不需要return语句都被统一(简单模式匹配)来完成。子句:

app(X, [Y | S], [Y | S2]) 

指出第二个参数是头部Y和尾部S的列表,第三个参数是头部Y和尾部S2的列表。所以它强制(通过使用统一)两个列表的头部是一样的。递归地,除了第三个参数列表在结尾处有一个元素(元素X)并且由第一个子句定义的事实之外,这两个列表变得完全相同。请注意,第二个子句仅适用于具有一个或多个元素的列表。所以,当我们检查空列表(第二个参数)递归然后榜第三的是由于第一条基本只包含一个多元素的元素X.

2

Prolog的程序被定义的事实和规则作出。您可以定义事实和规则,Prolog解释器会尝试提出解决方案以使其成为现实。除了这个基本概念,您还需要了解Prolog程序员广泛使用的另外两个重要概念。 这些是:

  1. 输入和输出参数:在Prolog中没有返回语句。一些变量将会是结果(输出),而另一些则是输入。在你的程序中,第一个和第二个参数是输入的,最后一个是输出。
  2. 模式匹配:如果列表表示为[Head|Tail]。 Head是第一个元素,Tail是剩余元素的列表。

当你调用app,例如,作为app(5, [1, 2, 3, 4], L).,Prolog的解释试图拿出值L这样app是真实的。

Prolog的解释是解决问题的步骤如下:

  1. 为了使app(X, [Y | S], [Y | S2])真正的,最后一个参数的第一个元素需要变得Y。所以,在我的例子中,L变成[1,S2]。
  2. 然后它会尝试匹配规则app(X, S, S2)。这里S是[2,3,4],S2是下一次运行的输出参数。然后第1步重复,但app(5, [2, 3, 4], S2)S2后变成[2,S2]。因此,L现在变成[1,2,S2]。
  3. 同样的事情会重复(递归),并且L被填充为[1,2,3,4,S2]。
  4. 现在,第二个参数是空的。所以,第一个事实app(X, [], [X])是匹配的。为了做到这一点,最后一个参数变成一个只包含X(在这种情况下为5)的列表,其结果是L为[1,2,3,4,5]。