7 *) |
7 *) |
8 |
8 |
9 signature DATATYPE_ABS_PROOFS = |
9 signature DATATYPE_ABS_PROOFS = |
10 sig |
10 sig |
11 include DATATYPE_COMMON |
11 include DATATYPE_COMMON |
12 val prove_casedist_thms : config -> string list -> |
12 val prove_casedist_thms : config -> string list -> descr list -> thm -> |
13 descr list -> (string * sort) list -> thm -> |
|
14 attribute list -> theory -> thm list * theory |
13 attribute list -> theory -> thm list * theory |
15 val prove_primrec_thms : config -> string list -> |
14 val prove_primrec_thms : config -> string list -> descr list -> |
16 descr list -> (string * sort) list -> |
15 (string -> thm list) -> thm list list -> thm list list * thm list list -> |
17 (string -> thm list) -> thm list list -> thm list list * thm list list -> |
16 thm -> theory -> (string list * thm list) * theory |
18 thm -> theory -> (string list * thm list) * theory |
17 val prove_case_thms : config -> string list -> descr list -> |
19 val prove_case_thms : config -> string list -> |
18 string list -> thm list -> theory -> (thm list list * string list) * theory |
20 descr list -> (string * sort) list -> |
19 val prove_split_thms : config -> string list -> descr list -> |
21 string list -> thm list -> theory -> (thm list list * string list) * theory |
20 thm list list -> thm list list -> thm list -> thm list list -> theory -> |
22 val prove_split_thms : config -> string list -> |
21 (thm * thm) list * theory |
23 descr list -> (string * sort) list -> |
|
24 thm list list -> thm list list -> thm list -> thm list list -> theory -> |
|
25 (thm * thm) list * theory |
|
26 val prove_nchotomys : config -> string list -> descr list -> |
22 val prove_nchotomys : config -> string list -> descr list -> |
27 (string * sort) list -> thm list -> theory -> thm list * theory |
23 thm list -> theory -> thm list * theory |
28 val prove_weak_case_congs : string list -> descr list -> |
24 val prove_weak_case_congs : string list -> descr list -> theory -> thm list * theory |
29 (string * sort) list -> theory -> thm list * theory |
25 val prove_case_congs : string list -> descr list -> |
30 val prove_case_congs : string list -> |
26 thm list -> thm list list -> theory -> thm list * theory |
31 descr list -> (string * sort) list -> |
|
32 thm list -> thm list list -> theory -> thm list * theory |
|
33 end; |
27 end; |
34 |
28 |
35 structure Datatype_Abs_Proofs: DATATYPE_ABS_PROOFS = |
29 structure Datatype_Abs_Proofs: DATATYPE_ABS_PROOFS = |
36 struct |
30 struct |
37 |
31 |
38 (************************ case distinction theorems ***************************) |
32 (************************ case distinction theorems ***************************) |
39 |
33 |
40 fun prove_casedist_thms (config : Datatype_Aux.config) |
34 fun prove_casedist_thms (config : Datatype_Aux.config) |
41 new_type_names descr sorts induct case_names_exhausts thy = |
35 new_type_names descr induct case_names_exhausts thy = |
42 let |
36 let |
43 val _ = Datatype_Aux.message config "Proving case distinction theorems ..."; |
37 val _ = Datatype_Aux.message config "Proving case distinction theorems ..."; |
44 |
38 |
45 val descr' = flat descr; |
39 val descr' = flat descr; |
46 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
40 val recTs = Datatype_Aux.get_rec_types descr'; |
47 val newTs = take (length (hd descr)) recTs; |
41 val newTs = take (length (hd descr)) recTs; |
48 |
42 |
49 val maxidx = Thm.maxidx_of induct; |
43 val maxidx = Thm.maxidx_of induct; |
50 val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct))); |
44 val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct))); |
51 |
45 |
73 REPEAT ((rtac impI 1) THEN (eresolve_tac prems 1)), |
67 REPEAT ((rtac impI 1) THEN (eresolve_tac prems 1)), |
74 REPEAT (rtac TrueI 1)]) |
68 REPEAT (rtac TrueI 1)]) |
75 end; |
69 end; |
76 |
70 |
77 val casedist_thms = |
71 val casedist_thms = |
78 map_index prove_casedist_thm (newTs ~~ Datatype_Prop.make_casedists descr sorts); |
72 map_index prove_casedist_thm (newTs ~~ Datatype_Prop.make_casedists descr); |
79 in |
73 in |
80 thy |
74 thy |
81 |> Datatype_Aux.store_thms_atts "exhaust" new_type_names |
75 |> Datatype_Aux.store_thms_atts "exhaust" new_type_names |
82 (map single case_names_exhausts) casedist_thms |
76 (map single case_names_exhausts) casedist_thms |
83 end; |
77 end; |
84 |
78 |
85 |
79 |
86 (*************************** primrec combinators ******************************) |
80 (*************************** primrec combinators ******************************) |
87 |
81 |
88 fun prove_primrec_thms (config : Datatype_Aux.config) new_type_names descr sorts |
82 fun prove_primrec_thms (config : Datatype_Aux.config) new_type_names descr |
89 injects_of constr_inject (dist_rewrites, other_dist_rewrites) induct thy = |
83 injects_of constr_inject (dist_rewrites, other_dist_rewrites) induct thy = |
90 let |
84 let |
91 val _ = Datatype_Aux.message config "Constructing primrec combinators ..."; |
85 val _ = Datatype_Aux.message config "Constructing primrec combinators ..."; |
92 |
86 |
93 val big_name = space_implode "_" new_type_names; |
87 val big_name = space_implode "_" new_type_names; |
94 val thy0 = Sign.add_path big_name thy; |
88 val thy0 = Sign.add_path big_name thy; |
95 |
89 |
96 val descr' = flat descr; |
90 val descr' = flat descr; |
97 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
91 val recTs = Datatype_Aux.get_rec_types descr'; |
98 val used = fold Term.add_tfree_namesT recTs []; |
92 val used = fold Term.add_tfree_namesT recTs []; |
99 val newTs = take (length (hd descr)) recTs; |
93 val newTs = take (length (hd descr)) recTs; |
100 |
94 |
101 val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct))); |
95 val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct))); |
102 |
96 |
104 val rec_set_names' = |
98 val rec_set_names' = |
105 if length descr' = 1 then [big_rec_name'] |
99 if length descr' = 1 then [big_rec_name'] |
106 else map (prefix (big_rec_name' ^ "_") o string_of_int) (1 upto length descr'); |
100 else map (prefix (big_rec_name' ^ "_") o string_of_int) (1 upto length descr'); |
107 val rec_set_names = map (Sign.full_bname thy0) rec_set_names'; |
101 val rec_set_names = map (Sign.full_bname thy0) rec_set_names'; |
108 |
102 |
109 val (rec_result_Ts, reccomb_fn_Ts) = Datatype_Prop.make_primrec_Ts descr sorts used; |
103 val (rec_result_Ts, reccomb_fn_Ts) = Datatype_Prop.make_primrec_Ts descr used; |
110 |
104 |
111 val rec_set_Ts = |
105 val rec_set_Ts = |
112 map (fn (T1, T2) => (reccomb_fn_Ts @ [T1, T2]) ---> HOLogic.boolT) (recTs ~~ rec_result_Ts); |
106 map (fn (T1, T2) => (reccomb_fn_Ts @ [T1, T2]) ---> HOLogic.boolT) (recTs ~~ rec_result_Ts); |
113 |
107 |
114 val rec_fns = |
108 val rec_fns = |
137 free1 :: t1s, free2 :: t2s) |
131 free1 :: t1s, free2 :: t2s) |
138 end |
132 end |
139 | _ => (j + 1, k, prems, free1 :: t1s, t2s)) |
133 | _ => (j + 1, k, prems, free1 :: t1s, t2s)) |
140 end; |
134 end; |
141 |
135 |
142 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
136 val Ts = map (Datatype_Aux.typ_of_dtyp descr') cargs; |
143 val (_, _, prems, t1s, t2s) = fold_rev mk_prem (cargs ~~ Ts) (1, 1, [], [], []); |
137 val (_, _, prems, t1s, t2s) = fold_rev mk_prem (cargs ~~ Ts) (1, 1, [], [], []); |
144 |
138 |
145 in |
139 in |
146 (rec_intr_ts @ |
140 (rec_intr_ts @ |
147 [Logic.list_implies (prems, HOLogic.mk_Trueprop |
141 [Logic.list_implies (prems, HOLogic.mk_Trueprop |
266 [rewrite_goals_tac reccomb_defs, |
260 [rewrite_goals_tac reccomb_defs, |
267 rtac @{thm the1_equality} 1, |
261 rtac @{thm the1_equality} 1, |
268 resolve_tac rec_unique_thms 1, |
262 resolve_tac rec_unique_thms 1, |
269 resolve_tac rec_intrs 1, |
263 resolve_tac rec_intrs 1, |
270 REPEAT (rtac allI 1 ORELSE resolve_tac rec_total_thms 1)])) |
264 REPEAT (rtac allI 1 ORELSE resolve_tac rec_total_thms 1)])) |
271 (Datatype_Prop.make_primrecs new_type_names descr sorts thy2); |
265 (Datatype_Prop.make_primrecs new_type_names descr thy2); |
272 in |
266 in |
273 thy2 |
267 thy2 |
274 |> Sign.add_path (space_implode "_" new_type_names) |
268 |> Sign.add_path (space_implode "_" new_type_names) |
275 |> Global_Theory.add_thmss [((Binding.name "recs", rec_thms), [Nitpick_Simps.add])] |
269 |> Global_Theory.add_thmss [((Binding.name "recs", rec_thms), [Nitpick_Simps.add])] |
276 ||> Sign.parent_path |
270 ||> Sign.parent_path |
280 |
274 |
281 |
275 |
282 (***************************** case combinators *******************************) |
276 (***************************** case combinators *******************************) |
283 |
277 |
284 fun prove_case_thms (config : Datatype_Aux.config) |
278 fun prove_case_thms (config : Datatype_Aux.config) |
285 new_type_names descr sorts reccomb_names primrec_thms thy = |
279 new_type_names descr reccomb_names primrec_thms thy = |
286 let |
280 let |
287 val _ = Datatype_Aux.message config "Proving characteristic theorems for case combinators ..."; |
281 val _ = Datatype_Aux.message config "Proving characteristic theorems for case combinators ..."; |
288 |
282 |
289 val thy1 = Sign.add_path (space_implode "_" new_type_names) thy; |
283 val thy1 = Sign.add_path (space_implode "_" new_type_names) thy; |
290 |
284 |
291 val descr' = flat descr; |
285 val descr' = flat descr; |
292 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
286 val recTs = Datatype_Aux.get_rec_types descr'; |
293 val used = fold Term.add_tfree_namesT recTs []; |
287 val used = fold Term.add_tfree_namesT recTs []; |
294 val newTs = take (length (hd descr)) recTs; |
288 val newTs = take (length (hd descr)) recTs; |
295 val T' = TFree (singleton (Name.variant_list used) "'t", HOLogic.typeS); |
289 val T' = TFree (singleton (Name.variant_list used) "'t", HOLogic.typeS); |
296 |
290 |
297 fun mk_dummyT dt = binder_types (Datatype_Aux.typ_of_dtyp descr' sorts dt) ---> T'; |
291 fun mk_dummyT dt = binder_types (Datatype_Aux.typ_of_dtyp descr' dt) ---> T'; |
298 |
292 |
299 val case_dummy_fns = |
293 val case_dummy_fns = |
300 map (fn (_, (_, _, constrs)) => map (fn (_, cargs) => |
294 map (fn (_, (_, _, constrs)) => map (fn (_, cargs) => |
301 let |
295 let |
302 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
296 val Ts = map (Datatype_Aux.typ_of_dtyp descr') cargs; |
303 val Ts' = map mk_dummyT (filter Datatype_Aux.is_rec_type cargs) |
297 val Ts' = map mk_dummyT (filter Datatype_Aux.is_rec_type cargs) |
304 in Const (@{const_name undefined}, Ts @ Ts' ---> T') end) constrs) descr'; |
298 in Const (@{const_name undefined}, Ts @ Ts' ---> T') end) constrs) descr'; |
305 |
299 |
306 val case_names = map (fn s => Sign.full_bname thy1 (s ^ "_case")) new_type_names; |
300 val case_names = map (fn s => Sign.full_bname thy1 (s ^ "_case")) new_type_names; |
307 |
301 |
310 val (case_defs, thy2) = |
304 val (case_defs, thy2) = |
311 fold (fn ((((i, (_, _, constrs)), T), name), recname) => fn (defs, thy) => |
305 fold (fn ((((i, (_, _, constrs)), T), name), recname) => fn (defs, thy) => |
312 let |
306 let |
313 val (fns1, fns2) = split_list (map (fn ((_, cargs), j) => |
307 val (fns1, fns2) = split_list (map (fn ((_, cargs), j) => |
314 let |
308 let |
315 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs; |
309 val Ts = map (Datatype_Aux.typ_of_dtyp descr') cargs; |
316 val Ts' = Ts @ map mk_dummyT (filter Datatype_Aux.is_rec_type cargs); |
310 val Ts' = Ts @ map mk_dummyT (filter Datatype_Aux.is_rec_type cargs); |
317 val frees' = map2 (Datatype_Aux.mk_Free "x") Ts' (1 upto length Ts'); |
311 val frees' = map2 (Datatype_Aux.mk_Free "x") Ts' (1 upto length Ts'); |
318 val frees = take (length cargs) frees'; |
312 val frees = take (length cargs) frees'; |
319 val free = Datatype_Aux.mk_Free "f" (Ts ---> T') j; |
313 val free = Datatype_Aux.mk_Free "f" (Ts ---> T') j; |
320 in |
314 in |
355 |
349 |
356 |
350 |
357 (******************************* case splitting *******************************) |
351 (******************************* case splitting *******************************) |
358 |
352 |
359 fun prove_split_thms (config : Datatype_Aux.config) |
353 fun prove_split_thms (config : Datatype_Aux.config) |
360 new_type_names descr sorts constr_inject dist_rewrites casedist_thms case_thms thy = |
354 new_type_names descr constr_inject dist_rewrites casedist_thms case_thms thy = |
361 let |
355 let |
362 val _ = Datatype_Aux.message config "Proving equations for case splitting ..."; |
356 val _ = Datatype_Aux.message config "Proving equations for case splitting ..."; |
363 |
357 |
364 val descr' = flat descr; |
358 val descr' = flat descr; |
365 val recTs = Datatype_Aux.get_rec_types descr' sorts; |
359 val recTs = Datatype_Aux.get_rec_types descr'; |
366 val newTs = take (length (hd descr)) recTs; |
360 val newTs = take (length (hd descr)) recTs; |
367 |
361 |
368 fun prove_split_thms ((((((t1, t2), inject), dist_rewrites'), exhaustion), case_thms'), T) = |
362 fun prove_split_thms ((((((t1, t2), inject), dist_rewrites'), exhaustion), case_thms'), T) = |
369 let |
363 let |
370 val cert = cterm_of thy; |
364 val cert = cterm_of thy; |
390 |> Datatype_Aux.store_thms "split" new_type_names split_thms |
384 |> Datatype_Aux.store_thms "split" new_type_names split_thms |
391 ||>> Datatype_Aux.store_thms "split_asm" new_type_names split_asm_thms |
385 ||>> Datatype_Aux.store_thms "split_asm" new_type_names split_asm_thms |
392 |-> (fn (thms1, thms2) => pair (thms1 ~~ thms2)) |
386 |-> (fn (thms1, thms2) => pair (thms1 ~~ thms2)) |
393 end; |
387 end; |
394 |
388 |
395 fun prove_weak_case_congs new_type_names descr sorts thy = |
389 fun prove_weak_case_congs new_type_names descr thy = |
396 let |
390 let |
397 fun prove_weak_case_cong t = |
391 fun prove_weak_case_cong t = |
398 Skip_Proof.prove_global thy [] (Logic.strip_imp_prems t) (Logic.strip_imp_concl t) |
392 Skip_Proof.prove_global thy [] (Logic.strip_imp_prems t) (Logic.strip_imp_concl t) |
399 (fn {prems, ...} => EVERY [rtac ((hd prems) RS arg_cong) 1]); |
393 (fn {prems, ...} => EVERY [rtac ((hd prems) RS arg_cong) 1]); |
400 |
394 |
401 val weak_case_congs = |
395 val weak_case_congs = |
402 map prove_weak_case_cong (Datatype_Prop.make_weak_case_congs new_type_names descr sorts thy); |
396 map prove_weak_case_cong (Datatype_Prop.make_weak_case_congs new_type_names descr thy); |
403 |
397 |
404 in thy |> Datatype_Aux.store_thms "weak_case_cong" new_type_names weak_case_congs end; |
398 in thy |> Datatype_Aux.store_thms "weak_case_cong" new_type_names weak_case_congs end; |
405 |
399 |
406 (************************* additional theorems for TFL ************************) |
400 (************************* additional theorems for TFL ************************) |
407 |
401 |
408 fun prove_nchotomys (config : Datatype_Aux.config) |
402 fun prove_nchotomys (config : Datatype_Aux.config) new_type_names descr casedist_thms thy = |
409 new_type_names descr sorts casedist_thms thy = |
|
410 let |
403 let |
411 val _ = Datatype_Aux.message config "Proving additional theorems for TFL ..."; |
404 val _ = Datatype_Aux.message config "Proving additional theorems for TFL ..."; |
412 |
405 |
413 fun prove_nchotomy (t, exhaustion) = |
406 fun prove_nchotomy (t, exhaustion) = |
414 let |
407 let |
422 Datatype_Aux.exh_tac (K exhaustion) 1, |
415 Datatype_Aux.exh_tac (K exhaustion) 1, |
423 ALLGOALS (fn i => tac i (i - 1))]) |
416 ALLGOALS (fn i => tac i (i - 1))]) |
424 end; |
417 end; |
425 |
418 |
426 val nchotomys = |
419 val nchotomys = |
427 map prove_nchotomy (Datatype_Prop.make_nchotomys descr sorts ~~ casedist_thms); |
420 map prove_nchotomy (Datatype_Prop.make_nchotomys descr ~~ casedist_thms); |
428 |
421 |
429 in thy |> Datatype_Aux.store_thms "nchotomy" new_type_names nchotomys end; |
422 in thy |> Datatype_Aux.store_thms "nchotomy" new_type_names nchotomys end; |
430 |
423 |
431 fun prove_case_congs new_type_names descr sorts nchotomys case_thms thy = |
424 fun prove_case_congs new_type_names descr nchotomys case_thms thy = |
432 let |
425 let |
433 fun prove_case_cong ((t, nchotomy), case_rewrites) = |
426 fun prove_case_cong ((t, nchotomy), case_rewrites) = |
434 let |
427 let |
435 val Const ("==>", _) $ tm $ _ = t; |
428 val Const ("==>", _) $ tm $ _ = t; |
436 val Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, _) $ _ $ Ma) = tm; |
429 val Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, _) $ _ $ Ma) = tm; |