src/HOL/Sum_Type.thy
changeset 33961 03f2ab6a4ea6
parent 31080 21ffc770ebc0
child 33962 abf9fa17452a
equal deleted inserted replaced
33960:53993394ac19 33961:03f2ab6a4ea6
     5 *)
     5 *)
     6 
     6 
     7 header{*The Disjoint Sum of Two Types*}
     7 header{*The Disjoint Sum of Two Types*}
     8 
     8 
     9 theory Sum_Type
     9 theory Sum_Type
    10 imports Typedef Fun
    10 imports Typedef Inductive Fun
    11 begin
    11 begin
    12 
    12 
    13 text{*The representations of the two injections*}
    13 text{*The representations of the two injections*}
    14 
    14 
    15 constdefs
    15 constdefs
   188 lemma Part_Int: "Part (A Int B) h = (Part A h) Int (Part B h)"
   188 lemma Part_Int: "Part (A Int B) h = (Part A h) Int (Part B h)"
   189 by blast
   189 by blast
   190 
   190 
   191 lemma Part_Collect: "Part (A Int {x. P x}) h = (Part A h) Int {x. P x}"
   191 lemma Part_Collect: "Part (A Int {x. P x}) h = (Part A h) Int {x. P x}"
   192 by blast
   192 by blast
       
   193 
       
   194 subsection {* Representing sums *}
       
   195 
       
   196 rep_datatype (sum) Inl Inr
       
   197 proof -
       
   198   fix P
       
   199   fix s :: "'a + 'b"
       
   200   assume x: "\<And>x\<Colon>'a. P (Inl x)" and y: "\<And>y\<Colon>'b. P (Inr y)"
       
   201   then show "P s" by (auto intro: sumE [of s])
       
   202 qed simp_all
       
   203 
       
   204 lemma sum_case_KK[simp]: "sum_case (%x. a) (%x. a) = (%x. a)"
       
   205   by (rule ext) (simp split: sum.split)
       
   206 
       
   207 lemma surjective_sum: "sum_case (%x::'a. f (Inl x)) (%y::'b. f (Inr y)) s = f(s)"
       
   208   apply (rule_tac s = s in sumE)
       
   209    apply (erule ssubst)
       
   210    apply (rule sum.cases(1))
       
   211   apply (erule ssubst)
       
   212   apply (rule sum.cases(2))
       
   213   done
       
   214 
       
   215 lemma sum_case_weak_cong: "s = t ==> sum_case f g s = sum_case f g t"
       
   216   -- {* Prevents simplification of @{text f} and @{text g}: much faster. *}
       
   217   by simp
       
   218 
       
   219 lemma sum_case_inject:
       
   220   "sum_case f1 f2 = sum_case g1 g2 ==> (f1 = g1 ==> f2 = g2 ==> P) ==> P"
       
   221 proof -
       
   222   assume a: "sum_case f1 f2 = sum_case g1 g2"
       
   223   assume r: "f1 = g1 ==> f2 = g2 ==> P"
       
   224   show P
       
   225     apply (rule r)
       
   226      apply (rule ext)
       
   227      apply (cut_tac x = "Inl x" in a [THEN fun_cong], simp)
       
   228     apply (rule ext)
       
   229     apply (cut_tac x = "Inr x" in a [THEN fun_cong], simp)
       
   230     done
       
   231 qed
       
   232 
       
   233 constdefs
       
   234   Suml :: "('a => 'c) => 'a + 'b => 'c"
       
   235   "Suml == (%f. sum_case f undefined)"
       
   236 
       
   237   Sumr :: "('b => 'c) => 'a + 'b => 'c"
       
   238   "Sumr == sum_case undefined"
       
   239 
       
   240 lemma [code]:
       
   241   "Suml f (Inl x) = f x"
       
   242   by (simp add: Suml_def)
       
   243 
       
   244 lemma [code]:
       
   245   "Sumr f (Inr x) = f x"
       
   246   by (simp add: Sumr_def)
       
   247 
       
   248 lemma Suml_inject: "Suml f = Suml g ==> f = g"
       
   249   by (unfold Suml_def) (erule sum_case_inject)
       
   250 
       
   251 lemma Sumr_inject: "Sumr f = Sumr g ==> f = g"
       
   252   by (unfold Sumr_def) (erule sum_case_inject)
       
   253 
       
   254 primrec Projl :: "'a + 'b => 'a"
       
   255 where Projl_Inl: "Projl (Inl x) = x"
       
   256 
       
   257 primrec Projr :: "'a + 'b => 'b"
       
   258 where Projr_Inr: "Projr (Inr x) = x"
       
   259 
       
   260 hide (open) const Suml Sumr Projl Projr
   193 
   261 
   194 
   262 
   195 ML
   263 ML
   196 {*
   264 {*
   197 val Inl_RepI = thm "Inl_RepI";
   265 val Inl_RepI = thm "Inl_RepI";