Theory NEMonad
section ‹Nondeterminism Error Monad›
text ‹
The NE monad used as basis for the state-error monad in our LLVM semantics.
Note: for abstract programs, we use an (equivalent) monad (nres), defined in
the original Monadic Refinement Framework.
That's for legacy reasons, and needs to be unified at some point!
›
theory NEMonad
imports "../Basic_Imports" Flat_CCPO
begin
subsection ‹Additions to Partial Function›
context partial_function_definitions
begin
lemma monotoneI:
"(⋀x. mono_body (λf. F f x)) ⟹ monotone le_fun le_fun F"
by (auto simp: monotone_def fun_ord_def)
lemma fp_unfold:
assumes "f ≡ fixp_fun F"
assumes "(⋀x. mono_body (λf. F f x))"
shows "f x = F f x"
using assms mono_body_fixp[of F] by auto
end
lemma fun_ordD: "fun_ord le f g ⟹ le (f x) (g x)"
by (auto simp: fun_ord_def)
lemma fun_ord_mono_alt: "monotone le (fun_ord le') f ⟷ (∀x. monotone le le' (λy. f y x))"
by (metis (mono_tags, lifting) fun_ord_def monotone_def)
method_setup pf_mono_prover = ‹Scan.succeed (SIMPLE_METHOD' o Subgoal.FOCUS_PREMS (fn {context=ctxt,...} => CHANGED (ALLGOALS (Partial_Function.mono_tac ctxt))))›
ML ‹
fun discharge_monos ctxt thm = let
fun aux ctxt thm = let
val prems = Thm.prems_of thm
fun prove_simple tac t ctxt = Goal.prove ctxt [] [] t (fn {context=ctxt, ...} => ALLGOALS (tac ctxt))
fun mono_tac ctxt = CHANGED o (Partial_Function.mono_tac ctxt)
fun cinst (t as @{mpat "⋀_. monotone (fun_ord _) _ _"}) = the_default asm_rl (try (prove_simple mono_tac t) ctxt)
| cinst _ = asm_rl
val insts = map cinst prems
val thm = thm OF insts
in
thm
end
in
singleton (Variable.trade (map o aux) ctxt) thm
end
›
attribute_setup discharge_monos
= ‹Scan.succeed (Thm.rule_attribute [] (discharge_monos o Context.proof_of))›
‹Try to discharge monotonicity premises›
subsection ‹Type Definition›
text ‹
The result of a nondeterministic computation
›