src/HOL/Tools/record.ML
changeset 46044 83b53c870efb
parent 46043 c66fa5ea4305
child 46046 05392bdd2286
equal deleted inserted replaced
46043:c66fa5ea4305 46044:83b53c870efb
   947 
   947 
   948 
   948 
   949 
   949 
   950 (** record simprocs **)
   950 (** record simprocs **)
   951 
   951 
   952 fun future_forward_prf_standard thy prf prop () =
   952 fun future_forward_prf_standard thy prf prop =
   953   let val thm =
   953   let val thm =
   954     if ! quick_and_dirty then Skip_Proof.make_thm thy prop
   954     if ! quick_and_dirty then Skip_Proof.make_thm thy prop
   955     else if Goal.future_enabled () then
   955     else if Goal.future_enabled () then
   956       Goal.future_result (Proof_Context.init_global thy) (Goal.fork prf) prop
   956       Goal.future_result (Proof_Context.init_global thy) (Goal.fork prf) prop
   957     else prf ()
   957     else prf ()
  1572     val _ = timing_msg ctxt "record extension preparing definitions";
  1572     val _ = timing_msg ctxt "record extension preparing definitions";
  1573 
  1573 
  1574 
  1574 
  1575     (* 1st stage part 1: introduce the tree of new types *)
  1575     (* 1st stage part 1: introduce the tree of new types *)
  1576 
  1576 
  1577     fun get_meta_tree () = build_meta_tree_type 1 thy vars more;
  1577     val (ext_body, typ_thy) = timeit_msg ctxt "record extension nested type def:" (fn () =>
  1578     val (ext_body, typ_thy) =
  1578       build_meta_tree_type 1 thy vars more);
  1579       timeit_msg ctxt "record extension nested type def:" get_meta_tree;
       
  1580 
  1579 
  1581 
  1580 
  1582     (* prepare declarations and definitions *)
  1581     (* prepare declarations and definitions *)
  1583 
  1582 
  1584     (* 1st stage part 2: define the ext constant *)
  1583     (* 1st stage part 2: define the ext constant *)
  1585 
  1584 
  1586     fun mk_ext args = list_comb (Const (ext_name, ext_type), args);
  1585     fun mk_ext args = list_comb (Const (ext_name, ext_type), args);
  1587     val ext_spec = Logic.mk_equals (mk_ext (vars @ [more]), ext_body);
  1586     val ext_spec = Logic.mk_equals (mk_ext (vars @ [more]), ext_body);
  1588 
  1587 
  1589     fun mk_defs () =
  1588     val ([ext_def], defs_thy) = timeit_msg ctxt "record extension constructor def:" (fn () =>
  1590       typ_thy
  1589       typ_thy
  1591       |> Sign.declare_const_global ((ext_binding, ext_type), NoSyn) |> snd
  1590       |> Sign.declare_const_global ((ext_binding, ext_type), NoSyn) |> snd
  1592       |> Global_Theory.add_defs false [((Thm.def_binding ext_binding, ext_spec), [])]
  1591       |> Global_Theory.add_defs false [((Thm.def_binding ext_binding, ext_spec), [])]
  1593       ||> Theory.checkpoint
  1592       ||> Theory.checkpoint);
  1594     val ([ext_def], defs_thy) =
       
  1595       timeit_msg ctxt "record extension constructor def:" mk_defs;
       
  1596 
  1593 
  1597 
  1594 
  1598     (* prepare propositions *)
  1595     (* prepare propositions *)
  1599 
  1596 
  1600     val _ = timing_msg ctxt "record extension preparing propositions";
  1597     val _ = timing_msg ctxt "record extension preparing propositions";
  1622          (All [dest_Free s] (P $ s), All (map dest_Free vars_more) (P $ ext))
  1619          (All [dest_Free s] (P $ s), All (map dest_Free vars_more) (P $ ext))
  1623       end;
  1620       end;
  1624 
  1621 
  1625     val prove_standard = prove_future_global true defs_thy;
  1622     val prove_standard = prove_future_global true defs_thy;
  1626 
  1623 
  1627     fun inject_prf () =
  1624     val inject = timeit_msg ctxt "record extension inject proof:" (fn () =>
  1628       simplify HOL_ss
  1625       simplify HOL_ss
  1629         (prove_standard [] inject_prop
  1626         (prove_standard [] inject_prop
  1630           (fn _ =>
  1627           (fn _ =>
  1631             simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1628             simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1632             REPEAT_DETERM
  1629             REPEAT_DETERM
  1633               (rtac @{thm refl_conj_eq} 1 ORELSE
  1630               (rtac @{thm refl_conj_eq} 1 ORELSE
  1634                 Iso_Tuple_Support.iso_tuple_intros_tac 1 ORELSE
  1631                 Iso_Tuple_Support.iso_tuple_intros_tac 1 ORELSE
  1635                 rtac refl 1)));
  1632                 rtac refl 1))));
  1636 
  1633 
  1637     val inject = timeit_msg ctxt "record extension inject proof:" inject_prf;
       
  1638 
  1634 
  1639     (*We need a surjection property r = (| f = f r, g = g r ... |)
  1635     (*We need a surjection property r = (| f = f r, g = g r ... |)
  1640       to prove other theorems. We haven't given names to the accessors
  1636       to prove other theorems. We haven't given names to the accessors
  1641       f, g etc yet however, so we generate an ext structure with
  1637       f, g etc yet however, so we generate an ext structure with
  1642       free variables as all arguments and allow the introduction tactic to
  1638       free variables as all arguments and allow the introduction tactic to
  1643       operate on it as far as it can. We then use Drule.export_without_context
  1639       operate on it as far as it can. We then use Drule.export_without_context
  1644       to convert the free variables into unifiable variables and unify them with
  1640       to convert the free variables into unifiable variables and unify them with
  1645       (roughly) the definition of the accessor.*)
  1641       (roughly) the definition of the accessor.*)
  1646     fun surject_prf () =
  1642     val surject = timeit_msg ctxt "record extension surjective proof:" (fn () =>
  1647       let
  1643       let
  1648         val cterm_ext = cterm_of defs_thy ext;
  1644         val cterm_ext = cterm_of defs_thy ext;
  1649         val start = named_cterm_instantiate [("y", cterm_ext)] surject_assist_idE;
  1645         val start = named_cterm_instantiate [("y", cterm_ext)] surject_assist_idE;
  1650         val tactic1 =
  1646         val tactic1 =
  1651           simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1647           simp_tac (HOL_basic_ss addsimps [ext_def]) 1 THEN
  1653         val tactic2 = REPEAT (rtac surject_assistI 1 THEN rtac refl 1);
  1649         val tactic2 = REPEAT (rtac surject_assistI 1 THEN rtac refl 1);
  1654         val [halfway] = Seq.list_of (tactic1 start);
  1650         val [halfway] = Seq.list_of (tactic1 start);
  1655         val [surject] = Seq.list_of (tactic2 (Drule.export_without_context halfway));
  1651         val [surject] = Seq.list_of (tactic2 (Drule.export_without_context halfway));
  1656       in
  1652       in
  1657         surject
  1653         surject
  1658       end;
  1654       end);
  1659     val surject = timeit_msg ctxt "record extension surjective proof:" surject_prf;
  1655 
  1660 
  1656 
  1661     fun split_meta_prf () =
  1657     val split_meta = timeit_msg ctxt "record extension split_meta proof:" (fn () =>
  1662       prove_standard [] split_meta_prop
  1658       prove_standard [] split_meta_prop
  1663         (fn _ =>
  1659         (fn _ =>
  1664           EVERY1
  1660           EVERY1
  1665            [rtac equal_intr_rule, Goal.norm_hhf_tac,
  1661            [rtac equal_intr_rule, Goal.norm_hhf_tac,
  1666             etac @{thm meta_allE}, atac,
  1662             etac @{thm meta_allE}, atac,
  1667             rtac (@{thm prop_subst} OF [surject]),
  1663             rtac (@{thm prop_subst} OF [surject]),
  1668             REPEAT o etac @{thm meta_allE}, atac]);
  1664             REPEAT o etac @{thm meta_allE}, atac]));
  1669     val split_meta = timeit_msg ctxt "record extension split_meta proof:" split_meta_prf;
  1665 
  1670 
  1666     val induct = timeit_msg ctxt "record extension induct proof:" (fn () =>
  1671     fun induct_prf () =
       
  1672       let val (assm, concl) = induct_prop in
  1667       let val (assm, concl) = induct_prop in
  1673         prove_standard [assm] concl
  1668         prove_standard [assm] concl
  1674           (fn {prems, ...} =>
  1669           (fn {prems, ...} =>
  1675             cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1 THEN
  1670             cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1 THEN
  1676             resolve_tac prems 2 THEN
  1671             resolve_tac prems 2 THEN
  1677             asm_simp_tac HOL_ss 1)
  1672             asm_simp_tac HOL_ss 1)
  1678       end;
  1673       end);
  1679     val induct = timeit_msg ctxt "record extension induct proof:" induct_prf;
       
  1680 
  1674 
  1681     val ([induct', inject', surjective', split_meta'], thm_thy) =
  1675     val ([induct', inject', surjective', split_meta'], thm_thy) =
  1682       defs_thy
  1676       defs_thy
  1683       |> Global_Theory.add_thms (map (Thm.no_attributes o apfst Binding.name)
  1677       |> Global_Theory.add_thms (map (Thm.no_attributes o apfst Binding.name)
  1684            [("ext_induct", induct),
  1678            [("ext_induct", induct),
  1983       rules for update_accessor_eq_assist can unify two different ways
  1977       rules for update_accessor_eq_assist can unify two different ways
  1984       on these constructors. If we take the complete result sequence of
  1978       on these constructors. If we take the complete result sequence of
  1985       running a the introduction tactic, we get one theorem for each upd/acc
  1979       running a the introduction tactic, we get one theorem for each upd/acc
  1986       pair, from which we can derive the bodies of our selector and
  1980       pair, from which we can derive the bodies of our selector and
  1987       updator and their convs.*)
  1981       updator and their convs.*)
  1988     fun get_access_update_thms () =
       
  1989       let
       
  1990         val r_rec0_Vars =
       
  1991           let
       
  1992             (*pick variable indices of 1 to avoid possible variable
       
  1993               collisions with existing variables in updacc_eq_triv*)
       
  1994             fun to_Var (Free (c, T)) = Var ((c, 1), T);
       
  1995           in mk_rec (map to_Var all_vars_more) 0 end;
       
  1996 
       
  1997         val cterm_rec = cterm_of ext_thy r_rec0;
       
  1998         val cterm_vrs = cterm_of ext_thy r_rec0_Vars;
       
  1999         val insts = [("v", cterm_rec), ("v'", cterm_vrs)];
       
  2000         val init_thm = named_cterm_instantiate insts updacc_eq_triv;
       
  2001         val terminal = rtac updacc_eq_idI 1 THEN rtac refl 1;
       
  2002         val tactic =
       
  2003           simp_tac (HOL_basic_ss addsimps ext_defs) 1 THEN
       
  2004           REPEAT (Iso_Tuple_Support.iso_tuple_intros_tac 1 ORELSE terminal);
       
  2005         val updaccs = Seq.list_of (tactic init_thm);
       
  2006       in
       
  2007         (updaccs RL [updacc_accessor_eqE],
       
  2008          updaccs RL [updacc_updator_eqE],
       
  2009          updaccs RL [updacc_cong_from_eq])
       
  2010       end;
       
  2011     val (accessor_thms, updator_thms, upd_acc_cong_assists) =
  1982     val (accessor_thms, updator_thms, upd_acc_cong_assists) =
  2012       timeit_msg ctxt "record getting tree access/updates:" get_access_update_thms;
  1983       timeit_msg ctxt "record getting tree access/updates:" (fn () =>
       
  1984         let
       
  1985           val r_rec0_Vars =
       
  1986             let
       
  1987               (*pick variable indices of 1 to avoid possible variable
       
  1988                 collisions with existing variables in updacc_eq_triv*)
       
  1989               fun to_Var (Free (c, T)) = Var ((c, 1), T);
       
  1990             in mk_rec (map to_Var all_vars_more) 0 end;
       
  1991 
       
  1992           val cterm_rec = cterm_of ext_thy r_rec0;
       
  1993           val cterm_vrs = cterm_of ext_thy r_rec0_Vars;
       
  1994           val insts = [("v", cterm_rec), ("v'", cterm_vrs)];
       
  1995           val init_thm = named_cterm_instantiate insts updacc_eq_triv;
       
  1996           val terminal = rtac updacc_eq_idI 1 THEN rtac refl 1;
       
  1997           val tactic =
       
  1998             simp_tac (HOL_basic_ss addsimps ext_defs) 1 THEN
       
  1999             REPEAT (Iso_Tuple_Support.iso_tuple_intros_tac 1 ORELSE terminal);
       
  2000           val updaccs = Seq.list_of (tactic init_thm);
       
  2001         in
       
  2002           (updaccs RL [updacc_accessor_eqE],
       
  2003            updaccs RL [updacc_updator_eqE],
       
  2004            updaccs RL [updacc_cong_from_eq])
       
  2005         end);
  2013 
  2006 
  2014     fun lastN xs = drop parent_fields_len xs;
  2007     fun lastN xs = drop parent_fields_len xs;
  2015 
  2008 
  2016     (*selectors*)
  2009     (*selectors*)
  2017     fun mk_sel_spec ((c, T), thm) =
  2010     fun mk_sel_spec ((c, T), thm) =
  2052         mk_rec ((map (mk_sel r0) all_fields) @ [HOLogic.unit]) 0;
  2045         mk_rec ((map (mk_sel r0) all_fields) @ [HOLogic.unit]) 0;
  2053 
  2046 
  2054 
  2047 
  2055     (* 2st stage: defs_thy *)
  2048     (* 2st stage: defs_thy *)
  2056 
  2049 
  2057     fun mk_defs () =
       
  2058       ext_thy
       
  2059       |> Sign.add_advanced_trfuns ([], [], advanced_print_translation, [])
       
  2060       |> Sign.restore_naming thy
       
  2061       |> Typedecl.abbrev_global (binding, map #1 alphas, NoSyn) recT0 |> snd
       
  2062       |> Typedecl.abbrev_global
       
  2063         (Binding.suffix_name schemeN binding, map #1 (alphas @ [zeta]), NoSyn) rec_schemeT0 |> snd
       
  2064       |> Sign.qualified_path false binding
       
  2065       |> fold (fn ((x, T), mx) => snd o Sign.declare_const_global ((Binding.name x, T), mx))
       
  2066         (sel_decls ~~ (field_syntax @ [NoSyn]))
       
  2067       |> fold (fn (x, T) => snd o Sign.declare_const_global ((Binding.name x, T), NoSyn))
       
  2068         (upd_decls @ [make_decl, fields_decl, extend_decl, truncate_decl])
       
  2069       |> (Global_Theory.add_defs false o
       
  2070             map (Thm.no_attributes o apfst (Binding.conceal o Binding.name))) sel_specs
       
  2071       ||>> (Global_Theory.add_defs false o
       
  2072             map (Thm.no_attributes o apfst (Binding.conceal o Binding.name))) upd_specs
       
  2073       ||>> (Global_Theory.add_defs false o
       
  2074             map (Thm.no_attributes o apfst (Binding.conceal o Binding.name)))
       
  2075         [make_spec, fields_spec, extend_spec, truncate_spec]
       
  2076       ||> Theory.checkpoint
       
  2077     val (((sel_defs, upd_defs), derived_defs), defs_thy) =
  2050     val (((sel_defs, upd_defs), derived_defs), defs_thy) =
  2078       timeit_msg ctxt "record trfuns/tyabbrs/selectors/updates/make/fields/extend/truncate defs:"
  2051       timeit_msg ctxt "record trfuns/tyabbrs/selectors/updates/make/fields/extend/truncate defs:"
  2079         mk_defs;
  2052         (fn () =>
       
  2053           ext_thy
       
  2054           |> Sign.add_advanced_trfuns ([], [], advanced_print_translation, [])
       
  2055           |> Sign.restore_naming thy
       
  2056           |> Typedecl.abbrev_global (binding, map #1 alphas, NoSyn) recT0 |> snd
       
  2057           |> Typedecl.abbrev_global
       
  2058             (Binding.suffix_name schemeN binding, map #1 (alphas @ [zeta]), NoSyn) rec_schemeT0 |> snd
       
  2059           |> Sign.qualified_path false binding
       
  2060           |> fold (fn ((x, T), mx) => snd o Sign.declare_const_global ((Binding.name x, T), mx))
       
  2061             (sel_decls ~~ (field_syntax @ [NoSyn]))
       
  2062           |> fold (fn (x, T) => snd o Sign.declare_const_global ((Binding.name x, T), NoSyn))
       
  2063             (upd_decls @ [make_decl, fields_decl, extend_decl, truncate_decl])
       
  2064           |> (Global_Theory.add_defs false o
       
  2065                 map (Thm.no_attributes o apfst (Binding.conceal o Binding.name))) sel_specs
       
  2066           ||>> (Global_Theory.add_defs false o
       
  2067                 map (Thm.no_attributes o apfst (Binding.conceal o Binding.name))) upd_specs
       
  2068           ||>> (Global_Theory.add_defs false o
       
  2069                 map (Thm.no_attributes o apfst (Binding.conceal o Binding.name)))
       
  2070             [make_spec, fields_spec, extend_spec, truncate_spec]
       
  2071           ||> Theory.checkpoint);
  2080 
  2072 
  2081     (* prepare propositions *)
  2073     (* prepare propositions *)
  2082     val _ = timing_msg ctxt "record preparing propositions";
  2074     val _ = timing_msg ctxt "record preparing propositions";
  2083     val P = Free (singleton (Name.variant_list all_variants) "P", rec_schemeT0 --> HOLogic.boolT);
  2075     val P = Free (singleton (Name.variant_list all_variants) "P", rec_schemeT0 --> HOLogic.boolT);
  2084     val C = Free (singleton (Name.variant_list all_variants) "C", HOLogic.boolT);
  2076     val C = Free (singleton (Name.variant_list all_variants) "C", HOLogic.boolT);
  2155       let val tac = simp_all_tac ss simps
  2147       let val tac = simp_all_tac ss simps
  2156       in fn prop => prove stndrd [] prop (K tac) end;
  2148       in fn prop => prove stndrd [] prop (K tac) end;
  2157 
  2149 
  2158     val ss = get_simpset defs_thy;
  2150     val ss = get_simpset defs_thy;
  2159 
  2151 
  2160     fun sel_convs_prf () =
  2152     val sel_convs = timeit_msg ctxt "record sel_convs proof:" (fn () =>
  2161       map (prove_simp false ss (sel_defs @ accessor_thms)) sel_conv_props;
  2153       map (prove_simp false ss (sel_defs @ accessor_thms)) sel_conv_props);
  2162     val sel_convs = timeit_msg ctxt "record sel_convs proof:" sel_convs_prf;
  2154 
  2163     fun sel_convs_standard_prf () = map Drule.export_without_context sel_convs;
  2155     val sel_convs_standard = timeit_msg ctxt "record sel_convs_standard proof:" (fn () =>
  2164     val sel_convs_standard =
  2156       map Drule.export_without_context sel_convs);
  2165       timeit_msg ctxt "record sel_convs_standard proof:" sel_convs_standard_prf;
  2157 
  2166 
  2158     val upd_convs = timeit_msg ctxt "record upd_convs proof:" (fn () =>
  2167     fun upd_convs_prf () =
  2159       map (prove_simp false ss (upd_defs @ updator_thms)) upd_conv_props);
  2168       map (prove_simp false ss (upd_defs @ updator_thms)) upd_conv_props;
  2160 
  2169     val upd_convs = timeit_msg ctxt "record upd_convs proof:" upd_convs_prf;
       
  2170     fun upd_convs_standard_prf () = map Drule.export_without_context upd_convs;
       
  2171     val upd_convs_standard =
  2161     val upd_convs_standard =
  2172       timeit_msg ctxt "record upd_convs_standard proof:" upd_convs_standard_prf;
  2162       timeit_msg ctxt "record upd_convs_standard proof:" (fn () =>
  2173 
  2163         map Drule.export_without_context upd_convs);
  2174     fun get_upd_acc_congs () =
  2164 
       
  2165     val (fold_congs, unfold_congs) = timeit_msg ctxt "record upd fold/unfold congs:" (fn () =>
  2175       let
  2166       let
  2176         val symdefs = map Thm.symmetric (sel_defs @ upd_defs);
  2167         val symdefs = map Thm.symmetric (sel_defs @ upd_defs);
  2177         val fold_ss = HOL_basic_ss addsimps symdefs;
  2168         val fold_ss = HOL_basic_ss addsimps symdefs;
  2178         val ua_congs = map (Drule.export_without_context o simplify fold_ss) upd_acc_cong_assists;
  2169         val ua_congs = map (Drule.export_without_context o simplify fold_ss) upd_acc_cong_assists;
  2179       in (ua_congs RL [updacc_foldE], ua_congs RL [updacc_unfoldE]) end;
  2170       in (ua_congs RL [updacc_foldE], ua_congs RL [updacc_unfoldE]) end);
  2180     val (fold_congs, unfold_congs) =
       
  2181       timeit_msg ctxt "record upd fold/unfold congs:" get_upd_acc_congs;
       
  2182 
  2171 
  2183     val parent_induct = Option.map #induct_scheme (try List.last parents);
  2172     val parent_induct = Option.map #induct_scheme (try List.last parents);
  2184 
  2173 
  2185     fun induct_scheme_prf () =
  2174     val induct_scheme = timeit_msg ctxt "record induct_scheme proof:" (fn () =>
  2186       prove_standard [] induct_scheme_prop
  2175       prove_standard [] induct_scheme_prop
  2187         (fn _ =>
  2176         (fn _ =>
  2188           EVERY
  2177           EVERY
  2189            [case parent_induct of NONE => all_tac | SOME ind => try_param_tac rN ind 1,
  2178            [case parent_induct of NONE => all_tac | SOME ind => try_param_tac rN ind 1,
  2190             try_param_tac rN ext_induct 1,
  2179             try_param_tac rN ext_induct 1,
  2191             asm_simp_tac HOL_basic_ss 1]);
  2180             asm_simp_tac HOL_basic_ss 1]));
  2192     val induct_scheme = timeit_msg ctxt "record induct_scheme proof:" induct_scheme_prf;
  2181 
  2193 
  2182     val induct = timeit_msg ctxt "record induct proof:" (fn () =>
  2194     fun induct_prf () =
       
  2195       let val (assm, concl) = induct_prop in
  2183       let val (assm, concl) = induct_prop in
  2196         prove_standard [assm] concl (fn {prems, ...} =>
  2184         prove_standard [assm] concl (fn {prems, ...} =>
  2197           try_param_tac rN induct_scheme 1
  2185           try_param_tac rN induct_scheme 1
  2198           THEN try_param_tac "more" @{thm unit.induct} 1
  2186           THEN try_param_tac "more" @{thm unit.induct} 1
  2199           THEN resolve_tac prems 1)
  2187           THEN resolve_tac prems 1)
  2200       end;
  2188       end);
  2201     val induct = timeit_msg ctxt "record induct proof:" induct_prf;
       
  2202 
  2189 
  2203     fun cases_scheme_prf () =
  2190     fun cases_scheme_prf () =
  2204       let
  2191       let
  2205         val _ $ (Pvar $ _) = concl_of induct_scheme;
  2192         val _ $ (Pvar $ _) = concl_of induct_scheme;
  2206         val ind =
  2193         val ind =
  2208             [(cterm_of defs_thy Pvar, cterm_of defs_thy
  2195             [(cterm_of defs_thy Pvar, cterm_of defs_thy
  2209               (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))]
  2196               (lambda w (HOLogic.imp $ HOLogic.mk_eq (r0, w) $ C)))]
  2210             induct_scheme;
  2197             induct_scheme;
  2211         in Object_Logic.rulify (mp OF [ind, refl]) end;
  2198         in Object_Logic.rulify (mp OF [ind, refl]) end;
  2212 
  2199 
  2213     val cases_scheme_prf = future_forward_prf cases_scheme_prf cases_scheme_prop;
  2200     val cases_scheme = timeit_msg ctxt "record cases_scheme proof:" (fn () =>
  2214     val cases_scheme = timeit_msg ctxt "record cases_scheme proof:" cases_scheme_prf;
  2201       future_forward_prf cases_scheme_prf cases_scheme_prop);
  2215 
  2202 
  2216     fun cases_prf () =
  2203     val cases = timeit_msg ctxt "record cases proof:" (fn () =>
  2217       prove_standard [] cases_prop
  2204       prove_standard [] cases_prop
  2218         (fn _ =>
  2205         (fn _ =>
  2219           try_param_tac rN cases_scheme 1 THEN
  2206           try_param_tac rN cases_scheme 1 THEN
  2220           simp_all_tac HOL_basic_ss [@{thm unit_all_eq1}]);
  2207           simp_all_tac HOL_basic_ss [@{thm unit_all_eq1}]));
  2221     val cases = timeit_msg ctxt "record cases proof:" cases_prf;
  2208 
  2222 
  2209     val surjective = timeit_msg ctxt "record surjective proof:" (fn () =>
  2223     fun surjective_prf () =
       
  2224       let
  2210       let
  2225         val leaf_ss =
  2211         val leaf_ss =
  2226           get_sel_upd_defs defs_thy addsimps (sel_defs @ @{thms o_assoc id_apply id_o o_id});
  2212           get_sel_upd_defs defs_thy addsimps (sel_defs @ @{thms o_assoc id_apply id_o o_id});
  2227         val init_ss = HOL_basic_ss addsimps ext_defs;
  2213         val init_ss = HOL_basic_ss addsimps ext_defs;
  2228       in
  2214       in
  2232              [rtac surject_assist_idE 1,
  2218              [rtac surject_assist_idE 1,
  2233               simp_tac init_ss 1,
  2219               simp_tac init_ss 1,
  2234               REPEAT
  2220               REPEAT
  2235                 (Iso_Tuple_Support.iso_tuple_intros_tac 1 ORELSE
  2221                 (Iso_Tuple_Support.iso_tuple_intros_tac 1 ORELSE
  2236                   (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))])
  2222                   (rtac surject_assistI 1 THEN simp_tac leaf_ss 1))])
  2237       end;
  2223       end);
  2238     val surjective = timeit_msg ctxt "record surjective proof:" surjective_prf;
  2224 
  2239 
  2225     val split_meta = timeit_msg ctxt "record split_meta proof:" (fn () =>
  2240     fun split_meta_prf () =
       
  2241       prove false [] split_meta_prop
  2226       prove false [] split_meta_prop
  2242         (fn _ =>
  2227         (fn _ =>
  2243           EVERY1
  2228           EVERY1
  2244            [rtac equal_intr_rule, Goal.norm_hhf_tac,
  2229            [rtac equal_intr_rule, Goal.norm_hhf_tac,
  2245             etac @{thm meta_allE}, atac,
  2230             etac @{thm meta_allE}, atac,
  2246             rtac (@{thm prop_subst} OF [surjective]),
  2231             rtac (@{thm prop_subst} OF [surjective]),
  2247             REPEAT o etac @{thm meta_allE}, atac]);
  2232             REPEAT o etac @{thm meta_allE}, atac]));
  2248     val split_meta = timeit_msg ctxt "record split_meta proof:" split_meta_prf;
  2233 
  2249     fun split_meta_standardise () = Drule.export_without_context split_meta;
  2234     val split_meta_standard = timeit_msg ctxt "record split_meta standard:" (fn () =>
  2250     val split_meta_standard =
  2235       Drule.export_without_context split_meta);
  2251       timeit_msg ctxt "record split_meta standard:" split_meta_standardise;
       
  2252 
  2236 
  2253     fun split_object_prf () =
  2237     fun split_object_prf () =
  2254       let
  2238       let
  2255         val cPI= cterm_of defs_thy (lambda r0 (Trueprop (P $ r0)));
  2239         val cPI= cterm_of defs_thy (lambda r0 (Trueprop (P $ r0)));
  2256         val _ $ Abs (_, _, P $ _) = fst (Logic.dest_equals (concl_of split_meta_standard));
  2240         val _ $ Abs (_, _, P $ _) = fst (Logic.dest_equals (concl_of split_meta_standard));
  2271           |> Thm.equal_elim (Thm.symmetric split_meta') (*!!r. P r*)
  2255           |> Thm.equal_elim (Thm.symmetric split_meta') (*!!r. P r*)
  2272           |> meta_to_obj_all                            (*All r. P r*)
  2256           |> meta_to_obj_all                            (*All r. P r*)
  2273           |> Thm.implies_intr cr                        (* 2 ==> 1 *)
  2257           |> Thm.implies_intr cr                        (* 2 ==> 1 *)
  2274      in thr COMP (thl COMP iffI) end;
  2258      in thr COMP (thl COMP iffI) end;
  2275 
  2259 
  2276 
  2260     val split_object = timeit_msg ctxt "record split_object proof:" (fn () =>
  2277     val split_object_prf = future_forward_prf split_object_prf split_object_prop;
  2261       future_forward_prf split_object_prf split_object_prop);
  2278     val split_object = timeit_msg ctxt "record split_object proof:" split_object_prf;
  2262 
  2279 
  2263     val split_ex = timeit_msg ctxt "record split_ex proof:" (fn () =>
  2280 
       
  2281     fun split_ex_prf () =
       
  2282       let
  2264       let
  2283         val ss = HOL_basic_ss addsimps @{thms not_ex [symmetric] Not_eq_iff};
  2265         val ss = HOL_basic_ss addsimps @{thms not_ex [symmetric] Not_eq_iff};
  2284         val P_nm = fst (dest_Free P);
  2266         val P_nm = fst (dest_Free P);
  2285         val not_P = cterm_of defs_thy (lambda r0 (HOLogic.mk_not (P $ r0)));
  2267         val not_P = cterm_of defs_thy (lambda r0 (HOLogic.mk_not (P $ r0)));
  2286         val so' = named_cterm_instantiate ([(P_nm, not_P)]) split_object;
  2268         val so' = named_cterm_instantiate ([(P_nm, not_P)]) split_object;
  2287         val so'' = simplify ss so';
  2269         val so'' = simplify ss so';
  2288       in
  2270       in
  2289         prove_standard [] split_ex_prop (fn _ => resolve_tac [so''] 1)
  2271         prove_standard [] split_ex_prop (fn _ => resolve_tac [so''] 1)
  2290       end;
  2272       end);
  2291     val split_ex = timeit_msg ctxt "record split_ex proof:" split_ex_prf;
       
  2292 
  2273 
  2293     fun equality_tac thms =
  2274     fun equality_tac thms =
  2294       let
  2275       let
  2295         val s' :: s :: eqs = rev thms;
  2276         val s' :: s :: eqs = rev thms;
  2296         val ss' = ss addsimps (s' :: s :: sel_convs_standard);
  2277         val ss' = ss addsimps (s' :: s :: sel_convs_standard);
  2297         val eqs' = map (simplify ss') eqs;
  2278         val eqs' = map (simplify ss') eqs;
  2298       in simp_tac (HOL_basic_ss addsimps (s' :: s :: eqs')) 1 end;
  2279       in simp_tac (HOL_basic_ss addsimps (s' :: s :: eqs')) 1 end;
  2299 
  2280 
  2300     fun equality_prf () =
  2281     val equality = timeit_msg ctxt "record equality proof:" (fn () =>
  2301       prove_standard [] equality_prop (fn {context, ...} =>
  2282       prove_standard [] equality_prop (fn {context, ...} =>
  2302         fn st =>
  2283         fn st =>
  2303           let val [s, s'] = map #1 (rev (Tactic.innermost_params 1 st)) in
  2284           let val [s, s'] = map #1 (rev (Tactic.innermost_params 1 st)) in
  2304             st |> (res_inst_tac context [((rN, 0), s)] cases_scheme 1 THEN
  2285             st |> (res_inst_tac context [((rN, 0), s)] cases_scheme 1 THEN
  2305               res_inst_tac context [((rN, 0), s')] cases_scheme 1 THEN
  2286               res_inst_tac context [((rN, 0), s')] cases_scheme 1 THEN
  2306               Subgoal.FOCUS (fn {prems, ...} => equality_tac prems) context 1)
  2287               Subgoal.FOCUS (fn {prems, ...} => equality_tac prems) context 1)
  2307              (*simp_all_tac ss (sel_convs) would also work but is less efficient*)
  2288              (*simp_all_tac ss (sel_convs) would also work but is less efficient*)
  2308           end);
  2289           end));
  2309     val equality = timeit_msg ctxt "record equality proof:" equality_prf;
       
  2310 
  2290 
  2311     val ((([sel_convs', upd_convs', sel_defs', upd_defs',
  2291     val ((([sel_convs', upd_convs', sel_defs', upd_defs',
  2312             fold_congs', unfold_congs',
  2292             fold_congs', unfold_congs',
  2313           splits' as [split_meta', split_object', split_ex'], derived_defs'],
  2293           splits' as [split_meta', split_object', split_ex'], derived_defs'],
  2314           [surjective', equality']),
  2294           [surjective', equality']),