Клипы бесконечные факты

Я занимаюсь разработкой экспертной системы, которая будет принимать решения о приеме с использованием PyClips. Тем не менее, код продолжал генерировать ошибки "недостаточно памяти". Я думаю, что я изолировал мою проблему. Что-то не так с моим файлом CLIPS. Надеюсь, кто-то может увидеть, что я делаю не так здесь. Это самая простая версия кода.... Я упростил ее для отладки: так вот мой шаблон, и в качестве аргумента есть только 1 правило: если стенограмма получена, то приложение завершено атрибут помечен как ИСТИНА.

; template for application facts
(deftemplate application "structure of an application"
(slot app-id (type INTEGER))
(slot app-complete (type SYMBOL))
(slot transcript-received (type SYMBOL))
 )


(defrule complete "rule for app completeness"

?f <- (application
        (transcript-received Yes)    
    )
=>
    (modify ?f
        (app-complete TRUE)
    )
)
; end.

Поэтому, когда я делаю (assert (application (app-id 123) (transcript-received Yes)))тогда я добавлю факт. Когда я нажимаю "выполнить", хотя.... окно в CLIPS начинает перегружаться тысячами фактов... атрибут app-complete выглядит помеченным как TRUE, однако факты просто продолжают циклически повторяться, безостановочно. Когда становится слишком много фактов, я говорю о 100K или о чем-то... тогда CLIPS просто уходит... Есть идеи, что я здесь делаю неправильно? Мой синтаксис как-то испорчен? Мои намерения состоят в том, чтобы затем иметь базу данных sqlite, чтобы иметь возможность читать "факты" из базы данных, чтобы система могла принимать решения… но я не могу пройти мимо этого!

1 ответ

Решение

Важно помнить, что при изменении deftemplate факт, факт убирается и утверждается новый (модифицированный) факт. Ваше правило также соответствует измененному факту, который затем снова изменяется и сопоставляется и т. Д., Что приводит к бесконечному циклу. Если бы вы запускали свой код при просмотре фактов и активаций, вы бы увидели что-то вроде этого:

<== f-1     (application (app-id 123) (app-complete nil) (transcript-received Yes))
==> f-2     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> Activation 0      complete: f-2
<== f-2     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> f-3     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> Activation 0      complete: f-3
<== f-3     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> f-4     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> Activation 0      complete: f-4
(etc.)

Вы можете предотвратить это, сопоставляя только те приложения, которые еще не завершены. Вот модифицированная версия вашего кода, которая добавляет по умолчанию FALSE значение для app-complete слот и соответствует только приложениям, которые не завершены:

(deftemplate application "structure of an application"
  (slot app-id (type INTEGER))
  (slot app-complete (type SYMBOL) (default FALSE))
  (slot transcript-received (type SYMBOL)))

(defrule complete "rule for app completeness"
  ?f <- (application (transcript-received Yes) (app-complete FALSE))
  =>
  (modify ?f (app-complete TRUE)))

Теперь, если вы смотрите факты и активации, вы должны увидеть следующее, когда вы отстаиваете свой факт и запускаете:

CLIPS> (assert (application (app-id 123) (transcript-received Yes)))
==> f-0     (application (app-id 123) (app-complete FALSE) (transcript-received Yes))
==> Activation 0      complete: f-0
<Fact-0>
CLIPS> (run)
<== f-0     (application (app-id 123) (app-complete FALSE) (transcript-received Yes))
==> f-1     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
CLIPS>
Другие вопросы по тегам