Mercurial > hg > Members > Moririn
view ModelChecking.agda @ 710:c588b77bc197
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 05 May 2022 14:23:49 +0900 |
parents | 6a805c8c1e53 |
children | 9be22bce3abd |
line wrap: on
line source
module ModelChecking where open import Level renaming (zero to Z ; suc to succ) open import Data.Nat hiding (compare) open import Data.Nat.Properties as NatProp open import Data.Maybe -- open import Data.Maybe.Properties open import Data.Empty open import Data.List -- open import Data.Tree.Binary -- open import Data.Product open import Function as F hiding (const) open import Relation.Binary open import Relation.Binary.PropositionalEquality open import Relation.Nullary open import logic open import Data.Unit hiding ( _≟_ ; _≤?_ ; _≤_) open import Relation.Binary.Definitions record AtomicNat : Set where field anid : ℕ value : ℕ -- -- single process implemenation -- f_set : {n : Level } {t : Set n} → AtomicNat → (value : ℕ) → ( AtomicNat → t ) → t f_set a v next = next record a { value = v } record Phils : Set where field pid : ℕ left right : AtomicNat pickup_rfork : {n : Level} {t : Set n} → Phils → ( Phils → t ) → t pickup_lfork : {n : Level} {t : Set n} → Phils → ( Phils → t ) → t eating : {n : Level} {t : Set n} → Phils → ( Phils → t ) → t putdown_rfork : {n : Level} {t : Set n} → Phils → ( Phils → t ) → t putdown_lfork : {n : Level} {t : Set n} → Phils → ( Phils → t ) → t thinking : {n : Level} {t : Set n} → Phils → ( Phils → t ) → t -- pickup_rfork p next = f_set (Phils.right p) (Phils.pid p) ( λ f → goto C_pickup_lfork record p { right = f } next ) pickup_rfork p next = f_set (Phils.right p) (Phils.pid p) ( λ f → pickup_lfork record p { right = f } next ) pickup_lfork p next = f_set (Phils.left p) (Phils.pid p) ( λ f → eating record p { left = f } next ) eating p next = putdown_rfork p next putdown_rfork p next = f_set (Phils.right p) 0 ( λ f → putdown_lfork record p { right = f } next ) putdown_lfork p next = f_set (Phils.left p) 0 ( λ f → thinking record p { left = f } next ) thinking p next = next p run : Phils run = pickup_rfork record { pid = 1 ; left = record { anid = 1 ; value = 0 } ; right = record { anid = 2 ; value = 0 } } $ λ p → p -- -- goto version -- data Code : Set where C_set : Code C_putdown_rfork : Code C_putdown_lfork : Code C_thinking : Code C_pickup_rfork : Code C_pickup_lfork : Code C_eating : Code -- -- all possible arguments in APIs -- record AtomicNatAPI : Set where field next : Code value : ℕ old : ℕ impl : AtomicNat record PhilsAPI : Set where field next : Code impl : Phils data Data : Set where D_AtomicNat : AtomicNat → Data D_Phils : Phils → Data A_AtomicNat : AtomicNatAPI → Data A_Phils : PhilsAPI → Data data Error : Set where E_cas_fail : Error open import hoareBinaryTree record Context : Set where field next : Code fail : Code phil : PhilsAPI atomicNat : AtomicNatAPI mbase : ℕ memory : bt Data error : Data fail_next : Code alloc-data : {n : Level} {t : Set n} → ( c : Context ) → ( Context → ℕ → t ) → t alloc-data {n} {t} c next = next record c { mbase = ( suc ( Context.mbase c ) ) } ( suc ( Context.mbase c ) ) update-data : {n : Level} {t : Set n} → ( c : Context ) → ℕ → Data → ( Context → t ) → t update-data c n x next = insertTree (Context.memory c) n x ( λ bt → next record c { memory = bt } ) f_cas : {n : Level} {t : Set n} → AtomicNat → (old now new : ℕ ) → ( Error → t) → ( AtomicNat → t ) → t f_cas a old now new error next with <-cmp old now ... | tri≈ ¬a b ¬c = next record a { value = new } ... | tri< a₁ ¬b ¬c = error E_cas_fail ... | tri> ¬a ¬b _ = error E_cas_fail -- -- second level stub -- g_set : {n : Level} {t : Set n} → Context → AtomicNat → ( Code → Context → t ) → t g_set {_} {t} c a next = f_set a ( AtomicNatAPI.value api ) $ λ a → next ( AtomicNatAPI.next api ) record c { atomicNat = record api { impl = a } } where api : AtomicNatAPI api = Context.atomicNat c g_cas : {n : Level} {t : Set n} → Context → AtomicNat → ( Code → Context → t ) → t g_cas {n} {t} c a next = f_cas a ( AtomicNatAPI.old api )( AtomicNat.value a ) ( AtomicNatAPI.value api ) ( λ e → next (Context.fail_next c) c ) $ λ a → next ( AtomicNatAPI.next api ) record c { atomicNat = record api { impl = a } } where api : AtomicNatAPI api = Context.atomicNat c g_putdown_rfork : {n : Level} {t : Set n} → Context → Phils → ( Code → Context → t ) → t g_putdown_rfork c p next = next C_set record c { atomicNat = record (Context.atomicNat c) { impl = Phils.right p ; value = Phils.pid p ; old = AtomicNat.value (Phils.right p ) ; next = C_putdown_lfork } } g_putdown_lfork : {n : Level} {t : Set n} → Context → Phils → ( Code → Context → t ) → t g_putdown_lfork c p next = next C_set record c { atomicNat = record (Context.atomicNat c) { impl = Phils.left p ; value = Phils.pid p ; old = AtomicNat.value (Phils.left p ) ; next = C_thinking } } g_thinking : {n : Level} {t : Set n} → Context → Phils → ( Code → Context → t ) → t g_thinking c p next = next C_pickup_rfork c g_pickup_rfork : {n : Level} {t : Set n} → Context → Phils → ( Code → Context → t ) → t g_pickup_rfork c p next = next C_set record c { atomicNat = record (Context.atomicNat c) { impl = Phils.right p ; value = 0 ; old = AtomicNat.value (Phils.right p ) ; next = C_pickup_lfork } } g_pickup_lfork : {n : Level} {t : Set n} → Context → Phils → ( Code → Context → t ) → t g_pickup_lfork c p next = next C_set record c { atomicNat = record (Context.atomicNat c) { impl = Phils.left p ; value = 0 ; old = AtomicNat.value (Phils.left p ) ; next = C_eating } } g_eating : {n : Level} {t : Set n} → Context → Phils → ( Code → Context → t ) → t g_eating c p next = next C_putdown_rfork c set_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t set_stub c next = f_cas (AtomicNatAPI.impl api) (AtomicNatAPI.old api) {!!} (AtomicNatAPI.value api) {!!} ( λ ai → next {!!} ) where api : AtomicNatAPI api = Context.atomicNat c ai : {!!} ai = updateTree {!!} {!!} {!!} {!!} {!!} putdown_rfork_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t putdown_rfork_stub p next = {!!} -- g_putdown_rfork ( Context.phil p ) ( λ ph → next record p { phil = ph ; next_code = C_putdown_lfork } ) putdown_lfork_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t putdown_lfork_stub p next = {!!} -- g_putdown_lfork ( Context.phil p ) ( λ ph → next record p { phil = ph ; next_code = C_thinking } ) thinking_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t thinking_stub p next = {!!} -- g_thinking ( Context.phil p ) ( λ ph → next record p { phil = ph ; next_code = C_pickup_rfork } ) pickup_rfork_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t pickup_rfork_stub p next = {!!} -- g_pickup_rfork ( Context.phil p ) ( λ ph → next record p { phil = ph ; next_code = C_pickup_lfork } ) pickup_lfork_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t pickup_lfork_stub p next = {!!} -- g_pickup_lfork ( Context.phil p ) ( λ ph → next record p { phil = ph ; next_code = C_eating } ) eating_stub : {n : Level} {t : Set n} → Context → ( Context → t) → t eating_stub p next = {!!} -- g_pickup_lfork ( Context.phil p ) ( λ ph → next record p { phil = ph ; next_code = C_putdown_rfork } ) code_table : {n : Level} {t : Set n} → Code → Context → ( Context → t) → t code_table C_set = set_stub code_table C_putdown_rfork = putdown_rfork_stub code_table C_putdown_lfork = putdown_lfork_stub code_table C_thinking = thinking_stub code_table C_pickup_rfork = pickup_rfork_stub code_table C_pickup_lfork = pickup_lfork_stub code_table C_eating = eating_stub open Context 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 {!!} p ( λ np → next0 (ps ++ ( np ∷ [] ) )) test : List Context test = step {!!} ( λ ps → ps ) test1 : List Context test1 = step {!!} $ λ ps → step ps $ λ ps → ps -- loop exexution -- concurrnt execution -- state db ( binary tree of processes ) -- depth first ececution -- verify temporal logic poroerries