2

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

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),然后在查询顺序相反时产生“假”,例如seed(apple1, appleseed0).

现在,我的谓词看起来像这样:

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

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

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

但我不能那样写它,因为这会使它成为一个没有错误的无限循环。我怎样才能做到这一点,以使查询在显示为“真”时显示为“真”,而在显示为seed(appleseed2, apple2)“假”时显示为“假” seed(apple2, appleseed2)

4

1 回答 1

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. 该定义为:“当为seed(A, B)真时sd(A, B)为真。”

于 2015-01-28T07:30:04.470 回答