我有一套规则和一组具有相同谓词的事实
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中做到这一点?
答案 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)).