А.4.3. Разработка правил
А.4.3. Разработка правил
В этом разделе мы рассмотрим набор правил, который помогает справиться с вырожденной формулировкой
Р0 задачи о лжецах и правдолюбцах. Первые два правила, unwrap-true и unwrap-false, извлекают содержимое высказывания в предположении, что персонаж, которому принадлежит высказывание, является соответственно правдолюбцем или лжецом, и на этом основании формируют объект claim.
;; Извлечение содержимого высказывания,
(defrule unwrap-true
(world (tag ?N) (scope truth))
(statement (speaker ?X) (claim $?Y) (tag ?N)) =>
(assert (claim (content Т ?Х) (reason ?N)
(scope truth)))
(assert (claim (content $?Y) (reason ?M)
(scope truth)))
)
(defrule unwrap-false
(world (tag ?N) (scope falsity))
(statement (speaker ?X) (claim $?Y) (tag ?N)) =>
(assert (claim (content F ?X) (reason ?N)
(scope falsity)))
(assert (claim (content NOT $?Y) (reason ?N)
(scope falsity)) )
В каждом из приведенных правил первый оператор в условной части делает предположение соответственно о правдивости или лживости персонажа, а второй оператор в заключительной части правила распространяет предположение на формируемые утверждения — объекты claim.
Далее нам понадобятся правила, которые введут отрицания в выражения. Поскольку —<Т(А) эквивалентно F(A), a —F(A) эквивалентно Т(А), то правила, выполняющие соответствующие преобразования, написать довольно просто. Анализ результатов применения этих правил значительно упростит выявление противоречий, следующих из определенного предположения.
;; Правила отрицания (defrule notl
?F <- (claim (content NOT Т ?Р)) =>
(modify ?F (content F ?P))
)
(defrule not2
?F <- (claim (content NOT F ?P)) =>
(modify ?F (content Т ?Р))
)
;; Выявление противоречия между предположением о
;; правдивости и следующими из него фактами,
(defrule contra-truth
(declare (salience 10))
?W <- (world (tag ?N) (scope truth))
?S <- (statement (speaker ?Y) (tag ?N))
?P <- (claim (content Т ?Х) (reason ?N) (scope truth))
?Q <- (claim (content F ?X) (reason ?N) (scope truth)) =>
(printout t crlf
"Statement is inconsistent if " ?Y " is a knight."
;; "Высказывание противоречиво, если " ?Y " правдолюбец."
t crlf)
(retract ?Q)
(retract ?P)
(modify ?W (scope falsity)) )
Если предположить, что исходное высказывание было правдивым, то в дальнейшем обнаруживается противоречивая пара утверждений, которые затем удаляются из рабочей памяти, а значение "правдивости" предположения в объекте world изменяется на falsity (лживость). Если же после этого также будет обнаружено противоречие, то мы приходим к выводу о глобальной несовместимости условий задачи, т.е. в данной постановке мы имеем дело с логическим парадоксом.
;; Выявление противоречия между предположением о
;; лживости и следующими из него фактами, (defrule contra-falsity
(declare (salience 10))
?W <- (world (tag ?N) (scope falsity))
?S <- (statement (speaker ?Y) (tag ?N))
?P <- (claim (content F ?X) (reason ?N) (scope falsity))
?Q <- (claim (content T ?X) (reason ?N)
(scope falsity)) => (printout t crlf
"Statement is inconsistent if " ?Y " is a knave. "
;; "Высказывание противоречиво, если " ?Y " лжец." t crlf)
(modify ?W (scope contra))
Правило sweep обеспечивает проверку, все ли следствия из неверного предположения удалены из памяти.
;; Удалить из базы фактов все утверждения,
;; которые следуют из предположения о правдивости.
(defrule sweep
(declare (salience 20))
(world (tag ?N) (scope falsity))
?F <- (claim (reason ?N) (scope truth)) =>
(retract ?F)
Обратите внимание на то, что правила contra-truth, contra-f alsity и sweep имеют более высокий приоритет (значение параметра salience), чем другие правила. Этим обеспечивается как можно более ранее обнаружение противоречия, а следовательно, и удаление из базы фактов утверждений, сделанных на основе предположения, приведшего к противоречию.
Если теперь запустить на выполнение программу, представив ей исходный набор фактов, соответствующих условию задачи РО, то программа обнаружит, что оба контекста противоречивы. Другими словами, независимо от того, предполагаем ли мы, что А говорит правду или лжет, программа обнаружит противоречие в контексте world. Трассировка программы в этом случае представлена в листинге А. 1. Строки, выведенные курсивом, — сообщения основной программы, а прочие — сообщения программы трассировки. Для удобства строки, указывающие на активизацию правил, представлены полужирным шрифтом.
Содержание раздела