这两个陈述之间有什么区别:
a)p(1),!
b)p(1):-!
我遇到了这段代码:
p(1).
p(2):-!.
p(3).
如果我将其重写为:
,该怎么办?p(1).
p(2),!.
p(3).
答案 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
。
我说了所有这些,表明这些是两个不同运营商的非常不同的背景:,
和:-
。