1 (* Title: ZF/inductive_package.ML |
1 (* Title: ZF/Tools/inductive_package.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 1994 University of Cambridge |
4 Copyright 1994 University of Cambridge |
5 |
5 |
6 Fixedpoint definition module -- for Inductive/Coinductive Definitions |
6 Fixedpoint definition module -- for Inductive/Coinductive Definitions |
65 intr_specs (monos, con_defs, type_intrs, type_elims) thy = |
65 intr_specs (monos, con_defs, type_intrs, type_elims) thy = |
66 let |
66 let |
67 val _ = Theory.requires thy "Inductive" "(co)inductive definitions"; |
67 val _ = Theory.requires thy "Inductive" "(co)inductive definitions"; |
68 val sign = sign_of thy; |
68 val sign = sign_of thy; |
69 |
69 |
70 val intr_tms = map (#2 o #1) intr_specs; |
70 val (intr_names, intr_tms) = split_list (map fst intr_specs); |
|
71 val case_names = RuleCases.case_names intr_names; |
71 |
72 |
72 (*recT and rec_params should agree for all mutually recursive components*) |
73 (*recT and rec_params should agree for all mutually recursive components*) |
73 val rec_hds = map head_of rec_tms; |
74 val rec_hds = map head_of rec_tms; |
74 |
75 |
75 val dummy = assert_all is_Const rec_hds |
76 val dummy = assert_all is_Const rec_hds |
97 val dummy = assert_all is_Free rec_params |
98 val dummy = assert_all is_Free rec_params |
98 (fn t => "Param in recursion term not a free variable: " ^ |
99 (fn t => "Param in recursion term not a free variable: " ^ |
99 Sign.string_of_term sign t); |
100 Sign.string_of_term sign t); |
100 |
101 |
101 (*** Construct the fixedpoint definition ***) |
102 (*** Construct the fixedpoint definition ***) |
102 val mk_variant = variant (foldr add_term_names (intr_tms,[])); |
103 val mk_variant = variant (foldr add_term_names (intr_tms, [])); |
103 |
104 |
104 val z' = mk_variant"z" and X' = mk_variant"X" and w' = mk_variant"w"; |
105 val z' = mk_variant"z" and X' = mk_variant"X" and w' = mk_variant"w"; |
105 |
106 |
106 fun dest_tprop (Const("Trueprop",_) $ P) = P |
107 fun dest_tprop (Const("Trueprop",_) $ P) = P |
107 | dest_tprop Q = error ("Ill-formed premise of introduction rule: " ^ |
108 | dest_tprop Q = error ("Ill-formed premise of introduction rule: " ^ |
521 |
522 |
522 val induct = CP.split_rule_var(pred_var, elem_type-->FOLogic.oT, induct0) |
523 val induct = CP.split_rule_var(pred_var, elem_type-->FOLogic.oT, induct0) |
523 |> standard |
524 |> standard |
524 and mutual_induct = CP.remove_split mutual_induct_fsplit |
525 and mutual_induct = CP.remove_split mutual_induct_fsplit |
525 |
526 |
526 val (thy', [induct', mutual_induct']) = thy |> |
527 val (thy', [induct', mutual_induct']) = thy |> PureThy.add_thms |
527 PureThy.add_thms [(("induct", induct), [InductAttrib.induct_set_global big_rec_name]), |
528 [(("induct", induct), [case_names, InductAttrib.induct_set_global big_rec_name]), |
528 (("mutual_induct", mutual_induct), [])]; |
529 (("mutual_induct", mutual_induct), [case_names])]; |
529 in (thy', induct', mutual_induct') |
530 in (thy', induct', mutual_induct') |
530 end; (*of induction_rules*) |
531 end; (*of induction_rules*) |
531 |
532 |
532 val raw_induct = standard ([big_rec_def, bnd_mono] MRS Fp.induct) |
533 val raw_induct = standard ([big_rec_def, bnd_mono] MRS Fp.induct) |
533 |
534 |
541 thy2 |
542 thy2 |
542 |> IndCases.declare big_rec_name make_cases |
543 |> IndCases.declare big_rec_name make_cases |
543 |> PureThy.add_thms |
544 |> PureThy.add_thms |
544 [(("bnd_mono", bnd_mono), []), |
545 [(("bnd_mono", bnd_mono), []), |
545 (("dom_subset", dom_subset), []), |
546 (("dom_subset", dom_subset), []), |
546 (("cases", elim), [InductAttrib.cases_set_global big_rec_name])] |
547 (("cases", elim), [case_names, InductAttrib.cases_set_global big_rec_name])] |
547 |>>> (PureThy.add_thmss o map Thm.no_attributes) |
548 |>>> (PureThy.add_thmss o map Thm.no_attributes) |
548 [("defs", defs), |
549 [("defs", defs), |
549 ("intros", intrs)]; |
550 ("intros", intrs)]; |
550 val (thy4, intrs'') = |
551 val (thy4, intrs'') = |
551 thy3 |> PureThy.add_thms |
552 thy3 |> PureThy.add_thms ((intr_names ~~ intrs') ~~ map #2 intr_specs) |
552 (map2 (fn (((bname, _), atts), th) => ((bname, th), atts)) (intr_specs, intrs')) |
|
553 |>> Theory.parent_path; |
553 |>> Theory.parent_path; |
554 in |
554 in |
555 (thy4, |
555 (thy4, |
556 {defs = defs', |
556 {defs = defs', |
557 bnd_mono = bnd_mono', |
557 bnd_mono = bnd_mono', |