Разработка правил
В этом разделе мы рассмотрим набор правил, который помогает справиться с вырожденной формулировкой Р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)