- •Введение
- •1. Составление программ
- •1.1. Основные определения
- •1.2. Декларации в программах
- •1.3. Объявление предикатов и типов их аргументов
- •1.4. Другие разделы программы
- •Упражнения
- •2. Механизмы доказательства правил
- •2.1. Сопоставление с откатом
- •2.2. Рекурсия
- •Упражнения
- •3.Операции в Visual Prolog. Ввод-вывод
- •3.1. Операции
- •3.2. Предикаты ввода-вывода
- •4. Управление процессом доказательства правил
- •4.1. Искусственный откат
- •4.2. Отсечение
- •4.3. Повтор, определяемый пользователем
- •5. Списки
- •5.1. Процедуры обработки списков
- •5.2. Организация стеков и очередей
- •6. Внутренняя база фактов
- •7. Иерархическая организация данных
- •8. Работа с деревьями и графами
- •8.1. Двоичные деревья
- •8.2. Графы
- •9. Работа с именами и строками
- •Заключение
- •Библиографический список
- •Оглавление
4.3. Повтор, определяемый пользователем
Вид правила повтора, определяемого пользователем, следующий:
repeat.
repeat:- repeat.
Таким образом, repeat – это рекурсивное правило, которое всегда успешно. С помощью repeat можно организовать бесконечное повторение процесса доказательства какого-либо правила или его части: если какая-либо подцель правила справа от repeat не доказывается и возникает откат, то благодаря repeat процесс доказательства повторяется.
Для примера приведем программу «эхо», которая дублирует на экране текст, вводимый с клавиатуры. Работа программы должна завершиться после ввода строки stop:
PREDICATES
nondeterm repeat
nondeterm run
анализ(string)
write_text
CLAUSES
repeat.
repeat :- repeat.
write_text:- nl, write("Введитетекст,яего
повторю"),nl,write("Для завершения работы
введитесловоstop"), nl.
run :- repeat, readln(Текст), write(Текст),
nl, анализ(Текст).
analiz("stop"):-nl, write("Сеанс окончен. До
свидания").
GOAL
write_text, run.
Если вводимый текст не является словом stop, то подцель «анализ» неуспешна и происходит откат, причем системные предикаты readln и write не пересогласовываются. В отсутствие repeat выполнение программы на первом введенном тексте закончилось бы, а так обеспечивается повторение выполнения предикатов справа от него до тех пор, пока цель «анализ» не станет успешной.
5. Списки
Список – последовательность, составленная из произвольного числа элементов, разделенных запятыми, и ограниченная квадратными скобками. Элементами списка могут быть простые и составные термы, переменные, списки (последние называются вложенными). Списки широко используются для представления различных объектов: графов, деревьев, карт городов, грамматик и т.п.
Примеры списков.
[a, b, c], [“студенты”, “программируют”, “на”, “Прологе”], [X, Y], студент ( [ иванов, а104 ]).
Пустой список обозначается [].
При работе со списками используется расщепление списка на голову (Head) и хвост (Tail). В Прологе введена специальная форма для записи такой пары: [ H | T ] . Символу ‘| ‘ может предшествовать один или несколько элементов, разделенных запятыми, которые соответствуют первым элементам списка. После символа ‘|’ должен быть записан только один элемент, который соответствует хвосту и записывается как переменная. Хвост списка рассматривается как список.
В соответствие с введенными терминами список определяется как рекурсивная структура данных, которая либо пуста, либо состоит из головы и хвоста. Хвост всегда список, а голова – любой объект, в частности, список.
Два списка могут сопоставляться неявно в процессе сопоставления с откатом, или явно при использовании предиката «=». Примеры успешных сопоставлений следующие:
1.[X,Y,Z] и [лиса, волк, заяц].
X = лиса
Y = волк
Z = заяц
2.[X | Y] и [лиса, волк, заяц].
X = лиса
Y = [волк, заяц]
3.[X | Y] и [лиса].
X = лиса
Y = [ ]
Неуспешное сопоставление: [X | Y,Z] и [лиса, волк, заяц].
В программах VIP для списка в разделе доменов указывается тип элементов списка и записывается символ «*», который говорит о том, что в списке присутствует ноль или более элементов. Например, описание списка из целых чисел выглядит так:
DOMAINS
integerlist = integer*
Объекты в списке в VIP могут быть любыми, но одного и того же типа, в том числе и другими списками. Например, двухуровневый список [[1,2,3],[7,10],[20]] можно описать так:
object=obj*
obj=integer*
В традиционном Прологе типы элементов одного списка могут быть различными. В VIP cуществуют специальные приемы для объединения в список элементов с разными доменами (см.разд. 7.)
