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-else,如下所示:Goal1 -> Goal2 ; Goal3. 注意Goal1 -> Goal2第一个参数 (;)/2 和 Goal3(else 部分)的 是第二个参数。这样一个 if-then-else 控件构造首先为 else-part(直觉上与;/2相关联)然后执行Goal1如果 [Goal1] 成功,Goal1 创建的所有选择点连同 删除 else 部分的选择点 并执行 Goal2。 如果 Goal1 失败,则执行 Goal3。

在这种情况下,我们有:

(true -> false) ; true

第一个trueGoal1,成功了。一旦发生这种情况,根据谓词行为的描述,将引导您进入第二个 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 箭头运算符的主要内容,如果未能解决你的问题,请参考以下文章

自定义 Prolog 算术函数

我的简单prolog代码抛出语法错误:运算符预期

; (或)Prolog中的运算符不会返回true,除非左侧为true,即使运算符的右侧本身返回true也是如此

@ <Prolog中的符号

Prolog解析证明器删除括号

MiniKanren 有“非”运算符吗?