我对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])
。
我不明白为什么要让它发挥作用。任何帮助将不胜感激。
答案 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 = 3
和Z = 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
是内置的,并且成功(我们不会在这里再次进行统一过程)。这意味着第三个条款成功。