Программирование на языке CLIPS

         

· Правый операнд утверждения


Новый вариант шаблона объекта world приведен ниже.

Объект world представляет контекст, сформированный определенными предположениями о правдивости или лживости персонажей.

Объект имеет уникальный идентификатор в поле tag, а смысл допущения - истинность или лживость - фиксируется в поле scope.

В поле context сохраняется текущий контекст анализируемого операнда дизъюнкции.

0 означает глобальный контекст дизъюнкции,

1 означает левый операнд,

2 означает правый операнд, (deftemplate world

(field tag (type INTEGER) (default 1))

(field scope (type SYMBOL) (default truth))

(field context (type INTEGER) (default 0)) )

Следующий шаг— разработка правил, манипулирующих контекстом. Приведенное ниже правило формирует контекст для левого операнда дизъюнкции.

(defrule left-or

?W <- (world (tag ?N) (context 0))



(claim (content OR ?P ?X ?Q ?Y)(reason ?N)

(scope ?V)) =>

(modify ?W (context 1)) (assert (claim

(content ?P ?X) (reason ?N) (scope ?V)

(context 1))) )

Это правило устанавливает значение 1 в поле context объекта world и формирует соответствующий объект claim.

По этому же принципу разработаем правило для формирования контекста правого операнда дизъюнкции.

(defrule right-or

?W <- (world (tag ?N) (context 1))

(claim (content OR ?P ?X ?Q ?Y) (reason ?N)

(scope ?V)) =>

(modify ?W (context 2)) (assert (claim

(content ?Q ?Y) (reason ?N) (scope ?V) (context 2))

)

Упражнение 2

Разработайте самостоятельно правило, которое оперировало бы с объектом claim содержим утверждение в конъюнктивной форме, как показано ниже.

(claim (content AND Т A F В) (reason 1) (scope truth))

Это правило должно разделить такое утверждение на два: суть первого — утверждение, что А — правдолюбец, а второго — утверждение, что В — лжец. Новые объекты claim должны существовать в текущем контексте, определенном в объекте world.

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

;; Выявление противоречия между предположением о


;; правдивости и следующими из него фактами

;; в разных контекстах одного и того же объекта world,

(defrule contra-truth-scope

(declare (salience 10)) (world (tag ?N)

(scope truth) (context ?T)) (claim

(content Т ?Х) (reason ?N) (scope truth)

(context ?S&:(< ?S ?T))) ?Q <- (claim

(content P ?x) (reason ?N)

(scope truth) (context ?T)) =>

(printout t "Disjunct " ?T

" is inconsistent with earlier truth context. "

;; "Дизъюнкт " ?T

;; " противоречит ранее установленному контексту правдивости.

" crlf)

(retract ?Q)

)

;; Выявление противоречия между предположением о

;; лживости и следующими из него фактами

;; в разных контекстах одного и того же объекта world.

(defrule contra-falsity-scope (declare (salience 10))

?W <- (world (tag ?N) (scope falsity)

(context ?T» (claim

(content F ?X) (reason ?N) (scope falsity)

(context ?S&:(< ?S ?T))) ?Q <- (claim (content Т ?Х)

(reason ?N)

(scope falsity) (context ?T)) =>

(printout t "Disjunct " ?T

" is inconsistent with earlier falsity context."

;; "Дизъюнкт " ?T

;; " противоречит ранее установленному контексту лживости . "

crlf)

(retract ?Q) )

Нам потребуется модифицировать и прежний вариант правила centra-truth.

;; Выявление противоречия между предположением о

;; правдивости и следующими из него фактами

;; в одном и том же контексте одного и того же объекта world .

(defrule contra-truth

(declare (salience 10))

?W <- (world (tag ?N) (scope truth))

?P <- (claim (content Т ?Х) (reason ?N)

(context ?S)

(scope truth) ) ?Q <- (claim (content F ?X)

(reason ?N) (context ?S)

(scope truth) ) =>

(printout t

"Statement is inconsistent if "?X " is a knight"

;; "Высказывание противоречиво, если " ? X

;; " правдолюбец . "

crlf)

(retract ?Q) (retract ?P) (modify ?W (scope falsity) (context 0)

;; Выявление противоречия между предположением о



;; лживости и следующими из него фактами

;; в одном и том же контексте одного и того же объекта world.

(defrule contra-falsity (declare (salience 10))

?W <- (world (tag ?N) (scope falsity))

?P <- (claim (content F ?X) (reason ?N)

(context ?S) (scope falsity))

?Q <- (claim (content Т ?Х) (reason ?N)

(context ?S)(scope falsity)) =>

(printout t

"Statement is inconsistent whether " ?X

" is knight or knave."

;; "Высказывание противоречиво, независимо от того,"

;; "является ли " ?Х " правдолюбцем или лжецом."

crlf)

(modify ?W (scope contra) )

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

(defrule consist-truth

(declare (salience -10))

?W <- (world (tag ?N) (scope truth))

(statement (speaker ?Y) (tag ?N)) =>

(printout t

"Statement is consistent:"

;; "Высказывание непротиворечиво:"

crlf)

(modify ?W (scope consist)

)

(defrule consist-falsity

(declare (salience -10)) ?W <- (world (tag ?N)

(scope falsity)) (statement (speaker ?Y) (tag ?N)) =>

(printout t

"Statement is consistent:"

;; "Высказывание непротиворечиво:"

crlf) (modify ?W (scope consist)

)

(defrule true-knight

(world (tag ?N) (scope consist))

?C <- (claim (content T ?X) (reason ?N) =>

(printout t

?X "is a knight" ;; ?X "- правдолюбец"

crlf) (retract ?C)

)

(defrule false-knave

(world (tag ?M) (scope consist))

?C <- (claim (content F ?X) (reason ?N))

(printout t

?X " is a knave" ;; ?X "- лжец"

crlf)

(retract ?C) )

Ниже приведено правило разделения операции конъюнкции, которое ранее мы предлагали вам разработать самостоятельно. Обратите внимание на то, что в нем также отслеживается контекст, хотя в данном случае без этого можно было бы и обойтись.

(defrule conj



(world (tag ?N (context ?S))

(claim (content AND ?P ?X ?Q ?Y) (reason ?N)

(scope ?V)) =>

(assert (claim

(content ?P ?X) (reason ?N) (scope ?V)

(context ?S))) (assert (claim

(content ?Q ?Y) (reason ?N) (scope ?V)

(context ?S))) )

Прежде чем запустить программу на выполнение, сформируем исходные факты в соответствии с условиями задачи Р4:

(deffacts the-facts

(world)

(statement (speaker A) (claim AND F A F B) (tag 1)) )

После запуска программы в режиме трассировки интерпретатор сформирует распечатку процесса ее выполнения, приведенную в листинге А.2.

Листинг А.2. Трассировка решения задачи Р4

CLIPS> (reset)

==> f-0 (initial-fact)

==> f-1 (world (tag 1) (scope truth) (context 0))

==> f-2 (statement (speaker A)

(claim OR F A T B) (reason 0) (tag 1))

CLIPS> (run)

FIRE 1 unwrap-trues f-1,f-2

Assumption

A is a knight, so (OR F A T B) is true.

==> f-3 (claim (content OR F A T B)

(reason 1) (scope truth) (context 0))

==> f-4 (claim (content T A) (reason 1)

(scope truth) (context 0)) FIRE 2 left-or: f-1,f-3

==> f-5 (claim (content F A) (reason 1)

(scope truth) (context 1))

<== f-1 (world (tag 1) (scope truth) (context 0))

==> f-6 (world (tag 1) (scope truth) (context 1))

FIRE 3 contra-truth-scope: f-6,f-4,f-5

Disjunct 1 is inconsistent with earlier truth context.

<== f-5 (claim (content F A) (reason 1)

(scope truth) (context 1)) FIRE 4 right-or: f-6,f-3 .

==> f-7 (claim (content Т В) (reason 1)

(scope truth) (context 2))

<== f-6 (world (tag 1) (scope truth)

(context 1))

==> f-8 (world (tag 1) (scope truth)

(context 2))

FIRE 5 consist-truth: f-8, f-2

Statement is consistent:

<== f-8 (world (tag 1) (scope truth) (context 2))

==> f-9 (world (tag 1) (scope consist) (context 2))

FIRE 6 true-knight: f-9, f-7

В is a knight

<== f-7 (claim (content Т В) (reason 1)

(scope truth) (context 2))

FIRE 7 true-knight: f-9,f-4

A is a knight

<== f-4 (claim (content Т A) (reason 1)

(scope truth) (context 0))



CLIPS>

A.4.5. Обратное прослеживание и множество контекстов

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

Упражнение 3

Р5. Встречаются два человека, А и В, которые заявляют следующее. А: "Я говорю правду, либо В лжец", В: " А говорит правду, либо я лжец".

К какой категории следует отнести каждый из персонажей? (Решите эту задачу самостоятельно вручную, используя ту же систему обозначений, которая применялась ранее в этом Приложении.)

Задача анализа высказываний нескольких персонажей потребует использования более сложной методики, которая получила наименование "обратное прослеживание на основе анализа зависимостей"(dependency-directed backtracking).

От программы потребуется выполнить обратное прослеживание (откат) в следующих ситуациях:


Содержание раздела