1 (* Title: HOL/ex/Simult.ML |
1 (* Title: HOL/ex/Simult.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 1993 University of Cambridge |
4 Copyright 1993 University of Cambridge |
5 |
5 |
6 Primitives for simultaneous recursive type definitions |
6 Primitives for simultaneous recursive type definitions |
7 includes worked example of trees & forests |
7 includes worked example of trees & forests |
8 |
8 |
16 (*** Monotonicity and unfolding of the function ***) |
16 (*** Monotonicity and unfolding of the function ***) |
17 |
17 |
18 goal Simult.thy "mono(%Z. A <*> Part Z In1 \ |
18 goal Simult.thy "mono(%Z. A <*> Part Z In1 \ |
19 \ <+> ({Numb(0)} <+> Part Z In0 <*> Part Z In1))"; |
19 \ <+> ({Numb(0)} <+> Part Z In0 <*> Part Z In1))"; |
20 by (REPEAT (ares_tac [monoI, subset_refl, usum_mono, uprod_mono, |
20 by (REPEAT (ares_tac [monoI, subset_refl, usum_mono, uprod_mono, |
21 Part_mono] 1)); |
21 Part_mono] 1)); |
22 qed "TF_fun_mono"; |
22 qed "TF_fun_mono"; |
23 |
23 |
24 val TF_unfold = TF_fun_mono RS (TF_def RS def_lfp_Tarski); |
24 val TF_unfold = TF_fun_mono RS (TF_def RS def_lfp_Tarski); |
25 |
25 |
26 goalw Simult.thy [TF_def] "!!A B. A<=B ==> TF(A) <= TF(B)"; |
26 goalw Simult.thy [TF_def] "!!A B. A<=B ==> TF(A) <= TF(B)"; |
42 |
42 |
43 val TF_Rep_defs = [TCONS_def,FNIL_def,FCONS_def,NIL_def,CONS_def]; |
43 val TF_Rep_defs = [TCONS_def,FNIL_def,FCONS_def,NIL_def,CONS_def]; |
44 |
44 |
45 val major::prems = goalw Simult.thy TF_Rep_defs |
45 val major::prems = goalw Simult.thy TF_Rep_defs |
46 "[| i: TF(A); \ |
46 "[| i: TF(A); \ |
47 \ !!M N. [| M: A; N: Part (TF A) In1; R(N) |] ==> R(TCONS M N); \ |
47 \ !!M N. [| M: A; N: Part (TF A) In1; R(N) |] ==> R(TCONS M N); \ |
48 \ R(FNIL); \ |
48 \ R(FNIL); \ |
49 \ !!M N. [| M: Part (TF A) In0; N: Part (TF A) In1; R(M); R(N) \ |
49 \ !!M N. [| M: Part (TF A) In0; N: Part (TF A) In1; R(M); R(N) \ |
50 \ |] ==> R(FCONS M N) \ |
50 \ |] ==> R(FCONS M N) \ |
51 \ |] ==> R(i)"; |
51 \ |] ==> R(i)"; |
52 by (rtac ([TF_def, TF_fun_mono, major] MRS def_induct) 1); |
52 by (rtac ([TF_def, TF_fun_mono, major] MRS def_induct) 1); |
53 by (fast_tac (set_cs addIs (prems@[PartI]) |
53 by (fast_tac (set_cs addIs (prems@[PartI]) |
54 addEs [usumE, uprodE, PartE]) 1); |
54 addEs [usumE, uprodE, PartE]) 1); |
55 qed "TF_induct"; |
55 qed "TF_induct"; |
56 |
56 |
57 (*This lemma replaces a use of subgoal_tac to prove tree_forest_induct*) |
57 (*This lemma replaces a use of subgoal_tac to prove tree_forest_induct*) |
58 val prems = goalw Simult.thy [Part_def] |
58 val prems = goalw Simult.thy [Part_def] |
59 "! M: TF(A). (M: Part (TF A) In0 --> P(M)) & (M: Part (TF A) In1 --> Q(M)) \ |
59 "! M: TF(A). (M: Part (TF A) In0 --> P(M)) & (M: Part (TF A) In1 --> Q(M)) \ |
60 \ ==> (! M: Part (TF A) In0. P(M)) & (! M: Part (TF A) In1. Q(M))"; |
60 \ ==> (! M: Part (TF A) In0. P(M)) & (! M: Part (TF A) In1. Q(M))"; |
61 by (cfast_tac prems 1); |
61 by (cfast_tac prems 1); |
62 qed "TF_induct_lemma"; |
62 qed "TF_induct_lemma"; |
63 |
63 |
64 val uplus_cs = set_cs addSIs [PartI] |
64 val uplus_cs = set_cs addSIs [PartI] |
65 addSDs [In0_inject, In1_inject] |
65 addSDs [In0_inject, In1_inject] |
66 addSEs [In0_neq_In1, In1_neq_In0, PartE]; |
66 addSEs [In0_neq_In1, In1_neq_In0, PartE]; |
67 |
67 |
68 (*Could prove ~ TCONS M N : Part (TF A) In1 etc. *) |
68 (*Could prove ~ TCONS M N : Part (TF A) In1 etc. *) |
69 |
69 |
70 (*Induction on TF with separate predicates P, Q*) |
70 (*Induction on TF with separate predicates P, Q*) |
71 val prems = goalw Simult.thy TF_Rep_defs |
71 val prems = goalw Simult.thy TF_Rep_defs |
82 qed "Tree_Forest_induct"; |
82 qed "Tree_Forest_induct"; |
83 |
83 |
84 (*Induction for the abstract types 'a tree, 'a forest*) |
84 (*Induction for the abstract types 'a tree, 'a forest*) |
85 val prems = goalw Simult.thy [Tcons_def,Fnil_def,Fcons_def] |
85 val prems = goalw Simult.thy [Tcons_def,Fnil_def,Fcons_def] |
86 "[| !!x ts. Q(ts) ==> P(Tcons x ts); \ |
86 "[| !!x ts. Q(ts) ==> P(Tcons x ts); \ |
87 \ Q(Fnil); \ |
87 \ Q(Fnil); \ |
88 \ !!t ts. [| P(t); Q(ts) |] ==> Q(Fcons t ts) \ |
88 \ !!t ts. [| P(t); Q(ts) |] ==> Q(Fcons t ts) \ |
89 \ |] ==> (! t. P(t)) & (! ts. Q(ts))"; |
89 \ |] ==> (! t. P(t)) & (! ts. Q(ts))"; |
90 by (res_inst_tac [("P1","%z.P(Abs_Tree(z))"), |
90 by (res_inst_tac [("P1","%z.P(Abs_Tree(z))"), |
91 ("Q1","%z.Q(Abs_Forest(z))")] |
91 ("Q1","%z.Q(Abs_Forest(z))")] |
92 (Tree_Forest_induct RS conjE) 1); |
92 (Tree_Forest_induct RS conjE) 1); |
93 (*Instantiates ?A1 to range(Leaf). *) |
93 (*Instantiates ?A1 to range(Leaf). *) |
94 by (fast_tac (set_cs addSEs [Rep_Tree_inverse RS subst, |
94 by (fast_tac (set_cs addSEs [Rep_Tree_inverse RS subst, |
95 Rep_Forest_inverse RS subst] |
95 Rep_Forest_inverse RS subst] |
96 addSIs [Rep_Tree,Rep_Forest]) 4); |
96 addSIs [Rep_Tree,Rep_Forest]) 4); |
97 (*Cannot use simplifier: the rewrites work in the wrong direction!*) |
97 (*Cannot use simplifier: the rewrites work in the wrong direction!*) |
98 by (ALLGOALS (fast_tac (set_cs addSEs [Abs_Tree_inverse RS subst, |
98 by (ALLGOALS (fast_tac (set_cs addSEs [Abs_Tree_inverse RS subst, |
99 Abs_Forest_inverse RS subst] |
99 Abs_Forest_inverse RS subst] |
100 addSIs prems))); |
100 addSIs prems))); |
101 qed "tree_forest_induct"; |
101 qed "tree_forest_induct"; |
102 |
102 |
103 |
103 |
104 |
104 |
105 (*** Isomorphisms ***) |
105 (*** Isomorphisms ***) |
130 <+> {Numb(0)} <+> Part (TF A) In0 <*> Part (TF A) In1 ==> c : TF(A) *) |
130 <+> {Numb(0)} <+> Part (TF A) In0 <*> Part (TF A) In1 ==> c : TF(A) *) |
131 val TF_I = TF_unfold RS equalityD2 RS subsetD; |
131 val TF_I = TF_unfold RS equalityD2 RS subsetD; |
132 |
132 |
133 (*For reasoning about the representation*) |
133 (*For reasoning about the representation*) |
134 val TF_Rep_cs = uplus_cs addIs [TF_I, uprodI, usum_In0I, usum_In1I] |
134 val TF_Rep_cs = uplus_cs addIs [TF_I, uprodI, usum_In0I, usum_In1I] |
135 addSEs [Scons_inject]; |
135 addSEs [Scons_inject]; |
136 |
136 |
137 val prems = goalw Simult.thy TF_Rep_defs |
137 val prems = goalw Simult.thy TF_Rep_defs |
138 "[| a: A; M: Part (TF A) In1 |] ==> TCONS a M : Part (TF A) In0"; |
138 "[| a: A; M: Part (TF A) In1 |] ==> TCONS a M : Part (TF A) In0"; |
139 by (fast_tac (TF_Rep_cs addIs prems) 1); |
139 by (fast_tac (TF_Rep_cs addIs prems) 1); |
140 qed "TCONS_I"; |
140 qed "TCONS_I"; |
193 |
193 |
194 (** Injectiveness of Tcons and Fcons **) |
194 (** Injectiveness of Tcons and Fcons **) |
195 |
195 |
196 (*For reasoning about abstract constructors*) |
196 (*For reasoning about abstract constructors*) |
197 val TF_cs = set_cs addSIs [Rep_Tree, Rep_Forest, TCONS_I, FNIL_I, FCONS_I] |
197 val TF_cs = set_cs addSIs [Rep_Tree, Rep_Forest, TCONS_I, FNIL_I, FCONS_I] |
198 addSEs [TCONS_inject, FCONS_inject, |
198 addSEs [TCONS_inject, FCONS_inject, |
199 TCONS_neq_FNIL, FNIL_neq_TCONS, |
199 TCONS_neq_FNIL, FNIL_neq_TCONS, |
200 FCONS_neq_FNIL, FNIL_neq_FCONS, |
200 FCONS_neq_FNIL, FNIL_neq_FCONS, |
201 TCONS_neq_FCONS, FCONS_neq_TCONS] |
201 TCONS_neq_FCONS, FCONS_neq_TCONS] |
202 addSDs [inj_onto_Abs_Tree RS inj_ontoD, |
202 addSDs [inj_onto_Abs_Tree RS inj_ontoD, |
203 inj_onto_Abs_Forest RS inj_ontoD, |
203 inj_onto_Abs_Forest RS inj_ontoD, |
204 inj_Rep_Tree RS injD, inj_Rep_Forest RS injD, |
204 inj_Rep_Tree RS injD, inj_Rep_Forest RS injD, |
205 Leaf_inject]; |
205 Leaf_inject]; |
206 |
206 |
207 goalw Simult.thy [Tcons_def] "(Tcons x xs=Tcons y ys) = (x=y & xs=ys)"; |
207 goalw Simult.thy [Tcons_def] "(Tcons x xs=Tcons y ys) = (x=y & xs=ys)"; |
208 by (fast_tac TF_cs 1); |
208 by (fast_tac TF_cs 1); |
209 qed "Tcons_Tcons_eq"; |
209 qed "Tcons_Tcons_eq"; |
210 bind_thm ("Tcons_inject", (Tcons_Tcons_eq RS iffD1 RS conjE)); |
210 bind_thm ("Tcons_inject", (Tcons_Tcons_eq RS iffD1 RS conjE)); |
231 wf_pred_sexp RS wf_trancl RS (TF_rec_def RS def_wfrec); |
231 wf_pred_sexp RS wf_trancl RS (TF_rec_def RS def_wfrec); |
232 |
232 |
233 (** conversion rules for TF_rec **) |
233 (** conversion rules for TF_rec **) |
234 |
234 |
235 goalw Simult.thy [TCONS_def] |
235 goalw Simult.thy [TCONS_def] |
236 "!!M N. [| M: sexp; N: sexp |] ==> \ |
236 "!!M N. [| M: sexp; N: sexp |] ==> \ |
237 \ TF_rec (TCONS M N) b c d = b M N (TF_rec N b c d)"; |
237 \ TF_rec (TCONS M N) b c d = b M N (TF_rec N b c d)"; |
238 by (rtac (TF_rec_unfold RS trans) 1); |
238 by (rtac (TF_rec_unfold RS trans) 1); |
239 by (simp_tac (!simpset addsimps [Case_In0, Split]) 1); |
239 by (simp_tac (!simpset addsimps [Case_In0, Split]) 1); |
240 by (asm_simp_tac (!simpset addsimps [In0_def]) 1); |
240 by (asm_simp_tac (!simpset addsimps [In0_def]) 1); |
241 qed "TF_rec_TCONS"; |
241 qed "TF_rec_TCONS"; |
244 by (rtac (TF_rec_unfold RS trans) 1); |
244 by (rtac (TF_rec_unfold RS trans) 1); |
245 by (simp_tac (HOL_ss addsimps [Case_In1, List_case_NIL]) 1); |
245 by (simp_tac (HOL_ss addsimps [Case_In1, List_case_NIL]) 1); |
246 qed "TF_rec_FNIL"; |
246 qed "TF_rec_FNIL"; |
247 |
247 |
248 goalw Simult.thy [FCONS_def] |
248 goalw Simult.thy [FCONS_def] |
249 "!!M N. [| M: sexp; N: sexp |] ==> \ |
249 "!!M N. [| M: sexp; N: sexp |] ==> \ |
250 \ TF_rec (FCONS M N) b c d = d M N (TF_rec M b c d) (TF_rec N b c d)"; |
250 \ TF_rec (FCONS M N) b c d = d M N (TF_rec M b c d) (TF_rec N b c d)"; |
251 by (rtac (TF_rec_unfold RS trans) 1); |
251 by (rtac (TF_rec_unfold RS trans) 1); |
252 by (simp_tac (HOL_ss addsimps [Case_In1, List_case_CONS]) 1); |
252 by (simp_tac (HOL_ss addsimps [Case_In1, List_case_CONS]) 1); |
253 by (asm_simp_tac (!simpset addsimps [CONS_def,In1_def]) 1); |
253 by (asm_simp_tac (!simpset addsimps [CONS_def,In1_def]) 1); |
254 qed "TF_rec_FCONS"; |
254 qed "TF_rec_FCONS"; |