在Prolog中仅撤回规则而不撤回同一谓词的事实

时间:2017-02-09 00:47:17

标签: prolog

我有一套规则和一组具有相同谓词的事实

p(1).
p(2).
g(1,1).
h(3,2).
p(X):- g(X,Y).
p(X):- h(X,Y).

我想做一个类似retractall的谓词,只删除规则而不是事实。如下所示:

retractRules(p(X)).

如何在Prolog中做到这一点?

2 个答案:

答案 0 :(得分:2)

由于我的逻辑缺陷只依赖于retract/1,我删除了之前的答案。

基于Paulo Moura使用clause/3的想法,这里使用ISO谓词clause/2的解决方案,使其更具便携性:

retractRules(R) :-
    clause(R, B),
    B \== true,
    retract(:-(R, B)),
    fail.
retractRules(_).

这里的假设是您的规则首先是动态创建的,并使用适当的指令(:- dynamic)声明为动态谓词。例如,在之前的某个地方,你会有类似的东西:

assertz(:-(p(X), g(X,Y))).

答案 1 :(得分:1)

您不能使用标准retract/1谓词来仅收回事实。 retract((p(_) :- Body))之类的调用会收回事实并将Body实例化为true

鉴于您正在使用SWI-Prolog,非可移植解决方案是使用clause/3获取对规则的引用,然后使用{{删除带有这些引用的子句1}}。假设erase/1是动态谓词:

p/1

你当然可以收回所有条款,然后只断言事实,但听起来有点过分了:

?- forall((clause(p(_), Body, Ref), Ref \== true), erase(Ref)).