src/CCL/Type.thy
changeset 60770 240563fbf41d
parent 60754 02924903a6fd
child 62020 5d208fd2507d
equal deleted inserted replaced
60769:cf7f3465eaf1 60770:240563fbf41d
     1 (*  Title:      CCL/Type.thy
     1 (*  Title:      CCL/Type.thy
     2     Author:     Martin Coen
     2     Author:     Martin Coen
     3     Copyright   1993  University of Cambridge
     3     Copyright   1993  University of Cambridge
     4 *)
     4 *)
     5 
     5 
     6 section {* Types in CCL are defined as sets of terms *}
     6 section \<open>Types in CCL are defined as sets of terms\<close>
     7 
     7 
     8 theory Type
     8 theory Type
     9 imports Term
     9 imports Term
    10 begin
    10 begin
    11 
    11 
    43   "A -> B"      => "CONST Pi(A, \<lambda>_. B)"
    43   "A -> B"      => "CONST Pi(A, \<lambda>_. B)"
    44   "SUM x:A. B"  => "CONST Sigma(A, \<lambda>x. B)"
    44   "SUM x:A. B"  => "CONST Sigma(A, \<lambda>x. B)"
    45   "A * B"       => "CONST Sigma(A, \<lambda>_. B)"
    45   "A * B"       => "CONST Sigma(A, \<lambda>_. B)"
    46   "{x: A. B}"   == "CONST Subtype(A, \<lambda>x. B)"
    46   "{x: A. B}"   == "CONST Subtype(A, \<lambda>x. B)"
    47 
    47 
    48 print_translation {*
    48 print_translation \<open>
    49  [(@{const_syntax Pi},
    49  [(@{const_syntax Pi},
    50     fn _ => Syntax_Trans.dependent_tr' (@{syntax_const "_Pi"}, @{syntax_const "_arrow"})),
    50     fn _ => Syntax_Trans.dependent_tr' (@{syntax_const "_Pi"}, @{syntax_const "_arrow"})),
    51   (@{const_syntax Sigma},
    51   (@{const_syntax Sigma},
    52     fn _ => Syntax_Trans.dependent_tr' (@{syntax_const "_Sigma"}, @{syntax_const "_star"}))]
    52     fn _ => Syntax_Trans.dependent_tr' (@{syntax_const "_Sigma"}, @{syntax_const "_star"}))]
    53 *}
    53 \<close>
    54 
    54 
    55 defs
    55 defs
    56   Subtype_def: "{x:A. P(x)} == {x. x:A \<and> P(x)}"
    56   Subtype_def: "{x:A. P(x)} == {x. x:A \<and> P(x)}"
    57   Unit_def:          "Unit == {x. x=one}"
    57   Unit_def:          "Unit == {x. x=one}"
    58   Bool_def:          "Bool == {x. x=true | x=false}"
    58   Bool_def:          "Bool == {x. x=true | x=false}"
    80 
    80 
    81 lemma subsetXH: "A <= B \<longleftrightarrow> (ALL x. x:A \<longrightarrow> x:B)"
    81 lemma subsetXH: "A <= B \<longleftrightarrow> (ALL x. x:A \<longrightarrow> x:B)"
    82   by blast
    82   by blast
    83 
    83 
    84 
    84 
    85 subsection {* Exhaustion Rules *}
    85 subsection \<open>Exhaustion Rules\<close>
    86 
    86 
    87 lemma EmptyXH: "\<And>a. a : {} \<longleftrightarrow> False"
    87 lemma EmptyXH: "\<And>a. a : {} \<longleftrightarrow> False"
    88   and SubtypeXH: "\<And>a A P. a : {x:A. P(x)} \<longleftrightarrow> (a:A \<and> P(a))"
    88   and SubtypeXH: "\<And>a A P. a : {x:A. P(x)} \<longleftrightarrow> (a:A \<and> P(a))"
    89   and UnitXH: "\<And>a. a : Unit          \<longleftrightarrow> a=one"
    89   and UnitXH: "\<And>a. a : Unit          \<longleftrightarrow> a=one"
    90   and BoolXH: "\<And>a. a : Bool          \<longleftrightarrow> a=true | a=false"
    90   and BoolXH: "\<And>a. a : Bool          \<longleftrightarrow> a=true | a=false"
    98 lemma LiftXH: "a : [A] \<longleftrightarrow> (a=bot | a:A)"
    98 lemma LiftXH: "a : [A] \<longleftrightarrow> (a=bot | a:A)"
    99   and TallXH: "a : TALL X. B(X) \<longleftrightarrow> (ALL X. a:B(X))"
    99   and TallXH: "a : TALL X. B(X) \<longleftrightarrow> (ALL X. a:B(X))"
   100   and TexXH: "a : TEX X. B(X) \<longleftrightarrow> (EX X. a:B(X))"
   100   and TexXH: "a : TEX X. B(X) \<longleftrightarrow> (EX X. a:B(X))"
   101   unfolding simp_type_defs by blast+
   101   unfolding simp_type_defs by blast+
   102 
   102 
   103 ML {* ML_Thms.bind_thms ("case_rls", XH_to_Es @{thms XHs}) *}
   103 ML \<open>ML_Thms.bind_thms ("case_rls", XH_to_Es @{thms XHs})\<close>
   104 
   104 
   105 
   105 
   106 subsection {* Canonical Type Rules *}
   106 subsection \<open>Canonical Type Rules\<close>
   107 
   107 
   108 lemma oneT: "one : Unit"
   108 lemma oneT: "one : Unit"
   109   and trueT: "true : Bool"
   109   and trueT: "true : Bool"
   110   and falseT: "false : Bool"
   110   and falseT: "false : Bool"
   111   and lamT: "\<And>b B. (\<And>x. x:A \<Longrightarrow> b(x):B(x)) \<Longrightarrow> lam x. b(x) : Pi(A,B)"
   111   and lamT: "\<And>b B. (\<And>x. x:A \<Longrightarrow> b(x):B(x)) \<Longrightarrow> lam x. b(x) : Pi(A,B)"
   115   by (blast intro: XHs [THEN iffD2])+
   115   by (blast intro: XHs [THEN iffD2])+
   116 
   116 
   117 lemmas canTs = oneT trueT falseT pairT lamT inlT inrT
   117 lemmas canTs = oneT trueT falseT pairT lamT inlT inrT
   118 
   118 
   119 
   119 
   120 subsection {* Non-Canonical Type Rules *}
   120 subsection \<open>Non-Canonical Type Rules\<close>
   121 
   121 
   122 lemma lem: "\<lbrakk>a:B(u); u = v\<rbrakk> \<Longrightarrow> a : B(v)"
   122 lemma lem: "\<lbrakk>a:B(u); u = v\<rbrakk> \<Longrightarrow> a : B(v)"
   123   by blast
   123   by blast
   124 
   124 
   125 
   125 
   126 ML {*
   126 ML \<open>
   127 fun mk_ncanT_tac top_crls crls =
   127 fun mk_ncanT_tac top_crls crls =
   128   SUBPROOF (fn {context = ctxt, prems = major :: prems, ...} =>
   128   SUBPROOF (fn {context = ctxt, prems = major :: prems, ...} =>
   129     resolve_tac ctxt ([major] RL top_crls) 1 THEN
   129     resolve_tac ctxt ([major] RL top_crls) 1 THEN
   130     REPEAT_SOME (eresolve_tac ctxt (crls @ @{thms exE bexE conjE disjE})) THEN
   130     REPEAT_SOME (eresolve_tac ctxt (crls @ @{thms exE bexE conjE disjE})) THEN
   131     ALLGOALS (asm_simp_tac ctxt) THEN
   131     ALLGOALS (asm_simp_tac ctxt) THEN
   132     ALLGOALS (assume_tac ctxt ORELSE' resolve_tac ctxt (prems RL [@{thm lem}])
   132     ALLGOALS (assume_tac ctxt ORELSE' resolve_tac ctxt (prems RL [@{thm lem}])
   133       ORELSE' eresolve_tac ctxt @{thms bspec}) THEN
   133       ORELSE' eresolve_tac ctxt @{thms bspec}) THEN
   134     safe_tac (ctxt addSIs prems))
   134     safe_tac (ctxt addSIs prems))
   135 *}
   135 \<close>
   136 
   136 
   137 method_setup ncanT = {*
   137 method_setup ncanT = \<open>
   138   Scan.succeed (SIMPLE_METHOD' o mk_ncanT_tac @{thms case_rls} @{thms case_rls})
   138   Scan.succeed (SIMPLE_METHOD' o mk_ncanT_tac @{thms case_rls} @{thms case_rls})
   139 *}
   139 \<close>
   140 
   140 
   141 lemma ifT: "\<lbrakk>b:Bool; b=true \<Longrightarrow> t:A(true); b=false \<Longrightarrow> u:A(false)\<rbrakk> \<Longrightarrow> if b then t else u : A(b)"
   141 lemma ifT: "\<lbrakk>b:Bool; b=true \<Longrightarrow> t:A(true); b=false \<Longrightarrow> u:A(false)\<rbrakk> \<Longrightarrow> if b then t else u : A(b)"
   142   by ncanT
   142   by ncanT
   143 
   143 
   144 lemma applyT: "\<lbrakk>f : Pi(A,B); a:A\<rbrakk> \<Longrightarrow> f ` a : B(a)"
   144 lemma applyT: "\<lbrakk>f : Pi(A,B); a:A\<rbrakk> \<Longrightarrow> f ` a : B(a)"
   154   by ncanT
   154   by ncanT
   155 
   155 
   156 lemmas ncanTs = ifT applyT splitT whenT
   156 lemmas ncanTs = ifT applyT splitT whenT
   157 
   157 
   158 
   158 
   159 subsection {* Subtypes *}
   159 subsection \<open>Subtypes\<close>
   160 
   160 
   161 lemma SubtypeD1: "a : Subtype(A, P) \<Longrightarrow> a : A"
   161 lemma SubtypeD1: "a : Subtype(A, P) \<Longrightarrow> a : A"
   162   and SubtypeD2: "a : Subtype(A, P) \<Longrightarrow> P(a)"
   162   and SubtypeD2: "a : Subtype(A, P) \<Longrightarrow> P(a)"
   163   by (simp_all add: SubtypeXH)
   163   by (simp_all add: SubtypeXH)
   164 
   164 
   167 
   167 
   168 lemma SubtypeE: "\<lbrakk>a : {x:A. P(x)}; \<lbrakk>a:A; P(a)\<rbrakk> \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q"
   168 lemma SubtypeE: "\<lbrakk>a : {x:A. P(x)}; \<lbrakk>a:A; P(a)\<rbrakk> \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q"
   169   by (simp add: SubtypeXH)
   169   by (simp add: SubtypeXH)
   170 
   170 
   171 
   171 
   172 subsection {* Monotonicity *}
   172 subsection \<open>Monotonicity\<close>
   173 
   173 
   174 lemma idM: "mono (\<lambda>X. X)"
   174 lemma idM: "mono (\<lambda>X. X)"
   175   apply (rule monoI)
   175   apply (rule monoI)
   176   apply assumption
   176   apply assumption
   177   done
   177   done
   204 lemma PlusM: "\<lbrakk>mono(\<lambda>X. A(X)); mono(\<lambda>X. B(X))\<rbrakk> \<Longrightarrow> mono(\<lambda>X. A(X)+B(X))"
   204 lemma PlusM: "\<lbrakk>mono(\<lambda>X. A(X)); mono(\<lambda>X. B(X))\<rbrakk> \<Longrightarrow> mono(\<lambda>X. A(X)+B(X))"
   205   by (blast intro!: subsetI [THEN monoI] canTs elim!: case_rls
   205   by (blast intro!: subsetI [THEN monoI] canTs elim!: case_rls
   206     dest!: monoD [THEN subsetD])
   206     dest!: monoD [THEN subsetD])
   207 
   207 
   208 
   208 
   209 subsection {* Recursive types *}
   209 subsection \<open>Recursive types\<close>
   210 
   210 
   211 subsubsection {* Conversion Rules for Fixed Points via monotonicity and Tarski *}
   211 subsubsection \<open>Conversion Rules for Fixed Points via monotonicity and Tarski\<close>
   212 
   212 
   213 lemma NatM: "mono(\<lambda>X. Unit+X)"
   213 lemma NatM: "mono(\<lambda>X. Unit+X)"
   214   apply (rule PlusM constM idM)+
   214   apply (rule PlusM constM idM)+
   215   done
   215   done
   216 
   216 
   243   done
   243   done
   244 
   244 
   245 lemmas ind_type_eqs = def_NatB def_ListB def_ListsB def_IListsB
   245 lemmas ind_type_eqs = def_NatB def_ListB def_ListsB def_IListsB
   246 
   246 
   247 
   247 
   248 subsection {* Exhaustion Rules *}
   248 subsection \<open>Exhaustion Rules\<close>
   249 
   249 
   250 lemma NatXH: "a : Nat \<longleftrightarrow> (a=zero | (EX x:Nat. a=succ(x)))"
   250 lemma NatXH: "a : Nat \<longleftrightarrow> (a=zero | (EX x:Nat. a=succ(x)))"
   251   and ListXH: "a : List(A) \<longleftrightarrow> (a=[] | (EX x:A. EX xs:List(A).a=x$xs))"
   251   and ListXH: "a : List(A) \<longleftrightarrow> (a=[] | (EX x:A. EX xs:List(A).a=x$xs))"
   252   and ListsXH: "a : Lists(A) \<longleftrightarrow> (a=[] | (EX x:A. EX xs:Lists(A).a=x$xs))"
   252   and ListsXH: "a : Lists(A) \<longleftrightarrow> (a=[] | (EX x:A. EX xs:Lists(A).a=x$xs))"
   253   and IListsXH: "a : ILists(A) \<longleftrightarrow> (EX x:A. EX xs:ILists(A).a=x$xs)"
   253   and IListsXH: "a : ILists(A) \<longleftrightarrow> (EX x:A. EX xs:ILists(A).a=x$xs)"
   254   unfolding ind_data_defs
   254   unfolding ind_data_defs
   255   by (rule ind_type_eqs [THEN XHlemma1], blast intro!: canTs elim!: case_rls)+
   255   by (rule ind_type_eqs [THEN XHlemma1], blast intro!: canTs elim!: case_rls)+
   256 
   256 
   257 lemmas iXHs = NatXH ListXH
   257 lemmas iXHs = NatXH ListXH
   258 
   258 
   259 ML {* ML_Thms.bind_thms ("icase_rls", XH_to_Es @{thms iXHs}) *}
   259 ML \<open>ML_Thms.bind_thms ("icase_rls", XH_to_Es @{thms iXHs})\<close>
   260 
   260 
   261 
   261 
   262 subsection {* Type Rules *}
   262 subsection \<open>Type Rules\<close>
   263 
   263 
   264 lemma zeroT: "zero : Nat"
   264 lemma zeroT: "zero : Nat"
   265   and succT: "n:Nat \<Longrightarrow> succ(n) : Nat"
   265   and succT: "n:Nat \<Longrightarrow> succ(n) : Nat"
   266   and nilT: "[] : List(A)"
   266   and nilT: "[] : List(A)"
   267   and consT: "\<lbrakk>h:A; t:List(A)\<rbrakk> \<Longrightarrow> h$t : List(A)"
   267   and consT: "\<lbrakk>h:A; t:List(A)\<rbrakk> \<Longrightarrow> h$t : List(A)"
   268   by (blast intro: iXHs [THEN iffD2])+
   268   by (blast intro: iXHs [THEN iffD2])+
   269 
   269 
   270 lemmas icanTs = zeroT succT nilT consT
   270 lemmas icanTs = zeroT succT nilT consT
   271 
   271 
   272 
   272 
   273 method_setup incanT = {*
   273 method_setup incanT = \<open>
   274   Scan.succeed (SIMPLE_METHOD' o mk_ncanT_tac @{thms icase_rls} @{thms case_rls})
   274   Scan.succeed (SIMPLE_METHOD' o mk_ncanT_tac @{thms icase_rls} @{thms case_rls})
   275 *}
   275 \<close>
   276 
   276 
   277 lemma ncaseT: "\<lbrakk>n:Nat; n=zero \<Longrightarrow> b:C(zero); \<And>x. \<lbrakk>x:Nat; n=succ(x)\<rbrakk> \<Longrightarrow> c(x):C(succ(x))\<rbrakk>
   277 lemma ncaseT: "\<lbrakk>n:Nat; n=zero \<Longrightarrow> b:C(zero); \<And>x. \<lbrakk>x:Nat; n=succ(x)\<rbrakk> \<Longrightarrow> c(x):C(succ(x))\<rbrakk>
   278     \<Longrightarrow> ncase(n,b,c) : C(n)"
   278     \<Longrightarrow> ncase(n,b,c) : C(n)"
   279   by incanT
   279   by incanT
   280 
   280 
   283   by incanT
   283   by incanT
   284 
   284 
   285 lemmas incanTs = ncaseT lcaseT
   285 lemmas incanTs = ncaseT lcaseT
   286 
   286 
   287 
   287 
   288 subsection {* Induction Rules *}
   288 subsection \<open>Induction Rules\<close>
   289 
   289 
   290 lemmas ind_Ms = NatM ListM
   290 lemmas ind_Ms = NatM ListM
   291 
   291 
   292 lemma Nat_ind: "\<lbrakk>n:Nat; P(zero); \<And>x. \<lbrakk>x:Nat; P(x)\<rbrakk> \<Longrightarrow> P(succ(x))\<rbrakk> \<Longrightarrow> P(n)"
   292 lemma Nat_ind: "\<lbrakk>n:Nat; P(zero); \<And>x. \<lbrakk>x:Nat; P(x)\<rbrakk> \<Longrightarrow> P(succ(x))\<rbrakk> \<Longrightarrow> P(n)"
   293   apply (unfold ind_data_defs)
   293   apply (unfold ind_data_defs)
   302   done
   302   done
   303 
   303 
   304 lemmas inds = Nat_ind List_ind
   304 lemmas inds = Nat_ind List_ind
   305 
   305 
   306 
   306 
   307 subsection {* Primitive Recursive Rules *}
   307 subsection \<open>Primitive Recursive Rules\<close>
   308 
   308 
   309 lemma nrecT: "\<lbrakk>n:Nat; b:C(zero); \<And>x g. \<lbrakk>x:Nat; g:C(x)\<rbrakk> \<Longrightarrow> c(x,g):C(succ(x))\<rbrakk>
   309 lemma nrecT: "\<lbrakk>n:Nat; b:C(zero); \<And>x g. \<lbrakk>x:Nat; g:C(x)\<rbrakk> \<Longrightarrow> c(x,g):C(succ(x))\<rbrakk>
   310     \<Longrightarrow> nrec(n,b,c) : C(n)"
   310     \<Longrightarrow> nrec(n,b,c) : C(n)"
   311   by (erule Nat_ind) auto
   311   by (erule Nat_ind) auto
   312 
   312 
   315   by (erule List_ind) auto
   315   by (erule List_ind) auto
   316 
   316 
   317 lemmas precTs = nrecT lrecT
   317 lemmas precTs = nrecT lrecT
   318 
   318 
   319 
   319 
   320 subsection {* Theorem proving *}
   320 subsection \<open>Theorem proving\<close>
   321 
   321 
   322 lemma SgE2: "\<lbrakk><a,b> : Sigma(A,B); \<lbrakk>a:A; b:B(a)\<rbrakk> \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
   322 lemma SgE2: "\<lbrakk><a,b> : Sigma(A,B); \<lbrakk>a:A; b:B(a)\<rbrakk> \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
   323   unfolding SgXH by blast
   323   unfolding SgXH by blast
   324 
   324 
   325 (* General theorem proving ignores non-canonical term-formers,             *)
   325 (* General theorem proving ignores non-canonical term-formers,             *)
   326 (*         - intro rules are type rules for canonical terms                *)
   326 (*         - intro rules are type rules for canonical terms                *)
   327 (*         - elim rules are case rules (no non-canonical terms appear)     *)
   327 (*         - elim rules are case rules (no non-canonical terms appear)     *)
   328 
   328 
   329 ML {* ML_Thms.bind_thms ("XHEs", XH_to_Es @{thms XHs}) *}
   329 ML \<open>ML_Thms.bind_thms ("XHEs", XH_to_Es @{thms XHs})\<close>
   330 
   330 
   331 lemmas [intro!] = SubtypeI canTs icanTs
   331 lemmas [intro!] = SubtypeI canTs icanTs
   332   and [elim!] = SubtypeE XHEs
   332   and [elim!] = SubtypeE XHEs
   333 
   333 
   334 
   334 
   335 subsection {* Infinite Data Types *}
   335 subsection \<open>Infinite Data Types\<close>
   336 
   336 
   337 lemma lfp_subset_gfp: "mono(f) \<Longrightarrow> lfp(f) <= gfp(f)"
   337 lemma lfp_subset_gfp: "mono(f) \<Longrightarrow> lfp(f) <= gfp(f)"
   338   apply (rule lfp_lowerbound [THEN subset_trans])
   338   apply (rule lfp_lowerbound [THEN subset_trans])
   339    apply (erule gfp_lemma3)
   339    apply (erule gfp_lemma3)
   340   apply (rule subset_refl)
   340   apply (rule subset_refl)
   362   apply (unfold cons_def)
   362   apply (unfold cons_def)
   363   apply blast
   363   apply blast
   364   done
   364   done
   365 
   365 
   366 
   366 
   367 subsection {* Lemmas and tactics for using the rule @{text
   367 subsection \<open>Lemmas and tactics for using the rule @{text
   368   "coinduct3"} on @{text "[="} and @{text "="} *}
   368   "coinduct3"} on @{text "[="} and @{text "="}\<close>
   369 
   369 
   370 lemma lfpI: "\<lbrakk>mono(f); a : f(lfp(f))\<rbrakk> \<Longrightarrow> a : lfp(f)"
   370 lemma lfpI: "\<lbrakk>mono(f); a : f(lfp(f))\<rbrakk> \<Longrightarrow> a : lfp(f)"
   371   apply (erule lfp_Tarski [THEN ssubst])
   371   apply (erule lfp_Tarski [THEN ssubst])
   372   apply assumption
   372   apply assumption
   373   done
   373   done
   377 
   377 
   378 lemma ssubst_pair: "\<lbrakk>a = a'; b = b'; <a',b'> : A\<rbrakk> \<Longrightarrow> <a,b> : A"
   378 lemma ssubst_pair: "\<lbrakk>a = a'; b = b'; <a',b'> : A\<rbrakk> \<Longrightarrow> <a,b> : A"
   379   by simp
   379   by simp
   380 
   380 
   381 
   381 
   382 ML {*
   382 ML \<open>
   383   val coinduct3_tac = SUBPROOF (fn {context = ctxt, prems = mono :: prems, ...} =>
   383   val coinduct3_tac = SUBPROOF (fn {context = ctxt, prems = mono :: prems, ...} =>
   384     fast_tac (ctxt addIs (mono RS @{thm coinduct3_mono_lemma} RS @{thm lfpI}) :: prems) 1);
   384     fast_tac (ctxt addIs (mono RS @{thm coinduct3_mono_lemma} RS @{thm lfpI}) :: prems) 1);
   385 *}
   385 \<close>
   386 
   386 
   387 method_setup coinduct3 = {* Scan.succeed (SIMPLE_METHOD' o coinduct3_tac) *}
   387 method_setup coinduct3 = \<open>Scan.succeed (SIMPLE_METHOD' o coinduct3_tac)\<close>
   388 
   388 
   389 lemma ci3_RI: "\<lbrakk>mono(Agen); a : R\<rbrakk> \<Longrightarrow> a : lfp(\<lambda>x. Agen(x) Un R Un A)"
   389 lemma ci3_RI: "\<lbrakk>mono(Agen); a : R\<rbrakk> \<Longrightarrow> a : lfp(\<lambda>x. Agen(x) Un R Un A)"
   390   by coinduct3
   390   by coinduct3
   391 
   391 
   392 lemma ci3_AgenI: "\<lbrakk>mono(Agen); a : Agen(lfp(\<lambda>x. Agen(x) Un R Un A))\<rbrakk> \<Longrightarrow>
   392 lemma ci3_AgenI: "\<lbrakk>mono(Agen); a : Agen(lfp(\<lambda>x. Agen(x) Un R Un A))\<rbrakk> \<Longrightarrow>
   394   by coinduct3
   394   by coinduct3
   395 
   395 
   396 lemma ci3_AI: "\<lbrakk>mono(Agen); a : A\<rbrakk> \<Longrightarrow> a : lfp(\<lambda>x. Agen(x) Un R Un A)"
   396 lemma ci3_AI: "\<lbrakk>mono(Agen); a : A\<rbrakk> \<Longrightarrow> a : lfp(\<lambda>x. Agen(x) Un R Un A)"
   397   by coinduct3
   397   by coinduct3
   398 
   398 
   399 ML {*
   399 ML \<open>
   400 fun genIs_tac ctxt genXH gen_mono =
   400 fun genIs_tac ctxt genXH gen_mono =
   401   resolve_tac ctxt [genXH RS @{thm iffD2}] THEN'
   401   resolve_tac ctxt [genXH RS @{thm iffD2}] THEN'
   402   simp_tac ctxt THEN'
   402   simp_tac ctxt THEN'
   403   TRY o fast_tac
   403   TRY o fast_tac
   404     (ctxt addIs [genXH RS @{thm iffD2}, gen_mono RS @{thm coinduct3_mono_lemma} RS @{thm lfpI}])
   404     (ctxt addIs [genXH RS @{thm iffD2}, gen_mono RS @{thm coinduct3_mono_lemma} RS @{thm lfpI}])
   405 *}
   405 \<close>
   406 
   406 
   407 method_setup genIs = {*
   407 method_setup genIs = \<open>
   408   Attrib.thm -- Attrib.thm >>
   408   Attrib.thm -- Attrib.thm >>
   409     (fn (genXH, gen_mono) => fn ctxt => SIMPLE_METHOD' (genIs_tac ctxt genXH gen_mono))
   409     (fn (genXH, gen_mono) => fn ctxt => SIMPLE_METHOD' (genIs_tac ctxt genXH gen_mono))
   410 *}
   410 \<close>
   411 
   411 
   412 
   412 
   413 subsection {* POgen *}
   413 subsection \<open>POgen\<close>
   414 
   414 
   415 lemma PO_refl: "<a,a> : PO"
   415 lemma PO_refl: "<a,a> : PO"
   416   by (rule po_refl [THEN PO_iff [THEN iffD1]])
   416   by (rule po_refl [THEN PO_iff [THEN iffD1]])
   417 
   417 
   418 lemma POgenIs:
   418 lemma POgenIs:
   431   "<[],[]> : POgen(lfp(\<lambda>x. POgen(x) Un R Un PO))"
   431   "<[],[]> : POgen(lfp(\<lambda>x. POgen(x) Un R Un PO))"
   432   "\<lbrakk><h,h'> : lfp(\<lambda>x. POgen(x) Un R Un PO);  <t,t'> : lfp(\<lambda>x. POgen(x) Un R Un PO)\<rbrakk>
   432   "\<lbrakk><h,h'> : lfp(\<lambda>x. POgen(x) Un R Un PO);  <t,t'> : lfp(\<lambda>x. POgen(x) Un R Un PO)\<rbrakk>
   433     \<Longrightarrow> <h$t,h'$t'> : POgen(lfp(\<lambda>x. POgen(x) Un R Un PO))"
   433     \<Longrightarrow> <h$t,h'$t'> : POgen(lfp(\<lambda>x. POgen(x) Un R Un PO))"
   434   unfolding data_defs by (genIs POgenXH POgen_mono)+
   434   unfolding data_defs by (genIs POgenXH POgen_mono)+
   435 
   435 
   436 ML {*
   436 ML \<open>
   437 fun POgen_tac ctxt (rla, rlb) i =
   437 fun POgen_tac ctxt (rla, rlb) i =
   438   SELECT_GOAL (safe_tac ctxt) i THEN
   438   SELECT_GOAL (safe_tac ctxt) i THEN
   439   resolve_tac ctxt [rlb RS (rla RS @{thm ssubst_pair})] i THEN
   439   resolve_tac ctxt [rlb RS (rla RS @{thm ssubst_pair})] i THEN
   440   (REPEAT (resolve_tac ctxt
   440   (REPEAT (resolve_tac ctxt
   441       (@{thms POgenIs} @ [@{thm PO_refl} RS (@{thm POgen_mono} RS @{thm ci3_AI})] @
   441       (@{thms POgenIs} @ [@{thm PO_refl} RS (@{thm POgen_mono} RS @{thm ci3_AI})] @
   442         (@{thms POgenIs} RL [@{thm POgen_mono} RS @{thm ci3_AgenI}]) @
   442         (@{thms POgenIs} RL [@{thm POgen_mono} RS @{thm ci3_AgenI}]) @
   443         [@{thm POgen_mono} RS @{thm ci3_RI}]) i))
   443         [@{thm POgen_mono} RS @{thm ci3_RI}]) i))
   444 *}
   444 \<close>
   445 
   445 
   446 
   446 
   447 subsection {* EQgen *}
   447 subsection \<open>EQgen\<close>
   448 
   448 
   449 lemma EQ_refl: "<a,a> : EQ"
   449 lemma EQ_refl: "<a,a> : EQ"
   450   by (rule refl [THEN EQ_iff [THEN iffD1]])
   450   by (rule refl [THEN EQ_iff [THEN iffD1]])
   451 
   451 
   452 lemma EQgenIs:
   452 lemma EQgenIs:
   465   "<[],[]> : EQgen(lfp(\<lambda>x. EQgen(x) Un R Un EQ))"
   465   "<[],[]> : EQgen(lfp(\<lambda>x. EQgen(x) Un R Un EQ))"
   466   "\<lbrakk><h,h'> : lfp(\<lambda>x. EQgen(x) Un R Un EQ); <t,t'> : lfp(\<lambda>x. EQgen(x) Un R Un EQ)\<rbrakk>
   466   "\<lbrakk><h,h'> : lfp(\<lambda>x. EQgen(x) Un R Un EQ); <t,t'> : lfp(\<lambda>x. EQgen(x) Un R Un EQ)\<rbrakk>
   467     \<Longrightarrow> <h$t,h'$t'> : EQgen(lfp(\<lambda>x. EQgen(x) Un R Un EQ))"
   467     \<Longrightarrow> <h$t,h'$t'> : EQgen(lfp(\<lambda>x. EQgen(x) Un R Un EQ))"
   468   unfolding data_defs by (genIs EQgenXH EQgen_mono)+
   468   unfolding data_defs by (genIs EQgenXH EQgen_mono)+
   469 
   469 
   470 ML {*
   470 ML \<open>
   471 fun EQgen_raw_tac ctxt i =
   471 fun EQgen_raw_tac ctxt i =
   472   (REPEAT (resolve_tac ctxt (@{thms EQgenIs} @
   472   (REPEAT (resolve_tac ctxt (@{thms EQgenIs} @
   473         [@{thm EQ_refl} RS (@{thm EQgen_mono} RS @{thm ci3_AI})] @
   473         [@{thm EQ_refl} RS (@{thm EQgen_mono} RS @{thm ci3_AI})] @
   474         (@{thms EQgenIs} RL [@{thm EQgen_mono} RS @{thm ci3_AgenI}]) @
   474         (@{thms EQgenIs} RL [@{thm EQgen_mono} RS @{thm ci3_AgenI}]) @
   475         [@{thm EQgen_mono} RS @{thm ci3_RI}]) i))
   475         [@{thm EQgen_mono} RS @{thm ci3_RI}]) i))
   482  SELECT_GOAL
   482  SELECT_GOAL
   483    (TRY (safe_tac ctxt) THEN
   483    (TRY (safe_tac ctxt) THEN
   484     resolve_tac ctxt ((rews @ [@{thm refl}]) RL ((rews @ [@{thm refl}]) RL [@{thm ssubst_pair}])) i THEN
   484     resolve_tac ctxt ((rews @ [@{thm refl}]) RL ((rews @ [@{thm refl}]) RL [@{thm ssubst_pair}])) i THEN
   485     ALLGOALS (simp_tac ctxt) THEN
   485     ALLGOALS (simp_tac ctxt) THEN
   486     ALLGOALS (EQgen_raw_tac ctxt)) i
   486     ALLGOALS (EQgen_raw_tac ctxt)) i
   487 *}
   487 \<close>
   488 
   488 
   489 method_setup EQgen = {*
   489 method_setup EQgen = \<open>
   490   Attrib.thms >> (fn ths => fn ctxt => SIMPLE_METHOD' (EQgen_tac ctxt ths))
   490   Attrib.thms >> (fn ths => fn ctxt => SIMPLE_METHOD' (EQgen_tac ctxt ths))
   491 *}
   491 \<close>
   492 
   492 
   493 end
   493 end