61 |
61 |
62 val quiet_mode = ref false; |
62 val quiet_mode = ref false; |
63 fun message s = if ! quiet_mode then () else writeln s; |
63 fun message s = if ! quiet_mode then () else writeln s; |
64 |
64 |
65 |
65 |
66 (* fundamental syntax *) |
66 (* syntax *) |
67 |
67 |
68 fun prune n xs = Library.drop (n, xs); |
68 fun prune n xs = Library.drop (n, xs); |
69 |
|
70 fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname); |
69 fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname); |
71 |
70 |
72 val Trueprop = HOLogic.mk_Trueprop; |
71 val Trueprop = HOLogic.mk_Trueprop; |
73 fun All xs t = Term.list_all_free (xs, t); |
72 fun All xs t = Term.list_all_free (xs, t); |
74 |
73 |
80 val (op :==) = Logic.mk_defpair; |
79 val (op :==) = Logic.mk_defpair; |
81 val (op ===) = Trueprop o HOLogic.mk_eq; |
80 val (op ===) = Trueprop o HOLogic.mk_eq; |
82 val (op ==>) = Logic.mk_implies; |
81 val (op ==>) = Logic.mk_implies; |
83 |
82 |
84 |
83 |
85 (* proof tools *) |
84 (* attributes *) |
|
85 |
|
86 val case_names_fields = RuleCases.case_names ["fields"]; |
|
87 fun induct_type_global name = [case_names_fields, InductAttrib.induct_type_global name]; |
|
88 fun cases_type_global name = [case_names_fields, InductAttrib.cases_type_global name]; |
|
89 |
|
90 |
|
91 (* tactics *) |
86 |
92 |
87 fun simp_all_tac ss simps = ALLGOALS (Simplifier.asm_full_simp_tac (ss addsimps simps)); |
93 fun simp_all_tac ss simps = ALLGOALS (Simplifier.asm_full_simp_tac (ss addsimps simps)); |
88 |
94 |
89 fun try_param_tac x s rule i st = |
95 fun try_param_tac x s rule i st = |
90 res_inst_tac [(x, (case Tactic.innermost_params i st of [] => s | (p, _) :: _ => p))] rule i st; |
96 res_inst_tac [(x, (case Tactic.innermost_params i st of [] => s | (p, _) :: _ => p))] rule i st; |
460 fun add_parents thy None parents = parents |
465 fun add_parents thy None parents = parents |
461 | add_parents thy (Some (types, name)) parents = |
466 | add_parents thy (Some (types, name)) parents = |
462 let |
467 let |
463 val sign = Theory.sign_of thy; |
468 val sign = Theory.sign_of thy; |
464 fun err msg = error (msg ^ " parent record " ^ quote name); |
469 fun err msg = error (msg ^ " parent record " ^ quote name); |
465 |
470 |
466 val {args, parent, fields, field_inducts, field_cases, simps} = |
471 val {args, parent, fields, field_inducts, field_cases, simps} = |
467 (case get_record thy name of Some info => info | None => err "Unknown"); |
472 (case get_record thy name of Some info => info | None => err "Unknown"); |
468 val _ = if length types <> length args then err "Bad number of arguments for" else (); |
473 val _ = if length types <> length args then err "Bad number of arguments for" else (); |
469 |
474 |
470 fun bad_inst ((x, S), T) = |
475 fun bad_inst ((x, S), T) = |
471 if Sign.of_sort sign (T, S) then None else Some x |
476 if Sign.of_sort sign (T, S) then None else Some x |
472 val bads = mapfilter bad_inst (args ~~ types); |
477 val bads = mapfilter bad_inst (args ~~ types); |
473 |
478 |
474 val inst = map fst args ~~ types; |
479 val inst = map fst args ~~ types; |
475 val subst = Term.map_type_tfree (fn (x, _) => the (assoc (inst, x))); |
480 val subst = Term.map_type_tfree (fn (x, _) => the (assoc (inst, x))); |
476 val parent' = apsome (apfst (map subst)) parent; |
481 val parent' = apsome (apfst (map subst)) parent; |
477 val fields' = map (apsnd subst) fields; |
482 val fields' = map (apsnd subst) fields; |
478 in |
483 in |
479 if not (null bads) then |
484 conditional (not (null bads)) (fn () => |
480 err ("Ill-sorted instantiation of " ^ commas bads ^ " in") |
485 err ("Ill-sorted instantiation of " ^ commas bads ^ " in")); |
481 else add_parents thy parent' |
486 add_parents thy parent' |
482 (make_parent_info name fields' field_inducts field_cases simps :: parents) |
487 (make_parent_info name fields' field_inducts field_cases simps :: parents) |
483 end; |
488 end; |
484 |
489 |
485 |
490 |
486 |
491 |
545 val record_split_method = |
550 val record_split_method = |
546 ("record_split", Method.no_args (Method.SIMPLE_METHOD' HEADGOAL record_split_tac), |
551 ("record_split", Method.no_args (Method.SIMPLE_METHOD' HEADGOAL record_split_tac), |
547 "split record fields"); |
552 "split record fields"); |
548 |
553 |
549 |
554 |
|
555 |
550 (** internal theory extenders **) |
556 (** internal theory extenders **) |
551 |
557 |
552 (* field_typedefs *) |
558 (* field_typedefs *) |
553 |
559 |
554 fun field_typedefs zeta moreT names theory = |
560 fun field_typedefs zeta moreT names theory = |
692 val r_parent = if null parent_fields then [] else [Free (rN, hd parentT)]; |
698 val r_parent = if null parent_fields then [] else [Free (rN, hd parentT)]; |
693 |
699 |
694 fun rec_schemeT n = mk_recordT (prune n all_fields, moreT); |
700 fun rec_schemeT n = mk_recordT (prune n all_fields, moreT); |
695 fun rec_scheme n = mk_record (prune n all_named_vars, more); |
701 fun rec_scheme n = mk_record (prune n all_named_vars, more); |
696 fun recT n = mk_recordT (prune n all_fields, HOLogic.unitT); |
702 fun recT n = mk_recordT (prune n all_fields, HOLogic.unitT); |
697 fun rec_ n = mk_record (prune n all_named_vars, HOLogic.unit); |
703 fun rec_ n = mk_record (prune n all_named_vars, HOLogic.unit); |
698 fun r_scheme n = Free (rN, rec_schemeT n); |
704 fun r_scheme n = Free (rN, rec_schemeT n); |
699 fun r n = Free (rN, recT n); |
705 fun r n = Free (rN, recT n); |
700 |
706 |
701 |
707 |
702 (* prepare print translation functions *) |
708 (* prepare print translation functions *) |
792 (*cases*) |
798 (*cases*) |
793 val C = Trueprop (Free (variant all_xs_more "C", HOLogic.boolT)); |
799 val C = Trueprop (Free (variant all_xs_more "C", HOLogic.boolT)); |
794 fun cases_scheme_prop n = |
800 fun cases_scheme_prop n = |
795 All (prune n all_xs_more ~~ prune n all_types_more) |
801 All (prune n all_xs_more ~~ prune n all_types_more) |
796 ((r_scheme n === rec_scheme n) ==> C) ==> C; |
802 ((r_scheme n === rec_scheme n) ==> C) ==> C; |
797 fun cases_prop n = |
803 fun cases_prop n = All (prune n all_xs ~~ prune n all_types) ((r n === rec_ n) ==> C) ==> C; |
798 All (prune n all_xs ~~ prune n all_types) ((r n === rec_ n) ==> C) ==> C; |
|
799 |
804 |
800 |
805 |
801 (* 1st stage: fields_thy *) |
806 (* 1st stage: fields_thy *) |
802 |
807 |
803 val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) = |
808 val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) = |
815 |
820 |
816 val (defs_thy, (((sel_defs, update_defs), derived_defs))) = |
821 val (defs_thy, (((sel_defs, update_defs), derived_defs))) = |
817 fields_thy |
822 fields_thy |
818 |> add_record_splits named_splits |
823 |> add_record_splits named_splits |
819 |> Theory.parent_path |
824 |> Theory.parent_path |
820 |> Theory.add_tyabbrs_i recordT_specs (*not made part of record name space!*) |
825 |> Theory.add_tyabbrs_i recordT_specs |
821 |> Theory.add_path bname |
826 |> Theory.add_path bname |
822 |> Theory.add_trfuns ([], [], field_tr's, []) |
827 |> Theory.add_trfuns ([], [], field_tr's, []) |
823 |> (Theory.add_consts_i o map Syntax.no_syn) |
828 |> (Theory.add_consts_i o map Syntax.no_syn) |
824 (sel_decls @ update_decls @ [make_decl, extend_decl, truncate_decl]) |
829 (sel_decls @ update_decls @ [make_decl, extend_decl, truncate_decl]) |
825 |> (PureThy.add_defs_i false o map Thm.no_attributes) sel_specs |
830 |> (PureThy.add_defs_i false o map Thm.no_attributes) sel_specs |
853 |
858 |
854 val induct_scheme0 = induct_scheme 0; |
859 val induct_scheme0 = induct_scheme 0; |
855 val cases_scheme0 = cases_scheme 0; |
860 val cases_scheme0 = cases_scheme 0; |
856 val more_induct_scheme = map induct_scheme ancestry; |
861 val more_induct_scheme = map induct_scheme ancestry; |
857 val more_cases_scheme = map cases_scheme ancestry; |
862 val more_cases_scheme = map cases_scheme ancestry; |
858 |
|
859 val case_names = RuleCases.case_names [fieldsN]; |
|
860 |
863 |
861 val (thms_thy, (([sel_convs', update_convs', sel_defs', update_defs', _], |
864 val (thms_thy, (([sel_convs', update_convs', sel_defs', update_defs', _], |
862 [induct_scheme', cases_scheme']), [more_induct_scheme', more_cases_scheme'])) = |
865 [induct_scheme', cases_scheme']), [more_induct_scheme', more_cases_scheme'])) = |
863 defs_thy |
866 defs_thy |
864 |> (PureThy.add_thmss o map Thm.no_attributes) |
867 |> (PureThy.add_thmss o map Thm.no_attributes) |
866 ("update_convs", update_convs), |
869 ("update_convs", update_convs), |
867 ("select_defs", sel_defs), |
870 ("select_defs", sel_defs), |
868 ("update_defs", update_defs), |
871 ("update_defs", update_defs), |
869 ("derived_defs", derived_defs)] |
872 ("derived_defs", derived_defs)] |
870 |>>> PureThy.add_thms |
873 |>>> PureThy.add_thms |
871 [(("induct_scheme", induct_scheme0), |
874 [(("induct_scheme", induct_scheme0), induct_type_global (suffix schemeN name)), |
872 [case_names, InductAttrib.induct_type_global (suffix schemeN name)]), |
875 (("cases_scheme", cases_scheme0), cases_type_global (suffix schemeN name))] |
873 (("cases_scheme", cases_scheme0), |
876 |>>> PureThy.add_thmss |
874 [case_names, InductAttrib.cases_type_global (suffix schemeN name)])] |
877 [(("more_induct_scheme", more_induct_scheme), induct_type_global ""), |
875 |>>> (PureThy.add_thmss o map Thm.no_attributes) |
878 (("more_cases_scheme", more_cases_scheme), cases_type_global "")]; |
876 [("more_induct_scheme", more_induct_scheme), |
|
877 ("more_cases_scheme", more_cases_scheme)]; |
|
878 |
879 |
879 |
880 |
880 (* 4th stage: more_thms_thy *) |
881 (* 4th stage: more_thms_thy *) |
881 |
882 |
882 val prove_standard = Tactic.prove_standard (Theory.sign_of thms_thy); |
883 val prove_standard = Tactic.prove_standard (Theory.sign_of thms_thy); |
906 THEN simp_all_tac HOL_basic_ss (parent_simps @ sel_convs)) |
907 THEN simp_all_tac HOL_basic_ss (parent_simps @ sel_convs)) |
907 end); |
908 end); |
908 |
909 |
909 val (more_thms_thy, [_, _, equality']) = |
910 val (more_thms_thy, [_, _, equality']) = |
910 thms_thy |> PureThy.add_thms |
911 thms_thy |> PureThy.add_thms |
911 [(("induct", induct0), [case_names, InductAttrib.induct_type_global name]), |
912 [(("induct", induct0), induct_type_global name), |
912 (("cases", cases0), [case_names, InductAttrib.cases_type_global name]), |
913 (("cases", cases0), cases_type_global name), |
913 (("equality", equality), [Classical.xtra_intro_global])] |
914 (("equality", equality), [Classical.xtra_intro_global])] |
914 |>> (#1 oo (PureThy.add_thmss o map Thm.no_attributes)) |
915 |>> (#1 oo PureThy.add_thmss) |
915 [("more_induct", more_induct), |
916 [(("more_induct", more_induct), induct_type_global ""), |
916 ("more_cases", more_cases)]; |
917 (("more_cases", more_cases), cases_type_global "")]; |
917 |
918 |
918 val simps = sel_convs' @ update_convs' @ [equality']; |
919 val simps = sel_convs' @ update_convs' @ [equality']; |
919 val iffs = field_injects; |
920 val iffs = field_injects; |
920 |
921 |
921 val more_thms_thy' = |
922 val more_thms_thy' = |