Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Рлп.doc
Скачиваний:
3
Добавлен:
18.09.2019
Размер:
279.55 Кб
Скачать

10 Типовые операции над списками в Прологе

Добавление нового элемента Файл add.pro

/* Добавление нового элемента */ domains list = integer* predicates add_list ( integer, list, list ) clauses add_list (H,List,[H|List]). Добавление нового элемента происходит как добавление “головы” к уже существующему списку. Цели могут быть такими:

add_list(1,[2,3],L)

Удаление одного элемента Файл erase.pro

/* Удаление одного элемента */  domains  list = integer* predicates  erase_list (list,list) clauses erase_list ([H|T],T). Данная операция противоположна предыдущей, элемент удаляется как “голова” существующего списка. Цели могут быть такими:

erase_list([1,2,3],L)

Поиск элемента в списке Файл find.pro

/* Поиск элемента */ domains digit_list=digit * digit=integer member_list=member * member=symbol predicates  find(digit,digit_list) find(member,member_list) clauses /* Проверяем сходство с “головой” */  find(H,[H|_]). /* Проверяем сходство с “головой” “хвоста” */  find(H,[_|T]):-find(H,T).

11. Операторская запись (нотация).

МОДИФИКАЦИЯ СИНТАКСИСА (ОПЕРАТОРНАЯ ЗАПИСЬ)

Прологовские операторы суть имена функций и/или предикатов (унарных и/или бинарных), записанных до, после или между аргументами, им свойственны приоритет или ассоциативность:

?- a+b+c = X+Y.

X = a + b

Y = c

Yes

?- a+b*c = X+Y.

X = a

Y = b * c

Yes

?- -a+b+c = X+Y.

X = -a + b

Y = c

Yes

В данных примерах встроенными операторами являются предикат  = и функторы +,- и *, но программист может ввести собственные операторы.

Атрибутика оператора:

*        предшествование, выраженное натуральным числом (от 0 до 1200): чем больше предшествование, тем меньше приоритет;

*        позиция – инфиксная, префиксная или постфиксная;

*        ассоциативность.

Предшествование выражают числом, а позицию и ассоциативность – одним из следующих способов:

*        префиксность оператора (точнее, префиксная запись оператора): fx или fy;

*        постфиксность оператора: xf или yf;

*        инфиксность оператора: xfx,xfy,yfx или yfy.

Здесь f – оператор, x и y – операнды:

*        запись yfx означает левую ассоциативность

a f b f c f d º ((a f b) f c) f d,

+  и * обладают левой ассоциативностью;

*        запись xfy означает правую ассоциативность

a f b f c º a f(b f c),

^  обладает правой ассоциативностью;

*        запись x f x говорит, что оператор не обладает ассоциативностью; например, mod, поэтому X is 120 mod 50 mod 2 – синтаксическая ошибка.

12.Арифметические действия Прологовская арифметика.

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

GNU Prolog 1.2.16

By Daniel Diaz

Copyright (C) 1999-2002 Daniel Diaz

| ?- X = 2, Y is X - 1.

X = 2

Y = 1

yes

| ?-

А вот так система поймет Вас неверно:

GNU Prolog 1.2.16

By Daniel Diaz

Copyright (C) 1999-2002 Daniel Diaz

| ?- X = 2, Y = X - 1.

X = 2

Y = 2-1

yes

| ?-

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

Для осуществления основных арифметических действий, можно воспользоваться несколькими предопределенными операторами.

  • + Сложение

  • - Вычитание

  • / Деление (вещественное)

  • mod модуль (остаток от целочисленного деления)

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

| ?- X = 15, Y is X mod 2.

X = 15

Y = 1

yes

| ?- X = 15, Y is mod(X,2).

X = 15

Y = 1

yes

| ?-

13. Управление работой механизма возврата.

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

меньше(X.Y) :-  XY, write(X),  write ('меньше, чем'),write(Y). меньше(Х.У) :-  XY, write(Y),  write ('меньше, 4CM'),write(X). Целевое утверждение 

?- меньше (5, 2). сопоставляется с головой первого утверждения при Х=5 и У=2. Однако не удается согласовать первый член конъюнкции в теле утверждения XПролог выдает сообщение “2 меньше, чем 5”. Запрос

?-меньше (2, 2). сопоставляется с головой первого утверждения, но тело утверждения согласовать не удается. Затем происходит сопоставление с головой второго утверждения, но согласовать тело опять-таки оказывается невозможно. Поэтому попытка доказательства целевого утверждения меньше(2, 2) заканчивается неудачей. Такой процесс согласования целевого утверждения путем прямого продвижения по программе называется прямой трассировкой (forward tracking). Даже если целевое утверждение согласовано, с помощью прямой трассировки мы можем попытаться получить другие варианты его доказательства, т.е. вновь согласовать целевое утверждение. Пролог производит доказательство конъюнкции целевых утверждений слева направо. При этом может встретиться целевое утверждение, согласовать которое не удается. Если такое случается, то происходит смещение влево до тех пор, пока не будет найдено целевое утверждение, которое может быть вновь согласовано, или не будут исчерпаны все предшествующие целевые утверждения.

14 Отсечение применяется для устранения бесконечных циклов, при программировании взаимоисключающих утверждений и при необходимости неудачного завершения доказательства цели. Рассмотрим все три случая на примерах. Пример 1. Устранение бесконечных циклов. Вновь обратимся к утверждениям, определяющим вычисление факториала (см. тему «Рекурсия»).

'факт'(0,1). 'факт'(K,F): - К1 is К-1, 'факт'(К1,F1), F is F1*К. Введя запрос:

?- 'факт'(0,X). получим

X=1 -> ;  Если мы поставим <;>, т.е. запросим еще решения, то Пролог сделает попытку сопоставить 'факт'(0,Х) со вторым утверждением 'факт'(К,F): -.. . Сопоставление успешно, и теперь делается попытка доказать цель 'факт'(-1,F1), что в свою очередь приводит к цели 'факт'(-2,F2) и так далее, т.е. образуется бесконечный цикл. К счастью, можно устранить такие ситуации, используя отсечение, и тем самым указывая Прологу, что не существует других решений в случае успешного согласования граничного условия.

'факт'(0,1):-!. 'факт'(К,F):-К1 is К-1,'факт'(К1,F1),F is F1*К. Учитывая данное определение 'факт' и задавая вопрос:

? - 'факт'(0,Х). получаем единственное решение:

X=1 -> ;  no

15 При использовании отсечения возможно возникновение двух видов ловушек: • отсечение исключает необходимые альтернативы; • отсечение разрушает декларативное восприятие программы. В качестве примера ловушки первого типа рассмотрим применение предиката 'между'(X,Y,Z) в двух различных вариантах: для генерации всех целых чисел Х, принадлежащих интервалу [Y,Z], и для проверки, находится ли целое число X в интервале [Y,Z], т.е. Y<=X<=Z.

'между'(X,X,Z):- X=<z.  'между'(X,Y,Z):- Y1 is Y+1,Y1=<z,'между'(x,y1,z). </z,'между'(x,y1,z). </z.

При запросе: ? - 'между'(Х,5,8). будут получены следующие решения

X=5 --> ;  X=6 --> ;  X=7 --> ;  X=8 --> ; 

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

'между1'(X,X,Z):-!,X=<z.  'между1'(X,Y,Z):-Y1 is Y+1,Y1=<z,'между1'(x,y1,z).  и попытаемся его использовать для контроля, принадлежит ли Х заданному интервалу [Y,Z]: ? - Х=3,'между1'(Х,2,4). yes </z,'между1'(x,y1,z). </z.

Как только будет достигнут момент согласования граничного условия 'между'(3,3,4), благодаря отсечению бесцельный поиск других решений в ответ на ввод <;> (или при любом другом способе инициирования возврата) производиться не будет, время доказательства цели сократится. Однако в таком виде этот предикат уже не сможет выступать в роли генератора, что показывает ответ на следующий запрос: 

?-'между'(Х,4,8). 'между'(4,4,8).?;  no Сравнение двух вариантов программы в примере 2 иллюстрирует ту ситуацию, когда введение отсечения приводит к потере декларативности определения отношения. Применять отсечение следует осторожно, соразмеряя выгоду от повышения эффективности программы с опасностью возникновения нежелательных эффектов.

16. Встроенные предикаты для ввода/вывода и форматирования объектов данных программы.

Пролог-программа имеет встроенные предикаты. Для ввода информации используется предикат

readint (переменная)- для ввода целочисленных данных

readreal (переменная)- для ввода вещественных данныхreadchar (переменная)- для ввода символьных данных

readln (переменная)- для ввода строковых данных

Для вывода результатов используется

write (список переменных)

nl переводит курсор на новую строку.

Встроенные предикаты обеспечивают возможности ввода-вывода информации:

  1. write/1 - этот предикат всегда успешен. Когда вызывается, то побочным эффектом будет вывод значения аргумента на экран. При бэктрекинге предикат дает неудачу. Бэктрекинг не сбрасывает побочный эффект.

  2. nl/0 - этот предикат всегда успешен. Когда вызывается, то побочным эффектом будет перевод на следующую строку. При бэктрекинге предикат дает неудачу. Бэктрекинг не сбрасывает побочный эффект.

  3. tab/1 - этот предикат всегда успешен. Когда вызывается, то побочным эффектом будет печать коли- чество пробелов заданное аргументом. Аргумент должен быть целым. При бэктрекинге предикат дает неудачу. Бэктрекинг не сбрасывает побочный эффект.

  4. read/1 - этот предикат читает терм , который вводится с клавиатуры и заканчивается точкой. Этот терм сопоста- вляется с аргументом. При бэктрекинге предикат дает неудачу. Бэктрекинг не сбрасывает побочный эффект.

Например,

 

pr1:- read(X),nl,write('X='),tab(2),write(X).

17. Базы знаний и базы данных в Турбо-Прологе Турбо-Пролог (ТП) позволяет работать с БД и БЗ. База данных в ТП понимается как совокупность файлов. Факты, расположенные в разделе clauses непосредственно в теле программы, образуют внут- реннюю (в терминологии ТП - статическую) базу данных. Информация в этой области не может изменяться в процессе выполнения программы. Факты, описанные предикатами из области database, образуют внешнюю (по отношению к телу программы) базу данных, которая в ТП называется динамической. Турбо-Пролог обеспечивает работу с БД, находящимися в файлах на внешних носителях. Для взаимодействия с такими данными ТП имеет ряд стандартных предикатов для чтения и сохранения БД в файле, для добавления и удаления фактов БД и т.д. Динамическое формирование правил в ТП не предусмотрено. ТП работает с БД, находящимися в оперативной памяти. Такие БД называются резидент- ными. Совокупность правил (разделы predicates и clauses) может быть вынесена в отдельный фаул, которому присвоим расширение RUL. Совместно с DBA-файлами, RUL-файлы будут образовывать базу знаний Пролог-программы. Используемая версия языка Пролог (Turbo Prolog version 2.0), не поддерживает изменение правил в ходе выполнения программы и, строго говоря, не обеспечивает работу с базами знаний. Однако, ограничиваясь статическими правилами, можно говорить об организации базы знаний с использованием Турбо-Пролога. Для работы в БД в Турбо-Прологе существуют следующие преди- каты. 1. Загрузка файла БД в оперативную память:

consult (DosFileName),

где DosFileName - Dos-имя файла БД, имеющее тип string. Например, для загрузки файла БД с именем GEO.DBA необходимо использовать предикат consult("geo.dba"). После выполнения этого предиката БД GEO.DBA становится резидентной. 2. Сохранение фактов БД в внешнем файле:

save (DosFileName),

где DosFileName - Dos - имя файла БД в формате string. Для сох- ранения фактов в файле GEO.DBA следует использовать предикат save("geo.dba")' после выполнения которого резидентная БД зано- сится в указанный файл. 3. Занесение новых фактов в резидентную БД осуществляется при помощи следующих предикатов:

assert(<факт>), asserta(<факт>), assertz(<факт>). Предикаты assert и assertz заносят указанный файл в конец БД, а предикат assertа - в начало. Удаление файлов их резидентной БД осуществляется при помощи предикатов

retract(<факт>), retractall(<факт>). Предикат retract удаляет первый из совпавших с указанным факт резидентной БД. Для удаления последующих фактов необходимо использовать откат(file). Предикат retractall удаляет все факты, совпадающие с заданным. Примеры использования:

retract(parent(tom,bob)), retractall(parent(tom,_)).

В первом случае удаляется единственный факт parent(tom,bob, а во втором происходит удаление всех фактов для предиката parent, первый аргумент которых имеет значение tom.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]