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 |
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 |
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 |
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; |
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 |
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 = |
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)]) |