Скачиваний:
31
Добавлен:
22.05.2015
Размер:
137.73 Кб
Скачать

Генерация списков

Генерация списков обычно производится рекурсивно. На каждом витке рекурсивного цикла в список добавляется, как правило, один элемент. Заполнение списка может производиться как слева направо, так и справа налево. Рассмотрим оба варианта на примерах.

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

Пример 1. Генерация списка целых чисел в заданном диапазоне [From..UpTo]:

implement main

open core, console

constants

className = "com/visual-prolog/main".

classVersion = "$JustDate: $$Revision: $".

class predicates

gen : (integer From, integer UpTo, integer* Список) procedure (i,i,o).

clauses

classInfo(className, classVersion).

gen(I,N,[]):-I>N,!. % Условие останова рекурсии

gen(I,N,[I|L]):-gen(I+1,N,L). % Продолжение рекурсии

run():-init(),

   gen(1,10,L), % Диапазон от 1 до 10

   write(L),

   _=readchar().

end implement main

goal

   mainExe::run(main::run).

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

Пример 2. Генерация реверсированного списка целых чисел в заданном диапазоне [From..UpTo]:

implement main

    open core, console

constants

className = "com/visual-prolog/main".

classVersion = "$JustDate: $$Revision: $".

class predicates

add : (integer From, integer UpTo, integer* ВходнойСписок, integer* ВыходнойСписок) procedure (i,i,i,o).

clauses

classInfo(className, classVersion).

add(I,N,L,L):-I>N,!.

add(I,N,T,L):-add(I+1,N,[I|T],L).

run():-init(),

   add(1,10,[],L),

   write(L),

   _=readchar().

end implement main

goal

   mainExe::run(main::run).

Пример 3. Добавление к входному списку ВходнойСписок целых чисел в реверсированном порядке в диапазоне [From..UpTo]:

implement main

    open core, console

constants className = "com/visual-prolog/main".

classVersion = "$JustDate: $$Revision: $".

class predicates add : (integer From, integer UpTo, integer* ВходнойСписок, integer* ВыходнойСписок) procedure (i,i,i,o).

clauses

classInfo(className, classVersion).

add(I,N,L,L):-I>N,!.

add(I,N,T,L):-add(I+1,N,[I|T],L).

run():-init(),

   add(1,10,[110,120,130],L),

   write(L),

   _=readchar().

end implement main

goal

   mainExe::run(main::run).

Задача 1. Переписать предикат из примера 1 в функциональном стиле:

gen : (integer From, integer UpTo) -> integer* Список.

Задача 2. Переписать предикат из примера 2 в функциональном стиле:

add : (integer From, integer UpTo, integer* ВходнойСписок) -> integer* ВыходнойСписок.

Задача 3. Написать предикат генерации списка первых n нечётных положительных целых чисел.

Задача 4. Написать предикат генерации списка первых n чисел гармонического ряда. Подсказка: n-й член такого ряда равен 1/n.

Задача 5. Написать предикат генерации списка первых n случайных целых чисел. Подсказка: функция, возвращающая случайное число описана в классе math.

Задача 6. Написать предикат генерации списка факториалов от 1! до n!.

Задача 7. Написать предикат генерации списка первых n чисел ряда Фибоначчи. Подсказка: первые два числа ряда Фибоначчи равны единице, каждый очередной элемент равен сумме двух предыдущих. Вот первые шесть чисел ряда Фибоначчи: 1, 1, 2, 3, 5, 8.

Соседние файлы в папке Лабораторные работы