# HG changeset patch # User ryokka # Date 1581451347 -32400 # Node ID 19ab6b8055ea8f4344972ed3111b1451794e6e86 # Parent e8655e0264b831ac5f5115c4582ae81f367eae61 fix slide diff -r e8655e0264b8 -r 19ab6b8055ea paper/master_paper.pdf Binary file paper/master_paper.pdf has changed diff -r e8655e0264b8 -r 19ab6b8055ea paper/master_paper.tex --- a/paper/master_paper.tex Tue Feb 11 02:31:26 2020 +0900 +++ b/paper/master_paper.tex Wed Feb 12 05:02:27 2020 +0900 @@ -19,7 +19,7 @@ \usepackage{type1cm} \usepackage[usenames]{color} \usepackage{ulem} -\usepackage{lstlinebgrd} +%% \usepackage{lstlinebgrd} \jtitle{Continuation based C での Hoare Logic を用いた仕様記述と検証} %% \etitle{Hoare Logic based Specification and Verification in Continuation based C} diff -r e8655e0264b8 -r 19ab6b8055ea slide/Makefile --- a/slide/Makefile Tue Feb 11 02:31:26 2020 +0900 +++ b/slide/Makefile Wed Feb 12 05:02:27 2020 +0900 @@ -5,7 +5,7 @@ .PHONY : all clean remake all: - slideshow build $(TARGET).md -t s6cr --h2 + slideshow build $(TARGET).md -t s6cr open $(TARGET).html clean: diff -r e8655e0264b8 -r 19ab6b8055ea slide/master-slide.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slide/master-slide.html Wed Feb 12 05:02:27 2020 +0900 @@ -0,0 +1,524 @@ + + + + + + + + + + + + + Continuation Based C の Hoare Logic を用いた仕様記述と検証 - CodiMD + + + + + + + + + + + + + + + + + +

Continuation Based C の Hoare Logic を用いた仕様記述と検証

琉球大学大学院 : 並列信頼研究室
+外間 政尊


OS の検証技術としての Hoare Logic の問題点


Hoare Logic をベースにした Gears 単位での検証


Agda

Agda は関数型言語

    name : type
+    name = value
+

関数には型と定義を与える
+型は : で、 値は = で与える
+仮定なしに使えるのは Set のみ

構成要素としては以下の3種類

    +
  1. 関数 +
      +
    • 型は(A : Set かつ B : Set のとき) A → B
    • +
    • 値は(x : A かつ y : B) λ x → y
    • +
    +
  2. +
  3. record
  4. +
  5. data
  6. +

Agda の record とその例 ∧

導入は2つのものが同時に存在すること

   A   B    
+------------ 
+   A ∧ B    
+

除去は名前を区別する必要がある

   A ∧ B           A ∧ B 
+ --------- pi1   --------- pi2       
+     A               B
+

A ∧ B が成り立っていれば (pi1 A ∧ B) → A、 (pi2 A ∧ B) → B
+Agda ではこのような同時に存在する型を record で書く

   record _∧_ (A B : Set) : Set
+     field
+         pi1 : A
+         pi2 : B
+

_∧_ は中間記法、変数が入る位置を _ で示せる
+実際の構築は x : A かつ y : B のとき

createAnd : (A : Set) → (B : Set) → A ∧ B
+createAnd x y = record {pi1 = x ; pi2 = y}
+

のように記述する
+C 言語での構造体のようなもの

A や B に論理式が入ると2つのものが同時に成り立つ証明ができる


Agda の data とその例 Sum

導入
+一つでも存在すること

        A               B
+  ----------- p1   ---------- p2
+     A ∨ B            A ∨ B  
+

除去
+A → C か B → C のとき C

               A      B
+               :      :
+      A ∨ B    C      C    
+   ------------------------ 
+           C                
+

A ∨ B が成り立っているとき A → A ∨ B、 B → A ∨ B
+どちらかが成り立つ型を data で書く\

    data _∨_ (A B : Set) : Set where
+       p1 : A → A ∨ B
+       p2 : B → A ∨ B
+

のように記述できる
+C 言語での union のようなもの
+p1、 p2 は case 文みたいな感じ


Hoare Logic

Hoare Logic はプログラム検証の手法
+事前条件( P )が成り立つとき、コマンド( C )を実行すると事後条件( Q )が成り立つ

これは { P } C { Q } の形で表され、Hoare Triple と呼ばれる

今回は以下のような while program を検証する

n = 10 となっているが検証では n は任意の自然数

    n = 10;
+    i = 0;
+
+    while (n>0)
+    {
+      i++;
+      n--;
+    }
+

Agda での Hoare Logic

Hoare Logic のプログラムは Command で構成される

Comm 型は data で記述されたコマンドのデータ構造

実際に実行するには解釈して動かす関数が必要

Commを使って while program を構築する

    data Comm : Set where
+      Skip  : Comm
+      Abort : Comm
+      PComm : PrimComm → Comm
+      Seq   : Comm → Comm → Comm
+      If    : Cond → Comm → Comm → Comm
+      While : Cond → Comm → Comm
+

Hoare Logic での while program

検証する while program の擬似コード

    n = 10;
+    i = 0;
+
+    while (n>0)
+    {
+      i++;
+      n--;
+    }
+

コマンドで構成した while program

    program : ℕ → Comm
+    program c10 = 
+        Seq ( PComm (λ env → record env {varn = c10}))
+        $ Seq ( PComm (λ env → record env {vari = 0}))
+        $ While (λ env → lt zero (varn env ) )
+          (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} ))
+            $ PComm (λ env → record env {varn = ((varn env) - 1)} ))
+

これは Hoare Logic のコマンドで以下のような構文木を記述している

        Seq
+       /    \
+   PComm     Seq
+ (n=c10)     /  \
+         PComm   While
+         (i=0)      |
+                  Cond
+                  (0<n)
+                    |
+                   Seq
+                  /   \
+              PComm    PComm
+              (i+1)     (n-1) 
+

Hoare Logic での Command に対応する仕様

Command に対応する証明がある

HTProof は Hoare Triple Proof

{P} Q {C}Cond → Comm → Cond に対応している

    data HTProof : Cond → Comm → Cond → Set where
+

すべての Command に対応する Proof を載せると長いので
+必要なものだけ


+PrimRule は 代入のときに成り立ってほしいルール

Axiom は Triple を受け取ってすべての Env は事前の Env が正しければ コマンドを実行した後のEnv も正しくなるという命題

      PrimRule : {bPre : Cond} → {pcm : PrimComm} → {bPost : Cond} →
+                 (pr : Axiom bPre pcm bPost) →
+                 HTProof bPre (PComm pcm) bPost
+

WekeningRule は 条件を緩める規則

While コマンドなどで条件が厳しいときに同時に成り立つ異なる条件へ変更必要がある

Tautology は2つの Cond 型 bPre、 bPre’ を受け取り、 bPre が成り立つとき、 bPre’が成り立つという命題

      WeakeningRule : {bPre : Cond} → {bPre' : Cond} → {cm : Comm} →
+                    {bPost' : Cond} → {bPost : Cond} →
+                    Tautology bPre bPre' →
+                    HTProof bPre' cm bPost' →
+                    Tautology bPost' bPost →
+                    HTProof bPre cm bPost
+

SeqRule は Seqcuence が正しい順番で行われることを保証

cm1、cm2 という2つのCommを受け取ってそれらがcm1、cm2の順で実行される

      SeqRule : {bPre : Cond} → {cm1 : Comm} → {bMid : Cond} →
+                {cm2 : Comm} → {bPost : Cond} →
+                HTProof bPre cm1 bMid →
+                HTProof bMid cm2 bPost →
+                HTProof bPre (Seq cm1 cm2) bPost
+

WhileRule は Comm 型の cm と Cond型の bInv、 bが存在するとき、
+事前に

      WhileRule : {cm : Comm} → {bInv : Cond} → {b : Cond} →
+                  HTProof (bInv and b) cm bInv →
+                  HTProof bInv (While b cm) (bInv and neg b)
+

検証をするためにはこの HTProof で program と同様の仕様を構成する必要がある

Hoare Logic での 仕様記述

HTProof で記述した仕様

HTProof が コマンドに対応しているのでほとんど同じ形で書けてる

    proof1 : (c10 : ℕ) → HTProof initCond (program c10 ) (termCond {c10})
+    proof1 c10 =
+        SeqRule {λ e → true} ( PrimRule (init-case {c10} ))
+        $ SeqRule {λ e →  Equal (varn e) c10} ( PrimRule lemma1   )
+        $ WeakeningRule {λ e → (Equal (varn e) c10) ∧ (Equal (vari e) 0)}  lemma2 (
+                WhileRule {_} {λ e → Equal ((varn e) + (vari e)) c10}
+                $ SeqRule (PrimRule {λ e →  whileInv e  ∧ lt zero (varn e) } lemma3 )
+                         $ PrimRule {whileInv'} {_} {whileInv}  lemma4 ) lemma5
+
    program : ℕ → Comm
+    program c10 = 
+        Seq ( PComm (λ env → record env {varn = c10}))
+        $ Seq ( PComm (λ env → record env {vari = 0}))
+        $ While (λ env → lt zero (varn env ) )
+          (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} ))
+            $ PComm (λ env → record env {varn = ((varn env) - 1)} ))
+

proof1 は条件がつながるのに必要な条件を lemma で記述している(lemma は長いので省略)

部分正当性は示せている

全体がつながっているが証明にはなっていない


Hoare Logic での健全性の証明

実際に正しく動作すること(健全性)を証明する必要がある

Satisfies は {P} C {Q} を受け取ってそれらが Comm で正しく成り立つ関係を返す

PrimSoundness は HTProof を受け取って Satisfies が成り立つことを Soundness を用いて実際に証明する

    PrimSoundness : {bPre : Cond} -> {cm : Comm} -> {bPost : Cond} ->
+                HTProof bPre cm bPost -> Satisfies bPre cm bPost
+    PrimSoundness {bPre} {cm} {bPost} ht = Soundness ht
+

Soundness は HTProof に対応した非常に複雑な証明

HTProof を渡すと Ruleに対応した証明を行う

proofOfProgram では 実際に構築した program と proof1 を使って健全性を証明している

    proofOfProgram : (c10 : ℕ) → (input output : Env )
+      → initCond input ≡ true
+      → (SemComm (program c10) input output)
+      → termCond {c10} output ≡ true
+    proofOfProgram c10 input output ic sem  = 
+      PrimSoundness (proof1 c10) input output ic sem
+

Continuation based C について

Continuation based C (CbC) は当研究室で開発してるプログラミング言語

CbC では処理の単位を CodeGear 、データの単位を DataGear とする

CodeGear は引数として Input の DataGear を受け取り、 Output の DataGear を返す

Output の DataGear は次の CodeGear の Input として接続される

cgdg-small.svg
+
+CodeGear の接続処理などのメタ計算は Meta CodeGear として定義

Meta CodeGear で信頼性の検証を行う


Agda での CodeGear、 DataGear の記述

     whileTest : {t : Set} → (c10 : Nat) 
+                   → (Code : Env → t) → t
+     whileTest c10 next = next (record {varn = c10 
+                                        ; vari = 0} )
+

CbC での Hoare Logic

CodeGear、DataGear を用いた Hoare Logic は図のようになる
+hoare-cg-dg.svg
+
+CodeGear が条件を引数として受け、継続先の CodeGear が次の条件を満たす様になる

下のコードは CodeGear、 DataGear を用いた Hoare Logic ベースの記述例である

    whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) → ((env : Envc ) 
+        → whileTestStateP s1 env → t) → t
+    whileTestPwP c10 next = next (whileTestP c10 ( λ env → env )) 
+        record { pi1 = refl ; pi2 = refl } 
+

CbC での while program

    n = 10;
+    i = 0;
+
+    while (n>0)
+    {
+      i++;
+      n--;
+    }
+

CbC での while program

    whileTestPCall : (c10 :  ℕ ) → Envc
+    whileTestPCall c10 = whileTestP' {_} {_} c10 (λ env → loopP' env (λ env →  env))
+

CbC での Hoare Logic 記述

CbC での Hoare Logic 記述では CodeGear が条件を受け取る

whileTestPwP は代入を行う CodeGear

    whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) 
+      → ((env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → t) → t
+    whileTestPwP c10 next = 
+      next (whileTestP c10 ( λ env → env )) (record { pi1 = refl ; pi2 = refl })
+

loopPwP’ は while loop をするための条件を持ち、ループをする CodeGear

n と (n ≡ varn env) を受け取り varn でのパターンマッチをしている

suc n の場合はループを抜けるか判断する CodeGear に継続する

更に継続先で loopPwP’ を呼ぶことで再帰的にループする

    loopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) 
+        → (n ≡ varn env) → (vari env + varn env ≡ c10 env) → 
+        (exit : (env : Envc ) → (vari env ≡ c10 env) → t) → t
+    loopPwP' zero env refl refl exit = exit env refl
+    loopPwP' (suc n) env refl refl exit = 
+        whileLoopPwP' (suc n) env refl refl 
+        (λ env x y → loopPwP' n env x y exit) exit
+

whileLoopPwP’ は while loop を抜けるか判断する CodeGear

loopPwP’から呼ばれている

    whileLoopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) 
+      → (n ≡ varn env) → (vari env + varn env ≡ c10 env)
+      → (next : (env : Envc ) → (pred n ≡ varn env) 
+          → (vari env + varn env ≡ c10 env) → t)
+      → (exit : (env : Envc ) → (vari env ≡ c10 env) → t) → t
+    whileLoopPwP' zero env refl refl _ exit = exit env refl
+    whileLoopPwP' (suc n) env refl refl next _ = 
+        next (record env {varn = pred (varn env) ; vari = suc (vari env)})
+        refl (+-suc n (vari env))
+

conv は whileTestPwP の事後条件から while loop のための loop invaliant に変更する

    conv : (env : Envc ) → (vari env ≡ 0) /\ (varn env ≡ c10 env) 
+        → varn env + vari env ≡ c10 env
+    conv e record { pi1 = refl ; pi2 = refl } = +zero
+

whileTestPCallwP’ は先程までの Hoare Logic の記述をつなげたもの

継続先の CodeGear に渡す条件が

    whileTestPCallwP' : (c :  ℕ ) → Set
+    whileTestPCallwP' c = whileTestPwP {_} {_} c (
+        λ env s → loopPwP' (varn env) env refl (conv env s) 
+          ( λ env s → vari env ≡ c10 env )  )
+

whileTestPCallwP’ では Hoare Logic の条件が接続できた


Hoare Logic をベースにした CbC での while loop

先程条件を接続した whileTestPCallwP’ を型に入れ、実際に実行してみる

    whileCallwP : (c : ℕ) → whileTestPCallwP' c
+    whileCallwP c = whileTestPwP {_} {_} c (λ env s →
+            loopPwP' (c10 env) env (sym (pi2 s)) (conv env s) {!!})
+

loopPwP’は任意の値を取ってループを行う CodeGear であった

しかし、引数で受け取った任意の自然数で実行するとループが停まらない

任意の自然数回ループする loopPwP’ が停まることを補助する loopHelper を記述した

     loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) 
+       → (varn env + vari env ≡ c10 env)
+       → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁))
+     loopHelper zero env eq refl rewrite eq = refl
+     loopHelper (suc n) env eq refl rewrite eq = loopHelper n 
+         (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) 
+           refl (+-suc n (vari env))
+

loopHelper を用いて記述した実行は実際に停止した

    helperCallwP : (c : ℕ) → whileTestPCallwP' c
+    helperCallwP c = whileTestPwP {_} {_} c 
+        (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero)
+

CbC での Hoare Logic の健全性

implies という data を用いて健全性の証明を行う

implies の型は A と B の条件を受け取る

このとき proof として A → B が存在すれば A implies B が証明できる

    data _implies_  (A B : Set ) : Set (succ Zero) where
+        proof : ( A → B ) → A implies B
+

代入を行う CodeGear である whileTestP を実行したとき、
+常に真の命題 と代入を終えたときの事後条件である
+(vari env ≡ 0) ∧ (varn env ≡ c10 env)
+を implies に入れた型を記述する

    whileTestPSem :  (c : ℕ) → whileTestP c 
+        ( λ env → ⊤ implies (vari env ≡ 0) ∧ (varn env ≡ c10 env) )
+    whileTestPSem c = proof ( λ _ → record { pi1 = refl ; pi2 = refl } )
+

証明では proof に( ⊤ → (vari env ≡ 0) ∧ (varn env ≡ c10 env) )であると記述できればよく
+ここでは λ _ → record { pi1 = refl ; pi2 = refl } がこれに対応する

whileTestPSemSound は output ≡ whileTestP c (λ e → e) を受け取ることで whileTestP の実行が終わった結果、つまり停止した CodeGear の実行結果が事後条件を満たしていることを証明している

    whileTestPSemSound : (c : ℕ ) (output : Envc ) → 
+        output ≡ whileTestP c (λ e → e) 
+        → ⊤ implies ((vari output ≡ 0) ∧ (varn output ≡ c))
+    whileTestPSemSound c output refl = whileTestPSem c
+

同様に他の CodeGear に対しても健全性の証明が可能

whileConvPSemSound は制約を緩める conversion の健全性の証明

whileConvPSemSound : {l : Level} → (input : Envc) → ((vari input ≡ 0) ∧ (varn input ≡ c)) implies (varn input + vari input ≡ c10 input)
+whileConvPSemSound input = proof λ x → (conversion input x) where
+  conversion : (env : Envc ) → (vari env ≡ 0) /\ (varn env ≡ c10 env) → varn env + vari env ≡ c10 env
+  conversion e record { pi1 = refl ; pi2 = refl } = +zero
+

whileLoopPSemSound は ループを行う CodeGear の 健全性の証明

whileLoopPSemSound : {l : Level} → (input output : Envc )
+   → (varn input + vari input ≡ c10 input)
+   →  output ≡ loopPP (varn input) input refl
+   → (varn input + vari input ≡ c10 input) implies (vari output ≡ c10 output)
+whileLoopPSemSound {l} input output pre eq = loopPPSem input output eq pre
+

loopPPSem を使って証明を行っている

loopPPSem : (input output : Envc ) →  output ≡ loopPP (varn input)  input refl
+    → (varn input + vari input ≡ c10 input ) 
+    → (varn input + vari input ≡ c10 input ) implies (vari output ≡ c10 output)
+loopPPSem input output refl s2p = loopPPSemInduct (varn input) input  refl refl s2p
+

まとめと今後の課題


+ + + + + + + + + diff -r e8655e0264b8 -r 19ab6b8055ea slide/master-slide.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slide/master-slide.md Wed Feb 12 05:02:27 2020 +0900 @@ -0,0 +1,572 @@ +Continuation Based C の Hoare Logic を用いた仕様記述と検証 +===== + +琉球大学大学院 : 並列信頼研究室\ +外間 政尊 + +--- + +## OS の検証技術としての Hoare Logic の問題点 +- OS やアプリケーションの信頼性は重要な課題 + +- 信頼性を上げるために仕様の検証が必要 + +- 検証にはモデル検査や**定理証明**などが存在する + +- また、仕様検証の手法として **Hoare Logic** がある + -通常の関数でも実行する前に必要な引数があって何らかの出力がある + - Hoare Logic ではコマンドを実行する上で引数が存在するなどの事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ +- Hoare Logic では関数が最低限のコマンドで分割されており記述が困難(変数の代入、コマンド実行の遷移等) + +--- +## Hoare Logic をベースにした Gears 単位での検証 +- 当研究室では 処理の単位を **CodeGear**、データの単位を **DataGear** としてプログラムを記述する手法を提案 +- CodeGear は Input DataGear を受け取り、処理を行って Output DataGear に書き込む +- CodeGear は継続を用いて次の CodeGear に接続される +- 定理証明支援機の Agda 上で Gears 単位を用いた検証を行う +- 本研究では Gears 単位を用いた Hoare Logic ベースの検証手法を提案する + +--- + +## Agda + Agda は関数型言語 +```AGAD + name : type + name = value +``` +関数には型と定義を与える\ +型は **:** で、 値は **=** で与える\ +仮定なしに使えるのは Set のみ + +構成要素としては以下の3種類 +1. 関数 + - 型は(A : Set かつ B : Set のとき) A → B + - 値は(x : A かつ y : B) λ x → y +1. record +1. data + +--- + +## Agda の record とその例 ∧ +導入は2つのものが同時に存在すること +``` + A B +------------ + A ∧ B +``` +除去は名前を区別する必要がある +``` + A ∧ B A ∧ B + --------- pi1 --------- pi2 + A B +``` +A ∧ B が成り立っていれば (pi1 A ∧ B) → A、 (pi2 A ∧ B) → B\ +Agda ではこのような同時に存在する型を **record** で書く +```AGDA + record _∧_ (A B : Set) : Set + field + pi1 : A + pi2 : B +``` +\_∧\_ は中間記法、変数が入る位置を _ で示せる\ +実際の構築は x : A かつ y : B のとき +```AGDA +createAnd : (A : Set) → (B : Set) → A ∧ B +createAnd x y = record {pi1 = x ; pi2 = y} +``` +のように記述する\ +C 言語での構造体のようなもの + +A や B に論理式が入ると2つのものが同時に成り立つ証明ができる + +--- + +## Agda の data とその例 Sum +導入\ +一つでも存在すること +``` + A B + ----------- p1 ---------- p2 + A ∨ B A ∨ B +``` +除去\ +A → C か B → C のとき C +``` + A B + : : + A ∨ B C C + ------------------------ + C +``` + + +A ∨ B が成り立っているとき A → A ∨ B、 B → A ∨ B\ +どちらかが成り立つ型を **data** で書く\ +```AGDA + data _∨_ (A B : Set) : Set where + p1 : A → A ∨ B + p2 : B → A ∨ B +``` +のように記述できる\ +C 言語での union のようなもの\ +p1、 p2 は case 文みたいな感じ + +--- + +## Hoare Logic +Hoare Logic はプログラム検証の手法\ +事前条件( P )が成り立つとき、コマンド( C )を実行すると事後条件( Q )が成り立つ + +これは **{ P } C { Q }** の形で表され、Hoare Triple と呼ばれる + + +今回は以下のような while program を検証する + +n = 10 となっているが検証では n は任意の自然数 +```C + n = 10; + i = 0; + + while (n>0) + { + i++; + n--; + } +``` + +--- + +## Agda での Hoare Logic +Hoare Logic のプログラムは Command で構成される + +Comm 型は data で記述されたコマンドのデータ構造 + +実際に実行するには解釈して動かす関数が必要 + +Commを使って while program を構築する + +```AGDA + data Comm : Set where + Skip : Comm + Abort : Comm + PComm : PrimComm → Comm + Seq : Comm → Comm → Comm + If : Cond → Comm → Comm → Comm + While : Cond → Comm → Comm +``` + +--- + +## Hoare Logic での while program +検証する while program の擬似コード +```C + n = 10; + i = 0; + + while (n>0) + { + i++; + n--; + } +``` +コマンドで構成した while program +```AGDA + program : ℕ → Comm + program c10 = + Seq ( PComm (λ env → record env {varn = c10})) + $ Seq ( PComm (λ env → record env {vari = 0})) + $ While (λ env → lt zero (varn env ) ) + (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} )) + $ PComm (λ env → record env {varn = ((varn env) - 1)} )) +``` + +これは Hoare Logic のコマンドで以下のような構文木を記述している + +``` + Seq + / \ + PComm Seq + (n=c10) / \ + PComm While + (i=0) | + Cond + (0 {cm : Comm} -> {bPost : Cond} -> + HTProof bPre cm bPost -> Satisfies bPre cm bPost + PrimSoundness {bPre} {cm} {bPost} ht = Soundness ht +``` +Soundness は HTProof に対応した非常に複雑な証明 + +HTProof を渡すと Ruleに対応した証明を行う + +proofOfProgram では 実際に構築した program と proof1 を使って健全性を証明している + +```AGDA + proofOfProgram : (c10 : ℕ) → (input output : Env ) + → initCond input ≡ true + → (SemComm (program c10) input output) + → termCond {c10} output ≡ true + proofOfProgram c10 input output ic sem = + PrimSoundness (proof1 c10) input output ic sem +``` + +--- +## Continuation based C について +Continuation based C (CbC) は当研究室で開発してるプログラミング言語 + +CbC では処理の単位を **CodeGear** 、データの単位を **DataGear** とする + +CodeGear は引数として Input の DataGear を受け取り、 Output の DataGear を返す + +Output の DataGear は次の CodeGear の Input として接続される + +![cgdg-small.svg](/attachment/5e42fdea7b378d004670d2fc) +CodeGear の接続処理などのメタ計算は Meta CodeGear として定義 + +Meta CodeGear で信頼性の検証を行う + + + + + +--- +## Agda での CodeGear、 DataGear の記述 + +- Agda での CodeGear は継続渡しで記述された関数 +```AGDA + whileTest : {t : Set} → (c10 : Nat) + → (Code : Env → t) → t + whileTest c10 next = next (record {varn = c10 + ; vari = 0} ) + ``` + - CodeGear の型は継続先を返す関数 + - **(Code : fa → t)** は継続先 + - 引数として継続先の CodeGear を受け取る + + + + + + + +--- +## CbC での Hoare Logic +CodeGear、DataGear を用いた Hoare Logic は図のようになる +![hoare-cg-dg.svg](/attachment/5e42baee7b378d004670d1f5) +CodeGear が条件を引数として受け、継続先の CodeGear が次の条件を満たす様になる + +下のコードは CodeGear、 DataGear を用いた Hoare Logic ベースの記述例である + +```AGDA + whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) → ((env : Envc ) + → whileTestStateP s1 env → t) → t + whileTestPwP c10 next = next (whileTestP c10 ( λ env → env )) + record { pi1 = refl ; pi2 = refl } +``` + + + + + + + + + + + + +--- +## CbC での while program +```C + n = 10; + i = 0; + + while (n>0) + { + i++; + n--; + } +``` + +CbC での while program +```AGDA + whileTestPCall : (c10 : ℕ ) → Envc + whileTestPCall c10 = whileTestP' {_} {_} c10 (λ env → loopP' env (λ env → env)) +``` +- whileTestP' が n = c10、 i = 0 の代入、 loopP' が while loop に対応している +- CbC での Hoare Logic 上でコマンドは CodeGear そのもの + - CodeGear は Hoare Logic のコマンドより自由な記述 + + +--- +## CbC での Hoare Logic 記述 +CbC での Hoare Logic 記述では CodeGear が条件を受け取る + +whileTestPwP は代入を行う CodeGear + +```AGDA + whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) + → ((env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → t) → t + whileTestPwP c10 next = + next (whileTestP c10 ( λ env → env )) (record { pi1 = refl ; pi2 = refl }) +``` +loopPwP' は while loop をするための条件を持ち、ループをする CodeGear + +n と (n ≡ varn env) を受け取り varn でのパターンマッチをしている + +suc n の場合はループを抜けるか判断する CodeGear に継続する + +更に継続先で loopPwP' を呼ぶことで再帰的にループする +```AGDA + loopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) + → (n ≡ varn env) → (vari env + varn env ≡ c10 env) → + (exit : (env : Envc ) → (vari env ≡ c10 env) → t) → t + loopPwP' zero env refl refl exit = exit env refl + loopPwP' (suc n) env refl refl exit = + whileLoopPwP' (suc n) env refl refl + (λ env x y → loopPwP' n env x y exit) exit +``` +whileLoopPwP' は while loop を抜けるか判断する CodeGear + +loopPwP'から呼ばれている +```AGDA + whileLoopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) + → (n ≡ varn env) → (vari env + varn env ≡ c10 env) + → (next : (env : Envc ) → (pred n ≡ varn env) + → (vari env + varn env ≡ c10 env) → t) + → (exit : (env : Envc ) → (vari env ≡ c10 env) → t) → t + whileLoopPwP' zero env refl refl _ exit = exit env refl + whileLoopPwP' (suc n) env refl refl next _ = + next (record env {varn = pred (varn env) ; vari = suc (vari env)}) + refl (+-suc n (vari env)) +``` + +conv は whileTestPwP の事後条件から while loop のための loop invaliant に変更する + +```AGDA + conv : (env : Envc ) → (vari env ≡ 0) /\ (varn env ≡ c10 env) + → varn env + vari env ≡ c10 env + conv e record { pi1 = refl ; pi2 = refl } = +zero +``` + +whileTestPCallwP' は先程までの Hoare Logic の記述をつなげたもの + +継続先の CodeGear に渡す条件が +```AGDA + whileTestPCallwP' : (c : ℕ ) → Set + whileTestPCallwP' c = whileTestPwP {_} {_} c ( + λ env s → loopPwP' (varn env) env refl (conv env s) + ( λ env s → vari env ≡ c10 env ) ) +``` + +whileTestPCallwP' では Hoare Logic の条件が接続できた + +--- + +## Hoare Logic をベースにした CbC での while loop +先程条件を接続した whileTestPCallwP' を型に入れ、実際に実行してみる +```AGDA + whileCallwP : (c : ℕ) → whileTestPCallwP' c + whileCallwP c = whileTestPwP {_} {_} c (λ env s → + loopPwP' (c10 env) env (sym (pi2 s)) (conv env s) {!!}) +``` +loopPwP'は任意の値を取ってループを行う CodeGear であった + +しかし、引数で受け取った任意の自然数で実行するとループが停まらない + +任意の自然数回ループする loopPwP' が停まることを補助する loopHelper を記述した +```AGDA + loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) + → (varn env + vari env ≡ c10 env) + → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁)) + loopHelper zero env eq refl rewrite eq = refl + loopHelper (suc n) env eq refl rewrite eq = loopHelper n + (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) + refl (+-suc n (vari env)) +``` +loopHelper を用いて記述した実行は実際に停止した +```AGDA + helperCallwP : (c : ℕ) → whileTestPCallwP' c + helperCallwP c = whileTestPwP {_} {_} c + (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero) +``` + +--- +## CbC での Hoare Logic の健全性 + +implies という data を用いて健全性の証明を行う + +implies の型は A と B の条件を受け取る + +このとき proof として A → B が存在すれば A implies B が証明できる +```AGDA + data _implies_ (A B : Set ) : Set (succ Zero) where + proof : ( A → B ) → A implies B +``` +代入を行う CodeGear である **whileTestP** を実行したとき、\ +常に真の命題 **⊤** と代入を終えたときの事後条件である\ +**(vari env ≡ 0) ∧ (varn env ≡ c10 env)** +を implies に入れた型を記述する + +```AGDA + whileTestPSem : (c : ℕ) → whileTestP c + ( λ env → ⊤ implies (vari env ≡ 0) ∧ (varn env ≡ c10 env) ) + whileTestPSem c = proof ( λ _ → record { pi1 = refl ; pi2 = refl } ) +``` + +証明では proof に( ⊤ → (vari env ≡ 0) ∧ (varn env ≡ c10 env) )であると記述できればよく\ +ここでは λ _ → record { pi1 = refl ; pi2 = refl } がこれに対応する + +**whileTestPSemSound** は output ≡ whileTestP c (λ e → e) を受け取ることで whileTestP の実行が終わった結果、つまり停止した CodeGear の実行結果が事後条件を満たしていることを証明している + +```AGDA + whileTestPSemSound : (c : ℕ ) (output : Envc ) → + output ≡ whileTestP c (λ e → e) + → ⊤ implies ((vari output ≡ 0) ∧ (varn output ≡ c)) + whileTestPSemSound c output refl = whileTestPSem c +``` + +同様に他の CodeGear に対しても健全性の証明が可能 + +whileConvPSemSound は制約を緩める conversion の健全性の証明 +```AGDA +whileConvPSemSound : {l : Level} → (input : Envc) → ((vari input ≡ 0) ∧ (varn input ≡ c)) implies (varn input + vari input ≡ c10 input) +whileConvPSemSound input = proof λ x → (conversion input x) where + conversion : (env : Envc ) → (vari env ≡ 0) /\ (varn env ≡ c10 env) → varn env + vari env ≡ c10 env + conversion e record { pi1 = refl ; pi2 = refl } = +zero +``` + +whileLoopPSemSound は ループを行う CodeGear の 健全性の証明 + +```AGDA +whileLoopPSemSound : {l : Level} → (input output : Envc ) + → (varn input + vari input ≡ c10 input) + → output ≡ loopPP (varn input) input refl + → (varn input + vari input ≡ c10 input) implies (vari output ≡ c10 output) +whileLoopPSemSound {l} input output pre eq = loopPPSem input output eq pre +``` + +loopPPSem を使って証明を行っている + +```AGDA +loopPPSem : (input output : Envc ) → output ≡ loopPP (varn input) input refl + → (varn input + vari input ≡ c10 input ) + → (varn input + vari input ≡ c10 input ) implies (vari output ≡ c10 output) +loopPPSem input output refl s2p = loopPPSemInduct (varn input) input refl refl s2p +``` + +--- +## まとめと今後の課題 +- CodeGear、 DataGear を用いた Hoare Logic ベースの仕様記述を導入した +- Hoare Logic ベースの検証で停止性を含めて検証できた +- Hoare Logic ベースの検証の健全性を証明できた + - while Program で使用した CodeGear を使って証明できた +- 今後の課題 + - BinaryTree の有限ループに対する証明 + - Hoare Logic で検証されたコードの CbC 変換 + - 並列実行での検証 + +--- \ No newline at end of file diff -r e8655e0264b8 -r 19ab6b8055ea slide/slide.html --- a/slide/slide.html Tue Feb 11 02:31:26 2020 +0900 +++ b/slide/slide.html Wed Feb 12 05:02:27 2020 +0900 @@ -7,7 +7,7 @@ - Continuation based C での Hoare Logic を用いた記述と検証 + Continuation based C での Hoare Logic を用いた仕様記述と検証 @@ -70,7 +70,7 @@
-

Continuation based C での Hoare Logic を用いた記述と検証

+

Continuation based C での Hoare Logic を用いた仕様記述と検証

@@ -91,9 +91,40 @@
@@ -105,13 +136,11 @@
  • 検証にはモデル検査や定理証明などが存在する
  • また、仕様検証の手法として Hoare Logic がある
      -
    • プログラムを書く上である関数は実行する前に必要な引数があって何らかの出力がある
    • -
    • Hoare Logic ではコマンドを実行する上で引数が存在するなどの事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ -
    • +
    • 通常の関数でも実行する前に必要な引数があって何らかの出力がある
    • +
    • Hoare Logic ではコマンドを実行する上で引数が存在するなどの事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ
  • -
  • Hoare Logic では関数が最低限のコマンドまで分割されており記述が困難(変数の代入、コマンド実行の遷移等)
  • -
  • 大規模なプログラムは構築しづらい
  • +
  • Hoare Logic では関数が最低限のコマンドで分割されており記述が困難(変数の代入、コマンド実行の遷移等)
  • @@ -129,31 +158,190 @@
  • 本研究では Gears 単位を用いた Hoare Logic ベースの検証手法を提案する
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +

    Agda

    + +
    -

    Agda のデータ型

    +

    Agda の record とその例 ∧

    + + + +
    + +
    + +

    Agda の data とその例 Sum

    + + + + +
    + +
    + +

    Hoare Logic

    + + + + +
    + +
    + +

    Agda での Hoare Logic

    + @@ -344,49 +607,46 @@
    -

    Gears をベースにした Hoare Logic と証明(全体)

    -
    -
    1    -- test = whileTest 10 (λ env → whileLoop env (λ env1 → env1))
    -2    proofGears : {c10 :  Nat } → Set
    -3    proofGears {c10} = whileTest' {_} {_} {c10} (λ n p1 →
    -4             conversion1 n p1  (λ n1 p2 → whileLoop' n1 p2 
    -5             (λ n2 →  ( vari n2 ≡ c10 )))) 
    +

    CbC での HTProof

    +
      +
    • HTProof に対応するものは各 Meta CodeGear に条件を渡したもの
    • +
    • それぞれが事前条件から事後条件を導く証明を持っている +
      +
      1  whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) 
      +2    → ((env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → t) → t
      +3  whileTestPwP c10 next = 
      +4    next (whileTestP c10 ( λ env → env )) (record { pi1 = refl ; pi2 = refl })
       
      -
      -
        -
      • proofGears は Hoare Logic をベースとした証明 -
          -
        • 先程のプログラムと違い、引数として証明も持っている
        • -
        +
    -
  • whileTest’ の継続に conversion1、その継続に whileLoop’ が来て最後の継続に vari が c10 と等しい
  • - - - - -
    - -
    - -

    Gears と Hoare Logic をベースにした証明(whileTest)

    -
    -
    1    whileTest' : {l : Level} {t : Set l} {c10 :  ℕ } 
    -2      → (Code : (env : Env )  → ((vari env) ≡ 0) ∧ ((varn env) ≡ c10) → t) → t
    -3    whileTest' {_} {_}  {c10} next = next 
    -4      (record env {vari = 0 ; varn = c10 }) (record {pi1 = refl ; pi2 = refl})
    +  
  • whileTestPCallwP’ は Hoare Logic の HTProof 記述 proof1 に相当
  • +
  • 比較用 proof1 +
    +
    1  proof1 : (c10 : ℕ) → HTProof initCond (program c10 ) (termCond {c10})
    +2  proof1 c10 =
    +3      SeqRule {λ e → true} ( PrimRule (init-case {c10} ))
    +4      $ SeqRule {λ e →  Equal (varn e) c10} ( PrimRule lemma1   )
    +5      $ WeakeningRule {λ e → (Equal (varn e) c10) ∧ (Equal (vari e) 0)}  lemma2 (
    +6              WhileRule {_} {λ e → Equal ((varn e) + (vari e)) c10}
    +7              $ SeqRule (PrimRule {λ e →  whileInv e  ∧ lt zero (varn e) } lemma3 )
    +8                       $ PrimRule {whileInv'} {_} {whileInv}  lemma4 ) lemma5
     
    +
    +
  • +
  • proof1 の lemma に相当する証明は Meta CodeGear で、継続先の CodeGear に渡す条件の証明 +
    +
    1  whileTestPCallwP' : (c :  ℕ ) → Set
    +2  whileTestPCallwP' c = whileTestPwP {_} {_} c (
    +3      λ env s → loopPwP' (varn env) env refl (conv env s) 
    +4        ( λ env s → vari env ≡ c10 env )  )
    +
    -
      -
    • 最初の Command なので PreCondition はない
    • -
    • (record {pi1 = refl ; pi2 = refl}) は (vari env) ≡ 0(varn env) ≡ c10の証明 -
        -
      • は pi1 と pi2 のフィールドをもつレコード型
      • -
      • 両方とも成り立つので refl
      • -
      +
  • -
  • Gears での PostCondition は 引数 → (Code : fa → PostCondition → t) → t
  • +
  • Hoare Logic では実装、部分正当性を分けて記述していた
  • +
  • CbC での Hoare Logic は実装と部分正当性を一体化できる
  • @@ -395,111 +655,27 @@
    -

    Gears と Hoare Logic をベースにした証明(conversion)

    -
    -
    1    conv : (env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → varn env + vari env ≡ c10 env
    -2    conv e record { pi1 = refl ; pi2 = refl } = +zero
    -
    -
    -
    +

    CbC での Soundness

      -
    • conv は制約を緩める CodeGear -
        -
      • (vari env ≡ 0) ∧ (varn env ≡ c10 env) が成り立つとき varn env + vari env ≡ c10 env が成り立つ
      • -
      -
    • -
    - - - - - - - - - - - - - - - -
    - -
    - -

    Gears と Hoare Logic をベースにした証明(whileLoop)

    -
    -
     1    whileLoopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) → (n ≡ varn env) → whileTestStateP s2 env
    - 2      → (next : (env : Envc ) → (pred n ≡ varn env) → whileTestStateP s2 env  → t)
    - 3      → (exit : (env : Envc ) → whileTestStateP sf env  → t) → t
    - 4    whileLoopPwP' zero env refl refl next exit = exit env refl
    - 5    whileLoopPwP' (suc n) env refl refl next exit = 
    - 6      next (record env {varn = pred (varn env) ; vari = suc (vari env) }) refl (+-suc n (vari env))
    - 7
    - 8    loopPwP' zero env refl refl exit = exit env refl
    - 9    loopPwP' (suc n) env refl refl exit  = whileLoopPwP' (suc n) env refl refl 
    -10        (λ env x y → loopPwP' n env x y exit) exit
    +  
  • 先程の whileTestPCallwP’ を命題として証明すると健全性が示せる +
    +
    1  whileTestPCallwP' : (c :  ℕ ) → Set
    +2  whileTestPCallwP' c = whileTestPwP {_} {_} c (
    +3      λ env s → loopPwP' (varn env) env refl (conv env s) 
    +4        ( λ env s → vari env ≡ c10 env )  )
     
    -
    -
      -
    • whileLoop も whileTest と同様に PreCondition が CodeGear に入りそれに対する証明が記述されている
    • -
    • ループが回るごとに、whileLoopPwP’ で停止か継続かを判断し、 loopPwP’ でループが回る
    • -
    - - - -
  • - -
    - -

    Gears と Hoare Logic をベースにした仕様記述

    -
    -
    1    whileProofs : (c :  ℕ ) → Set
    -2    whileProofs c = whileTestPwP {_} {_} c 
    -3       ( λ env s → conv1 env s 
    -4       ( λ env s → loopPwP' (varn env) env refl s 
    -5       ( λ env s → vari env ≡ c10 env )))
    +    
    + +
  • 実際に値が入ると命題は成り立つが任意の値だと停止せず証明が終わらない +
    +
    1  whileCallwP : (c : ℕ) → whileTestPCallwP' c
    +2  whileCallwP c = whileTestPwP {_} {_} c (λ env s →
    +3    loopPwP' (c10 env) env (sym (pi2 s)) (conv env s) {!!})
     
    -
    -
      -
    • whileProofs では最終状態が vari と c10 が等しくなるため仕様になっている
    • -
    - - - -
  • - -
    - -

    Gears と Hoare Logic を用いた仕様の証明

    -
    -
     1--    whileProofs c = whileTestPwP {_} {_} c 
    - 2--       ( λ env s → conv1 env s 
    - 3--       ( λ env s → loopPwP' (varn env) env refl s 
    - 4--       ( λ env s → vari env ≡ c10 env )))
    - 5
    - 6    ProofGears : (c : ℕ) → whileProofs c
    - 7    ProofGears c = whileTestPwP {_} {_} c
    - 8      (λ env s →  loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl +zero
    - 9      (λ env₁ s₁ → {!!}))
    -10
    -11    Goal: loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl
    -12          +zero (λ env₂ s₂ → vari env₂ ≡ c10 env₂)
    -13    ------------------------------------------------------------
    -14    s₁   : vari env₁ ≡ c10 env₁
    -15    env₁ : Envc
    -16    s    : (vari env ≡ 0) /\ (varn env ≡ c10 env)
    -17    env  : Envc
    -18    c    : ℕ
    -
    -
    -
    -
      -
    • 先程の whileProofs で行った仕様記述を型に記述し、実際に証明していく
    • -
    • しかし loopPwP’ のループが進まず証明できない
    • +
    + @@ -509,18 +685,21 @@

    検証時の Loop の解決

    -
    -
    1    loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) → (seq : whileTestStateP s2 env) 
    -2      → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁))
    -3    loopHelper zero env eq refl rewrite eq = refl
    -4    loopHelper (suc n) env eq refl rewrite eq = loopHelper n 
    -5      (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) refl (+-suc n (vari env))
    +
      +
    • loopHelper は今回のループを解決する証明 +
      +
      1   loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) 
      +2     → (varn env + vari env ≡ c10 env)
      +3     → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁))
      +4   loopHelper zero env eq refl rewrite eq = refl
      +5   loopHelper (suc n) env eq refl rewrite eq = loopHelper n 
      +6       (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) 
      +7         refl (+-suc n (vari env))
       
      -
      -
        -
      • loopHelper は今回のループを解決する証明
      • -
      • ループ解決のためにループの簡約ができた
      • +
    + +
  • ここでは任意の回数回る while loop が必ず最終条件を満たす
  • @@ -531,13 +710,9 @@

    Gears と Hoare Logic を用いた仕様の証明(完成)

    -
    1    --    whileProofs c = whileTestPwP {_} {_} c 
    -2    --       ( λ env s → conv1 env s 
    -3    --       ( λ env s → loopPwP' (varn env) env refl s 
    -4    --       ( λ env s → vari env ≡ c10 env )))
    -5    ProofGears : (c : ℕ) → whileProofs c
    -6    ProofGears c = whileTestPwP {_} {_} c 
    -7       (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero)
    +  
    1    helperCallwP : (c : ℕ) → whileTestPCallwP' c
    +2    helperCallwP c = whileTestPwP {_} {_} c 
    +3        (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero)
     
    @@ -565,6 +740,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff -r e8655e0264b8 -r 19ab6b8055ea slide/slide.md --- a/slide/slide.md Tue Feb 11 02:31:26 2020 +0900 +++ b/slide/slide.md Wed Feb 12 05:02:27 2020 +0900 @@ -1,13 +1,44 @@ -title: Continuation based C での Hoare Logic を用いた記述と検証 +title: Continuation based C での Hoare Logic を用いた仕様記述と検証 author: 外間政尊 profile: - 琉球大学 : 並列信頼研究室 lang: Japanese @@ -17,11 +48,9 @@ - 信頼性を上げるために仕様の検証が必要 - 検証にはモデル検査や**定理証明**などが存在する - また、仕様検証の手法として **Hoare Logic** がある - - プログラムを書く上である関数は実行する前に必要な引数があって何らかの出力がある + - 通常の関数でも実行する前に必要な引数があって何らかの出力がある - Hoare Logic ではコマンドを実行する上で引数が存在するなどの事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ - -- Hoare Logic では関数が最低限のコマンドまで分割されており記述が困難(変数の代入、コマンド実行の遷移等) -- 大規模なプログラムは構築しづらい +- Hoare Logic では関数が最低限のコマンドで分割されており記述が困難(変数の代入、コマンド実行の遷移等) ## Hoare Logic をベースにした Gears 単位での検証 - 当研究室では 処理の単位を **CodeGear**、データの単位を **DataGear** としてプログラムを記述する手法を提案 @@ -30,240 +59,358 @@ - 定理証明支援機の Agda 上で Gears 単位を用いた検証を行う - 本研究では Gears 単位を用いた Hoare Logic ベースの検証手法を提案する -## Agda のデータ型 -- **データ型**はプリミティブなデータ -- この型のとき値は一意に定まる -```SHELL - data Nat : Set where - zero : Nat - suc : Nat → Nat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Agda +- Agda は関数型言語 +```AGAD + name : type + name = value ``` -- **レコード型**は複数のデータをまとめる -- 複数の値を保持できる -```SHELL - record Env : Set where - field - varn : Nat - vari : Nat +- 関数には型と定義を与える + - 型は **:** で、 値は **=** で与える +- 仮定なしに使えるのは Set のみ +- 構成要素としては以下の3種類 + 1. 関数 + - 型は A → B + - 値は λ x → y + 1. record + 1. data +- つぎは record と data について + +## Agda の record とその例 ∧ +- 2つのものが同時に存在すること +- A ∧ B が成り立っていれば (pi1 A ∧ B) → A、 (pi2 A ∧ B) → B +- Agda ではこのような同時に存在する型を **record** で書く +```AGDA + record _∧_ (A B : Set) : Set + field + pi1 : A + pi2 : B +``` +- _∧_ は中間記法、変数が入る位置を _ で示せる +- 実際の構築は x : A かつ y : B のとき +```AGDA + record {pi1 = x ; pi2 = y} +``` +- のように記述する +- C での構造体のようなもの + +## Agda の data とその例 Sum +- 一つでも存在すること +- A ∨ B が成り立っているとき A → A ∨ B、 B → A ∨ B +- どちらかが成り立つ型を **data** で書く +```AGDA + data _∨_ (A B : Set) : Set where + p1 : A → A ∨ B + p2 : B → A ∨ B +``` +- のように記述できる +- C での union のようなもの +- p1、 p2 は case 文みたいな + +- 次は Hoare Logic + +## Hoare Logic +- Hoare Logic はプログラム検証の手法 +- 事前条件(P)が成り立つとき、コマンド(C)を実行すると事後条件(Q)が成り立つ + - **{P} C {Q}** の形で表される + - コマンドが制限されてる +- 今回は以下のような while program を検証する +- n = 10 となっているが検証では n は任意の自然数 +```C + n = 10; + i = 0; + + while (n>0) + { + i++; + n--; + } +``` +- 次は Agda の Hoare Logic で while program をみる + +## Agda での Hoare Logic +- Hoare Logic のプログラムは Command で構成される +- Comm は data で記述されたコマンド +- このコマンドを使って while program を構築する +```AGDA + data Comm : Set where + Skip : Comm + Abort : Comm + PComm : PrimComm → Comm + Seq : Comm → Comm → Comm + If : Cond → Comm → Comm → Comm + While : Cond → Comm → Comm ``` -## Agda の関数 -- 関数にも同様に型が必要 -```HASKELL - +1 : ℕ → ℕ - +1 m = suc m +## Hoare Logic での while program +- C の while program +```C + n = 10; + i = 0; + + while (n>0) + { + i++; + n--; + } +``` +- Hoare Logic での while program +```AGDA + program : ℕ → Comm + program c10 = + Seq ( PComm (λ env → record env {varn = c10})) + $ Seq ( PComm (λ env → record env {vari = 0})) + $ While (λ env → lt zero (varn env ) ) + (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} )) + $ PComm (λ env → record env {varn = ((varn env) - 1)} )) +``` +- 次は Hoare Logic での検証 - -- eval +1 zero - -- return suc zero -``` -- 関数の型は **input → output** -- 複数入力がある場合は **input1 → input2 → output** -- **=** の左側は関数名と引数、右側に実装 + -## Agda での証明 -- 関数との違いは**型が証明すべき論理式**で**関数自体がそれを満たす導出** -```HASKELL - +zero : { y : Nat } → y + zero ≡ y - +zero {zero} = refl - +zero {suc y} = cong suc ( +zero {y} ) +## Hoare Logic での Command に対応する仕様 +- Command に対応する証明がある +```AGDA + data HTProof : Cond → Comm → Cond → Set where + PrimRule : {bPre : Cond} → {pcm : PrimComm} → {bPost : Cond} → + (pr : Axiom bPre pcm bPost) → + HTProof bPre (PComm pcm) bPost + SkipRule : (b : Cond) → HTProof b Skip b + AbortRule : (bPre : Cond) → (bPost : Cond) → + HTProof bPre Abort bPost + WeakeningRule : {bPre : Cond} → {bPre' : Cond} → {cm : Comm} → + {bPost' : Cond} → {bPost : Cond} → + Tautology bPre bPre' → + HTProof bPre' cm bPost' → + Tautology bPost' bPost → + HTProof bPre cm bPost + SeqRule : {bPre : Cond} → {cm1 : Comm} → {bMid : Cond} → + {cm2 : Comm} → {bPost : Cond} → + HTProof bPre cm1 bMid → + HTProof bMid cm2 bPost → + HTProof bPre (Seq cm1 cm2) bPost + IfRule : {cmThen : Comm} → {cmElse : Comm} → + {bPre : Cond} → {bPost : Cond} → + {b : Cond} → + HTProof (bPre and b) cmThen bPost → + HTProof (bPre and neg b) cmElse bPost → + HTProof bPre (If b cmThen cmElse) bPost + WhileRule : {cm : Comm} → {bInv : Cond} → {b : Cond} → + HTProof (bInv and b) cm bInv → + HTProof bInv (While b cm) (bInv and neg b) ``` -- **refl** は **x ≡ x** -- **cong** は **関数** と等式を受け取って、等式の両辺に関数を適応しても等しくなること -- **+zero** は任意の自然数の右から zero を足しても元の数と等しいことの証明 - - **y = zero** のときは **zero ≡ zero** のため refl - - **y = suc y** のときは cong を使い y の数を減らして帰納的に証明している +- 検証をするためにはこの HTProof で program と同様の仕様を構成する必要がある -## Gears について -- **Gears** は当研究室で提案しているプログラム記述手法 -- 処理の単位を **CodeGear** 、データの単位を **DataGear** +## Hoare Logic での 仕様記述と部分正当性 +- HTProof で記述した仕様 +- lemma は事前条件からコマンドを通して事後条件が成り立つこと(部分正当性)の証明(長いので省略) +```AGDA + proof1 : (c10 : ℕ) → HTProof initCond (program c10 ) (termCond {c10}) + proof1 c10 = + SeqRule {λ e → true} ( PrimRule (init-case {c10} )) + $ SeqRule {λ e → Equal (varn e) c10} ( PrimRule lemma1 ) + $ WeakeningRule {λ e → (Equal (varn e) c10) ∧ (Equal (vari e) 0)} lemma2 ( + WhileRule {_} {λ e → Equal ((varn e) + (vari e)) c10} + $ SeqRule (PrimRule {λ e → whileInv e ∧ lt zero (varn e) } lemma3 ) + $ PrimRule {whileInv'} {_} {whileInv} lemma4 ) lemma5 +``` +- 比較のために元の while program +```AGDA + program : ℕ → Comm + program c10 = + Seq ( PComm (λ env → record env {varn = c10})) + $ Seq ( PComm (λ env → record env {vari = 0})) + $ While (λ env → lt zero (varn env ) ) + (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} )) + $ PComm (λ env → record env {varn = ((varn env) - 1)} )) +``` +- Command と対応した仕様があるため形がほぼ一緒 + - while ループするときに強い条件を緩めている規則が違うくらい(Weacening Rule) +- proof1 は HTProof が正しく繋げることで部分正当性まで証明 + +## Hoare Logic での健全性の証明 +- proof1 は部分正当性を示せた +- 実際に正しく動作すること(健全性)を証明する必要がある +- Satisfies は {P} C {Q} を受け取ってそれらが Comm で正しく成り立つ関係を返す +- PrimSoundness は HTProof を受け取って Satisfies が成り立つことを Soundness を用いて実際に証明する +```AGDA + PrimSoundness : {bPre : Cond} -> {cm : Comm} -> {bPost : Cond} -> + HTProof bPre cm bPost -> Satisfies bPre cm bPost + PrimSoundness {bPre} {cm} {bPost} ht = Soundness ht +``` +- proofOfProgram では 実際に構築した program と proof1 を使って健全性を証明している +```AGDA + proofOfProgram : (c10 : ℕ) → (input output : Env ) + → initCond input ≡ true + → (SemComm (program c10) input output) + → termCond {c10} output ≡ true + proofOfProgram c10 input output ic sem = + PrimSoundness (proof1 c10) input output ic sem +``` + + +## Continuation based C について +- Continuation based C (CbC) は当研究室で開発してるプログラミング言語 +- CbC では処理の単位を **CodeGear** 、データの単位を **DataGear** とする - CodeGear は引数として Input の DataGear を受け取り、 Output の DataGear を返す - Output の DataGear は次の CodeGear の Input として接続される - - CodeGear の接続処理などのメタ計算は Meta CodeGear として定義 - Meta CodeGear で信頼性の検証を行う

    - - -## Agda での DataGear -- **DataGear** は CodeGear でつかわれる引数をまとめたもの -- Agda は CbC の上位言語 - - メタ計算を含めて記述できる -- DataGear は Agda の CodeGear で使うことのできる**全てのデータ** - - -## Agda での CodeGear -- Agda での CodeGear は継続渡しで記述された関数 -```AGDA - whileTest : {t : Set} → (c10 : Nat) - → (Code : Env → t) → t - whileTest c10 next = next (record {varn = c10 - ; vari = 0} ) -``` -- CodeGear の型は継続先を返す関数 -- **(Code : fa → t)** は継続先 -- 引数として継続先の CodeGear を受け取る - -## Agda での Gears の記述(whileLoop) -- 関数の動作を条件で変えたいときはパターンマッチを行う -```AGDA - whileLoop : {l : Level} {t : Set l} → Envc - → (next : Envc → t) → (exit : Envc → t) → t - whileLoop env@(record { c10 = _ ; varn = zero ; vari = _ }) _ exit = exit env - whileLoop record { c10 = _ ; varn = suc varn1 ; vari = vari } next _ = - next (record {c10 = _ ; varn = varn1 ; vari = suc vari }) -``` -- whileLoop は varn が 0 より大きい間ループする - - -## Hoare Logic をベースとした Gears での検証手法 -```C - n = 10; - i = 0; - - while (n>0) - { - i++; - n--; - } -``` -- 今回 Hoare Logic で証明する次のようなコードを検証した -- このプログラムは変数iとnをもち、 n>0 の間nの値を減らし、i の値を増やす -- n ≡ 0 のとき停止するため、終了時の変数の結果は i ≡ 10、n ≡ 0 になる - -## Gears をベースにしたプログラム -```AGDA - test : Env - test = whileTest 10 (λ env → whileLoop env (λ env1 → env1)) - - -- whileTest : {t : Set} → (c10 : Nat) → (Code : Env → t) → t - -- whileLoop : {t : Set} → Env → (Code : Env → t) → t -``` -- test は whileTest と whileLoop を実行した結果を返す関数 -- whileTest の継続先にDataGear を受け取って whileLoop に渡す - - **(λ 引数 → )**は無名の関数で引数を受け取って継続する -## Gears をベースにした Hoare Logic と証明(全体) +## CbC での Hoare Logic +- CodeGear、DataGear を用いた Hoare Logic は図のようになる +

    +- CodeGear が条件を引数として受け、継続先の CodeGear が次の条件を満たす様になる + +## CbC での while program +- 比較用の Hoare Logic での while program ```AGDA - -- test = whileTest 10 (λ env → whileLoop env (λ env1 → env1)) - proofGears : {c10 : Nat } → Set - proofGears {c10} = whileTest' {_} {_} {c10} (λ n p1 → - conversion1 n p1 (λ n1 p2 → whileLoop' n1 p2 - (λ n2 → ( vari n2 ≡ c10 )))) -``` -- proofGears は Hoare Logic をベースとした証明 - - 先程のプログラムと違い、引数として証明も持っている -- whileTest' の継続に conversion1、その継続に whileLoop' が来て最後の継続に vari が c10 と等しい - -## Gears と Hoare Logic をベースにした証明(whileTest) -```AGDA - whileTest' : {l : Level} {t : Set l} {c10 : ℕ } - → (Code : (env : Env ) → ((vari env) ≡ 0) ∧ ((varn env) ≡ c10) → t) → t - whileTest' {_} {_} {c10} next = next - (record env {vari = 0 ; varn = c10 }) (record {pi1 = refl ; pi2 = refl}) + program : ℕ → Comm + program c10 = + Seq ( PComm (λ env → record env {varn = c10})) + $ Seq ( PComm (λ env → record env {vari = 0})) + $ While (λ env → lt zero (varn env ) ) + (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} )) + $ PComm (λ env → record env {varn = ((varn env) - 1)} )) ``` -- 最初の Command なので PreCondition はない -- (record {pi1 = refl ; pi2 = refl}) は **(vari env) ≡ 0** と **(varn env) ≡ c10**の証明 - - **_∧_** は pi1 と pi2 のフィールドをもつレコード型 - - 両方とも成り立つので **refl** -- Gears での PostCondition は **引数 → (Code : fa → PostCondition → t) → t** - -## Gears と Hoare Logic をベースにした証明(conversion) +- CbC での while program ```AGDA - conv : (env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → varn env + vari env ≡ c10 env - conv e record { pi1 = refl ; pi2 = refl } = +zero + whileTestPCall : (c10 : ℕ ) → Envc + whileTestPCall c10 = whileTestP' {_} {_} c10 (λ env → loopP' env (λ env → env)) ``` -- conv は制約を緩める CodeGear - - **(vari env ≡ 0) ∧ (varn env ≡ c10 env)** が成り立つとき **varn env + vari env ≡ c10 env** が成り立つ +- whileTestP' が n = c10、 i = 0 の代入、 loopP' が while loop に対応している +- CbC での Hoare Logic 上でコマンドは CodeGear そのもの + - CodeGear は Hoare Logic のコマンドより自由な記述 - - - - - - - - - - - - -## Gears と Hoare Logic をベースにした証明(whileLoop) +## CbC での HTProof +- HTProof に対応するものは各 Meta CodeGear に条件を渡したもの +- それぞれが事前条件から事後条件を導く証明を持っている ```AGDA - whileLoopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) → (n ≡ varn env) → whileTestStateP s2 env - → (next : (env : Envc ) → (pred n ≡ varn env) → whileTestStateP s2 env → t) - → (exit : (env : Envc ) → whileTestStateP sf env → t) → t - whileLoopPwP' zero env refl refl next exit = exit env refl - whileLoopPwP' (suc n) env refl refl next exit = - next (record env {varn = pred (varn env) ; vari = suc (vari env) }) refl (+-suc n (vari env)) - - loopPwP' zero env refl refl exit = exit env refl - loopPwP' (suc n) env refl refl exit = whileLoopPwP' (suc n) env refl refl - (λ env x y → loopPwP' n env x y exit) exit + whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) + → ((env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → t) → t + whileTestPwP c10 next = + next (whileTestP c10 ( λ env → env )) (record { pi1 = refl ; pi2 = refl }) ``` -- whileLoop も whileTest と同様に PreCondition が CodeGear に入りそれに対する証明が記述されている -- ループが回るごとに、**whileLoopPwP'** で停止か継続かを判断し、 **loopPwP'** でループが回る - - -## Gears と Hoare Logic をベースにした仕様記述 +- whileTestPCallwP' は Hoare Logic の HTProof 記述 proof1 に相当 +- 比較用 proof1 ```AGDA - whileProofs : (c : ℕ ) → Set - whileProofs c = whileTestPwP {_} {_} c - ( λ env s → conv1 env s - ( λ env s → loopPwP' (varn env) env refl s - ( λ env s → vari env ≡ c10 env ))) + proof1 : (c10 : ℕ) → HTProof initCond (program c10 ) (termCond {c10}) + proof1 c10 = + SeqRule {λ e → true} ( PrimRule (init-case {c10} )) + $ SeqRule {λ e → Equal (varn e) c10} ( PrimRule lemma1 ) + $ WeakeningRule {λ e → (Equal (varn e) c10) ∧ (Equal (vari e) 0)} lemma2 ( + WhileRule {_} {λ e → Equal ((varn e) + (vari e)) c10} + $ SeqRule (PrimRule {λ e → whileInv e ∧ lt zero (varn e) } lemma3 ) + $ PrimRule {whileInv'} {_} {whileInv} lemma4 ) lemma5 ``` -- **whileProofs** では最終状態が vari と c10 が等しくなるため仕様になっている +- proof1 の lemma に相当する証明は Meta CodeGear で、継続先の CodeGear に渡す条件の証明 +```AGDA + whileTestPCallwP' : (c : ℕ ) → Set + whileTestPCallwP' c = whileTestPwP {_} {_} c ( + λ env s → loopPwP' (varn env) env refl (conv env s) + ( λ env s → vari env ≡ c10 env ) ) +``` +- Hoare Logic では実装、部分正当性を分けて記述していた +- CbC での Hoare Logic は実装と部分正当性を一体化できる - - -## Gears と Hoare Logic を用いた仕様の証明 +## CbC での Soundness +- 先程の whileTestPCallwP' を命題として証明すると健全性が示せる ```AGDA --- whileProofs c = whileTestPwP {_} {_} c --- ( λ env s → conv1 env s --- ( λ env s → loopPwP' (varn env) env refl s --- ( λ env s → vari env ≡ c10 env ))) - - ProofGears : (c : ℕ) → whileProofs c - ProofGears c = whileTestPwP {_} {_} c - (λ env s → loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl +zero - (λ env₁ s₁ → {!!})) - - Goal: loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl - +zero (λ env₂ s₂ → vari env₂ ≡ c10 env₂) - ———————————————————————————————————————————————————————————— - s₁ : vari env₁ ≡ c10 env₁ - env₁ : Envc - s : (vari env ≡ 0) /\ (varn env ≡ c10 env) - env : Envc - c : ℕ + whileTestPCallwP' : (c : ℕ ) → Set + whileTestPCallwP' c = whileTestPwP {_} {_} c ( + λ env s → loopPwP' (varn env) env refl (conv env s) + ( λ env s → vari env ≡ c10 env ) ) ``` -- 先程の **whileProofs** で行った仕様記述を型に記述し、実際に証明していく -- しかし loopPwP' のループが進まず証明できない +- 実際に値が入ると命題は成り立つが任意の値だと停止せず証明が終わらない +```AGDA + whileCallwP : (c : ℕ) → whileTestPCallwP' c + whileCallwP c = whileTestPwP {_} {_} c (λ env s → + loopPwP' (c10 env) env (sym (pi2 s)) (conv env s) {!!}) +``` ## 検証時の Loop の解決 +- **loopHelper** は今回のループを解決する証明 ```AGDA - loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) → (seq : whileTestStateP s2 env) - → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁)) - loopHelper zero env eq refl rewrite eq = refl - loopHelper (suc n) env eq refl rewrite eq = loopHelper n - (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) refl (+-suc n (vari env)) + loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) + → (varn env + vari env ≡ c10 env) + → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁)) + loopHelper zero env eq refl rewrite eq = refl + loopHelper (suc n) env eq refl rewrite eq = loopHelper n + (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) + refl (+-suc n (vari env)) ``` -- **loopHelper** は今回のループを解決する証明 -- ループ解決のためにループの簡約ができた +- ここでは任意の回数回る while loop が必ず最終条件を満たす ## Gears と Hoare Logic を用いた仕様の証明(完成) ```AGDA - -- whileProofs c = whileTestPwP {_} {_} c - -- ( λ env s → conv1 env s - -- ( λ env s → loopPwP' (varn env) env refl s - -- ( λ env s → vari env ≡ c10 env ))) - ProofGears : (c : ℕ) → whileProofs c - ProofGears c = whileTestPwP {_} {_} c - (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero) + helperCallwP : (c : ℕ) → whileTestPCallwP' c + helperCallwP c = whileTestPwP {_} {_} c + (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero) ``` -- **loopHelper** を使って簡約することで **whileProofs** の証明を行うことができた + - **loopHelper** を使って簡約することで **whileProofs** の証明を行うことができた ## まとめと今後の課題 - CodeGear、 DataGear を用いた Hoare Logic ベースの仕様記述を導入した @@ -273,3 +420,236 @@ - BinaryTree の有限ループに対する証明 - Hoare Logic で検証されたコードの CbC 変換 - 並列実行での検証 + + + + + + + + + + + + + + + + + + + + +## Agda での CodeGear +- Agda での CodeGear は継続渡しで記述された関数 +```AGDA + whileTest : {t : Set} → (c10 : Nat) + → (Code : Env → t) → t + whileTest c10 next = next (record {varn = c10 + ; vari = 0} ) + ``` + - CodeGear の型は継続先を返す関数 + - **(Code : fa → t)** は継続先 + - 引数として継続先の CodeGear を受け取る + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## まとめと今後の課題 +- CodeGear、 DataGear を用いた Hoare Logic ベースの仕様記述を導入した +- Hoare Logic ベースの検証を実際に行うことができた +- 証明時の任意回の有限ループに対する解決を行えた +- 今後の課題 + - BinaryTree の有限ループに対する証明 + - Hoare Logic で検証されたコードの CbC 変換 + - 並列実行での検証 + + +```AGDA +loopPPSem : (input output : Envc ) → output ≡ loopPP (varn input) input refl + → (varn input + vari input ≡ c10 input ) → (varn input + vari input ≡ c10 input ) implies (vari output ≡ c10 output) +loopPPSem input output refl s2p = loopPPSemInduct (varn input) input refl refl s2p + where + lem : (n : ℕ) → (env : Envc) → n + suc (vari env) ≡ suc (n + vari env) + lem n env = +-suc (n) (vari env) + loopPPSemInduct : (n : ℕ) → (current : Envc) → (eq : n ≡ varn current) + → (loopeq : output ≡ loopPP n current eq) + → (whileTestStateP s2 current ) + → (whileTestStateP s2 current ) implies (vari output ≡ c10 output) + loopPPSemInduct zero current refl loopeq refl rewrite loopeq = proof (λ x → refl) + loopPPSemInduct (suc n) current refl loopeq refl rewrite (sym (lem n current)) = + whileLoopPSem current refl + (λ output x → loopPPSemInduct n (record { c10 = n + suc (vari current) ; varn = n ; vari = suc (vari current) }) refl loopeq refl) + (λ output x → loopPPSemInduct n (record { c10 = n + suc (vari current) ; varn = n ; vari = suc (vari current) }) refl loopeq refl) +``` + +```AGDA +whileLoopPSem : {l : Level} {t : Set l} → (input : Envc ) → varn input + vari input ≡ c10 input + → (next : (output : Envc ) + → (varn input + vari input ≡ c10 input) implies (varn output + vari output ≡ c10 output ) → t) + → (exit : (output : Envc ) + → (varn input + vari input ≡ c10 input ) implies (vari env) ≡ (c10 env) → t) → t +whileLoopPSem env s next exit with varn env | s +... | zero | _ = exit env (proof (λ z → z)) +... | (suc varn ) | refl = next ( record env { varn = varn ; vari = suc (vari env) } ) + (proof λ x → +-suc varn (vari env) ) +``` diff -r e8655e0264b8 -r 19ab6b8055ea slide/slide.mm --- a/slide/slide.mm Tue Feb 11 02:31:26 2020 +0900 +++ b/slide/slide.mm Wed Feb 12 05:02:27 2020 +0900 @@ -34,17 +34,18 @@ - + + - + - + - + @@ -53,11 +54,26 @@ - - + + - + + + + + + + + + + + + + + + + diff -r e8655e0264b8 -r 19ab6b8055ea slide/slide.pdf.html --- a/slide/slide.pdf.html Tue Feb 11 02:31:26 2020 +0900 +++ b/slide/slide.pdf.html Wed Feb 12 05:02:27 2020 +0900 @@ -7,7 +7,7 @@ - Continuation based C での Hoare Logic を用いた記述と検証 + Continuation based C での Hoare Logic を用いた仕様記述と検証 @@ -55,7 +55,7 @@
    -

    Continuation based C での Hoare Logic を用いた記述と検証

    +

    Continuation based C での Hoare Logic を用いた仕様記述と検証

    @@ -75,9 +75,40 @@
    @@ -89,13 +120,11 @@
  • 検証にはモデル検査や定理証明などが存在する
  • また、仕様検証の手法として Hoare Logic がある
      -
    • プログラムを書く上である関数は実行する前に必要な引数があって何らかの出力がある
    • -
    • Hoare Logic ではコマンドを実行する上で引数が存在するなどの事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ -
    • +
    • 通常の関数でも実行する前に必要な引数があって何らかの出力がある
    • +
    • Hoare Logic ではコマンドを実行する上で引数が存在するなどの事前に成り立つ条件があり、コマンド実行後に異なる条件が成り立つ
  • -
  • Hoare Logic では関数が最低限のコマンドまで分割されており記述が困難(変数の代入、コマンド実行の遷移等)
  • -
  • 大規模なプログラムは構築しづらい
  • +
  • Hoare Logic では関数が最低限のコマンドで分割されており記述が困難(変数の代入、コマンド実行の遷移等)
  • @@ -113,31 +142,190 @@
  • 本研究では Gears 単位を用いた Hoare Logic ベースの検証手法を提案する
  • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +

    Agda

    +
      +
    • Agda は関数型言語 +
      +
      1  name : type
      +2  name = value
      +
      +
      +
      +
    • +
    • 関数には型と定義を与える +
        +
      • 型は : で、 値は = で与える
      • +
      +
    • +
    • 仮定なしに使えるのは Set のみ
    • +
    • 構成要素としては以下の3種類 +
        +
      1. 関数 +
          +
        • 型は A → B
        • +
        • 値は λ x → y
        • +
        +
      2. +
      3. record
      4. +
      5. data
      6. +
      +
    • +
    • つぎは record と data について
    • +
    +
    -

    Agda のデータ型

    +

    Agda の record とその例 ∧

      -
    • データ型はプリミティブなデータ
    • -
    • この型のとき値は一意に定まる -
      -
      1  data Nat : Set where
      -2      zero : Nat
      -3      suc  : Nat → Nat
      +  
    • 2つのものが同時に存在すること
    • +
    • A ∧ B が成り立っていれば (pi1 A ∧ B) → A、 (pi2 A ∧ B) → B
    • +
    • Agda ではこのような同時に存在する型を record で書く +
      +
      1 record _∧_ (A B : Set) : Set
      +2   field
      +3       pi1 : A
      +4       pi2 : B
      +
      +
      +
      +
    • +
    • は中間記法、変数が入る位置を _ で示せる
    • +
    • 実際の構築は x : A かつ y : B のとき +
      +
      1 record {pi1 = x ; pi2 = y}
      +
      +
      +
      +
    • +
    • のように記述する
    • +
    • C での構造体のようなもの
    • +
    + + + +
    + +
    + +

    Agda の data とその例 Sum

    +
      +
    • 一つでも存在すること
    • +
    • A ∨ B が成り立っているとき A → A ∨ B、 B → A ∨ B
    • +
    • どちらかが成り立つ型を data で書く +
      +
      1  data _∨_ (A B : Set) : Set where
      +2     p1 : A → A ∨ B
      +3     p2 : B → A ∨ B
       
    • -
    • レコード型は複数のデータをまとめる
    • -
    • 複数の値を保持できる -
      -
      1  record Env : Set where 
      -2      field
      -3        varn : Nat
      -4        vari : Nat
      +  
    • のように記述できる
    • +
    • C での union のようなもの
    • +
    • +

      p1、 p2 は case 文みたいな

      +
    • +
    • 次は Hoare Logic
    • +
    + + + +
    + +
    + +

    Hoare Logic

    +
      +
    • Hoare Logic はプログラム検証の手法
    • +
    • 事前条件(P)が成り立つとき、コマンド(C)を実行すると事後条件(Q)が成り立つ +
        +
      • {P} C {Q} の形で表される
      • +
      • コマンドが制限されてる
      • +
      +
    • +
    • 今回は以下のような while program を検証する
    • +
    • n = 10 となっているが検証では n は任意の自然数 +
      +
      1  n = 10;
      +2  i = 0;
      +3
      +4  while (n>0)
      +5  {
      +6    i++;
      +7    n--;
      +8  }
      +
      +
      +
      +
    • +
    • 次は Agda の Hoare Logic で while program をみる
    • +
    + + + +
    + +
    + +

    Agda での Hoare Logic

    +
      +
    • Hoare Logic のプログラムは Command で構成される
    • +
    • Comm は data で記述されたコマンド
    • +
    • このコマンドを使って while program を構築する +
      +
      1  data Comm : Set where
      +2    Skip  : Comm
      +3    Abort : Comm
      +4    PComm : PrimComm → Comm
      +5    Seq   : Comm → Comm → Comm
      +6    If    : Cond → Comm → Comm → Comm
      +7    While : Cond → Comm → Comm
       
      @@ -150,22 +338,104 @@
      -

      Agda の関数

      +

      Hoare Logic での while program

        -
      • 関数にも同様に型が必要 -
        -
        1  +1 : ℕ → ℕ
        -2  +1 m = suc m
        +  
      • C の while program +
        +
        1  n = 10;
        +2  i = 0;
         3
        -4  -- eval +1 zero
        -5  -- return suc zero
        +4  while (n>0)
        +5  {
        +6    i++;
        +7    n--;
        +8  }
        +
        +
        +
        +
      • +
      • Hoare Logic での while program +
        +
        1  program : ℕ → Comm
        +2  program c10 = 
        +3      Seq ( PComm (λ env → record env {varn = c10}))
        +4      $ Seq ( PComm (λ env → record env {vari = 0}))
        +5      $ While (λ env → lt zero (varn env ) )
        +6        (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} ))
        +7          $ PComm (λ env → record env {varn = ((varn env) - 1)} ))
         
      • -
      • 関数の型は input → output
      • -
      • 複数入力がある場合は input1 → input2 → output
      • -
      • = の左側は関数名と引数、右側に実装
      • +
      • 次は Hoare Logic での検証
      • +
      + + + + + +
      + +
      + +

      Hoare Logic での Command に対応する仕様

      +
        +
      • Command に対応する証明がある +
        +
         1  data HTProof : Cond → Comm → Cond → Set where
        + 2    PrimRule : {bPre : Cond} → {pcm : PrimComm} → {bPost : Cond} →
        + 3               (pr : Axiom bPre pcm bPost) →
        + 4               HTProof bPre (PComm pcm) bPost
        + 5    SkipRule : (b : Cond) → HTProof b Skip b
        + 6    AbortRule : (bPre : Cond) → (bPost : Cond) →
        + 7                HTProof bPre Abort bPost
        + 8    WeakeningRule : {bPre : Cond} → {bPre' : Cond} → {cm : Comm} →
        + 9                  {bPost' : Cond} → {bPost : Cond} →
        +10                  Tautology bPre bPre' →
        +11                  HTProof bPre' cm bPost' →
        +12                  Tautology bPost' bPost →
        +13                  HTProof bPre cm bPost
        +14    SeqRule : {bPre : Cond} → {cm1 : Comm} → {bMid : Cond} →
        +15              {cm2 : Comm} → {bPost : Cond} →
        +16              HTProof bPre cm1 bMid →
        +17              HTProof bMid cm2 bPost →
        +18              HTProof bPre (Seq cm1 cm2) bPost
        +19    IfRule : {cmThen : Comm} → {cmElse : Comm} →
        +20             {bPre : Cond} → {bPost : Cond} →
        +21             {b : Cond} →
        +22             HTProof (bPre and b) cmThen bPost →
        +23             HTProof (bPre and neg b) cmElse bPost →
        +24             HTProof bPre (If b cmThen cmElse) bPost
        +25    WhileRule : {cm : Comm} → {bInv : Cond} → {b : Cond} →
        +26                HTProof (bInv and b) cm bInv →
        +27                HTProof bInv (While b cm) (bInv and neg b)
        +
        +
        +
        +
      • +
      • 検証をするためにはこの HTProof で program と同様の仕様を構成する必要がある
      @@ -174,25 +444,76 @@
      -

      Agda での証明

      +

      Hoare Logic での 仕様記述と部分正当性

        -
      • 関数との違いは型が証明すべき論理式関数自体がそれを満たす導出 -
        -
        1  +zero : { y : Nat } → y + zero ≡ y
        -2  +zero {zero} = refl
        -3  +zero {suc y} = cong suc ( +zero {y} )
        +  
      • HTProof で記述した仕様
      • +
      • lemma は事前条件からコマンドを通して事後条件が成り立つこと(部分正当性)の証明(長いので省略) +
        +
        1  proof1 : (c10 : ℕ) → HTProof initCond (program c10 ) (termCond {c10})
        +2  proof1 c10 =
        +3      SeqRule {λ e → true} ( PrimRule (init-case {c10} ))
        +4      $ SeqRule {λ e →  Equal (varn e) c10} ( PrimRule lemma1   )
        +5      $ WeakeningRule {λ e → (Equal (varn e) c10) ∧ (Equal (vari e) 0)}  lemma2 (
        +6              WhileRule {_} {λ e → Equal ((varn e) + (vari e)) c10}
        +7              $ SeqRule (PrimRule {λ e →  whileInv e  ∧ lt zero (varn e) } lemma3 )
        +8                       $ PrimRule {whileInv'} {_} {whileInv}  lemma4 ) lemma5
        +
        +
        +
        +
      • +
      • 比較のために元の while program +
        +
        1  program : ℕ → Comm
        +2  program c10 = 
        +3      Seq ( PComm (λ env → record env {varn = c10}))
        +4      $ Seq ( PComm (λ env → record env {vari = 0}))
        +5      $ While (λ env → lt zero (varn env ) )
        +6        (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} ))
        +7          $ PComm (λ env → record env {varn = ((varn env) - 1)} ))
         
      • -
      • reflx ≡ x
      • -
      • cong関数 と等式を受け取って、等式の両辺に関数を適応しても等しくなること
      • -
      • +zero は任意の自然数の右から zero を足しても元の数と等しいことの証明 +
      • Command と対応した仕様があるため形がほぼ一緒
          -
        • y = zero のときは zero ≡ zero のため refl
        • -
        • y = suc y のときは cong を使い y の数を減らして帰納的に証明している
        • +
        • while ループするときに強い条件を緩めている規則が違うくらい(Weacening Rule)
      • +
      • proof1 は HTProof が正しく繋げることで部分正当性まで証明
      • +
      + + + +
      + +
      + +

      Hoare Logic での健全性の証明

      +
        +
      • proof1 は部分正当性を示せた
      • +
      • 実際に正しく動作すること(健全性)を証明する必要がある
      • +
      • Satisfies は {P} C {Q} を受け取ってそれらが Comm で正しく成り立つ関係を返す
      • +
      • PrimSoundness は HTProof を受け取って Satisfies が成り立つことを Soundness を用いて実際に証明する +
        +
        1  PrimSoundness : {bPre : Cond} -> {cm : Comm} -> {bPost : Cond} ->
        +2              HTProof bPre cm bPost -> Satisfies bPre cm bPost
        +3  PrimSoundness {bPre} {cm} {bPost} ht = Soundness ht
        +
        +
        +
        +
      • +
      • proofOfProgram では 実際に構築した program と proof1 を使って健全性を証明している +
        +
        1  proofOfProgram : (c10 : ℕ) → (input output : Env )
        +2    → initCond input ≡ true
        +3    → (SemComm (program c10) input output)
        +4    → termCond {c10} output ≡ true
        +5  proofOfProgram c10 input output ic sem  = 
        +6    PrimSoundness (proof1 c10) input output ic sem
        +
        +
        +
        +
      @@ -201,18 +522,16 @@
      -

      Gears について

      +

      Continuation based C について

        -
      • Gears は当研究室で提案しているプログラム記述手法
      • -
      • 処理の単位を CodeGear 、データの単位を DataGear
      • +
      • Continuation based C (CbC) は当研究室で開発してるプログラミング言語
      • +
      • CbC では処理の単位を CodeGear 、データの単位を DataGear とする
      • CodeGear は引数として Input の DataGear を受け取り、 Output の DataGear を返す
      • -
      • Output の DataGear は次の CodeGear の Input として接続される -
      • +
      • Output の DataGear は次の CodeGear の Input として接続される
      • CodeGear の接続処理などのメタ計算は Meta CodeGear として定義
      • Meta CodeGear で信頼性の検証を行う

      - @@ -220,34 +539,13 @@
      -

      Agda での DataGear

      +

      CbC での Hoare Logic

        -
      • DataGear は CodeGear でつかわれる引数をまとめたもの
      • -
      • Agda は CodeGear、 DataGear は検証メタ計算そのものと考えられる
      • -
      • DataGear は Agda の CodeGear で使われる全てのデータに当たる
      • +
      • CodeGear、DataGear を用いた Hoare Logic は図のようになる
      - - - -
      - -
      - -

      Agda での CodeGear

      +

        -
      • Agda での CodeGear は継続渡しで記述された関数 -
        -
        1  whileTest : {t : Set} → (c10 : Nat) 
        -2                → (Code : Env → t) → t
        -3  whileTest c10 next = next (record {varn = c10 
        -4                                     ; vari = 0} )
        -
        -
        -
        -
      • -
      • CodeGear の型は引数 → (Code : fa → t) → t
      • -
      • (Code : fa → t) は継続先
      • -
      • 引数として継続先を受け取って計算結果を渡す
      • +
      • CodeGear が条件を引数として受け、継続先の CodeGear が次の条件を満たす様になる
      @@ -256,68 +554,33 @@
      -

      Agda での Gears の記述(whileLoop)

      +

      CbC での while program

        -
      • 関数の動作を条件で変えたいときはパターンマッチを行う +
      • 比較用の Hoare Logic での while program
        -
        1  whileLoop : {l : Level} {t : Set l} → Envc 
        -2     → (next : Envc → t) → (exit : Envc → t) → t
        -3  whileLoop env@(record { c10 = _ ; varn = zero ; vari = _ }) _ exit = exit env
        -4  whileLoop record { c10 = _ ; varn = suc varn1 ; vari = vari } next _ = 
        -5       next (record {c10 = _ ; varn = varn1 ; vari = suc vari })
        +  
        1  program : ℕ → Comm
        +2  program c10 = 
        +3      Seq ( PComm (λ env → record env {varn = c10}))
        +4      $ Seq ( PComm (λ env → record env {vari = 0}))
        +5      $ While (λ env → lt zero (varn env ) )
        +6        (Seq (PComm (λ env → record env {vari = ((vari env) + 1)} ))
        +7          $ PComm (λ env → record env {varn = ((varn env) - 1)} ))
         
      • -
      • whileLoop は varn が 0 より大きい間ループする
      • -
      - - - -
      - -
      - -

      Hoare Logic をベースとした Gears での検証手法

      -
      -
      1   n = 10;
      -2   i = 0;
      -3
      -4   while (n>0)
      -5   {
      -6     i++;
      -7     n--;
      -8   }
      +  
    • CbC での while program +
      +
      1  whileTestPCall : (c10 :  ℕ ) → Envc
      +2  whileTestPCall c10 = whileTestP' {_} {_} c10 (λ env → loopP' env (λ env →  env))
       
      -
      -
        -
      • 今回 Hoare Logic で証明する次のようなコードを検証した
      • -
      • このプログラムは変数iとnをもち、 n>0 の間nの値を減らし、i の値を増やす
      • -
      • n ≡ 0 のとき停止するため、終了時の変数の結果は i ≡ 10、n ≡ 0 になる
      • -
      - - - -
    • - -
      - -

      Gears をベースにしたプログラム

      -
      -
      1    test : Env
      -2    test = whileTest 10 (λ env → whileLoop env (λ env1 → env1))
      -3
      -4    -- whileTest : {t : Set} → (c10 : Nat) → (Code : Env → t) → t
      -5    -- whileLoop : {t : Set} → Env → (Code : Env → t) → t
      -
      -
      -
      -
        -
      • test は whileTest と whileLoop を実行した結果を返す関数
      • -
      • whileTest の継続先にDataGear を受け取って whileLoop に渡す +
      +
    • +
    • whileTestP’ が n = c10、 i = 0 の代入、 loopP’ が while loop に対応している
    • +
    • CbC での Hoare Logic 上でコマンドは CodeGear そのもの
        -
      • (λ 引数 → )は無名の関数で引数を受け取って継続する
      • +
      • CodeGear は Hoare Logic のコマンドより自由な記述
    @@ -328,49 +591,46 @@
    -

    Gears をベースにした Hoare Logic と証明(全体)

    -
    -
    1    -- test = whileTest 10 (λ env → whileLoop env (λ env1 → env1))
    -2    proofGears : {c10 :  Nat } → Set
    -3    proofGears {c10} = whileTest' {_} {_} {c10} (λ n p1 →
    -4             conversion1 n p1  (λ n1 p2 → whileLoop' n1 p2 
    -5             (λ n2 →  ( vari n2 ≡ c10 )))) 
    +

    CbC での HTProof

    +
      +
    • HTProof に対応するものは各 Meta CodeGear に条件を渡したもの
    • +
    • それぞれが事前条件から事後条件を導く証明を持っている +
      +
      1  whileTestPwP : {l : Level} {t : Set l} → (c10 : ℕ) 
      +2    → ((env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → t) → t
      +3  whileTestPwP c10 next = 
      +4    next (whileTestP c10 ( λ env → env )) (record { pi1 = refl ; pi2 = refl })
       
      -
      -
        -
      • proofGears は Hoare Logic をベースとした証明 -
          -
        • 先程のプログラムと違い、引数として証明も持っている
        • -
        +
    -
  • whileTest’ の継続に conversion1、その継続に whileLoop’ が来て最後の継続に vari が c10 と等しい
  • - - - - -
    - -
    - -

    Gears と Hoare Logic をベースにした証明(whileTest)

    -
    -
    1    whileTest' : {l : Level} {t : Set l} {c10 :  ℕ } 
    -2      → (Code : (env : Env )  → ((vari env) ≡ 0) ∧ ((varn env) ≡ c10) → t) → t
    -3    whileTest' {_} {_}  {c10} next = next 
    -4      (record env {vari = 0 ; varn = c10 }) (record {pi1 = refl ; pi2 = refl})
    +  
  • whileTestPCallwP’ は Hoare Logic の HTProof 記述 proof1 に相当
  • +
  • 比較用 proof1 +
    +
    1  proof1 : (c10 : ℕ) → HTProof initCond (program c10 ) (termCond {c10})
    +2  proof1 c10 =
    +3      SeqRule {λ e → true} ( PrimRule (init-case {c10} ))
    +4      $ SeqRule {λ e →  Equal (varn e) c10} ( PrimRule lemma1   )
    +5      $ WeakeningRule {λ e → (Equal (varn e) c10) ∧ (Equal (vari e) 0)}  lemma2 (
    +6              WhileRule {_} {λ e → Equal ((varn e) + (vari e)) c10}
    +7              $ SeqRule (PrimRule {λ e →  whileInv e  ∧ lt zero (varn e) } lemma3 )
    +8                       $ PrimRule {whileInv'} {_} {whileInv}  lemma4 ) lemma5
     
    +
    +
  • +
  • proof1 の lemma に相当する証明は Meta CodeGear で、継続先の CodeGear に渡す条件の証明 +
    +
    1  whileTestPCallwP' : (c :  ℕ ) → Set
    +2  whileTestPCallwP' c = whileTestPwP {_} {_} c (
    +3      λ env s → loopPwP' (varn env) env refl (conv env s) 
    +4        ( λ env s → vari env ≡ c10 env )  )
    +
    -
      -
    • 最初の Command なので PreCondition はない
    • -
    • (record {pi1 = refl ; pi2 = refl}) は (vari env) ≡ 0(varn env) ≡ c10の証明 -
        -
      • は pi1 と pi2 のフィールドをもつレコード型
      • -
      • 両方とも成り立つので refl
      • -
      +
  • -
  • Gears での PostCondition は 引数 → (Code : fa → PostCondition → t) → t
  • +
  • Hoare Logic では実装、部分正当性を分けて記述していた
  • +
  • CbC での Hoare Logic は実装と部分正当性を一体化できる
  • @@ -379,111 +639,27 @@
    -

    Gears と Hoare Logic をベースにした証明(conversion)

    -
    -
    1    conv : (env : Envc ) → (vari env ≡ 0) ∧ (varn env ≡ c10 env) → varn env + vari env ≡ c10 env
    -2    conv e record { pi1 = refl ; pi2 = refl } = +zero
    -
    -
    -
    +

    CbC での Soundness

      -
    • conv は制約を緩める CodeGear -
        -
      • (vari env ≡ 0) ∧ (varn env ≡ c10 env) が成り立つとき varn env + vari env ≡ c10 env が成り立つ
      • -
      -
    • -
    - - - - - - - - - - - - - - - -
    - -
    - -

    Gears と Hoare Logic をベースにした証明(whileLoop)

    -
    -
     1    whileLoopPwP' : {l : Level} {t : Set l} → (n : ℕ) → (env : Envc ) → (n ≡ varn env) → whileTestStateP s2 env
    - 2      → (next : (env : Envc ) → (pred n ≡ varn env) → whileTestStateP s2 env  → t)
    - 3      → (exit : (env : Envc ) → whileTestStateP sf env  → t) → t
    - 4    whileLoopPwP' zero env refl refl next exit = exit env refl
    - 5    whileLoopPwP' (suc n) env refl refl next exit = 
    - 6      next (record env {varn = pred (varn env) ; vari = suc (vari env) }) refl (+-suc n (vari env))
    - 7
    - 8    loopPwP' zero env refl refl exit = exit env refl
    - 9    loopPwP' (suc n) env refl refl exit  = whileLoopPwP' (suc n) env refl refl 
    -10        (λ env x y → loopPwP' n env x y exit) exit
    +  
  • 先程の whileTestPCallwP’ を命題として証明すると健全性が示せる +
    +
    1  whileTestPCallwP' : (c :  ℕ ) → Set
    +2  whileTestPCallwP' c = whileTestPwP {_} {_} c (
    +3      λ env s → loopPwP' (varn env) env refl (conv env s) 
    +4        ( λ env s → vari env ≡ c10 env )  )
     
    -
    -
      -
    • whileLoop も whileTest と同様に PreCondition が CodeGear に入りそれに対する証明が記述されている
    • -
    • ループが回るごとに、whileLoopPwP’ で停止か継続かを判断し、 loopPwP’ でループが回る
    • -
    - - - -
  • - -
    - -

    Gears と Hoare Logic をベースにした仕様記述

    -
    -
    1    whileProofs : (c :  ℕ ) → Set
    -2    whileProofs c = whileTestPwP {_} {_} c 
    -3       ( λ env s → conv1 env s 
    -4       ( λ env s → loopPwP' (varn env) env refl s 
    -5       ( λ env s → vari env ≡ c10 env )))
    +    
    + +
  • 実際に値が入ると命題は成り立つが任意の値だと停止せず証明が終わらない +
    +
    1  whileCallwP : (c : ℕ) → whileTestPCallwP' c
    +2  whileCallwP c = whileTestPwP {_} {_} c (λ env s →
    +3    loopPwP' (c10 env) env (sym (pi2 s)) (conv env s) {!!})
     
    -
    -
      -
    • whileProofs では最終状態が vari と c10 が等しくなるため仕様になっている
    • -
    - - - -
  • - -
    - -

    Gears と Hoare Logic を用いた仕様の証明

    -
    -
     1--    whileProofs c = whileTestPwP {_} {_} c 
    - 2--       ( λ env s → conv1 env s 
    - 3--       ( λ env s → loopPwP' (varn env) env refl s 
    - 4--       ( λ env s → vari env ≡ c10 env )))
    - 5
    - 6    ProofGears : (c : ℕ) → whileProofs c
    - 7    ProofGears c = whileTestPwP {_} {_} c
    - 8      (λ env s →  loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl +zero
    - 9      (λ env₁ s₁ → {!!}))
    -10
    -11    Goal: loopPwP' c (record { c10 = c ; varn = c ; vari = 0 }) refl
    -12          +zero (λ env₂ s₂ → vari env₂ ≡ c10 env₂)
    -13    ------------------------------------------------------------
    -14    s₁   : vari env₁ ≡ c10 env₁
    -15    env₁ : Envc
    -16    s    : (vari env ≡ 0) /\ (varn env ≡ c10 env)
    -17    env  : Envc
    -18    c    : ℕ
    -
    -
    -
    -
      -
    • 先程の whileProofs で行った仕様記述を型に記述し、実際に証明していく
    • -
    • しかし loopPwP’ のループが進まず証明できない
    • +
    + @@ -493,18 +669,21 @@

    検証時の Loop の解決

    -
    -
    1    loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) → (seq : whileTestStateP s2 env) 
    -2      → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁))
    -3    loopHelper zero env eq refl rewrite eq = refl
    -4    loopHelper (suc n) env eq refl rewrite eq = loopHelper n 
    -5      (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) refl (+-suc n (vari env))
    +
      +
    • loopHelper は今回のループを解決する証明 +
      +
      1   loopHelper : (n : ℕ) → (env : Envc ) → (eq : varn env ≡ n) 
      +2     → (varn env + vari env ≡ c10 env)
      +3     → loopPwP' n env (sym eq) seq (λ env₁ x → (vari env₁ ≡ c10 env₁))
      +4   loopHelper zero env eq refl rewrite eq = refl
      +5   loopHelper (suc n) env eq refl rewrite eq = loopHelper n 
      +6       (record { c10 = suc (n + vari env) ; varn = n ; vari = suc (vari env) }) 
      +7         refl (+-suc n (vari env))
       
      -
      -
        -
      • loopHelper は今回のループを解決する証明
      • -
      • ループ解決のためにループの簡約ができた
      • +
    + +
  • ここでは任意の回数回る while loop が必ず最終条件を満たす
  • @@ -515,13 +694,9 @@

    Gears と Hoare Logic を用いた仕様の証明(完成)

    -
    1    --    whileProofs c = whileTestPwP {_} {_} c 
    -2    --       ( λ env s → conv1 env s 
    -3    --       ( λ env s → loopPwP' (varn env) env refl s 
    -4    --       ( λ env s → vari env ≡ c10 env )))
    -5    ProofGears : (c : ℕ) → whileProofs c
    -6    ProofGears c = whileTestPwP {_} {_} c 
    -7       (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero)
    +  
    1    helperCallwP : (c : ℕ) → whileTestPCallwP' c
    +2    helperCallwP c = whileTestPwP {_} {_} c 
    +3        (λ env s → loopHelper c (record { c10 = c ; varn = c ; vari = zero }) refl +zero)
     
    @@ -549,6 +724,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +