1 (* Title: HOL/ex/term |
1 (* Title: HOL/ex/Term |
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 1992 University of Cambridge |
4 Copyright 1992 University of Cambridge |
5 |
5 |
6 For term.thy. illustrates List functor |
6 Terms over a given alphabet -- function applications; illustrates list functor |
7 (essentially the same type as in Trees & Forests) |
7 (essentially the same type as in Trees & Forests) |
8 *) |
8 *) |
9 |
9 |
10 open Term; |
10 open Term; |
11 |
11 |
12 (*** Monotonicity and unfolding of the function ***) |
12 (*** Monotonicity and unfolding of the function ***) |
13 |
13 |
14 goal Term.thy "mono(%Z. A <*> List(Z))"; |
14 goal Term.thy "term(A) = A <*> list(term(A))"; |
15 by (REPEAT (ares_tac [monoI, subset_refl, List_mono, uprod_mono] 1)); |
15 by (fast_tac (univ_cs addSIs (equalityI :: term.intrs) |
16 val Term_fun_mono = result(); |
16 addEs [term.elim]) 1); |
|
17 val term_unfold = result(); |
17 |
18 |
18 val Term_unfold = Term_fun_mono RS (Term_def RS def_lfp_Tarski); |
19 (*This justifies using term in other recursive type definitions*) |
|
20 goalw Term.thy term.defs "!!A B. A<=B ==> term(A) <= term(B)"; |
|
21 by (REPEAT (ares_tac ([lfp_mono, list_mono] @ basic_monos) 1)); |
|
22 val term_mono = result(); |
19 |
23 |
20 (*This justifies using Term in other recursive type definitions*) |
24 (** Type checking -- term creates well-founded sets **) |
21 goalw Term.thy [Term_def] "!!A B. A<=B ==> Term(A) <= Term(B)"; |
|
22 by (REPEAT (ares_tac [lfp_mono, subset_refl, List_mono, uprod_mono] 1)); |
|
23 val Term_mono = result(); |
|
24 |
25 |
25 (** Type checking rules -- Term creates well-founded sets **) |
26 goalw Term.thy term.defs "term(sexp) <= sexp"; |
|
27 by (rtac lfp_lowerbound 1); |
|
28 by (fast_tac (univ_cs addIs [sexp.SconsI, list_sexp RS subsetD]) 1); |
|
29 val term_sexp = result(); |
26 |
30 |
27 val prems = goalw Term.thy [Term_def] "Term(Sexp) <= Sexp"; |
31 (* A <= sexp ==> term(A) <= sexp *) |
28 by (rtac lfp_lowerbound 1); |
32 val term_subset_sexp = standard ([term_mono, term_sexp] MRS subset_trans); |
29 by (fast_tac (univ_cs addIs [Sexp_SconsI, List_Sexp RS subsetD]) 1); |
|
30 val Term_Sexp = result(); |
|
31 |
|
32 (* A <= Sexp ==> Term(A) <= Sexp *) |
|
33 val Term_subset_Sexp = standard |
|
34 (Term_mono RS (Term_Sexp RSN (2,subset_trans))); |
|
35 |
33 |
36 |
34 |
37 (** Elimination -- structural induction on the set Term(A) **) |
35 (** Elimination -- structural induction on the set term(A) **) |
38 |
36 |
39 (*Induction for the set Term(A) *) |
37 (*Induction for the set term(A) *) |
40 val [major,minor] = goal Term.thy |
38 val [major,minor] = goal Term.thy |
41 "[| M: Term(A); \ |
39 "[| M: term(A); \ |
42 \ !!x zs. [| x: A; zs: List(Term(A)); zs: List({x.R(x)}) \ |
40 \ !!x zs. [| x: A; zs: list(term(A)); zs: list({x.R(x)}) \ |
43 \ |] ==> R(x$zs) \ |
41 \ |] ==> R(x$zs) \ |
44 \ |] ==> R(M)"; |
42 \ |] ==> R(M)"; |
45 by (rtac (major RS (Term_def RS def_induct)) 1); |
43 by (rtac (major RS term.induct) 1); |
46 by (rtac Term_fun_mono 1); |
44 by (REPEAT (eresolve_tac ([minor] @ |
47 by (REPEAT (eresolve_tac ([uprodE, ssubst, minor] @ |
45 ([Int_lower1,Int_lower2] RL [list_mono RS subsetD])) 1)); |
48 ([Int_lower1,Int_lower2] RL [List_mono RS subsetD])) 1)); |
46 (*Proof could also use mono_Int RS subsetD RS IntE *) |
49 val Term_induct = result(); |
47 val term_induct = result(); |
50 |
48 |
51 (*Induction on Term(A) followed by induction on List *) |
49 (*Induction on term(A) followed by induction on list *) |
52 val major::prems = goal Term.thy |
50 val major::prems = goal Term.thy |
53 "[| M: Term(A); \ |
51 "[| M: term(A); \ |
54 \ !!x. [| x: A |] ==> R(x$NIL); \ |
52 \ !!x. [| x: A |] ==> R(x$NIL); \ |
55 \ !!x z zs. [| x: A; z: Term(A); zs: List(Term(A)); R(x$zs) \ |
53 \ !!x z zs. [| x: A; z: term(A); zs: list(term(A)); R(x$zs) \ |
56 \ |] ==> R(x $ CONS(z,zs)) \ |
54 \ |] ==> R(x $ CONS(z,zs)) \ |
57 \ |] ==> R(M)"; |
55 \ |] ==> R(M)"; |
58 by (rtac (major RS Term_induct) 1); |
56 by (rtac (major RS term_induct) 1); |
59 by (etac List_induct 1); |
57 by (etac list.induct 1); |
60 by (REPEAT (ares_tac prems 1)); |
58 by (REPEAT (ares_tac prems 1)); |
61 val Term_induct2 = result(); |
59 val term_induct2 = result(); |
62 |
60 |
63 (*** Structural Induction on the abstract type 'a term ***) |
61 (*** Structural Induction on the abstract type 'a term ***) |
64 |
62 |
65 val list_all_ss = map_ss addsimps [list_all_Nil, list_all_Cons]; |
63 val list_all_ss = map_ss addsimps [list_all_Nil, list_all_Cons]; |
66 |
64 |
67 val Rep_Term_in_Sexp = |
65 val Rep_term_in_sexp = |
68 Rep_Term RS (range_Leaf_subset_Sexp RS Term_subset_Sexp RS subsetD); |
66 Rep_term RS (range_Leaf_subset_sexp RS term_subset_sexp RS subsetD); |
69 |
67 |
70 (*Induction for the abstract type 'a term*) |
68 (*Induction for the abstract type 'a term*) |
71 val prems = goalw Term.thy [App_def,Rep_TList_def,Abs_TList_def] |
69 val prems = goalw Term.thy [App_def,Rep_Tlist_def,Abs_Tlist_def] |
72 "[| !!x ts. list_all(R,ts) ==> R(App(x,ts)) \ |
70 "[| !!x ts. list_all(R,ts) ==> R(App(x,ts)) \ |
73 \ |] ==> R(t)"; |
71 \ |] ==> R(t)"; |
74 by (rtac (Rep_Term_inverse RS subst) 1); (*types force good instantiation*) |
72 by (rtac (Rep_term_inverse RS subst) 1); (*types force good instantiation*) |
75 by (res_inst_tac [("P","Rep_Term(t) : Sexp")] conjunct2 1); |
73 by (res_inst_tac [("P","Rep_term(t) : sexp")] conjunct2 1); |
76 by (rtac (Rep_Term RS Term_induct) 1); |
74 by (rtac (Rep_term RS term_induct) 1); |
77 by (REPEAT (ares_tac [conjI, Sexp_SconsI, Term_subset_Sexp RS |
75 by (REPEAT (ares_tac [conjI, sexp.SconsI, term_subset_sexp RS |
78 List_subset_Sexp,range_Leaf_subset_Sexp] 1 |
76 list_subset_sexp, range_Leaf_subset_sexp] 1 |
79 ORELSE etac rev_subsetD 1)); |
77 ORELSE etac rev_subsetD 1)); |
80 by (eres_inst_tac [("A1","Term(?u)"), ("f1","Rep_Term"), ("g1","Abs_Term")] |
78 by (eres_inst_tac [("A1","term(?u)"), ("f1","Rep_term"), ("g1","Abs_term")] |
81 (Abs_map_inverse RS subst) 1); |
79 (Abs_map_inverse RS subst) 1); |
82 by (rtac (range_Leaf_subset_Sexp RS Term_subset_Sexp) 1); |
80 by (rtac (range_Leaf_subset_sexp RS term_subset_sexp) 1); |
83 by (etac Abs_Term_inverse 1); |
81 by (etac Abs_term_inverse 1); |
84 by (etac rangeE 1); |
82 by (etac rangeE 1); |
85 by (hyp_subst_tac 1); |
83 by (hyp_subst_tac 1); |
86 by (resolve_tac prems 1); |
84 by (resolve_tac prems 1); |
87 by (etac List_induct 1); |
85 by (etac list.induct 1); |
88 by (etac CollectE 2); |
86 by (etac CollectE 2); |
89 by (stac Abs_map_CONS 2); |
87 by (stac Abs_map_CONS 2); |
90 by (etac conjunct1 2); |
88 by (etac conjunct1 2); |
91 by (etac rev_subsetD 2); |
89 by (etac rev_subsetD 2); |
92 by (rtac List_subset_Sexp 2); |
90 by (rtac list_subset_sexp 2); |
93 by (fast_tac set_cs 2); |
91 by (fast_tac set_cs 2); |
94 by (ALLGOALS (asm_simp_tac list_all_ss)); |
92 by (ALLGOALS (asm_simp_tac list_all_ss)); |
95 val term_induct = result(); |
93 val term_induct = result(); |
96 |
94 |
97 (*Induction for the abstract type 'a term*) |
95 (*Induction for the abstract type 'a term*) |
109 fun term_ind2_tac a i = |
107 fun term_ind2_tac a i = |
110 EVERY [res_inst_tac [("t",a)] term_induct2 i, |
108 EVERY [res_inst_tac [("t",a)] term_induct2 i, |
111 rename_last_tac a ["1","s"] (i+1)]; |
109 rename_last_tac a ["1","s"] (i+1)]; |
112 |
110 |
113 |
111 |
114 (** Introduction rule for Term **) |
|
115 |
112 |
116 (* c : A <*> List(Term(A)) ==> c : Term(A) *) |
113 (*** Term_rec -- by wf recursion on pred_sexp ***) |
117 val TermI = standard (Term_unfold RS equalityD2 RS subsetD); |
|
118 |
|
119 (*The constant APP is not declared; it is simply . *) |
|
120 val prems = goal Term.thy "[| M: A; N : List(Term(A)) |] ==> M$N : Term(A)"; |
|
121 by (REPEAT (resolve_tac (prems@[TermI, ListI, uprodI]) 1)); |
|
122 val APP_I = result(); |
|
123 |
|
124 |
|
125 (*** Term_rec -- by wf recursion on pred_Sexp ***) |
|
126 |
114 |
127 val Term_rec_unfold = |
115 val Term_rec_unfold = |
128 wf_pred_Sexp RS wf_trancl RS (Term_rec_def RS def_wfrec); |
116 wf_pred_sexp RS wf_trancl RS (Term_rec_def RS def_wfrec); |
129 |
117 |
130 (** conversion rules **) |
118 (** conversion rules **) |
131 |
119 |
132 val [prem] = goal Term.thy |
120 val [prem] = goal Term.thy |
133 "N: List(Term(A)) ==> \ |
121 "N: list(term(A)) ==> \ |
134 \ !M. <N,M>: pred_Sexp^+ --> \ |
122 \ !M. <N,M>: pred_sexp^+ --> \ |
135 \ Abs_map(cut(h, pred_Sexp^+, M), N) = \ |
123 \ Abs_map(cut(h, pred_sexp^+, M), N) = \ |
136 \ Abs_map(h,N)"; |
124 \ Abs_map(h,N)"; |
137 by (rtac (prem RS List_induct) 1); |
125 by (rtac (prem RS list.induct) 1); |
138 by (simp_tac list_all_ss 1); |
126 by (simp_tac list_all_ss 1); |
139 by (strip_tac 1); |
127 by (strip_tac 1); |
140 by (etac (pred_Sexp_CONS_D RS conjE) 1); |
128 by (etac (pred_sexp_CONS_D RS conjE) 1); |
141 by (asm_simp_tac (list_all_ss addsimps [trancl_pred_SexpD1, cut_apply]) 1); |
129 by (asm_simp_tac (list_all_ss addsimps [trancl_pred_sexpD1, cut_apply]) 1); |
142 val Abs_map_lemma = result(); |
130 val Abs_map_lemma = result(); |
143 |
131 |
144 val [prem1,prem2,A_subset_Sexp] = goal Term.thy |
132 val [prem1,prem2,A_subset_sexp] = goal Term.thy |
145 "[| M: Sexp; N: List(Term(A)); A<=Sexp |] ==> \ |
133 "[| M: sexp; N: list(term(A)); A<=sexp |] ==> \ |
146 \ Term_rec(M$N, d) = d(M, N, Abs_map(%Z. Term_rec(Z,d), N))"; |
134 \ Term_rec(M$N, d) = d(M, N, Abs_map(%Z. Term_rec(Z,d), N))"; |
147 by (rtac (Term_rec_unfold RS trans) 1); |
135 by (rtac (Term_rec_unfold RS trans) 1); |
148 by (simp_tac (HOL_ss addsimps |
136 by (simp_tac (HOL_ss addsimps |
149 [Split, |
137 [Split, |
150 prem2 RS Abs_map_lemma RS spec RS mp, pred_SexpI2 RS r_into_trancl, |
138 prem2 RS Abs_map_lemma RS spec RS mp, pred_sexpI2 RS r_into_trancl, |
151 prem1, prem2 RS rev_subsetD, List_subset_Sexp, |
139 prem1, prem2 RS rev_subsetD, list_subset_sexp, |
152 Term_subset_Sexp, A_subset_Sexp])1); |
140 term_subset_sexp, A_subset_sexp])1); |
153 val Term_rec = result(); |
141 val Term_rec = result(); |
154 |
142 |
155 (*** term_rec -- by Term_rec ***) |
143 (*** term_rec -- by Term_rec ***) |
156 |
144 |
157 local |
145 local |
158 val Rep_map_type1 = read_instantiate_sg (sign_of Term.thy) |
146 val Rep_map_type1 = read_instantiate_sg (sign_of Term.thy) |
159 [("f","Rep_Term")] Rep_map_type; |
147 [("f","Rep_term")] Rep_map_type; |
160 val Rep_TList = Rep_Term RS Rep_map_type1; |
148 val Rep_Tlist = Rep_term RS Rep_map_type1; |
161 val Rep_Term_rec = range_Leaf_subset_Sexp RSN (2,Rep_TList RSN(2,Term_rec)); |
149 val Rep_Term_rec = range_Leaf_subset_sexp RSN (2,Rep_Tlist RSN(2,Term_rec)); |
162 |
150 |
163 (*Now avoids conditional rewriting with the premise N: List(Term(A)), |
151 (*Now avoids conditional rewriting with the premise N: list(term(A)), |
164 since A will be uninstantiated and will cause rewriting to fail. *) |
152 since A will be uninstantiated and will cause rewriting to fail. *) |
165 val term_rec_ss = HOL_ss |
153 val term_rec_ss = HOL_ss |
166 addsimps [Rep_TList RS (rangeI RS APP_I RS Abs_Term_inverse), |
154 addsimps [Rep_Tlist RS (rangeI RS term.APP_I RS Abs_term_inverse), |
167 Rep_Term_in_Sexp, Rep_Term_rec, Rep_Term_inverse, |
155 Rep_term_in_sexp, Rep_Term_rec, Rep_term_inverse, |
168 inj_Leaf, Inv_f_f, |
156 inj_Leaf, Inv_f_f, |
169 Abs_Rep_map, map_ident, Sexp_LeafI] |
157 Abs_Rep_map, map_ident, sexp.LeafI] |
170 in |
158 in |
171 |
159 |
172 val term_rec = prove_goalw Term.thy |
160 val term_rec = prove_goalw Term.thy |
173 [term_rec_def, App_def, Rep_TList_def, Abs_TList_def] |
161 [term_rec_def, App_def, Rep_Tlist_def, Abs_Tlist_def] |
174 "term_rec(App(f,ts), d) = d(f, ts, map (%t. term_rec(t,d), ts))" |
162 "term_rec(App(f,ts), d) = d(f, ts, map (%t. term_rec(t,d), ts))" |
175 (fn _ => [simp_tac term_rec_ss 1]) |
163 (fn _ => [simp_tac term_rec_ss 1]) |
176 |
164 |
177 end; |
165 end; |