src/HOL/Tools/record.ML
changeset 32764 690f9cccf232
parent 32763 ebfaf9e3c03a
child 32765 3032c0308019
equal deleted inserted replaced
32763:ebfaf9e3c03a 32764:690f9cccf232
   199 
   199 
   200 
   200 
   201 structure Record: RECORD =
   201 structure Record: RECORD =
   202 struct
   202 struct
   203 
   203 
   204 val eq_reflection = thm "eq_reflection";
   204 val eq_reflection = @{thm eq_reflection};
   205 val Pair_eq = thm "Product_Type.prod.inject";
   205 val Pair_eq = @{thm Product_Type.prod.inject};
   206 val atomize_all = thm "HOL.atomize_all";
   206 val atomize_all = @{thm HOL.atomize_all};
   207 val atomize_imp = thm "HOL.atomize_imp";
   207 val atomize_imp = @{thm HOL.atomize_imp};
   208 val meta_allE = thm "Pure.meta_allE";
   208 val meta_allE = @{thm Pure.meta_allE};
   209 val prop_subst = thm "prop_subst";
   209 val prop_subst = @{thm prop_subst};
   210 val Pair_sel_convs = [fst_conv, snd_conv];
   210 val Pair_sel_convs = [fst_conv, snd_conv];
   211 val K_record_comp = @{thm "K_record_comp"};
   211 val K_record_comp = @{thm K_record_comp};
   212 val K_comp_convs = [@{thm o_apply}, K_record_comp]
   212 val K_comp_convs = [@{thm o_apply}, K_record_comp]
   213 val transitive_thm = thm "transitive";
   213 val transitive_thm = @{thm transitive};
   214 val o_assoc = @{thm "o_assoc"};
   214 val o_assoc = @{thm o_assoc};
   215 val id_apply = @{thm id_apply};
   215 val id_apply = @{thm id_apply};
   216 val id_o_apps = [@{thm id_apply}, @{thm id_o}, @{thm o_id}];
   216 val id_o_apps = [@{thm id_apply}, @{thm id_o}, @{thm o_id}];
   217 val Not_eq_iff = @{thm Not_eq_iff};
   217 val Not_eq_iff = @{thm Not_eq_iff};
   218 
   218 
   219 val refl_conj_eq = thm "refl_conj_eq";
   219 val refl_conj_eq = @{thm refl_conj_eq};
   220 val meta_all_sameI = thm "meta_all_sameI";
   220 val meta_all_sameI = @{thm meta_all_sameI};
   221 val meta_iffD2 = thm "meta_iffD2";
       
   222 
   221 
   223 val surject_assistI = @{thm "istuple_surjective_proof_assistI"};
   222 val surject_assistI = @{thm "istuple_surjective_proof_assistI"};
   224 val surject_assist_idE = @{thm "istuple_surjective_proof_assist_idE"};
   223 val surject_assist_idE = @{thm "istuple_surjective_proof_assist_idE"};
   225 
   224 
   226 val updacc_accessor_eqE = @{thm "update_accessor_accessor_eqE"};
   225 val updacc_accessor_eqE = @{thm "update_accessor_accessor_eqE"};
   234 val updacc_noop_compE = @{thm "update_accessor_noop_compE"};
   233 val updacc_noop_compE = @{thm "update_accessor_noop_compE"};
   235 val updacc_cong_idI = @{thm "update_accessor_cong_assist_idI"};
   234 val updacc_cong_idI = @{thm "update_accessor_cong_assist_idI"};
   236 val updacc_cong_triv = @{thm "update_accessor_cong_assist_triv"};
   235 val updacc_cong_triv = @{thm "update_accessor_cong_assist_triv"};
   237 val updacc_cong_from_eq = @{thm "istuple_update_accessor_cong_from_eq"};
   236 val updacc_cong_from_eq = @{thm "istuple_update_accessor_cong_from_eq"};
   238 
   237 
   239 val o_eq_dest = thm "o_eq_dest";
   238 val o_eq_dest = @{thm o_eq_dest};
   240 val o_eq_id_dest = thm "o_eq_id_dest";
   239 val o_eq_id_dest = @{thm o_eq_id_dest};
   241 val o_eq_dest_lhs = thm "o_eq_dest_lhs";
   240 val o_eq_dest_lhs = @{thm o_eq_dest_lhs};
   242 
   241 
   243 
   242 
   244 
   243 
   245 (** name components **)
   244 (** name components **)
   246 
   245 
   393 
   392 
   394 fun rec_id i T =
   393 fun rec_id i T =
   395   let
   394   let
   396     val rTs = dest_recTs T;
   395     val rTs = dest_recTs T;
   397     val rTs' = if i < 0 then rTs else Library.take (i, rTs);
   396     val rTs' = if i < 0 then rTs else Library.take (i, rTs);
   398   in Library.foldl (fn (s, (c, T)) => s ^ c) ("", rTs') end;   (* FIXME ? *)
   397   in implode (map #1 rTs') end;
   399 
   398 
   400 
   399 
   401 
   400 
   402 (*** extend theory by record definition ***)
   401 (*** extend theory by record definition ***)
   403 
   402 
   441     defset: Simplifier.simpset,
   440     defset: Simplifier.simpset,
   442     foldcong: Simplifier.simpset,
   441     foldcong: Simplifier.simpset,
   443     unfoldcong: Simplifier.simpset},
   442     unfoldcong: Simplifier.simpset},
   444   equalities: thm Symtab.table,
   443   equalities: thm Symtab.table,
   445   extinjects: thm list,
   444   extinjects: thm list,
   446   extsplit: thm Symtab.table,  (* maps extension name to split rule *)
   445   extsplit: thm Symtab.table,  (*maps extension name to split rule*)
   447   splits: (thm*thm*thm*thm) Symtab.table,  (* !!, !, EX - split-equalities, induct rule *)
   446   splits: (thm * thm * thm * thm) Symtab.table,  (*!!, !, EX - split-equalities, induct rule*)
   448   extfields: (string*typ) list Symtab.table,  (* maps extension to its fields *)
   447   extfields: (string * typ) list Symtab.table,  (*maps extension to its fields*)
   449   fieldext: (string*typ list) Symtab.table};  (* maps field to its extension *)
   448   fieldext: (string * typ list) Symtab.table};  (*maps field to its extension*)
   450 
   449 
   451 fun make_record_data
   450 fun make_record_data
   452     records sel_upd equalities extinjects extsplit splits extfields fieldext =
   451     records sel_upd equalities extinjects extsplit splits extfields fieldext =
   453  {records = records, sel_upd = sel_upd,
   452  {records = records, sel_upd = sel_upd,
   454   equalities = equalities, extinjects=extinjects, extsplit = extsplit, splits = splits,
   453   equalities = equalities, extinjects=extinjects, extsplit = extsplit, splits = splits,
   544 
   543 
   545 val get_sel_upd = #sel_upd o RecordsData.get;
   544 val get_sel_upd = #sel_upd o RecordsData.get;
   546 
   545 
   547 val is_selector = Symtab.defined o #selectors o get_sel_upd;
   546 val is_selector = Symtab.defined o #selectors o get_sel_upd;
   548 val get_updates = Symtab.lookup o #updates o get_sel_upd;
   547 val get_updates = Symtab.lookup o #updates o get_sel_upd;
   549 fun get_ss_with_context getss thy =
   548 fun get_ss_with_context getss thy = Simplifier.theory_context thy (getss (get_sel_upd thy));
   550     Simplifier.theory_context thy (getss (get_sel_upd thy));
   549 
   551 
   550 val get_simpset = get_ss_with_context #simpset;
   552 val get_simpset = get_ss_with_context (#simpset);
   551 val get_sel_upd_defs = get_ss_with_context #defset;
   553 val get_sel_upd_defs = get_ss_with_context (#defset);
   552 val get_foldcong_ss = get_ss_with_context #foldcong;
   554 val get_foldcong_ss = get_ss_with_context (#foldcong);
   553 val get_unfoldcong_ss = get_ss_with_context #unfoldcong;
   555 val get_unfoldcong_ss = get_ss_with_context (#unfoldcong);
       
   556 
   554 
   557 fun get_update_details u thy =
   555 fun get_update_details u thy =
   558   let val sel_upd = get_sel_upd thy in
   556   let val sel_upd = get_sel_upd thy in
   559     (case Symtab.lookup (#updates sel_upd) u of
   557     (case Symtab.lookup (#updates sel_upd) u of
   560       SOME s =>
   558       SOME s =>
  1155           then o_eq_dest
  1153           then o_eq_dest
  1156           else o_eq_id_dest;
  1154           else o_eq_id_dest;
  1157       in standard (othm RS dest) end;
  1155       in standard (othm RS dest) end;
  1158   in map get_simp upd_funs end;
  1156   in map get_simp upd_funs end;
  1159 
  1157 
  1160 (* FIXME dup? *)
       
  1161 structure SymSymTab =
       
  1162   Table(type key = string * string val ord = prod_ord fast_string_ord fast_string_ord);
       
  1163 
       
  1164 fun get_updupd_simp thy defset intros_tac u u' comp =
  1158 fun get_updupd_simp thy defset intros_tac u u' comp =
  1165   let
  1159   let
  1166     val f = Free ("f", domain_type (fastype_of u));
  1160     val f = Free ("f", domain_type (fastype_of u));
  1167     val f' = Free ("f'", domain_type (fastype_of u'));
  1161     val f' = Free ("f'", domain_type (fastype_of u'));
  1168     val lhs = mk_comp (u $ f) (u' $ f');
  1162     val lhs = mk_comp (u $ f) (u' $ f');
  1190     fun build_swaps_to_eq upd [] swaps = swaps
  1184     fun build_swaps_to_eq upd [] swaps = swaps
  1191       | build_swaps_to_eq upd (u :: us) swaps =
  1185       | build_swaps_to_eq upd (u :: us) swaps =
  1192           let
  1186           let
  1193             val key = (cname u, cname upd);
  1187             val key = (cname u, cname upd);
  1194             val newswaps =
  1188             val newswaps =
  1195               if SymSymTab.defined swaps key then swaps
  1189               if Symreltab.defined swaps key then swaps
  1196               else SymSymTab.insert (K true) (key, getswap u upd) swaps;
  1190               else Symreltab.insert (K true) (key, getswap u upd) swaps;
  1197           in
  1191           in
  1198             if cname u = cname upd then newswaps
  1192             if cname u = cname upd then newswaps
  1199             else build_swaps_to_eq upd us newswaps
  1193             else build_swaps_to_eq upd us newswaps
  1200           end;
  1194           end;
  1201     fun swaps_needed [] prev seen swaps = map snd (SymSymTab.dest swaps)
  1195     fun swaps_needed [] prev seen swaps = map snd (Symreltab.dest swaps)
  1202       | swaps_needed (u :: us) prev seen swaps =
  1196       | swaps_needed (u :: us) prev seen swaps =
  1203           if Symtab.defined seen (cname u)
  1197           if Symtab.defined seen (cname u)
  1204           then swaps_needed us prev seen (build_swaps_to_eq u prev swaps)
  1198           then swaps_needed us prev seen (build_swaps_to_eq u prev swaps)
  1205           else swaps_needed us (u :: prev) (Symtab.insert (K true) (cname u, ()) seen) swaps;
  1199           else swaps_needed us (u :: prev) (Symtab.insert (K true) (cname u, ()) seen) swaps;
  1206   in swaps_needed upd_funs [] Symtab.empty SymSymTab.empty end;
  1200   in swaps_needed upd_funs [] Symtab.empty Symreltab.empty end;
  1207 
  1201 
  1208 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate;
  1202 val named_cterm_instantiate = IsTupleSupport.named_cterm_instantiate;
  1209 
  1203 
  1210 fun prove_unfold_defs thy ss T ex_simps ex_simprs prop =
  1204 fun prove_unfold_defs thy ss T ex_simps ex_simprs prop =
  1211   let
  1205   let
  1538             handle TERM _ => NONE)
  1532             handle TERM _ => NONE)
  1539         | _ => NONE)
  1533         | _ => NONE)
  1540       end);
  1534       end);
  1541 
  1535 
  1542 
  1536 
  1543 local
       
  1544 
       
  1545 val inductive_atomize = thms "induct_atomize";
       
  1546 val inductive_rulify = thms "induct_rulify";
       
  1547 
       
  1548 in
       
  1549 
       
  1550 (* record_split_simp_tac *)
  1537 (* record_split_simp_tac *)
  1551 
  1538 
  1552 (*Split (and simplify) all records in the goal for which P holds.
  1539 (*Split (and simplify) all records in the goal for which P holds.
  1553   For quantified occurrences of a record
  1540   For quantified occurrences of a record
  1554   P can peek on the whole subterm (including the quantifier); for free variables P
  1541   P can peek on the whole subterm (including the quantifier); for free variables P
  1563     val has_rec = exists_Const
  1550     val has_rec = exists_Const
  1564       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1551       (fn (s, Type (_, [Type (_, [T, _]), _])) =>
  1565           (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T
  1552           (s = "all" orelse s = "All" orelse s = "Ex") andalso is_recT T
  1566         | _ => false);
  1553         | _ => false);
  1567 
  1554 
  1568     val goal = nth (Thm.prems_of st) (i - 1);
  1555     val goal = nth (Thm.prems_of st) (i - 1);    (* FIXME SUBGOAL *)
  1569     val frees = List.filter (is_recT o type_of) (OldTerm.term_frees goal);
  1556     val frees = filter (is_recT o type_of) (OldTerm.term_frees goal);
  1570 
  1557 
  1571     fun mk_split_free_tac free induct_thm i =
  1558     fun mk_split_free_tac free induct_thm i =
  1572       let
  1559       let
  1573         val cfree = cterm_of thy free;
  1560         val cfree = cterm_of thy free;
  1574         val _$ (_ $ r) = concl_of induct_thm;
  1561         val _$ (_ $ r) = concl_of induct_thm;
  1575         val crec = cterm_of thy r;
  1562         val crec = cterm_of thy r;
  1576         val thm = cterm_instantiate [(crec, cfree)] induct_thm;
  1563         val thm = cterm_instantiate [(crec, cfree)] induct_thm;
  1577       in
  1564       in
  1578         EVERY
  1565         EVERY
  1579          [simp_tac (HOL_basic_ss addsimps inductive_atomize) i,
  1566          [simp_tac (HOL_basic_ss addsimps @{thms induct_atomize}) i,
  1580           rtac thm i,
  1567           rtac thm i,
  1581           simp_tac (HOL_basic_ss addsimps inductive_rulify) i]
  1568           simp_tac (HOL_basic_ss addsimps @{thms induct_rulify}) i]
  1582       end;
  1569       end;
  1583 
  1570 
  1584     fun split_free_tac P i (free as Free (n, T)) =
  1571     fun split_free_tac P i (free as Free (n, T)) =
  1585           (case rec_id ~1 T of
  1572           (case rec_id ~1 T of
  1586             "" => NONE
  1573             "" => NONE
  1602   in
  1589   in
  1603     st |>
  1590     st |>
  1604       (EVERY split_frees_tacs THEN
  1591       (EVERY split_frees_tacs THEN
  1605         Simplifier.full_simp_tac (get_simpset thy addsimps thms' addsimprocs simprocs) i)
  1592         Simplifier.full_simp_tac (get_simpset thy addsimps thms' addsimprocs simprocs) i)
  1606   end handle Empty => Seq.empty;
  1593   end handle Empty => Seq.empty;
  1607 end;
       
  1608 
  1594 
  1609 
  1595 
  1610 (* record_split_tac *)
  1596 (* record_split_tac *)
  1611 
  1597 
  1612 (*Split all records in the goal, which are quantified by ! or !!.*)
  1598 (*Split all records in the goal, which are quantified by ! or !!.*)
  1744     val len = length fields;
  1730     val len = length fields;
  1745     val idxms = 0 upto len;
  1731     val idxms = 0 upto len;
  1746 
  1732 
  1747     (*before doing anything else, create the tree of new types
  1733     (*before doing anything else, create the tree of new types
  1748       that will back the record extension*)
  1734       that will back the record extension*)
  1749 
  1735     (* FIXME cf. BalancedTree.make *)
  1750     fun mktreeT [] = raise TYPE ("mktreeT: empty list", [], [])
  1736     fun mktreeT [] = raise TYPE ("mktreeT: empty list", [], [])
  1751       | mktreeT [T] = T
  1737       | mktreeT [T] = T
  1752       | mktreeT xs =
  1738       | mktreeT xs =
  1753           let
  1739           let
  1754             val len = length xs;
  1740             val len = length xs;
  1757             val right = List.drop (xs, half);
  1743             val right = List.drop (xs, half);
  1758           in
  1744           in
  1759             HOLogic.mk_prodT (mktreeT left, mktreeT right)
  1745             HOLogic.mk_prodT (mktreeT left, mktreeT right)
  1760           end;
  1746           end;
  1761 
  1747 
       
  1748     (* FIXME cf. BalancedTree.make *)
  1762     fun mktreeV [] = raise TYPE ("mktreeV: empty list", [], [])
  1749     fun mktreeV [] = raise TYPE ("mktreeV: empty list", [], [])
  1763       | mktreeV [T] = T
  1750       | mktreeV [T] = T
  1764       | mktreeV xs =
  1751       | mktreeV xs =
  1765           let
  1752           let
  1766             val len = length xs;
  1753             val len = length xs;
  1769             val right = List.drop (xs, half);
  1756             val right = List.drop (xs, half);
  1770           in
  1757           in
  1771             IsTupleSupport.mk_cons_tuple (mktreeV left, mktreeV right)
  1758             IsTupleSupport.mk_cons_tuple (mktreeV left, mktreeV right)
  1772           end;
  1759           end;
  1773 
  1760 
  1774     fun mk_istuple ((thy, i), (left, rght)) =
  1761     fun mk_istuple (left, right) (thy, i) =
  1775       let
  1762       let
  1776         val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i;
  1763         val suff = if i = 0 then ext_typeN else inner_typeN ^ string_of_int i;
  1777         val nm = suffix suff (Long_Name.base_name name);
  1764         val nm = suffix suff (Long_Name.base_name name);
  1778         val (isom, cons, thy') =
  1765         val (isom, cons, thy') =
  1779           IsTupleSupport.add_istuple_type
  1766           IsTupleSupport.add_istuple_type
  1780             (nm, alphas_zeta) (fastype_of left, fastype_of rght) thy;
  1767             (nm, alphas_zeta) (fastype_of left, fastype_of right) thy;
  1781       in
  1768       in
  1782         ((thy', i + 1), cons $ left $ rght)
  1769         (cons $ left $ right, (thy', i + 1))
  1783       end;
  1770       end;
  1784 
  1771 
  1785     (*trying to create a 1-element istuple will fail, and
  1772     (*trying to create a 1-element istuple will fail, and is pointless anyway*)
  1786       is pointless anyway*)
  1773     fun mk_even_istuple [arg] = pair arg
  1787     fun mk_even_istuple ((thy, i), [arg]) = ((thy, i), arg)
  1774       | mk_even_istuple args = mk_istuple (IsTupleSupport.dest_cons_tuple (mktreeV args));
  1788       | mk_even_istuple ((thy, i), args) =
       
  1789           mk_istuple ((thy, i), IsTupleSupport.dest_cons_tuple (mktreeV args));
       
  1790 
  1775 
  1791     fun build_meta_tree_type i thy vars more =
  1776     fun build_meta_tree_type i thy vars more =
  1792       let val len = length vars in
  1777       let val len = length vars in
  1793         if len < 1 then raise (TYPE ("meta_tree_type args too short", [], vars))
  1778         if len < 1 then raise TYPE ("meta_tree_type args too short", [], vars)
  1794         else if len > 16 then
  1779         else if len > 16 then
  1795           let
  1780           let
  1796             fun group16 [] = []
  1781             fun group16 [] = []
  1797               | group16 xs = Library.take (16, xs) :: group16 (Library.drop (16, xs));
  1782               | group16 xs = Library.take (16, xs) :: group16 (Library.drop (16, xs));
  1798             val vars' = group16 vars;
  1783             val vars' = group16 vars;
  1799             val ((thy', i'), composites) =
  1784             val (composites, (thy', i')) = fold_map mk_even_istuple vars' (thy, i);
  1800               Library.foldl_map mk_even_istuple ((thy, i), vars');   (* FIXME fold_map !? *)
       
  1801           in
  1785           in
  1802             build_meta_tree_type i' thy' composites more
  1786             build_meta_tree_type i' thy' composites more
  1803           end
  1787           end
  1804         else
  1788         else
  1805           let val ((thy', i'), term) = mk_istuple ((thy, 0), (mktreeV vars, more))
  1789           let val (term, (thy', i')) = mk_istuple (mktreeV vars, more) (thy, 0)
  1806           in (term, thy') end
  1790           in (term, thy') end
  1807       end;
  1791       end;
  1808 
  1792 
  1809     val _ = timing_msg "record extension preparing definitions";
  1793     val _ = timing_msg "record extension preparing definitions";
  1810 
  1794 
  1840     val named_vars_more = (names @ [full moreN]) ~~ vars_more;
  1824     val named_vars_more = (names @ [full moreN]) ~~ vars_more;
  1841     val variants = map (fn Free (x, _) => x) vars_more;
  1825     val variants = map (fn Free (x, _) => x) vars_more;
  1842     val ext = mk_ext vars_more;
  1826     val ext = mk_ext vars_more;
  1843     val s = Free (rN, extT);
  1827     val s = Free (rN, extT);
  1844     val w = Free (wN, extT);
  1828     val w = Free (wN, extT);
  1845     val P = Free (Name.variant variants "P", extT-->HOLogic.boolT);
  1829     val P = Free (Name.variant variants "P", extT --> HOLogic.boolT);
  1846     val C = Free (Name.variant variants "C", HOLogic.boolT);
  1830     val C = Free (Name.variant variants "C", HOLogic.boolT);
  1847     val intros_tac = IsTupleSupport.istuple_intros_tac defs_thy;
  1831     val intros_tac = IsTupleSupport.istuple_intros_tac defs_thy;
  1848 
  1832 
  1849     val inject_prop =
  1833     val inject_prop =
  1850       let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in
  1834       let val vars_more' = map (fn (Free (x, T)) => Free (x ^ "'", T)) vars_more in
  1922     fun induct_prf () =
  1906     fun induct_prf () =
  1923       let val (assm, concl) = induct_prop in
  1907       let val (assm, concl) = induct_prop in
  1924         prove_standard [assm] concl
  1908         prove_standard [assm] concl
  1925           (fn {prems, ...} =>
  1909           (fn {prems, ...} =>
  1926             EVERY
  1910             EVERY
  1927              [cut_rules_tac [split_meta RS meta_iffD2] 1,
  1911              [cut_rules_tac [split_meta RS Drule.equal_elim_rule2] 1,
  1928               resolve_tac prems 2,
  1912               resolve_tac prems 2,
  1929               asm_simp_tac HOL_ss 1])
  1913               asm_simp_tac HOL_ss 1])
  1930       end;
  1914       end;
  1931     val induct = timeit_msg "record extension induct proof:" induct_prf;
  1915     val induct = timeit_msg "record extension induct proof:" induct_prf;
  1932 
  1916 
  1942 
  1926 
  1943 fun chunks [] [] = []
  1927 fun chunks [] [] = []
  1944   | chunks [] xs = [xs]
  1928   | chunks [] xs = [xs]
  1945   | chunks (l :: ls) xs = Library.take (l, xs) :: chunks ls (Library.drop (l, xs));
  1929   | chunks (l :: ls) xs = Library.take (l, xs) :: chunks ls (Library.drop (l, xs));
  1946 
  1930 
  1947 fun chop_last [] = error "last: list should not be empty"
  1931 fun chop_last [] = error "chop_last: list should not be empty"
  1948   | chop_last [x] = ([], x)
  1932   | chop_last [x] = ([], x)
  1949   | chop_last (x :: xs) = let val (tl, l) = chop_last xs in (x :: tl, l) end;
  1933   | chop_last (x :: xs) = let val (tl, l) = chop_last xs in (x :: tl, l) end;
  1950 
  1934 
  1951 fun subst_last s [] = error "subst_last: list should not be empty"
  1935 fun subst_last s [] = error "subst_last: list should not be empty"
  1952   | subst_last s [x] = [s]
  1936   | subst_last s [x] = [s]
  2012     val types = map snd fields;
  1996     val types = map snd fields;
  2013     val alphas_fields = List.foldr OldTerm.add_typ_tfree_names [] types;
  1997     val alphas_fields = List.foldr OldTerm.add_typ_tfree_names [] types;
  2014     val alphas_ext = alphas inter alphas_fields;
  1998     val alphas_ext = alphas inter alphas_fields;
  2015     val len = length fields;
  1999     val len = length fields;
  2016     val variants =
  2000     val variants =
  2017       Name.variant_list (moreN :: rN :: (rN ^ "'") :: wN :: parent_variants) (map fst bfields);
  2001       Name.variant_list (moreN :: rN :: (rN ^ "'") :: wN :: parent_variants)
       
  2002         (map fst bfields);
  2018     val vars = ListPair.map Free (variants, types);
  2003     val vars = ListPair.map Free (variants, types);
  2019     val named_vars = names ~~ vars;
  2004     val named_vars = names ~~ vars;
  2020     val idxs = 0 upto (len - 1);
  2005     val idxs = 0 upto (len - 1);
  2021     val idxms = 0 upto len;
  2006     val idxms = 0 upto len;
  2022 
  2007 
  2051     val _ = timing_msg "record preparing definitions";
  2036     val _ = timing_msg "record preparing definitions";
  2052     val Type extension_scheme = extT;
  2037     val Type extension_scheme = extT;
  2053     val extension_name = unsuffix ext_typeN (fst extension_scheme);
  2038     val extension_name = unsuffix ext_typeN (fst extension_scheme);
  2054     val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end;
  2039     val extension = let val (n, Ts) = extension_scheme in (n, subst_last HOLogic.unitT Ts) end;
  2055     val extension_names = map (unsuffix ext_typeN o fst o #extension) parents @ [extN];
  2040     val extension_names = map (unsuffix ext_typeN o fst o #extension) parents @ [extN];
  2056     val extension_id = Library.foldl (op ^) ("", extension_names);  (* FIXME implode!? *)
  2041     val extension_id = implode extension_names;
  2057 
       
  2058 
  2042 
  2059     fun rec_schemeT n = mk_recordT (map #extension (prune n parents)) extT;
  2043     fun rec_schemeT n = mk_recordT (map #extension (prune n parents)) extT;
  2060     val rec_schemeT0 = rec_schemeT 0;
  2044     val rec_schemeT0 = rec_schemeT 0;
  2061 
  2045 
  2062     fun recT n =
  2046     fun recT n =
  2184           else raise TERM ("mk_sel_spec: different arg", [arg]);
  2168           else raise TERM ("mk_sel_spec: different arg", [arg]);
  2185       in
  2169       in
  2186         Const (mk_selC rec_schemeT0 (c, T)) :== acc
  2170         Const (mk_selC rec_schemeT0 (c, T)) :== acc
  2187       end;
  2171       end;
  2188     val sel_specs = map mk_sel_spec (fields_more ~~ lastN accessor_thms);
  2172     val sel_specs = map mk_sel_spec (fields_more ~~ lastN accessor_thms);
  2189 
       
  2190 
  2173 
  2191     (*updates*)
  2174     (*updates*)
  2192     fun mk_upd_spec ((c, T), thm) =
  2175     fun mk_upd_spec ((c, T), thm) =
  2193       let
  2176       let
  2194         val (upd $ _ $ arg) =
  2177         val (upd $ _ $ arg) =
  2518       |> (snd oo PureThy.add_thmss)
  2501       |> (snd oo PureThy.add_thmss)
  2519           [((Binding.name "simps", sel_upd_simps),
  2502           [((Binding.name "simps", sel_upd_simps),
  2520             [Simplifier.simp_add, Nitpick_Const_Simps.add]),
  2503             [Simplifier.simp_add, Nitpick_Const_Simps.add]),
  2521            ((Binding.name "iffs", iffs), [iff_add])]
  2504            ((Binding.name "iffs", iffs), [iff_add])]
  2522       |> put_record name (make_record_info args parent fields extension induct_scheme' ext_def)
  2505       |> put_record name (make_record_info args parent fields extension induct_scheme' ext_def)
  2523       |> put_sel_upd names full_moreN depth sel_upd_simps
  2506       |> put_sel_upd names full_moreN depth sel_upd_simps sel_upd_defs (fold_congs', unfold_congs')
  2524                            sel_upd_defs (fold_congs', unfold_congs')
       
  2525       |> add_record_equalities extension_id equality'
  2507       |> add_record_equalities extension_id equality'
  2526       |> add_extinjects ext_inject
  2508       |> add_extinjects ext_inject
  2527       |> add_extsplit extension_name ext_split
  2509       |> add_extsplit extension_name ext_split
  2528       |> add_record_splits extension_id (split_meta', split_object', split_ex', induct_scheme')
  2510       |> add_record_splits extension_id (split_meta', split_object', split_ex', induct_scheme')
  2529       |> add_extfields extension_name (fields @ [(full_moreN, moreT)])
  2511       |> add_extfields extension_name (fields @ [(full_moreN, moreT)])