Клипы бесконечные факты
Я занимаюсь разработкой экспертной системы, которая будет принимать решения о приеме с использованием 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>