| author | wenzelm | 
| Mon, 16 Nov 2020 23:49:20 +0100 | |
| changeset 72628 | 5e616a454b23 | 
| parent 69597 | ff784d5a5bfb | 
| child 74305 | 28a582aa25dd | 
| permissions | -rw-r--r-- | 
| 42151 | 1 | (* Title: HOL/HOLCF/Tools/Domain/domain_induction.ML | 
| 23152 | 2 | Author: David von Oheimb | 
| 32740 | 3 | Author: Brian Huffman | 
| 23152 | 4 | |
| 40040 
3adb92ee2f22
rename domain_theorems.ML to domain_induction.ML; rename domain_extender.ML to domain.ML
 huffman parents: 
40029diff
changeset | 5 | Proofs of high-level (co)induction rules for domain command. | 
| 23152 | 6 | *) | 
| 7 | ||
| 40040 
3adb92ee2f22
rename domain_theorems.ML to domain_induction.ML; rename domain_extender.ML to domain.ML
 huffman parents: 
40029diff
changeset | 8 | signature DOMAIN_INDUCTION = | 
| 31005 | 9 | sig | 
| 35657 
0537c34c6067
pass take_induct_info as an argument to comp_theorems
 huffman parents: 
35654diff
changeset | 10 | val comp_theorems : | 
| 40097 
429cd74f795f
remove legacy comp_dbind option from domain package
 huffman parents: 
40040diff
changeset | 11 | binding list -> | 
| 35657 
0537c34c6067
pass take_induct_info as an argument to comp_theorems
 huffman parents: 
35654diff
changeset | 12 | Domain_Take_Proofs.take_induct_info -> | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 13 | Domain_Constructors.constr_info list -> | 
| 35657 
0537c34c6067
pass take_induct_info as an argument to comp_theorems
 huffman parents: 
35654diff
changeset | 14 | theory -> thm list * theory | 
| 
0537c34c6067
pass take_induct_info as an argument to comp_theorems
 huffman parents: 
35654diff
changeset | 15 | |
| 40832 | 16 | val quiet_mode: bool Unsynchronized.ref | 
| 17 | val trace_domain: bool Unsynchronized.ref | |
| 18 | end | |
| 31005 | 19 | |
| 41296 
6aaf80ea9715
switch to transparent ascription, to avoid warning messages
 huffman parents: 
41214diff
changeset | 20 | structure Domain_Induction : DOMAIN_INDUCTION = | 
| 31005 | 21 | struct | 
| 23152 | 22 | |
| 40832 | 23 | val quiet_mode = Unsynchronized.ref false | 
| 24 | val trace_domain = Unsynchronized.ref false | |
| 29402 | 25 | |
| 40832 | 26 | fun message s = if !quiet_mode then () else writeln s | 
| 27 | fun trace s = if !trace_domain then tracing s else () | |
| 29402 | 28 | |
| 40832 | 29 | open HOLCF_Library | 
| 23152 | 30 | |
| 40013 | 31 | (******************************************************************************) | 
| 32 | (***************************** proofs about take ******************************) | |
| 33 | (******************************************************************************) | |
| 23152 | 34 | |
| 40013 | 35 | fun take_theorems | 
| 40019 
05cda34d36e7
put constructor argument specs in constr_info type
 huffman parents: 
40018diff
changeset | 36 | (dbinds : binding list) | 
| 35775 
9b7e2e17be69
pass take_info as argument to Domain_Theorems.theorems
 huffman parents: 
35774diff
changeset | 37 | (take_info : Domain_Take_Proofs.take_induct_info) | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 38 | (constr_infos : Domain_Constructors.constr_info list) | 
| 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 39 | (thy : theory) : thm list list * theory = | 
| 23152 | 40 | let | 
| 40832 | 41 |   val {take_consts, take_Suc_thms, deflation_take_thms, ...} = take_info
 | 
| 42 | val deflation_thms = Domain_Take_Proofs.get_deflation_thms thy | |
| 23152 | 43 | |
| 69597 | 44 |   val n = Free ("n", \<^typ>\<open>nat\<close>)
 | 
| 45 | val n' = \<^const>\<open>Suc\<close> $ n | |
| 35559 | 46 | |
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 47 | local | 
| 40832 | 48 | val newTs = map (#absT o #iso_info) constr_infos | 
| 49 | val subs = newTs ~~ map (fn t => t $ n) take_consts | |
| 69597 | 50 | fun is_ID (Const (c, _)) = (c = \<^const_name>\<open>ID\<close>) | 
| 40832 | 51 | | is_ID _ = false | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 52 | in | 
| 40488 | 53 | fun map_of_arg thy v T = | 
| 40832 | 54 | let val m = Domain_Take_Proofs.map_of_typ thy subs T | 
| 55 | in if is_ID m then v else mk_capply (m, v) end | |
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 56 | end | 
| 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 57 | |
| 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 58 | fun prove_take_apps | 
| 40019 
05cda34d36e7
put constructor argument specs in constr_info type
 huffman parents: 
40018diff
changeset | 59 | ((dbind, take_const), constr_info) thy = | 
| 23152 | 60 | let | 
| 41214 | 61 |       val {iso_info, con_specs, con_betas, ...} : Domain_Constructors.constr_info = constr_info
 | 
| 40832 | 62 |       val {abs_inverse, ...} = iso_info
 | 
| 40019 
05cda34d36e7
put constructor argument specs in constr_info type
 huffman parents: 
40018diff
changeset | 63 | fun prove_take_app (con_const, args) = | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 64 | let | 
| 40832 | 65 | val Ts = map snd args | 
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
54895diff
changeset | 66 | val ns = Name.variant_list ["n"] (Old_Datatype_Prop.make_tnames Ts) | 
| 40832 | 67 | val vs = map Free (ns ~~ Ts) | 
| 68 | val lhs = mk_capply (take_const $ n', list_ccomb (con_const, vs)) | |
| 69 | val rhs = list_ccomb (con_const, map2 (map_of_arg thy) vs Ts) | |
| 70 | val goal = mk_trp (mk_eq (lhs, rhs)) | |
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 71 | val rules = | 
| 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 72 |               [abs_inverse] @ con_betas @ @{thms take_con_rules}
 | 
| 40832 | 73 | @ take_Suc_thms @ deflation_thms @ deflation_take_thms | 
| 54895 | 74 | fun tac ctxt = simp_tac (put_simpset HOL_basic_ss ctxt addsimps rules) 1 | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 75 | in | 
| 54895 | 76 | Goal.prove_global thy [] [] goal (tac o #context) | 
| 40832 | 77 | end | 
| 78 | val take_apps = map prove_take_app con_specs | |
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 79 | in | 
| 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 80 | yield_singleton Global_Theory.add_thmss | 
| 63003 | 81 | ((Binding.qualify_name true dbind "take_rews", take_apps), | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 82 | [Simplifier.simp_add]) thy | 
| 40832 | 83 | end | 
| 23152 | 84 | in | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 85 | fold_map prove_take_apps | 
| 40019 
05cda34d36e7
put constructor argument specs in constr_info type
 huffman parents: 
40018diff
changeset | 86 | (dbinds ~~ take_consts ~~ constr_infos) thy | 
| 40832 | 87 | end | 
| 23152 | 88 | |
| 40029 | 89 | (******************************************************************************) | 
| 90 | (****************************** induction rules *******************************) | |
| 91 | (******************************************************************************) | |
| 40013 | 92 | |
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 93 | val case_UU_allI = | 
| 67613 | 94 |     @{lemma "(\<And>x. x \<noteq> UU \<Longrightarrow> P x) \<Longrightarrow> P UU \<Longrightarrow> \<forall>x. P x" by metis}
 | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 95 | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 96 | fun prove_induction | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 97 | (comp_dbind : binding) | 
| 40018 | 98 | (constr_infos : Domain_Constructors.constr_info list) | 
| 99 | (take_info : Domain_Take_Proofs.take_induct_info) | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 100 | (take_rews : thm list) | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 101 | (thy : theory) = | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 102 | let | 
| 40832 | 103 | val comp_dname = Binding.name_of comp_dbind | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 104 | |
| 40832 | 105 | val iso_infos = map #iso_info constr_infos | 
| 106 | val exhausts = map #exhaust constr_infos | |
| 107 | val con_rews = maps #con_rews constr_infos | |
| 108 |   val {take_consts, take_induct_thms, ...} = take_info
 | |
| 35658 | 109 | |
| 40832 | 110 | val newTs = map #absT iso_infos | 
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
54895diff
changeset | 111 | val P_names = Old_Datatype_Prop.indexify_names (map (K "P") newTs) | 
| 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
54895diff
changeset | 112 | val x_names = Old_Datatype_Prop.indexify_names (map (K "x") newTs) | 
| 40832 | 113 | val P_types = map (fn T => T --> HOLogic.boolT) newTs | 
| 114 | val Ps = map Free (P_names ~~ P_types) | |
| 115 | val xs = map Free (x_names ~~ newTs) | |
| 116 |   val n = Free ("n", HOLogic.natT)
 | |
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 117 | |
| 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 118 | fun con_assm defined p (con, args) = | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 119 | let | 
| 40832 | 120 | val Ts = map snd args | 
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
54895diff
changeset | 121 | val ns = Name.variant_list P_names (Old_Datatype_Prop.make_tnames Ts) | 
| 40832 | 122 | val vs = map Free (ns ~~ Ts) | 
| 123 | val nonlazy = map snd (filter_out (fst o fst) (args ~~ vs)) | |
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 124 | fun ind_hyp (v, T) t = | 
| 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 125 | case AList.lookup (op =) (newTs ~~ Ps) T of NONE => t | 
| 40832 | 126 | | SOME p' => Logic.mk_implies (mk_trp (p' $ v), t) | 
| 127 | val t1 = mk_trp (p $ list_ccomb (con, vs)) | |
| 128 | val t2 = fold_rev ind_hyp (vs ~~ Ts) t1 | |
| 129 | val t3 = Logic.list_implies (map (mk_trp o mk_defined) nonlazy, t2) | |
| 130 | in fold_rev Logic.all vs (if defined then t3 else t2) end | |
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 131 | fun eq_assms ((p, T), cons) = | 
| 40832 | 132 | mk_trp (p $ HOLCF_Library.mk_bottom T) :: map (con_assm true p) cons | 
| 133 | val assms = maps eq_assms (Ps ~~ newTs ~~ map #con_specs constr_infos) | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 134 | |
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 135 | fun quant_tac ctxt i = EVERY | 
| 59780 | 136 | (map (fn name => | 
| 137 |       Rule_Insts.res_inst_tac ctxt [((("x", 0), Position.none), name)] [] spec i) x_names)
 | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 138 | |
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 139 | (* FIXME: move this message to domain_take_proofs.ML *) | 
| 40832 | 140 | val is_finite = #is_finite take_info | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 141 | val _ = if is_finite | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 142 |           then message ("Proving finiteness rule for domain "^comp_dname^" ...")
 | 
| 40832 | 143 | else () | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 144 | |
| 40832 | 145 | val _ = trace " Proving finite_ind..." | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 146 | val finite_ind = | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 147 | let | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 148 | val concls = | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 149 | map (fn ((P, t), x) => P $ mk_capply (t $ n, x)) | 
| 40832 | 150 | (Ps ~~ take_consts ~~ xs) | 
| 151 | val goal = mk_trp (foldr1 mk_conj concls) | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 152 | |
| 42793 | 153 |       fun tacf {prems, context = ctxt} =
 | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 154 | let | 
| 61087 | 155 |           val take_ctxt = put_simpset HOL_ss ctxt addsimps (@{thm Rep_cfun_strict1} :: take_rews)
 | 
| 156 | ||
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 157 | (* Prove stronger prems, without definedness side conditions *) | 
| 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 158 | fun con_thm p (con, args) = | 
| 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 159 | let | 
| 40832 | 160 | val subgoal = con_assm false p (con, args) | 
| 45654 | 161 |               val rules = prems @ con_rews @ @{thms simp_thms}
 | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
45654diff
changeset | 162 | val simplify = asm_simp_tac (put_simpset HOL_basic_ss ctxt addsimps rules) | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 163 | fun arg_tac (lazy, _) = | 
| 60754 | 164 | resolve_tac ctxt [if lazy then allI else case_UU_allI] 1 | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
51717diff
changeset | 165 | fun tacs ctxt = | 
| 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
51717diff
changeset | 166 |                   rewrite_goals_tac ctxt @{thms atomize_all atomize_imp} ::
 | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 167 | map arg_tac args @ | 
| 60754 | 168 | [REPEAT (resolve_tac ctxt [impI] 1), ALLGOALS simplify] | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 169 | in | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
51717diff
changeset | 170 | Goal.prove ctxt [] [] subgoal (EVERY o tacs o #context) | 
| 40832 | 171 | end | 
| 172 | fun eq_thms (p, cons) = map (con_thm p) cons | |
| 173 | val conss = map #con_specs constr_infos | |
| 174 | val prems' = maps eq_thms (Ps ~~ conss) | |
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 175 | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 176 | val tacs1 = [ | 
| 42793 | 177 | quant_tac ctxt 1, | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
45654diff
changeset | 178 | simp_tac (put_simpset HOL_ss ctxt) 1, | 
| 59826 | 179 | Induct_Tacs.induct_tac ctxt [[SOME "n"]] NONE 1, | 
| 61087 | 180 | simp_tac (take_ctxt addsimps prems) 1, | 
| 42793 | 181 | TRY (safe_tac (put_claset HOL_cs ctxt))] | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 182 | fun con_tac _ = | 
| 61087 | 183 | asm_simp_tac take_ctxt 1 THEN | 
| 60754 | 184 | (resolve_tac ctxt prems' THEN_ALL_NEW eresolve_tac ctxt [spec]) 1 | 
| 35781 
b7738ab762b1
renamed some lemmas generated by the domain package
 huffman parents: 
35777diff
changeset | 185 | fun cases_tacs (cons, exhaust) = | 
| 59780 | 186 |             Rule_Insts.res_inst_tac ctxt [((("y", 0), Position.none), "x")] [] exhaust 1 ::
 | 
| 61087 | 187 | asm_simp_tac (take_ctxt addsimps prems) 1 :: | 
| 40832 | 188 | map con_tac cons | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 189 | val tacs = tacs1 @ maps cases_tacs (conss ~~ exhausts) | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 190 | in | 
| 40020 
0cbb08bf18df
rewrite proof automation for finite_ind; get rid of case_UU_tac
 huffman parents: 
40019diff
changeset | 191 | EVERY (map DETERM tacs) | 
| 40832 | 192 | end | 
| 193 | in Goal.prove_global thy [] assms goal tacf end | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 194 | |
| 40832 | 195 | val _ = trace " Proving ind..." | 
| 35661 
ede27eb8e94b
don't generate rule foo.finites for non-flat domains; use take_induct rule to prove induction rule
 huffman parents: 
35660diff
changeset | 196 | val ind = | 
| 40022 | 197 | let | 
| 40832 | 198 | val concls = map (op $) (Ps ~~ xs) | 
| 199 | val goal = mk_trp (foldr1 mk_conj concls) | |
| 200 | val adms = if is_finite then [] else map (mk_trp o mk_adm) Ps | |
| 42793 | 201 |       fun tacf {prems, context = ctxt} =
 | 
| 40022 | 202 | let | 
| 203 | fun finite_tac (take_induct, fin_ind) = | |
| 60754 | 204 | resolve_tac ctxt [take_induct] 1 THEN | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
58112diff
changeset | 205 | (if is_finite then all_tac else resolve_tac ctxt prems 1) THEN | 
| 60754 | 206 | (resolve_tac ctxt [fin_ind] THEN_ALL_NEW solve_tac ctxt prems) 1 | 
| 42793 | 207 | val fin_inds = Project_Rule.projections ctxt finite_ind | 
| 40022 | 208 | in | 
| 42793 | 209 | TRY (safe_tac (put_claset HOL_cs ctxt)) THEN | 
| 40022 | 210 | EVERY (map finite_tac (take_induct_thms ~~ fin_inds)) | 
| 40832 | 211 | end | 
| 40022 | 212 | in Goal.prove_global thy [] (adms @ assms) goal tacf end | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 213 | |
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 214 | (* case names for induction rules *) | 
| 40832 | 215 | val dnames = map (fst o dest_Type) newTs | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 216 | val case_ns = | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 217 | let | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 218 | val adms = | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 219 | if is_finite then [] else | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 220 | if length dnames = 1 then ["adm"] else | 
| 40832 | 221 | map (fn s => "adm_" ^ Long_Name.base_name s) dnames | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 222 | val bottoms = | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 223 | if length dnames = 1 then ["bottom"] else | 
| 40832 | 224 | map (fn s => "bottom_" ^ Long_Name.base_name s) dnames | 
| 41214 | 225 | fun one_eq bot (constr_info : Domain_Constructors.constr_info) = | 
| 44080 
53d95b52954c
HOLCF: fix warnings about unreferenced identifiers
 huffman parents: 
42793diff
changeset | 226 | let fun name_of (c, _) = Long_Name.base_name (fst (dest_Const c)) | 
| 40832 | 227 | in bot :: map name_of (#con_specs constr_info) end | 
| 228 | in adms @ flat (map2 one_eq bottoms constr_infos) end | |
| 35630 
8e562d56d404
add case_names attribute to casedist and ind rules
 huffman parents: 
35601diff
changeset | 229 | |
| 42361 | 230 | val inducts = Project_Rule.projections (Proof_Context.init_global thy) ind | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 231 | fun ind_rule (dname, rule) = | 
| 40026 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 232 | ((Binding.empty, rule), | 
| 40832 | 233 | [Rule_Cases.case_names case_ns, Induct.induct_type dname]) | 
| 35630 
8e562d56d404
add case_names attribute to casedist and ind rules
 huffman parents: 
35601diff
changeset | 234 | |
| 35774 | 235 | in | 
| 236 | thy | |
| 40026 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 237 | |> snd o Global_Theory.add_thms [ | 
| 63003 | 238 | ((Binding.qualify_name true comp_dbind "finite_induct", finite_ind), []), | 
| 239 | ((Binding.qualify_name true comp_dbind "induct", ind), [])] | |
| 40026 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 240 | |> (snd o Global_Theory.add_thms (map ind_rule (dnames ~~ inducts))) | 
| 40832 | 241 | end (* prove_induction *) | 
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 242 | |
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 243 | (******************************************************************************) | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 244 | (************************ bisimulation and coinduction ************************) | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 245 | (******************************************************************************) | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 246 | |
| 35574 
ee5df989b7c4
move coinduction-related stuff into function prove_coindunction
 huffman parents: 
35560diff
changeset | 247 | fun prove_coinduction | 
| 40025 | 248 | (comp_dbind : binding, dbinds : binding list) | 
| 249 | (constr_infos : Domain_Constructors.constr_info list) | |
| 250 | (take_info : Domain_Take_Proofs.take_induct_info) | |
| 251 | (take_rews : thm list list) | |
| 35599 
20670f5564e9
skip coinduction proofs for indirect-recursive domain definitions
 huffman parents: 
35597diff
changeset | 252 | (thy : theory) : theory = | 
| 23152 | 253 | let | 
| 40832 | 254 | val iso_infos = map #iso_info constr_infos | 
| 255 | val newTs = map #absT iso_infos | |
| 40025 | 256 | |
| 40832 | 257 |   val {take_consts, take_0_thms, take_lemma_thms, ...} = take_info
 | 
| 23152 | 258 | |
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
54895diff
changeset | 259 | val R_names = Old_Datatype_Prop.indexify_names (map (K "R") newTs) | 
| 40832 | 260 | val R_types = map (fn T => T --> T --> boolT) newTs | 
| 261 | val Rs = map Free (R_names ~~ R_types) | |
| 262 |   val n = Free ("n", natT)
 | |
| 263 | val reserved = "x" :: "y" :: R_names | |
| 35497 | 264 | |
| 40025 | 265 | (* declare bisimulation predicate *) | 
| 40832 | 266 | val bisim_bind = Binding.suffix_name "_bisim" comp_dbind | 
| 267 | val bisim_type = R_types ---> boolT | |
| 35497 | 268 | val (bisim_const, thy) = | 
| 42375 
774df7c59508
report Name_Space.declare/define, relatively to context;
 wenzelm parents: 
42364diff
changeset | 269 | Sign.declare_const_global ((bisim_bind, bisim_type), NoSyn) thy | 
| 35497 | 270 | |
| 40025 | 271 | (* define bisimulation predicate *) | 
| 272 | local | |
| 273 | fun one_con T (con, args) = | |
| 274 | let | |
| 40832 | 275 | val Ts = map snd args | 
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
54895diff
changeset | 276 | val ns1 = Name.variant_list reserved (Old_Datatype_Prop.make_tnames Ts) | 
| 40832 | 277 | val ns2 = map (fn n => n^"'") ns1 | 
| 278 | val vs1 = map Free (ns1 ~~ Ts) | |
| 279 | val vs2 = map Free (ns2 ~~ Ts) | |
| 280 |         val eq1 = mk_eq (Free ("x", T), list_ccomb (con, vs1))
 | |
| 281 |         val eq2 = mk_eq (Free ("y", T), list_ccomb (con, vs2))
 | |
| 40025 | 282 | fun rel ((v1, v2), T) = | 
| 283 | case AList.lookup (op =) (newTs ~~ Rs) T of | |
| 40832 | 284 | NONE => mk_eq (v1, v2) | SOME r => r $ v1 $ v2 | 
| 285 | val eqs = foldr1 mk_conj (map rel (vs1 ~~ vs2 ~~ Ts) @ [eq1, eq2]) | |
| 40025 | 286 | in | 
| 287 | Library.foldr mk_ex (vs1 @ vs2, eqs) | |
| 40832 | 288 | end | 
| 40025 | 289 | fun one_eq ((T, R), cons) = | 
| 290 | let | |
| 40832 | 291 |         val x = Free ("x", T)
 | 
| 292 |         val y = Free ("y", T)
 | |
| 293 | val disj1 = mk_conj (mk_eq (x, mk_bottom T), mk_eq (y, mk_bottom T)) | |
| 294 | val disjs = disj1 :: map (one_con T) cons | |
| 40025 | 295 | in | 
| 296 | mk_all (x, mk_all (y, mk_imp (R $ x $ y, foldr1 mk_disj disjs))) | |
| 40832 | 297 | end | 
| 298 | val conjs = map one_eq (newTs ~~ Rs ~~ map #con_specs constr_infos) | |
| 299 | val bisim_rhs = lambdas Rs (Library.foldr1 mk_conj conjs) | |
| 300 | val bisim_eqn = Logic.mk_equals (bisim_const, bisim_rhs) | |
| 40025 | 301 | in | 
| 302 | val (bisim_def_thm, thy) = thy |> | |
| 303 | yield_singleton (Global_Theory.add_defs false) | |
| 63003 | 304 | ((Binding.qualify_name true comp_dbind "bisim_def", bisim_eqn), []) | 
| 40025 | 305 | end (* local *) | 
| 35497 | 306 | |
| 40025 | 307 | (* prove coinduction lemma *) | 
| 308 | val coind_lemma = | |
| 35497 | 309 | let | 
| 40832 | 310 | val assm = mk_trp (list_comb (bisim_const, Rs)) | 
| 40025 | 311 | fun one ((T, R), take_const) = | 
| 312 | let | |
| 40832 | 313 |           val x = Free ("x", T)
 | 
| 314 |           val y = Free ("y", T)
 | |
| 315 | val lhs = mk_capply (take_const $ n, x) | |
| 316 | val rhs = mk_capply (take_const $ n, y) | |
| 40025 | 317 | in | 
| 318 | mk_all (x, mk_all (y, mk_imp (R $ x $ y, mk_eq (lhs, rhs)))) | |
| 40832 | 319 | end | 
| 40025 | 320 | val goal = | 
| 40832 | 321 | mk_trp (foldr1 mk_conj (map one (newTs ~~ Rs ~~ take_consts))) | 
| 322 |       val rules = @{thm Rep_cfun_strict1} :: take_0_thms
 | |
| 42793 | 323 |       fun tacf {prems, context = ctxt} =
 | 
| 40025 | 324 | let | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
51717diff
changeset | 325 | val prem' = rewrite_rule ctxt [bisim_def_thm] (hd prems) | 
| 42793 | 326 | val prems' = Project_Rule.projections ctxt prem' | 
| 40832 | 327 | val dests = map (fn th => th RS spec RS spec RS mp) prems' | 
| 40025 | 328 | fun one_tac (dest, rews) = | 
| 60754 | 329 | dresolve_tac ctxt [dest] 1 THEN safe_tac (put_claset HOL_cs ctxt) THEN | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
45654diff
changeset | 330 | ALLGOALS (asm_simp_tac (put_simpset HOL_basic_ss ctxt addsimps rews)) | 
| 40025 | 331 | in | 
| 60754 | 332 |           resolve_tac ctxt @{thms nat.induct} 1 THEN
 | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
45654diff
changeset | 333 | simp_tac (put_simpset HOL_ss ctxt addsimps rules) 1 THEN | 
| 42793 | 334 | safe_tac (put_claset HOL_cs ctxt) THEN | 
| 40025 | 335 | EVERY (map one_tac (dests ~~ take_rews)) | 
| 336 | end | |
| 35497 | 337 | in | 
| 40025 | 338 | Goal.prove_global thy [] [assm] goal tacf | 
| 40832 | 339 | end | 
| 40025 | 340 | |
| 341 | (* prove individual coinduction rules *) | |
| 342 | fun prove_coind ((T, R), take_lemma) = | |
| 343 | let | |
| 40832 | 344 |       val x = Free ("x", T)
 | 
| 345 |       val y = Free ("y", T)
 | |
| 346 | val assm1 = mk_trp (list_comb (bisim_const, Rs)) | |
| 347 | val assm2 = mk_trp (R $ x $ y) | |
| 348 | val goal = mk_trp (mk_eq (x, y)) | |
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
45654diff
changeset | 349 |       fun tacf {prems, context = ctxt} =
 | 
| 40025 | 350 | let | 
| 40832 | 351 | val rule = hd prems RS coind_lemma | 
| 40025 | 352 | in | 
| 60754 | 353 | resolve_tac ctxt [take_lemma] 1 THEN | 
| 51717 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 wenzelm parents: 
45654diff
changeset | 354 | asm_simp_tac (put_simpset HOL_basic_ss ctxt addsimps (rule :: prems)) 1 | 
| 40832 | 355 | end | 
| 40025 | 356 | in | 
| 357 | Goal.prove_global thy [] [assm1, assm2] goal tacf | |
| 40832 | 358 | end | 
| 359 | val coinds = map prove_coind (newTs ~~ Rs ~~ take_lemma_thms) | |
| 63003 | 360 | val coind_binds = map (fn b => Binding.qualify_name true b "coinduct") dbinds | 
| 35497 | 361 | |
| 362 | in | |
| 40025 | 363 | thy |> snd o Global_Theory.add_thms | 
| 364 | (map Thm.no_attributes (coind_binds ~~ coinds)) | |
| 40832 | 365 | end (* let *) | 
| 35574 
ee5df989b7c4
move coinduction-related stuff into function prove_coindunction
 huffman parents: 
35560diff
changeset | 366 | |
| 40018 | 367 | (******************************************************************************) | 
| 368 | (******************************* main function ********************************) | |
| 369 | (******************************************************************************) | |
| 370 | ||
| 35657 
0537c34c6067
pass take_induct_info as an argument to comp_theorems
 huffman parents: 
35654diff
changeset | 371 | fun comp_theorems | 
| 40019 
05cda34d36e7
put constructor argument specs in constr_info type
 huffman parents: 
40018diff
changeset | 372 | (dbinds : binding list) | 
| 35659 | 373 | (take_info : Domain_Take_Proofs.take_induct_info) | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 374 | (constr_infos : Domain_Constructors.constr_info list) | 
| 35657 
0537c34c6067
pass take_induct_info as an argument to comp_theorems
 huffman parents: 
35654diff
changeset | 375 | (thy : theory) = | 
| 35574 
ee5df989b7c4
move coinduction-related stuff into function prove_coindunction
 huffman parents: 
35560diff
changeset | 376 | let | 
| 40097 
429cd74f795f
remove legacy comp_dbind option from domain package
 huffman parents: 
40040diff
changeset | 377 | |
| 63006 | 378 | val comp_dbind = Binding.conglomerate dbinds | 
| 379 | val comp_dname = Binding.name_of comp_dbind | |
| 35574 
ee5df989b7c4
move coinduction-related stuff into function prove_coindunction
 huffman parents: 
35560diff
changeset | 380 | |
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 381 | (* Test for emptiness *) | 
| 40026 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 382 | (* FIXME: reimplement emptiness test | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 383 | local | 
| 40832 | 384 | open Domain_Library | 
| 385 | val dnames = map (fst o fst) eqs | |
| 386 | val conss = map snd eqs | |
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 387 | fun rec_to ns lazy_rec (n,cons) = forall (exists (fn arg => | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 388 | is_rec arg andalso not (member (op =) ns (rec_of arg)) andalso | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 389 | ((rec_of arg = n andalso not (lazy_rec orelse is_lazy arg)) orelse | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 390 | rec_of arg <> n andalso rec_to (rec_of arg::ns) | 
| 42364 | 391 | (lazy_rec orelse is_lazy arg) (n, nth conss (rec_of arg))) | 
| 40832 | 392 | ) o snd) cons | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 393 | fun warn (n,cons) = | 
| 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 394 | if rec_to [] false (n,cons) | 
| 42364 | 395 |     then (warning ("domain " ^ nth dnames n ^ " is empty!") true)
 | 
| 40832 | 396 | else false | 
| 40023 
a868e9d73031
move emptiness check to comp_theorems; remove eqs parameter to prove_induction; remove dead code
 huffman parents: 
40022diff
changeset | 397 | in | 
| 40832 | 398 | val n__eqs = mapn (fn n => fn (_,cons) => (n,cons)) 0 eqs | 
| 399 | val is_emptys = map warn n__eqs | |
| 400 | end | |
| 40026 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 401 | *) | 
| 23152 | 402 | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 403 | (* Test for indirect recursion *) | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 404 | local | 
| 40832 | 405 | val newTs = map (#absT o #iso_info) constr_infos | 
| 40026 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 406 | fun indirect_typ (Type (_, Ts)) = | 
| 
8f8f18a88685
remove last few dependencies on domain_library.ML and delete it; temporarily disable emptiness check
 huffman parents: 
40025diff
changeset | 407 | exists (fn T => member (op =) newTs T orelse indirect_typ T) Ts | 
| 40832 | 408 | | indirect_typ _ = false | 
| 409 | fun indirect_arg (_, T) = indirect_typ T | |
| 410 | fun indirect_con (_, args) = exists indirect_arg args | |
| 411 | fun indirect_eq cons = exists indirect_con cons | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 412 | in | 
| 40832 | 413 | val is_indirect = exists indirect_eq (map #con_specs constr_infos) | 
| 35599 
20670f5564e9
skip coinduction proofs for indirect-recursive domain definitions
 huffman parents: 
35597diff
changeset | 414 | val _ = | 
| 
20670f5564e9
skip coinduction proofs for indirect-recursive domain definitions
 huffman parents: 
35597diff
changeset | 415 | if is_indirect | 
| 
20670f5564e9
skip coinduction proofs for indirect-recursive domain definitions
 huffman parents: 
35597diff
changeset | 416 | then message "Indirect recursion detected, skipping proofs of (co)induction rules" | 
| 40832 | 417 |       else message ("Proving induction properties of domain "^comp_dname^" ...")
 | 
| 418 | end | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 419 | |
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 420 | (* theorems about take *) | 
| 23152 | 421 | |
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 422 | val (take_rewss, thy) = | 
| 40832 | 423 | take_theorems dbinds take_info constr_infos thy | 
| 23152 | 424 | |
| 44080 
53d95b52954c
HOLCF: fix warnings about unreferenced identifiers
 huffman parents: 
42793diff
changeset | 425 | val {take_0_thms, take_strict_thms, ...} = take_info
 | 
| 40016 
2eff1cbc1ccb
remove function Domain_Theorems.theorems; bind theorem names directly from Domain_Constructors.add_domain_constructors
 huffman parents: 
40014diff
changeset | 426 | |
| 40832 | 427 | val take_rews = take_0_thms @ take_strict_thms @ flat take_rewss | 
| 23152 | 428 | |
| 35585 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 429 | (* prove induction rules, unless definition is indirect recursive *) | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 430 | val thy = | 
| 
555f26f00e47
skip proof of induction rule for indirect-recursive domain definitions
 huffman parents: 
35574diff
changeset | 431 | if is_indirect then thy else | 
| 40832 | 432 | prove_induction comp_dbind constr_infos take_info take_rews thy | 
| 23152 | 433 | |
| 35599 
20670f5564e9
skip coinduction proofs for indirect-recursive domain definitions
 huffman parents: 
35597diff
changeset | 434 | val thy = | 
| 
20670f5564e9
skip coinduction proofs for indirect-recursive domain definitions
 huffman parents: 
35597diff
changeset | 435 | if is_indirect then thy else | 
| 40832 | 436 | prove_coinduction (comp_dbind, dbinds) constr_infos take_info take_rewss thy | 
| 23152 | 437 | |
| 35642 
f478d5a9d238
generate separate qualified theorem name for each type's reach and take_lemma
 huffman parents: 
35630diff
changeset | 438 | in | 
| 
f478d5a9d238
generate separate qualified theorem name for each type's reach and take_lemma
 huffman parents: 
35630diff
changeset | 439 | (take_rews, thy) | 
| 40832 | 440 | end (* let *) | 
| 441 | end (* struct *) |