Алгоритм работы программы "зобъект

Процедура "зобъект" имеет на два аргумента больше, чем процедура "объект". Через четвертый аргумент процедуры "зобъект" возвращается результат процесса грамматического разбора. Например, если будет обнаружен объект "па" (предикат + аргумент), то процедура разбора возвратит структуру, состоящую из предиката, аргумента и значения:

(p,a,v)

Список таких структур строится нетерминалами "па список" и "уточ­нение". Построенные списки объединяются в один список в нетерминале "предложение". Список структур, вырабатываемый нетерминалом "пред­ложение", содержит все аргументы, к которым нужно обратиться в итого­вом Пролог-запросе. Пятый аргумент процедуры "зобъект" используется только в правиле "предложение"; он является списком всех структур, которые требуется вывести на печать после выполнения Пролог-запроса.

Выходные данные процедуры грамматического разбора

Можно проверить работу процедуры грамматического разбора, проана­лизировав результаты, которые вырабатывает тестовый запрос.

| ?- зобъект (

[выдать, служащий, имя, и, отдел, менеджер, где,

код, служащий, является, отдел, код],

[ ], предложение, Tlist, Printlist).

Tlist= [ т (служащий, имя, _613),

т (отдел, менеджер, _642),

т (служащий, код, _668),

т (отдел, код, _668) ]

Printlist= [ т (служащий, имя, _613),

т (отдел, менеджер, _642) ]

Заметьте, что в списке «Printlist» содержатся только те структуры, к которым имеется обращение из "па_список" после команды "выдать". Поэтому список «Printlist» является подмножеством списка «Tlist». Список «Tlist» содержит все объекты "па", упомянутые в запросе. В результате действия правила "уточнение" одна и та же переменная _668 появляется и в структуре, несущей информацию о служащем, и в структу­ре со сведениями об отделе.

Процедура "построить_псписки"

Следующей задачей будет объединение каждого множества струк­тур "т" с одинаковыми именами предикатов в список, состоящий из имени предиката и пар имя/значение аргумента. Каждая пара имя/значение аргу­мента обозначается идентификатором « AVpair » и записывается в виде структуры «п(Имя, Значение)». Итоговый список таких структур носит название «Plist».

Пусть, к примеру, в списке «Tlist», построенном процедурой грамма­тического разбора/содержатся две структуры "т":

[т(служащий,имя,_1), т (служащий,код,_2)]

Тогда будет сгенерирован такой список « Plist »:

[служащий, п (имя,„I), п (код,_2) ]

Процедура "построить_псписки" берет в качестве входного аргумента список «Tlist», выработанный процедурой "зобъект", а затем генерирует список «Plists», каждым элементом которого является список «Plist». Каждому списку «Plist» соответствует отдельный предикат, встречающийся в списке «Tlist » . Процедура "построить_псписки" отсле­живает предикаты, которые она уже обработала, помещая их во второй аргумент, обозначаемый идентификатором «Donelist». Когда процедура построить_псписки" встречает необработанный предикат, она вызывает процедуру "построить_парыАЗ" для построения структур "п" по всем структурам "т" из списка «Tlist», содержащим этот предикат. Вызов Процедуры "унифицировать_перем" преобразует получившийся список структур "п" таким образом, что переменные, несущие информацию о зна­чениях аргументов, унифицируются в тех случаях, когда совпадают имена аргументов. Например, если в список структур « AVpairsI » (входная информация для процедуры "унифицировать_перем") входят такие две структуры "п":

[п (имя,_50),. . . п (имя. —65)],

то в списке структур «AVpairs2 » (выходная информация процедуры "унифицировать_перем") будут унифицированными такие неконкрети­зированные переменные:

[п(имя. -50), . . . п(имя,„50)].

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

% имена переменных:

% Р = имя предиката

% А = имя аргумента

% V = значение аргумента (неконкретизированная

% переменная)

%Tlist = [t(p,a,v),t(p,a,v),...]

% AVpairs = [п (А, V), п (А, V),. . . ]

% Plist = [P,n(A,V),n(A,V)....]

% Plists = список, каждый элемент которого - это список Plist

% построить_псписки:

% преобразовать список структур т (Р, А, V) в

% Р + список структур п (А, V).

% + + _

построить_псписки ([],_, [ ]).

% пропустить структуру т(Р, А, V), , если значение Р содержится в

% списке Donelist:

построить_псписки ([т(Р, А, V); Tlist], Donelist, Plists) :-

элемент (Р, Donelist),

!, построить-псписки (Tlist, Donelist, Plists).

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

построить-псписки ([т (Р, А, V); Tlist], Donelist,

[[Р| AVpairs2 ] | Plists]) :-

построить-парыАЗ (Р, [t(p,a,v); Tlist] ,AVpairsl),

унифицировать_перем (AVpairsI, AVpairs2),

% добавить Р в список Donelist:

!, построить-псписки (Tlist, [P ; Donelist], Plists).

% построить_парыАЗ:

% построить список структур п (А, V) для одного предиката.

% + + -

построить-парыАЗ (_, [ ], [ ]).

%Р (первый аргумент) согласуется с Р, входящим в структуру

%т(Р, А, V), поэтому добавить структуру п(А, V) в список AVpairs:

построить_парыАЗ (Р, [т(Р, А, V) ; Tlist],

[п (A, V); AVpairs]) :-

!, построить_парыАЗ (Р, Tlist, AVpairs).

% Р 1 не согласуется с Р2, поэтому продвинуться вперед:

построить_парыАЗ (Р1, [т(Р2, А, V) ; Tlist], AVpairs) :-

!, построить-парыАЗ (Р1, Tlist, AVpairs).

% + _

унифицировать-перем ([ ], [ ]).

унифицировать_перем ([п(А, V) | In-AVpairs],

[п(А, V) ; Out-AVpairs]) :-

% "элемент" унифицирует V с V, когда А согласуется с А:

элемент (п(А, V), In_AVpairs),

!, унифицировать_перем (In_AVpairs, Out_AVpairs).

унифицировать-перем ([п(А, V); In_AVpairs],

[п(А, V) ; Out-AVpairs]) :-

% если подцель "элемент" потерпит неудачу, перейти к

% следующей паре:

!, унифицировать-перем (hi-AVpairs, Out—A Vpairs).

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