我有一组规则和一组具有相同谓词的事实
p(1).
p(2).
g(1,1).
h(3,2).
p(X):- g(X,Y).
p(X):- h(X,Y).
Run Code Online (Sandbox Code Playgroud)
我想做一个类似收回的谓词,只删除规则而不删除事实。所以像这样:
retractRules(p(X)).
Run Code Online (Sandbox Code Playgroud)
在 Prolog 中如何做到这一点?
您不能使用标准retract/1谓词来仅撤回事实。诸如 之类的调用retract((p(_) :- Body))会撤回事实并实例化Body到true。
鉴于您正在使用 SWI-Prolog,不可移植的解决方案是使用clause/3来获取对规则的引用,然后使用 删除包含这些引用的子句erase/1。假设p/1是一个动态谓词:
?- forall((clause(p(_), Body, Ref), Body \== true), erase(Ref)).
Run Code Online (Sandbox Code Playgroud)
您当然可以撤回所有条款,然后仅断言事实,但这听起来有些过分:
?- forall((retract(p(X) :- Body), Body == true), assertz(p(X)).
Run Code Online (Sandbox Code Playgroud)