| author | blanchet | 
| Fri, 17 Dec 2010 23:09:53 +0100 | |
| changeset 41260 | ff38ea43aada | 
| parent 40822 | 98a5faa5aec0 | 
| child 41959 | b460124855b8 | 
| permissions | -rw-r--r-- | 
| 15172 | 1 | (* Title: HOL/Induct/QuoNestedDataType | 
| 2 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | |
| 3 | Copyright 2004 University of Cambridge | |
| 4 | *) | |
| 5 | ||
| 6 | header{*Quotienting a Free Algebra Involving Nested Recursion*}
 | |
| 7 | ||
| 16417 | 8 | theory QuoNestedDataType imports Main begin | 
| 15172 | 9 | |
| 10 | subsection{*Defining the Free Algebra*}
 | |
| 11 | ||
| 12 | text{*Messages with encryption and decryption as free constructors.*}
 | |
| 13 | datatype | |
| 14 | freeExp = VAR nat | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
30198diff
changeset | 15 | | PLUS freeExp freeExp | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
30198diff
changeset | 16 | | FNCALL nat "freeExp list" | 
| 15172 | 17 | |
| 18 | text{*The equivalence relation, which makes PLUS associative.*}
 | |
| 19 | ||
| 20 | text{*The first rule is the desired equation. The next three rules
 | |
| 21 | make the equations applicable to subterms. The last two rules are symmetry | |
| 22 | and transitivity.*} | |
| 23746 | 23 | inductive_set | 
| 24 | exprel :: "(freeExp * freeExp) set" | |
| 25 | and exp_rel :: "[freeExp, freeExp] => bool" (infixl "\<sim>" 50) | |
| 26 | where | |
| 27 | "X \<sim> Y == (X,Y) \<in> exprel" | |
| 28 | | ASSOC: "PLUS X (PLUS Y Z) \<sim> PLUS (PLUS X Y) Z" | |
| 29 | | VAR: "VAR N \<sim> VAR N" | |
| 30 | | PLUS: "\<lbrakk>X \<sim> X'; Y \<sim> Y'\<rbrakk> \<Longrightarrow> PLUS X Y \<sim> PLUS X' Y'" | |
| 31 | | FNCALL: "(Xs,Xs') \<in> listrel exprel \<Longrightarrow> FNCALL F Xs \<sim> FNCALL F Xs'" | |
| 32 | | SYM: "X \<sim> Y \<Longrightarrow> Y \<sim> X" | |
| 33 | | TRANS: "\<lbrakk>X \<sim> Y; Y \<sim> Z\<rbrakk> \<Longrightarrow> X \<sim> Z" | |
| 15172 | 34 | monos listrel_mono | 
| 35 | ||
| 36 | ||
| 37 | text{*Proving that it is an equivalence relation*}
 | |
| 38 | ||
| 18460 | 39 | lemma exprel_refl: "X \<sim> X" | 
| 40 | and list_exprel_refl: "(Xs,Xs) \<in> listrel(exprel)" | |
| 23746 | 41 | by (induct X and Xs) (blast intro: exprel.intros listrel.intros)+ | 
| 15172 | 42 | |
| 43 | theorem equiv_exprel: "equiv UNIV exprel" | |
| 18460 | 44 | proof - | 
| 30198 | 45 | have "refl exprel" by (simp add: refl_on_def exprel_refl) | 
| 18460 | 46 | moreover have "sym exprel" by (simp add: sym_def, blast intro: exprel.SYM) | 
| 47 | moreover have "trans exprel" by (simp add: trans_def, blast intro: exprel.TRANS) | |
| 48 | ultimately show ?thesis by (simp add: equiv_def) | |
| 15172 | 49 | qed | 
| 50 | ||
| 51 | theorem equiv_list_exprel: "equiv UNIV (listrel exprel)" | |
| 18460 | 52 | using equiv_listrel [OF equiv_exprel] by simp | 
| 15172 | 53 | |
| 54 | ||
| 55 | lemma FNCALL_Nil: "FNCALL F [] \<sim> FNCALL F []" | |
| 56 | apply (rule exprel.intros) | |
| 23746 | 57 | apply (rule listrel.intros) | 
| 15172 | 58 | done | 
| 59 | ||
| 60 | lemma FNCALL_Cons: | |
| 61 | "\<lbrakk>X \<sim> X'; (Xs,Xs') \<in> listrel(exprel)\<rbrakk> | |
| 62 | \<Longrightarrow> FNCALL F (X#Xs) \<sim> FNCALL F (X'#Xs')" | |
| 23746 | 63 | by (blast intro: exprel.intros listrel.intros) | 
| 15172 | 64 | |
| 65 | ||
| 66 | ||
| 67 | subsection{*Some Functions on the Free Algebra*}
 | |
| 68 | ||
| 69 | subsubsection{*The Set of Variables*}
 | |
| 70 | ||
| 71 | text{*A function to return the set of variables present in a message.  It will
 | |
| 72 | be lifted to the initial algrebra, to serve as an example of that process. | |
| 73 | Note that the "free" refers to the free datatype rather than to the concept | |
| 74 | of a free variable.*} | |
| 39246 | 75 | primrec freevars :: "freeExp \<Rightarrow> nat set" | 
| 76 | and freevars_list :: "freeExp list \<Rightarrow> nat set" where | |
| 77 |   "freevars (VAR N) = {N}"
 | |
| 78 | | "freevars (PLUS X Y) = freevars X \<union> freevars Y" | |
| 79 | | "freevars (FNCALL F Xs) = freevars_list Xs" | |
| 15172 | 80 | |
| 39246 | 81 | | "freevars_list [] = {}"
 | 
| 82 | | "freevars_list (X # Xs) = freevars X \<union> freevars_list Xs" | |
| 15172 | 83 | |
| 84 | text{*This theorem lets us prove that the vars function respects the
 | |
| 85 | equivalence relation. It also helps us prove that Variable | |
| 86 | (the abstract constructor) is injective*} | |
| 87 | theorem exprel_imp_eq_freevars: "U \<sim> V \<Longrightarrow> freevars U = freevars V" | |
| 18460 | 88 | apply (induct set: exprel) | 
| 23746 | 89 | apply (erule_tac [4] listrel.induct) | 
| 15172 | 90 | apply (simp_all add: Un_assoc) | 
| 91 | done | |
| 92 | ||
| 93 | ||
| 94 | ||
| 95 | subsubsection{*Functions for Freeness*}
 | |
| 96 | ||
| 97 | text{*A discriminator function to distinguish vars, sums and function calls*}
 | |
| 39246 | 98 | primrec freediscrim :: "freeExp \<Rightarrow> int" where | 
| 99 | "freediscrim (VAR N) = 0" | |
| 100 | | "freediscrim (PLUS X Y) = 1" | |
| 101 | | "freediscrim (FNCALL F Xs) = 2" | |
| 15172 | 102 | |
| 103 | theorem exprel_imp_eq_freediscrim: | |
| 104 | "U \<sim> V \<Longrightarrow> freediscrim U = freediscrim V" | |
| 18460 | 105 | by (induct set: exprel) auto | 
| 15172 | 106 | |
| 107 | ||
| 108 | text{*This function, which returns the function name, is used to
 | |
| 109 | prove part of the injectivity property for FnCall.*} | |
| 39246 | 110 | primrec freefun :: "freeExp \<Rightarrow> nat" where | 
| 111 | "freefun (VAR N) = 0" | |
| 112 | | "freefun (PLUS X Y) = 0" | |
| 113 | | "freefun (FNCALL F Xs) = F" | |
| 15172 | 114 | |
| 115 | theorem exprel_imp_eq_freefun: | |
| 116 | "U \<sim> V \<Longrightarrow> freefun U = freefun V" | |
| 23746 | 117 | by (induct set: exprel) (simp_all add: listrel.intros) | 
| 15172 | 118 | |
| 119 | ||
| 120 | text{*This function, which returns the list of function arguments, is used to
 | |
| 121 | prove part of the injectivity property for FnCall.*} | |
| 39246 | 122 | primrec freeargs :: "freeExp \<Rightarrow> freeExp list" where | 
| 123 | "freeargs (VAR N) = []" | |
| 124 | | "freeargs (PLUS X Y) = []" | |
| 125 | | "freeargs (FNCALL F Xs) = Xs" | |
| 15172 | 126 | |
| 127 | theorem exprel_imp_eqv_freeargs: | |
| 40822 | 128 | assumes "U \<sim> V" | 
| 129 | shows "(freeargs U, freeargs V) \<in> listrel exprel" | |
| 130 | proof - | |
| 131 | from equiv_list_exprel have sym: "sym (listrel exprel)" by (rule equivE) | |
| 132 | from equiv_list_exprel have trans: "trans (listrel exprel)" by (rule equivE) | |
| 133 | from assms show ?thesis | |
| 134 | apply induct | |
| 135 | apply (erule_tac [4] listrel.induct) | |
| 136 | apply (simp_all add: listrel.intros) | |
| 137 | apply (blast intro: symD [OF sym]) | |
| 138 | apply (blast intro: transD [OF trans]) | |
| 139 | done | |
| 140 | qed | |
| 15172 | 141 | |
| 142 | ||
| 143 | subsection{*The Initial Algebra: A Quotiented Message Type*}
 | |
| 144 | ||
| 145 | ||
| 146 | typedef (Exp) exp = "UNIV//exprel" | |
| 147 | by (auto simp add: quotient_def) | |
| 148 | ||
| 149 | text{*The abstract message constructors*}
 | |
| 150 | ||
| 19736 | 151 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 152 | Var :: "nat \<Rightarrow> exp" where | 
| 19736 | 153 |   "Var N = Abs_Exp(exprel``{VAR N})"
 | 
| 15172 | 154 | |
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 155 | definition | 
| 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 156 | Plus :: "[exp,exp] \<Rightarrow> exp" where | 
| 19736 | 157 | "Plus X Y = | 
| 15172 | 158 |        Abs_Exp (\<Union>U \<in> Rep_Exp X. \<Union>V \<in> Rep_Exp Y. exprel``{PLUS U V})"
 | 
| 159 | ||
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 160 | definition | 
| 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 161 | FnCall :: "[nat, exp list] \<Rightarrow> exp" where | 
| 19736 | 162 | "FnCall F Xs = | 
| 15172 | 163 |        Abs_Exp (\<Union>Us \<in> listset (map Rep_Exp Xs). exprel `` {FNCALL F Us})"
 | 
| 164 | ||
| 165 | ||
| 166 | text{*Reduces equality of equivalence classes to the @{term exprel} relation:
 | |
| 167 |   @{term "(exprel `` {x} = exprel `` {y}) = ((x,y) \<in> exprel)"} *}
 | |
| 168 | lemmas equiv_exprel_iff = eq_equiv_class_iff [OF equiv_exprel UNIV_I UNIV_I] | |
| 169 | ||
| 170 | declare equiv_exprel_iff [simp] | |
| 171 | ||
| 172 | ||
| 173 | text{*All equivalence classes belong to set of representatives*}
 | |
| 174 | lemma [simp]: "exprel``{U} \<in> Exp"
 | |
| 175 | by (auto simp add: Exp_def quotient_def intro: exprel_refl) | |
| 176 | ||
| 177 | lemma inj_on_Abs_Exp: "inj_on Abs_Exp Exp" | |
| 178 | apply (rule inj_on_inverseI) | |
| 179 | apply (erule Abs_Exp_inverse) | |
| 180 | done | |
| 181 | ||
| 182 | text{*Reduces equality on abstractions to equality on representatives*}
 | |
| 183 | declare inj_on_Abs_Exp [THEN inj_on_iff, simp] | |
| 184 | ||
| 185 | declare Abs_Exp_inverse [simp] | |
| 186 | ||
| 187 | ||
| 188 | text{*Case analysis on the representation of a exp as an equivalence class.*}
 | |
| 189 | lemma eq_Abs_Exp [case_names Abs_Exp, cases type: exp]: | |
| 190 |      "(!!U. z = Abs_Exp(exprel``{U}) ==> P) ==> P"
 | |
| 191 | apply (rule Rep_Exp [of z, unfolded Exp_def, THEN quotientE]) | |
| 192 | apply (drule arg_cong [where f=Abs_Exp]) | |
| 193 | apply (auto simp add: Rep_Exp_inverse intro: exprel_refl) | |
| 194 | done | |
| 195 | ||
| 196 | ||
| 197 | subsection{*Every list of abstract expressions can be expressed in terms of a
 | |
| 198 | list of concrete expressions*} | |
| 199 | ||
| 19736 | 200 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 201 | Abs_ExpList :: "freeExp list => exp list" where | 
| 19736 | 202 |   "Abs_ExpList Xs = map (%U. Abs_Exp(exprel``{U})) Xs"
 | 
| 15172 | 203 | |
| 204 | lemma Abs_ExpList_Nil [simp]: "Abs_ExpList [] == []" | |
| 205 | by (simp add: Abs_ExpList_def) | |
| 206 | ||
| 207 | lemma Abs_ExpList_Cons [simp]: | |
| 208 |      "Abs_ExpList (X#Xs) == Abs_Exp (exprel``{X}) # Abs_ExpList Xs"
 | |
| 209 | by (simp add: Abs_ExpList_def) | |
| 210 | ||
| 211 | lemma ExpList_rep: "\<exists>Us. z = Abs_ExpList Us" | |
| 212 | apply (induct z) | |
| 213 | apply (rule_tac [2] z=a in eq_Abs_Exp) | |
| 18447 | 214 | apply (auto simp add: Abs_ExpList_def Cons_eq_map_conv intro: exprel_refl) | 
| 15172 | 215 | done | 
| 216 | ||
| 217 | lemma eq_Abs_ExpList [case_names Abs_ExpList]: | |
| 218 | "(!!Us. z = Abs_ExpList Us ==> P) ==> P" | |
| 219 | by (rule exE [OF ExpList_rep], blast) | |
| 220 | ||
| 221 | ||
| 222 | subsubsection{*Characteristic Equations for the Abstract Constructors*}
 | |
| 223 | ||
| 224 | lemma Plus: "Plus (Abs_Exp(exprel``{U})) (Abs_Exp(exprel``{V})) = 
 | |
| 225 |              Abs_Exp (exprel``{PLUS U V})"
 | |
| 226 | proof - | |
| 227 |   have "(\<lambda>U V. exprel `` {PLUS U V}) respects2 exprel"
 | |
| 40822 | 228 | by (auto simp add: congruent2_def exprel.PLUS) | 
| 15172 | 229 | thus ?thesis | 
| 230 | by (simp add: Plus_def UN_equiv_class2 [OF equiv_exprel equiv_exprel]) | |
| 231 | qed | |
| 232 | ||
| 233 | text{*It is not clear what to do with FnCall: it's argument is an abstraction
 | |
| 234 | of an @{typ "exp list"}. Is it just Nil or Cons? What seems to work best is to
 | |
| 235 | regard an @{typ "exp list"} as a @{term "listrel exprel"} equivalence class*}
 | |
| 236 | ||
| 237 | text{*This theorem is easily proved but never used. There's no obvious way
 | |
| 238 | even to state the analogous result, @{text FnCall_Cons}.*}
 | |
| 239 | lemma FnCall_Nil: "FnCall F [] = Abs_Exp (exprel``{FNCALL F []})"
 | |
| 240 | by (simp add: FnCall_def) | |
| 241 | ||
| 242 | lemma FnCall_respects: | |
| 243 |      "(\<lambda>Us. exprel `` {FNCALL F Us}) respects (listrel exprel)"
 | |
| 40822 | 244 | by (auto simp add: congruent_def exprel.FNCALL) | 
| 15172 | 245 | |
| 246 | lemma FnCall_sing: | |
| 247 |      "FnCall F [Abs_Exp(exprel``{U})] = Abs_Exp (exprel``{FNCALL F [U]})"
 | |
| 248 | proof - | |
| 249 |   have "(\<lambda>U. exprel `` {FNCALL F [U]}) respects exprel"
 | |
| 40822 | 250 | by (auto simp add: congruent_def FNCALL_Cons listrel.intros) | 
| 15172 | 251 | thus ?thesis | 
| 252 | by (simp add: FnCall_def UN_equiv_class [OF equiv_exprel]) | |
| 253 | qed | |
| 254 | ||
| 255 | lemma listset_Rep_Exp_Abs_Exp: | |
| 256 |      "listset (map Rep_Exp (Abs_ExpList Us)) = listrel exprel `` {Us}";
 | |
| 18460 | 257 | by (induct Us) (simp_all add: listrel_Cons Abs_ExpList_def) | 
| 15172 | 258 | |
| 259 | lemma FnCall: | |
| 260 |      "FnCall F (Abs_ExpList Us) = Abs_Exp (exprel``{FNCALL F Us})"
 | |
| 261 | proof - | |
| 262 |   have "(\<lambda>Us. exprel `` {FNCALL F Us}) respects (listrel exprel)"
 | |
| 40822 | 263 | by (auto simp add: congruent_def exprel.FNCALL) | 
| 15172 | 264 | thus ?thesis | 
| 265 | by (simp add: FnCall_def UN_equiv_class [OF equiv_list_exprel] | |
| 266 | listset_Rep_Exp_Abs_Exp) | |
| 267 | qed | |
| 268 | ||
| 269 | ||
| 270 | text{*Establishing this equation is the point of the whole exercise*}
 | |
| 271 | theorem Plus_assoc: "Plus X (Plus Y Z) = Plus (Plus X Y) Z" | |
| 272 | by (cases X, cases Y, cases Z, simp add: Plus exprel.ASSOC) | |
| 273 | ||
| 274 | ||
| 275 | ||
| 276 | subsection{*The Abstract Function to Return the Set of Variables*}
 | |
| 277 | ||
| 19736 | 278 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 279 | vars :: "exp \<Rightarrow> nat set" where | 
| 19736 | 280 | "vars X = (\<Union>U \<in> Rep_Exp X. freevars U)" | 
| 15172 | 281 | |
| 282 | lemma vars_respects: "freevars respects exprel" | |
| 40822 | 283 | by (auto simp add: congruent_def exprel_imp_eq_freevars) | 
| 15172 | 284 | |
| 285 | text{*The extension of the function @{term vars} to lists*}
 | |
| 39246 | 286 | primrec vars_list :: "exp list \<Rightarrow> nat set" where | 
| 287 |   "vars_list []    = {}"
 | |
| 288 | | "vars_list(E#Es) = vars E \<union> vars_list Es" | |
| 15172 | 289 | |
| 290 | ||
| 291 | text{*Now prove the three equations for @{term vars}*}
 | |
| 292 | ||
| 293 | lemma vars_Variable [simp]: "vars (Var N) = {N}"
 | |
| 294 | by (simp add: vars_def Var_def | |
| 295 | UN_equiv_class [OF equiv_exprel vars_respects]) | |
| 296 | ||
| 297 | lemma vars_Plus [simp]: "vars (Plus X Y) = vars X \<union> vars Y" | |
| 298 | apply (cases X, cases Y) | |
| 299 | apply (simp add: vars_def Plus | |
| 300 | UN_equiv_class [OF equiv_exprel vars_respects]) | |
| 301 | done | |
| 302 | ||
| 303 | lemma vars_FnCall [simp]: "vars (FnCall F Xs) = vars_list Xs" | |
| 304 | apply (cases Xs rule: eq_Abs_ExpList) | |
| 305 | apply (simp add: FnCall) | |
| 306 | apply (induct_tac Us) | |
| 307 | apply (simp_all add: vars_def UN_equiv_class [OF equiv_exprel vars_respects]) | |
| 308 | done | |
| 309 | ||
| 310 | lemma vars_FnCall_Nil: "vars (FnCall F Nil) = {}" 
 | |
| 311 | by simp | |
| 312 | ||
| 313 | lemma vars_FnCall_Cons: "vars (FnCall F (X#Xs)) = vars X \<union> vars_list Xs" | |
| 314 | by simp | |
| 315 | ||
| 316 | ||
| 317 | subsection{*Injectivity Properties of Some Constructors*}
 | |
| 318 | ||
| 319 | lemma VAR_imp_eq: "VAR m \<sim> VAR n \<Longrightarrow> m = n" | |
| 320 | by (drule exprel_imp_eq_freevars, simp) | |
| 321 | ||
| 322 | text{*Can also be proved using the function @{term vars}*}
 | |
| 323 | lemma Var_Var_eq [iff]: "(Var m = Var n) = (m = n)" | |
| 324 | by (auto simp add: Var_def exprel_refl dest: VAR_imp_eq) | |
| 325 | ||
| 326 | lemma VAR_neqv_PLUS: "VAR m \<sim> PLUS X Y \<Longrightarrow> False" | |
| 327 | by (drule exprel_imp_eq_freediscrim, simp) | |
| 328 | ||
| 329 | theorem Var_neq_Plus [iff]: "Var N \<noteq> Plus X Y" | |
| 330 | apply (cases X, cases Y) | |
| 331 | apply (simp add: Var_def Plus) | |
| 332 | apply (blast dest: VAR_neqv_PLUS) | |
| 333 | done | |
| 334 | ||
| 335 | theorem Var_neq_FnCall [iff]: "Var N \<noteq> FnCall F Xs" | |
| 336 | apply (cases Xs rule: eq_Abs_ExpList) | |
| 337 | apply (auto simp add: FnCall Var_def) | |
| 338 | apply (drule exprel_imp_eq_freediscrim, simp) | |
| 339 | done | |
| 340 | ||
| 341 | subsection{*Injectivity of @{term FnCall}*}
 | |
| 342 | ||
| 19736 | 343 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 344 | "fun" :: "exp \<Rightarrow> nat" where | 
| 39910 | 345 |   "fun X = the_elem (\<Union>U \<in> Rep_Exp X. {freefun U})"
 | 
| 15172 | 346 | |
| 347 | lemma fun_respects: "(%U. {freefun U}) respects exprel"
 | |
| 40822 | 348 | by (auto simp add: congruent_def exprel_imp_eq_freefun) | 
| 15172 | 349 | |
| 350 | lemma fun_FnCall [simp]: "fun (FnCall F Xs) = F" | |
| 351 | apply (cases Xs rule: eq_Abs_ExpList) | |
| 352 | apply (simp add: FnCall fun_def UN_equiv_class [OF equiv_exprel fun_respects]) | |
| 353 | done | |
| 354 | ||
| 19736 | 355 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 356 | args :: "exp \<Rightarrow> exp list" where | 
| 39910 | 357 |   "args X = the_elem (\<Union>U \<in> Rep_Exp X. {Abs_ExpList (freeargs U)})"
 | 
| 15172 | 358 | |
| 359 | text{*This result can probably be generalized to arbitrary equivalence
 | |
| 360 | relations, but with little benefit here.*} | |
| 361 | lemma Abs_ExpList_eq: | |
| 362 | "(y, z) \<in> listrel exprel \<Longrightarrow> Abs_ExpList (y) = Abs_ExpList (z)" | |
| 18460 | 363 | by (induct set: listrel) simp_all | 
| 15172 | 364 | |
| 365 | lemma args_respects: "(%U. {Abs_ExpList (freeargs U)}) respects exprel"
 | |
| 40822 | 366 | by (auto simp add: congruent_def Abs_ExpList_eq exprel_imp_eqv_freeargs) | 
| 15172 | 367 | |
| 368 | lemma args_FnCall [simp]: "args (FnCall F Xs) = Xs" | |
| 369 | apply (cases Xs rule: eq_Abs_ExpList) | |
| 370 | apply (simp add: FnCall args_def UN_equiv_class [OF equiv_exprel args_respects]) | |
| 371 | done | |
| 372 | ||
| 373 | ||
| 374 | lemma FnCall_FnCall_eq [iff]: | |
| 375 | "(FnCall F Xs = FnCall F' Xs') = (F=F' & Xs=Xs')" | |
| 376 | proof | |
| 377 | assume "FnCall F Xs = FnCall F' Xs'" | |
| 378 | hence "fun (FnCall F Xs) = fun (FnCall F' Xs')" | |
| 379 | and "args (FnCall F Xs) = args (FnCall F' Xs')" by auto | |
| 380 | thus "F=F' & Xs=Xs'" by simp | |
| 381 | next | |
| 382 | assume "F=F' & Xs=Xs'" thus "FnCall F Xs = FnCall F' Xs'" by simp | |
| 383 | qed | |
| 384 | ||
| 385 | ||
| 386 | subsection{*The Abstract Discriminator*}
 | |
| 387 | text{*However, as @{text FnCall_Var_neq_Var} illustrates, we don't need this
 | |
| 388 | function in order to prove discrimination theorems.*} | |
| 389 | ||
| 19736 | 390 | definition | 
| 21404 
eb85850d3eb7
more robust syntax for definition/abbreviation/notation;
 wenzelm parents: 
21210diff
changeset | 391 | discrim :: "exp \<Rightarrow> int" where | 
| 39910 | 392 |   "discrim X = the_elem (\<Union>U \<in> Rep_Exp X. {freediscrim U})"
 | 
| 15172 | 393 | |
| 394 | lemma discrim_respects: "(\<lambda>U. {freediscrim U}) respects exprel"
 | |
| 40822 | 395 | by (auto simp add: congruent_def exprel_imp_eq_freediscrim) | 
| 15172 | 396 | |
| 397 | text{*Now prove the four equations for @{term discrim}*}
 | |
| 398 | ||
| 399 | lemma discrim_Var [simp]: "discrim (Var N) = 0" | |
| 400 | by (simp add: discrim_def Var_def | |
| 401 | UN_equiv_class [OF equiv_exprel discrim_respects]) | |
| 402 | ||
| 403 | lemma discrim_Plus [simp]: "discrim (Plus X Y) = 1" | |
| 404 | apply (cases X, cases Y) | |
| 405 | apply (simp add: discrim_def Plus | |
| 406 | UN_equiv_class [OF equiv_exprel discrim_respects]) | |
| 407 | done | |
| 408 | ||
| 409 | lemma discrim_FnCall [simp]: "discrim (FnCall F Xs) = 2" | |
| 410 | apply (rule_tac z=Xs in eq_Abs_ExpList) | |
| 411 | apply (simp add: discrim_def FnCall | |
| 412 | UN_equiv_class [OF equiv_exprel discrim_respects]) | |
| 413 | done | |
| 414 | ||
| 415 | ||
| 416 | text{*The structural induction rule for the abstract type*}
 | |
| 18460 | 417 | theorem exp_inducts: | 
| 15172 | 418 | assumes V: "\<And>nat. P1 (Var nat)" | 
| 419 | and P: "\<And>exp1 exp2. \<lbrakk>P1 exp1; P1 exp2\<rbrakk> \<Longrightarrow> P1 (Plus exp1 exp2)" | |
| 420 | and F: "\<And>nat list. P2 list \<Longrightarrow> P1 (FnCall nat list)" | |
| 421 | and Nil: "P2 []" | |
| 422 | and Cons: "\<And>exp list. \<lbrakk>P1 exp; P2 list\<rbrakk> \<Longrightarrow> P2 (exp # list)" | |
| 18460 | 423 | shows "P1 exp" and "P2 list" | 
| 424 | proof - | |
| 425 |   obtain U where exp: "exp = (Abs_Exp (exprel `` {U}))" by (cases exp)
 | |
| 426 | obtain Us where list: "list = Abs_ExpList Us" by (rule eq_Abs_ExpList) | |
| 427 |   have "P1 (Abs_Exp (exprel `` {U}))" and "P2 (Abs_ExpList Us)"
 | |
| 15172 | 428 | proof (induct U and Us) | 
| 18460 | 429 | case (VAR nat) | 
| 15172 | 430 | with V show ?case by (simp add: Var_def) | 
| 431 | next | |
| 432 | case (PLUS X Y) | |
| 433 |     with P [of "Abs_Exp (exprel `` {X})" "Abs_Exp (exprel `` {Y})"]
 | |
| 434 | show ?case by (simp add: Plus) | |
| 435 | next | |
| 436 | case (FNCALL nat list) | |
| 437 | with F [of "Abs_ExpList list"] | |
| 438 | show ?case by (simp add: FnCall) | |
| 439 | next | |
| 440 | case Nil_freeExp | |
| 441 | with Nil show ?case by simp | |
| 442 | next | |
| 443 | case Cons_freeExp | |
| 18460 | 444 | with Cons show ?case by simp | 
| 15172 | 445 | qed | 
| 18460 | 446 | with exp and list show "P1 exp" and "P2 list" by (simp_all only:) | 
| 15172 | 447 | qed | 
| 448 | ||
| 449 | end |