【问题标题】:How to properly express inequality in prolog?如何正确表达序言中的不等式?
【发布时间】:2015-10-31 04:44:34
【问题描述】:

TL;DR: sibling(a,X) 成功,答案为 X = a,但 sibling(a,a) 失败。


我有以下 Prolog 文件:

children(a, c).
children(a, d).
children(b, c).
children(b, d).

sibling(X, Y) :-
   X \== Y, A \== B,
   children(X, A), children(X, B),
   children(Y, A), children(Y, B).

对我来说似乎很清楚,如果他们的父母相同,两个人就是兄弟姐妹。此外,一个人不是他们自己的兄弟姐妹。

但是当我尝试在 GNU Prolog 上运行一些查询时,我得到了一些奇怪的结果:

| ?- sibling(a, b).

true ? a

true

true

yes

这是预期的行为。 ab 是兄弟姐妹。有三个结果,这有点奇怪,但我假设 Prolog 正在绑定 A = c, B = dA = d, B = c

| ?- sibling(a, a).

no

我认为这意味着 aa 不是兄弟姐妹。

| ?- sibling(a, X).

X = a ? a

X = b

X = a

X = b

X = a

X = b

X = a

X = b

(15 ms) yes

这就是我卡住的地方:它说X = a,这意味着sibling(a,a) 是真的,但是sibling(a,a) 在上一个查询中失败

我觉得我不明白 \== 在 Prolog 中的实际作用。

发生了什么,我该如何解决?

【问题讨论】:

标签: prolog prolog-dif


【解决方案1】:

TL;DR: 使用——或iso_dif/2(在 一致的系统上,如)!


好问题,+1!

事实上,这是我问过自己的一个问题,答案与有关:逻辑纯度是什么的核心方面 使 Prolog 作为一种语言如此特别,因为它使您能够:

  • 描述——不是规定
  • 编写关系型代码,而不仅仅是功能性代码
  • 从问题/解决方案的角度思考,而不是搜索过程本身的各个步骤
  • 在更高的层次上运作——不要迷失在细节中

与许多其他编程语言不同,Prolog 程序同时具有过程语义(定义执行步骤及其顺序)和声明性语义(允许您声明应该保持的关系并让 Prolog 处理器找到正确的执行方式本身)。

但是,请注意:Prolog 有一些特性,当使用时,破坏声明性语义。为防止这种情况发生,请尝试将您的应用程序分为两部分:不纯的外壳,用于处理副作用(输入/输出)逻辑纯基 包含纯单调 Prolog 代码。

【讨论】:

    【解决方案2】:

    尝试将不等式移到谓词的末尾。也许它给了你真实的因为它还没有被实例化。

    sibling(X,Y):- children(X, A), children(X, B),
                   children(Y, A), children(Y, B),
                   X \== Y, A \== B.
    

    【讨论】:

    • 我认为序言中的顺序无关紧要,但事实证明确实如此。谢谢!
    • @repeat 哦,大写字母,我没看到,抱歉哈哈
    • @parchment:如果您使用 impure 原语,排序通常很重要。我建议您查看@repeat 的出色答案。使用dif/2 表示纯粹的不等式,可用于所有方向。
    猜你喜欢
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    相关资源
    最近更新 更多