Prolog if-then-else结构: - > vs* - > vs. if_/3

Nam*_*nge 5 if-statement prolog control-structure implication logical-purity

正如另一个我似乎无法找到的StackOverflow答案所述,这种模式在实际的Prolog代码中经常出现:

pred(X) :-
    guard(X),
    ...
pred(X) :-
    \+ guard(X),
    ...
Run Code Online (Sandbox Code Playgroud)

许多人试图将其浓缩

pred(X) :-
    (guard(X) ->
    ...
    ;
    ...).
Run Code Online (Sandbox Code Playgroud)

但是众所周知,箭头结构会破坏选择点并且不符合逻辑.

在Ulrich Neumerkel和Stefan Kral的Indexing dif/2中,if_/3提出了一个单调且合乎逻辑的谓词,然而在论文中他们提到了另一个引起我注意的结构:*->.

*->构造的功能与上面的unsugared guard子句完全相同,因此它似乎非常适合我的用途,因为我不希望有一个必需的具体条件,if_/3而且我不太关心额外的选择点.如果我没有弄错(编辑:我),它提供了相同的语义,if_/3但没有要求在条件谓词中添加"具体化".

然而,在它的SWI文档中,它声称"这种构造很少使用",这对我来说似乎很奇怪.*->在我看来,它比->你在尝试进行纯逻辑编程时更好.有没有理由避免这种结构,或者是否有更好的替代整个保护条款/否定保护条款模式?

mat*_*mat 5

我们来尝试一下吧!您给出的模式是:

预测(X):-
    (守卫(X)->
         ...
    ; ...
    )。

我现在使用(*->)/2并填写“...”,如下所示:

预测(X):-
        ( 守卫(X) *->
            
        ;   
        )。

此外,作为guard/1,我定义了明显的谓词:

警卫(一)。

现在,让我们问pred/1一个最常见的问题有没有解决方案?

?- pred(X)。
错误的。

因此,根据谓词,不存在X这样的术语pred(X)true

但这是错误的,因为实际上有这样一个术语:

?- 预测(b)。
真的。

事实上,pred/1无穷多个解。在这种情况下,谓词表明根本不存在可以接受吗?当然,因为答案的计算效率非常高,不是吗?

我们得出的结论是,它(*->)/2有一个重要的缺点(->)/2:如果仅进一步实例化条件中出现的变量,则在适用不同分支的情况下,它可能会错误地提交到其中一个分支。以这种方式依赖于其参数实例化的谓词永远不可能是纯的,因为它抵消了我们期望适用于纯逻辑程序的单调推理。特别是,从逻辑角度来看,既然成立,我们期望,它是的概括一定不会失败。一旦这个属性被打破,你就不能再应用声明式调试和其他让你更容易理解、推理和管理 Prolog 程序的重要方法,而这首先构成了声明式编程的主要吸引力。pred(b)pred(X)pred(b)

你提到的问题大概是什么用途if_3/

  • 请注意,使 `(\+)/1` 以与 `dif/2` 相同的方式工作相当于*构造性否定*。您可以在*7 一般具体化*中找到对此的讨论。至少从给出的例子来看,与“if_/3”的“整个运行”相比,一般具体化的成本要高得多。 (3认同)
  • @NameMcChange:根据 `guard/1` 的非常精确的含义,您可能需要 `when(ground(X), \+ Guard(X))` 或介于两者之间的东西。这正是建设性否定如此昂贵的原因。您或多或少需要一个元解释器来监视“guard/1”的行为。 (2认同)