- •Введение
- •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. Работа с именами и строками
- •Заключение
- •Библиографический список
- •Оглавление
7. Иерархическая организация данных
В отличие от реляционных баз данных Пролог позволяет организовывать иерархическую структуру данных и делать к ней запросы без формирования нескольких связанных таблиц.
В основе иерархической организации данных лежат структуры. Структуры удобно изображать с помощью деревьев. На рис. 2 приведено графическое изображение трехуровневой структуры
«студент (номер_группы, фио(имя, фамилия), адрес(улица, дом, квартира))».
При анализе структур используют понятие функтора – названия узла дерева. Корень дерева называется главным функтором. В нашем случае главный функтор – «студент».
Структура рассматривается как целостный объект и может участвовать в операции сопоставления по общим правилам, изложенным в подразд. 2.1 Примеры сопоставления двухуровневой структуры «расстояние (точка(значение, значение), точка(значение, значение))» приведены в табл.1. Здесь же добавим, что структура может целиком конкретизировать переменную при выполнении предиката «=».
С= студент(а_98, фио(“Иван”, “Петров”),
адрес(“Александровская”,2, 23)).
Для описания структур в VIP используются составные домены. В составном домене тип аргумента структуры объявляется как структура.
В нашей структуре «студент» выберем в качестве доменов номер_группы, фио_студента, адрес _студента. Предикат будет выглядеть следующим образом:
студент (номер_группы, фио_студента, адрес_студента).
Домены опишем так, как они приведены в исходной структуре.
фио_студента=фио(имя, фамилия).
адрес_студента=адрес(улица, дом, квартира).
Имя, фамилию, улицу определим как string, дом и квартиру как integer, номер_группы как symbol.

Рис. 2
DOMAINS
фио_студента = фио(имя, фамилия)
адрес_студента=адрес(улица, дом, квартира)
номер_группы=symbol
имя, фамилия, улица =string
дом, квартира=integer
PREDICATES
студент (номер_группы, фио_студента, адрес_студента)
run
CLAUSES
студент(а_98, фио(“Иван”, “Петров”), адрес(“Александровская”,2, 23)).
студент(а_97, фио(“Владимир”, “Сидоров”), адрес(“Петровская”,16, 38)).
студент(а_98, фио(“Петр”, “Демов”), адрес(“Александровская ”,26, 2)).
run:-студент( X, Y, Z), write (X,Y,Z), fail.
GOAL
run.
При успехе доказательства переменные конкретизируются в соответствии с объявлением доменов следующими значениями:
X=а_98 Y = фио(“Иван”, “Петров”) Z= адрес(“Свердлова”,16,
223))
X=а_97 Y= фио(“Владимир”, “Сидоров” Y= ад
рес(“Петровская”,16, 38))
X=а_98, Y= фио(“Петр”, “Демов”)
Z=адрес(“Александровская ”,26, 2)
Использованием анонимных переменных в запросах позволяет существенно упростить их форму. Сформируем следующий запрос: кто из студентов живет на ул. Александровской?
run:-студент( _, Y, адрес(“Александровская”,_, _), write (X,Y), fail.
Y = фио(“Иван”, “Петров”)
Y= фио(“Петр”, “Демов”)
Структура составного домена может быть достаточно сложной.
Для составных доменов в Прологе имеется возможность формирования нескольких вариантов объявлений, которые перечисляются в разделе доменов через «;». Такой способ объявления доменов называется множественным или альтернативным.
К примеру, создадим БЗ для фактов следующего вида:
исследователь(имя, научные_труды).
Под научными трудами обычно понимают статьи или монографии. Для монографии будем указывать только название и год издания, для статьи еще и название журнала. Домен «научные_труды» получается составным с двумя вариантами описаний.
DOMAINS
научные_труды= монография(название, год);
статья(название, журнал, год)
название, журнал=string
год=integer
имя=string
PREDICATES
исследователь(имя, научные_труды)
CLAUSES
исследователь(“Иванов П.И.”, монография("Животные в лесах Амазонки" , 2001)).
исследователь(“Иванов П.И.”, статья (“Влияние повышенной влажности на развитие живых организмов" , “Природа”, 2004)).
исследователь(“Петров В.Н.”, статья ("Развитие микроорганизмов в щелочной среде", “Биология”, 2008)).
GOAL
исследователь (Иванов,Y),fail.
Y= монография("Животные в лесах Амазонки" , 2001))
Y= статья (“Влияние повышенной влажности на развитие живых организмов" , “Природа”, 2001)).
Множественные домены используются для представления в VIP списков, элементы которых принадлежат к разным типам. Предположим, что необходимо в программе использовать список
[ 2, 9, “ книга”, ‘a’, 123, [1,2,3]] ,
( В традиционном Прологе работа с такими списками затруднений не вызывает.)
Тогда в разделе доменов нужно сделать следующие объявления:
элемент = i(integer); c(char); s(string)
list=элемент*
элемент=l(list)
В соответствии с ними список в программе будет иметь вид
[i(2), i(9), s(“книга”), c(‘a’), i(123), l([i(1), i(2), i(3)])].
