Theory Munta_Error_Monad_Add

(* Author: Peter Lammich *)
section ‹More Material on the Error Monad›

theory Munta_Error_Monad_Add
imports
  Certification_Monads.Check_Monad
  Show.Show_Instances
begin
(* TODO: Move *)
abbreviation "assert_opt Φ  if Φ then Some () else None"

definition "lift_opt m e  case m of Some x  Error_Monad.return x | None  Error_Monad.error e"

lemma lift_opt_simps[simp]:
  "lift_opt None e = error e"
  "lift_opt (Some v) e = return v"
  by (auto simp: lift_opt_def)

(* TODO: Move *)
lemma reflcl_image_iff[simp]: "R=``S = SR``S" by blast

named_theorems return_iff

lemma bind_return_iff[return_iff]: "Error_Monad.bind m f = Inr y  (x. m = Inr x  f x = Inr y)"
  by auto

lemma lift_opt_return_iff[return_iff]: "lift_opt m e = Inr x  m=Some x"
  unfolding lift_opt_def by (auto split: option.split)

lemma check_return_iff[return_iff]: "check Φ e = Inr uu  Φ"
  by (auto simp: check_def)


lemma check_simps[simp]:
  "check True e = succeed"
  "check False e = error e"
  by (auto simp: check_def)

lemma Let_return_iff[return_iff]: "(let x=v in f x) = Inr w  f v = Inr w" by simp


abbreviation ERR :: "shows  (unit  shows)" where "ERR s  λ_. s"
abbreviation ERRS :: "string  (unit  shows)" where "ERRS s  ERR (shows s)"


lemma error_monad_bind_split:
"P (bind m f)  (v. m = Inl v  P (Inl v))  (v. m = Inr v  P (f v))"
by (cases m) auto

lemma error_monad_bind_split_asm:
"P (bind m f)  ¬ (x. m = Inl x  ¬ P (Inl x)  (x. m = Inr x  ¬ P (f x)))"
  by (cases m) auto

lemmas error_monad_bind_splits =error_monad_bind_split error_monad_bind_split_asm

end