Общие стратегии доказательства, чтобы показать правильность рекурсивных функций?

Мне интересно, существует ли какое-либо правило/схема работы с проверкой правильности алгоритма? Например, мы имеем функцию $F $, определенную на натуральных числах и определяемую ниже:

function F(n,k)
begin
  if k=0 then return 1
  else if (n mod 2 = 0) and (k mod 2 = 1) then return 0
  else return F(n div 2, k div 2);
end;

где $n\\ text {div}\2 =\left\lfloor\frac {n} {2}\right\rfloor $

задача состоит в том, чтобы доказать, что $F (n, k) =\begin {cases} 1\Leftrightarrow {n\select k}\\ text {mod}\2 = 1\0\text {other}\end {cases} $

Это не выглядит очень сложным (я не прав?), но я не знаю, как это должно быть структурировано. Я был бы очень благодарен за помощь.

Ответ 1

Корректность рекурсивных алгоритмов часто доказывается математической индукцией . Этот метод состоит из двух частей: во-первых, вы устанавливаете основу, а затем используете индуктивный шаг.

В вашем случае основой являются все случаи, когда k = 0, или когда k нечетно, но n четно.

Индуктивный шаг требует подтверждения того, что когда f(n,k) верно, f(2*n,2*k), f(2*n+1,2*k), f(2*n,2*k+1) и f(2*n+1,2*k+1) все правильно.

Ответ 2

За пределами математического обоснования вашей логики (например: индуктивное доказательство), есть некоторые результаты в области вычислительной науки, связанной с этим.

Вы можете начать здесь для описания темы: Correctness
В вашем конкретном случае вас будет интересовать частичная правильность, чтобы показать, что ответ является предполагаемым. Затем полная правильность, чтобы показать, что программа завершается.

Логика Hoare может решить вашу неполную корректность.

Что касается завершения этой конкретной проблемы:

Если (n% 2 == 0 и k% 1 == 1) или (k == 0) программа завершается, в противном случае она возвращается к случаю n/2, k/2.
Используя сильную индукцию на k, мы можем показать, что программа всегда достигает одного из терминальных узлов, где k == 0. (Он может завершиться раньше в первом предложении, но нам нужно было только показать, что он вообще завершается, что это делает)

Итак, я оставил вам доказательство неполной корректности (потому что я этого не знаю)

Ответ 3

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

В этом случае я попытаюсь доказать обоснованную индукцию. В частности, я бы доказал, что

  • Функция верна для всех входов формы (n, 0).
  • Предполагая, что для всех входов (n ', k') таких, что (n ', k') лексикографически меньше (n, k), функция правильна, докажите, что она правильна для (n, k).

Специфика этого доказательства должна была бы использовать особенности вашей функции и bahvaior биномиальных коэффициентов, но общий шаблон такой, как указано выше.

Надеюсь, это поможет!