这两个语句有什么区别:a) p(1),!; b) p(1):-!;
What is the difference between this two statements: a) p(1),!; b) p(1):-!;
这两个语句有什么区别:
a) p(1),!
b) p(1):-!
我遇到了这段代码:
p(1).
p(2):-!.
p(3).
如果我将其重写为:
p(1).
p(2),!.
p(3).
我相信您看到的是一个非常简单的例子,它使 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 中的 "top level" 处。换句话说,这不是合法的序言:
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
| ?-
你看成功了,因为cut,成功了一次就没有选择点了。另一方面,如果我们定义:
foo :- p(2).
foo.
然后查询行为不同:
| ?- foo.
true ? ;
yes
此处,foo
成功,并且由于缺少剪切和额外的 foo
clause/fact,留下了一个选择点。我们告诉 Prolog 寻找更多的解决方案 (;
),我们又得到一个,结果是 yes
.
我说了这么多是为了表明对于两个不同的运算符来说,这些是非常不同的上下文:,
和 :-
。
这两个语句有什么区别:
a) p(1),!
b) p(1):-!
我遇到了这段代码:
p(1).
p(2):-!.
p(3).
如果我将其重写为:
p(1).
p(2),!.
p(3).
我相信您看到的是一个非常简单的例子,它使 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 中的 "top level" 处。换句话说,这不是合法的序言:
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
| ?-
你看成功了,因为cut,成功了一次就没有选择点了。另一方面,如果我们定义:
foo :- p(2).
foo.
然后查询行为不同:
| ?- foo.
true ? ;
yes
此处,foo
成功,并且由于缺少剪切和额外的 foo
clause/fact,留下了一个选择点。我们告诉 Prolog 寻找更多的解决方案 (;
),我们又得到一个,结果是 yes
.
我说了这么多是为了表明对于两个不同的运算符来说,这些是非常不同的上下文:,
和 :-
。