Клипы: проверка правильных фактов - PullRequest
0 голосов
/ 26 апреля 2019

У меня есть ряд правил и набор исходных (assert) фактов. Теперь я хочу добавить эти факты, запустить правила, а затем применить другой набор правил, чтобы проверить, содержат ли текущие существующие факты после (run) правильные факты и ничего больше, без запуска предыдущих правил и без уничтожения текущих фактов. Затем я хочу продолжать применять новые факты, запускать новые правила, проверять новые вставленные факты и т. Д.

Как я могу это сделать? Мой тестовый (пакетный) файл выглядит примерно так:

(clear) ; just in case
(load constructs.clp) ; All loaded in the MAIN module.

(assert (blabla))
(assert (blabla2))
(run)

;; Code (rules/functions... I'm still wondering how to do it) to check
;; current facts

(assert (blabla3))
(assert (blabla4))
(run)

;; More tests.

(exit)

Я пытался создать для каждого deftemplate T a deftemplate T-copy с одинаковыми слотами, и они применяют факт (assert (testing)), чтобы сначала сделать копии. Затем я запускаю набор правил с целью тестирования и большей важностью, который «останавливает» выполнение (run), когда оно выполнено, чтобы избежать применения предыдущих правил (правил, которые я тестирую). Проблема с этим подходом, помимо того, что требуется слишком много шагов, состоит в том, что я не знаю значимости исходных правил и поэтому не могу быть уверен, что правила тестирования будут иметь больший приоритет.

Мне известны конструкции defmodule и стек фокусировки, но я их еще не понял. Если мои предположения верны, я думаю, что я мог бы поместить все свои правила тестирования в конкретный модуль и сосредоточить внимание на этом модуле, чтобы избежать выполнения любого ГЛАВНОГО правила. Если что-то не так, я (halt) выполнение по одному из правил тестирования или просто (exit) пакетный скрипт. Если все в порядке, я выталкиваю модуль тестирования, чтобы вернуться в MAIN, добавляю еще раз assert, (run), и они снова толкают модуль тестирования с новыми тестами, чтобы проверить, все ли по-прежнему правильно.

Но я не уверен, что мои предположения верны. Я хотел бы увидеть пример того, как мне проводить тестирование.

PD: Кроме того, моя версия CLIPS не поддерживает запросы по фактам.

1 Ответ

1 голос
/ 30 апреля 2019

Вот общая идея отделения основной группы правил от правил, выполняющих тестирование, на отдельные модули, а затем с помощью команды focus для выполнения правил тестирования.

CLIPS> (defmodule MAIN (export ?ALL))
CLIPS> (deftemplate MAIN::point (slot x) (slot y))
CLIPS> 
(defrule MAIN::r1
   =>
   (assert (point (x 1) (y 2)))
   (assert (point (x 1) (y 5))))
CLIPS> (defmodule TESTING (import MAIN ?ALL))
CLIPS> 
(defrule TESTING::horizontal
   (point (x ?x1) (y ?y))
   (point (x ?x2&:(< ?x2 ?x1)) (y ?y))
   =>
   (printout t "Horizonal issue " ?y crlf))
CLIPS> (reset)
CLIPS> (agenda)
0      r1: *
For a total of 1 activation.
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (point (x 1) (y 2))
f-2     (point (x 1) (y 5))
For a total of 3 facts.
CLIPS> (focus TESTING)
TRUE
CLIPS> (agenda)
CLIPS> (run)
CLIPS> 
(defrule MAIN::r2
   =>
   (assert (point (x 3) (y 2))))
CLIPS> (run)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (point (x 1) (y 2))
f-2     (point (x 1) (y 5))
f-3     (point (x 3) (y 2))
For a total of 4 facts.
CLIPS> (focus TESTING)
TRUE
CLIPS> (run)
Horizonal issue 2
CLIPS> 
(defrule TESTING::vertical
   (point (x ?x) (y ?y1))
   (point (x ?x) (y ?y2&:(< ?y2 ?y1)))
   =>
   (printout t "Vertical issue " ?x crlf))
CLIPS> (focus TESTING)
TRUE
CLIPS> (agenda)
0      vertical: f-2,f-1
For a total of 1 activation.
CLIPS> (run)
Vertical issue 1
CLIPS> 
...