Coq — интерактивный помощник доказательства, на котором проверяют теоремы и программы. Он основан на исчислении индуктивных конструкций с зависимыми типами: утверждение формулируется как тип, а доказательство — как терм этого типа, который проверяет ядро. Если ядро приняло терм, ошибки в доказательстве нет по построению. В 2025 году проект переименован в Rocq, но имя Coq по-прежнему широко используется в дистрибутивах, литературе и названиях библиотек. Разберём установку, первое доказательство, тактики, сборку проекта и извлечение кода.

Зачем это нужно на практике

Обычные тесты проверяют несколько примеров и не покрывают все входы. Coq позволяет доказать свойство для всех значений сразу: что сортировка возвращает перестановку входа, что компилятор сохраняет семантику, что протокол не выдаёт секрет. На нём построены проверенный компилятор CompCert, библиотеки математики Mathematical Components и криптографические реализации HACL*.

Порог входа высокий: нужно привыкнуть к зависимым типам и к тому, что доказательство — это программа. Зато результат не стареет: доказанное свойство остаётся верным, пока не изменились формулировка и аксиомы.

Установка

Проще всего поставить через opam — менеджер пакетов OCaml, на котором написан сам Coq. Отдельные пакеты есть в Debian, Ubuntu и Fedora, но версия в репозиториях часто отстаёт.

opam init
opam switch create coq-env ocaml-base-compiler.4.14.2
opam install coq coqide

Для работы в редакторе есть несколько вариантов: CoqIDE идёт в комплекте, Proof General работает в Emacs, VsCoq — расширение для VS Code, Coqtail — для Vim. Все они общаются с одним и тем же ядром, разница только в удобстве.

coqc --version
coqtop

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

Первое доказательство

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

Require Import Arith.
Require Import Lia.

Theorem plus_comm_example : forall n m : nat, n + m = m + n.
Proof.
  intros n m.
  lia.
Qed.

Тактика intros вводит переменные из цели, lia решает линейную арифметику. Для более сложных утверждений придётся разбирать структуру: induction по n, simpl для вычислений, rewrite для подстановки равенств.

Проверить, что доказательство принято, можно командой Print plus_comm_example. Coq покажет терм — иногда он выглядит устрашающе, но это нормально: терм строит машина, а не человек.

Тактики и структура доказательства

Доказательство в Coq — последовательность тактик между Proof и Qed. Qed проверяет терм и делает его непрозрачным; Defined оставляет тело видимым, что нужно, если доказательство потом вычисляется.

  • intros — вводит предпосылки и переменные.
  • apply — применяет гипотезу или лемму к цели.
  • rewrite — заменяет подвыражение по равенству.
  • induction и destruct — разбирают случаи и индукцию.
  • simpl и compute — упрощают и вычисляют.
  • split, exists, constructor — работают с конъюнкцией и кванторами.
  • auto, lia, ring — автоматические решатели для своих областей.

Стиль имеет значение. Длинное доказательство без промежуточных утверждений трудно сопровождать; используйте assert или have, чтобы зафиксировать локальный факт с понятным именем.

Списки и индукция

Библиотека списков подключается из стандартной поставки. Нотации включаются отдельно, иначе квадратные скобки не разбираются.

From Coq Require Import List.
Import ListNotations.

Lemma app_nil_r : forall (A : Type) (xs : list A), xs ++ [] = xs.
Proof.
  intros A xs.
  induction xs as [| x rest IH].
  - reflexivity.
  - simpl. rewrite IH. reflexivity.
Qed.

Здесь видно типичный каркас: индукция даёт два случая, для пустого списка работает reflexivity, для шага — simpl и применение гипотезы индукции. Именно так доказывается большинство свойств рекурсивных функций.

Сборка проекта

Для одного файла хватает coqc, но проект из десятков файлов собирают через coq_makefile. Файл _CoqProject задаёт логические пути и порядок компиляции.

coq_makefile -f _CoqProject -o Makefile
make
make install

В _CoqProject указываются флаги -Q для привязки каталога к логическому имени и список файлов. Без -Q импорт между файлами не найдёт библиотеку, и вы получите ошибку «Cannot find library».

-Q src MyProject
src/Util.v
src/Main.v

Для непрерывной интеграции есть официальные Docker-образы; сборка в контейнере полезна, когда версия Coq должна совпадать у всех участников.

Извлечение кода

Одна из сильных сторон — извлечение проверенных функций в OCaml, Haskell или Scheme. Вы пишете и доказываете на Coq, а исполняемый код генерируется автоматически.

Require Import Extraction.
Extraction Language OCaml.
Extraction plus.

Важно помнить о границе доверия: извлечённый код полагается на рантайм целевого языка, целые числа и ввод-вывод. Доказательство относится к функциональной части, а не к операционной системе, на которой код запущен.

Отладка доказательств

Ошибки типов в Coq многословны, но информативны. Первое, что стоит сделать, — включить полную печать: Set Printing All показывает все неявные аргументы и нотации в развёрнутом виде.

  • «Cannot find library» — проверьте флаги -Q и -R, порядок файлов в _CoqProject.
  • «Expected a proof of…» — цель не совпала с тем, что вы применяете; смотрите на неявные аргументы.
  • Тактика не срабатывает — проверьте, не раскрыто ли определение; поможет unfold или cbv.
  • Доказательство долго проверяется — упростите терм, уберите compute и лишние simpl.

Команды Check, Print, Search и Locate экономят часы: Check показывает тип, Search ищет леммы по шаблону, Locate находит определение по имени. Show Proof выводит текущий терм доказательства.

Ограничения и здравый смысл

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

Начинайте с малого: одна функция, одно свойство, одно доказательство. Через неделю вы будете читать чужие формализации, а через месяц — писать свои без страха перед словом «индукция».

Итог

Coq, а теперь и Rocq, — инструмент для тех, кому нужна уверенность сильнее тестов. Он требует времени и аккуратности, зато даёт машинно проверяемое доказательство, которое не зависит от настроения ревьюера. Начните с opam, coqtop и простой теоремы о сложении, затем перейдите к спискам и сборке через coq_makefile. Извлечение кода в OCaml покажет, что формальная математика вполне пригодна для практических программ.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте