Мягкое введение в Coq: используем тактики

в 5:23, , рубрики: coq, формальная верификация, функциональное программирование, метки: ,

Доказательство упрощением

Итак, в предыдущих частях мы определили новые типы данных и функции над ними. Настало время обратиться к вопросу о том, как сформулировать и доказать их свойства и поведение. В некотором смысле мы уже начали делать это – в первой части мы написали своего рода юнит-тест, используя ключевое слово Example, который содержал некоторые утверждения о поведении некоторой функции, применяемой к определенному набору аргументов. Используя определение функции, Coq упрощает выражение и проверяет на равенство его левую и правую часть.

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

Theorem plus_O_n : forall n : nat, 0 + n = n.
Proof.
  simpl. reflexivity. Qed.

Команда reflexivity неявно упрощает обе стороны выражения перед сравнением.

Ключевые слова simpl и reflexivity являются примерами тактик. Главная цель тактики – подсказать Coq каким образом следует проверить корректность нужных утверждений. Существует довольно узкий круг задач, корректность которых может быть доказана автоматически. Докажем, что 2 + 2 = 4:

Coq < Lemma using_auto: 2 + 2 = 4.
1 subgoal
  
  ============================
   2 + 2 = 4

using_auto < Proof. auto. Qed.

Proof completed.

auto.

using_auto is defined

В подавляющем большинстве случаев необходимо использовать тактики.

Тактика intros

Помимо юнит-тестов, которые применяют функции к набору аргументов, мы будем заинтересованы в доказательстве свойств программ, формулировка которых содержит математические кванторы (например, «для всех натуральных чисел n») и гипотезы (например, «пусть a = b»). Тактика intros позволяет перенести кванторы и гипотезы из утверждения в контекст текущих рассуждений. Докажем, что результатом умножения слева любого натурального числа на нуль является нуль:

Theorem mult_zero: forall n : nat, 0 * n = 0.
Proof. intros n. reflexivity. Qed.

Доказательство перезаписью

Рассмотрим более интересный пример:

Theorem plus_id_example : forall n m : nat,
n = m ->
n + m = m + n.

Вместо того, чтобы формулировать и доказывать универсальное утверждение относительно любых n и m, эта теорема гласит о более узких свойствах, которые имеют место при n = m. Поскольку n и m – произвольные числа, мы не можем использовать упрощение для доказательства. Вместо этого, мы докажем, что заменяя m на n в условии (в предположении n = m), мы получим верное тождество. Тактика, которая указывает Coq совершить такую замену, называется rewrite:

Proof.
 intros n m.
 intros H.
 rewrite -> H.
 reflexivity. Qed.

Для того, чтобы лучше понять что же здесь произошло, я настоятельно рекомендую запустить этот пример в CoqIDE и последовательно пройти по этому доказательству.

Итак, формулируем теорему и начинаем доказательство:

image

Следующим шагом переносим выражения из-под кванторов всеобщности и гипотезу в текущий контекст доказательства (в правой верхней части CoqIDE наблюдаем как изменяется текущий контекст доказательства):

image

Осуществляем перезапись текущей цели доказательства:

image

Заканчиваем доказательство с помощью упрощения:

image

Заключение

В следующей части мы познакомимся с более продвинутыми тактиками и начнем работать со структурами данных в Coq. Еще раз обращаю внимание читателя на важность самостоятельного запуска примеров в CoqIDE.

Ссылки на предыдущие части:

  1. Начало.
  2. Индуктивные определения.

Автор: ymn

Источник

Поделиться

* - обязательные к заполнению поля