Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
zhukov-1.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
61.01 Кб
Скачать

8.Организация рекурсии

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

Обычно в большинстве рекурсивных определений можно выделить база+шаг

База-часть определений в которых не встречаются вызовы самого предиката.Шаг-

Рекурсия – это второе средство для организации повторяющихся действий в Прологе. Рекурсивная процедура – это процедура, вызывающая сама себя до тех пор, пока не будет соблюдено некоторое условие, которое остановит рекурсию. Такое условие называют граничным.

Примером рекурсивных вычислений является известный алгоритм вычисления факториала. Факториал числа N определяется согласно алгоритму:

  1. 1!=1

  2. N!=N*(N-1)!

Реализация этого алгоритма на языке Пролог имеет такой вид: domains N, F = real                  % Вещественный тип имеет больший диапазон predicates factorial( N, F ) clauses factorial( 1, 1 ).                          % База рекурсии, ограничение вычислений factorial( N, R ):– N> 0,            % Правило с рекурсией N1 = N - 1, factorial( N1, R1 ), R = R1 * N. goal factorial( 8, F), write( F ).           % Пример вычисления 8!

При каждом вызове дизъюнкта  factorial  генерируются новые переменные, которые действуют всегда только на своем уровне вложенности, пока не встретится условие прекращения вычислений (базис рекурсии). Только после этого на обратном пути прохождения рекурсии определяются результаты. Считается, что используется хвостовая рекурсия, если последнее условие в последнем правиле является рекурсивным. Такая рекурсия имеет преимущество перед нехвостовой рекурсией, так как позволяет ограничить рост стека и строго контролировать процесс возврата. По сути, хвостовая рекурсия – это итеративный процесс. В приведенном примере вычисления факториала рекурсия нехвостовая, а отношения aboveв рассмотренном выше примере – хвостовая.

9.Вычисление частичных сумм рядов

10.Списки в турбопрологе

Список ─ последовательность из произвольного числа элементов. Элементы списка разделяются запятыми и заключаются в квадратные скобки. Любой список представляет собой:

  • либо пустой список (атом []);

  • либо непустой список ─ структуру, состоящую из двух

частей: первый элемент ─ голова (Head) списка; второй

элемент ─ хвост (Tail) списка.

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

[ Элемент1, Элемент2,...]

или

[ Голова | Хвост ]

или

[ Элемент1, Элемент2,... | Остальные].

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

[1,2,3,6,9,3,4]

[3.2,4.6,1.1,2.64,100.2]

["Вчера","Сегодня","Завтра"]

Количество элементов в списке называется его длиной. Список, не содержащий элементов, называется пустым или нулевым списком. Он обозначается так: []. Непустой список можно рассматривать как состоящий из двух частей: первый элемент списка ─ его голова, и остальная часть списка ─ хвост. Голова является элементом списка, хвост есть список сам по себе. Турбо-Пролог позволяет, в частности, выполнять над списками следующие операции: доступ к элементам списка, проверку на принадлежность к списку, сортировку элементов списка в порядке возрастания или убывания.

Если требуется включить в список элементы, относящиеся к разным типам данных (в том числе и к типу список), то нужно определить домен с альтернативами объектов разного типа, например, следующим образом:

domains

item = c (char); i (integer); s (string) /* c, i, s – функторыпредикатов */

item _list = item* /* домен списков смешанного типа */

predicates

list (item _list)

clauses

list ([i (10), i (12), i (2000), s (“НГПУИФМИЭО”), c (“N”)]).

Рассмотрим программу "Птицы"с использованием списков.

/* Программа: П т и ц ы. */

domains

bird_list = bird_name*

bird_name = symbol

predicates

birds(bird_list)

clauses

birds(["ласточка","синица","чиж","воробей"]).

Отличительной особенностью описания списка является наличие звездочки (*) после имени списка элементов. Так запись bird_name* указывает на то, что это описание списка, элементами которoго являются bird_name (птицы).

Описание в разделе domains, следовательно , может выглядеть либо как

bird_list = bird_name*

bird_name = symbol

либокак

bird_list = symbol*

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

birds(bird_list)

Сам список присутствует в разделе утверждений clauses:

birds(["ласточка","синица","чиж","воробей"]).

Выполните программу со следующими внешними запросами:

birds(All).

birds([_,_,_,B]).

birds([B1,B2,_,_]).

В программе "Птицы" для получения доступа к элементам списков были использованы внешние целевые утверждения. Задание цели в виде birds(All) обеспечивало присваивание переменной All всего списка в целом. Напротив, цель birds([_,_,_,B]) позволила извлечь из списка лишь один элемент. В этом случае, требовалось точное знание числа элементов списка. Для работы со списками, длина которых заранее неизвестна, используется метод разделения списка на голову и хвост. Данный метод работает вне зависимости от длины списка, до тех пор, пока список не будет исчерпан. Операция деления списка на голову и хвост обозначается при помощи вертикальной черты (|):

[Head|Tail].

Head здесь является переменной для обозначения головы списка, переменная Tail обозначает хвост списка.

Программа "Голова - хвост" демонстрирует использование метода. Это ─ программа печати введенных пользователем списков целых чисел и символов.

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