Mercurial > hg > Gears > GearsAgda
diff ModelChecking.agda @ 949:057d3309ed9d
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 04 Aug 2024 13:05:12 +0900 |
parents | f2a3f5707075 |
children |
line wrap: on
line diff
--- a/ModelChecking.agda Sat Jul 20 17:01:50 2024 +0900 +++ b/ModelChecking.agda Sun Aug 04 13:05:12 2024 +0900 @@ -1,3 +1,5 @@ +-- {-# OPTIONS --cubical-compatible --allow-unsolved-metas #-} +{-# OPTIONS --cubical-compatible --safe #-} module ModelChecking where open import Level renaming (zero to Z ; suc to succ) @@ -33,44 +35,12 @@ f_set : {n : Level } {t : Set n} → AtomicNat → (value : ℕ) → ( AtomicNat → t ) → t f_set a v next = next record a { value = v } -record Phil : Set where - field - ptr : ℕ - left right : AtomicNat - -init-Phil : Phil -init-Phil = record { ptr = 0 ; left = init-AtomicNat ; right = init-AtomicNat } - -pickup_rfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t -pickup_lfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t -eating : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t -putdown_rfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t -putdown_lfork : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t -thinking : {n : Level} {t : Set n} → Phil → ( Phil → t ) → t - -pickup_rfork p next = f_set (Phil.right p) (Phil.ptr p) ( λ f → pickup_lfork record p { right = f } next ) -pickup_lfork p next = f_set (Phil.left p) (Phil.ptr p) ( λ f → eating record p { left = f } next ) -eating p next = putdown_rfork p next -putdown_rfork p next = f_set (Phil.right p) 0 ( λ f → putdown_lfork record p { right = f } next ) -putdown_lfork p next = f_set (Phil.left p) 0 ( λ f → thinking record p { left = f } next ) -thinking p next = next p - -run : Phil -run = pickup_rfork record { ptr = 1 ; left = record { ptr = 2 ; value = 0 } ; right = record { ptr = 3 ; value = 0 } } $ λ p → p - -- -- Coda Gear -- data Code : Set where - C_nop : Code - C_cas_int : Code - C_putdown_rfork : Code - C_putdown_lfork : Code - C_thinking : Code - C_pickup_rfork : Code - C_pickup_lfork : Code - C_eating : Code + CC_nop : Code -- -- all possible arguments in -APIs @@ -82,11 +52,6 @@ value : ℕ impl : AtomicNat -record Phil-API : Set where - field - next : Code - impl : Phil - data Error : Set where E_panic : Error E_cas_fail : Error @@ -96,17 +61,15 @@ -- -- waiting / pointer / available -- + data Data : Set where -- D_AtomicNat : AtomicNat → ℕ → Data - D_AtomicNat : AtomicNat → Data - D_Phil : Phil → Data - D_Error : Error → Data + CD_AtomicNat : AtomicNat → Data -- data API : Set where -- A_AtomicNat : AtomicNat-API → API -- A_Phil : Phil-API → API -open import hoareBinaryTree record Context : Set where field @@ -116,11 +79,11 @@ -- -API list (frame in Gears Agda ) --- a Data of API -- api : List API -- c_Phil-API : Maybe Phil-API - c_Phil-API : Phil-API - c_AtomicNat-API : AtomicNat-API + -- c_Phil-API : ? + -- c_AtomicNat-API : AtomicNat-API mbase : ℕ - memory : bt Data + -- memory : ? error : Data fail_next : Code @@ -128,80 +91,29 @@ -- second level stub -- AtomicInt_cas_stub : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -AtomicInt_cas_stub {_} {t} c next = updateTree (Context.memory c) (AtomicNat.ptr ai) ( D_AtomicNat (record ai { value = AtomicNat-API.value api } )) - ( λ bt → next ( Context.fail c ) c ) -- segmentation fault ( null pointer ) - $ λ prev bt → f_cas prev bt where - api : AtomicNat-API - api = Context.c_AtomicNat-API c - ai : AtomicNat - ai = AtomicNat-API.impl api - f_cas : Data → bt Data → t - f_cas (D_AtomicNat prev) bt with <-cmp ( AtomicNat.value ai ) ( AtomicNat.value prev ) - ... | tri≈ ¬a b ¬c = next (AtomicNat-API.next api) ( record c { memory = bt ; c_AtomicNat-API = record api { impl = prev } } ) -- update memory - ... | tri< a₁ ¬b ¬c = next (AtomicNat-API.fail api) c --- cleaer API - ... | tri> ¬a ¬b _ = next (AtomicNat-API.fail api) c - f_cas a bt = next ( Context.fail c ) c -- type error / panic - --- putdown_rfork : Phil → (? → t) → t --- putdown_rfork p next = goto p->lfork->cas( 0 , putdown_lfork, putdown_lfork ) , next - -Phil_putdown_rfork_sub : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -Phil_putdown_rfork_sub c next = next C_cas_int record c { - c_AtomicNat-API = record { impl = Phil.right phil ; value = 0 ; fail = C_putdown_lfork ; next = C_putdown_lfork } } where - phil : Phil - phil = Phil-API.impl ( Context.c_Phil-API c ) +AtomicInt_cas_stub {_} {t} c next = ? -Phil_putdown_lfork_sub : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -Phil_putdown_lfork_sub c next = next C_cas_int record c { - c_AtomicNat-API = record { impl = Phil.left phil ; value = 0 ; fail = C_thinking ; next = C_thinking } } where - phil : Phil - phil = Phil-API.impl ( Context.c_Phil-API c ) - -Phil_thiking : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -Phil_thiking c next = next C_pickup_rfork c - -Phil_pickup_lfork_sub : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -Phil_pickup_lfork_sub c next = next C_cas_int record c { - c_AtomicNat-API = record { impl = Phil.left phil ; value = Phil.ptr phil ; fail = C_pickup_lfork ; next = C_pickup_rfork } } where - phil : Phil - phil = Phil-API.impl ( Context.c_Phil-API c ) - -Phil_pickup_rfork_sub : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -Phil_pickup_rfork_sub c next = next C_cas_int record c { - c_AtomicNat-API = record { impl = Phil.left phil ; value = Phil.ptr phil ; fail = C_pickup_rfork ; next = C_eating } } where - phil : Phil - phil = Phil-API.impl ( Context.c_Phil-API c ) - -Phil_eating_sub : {n : Level} {t : Set n} → Context → ( Code → Context → t ) → t -Phil_eating_sub c next = next C_putdown_rfork c code_table : {n : Level} {t : Set n} → Code → Context → ( Code → Context → t) → t -code_table C_nop = λ c next → next C_nop c -code_table C_cas_int = AtomicInt_cas_stub -code_table C_putdown_rfork = Phil_putdown_rfork_sub -code_table C_putdown_lfork = Phil_putdown_lfork_sub -code_table C_thinking = Phil_thiking -code_table C_pickup_rfork = Phil_pickup_lfork_sub -code_table C_pickup_lfork = Phil_pickup_rfork_sub -code_table C_eating = Phil_eating_sub +code_table = ? step : {n : Level} {t : Set n} → List Context → (List Context → t) → t step {n} {t} [] next0 = next0 [] step {n} {t} (p ∷ ps) next0 = code_table (Context.next p) p ( λ code np → next0 (update-context ps np ++ ( record np { next = code } ∷ [] ))) where update-context : List Context → Context → List Context update-context [] _ = [] - update-context (c1 ∷ t) np = record c1 { memory = Context.memory np ; mbase = Context.mbase np } ∷ t + update-context (c1 ∷ t) np = ? -- record c1 { memory = Context.memory np ; mbase = Context.mbase np } ∷ t init-context : Context init-context = record { - next = C_nop - ; fail = C_nop - ; c_Phil-API = record { next = C_nop ; impl = init-Phil } - ; c_AtomicNat-API = record { next = C_nop ; fail = C_nop ; value = 0 ; impl = init-AtomicNat } + next = CC_nop + ; fail = CC_nop + -- ; c_Phil-API = ? + -- ; c_AtomicNat-API = record { next = CC_nop ; fail = CC_nop ; value = 0 ; impl = init-AtomicNat } ; mbase = 0 - ; memory = leaf - ; error = D_Error E_panic - ; fail_next = C_nop + -- ; memory = ? + ; error = ? + ; fail_next = CC_nop } alloc-data : {n : Level} {t : Set n} → ( c : Context ) → ( Context → ℕ → t ) → t @@ -209,51 +121,61 @@ mnext = suc ( Context.mbase c ) new-data : {n : Level} {t : Set n} → ( c : Context ) → (ℕ → Data ) → ( Context → ℕ → t ) → t -new-data c x next = alloc-data c $ λ c1 n → insertTree (Context.memory c1) n (x n) ( λ bt → next record c1 { memory = bt } n ) +new-data c x next = alloc-data c $ λ c1 n → ? -- insertTree (Context.memory c1) n (x n) ( λ bt → next record c1 { memory = bt } n ) init-AtomicNat0 : {n : Level} {t : Set n} → Context → ( Context → ℕ → t ) → t -init-AtomicNat0 c1 next = new-data c1 ( λ ptr → D_AtomicNat (a ptr) ) $ λ c2 ptr → next c2 ptr where - a : ℕ → AtomicNat - a ptr = record { ptr = ptr ; value = 0 } +init-AtomicNat0 c1 next = ? + +add< : { i : ℕ } (j : ℕ ) → i < suc i + j +add< {i} j = begin + suc i ≤⟨ m≤m+n (suc i) j ⟩ + suc i + j ∎ where open ≤-Reasoning + +nat-<> : { x y : ℕ } → x < y → y < x → ⊥ +nat-<> {x} {y} x<y y<x with <-cmp x y +... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x ) +... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x ) +... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<y ) -init-Phil-0 : (ps : List Context) → (left right : AtomicNat ) → List Context -init-Phil-0 ps left right = new-data (c1 ps) ( λ ptr → D_Phil (p ptr) ) $ λ c ptr → record c { c_Phil-API = record { next = C_thinking ; impl = p ptr }} ∷ ps where - p : ℕ → Phil - p ptr = record init-Phil { ptr = ptr ; left = left ; right = right } - c1 : List Context → Context - c1 [] = init-context - c1 (c2 ∷ ct) = c2 +nat-≤> : { x y : ℕ } → x ≤ y → y < x → ⊥ +nat-≤> {x} {y} x≤y y<x with <-cmp x y +... | tri< a ¬b ¬c = ⊥-elim ( ¬c y<x ) +... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c y<x ) +... | tri> ¬a ¬b c = ? -init-AtomicNat1 : {n : Level} {t : Set n} → Context → ( Context → AtomicNat → t ) → t -init-AtomicNat1 c1 next = new-data c1 ( λ ptr → D_AtomicNat (a ptr) ) $ λ c2 ptr → next c2 (a ptr) where - a : ℕ → AtomicNat - a ptr = record { ptr = ptr ; value = 0 } + +nat-<≡ : { x : ℕ } → x < x → ⊥ +nat-<≡ {x} x<x with <-cmp x x +... | tri< a ¬b ¬c = ⊥-elim ( ¬c x<x ) +... | tri≈ ¬a b ¬c = ⊥-elim ( ¬c x<x ) +... | tri> ¬a ¬b c = ⊥-elim ( ¬a x<x ) -init-Phil-1 : (c1 : Context) → Context -init-Phil-1 c1 = record c1 { memory = mem2 $ mem1 $ mem ; mbase = n + 3 } where - n : ℕ - n = Context.mbase c1 - left = record { ptr = suc n ; value = 0} - right = record { ptr = suc (suc n) ; value = 0} - mem : bt Data - mem = insertTree ( Context.memory c1) (suc n) (D_AtomicNat left) - $ λ t → t - mem1 : bt Data → bt Data - mem1 t = insertTree t (suc (suc n)) (D_AtomicNat right ) - $ λ t → t - mem2 : bt Data → bt Data - mem2 t = insertTree t (n + 3) (D_Phil record { ptr = n + 3 ; left = left ; right = right }) - $ λ t → t - -test-i0 : bt Data -test-i0 = Context.memory (init-Phil-1 init-context) +nat-≡< : { x y : ℕ } → x ≡ y → x < y → ⊥ +nat-≡< refl lt = nat-<≡ lt + +lemma3 : {i j : ℕ} → 0 ≡ i → j < i → ⊥ +lemma3 refl () +lemma5 : {i j : ℕ} → i < 1 → j < i → ⊥ +lemma5 {i} {j} i<1 j<i with <-cmp j i +... | tri< a ¬b ¬c = ⊥-elim ( ¬c ? ) +... | tri≈ ¬a b ¬c = ⊥-elim (¬a j<i ) +... | tri> ¬a ¬b c = ⊥-elim ( ¬a j<i ) -make-phil : ℕ → Context -make-phil zero = init-context -make-phil (suc n) = init-Phil-1 ( make-phil n ) +¬x<x : {x : ℕ} → ¬ (x < x) +¬x<x x<x = ? -test-i5 : bt Data -test-i5 = Context.memory (make-phil 5) +TerminatingLoopS : {l m : Level} {t : Set l} (Index : Set m ) → {Invraiant : Index → Set m } → ( reduce : Index → ℕ) + → (r : Index) → (p : Invraiant r) + → (loop : (r : Index) → Invraiant r → (next : (r1 : Index) → Invraiant r1 → reduce r1 < reduce r → t ) → t) → t +TerminatingLoopS {_} {_} {t} Index {Invraiant} reduce r p loop with <-cmp 0 (reduce r) +... | tri≈ ¬a b ¬c = loop r p (λ r1 p1 lt → ⊥-elim (lemma3 b lt) ) +... | tri< a ¬b ¬c = loop r p (λ r1 p1 lt1 → TerminatingLoop1 (reduce r) r r1 (m≤n⇒m≤1+n lt1) p1 lt1 ) where + TerminatingLoop1 : (j : ℕ) → (r r1 : Index) → reduce r1 < suc j → Invraiant r1 → reduce r1 < reduce r → t + TerminatingLoop1 zero r r1 n≤j p1 lt = loop r1 p1 (λ r2 p1 lt1 → ⊥-elim (lemma5 n≤j lt1)) + TerminatingLoop1 (suc j) r r1 n≤j p1 lt with <-cmp (reduce r1) (suc j) + ... | tri< a ¬b ¬c = TerminatingLoop1 j r r1 a p1 lt + ... | tri≈ ¬a b ¬c = loop r1 p1 (λ r2 p2 lt1 → TerminatingLoop1 j r1 r2 (subst (λ k → reduce r2 < k ) b lt1 ) p2 lt1 ) + ... | tri> ¬a ¬b c = ⊥-elim ( nat-≤> c n≤j ) -- loop exexution