Рекурсивные функции
Примитивно рекурсивные функции
Программы с конечным числом переменных напоминали ассемблер; рассматриваемые в этом разделе рекурсивные функции скорее напоминают функциональное программирование, когда одни функции определяются через другие. Мы будем рассматривать функции с натуральными аргументами и значениями. Вообще говоря, функции могут быть не всюду определенными, так что говоря о функции n аргументов (функции из Nn в N, n -местной функции), мы имеем в виду функцию, определенную на некотором подмножестве Nn со значениями в N.
Пусть имеется k -местная функция f и k штук n -местных функций g1,...,gk. Тогда из них можно сформировать одну n -местную функцию
![\langle x_1,\dots,x_n\rangle \mapsto
f(g_1(x_1,\dots,x_n),\dots,g_k(x_1,\ldots,x_n)).](/sites/default/files/tex_cache/887955ad4415ccc709b078acb9052e40.png)
Говорят, что определенная таким образом функция получена из функций f и g1,...,gk с помощью операции подстановки.
Другая операция, называемая операцией рекурсии, или примитивной рекурсии, применяется к k -местной функции f и (k+2) -местной функции g. Ее результатом будет (k+1) -местная функция h, определяемая так:
h(x1,...,xk,0)=f(x1,...,xk); h(x1,...,xk,y+1)=g(x1,...,xk,y,h(x1,...,xk,y)).
В последовательности h(x1,...,xn,0),h(x1,...,xn,1),... каждое значение определяется через предыдущее, поэтому если какое-то из значений не определено, то не определены и все последующие.
Для единообразия будем считать, что нуль-местные функции (функции без аргументов) суть константы; это позволяет рекурсивно определять функции одной переменной.
Примитивно рекурсивными называют функции, которые можно получить с помощью операций подстановки и рекурсии из следующих базисных функций: константы 0, операции прибавления
единицы s : x x+1 и семейства функций проекции:
это
семейство для каждого k
содержит k штук k -местных
функций
.
Функции проекции позволяют выполнять " неоднородные"
подстановки: скажем, можно получить функцию из функций f и h,
комбинируя их с
функциями проекции: сначала получаем функцию
(подстановка
в g ),
затем
(подстановка
в h ), затем полученные две
функции
вместе с функцией
подставляем в f.
Подставляя константу 0 в функцию прибавления единицы, получаем константу (функцию нуля аргументов) 1. Затем можно получить константы 2, 3 и т.д.
Примеры примитивно рекурсивных функций
Как и с другими вычислительными моделями, важно накопить некоторый программистский опыт.
Сложение. Функция получается с помощью рекурсии:
sum(x,0)=x; sum(x,y+1)=sum(x,y)+1.
Надо, конечно, представить правую часть второго равенства как результат подстановки. Формально говоря, h(x,y,z) в определении рекурсии надо положить равным s(z), где s функция прибавления единицы.
Умножение. Функция получается с помощью рекурсии
(с использованием сложения):
prod(x,0)=0; prod(x,y+1)=prod(x,y)+x.
Аналогичным образом можно перейти от умножения к возведению в степень.
Усеченное вычитание. Мы говорим об " усеченном вычитании" при
и
при
,
поскольку мы имеем дело только с натуральными (целыми
неотрицательными) числами. Одноместная функция усеченного вычитания
единицы определяется рекурсивно:
![\begin{align*}
0\subtr 1&=0;\\
(y+1)\subtr 1&=y.
\end{align*}](/sites/default/files/tex_cache/c66dbf2c66751b8692dad50fd17794d8.png)
(Рекурсия здесь формальна, так как предыдущее значение не используется.) После этого усеченное вычитание для произвольных аргументов можно определить так:
![\begin{align*}
x\subtr 0&=x;\\
x\subtr (y+1)&=(x\subtr y)\subtr 1.
\end{align*}](/sites/default/files/tex_cache/c8448dd3b3da06917dfbce147ed9f576.png)