Шаг 23.
Основы логического программирования.
Описание доменов

    На этом шаге мы рассмотрим описание доменов.

    Как в любом другом языке программирования, в Прологе все используемые конструкции должны быть предварительно описаны. Поэтому в описании предиката мы должны указать типы его аргументов.

    В Прологе имеется 6 встроенных типов доменов, решающих эту задачу. Кроме того, существует возможность создания новых типов доменов на базе стандартных.

    Основные стандартные домены перечислены в таблице 1.

Таблица 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
  1. Последовательность букв, цифр и подчеркиваний, начинающаяся с маленькой буквы (латинской или русской) или большой русской буквы.
  2. Последовательность любых символов, заключенная в кавычки. Используется тогда, когда имя должно начинаться с большой латинской буквы или содержать пробелы. Длина символьной константы не превышает 250 символов.
"телефонный номер",
alfa_beta_gamma,
"Alfa_beta_gamma",
Сидоров_П_П
Файлы file Допустимое в DOS имя файла. При операциях с файлами связывается с конкретными файлами или устройствами. mail.txt,
BIRDS.DBA

    Помимо использования стандартных типов доменов в Прологе можно создавать свои типы доменов в разделе domains. Перечислим основные способы создания новых доменов.

  1. Создание псевдонимов (альтернативных имен) стандартных доменов. Эта операция осуществляется по следующей схеме:

        <новое имя домена> = <стандартное имя домена>.

        Этот формат служит для объявления нового имени домена, состоящего из элементов (доменов) стандартных типов, к которым относятся типы, перечисленные в таблице 1. Этот способ применяется для объявления типов объектов, которые подобны синтаксически, но отличаются семантически (по смыслу), и поэтому не должны в программе смешиваться друг с другом. Отнесение их к различным, определенным программистом типам, позволяет компилятору осуществлять тщательный контроль их использования в программе.


        Следующий фрагмент программы иллюстрирует использование рассмотренных конструкций:
    .   .   .   .   .   .   .
       domains
           name = string
       predicates
           men (name)
           woman (name)
           brother (name,name)
    .   .   .   .   .   .   .
    
    Этот же фрагмент программы можно было записать так:
    .   .   .   .   .   .   .
       predicates
           men (string)
           woman (string)
           brother (string, string)
    .   .   .   .   .   .   .
    

        Понятно, что в первом случае, глядя на описания предикатов, ясно, что в качестве аргументов предикатов нужно использовать имена людей. При использовании второй формы описания предикатов ничего конкретного сказать нельзя. Таким образом, использование альтернативных имен доменов делает программу более понятной.

  2. Создание домена типа "список". Этот формат применяется при описании предикатов, осуществляющих обработку списков. Общий вид создания такого домена следующий:

        <домен типа "список"> = <тип элементов списка>*.

        Символ "*" (звездочка) "говорит" о том, что создаваемый домен является списком. Тип элементов списка может относиться как к стандартному типу, так и к доменам, определенным программистом. Например:

       list_int = integer* /*Домен типа списка целых чисел.*/
       list_char = char*  /*Домен типа списка символов.*/
    

        Более детально мы рассмотрим описание доменов типа "список" в соответствующем разделе.

  3. Создание домена типа "структура". Чаще всего этот формат применяется при организации баз данных. Его общий вид следующий:
    <структура> = 
              <функтор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. Его описание таково:
       personal_library=book(title,author,publisher,year)
       collector,title,author,publisher=symbol
       year=integer
    
        Предикат, использующий эту структуру, определяется так: collection(collector,personal_library). Описание содержит два имени объектов. Первое имя относится к обычному объекту, второе - к структуре из нескольких объектов.

        Использование доменной структуры упрощает структуру предиката. Если не использовать конструкцию доменной структуры, то программа требовала бы такого описания предиката collection:

       collection(collector,title,author,publisher,year)
    

        В этом описании 4 последних объекта обозначают атрибуты книги. Правило, которое оперирует с персональными библиотеками рассматривало бы эти 4 последних объекта как независимые сущности, что сделало бы код программы более сложным.

        Данная программа использует внешнюю цель. Для того чтобы узнать, какие книги принадлежат В.В.Иванову, необходимо ввести такое целевое утверждение:

      collection("В.В.Иванов",B).
    

        Объект "В.В.Иванов" является частным значением из домена collector, а B - свободной переменной. Цель заключается в отыскании всех книг, принадлежащих В.В.Иванову.

        Предположим теперь, что требуется узнать имена владельцев и названия книг, напечатанных в 1990 году. Цель для поиска этой информации выглядит следующим образом:

       collection(Collector,book(Title,_,_,1990)).
    

        Здесь свободными переменными являются уже Сollector и Title. Подчерки (_) указывают на то, что нас не интересуют объекты с родовыми именами author и publisher. (Подчерк замещает собой анонимную переменную)

  4. Создание домена типа "файл". Этот домен применяется в том случае, когда в программе необходимо ссылаться на файлы с помощью файловых переменных (логических имен файлов). Формат создания такого домена следующий:
      file = <имя1>;< имя1>; ...; < имяN> .
    

        Как видно из приведенного формата можно указывать несколько логических имен файлов, но само описание должно быть единственным. Например, объявление:

       file = datafile1;datafile2
    
    определяет два логических имени (для разных файлов). Существует несколько предопределенных (встроенных в язык) логических имен файлов. К ним относятся логические имена:
    • printer - для устройства печати;
    • screen - для экрана;
    • keyboard - для клавиатуры;
    • com1 - для дополнительного устройства связи.


    Замечание. Количество имен, объявляемых в разделе domains, не должно превышать 250.

    На следующем шаге мы рассмотрим задание типов аргументов.




Предыдущий шаг Содержание Следующий шаг