【问题标题】:Success and failure when querying the database查询数据库的成功与失败
【发布时间】:2015-01-28 06:36:22
【问题描述】:

所以我一直在做一个我一直在做的练习。我有以下事实:

sd(appleseed0, appleseed1).

sd(appleseed0, apple1).
sd(appleseed1, apple1).
sd(appleseed2, apple1).

sd(appleseed0, apple2).
sd(appleseed1, apple2).
sd(appleseed2, apple2).

这意味着 appleseed1 来自 appleseed0,apple1 来自 appleseed0,等等。我遇到的问题是,如果值被切换,我需要它打印出 false。意思是,当查询为seed(appleseed0, apple1) 时,我希望查询结果为“true”,然后当查询与seed(apple1, appleseed0). 的顺序相反时,我希望查询结果为“false”

现在,我的谓词如下所示:

seed(A,B) :- sd(A,B) ; sd(B,A).

我知道这就是为什么我的查询无论顺序如何都返回 true,但我唯一的另一个想法是:

seed(A,B) :- sd(A,B). 

但我不能这样写,因为这会使其成为一个没有错误的无限循环。我怎样才能做到这一点,以使查询在以seed(appleseed2, apple2) 之类的形式显示时为“true”,而在以seed(apple2, appleseed2) 之类的形式显示时为“false”?

【问题讨论】:

  • 如果“apple1 来自 appleseed0”,为什么 apple1 也来自 appleseed1?目前还不清楚 sd/2 是什么意思。

标签: prolog prolog-toplevel


【解决方案1】:

希望我能正确阅读您的问题:

您不需要额外的谓词。事实上,您正在寻找的是查询:

?- sd(A, B).

正如您所描述的那样,这将成功或失败。谓词

seed(A, B) :-
    (   sd(A, B)
    ;   sd(B, A)
    ).

(就像你的一样,只是为了更容易理解而格式化)读取:“seed(A, B) 为真,sd(A, B) 为真。当sd(B, A) 为真时,它也为真”(就像你已经注意到的那样)。一个有趣的副作用是,如果您的数据库中有这两个事实:

sd(foo, bar).
sd(bar, foo).

然后查询:

?- seed(foo, bar).

会成功两次(!),就像查询一样

?- seed(bar, foo).

或等效的顶级查询

?- sd(bar, foo) ; sd(foo, bar).

最后一个查询清楚地说明了为什么查询会成功两次。

什么让我困惑:你为什么这么认为

seed(A, B) :-
    sd(A, B).

会导致无限循环吗?有没有你没有展示的程序的某些部分?就目前而言,定义这样的谓词等同于给sd/2 一个别名seed/2。此定义为:“sd(A, B) 为真时,seed(A, B) 为真。”

【讨论】:

  • 啊,这很有道理。我对(1)种子(A,B):-种子(A,B)感到困惑,我没有考虑(2)种子(A,B):-sd(A,B)。我假设由于(1)会产生一个“无限循环”,其中没有什么是错误的,那么(2)会做同样的事情,因为它似乎在做和(1)一样的事情。从逻辑上讲,(2)是有道理的。你的解释消除了我的困惑。谢谢!我是 Prolog 的新手,所以这对我的学习很有价值!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
相关资源
最近更新 更多