Coq を使った証明 : まとめ

Coq を使った証明 : まとめ
稲葉
今日の内容
型システム
対話的証明環境
Minimal Logic での証明
自動証明探索
Inductive な定義と証明
論理演算子
「=」とreduction
CoInductive な定義と証明
型システム (階層構造)
fun n => n+1 など
nat → nat
Set
[1, 2, 3] など
list nat
Type
P→Q の証明
P→Q
Prop
odd 3 の証明
odd 3
型システム(2つのプリミティブ)
Product ( → )
(P->Q) -> (Q->R) -> (P->R)
 nat -> nat
全称量化命題
Dependent Product ( ∀ )
forall
forall
forall
forall
x:nat,
A:Set,
x:nat,
x:nat,
Set以外に依存した型
odd x -> even (S x)
list A -> list A
int_type_with_bits x
0<x -> nat
多相型
部分関数
型システム(ユーザー定義の型)
Inductive
後述
CoInductive
後述
対話的証明環境 (1)
Theorem 名前 : 命題.
Lemma 名前 : 命題.
Remark 名前 : 命題.
Fact 名前 : 命題.
 …などで証明開始
Qed.
Defined.
 …などで証明おわり。
対話的証明環境 (2)
Restart.
 …で証明を振り出しに戻す
Undo.
 …で1ステップ戻る
Abort.
 …でその定理の証明を破棄
Suspend. と Resume.
 …で、証明を一時中断してTopLevelに帰る
対話型証明環境 (3)
命題Pを型とするtermは、「命題Pの証明」で
あった。
したがって、「命題Pを証明すること」
= 「型Pを持つtermを具体的に構成すること」
「仮定(型環境) ├ t : ゴール」 を満たす
term t を対話的に構築する
Minimal Logic での証明 (1)
Product と Dependent Product のみの場合
使う tactic は、基本的には2つだけ
intro x

H├ A→B
を
H,x:A ├ B
に
apply f

H,f:A→B├B’
を
H,f:A→B├A’
に
Minimal Logic での証明 (2)
intro 変数名
intros 変数名…
ゴールが (Dependent) Product の時、ゴールの前
件を仮定にもってくる
apply 変数名
apply 変数名 with (名:= term)…
(Dependent) Product 型を持つ変数を指定すると、
その後件とゴールをunifyしてゴールを前件に書き
換える
Minimal Logic での証明 (3)
便利機能
 exact H.
 apply H と同じ。Hの型がゴールと完全一致するとき使う
 assumption.
 仮定の中のどれかが exact.
 eapply H.
 unify の結果、束縛が完全に決まらず変数が残ってしま
う場合、エラーとせずに、変数を残してゴールを変形する。
Prolog っぽい動作になる。
Minimal Logic での証明 (4)
便利機能
 cut A
H├ B
を
H├A
と
H├A→B
に
 generalize x
 intro しすぎたときに「戻す」
H,x:A├ B
を
H,x:A ├ A→B
に
 xがBでFreeならDependent, そうでなければ普通の
Product
 generalize (Bのsubterm) という使い方もできる
Minimal Logic での証明 (5)
便利機能
SearchPattern
例: SearchPattern (_ ∧_).
指定したパターンにapply可能な定義のリストを表示
Set Implicit Arguments.
Dependent Product の引数を省略しても推論してくれる
ようになるオプション。
自動証明探索 (1)
auto
「intro」と、「仮定のapply」を使ってひたすら探索
eauto
autoでのapplyの代わりにeapplyを使う
trivial
auto 1. と同じ
各tacticには「コスト」が設定されている。introは0,
仮定のapplyは1, …。
自動証明探索 (2)
auto with ヒントデータベース
仮定だけでなく、ヒントデータベースにある定理の
applyも試みるauto
Hint Resolve 定理名達 : データベース名
データベースの作成
Hint ~ ~ ~ ~
で、apply以外のtacticも探索させられるらしい…
Inductive な定義と証明 (1)
Inductive な型定義
こんな感じ
Inductive nat : Set :=
| O : nat
| S : nat -> nat.
Inductive list (A:Set) : Set :=
| nil : list A
| cons : A -> list A -> list A.
Inductiveな定義と証明 (2)
同時に、帰納法の公理が定義される
Inductive nat : Set :=
| O : nat
| S : nat -> nat.
nat_ind :
forall P: nat -> Prop,
P 0 ->
forall n:nat, (P n -> P (S n)) ->
forall n:nat, P n
Inductive な定義と証明 (3)
Inductive な命題の定義 (同様)
Inductive even : nat->Prop :=
| ev0 : even 0
| ev2 : forall n:nat,
even n -> even (S(S n)).
ev0 は even 0 の証明
ev2 4 (ev2 2 ev0) は even 4 の証明
Inductive な定義と証明 (4)
同時に、帰納法の公理
even_ind :
forall P: nat -> Prop,
P 0 ->
forall n:nat, (even n -> P n -> P SSn) ->
forall n:nat, even n -> P n
Inductive な定義と証明 (5)
基本的に使うtacticは、intro, apply ともう2つ
elim H.
 H は変数名(仮定や定理の証明など)。
 H の型が Inductive T のとき、かなり賢く 「apply
T_ind. 」してくれるtactic
 pattern ; apply T_ind with …; try exact H.
case H.
 T_ind を使わず、単純にInductive定義のコンスト
ラクタごとに場合わけ。「帰納法の仮定」なし
Inductive な定義と証明 (6)
便利機能
 induction H.
 「intro ; intro ; … ; elim H」 と同じ
 intros [H1 H2 H3 …]
 「intro X; case X; intros H1 H2 H3 …」 と同じ
 intros [H1 | H2 | H3 | …]
 「intro X; case X; (intros H1 | intro H2 | …)」 と同じ
Inductive な定義と証明 (7)
 便利機能
 constructor N.
 「apply N番目のコンストラクタ」 と同じ
 split
 「constructor 1」 と同じ (コンストラクタ1個のとき専用)
 left
 「constructor 1」 と同じ (コンストラクタ2個のとき専用)
 right
 「constructor 2」 と同じ (コンストラクタ2個のとき専用)
 exists t
 「constructor 1 with t」 と同じ (1個専用)
Inductive な定義と証明 (8)
便利機能
 discriminate H.
 仮定 H: A = B があって A と B が違うコンストラクタ
 discriminate.
 ゴールが ~(A=B). で A と B が違うコンストラクタ
 injection H.
 H:c x=c y├G を H:c x=c y├x=y→G に
 inversion H.
 H:P x のとき。P xの全ての可能なコンストラクタの前件
を仮定にもってくる。1個もなければ証明終了。
Inductive な定義と証明 (9)
 inversion なしで
~(even 1) の証明
forall n:nat, even n -> n<>1 なら even_ind で
証明できる
 discriminate なしで
 H:0=S 0 ├ False の証明
 (fun n:nat =>
match n with
0->True | S _-> False) (S 0)
= False は証明できる。rewrite。
論理演算子 (1)
 Inductive True : Prop :=
 I : True.
 Inductive False : Prop := .
 Inductive and (A B: Prop) : Prop :=
 conj : A -> B -> and A B
 Inductive or (A B: Prop) : Prop :=
 or_introl : A -> or A B
 or_intror : B -> or A B.
 Inductive ex (A:Type)(P:A->Prop) : Prop :=
 ex_intro : forall x:A, P x -> ex A P.
 Inductive eq (A:Type)(x:A) : A->Prop :=
 refl_equal : eq A x x.
論理演算子 (2)
 Definition not (P:Prop) := P->False.
not に関する証明に便利な tactic.
 apply False_ind.
 ゴールをFalseに変える
 absurd P.
 ゴールがFalseのとき、それをPと~Pの2つに変える
 contradiction
 現在の仮定の中から型がFalseのものを探す
「=」とreduction (1)
「H : A = B」 のとき…
rewrite H.
 ゴール内の A を B に置き換える
rewrite <- H.
 ゴール内の B を A に置き換える
実は elim H
rewrite H in H2.
 仮定H2内の A を B に置き換える
「=」とreduction (2)
 unfold t.
 ゴールの subterm t の定義を展開
 unfold t in H.
 仮定の subterm を unfold.
 red.
 ゴールが _→…→_→(c t … t) なら unfold c.
 simpl.
cbv…
lazy…
compute….
がんばってδβιζ変換
 pattern t at 場所.
 ゴールの t をラムダ抽象。tが複数あるときは指定できる
CoInductive な定義と証明 (1)
Inductiveな定義と文法はほぼ同じ
CoInductive Llist (A:Set) : Set :=
| Lnil : Llist A
| Lcons : A -> Llist A -> Llist A.
ただし帰納法のための公理は定義されない
Base Case がなくてもよい
CoInductive な定義と証明 (2)
基本的に使うtacticは、intro, apply と
elim, induction は使えない
case, discriminate, injection, inversion は
使える
cofix
現在の(CoFixpointな述語による)ゴールを、そのま
ま仮定部にコピーする。ただし、その仮定は「apply
コンストラクタ」の直下でしか使えない