149 |
149 |
150 val lemma_tac = FIRST' [eresolve_tac [asm_rl, conjE, PartE, mp], |
150 val lemma_tac = FIRST' [eresolve_tac [asm_rl, conjE, PartE, mp], |
151 resolve_tac [allI, impI, conjI, Part_eqI], |
151 resolve_tac [allI, impI, conjI, Part_eqI], |
152 dresolve_tac [spec, mp, Pr.fsplitD]]; |
152 dresolve_tac [spec, mp, Pr.fsplitD]]; |
153 |
153 |
|
154 val need_mutual = length Intr_elim.rec_names > 1; |
|
155 |
154 val lemma = (*makes the link between the two induction rules*) |
156 val lemma = (*makes the link between the two induction rules*) |
155 prove_goalw_cterm part_rec_defs |
157 if need_mutual then |
156 (cterm_of sign (Logic.mk_implies (induct_concl,mutual_induct_concl))) |
158 (writeln " Proving the mutual induction rule..."; |
157 (fn prems => |
159 prove_goalw_cterm part_rec_defs |
158 [cut_facts_tac prems 1, |
160 (cterm_of sign (Logic.mk_implies (induct_concl, |
159 REPEAT (rewrite_goals_tac [Pr.split_eq] THEN |
161 mutual_induct_concl))) |
160 lemma_tac 1)]); |
162 (fn prems => |
|
163 [cut_facts_tac prems 1, |
|
164 REPEAT (rewrite_goals_tac [Pr.split_eq] THEN |
|
165 lemma_tac 1)])) |
|
166 else TrueI; |
161 |
167 |
162 (*Mutual induction follows by freeness of Inl/Inr.*) |
168 (*Mutual induction follows by freeness of Inl/Inr.*) |
163 |
169 |
164 (*Simplification largely reduces the mutual induction rule to the |
170 (*Simplification largely reduces the mutual induction rule to the |
165 standard rule*) |
171 standard rule*) |
201 DEPTH_SOLVE (FIRSTGOAL (ares_tac [impI] ORELSE' |
207 DEPTH_SOLVE (FIRSTGOAL (ares_tac [impI] ORELSE' |
202 eresolve_tac (conjE::mp::cmonos)))) |
208 eresolve_tac (conjE::mp::cmonos)))) |
203 ) i) |
209 ) i) |
204 THEN mutual_ind_tac prems (i-1); |
210 THEN mutual_ind_tac prems (i-1); |
205 |
211 |
206 val _ = writeln " Proving the mutual induction rule..."; |
|
207 |
|
208 val mutual_induct_fsplit = |
212 val mutual_induct_fsplit = |
|
213 if need_mutual then |
209 prove_goalw_cterm [] |
214 prove_goalw_cterm [] |
210 (cterm_of sign |
215 (cterm_of sign |
211 (Logic.list_implies |
216 (Logic.list_implies |
212 (map (induct_prem (Inductive.rec_tms~~preds)) Inductive.intr_tms, |
217 (map (induct_prem (Inductive.rec_tms~~preds)) Inductive.intr_tms, |
213 mutual_induct_concl))) |
218 mutual_induct_concl))) |
214 (fn prems => |
219 (fn prems => |
215 [rtac (quant_induct RS lemma) 1, |
220 [rtac (quant_induct RS lemma) 1, |
216 mutual_ind_tac (rev prems) (length prems)]); |
221 mutual_ind_tac (rev prems) (length prems)]) |
217 |
222 else TrueI; |
218 |
|
219 |
223 |
220 (** Uncurrying the predicate in the ordinary induction rule **) |
224 (** Uncurrying the predicate in the ordinary induction rule **) |
221 |
225 |
222 (*instantiate the variable to a tuple, if it is non-trivial, in order to |
226 (*instantiate the variable to a tuple, if it is non-trivial, in order to |
223 allow the predicate to be "opened up". |
227 allow the predicate to be "opened up". |
238 (CP.split_rule_var |
242 (CP.split_rule_var |
239 (Var((pred_name,2), elem_type --> Ind_Syntax.oT), |
243 (Var((pred_name,2), elem_type --> Ind_Syntax.oT), |
240 induct0)); |
244 induct0)); |
241 |
245 |
242 (*Just "True" unless there's true mutual recursion. This saves storage.*) |
246 (*Just "True" unless there's true mutual recursion. This saves storage.*) |
243 val mutual_induct = |
247 val mutual_induct = CP.remove_split mutual_induct_fsplit |
244 if length Intr_elim.rec_names > 1 |
|
245 then CP.remove_split mutual_induct_fsplit |
|
246 else TrueI; |
|
247 end |
248 end |
248 end; |
249 end; |