summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/isabelle/State_lemmas.thy8
-rw-r--r--lib/isabelle/State_monad_lemmas.thy200
-rw-r--r--src/gen_lib/state_monad.lem32
3 files changed, 195 insertions, 45 deletions
diff --git a/lib/isabelle/State_lemmas.thy b/lib/isabelle/State_lemmas.thy
index 9c5dd8af..d8ab5db9 100644
--- a/lib/isabelle/State_lemmas.thy
+++ b/lib/isabelle/State_lemmas.thy
@@ -13,7 +13,7 @@ lemma liftState_bind[simp]:
lemma liftState_return[simp]: "liftState r (return a) = returnS a" by (auto simp: return_def)
lemma Value_liftState_Run:
- assumes "(Value a, s') \<in> set (liftState r m s)"
+ assumes "(Value a, s') \<in> liftState r m s"
obtains t where "Run m t a"
by (use assms in \<open>induction r m arbitrary: s s' rule: liftState.induct\<close>;
auto simp add: failS_def throwS_def returnS_def simp del: read_regvalS.simps;
@@ -101,8 +101,8 @@ lemma liftState_foreachM[simp]:
lemma whileS_dom_step:
assumes "whileS_dom (vars, cond, body, s)"
- and "(Value True, s') \<in> set (cond vars s)"
- and "(Value vars', s'') \<in> set (body vars s')"
+ and "(Value True, s') \<in> cond vars s"
+ and "(Value vars', s'') \<in> body vars s'"
shows "whileS_dom (vars', cond, body, s'')"
by (use assms in \<open>induction vars cond body s arbitrary: vars' s' s'' rule: whileS.pinduct\<close>)
(auto intro: whileS.domintros)
@@ -143,7 +143,7 @@ proof (use assms in \<open>induction vars "liftState r \<circ> cond" "liftState
show "\<exists>t. Run (cond vars) t True" using while that by (auto elim: Value_liftState_Run)
show "\<exists>t'. Run (body vars) t' vars'" using while' that by (auto elim: Value_liftState_Run)
qed
- then show ?case using while while' that by (auto intro: IH)
+ then show ?case using while while' that IH by auto
qed auto
then show ?case by auto
qed auto
diff --git a/lib/isabelle/State_monad_lemmas.thy b/lib/isabelle/State_monad_lemmas.thy
index d8730421..746fd315 100644
--- a/lib/isabelle/State_monad_lemmas.thy
+++ b/lib/isabelle/State_monad_lemmas.thy
@@ -8,34 +8,36 @@ context
notes returnS_def[simp] and failS_def[simp] and throwS_def[simp] and readS_def[simp] and updateS_def[simp]
begin
-abbreviation "bindS_aux f \<equiv> (\<lambda>r. case r of (Value a, s') \<Rightarrow> f a s' | (Ex e, s') \<Rightarrow> [(Ex e, s')])"
-abbreviation "bindS_app ms f \<equiv> List.concat (List.map (bindS_aux f) ms)"
+abbreviation "bindS_aux f \<equiv> (\<lambda>r. case r of (Value a, s') \<Rightarrow> f a s' | (Ex e, s') \<Rightarrow> {(Ex e, s')})"
+abbreviation "bindS_app ms f \<equiv> \<Union>(bindS_aux f ` ms)"
lemma bindS_ext_cong[fundef_cong]:
assumes m: "m1 s = m2 s"
- and f: "\<And>a s'. (Value a, s') \<in> set (m2 s) \<Longrightarrow> f1 a s' = f2 a s'"
+ and f: "\<And>a s'. (Value a, s') \<in> (m2 s) \<Longrightarrow> f1 a s' = f2 a s'"
shows "bindS m1 f1 s = bindS m2 f2 s"
-proof -
+ using assms unfolding bindS_def by (auto split: result.splits)
+(* proof -
have "bindS_app (m2 s) f1 = bindS_app (m2 s) f2"
- using f by (intro arg_cong[where f = List.concat]) (auto intro: map_ext split: result.splits)
+ using f by (auto split: result.splits)
then show ?thesis using m by (auto simp: bindS_def)
-qed
+qed *)
lemma bindS_cong[fundef_cong]:
assumes m: "m1 = m2"
- and f: "\<And>s a s'. (Value a, s') \<in> set (m2 s) \<Longrightarrow> f1 a s' = f2 a s'"
+ and f: "\<And>s a s'. (Value a, s') \<in> (m2 s) \<Longrightarrow> f1 a s' = f2 a s'"
shows "bindS m1 f1 = bindS m2 f2"
- using assms by (blast intro: bindS_ext_cong)
+ using assms by (intro ext bindS_ext_cong; blast)
lemma bindS_returnS_left[simp]: "bindS (returnS x) f = f x"
by (auto simp add: bindS_def)
lemma bindS_returnS_right[simp]: "bindS m returnS = (m :: ('regs, 'a, 'e) monadS)"
-proof -
+ by (intro ext) (auto simp: bindS_def split: result.splits)
+(* proof -
have "List.concat (map (bindS_aux returnS) ms) = ms" for ms :: "(('a, 'e) result \<times> 'regs sequential_state) list"
by (induction ms) (auto split: result.splits)
then show ?thesis unfolding bindS_def by blast
-qed
+qed *)
lemma bindS_readS: "bindS (readS f) m = (\<lambda>s. m (f s) s)"
by (auto simp: bindS_def)
@@ -43,30 +45,100 @@ lemma bindS_readS: "bindS (readS f) m = (\<lambda>s. m (f s) s)"
lemma bindS_updateS: "bindS (updateS f) m = (\<lambda>s. m () (f s))"
by (auto simp: bindS_def)
-lemma bindS_assoc[simp]: "bindS (bindS m f) g = bindS m (\<lambda>x. bindS (f x) g)"
+
+lemma result_cases:
+ fixes r :: "('a, 'e) result"
+ obtains (Value) a where "r = Value a"
+ | (Throw) e where "r = Ex (Throw e)"
+ | (Failure) msg where "r = Ex (Failure msg)"
+proof (cases r)
+ case (Ex ex) then show ?thesis by (cases ex; auto intro: that)
+qed
+
+lemma result_state_cases:
+ fixes rs :: "('a, 'e) result \<times> 's"
+ obtains (Value) a s where "rs = (Value a, s)"
+ | (Throw) e s where "rs = (Ex (Throw e), s)"
+ | (Failure) msg s where "rs = (Ex (Failure msg), s)"
proof -
+ obtain r s where rs: "rs = (r, s)" by (cases rs)
+ then show thesis by (cases r rule: result_cases) (auto intro: that)
+qed
+
+lemma monadS_ext_eqI:
+ fixes m m' :: "('regs, 'a, 'e) monadS"
+ assumes "\<And>a s'. (Value a, s') \<in> m s \<longleftrightarrow> (Value a, s') \<in> m' s"
+ and "\<And>e s'. (Ex (Throw e), s') \<in> m s \<longleftrightarrow> (Ex (Throw e), s') \<in> m' s"
+ and "\<And>msg s'. (Ex (Failure msg), s') \<in> m s \<longleftrightarrow> (Ex (Failure msg), s') \<in> m' s"
+ shows "m s = m' s"
+proof (intro set_eqI)
+ fix x
+ show "x \<in> m s \<longleftrightarrow> x \<in> m' s" using assms by (cases x rule: result_state_cases) auto
+qed
+
+lemma monadS_eqI:
+ fixes m m' :: "('regs, 'a, 'e) monadS"
+ assumes "\<And>s a s'. (Value a, s') \<in> m s \<longleftrightarrow> (Value a, s') \<in> m' s"
+ and "\<And>s e s'. (Ex (Throw e), s') \<in> m s \<longleftrightarrow> (Ex (Throw e), s') \<in> m' s"
+ and "\<And>s msg s'. (Ex (Failure msg), s') \<in> m s \<longleftrightarrow> (Ex (Failure msg), s') \<in> m' s"
+ shows "m = m'"
+ using assms by (intro ext monadS_ext_eqI)
+
+lemma
+ assumes "(Value a, s') \<in> bindS m f s"
+ obtains a' s'' where "(Value a', s'') \<in> m s" and "(Value a, s') \<in> f a' s''"
+ using assms by (auto simp: bindS_def split: result.splits)
+
+lemma
+ assumes "(Ex e, s') \<in> bindS m f s"
+ obtains (Left) "(Ex e, s') \<in> m s"
+ | (Right) a s'' where "(Value a, s'') \<in> m s" and "(Ex e, s') \<in> f a s''"
+ using assms by (auto simp: bindS_def split: result.splits)
+
+lemma bindS_cases:
+ assumes "(r, s') \<in> bindS m f s"
+ obtains (Value) a a' s'' where "r = Value a" and "(Value a', s'') \<in> m s" and "(Value a, s') \<in> f a' s''"
+ | (Ex_Left) e where "r = Ex e" and "(Ex e, s') \<in> m s"
+ | (Ex_Right) e a s'' where "r = Ex e" and "(Value a, s'') \<in> m s" and "(Ex e, s') \<in> f a s''"
+ using assms by (cases r; auto simp: bindS_def split: result.splits)
+
+lemma bindS_intros:
+ "\<And>m f s a s' a' s''. (Value a', s'') \<in> m s \<Longrightarrow> (Value a, s') \<in> f a' s'' \<Longrightarrow> (Value a, s') \<in> bindS m f s"
+ "\<And>m f s e s'. (Ex e, s') \<in> m s \<Longrightarrow> (Ex e, s') \<in> bindS m f s"
+ "\<And>m f s e s' a s''. (Ex e, s') \<in> f a s'' \<Longrightarrow> (Value a, s'') \<in> m s \<Longrightarrow> (Ex e, s') \<in> bindS m f s"
+ by (auto simp: bindS_def intro: bexI[rotated])
+
+lemma bindS_assoc[simp]: "bindS (bindS m f) g = bindS m (\<lambda>x. bindS (f x) g)"
+ by (auto elim!: bindS_cases intro: bindS_intros monadS_eqI)
+(*proof -
have "List.concat (map (bindS_aux g) (List.concat (map (bindS_aux f) xs))) =
List.concat (map (bindS_aux (\<lambda>x s. List.concat (map (bindS_aux g) (f x s)))) xs)" for xs
by (induction xs) (auto split: result.splits)
then show ?thesis unfolding bindS_def by auto
-qed
+qed*)
lemma bindS_failS[simp]: "bindS (failS msg) f = failS msg" by (auto simp: bindS_def)
lemma bindS_throwS[simp]: "bindS (throwS e) f = throwS e" by (auto simp: bindS_def)
declare seqS_def[simp]
lemma Value_bindS_elim:
- assumes "(Value a, s') \<in> set (bindS m f s)"
- obtains s'' a' where "(Value a', s'') \<in> set (m s)" and "(Value a, s') \<in> set (f a' s'')"
- using assms by (auto simp: bindS_def; split result.splits; auto)
+ assumes "(Value a, s') \<in> bindS m f s"
+ obtains s'' a' where "(Value a', s'') \<in> m s" and "(Value a, s') \<in> f a' s''"
+ using assms by (auto elim: bindS_cases)
+
+lemma Ex_bindS_elim:
+ assumes "(Ex e, s') \<in> bindS m f s"
+ obtains (Left) "(Ex e, s') \<in> m s"
+ | (Right) s'' a' where "(Value a', s'') \<in> m s" and "(Ex e, s') \<in> f a' s''"
+ using assms by (auto elim: bindS_cases)
abbreviation
"try_catchS_aux h r \<equiv>
(case r of
(Value a, s') => returnS a s'
| (Ex (Throw e), s') => h e s'
- | (Ex (Failure msg), s') => [(Ex (Failure msg), s')])"
-abbreviation "try_catchS_app ms h \<equiv> List.concat (List.map (try_catchS_aux h) ms)"
+ | (Ex (Failure msg), s') => {(Ex (Failure msg), s')})"
+abbreviation "try_catchS_app ms h \<equiv> \<Union>(try_catchS_aux h ` ms)"
lemma try_catchS_returnS[simp]: "try_catchS (returnS a) h = returnS a"
and try_catchS_failS[simp]: "try_catchS (failS msg) h = failS msg"
@@ -78,6 +150,31 @@ lemma try_catchS_cong[cong]:
shows "try_catchS m1 h1 = try_catchS m2 h2"
using assms by (intro arg_cong2[where f = try_catchS] ext) auto
+lemma try_catchS_cases:
+ assumes "(r, s') \<in> try_catchS m h s"
+ obtains (Value) a where "r = Value a" and "(Value a, s') \<in> m s"
+ | (Fail) msg where "r = Ex (Failure msg)" and "(Ex (Failure msg), s') \<in> m s"
+ | (h) e s'' where "(Ex (Throw e), s'') \<in> m s" and "(r, s') \<in> h e s''"
+ using assms by (cases r rule: result_cases) (auto simp: try_catchS_def split: result.splits ex.splits)
+
+lemma try_catchS_intros:
+ "\<And>m h s a s'. (Value a, s') \<in> m s \<Longrightarrow> (Value a, s') \<in> try_catchS m h s"
+ "\<And>m h s msg s'. (Ex (Failure msg), s') \<in> m s \<Longrightarrow> (Ex (Failure msg), s') \<in> try_catchS m h s"
+ "\<And>m h s e s'' r s'. (Ex (Throw e), s'') \<in> m s \<Longrightarrow> (r, s') \<in> h e s'' \<Longrightarrow> (r, s') \<in> try_catchS m h s"
+ by (auto simp: try_catchS_def intro: bexI[rotated])
+
+fun ignore_throw_aux :: "(('a, 'e1) result \<times> 's) \<Rightarrow> (('a, 'e2) result \<times> 's) set" where
+ "ignore_throw_aux (Value a, s') = {(Value a, s')}"
+| "ignore_throw_aux (Ex (Throw e), s') = {}"
+| "ignore_throw_aux (Ex (Failure msg), s') = {(Ex (Failure msg), s')}"
+definition "ignore_throw m s \<equiv> \<Union>(ignore_throw_aux ` m s)"
+
+(*fun ignore_throw_aux :: "(('a, 'e1) result \<times> 's) \<Rightarrow> (('a, 'e2) result \<times> 's) list" where
+ "ignore_throw_aux r \<equiv>
+ (case r of
+ (Value a, s') => returnS a s'
+ | (Ex (Throw e), s') => h e s'
+ | (Ex (Failure msg), s') => {(Ex (Failure msg), s')})"
fun ignore_throw_app :: "(('a, 'e1) result \<times> 's) list \<Rightarrow> (('a, 'e2) result \<times> 's) list" where
"ignore_throw_app [] = []"
| "ignore_throw_app ((Value a, s) # ms) = (Value a, s) # ignore_throw_app ms"
@@ -95,12 +192,31 @@ lemma ignore_throw_app_append[simp]:
lemma ignore_throw_app_bindS_app[simp]:
"ignore_throw_app (bindS_app ms f) = bindS_app (ignore_throw_app ms) (ignore_throw \<circ> f)"
- by (induction ms rule: ignore_throw_app.induct) (auto split: result.splits)
+ by (induction ms rule: ignore_throw_app.induct) (auto split: result.splits)*)
+
+lemma [simp]:
+ "(Value a, s') \<in> ignore_throw_aux ms \<longleftrightarrow> ms = (Value a, s')"
+ "(Ex (Throw e), s') \<in> ignore_throw_aux ms \<longleftrightarrow> False"
+ "(Ex (Failure msg), s') \<in> ignore_throw_aux ms \<longleftrightarrow> ms = (Ex (Failure msg), s')"
+ by (cases ms rule: result_state_cases; auto)+
+
+(*lemma [simp]: "(Value a, s') \<in> ignore_throw m s \<longleftrightarrow> (Value a, s') \<in> m s"
+ "(Value a, s') \<in> ignore_throw m s \<longleftrightarrow> (Value a, s') \<in> m s"
+ "(Ex (Throw e), s') \<in> ignore_throw m s \<longleftrightarrow> False"
+ "(Ex (Failure msg), s') \<in> ignore_throw_aux ms \<longleftrightarrow> ms = (Ex (Failure msg), s')"
+ by (auto simp: ignore_throw_def)*)
+
+lemma ignore_throw_cases:
+ assumes no_throw: "ignore_throw m s = m s"
+ and r: "(r, s') \<in> m s"
+ obtains (Value) a where "r = Value a"
+ | (Failure) msg where "r = Ex (Failure msg)"
+ using r unfolding no_throw[symmetric]
+ by (cases r rule: result_cases) (auto simp: ignore_throw_def)
lemma ignore_throw_bindS[simp]:
"ignore_throw (bindS m f) = bindS (ignore_throw m) (ignore_throw \<circ> f)"
- "ignore_throw (bindS m f) s = bindS (ignore_throw m) (ignore_throw \<circ> f) s"
- unfolding bindS_def by auto
+ by (intro monadS_eqI) (auto simp: ignore_throw_def elim!: bindS_cases intro: bindS_intros)
lemma try_catchS_bindS_no_throw:
fixes m1 :: "('r, 'a, 'e1) monadS" and m2 :: "('r, 'a, 'e2) monadS"
@@ -109,13 +225,47 @@ lemma try_catchS_bindS_no_throw:
shows "try_catchS (bindS m1 f) h = bindS m2 (\<lambda>a. try_catchS (f a) h)"
proof
fix s
+ have "try_catchS (bindS m1 f) h s = bindS (ignore_throw m1) (\<lambda>a. try_catchS (f a) h) s"
+ by (intro monadS_ext_eqI;
+ auto elim!: bindS_cases try_catchS_cases elim: ignore_throw_cases[OF m1];
+ auto simp: ignore_throw_def intro: bindS_intros try_catchS_intros)
+ also have "\<dots> = bindS m2 (\<lambda>a. try_catchS (f a) h) s" using m2 by (intro bindS_ext_cong) auto
+ finally show "try_catchS (bindS m1 f) h s = bindS m2 (\<lambda>a. try_catchS (f a) h) s" .
+qed
+(*proof
+ fix s
have 1: "try_catchS_app (bindS_app ms f) h =
bindS_app (ignore_throw_app ms) (\<lambda>a s'. try_catchS_app (f a s') h)"
if "ignore_throw_app ms = ms" for ms
using that by (induction ms rule: ignore_throw_app.induct) auto
then show "try_catchS (bindS m1 f) h s = bindS m2 (\<lambda>a. try_catchS (f a) h) s"
using m1 unfolding try_catchS_def bindS_def m2[symmetric] by blast
-qed
+qed*)
+
+(*lemma no_throwI:
+ fixes m1 :: "('regs, 'a, 'e1) monadS" and m2 :: "('regs, 'a, 'e2) monadS"
+ assumes "\<And>a s'. (Value a, s') \<in> m1 s \<longleftrightarrow> (Value a, s') \<in> m2 s"
+ and "\<And>msg s'. (Ex (Failure msg), s') \<in> m1 s \<longleftrightarrow> (Ex (Failure msg), s') \<in> m2 s"
+ and "\<And>e s'. (Ex (Throw e), s') \<notin> m1 s"
+ and "\<And>e s'. (Ex (Throw e), s') \<notin> m2 s"
+ shows "ignore_throw m1 s = m2 s"
+ using assms by (intro monadS_ext_eqI) (auto simp: ignore_throw_def)*)
+
+(*lemma no_throw_bindSI:
+ assumes "ignore_throw m1 s = m2 s"
+and "\<And>a s'. (Value a, s') \<in> m2 s \<Longrightarrow> ignore_throw (f1 a) s' = f2 a s'"
+shows "ignore_throw (bindS m1 f1) s = bindS m2 f2 s"
+ using assms unfolding ignore_throw_bindS apply (intro monadS_ext_eqI) apply auto apply (auto elim!: bindS_cases intro: bindS_intros)
+ defer thm bindS_intros
+ apply (intro bindS_intros(3)) apply auto
+ apply (intro bindS_intros(3)) apply auto
+ done
+
+lemma
+ "\<And>BC rk a sz s. ignore_throw (read_mem_bytesS BC rk a sz) s = read_mem_bytesS BC rk a sz s"
+ unfolding read_mem_bytesS_def Let_def seqS_def
+ apply (intro no_throw_bindSI)
+ oops*)
lemma no_throw_mem_builtins:
"\<And>a. ignore_throw (returnS a) = returnS a"
@@ -130,16 +280,16 @@ lemma no_throw_mem_builtins:
unfolding read_mem_bytesS_def read_memS_def read_tagS_def write_mem_eaS_def
unfolding write_mem_valS_def write_mem_bytesS_def write_tagS_def
unfolding excl_resultS_def undefined_boolS_def
- by (auto simp: bindS_def chooseS_def Let_def split: option.splits prod.splits)+
+ by (auto simp: ignore_throw_def bindS_def chooseS_def Let_def split: option.splits prod.splits)
lemma no_throw_read_memS: "ignore_throw (read_memS BCa BCb rk a sz) s = read_memS BCa BCb rk a sz s"
- by (auto simp: read_memS_def no_throw_mem_builtins cong: bindS_cong)
+ by (auto simp: read_memS_def no_throw_mem_builtins cong: bindS_ext_cong)
lemma no_throw_read_regvalS: "ignore_throw (read_regvalS r reg_name) s = read_regvalS r reg_name s"
- by (cases r) (auto simp: bindS_def split: option.splits)
+ by (cases r) (auto simp: ignore_throw_def bindS_def split: option.splits)
lemma no_throw_write_regvalS: "ignore_throw (write_regvalS r reg_name v) s = write_regvalS r reg_name v s"
- by (cases r) (auto simp: bindS_def split: option.splits)
+ by (cases r) (auto simp: ignore_throw_def bindS_def split: option.splits)
lemmas no_throw_builtins[simp, intro] =
no_throw_mem_builtins no_throw_read_regvalS no_throw_write_regvalS no_throw_read_memS
diff --git a/src/gen_lib/state_monad.lem b/src/gen_lib/state_monad.lem
index 26179244..26f912fd 100644
--- a/src/gen_lib/state_monad.lem
+++ b/src/gen_lib/state_monad.lem
@@ -38,17 +38,17 @@ type result 'a 'e =
(* State, nondeterminism and exception monad with result value type 'a
and exception type 'e. *)
-type monadS 'regs 'a 'e = sequential_state 'regs -> list (result 'a 'e * sequential_state 'regs)
+type monadS 'regs 'a 'e = sequential_state 'regs -> set (result 'a 'e * sequential_state 'regs)
val returnS : forall 'regs 'a 'e. 'a -> monadS 'regs 'a 'e
-let returnS a s = [(Value a,s)]
+let returnS a s = {(Value a,s)}
val bindS : forall 'regs 'a 'b 'e. monadS 'regs 'a 'e -> ('a -> monadS 'regs 'b 'e) -> monadS 'regs 'b 'e
let bindS m f (s : sequential_state 'regs) =
- List.concatMap (function
- | (Value a, s') -> f a s'
- | (Ex e, s') -> [(Ex e, s')]
- end) (m s)
+ Set.bigunion (Set.map (function
+ | (Value a, s') -> f a s'
+ | (Ex e, s') -> {(Ex e, s')}
+ end) (m s))
val seqS: forall 'regs 'b 'e. monadS 'regs unit 'e -> monadS 'regs 'b 'e -> monadS 'regs 'b 'e
let seqS m n = bindS m (fun (_ : unit) -> n)
@@ -56,8 +56,8 @@ let seqS m n = bindS m (fun (_ : unit) -> n)
let inline (>>$=) = bindS
let inline (>>$) = seqS
-val chooseS : forall 'regs 'a 'e. list 'a -> monadS 'regs 'a 'e
-let chooseS xs s = List.map (fun x -> (Value x, s)) xs
+val chooseS : forall 'regs 'a 'e. SetType 'a => set 'a -> monadS 'regs 'a 'e
+let chooseS xs s = Set.map (fun x -> (Value x, s)) xs
val readS : forall 'regs 'a 'e. (sequential_state 'regs -> 'a) -> monadS 'regs 'a 'e
let readS f = (fun s -> returnS (f s) s)
@@ -66,7 +66,7 @@ val updateS : forall 'regs 'e. (sequential_state 'regs -> sequential_state 'regs
let updateS f = (fun s -> returnS () (f s))
val failS : forall 'regs 'a 'e. string -> monadS 'regs 'a 'e
-let failS msg s = [(Ex (Failure msg), s)]
+let failS msg s = {(Ex (Failure msg), s)}
val undefined_boolS : forall 'regval 'regs 'a 'e. unit -> monadS 'regs bool 'e
let undefined_boolS () =
@@ -78,15 +78,15 @@ val exitS : forall 'regs 'e 'a. unit -> monadS 'regs 'a 'e
let exitS () = failS "exit"
val throwS : forall 'regs 'a 'e. 'e -> monadS 'regs 'a 'e
-let throwS e s = [(Ex (Throw e), s)]
+let throwS e s = {(Ex (Throw e), s)}
val try_catchS : forall 'regs 'a 'e1 'e2. monadS 'regs 'a 'e1 -> ('e1 -> monadS 'regs 'a 'e2) -> monadS 'regs 'a 'e2
let try_catchS m h s =
- List.concatMap (function
- | (Value a, s') -> returnS a s'
- | (Ex (Throw e), s') -> h e s'
- | (Ex (Failure msg), s') -> [(Ex (Failure msg), s')]
- end) (m s)
+ Set.bigunion (Set.map (function
+ | (Value a, s') -> returnS a s'
+ | (Ex (Throw e), s') -> h e s'
+ | (Ex (Failure msg), s') -> {(Ex (Failure msg), s')}
+ end) (m s))
val assert_expS : forall 'regs 'e. bool -> string -> monadS 'regs unit 'e
let assert_expS exp msg = if exp then returnS () else failS msg
@@ -150,7 +150,7 @@ val excl_resultS : forall 'regs 'e. unit -> monadS 'regs bool 'e
let excl_resultS () =
readS (fun s -> s.last_exclusive_operation_was_load) >>$= (fun excl_load ->
updateS (fun s -> <| s with last_exclusive_operation_was_load = false |>) >>$
- chooseS (if excl_load then [false; true] else [false]))
+ chooseS (if excl_load then {false; true} else {false}))
val write_mem_eaS : forall 'regs 'e 'a. Bitvector 'a => write_kind -> 'a -> nat -> monadS 'regs unit 'e
let write_mem_eaS write_kind addr sz =