SlideShare ist ein Scribd-Unternehmen logo
1 von 39
Downloaden Sie, um offline zu lesen
Coq とは ?
Coq はINRIA (フランス国立情報学自動制御研究所) によって開発されている定理証
明支援系である.Coq は,表現力の高い型をもつラムダ計算であるCalculus of
Inductive Constructions と呼ばれる計算体系に基づいている(以後,「項」はCoq の
型システムにより拡張されたラムダ項を指すものとする).型や関数を自ら定義すること
により,関数型プログラミング言語として用いることができる. また,Curry-Howard 対
応により,命題に対応づけられる型をもつ項を構成することにより,証明を構成すること
ができる.Coq の型システムは依存型をもち,関数をはじめとした項をパラメータとし
て取る型を定義することにより,述語を表現することができる.さらに,それら述語を
tactic と呼ばれる言語を用いて対話的に証明することが可能である.

                 ( “定理証明支援系Coqを用いたプログラム運算” より引用 )
Coq とは ?
 「定理証明支援系」と呼ばれる物
 関数型言語の文法で定義や関数を記述する事ができる
 命題や関数に対して対話的に自然演繹をベースとした
  証明を構築する事ができる
 内部で定義した関数を他の言語で書き出す事ができる
 関数の性質を証明しながらプログラムが作れるので安全
 なプログラムが書ける!!
自然演繹
 「自然な」証明体系をモデルとして提供する証明論理の
  手法
 単純な規則を組み合わせる事により証明を構築していく



      OR記号(∨)の交換法則の証明
                    ������           ������
       [������ ∨ ������] ������ ∨ ������ ∨ ������ ������ ∨ ������ (∨ ������)
                                             (∨ ������)
                       ������ ∨ ������                      (⇒ ������)
                    ������ ∨ ������ ⇒ ������ ∨ ������
                          藤田先生の講義資料がわかりやすいよ!
規則の一部
������ ������          ������ ∧ ������               ������ ∧ ������
        ∧ ������           ∧ ������                  ∧ ������
������ ∧ ������          ������                     ������

                                         ������     [������]
   ������             ������            ������ ∨ ������ ⋮         ⋮
        ∨ ������           ∨ ������              ������      ������ ∨ ������
������ ∨ ������        ������ ∨ ������                 ������
  [������]
    ⋮
   ������          ������ ⇒ ������   ������                ¬������ ������
        ⇒ ������                  ⇒ ������                ¬������
������ ⇒ ������            ������                         ������
例:ド・モルガンの法則
 ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������) の証明




    注) 「⊥」は矛盾を示す定数, 「¬P」は「P⇒⊥」の略記
例:ド・モルガンの法則
                                     ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������) の証明
        2          1           3          1
   ������        ¬������          ������        ¬������
                                                          5
            ⊥                      ⊥          ¬������ ∨ ¬������
                                                              1
                           ⊥
                                     2
                          ������ ⇒⊥ 3       ������ ∧ ������ 4                 4
                       ������ ⇒ ������ ⇒⊥          ������       ������ ∧ ������
                                ������ ⇒⊥                   ������
                                            ⊥     4
                                       ¬(������ ∧ ������)          5
                                 ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������)


   注) 「⊥」は矛盾を示す定数, 「¬P」は「P⇒⊥」の略記
勿論手作業でもできるけど…
 さっきみたいなちょっとした定理でも証明の方法を自力で
考えるのは辛い
 系そのものが単純だからこそ大掛かりな証明は非常にプ
ロセスが多くなる
 そんなプロセスが多い証明なんかしたら間違いや抜けが
あるかもしれない!!
閑話休題
(関数型)プログラミングの話
• データは全て「型」を持っている
• 関数の型は typeA→typeB と表される
 • a→bなる関数に型aのデータを渡すと
   全体の型はbである
(関数型)プログラミングの話
• データは全て「型」を持っている
• 関数の型は typeA→typeB と表される
 • a→bなる関数に型aのデータを渡すと
   全体の型はbである
 • 「もしFがa->bの型をもっていて, Nがaの型
   をもっていたらFNの型はbである」

        ������: ������ → ������      ������: ������
               ������������ ∶ ������
ラムダ抽象
 今度は「a→bなる形を持つ関数とは何か」を考える
 「仮に型がaであるデータxがあり, それを元にした
計算結果の型がbであるならば, その計算Mは(xの内
容に関わらず)a→bの型を持っている」

               [������: ������]
                  ⋮
                ������: ������
         ������������. ������: ������ → ������
完全に一致
         ������: ������                     [������]
           ⋮                          ⋮
         ������: ������     (������������������)         ������   ⇒ ������
  ������������. ������: ������ → ������               ������ ⇒ ������

������: ������ → ������      ������: ������          ������ ⇒ ������   ������
                        (������������������)                ⇒ ������
       ������������ ∶ ������                     ������
カリー・ハワード同型対応
 難しい話を色々すっ飛ばすと, 以下の事柄は見事に対応
しているらしい.
     型付きラムダ計算    自然演繹
        型         命題
      抽象規則      ⇒の導入規則

      適応規則      ⇒の除去規則

      プログラム       証明

      ベータ簡約      証明の簡約
Coqことはじめ
 Coq公式ページ ( http://coq.inria.fr/ ) からインストー
  ラーをダウンロードできる
 実行するとCoq本体と「Coq IDE」というGUI環境がインス
  トールされる
[������]
Coqでの証明の例     ������ ⇒ ������
        • 線が引いてあるのがユー
         ザーの入力
        • 途中に現れている出力が前
         提(既知の部分)と目標(未
         知の部分)を示している
         (IDEだと入力エリアの横に
         表示される)
Coqでの証明の手順
 証明したい物をCoqに宣言する
 宣言した物を「目標」として証明モードに入る
 目標と前提に対して「導入」と「除去」という操作をくりかえして
 証明を行う
  導入
   目標を使って前提を追加する操作(仮定を立てる事に相当)
  除去
   前提を使って目標を変形する動作(仮定を除去する事に相当)
 名前をつけていれば後からその定理を別の証明で使用する
 事ができる
操作の例(一部)
intro         → , ~ , ∀に対しての導入   “forall P : …” や
                                 “A → …”の前半を前提に追加
intros        可能な限りintroを実行する
                                 し後半を新たな目標とする
apply (H P)   →, ∀に対しての除去        目標の中のPに定理Hを適応した
                                 物を新たな目標とする
case H        ∨, ∧に対しての除去        P∨QなるHと目標GからP→Gと
                                 Q→Gの2つを新たな目標にする
                                 HがP∧Qの場合は P→Q→Gを新た
                                 な目標にする
destruct H                       caseと同じ働きだがHを前提から
                                 消去しintrosを行う
rewrite H     = (等号)に対しての除去      等号を含んでいる定理Hを用いて
                                 目標を書き換える
unfold f      関数の展開              目標の中の関数fを定義式に書き
                                 換える
基本的な方針
                   前提に以下の物がある時
H:forall X, A->B        目標がBであれば apply H
H:~A                   目標がFalseであれば apply H
H:A∧B                     case H, destruct H
H:A∨B

                   目標に以下の物がある時
forall X, A                 intro, intros
A->B
~A                          intro, unfold
その他                  SerchPattern という命令が存在する.
                   コレを使えば使えそうな定理を探す事ができる


       これらを繰り返す事で機械的に証明を行う事ができる
証明の例
 ∧, ∨の交換法則
 ド・モルガンの定理
 ������ ⇒ ������ ⇒ ������ ⇒ ������ ⇒ (������ ⇒ ������)
 ������ ∨ ¬������ ⇒ ¬¬������ ⇒ ������
∨の交換法則
                   2     ������ 1         ������ 1
         ������ ∨ ������       ������ ∨ ������ ∨ ������ ������ ∨ ������ ∨ ������ (∨ ������1 )
                            ������ ∨ ������                       (⇒ ������ 2 )
                          ������ ∨ ������ ⇒ ������ ∨ ������
Fact orsw : forall (A B:Prop), A∨B->B∨A. (*宣言*)
intros.
case H.           (* H:A∨B から A→B∨A と B→B∨A を目標とする*)
intro.
apply or_intror.        (* or_intror : forall A B:Prop, B->A∨B *)
apply H0.               (* H0:A *)
intro.
apply or_introl.        (* or_introl : forall A B:Prop, A->A∨B *)
apply H0.
Qed.
∧の交換法則
                    ������ ∧ ������ 1 ������ ∧ ������ 1
                        ������         ������
                           ������ ∧ ������      (⇒ ������1 )
                     ������ ∧ ������ ⇒ ������ ∧ ������
Goal forall (P Q:Prop), P∧Q->Q∧P.
intros.
case H.         (* H:P∧Q *)
intros.
apply conj.     (* conj:forall A B:Prop, A→B→A∧B *)
apply H1.
apply H0.
Qed.
ド・モルガンの法則
                                      2          1           3          1
                                 ������        ¬������          ������        ¬������
                                          ⊥                      ⊥                      5
                                                                            ¬������ ∨ ¬������
                                                                                            1
                                                          ⊥
                                                                   2
Goal forall (P Q:Prop), ~P∨~Q -> ~(P∧Q).                ������ ⇒⊥         ������ ∧ ������ 4
intros.                                              ������ ⇒ ������ ⇒⊥
                                                                 3
                                                                         ������        ������ ∧ ������ 4
intro.                                                        ������ ⇒⊥                   ������
case H0.        (* H0:P∧Q *)                                              ⊥     4
intros.                                                              ¬(������ ∧ ������)          5
case H.         (* H:¬P∨¬Q *)                                  ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������)
intro.
apply H3.       (* H3:¬P *)
apply H1.       (* H1:P *)
intro.
apply H3.
apply H2.       (*H2:Q*)
Qed.
三段論法的な何か
������ ⇒ ������ 3   ������   1
                 (⇒ ������)    [������ ⇒ ������]2
       ������                             (⇒ ������)
                  ������                         ⇒ ������1
                   ������ ⇒ ������                                ⇒ ������ 2
                ������ ⇒ ������ ⇒ ������ ⇒ ������
                                                                   (⇒ ������ 3 )
             ������ ⇒ ������ ⇒ ������ ⇒ ������ ⇒ ������ ⇒ ������

      Goal forall (A B C:Prop), (B->C)->(A->B)->(A->C).
      intros.
      apply H.
      apply H0.
      apply H1.
      Qed.
背理法                     2          1
                  ¬������       ¬¬������
                         ⊥
         ������ 2
                         ������       ⇒ ������ 1 ������ ∨ ¬¬������ 3
       ¬¬������ ⇒ ������     ¬¬������ ⇒ ������                       (⇒ ������2 )
                      ¬¬������ ⇒ ������
                                     (⇒ ������3 )
                 ������ ∨ ¬������ ⇒ ¬������ ⇒ ������

Goal forall (A:Prop), A∧~A -> ~~A -> A.
unfold not.
intros.
destruct H.
apply H.
apply False_ind.    (* False_ind: forall P : Prop, False -> P *)
apply H0.
apply H.
Qed.
         ※この証明では背理法の妥当性そのものは証明できていない事に注意!
その他有用なコマンド
assert P           命題Pを新たな目標として追加する

cut P              命題Pを新たな目標として追加した上で現在の目標Gを P→Gに書き換える

discriminate       前提に間違った等式(「2=3」等)がある場合直ちに全体を真とする

replace a with b   目標のaをbに変えた上で「b=a」を新たな目標として追加する

simpl              目標の式をベータ簡約する

simpl in H         前提Hをベータ簡約する

auto               可能な限り自動で証明を行う
tauto
Require Import M   モジュールMで定義されている物を使用可能にする


 実はさっきの例程度の証明だったら tauto というコマンド
  で自動的にやってくれる
「プログラム」の書き方
     早う
関数とデータ型の定義
Inductive name : Type :=
                                           データ型の定義
         cName:Type [ | cName:type ]*
Definition name : [param]* : Type := exp   非再帰関数や定理の定義
                                           (停止性が明らかな)再帰関数の
Fixpoint name : [param]* : Type := exp
                                           定義
                                           (停止性が明らかでない)再帰関
Function name : [param]*
                                           数の定義(Recdefのインポートが
        {measure exp1} : Type := exp2
                                           必要)

     「measure exp1」の exp1 にはこの関数が停止する根拠を書かな
     ければいけない. Functionで関数を定義しようとすると即座に停
     止性についての証明が要求される
定義の例 : リストとその演算
Inductive list (A : Type) : Type :=
 | nil : list A
 | cons : A -> list A -> list A.

Fixpoint app (A : Type)(l l' : list A) : list A :=
  match l with
  | nil => l'
  | cons x xs => cons x (app A xs l')
  end.



      match v with … end
      vについてのパターンマッチをするための構文
定義の例 : 自然数とその演算
                                     module Plus where
Inductive nat : Set :=
  | O : nat
                                     import qualified Prelude
  | S : nat -> nat.
                                     data Nat =
Fixpoint plus (n m : nat) : nat :=
                                        O
  match n with
                                      | S Nat
  | O => m
  | S p => S (plus p m)
                                     plus :: Nat -> Nat -> Nat
  end.
                                     plus n m =
            Coqでの定義                    case n of {
                                        O -> m;
                                        S p -> S (plus p m)}
                                         (Haskell用に出力した場合)
帰納法を用いた証明
 証明に帰納法を用いる時は induction という操作を行う
   「induction x」 とすると, 目標の中のxに対して適切
    な帰納法の目標を設定してくれる
   list の場合は 「P:list A→Prop」に対して「P(nil)」と
    「∀x xs ,P(xs)→P(x:xs)」を目標にしてくれる
l++nil=l の証明
Require Import List.
        (* listについての演算子等が定義されてる *)
Theorem app_zero : forall (A:Type)(l:list A), l++nil=l.
intros.        (* 目標が l ++ nil = l になる *)
induction l.
simpl.         (* 目標の式をベータ簡約する操作 *)
reflexivity. (* 目標が正しい等式の時に証明を完了する *)
simpl.
apply (f_equal (cons a)).
(*
        f_equal : forall (A B : Type) (f : A -> B) (x y : A),
               x = y -> f x = f y
*)
apply IHl.
Qed.
n+0 = n の証明
Goal forall ( n:nat ),n+0 = n.
intros.
induction n.
reflexivity. (* 目標が等式の時に証明を完了する *)
simpl.        (* 目標の式をベータ簡約する操作 *)
f_equal.
apply IHn.
Qed.
negb   : bool→bool

クイックソート                         leb    : nat→nat→bool
                                filter : (A→bool)→list A→list A

Requie Import List.
Fixpoint qsort (l:list nat):list nat:=
 match l with
       | nil => nil
       | x::xs => qsort (filter (leb x) xs) ++
              (x::nil)++
              qsort (filter (fun t=>negb(leb x t)) xs)
 end.
 クイックソートを定義しようとしてこのように定義しても受け
  付けてくれない
 この表記だと再帰部分のリストが引数より小さくなっている
  事が直ちに保証できない
クイックソートの定義部分
Function qsort (l:list nat) {measure length l} : list nat :=
  match l with
  | nil => nil
  | x :: xs => qsort (filter (leb x) xs)
               ++ (x ::nil)++
               qsort (filter (fun t=>negb(leb x t)) xs)
end.

 定義部分はFunctionを用いてこのようになる
 この入力の直後に再帰部分に対して length l が確かに
  小さくなる事について証明を求められるが…
補助定理の証明
Lemma fil_len : forall (l:list nat) (p:nat->bool),
  length (filter p l) <= length l.
intros.
induction l.
unfold length.
auto.
simpl.
case (p a).          その前にこのような定理を証明して
simpl.                おく
apply le_n_S.
apply IHl.           フィルタ関数に通したリストは長さが
auto.                 必ず元のリスト以下になっている事の
Qed.                  証明
停止性の証明
Function qsort (l : list nat) {measure length l} : list
nat :=
        (中略)
end.

intros.
simpl.
apply le_n_S.           先の定理(fil_len)を定義した後に関
apply fil_len.           数の定義をする
intros.
                        intros からが停止性の証明の部分
simpl.
apply le_n_S.           ここまでやって初めてクイックソートが
apply fil_len.           定義できる
Defined.
参考資料
 Yves Bertot. Coq in a hurry.
 池淵未来. プログラミングCoq
  (http://www.iij-ii.co.jp/lab/techdoc/coqt/)
 Gerard Huet and Christine Paulim Mohring.
  Interactive Theorem Proving and Program
  Development

Weitere ähnliche Inhalte

Was ist angesagt?

プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
Takuya Akiba
 
「型の理論」と証明支援システム -- COQの世界
「型の理論」と証明支援システム -- COQの世界「型の理論」と証明支援システム -- COQの世界
「型の理論」と証明支援システム -- COQの世界
maruyama097
 

Was ist angesagt? (20)

プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
 
Parser combinatorってなんなのさ
Parser combinatorってなんなのさParser combinatorってなんなのさ
Parser combinatorってなんなのさ
 
証明プログラミング超入門
証明プログラミング超入門証明プログラミング超入門
証明プログラミング超入門
 
自動定理証明の紹介
自動定理証明の紹介自動定理証明の紹介
自動定理証明の紹介
 
「型の理論」と証明支援システム -- COQの世界
「型の理論」と証明支援システム -- COQの世界「型の理論」と証明支援システム -- COQの世界
「型の理論」と証明支援システム -- COQの世界
 
Coqチュートリアル
CoqチュートリアルCoqチュートリアル
Coqチュートリアル
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
Scala 初心者が米田の補題を Scala で考えてみた
Scala 初心者が米田の補題を Scala で考えてみたScala 初心者が米田の補題を Scala で考えてみた
Scala 初心者が米田の補題を Scala で考えてみた
 
Union find(素集合データ構造)
Union find(素集合データ構造)Union find(素集合データ構造)
Union find(素集合データ構造)
 
定理証明支援系Coqについて
定理証明支援系Coqについて定理証明支援系Coqについて
定理証明支援系Coqについて
 
Marp入門
Marp入門Marp入門
Marp入門
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
ベイズ推定の概要@広島ベイズ塾
ベイズ推定の概要@広島ベイズ塾ベイズ推定の概要@広島ベイズ塾
ベイズ推定の概要@広島ベイズ塾
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
 
2018年01月27日 TensorBoardによる学習の可視化
2018年01月27日 TensorBoardによる学習の可視化2018年01月27日 TensorBoardによる学習の可視化
2018年01月27日 TensorBoardによる学習の可視化
 
Katib
KatibKatib
Katib
 
実用Brainf*ckプログラミング
実用Brainf*ckプログラミング実用Brainf*ckプログラミング
実用Brainf*ckプログラミング
 

よくわかるCoqプログラミング

  • 1.
  • 2. Coq とは ? Coq はINRIA (フランス国立情報学自動制御研究所) によって開発されている定理証 明支援系である.Coq は,表現力の高い型をもつラムダ計算であるCalculus of Inductive Constructions と呼ばれる計算体系に基づいている(以後,「項」はCoq の 型システムにより拡張されたラムダ項を指すものとする).型や関数を自ら定義すること により,関数型プログラミング言語として用いることができる. また,Curry-Howard 対 応により,命題に対応づけられる型をもつ項を構成することにより,証明を構成すること ができる.Coq の型システムは依存型をもち,関数をはじめとした項をパラメータとし て取る型を定義することにより,述語を表現することができる.さらに,それら述語を tactic と呼ばれる言語を用いて対話的に証明することが可能である. ( “定理証明支援系Coqを用いたプログラム運算” より引用 )
  • 3. Coq とは ?  「定理証明支援系」と呼ばれる物  関数型言語の文法で定義や関数を記述する事ができる  命題や関数に対して対話的に自然演繹をベースとした 証明を構築する事ができる  内部で定義した関数を他の言語で書き出す事ができる  関数の性質を証明しながらプログラムが作れるので安全 なプログラムが書ける!!
  • 4. 自然演繹  「自然な」証明体系をモデルとして提供する証明論理の 手法  単純な規則を組み合わせる事により証明を構築していく OR記号(∨)の交換法則の証明 ������ ������ [������ ∨ ������] ������ ∨ ������ ∨ ������ ������ ∨ ������ (∨ ������) (∨ ������) ������ ∨ ������ (⇒ ������) ������ ∨ ������ ⇒ ������ ∨ ������ 藤田先生の講義資料がわかりやすいよ!
  • 5. 規則の一部 ������ ������ ������ ∧ ������ ������ ∧ ������ ∧ ������ ∧ ������ ∧ ������ ������ ∧ ������ ������ ������ ������ [������] ������ ������ ������ ∨ ������ ⋮ ⋮ ∨ ������ ∨ ������ ������ ������ ∨ ������ ������ ∨ ������ ������ ∨ ������ ������ [������] ⋮ ������ ������ ⇒ ������ ������ ¬������ ������ ⇒ ������ ⇒ ������ ¬������ ������ ⇒ ������ ������ ������
  • 6. 例:ド・モルガンの法則 ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������) の証明 注) 「⊥」は矛盾を示す定数, 「¬P」は「P⇒⊥」の略記
  • 7. 例:ド・モルガンの法則 ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������) の証明 2 1 3 1 ������ ¬������ ������ ¬������ 5 ⊥ ⊥ ¬������ ∨ ¬������ 1 ⊥ 2 ������ ⇒⊥ 3 ������ ∧ ������ 4 4 ������ ⇒ ������ ⇒⊥ ������ ������ ∧ ������ ������ ⇒⊥ ������ ⊥ 4 ¬(������ ∧ ������) 5 ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������) 注) 「⊥」は矛盾を示す定数, 「¬P」は「P⇒⊥」の略記
  • 10. (関数型)プログラミングの話 • データは全て「型」を持っている • 関数の型は typeA→typeB と表される • a→bなる関数に型aのデータを渡すと 全体の型はbである
  • 11. (関数型)プログラミングの話 • データは全て「型」を持っている • 関数の型は typeA→typeB と表される • a→bなる関数に型aのデータを渡すと 全体の型はbである • 「もしFがa->bの型をもっていて, Nがaの型 をもっていたらFNの型はbである」 ������: ������ → ������ ������: ������ ������������ ∶ ������
  • 12. ラムダ抽象  今度は「a→bなる形を持つ関数とは何か」を考える  「仮に型がaであるデータxがあり, それを元にした 計算結果の型がbであるならば, その計算Mは(xの内 容に関わらず)a→bの型を持っている」 [������: ������] ⋮ ������: ������ ������������. ������: ������ → ������
  • 13. 完全に一致 ������: ������ [������] ⋮ ⋮ ������: ������ (������������������) ������ ⇒ ������ ������������. ������: ������ → ������ ������ ⇒ ������ ������: ������ → ������ ������: ������ ������ ⇒ ������ ������ (������������������) ⇒ ������ ������������ ∶ ������ ������
  • 14. カリー・ハワード同型対応  難しい話を色々すっ飛ばすと, 以下の事柄は見事に対応 しているらしい. 型付きラムダ計算 自然演繹 型 命題 抽象規則 ⇒の導入規則 適応規則 ⇒の除去規則 プログラム 証明 ベータ簡約 証明の簡約
  • 15. Coqことはじめ  Coq公式ページ ( http://coq.inria.fr/ ) からインストー ラーをダウンロードできる  実行するとCoq本体と「Coq IDE」というGUI環境がインス トールされる
  • 16. [������] Coqでの証明の例 ������ ⇒ ������ • 線が引いてあるのがユー ザーの入力 • 途中に現れている出力が前 提(既知の部分)と目標(未 知の部分)を示している (IDEだと入力エリアの横に 表示される)
  • 17. Coqでの証明の手順  証明したい物をCoqに宣言する  宣言した物を「目標」として証明モードに入る  目標と前提に対して「導入」と「除去」という操作をくりかえして 証明を行う  導入 目標を使って前提を追加する操作(仮定を立てる事に相当)  除去 前提を使って目標を変形する動作(仮定を除去する事に相当)  名前をつけていれば後からその定理を別の証明で使用する 事ができる
  • 18. 操作の例(一部) intro → , ~ , ∀に対しての導入 “forall P : …” や “A → …”の前半を前提に追加 intros 可能な限りintroを実行する し後半を新たな目標とする apply (H P) →, ∀に対しての除去 目標の中のPに定理Hを適応した 物を新たな目標とする case H ∨, ∧に対しての除去 P∨QなるHと目標GからP→Gと Q→Gの2つを新たな目標にする HがP∧Qの場合は P→Q→Gを新た な目標にする destruct H caseと同じ働きだがHを前提から 消去しintrosを行う rewrite H = (等号)に対しての除去 等号を含んでいる定理Hを用いて 目標を書き換える unfold f 関数の展開 目標の中の関数fを定義式に書き 換える
  • 19. 基本的な方針 前提に以下の物がある時 H:forall X, A->B 目標がBであれば apply H H:~A 目標がFalseであれば apply H H:A∧B case H, destruct H H:A∨B 目標に以下の物がある時 forall X, A intro, intros A->B ~A intro, unfold その他 SerchPattern という命令が存在する. コレを使えば使えそうな定理を探す事ができる これらを繰り返す事で機械的に証明を行う事ができる
  • 20. 証明の例  ∧, ∨の交換法則  ド・モルガンの定理  ������ ⇒ ������ ⇒ ������ ⇒ ������ ⇒ (������ ⇒ ������)  ������ ∨ ¬������ ⇒ ¬¬������ ⇒ ������
  • 21. ∨の交換法則 2 ������ 1 ������ 1 ������ ∨ ������ ������ ∨ ������ ∨ ������ ������ ∨ ������ ∨ ������ (∨ ������1 ) ������ ∨ ������ (⇒ ������ 2 ) ������ ∨ ������ ⇒ ������ ∨ ������ Fact orsw : forall (A B:Prop), A∨B->B∨A. (*宣言*) intros. case H. (* H:A∨B から A→B∨A と B→B∨A を目標とする*) intro. apply or_intror. (* or_intror : forall A B:Prop, B->A∨B *) apply H0. (* H0:A *) intro. apply or_introl. (* or_introl : forall A B:Prop, A->A∨B *) apply H0. Qed.
  • 22. ∧の交換法則 ������ ∧ ������ 1 ������ ∧ ������ 1 ������ ������ ������ ∧ ������ (⇒ ������1 ) ������ ∧ ������ ⇒ ������ ∧ ������ Goal forall (P Q:Prop), P∧Q->Q∧P. intros. case H. (* H:P∧Q *) intros. apply conj. (* conj:forall A B:Prop, A→B→A∧B *) apply H1. apply H0. Qed.
  • 23. ド・モルガンの法則 2 1 3 1 ������ ¬������ ������ ¬������ ⊥ ⊥ 5 ¬������ ∨ ¬������ 1 ⊥ 2 Goal forall (P Q:Prop), ~P∨~Q -> ~(P∧Q). ������ ⇒⊥ ������ ∧ ������ 4 intros. ������ ⇒ ������ ⇒⊥ 3 ������ ������ ∧ ������ 4 intro. ������ ⇒⊥ ������ case H0. (* H0:P∧Q *) ⊥ 4 intros. ¬(������ ∧ ������) 5 case H. (* H:¬P∨¬Q *) ¬������ ∨ ¬������ ⇒ ¬(������ ∧ ������) intro. apply H3. (* H3:¬P *) apply H1. (* H1:P *) intro. apply H3. apply H2. (*H2:Q*) Qed.
  • 24. 三段論法的な何か ������ ⇒ ������ 3 ������ 1 (⇒ ������) [������ ⇒ ������]2 ������ (⇒ ������) ������ ⇒ ������1 ������ ⇒ ������ ⇒ ������ 2 ������ ⇒ ������ ⇒ ������ ⇒ ������ (⇒ ������ 3 ) ������ ⇒ ������ ⇒ ������ ⇒ ������ ⇒ ������ ⇒ ������ Goal forall (A B C:Prop), (B->C)->(A->B)->(A->C). intros. apply H. apply H0. apply H1. Qed.
  • 25. 背理法 2 1 ¬������ ¬¬������ ⊥ ������ 2 ������ ⇒ ������ 1 ������ ∨ ¬¬������ 3 ¬¬������ ⇒ ������ ¬¬������ ⇒ ������ (⇒ ������2 ) ¬¬������ ⇒ ������ (⇒ ������3 ) ������ ∨ ¬������ ⇒ ¬������ ⇒ ������ Goal forall (A:Prop), A∧~A -> ~~A -> A. unfold not. intros. destruct H. apply H. apply False_ind. (* False_ind: forall P : Prop, False -> P *) apply H0. apply H. Qed. ※この証明では背理法の妥当性そのものは証明できていない事に注意!
  • 26. その他有用なコマンド assert P 命題Pを新たな目標として追加する cut P 命題Pを新たな目標として追加した上で現在の目標Gを P→Gに書き換える discriminate 前提に間違った等式(「2=3」等)がある場合直ちに全体を真とする replace a with b 目標のaをbに変えた上で「b=a」を新たな目標として追加する simpl 目標の式をベータ簡約する simpl in H 前提Hをベータ簡約する auto 可能な限り自動で証明を行う tauto Require Import M モジュールMで定義されている物を使用可能にする  実はさっきの例程度の証明だったら tauto というコマンド で自動的にやってくれる
  • 28. 関数とデータ型の定義 Inductive name : Type := データ型の定義 cName:Type [ | cName:type ]* Definition name : [param]* : Type := exp 非再帰関数や定理の定義 (停止性が明らかな)再帰関数の Fixpoint name : [param]* : Type := exp 定義 (停止性が明らかでない)再帰関 Function name : [param]* 数の定義(Recdefのインポートが {measure exp1} : Type := exp2 必要) 「measure exp1」の exp1 にはこの関数が停止する根拠を書かな ければいけない. Functionで関数を定義しようとすると即座に停 止性についての証明が要求される
  • 29. 定義の例 : リストとその演算 Inductive list (A : Type) : Type := | nil : list A | cons : A -> list A -> list A. Fixpoint app (A : Type)(l l' : list A) : list A := match l with | nil => l' | cons x xs => cons x (app A xs l') end. match v with … end vについてのパターンマッチをするための構文
  • 30. 定義の例 : 自然数とその演算 module Plus where Inductive nat : Set := | O : nat import qualified Prelude | S : nat -> nat. data Nat = Fixpoint plus (n m : nat) : nat := O match n with | S Nat | O => m | S p => S (plus p m) plus :: Nat -> Nat -> Nat end. plus n m = Coqでの定義 case n of { O -> m; S p -> S (plus p m)} (Haskell用に出力した場合)
  • 31. 帰納法を用いた証明  証明に帰納法を用いる時は induction という操作を行う  「induction x」 とすると, 目標の中のxに対して適切 な帰納法の目標を設定してくれる  list の場合は 「P:list A→Prop」に対して「P(nil)」と 「∀x xs ,P(xs)→P(x:xs)」を目標にしてくれる
  • 32. l++nil=l の証明 Require Import List. (* listについての演算子等が定義されてる *) Theorem app_zero : forall (A:Type)(l:list A), l++nil=l. intros. (* 目標が l ++ nil = l になる *) induction l. simpl. (* 目標の式をベータ簡約する操作 *) reflexivity. (* 目標が正しい等式の時に証明を完了する *) simpl. apply (f_equal (cons a)). (* f_equal : forall (A B : Type) (f : A -> B) (x y : A), x = y -> f x = f y *) apply IHl. Qed.
  • 33. n+0 = n の証明 Goal forall ( n:nat ),n+0 = n. intros. induction n. reflexivity. (* 目標が等式の時に証明を完了する *) simpl. (* 目標の式をベータ簡約する操作 *) f_equal. apply IHn. Qed.
  • 34. negb : bool→bool クイックソート leb : nat→nat→bool filter : (A→bool)→list A→list A Requie Import List. Fixpoint qsort (l:list nat):list nat:= match l with | nil => nil | x::xs => qsort (filter (leb x) xs) ++ (x::nil)++ qsort (filter (fun t=>negb(leb x t)) xs) end.  クイックソートを定義しようとしてこのように定義しても受け 付けてくれない  この表記だと再帰部分のリストが引数より小さくなっている 事が直ちに保証できない
  • 35. クイックソートの定義部分 Function qsort (l:list nat) {measure length l} : list nat := match l with | nil => nil | x :: xs => qsort (filter (leb x) xs) ++ (x ::nil)++ qsort (filter (fun t=>negb(leb x t)) xs) end.  定義部分はFunctionを用いてこのようになる  この入力の直後に再帰部分に対して length l が確かに 小さくなる事について証明を求められるが…
  • 36. 補助定理の証明 Lemma fil_len : forall (l:list nat) (p:nat->bool), length (filter p l) <= length l. intros. induction l. unfold length. auto. simpl. case (p a).  その前にこのような定理を証明して simpl. おく apply le_n_S. apply IHl.  フィルタ関数に通したリストは長さが auto. 必ず元のリスト以下になっている事の Qed. 証明
  • 37. 停止性の証明 Function qsort (l : list nat) {measure length l} : list nat := (中略) end. intros. simpl. apply le_n_S.  先の定理(fil_len)を定義した後に関 apply fil_len. 数の定義をする intros.  intros からが停止性の証明の部分 simpl. apply le_n_S.  ここまでやって初めてクイックソートが apply fil_len. 定義できる Defined.
  • 38.
  • 39. 参考資料  Yves Bertot. Coq in a hurry.  池淵未来. プログラミングCoq (http://www.iij-ii.co.jp/lab/techdoc/coqt/)  Gerard Huet and Christine Paulim Mohring. Interactive Theorem Proving and Program Development