关于 Prolog 的一个常见误解是它没有函数:它只有谓词。谓词没有输入或输出,它统一了调用它的变量。因此,谓词可以是多向的。
关于 prolog 的另一个误解是,如果你调用:
append(foo(X), goo(Y)).
Prolog 会将foo(x) 和goo(Y) 视为谓词调用。它不是:在这种情况下foo(X) 和goo(Y) 是术语。带有函子(不是谓词)的术语和术语。所以这里foo(X) 是函子foo/1 的术语,术语X 作为第一个(也是唯一的)参数。
但是,您可以调用谓词,方法是将它们写在另一个谓词的正文中。
例如你可能想要的:
hi(X) :-
foo(A),
goo(B),
append(A, B, X).
那么这是如何工作的呢?如果我们调用hi(X),那么 Prolog 将在源代码中查找是否存在由该名称定义的谓词。如果有,它将旨在从上到下执行谓词的子句。这里只有一个子句hi/1,就是我们刚刚写的那个。所以现在 Prolog 将开始执行该子句的 body。
我们现在看到正文中的第一项是foo(A)(注意A,而不是X)。所以现在 Prolog 将再次为 foo/1 谓词寻找一个子句。你的问题中有一个。 foo([a,b,c])。这意味着 Prolog 现在将执行 unification。它将统一我们的变量A 与事实。所以在调用foo/1 谓词之后,现在是A = [a,b,c]。我们对goo(B) 做同样的事情:调用它之后,B = [d,e,f]。
最后我们打电话给append(A, B, X).。现在append/3 是一个内置谓词,它将两个第一个参数中的列表附加到第三个参数(但它可以多向使用)。调用后,X 将统一为[a,b,c,d,e,f]。由于谓词调用结束,Prolog 会报告X = [a,b,c,d,e,f]。
我们现在完成了吗?不! Prolog 的另一个重要方面是它在语法上免费回溯。这意味着对于我们完成的每个谓词调用(foo(A)、goo(B) 和 append(C)),仍然可能存在我们感兴趣的子句。所以从概念上讲,Prolog 解释器会寻找更多的答案。但在这里我们很幸运foo/1 和goo/1 只有一个定义。请注意,大多数 Prolog 解释器不必在这里进行回溯,因为他们会做一些记录,以便提前知道我们是否应该尝试回溯。