А.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)) )
Далее нам понадобятся правила, которые введут отрицания в выражения. Поскольку —<Т(А) эквивалентно 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)) )
;; Выявление противоречия между предположением о
;; лживости и следующими из него фактами, (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))
;; Удалить из базы фактов все утверждения,
;; которые следуют из предположения о правдивости.
(defrule sweep
(declare (salience 20))
(world (tag ?N) (scope falsity))
?F <- (claim (reason ?N) (scope truth)) =>
(retract ?F)
Если теперь запустить на выполнение программу, представив ей исходный набор фактов, соответствующих условию задачи РО, то программа обнаружит, что оба контекста противоречивы. Другими словами, независимо от того, предполагаем ли мы, что А говорит правду или лжет, программа обнаружит противоречие в контексте world. Трассировка программы в этом случае представлена в листинге А. 1. Строки, выведенные курсивом, — сообщения основной программы, а прочие — сообщения программы трассировки. Для удобства строки, указывающие на активизацию правил, представлены полужирным шрифтом.