1 (* Title: ZF/intr_elim.ML |
1 (* Title: ZF/intr_elim.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
4 Copyright 1994 University of Cambridge |
4 Copyright 1994 University of Cambridge |
5 |
5 |
6 Introduction/elimination rule module -- for Inductive/Coinductive Definitions |
6 Introduction/elimination rule module -- for Inductive/Coinductive Definitions |
7 *) |
7 *) |
8 |
8 |
9 signature INDUCTIVE_ARG = (** Description of a (co)inductive def **) |
9 signature INDUCTIVE_ARG = (** Description of a (co)inductive def **) |
10 sig |
10 sig |
11 val thy : theory (*new theory with inductive defs*) |
11 val thy : theory (*new theory with inductive defs*) |
12 val monos : thm list (*monotonicity of each M operator*) |
12 val monos : thm list (*monotonicity of each M operator*) |
13 val con_defs : thm list (*definitions of the constructors*) |
13 val con_defs : thm list (*definitions of the constructors*) |
14 val type_intrs : thm list (*type-checking intro rules*) |
14 val type_intrs : thm list (*type-checking intro rules*) |
15 val type_elims : thm list (*type-checking elim rules*) |
15 val type_elims : thm list (*type-checking elim rules*) |
16 end; |
16 end; |
17 |
17 |
18 |
18 |
19 signature INDUCTIVE_I = (** Terms read from the theory section **) |
19 signature INDUCTIVE_I = (** Terms read from the theory section **) |
20 sig |
20 sig |
21 val rec_tms : term list (*the recursive sets*) |
21 val rec_tms : term list (*the recursive sets*) |
22 val dom_sum : term (*their common domain*) |
22 val dom_sum : term (*their common domain*) |
23 val intr_tms : term list (*terms for the introduction rules*) |
23 val intr_tms : term list (*terms for the introduction rules*) |
24 end; |
24 end; |
25 |
25 |
26 signature INTR_ELIM = |
26 signature INTR_ELIM = |
27 sig |
27 sig |
28 val thy : theory (*copy of input theory*) |
28 val thy : theory (*copy of input theory*) |
29 val defs : thm list (*definitions made in thy*) |
29 val defs : thm list (*definitions made in thy*) |
30 val bnd_mono : thm (*monotonicity for the lfp definition*) |
30 val bnd_mono : thm (*monotonicity for the lfp definition*) |
31 val dom_subset : thm (*inclusion of recursive set in dom*) |
31 val dom_subset : thm (*inclusion of recursive set in dom*) |
32 val intrs : thm list (*introduction rules*) |
32 val intrs : thm list (*introduction rules*) |
33 val elim : thm (*case analysis theorem*) |
33 val elim : thm (*case analysis theorem*) |
34 val mk_cases : thm list -> string -> thm (*generates case theorems*) |
34 val mk_cases : thm list -> string -> thm (*generates case theorems*) |
35 end; |
35 end; |
36 |
36 |
37 signature INTR_ELIM_AUX = (** Used to make induction rules **) |
37 signature INTR_ELIM_AUX = (** Used to make induction rules **) |
38 sig |
38 sig |
39 val raw_induct : thm (*raw induction rule from Fp.induct*) |
39 val raw_induct : thm (*raw induction rule from Fp.induct*) |
40 val rec_names : string list (*names of recursive sets*) |
40 val rec_names : string list (*names of recursive sets*) |
41 end; |
41 end; |
42 |
42 |
43 (*prove intr/elim rules for a fixedpoint definition*) |
43 (*prove intr/elim rules for a fixedpoint definition*) |
44 functor Intr_elim_Fun |
44 functor Intr_elim_Fun |
45 (structure Inductive: sig include INDUCTIVE_ARG INDUCTIVE_I end |
45 (structure Inductive: sig include INDUCTIVE_ARG INDUCTIVE_I end |
50 val rec_names = map (#1 o dest_Const o head_of) Inductive.rec_tms; |
50 val rec_names = map (#1 o dest_Const o head_of) Inductive.rec_tms; |
51 val big_rec_name = space_implode "_" rec_names; |
51 val big_rec_name = space_implode "_" rec_names; |
52 |
52 |
53 val _ = deny (big_rec_name mem map ! (stamps_of_thy Inductive.thy)) |
53 val _ = deny (big_rec_name mem map ! (stamps_of_thy Inductive.thy)) |
54 ("Definition " ^ big_rec_name ^ |
54 ("Definition " ^ big_rec_name ^ |
55 " would clash with the theory of the same name!"); |
55 " would clash with the theory of the same name!"); |
56 |
56 |
57 (*fetch fp definitions from the theory*) |
57 (*fetch fp definitions from the theory*) |
58 val big_rec_def::part_rec_defs = |
58 val big_rec_def::part_rec_defs = |
59 map (get_def Inductive.thy) |
59 map (get_def Inductive.thy) |
60 (case rec_names of [_] => rec_names | _ => big_rec_name::rec_names); |
60 (case rec_names of [_] => rec_names | _ => big_rec_name::rec_names); |
71 val bnd_mono = |
71 val bnd_mono = |
72 prove_goalw_cterm [] |
72 prove_goalw_cterm [] |
73 (cterm_of sign (Ind_Syntax.mk_tprop (Fp.bnd_mono $ dom_sum $ fp_abs))) |
73 (cterm_of sign (Ind_Syntax.mk_tprop (Fp.bnd_mono $ dom_sum $ fp_abs))) |
74 (fn _ => |
74 (fn _ => |
75 [rtac (Collect_subset RS bnd_monoI) 1, |
75 [rtac (Collect_subset RS bnd_monoI) 1, |
76 REPEAT (ares_tac (basic_monos @ Inductive.monos) 1)]); |
76 REPEAT (ares_tac (basic_monos @ Inductive.monos) 1)]); |
77 |
77 |
78 val dom_subset = standard (big_rec_def RS Fp.subs); |
78 val dom_subset = standard (big_rec_def RS Fp.subs); |
79 |
79 |
80 val unfold = standard ([big_rec_def, bnd_mono] MRS Fp.Tarski); |
80 val unfold = standard ([big_rec_def, bnd_mono] MRS Fp.Tarski); |
81 |
81 |
108 (*Now solve the equations like Tcons(a,f) = Inl(?b4)*) |
108 (*Now solve the equations like Tcons(a,f) = Inl(?b4)*) |
109 rewrite_goals_tac Inductive.con_defs, |
109 rewrite_goals_tac Inductive.con_defs, |
110 REPEAT (rtac refl 2), |
110 REPEAT (rtac refl 2), |
111 (*Typechecking; this can fail*) |
111 (*Typechecking; this can fail*) |
112 REPEAT (FIRSTGOAL ( dresolve_tac rec_typechecks |
112 REPEAT (FIRSTGOAL ( dresolve_tac rec_typechecks |
113 ORELSE' eresolve_tac (asm_rl::PartE::SigmaE2:: |
113 ORELSE' eresolve_tac (asm_rl::PartE::SigmaE2:: |
114 Inductive.type_elims) |
114 Inductive.type_elims) |
115 ORELSE' hyp_subst_tac)), |
115 ORELSE' hyp_subst_tac)), |
116 DEPTH_SOLVE (swap_res_tac (SigmaI::subsetI::Inductive.type_intrs) 1)]; |
116 DEPTH_SOLVE (swap_res_tac (SigmaI::subsetI::Inductive.type_intrs) 1)]; |
117 |
117 |
118 (*combines disjI1 and disjI2 to access the corresponding nested disjunct...*) |
118 (*combines disjI1 and disjI2 to access the corresponding nested disjunct...*) |
119 val mk_disj_rls = |
119 val mk_disj_rls = |
120 let fun f rl = rl RS disjI1 |
120 let fun f rl = rl RS disjI1 |
121 and g rl = rl RS disjI2 |
121 and g rl = rl RS disjI2 |
122 in accesses_bal(f, g, asm_rl) end; |
122 in accesses_bal(f, g, asm_rl) end; |
123 |
123 |
124 val intrs = map (uncurry (prove_goalw_cterm part_rec_defs)) |
124 val intrs = map (uncurry (prove_goalw_cterm part_rec_defs)) |
125 (map (cterm_of sign) Inductive.intr_tms ~~ |
125 (map (cterm_of sign) Inductive.intr_tms ~~ |
126 map intro_tacsf (mk_disj_rls(length Inductive.intr_tms))); |
126 map intro_tacsf (mk_disj_rls(length Inductive.intr_tms))); |
127 |
127 |
128 (********) |
128 (********) |
129 val _ = writeln " Proving the elimination rule..."; |
129 val _ = writeln " Proving the elimination rule..."; |
130 |
130 |
131 (*Breaks down logical connectives in the monotonic function*) |
131 (*Breaks down logical connectives in the monotonic function*) |
132 val basic_elim_tac = |
132 val basic_elim_tac = |
133 REPEAT (SOMEGOAL (eresolve_tac (Ind_Syntax.elim_rls @ Su.free_SEs) |
133 REPEAT (SOMEGOAL (eresolve_tac (Ind_Syntax.elim_rls @ Su.free_SEs) |
134 ORELSE' bound_hyp_subst_tac)) |
134 ORELSE' bound_hyp_subst_tac)) |
135 THEN prune_params_tac |
135 THEN prune_params_tac |
136 (*Mutual recursion: collapse references to Part(D,h)*) |
136 (*Mutual recursion: collapse references to Part(D,h)*) |
137 THEN fold_tac part_rec_defs; |
137 THEN fold_tac part_rec_defs; |
138 |
138 |
139 in |
139 in |
143 and bnd_mono = bnd_mono |
143 and bnd_mono = bnd_mono |
144 and dom_subset = dom_subset |
144 and dom_subset = dom_subset |
145 and intrs = intrs; |
145 and intrs = intrs; |
146 |
146 |
147 val elim = rule_by_tactic basic_elim_tac |
147 val elim = rule_by_tactic basic_elim_tac |
148 (unfold RS Ind_Syntax.equals_CollectD); |
148 (unfold RS Ind_Syntax.equals_CollectD); |
149 |
149 |
150 (*Applies freeness of the given constructors, which *must* be unfolded by |
150 (*Applies freeness of the given constructors, which *must* be unfolded by |
151 the given defs. Cannot simply use the local con_defs because |
151 the given defs. Cannot simply use the local con_defs because |
152 con_defs=[] for inference systems. |
152 con_defs=[] for inference systems. |
153 String s should have the form t:Si where Si is an inductive set*) |
153 String s should have the form t:Si where Si is an inductive set*) |
154 fun mk_cases defs s = |
154 fun mk_cases defs s = |
155 rule_by_tactic (rewrite_goals_tac defs THEN |
155 rule_by_tactic (rewrite_goals_tac defs THEN |
156 basic_elim_tac THEN |
156 basic_elim_tac THEN |
157 fold_tac defs) |
157 fold_tac defs) |
158 (assume_read Inductive.thy s RS elim); |
158 (assume_read Inductive.thy s RS elim); |
159 |
159 |
160 val raw_induct = standard ([big_rec_def, bnd_mono] MRS Fp.induct) |
160 val raw_induct = standard ([big_rec_def, bnd_mono] MRS Fp.induct) |
161 and rec_names = rec_names |
161 and rec_names = rec_names |
162 end |
162 end |
163 end; |
163 end; |