summaryrefslogtreecommitdiff
path: root/src/gen_lib/0.11/sail2_state.lem
diff options
context:
space:
mode:
authorAlasdair Armstrong2019-07-18 18:56:53 +0100
committerAlasdair Armstrong2019-07-18 19:03:06 +0100
commit3fb4cf236c0d4b15831576faa45c763853632568 (patch)
tree4c00f2a6508855b3dfe842e5c8de03bfc601f878 /src/gen_lib/0.11/sail2_state.lem
parenta5a6913a110746463e5ca3e5322460617e2eb113 (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.lem105
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