8 val HOLCF_ss = @{simpset}; |
8 val HOLCF_ss = @{simpset}; |
9 |
9 |
10 signature DOMAIN_THEOREMS = |
10 signature DOMAIN_THEOREMS = |
11 sig |
11 sig |
12 val comp_theorems : |
12 val comp_theorems : |
13 binding * Domain_Library.eq list -> |
13 binding -> binding list -> |
14 binding list -> |
|
15 Domain_Take_Proofs.take_induct_info -> |
14 Domain_Take_Proofs.take_induct_info -> |
16 Domain_Constructors.constr_info list -> |
15 Domain_Constructors.constr_info list -> |
17 theory -> thm list * theory |
16 theory -> thm list * theory |
18 |
17 |
19 val quiet_mode: bool Unsynchronized.ref; |
18 val quiet_mode: bool Unsynchronized.ref; |
152 (constr_infos : Domain_Constructors.constr_info list) |
151 (constr_infos : Domain_Constructors.constr_info list) |
153 (take_info : Domain_Take_Proofs.take_induct_info) |
152 (take_info : Domain_Take_Proofs.take_induct_info) |
154 (take_rews : thm list) |
153 (take_rews : thm list) |
155 (thy : theory) = |
154 (thy : theory) = |
156 let |
155 let |
157 val comp_dname = Sign.full_name thy comp_dbind; |
156 val comp_dname = Binding.name_of comp_dbind; |
158 |
157 |
159 val iso_infos = map #iso_info constr_infos; |
158 val iso_infos = map #iso_info constr_infos; |
160 val exhausts = map #exhaust constr_infos; |
159 val exhausts = map #exhaust constr_infos; |
161 val con_rews = maps #con_rews constr_infos; |
160 val con_rews = maps #con_rews constr_infos; |
162 val {take_consts, take_induct_thms, ...} = take_info; |
161 val {take_consts, take_induct_thms, ...} = take_info; |
279 in bot :: map name_of (#con_specs constr_info) end; |
278 in bot :: map name_of (#con_specs constr_info) end; |
280 in adms @ flat (map2 one_eq bottoms constr_infos) end; |
279 in adms @ flat (map2 one_eq bottoms constr_infos) end; |
281 |
280 |
282 val inducts = Project_Rule.projections (ProofContext.init_global thy) ind; |
281 val inducts = Project_Rule.projections (ProofContext.init_global thy) ind; |
283 fun ind_rule (dname, rule) = |
282 fun ind_rule (dname, rule) = |
284 ((Binding.empty, [rule]), |
283 ((Binding.empty, rule), |
285 [Rule_Cases.case_names case_ns, Induct.induct_type dname]); |
284 [Rule_Cases.case_names case_ns, Induct.induct_type dname]); |
286 |
285 |
287 in |
286 in |
288 thy |
287 thy |
289 |> snd o Global_Theory.add_thmss [ |
288 |> snd o Global_Theory.add_thms [ |
290 ((Binding.qualified true "finite_induct" comp_dbind, [finite_ind]), []), |
289 ((Binding.qualified true "finite_induct" comp_dbind, finite_ind), []), |
291 ((Binding.qualified true "induct" comp_dbind, [ind] ), [])] |
290 ((Binding.qualified true "induct" comp_dbind, ind ), [])] |
292 |> (snd o Global_Theory.add_thmss (map ind_rule (dnames ~~ inducts))) |
291 |> (snd o Global_Theory.add_thms (map ind_rule (dnames ~~ inducts))) |
293 end; (* prove_induction *) |
292 end; (* prove_induction *) |
294 |
293 |
295 (******************************************************************************) |
294 (******************************************************************************) |
296 (************************ bisimulation and coinduction ************************) |
295 (************************ bisimulation and coinduction ************************) |
297 (******************************************************************************) |
296 (******************************************************************************) |
301 (constr_infos : Domain_Constructors.constr_info list) |
300 (constr_infos : Domain_Constructors.constr_info list) |
302 (take_info : Domain_Take_Proofs.take_induct_info) |
301 (take_info : Domain_Take_Proofs.take_induct_info) |
303 (take_rews : thm list list) |
302 (take_rews : thm list list) |
304 (thy : theory) : theory = |
303 (thy : theory) : theory = |
305 let |
304 let |
306 val comp_dname = Sign.full_name thy comp_dbind; |
|
307 |
|
308 val iso_infos = map #iso_info constr_infos; |
305 val iso_infos = map #iso_info constr_infos; |
309 val newTs = map #absT iso_infos; |
306 val newTs = map #absT iso_infos; |
310 |
307 |
311 val {take_consts, take_0_thms, take_lemma_thms, ...} = take_info; |
308 val {take_consts, take_0_thms, take_lemma_thms, ...} = take_info; |
312 |
309 |
421 (******************************************************************************) |
418 (******************************************************************************) |
422 (******************************* main function ********************************) |
419 (******************************* main function ********************************) |
423 (******************************************************************************) |
420 (******************************************************************************) |
424 |
421 |
425 fun comp_theorems |
422 fun comp_theorems |
426 (comp_dbind : binding, eqs : Domain_Library.eq list) |
423 (comp_dbind : binding) |
427 (dbinds : binding list) |
424 (dbinds : binding list) |
428 (take_info : Domain_Take_Proofs.take_induct_info) |
425 (take_info : Domain_Take_Proofs.take_induct_info) |
429 (constr_infos : Domain_Constructors.constr_info list) |
426 (constr_infos : Domain_Constructors.constr_info list) |
430 (thy : theory) = |
427 (thy : theory) = |
431 let |
428 let |
432 val dnames = map (fst o fst) eqs; |
429 val comp_dname = Binding.name_of comp_dbind; |
433 val comp_dname = Sign.full_name thy comp_dbind; |
|
434 |
430 |
435 (* Test for emptiness *) |
431 (* Test for emptiness *) |
|
432 (* FIXME: reimplement emptiness test |
436 local |
433 local |
437 open Domain_Library; |
434 open Domain_Library; |
|
435 val dnames = map (fst o fst) eqs; |
438 val conss = map snd eqs; |
436 val conss = map snd eqs; |
439 fun rec_to ns lazy_rec (n,cons) = forall (exists (fn arg => |
437 fun rec_to ns lazy_rec (n,cons) = forall (exists (fn arg => |
440 is_rec arg andalso not (member (op =) ns (rec_of arg)) andalso |
438 is_rec arg andalso not (member (op =) ns (rec_of arg)) andalso |
441 ((rec_of arg = n andalso not (lazy_rec orelse is_lazy arg)) orelse |
439 ((rec_of arg = n andalso not (lazy_rec orelse is_lazy arg)) orelse |
442 rec_of arg <> n andalso rec_to (rec_of arg::ns) |
440 rec_of arg <> n andalso rec_to (rec_of arg::ns) |
448 else false; |
446 else false; |
449 in |
447 in |
450 val n__eqs = mapn (fn n => fn (_,cons) => (n,cons)) 0 eqs; |
448 val n__eqs = mapn (fn n => fn (_,cons) => (n,cons)) 0 eqs; |
451 val is_emptys = map warn n__eqs; |
449 val is_emptys = map warn n__eqs; |
452 end; |
450 end; |
|
451 *) |
453 |
452 |
454 (* Test for indirect recursion *) |
453 (* Test for indirect recursion *) |
455 local |
454 local |
456 open Domain_Library; |
455 val newTs = map (#absT o #iso_info) constr_infos; |
457 fun indirect_arg arg = |
456 fun indirect_typ (Type (_, Ts)) = |
458 rec_of arg = ~1 andalso Datatype_Aux.is_rec_type (dtyp_of arg); |
457 exists (fn T => member (op =) newTs T orelse indirect_typ T) Ts |
|
458 | indirect_typ _ = false; |
|
459 fun indirect_arg (_, T) = indirect_typ T; |
459 fun indirect_con (_, args) = exists indirect_arg args; |
460 fun indirect_con (_, args) = exists indirect_arg args; |
460 fun indirect_eq (_, cons) = exists indirect_con cons; |
461 fun indirect_eq cons = exists indirect_con cons; |
461 in |
462 in |
462 val is_indirect = exists indirect_eq eqs; |
463 val is_indirect = exists indirect_eq (map #con_specs constr_infos); |
463 val _ = |
464 val _ = |
464 if is_indirect |
465 if is_indirect |
465 then message "Indirect recursion detected, skipping proofs of (co)induction rules" |
466 then message "Indirect recursion detected, skipping proofs of (co)induction rules" |
466 else message ("Proving induction properties of domain "^comp_dname^" ..."); |
467 else message ("Proving induction properties of domain "^comp_dname^" ..."); |
467 end; |
468 end; |