SWI-Prolog谓词

时间:2017-05-09 15:44:32

标签: prolog

我对prolog很新,我的教授似乎忘记了教授课程的基本用法。他给了我们编写谓词stmt和stmts的任务,第一个谓词看起来像:

stmt([pass|X], X).
stmt([declare,N|X], X) :- atom(N).
stmt([use,N|X], X) :- atom(N).

然后传递测试代码stmt([use,x,something,else],[something,else])。

第二部分如下所示:

  

定义一个stmts谓词,如果{stmts(List1, List2)}以匹配(stmts)非终结符的原子开始,然后继续(List1)中的原子,则List2是可证明的。例如,以下查询应该生成true:   stmts([pass,use,x,more,stuff],[more,stuff])

我不明白为什么要让它发挥作用。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

它起作用是因为Prolog中的统一过程以及Prolog中的列表是链接列表这一事实。

首先,理解列表是在CONS-way中实现(如果我没记错的话,该术语来自Lisp)可能是有用的。这意味着有一个仿函数(为简单起见,我们这里使用cons/2),这样列表[use,x,something,else]的结构类似于cons(use,cons(x,cons(something,cons(else,nil))))nil是列表的末尾)。所以以链表方式。

接下来,如果您“在Prolog中调用谓词”,则会发生统一。它旨在将调用中的参数与子句头部中的参数统一起来。例如,如果克劳斯的头部是foo(bar(X,qux(Y)))并且您使用foo(bar(3,Z))调用它,那么结果是X = 3Z = qux(Y) X和{{1}是“未实例化的变量”。

如果我们将这两者结合起来,我们会发现代码的 desugared 变体是:

Y

现在,如果我们致电stmt(cons(pass,X), X). stmt(cons(declare,cons(N,X)), X) :- atom(N). stmt(cons(use,cons(N,X)), X) :- atom(N). ,将会发生统一。 First Prolog旨在与第一个条款统一起来:

stmt(cons(use,cons(x,cons(something,cons(else,nil)))),cons(something,cons(else,nil))).

(我使用椭圆来保持简单)。

统一将旨在统一第一个论点,如:

stmt(cons(pass,X),         X)
stmt(cons(use, cons(x,...),cons(something,cons(else,nil)))

现在统一将剥离:删除第一个统一,并注入参数的统一,所以:

cons(pass,X) ~ cons(use,cons(else,...))
X ~ cons(something,cons(else,nil))

现在Prolog pass ~ use X ~ cons(else,...) X ~ cons(something,cons(else,nil)) pass常量(因为它们以小写字母开头)。此外,Prolog中的所有常量都是不同的(除非具有相同的“名称”,否则可以这么说)。因为use无法统一。第一个条款“失败”。

在Prolog中,回溯机制到位:在调用第一个子句后 - 无论是成功还是失败 - Prolog将使用第二个子句,第三个子句和第二个子句重试该调用。等等。

所以现在我们的目标是统一通话。所以现在我们执行统一,如:

pass ~ use

这导致统一如:

stmt(cons(declare,cons(N,X  )),X)
stmt(cons(use,    cons(x,...)),cons(something,cons(else,nil)))

我们再次剥离

cons(declare,cons(N,X)) ~ cons(use,cons(x,...))
X ~ cons(something,cons(else,nil))

再一次,这是一次失败。

我们最后的尝试是:

declare ~ use
cons(N,X) ~ cons(x,...)
X ~ cons(something,cons(else,nil))

产生:

stmt(cons(use,cons(N,X)) ,X).
stmt(cons(use,cons(x,...),cons(something,cons(else,nil)))

然后产生:

cons(use,cons(N,X)) ~ cons(use,cons(x,...))
X ~ cons(something,cons(else,nil))

导致:

use ~ use
cons(N,X) ~ cons(x,...)
X ~ cons(something,cons(else,nil))

use ~ use N ~ x X ~ ... X ~ cons(something,cons(else,nil)) ...)。所以现在统一已经成功,欢呼。但我们还没有。现在第三个子句的 head 已成功,这意味着我们现在必须对该子句的 body 执行调用。所以我们打电话:

cons(something,cons(else,nil))

atom(N). 起,就意味着我们致电N = x。现在x是内置的,并且成功(我们不会在这里再次进行统一过程)。这意味着第三个条款成功。