Prolog 箭头运算符
Posted
技术标签:
【中文标题】Prolog 箭头运算符【英文标题】:Prolog arrow operator 【发布时间】:2014-01-30 14:19:33 【问题描述】:| ?- true ; (true->false)
yes
| ?- (true->false) ; true.
no
| ?- false ; true.
yes
据我了解,“是”/“否”结果告诉用户查询是否成功。查询在谓词 true
上总是成功,而在 false
上总是失败。
因为;/2
表示OR(可交换),所以前两个查询应该是等价的(都成功)
在谓词逻辑中,公式 (true->false)
和 false
的计算结果为 FALSE,因此最后两个查询应该是等价的
因此:第二个查询似乎与理论逻辑不一致
我的推理有误吗?我觉得我没有理解一些基本的东西。
【问题讨论】:
【参考方案1】:这是一个很好的问题。
为了详细说明@larsmans 的答案,->/2
谓词在与;/2
谓词结合时充当if-then-else
。就其本身而言,它只是if-then
。
查看if-then-else
构造,GNU Prolog manual says中给出的描述:
->/2
通常与;/2
组合以定义if-then-els
e,如下所示:Goal1 -> Goal2 ; Goal3.
注意Goal1 -> Goal2
是第一个参数 (;)/2 和 Goal3(else 部分)的 是第二个参数。这样一个if-then-else
控件构造首先为 else-part(直觉上与;/2
相关联)然后执行Goal1
。 如果 [Goal1
] 成功,Goal1
创建的所有选择点连同 删除 else 部分的选择点 并执行 Goal2。 如果 Goal1 失败,则执行 Goal3。
在这种情况下,我们有:
(true -> false) ; true
第一个true
是Goal1
,成功了。一旦发生这种情况,根据谓词行为的描述,将引导您进入第二个 true
语句 (Goal3
) 的选择点将被删除。所以当遇到false
时,会发生失败,不回溯到第二个true
,整个查询都会失败。
但是,如果你做了这样的事情:
foo :-
true -> false.
foo :-
true
在第一个foo
子句失败后有一个选择点,所以你得到:
| ?- foo.
yes.
我认为混淆源于将
false ; true
与(true -> false) ; true
进行比较。更类似于(true -> false) ; true
的表达式是:
(true, !, false) ; true
由于;
的工作方式,它也将评估为false
。 ;
在第一个子句失败的情况下提供了一个选择点。但是如果第一个子句有删减,去掉了选择点,就不会被取走,查询整体失败。
【讨论】:
表达式不能看成;(->(true, false), true)
吗?在这种情况下,如何“删除 else 部分的选择点 [...]”是可能的,因为 '->/2' 是 ';/2' 的参数,所以它不应该能够改变它的定义?
@octavian,其实拿;((true,!,false),false)
的类似例子来说是一致的。该查询将返回false
,因为即使第一个表达式是false
,选择点已被删减。我在回答中添加了进一步的解释。
确实是一个罕见的 - 好的和有趣的 - 问题。 :) 我只是补充一点,省略错误的替代方案((true -> false; false) ; true.
)是很自然的,这个 Q 表明在 Prolog 中我们应该非常小心。
@octavian 我的回答满意吗?【参考方案2】:
Prolog 中的箭头与一阶逻辑中的实质含义不对应。它是一个三元“if-then-else”运算符,带有可选选项。由于它是在 Prolog 语法中实现的,
(true -> false) ; true
并不意味着你认为它会做什么。解析为true -> false ; true
:
?- ((true -> false) ; true) =.. Expr.
Expr = [;, (true->false), true].
?- (true -> false ; true) =.. Expr.
Expr = [;, (true->false), true].
所以它失败了,因为它的意思是“如果true
然后false
否则true
”,即false
。
【讨论】:
你的意思是说“如果true
然后false
否则true
”?
@octavian:嗯,是的。解决了这个问题。以上是关于Prolog 箭头运算符的主要内容,如果未能解决你的问题,请参考以下文章