На этом шаге мы рассмотрим описание доменов.
Как в любом другом языке программирования, в Прологе все используемые конструкции должны быть предварительно описаны. Поэтому в описании предиката мы должны указать типы его аргументов.
В Прологе имеется 6 встроенных типов доменов, решающих эту задачу. Кроме того, существует возможность создания новых типов доменов на базе стандартных.
Основные стандартные домены перечислены в таблице 1.
Тип данных | Ключевое слово | Диапазон значений | Примеры использования |
---|---|---|---|
Символы | char | Все возможные символы | a', 'b', '#', 'B', '\13','%' |
Целые числа | integer | От -32768 до 32767 | -63, 23, 2349, 32763 |
Действительные числа | real | От +1Е-307 до +1Е308 | 42769, 8324, 360, 093, 1.25Е23, 5.15Е-9 |
Строки | string | Последовательность символов (не более 250) | "today", "123", "пример строки" |
Символьная константа | symbol |
|
"телефонный номер", alfa_beta_gamma, "Alfa_beta_gamma", Сидоров_П_П |
Файлы | file | Допустимое в DOS имя файла. При операциях с файлами связывается с конкретными файлами или устройствами. | mail.txt, BIRDS.DBA |
Помимо использования стандартных типов доменов в Прологе можно создавать свои типы доменов в разделе domains. Перечислим основные способы создания новых доменов.
<новое имя домена> = <стандартное имя домена>.
Этот формат служит для объявления нового имени домена, состоящего из элементов (доменов) стандартных типов, к которым относятся типы, перечисленные в таблице 1. Этот способ применяется для объявления типов объектов, которые подобны синтаксически, но отличаются семантически (по смыслу), и поэтому не должны в программе смешиваться друг с другом. Отнесение их к различным, определенным программистом типам, позволяет компилятору осуществлять тщательный контроль их использования в программе.
. . . . . . . domains name = string predicates men (name) woman (name) brother (name,name) . . . . . . .
. . . . . . . predicates men (string) woman (string) brother (string, string) . . . . . . .
Понятно, что в первом случае, глядя на описания предикатов, ясно, что в качестве аргументов предикатов нужно использовать имена людей. При использовании второй формы описания предикатов ничего конкретного сказать нельзя. Таким образом, использование альтернативных имен доменов делает программу более понятной.
<домен типа "список"> = <тип элементов списка>*.
Символ "*" (звездочка) "говорит" о том, что создаваемый домен является списком. Тип элементов списка может относиться как к стандартному типу, так и к доменам, определенным программистом. Например:
list_int = integer* /*Домен типа списка целых чисел.*/ list_char = char* /*Домен типа списка символов.*/
Более детально мы рассмотрим описание доменов типа "список" в соответствующем разделе.
<структура> = <функтор1> (<домен11>,<домен12>, ...,<домен1N>); <функтор2> (<домен21>,<домен22>, ...,<домен2N>)
Объявление структуры (домена, состоящего из сложных и перекрывающихся объектов) состоит из имени структуры - функтора и доменов всех используемых компонент и подкомпонент данной структуры. Например, можно объявить домен "владелец" так:
владелец = имеет(фамилия,книга)
имеет(Иванов,книга(Стругацкие,"Жук в муравейнике"))
Правая часть объявления структуры может содержать описание альтернативных вариантов, разделенных служебным словом or или знаком ";". Каждая альтернатива должна содержать уникальный функтор и список действительно используемых доменов. Например, объявление:
водитель=имеет(имя,автомобиль);документы(имя, автомобиль)
/* Программа Б и б л и о т е к а */ /* Назначение. Демонстрация одноуровневого составного объекта. */ domains personal_library = book(title,author,publisher,year) /* персональная библиотека = книга(название,автор, издательство,год издания) */ collector,title,author,publisher = symbol year = integer predicates collection(collector,personal_library) /* коллекция (имя коллекционера, библиотека) */ clauses collection("В.В.Иванов",book("Программирование на языке ПРОЛОГ для искусственного интеллекта","Братко И.", "Мир",1990)). collection("В.В.Иванов",book("Использование Турбо_Пролога", "Ин Ц., Соломон Д","Мир",1993)). collection("С.С.Сидоров",book("Реляционный язык Пролог и его применение", "Малпас Дж.","Наука",1990)). collection("С.С.Сидоров",book("Программирование экспертных систем на Турбо-Прологе", "Марселиус Д.","Финансы и статистика", 1994)). collection("П.П.Петров",book("Искусство программирования на языке Пролог", "Стерлинг Р., Шапиро Э.","Мир",1990)). collection("П.П.Петров",book("Турбо-Пролог в сжатом изложении", "Янсон А.","Мир",1991)). /* К о н е ц программы. */
personal_library=book(title,author,publisher,year) collector,title,author,publisher=symbol year=integer
Использование доменной структуры упрощает структуру предиката. Если не использовать конструкцию доменной структуры, то программа требовала бы такого описания предиката collection:
collection(collector,title,author,publisher,year)
В этом описании 4 последних объекта обозначают атрибуты книги. Правило, которое оперирует с персональными библиотеками рассматривало бы эти 4 последних объекта как независимые сущности, что сделало бы код программы более сложным.
Данная программа использует внешнюю цель. Для того чтобы узнать, какие книги принадлежат В.В.Иванову, необходимо ввести такое целевое утверждение:
collection("В.В.Иванов",B).
Объект "В.В.Иванов" является частным значением из домена collector, а B - свободной переменной. Цель заключается в отыскании всех книг, принадлежащих В.В.Иванову.
Предположим теперь, что требуется узнать имена владельцев и названия книг, напечатанных в 1990 году. Цель для поиска этой информации выглядит следующим образом:
collection(Collector,book(Title,_,_,1990)).
Здесь свободными переменными являются уже Сollector и Title. Подчерки (_) указывают на то, что нас не интересуют объекты с родовыми именами author и publisher. (Подчерк замещает собой анонимную переменную)
file = <имя1>;< имя1>; ...; < имяN> .
Как видно из приведенного формата можно указывать несколько логических имен файлов, но само описание должно быть единственным. Например, объявление:
file = datafile1;datafile2
На следующем шаге мы рассмотрим задание типов аргументов.