Унификация статических и действительных термов
В данном разделе мы собираемся рассмотреть предикат unify_term, фак-
тически являющийся карбюратором нашей машины вывода. Он получает на входе
статические термы, действительные термы, а также среду, а на выходе дает
принятую в Прологе унификацию двух различных типов термов, отображаемых
посредством создания переменных, помещаемых в среду.
Предикат unify_term действует совместно с предикатом unify_terml,
который просто вызывает unify_term для каждого элемента списка аргументов
унифицируемого терма. Объявления и определения unify_term и unify_terml
выглядят так:
predicate
determ unify_term(aTerm,sTerm,env)
determ unify_terml(aTermList,sTermList,env)
clauses
unify_terml([],[],_):-!.
unify_terml([ATerm1|ATL1],[STerm2|STL2],Env):-
unify_term(ATerm1,STerm2,Env),unify_terml(ATL1,STL2,Env).
unify_term(ATerm,var(ID),Env):-
free(ID),free(ATerm),!,
createVar(ATerm,Env,ID).
unify_term(_,STerm,_):-
bound(STerm),
Sterm=var("_"),!.
unify_term(ATerm,var(ID),Env):-
bound(ID),!,
member(e(ID,ATerm1),Env),
ATerm1=ATerm.
unify_term(int(I),int(I),_):-!.
unify_term(atom(A),atom(A),_):-!.
unify_term(str(S),str(S),_):-!.
unify_term(char(C),char(C),_):-!.
unify_term(list(H1,T1),list(H2,T2),Env):-!,
unify_term(H1,H2,Env),
unify_term(T1,T2,Env).
unify_term(nill,nill,_):-!.
unify_term(cmp(ID,L1),cmp(ID,L2),Env):-!,
unify_terml(L1,L2,Env).
Сейчас мы не будем касаться двух первых предложений для unify_term,
потому что они предназначены для специальных действий с переменными и
средой в некоторых конкретных условиях, что иногда также влечет за собой
иной потоковый шаблон.
Второе предложение unify_term обрабатывает пустую унификацию с ано-
нимными переменными, что может быть использовано интерпретатором правил
(мы обсудим это дальше).
Третье предложение для unify_term создает aTerm (активный терм) и
устанавливает среду для переменных в списке аргументов.
Четвертое предложение для unify_term отвечает за создание трех ак-
тивных термов в среде и проверку на стандартное унификационное равенство
в случае наличия обоих термов.
unify_term(АTerm, var(ID), Env):- /* (aTerm, sTerm, среда)*/
bound(ID),! /* удостовериться, что ID существует */
member(e(ID, АTerml), Env), /* обновляет ID и Terml в среде*/
АTerml = АTerm /*унифицирует aTerm со значением в среде ID*/
Проверка на установку ID сделана для того, чтобы избежать активации
предложения для потокового шаблона, где sTerm является аргуменом вывода,
в этом случае он частично связан с var(_) (это подробно объяснено далее).
Когда вызывается предикат member, то он или связывает АTerm1 с пере-
менной, идентефицируемой ID или, если в среде еще нет ID, member добавит
его и вернет АTerm1 несвязанным. После этого унификация двух термов
(АTerm и АTerm1) происходит одним из трех способов:
1. Если оба терма связаны, то унификация двух термов заканчива-
ется успешно или нет (это зависит от их значений).
2. Если связан только один терм, то унификация произойдет путем
установки двух термов друг на друга.
3. Если оба терма являются свободными переменными, то они раз-
деляются (что означает, что они будут представлены указателем,
и каждый указатель будет указывать на один и тот же свободны
адрес).
Вот несколько целей, показывающих, как происходит связывание пере-
менных в среде:
Способ, каким вызывается предикат member, очень важен. Он показыва-
ет, как легко, не думая об аргументах потока, можно создать хаос. Вместо
такого предложения, как
unify_term(АTerm, var(ID), Env):-bound(ID),!
member(e(ID, АTerml), Env),
АTerml = АTerm
вы может захотеться воспользоваться
unify_term(АTerm, var(ID), Env):-bound(ID),!
member(e(ID, АTerml), Env).
надеясь, что традиционное сопоставление заголовков, принятое в Прологе,
сделает то, что последующая унификация (АTerml = АTerm) делает в исходном
вызове. Однако, если вы внимательнее отнесетесь к определению предиката
member
member(X, [X|_]):-!.
member(X, [_|L]):-member(X,L).
то увидите, что вызов member(e(ID, АTerml), Env). никогда не приведет к
неуспеху, даже в случае различных термов. Вместо этого, member создаст
два элемента в среде, имеющих два различных значения для одной и той же
переменной. Например, если такой элемент уже был в среде:
e("X", int(<некоторое_значение>))
и у вас было member(e("X", ATerm, Env), где АTerm = другое_значение. то
member добавит новый элемент для "Х", и среда будет выглядеть так:
e("X", int(<некоторое_значение>))
e("X", int(<другое_значение>))
Вот цель, показывающая данную ситуацию:
Goal: Env=(e("x", int(0))|_]
member=(e("x", int(1)), Env)
Env=(e("x", int(0)), e("x", int(1))|_]
1 Solution
Почему для каждого функтора требуются отдельные предложения (тип ар-
гумента?). Функторам сложных объектов в Турбо Прологе присваиваются одно-
байтные значения, повышающие эффективность использования памяти и увели-
чивающие скорость, поэтому, хотя "int" и "int" одинаково выглядят в пра-
виле unify_term(int(I), int (I),_):-..., но они относятся к различным об-
ластям (соответственно aTerm и sTerm). Они могут корректно быть установ-
лены друг на друга.
Обратите внимание, что многие базы правил не включают понятие иден-
тефикаторов как отдельного типа данных и редко используют списки. В край-
нем случае, вам придется включить те типы из областей терминов (и соот-
ветствующие предложения для unify_term), которые используются в конкрет-
ной прикладной задаче.
- Справочное руководство по турбо прологу 2.0
- Глава 2. Элементы языка 50
- Глава 3. Интерфейс с другими языками 75
- Часть 2. Стандартные предикаты 91
- Часть 3. Приложения 250
- Введение
- Дистрибутивные диски
- Рекомендуемая литература:
- Часть 1. Руководство программиста по турбо прологу глава 1. Система меню турбо пролога
- Пользователям Турбо Пролога 1.X
- Структура меню Турбо Пролога
- Выбор элементов меню.
- "Горячие" клавиши.
- Системные окна и строки помощи
- Окно редактирования.
- Как войти в окно редактирования
- Компоненты окна редактирования
- Как выйти из окна редактирования.
- Окно трассировки
- Окно сообщений
- Диалоговое окно
- Строка помощи
- Главное меню.
- Окно редактирования.
- Окно вспомогательного редактирования (Xedit).
- Окно просмотра.
- Изменение размера окон.
- Просмотр окон
- Создание нового файла.
- Загрузка существующего файла.
- Команды редактора.
- Сохранение исходного текста в файле.
- Запись исходного текста на диск
- Вспомогательный редактор
- Меню и команды
- Меню файлов (Files)
- Загрузка файлов (Load)
- "Указка" (Pick)
- Новый (New)
- Выход (Quit)
- Команда редактирования (Edit)
- Команда запуска (Run)
- Меню компиляции (Compile)
- Память (Memory)
- Меню опций (Options)
- Опции компоновки (Link Options)
- Стек (Stack)
- Область ссылок (Trail Array)
- "Куча" (Heap)
- Контроль во время исполнения (Run-time check)
- Цвета (Colors)
- Размер окна (Window size)
- Каталоги
- Текущий каталог (Current directory)
- Авто-загрузка сообщений (Avto-Load Message)
- Режим экрана (Screen mode)
- Конфигурация клавиатуры (Keyboard Configuration)
- Перемещение курсора (Cursor movement)
- Глава 2. Элементы языка
- Ключевые слова.
- Специальные предикаты.
- Разделы программы.
- Раздел доменов (domains).
- Стандартные домены.
- Списковые домены.
- Домены составных объектов.
- Файловый домен.
- Специально заданные предопределенные домены.
- Сокращение объявлений доменов.
- Объявление ссылочных доменов.
- Раздел предикатов (predicates).
- Раздел базы данных (database).
- Раздел предложений (clauses).
- Простые константы.
- Переменные.
- Составные объекты.
- Списки - Специальный вид составных объектов.
- Раздел констант.
- Условная компиляция.
- Включение файлов в вашу программу.
- Директивы компилятора.
- Управление памятью в Турбо Прологе.
- Экономия ресурсов памяти.
- Управление распределением памяти.
- Генерирование выполняемых программ.
- Модульное программирование.
- Проекты.
- Глобальные объявления.
- Глобальные домены.
- Глобальная база данных.
- Глобальные предикаты.
- Компиляция и компоновка модулей.
- Пример.
- Глава 3. Интерфейс с другими языками
- Вызов других языков из Турбо Пролога.
- Что делать перед вызовом.
- Объявление внешних предикатов.
- Вызов соглашений и передача параметров.
- Соглашение об обозначениях
- Использование ключевого слова as
- Вызов процедуры, написанной на Си из Пролога.
- Опции компилятора Турбо Си и компоновка.
- Вызов программ на языке ассемблера из Турбо Пролога.
- Использование внутреннего ассемблера Турбо Си.
- Вызов Турбо Пролога из других языков.
- Динамическое распределение памяти.
- Передача составных объектов в другие языки.
- Передача списков.
- Передача структур.
- Примеры.
- Обработка списков.
- Программирование на низком уровне.
- Часть 2. Стандартные предикаты
- Arc/5 Графика
- Bar/4 Графика
- Bt_close/2 Внешняя База Данных
- Bt_create/5 Внешняя База Данных
- Bt_delete/2 Внешняя База Данных
- Bt_open/3 Внешняя База Данных
- Bt_statistics/8 Внешняя База Данных
- Chain_delete/2 Внешняя База Данных
- Chain_first/3 Внешняя База Данных
- Chain_inserta/5 Внешняя База Данных
- Chain_insertafter/5 Внешняя База Данных
- Chain_insertz/5 Внешняя База Данных
- Chain_last/3 Внешняя База Данных
- Chain_next/3 Внешняя База Данных
- Chain_prev/3 Внешняя База Данных
- Chain_terms/5 Внешняя База Данных
- Circle/3 Графика
- Cleardevice/0 Графика
- Clearviewport/0 Графика
- Closegraph/0 Графика
- Db_btrees/2 Внешняя База Данных
- Db_chains/2 Внешняя База Данных
- Db_close/1 Внешняя База Данных
- Db_create/3 Внешняя База Данных
- Db_delete/2 Внешняя База Данных
- Db_flush/1 Внешняя База Данных
- Db_garbagecollect/1 Внешняя База Данных
- Db_open/3 Внешняя База Данных
- Db_openinvalid/3 Внешняя База Данных
- Db_statistics/5 Внешняя База Данных
- Detectgraph/2 Графика
- Drawpoly/1 Графика
- Ellipse/6 Графика
- Fillellipse/4 Графика
- Fillpoly/1 Графика
- Floodfill/3 Графика
- Getarccoords/6 Графика
- Getaspectratio/2 Графика
- Getbkcolor/1 Графика
- Getcolor/1 Графика
- Getdefaultpalette/1 Графика
- Getdrivername/1 Графика
- Getfillpattern/1 Графика
- Getfillsettings/2 Графика
- Getgraphmode/1 Графика
- Getimage/6 Графика
- Getlinesettings/3 Графика
- Getmaxcolor/1 Графика
- Getmaxx/1 Графика
- Getmaxy/1 Графика
- Getmaxmode/1 Графика
- Getmodename/2 Графика
- Getmoderange/3 Графика
- Getpalette/1 Графика
- Getpalettesize/1 Графика
- Getpixel/3 Графика
- Gettextsettings/5 Графика
- Getviewsettings/5 Графика
- Getx/1 Графика
- Gety/1 Графика
- Graphdefaults/0 Графика
- Graphresult/1 Графика
- Imagesize/5 Графика
- Initgraph/5 Графика
- Key_current/4 Внешняя База Данных
- Key_delete/4 Внешняя База Данных
- Key_first/3 Внешняя База Данных
- Key_insert/4 Внешняя База Данных
- Key_last/3 Внешняя База Данных
- Key_next/3 Внешняя База Данных
- Key_prev/3 Внешняя База Данных
- Key_search/4 Внешняя База Данных
- Line/4 Графика
- Linerel/2 Графика
- Lineto/2 Графика
- Moverel/2 Графика
- Moveto/2 Графика
- Outtext/1 Графика
- Outtextxy/3 Графика
- Pieslice/5 Графика
- Pieslicexy/6 Графика
- Putimage/4 Графика
- Putpixel/3 Графика
- Rectangle/4 Графика
- Restorecrtmode/0 Графика
- Setactivepage/1 Графика
- Setallpalette/1 Графика
- Setaspectratio/2 Графика
- Setbkcolor/1 Графика
- Setcolor/1 Графика
- Setfillpattern/2 Графика
- Setfillstyle/2 Графика
- Setgraphmode/1 Графика
- Setgraphbufsize/1 Графика
- Setlinestyle/3 Графика
- Setpalette/2 Графика
- Setrgbcolor/4 Графика
- Settextjustify/2 Графика
- Settextstyle/3 Графика
- Setusercharsize/4 Графика
- Setviewport/5 Графика
- Setvisualpage/1 Графика
- Setwritemode/1 Графика
- Term_delete/3 Внешняя База Данных
- Term_replace/4 Внешняя База Данных
- Textheight/2 Графика
- Textwidth/2 Графика
- Часть 3. Приложения приложение а. Введение вdos
- Что такое dos
- Как загрузить программу?
- Каталоги
- Подкаталоги
- Avtoexec.Bat-файл
- Команда path
- Смена каталогов
- Приложениеb. Интерактивный редактор турбо пролога
- Быстрый вход, быстрый выход
- Служебная строка окна редактора
- Основные команды редактора
- Команды Редактора, совпадающие с командами WordStar Основные команды работы с курсором
- Команды быстрого движения курсора
- Команды вставки и удаления
- Команды работы с блоками
- Остальные команды редактора
- Старые команды
- Поиск и замена
- Редактор Турбо Пролога по сравнению с WordStar
- Корректировка файла на диске.
- Приложение c. Сообщения об ошибках
- Приложение d. Различия между версиями 1.1 и 2.0
- Файл определения проекта
- Новые ограничения по именам
- Новые предопределенные домены
- Контроль состава параметров шаблона (flow pattern)
- Поддержка старых командных клавиш редактора
- Ошибочные ситуации в стандартных предикатах
- Расширение Турбо Пролога 2.0
- Системные расширения
- Приложениеe. Словарь специальных терминов
- Приложение f. Географическая база данных (Geobase)
- Использование Geobase
- Системы с 2-мя флоппи-дисковыми устройствами
- Компиляция Geobase
- Создание автономной программы
- Главное меню Geobase
- Справка
- Команды dos
- Редактор
- Запросы к базе данных
- Просмотр языка
- Корректировка языка
- Принципы Geobase
- Использование принципа Geobase
- Создание вашей базы данных
- Преобразование Geobase
- Предикат "ent"
- Предикат "db"
- Трансляция запросов на естественном языке
- Внутренние имена объектов
- Внутренние имена связей
- Определение структуры предложений
- База данных языка
- Грамматический разбор с помощью разделения списков
- Заключение
- Приложение g. Анализатор предложений на турбо прологе
- Использование анализатора предложений
- Помощь пользователя
- Операционная система
- Редактирование базы данных
- Загрузка базы данных из файла
- Сохранение базы данных
- Анализ предложений
- «Показать/изменить словарь»
- Приложениеh.Geni: оболочка экспертной системы
- Использование geni
- Запросы geni
- Просмотр знаний
- Корректировка базы знаний
- Сохранение базы знаний
- Создание новой базы знаний
- Чистка текущей базы знаний
- Проектирование новой базы знаний
- Приложение I. Tlib: библиотека турбо
- Компоненты командной строки tlib
- Компонент «описание»
- Список операций
- Имена файла и модуля
- Операции tlib
- Создание библиотеки
- Использование файла ответа
- Расширенные возможности: опция /с
- Примеры
- Приложение j. Tlink: компоновщик турбо
- Активизация tlink
- Использование ответных файлов
- Компоновка модулей Турбо Пролога и Турбо Си.
- Модуль инициализации
- Библиотеки
- Опции tlink
- Опция /c
- Опция /d
- Опция /I
- Опция /l
- Опции /m, /s, /X
- Опция /m
- Опция /s
- Опция /X
- Опция /n
- Ограничения
- Сообщения об ошибках
- Предупреждения
- Нефатальные ошибки
- Фатальные ошибки
- Приложение k. Метапрограммирование Введение
- Пролог/Турбо: развитие и философские установки
- Конструкторские решения в Турбо Прологе
- Чем Турбо зарядило Турбо Пролог
- Интерпретатор правил с обратной цепочкой рассуждений
- Термы (горючее для интерпретатора правил)
- Статические термы: область sTerm (статических термов)
- Интерпретирование области термов.
- Что такое интерпретатор?
- Интерпретация правил в Прологе
- Использование sTerm и aTerm для моделирования интерпретатора правил
- Переменные и среда
- Процесс унификации
- Унификация статических и действительных термов
- Интерпретация тела правила
- Выполнение выполняемых термов: предикат call.
- Встроенные предикаты
- Сканнер и транслятор
- Операторы традиционного Пролога
- Использование операторов в Турбо Прологе
- Интерпретатор Пролога
- Реализация трассировки
- Теперь объединим все вместе
- Расширения экспертной системы
- Цепочка с прямым порядком рассуждений
- Стандартные предикаты, реализованные в pie
- Заключение