8 |
8 |
9 open SList; |
9 open SList; |
10 |
10 |
11 val list_con_defs = [NIL_def, CONS_def]; |
11 val list_con_defs = [NIL_def, CONS_def]; |
12 |
12 |
13 goal SList.thy "list(A) = {Numb(0)} <+> (A <*> list(A))"; |
13 Goal "list(A) = {Numb(0)} <+> (A <*> list(A))"; |
14 let val rew = rewrite_rule list_con_defs in |
14 let val rew = rewrite_rule list_con_defs in |
15 by (fast_tac (claset() addSIs (equalityI :: map rew list.intrs) |
15 by (fast_tac (claset() addSIs (equalityI :: map rew list.intrs) |
16 addEs [rew list.elim]) 1) |
16 addEs [rew list.elim]) 1) |
17 end; |
17 end; |
18 qed "list_unfold"; |
18 qed "list_unfold"; |
19 |
19 |
20 (*This justifies using list in other recursive type definitions*) |
20 (*This justifies using list in other recursive type definitions*) |
21 goalw SList.thy list.defs "!!A B. A<=B ==> list(A) <= list(B)"; |
21 Goalw list.defs "!!A B. A<=B ==> list(A) <= list(B)"; |
22 by (rtac lfp_mono 1); |
22 by (rtac lfp_mono 1); |
23 by (REPEAT (ares_tac basic_monos 1)); |
23 by (REPEAT (ares_tac basic_monos 1)); |
24 qed "list_mono"; |
24 qed "list_mono"; |
25 |
25 |
26 (*Type checking -- list creates well-founded sets*) |
26 (*Type checking -- list creates well-founded sets*) |
27 goalw SList.thy (list_con_defs @ list.defs) "list(sexp) <= sexp"; |
27 Goalw (list_con_defs @ list.defs) "list(sexp) <= sexp"; |
28 by (rtac lfp_lowerbound 1); |
28 by (rtac lfp_lowerbound 1); |
29 by (fast_tac (claset() addIs sexp.intrs@[sexp_In0I,sexp_In1I]) 1); |
29 by (fast_tac (claset() addIs sexp.intrs@[sexp_In0I,sexp_In1I]) 1); |
30 qed "list_sexp"; |
30 qed "list_sexp"; |
31 |
31 |
32 (* A <= sexp ==> list(A) <= sexp *) |
32 (* A <= sexp ==> list(A) <= sexp *) |
47 EVERY [res_inst_tac [("l",a)] list_induct2 M, |
47 EVERY [res_inst_tac [("l",a)] list_induct2 M, |
48 rename_last_tac a ["1"] (M+1)]; |
48 rename_last_tac a ["1"] (M+1)]; |
49 |
49 |
50 (*** Isomorphisms ***) |
50 (*** Isomorphisms ***) |
51 |
51 |
52 goal SList.thy "inj(Rep_list)"; |
52 Goal "inj(Rep_list)"; |
53 by (rtac inj_inverseI 1); |
53 by (rtac inj_inverseI 1); |
54 by (rtac Rep_list_inverse 1); |
54 by (rtac Rep_list_inverse 1); |
55 qed "inj_Rep_list"; |
55 qed "inj_Rep_list"; |
56 |
56 |
57 goal SList.thy "inj_on Abs_list (list(range Leaf))"; |
57 Goal "inj_on Abs_list (list(range Leaf))"; |
58 by (rtac inj_on_inverseI 1); |
58 by (rtac inj_on_inverseI 1); |
59 by (etac Abs_list_inverse 1); |
59 by (etac Abs_list_inverse 1); |
60 qed "inj_on_Abs_list"; |
60 qed "inj_on_Abs_list"; |
61 |
61 |
62 (** Distinctness of constructors **) |
62 (** Distinctness of constructors **) |
63 |
63 |
64 goalw SList.thy list_con_defs "CONS M N ~= NIL"; |
64 Goalw list_con_defs "CONS M N ~= NIL"; |
65 by (rtac In1_not_In0 1); |
65 by (rtac In1_not_In0 1); |
66 qed "CONS_not_NIL"; |
66 qed "CONS_not_NIL"; |
67 bind_thm ("NIL_not_CONS", (CONS_not_NIL RS not_sym)); |
67 bind_thm ("NIL_not_CONS", (CONS_not_NIL RS not_sym)); |
68 |
68 |
69 bind_thm ("CONS_neq_NIL", (CONS_not_NIL RS notE)); |
69 bind_thm ("CONS_neq_NIL", (CONS_not_NIL RS notE)); |
70 val NIL_neq_CONS = sym RS CONS_neq_NIL; |
70 val NIL_neq_CONS = sym RS CONS_neq_NIL; |
71 |
71 |
72 goalw SList.thy [Nil_def,Cons_def] "x # xs ~= Nil"; |
72 Goalw [Nil_def,Cons_def] "x # xs ~= Nil"; |
73 by (rtac (CONS_not_NIL RS (inj_on_Abs_list RS inj_on_contraD)) 1); |
73 by (rtac (CONS_not_NIL RS (inj_on_Abs_list RS inj_on_contraD)) 1); |
74 by (REPEAT (resolve_tac (list.intrs @ [rangeI, Rep_list]) 1)); |
74 by (REPEAT (resolve_tac (list.intrs @ [rangeI, Rep_list]) 1)); |
75 qed "Cons_not_Nil"; |
75 qed "Cons_not_Nil"; |
76 |
76 |
77 bind_thm ("Nil_not_Cons", Cons_not_Nil RS not_sym); |
77 bind_thm ("Nil_not_Cons", Cons_not_Nil RS not_sym); |
78 |
78 |
79 (** Injectiveness of CONS and Cons **) |
79 (** Injectiveness of CONS and Cons **) |
80 |
80 |
81 goalw SList.thy [CONS_def] "(CONS K M=CONS L N) = (K=L & M=N)"; |
81 Goalw [CONS_def] "(CONS K M=CONS L N) = (K=L & M=N)"; |
82 by (fast_tac (claset() addSEs [Scons_inject, make_elim In1_inject]) 1); |
82 by (fast_tac (claset() addSEs [Scons_inject, make_elim In1_inject]) 1); |
83 qed "CONS_CONS_eq"; |
83 qed "CONS_CONS_eq"; |
84 |
84 |
85 (*For reasoning about abstract list constructors*) |
85 (*For reasoning about abstract list constructors*) |
86 AddIs ([Rep_list] @ list.intrs); |
86 AddIs ([Rep_list] @ list.intrs); |
88 AddIffs [CONS_not_NIL, NIL_not_CONS, CONS_CONS_eq]; |
88 AddIffs [CONS_not_NIL, NIL_not_CONS, CONS_CONS_eq]; |
89 |
89 |
90 AddSDs [inj_on_Abs_list RS inj_onD, |
90 AddSDs [inj_on_Abs_list RS inj_onD, |
91 inj_Rep_list RS injD, Leaf_inject]; |
91 inj_Rep_list RS injD, Leaf_inject]; |
92 |
92 |
93 goalw SList.thy [Cons_def] "(x#xs=y#ys) = (x=y & xs=ys)"; |
93 Goalw [Cons_def] "(x#xs=y#ys) = (x=y & xs=ys)"; |
94 by (Fast_tac 1); |
94 by (Fast_tac 1); |
95 qed "Cons_Cons_eq"; |
95 qed "Cons_Cons_eq"; |
96 bind_thm ("Cons_inject2", (Cons_Cons_eq RS iffD1 RS conjE)); |
96 bind_thm ("Cons_inject2", (Cons_Cons_eq RS iffD1 RS conjE)); |
97 |
97 |
98 val [major] = goal SList.thy "CONS M N: list(A) ==> M: A & N: list(A)"; |
98 val [major] = goal SList.thy "CONS M N: list(A) ==> M: A & N: list(A)"; |
111 (*Reasoning about constructors and their freeness*) |
111 (*Reasoning about constructors and their freeness*) |
112 Addsimps list.intrs; |
112 Addsimps list.intrs; |
113 |
113 |
114 AddIffs [Cons_not_Nil, Nil_not_Cons, Cons_Cons_eq]; |
114 AddIffs [Cons_not_Nil, Nil_not_Cons, Cons_Cons_eq]; |
115 |
115 |
116 goal SList.thy "!!N. N: list(A) ==> !M. N ~= CONS M N"; |
116 Goal "!!N. N: list(A) ==> !M. N ~= CONS M N"; |
117 by (etac list.induct 1); |
117 by (etac list.induct 1); |
118 by (ALLGOALS Asm_simp_tac); |
118 by (ALLGOALS Asm_simp_tac); |
119 qed "not_CONS_self"; |
119 qed "not_CONS_self"; |
120 |
120 |
121 goal SList.thy "!x. l ~= x#l"; |
121 Goal "!x. l ~= x#l"; |
122 by (list_ind_tac "l" 1); |
122 by (list_ind_tac "l" 1); |
123 by (ALLGOALS Asm_simp_tac); |
123 by (ALLGOALS Asm_simp_tac); |
124 qed "not_Cons_self2"; |
124 qed "not_Cons_self2"; |
125 |
125 |
126 |
126 |
127 goal SList.thy "(xs ~= []) = (? y ys. xs = y#ys)"; |
127 Goal "(xs ~= []) = (? y ys. xs = y#ys)"; |
128 by (list_ind_tac "xs" 1); |
128 by (list_ind_tac "xs" 1); |
129 by (Simp_tac 1); |
129 by (Simp_tac 1); |
130 by (Asm_simp_tac 1); |
130 by (Asm_simp_tac 1); |
131 by (REPEAT(resolve_tac [exI,refl,conjI] 1)); |
131 by (REPEAT(resolve_tac [exI,refl,conjI] 1)); |
132 qed "neq_Nil_conv2"; |
132 qed "neq_Nil_conv2"; |
133 |
133 |
134 (** Conversion rules for List_case: case analysis operator **) |
134 (** Conversion rules for List_case: case analysis operator **) |
135 |
135 |
136 goalw SList.thy [List_case_def,NIL_def] "List_case c h NIL = c"; |
136 Goalw [List_case_def,NIL_def] "List_case c h NIL = c"; |
137 by (rtac Case_In0 1); |
137 by (rtac Case_In0 1); |
138 qed "List_case_NIL"; |
138 qed "List_case_NIL"; |
139 |
139 |
140 goalw SList.thy [List_case_def,CONS_def] "List_case c h (CONS M N) = h M N"; |
140 Goalw [List_case_def,CONS_def] "List_case c h (CONS M N) = h M N"; |
141 by (Simp_tac 1); |
141 by (Simp_tac 1); |
142 qed "List_case_CONS"; |
142 qed "List_case_CONS"; |
143 |
143 |
144 Addsimps [List_case_NIL, List_case_CONS]; |
144 Addsimps [List_case_NIL, List_case_CONS]; |
145 |
145 |
147 (*** List_rec -- by wf recursion on pred_sexp ***) |
147 (*** List_rec -- by wf recursion on pred_sexp ***) |
148 |
148 |
149 (* The trancl(pred_sexp) is essential because pred_sexp_CONS_I1,2 would not |
149 (* The trancl(pred_sexp) is essential because pred_sexp_CONS_I1,2 would not |
150 hold if pred_sexp^+ were changed to pred_sexp. *) |
150 hold if pred_sexp^+ were changed to pred_sexp. *) |
151 |
151 |
152 goal SList.thy |
152 Goal |
153 "(%M. List_rec M c d) = wfrec (trancl pred_sexp) \ |
153 "(%M. List_rec M c d) = wfrec (trancl pred_sexp) \ |
154 \ (%g. List_case c (%x y. d x y (g y)))"; |
154 \ (%g. List_case c (%x y. d x y (g y)))"; |
155 by (simp_tac (HOL_ss addsimps [List_rec_def]) 1); |
155 by (simp_tac (HOL_ss addsimps [List_rec_def]) 1); |
156 val List_rec_unfold = standard |
156 val List_rec_unfold = standard |
157 ((wf_pred_sexp RS wf_trancl) RS ((result() RS eq_reflection) RS def_wfrec)); |
157 ((wf_pred_sexp RS wf_trancl) RS ((result() RS eq_reflection) RS def_wfrec)); |
162 * |> standard; |
162 * |> standard; |
163 *---------------------------------------------------------------------------*) |
163 *---------------------------------------------------------------------------*) |
164 |
164 |
165 (** pred_sexp lemmas **) |
165 (** pred_sexp lemmas **) |
166 |
166 |
167 goalw SList.thy [CONS_def,In1_def] |
167 Goalw [CONS_def,In1_def] |
168 "!!M. [| M: sexp; N: sexp |] ==> (M, CONS M N) : pred_sexp^+"; |
168 "!!M. [| M: sexp; N: sexp |] ==> (M, CONS M N) : pred_sexp^+"; |
169 by (Asm_simp_tac 1); |
169 by (Asm_simp_tac 1); |
170 qed "pred_sexp_CONS_I1"; |
170 qed "pred_sexp_CONS_I1"; |
171 |
171 |
172 goalw SList.thy [CONS_def,In1_def] |
172 Goalw [CONS_def,In1_def] |
173 "!!M. [| M: sexp; N: sexp |] ==> (N, CONS M N) : pred_sexp^+"; |
173 "!!M. [| M: sexp; N: sexp |] ==> (N, CONS M N) : pred_sexp^+"; |
174 by (Asm_simp_tac 1); |
174 by (Asm_simp_tac 1); |
175 qed "pred_sexp_CONS_I2"; |
175 qed "pred_sexp_CONS_I2"; |
176 |
176 |
177 val [prem] = goal SList.thy |
177 val [prem] = goal SList.thy |
184 prem RSN (2, trans_trancl RS transD)] 1)); |
184 prem RSN (2, trans_trancl RS transD)] 1)); |
185 qed "pred_sexp_CONS_D"; |
185 qed "pred_sexp_CONS_D"; |
186 |
186 |
187 (** Conversion rules for List_rec **) |
187 (** Conversion rules for List_rec **) |
188 |
188 |
189 goal SList.thy "List_rec NIL c h = c"; |
189 Goal "List_rec NIL c h = c"; |
190 by (rtac (List_rec_unfold RS trans) 1); |
190 by (rtac (List_rec_unfold RS trans) 1); |
191 by (Simp_tac 1); |
191 by (Simp_tac 1); |
192 qed "List_rec_NIL"; |
192 qed "List_rec_NIL"; |
193 |
193 |
194 goal SList.thy "!!M. [| M: sexp; N: sexp |] ==> \ |
194 Goal "!!M. [| M: sexp; N: sexp |] ==> \ |
195 \ List_rec (CONS M N) c h = h M N (List_rec N c h)"; |
195 \ List_rec (CONS M N) c h = h M N (List_rec N c h)"; |
196 by (rtac (List_rec_unfold RS trans) 1); |
196 by (rtac (List_rec_unfold RS trans) 1); |
197 by (asm_simp_tac (simpset() addsimps [pred_sexp_CONS_I2]) 1); |
197 by (asm_simp_tac (simpset() addsimps [pred_sexp_CONS_I2]) 1); |
198 qed "List_rec_CONS"; |
198 qed "List_rec_CONS"; |
199 |
199 |
235 by (ALLGOALS(asm_simp_tac (simpset() addsimps ([sexp_A_I,sexp_ListA_I]@prems)))); |
235 by (ALLGOALS(asm_simp_tac (simpset() addsimps ([sexp_A_I,sexp_ListA_I]@prems)))); |
236 qed "List_rec_type"; |
236 qed "List_rec_type"; |
237 |
237 |
238 (** Generalized map functionals **) |
238 (** Generalized map functionals **) |
239 |
239 |
240 goalw SList.thy [Rep_map_def] "Rep_map f Nil = NIL"; |
240 Goalw [Rep_map_def] "Rep_map f Nil = NIL"; |
241 by (rtac list_rec_Nil 1); |
241 by (rtac list_rec_Nil 1); |
242 qed "Rep_map_Nil"; |
242 qed "Rep_map_Nil"; |
243 |
243 |
244 goalw SList.thy [Rep_map_def] |
244 Goalw [Rep_map_def] |
245 "Rep_map f (x#xs) = CONS (f x) (Rep_map f xs)"; |
245 "Rep_map f (x#xs) = CONS (f x) (Rep_map f xs)"; |
246 by (rtac list_rec_Cons 1); |
246 by (rtac list_rec_Cons 1); |
247 qed "Rep_map_Cons"; |
247 qed "Rep_map_Cons"; |
248 |
248 |
249 goalw SList.thy [Rep_map_def] "!!f. (!!x. f(x): A) ==> Rep_map f xs: list(A)"; |
249 Goalw [Rep_map_def] "!!f. (!!x. f(x): A) ==> Rep_map f xs: list(A)"; |
250 by (rtac list_induct2 1); |
250 by (rtac list_induct2 1); |
251 by (ALLGOALS Asm_simp_tac); |
251 by (ALLGOALS Asm_simp_tac); |
252 qed "Rep_map_type"; |
252 qed "Rep_map_type"; |
253 |
253 |
254 goalw SList.thy [Abs_map_def] "Abs_map g NIL = Nil"; |
254 Goalw [Abs_map_def] "Abs_map g NIL = Nil"; |
255 by (rtac List_rec_NIL 1); |
255 by (rtac List_rec_NIL 1); |
256 qed "Abs_map_NIL"; |
256 qed "Abs_map_NIL"; |
257 |
257 |
258 val prems = goalw SList.thy [Abs_map_def] |
258 val prems = goalw SList.thy [Abs_map_def] |
259 "[| M: sexp; N: sexp |] ==> \ |
259 "[| M: sexp; N: sexp |] ==> \ |
301 filter_Nil, filter_Cons]; |
301 filter_Nil, filter_Cons]; |
302 |
302 |
303 |
303 |
304 (** @ - append **) |
304 (** @ - append **) |
305 |
305 |
306 goal SList.thy "(xs@ys)@zs = xs@(ys@zs)"; |
306 Goal "(xs@ys)@zs = xs@(ys@zs)"; |
307 by (list_ind_tac "xs" 1); |
307 by (list_ind_tac "xs" 1); |
308 by (ALLGOALS Asm_simp_tac); |
308 by (ALLGOALS Asm_simp_tac); |
309 qed "append_assoc2"; |
309 qed "append_assoc2"; |
310 |
310 |
311 goal SList.thy "xs @ [] = xs"; |
311 Goal "xs @ [] = xs"; |
312 by (list_ind_tac "xs" 1); |
312 by (list_ind_tac "xs" 1); |
313 by (ALLGOALS Asm_simp_tac); |
313 by (ALLGOALS Asm_simp_tac); |
314 qed "append_Nil4"; |
314 qed "append_Nil4"; |
315 |
315 |
316 (** mem **) |
316 (** mem **) |
317 |
317 |
318 goal SList.thy "x mem (xs@ys) = (x mem xs | x mem ys)"; |
318 Goal "x mem (xs@ys) = (x mem xs | x mem ys)"; |
319 by (list_ind_tac "xs" 1); |
319 by (list_ind_tac "xs" 1); |
320 by (ALLGOALS Asm_simp_tac); |
320 by (ALLGOALS Asm_simp_tac); |
321 qed "mem_append2"; |
321 qed "mem_append2"; |
322 |
322 |
323 goal SList.thy "x mem [x:xs. P(x)] = (x mem xs & P(x))"; |
323 Goal "x mem [x:xs. P(x)] = (x mem xs & P(x))"; |
324 by (list_ind_tac "xs" 1); |
324 by (list_ind_tac "xs" 1); |
325 by (ALLGOALS Asm_simp_tac); |
325 by (ALLGOALS Asm_simp_tac); |
326 qed "mem_filter2"; |
326 qed "mem_filter2"; |
327 |
327 |
328 |
328 |
339 |
339 |
340 (*Rep_map_inverse is obtained via Abs_Rep_map and map_ident*) |
340 (*Rep_map_inverse is obtained via Abs_Rep_map and map_ident*) |
341 |
341 |
342 (** list_case **) |
342 (** list_case **) |
343 |
343 |
344 goal SList.thy |
344 Goal |
345 "P(list_case a f xs) = ((xs=[] --> P(a)) & \ |
345 "P(list_case a f xs) = ((xs=[] --> P(a)) & \ |
346 \ (!y ys. xs=y#ys --> P(f y ys)))"; |
346 \ (!y ys. xs=y#ys --> P(f y ys)))"; |
347 by (list_ind_tac "xs" 1); |
347 by (list_ind_tac "xs" 1); |
348 by (ALLGOALS Asm_simp_tac); |
348 by (ALLGOALS Asm_simp_tac); |
349 qed "split_list_case2"; |
349 qed "split_list_case2"; |
350 |
350 |
351 |
351 |
352 (** Additional mapping lemmas **) |
352 (** Additional mapping lemmas **) |
353 |
353 |
354 goal SList.thy "map (%x. x) xs = xs"; |
354 Goal "map (%x. x) xs = xs"; |
355 by (list_ind_tac "xs" 1); |
355 by (list_ind_tac "xs" 1); |
356 by (ALLGOALS Asm_simp_tac); |
356 by (ALLGOALS Asm_simp_tac); |
357 qed "map_ident2"; |
357 qed "map_ident2"; |
358 |
358 |
359 goal SList.thy "map f (xs@ys) = map f xs @ map f ys"; |
359 Goal "map f (xs@ys) = map f xs @ map f ys"; |
360 by (list_ind_tac "xs" 1); |
360 by (list_ind_tac "xs" 1); |
361 by (ALLGOALS Asm_simp_tac); |
361 by (ALLGOALS Asm_simp_tac); |
362 qed "map_append2"; |
362 qed "map_append2"; |
363 |
363 |
364 goalw SList.thy [o_def] "map (f o g) xs = map f (map g xs)"; |
364 Goalw [o_def] "map (f o g) xs = map f (map g xs)"; |
365 by (list_ind_tac "xs" 1); |
365 by (list_ind_tac "xs" 1); |
366 by (ALLGOALS Asm_simp_tac); |
366 by (ALLGOALS Asm_simp_tac); |
367 qed "map_compose2"; |
367 qed "map_compose2"; |
368 |
368 |
369 goal SList.thy "!!f. (!!x. f(x): sexp) ==> \ |
369 Goal "!!f. (!!x. f(x): sexp) ==> \ |
370 \ Abs_map g (Rep_map f xs) = map (%t. g(f(t))) xs"; |
370 \ Abs_map g (Rep_map f xs) = map (%t. g(f(t))) xs"; |
371 by (list_ind_tac "xs" 1); |
371 by (list_ind_tac "xs" 1); |
372 by (ALLGOALS (asm_simp_tac(simpset() addsimps |
372 by (ALLGOALS (asm_simp_tac(simpset() addsimps |
373 [Rep_map_type, list_sexp RS subsetD]))); |
373 [Rep_map_type, list_sexp RS subsetD]))); |
374 qed "Abs_Rep_map"; |
374 qed "Abs_Rep_map"; |