Как клипы не повторяют выполнение правил? - PullRequest
0 голосов
/ 10 июня 2018

У меня проблемы с пониманием, почему этот код клипа не попадает в бесконечный цикл

(defrule rule0
=>
        (assert (my-fact))
)

(defrule rule1
        ?f <- (my-fact)
=>
        (retract ?f)
)

Насколько я знаю, rule0 выполняется, утверждая my-fact, затем rule1выполняется втягивая его.Почему rule0 не выполняется снова сейчас?
Вот мои мысли:

  • Клипы запоминают для каждого правила, если оно было выполнено с использованием некоторых базовых фактов, и избегают повторного выполнения этого правила с использованиемте же базовые факты.
  • Существует какой-то оптимизатор, который обнаружил цикл и избежал его.
  • Клипы запоминают факты, которые были вставлены и удалены, и избегают повторной вставки этих фактов (очень сомневаюсьэто, я почти уверен, что это не может быть так).

Примечание. Я абстрагировал этот фрагмент кода от другой небольшой программы, которая использует шаблоны вместо фактов.

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

В Википедии есть хороший обзор того, как работает алгоритм Rete.Одна из ключевых концепций, которую нужно понять, заключается в том, что правила не ищут данные, которые их удовлетворяют, а данные ищут правила, которые они удовлетворяют.Алгоритм повторения предполагает, что большинство данных остается неизменным после каждого срабатывания правила, поэтому поиск данных по правилам будет неэффективным, поскольку только часть данных изменяется после каждого срабатывания правила.Вместо этого правила сохраняют состояние того, что уже сопоставлено, и когда вносятся изменения в данные, которые влияют на это состояние, оно обновляется.

Когда правило правила 0 определено, оно активируется, потому что у него нет условий.Когда правило rule1 определено, оно не активируется, потому что my-fact еще не существует.Когда выполняется правило rule0, утверждается факт my-fact, а затем правило rule1 обновляет свое состояние и активируется.Когда выполняется правило rule1, my-fact отменяется, а состояние правила rule1 обновляется, поскольку оно соответствует my-fact.Это правило не влияет на правило rule0, поскольку в нем нет условий, соответствующих моему факту.

0 голосов
/ 11 июня 2018

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

Здесь мы имеем особый случай.Поскольку у rule0 нет LHS, оно не сработает во второй раз, даже если база фактов изменится.Отсутствие LHS означает отсутствие сопоставления с образцом и, следовательно, дальнейшую активацию.

Но вы можете снова запустить правило с помощью команды обновления.

CLIPS> (run)
CLIPS> (refresh rule0)
CLIPS> (agenda)
0      rule0: *
For a total of 1 activation.

Обычно вы не можете вставить фактесли тот же факт уже есть в вашей базе фактов (если он был отозван, вы можете добавить его снова).Вы можете изменить это с помощью ( set-fact-duplication ):

CLIPS> (set-fact-duplication TRUE)

Но я бы не рекомендовал это.

...