提问人:Xiaoyong Guo 提问时间:2/17/2022 最后编辑:falseXiaoyong Guo 更新时间:2/19/2022 访问量:71
如何定义Prolog规则实现双向查询?
How can I define Prolog rule to achieve bidirectional query?
问:
我已经定义了
double(X,Y) :- Y is X*2.
当我查询时,我得到.double(3,Y)
Y=6
但是当我查询时,我无法得到.double(X,6),
X=3
是否可以定义一个双向有效的规则?
答:
1赞
Will Ness
2/17/2022
#1
是的,您需要检查哪些变量尚未设置,并采取相应的措施。没有错误检查的骨架代码:
double(X,Y) :- % Y = 2*X
( var(X) ->
( var(Y) -> freeze(X, double(X,Y)),
freeze(Y, double(X,Y))
; X is Y/2
)
; Y is 2*X
).
这给了我们,在SWI Prolog中,
33 ?- double(3,6).
true.
34 ?- double(3,Y).
Y = 6.
35 ?- double(X,6).
X = 3.
36 ?- double(X,Y).
freeze(X, double(X, Y)),
freeze(Y, double(X, Y)).
37 ?- double(X,Y),Y=6.
X = 3,
Y = 6.
38 ?- double(X,Y),X=3.
X = 3,
Y = 6.
39 ?- double(X,Y),X=3,Y=41.
false.
或者,您可以执行以下操作
41 ?- use_module( library(clpfd)).
true.
42 ?- [user].
double(X,Y):- Y #= X * 2.
以实现相同的目的。
0赞
Nicholas Carey
2/19/2022
#2
我可能会做这样的事情:
double(X,Y) :- nonvar(X), Y is X * 2 .
double(X,Y) :- nonvar(Y), X is Y / 2 .
尽管这确实使您在两个参数都实例化时获得了 2 个解决方案的可能性(将成功两次)。double(3,1.5).
您可以通过多种方式解决此问题:
使用切口来消除无关的选择点。
double(X,Y) :- nonvar(X), Y is X * 2 , ! . double(X,Y) :- nonvar(Y), X is Y / 2 .
添加其他类型检查。
double(X,Y) :- nonvar(X), var(Y), Y is X * 2 . double(X,Y) :- nonvar(Y), X is Y / 2 .
或更多:
double(X,Y) :- nonvar(X), nonvar(Y), X =:= Y . double(X,Y) :- nonvar(X), var(Y), Y is X * 2 . double(X,Y) :- var(X), nonvar(Y), X is Y / 2 .
如果你走这条路,如果你愿意,可以添加第四个情况,这将产生一个无限的数字序列和它们的双精度:
double(X,Y) :- nonvar(X), nonvar(Y), X =:= Y . double(X,Y) :- nonvar(X), var(Y), Y is X * 2 . double(X,Y) :- var(X), nonvar(Y), X is Y / 2 . double(X,Y) :- var(X), var(Y), between(0,infinity), Y is X * 2.
评论