【发布时间】:2021-03-04 22:44:22
【问题描述】:
我有以下 Prolog 规则:
p(X,Y):- q(Y,X), r(Y), s(Y), t(X).
已知r(Y)和s(Y)只有一种解,而q(X,Y)和p(X,Y)有几种解。
任务是使用辅助谓词优化规则。
我的猜测是在 s(Y) 和 t(X) 之间放置一个 Cut 以防止无用的回溯。
可以写什么样的辅助谓词来优化这条规则?
【问题讨论】:
标签: prolog
我有以下 Prolog 规则:
p(X,Y):- q(Y,X), r(Y), s(Y), t(X).
已知r(Y)和s(Y)只有一种解,而q(X,Y)和p(X,Y)有几种解。
任务是使用辅助谓词优化规则。
我的猜测是在 s(Y) 和 t(X) 之间放置一个 Cut 以防止无用的回溯。
可以写什么样的辅助谓词来优化这条规则?
【问题讨论】:
标签: prolog
小心剪裁。例如,如果 - 在您的第一次尝试中 - 您选择了正确的 Y,但错误的 X(对于 t(X))在谓词正文中使用剪切将提供错误的答案。
例子:
r(1).
s(1).
t(X):- member(X,[7,8,9,6]).
q(Y,X):- member(X,[1,2,3,6]), member(Y,[3,4,5,6,1]).
p(X,Y):- q(Y,X), r(Y), s(Y), t(X).
?- p(X,Y).
X = 6,
Y = 1.
但是有
p(X,Y):- q(Y,X), r(Y), s(Y), !, t(X).
?- p(X,Y).
false.
如果您在 aux 谓词中使用剪切,剪切不会丢弃“正确”答案,因为即使 aux/2 被传递一次,在预测 p/2 中仍然允许回溯:
aux(Y) :- r(Y), s(Y), !.
p(X,Y):- q(Y,X), aux(Y), t(X).
?- p(X,Y).
X = 6,
Y = 1.
我刚刚看到使用 aux 谓词没有任何改进。但是使用
aux(Y) :- r(Y), !, s(Y).
或
aux(Y) :- !, r(Y), s(Y).
如果s/1 计算成本高,可能会提高速度。只有在之前实例化了 Y 时才应使用第二种解决方案。此外,对谓词重新排序可能会加快速度。
【讨论】:
aux/1 中间的剪辑阻止了子目标 s(Y) 的进一步回溯,一旦 r(Y) 评估为真?并且aux/1 不会阻止p(X,Y) 中的回溯?