Использование процедуры "d_to_m"

Подадим на вход процедуры "d_to_m" простой факт, записанный на DEC-10 Прологе, и посмотрим, что получится на выходе процедуры. Факт:

отец(филип,чарльз).

можно представить в виде списка слов:

[ отец,' (', филип, чарльз, ')','.']

Этот список можно подвергнуть грамматическому разбору:

! ?- d_to_m (фраза,

[ отец,' (', филип, чарльз,')',' .' ],

[],МР,[]).

MP=['('.'(',отец,филип, чарльз,')',')']

От формы записи в виде списка легко можно перейти к обычной форме записи факта в микро-Прологе:

( (отец филип чарльз) )

С другой стороны, правило, записанное на микро-Прологе:

((элемент X(Y | Z)) (элемент X Z))

можно разложить на следующие элементы:

['(','(',элемент, X,'(\Y,'! ',Z,')',

')','(', элемент, X, Z,')' ’)']

Затем это правило можно подвергнуть грамматическому разбору:

! ? - d_to_m(фраза, DEC,[ ],

['(','(',элемент,Х,'(',Y,

'|',Z,')',')','(',элемент,

X,Z,')',')' ]),

[]).

DEC=[элемент.' (', X,',',[','Y'.' |',

'Z',' ]',' )' ,' :- , элемент,' (',

X,',',Z,')','.']

От формы записи в виде списка можно перейти к следующей форме:

элемент (X. [Y| Z]) :- элемент (X, Z).

Улучшение интерфейса с пользователем

Одно из затруднений, связанных с использованием приведенных выше запросов, заключается в том, что для этих запросов требуется кропотли­вый перевод языковых выражений в списки, состоящие из элементов. Ранее мы уже пользовались программой, которая автоматизировала эту утомительную задачу. Это был лексический анализатор "читатьпредлож", описанный в начале главы. Однако для того, чтобы стало возможным применение процедуры "читатьпредлож" для ввода Пролог - текстов, в базу данных "пунктуация" необходимо добавить дополнительные лексико­графические символы, такие как , и ; .

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

печать_выраж ( [ ]) :- n1.

печать_выраж (X ; Y]) :-

write(X), write(' '), печать_выраж(Y).

Теперь можно употребить процедуру "d_to_m" в нижеследующем состав­ном запросе:

! ?- write (' введите фразу DEC-10 Пролога:'),

nl,

читатьпредлож (DЕС),

d_to_m (фраза, DEC, [ ], МР, [ ] ),

печать_выраж (МР),

fail.

введите фразу DEC-10 Пролога:

отец(филип, чарльз).

( (отец филип чарльз) )

нет

Подцель «fail», стоящая в конце запроса, подавляет печать значений переменных.

Ограничения процедуры "d_to_m"

Приведенная версия процедуры "d_to_m" не может обрабатывать следующие синтаксические особенности DEC-10 Пролога:

1) структуры;

2) префиксные, инфиксные и постфиксные операции;

3) большую часть в строенных предикатов.

Это как раз те особенности, по которым отсутствует структурное сходст­во между рассматриваемыми версиями языка Пролог. Поэтому для рас­ширения процедуры "d_to_m" с тем, чтобы она смогла работать с этими языковыми средствами, потребуется добавить правила, которые будут применяться только при конвертировании в одну сторону. Например, вследствие того, что в микро-Прологе отсутствуют структуры общего назначения, имеющиеся в DEC-10 Прологе( в микро-Прологе есть целостные информационные элементы (tuples), но они не могут быть вложенными таким же образом, как структуры.), программист, пишущий программы на микро-Прологе, пользуется списками во многих ситуациях, в которых программист, работающий на DEC-10 Прологе, употребил бы структуру. Поэтому если бы программа "d_to_m" применялась для кон­вертирования с DEC-10 Пролога на микро-Пролог, то она должна была бы преобразовывать каждую структуру DEC-10 Пролога в список микро-Пролога. Но в этом случае при переводе программ с микро-Пролога на DEC-10 Пролог возникла бы неоднозначность: если программа-конвертер [встретит в микро - прологовском тексте список, то будет неясно во что его следует преобразовывать - в список DEC-10 Пролога или же в структу­ру DEC-10? Если допустить, чтобы правила, устанавливающие взаимное соответствие между структурой DEC-10 Пролога и списком микро - Пролога, были бы полностью двунаправленными, то в программе "d_to_m" Нужно было бы иметь два способа грамматического разбора каждого спискa микро-Пролога.

Наиболее надежное, хотя и требующее кропотливой работы решение этой задачи состоит в том, что заранее объявлять имена и количества аргу­ментов всех структур DEC-10, используемых в программе. Тогда если при переводе с микро-Пролога на DEC-10 Пролог программа "d_to_m" (Встретит список микро-Пролога, то она обратится к базе данных, состоящей из структур DEC-10, чтобы выяснить, во что нужно преобразовать этот конкретный список - в DEC-10 структуру или же в список DEC-10. Приведем текст расширения программы "d_to_m", которое реализует на практике этот метод работы со структурами.

% база данных, состоящая из структур DEC-10:

% Имя Количество аргументов

структура (клиент, 3).

структура (маршрут, 3).

% преобразовать список микро-Пролога в структуру DEC-10:

% структура _или_список -—> атом ( арг_ты ) // ( атом арг_ты )

d_to_m (структура_или_список, Id, Od, Im, Om) :—

найти__допустимую_структуру (Id, Od, Im, Om).

% _ _

найти_опустимую_структуру ([ Имя,' (' | Rd], Od,

% + _

['(',Имя ! Rm],Om) :-

var (Rd), % направление: с МР на DEC

atom (Имя),

% проверить, является ли переменная Имя именем структуры

% DEC-10:

структура (Имя, Кол_во_арг),

% взять арг_ты из начала списка Rm:

d_to_m (арг_ты, Rd, [')' j Od], Rm,

[')','Оm]),

% проверить правильность количества аргументов:

length (Rm, Rm длина),

length ([')' \ От], От длина),

Кол_во_арг is Оmдлина — Rmдлина.

% преобразовать структуру DEC-10 в список микро-Пролога:

% структура_или_список -->атом (арг_ты) // (атом арг_ты)

d_to_m (структура _или_список, [Имя,' (' | Rd], Od,

['(',Имя |Rm],Оm) :-

var (Rm), % направление: с DEC на МР

atоm (Имя),

d_to_m (арг_ты, Rd [')' | Od], Rm, [')' | Оm] ).

% преобразовать список микро-Пролога в список DEC-10 или

% наоборот:

% структура_или_список ~—> список // список

d_to_m (структура _или_список, Id, Od, Im, От) :—

not (найти__допустимую_структуру (Id, Od, Im, Оm)),

d_to_m (список, Id, Od, Im, Оm).

% аргумент ~->перем ; атом; структура _или_список

d to_m (аргумент. Id, Od, Im, Om) :-

d_to_m (перем, Id, Od, Im, Om)

;

d_to_m (атом. Id, Od, Im, Om)

;

d_to_m (структура_или_список. Id, Od, Im, Om).

Нижеследующие запросы иллюстрируют работу данного расширения процедуры "d_to_m".

| ?— repeat,

write (' введите структуру или список микро-'),

write (' Пролога:'), n1,

читатьпредлож (МР),

oдин_paз(d_to_m (структура _или_список, DEC, [ ], МР, [ ]))

пeчaть_выpaж(DEC), nl,

fail.

введите структуру или список микро-Пролога:

(один два три)

[ один, два, три ]

введите структуру или список микро-Пролога:

(клиент смит сокращенная неделя)

клиент (смит, сокращенная, неделя)

введите структуру или список микро-Пролога:

(маршрут нью-йорк бостон)

[ маршрут, нью_йорк, бостон ]

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

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

Соседние файлы в папке Гл.0,1,2,3,4,5,Предисловие