- •Глава 4
- •Введение
- •Три точки зрения на Пролог-программу
- •4. 1. Реляционный подход
- •Изображение отношений
- •Ограничения, обеспечивающие целостность, которые накладываются при записи отношений в программу
- •Ограничения, обеспечивающие целостность, накладываемые при выборке фраз
- •Реализация свойств отношений
- •Нерефлексивность
- •Симметричное и транзитивное отношение
- •Первая попытка
- •Вторая попытка
- •Запоминание списка посещенных мест
- •4. 2. Взгляд на программу с точки зрения потока данных Переход от выходного потока данных к программе
- •Упорядоченные множества ответов
- •Генерирование бесконечного множества
- •Экологический процесс
- •Версия программы, в которой применяется поиск с возвратом
- •Рекурсивная версия программы
- •Планирование производственных операций
- •Сильные и слабые стороны подхода к программе с позиций потока данных
- •4.3. Бихевиористический подход Приведенные ранее примеры, в которых проявился бихевиористический подход
- •Ограничение сферы действия эффектов поведения
- •Программа "найти_или_спросить"
- •Оценка бихевиористического подхода
- •Библиографические заметки
- •Упражнения
4. 2. Взгляд на программу с точки зрения потока данных Переход от выходного потока данных к программе
В соответствии с подходом к программе с позиций потока данных, множество ответов (или выходной поток данных) программы вырабатывается в соответствии с внутренней структурой программы в результате выполнения запроса. Если множество ответов будет известно заранее, то составление программы сведется к реализации такой ее внутренней структуры, которая обеспечит выдачу этих ответов. Назначение программы состоит именно в генерировании заданного множества ответов, а то, каким образом это достигается, не имеет значения. Программа может вырабатывать множество ответов либо в качестве реакции на входной поток данных, поступающих во время выполнения программы (т. е. представленный как аргумент запроса), либо при обращении к другим фразам текущей программы. После того, как программа, генерирующая заданное множество ответов, будет написана, ее можно использовать в качестве модуля при составлении других программ.
В гл. 3 рассматривались два основных семейства алгоритмов, используемых в Пролог-программах, - алгоритмы поиска с возвратом и рекурсивные алгоритмы. Для многих типов задач эти виды алгоритмов одинаково эффективны. В оставшейся части данного раздела продемонстрируем реализацию подхода к программе с позиций потока данных с примерами употребления обоих видов алгоритмов.
Множество ответов программы - это множество значений, вырабатываемых программой при определенных условиях, которые специфицируются запросом и множеством всех фраз, содержащихся в текущей программе. Рассмотрим тривиальный пример. Пусть спецификация множества ответов заключается в следующем: если номер отдела равен 100, то программа должна выдавать имена служащих - Брайен и Ральф. Простейшая программа, удовлетворяющая этой спецификации, состоит всего из двух фраз:
служащий (брайен, 100).
служащий (ральф, 100).
Запрос:
|? - служащий (Имя, 100).
приведет к выдаче значений:
Имя = брайен;
Имя = ральф
Упорядоченные множества ответов
Важной характеристикой множества ответов является то, имеет ли значение порядок ответов. Для программы "служащий", приведенной выше, порядок следования ответов не имеет никакого значения. Теперь рассмотрим программу, множеством ответов которой является упорядоченное множество четырехбитовых двоичных чисел - от 0000 до 1111.
Генератор двоичных чисел
Тогда запрос:
|? - число (А, В, С, D). % (1)
должен выдавать при помощи конкретизированных переменных цифры двоичного числа. Каждый раз, когда пользователь вводит символ;, запрос должен вырабатывать следующее по порядку двоичное число. Первым ответом должно быть:
А=0
В=0
С=0
D=0;
Следующий ответ должен быть таким:
А=0
В=0
C=0
D=1;
и т. д. Простейший способ генерирования такого множества ответов заключается в определении упорядоченного множества фактов "число":
число (0, 0, 0, 0).
число (0, 0, 0, 1).
число (0, 0, 1, 0).
число (0, 0, 1, 1).
число (0, 1, 0, 0).
…
число (1, 1, 1, 1).
Запрос (1), приведенный выше, будет каждый раз, возвращаясь назад, вырабатывать нужные ответы. Однако можно добиться точно таких же результатов и при помощи гораздо более компактной процедуры.
Множество ответов здесь эквивалентно некоторому шаблону, в котором чередуются нули и единицы, поэтому начнем с написания простой процедуры, которая выдает попеременно то нуль, то единицу:
цифра (0).
цифра (1).
Затем нужно составить правило "двоичн_число", которое четыре раза вызывает процедуру "цифра":
двоичн_число (А, В, С, D):—
цифра (А), цифра (В), цифра (С), цифра (D).
Вы самостоятельно сможете понять, какие результаты принесет запрос к этому правилу. Это правило будет выполнять точно такие же действия, как и четыре вложенных цикла "пока" ("while") в процедурном языке:
А=0
while А < = 1 begin
В=0
while В < = 1 begin
С=0
while С <= 1 begin
D=0
while D < = 1 begin
print A B C D
D=D+ 1
end
C=C+ 1
end
B=B+ 1
end
A=A+ 1
end
В множестве ответов насчитывается ровно 16 элементов. Приведенное правило "двоичн_число" потерпит неудачу, если пользователь запросит еще один ответ, когда переменные А, В, С и D конкретизированы значением 1.