src/HOL/Datatype.thy
changeset 12918 bca45be2d25b
parent 12029 7df1d840d01d
child 13635 c41e88151b54
--- a/src/HOL/Datatype.thy	Thu Feb 21 20:06:39 2002 +0100
+++ b/src/HOL/Datatype.thy	Thu Feb 21 20:08:09 2002 +0100
@@ -4,10 +4,12 @@
     License:    GPL (GNU GENERAL PUBLIC LICENSE)
 *)
 
-header {* Final stage of datatype setup *}
+header {* Datatypes *}
 
 theory Datatype = Datatype_Universe:
 
+subsection {* Finishing the datatype package setup *}
+
 text {* Belongs to theory @{text Datatype_Universe}; hides popular names. *}
 hide const Node Atom Leaf Numb Lim Funs Split Case
 hide type node item
@@ -22,11 +24,6 @@
 declare case_split [cases type: bool]
   -- "prefer plain propositional version"
 
-rep_datatype sum
-  distinct Inl_not_Inr Inr_not_Inl
-  inject Inl_eq Inr_eq
-  induction sum_induct
-
 rep_datatype unit
   induction unit_induct
 
@@ -34,7 +31,47 @@
   inject Pair_eq
   induction prod_induct
 
-text {* Further cases/induct rules for 3--7 tuples. *}
+rep_datatype sum
+  distinct Inl_not_Inr Inr_not_Inl
+  inject Inl_eq Inr_eq
+  induction sum_induct
+
+ML {*
+  val [sum_case_Inl, sum_case_Inr] = thms "sum.cases";
+  bind_thm ("sum_case_Inl", sum_case_Inl);
+  bind_thm ("sum_case_Inr", sum_case_Inr);
+*} -- {* compatibility *}
+
+lemma surjective_sum: "sum_case (%x::'a. f (Inl x)) (%y::'b. f (Inr y)) s = f(s)"
+  apply (rule_tac s = s in sumE)
+   apply (erule ssubst)
+   apply (rule sum_case_Inl)
+  apply (erule ssubst)
+  apply (rule sum_case_Inr)
+  done
+
+lemma sum_case_weak_cong: "s = t ==> sum_case f g s = sum_case f g t"
+  -- {* Prevents simplification of @{text f} and @{text g}: much faster. *}
+  by (erule arg_cong)
+
+lemma sum_case_inject:
+  "sum_case f1 f2 = sum_case g1 g2 ==> (f1 = g1 ==> f2 = g2 ==> P) ==> P"
+proof -
+  assume a: "sum_case f1 f2 = sum_case g1 g2"
+  assume r: "f1 = g1 ==> f2 = g2 ==> P"
+  show P
+    apply (rule r)
+     apply (rule ext)
+     apply (cut_tac x = "Inl x" in a [THEN fun_cong])
+     apply simp
+    apply (rule ext)
+    apply (cut_tac x = "Inr x" in a [THEN fun_cong])
+    apply simp
+    done
+qed
+
+
+subsection {* Further cases/induct rules for tuples *}
 
 lemma prod_cases3 [case_names fields, cases type]:
     "(!!a b c. y = (a, b, c) ==> P) ==> P"
@@ -91,4 +128,67 @@
     "(!!a b c d e f g. P (a, b, c, d, e, f, g)) ==> P x"
   by (cases x) blast
 
+
+subsection {* The option type *}
+
+datatype 'a option = None | Some 'a
+
+lemma not_None_eq [iff]: "(x ~= None) = (EX y. x = Some y)"
+  by (induct x) auto
+
+lemma not_Some_eq [iff]: "(ALL y. x ~= Some y) = (x = None)"
+  by (induct x) auto
+
+lemma option_caseE:
+  "(case x of None => P | Some y => Q y) ==>
+    (x = None ==> P ==> R) ==>
+    (!!y. x = Some y ==> Q y ==> R) ==> R"
+  by (cases x) simp_all
+
+
+subsubsection {* Operations *}
+
+consts
+  the :: "'a option => 'a"
+primrec
+  "the (Some x) = x"
+
+consts
+  o2s :: "'a option => 'a set"
+primrec
+  "o2s None = {}"
+  "o2s (Some x) = {x}"
+
+lemma ospec [dest]: "(ALL x:o2s A. P x) ==> A = Some x ==> P x"
+  by simp
+
+ML_setup {* claset_ref() := claset() addSD2 ("ospec", thm "ospec") *}
+
+lemma elem_o2s [iff]: "(x : o2s xo) = (xo = Some x)"
+  by (cases xo) auto
+
+lemma o2s_empty_eq [simp]: "(o2s xo = {}) = (xo = None)"
+  by (cases xo) auto
+
+
+constdefs
+  option_map :: "('a => 'b) => ('a option => 'b option)"
+  "option_map == %f y. case y of None => None | Some x => Some (f x)"
+
+lemma option_map_None [simp]: "option_map f None = None"
+  by (simp add: option_map_def)
+
+lemma option_map_Some [simp]: "option_map f (Some x) = Some (f x)"
+  by (simp add: option_map_def)
+
+lemma option_map_eq_Some [iff]:
+    "(option_map f xo = Some y) = (EX z. xo = Some z & f z = y)"
+  by (simp add: option_map_def split add: option.split)
+
+lemma option_map_o_sum_case [simp]:
+    "option_map f o sum_case g h = sum_case (option_map f o g) (option_map f o h)"
+  apply (rule ext)
+  apply (simp split add: sum.split)
+  done
+
 end