这两个陈述有什么区别:a)p(1),!; b)p(1): - !;

时间:2015-03-13 06:56:39

标签: prolog

这两个陈述之间有什么区别:

a)p(1),!

b)p(1):-!

我遇到了这段代码:

p(1).
p(2):-!.
p(3).

如果我将其重写为:

,该怎么办?
p(1).
p(2),!.
p(3).

1 个答案:

答案 0 :(得分:0)

我相信您正在查看一个非常简单的示例,该示例似乎表明p(2) :- !p(2), !之间存在行为的相似性或等同性。看起来他们都在查询p(2),如果成功匹配,则继续进行切换并截断进一步的回溯。但事实并非如此。

表达式p(2) :- !.是一个谓词子句,它定义了一条规则,其中 p(2)为真,并且不需要检查其他解决方案。当您查询表格p(X)时,Prolog将尝试查找与其匹配的事实或规则头。在这种情况下,p(2)是匹配,Prolog遵循规则。举个例子,如果你有:

p(2).
p(2).

并查询:

| ?- p(X).

你得到:

| ?- p(X).

X = 2 ? ;

X = 2

(1 ms) yes
| ?-

然而,如果你有这些事实

p(2) :- !.
p(2).

然后你得到:

| ?- p(X).

X = 2

yes
| ?-

另一方面,表达式p(2), !.在语法上不能出现在"顶层"在Prolog。换句话说,这不是合法的Prolog:

p(2), !.
p(2).

如果您尝试这样做,则会收到如下错误:

error: user:1: native code procedure (',')/2 cannot be redefined (ignored)

Prolog认为您正在尝试重新定义,运营商。那是因为表达式p(2), !.看起来像:

','(p(2), !).   % Create a definition for ','

确实,p(2) :- !在Prolog中被称为术语':-'(p(2), !)p(2)是该条款的 head ),它专门对待它在顶层。但是,p(2), !在语法上需要成为子句的一部分而不是顶级。在这种情况下,术语p(2)不是Prolog试图匹配的条款的头部。相反,它是一个查询,它是另一个Predicate子句的一部分。例如:

% Define 'foo'
foo :- p(2), !.
foo.

如果我们查询:

| ?- foo.

yes
| ?-

你看到它成功了,并且由于削减,在成功后没有留下任何选择点。另一方面,如果我们定义:

foo :- p(2).
foo.

然后查询的行为有所不同:

| ?- foo.

true ? ;

yes

在这里,foo成功,并且由于缺少剪切和额外的foo子句/事实,留下了一个选择点。我们告诉Prolog寻求更多解决方案(;),我们再收到一个,结果是yes

我说了所有这些,表明这些是两个不同运营商的非常不同的背景:,:-