| author | haftmann | 
| Wed, 02 Dec 2009 17:53:34 +0100 | |
| changeset 33938 | 7ed48b28bb7f | 
| parent 32153 | a0e57fb1b930 | 
| child 35054 | a5db9779b026 | 
| permissions | -rw-r--r-- | 
| 17456 | 1 | (* Title: CCL/Type.thy | 
| 0 | 2 | Author: Martin Coen | 
| 3 | Copyright 1993 University of Cambridge | |
| 4 | *) | |
| 5 | ||
| 17456 | 6 | header {* Types in CCL are defined as sets of terms *}
 | 
| 7 | ||
| 8 | theory Type | |
| 9 | imports Term | |
| 10 | begin | |
| 0 | 11 | |
| 12 | consts | |
| 13 | ||
| 14 | Subtype :: "['a set, 'a => o] => 'a set" | |
| 15 | Bool :: "i set" | |
| 16 | Unit :: "i set" | |
| 24825 | 17 | Plus :: "[i set, i set] => i set" (infixr "+" 55) | 
| 0 | 18 | Pi :: "[i set, i => i set] => i set" | 
| 19 | Sigma :: "[i set, i => i set] => i set" | |
| 20 | Nat :: "i set" | |
| 21 | List :: "i set => i set" | |
| 22 | Lists :: "i set => i set" | |
| 23 | ILists :: "i set => i set" | |
| 999 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 24 | TAll :: "(i set => i set) => i set" (binder "TALL " 55) | 
| 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 25 | TEx :: "(i set => i set) => i set" (binder "TEX " 55) | 
| 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 26 |   Lift          :: "i set => i set"                  ("(3[_])")
 | 
| 0 | 27 | |
| 28 | SPLIT :: "[i, [i, i] => i set] => i set" | |
| 29 | ||
| 14765 | 30 | syntax | 
| 999 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 31 |   "@Pi"         :: "[idt, i set, i set] => i set"    ("(3PROD _:_./ _)"
 | 
| 1474 | 32 | [0,0,60] 60) | 
| 999 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 33 | |
| 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 34 |   "@Sigma"      :: "[idt, i set, i set] => i set"    ("(3SUM _:_./ _)"
 | 
| 1474 | 35 | [0,0,60] 60) | 
| 17456 | 36 | |
| 999 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 37 |   "@->"         :: "[i set, i set] => i set"         ("(_ ->/ _)"  [54, 53] 53)
 | 
| 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 38 |   "@*"          :: "[i set, i set] => i set"         ("(_ */ _)" [56, 55] 55)
 | 
| 
9bf3816298d0
Gave tighter priorities to SUM and PROD to reduce ambiguities.
 lcp parents: 
22diff
changeset | 39 |   "@Subtype"    :: "[idt, 'a set, o] => 'a set"      ("(1{_: _ ./ _})")
 | 
| 0 | 40 | |
| 41 | translations | |
| 42 | "PROD x:A. B" => "Pi(A, %x. B)" | |
| 17782 | 43 | "A -> B" => "Pi(A, %_. B)" | 
| 0 | 44 | "SUM x:A. B" => "Sigma(A, %x. B)" | 
| 17782 | 45 | "A * B" => "Sigma(A, %_. B)" | 
| 0 | 46 |   "{x: A. B}"   == "Subtype(A, %x. B)"
 | 
| 47 | ||
| 17456 | 48 | print_translation {*
 | 
| 49 |   [("Pi", dependent_tr' ("@Pi", "@->")),
 | |
| 50 |    ("Sigma", dependent_tr' ("@Sigma", "@*"))] *}
 | |
| 0 | 51 | |
| 17456 | 52 | axioms | 
| 53 |   Subtype_def: "{x:A. P(x)} == {x. x:A & P(x)}"
 | |
| 54 |   Unit_def:          "Unit == {x. x=one}"
 | |
| 55 |   Bool_def:          "Bool == {x. x=true | x=false}"
 | |
| 56 |   Plus_def:           "A+B == {x. (EX a:A. x=inl(a)) | (EX b:B. x=inr(b))}"
 | |
| 57 |   Pi_def:         "Pi(A,B) == {x. EX b. x=lam x. b(x) & (ALL x:A. b(x):B(x))}"
 | |
| 58 |   Sigma_def:   "Sigma(A,B) == {x. EX a:A. EX b:B(a).x=<a,b>}"
 | |
| 59 | Nat_def: "Nat == lfp(% X. Unit + X)" | |
| 60 | List_def: "List(A) == lfp(% X. Unit + A*X)" | |
| 0 | 61 | |
| 17456 | 62 | Lists_def: "Lists(A) == gfp(% X. Unit + A*X)" | 
| 63 |   ILists_def:   "ILists(A) == gfp(% X.{} + A*X)"
 | |
| 0 | 64 | |
| 17456 | 65 |   Tall_def:   "TALL X. B(X) == Inter({X. EX Y. X=B(Y)})"
 | 
| 66 |   Tex_def:     "TEX X. B(X) == Union({X. EX Y. X=B(Y)})"
 | |
| 67 |   Lift_def:           "[A] == A Un {bot}"
 | |
| 0 | 68 | |
| 17456 | 69 |   SPLIT_def:   "SPLIT(p,B) == Union({A. EX x y. p=<x,y> & A=B(x,y)})"
 | 
| 70 | ||
| 20140 | 71 | |
| 72 | lemmas simp_type_defs = | |
| 73 | Subtype_def Unit_def Bool_def Plus_def Sigma_def Pi_def Lift_def Tall_def Tex_def | |
| 74 | and ind_type_defs = Nat_def List_def | |
| 75 | and simp_data_defs = one_def inl_def inr_def | |
| 76 | and ind_data_defs = zero_def succ_def nil_def cons_def | |
| 77 | ||
| 78 | lemma subsetXH: "A <= B <-> (ALL x. x:A --> x:B)" | |
| 79 | by blast | |
| 80 | ||
| 81 | ||
| 82 | subsection {* Exhaustion Rules *}
 | |
| 83 | ||
| 84 | lemma EmptyXH: "!!a. a : {} <-> False"
 | |
| 85 |   and SubtypeXH: "!!a A P. a : {x:A. P(x)} <-> (a:A & P(a))"
 | |
| 86 | and UnitXH: "!!a. a : Unit <-> a=one" | |
| 87 | and BoolXH: "!!a. a : Bool <-> a=true | a=false" | |
| 88 | and PlusXH: "!!a A B. a : A+B <-> (EX x:A. a=inl(x)) | (EX x:B. a=inr(x))" | |
| 89 | and PiXH: "!!a A B. a : PROD x:A. B(x) <-> (EX b. a=lam x. b(x) & (ALL x:A. b(x):B(x)))" | |
| 90 | and SgXH: "!!a A B. a : SUM x:A. B(x) <-> (EX x:A. EX y:B(x).a=<x,y>)" | |
| 91 | unfolding simp_type_defs by blast+ | |
| 92 | ||
| 93 | lemmas XHs = EmptyXH SubtypeXH UnitXH BoolXH PlusXH PiXH SgXH | |
| 94 | ||
| 95 | lemma LiftXH: "a : [A] <-> (a=bot | a:A)" | |
| 96 | and TallXH: "a : TALL X. B(X) <-> (ALL X. a:B(X))" | |
| 97 | and TexXH: "a : TEX X. B(X) <-> (EX X. a:B(X))" | |
| 98 | unfolding simp_type_defs by blast+ | |
| 99 | ||
| 100 | ML {*
 | |
| 101 | bind_thms ("case_rls", XH_to_Es (thms "XHs"));
 | |
| 102 | *} | |
| 103 | ||
| 104 | ||
| 105 | subsection {* Canonical Type Rules *}
 | |
| 106 | ||
| 107 | lemma oneT: "one : Unit" | |
| 108 | and trueT: "true : Bool" | |
| 109 | and falseT: "false : Bool" | |
| 110 | and lamT: "!!b B. [| !!x. x:A ==> b(x):B(x) |] ==> lam x. b(x) : Pi(A,B)" | |
| 111 | and pairT: "!!b B. [| a:A; b:B(a) |] ==> <a,b>:Sigma(A,B)" | |
| 112 | and inlT: "a:A ==> inl(a) : A+B" | |
| 113 | and inrT: "b:B ==> inr(b) : A+B" | |
| 114 | by (blast intro: XHs [THEN iffD2])+ | |
| 115 | ||
| 116 | lemmas canTs = oneT trueT falseT pairT lamT inlT inrT | |
| 117 | ||
| 118 | ||
| 119 | subsection {* Non-Canonical Type Rules *}
 | |
| 120 | ||
| 121 | lemma lem: "[| a:B(u); u=v |] ==> a : B(v)" | |
| 122 | by blast | |
| 123 | ||
| 124 | ||
| 125 | ML {*
 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 126 | fun mk_ncanT_tac top_crls crls = | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 127 |   SUBPROOF (fn {context = ctxt, prems = major :: prems, ...} =>
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 128 | resolve_tac ([major] RL top_crls) 1 THEN | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 129 |     REPEAT_SOME (eresolve_tac (crls @ [exE, @{thm bexE}, conjE, disjE])) THEN
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 130 | ALLGOALS (asm_simp_tac (simpset_of ctxt)) THEN | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 131 |     ALLGOALS (ares_tac (prems RL [@{thm lem}]) ORELSE' etac @{thm bspec}) THEN
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 132 | safe_tac (claset_of ctxt addSIs prems)) | 
| 28272 
ed959a0f650b
proper thm antiquotations within ML solve obscure context problems (due to update of ML environment);
 wenzelm parents: 
26342diff
changeset | 133 | *} | 
| 20140 | 134 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 135 | method_setup ncanT = {*
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 136 |   Scan.succeed (SIMPLE_METHOD' o mk_ncanT_tac @{thms case_rls} @{thms case_rls})
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 137 | *} "" | 
| 20140 | 138 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 139 | lemma ifT: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 140 | "[| b:Bool; b=true ==> t:A(true); b=false ==> u:A(false) |] ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 141 | if b then t else u : A(b)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 142 | by ncanT | 
| 20140 | 143 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 144 | lemma applyT: "[| f : Pi(A,B); a:A |] ==> f ` a : B(a)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 145 | by ncanT | 
| 20140 | 146 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 147 | lemma splitT: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 148 | "[| p:Sigma(A,B); !!x y. [| x:A; y:B(x); p=<x,y> |] ==> c(x,y):C(<x,y>) |] | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 149 | ==> split(p,c):C(p)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 150 | by ncanT | 
| 20140 | 151 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 152 | lemma whenT: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 153 | "[| p:A+B; !!x.[| x:A; p=inl(x) |] ==> a(x):C(inl(x)); !!y.[| y:B; p=inr(y) |] | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 154 | ==> b(y):C(inr(y)) |] ==> when(p,a,b) : C(p)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 155 | by ncanT | 
| 20140 | 156 | |
| 157 | lemmas ncanTs = ifT applyT splitT whenT | |
| 158 | ||
| 159 | ||
| 160 | subsection {* Subtypes *}
 | |
| 161 | ||
| 162 | lemma SubtypeD1: "a : Subtype(A, P) ==> a : A" | |
| 163 | and SubtypeD2: "a : Subtype(A, P) ==> P(a)" | |
| 164 | by (simp_all add: SubtypeXH) | |
| 165 | ||
| 166 | lemma SubtypeI: "[| a:A;  P(a) |] ==> a : {x:A. P(x)}"
 | |
| 167 | by (simp add: SubtypeXH) | |
| 168 | ||
| 169 | lemma SubtypeE: "[| a : {x:A. P(x)};  [| a:A;  P(a) |] ==> Q |] ==> Q"
 | |
| 170 | by (simp add: SubtypeXH) | |
| 171 | ||
| 172 | ||
| 173 | subsection {* Monotonicity *}
 | |
| 174 | ||
| 175 | lemma idM: "mono (%X. X)" | |
| 176 | apply (rule monoI) | |
| 177 | apply assumption | |
| 178 | done | |
| 179 | ||
| 180 | lemma constM: "mono(%X. A)" | |
| 181 | apply (rule monoI) | |
| 182 | apply (rule subset_refl) | |
| 183 | done | |
| 184 | ||
| 185 | lemma "mono(%X. A(X)) ==> mono(%X.[A(X)])" | |
| 186 | apply (rule subsetI [THEN monoI]) | |
| 187 | apply (drule LiftXH [THEN iffD1]) | |
| 188 | apply (erule disjE) | |
| 189 | apply (erule disjI1 [THEN LiftXH [THEN iffD2]]) | |
| 190 | apply (rule disjI2 [THEN LiftXH [THEN iffD2]]) | |
| 191 | apply (drule (1) monoD) | |
| 192 | apply blast | |
| 193 | done | |
| 194 | ||
| 195 | lemma SgM: | |
| 196 | "[| mono(%X. A(X)); !!x X. x:A(X) ==> mono(%X. B(X,x)) |] ==> | |
| 197 | mono(%X. Sigma(A(X),B(X)))" | |
| 198 | by (blast intro!: subsetI [THEN monoI] canTs elim!: case_rls | |
| 199 | dest!: monoD [THEN subsetD]) | |
| 200 | ||
| 201 | lemma PiM: | |
| 202 | "[| !!x. x:A ==> mono(%X. B(X,x)) |] ==> mono(%X. Pi(A,B(X)))" | |
| 203 | by (blast intro!: subsetI [THEN monoI] canTs elim!: case_rls | |
| 204 | dest!: monoD [THEN subsetD]) | |
| 205 | ||
| 206 | lemma PlusM: | |
| 207 | "[| mono(%X. A(X)); mono(%X. B(X)) |] ==> mono(%X. A(X)+B(X))" | |
| 208 | by (blast intro!: subsetI [THEN monoI] canTs elim!: case_rls | |
| 209 | dest!: monoD [THEN subsetD]) | |
| 210 | ||
| 211 | ||
| 212 | subsection {* Recursive types *}
 | |
| 213 | ||
| 214 | subsubsection {* Conversion Rules for Fixed Points via monotonicity and Tarski *}
 | |
| 215 | ||
| 216 | lemma NatM: "mono(%X. Unit+X)"; | |
| 217 | apply (rule PlusM constM idM)+ | |
| 218 | done | |
| 219 | ||
| 220 | lemma def_NatB: "Nat = Unit + Nat" | |
| 221 | apply (rule def_lfp_Tarski [OF Nat_def]) | |
| 222 | apply (rule NatM) | |
| 223 | done | |
| 224 | ||
| 225 | lemma ListM: "mono(%X.(Unit+Sigma(A,%y. X)))" | |
| 226 | apply (rule PlusM SgM constM idM)+ | |
| 227 | done | |
| 228 | ||
| 229 | lemma def_ListB: "List(A) = Unit + A * List(A)" | |
| 230 | apply (rule def_lfp_Tarski [OF List_def]) | |
| 231 | apply (rule ListM) | |
| 232 | done | |
| 233 | ||
| 234 | lemma def_ListsB: "Lists(A) = Unit + A * Lists(A)" | |
| 235 | apply (rule def_gfp_Tarski [OF Lists_def]) | |
| 236 | apply (rule ListM) | |
| 237 | done | |
| 238 | ||
| 239 | lemma IListsM: "mono(%X.({} + Sigma(A,%y. X)))"
 | |
| 240 | apply (rule PlusM SgM constM idM)+ | |
| 241 | done | |
| 242 | ||
| 243 | lemma def_IListsB: "ILists(A) = {} + A * ILists(A)"
 | |
| 244 | apply (rule def_gfp_Tarski [OF ILists_def]) | |
| 245 | apply (rule IListsM) | |
| 246 | done | |
| 247 | ||
| 248 | lemmas ind_type_eqs = def_NatB def_ListB def_ListsB def_IListsB | |
| 249 | ||
| 250 | ||
| 251 | subsection {* Exhaustion Rules *}
 | |
| 252 | ||
| 253 | lemma NatXH: "a : Nat <-> (a=zero | (EX x:Nat. a=succ(x)))" | |
| 254 | and ListXH: "a : List(A) <-> (a=[] | (EX x:A. EX xs:List(A).a=x$xs))" | |
| 255 | and ListsXH: "a : Lists(A) <-> (a=[] | (EX x:A. EX xs:Lists(A).a=x$xs))" | |
| 256 | and IListsXH: "a : ILists(A) <-> (EX x:A. EX xs:ILists(A).a=x$xs)" | |
| 257 | unfolding ind_data_defs | |
| 258 | by (rule ind_type_eqs [THEN XHlemma1], blast intro!: canTs elim!: case_rls)+ | |
| 259 | ||
| 260 | lemmas iXHs = NatXH ListXH | |
| 261 | ||
| 262 | ML {* bind_thms ("icase_rls", XH_to_Es (thms "iXHs")) *}
 | |
| 263 | ||
| 264 | ||
| 265 | subsection {* Type Rules *}
 | |
| 266 | ||
| 267 | lemma zeroT: "zero : Nat" | |
| 268 | and succT: "n:Nat ==> succ(n) : Nat" | |
| 269 | and nilT: "[] : List(A)" | |
| 270 | and consT: "[| h:A; t:List(A) |] ==> h$t : List(A)" | |
| 271 | by (blast intro: iXHs [THEN iffD2])+ | |
| 272 | ||
| 273 | lemmas icanTs = zeroT succT nilT consT | |
| 274 | ||
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 275 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 276 | method_setup incanT = {*
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 277 |   Scan.succeed (SIMPLE_METHOD' o mk_ncanT_tac @{thms icase_rls} @{thms case_rls})
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 278 | *} "" | 
| 20140 | 279 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 280 | lemma ncaseT: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 281 | "[| n:Nat; n=zero ==> b:C(zero); !!x.[| x:Nat; n=succ(x) |] ==> c(x):C(succ(x)) |] | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 282 | ==> ncase(n,b,c) : C(n)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 283 | by incanT | 
| 20140 | 284 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 285 | lemma lcaseT: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 286 | "[| l:List(A); l=[] ==> b:C([]); !!h t.[| h:A; t:List(A); l=h$t |] ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 287 | c(h,t):C(h$t) |] ==> lcase(l,b,c) : C(l)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 288 | by incanT | 
| 20140 | 289 | |
| 290 | lemmas incanTs = ncaseT lcaseT | |
| 291 | ||
| 292 | ||
| 293 | subsection {* Induction Rules *}
 | |
| 294 | ||
| 295 | lemmas ind_Ms = NatM ListM | |
| 296 | ||
| 297 | lemma Nat_ind: "[| n:Nat; P(zero); !!x.[| x:Nat; P(x) |] ==> P(succ(x)) |] ==> P(n)" | |
| 298 | apply (unfold ind_data_defs) | |
| 299 | apply (erule def_induct [OF Nat_def _ NatM]) | |
| 300 | apply (blast intro: canTs elim!: case_rls) | |
| 301 | done | |
| 302 | ||
| 303 | lemma List_ind: | |
| 304 | "[| l:List(A); P([]); !!x xs.[| x:A; xs:List(A); P(xs) |] ==> P(x$xs) |] ==> P(l)" | |
| 305 | apply (unfold ind_data_defs) | |
| 306 | apply (erule def_induct [OF List_def _ ListM]) | |
| 307 | apply (blast intro: canTs elim!: case_rls) | |
| 308 | done | |
| 309 | ||
| 310 | lemmas inds = Nat_ind List_ind | |
| 311 | ||
| 312 | ||
| 313 | subsection {* Primitive Recursive Rules *}
 | |
| 314 | ||
| 315 | lemma nrecT: | |
| 316 | "[| n:Nat; b:C(zero); | |
| 317 | !!x g.[| x:Nat; g:C(x) |] ==> c(x,g):C(succ(x)) |] ==> | |
| 318 | nrec(n,b,c) : C(n)" | |
| 319 | by (erule Nat_ind) auto | |
| 320 | ||
| 321 | lemma lrecT: | |
| 322 | "[| l:List(A); b:C([]); | |
| 323 | !!x xs g.[| x:A; xs:List(A); g:C(xs) |] ==> c(x,xs,g):C(x$xs) |] ==> | |
| 324 | lrec(l,b,c) : C(l)" | |
| 325 | by (erule List_ind) auto | |
| 326 | ||
| 327 | lemmas precTs = nrecT lrecT | |
| 328 | ||
| 329 | ||
| 330 | subsection {* Theorem proving *}
 | |
| 331 | ||
| 332 | lemma SgE2: | |
| 333 | "[| <a,b> : Sigma(A,B); [| a:A; b:B(a) |] ==> P |] ==> P" | |
| 334 | unfolding SgXH by blast | |
| 335 | ||
| 336 | (* General theorem proving ignores non-canonical term-formers, *) | |
| 337 | (* - intro rules are type rules for canonical terms *) | |
| 338 | (* - elim rules are case rules (no non-canonical terms appear) *) | |
| 339 | ||
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 340 | ML {* bind_thms ("XHEs", XH_to_Es @{thms XHs}) *}
 | 
| 20140 | 341 | |
| 342 | lemmas [intro!] = SubtypeI canTs icanTs | |
| 343 | and [elim!] = SubtypeE XHEs | |
| 344 | ||
| 345 | ||
| 346 | subsection {* Infinite Data Types *}
 | |
| 347 | ||
| 348 | lemma lfp_subset_gfp: "mono(f) ==> lfp(f) <= gfp(f)" | |
| 349 | apply (rule lfp_lowerbound [THEN subset_trans]) | |
| 350 | apply (erule gfp_lemma3) | |
| 351 | apply (rule subset_refl) | |
| 352 | done | |
| 353 | ||
| 354 | lemma gfpI: | |
| 355 | assumes "a:A" | |
| 356 | and "!!x X.[| x:A; ALL y:A. t(y):X |] ==> t(x) : B(X)" | |
| 357 | shows "t(a) : gfp(B)" | |
| 358 | apply (rule coinduct) | |
| 359 | apply (rule_tac P = "%x. EX y:A. x=t (y)" in CollectI) | |
| 360 | apply (blast intro!: prems)+ | |
| 361 | done | |
| 362 | ||
| 363 | lemma def_gfpI: | |
| 364 | "[| C==gfp(B); a:A; !!x X.[| x:A; ALL y:A. t(y):X |] ==> t(x) : B(X) |] ==> | |
| 365 | t(a) : C" | |
| 366 | apply unfold | |
| 367 | apply (erule gfpI) | |
| 368 | apply blast | |
| 369 | done | |
| 370 | ||
| 371 | (* EG *) | |
| 372 | lemma "letrec g x be zero$g(x) in g(bot) : Lists(Nat)" | |
| 373 | apply (rule refl [THEN UnitXH [THEN iffD2], THEN Lists_def [THEN def_gfpI]]) | |
| 374 | apply (subst letrecB) | |
| 375 | apply (unfold cons_def) | |
| 376 | apply blast | |
| 377 | done | |
| 378 | ||
| 379 | ||
| 380 | subsection {* Lemmas and tactics for using the rule @{text
 | |
| 381 |   "coinduct3"} on @{text "[="} and @{text "="} *}
 | |
| 382 | ||
| 383 | lemma lfpI: "[| mono(f); a : f(lfp(f)) |] ==> a : lfp(f)" | |
| 384 | apply (erule lfp_Tarski [THEN ssubst]) | |
| 385 | apply assumption | |
| 386 | done | |
| 387 | ||
| 388 | lemma ssubst_single: "[| a=a'; a' : A |] ==> a : A" | |
| 389 | by simp | |
| 390 | ||
| 391 | lemma ssubst_pair: "[| a=a'; b=b'; <a',b'> : A |] ==> <a,b> : A" | |
| 392 | by simp | |
| 393 | ||
| 394 | ||
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 395 | ML {*
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 396 |   val coinduct3_tac = SUBPROOF (fn {context = ctxt, prems = mono :: prems, ...} =>
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 397 | (fast_tac (claset_of ctxt addIs | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 398 |         (mono RS @{thm coinduct3_mono_lemma} RS @{thm lfpI}) :: prems) 1));
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 399 | *} | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 400 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 401 | method_setup coinduct3 = {*
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 402 | Scan.succeed (SIMPLE_METHOD' o coinduct3_tac) | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 403 | *} "" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 404 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 405 | lemma ci3_RI: "[| mono(Agen); a : R |] ==> a : lfp(%x. Agen(x) Un R Un A)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 406 | by coinduct3 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 407 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 408 | lemma ci3_AgenI: "[| mono(Agen); a : Agen(lfp(%x. Agen(x) Un R Un A)) |] ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 409 | a : lfp(%x. Agen(x) Un R Un A)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 410 | by coinduct3 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 411 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 412 | lemma ci3_AI: "[| mono(Agen); a : A |] ==> a : lfp(%x. Agen(x) Un R Un A)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 413 | by coinduct3 | 
| 20140 | 414 | |
| 415 | ML {*
 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 416 | fun genIs_tac ctxt genXH gen_mono = | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 417 | rtac (genXH RS iffD2) THEN' | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 418 | simp_tac (simpset_of ctxt) THEN' | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 419 | TRY o fast_tac (claset_of ctxt addIs | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 420 |         [genXH RS iffD2, gen_mono RS @{thm coinduct3_mono_lemma} RS @{thm lfpI}])
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 421 | *} | 
| 20140 | 422 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 423 | method_setup genIs = {*
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 424 | Attrib.thm -- Attrib.thm >> (fn (genXH, gen_mono) => fn ctxt => | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 425 | SIMPLE_METHOD' (genIs_tac ctxt genXH gen_mono)) | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 426 | *} "" | 
| 20140 | 427 | |
| 428 | ||
| 429 | subsection {* POgen *}
 | |
| 430 | ||
| 431 | lemma PO_refl: "<a,a> : PO" | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 432 | by (rule po_refl [THEN PO_iff [THEN iffD1]]) | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 433 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 434 | lemma POgenIs: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 435 | "<true,true> : POgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 436 | "<false,false> : POgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 437 | "[| <a,a'> : R; <b,b'> : R |] ==> <<a,b>,<a',b'>> : POgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 438 | "!!b b'. [|!!x. <b(x),b'(x)> : R |] ==><lam x. b(x),lam x. b'(x)> : POgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 439 | "<one,one> : POgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 440 | "<a,a'> : lfp(%x. POgen(x) Un R Un PO) ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 441 | <inl(a),inl(a')> : POgen(lfp(%x. POgen(x) Un R Un PO))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 442 | "<b,b'> : lfp(%x. POgen(x) Un R Un PO) ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 443 | <inr(b),inr(b')> : POgen(lfp(%x. POgen(x) Un R Un PO))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 444 | "<zero,zero> : POgen(lfp(%x. POgen(x) Un R Un PO))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 445 | "<n,n'> : lfp(%x. POgen(x) Un R Un PO) ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 446 | <succ(n),succ(n')> : POgen(lfp(%x. POgen(x) Un R Un PO))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 447 | "<[],[]> : POgen(lfp(%x. POgen(x) Un R Un PO))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 448 | "[| <h,h'> : lfp(%x. POgen(x) Un R Un PO); <t,t'> : lfp(%x. POgen(x) Un R Un PO) |] | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 449 | ==> <h$t,h'$t'> : POgen(lfp(%x. POgen(x) Un R Un PO))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 450 | unfolding data_defs by (genIs POgenXH POgen_mono)+ | 
| 20140 | 451 | |
| 452 | ML {*
 | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 453 | fun POgen_tac ctxt (rla, rlb) i = | 
| 32149 
ef59550a55d3
renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
 wenzelm parents: 
32010diff
changeset | 454 | SELECT_GOAL (safe_tac (claset_of ctxt)) i THEN | 
| 32010 | 455 |   rtac (rlb RS (rla RS @{thm ssubst_pair})) i THEN
 | 
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 456 | (REPEAT (resolve_tac | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 457 |       (@{thms POgenIs} @ [@{thm PO_refl} RS (@{thm POgen_mono} RS @{thm ci3_AI})] @
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 458 |         (@{thms POgenIs} RL [@{thm POgen_mono} RS @{thm ci3_AgenI}]) @
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 459 |         [@{thm POgen_mono} RS @{thm ci3_RI}]) i))
 | 
| 20140 | 460 | *} | 
| 461 | ||
| 462 | ||
| 463 | subsection {* EQgen *}
 | |
| 464 | ||
| 465 | lemma EQ_refl: "<a,a> : EQ" | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 466 | by (rule refl [THEN EQ_iff [THEN iffD1]]) | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 467 | |
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 468 | lemma EQgenIs: | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 469 | "<true,true> : EQgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 470 | "<false,false> : EQgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 471 | "[| <a,a'> : R; <b,b'> : R |] ==> <<a,b>,<a',b'>> : EQgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 472 | "!!b b'. [|!!x. <b(x),b'(x)> : R |] ==> <lam x. b(x),lam x. b'(x)> : EQgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 473 | "<one,one> : EQgen(R)" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 474 | "<a,a'> : lfp(%x. EQgen(x) Un R Un EQ) ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 475 | <inl(a),inl(a')> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 476 | "<b,b'> : lfp(%x. EQgen(x) Un R Un EQ) ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 477 | <inr(b),inr(b')> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 478 | "<zero,zero> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 479 | "<n,n'> : lfp(%x. EQgen(x) Un R Un EQ) ==> | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 480 | <succ(n),succ(n')> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 481 | "<[],[]> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 482 | "[| <h,h'> : lfp(%x. EQgen(x) Un R Un EQ); <t,t'> : lfp(%x. EQgen(x) Un R Un EQ) |] | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 483 | ==> <h$t,h'$t'> : EQgen(lfp(%x. EQgen(x) Un R Un EQ))" | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 484 | unfolding data_defs by (genIs EQgenXH EQgen_mono)+ | 
| 20140 | 485 | |
| 486 | ML {*
 | |
| 487 | fun EQgen_raw_tac i = | |
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 488 |   (REPEAT (resolve_tac (@{thms EQgenIs} @
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 489 |         [@{thm EQ_refl} RS (@{thm EQgen_mono} RS @{thm ci3_AI})] @
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 490 |         (@{thms EQgenIs} RL [@{thm EQgen_mono} RS @{thm ci3_AgenI}]) @
 | 
| 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 491 |         [@{thm EQgen_mono} RS @{thm ci3_RI}]) i))
 | 
| 20140 | 492 | |
| 493 | (* Goals of the form R <= EQgen(R) - rewrite elements <a,b> : EQgen(R) using rews and *) | |
| 494 | (* then reduce this to a goal <a',b'> : R (hopefully?) *) | |
| 495 | (* rews are rewrite rules that would cause looping in the simpifier *) | |
| 496 | ||
| 23894 
1a4167d761ac
tactics: avoid dynamic reference to accidental theory context (via ML_Context.the_context etc.);
 wenzelm parents: 
20140diff
changeset | 497 | fun EQgen_tac ctxt rews i = | 
| 20140 | 498 | SELECT_GOAL | 
| 32149 
ef59550a55d3
renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
 wenzelm parents: 
32010diff
changeset | 499 | (TRY (safe_tac (claset_of ctxt)) THEN | 
| 32153 
a0e57fb1b930
misc modernization: proper method setup instead of adhoc ML proofs;
 wenzelm parents: 
32149diff
changeset | 500 |     resolve_tac ((rews @ [refl]) RL ((rews @ [refl]) RL [@{thm ssubst_pair}])) i THEN
 | 
| 32149 
ef59550a55d3
renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
 wenzelm parents: 
32010diff
changeset | 501 | ALLGOALS (simp_tac (simpset_of ctxt)) THEN | 
| 20140 | 502 | ALLGOALS EQgen_raw_tac) i | 
| 503 | *} | |
| 0 | 504 | |
| 505 | end |