
2.4. О технике рекурсивного программирования 155
Если
„проиграть" этот алгоритм на машине обработки фор-
муляров, то мы увидим, что в (каскадной) рекурсии для
contains
повторяются вызовы вычислений при одних и тех же
значениях аргумента. Чтобы избежать этого, надо построить пол-
ную кодовую таблицу. Это особенно выгодно, если имеется
много вызовов функции cod с одним и тем же значением
аргу-
мента s
(частичное
вычисление,
см. 2.6.3).
2.4.2.
Как
доказывать
свойства
алгоритмов?
Утверждения о свойствах алгоритмов весьма важны для по-
нимания
их сути. Так, подпрограммы
merge,
gcd и .+. обладают
тем свойством, что они допускают перестановку аргументов,
а значит задают коммутативные двуместные операции. Дока-
зать этот факт, исходя из рекурсивного определения, стоит
значительно больших усилий.
В случае подпрограммы
merge
из 2.3.2 (f) указанное свой-
ство устанавливается просто. Запись этой подпрограммы сим-
метрична относительно и и и, при перестановке и и v она пере-
ходит сама в себя, поскольку порядок отдельных ветвей при»
охраняемом разборе случаев не имеет значения. Здесь интере-
сующее нас свойство видно с одного взгляда на подпрограмму.
В случае подпрограммы
gcdl
из
2.3.2(d)
необходимо снача-
ла преобразовать подпрограмму. Нам достаточно показать, что
для m < п справедливо равенство
gcdl{m,
n) =
gcdl
(n, m).
Но
из данного в
2.3.2(d)
определения подпрограммы mod сле-
дует,
что
т <
п=>mod{m,n)
= m,
поэтому
gcdl{m,n)
= {\\ n = Q
then
m
else
gcdl(n,m)
fi).
Тем самым для п >0 доказано, что
gcdl(m,
п) =
gcdl
(n, т).
Чтобы установить равенство
gcdl(m,
0) =
gcdl
(0, m), достаточ-
но
рассмотреть случай т ф 0. В этом случае, однако, по опре-
делению,
gcdl{0,
m) —
gcdl(m,
mod(0,
m)), a
mod(0,
m) = 0.
Наконец,
в случае подпрограммы
plus
из
2.4.1.2
доказать
коммутативность такими преобразованиями нельзя, здесь не-
обходимо прибегнуть к доказательству по индукции (Сколем,.
1923 г.).
Часто при решении задач исходят из характеристических
свойств искомого алгоритмического решения (см.
2.4.1.5).
Если
надо убедиться, что данная (рекурсивная) подпрограмма яв-
ляется решением, то это делают, выводя из неё все требуемые
свойства. Например, подпрограмма mod из 2.3.2 (с) обладает