查询数据库时的成功与失败
Success and failure when querying the database
所以我一直在做一个练习。我有以下事实:
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",然后当查询的顺序相反时为 "false",例如 seed(apple1, appleseed0).
现在,我的谓词如下所示:
seed(A,B) :- sd(A,B) ; sd(B,A).
我知道这就是我的查询返回 true 的原因,无论顺序如何,但我唯一的其他想法是:
seed(A,B) :- sd(A,B).
但我不能那样写,因为那样会使它成为一个没有错误的无限循环。我怎样才能使查询在显示 seed(appleseed2, apple2)
和 "false" 时显示 "true" 时显示 seed(apple2, appleseed2)
?
希望我没看错你的问题:
您不需要额外的谓词。事实上,您正在寻找的是查询:
?- 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)
为真时。”
所以我一直在做一个练习。我有以下事实:
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",然后当查询的顺序相反时为 "false",例如 seed(apple1, appleseed0).
现在,我的谓词如下所示:
seed(A,B) :- sd(A,B) ; sd(B,A).
我知道这就是我的查询返回 true 的原因,无论顺序如何,但我唯一的其他想法是:
seed(A,B) :- sd(A,B).
但我不能那样写,因为那样会使它成为一个没有错误的无限循环。我怎样才能使查询在显示 seed(appleseed2, apple2)
和 "false" 时显示 "true" 时显示 seed(apple2, appleseed2)
?
希望我没看错你的问题:
您不需要额外的谓词。事实上,您正在寻找的是查询:
?- 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)
为真时。”