Скачиваний:
201
Добавлен:
17.06.2016
Размер:
2.69 Mб
Скачать

Упражнение

1. Запишите предикат oddlist, который использует два аргумента. Пер-

вый аргумент - список целых, а второй - это список нечетных чисел,

найденных в первом списке.

2. Запишите предикат real_average, который вычисляет среднее значе-

ние всех элементов списка действительных чисел.

3. Запишите предикат, в котором первый аргумент - это составной спи-

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

все подсписки. Такой предикат известен как flatten, так как он вы-

равнивает список из списков в один список.

Например вызов

flatten([s(ed), i(3), l([r(3.9), l([s(sally)])])], r(4.21), X)

даст результат

X = [s(ed), i(3), r(3.9), s(sally), r(4.21)]

1 Solution

который получается из первоначального списка после выравнивания.

Грамматический разбор списков

Программа CH08EX10.PRO иллюстрирует грамматический разбор списков.

Процесс грамматического разбора работает, снижая проблему; в этом примере

мы преобразуем каждую строку в прологовую структуру, которую можно ис-

пользовать или оценить позднее.

Грамматический разбор в этом примере предназначен для очень прими-

тивного компьютерного языка. Хотя этот пример очень преждевременен для

данной стадии обучения, мы решили его все же привести именно здесь пото-

му, что грамматический разбор - одна из областей, где Турбо Пролог осо-

бенно силен. Если вы не чувствуете себя готовыми для этой темы, можно

пропустить этот пример и продолжить изучение без какой-либо потери целос-

тности.

/* Программа CH08EX10.PRO */

domains

toklist = string*

predicates

tokl(string,toklist)

clauses

tokl(Str,[H|T]):-

fronttoken(Str,H,Str1),!,

tokl(Strl,T).

tokl(_,[]).

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *

* Это вторая часть программы в грамматичкском разборе *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * */

domains

programm = programm(statementlist)

statementlist = statement*

/* * * * * * * * * * * * * * * * * * * * * *

* Определение из чего состоит утверждение *

* * * * * * * * * * * * * * * * * * * * * */

statement = if_Then_Else(exp, statement,statement);

if_Then(exp,statement);

while(exp,statement);

assing(id,exp)

/* * * * * * * * * * * * *

* Определение выражений *

* * * * * * * * * * * * */

exp = plus(exp,exp);

minus(exp,exp);

var(id);

int(integer)

id = string

predicates

s_program(toklist,program)

s_statement(toklist,toklist,statementlist)

s_exp(toklist,toklist,exp)

s_exp1(toklist,toklist,exp,exp)

s_exp2(toklist,toklist,exp)

clauses

s_program(List1,program(StatementList)):-

s_statementlist(List1,List2,StatementList),

List2=[].

s_statementlist([],[],[]):-!.

s_statementlist(List1,List4,[Statement|Program]):-

s_statement(List1,List2,Statement),

List2=[";"|List3],

s_ (List3,List4,Prgram).

s_statement["if"|List1],List7,if_then_else(Exp,

Snatement1,Statament2)):-

s_exp(List1,List2,Exp),

List2=["then"|List3],

s_statementList3,List4,Statement1),

List4=["else"|List5],!,

s_statementList5,List6,Statement2),

List6=["fi"|List7].

s_statement["if"|List1],List5,if_then(Exp,Statement)):-!,

s_exp(List1,List2,Exp),

List2=["then"|List3],

s_statementList3,List4,Statement),

List4=["fi"|List5].

s_statement["do"|List1],List4,while(Exp,Statement)):-!,

s_statementList1,List2,Statement),

List2=["while"|List3],

s_exp(List3,List4,Exp).

s_statement[Id|List1],List3,assing(Id,Exp)):-

isname(Id),

List1=["="|List2],

s_exp(List2,List3,Exp).

s_exp(LIST1,List3,Exp):-

s_exp2(List1,List2,Exp1),

s_exp1(List2,List3,Exp1,Exp).

s_exp1(["+"|List1],List3,Exp1,Exp):-!,

s_exp2(List1,List2,Exp2),

s_exp1(List2,List3,plus(Exp1,Exp2),Exp).

s_exp1(["-"|List1],List3,Exp1,Exp):-!,

s_exp2(List1,List2,Exp2),

s_exp1(List2,List3,minus(Exp1,Exp2),Exp).

s_exp1(List,List,Exp,Exp).

s_exp2([Int|Rest],Rest,int(I)):-str_int(Int,I),!.

s_exp2([Id|Rest],Rest,var(Id):-isname(Id).

Загрузите и запустите эту программу (нажав Alt-R), затем введите

следующее целевое утверждение:

Goal: tokl("b=2;if b then a=1 else a=2 fi; do a=a-1 while a;Ans),

s_program(Ans,Res).

Турбо Пролог вернет программную структуру:

Ans=["b","=","2",";","if","b","then","a","=","1",

"else","a","=","2","fi",";","do","a","="."a",

"-","1","while","a",";"

],

Res=program([assing("b",ins(2)),

if_then_else(var("b"),assing("a",int(1)),

assing("a",int(2))),

while(var("a"),assing("a",minus(var("a"),int(1))))

])

1 Solutions

Преобразование в этом примере разделяется на два этапа: просмотр и

грамматический разбор. Предикат tokl при просмотре принимает строку и

преобразует ее в список названий. Все предикаты с именем на s - это пре-

дикаты грамматического разбора. В этом примере входной текст - это паска-

леподобная программа, составленная из паскалеподобных утверждений. Язык

программирования понимает только некоторые утверждения : IF THEN ELSE, IF

THEN, DO WHILE и ASSIGMENT. Утверждения составляются из выражений и дру-

гих утверждений. Выражение: сложение, вычитание, переменные, целые.

Вот как работает эта программа:

1. Первое предложение просмотра s_program исследует список названий

и проверяет, можно ли их преобразовать в список утверждений.

2. Предикат s_statementlist проверяет, могут ли названия в списке

названий быть разделены на отдельные утвержденния, каждое заканчива-

ющееся точкой с запятой.

3. Предикат s_statement проверяет является ли первое название списка

названий правильным утверждением. Если да, то утверждение возвраща-

ется в структуру и оставшиеся названия возвращаются к предикату

s_statement.

a. Четыре s_statement предложения относятся к четырем типам ут-

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

s_ statement предложение не может перевести список названий в IF

THEN ELSE утверждение, то работает следующее предложение, которое

пытается преобразовать список названий в утверждение IF THEN. Ес-

ли и это не удается, то следующее предложение преобразует список

названий в DO WHILE утверждение.

b. Если первые три s_statement предложения неудались, то послед-

нее предложение для этого предиката проверяет не является ли ут-

верждение assigment. Для этого предложение проверяет, является ли

первый терм - идентификатором, является ли второй терм - "=", яв-

ляются ли следующие термы - выражениями.

4. Предикаты s_exp, s_exp1 и s_exp2 работают также, проверяя являют-

ся ли первые термы выражениями, и если - да, то возвращают остаток

термов к s_statement.

Для более детального рассмотрения примера грамматического разбора

смотрите приложение "Анализатор предложений" (в книге Турбо Пролог. Спра-

вочное Руководство) и программу SEN_AN.PRO на вашем диске.

Соседние файлы в папке Документация