2017-02-09 9 views
3

У меня есть набор правил и набор фактов с тем же предикатомСкладывание только правило, а не факты одного и того же предиката в Прологе

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

Вы собираетесь получить «несмежный предикат» предупреждение с этим кодом, так как определения положений для 'р/1' разделены определений другой предикат. Это означает, что кластеры p (X) 'вообще не распознаются. – lurker

ответ

1

Вы не можете использовать стандартный предикат retract/1, чтобы убрать только факты. Вызов, такой как retract((p(_) :- Body)), убирает факты и создает экземпляры Body по true.

Учитывая, что вы используете SWI-Пролог непереносимой решения является использование clause/3, чтобы получить ссылки на правила, а затем удалить пункты с этими ссылками с помощью erase/1. Предполагая, что p/1 представляет собой динамический предикат:

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

Вы могли бы, конечно, убрать все положения, а затем утверждать обратно только факты, но это звучит излишеством:

?- forall((retract(p(X) :- Body), Body == true), assertz(p(X)). 
+2

Решение, которое работает в GNU Prolog и SWI Prolog, использует 'clause/2':' retractRules (R): - предложение (R, B), B \ == true, retract (:-(R, B)), fail.' – lurker

2

Я удалил свой предшествующий ответ из-за к недостаток в моей логике, который полагался только на retract/1.

Опираясь на идеях Пауло Муры использования clause/3, вот решение, используя предикат ISO clause/2, что делает его немного более портативным:

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

Здесь предполагается, что ваша норма была динамически создана в первую очередь , и объявлен динамическим предикатом, используя соответствующую директиву (:- dynamic). Например, где-то раньше, вы бы что-то вроде:

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

 Смежные вопросы

  • Нет связанных вопросов^_^