- •Глава 6 представление знаний
- •6.1. Представление знаний при помощи пролога
- •Исчисление предикатов
- •Вычислительные формализмы
- •Пролог как вычислительный формализм
- •Формальный смысл
- •Внешний смысл
- •Обманчивая природа внешнего смысла
- •Представление знаний при помощи языка Си
- •Расширение языка Пролог
- •Другие вычислительные формализмы
- •6.2. Семантические сети Узлы и дуги
- •Семантическая сеть как Пролог-программа
- •6.3. Фреймы Представление знаний о ситуациях
- •Наследование значений слотов
- •Оценка формализма фреймов
- •Реализация фрейм - программы на Прологе
- •Запрет наследования
- •6.4. Объектно-ориентированное программирование Объекты и сообщения
- •Наследование
- •Объектно-ориентированное программирование в терминах абстрактных типов данных
- •Объектно-ориентированное программирование в терминах формализма фреймов
- •6.5. Механизм наследования в прологе Наследование в других формализмах
- •Наследование в Прологе
- •Состояния знаний
- •Обзор механизма наследования
- •Создание дерева состояний
- •Процедура "послать"
- •Опровержение фразы
- •Концепции механизма наследования
- •Пример с собранием
- •Пример с птицами
- •Реализация процедуры "послать"
- •Алгоритм работы процедуры "послать"
- •6.6. Программа, выполняющая запросы к базе данных
- •Состояния как виртуальные базы данных
- •Использование процедуры "з"
- •Опрос базы данных (добавление нового состояния)
- •Процедура "отобразитьсостояния"
- •Полезные свойства программы, выполняющей запросы к базе данных
- •Реализация программы, выполняющей запросы
- •Процедура "отобразить"
- •Процедура "з"
- •Процедура "характер"
- •6.7. Описание изменений базы данных
- •Мир кубиков
- •Картина состояния
- •Внесение изменений в базу данных при помощи процедуры "поместить"
- •Реализация процедуры "поместить"
- •Оценка механизма наследования
- •Процедура "послать" как предикат метаязыка
- •Библиографические заметки
- •Упражнения
Реализация процедуры "послать"
Процедура послать реализуется следующим образом.
% послать: адресовать запрос к состоянию послать (Состояние, Q) :-
Q =. . [X | Y], % представить запрос в виде списка
послать0 (Состояние, Состояние, [XJY]).
% Q состояние - это состояние, к которому был адресован
% исходный запрос.
послатьО (Q состояние. Состояние, [X ! Y]) :-
Q =. . [X, Состояние | Y], % синтезировать запрос к
% состоянию
Q, % выполнить запрос
not (опровергнут ((Qсостояние, Состояние, Q)).
послатьО ((Qсостояние. Состояние, [X i'Y]):-
% сгенерировать порождающее состояние:
порождение (Состояние, ПорождСост),
% попробовать выполнить запрос к порождающему
% состоянию:
послать0 (Qсостояние, ПорождСост, [X [ Y]) .
% считать запрос Q опровергнутым, если он опровергается
% для состояния равного или более высокого, чем то состоя-
% ние, к которому был обращен исходный запрос.
опровергнут(Qсостояние, Состояние, Q) :—
опровергнуть (Nсостояние, Q),
% состояние Nсостояние, где запрос Q опровергается,
% должно быть более высоким или равным состоянию запроса:
больше_или_равно (Nсостояние, Qсостояние),
% но меньше или равно Состоянию, к которому был
% адресован запрос Q:
больше_или_равно (Состояние, Nсостояние),!.
больше_или_равно (X, X) :— !.
больше_или_равно (X, Y) :—
порождение (Y, Z),
больше_или_равно (X, Z).
Правило "опровергнут" можно прочесть так:
Фраза опровергается
с точки зрения имеющегося запроса, если
она опровергается в некотором состоянии Nсостояние,
более высоком или равном тому состоянию, в которое
фраза была первоначально добавлена,
и менее высоком или равном состоянию, к которому
запрос был адресован.
Отношение между переменными «Состояние», «Qсостояние» и «Nсостояние» в правиле "опровергнут" показано на рис. 6.6.
Алгоритм работы процедуры "послать"
Процедура "послать" берет запрос Q, превращает его в список, а затем вызывает процедуру "послать0". Первый аргумент процедуры "послать0" -- это название состояния, к которому был обращен исходный запрос- Он остается неизменным при всех последующих рекурсивных вызовах процедуры "послать0". Вторым аргументом процедуры "послать0" является имя того состояния, где будет осуществляться попытка выполнения запроса. При первом вызове процедуры "послать0" второй аргумент будет равен первому, но при каждом последующем рекурсивном обращении он будет становиться именем родителя предыдущего состояния.
Процедура "послать0" синтезирует запрос Q по своему третьему аргументу, включая в запрос в качестве первого аргумента имя текущего состояния. Затем запрос Q выполняется и, если он оказывается успешным, процедура "послать0" осуществляет проверку, чтобы убедиться, что выработанный ответ не был опровергнут где-либо между состоянием запроса и текущим состоянием. Если пользователь затребует другой ответ, процедура "послать0" проведет поиск с возвратом с целью нахождения нового ответа в том же самом состоянии, где был найден предыдущий ответ. Если для этого состояния больше не будет ответов, то процедура "послать0" выполнит рекурсивные действия и приступит к поиску ответов в состоянии, являющемся родителем данного состояния. Этот процесс продолжится вплоть до достижения самого верхнего состояния.