3

我的例子是使用 append 仿函数:

append([],L,L). 
append([H|T],L2,[H|L3])  :-  append(T,L2,L3).

//append([123],[abc],L3). this is the query

真正让我困惑的是 [H|L3] 列表。形成我读到的内容,这会引起人们的注意,那么如何将其附加到列表中。当它在列表中递归并开始返回时,它是如何附加的?提前致谢。

4

3 回答 3

5

该符号[H|T]是 . 的语法糖'.'(H, T)。所以它是一个有名字的函子.——一个点和两个参数。考虑:

?- [1,2,3] = [X|L]。
X = 1,
L = [2, 3]。

在这里我们问,是否有方程的解[1,2,3] = [X|L]。而且,是的,这两个答案替换描述了一个解决方案。求解这个方程的过程称为统一。这个过程包含了数据结构的读取、选择和写入。所以,你可以称之为“脱头”,但你会错过背后的普遍性。毕竟:

?- X = 1,L = [2, 3],M = [X|L]。
X = 1,
L = [2, 3],
M = [1, 2, 3]。

在这里,我们从一个较小的列表中构建了一个新列表。但什么是:

?- M = [X|L]。
M = [X|L]。

这个答案暗示了许多解决方案。例如,所有长度为 1 和更长的列表。

由于您正在查看append/3,请考虑以下查询:

?-附加(Xs,Ys,[X,Y,Z])。
?-附加(Xs,Xs,Zs)。
?-附加(Xs,Ys,Zs)

更多关于列表语法

于 2012-04-25T06:59:49.523 回答
3

trace/0当您想知道执行的样子时,您可以在这些情况下使用。

这是它的概述。

  • 你打电话append([1, 2, 3], [a, b, c], L3).
  • [1, 2, 3]不为空,则应用第二个子句
  • 它呼唤append([2, 3], [a, b, c], L4).并记住它的头L3就像它的头,[1, 2, 3]它的尾巴L3L4
  • [2, 3]不为空,则应用第二个子句
  • 它呼唤append([3], [a, b, c], L5).并记住它的头L4就像它的头,[2, 3]它的尾巴L4L5
  • [3]不为空,则应用第二个子句
  • 它呼唤append([], [a, b, c], L6).并记住它的头L5就像它的头,[3]它的尾巴L5L6
  • []与 结合[],应用第一个子句
  • 它说L6[a, b, c]

现在Prolog有所有的信息来回答你:

L6 = [a, b, c],
L5 = [3|L6],
L4 = [2|L5],
L3 = [1|L4].

将允许 Prolog 得出结论L3 = [1, 2, 3, a, b, c]

希望它有所帮助。

于 2012-04-25T06:55:36.490 回答
1

在 Prolog 中,你永远不会做任何像“起飞”那样活跃的事情。将其视为“专注于”可能会更好。(Prolog 本质上是声明性的;您不说要做什么,而是说某物的样子。)例如,列表可能是空的 ( []) 或非空的 ( [H|T]);每个非空列表都有一个 headH和一个 tail T,并且|只是让您引用它们。根据需要,统一可以使用列表的声明[H|T]来拆分列表或将列表放在一起。

于 2012-04-25T05:48:28.223 回答