Чтение онлайн

на главную - закладки

Жанры

Программирование на языке пролог
Шрифт:

?- имя(а,b,с) =.. X.

X = [имя,а,b,с]

?- присоединить([А|В],С, [A|D]) =..L.

A = _2, В = _3, С = _4, D = _5, L = [присоединить,[_2|_3],_4,[_2|_5]]

?- [a,b,c,d] =..L.

L = ['.',a,[b,c,d]].

?- (a+b) =.. L.

L = [+,a,b].

?- (a+b) =..

[+,A,B] A = а, В = b

?- [a,b,c,d] =..

[A|B] A = '.', В = [a,[b,c,d]]

?- X =.. [a,b,c,d]

X = a(b,c,d).

?- X =.. [присоединить,[a,b,],[c],[a,b,c]].

X = присоединить([а,b],[с],[а,b,с])

Примеры использования предиката =.. приведены в разд. 7.12.

name(А,L)

В то время как предикаты functor, argи =..используются для формирования произвольных структур и доступа к их аргументам,

предикат nameиспользуется для работы с произвольными атомами. Предикат nameсопоставляет атому список литер (их ASCII кодов), из которых состоит этот атом. Данный предикат можно использовать как для определения литер, составляющих указанный атом, так и для определения атома, содержащего заданные литеры. Целевое утверждение name(A, L)означает, что литеры, образующие атом А, являются элементами списка L. Если аргументу А уже присвоено значение, то Пролог создает список литер и пытается сопоставить его с L. В противном случае Пролог использует список Lдля создания атома, который станет значением А. Приведем примеры использования предиката name:

?- name(apple,X).

X = [97,112,112,108,100]

?- name(X,[97,l12,112,108,100]).

X = apple

?- name(apple,"apple").

да

?- name(apple,"pear").

нет

В разд. 9.5 предикат nameиспользуется для доступа к внутренней структуре слов английского языка, представляемых атомами Пролога.

6.6. Воздействие на процесс возврата

В Прологе есть два встроенных предиката, изменяющих нормальную последовательность событий, происходящих в процессе возврата. Предикат « !» устраняет возможности для повторного согласования целевых утверждений, а предикат repeatсоздает новые альтернативы там, где их не было ранее.

Отсечение

Символ отсечения ('!') можно рассматривать как встроенный предикат, который лишает Пролог-систему возможности изменить некоторые из решений, принятых ею ранее. Более подробное описание отсечения смотрите в гл. 4.

repeat

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

repeat.

repeat:- repeat.

Что произойдет, если мы поместим предикат repeatкак целевое утверждение в одно из наших правил?

Во-первых, это целевое утверждение согласуется с базой данных, так как имеется соответствующий факт – первое утверждение определения предиката repeat.Во-вторых, если в процессе возврата вновь будет достигнуто это место, то Пролог будет иметь возможность испробовать альтернативу – правило (второе утверждение). При использовании правила порождается другое целевое утверждение repeat.Так как оно сопоставляется с фактом для предиката repeat,то это целевое утверждение вновь согласуется с базой данных. Если процесс возврата снова дойдет до этого места, то Пролог вновь использует правило там, где он ранее использовал факт. Чтобы доказать согласованность вновь порожденного целевого утверждения, он снова выберет факт. И так далее. В действительности в процессе возврата целевое утверждение repeatможет быть согласовано бесконечное число раз. Обратим внимание на существенность порядка, в котором записаны утверждения для предиката repeat.(Что произойдет, если факт будет записан после правила?)

Для чего нужно порождать целевые утверждения, которые всегда будут согласовываться в процессе возврата? Они нужны для того, чтобы создавать правила, в которых имеется возможность выбора вариантов, из правил, которые

такой возможности не содержат. И тем самым мы можем заставить их порождать каждый раз различные значения.

Рассмотрим встроенный предикат get0,который описан в гл. 5. Если Пролог пытается доказать согласованность целевого утверждения get0(X), то он понимает это как указание взять очередную литеру (букву, цифру, пробел или что-либо еще), которая была введена в систему, и попытаться сопоставить целочисленный код этой литеры со значением X. Если они будут сопоставимы, то целевое утверждение считается согласованным, в противном случае оно несогласовано. При этом нет никакого выбора – предикат get0всегда обрабатывает только текущую литеру, введенную в систему в момент обращения к предикату. При следующем обращении к целевому утверждению, включающему get0, он возьмет следующую литеру, но при этом опять не будет никакого выбора. Мы можем определить новый предикат new_getследующим образом:

new_get(X):- repeat, get0(X).

Предикат new_getобладает следующим свойством: он порождает одно за одним значения всех последующих литер (в порядке их поступления) как альтернативные решения. Почему так получается? Когда мы первый раз вызываем new_get(X),то подцель repeatсогласуется и подцель getO(X)тоже, при этом переменная Xконкретизируется очередной литерой. Когда мы инициируем возврат, то выясняется, что последним местом, где имелся выбор, является repeat. Пролог забывает все, что было сделано с того момента, а повторное согласование целевого утверждения repeatуспешно завершается. Теперь он вновь должен обратить свое внимание на getO(X).К этому моменту текущей литерой является следующая литера, и в результате Xполучает в качестве значения вторую литеру.

Мы можем использовать наше определение new_get,чтобы определить другой полезный предикат. Предикат getобычно является встроенным. Когда Пролог обрабатывает целевое утверждение get(X),он рассматривает его как указание читать литеры до тех пор, пока он не найдет очередную неуправляющую литеру, имеющую изображение при печати (пробел, признак конца строки и т. д.). Затем он пытается сопоставить целочисленный код этой литеры со значением X. Мы можем написать приблизительное определение предиката getследующим образом:

get(X):- new_get(X), X › 32.

Чтобы понять это определение, нужно вспомнить, что в кодировке ASCII все неуправляющие (печатаемые) литеры имеют код, превышающий 32, все остальные литеры имеют код, меньший или равный 32. Что происходит при попытке согласовать get(X)?Прежде всего new_get(X)сопоставляет X с текущей литерой, введенной в систему. Если ее код меньше или равен 32, то следующее целевое утверждение неверно и new_getбудет вынужден породить следующую литеру как следующее возможное решение. Эта литера будет затем сравнена с 32 и так далее. В конце концов new_getнайдет неуправляющую литеру, сравнение закончится успешно и код этой литеры будет возвращен в качестве результата get.

Упражнение 6.1.Приведенное определение предиката getне будет работать надлежащим образом, если мы обратимся к целевому утверждению get(X)с уже определенным значением X. Почему это происходит?

Неприятность, связанная с предикатом repeat,состоит в том, что он всегда имеет альтернативное решение. Следовательно, в процессе возврата repeatникогда не будут пересмотрены решения, принятые раньше, чем произошел последний вызов repeat,если только мы не отсечем каким-либо образом эту постоянную возможность выбора. В силу сказанного предыдущие определения должны быть переписаны следующим образом:

Поделиться:
Популярные книги

Сын Тишайшего

Яманов Александр
1. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.20
рейтинг книги
Сын Тишайшего

"Искажающие реальность" Компиляция. Книги 1-14

Атаманов Михаил Александрович
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Искажающие реальность Компиляция. Книги 1-14

Школа. Первый пояс

Игнатов Михаил Павлович
2. Путь
Фантастика:
фэнтези
7.67
рейтинг книги
Школа. Первый пояс

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Аргумент барона Бронина 4

Ковальчук Олег Валентинович
4. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 4

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Измена. Право на обман

Арская Арина
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на обман

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Жаба с кошельком

Донцова Дарья
19. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
8.26
рейтинг книги
Жаба с кошельком

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Академия чаросвет. Тень

Ярошинская Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Академия чаросвет. Тень

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4