652 (Syntax.term_of_typ false (HOLogic.unitT)); |
652 (Syntax.term_of_typ false (HOLogic.unitT)); |
653 val adv_record_type_scheme_tr = |
653 val adv_record_type_scheme_tr = |
654 gen_adv_record_type_scheme_tr "_field_types" "_field_type" ext_typeN; |
654 gen_adv_record_type_scheme_tr "_field_types" "_field_type" ext_typeN; |
655 |
655 |
656 |
656 |
657 val parse_translation = |
657 val parse_translation = |
658 [("_record_update", record_update_tr), |
658 [("_record_update", record_update_tr), |
659 ("_update_name", update_name_tr)]; |
659 ("_update_name", update_name_tr)]; |
660 |
660 |
661 |
661 |
662 val adv_parse_translation = |
662 val adv_parse_translation = |
663 [("_record",adv_record_tr), |
663 [("_record",adv_record_tr), |
664 ("_record_scheme",adv_record_scheme_tr), |
664 ("_record_scheme",adv_record_scheme_tr), |
665 ("_record_type",adv_record_type_tr), |
665 ("_record_type",adv_record_type_tr), |
666 ("_record_type_scheme",adv_record_type_scheme_tr)]; |
666 ("_record_type_scheme",adv_record_type_scheme_tr)]; |
667 |
667 |
874 val T = domain_type fT; |
874 val T = domain_type fT; |
875 val (x,T') = hd (Term.variant_frees t' [("x",T)]); |
875 val (x,T') = hd (Term.variant_frees t' [("x",T)]); |
876 val f_x = Free (f',fT)$(Free (x,T')); |
876 val f_x = Free (f',fT)$(Free (x,T')); |
877 fun is_constr (Const (c,_)$_) = can (unsuffix extN) c |
877 fun is_constr (Const (c,_)$_) = can (unsuffix extN) c |
878 | is_constr _ = false; |
878 | is_constr _ = false; |
879 fun subst (t as u$w) = if Free (f',fT)=u |
879 fun subst (t as u$w) = if Free (f',fT)=u |
880 then if is_constr w then f_x |
880 then if is_constr w then f_x |
881 else raise TERM ("abstract_over_fun_app",[t]) |
881 else raise TERM ("abstract_over_fun_app",[t]) |
882 else subst u$subst w |
882 else subst u$subst w |
883 | subst (Abs (x,T,t)) = (Abs (x,T,subst t)) |
883 | subst (Abs (x,T,t)) = (Abs (x,T,subst t)) |
884 | subst t = t |
884 | subst t = t |
885 val t'' = abstract_over (f_x,subst t'); |
885 val t'' = abstract_over (f_x,subst t'); |
886 val vars = strip_qnt_vars "all" t''; |
886 val vars = strip_qnt_vars "all" t''; |
887 val bdy = strip_qnt_body "all" t''; |
887 val bdy = strip_qnt_body "all" t''; |
888 |
888 |
889 in list_abs ((x,T')::vars,bdy) end |
889 in list_abs ((x,T')::vars,bdy) end |
890 | abstract_over_fun_app t = raise TERM ("abstract_over_fun_app",[t]); |
890 | abstract_over_fun_app t = raise TERM ("abstract_over_fun_app",[t]); |
891 (* Generates a theorem of the kind: |
891 (* Generates a theorem of the kind: |
892 * !!f x*. PROP P (f ( r x* ) x* == !!r x*. PROP P r x* |
892 * !!f x*. PROP P (f ( r x* ) x* == !!r x*. PROP P r x* |
893 *) |
893 *) |
894 fun mk_fun_apply_eq (Abs (f, fT, t)) thy = |
894 fun mk_fun_apply_eq (Abs (f, fT, t)) thy = |
895 let |
895 let |
896 val rT = domain_type fT; |
896 val rT = domain_type fT; |
897 val vars = Term.strip_qnt_vars "all" t; |
897 val vars = Term.strip_qnt_vars "all" t; |
898 val Ts = map snd vars; |
898 val Ts = map snd vars; |
899 val n = length vars; |
899 val n = length vars; |
900 fun app_bounds 0 t = t$Bound 0 |
900 fun app_bounds 0 t = t$Bound 0 |
901 | app_bounds n t = if n > 0 then app_bounds (n-1) (t$Bound n) else t |
901 | app_bounds n t = if n > 0 then app_bounds (n-1) (t$Bound n) else t |
902 |
902 |
903 |
903 |
904 val [P,r] = Term.variant_frees t [("P",rT::Ts--->Term.propT),("r",Ts--->rT)]; |
904 val [P,r] = Term.variant_frees t [("P",rT::Ts--->Term.propT),("r",Ts--->rT)]; |
905 val prop = Logic.mk_equals |
905 val prop = Logic.mk_equals |
906 (list_all ((f,fT)::vars, |
906 (list_all ((f,fT)::vars, |
907 app_bounds (n - 1) ((Free P)$(Bound n$app_bounds (n-1) (Free r)))), |
907 app_bounds (n - 1) ((Free P)$(Bound n$app_bounds (n-1) (Free r)))), |
908 list_all ((fst r,rT)::vars, |
908 list_all ((fst r,rT)::vars, |
909 app_bounds (n - 1) ((Free P)$Bound n))); |
909 app_bounds (n - 1) ((Free P)$Bound n))); |
910 val prove_standard = quick_and_dirty_prove true thy; |
910 val prove_standard = quick_and_dirty_prove true thy; |
911 val thm = prove_standard [] prop (fn prems => |
911 val thm = prove_standard [] prop (fn prems => |
912 EVERY [rtac equal_intr_rule 1, |
912 EVERY [rtac equal_intr_rule 1, |
913 Goal.norm_hhf_tac 1,REPEAT (etac meta_allE 1), atac 1, |
913 Goal.norm_hhf_tac 1,REPEAT (etac meta_allE 1), atac 1, |
914 Goal.norm_hhf_tac 1,REPEAT (etac meta_allE 1), atac 1]); |
914 Goal.norm_hhf_tac 1,REPEAT (etac meta_allE 1), atac 1]); |
915 in thm end |
915 in thm end |
916 | mk_fun_apply_eq t thy = raise TERM ("mk_fun_apply_eq",[t]); |
916 | mk_fun_apply_eq t thy = raise TERM ("mk_fun_apply_eq",[t]); |
917 |
917 |
926 (fn thy => fn _ => fn t => |
926 (fn thy => fn _ => fn t => |
927 (case t of (Const ("all", Type (_, [Type (_, [Type("fun",[T,T']), _]), _])))$ |
927 (case t of (Const ("all", Type (_, [Type (_, [Type("fun",[T,T']), _]), _])))$ |
928 (trm as Abs _) => |
928 (trm as Abs _) => |
929 (case rec_id (~1) T of |
929 (case rec_id (~1) T of |
930 "" => NONE |
930 "" => NONE |
931 | n => if T=T' |
931 | n => if T=T' |
932 then (let |
932 then (let |
933 val P=cterm_of thy (abstract_over_fun_app trm); |
933 val P=cterm_of thy (abstract_over_fun_app trm); |
934 val thm = mk_fun_apply_eq trm thy; |
934 val thm = mk_fun_apply_eq trm thy; |
935 val PV = cterm_of thy (hd (term_vars (prop_of thm))); |
935 val PV = cterm_of thy (hd (term_vars (prop_of thm))); |
936 val thm' = cterm_instantiate [(PV,P)] thm; |
936 val thm' = cterm_instantiate [(PV,P)] thm; |
937 in SOME thm' end handle TERM _ => NONE) |
937 in SOME thm' end handle TERM _ => NONE) |
938 else NONE) |
938 else NONE) |
939 | _ => NONE)) |
939 | _ => NONE)) |
940 end |
940 end |
941 |
941 |
942 fun prove_split_simp thy ss T prop = |
942 fun prove_split_simp thy ss T prop = |
943 let |
943 let |
1062 then let val kv = ("k", kT); |
1062 then let val kv = ("k", kT); |
1063 val kb = Bound (length vars); |
1063 val kb = Bound (length vars); |
1064 in ((Const (u,uT)$k$sprout,Const (u,uT)$kb$skeleton),kv::vars) end |
1064 in ((Const (u,uT)$k$sprout,Const (u,uT)$kb$skeleton),kv::vars) end |
1065 else ((sprout,skeleton),vars); |
1065 else ((sprout,skeleton),vars); |
1066 |
1066 |
1067 fun is_upd_same (sprout,skeleton) u |
1067 fun is_upd_same (sprout,skeleton) u |
1068 ((K_rec as Const ("Record.K_record",_))$ |
1068 ((K_rec as Const ("Record.K_record",_))$ |
1069 ((sel as Const (s,_))$r)) = |
1069 ((sel as Const (s,_))$r)) = |
1070 if (unsuffix updateN u) = s andalso (seed s sprout) = r |
1070 if (unsuffix updateN u) = s andalso (seed s sprout) = r |
1071 then SOME (K_rec,sel,seed s skeleton) |
1071 then SOME (K_rec,sel,seed s skeleton) |
1072 else NONE |
1072 else NONE |
1073 | is_upd_same _ _ _ = NONE |
1073 | is_upd_same _ _ _ = NONE |
1074 |
1074 |
1075 fun init_seed r = ((r,Bound 0), [("r", rT)]); |
1075 fun init_seed r = ((r,Bound 0), [("r", rT)]); |
1076 |
1076 |
1077 fun add (n:string) f fmaps = |
1077 fun add (n:string) f fmaps = |
1078 (case AList.lookup (op =) fmaps n of |
1078 (case AList.lookup (op =) fmaps n of |
1079 NONE => AList.update (op =) (n,[f]) fmaps |
1079 NONE => AList.update (op =) (n,[f]) fmaps |
1080 | SOME fs => AList.update (op =) (n,f::fs) fmaps) |
1080 | SOME fs => AList.update (op =) (n,f::fs) fmaps) |
1081 |
1081 |
1082 fun comps (n:string) T fmaps = |
1082 fun comps (n:string) T fmaps = |
1083 (case AList.lookup (op =) fmaps n of |
1083 (case AList.lookup (op =) fmaps n of |
1084 SOME fs => |
1084 SOME fs => |
1085 foldr1 (fn (f,g) => Const ("Fun.comp",(T-->T)-->(T-->T)-->(T-->T))$f$g) fs |
1085 foldr1 (fn (f,g) => Const ("Fun.comp",(T-->T)-->(T-->T)-->(T-->T))$f$g) fs |
1086 | NONE => error ("record_upd_simproc.comps")) |
1086 | NONE => error ("record_upd_simproc.comps")) |
1087 |
1087 |
1088 (* mk_updterm returns either |
1088 (* mk_updterm returns either |
1089 * - Init (orig-term, orig-term-skeleton, vars) if no optimisation can be made, |
1089 * - Init (orig-term, orig-term-skeleton, vars) if no optimisation can be made, |
1090 * where vars are the bound variables in the skeleton |
1090 * where vars are the bound variables in the skeleton |
1091 * - Inter (orig-term-skeleton,simplified-term-skeleton, |
1091 * - Inter (orig-term-skeleton,simplified-term-skeleton, |
1092 * vars, (term-sprout, skeleton-sprout)) |
1092 * vars, (term-sprout, skeleton-sprout)) |
1623 fun mkrefl (c,T) = Thm.reflexive |
1623 fun mkrefl (c,T) = Thm.reflexive |
1624 (cterm_of defs_thy (Free (Name.variant variants (base c ^ "'"),T-->T))); |
1624 (cterm_of defs_thy (Free (Name.variant variants (base c ^ "'"),T-->T))); |
1625 val refls = map mkrefl fields_more; |
1625 val refls = map mkrefl fields_more; |
1626 val dest_convs' = map mk_meta_eq dest_convs; |
1626 val dest_convs' = map mk_meta_eq dest_convs; |
1627 val map_eqs = map (uncurry Thm.combination) (refls ~~ dest_convs'); |
1627 val map_eqs = map (uncurry Thm.combination) (refls ~~ dest_convs'); |
1628 |
1628 |
1629 val constr_refl = Thm.reflexive (cterm_of defs_thy (head_of ext)); |
1629 val constr_refl = Thm.reflexive (cterm_of defs_thy (head_of ext)); |
1630 |
1630 |
1631 fun mkthm (udef,(fld_refl,thms)) = |
1631 fun mkthm (udef,(fld_refl,thms)) = |
1632 let val bdyeq = Library.foldl (uncurry Thm.combination) (constr_refl,thms); |
1632 let val bdyeq = Library.foldl (uncurry Thm.combination) (constr_refl,thms); |
1633 (* (|N=N (|N=N,M=M,K=K,more=more|) |
1633 (* (|N=N (|N=N,M=M,K=K,more=more|) |
1662 rtac (prop_subst OF [surjective]) 1, |
1662 rtac (prop_subst OF [surjective]) 1, |
1663 REPEAT (etac meta_allE 1), atac 1]); |
1663 REPEAT (etac meta_allE 1), atac 1]); |
1664 val split_meta = timeit_msg "record extension split_meta proof:" split_meta_prf; |
1664 val split_meta = timeit_msg "record extension split_meta proof:" split_meta_prf; |
1665 |
1665 |
1666 |
1666 |
1667 val (([inject',induct',cases',surjective',split_meta'], |
1667 val (([inject',induct',cases',surjective',split_meta'], |
1668 [dest_convs',upd_convs']), |
1668 [dest_convs',upd_convs']), |
1669 thm_thy) = |
1669 thm_thy) = |
1670 defs_thy |
1670 defs_thy |
1671 |> (PureThy.add_thms o map Thm.no_attributes) |
1671 |> (PureThy.add_thms o map Thm.no_attributes) |
1672 [("ext_inject", inject), |
1672 [("ext_inject", inject), |
1913 (upd_decls @ [make_decl, fields_decl, extend_decl, truncate_decl]) |
1913 (upd_decls @ [make_decl, fields_decl, extend_decl, truncate_decl]) |
1914 |> ((PureThy.add_defs_i false o map Thm.no_attributes) sel_specs) |
1914 |> ((PureThy.add_defs_i false o map Thm.no_attributes) sel_specs) |
1915 ||>> ((PureThy.add_defs_i false o map Thm.no_attributes) upd_specs) |
1915 ||>> ((PureThy.add_defs_i false o map Thm.no_attributes) upd_specs) |
1916 ||>> ((PureThy.add_defs_i false o map Thm.no_attributes) |
1916 ||>> ((PureThy.add_defs_i false o map Thm.no_attributes) |
1917 [make_spec, fields_spec, extend_spec, truncate_spec]) |
1917 [make_spec, fields_spec, extend_spec, truncate_spec]) |
1918 |-> (fn defs as ((sel_defs, upd_defs), derived_defs) => |
1918 |-> (fn defs as ((sel_defs, upd_defs), derived_defs) => |
1919 fold Code.add_default_func sel_defs |
1919 fold Code.add_default_func sel_defs |
1920 #> fold Code.add_default_func upd_defs |
1920 #> fold Code.add_default_func upd_defs |
1921 #> fold Code.add_default_func derived_defs |
1921 #> fold Code.add_default_func derived_defs |
1922 #> pair defs) |
1922 #> pair defs) |
1923 val (((sel_defs, upd_defs), derived_defs), defs_thy) = |
1923 val (((sel_defs, upd_defs), derived_defs), defs_thy) = |