Джесс. Есть ли эффективный способ проверить, находится ли факт в рабочей памяти?

Для простоты предположим, что у меня есть следующие два шаблона:

(deftemplate JessObjA (declare (from-class JessObjA)) )
(deftemplate JessObjB (declare (from-class JessObjB)) )

и правило, которое добавляет JessObjB в память всякий раз, когда происходит совпадение с JessObjA. В дополнение к этому у меня есть объект, подобный списку, в моей программе Java, в котором хранятся эти JessObjB (либо идентификатор факта, либо ссылка. Я не определился с этим, так как не знаю, что лучше на данный момент):

(defrule one-for-one
(logical
    ?x <- (JessObjA)
)
=>
    (bind ?p (new JessObjB ))
    (printout t "made a new JessObjB" ?p crlf)
    (add ?p)

    (bind ?list (fetch someList))
    (?list add ?p)
)

Я хочу обновлять содержимое someList. Я знаю, что если я отзову свой JessObjA, факт, связанный с JessObjB, также будет отозван, но оба объекта Fact и JessObjB все еще остаются в памяти Java (если мой список содержит ссылки).

Что я хочу сделать, так это периодически проверять в моем списке, ссылаются ли какие-либо значения на идентификаторы фактов, которых больше нет в памяти. Моя первая мысль — использовать (fact-id <id>), но на самом деле это вызывает исключение, если факта больше нет в памяти. Кроме того, это медленная функция , чего я хотел бы избежать.

Мое единственное работающее решение до сих пор уродливо: мой список содержит JessObjB объектов, и чтобы проверить, существует ли он как факт или нет, я вызываю Rete.getShadowFactForObject на нем, и если я сталкиваюсь с JessException, то я знаю, что его больше нет в памяти, так что я могу удалить его из списка.

Есть ли более элегантный способ сделать это?


person Tingy    schedule 19.06.2020    source источник


Ответы (1)


Если вам нужно выполнить действие при выполнении некоторого условия, лучше всего написать правило, соответствующее условию. Если у вас есть A, но нет B, правило должно: (a1) создать B, (a2) вставить B в список‹>. Если у вас есть B, но нет A, другое правило должно: (b1) убрать B, (b2) удалить B из списка‹>. Поскольку ваше правило «один к одному» не допускает кодирования (b2), вы не можете использовать «логический» CE.

Поддержание списка Java в актуальном состоянии гораздо предпочтительнее решения, использующего два правила.

person laune    schedule 20.06.2020
comment
Проблема в том, что мои фактические правила для моей программы сложнее, чем мое правило один к одному. И я использую Джесс для усиления логической поддержки. Я хотел бы избежать создания дополнительных правил, согласующихся с отсутствием фактов. - person Tingy; 22.06.2020
comment
Так почему же вы вообще храните этот список «Б»? Вы всегда можете получить список всех B, запросив рабочую память. Избыточность информации — это всегда запах кода. - person laune; 24.06.2020
comment
Итак, у меня есть набор правил, R1, R2,..., и каждое правило создает одинаковые типы Фактов, но мне интересно отслеживать, какое правило создает указанный Факт. Я храню эту информацию в виде карты, где запись для ключа R1 содержит список‹B› и так далее. Есть ли лучший способ отслеживать это? Я должен отметить, что наличие разных шаблонов фактов для каждого правила не подходит для этого приложения в частности. - person Tingy; 25.06.2020