60 val (Some pred) = gen_assoc (op aconv) (ind_alist, X) |
60 val (Some pred) = gen_assoc (op aconv) (ind_alist, X) |
61 val concl = FOLogic.mk_Trueprop (pred $ t) |
61 val concl = FOLogic.mk_Trueprop (pred $ t) |
62 in list_all_free (quantfrees, Logic.list_implies (iprems,concl)) end |
62 in list_all_free (quantfrees, Logic.list_implies (iprems,concl)) end |
63 handle Bind => error"Recursion term not found in conclusion"; |
63 handle Bind => error"Recursion term not found in conclusion"; |
64 |
64 |
65 (*Reduces backtracking by delivering the correct premise to each goal. |
65 (*Minimizes backtracking by delivering the correct premise to each goal. |
66 Intro rules with extra Vars in premises still cause some backtracking *) |
66 Intro rules with extra Vars in premises still cause some backtracking *) |
67 fun ind_tac [] 0 = all_tac |
67 fun ind_tac [] 0 = all_tac |
68 | ind_tac(prem::prems) i = |
68 | ind_tac(prem::prems) i = |
69 DEPTH_SOLVE_1 (ares_tac [prem, refl] i) THEN |
69 DEPTH_SOLVE_1 (ares_tac [prem, refl] i) THEN |
70 ind_tac prems (i-1); |
70 ind_tac prems (i-1); |
72 val pred = Free(pred_name, Ind_Syntax.iT --> FOLogic.oT); |
72 val pred = Free(pred_name, Ind_Syntax.iT --> FOLogic.oT); |
73 |
73 |
74 val ind_prems = map (induct_prem (map (rpair pred) Inductive.rec_tms)) |
74 val ind_prems = map (induct_prem (map (rpair pred) Inductive.rec_tms)) |
75 Inductive.intr_tms; |
75 Inductive.intr_tms; |
76 |
76 |
77 (*Debugging code... |
77 val _ = if !Ind_Syntax.trace then |
78 val _ = writeln "ind_prems = "; |
78 (writeln "ind_prems = "; |
79 val _ = seq (writeln o Sign.string_of_term sign) ind_prems; |
79 seq (writeln o Sign.string_of_term sign) ind_prems; |
80 *) |
80 writeln "raw_induct = "; print_thm Intr_elim.raw_induct) |
|
81 else (); |
|
82 |
81 |
83 |
82 (*We use a MINIMAL simpset because others (such as FOL_ss) contain too many |
84 (*We use a MINIMAL simpset because others (such as FOL_ss) contain too many |
83 simplifications. If the premises get simplified, then the proofs will |
85 simplifications. If the premises get simplified, then the proofs could |
84 fail. *) |
86 fail. *) |
85 val min_ss = empty_ss |
87 val min_ss = empty_ss |
86 setmksimps (map mk_meta_eq o ZF_atomize o gen_all) |
88 setmksimps (map mk_meta_eq o ZF_atomize o gen_all) |
87 setSolver (fn prems => resolve_tac (triv_rls@prems) |
89 setSolver (fn prems => resolve_tac (triv_rls@prems) |
88 ORELSE' assume_tac |
90 ORELSE' assume_tac |
96 (fn prems => |
98 (fn prems => |
97 [rtac (impI RS allI) 1, |
99 [rtac (impI RS allI) 1, |
98 DETERM (etac Intr_elim.raw_induct 1), |
100 DETERM (etac Intr_elim.raw_induct 1), |
99 (*Push Part inside Collect*) |
101 (*Push Part inside Collect*) |
100 full_simp_tac (min_ss addsimps [Part_Collect]) 1, |
102 full_simp_tac (min_ss addsimps [Part_Collect]) 1, |
101 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, exE, conjE, disjE] ORELSE' |
103 (*This CollectE and disjE separates out the introduction rules*) |
102 hyp_subst_tac)), |
104 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, disjE])), |
|
105 (*Now break down the individual cases. No disjE here in case |
|
106 some premise involves disjunction.*) |
|
107 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, exE, conjE] |
|
108 ORELSE' hyp_subst_tac)), |
103 ind_tac (rev prems) (length prems) ]); |
109 ind_tac (rev prems) (length prems) ]); |
104 |
110 |
105 (*** Prove the simultaneous induction rule ***) |
111 (*** Prove the simultaneous induction rule ***) |
106 |
112 |
107 (*Make distinct predicates for each inductive set*) |
113 (*Make distinct predicates for each inductive set*) |
163 mutual_induct_concl))) |
169 mutual_induct_concl))) |
164 (fn prems => |
170 (fn prems => |
165 [cut_facts_tac prems 1, |
171 [cut_facts_tac prems 1, |
166 REPEAT (rewrite_goals_tac [Pr.split_eq] THEN |
172 REPEAT (rewrite_goals_tac [Pr.split_eq] THEN |
167 lemma_tac 1)])) |
173 lemma_tac 1)])) |
168 else TrueI; |
174 else (writeln " [ No mutual induction rule needed ]"; |
|
175 TrueI); |
169 |
176 |
170 (*Mutual induction follows by freeness of Inl/Inr.*) |
177 (*Mutual induction follows by freeness of Inl/Inr.*) |
171 |
178 |
172 (*Simplification largely reduces the mutual induction rule to the |
179 (*Simplification largely reduces the mutual induction rule to the |
173 standard rule*) |
180 standard rule*) |
182 where t==Part(tf,Inl) and f==Part(tf,Inr) to list({v: tf. P_t(v)}). |
189 where t==Part(tf,Inl) and f==Part(tf,Inr) to list({v: tf. P_t(v)}). |
183 Instead the following rules extract the relevant conjunct. |
190 Instead the following rules extract the relevant conjunct. |
184 *) |
191 *) |
185 val cmonos = [subset_refl RS Collect_mono] RL Inductive.monos RLN (2,[rev_subsetD]); |
192 val cmonos = [subset_refl RS Collect_mono] RL Inductive.monos RLN (2,[rev_subsetD]); |
186 |
193 |
187 (*Avoids backtracking by delivering the correct premise to each goal*) |
194 (*Minimizes backtracking by delivering the correct premise to each goal*) |
188 fun mutual_ind_tac [] 0 = all_tac |
195 fun mutual_ind_tac [] 0 = all_tac |
189 | mutual_ind_tac(prem::prems) i = |
196 | mutual_ind_tac(prem::prems) i = |
190 DETERM |
197 DETERM |
191 (SELECT_GOAL |
198 (SELECT_GOAL |
192 ( |
199 ( |