src/HOL/Tools/record_package.ML
changeset 11927 96f267adc029
parent 11923 929d97ed8c0f
child 11934 6c1bf72430b6
equal deleted inserted replaced
11926:e31f781611b3 11927:96f267adc029
    48 
    48 
    49 val product_typeI = thm "product_typeI";
    49 val product_typeI = thm "product_typeI";
    50 val product_type_inject = thm "product_type_inject";
    50 val product_type_inject = thm "product_type_inject";
    51 val product_type_conv1 = thm "product_type_conv1";
    51 val product_type_conv1 = thm "product_type_conv1";
    52 val product_type_conv2 = thm "product_type_conv2";
    52 val product_type_conv2 = thm "product_type_conv2";
       
    53 val product_type_induct = thm "product_type_induct";
       
    54 val product_type_cases = thm "product_type_cases";
    53 val product_type_split_paired_all = thm "product_type_split_paired_all";
    55 val product_type_split_paired_all = thm "product_type_split_paired_all";
    54 
    56 
    55 
    57 
    56 
    58 
    57 (*** utilities ***)
    59 (*** utilities ***)
    62 fun message s = if ! quiet_mode then () else writeln s;
    64 fun message s = if ! quiet_mode then () else writeln s;
    63 
    65 
    64 
    66 
    65 (* fundamental syntax *)
    67 (* fundamental syntax *)
    66 
    68 
    67 infix 0 :== ===;
    69 fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname);
    68 
    70 
       
    71 val Trueprop = HOLogic.mk_Trueprop;
       
    72 fun All xs t = Term.list_all_free (xs, t);
       
    73 
       
    74 infix 0 :== === ==>;
    69 val (op :==) = Logic.mk_defpair;
    75 val (op :==) = Logic.mk_defpair;
    70 val (op ===) = HOLogic.mk_Trueprop o HOLogic.mk_eq;
    76 val (op ===) = Trueprop o HOLogic.mk_eq;
    71 
    77 val (op ==>) = Logic.mk_implies;
    72 fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname);
    78 
    73 
    79 
    74 
    80 (* proof tools *)
    75 (* proof by simplification *)
    81 
       
    82 fun prove_goal sign goal tacs =
       
    83   Goals.prove_goalw_cterm [] (Thm.cterm_of sign goal) tacs
       
    84   handle ERROR => error ("The error(s) above occurred while trying to prove " ^
       
    85     quote (Sign.string_of_term sign goal));
    76 
    86 
    77 fun prove_simp sign ss tacs simps =
    87 fun prove_simp sign ss tacs simps =
    78   let
    88   let
    79     val ss' = Simplifier.addsimps (ss, simps);
    89     val ss' = Simplifier.addsimps (ss, simps);
    80 
    90     fun prove goal = prove_goal sign goal
    81     fun prove goal =
    91       (K (tacs @ [ALLGOALS (Simplifier.asm_full_simp_tac ss')]));
    82       Goals.prove_goalw_cterm [] (Thm.cterm_of sign goal)
       
    83         (K (tacs @ [ALLGOALS (Simplifier.asm_full_simp_tac ss')]))
       
    84       handle ERROR => error ("The error(s) above occurred while trying to prove "
       
    85         ^ quote (Sign.string_of_term sign goal));
       
    86   in prove end;
    92   in prove end;
    87 
    93 
       
    94 fun try_param_tac x s rule i st =
       
    95   res_inst_tac [(x, (case Tactic.innermost_params i st of [] => s | (p, _) :: _ => p))] rule i st;
       
    96 
    88 
    97 
    89 
    98 
    90 (*** syntax operations ***)
    99 (*** syntax operations ***)
    91 
   100 
    92 (** name components **)
   101 (** name components **)
    93 
   102 
    94 val recordN = "record";
   103 val rN = "r";
    95 val moreN = "more";
   104 val moreN = "more";
    96 val schemeN = "_scheme";
   105 val schemeN = "_scheme";
    97 val field_typeN = "_field_type";
   106 val field_typeN = "_field_type";
    98 val fieldN = "_field";
   107 val fieldN = "_field";
    99 val fstN = "_val";
   108 val fstN = "_val";
   100 val sndN = "_more";
   109 val sndN = "_more";
   101 val updateN = "_update";
   110 val updateN = "_update";
   102 val makeN = "make";
   111 val makeN = "make";
   103 val make_schemeN = "make_scheme";
   112 val make_schemeN = "make_scheme";
       
   113 val recordN = "record";
   104 
   114 
   105 (*see typedef_package.ML*)
   115 (*see typedef_package.ML*)
   106 val RepN = "Rep_";
   116 val RepN = "Rep_";
   107 val AbsN = "Abs_";
   117 val AbsN = "Abs_";
   108 
   118 
   292 val record_type_tr' =
   302 val record_type_tr' =
   293   gen_record_tr' "_field_types" "_field_type" field_typeN
   303   gen_record_tr' "_field_types" "_field_type" field_typeN
   294     (fn Const ("unit", _) => true | _ => false) "_record_type" "_record_type_scheme";
   304     (fn Const ("unit", _) => true | _ => false) "_record_type" "_record_type_scheme";
   295 
   305 
   296 val record_tr' =
   306 val record_tr' =
   297   gen_record_tr' "_fields" "_field" fieldN HOLogic.is_unit "_record" "_record_scheme";
   307   gen_record_tr' "_fields" "_field" fieldN
       
   308     (fn Const ("Unity", _) => true | _ => false) "_record" "_record_scheme";
   298 
   309 
   299 fun record_update_tr' tm =
   310 fun record_update_tr' tm =
   300   let val (ts, u) = gen_fields_tr' "_update" updateN tm in
   311   let val (ts, u) = gen_fields_tr' "_update" updateN tm in
   301     Syntax.const "_record_update" $ u $
   312     Syntax.const "_record_update" $ u $
   302       foldr1 (fn (v, w) => Syntax.const "_updates" $ v $ w) (rev ts)
   313       foldr1 (fn (v, w) => Syntax.const "_updates" $ v $ w) (rev ts)
   322 
   333 
   323 type record_info =
   334 type record_info =
   324  {args: (string * sort) list,
   335  {args: (string * sort) list,
   325   parent: (typ list * string) option,
   336   parent: (typ list * string) option,
   326   fields: (string * typ) list,
   337   fields: (string * typ) list,
   327   simps: thm list};
   338   simps: thm list, induct: thm, cases: thm};
       
   339 
       
   340 fun make_record_info args parent fields simps induct cases =
       
   341  {args = args, parent = parent, fields = fields, simps = simps,
       
   342   induct = induct, cases = cases}: record_info;
   328 
   343 
   329 type parent_info =
   344 type parent_info =
   330  {name: string,
   345  {name: string,
   331   fields: (string * typ) list,
   346   fields: (string * typ) list,
   332   simps: thm list};
   347   simps: thm list, induct: thm, cases: thm};
       
   348 
       
   349 fun make_parent_info name fields simps induct cases =
       
   350  {name = name, fields = fields, simps = simps,
       
   351   induct = induct, cases = cases}: parent_info;
       
   352 
   333 
   353 
   334 
   354 
   335 (* data kind 'HOL/records' *)
   355 (* data kind 'HOL/records' *)
   336 
   356 
   337 type record_data =
   357 type record_data =
   384             [Pretty.block [prt_typ (Type (name, Ts)), Pretty.str " +"]];
   404             [Pretty.block [prt_typ (Type (name, Ts)), Pretty.str " +"]];
   385 
   405 
   386       fun pretty_field (c, T) = Pretty.block
   406       fun pretty_field (c, T) = Pretty.block
   387         [Pretty.str (ext_const c), Pretty.str " ::", Pretty.brk 1, Pretty.quote (prt_typ T)];
   407         [Pretty.str (ext_const c), Pretty.str " ::", Pretty.brk 1, Pretty.quote (prt_typ T)];
   388 
   408 
   389       fun pretty_record (name, {args, parent, fields, simps = _}) = Pretty.block (Pretty.fbreaks
   409       fun pretty_record (name, {args, parent, fields, simps = _, induct = _, cases = _}) =
   390         (Pretty.block [prt_typ (Type (name, map TFree args)), Pretty.str " = "] ::
   410         Pretty.block (Pretty.fbreaks (Pretty.block
       
   411           [prt_typ (Type (name, map TFree args)), Pretty.str " = "] ::
   391           pretty_parent parent @ map pretty_field fields));
   412           pretty_parent parent @ map pretty_field fields));
   392     in
   413     in
   393       map pretty_record (Sign.cond_extern_table sg Sign.typeK recs)
   414       map pretty_record (Sign.cond_extern_table sg Sign.typeK recs)
   394       |> Pretty.chunks |> Pretty.writeln
   415       |> Pretty.chunks |> Pretty.writeln
   395     end;
   416     end;
   450 fun inst_record thy (types, name) =
   471 fun inst_record thy (types, name) =
   451   let
   472   let
   452     val sign = Theory.sign_of thy;
   473     val sign = Theory.sign_of thy;
   453     fun err msg = error (msg ^ " parent record " ^ quote name);
   474     fun err msg = error (msg ^ " parent record " ^ quote name);
   454 
   475 
   455     val {args, parent, fields, simps} =
   476     val {args, parent, fields, simps, induct, cases} =
   456       (case get_record thy name of Some info => info | None => err "Unknown");
   477       (case get_record thy name of Some info => info | None => err "Unknown");
   457     val _ = if length types <> length args then err "Bad number of arguments for" else ();
   478     val _ = if length types <> length args then err "Bad number of arguments for" else ();
   458 
   479 
   459     fun bad_inst ((x, S), T) =
   480     fun bad_inst ((x, S), T) =
   460       if Sign.of_sort sign (T, S) then None else Some x
   481       if Sign.of_sort sign (T, S) then None else Some x
   463     val inst = map fst args ~~ types;
   484     val inst = map fst args ~~ types;
   464     val subst = Term.map_type_tfree (fn (x, _) => the (assoc (inst, x)));
   485     val subst = Term.map_type_tfree (fn (x, _) => the (assoc (inst, x)));
   465   in
   486   in
   466     if not (null bads) then
   487     if not (null bads) then
   467       err ("Ill-sorted instantiation of " ^ commas bads ^ " in")
   488       err ("Ill-sorted instantiation of " ^ commas bads ^ " in")
   468     else (apsome (apfst (map subst)) parent, map (apsnd subst) fields, simps)
   489     else (apsome (apfst (map subst)) parent, map (apsnd subst) fields, simps, induct, cases)
   469   end;
   490   end;
   470 
   491 
   471 fun add_parents thy (None, parents) = parents
   492 fun add_parents thy (None, parents) = parents
   472   | add_parents thy (Some (types, name), parents) =
   493   | add_parents thy (Some (types, name), parents) =
   473       let val (pparent, pfields, psimps) = inst_record thy (types, name)
   494       let val (parent, fields, simps, induct, cases) = inst_record thy (types, name)
   474       in add_parents thy (pparent, {name = name, fields = pfields, simps = psimps} :: parents) end;
   495       in add_parents thy (parent, make_parent_info name fields simps induct cases :: parents) end;
   475 
   496 
   476 
   497 
   477 
   498 
   478 (** record simproc **)
   499 (** record simproc **)
   479 
   500 
   608 
   629 
   609     fun make th = map (fn prod_type => Drule.standard (th OF [prod_type])) prod_types;
   630     fun make th = map (fn prod_type => Drule.standard (th OF [prod_type])) prod_types;
   610 
   631 
   611     val field_injects = make product_type_inject;
   632     val field_injects = make product_type_inject;
   612     val dest_convs = make product_type_conv1 @ make product_type_conv2;
   633     val dest_convs = make product_type_conv1 @ make product_type_conv2;
       
   634     val field_inducts = make product_type_induct;
       
   635     val field_cases = make product_type_cases;
   613     val field_splits = make product_type_split_paired_all;
   636     val field_splits = make product_type_split_paired_all;
   614 
   637 
   615     val thms_thy =
   638     val thms_thy =
   616       defs_thy
   639       defs_thy
   617       |> (#1 oo (PureThy.add_thmss o map Thm.no_attributes))
   640       |> (PureThy.add_thmss o map Thm.no_attributes)
   618         [("field_defs", field_defs),
   641         [("field_defs", field_defs),
   619           ("dest_defs", dest_defs1 @ dest_defs2),
   642           ("dest_defs", dest_defs1 @ dest_defs2),
   620           ("dest_convs", dest_convs),
   643           ("dest_convs", dest_convs),
   621           ("field_splits", field_splits)];
   644           ("field_inducts", field_inducts),
   622 
   645           ("field_cases", field_cases),
   623   in (thms_thy, dest_convs, field_injects, field_splits) end;
   646           ("field_splits", field_splits)] |> #1;
       
   647 
       
   648   in (thms_thy, dest_convs, field_injects, field_splits, field_inducts, field_cases) end;
   624 
   649 
   625 
   650 
   626 (* record_definition *)
   651 (* record_definition *)
   627 
   652 
   628 fun record_definition (args, bname) parent (parents: parent_info list) bfields thy =
   653 fun record_definition (args, bname) parent (parents: parent_info list) bfields thy =
   634 
   659 
   635     (* basic components *)
   660     (* basic components *)
   636 
   661 
   637     val alphas = map fst args;
   662     val alphas = map fst args;
   638     val name = Sign.full_name sign bname;       (*not made part of record name space!*)
   663     val name = Sign.full_name sign bname;       (*not made part of record name space!*)
       
   664 
       
   665     val previous = if null parents then None else Some (last_elem parents);
   639 
   666 
   640     val parent_fields = flat (map #fields parents);
   667     val parent_fields = flat (map #fields parents);
   641     val parent_names = map fst parent_fields;
   668     val parent_names = map fst parent_fields;
   642     val parent_types = map snd parent_fields;
   669     val parent_types = map snd parent_fields;
   643     val parent_len = length parent_fields;
   670     val parent_len = length parent_fields;
   644     val parent_xs = variantlist (map (base o fst) parent_fields, [moreN, recordN]);
   671     val parent_xs = variantlist (map (base o fst) parent_fields, [moreN, rN]);
   645     val parent_vars = ListPair.map Free (parent_xs, parent_types);
   672     val parent_vars = ListPair.map Free (parent_xs, parent_types);
   646     val parent_named_vars = parent_names ~~ parent_vars;
   673     val parent_named_vars = parent_names ~~ parent_vars;
   647 
   674 
   648     val fields = map (apfst full) bfields;
   675     val fields = map (apfst full) bfields;
   649     val names = map fst fields;
   676     val names = map fst fields;
   650     val types = map snd fields;
   677     val types = map snd fields;
   651     val len = length fields;
   678     val len = length fields;
   652     val xs = variantlist (map fst bfields, moreN :: recordN :: parent_xs);
   679     val xs = variantlist (map fst bfields, moreN :: rN :: parent_xs);
   653     val vars = ListPair.map Free (xs, types);
   680     val vars = ListPair.map Free (xs, types);
   654     val named_vars = names ~~ vars;
   681     val named_vars = names ~~ vars;
   655 
   682 
   656     val all_fields = parent_fields @ fields;
   683     val all_fields = parent_fields @ fields;
   657     val all_names = parent_names @ names;
   684     val all_names = parent_names @ names;
   665     val moreT = TFree (zeta, moreS);
   692     val moreT = TFree (zeta, moreS);
   666     val more = Free (moreN, moreT);
   693     val more = Free (moreN, moreT);
   667     val full_moreN = full moreN;
   694     val full_moreN = full moreN;
   668     fun more_part t = mk_more t full_moreN;
   695     fun more_part t = mk_more t full_moreN;
   669     fun more_part_update t x = mk_more_update t (full_moreN, x);
   696     fun more_part_update t x = mk_more_update t (full_moreN, x);
       
   697     val all_types_more = all_types @ [moreT];
       
   698     val all_xs_more = all_xs @ [moreN];
   670 
   699 
   671     val parent_more = funpow parent_len mk_snd;
   700     val parent_more = funpow parent_len mk_snd;
   672     val idxs = 0 upto (len - 1);
   701     val idxs = 0 upto (len - 1);
   673 
   702 
   674     val rec_schemeT = mk_recordT (all_fields, moreT);
   703     val rec_schemeT = mk_recordT (all_fields, moreT);
   675     val rec_scheme = mk_record (all_named_vars, more);
   704     val rec_scheme = mk_record (all_named_vars, more);
   676     val r = Free (recordN, rec_schemeT);
       
   677     val recT = mk_recordT (all_fields, HOLogic.unitT);
   705     val recT = mk_recordT (all_fields, HOLogic.unitT);
       
   706     val rec_ = mk_record (all_named_vars, HOLogic.unit);
       
   707     val r = Free (rN, rec_schemeT);
       
   708     val r' = Free (rN, recT);
   678 
   709 
   679 
   710 
   680     (* prepare print translation functions *)
   711     (* prepare print translation functions *)
   681 
   712 
   682     val field_tr's =
   713     val field_tr's =
   690     val update_decls = map (mk_updateC rec_schemeT) bfields @
   721     val update_decls = map (mk_updateC rec_schemeT) bfields @
   691       [mk_more_updateC rec_schemeT (moreN, moreT)];
   722       [mk_more_updateC rec_schemeT (moreN, moreT)];
   692     val make_decls =
   723     val make_decls =
   693       [(mk_makeC rec_schemeT (make_schemeN, all_types @ [moreT])),
   724       [(mk_makeC rec_schemeT (make_schemeN, all_types @ [moreT])),
   694        (mk_makeC recT (makeN, all_types))];
   725        (mk_makeC recT (makeN, all_types))];
       
   726     val record_decl = (recordN, rec_schemeT --> recT);
   695 
   727 
   696 
   728 
   697     (* prepare definitions *)
   729     (* prepare definitions *)
   698 
   730 
   699     (*record (scheme) type abbreviation*)
   731     (*record (scheme) type abbreviation*)
   720     (*makes*)
   752     (*makes*)
   721     val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT]));
   753     val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT]));
   722     val make = Const (mk_makeC recT (full makeN, all_types));
   754     val make = Const (mk_makeC recT (full makeN, all_types));
   723     val make_specs =
   755     val make_specs =
   724       [list_comb (make_scheme, all_vars) $ more :== rec_scheme,
   756       [list_comb (make_scheme, all_vars) $ more :== rec_scheme,
   725         list_comb (make, all_vars) :== mk_record (all_named_vars, HOLogic.unit)];
   757         list_comb (make, all_vars) :== rec_];
       
   758     val record_spec =
       
   759       Const (full recordN, rec_schemeT --> recT) $ r :== mk_record (all_sels, HOLogic.unit);
   726 
   760 
   727 
   761 
   728     (* prepare propositions *)
   762     (* prepare propositions *)
   729 
   763 
   730     (*selectors*)
   764     (*selectors*)
   744         in [more_part_update rec_scheme more' === mk_record (all_named_vars, more')] end;
   778         in [more_part_update rec_scheme more' === mk_record (all_named_vars, more')] end;
   745 
   779 
   746     (*equality*)
   780     (*equality*)
   747     fun mk_sel_eq (t, T) =
   781     fun mk_sel_eq (t, T) =
   748       let val t' = Term.abstract_over (r, t)
   782       let val t' = Term.abstract_over (r, t)
   749       in HOLogic.mk_Trueprop (HOLogic.eq_const T $ Term.incr_boundvars 1 t' $ t') end;
   783       in Trueprop (HOLogic.eq_const T $ Term.incr_boundvars 1 t' $ t') end;
   750     val sel_eqs = map2 mk_sel_eq (map (mk_sel r) all_names @ [more_part r], all_types @ [moreT]);
   784     val sel_eqs = map2 mk_sel_eq (map (mk_sel r) all_names @ [more_part r], all_types @ [moreT]);
   751     val equality_prop =
   785     val equality_prop =
   752       Term.all rec_schemeT $ (Abs ("r", rec_schemeT,
   786       Term.all rec_schemeT $ (Abs ("r", rec_schemeT,
   753         Term.all rec_schemeT $ (Abs ("r'", rec_schemeT,
   787         Term.all rec_schemeT $ (Abs ("r'", rec_schemeT,
   754           Logic.list_implies (sel_eqs,
   788           Logic.list_implies (sel_eqs,
   755             HOLogic.mk_Trueprop (HOLogic.eq_const rec_schemeT $ Bound 1 $ Bound 0))))));
   789             Trueprop (HOLogic.eq_const rec_schemeT $ Bound 1 $ Bound 0))))));
       
   790 
       
   791     (*induct*)
       
   792     val P = Free ("P", rec_schemeT --> HOLogic.boolT);
       
   793     val P' = Free ("P", recT --> HOLogic.boolT);
       
   794     val induct_scheme_prop =
       
   795       All (all_xs_more ~~ all_types_more) (Trueprop (P $ rec_scheme)) ==> Trueprop (P $ r);
       
   796     val induct_prop = All (all_xs ~~ all_types) (Trueprop (P' $ rec_)) ==> Trueprop (P' $ r');
       
   797 
       
   798     (*cases*)
       
   799     val C = Trueprop (Free (variant all_xs_more "C", HOLogic.boolT));
       
   800     val cases_scheme_prop = All (all_xs_more ~~ all_types_more) ((r === rec_scheme) ==> C) ==> C;
       
   801     val cases_prop = All (all_xs ~~ all_types) ((r' === rec_) ==> C) ==> C;
   756 
   802 
   757 
   803 
   758     (* 1st stage: fields_thy *)
   804     (* 1st stage: fields_thy *)
   759 
   805 
   760     val (fields_thy, field_simps, field_injects, field_splits) =
   806     val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) =
   761       thy
   807       thy
   762       |> Theory.add_path bname
   808       |> Theory.add_path bname
   763       |> field_definitions fields names xs alphas zeta moreT more vars named_vars;
   809       |> field_definitions fields names xs alphas zeta moreT more vars named_vars;
   764 
   810 
   765     val named_splits = map2 (fn (c, th) => (suffix field_typeN c, th)) (names, field_splits);
   811     val named_splits = map2 (fn (c, th) => (suffix field_typeN c, th)) (names, field_splits);
   766 
   812 
   767 
   813 
   768     (* 2nd stage: defs_thy *)
   814     (* 2nd stage: defs_thy *)
   769 
   815 
   770     val (defs_thy, ((sel_defs, update_defs), make_defs)) =
   816     val (defs_thy, (((sel_defs, update_defs), make_defs), [record_def])) =
   771       fields_thy
   817       fields_thy
   772       |> add_record_splits named_splits
   818       |> add_record_splits named_splits
   773       |> Theory.parent_path
   819       |> Theory.parent_path
   774       |> Theory.add_tyabbrs_i recordT_specs     (*not made part of record name space!*)
   820       |> Theory.add_tyabbrs_i recordT_specs     (*not made part of record name space!*)
   775       |> Theory.add_path bname
   821       |> Theory.add_path bname
   776       |> Theory.add_trfuns ([], [], field_tr's, [])
   822       |> Theory.add_trfuns ([], [], field_tr's, [])
   777       |> (Theory.add_consts_i o map Syntax.no_syn)
   823       |> (Theory.add_consts_i o map Syntax.no_syn)
   778         (sel_decls @ update_decls @ make_decls)
   824         (sel_decls @ update_decls @ make_decls @ [record_decl])
   779       |> (PureThy.add_defs_i false o map Thm.no_attributes) sel_specs
   825       |> (PureThy.add_defs_i false o map Thm.no_attributes) sel_specs
   780       |>>> (PureThy.add_defs_i false o map Thm.no_attributes) update_specs
   826       |>>> (PureThy.add_defs_i false o map Thm.no_attributes) update_specs
   781       |>>> (PureThy.add_defs_i false o map Thm.no_attributes) make_specs;
   827       |>>> (PureThy.add_defs_i false o map Thm.no_attributes) make_specs
       
   828       |>>> (PureThy.add_defs_i false o map Thm.no_attributes) [record_spec];
       
   829 
       
   830     val defs_sg = Theory.sign_of defs_thy;
   782 
   831 
   783 
   832 
   784     (* 3rd stage: thms_thy *)
   833     (* 3rd stage: thms_thy *)
   785 
   834 
   786     val parent_simps = flat (map #simps parents);
   835     val parent_simps = flat (map #simps parents);
   787     val prove = prove_simp (Theory.sign_of defs_thy) HOL_basic_ss [];
   836     val prove = prove_simp defs_sg HOL_basic_ss [];
   788     val prove' = prove_simp (Theory.sign_of defs_thy) HOL_ss;
   837     val prove' = prove_simp defs_sg HOL_ss;
   789 
   838 
   790     val sel_convs = map (prove (parent_simps @ sel_defs @ field_simps)) sel_props;
   839     val sel_convs = map (prove (parent_simps @ sel_defs @ field_simps)) sel_props;
   791     val update_convs = map (prove (parent_simps @ update_defs @ sel_convs)) update_props;
   840     val update_convs = map (prove (parent_simps @ update_defs @ sel_convs)) update_props;
   792     val equality =
   841     val equality =
   793       prove' [ALLGOALS record_split_tac] (parent_simps @ sel_convs @ field_injects) equality_prop;
   842       prove' [ALLGOALS record_split_tac] (parent_simps @ sel_convs @ field_injects) equality_prop;
   794 
   843 
   795     val simps = field_simps @ sel_convs @ update_convs @ make_defs @ [equality];
   844     val induct_scheme = prove_goal defs_sg induct_scheme_prop (fn prems =>
       
   845         (case previous of Some {induct, ...} => res_inst_tac [(rN, rN)] induct 1
       
   846         | None => all_tac) :: map (fn rule => try_param_tac "p" rN rule 1) field_inducts @
       
   847         [resolve_tac prems 1]);
       
   848 
       
   849     val induct = prove_goal defs_sg induct_prop (fn prems =>
       
   850         [res_inst_tac [(rN, rN)] induct_scheme 1,
       
   851          try_param_tac "x" "more" unit_induct 1, resolve_tac prems 1]);
       
   852 
       
   853     val cases_scheme = prove_goal defs_sg cases_scheme_prop (fn prems =>
       
   854         Method.insert_tac prems 1 ::
       
   855         (case previous of Some {cases, ...} => try_param_tac rN rN cases 1
       
   856         | None => all_tac) :: map (fn rule => try_param_tac "p" rN rule 1) field_cases @
       
   857         [Simplifier.asm_full_simp_tac HOL_basic_ss 1]);
       
   858 
       
   859     val cases = prove_goal defs_sg cases_prop (fn prems =>
       
   860         [Method.insert_tac prems 1, res_inst_tac [(rN, rN)] cases_scheme 1,
       
   861          Simplifier.asm_full_simp_tac (HOL_basic_ss addsimps [unit_all_eq1]) 1]);
       
   862 
       
   863     val simps = field_simps @ sel_convs @ update_convs @ [equality];
   796     val iffs = field_injects;
   864     val iffs = field_injects;
   797 
   865 
   798     val thms_thy =
   866     val thms_thy =
   799       defs_thy
   867       defs_thy
   800       |> (#1 oo (PureThy.add_thmss o map Thm.no_attributes))
   868       |> (#1 oo (PureThy.add_thmss o map Thm.no_attributes))
   802           ("update_defs", update_defs),
   870           ("update_defs", update_defs),
   803           ("make_defs", make_defs),
   871           ("make_defs", make_defs),
   804           ("select_convs", sel_convs),
   872           ("select_convs", sel_convs),
   805           ("update_convs", update_convs)]
   873           ("update_convs", update_convs)]
   806       |> (#1 oo PureThy.add_thms)
   874       |> (#1 oo PureThy.add_thms)
   807           [(("equality", equality), [Classical.xtra_intro_global])]
   875           [(("equality", equality), [Classical.xtra_intro_global]),
       
   876            (("induct_scheme", induct_scheme),
       
   877              [InductAttrib.induct_type_global (suffix schemeN name)]),
       
   878            (("induct", induct), [InductAttrib.induct_type_global name]),
       
   879            (("cases_scheme", cases_scheme),
       
   880              [InductAttrib.cases_type_global (suffix schemeN name)]),
       
   881            (("cases", cases), [InductAttrib.cases_type_global name])]
   808       |> (#1 oo PureThy.add_thmss)
   882       |> (#1 oo PureThy.add_thmss)
   809         [(("simps", simps), [Simplifier.simp_add_global]),
   883         [(("simps", simps), [Simplifier.simp_add_global]),
   810          (("iffs", iffs), [iff_add_global])];
   884          (("iffs", iffs), [iff_add_global])];
   811 
   885 
   812 
   886 
   813     (* 4th stage: final_thy *)
   887     (* 4th stage: final_thy *)
   814 
   888 
   815     val final_thy =
   889     val final_thy =
   816       thms_thy
   890       thms_thy
   817       |> put_record name {args = args, parent = parent, fields = fields, simps = simps}
   891       |> put_record name (make_record_info args parent fields simps induct_scheme cases_scheme)
   818       |> put_sel_upd (names @ [full_moreN]) (field_simps @ sel_defs @ update_defs)
   892       |> put_sel_upd (names @ [full_moreN]) (field_simps @ sel_defs @ update_defs)
   819       |> Theory.parent_path;
   893       |> Theory.parent_path;
   820 
   894 
   821   in (final_thy, {simps = simps, iffs = iffs}) end;
   895   in (final_thy, {simps = simps, iffs = iffs}) end;
   822 
   896