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

Ed *_*rts 5 prolog

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

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 中如何做到这一点?

Pau*_*ura 1

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

鉴于您正在使用 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)

  • 在 GNU Prolog 和 SWI Prolog 中工作的解决方案是使用 `clause/2`: `retractRules(R) :- Clause(R, B), B \== true, revoke(:-(R, B)), failed .` (2认同)