69 fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname); |
69 fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname); |
70 |
70 |
71 val Trueprop = HOLogic.mk_Trueprop; |
71 val Trueprop = HOLogic.mk_Trueprop; |
72 fun All xs t = Term.list_all_free (xs, t); |
72 fun All xs t = Term.list_all_free (xs, t); |
73 |
73 |
74 infix 0 :== === ==>; |
74 infix 9 $$; |
|
75 infix 0 :== ===; |
|
76 infixr 0 ==>; |
|
77 |
|
78 val (op $$) = Term.list_comb; |
75 val (op :==) = Logic.mk_defpair; |
79 val (op :==) = Logic.mk_defpair; |
76 val (op ===) = Trueprop o HOLogic.mk_eq; |
80 val (op ===) = Trueprop o HOLogic.mk_eq; |
77 val (op ==>) = Logic.mk_implies; |
81 val (op ==>) = Logic.mk_implies; |
78 |
82 |
79 |
83 |
201 |
206 |
202 fun mk_sel r c = |
207 fun mk_sel r c = |
203 let val rT = fastype_of r |
208 let val rT = fastype_of r |
204 in Const (mk_selC rT (c, find_fieldT c rT)) $ r end; |
209 in Const (mk_selC rT (c, find_fieldT c rT)) $ r end; |
205 |
210 |
|
211 fun mk_named_sels names r = names ~~ map (mk_sel r) names; |
|
212 |
206 val mk_moreC = mk_selC; |
213 val mk_moreC = mk_selC; |
207 |
214 |
208 fun mk_more r c = |
215 fun mk_more r c = |
209 let val rT = fastype_of r |
216 let val rT = fastype_of r |
210 in Const (mk_moreC rT (c, snd (dest_recordT rT))) $ r end; |
217 in Const (mk_moreC rT (c, snd (dest_recordT rT))) $ r end; |
221 val mk_more_updateC = mk_updateC; |
228 val mk_more_updateC = mk_updateC; |
222 |
229 |
223 fun mk_more_update r (c, x) = |
230 fun mk_more_update r (c, x) = |
224 let val rT = fastype_of r |
231 let val rT = fastype_of r |
225 in Const (mk_more_updateC rT (c, snd (dest_recordT rT))) $ x $ r end; |
232 in Const (mk_more_updateC rT (c, snd (dest_recordT rT))) $ x $ r end; |
226 |
|
227 |
|
228 (* make *) |
|
229 |
|
230 fun mk_makeC rT (c, Ts) = (c, Ts ---> rT); |
|
231 |
233 |
232 |
234 |
233 |
235 |
234 (** concrete syntax for records **) |
236 (** concrete syntax for records **) |
235 |
237 |
261 fun record_update_tr [t, u] = |
263 fun record_update_tr [t, u] = |
262 foldr (op $) (rev (gen_fields_tr "_updates" "_update" updateN u), t) |
264 foldr (op $) (rev (gen_fields_tr "_updates" "_update" updateN u), t) |
263 | record_update_tr ts = raise TERM ("record_update_tr", ts); |
265 | record_update_tr ts = raise TERM ("record_update_tr", ts); |
264 |
266 |
265 |
267 |
266 fun update_name_tr (Free (x, T) :: ts) = Term.list_comb (Free (suffix updateN x, T), ts) |
268 fun update_name_tr (Free (x, T) :: ts) = Free (suffix updateN x, T) $$ ts |
267 | update_name_tr (Const (x, T) :: ts) = Term.list_comb (Const (suffix updateN x, T), ts) |
269 | update_name_tr (Const (x, T) :: ts) = Const (suffix updateN x, T) $$ ts |
268 | update_name_tr (((c as Const ("_constrain", _)) $ t $ ty) :: ts) = |
270 | update_name_tr (((c as Const ("_constrain", _)) $ t $ ty) :: ts) = |
269 Term.list_comb (c $ update_name_tr [t] $ |
271 (c $ update_name_tr [t] $ (Syntax.const "fun" $ ty $ Syntax.const "dummy")) $$ ts |
270 (Syntax.const "fun" $ ty $ Syntax.const "dummy"), ts) |
|
271 | update_name_tr ts = raise TERM ("update_name_tr", ts); |
272 | update_name_tr ts = raise TERM ("update_name_tr", ts); |
272 |
273 |
273 |
274 |
274 val parse_translation = |
275 val parse_translation = |
275 [("_record_type", record_type_tr), |
276 [("_record_type", record_type_tr), |
698 val all_xs_more = all_xs @ [moreN]; |
699 val all_xs_more = all_xs @ [moreN]; |
699 |
700 |
700 val parent_more = funpow parent_len mk_snd; |
701 val parent_more = funpow parent_len mk_snd; |
701 val idxs = 0 upto (len - 1); |
702 val idxs = 0 upto (len - 1); |
702 |
703 |
|
704 val parentT = if null parent_fields then [] else [mk_recordT (parent_fields, HOLogic.unitT)]; |
|
705 val r_parent = if null parent_fields then [] else [Free (rN, hd parentT)]; |
|
706 |
703 val rec_schemeT = mk_recordT (all_fields, moreT); |
707 val rec_schemeT = mk_recordT (all_fields, moreT); |
704 val rec_scheme = mk_record (all_named_vars, more); |
708 val rec_scheme = mk_record (all_named_vars, more); |
705 val recT = mk_recordT (all_fields, HOLogic.unitT); |
709 val recT = mk_recordT (all_fields, HOLogic.unitT); |
706 val rec_ = mk_record (all_named_vars, HOLogic.unit); |
710 val rec_ = mk_record (all_named_vars, HOLogic.unit); |
707 val r = Free (rN, rec_schemeT); |
711 val r_scheme = Free (rN, rec_schemeT); |
708 val r' = Free (rN, recT); |
712 val r = Free (rN, recT); |
709 |
713 |
710 |
714 |
711 (* prepare print translation functions *) |
715 (* prepare print translation functions *) |
712 |
716 |
713 val field_tr's = |
717 val field_tr's = |
718 |
722 |
719 val sel_decls = map (mk_selC rec_schemeT) bfields @ |
723 val sel_decls = map (mk_selC rec_schemeT) bfields @ |
720 [mk_moreC rec_schemeT (moreN, moreT)]; |
724 [mk_moreC rec_schemeT (moreN, moreT)]; |
721 val update_decls = map (mk_updateC rec_schemeT) bfields @ |
725 val update_decls = map (mk_updateC rec_schemeT) bfields @ |
722 [mk_more_updateC rec_schemeT (moreN, moreT)]; |
726 [mk_more_updateC rec_schemeT (moreN, moreT)]; |
723 val make_decls = |
727 val make_decl = (makeN, parentT ---> types ---> recT); |
724 [(mk_makeC rec_schemeT (make_schemeN, all_types @ [moreT])), |
728 val extend_decl = (extendN, recT --> moreT --> rec_schemeT); |
725 (mk_makeC recT (makeN, all_types))]; |
729 val truncate_decl = (truncateN, rec_schemeT --> recT); |
726 val record_decl = (recordN, rec_schemeT --> recT); |
|
727 |
730 |
728 |
731 |
729 (* prepare definitions *) |
732 (* prepare definitions *) |
730 |
733 |
731 (*record (scheme) type abbreviation*) |
734 (*record (scheme) type abbreviation*) |
733 [(suffix schemeN bname, alphas @ [zeta], rec_schemeT, Syntax.NoSyn), |
736 [(suffix schemeN bname, alphas @ [zeta], rec_schemeT, Syntax.NoSyn), |
734 (bname, alphas, recT, Syntax.NoSyn)]; |
737 (bname, alphas, recT, Syntax.NoSyn)]; |
735 |
738 |
736 (*selectors*) |
739 (*selectors*) |
737 fun mk_sel_spec (i, c) = |
740 fun mk_sel_spec (i, c) = |
738 mk_sel r c :== mk_fst (funpow i mk_snd (parent_more r)); |
741 mk_sel r_scheme c :== mk_fst (funpow i mk_snd (parent_more r_scheme)); |
739 val sel_specs = |
742 val sel_specs = |
740 ListPair.map mk_sel_spec (idxs, names) @ |
743 ListPair.map mk_sel_spec (idxs, names) @ |
741 [more_part r :== funpow len mk_snd (parent_more r)]; |
744 [more_part r_scheme :== funpow len mk_snd (parent_more r_scheme)]; |
742 |
745 |
743 (*updates*) |
746 (*updates*) |
744 val all_sels = all_names ~~ map (mk_sel r) all_names; |
747 val all_sels = mk_named_sels all_names r_scheme; |
745 fun mk_upd_spec (i, (c, x)) = |
748 fun mk_upd_spec (i, (c, x)) = |
746 mk_update r (c, x) :== |
749 mk_update r_scheme (c, x) :== |
747 mk_record (nth_update (c, x) (parent_len + i, all_sels), more_part r) |
750 mk_record (nth_update (c, x) (parent_len + i, all_sels), more_part r_scheme) |
748 val update_specs = |
751 val update_specs = |
749 ListPair.map mk_upd_spec (idxs, named_vars) @ |
752 ListPair.map mk_upd_spec (idxs, named_vars) @ |
750 [more_part_update r more :== mk_record (all_sels, more)]; |
753 [more_part_update r_scheme more :== mk_record (all_sels, more)]; |
751 |
754 |
752 (*makes*) |
755 (*derived operations*) |
753 val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT])); |
756 val make_spec = Const (full makeN, parentT ---> types ---> recT) $$ r_parent $$ vars :== |
754 val make = Const (mk_makeC recT (full makeN, all_types)); |
757 mk_record (flat (map (mk_named_sels parent_names) r_parent) @ named_vars, HOLogic.unit); |
755 val make_specs = |
758 val extend_spec = Const (full extendN, recT --> moreT --> rec_schemeT) $ r $ more :== |
756 [list_comb (make_scheme, all_vars) $ more :== rec_scheme, |
759 mk_record (mk_named_sels all_names r, more); |
757 list_comb (make, all_vars) :== rec_]; |
760 val truncate_spec = Const (full truncateN, rec_schemeT --> recT) $ r_scheme :== |
758 val record_spec = |
761 mk_record (all_sels, HOLogic.unit); |
759 Const (full recordN, rec_schemeT --> recT) $ r :== mk_record (all_sels, HOLogic.unit); |
|
760 |
762 |
761 |
763 |
762 (* prepare propositions *) |
764 (* prepare propositions *) |
763 |
765 |
764 (*selectors*) |
766 (*selectors*) |
777 let val more' = Free (variant all_xs (moreN ^ "'"), moreT) |
779 let val more' = Free (variant all_xs (moreN ^ "'"), moreT) |
778 in [more_part_update rec_scheme more' === mk_record (all_named_vars, more')] end; |
780 in [more_part_update rec_scheme more' === mk_record (all_named_vars, more')] end; |
779 |
781 |
780 (*equality*) |
782 (*equality*) |
781 fun mk_sel_eq (t, T) = |
783 fun mk_sel_eq (t, T) = |
782 let val t' = Term.abstract_over (r, t) |
784 let val t' = Term.abstract_over (r_scheme, t) |
783 in Trueprop (HOLogic.eq_const T $ Term.incr_boundvars 1 t' $ t') end; |
785 in Trueprop (HOLogic.eq_const T $ Term.incr_boundvars 1 t' $ t') end; |
784 val sel_eqs = map2 mk_sel_eq (map (mk_sel r) all_names @ [more_part r], all_types @ [moreT]); |
786 val sel_eqs = |
|
787 map2 mk_sel_eq (map (mk_sel r_scheme) all_names @ [more_part r_scheme], all_types @ [moreT]); |
785 val equality_prop = |
788 val equality_prop = |
786 Term.all rec_schemeT $ (Abs ("r", rec_schemeT, |
789 Term.all rec_schemeT $ (Abs ("r", rec_schemeT, |
787 Term.all rec_schemeT $ (Abs ("r'", rec_schemeT, |
790 Term.all rec_schemeT $ (Abs ("r'", rec_schemeT, |
788 Logic.list_implies (sel_eqs, |
791 Logic.list_implies (sel_eqs, |
789 Trueprop (HOLogic.eq_const rec_schemeT $ Bound 1 $ Bound 0)))))); |
792 Trueprop (HOLogic.eq_const rec_schemeT $ Bound 1 $ Bound 0)))))); |
790 |
793 |
791 (*induct*) |
794 (*induct*) |
792 val P = Free ("P", rec_schemeT --> HOLogic.boolT); |
795 val P = Free ("P", rec_schemeT --> HOLogic.boolT); |
793 val P' = Free ("P", recT --> HOLogic.boolT); |
796 val P' = Free ("P", recT --> HOLogic.boolT); |
794 val induct_scheme_prop = |
797 val induct_scheme_prop = |
795 All (all_xs_more ~~ all_types_more) (Trueprop (P $ rec_scheme)) ==> Trueprop (P $ r); |
798 All (all_xs_more ~~ all_types_more) (Trueprop (P $ rec_scheme)) ==> Trueprop (P $ r_scheme); |
796 val induct_prop = All (all_xs ~~ all_types) (Trueprop (P' $ rec_)) ==> Trueprop (P' $ r'); |
799 val induct_prop = All (all_xs ~~ all_types) (Trueprop (P' $ rec_)) ==> Trueprop (P' $ r); |
797 |
800 |
798 (*cases*) |
801 (*cases*) |
799 val C = Trueprop (Free (variant all_xs_more "C", HOLogic.boolT)); |
802 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; |
803 val cases_scheme_prop = |
801 val cases_prop = All (all_xs ~~ all_types) ((r' === rec_) ==> C) ==> C; |
804 All (all_xs_more ~~ all_types_more) ((r_scheme === rec_scheme) ==> C) ==> C; |
|
805 val cases_prop = All (all_xs ~~ all_types) ((r === rec_) ==> C) ==> C; |
802 |
806 |
803 |
807 |
804 (* 1st stage: fields_thy *) |
808 (* 1st stage: fields_thy *) |
805 |
809 |
806 val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) = |
810 val (fields_thy, field_simps, field_injects, field_splits, field_inducts, field_cases) = |
811 val named_splits = map2 (fn (c, th) => (suffix field_typeN c, th)) (names, field_splits); |
815 val named_splits = map2 (fn (c, th) => (suffix field_typeN c, th)) (names, field_splits); |
812 |
816 |
813 |
817 |
814 (* 2nd stage: defs_thy *) |
818 (* 2nd stage: defs_thy *) |
815 |
819 |
816 val (defs_thy, (((sel_defs, update_defs), make_defs), [record_def])) = |
820 val (defs_thy, (((sel_defs, update_defs), derived_defs))) = |
817 fields_thy |
821 fields_thy |
818 |> add_record_splits named_splits |
822 |> add_record_splits named_splits |
819 |> Theory.parent_path |
823 |> Theory.parent_path |
820 |> Theory.add_tyabbrs_i recordT_specs (*not made part of record name space!*) |
824 |> Theory.add_tyabbrs_i recordT_specs (*not made part of record name space!*) |
821 |> Theory.add_path bname |
825 |> Theory.add_path bname |
822 |> Theory.add_trfuns ([], [], field_tr's, []) |
826 |> Theory.add_trfuns ([], [], field_tr's, []) |
823 |> (Theory.add_consts_i o map Syntax.no_syn) |
827 |> (Theory.add_consts_i o map Syntax.no_syn) |
824 (sel_decls @ update_decls @ make_decls @ [record_decl]) |
828 (sel_decls @ update_decls @ [make_decl, extend_decl, truncate_decl]) |
825 |> (PureThy.add_defs_i false o map Thm.no_attributes) sel_specs |
829 |> (PureThy.add_defs_i false o map Thm.no_attributes) sel_specs |
826 |>>> (PureThy.add_defs_i false o map Thm.no_attributes) update_specs |
830 |>>> (PureThy.add_defs_i false o map Thm.no_attributes) update_specs |
827 |>>> (PureThy.add_defs_i false o map Thm.no_attributes) make_specs |
831 |>>> (PureThy.add_defs_i false o map Thm.no_attributes) |
828 |>>> (PureThy.add_defs_i false o map Thm.no_attributes) [record_spec]; |
832 [make_spec, extend_spec, truncate_spec]; |
829 |
833 |
830 val defs_sg = Theory.sign_of defs_thy; |
834 val defs_sg = Theory.sign_of defs_thy; |
831 |
835 |
832 |
836 |
833 (* 3rd stage: thms_thy *) |
837 (* 3rd stage: thms_thy *) |
866 val thms_thy = |
870 val thms_thy = |
867 defs_thy |
871 defs_thy |
868 |> (#1 oo (PureThy.add_thmss o map Thm.no_attributes)) |
872 |> (#1 oo (PureThy.add_thmss o map Thm.no_attributes)) |
869 [("select_defs", sel_defs), |
873 [("select_defs", sel_defs), |
870 ("update_defs", update_defs), |
874 ("update_defs", update_defs), |
871 ("make_defs", make_defs), |
875 ("derived_defs", derived_defs), |
872 ("select_convs", sel_convs), |
876 ("select_convs", sel_convs), |
873 ("update_convs", update_convs)] |
877 ("update_convs", update_convs)] |
874 |> (#1 oo PureThy.add_thms) |
878 |> (#1 oo PureThy.add_thms) |
875 [(("equality", equality), [Classical.xtra_intro_global]), |
879 [(("equality", equality), [Classical.xtra_intro_global]), |
876 (("induct_scheme", induct_scheme), |
880 (("induct_scheme", induct_scheme), |