src/HOL/Tools/record_package.ML
changeset 12255 93d4972238c7
parent 12247 9b029789aff6
child 12265 6df58e87ec91
equal deleted inserted replaced
12254:78bc1f3462b5 12255:93d4972238c7
    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;
   104 val sndN = "_more";
   110 val sndN = "_more";
   105 val updateN = "_update";
   111 val updateN = "_update";
   106 val makeN = "make";
   112 val makeN = "make";
   107 val extendN = "extend";
   113 val extendN = "extend";
   108 val truncateN = "truncate";
   114 val truncateN = "truncate";
   109 val fieldsN = "fields";
       
   110 
   115 
   111 
   116 
   112 (*see typedef_package.ML*)
   117 (*see typedef_package.ML*)
   113 val RepN = "Rep_";
   118 val RepN = "Rep_";
   114 val AbsN = "Abs_";
   119 val AbsN = "Abs_";
   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' =