diff options
| author | Alasdair Armstrong | 2019-07-18 18:56:53 +0100 |
|---|---|---|
| committer | Alasdair Armstrong | 2019-07-18 19:03:06 +0100 |
| commit | 3fb4cf236c0d4b15831576faa45c763853632568 (patch) | |
| tree | 4c00f2a6508855b3dfe842e5c8de03bfc601f878 /src/gen_lib/0.11/sail2_state.lem | |
| parent | a5a6913a110746463e5ca3e5322460617e2eb113 (diff) | |
Need to separate out the 0.10 lem library from upcoming 0.11
Unlike the prompt-monad change I don't see a way to do this easily
purely on the model side
Make sure a64_barrier_type and domain aren't visible for RISC-V
isabelle build
Diffstat (limited to 'src/gen_lib/0.11/sail2_state.lem')
| -rw-r--r-- | src/gen_lib/0.11/sail2_state.lem | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/gen_lib/0.11/sail2_state.lem b/src/gen_lib/0.11/sail2_state.lem new file mode 100644 index 00000000..ec787764 --- /dev/null +++ b/src/gen_lib/0.11/sail2_state.lem @@ -0,0 +1,105 @@ +open import Pervasives_extra +open import Sail2_values +open import Sail2_state_monad +open import {isabelle} `Sail2_state_monad_lemmas` + +val iterS_aux : forall 'rv 'a 'e. integer -> (integer -> 'a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e +let rec iterS_aux i f xs = match xs with + | x :: xs -> f i x >>$ iterS_aux (i + 1) f xs + | [] -> returnS () + end + +declare {isabelle} termination_argument iterS_aux = automatic + +val iteriS : forall 'rv 'a 'e. (integer -> 'a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e +let iteriS f xs = iterS_aux 0 f xs + +val iterS : forall 'rv 'a 'e. ('a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e +let iterS f xs = iteriS (fun _ x -> f x) xs + +val foreachS : forall 'a 'rv 'vars 'e. + list 'a -> 'vars -> ('a -> 'vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e +let rec foreachS xs vars body = match xs with + | [] -> returnS vars + | x :: xs -> + body x vars >>$= fun vars -> + foreachS xs vars body +end + +declare {isabelle} termination_argument foreachS = automatic + +val genlistS : forall 'a 'rv 'e. (nat -> monadS 'rv 'a 'e) -> nat -> monadS 'rv (list 'a) 'e +let genlistS f n = + let indices = genlist (fun n -> n) n in + foreachS indices [] (fun n xs -> (f n >>$= (fun x -> returnS (xs ++ [x])))) + +val and_boolS : forall 'rv 'e. monadS 'rv bool 'e -> monadS 'rv bool 'e -> monadS 'rv bool 'e +let and_boolS l r = l >>$= (fun l -> if l then r else returnS false) + +val or_boolS : forall 'rv 'e. monadS 'rv bool 'e -> monadS 'rv bool 'e -> monadS 'rv bool 'e +let or_boolS l r = l >>$= (fun l -> if l then returnS true else r) + +val bool_of_bitU_fail : forall 'rv 'e. bitU -> monadS 'rv bool 'e +let bool_of_bitU_fail = function + | B0 -> returnS false + | B1 -> returnS true + | BU -> failS "bool_of_bitU" +end + +val bool_of_bitU_nondetS : forall 'rv 'e. bitU -> monadS 'rv bool 'e +let bool_of_bitU_nondetS = function + | B0 -> returnS false + | B1 -> returnS true + | BU -> undefined_boolS () +end + +val bools_of_bits_nondetS : forall 'rv 'e. list bitU -> monadS 'rv (list bool) 'e +let bools_of_bits_nondetS bits = + foreachS bits [] + (fun b bools -> + bool_of_bitU_nondetS b >>$= (fun b -> + returnS (bools ++ [b]))) + +val of_bits_nondetS : forall 'rv 'a 'e. Bitvector 'a => list bitU -> monadS 'rv 'a 'e +let of_bits_nondetS bits = + bools_of_bits_nondetS bits >>$= (fun bs -> + returnS (of_bools bs)) + +val of_bits_failS : forall 'rv 'a 'e. Bitvector 'a => list bitU -> monadS 'rv 'a 'e +let of_bits_failS bits = maybe_failS "of_bits" (of_bits bits) + +val mword_nondetS : forall 'rv 'a 'e. Size 'a => unit -> monadS 'rv (mword 'a) 'e +let mword_nondetS () = + bools_of_bits_nondetS (repeat [BU] (integerFromNat size)) >>$= (fun bs -> + returnS (wordFromBitlist bs)) + + +val whileS : forall 'rv 'vars 'e. 'vars -> ('vars -> monadS 'rv bool 'e) -> + ('vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e +let rec whileS vars cond body s = + (cond vars >>$= (fun cond_val s' -> + if cond_val then + (body vars >>$= (fun vars s'' -> whileS vars cond body s'')) s' + else returnS vars s')) s + +val untilS : forall 'rv 'vars 'e. 'vars -> ('vars -> monadS 'rv bool 'e) -> + ('vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e +let rec untilS vars cond body s = + (body vars >>$= (fun vars s' -> + (cond vars >>$= (fun cond_val s'' -> + if cond_val then returnS vars s'' else untilS vars cond body s'')) s')) s + +val choose_boolsS : forall 'rv 'e. nat -> monadS 'rv (list bool) 'e +let choose_boolsS n = genlistS (fun _ -> choose_boolS ()) n + +(* TODO: Replace by chooseS and prove equivalence to prompt monad version *) +val internal_pickS : forall 'rv 'a 'e. list 'a -> monadS 'rv 'a 'e +let internal_pickS xs = + (* Use sufficiently many nondeterministically chosen bits and convert into an + index into the list *) + choose_boolsS (List.length xs) >>$= fun bs -> + let idx = (natFromNatural (nat_of_bools bs)) mod List.length xs in + match index xs idx with + | Just x -> returnS x + | Nothing -> failS "choose internal_pick" + end |
