Интернет магазин китайских планшетных компьютеров



Компьютеры - Coq - Примеры

01 мая 2011


Оглавление:
1. Coq
2. Примеры
3. Инструменты
4. Язык
5. Библиотеки и приложения



Ассоциативность композиции функций

Доказательство «на бумаге».

 \circ h

= \lambda x. ; δ-эквивалентность

= \lambda x.) ; δ-эквивалентность

= \lambda x.)) ; β-эквивалентность

f \circ

= \lambda x. f~x) ; δ-эквивалентность

= \lambda x. f)~x) ; δ-эквивалентность

= \lambda x. f) ; β-эквивалентность

По транзитивности равенства

 \circ h = f \circ

Доказательство в Coq.

 Definition cf := fun t0 t1 t2 : Type
   => fun => fun x => f.
 Implicit Arguments cf.
 Notation "f @ g" :=.
 
 Definition cf_assoc := fun
  
   => : @ h = f @.

cf — определение композиции функций. Notation вводит инфиксное обозначение @ для композиции функций.

cf_assoc — собственно доказательство. Coq основан на изоморфизме Карри-Говарда, поэтому доказательство есть терм лямбда-исчисления.

fun … => … в Coq обозначает лямбда-абстракцию. Функциям даются имена f, g, h, а их областям определения и областям значений даются имена t0, t1, t2, t3.

Кроме лямбда-абстракции доказательство состоит из refl_equal — аксиомы рефлексивности равенства. Нам нужно привести левую и правую части равенства с помощью βδ-редукций к одному выражению. Coq сам выполняет βδ-редукцию, поэтому доказательство практически пустое.

Чтобы понять роль refl_equal, выполните Check. Coq покажет автоматически выведенный тип этого терма, а именно, 2 = 2. Но в доказательстве cf_assoc аргумент refl_equal заменён на подчёркивание. Coq сам может вывести этот аргумент. Это сокращает объём доказательства. Выполнив Print cf_assoc., можно убедиться, что Coq вывел терм @ h вместо подчёркивания.

Коммутативность умножения в арифметике Пеано

Тип натуральных чисел определён в стандартной библиотеке так:

 Inductive nat : Set :=
   | O : nat
   | S : nat -> nat.

O есть ноль и S есть функция, возвращающая следующее число.

Необходимо доказать, что n \cdot m = m \cdot n. Доказательство строится с помощью математической индукции по одному из множителей.

Доказательство «на бумаге»

Будут использоваться обозначения, принятые в Coq, чтобы было легче сопоставить оба доказательства.

Выполним индукцию по n.

База индукции: доказать O \cdot m = m \cdot O. Высказывание O \cdot m = O следует из βδι-преобразования. O = m \cdot O доказывается отдельной леммой.

Шаг индукции: имея индуктивную гипотезу n \cdot m = m \cdot n, доказать  \cdot m = m \cdot. Из βδι-преобразования следует  \cdot m = m + n \cdot m. Имеется лемма, которая утверждает m \cdot n + m = m \cdot. Используем коммутативность сложения и индуктивную гипотезу.

Доказательство в Coq

Следующее доказательство скопировано с небольшими изменениями из стандартной библиотеки. Оно использует тактики.

Тактика автоматически генерирует доказательство, опираясь на цель. Конечно, должен существовать алгоритм поиска доказательства. В некоторых случаях тактики могут сильно уменьшить объём доказательства.

Чтобы использовать тактики, необходимо после Definition указать тип, но опустить лямбда-терм, то есть само доказательство. Тогда Coq переходит в «proof editing mode», где можно построить доказательство с помощью тактик.

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

«Proof editing mode» не запрещает строить доказательство как лямбда-терм. Тактика refine доказать цель с помощью указанного после refine лябмда-терма. refine имеет следующую дополнительную возможность: если в лябмда-терме вместо некоторых подтермов стоит подчёркивание и Coq не может вывести значение подтермов автоматически, то это подчёркивание генерирует подцель. Таким образом, refine может генерировать произвольное количество подцелей.

 Require Import Coq.Arith.Plus.
 
 Definition mult_comm : forall n m, n * m = m * n.
 Proof.
 intros. elim n.
 auto with arith.
 intros. simpl in |- *. elim mult_n_Sm. elim H. apply plus_comm.
 Qed.

intros вводит предпосылки. elim применяет математическую индукцию, после чего цель доказательства разбивается на две подцели: база и шаг индукции. auto with arith доказывает базу индукции; тактика auto ищет простым перебором подходящую теорему в базе данных теорем и подставляет её в доказательство. В данном случае она находит лемму mult_n_O. В этом можно убедиться, выполнив Show Proof. При доказательстве шага индукции применяются леммы mult_n_Sm, plus_comm, и индуктивная гипотеза H. Имя индуктивной гипотезы было сгенерировано автоматически тактикой intros, второе вхождение тактики. simpl in |- * выполняет βδι-преобразование цели. Хотя она не генерирует доказательства, но она приводит цель к такому виду, который нужен для вывода аргументов тактикой apply plus_comm.

То же доказательство можно выразить лямбда-термом.

 Definition mult_comm := fun n:nat
 => fix rec
 : n * m = m * n
 := match m as m return n * m = m * n with
   | O => sym_eq
   | S pm => match rec pm in _ = dep return _ = n + dep
     with refl_equal =>
       match mult_n_Sm _ _ in _ = dep return dep = _
       with refl_equal => plus_comm _ _ end
     end
   end.

elim n соответствует fix … match … as …. Остальные elim соответствуют match … in _=dep …. В доказательстве с помощью тактик нет нужды указывать конструкторы O и S, так как они выводятся из nat.

 Definition mult_comm := fun n:nat
 => nat_ind
  )
   (fun _ rec =>
     eq_ind _
    
       _)
     _ rec).

Это более компактная, хотя менее наглядная запись. nat_ind и eq_ind называются принципами индукции и являются функциями, сгенерированными согласно структуре индуктивных типов. Тактики вставляют в доказательство именно эти функции.

Как видно, тактики позволяют опускать множество термов, которые можно вывести автоматически.

Коммутативность умножения в кольце Гротендика

Это пример использования специализированной тактики ring. Она выполняет преобразования формул, построенных из операций полукольца или кольца.

Кольцо Гротендика конструируется из полукольца следующим образом. int_bipart — носитель кольца — есть вторая декартова степень nat — носителя полукольца.

 Record int_bipart : Set := {pneg : nat; ppos : nat}.

Record не только конструирует декартово произведение множеств, но и генерирует левую и правую проекции. Значение i из множества int_bipart можно понимать как решение уравнения x + =, где x — неизвестная величина. Если  >, то решение является отрицательным числом.

Сложение в кольце определено как покомпонентное сложение, то есть pneg левого слагаемого складывается с pneg правого слагаемого, ppos левого слагаемого складывается с ppos правого слагаемого.

 Notation "a !+ b" :=.
 Definition plus a b := Build_int_bipart
  .
 Notation "a + b" :=.

Мы обозначаем сложение в полукольце как «!+» и сложение в кольце как «+».

Умножение определяется так: в часть pneg идут произведения разных компонент, в часть ppos идут произведения одинаковых компонент.

 Notation "a !* b" :=.
 Definition mult a b := Build_int_bipart
  
  .
 Notation "a * b" :=.

Мы обозначаем умножение в полукольце как «!*» и умножение в кольце как «*».

Сначала докажем лемму «если оба компонента int_bipart равны, то int_bipart равны».

 Definition int_bipart_eq_part
   : forall an bn, an = bn -> forall ap bp, ap = bp
   -> Build_int_bipart an ap = Build_int_bipart bn bp.
 Proof.
 refine.
 refine _ _ eqn).
 refine.
 Qed.

Теперь докажем коммутативность умножения в кольце, то есть n * m = m * n.

 Require Import ArithRing.
 
 Definition mult_comm : forall n m, n * m = m * n.
 Proof.
 refine; simpl; ring.
 Qed.

Нужно доказать равенство двух int_bipart. Лемма int_bipart_eq_part разбивает нашу цель на две подцели. Первая подцель есть равенство компонент pneg, вторая подцель есть равенство компонент ppos. Увидеть эти подцели можно, если сразу после Proof. выполнить refine. «;» между refine и означает, что комбинированная тактика доказывает все подцели, генерируемые тактикой refine.

Чтобы доказать «на бумаге», нужно последовательно применить свойства операций полукольца:

 \cdot + \cdot

= \cdot + \cdot ; коммутативность умножения

= \cdot + \cdot ; коммутативность умножения

= \cdot + \cdot ; коммутативность сложения

 \cdot + \cdot

= \cdot + \cdot ; коммутативность умножения

= \cdot + \cdot ; коммутативность умножения

Тактика ring генерирует все эти преобразования автоматически.



Просмотров: 4254


<<<