179 Type ("fun", [T, Type ("Nominal.noption", [replace_types U])]) |
179 Type ("fun", [T, Type ("Nominal.noption", [replace_types U])]) |
180 | replace_types (Type (s, Ts)) = |
180 | replace_types (Type (s, Ts)) = |
181 Type (getOpt (AList.lookup op = ps s, s), map replace_types Ts) |
181 Type (getOpt (AList.lookup op = ps s, s), map replace_types Ts) |
182 | replace_types T = T; |
182 | replace_types T = T; |
183 |
183 |
184 fun replace_types' (Type (s, Ts)) = |
|
185 Type (getOpt (AList.lookup op = rps s, s), map replace_types' Ts) |
|
186 | replace_types' T = T; |
|
187 |
|
188 val dts'' = map (fn (tvs, tname, mx, constrs) => (tvs, tname ^ "_Rep", NoSyn, |
184 val dts'' = map (fn (tvs, tname, mx, constrs) => (tvs, tname ^ "_Rep", NoSyn, |
189 map (fn (cname, cargs, mx) => (cname, |
185 map (fn (cname, cargs, mx) => (cname ^ "_Rep", |
190 map (augment_sort_typ o replace_types) cargs, NoSyn)) constrs)) dts'; |
186 map (augment_sort_typ o replace_types) cargs, NoSyn)) constrs)) dts'; |
191 |
187 |
192 val new_type_names' = map (fn n => n ^ "_Rep") new_type_names; |
188 val new_type_names' = map (fn n => n ^ "_Rep") new_type_names; |
193 val full_new_type_names' = map (Sign.full_name (sign_of thy)) new_type_names'; |
189 val full_new_type_names' = map (Sign.full_name (sign_of thy)) new_type_names'; |
194 |
190 |
663 (fn (i, ("Nominal.noption", _, _)) => NONE |
659 (fn (i, ("Nominal.noption", _, _)) => NONE |
664 | (i, (s, dts, constrs)) => |
660 | (i, (s, dts, constrs)) => |
665 let |
661 let |
666 val SOME index = AList.lookup op = ty_idxs i; |
662 val SOME index = AList.lookup op = ty_idxs i; |
667 val (constrs1, constrs2) = ListPair.unzip |
663 val (constrs1, constrs2) = ListPair.unzip |
668 (map (fn (cname, cargs) => apfst (pair (strip_nth_name 2 cname)) |
664 (map (fn (cname, cargs) => apfst (pair (strip_nth_name 2 (strip_nth_name 1 cname))) |
669 (foldl_map (fn (dts, dt) => |
665 (foldl_map (fn (dts, dt) => |
670 let val (dts', dt') = strip_option dt |
666 let val (dts', dt') = strip_option dt |
671 in (dts @ dts' @ [reindex dt'], (length dts, length dts')) end) |
667 in (dts @ dts' @ [reindex dt'], (length dts, length dts')) end) |
672 ([], cargs))) constrs) |
668 ([], cargs))) constrs) |
673 in SOME ((index, (strip_nth_name 1 s, map reindex dts, constrs1)), |
669 in SOME ((index, (strip_nth_name 1 s, map reindex dts, constrs1)), |
694 val newTs' = Library.take (length new_type_names, recTs'); |
694 val newTs' = Library.take (length new_type_names, recTs'); |
695 val newTs = Library.take (length new_type_names, recTs); |
695 val newTs = Library.take (length new_type_names, recTs); |
696 |
696 |
697 val full_new_type_names = map (Sign.full_name (sign_of thy)) new_type_names; |
697 val full_new_type_names = map (Sign.full_name (sign_of thy)) new_type_names; |
698 |
698 |
699 fun make_constr_def tname T T' ((thy, defs, eqns), ((cname, cargs), (cname', mx))) = |
699 fun make_constr_def tname T T' ((thy, defs, eqns), |
700 let |
700 (((cname_rep, _), (cname, cargs)), (cname', mx))) = |
701 fun constr_arg (dt, (j, l_args, r_args)) = |
701 let |
|
702 fun constr_arg ((dts, dt), (j, l_args, r_args)) = |
702 let |
703 let |
703 val x' = mk_Free "x" (typ_of_dtyp' dt) j; |
704 val xs = map (fn (dt, i) => mk_Free "x" (typ_of_dtyp descr'' sorts' dt) i) |
704 val (dts, dt') = strip_option dt; |
|
705 val xs = map (fn (dt, i) => mk_Free "x" (typ_of_dtyp' dt) i) |
|
706 (dts ~~ (j upto j + length dts - 1)) |
705 (dts ~~ (j upto j + length dts - 1)) |
707 val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts) |
706 val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts) |
708 val (dts', dt'') = strip_dtyp dt' |
|
709 in |
707 in |
710 (j + length dts + 1, |
708 (j + length dts + 1, |
711 xs @ x :: l_args, |
709 xs @ x :: l_args, |
712 foldr mk_abs_fun |
710 foldr mk_abs_fun |
713 (case dt'' of |
711 (case dt of |
714 DtRec k => if k < length new_type_names then |
712 DtRec k => if k < length new_type_names then |
715 list_abs (map (pair "z" o typ_of_dtyp') dts', |
713 Const (List.nth (rep_names, k), typ_of_dtyp descr'' sorts' dt --> |
716 Const (List.nth (rep_names, k), typ_of_dtyp' dt'' --> |
714 typ_of_dtyp descr sorts' dt) $ x |
717 typ_of_dtyp descr sorts' dt'') $ app_bnds x (length dts')) |
|
718 else error "nested recursion not (yet) supported" |
715 else error "nested recursion not (yet) supported" |
719 | _ => x) xs :: r_args) |
716 | _ => x) xs :: r_args) |
720 end |
717 end |
721 |
718 |
722 val (_, l_args, r_args) = foldr constr_arg (1, [], []) cargs; |
719 val (_, l_args, r_args) = foldr constr_arg (1, [], []) cargs; |
723 val abs_name = Sign.intern_const (Theory.sign_of thy) ("Abs_" ^ tname); |
720 val abs_name = Sign.intern_const (Theory.sign_of thy) ("Abs_" ^ tname); |
724 val rep_name = Sign.intern_const (Theory.sign_of thy) ("Rep_" ^ tname); |
721 val rep_name = Sign.intern_const (Theory.sign_of thy) ("Rep_" ^ tname); |
725 val constrT = map fastype_of l_args ---> T; |
722 val constrT = map fastype_of l_args ---> T; |
726 val lhs = list_comb (Const (Sign.full_name thy (Sign.base_name cname), |
723 val lhs = list_comb (Const (cname, constrT), l_args); |
727 constrT), l_args); |
724 val rhs = list_comb (Const (cname_rep, map fastype_of r_args ---> T'), r_args); |
728 val rhs = list_comb (Const (cname, map fastype_of r_args ---> T'), r_args); |
|
729 val def = Logic.mk_equals (lhs, Const (abs_name, T' --> T) $ rhs); |
725 val def = Logic.mk_equals (lhs, Const (abs_name, T' --> T) $ rhs); |
730 val eqn = HOLogic.mk_Trueprop (HOLogic.mk_eq |
726 val eqn = HOLogic.mk_Trueprop (HOLogic.mk_eq |
731 (Const (rep_name, T --> T') $ lhs, rhs)); |
727 (Const (rep_name, T --> T') $ lhs, rhs)); |
732 val def_name = (Sign.base_name cname) ^ "_def"; |
728 val def_name = (Sign.base_name cname) ^ "_def"; |
733 val ([def_thm], thy') = thy |> |
729 val ([def_thm], thy') = thy |> |
734 Theory.add_consts_i [(cname', constrT, mx)] |> |
730 Theory.add_consts_i [(cname', constrT, mx)] |> |
735 (PureThy.add_defs_i false o map Thm.no_attributes) [(def_name, def)] |
731 (PureThy.add_defs_i false o map Thm.no_attributes) [(def_name, def)] |
736 in (thy', defs @ [def_thm], eqns @ [eqn]) end; |
732 in (thy', defs @ [def_thm], eqns @ [eqn]) end; |
737 |
733 |
738 fun dt_constr_defs ((thy, defs, eqns, dist_lemmas), |
734 fun dt_constr_defs ((thy, defs, eqns, dist_lemmas), ((((((_, (_, _, constrs)), |
739 (((((_, (_, _, constrs)), tname), T), T'), constr_syntax)) = |
735 (_, (_, _, constrs'))), tname), T), T'), constr_syntax)) = |
740 let |
736 let |
741 val rep_const = cterm_of thy |
737 val rep_const = cterm_of thy |
742 (Const (Sign.intern_const thy ("Rep_" ^ tname), T --> T')); |
738 (Const (Sign.intern_const thy ("Rep_" ^ tname), T --> T')); |
743 val dist = standard (cterm_instantiate [(cterm_of thy distinct_f, rep_const)] distinct_lemma); |
739 val dist = standard (cterm_instantiate [(cterm_of thy distinct_f, rep_const)] distinct_lemma); |
744 val (thy', defs', eqns') = Library.foldl (make_constr_def tname T T') |
740 val (thy', defs', eqns') = Library.foldl (make_constr_def tname T T') |
745 ((Theory.add_path tname thy, defs, []), constrs ~~ constr_syntax) |
741 ((Theory.add_path tname thy, defs, []), constrs ~~ constrs' ~~ constr_syntax) |
746 in |
742 in |
747 (parent_path flat_names thy', defs', eqns @ [eqns'], dist_lemmas @ [dist]) |
743 (parent_path flat_names thy', defs', eqns @ [eqns'], dist_lemmas @ [dist]) |
748 end; |
744 end; |
749 |
745 |
750 val (thy8, constr_defs, constr_rep_eqns, dist_lemmas) = Library.foldl dt_constr_defs |
746 val (thy8, constr_defs, constr_rep_eqns, dist_lemmas) = Library.foldl dt_constr_defs |
751 ((thy7, [], [], []), List.take (descr, length new_type_names) ~~ |
747 ((thy7, [], [], []), List.take (descr, length new_type_names) ~~ |
|
748 List.take (pdescr, length new_type_names) ~~ |
752 new_type_names ~~ newTs ~~ newTs' ~~ constr_syntax); |
749 new_type_names ~~ newTs ~~ newTs' ~~ constr_syntax); |
753 |
750 |
754 val abs_inject_thms = map (fn tname => |
751 val abs_inject_thms = map (fn tname => |
755 PureThy.get_thm thy8 (Name ("Abs_" ^ tname ^ "_inject"))) new_type_names; |
752 PureThy.get_thm thy8 (Name ("Abs_" ^ tname ^ "_inject"))) new_type_names; |
756 |
753 |
866 (symmetric perm_fun_def :: abs_perm)) 1), |
860 (symmetric perm_fun_def :: abs_perm)) 1), |
867 TRY (simp_tac (HOL_basic_ss addsimps |
861 TRY (simp_tac (HOL_basic_ss addsimps |
868 (perm_fun_def :: perm_defs @ Rep_thms @ Abs_inverse_thms @ |
862 (perm_fun_def :: perm_defs @ Rep_thms @ Abs_inverse_thms @ |
869 perm_closed_thms)) 1)])) |
863 perm_closed_thms)) 1)])) |
870 end) (constrs ~~ constr_rep_thms)) (atoms ~~ perm_closed_thmss)) |
864 end) (constrs ~~ constr_rep_thms)) (atoms ~~ perm_closed_thmss)) |
871 end) (List.take (descr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss); |
865 end) (List.take (pdescr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss); |
872 |
866 |
873 (** prove injectivity of constructors **) |
867 (** prove injectivity of constructors **) |
874 |
868 |
875 val rep_inject_thms' = map (fn th => th RS sym) rep_inject_thms; |
869 val rep_inject_thms' = map (fn th => th RS sym) rep_inject_thms; |
876 val alpha = PureThy.get_thms thy8 (Name "alpha"); |
870 val alpha = PureThy.get_thms thy8 (Name "alpha"); |
877 val abs_fresh = PureThy.get_thms thy8 (Name "abs_fresh"); |
871 val abs_fresh = PureThy.get_thms thy8 (Name "abs_fresh"); |
878 val fresh_def = PureThy.get_thm thy8 (Name "fresh_def"); |
872 val fresh_def = PureThy.get_thm thy8 (Name "fresh_def"); |
879 val supp_def = PureThy.get_thm thy8 (Name "supp_def"); |
873 val supp_def = PureThy.get_thm thy8 (Name "supp_def"); |
880 |
874 |
881 val inject_thms = map (fn (((i, (_, _, constrs)), tname), constr_rep_thms) => |
875 val inject_thms = map (fn (((i, (_, _, constrs)), tname), constr_rep_thms) => |
882 let val T = replace_types' (nth_dtyp i) |
876 let val T = nth_dtyp' i |
883 in List.mapPartial (fn ((cname, dts), constr_rep_thm) => |
877 in List.mapPartial (fn ((cname, dts), constr_rep_thm) => |
884 if null dts then NONE else SOME |
878 if null dts then NONE else SOME |
885 let |
879 let |
886 val cname = Sign.intern_const thy8 |
880 val cname = Sign.intern_const thy8 |
887 (NameSpace.append tname (Sign.base_name cname)); |
881 (NameSpace.append tname (Sign.base_name cname)); |
888 |
882 |
889 fun make_inj (dt, (j, args1, args2, eqs)) = |
883 fun make_inj ((dts, dt), (j, args1, args2, eqs)) = |
890 let |
884 let |
891 val x' = mk_Free "x" (typ_of_dtyp' dt) j; |
885 val Ts_idx = map (typ_of_dtyp descr'' sorts') dts ~~ (j upto j + length dts - 1); |
892 val y' = mk_Free "y" (typ_of_dtyp' dt) j; |
|
893 val (dts, dt') = strip_option dt; |
|
894 val Ts_idx = map typ_of_dtyp' dts ~~ (j upto j + length dts - 1); |
|
895 val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx; |
886 val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx; |
896 val ys = map (fn (T, i) => mk_Free "y" T i) Ts_idx; |
887 val ys = map (fn (T, i) => mk_Free "y" T i) Ts_idx; |
897 val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts); |
888 val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts); |
898 val y = mk_Free "y" (typ_of_dtyp' dt') (j + length dts); |
889 val y = mk_Free "y" (typ_of_dtyp descr'' sorts' dt) (j + length dts) |
899 val (dts', dt'') = strip_dtyp dt'; |
|
900 in |
890 in |
901 (j + length dts + 1, |
891 (j + length dts + 1, |
902 xs @ (x :: args1), ys @ (y :: args2), |
892 xs @ (x :: args1), ys @ (y :: args2), |
903 HOLogic.mk_eq |
893 HOLogic.mk_eq |
904 (foldr mk_abs_fun x xs, foldr mk_abs_fun y ys) :: eqs) |
894 (foldr mk_abs_fun x xs, foldr mk_abs_fun y ys) :: eqs) |
918 alpha @ abs_perm @ abs_fresh @ rep_inject_thms @ |
908 alpha @ abs_perm @ abs_fresh @ rep_inject_thms @ |
919 perm_rep_perm_thms)) 1), |
909 perm_rep_perm_thms)) 1), |
920 TRY (asm_full_simp_tac (HOL_basic_ss addsimps (perm_fun_def :: |
910 TRY (asm_full_simp_tac (HOL_basic_ss addsimps (perm_fun_def :: |
921 expand_fun_eq :: rep_inject_thms @ perm_rep_perm_thms)) 1)])) |
911 expand_fun_eq :: rep_inject_thms @ perm_rep_perm_thms)) 1)])) |
922 end) (constrs ~~ constr_rep_thms) |
912 end) (constrs ~~ constr_rep_thms) |
923 end) (List.take (descr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss); |
913 end) (List.take (pdescr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss); |
924 |
914 |
925 (** equations for support and freshness **) |
915 (** equations for support and freshness **) |
926 |
916 |
927 val Un_assoc = PureThy.get_thm thy8 (Name "Un_assoc"); |
917 val Un_assoc = PureThy.get_thm thy8 (Name "Un_assoc"); |
928 val de_Morgan_conj = PureThy.get_thm thy8 (Name "de_Morgan_conj"); |
918 val de_Morgan_conj = PureThy.get_thm thy8 (Name "de_Morgan_conj"); |
929 val Collect_disj_eq = PureThy.get_thm thy8 (Name "Collect_disj_eq"); |
919 val Collect_disj_eq = PureThy.get_thm thy8 (Name "Collect_disj_eq"); |
930 val finite_Un = PureThy.get_thm thy8 (Name "finite_Un"); |
920 val finite_Un = PureThy.get_thm thy8 (Name "finite_Un"); |
931 |
921 |
932 val (supp_thms, fresh_thms) = ListPair.unzip (map ListPair.unzip |
922 val (supp_thms, fresh_thms) = ListPair.unzip (map ListPair.unzip |
933 (map (fn ((((i, (_, _, constrs)), tname), inject_thms'), perm_thms') => |
923 (map (fn ((((i, (_, _, constrs)), tname), inject_thms'), perm_thms') => |
934 let val T = replace_types' (nth_dtyp i) |
924 let val T = nth_dtyp' i |
935 in List.concat (map (fn (cname, dts) => map (fn atom => |
925 in List.concat (map (fn (cname, dts) => map (fn atom => |
936 let |
926 let |
937 val cname = Sign.intern_const thy8 |
927 val cname = Sign.intern_const thy8 |
938 (NameSpace.append tname (Sign.base_name cname)); |
928 (NameSpace.append tname (Sign.base_name cname)); |
939 val atomT = Type (atom, []); |
929 val atomT = Type (atom, []); |
940 |
930 |
941 fun process_constr (dt, (j, args1, args2)) = |
931 fun process_constr ((dts, dt), (j, args1, args2)) = |
942 let |
932 let |
943 val x' = mk_Free "x" (typ_of_dtyp' dt) j; |
933 val Ts_idx = map (typ_of_dtyp descr'' sorts') dts ~~ (j upto j + length dts - 1); |
944 val (dts, dt') = strip_option dt; |
|
945 val Ts_idx = map typ_of_dtyp' dts ~~ (j upto j + length dts - 1); |
|
946 val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx; |
934 val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx; |
947 val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts); |
935 val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts) |
948 val (dts', dt'') = strip_dtyp dt'; |
|
949 in |
936 in |
950 (j + length dts + 1, |
937 (j + length dts + 1, |
951 xs @ (x :: args1), foldr mk_abs_fun x xs :: args2) |
938 xs @ (x :: args1), foldr mk_abs_fun x xs :: args2) |
952 end; |
939 end; |
953 |
940 |
976 if null dts then HOLogic.true_const |
963 if null dts then HOLogic.true_const |
977 else foldr1 HOLogic.mk_conj (map fresh args2)))) |
964 else foldr1 HOLogic.mk_conj (map fresh args2)))) |
978 (fn _ => |
965 (fn _ => |
979 simp_tac (simpset_of thy8 addsimps [fresh_def, supp_thm]) 1))) |
966 simp_tac (simpset_of thy8 addsimps [fresh_def, supp_thm]) 1))) |
980 end) atoms) constrs) |
967 end) atoms) constrs) |
981 end) (List.take (descr, length new_type_names) ~~ new_type_names ~~ inject_thms ~~ perm_simps'))); |
968 end) (List.take (pdescr, length new_type_names) ~~ new_type_names ~~ inject_thms ~~ perm_simps'))); |
982 |
969 |
983 (**** weak induction theorem ****) |
970 (**** weak induction theorem ****) |
984 |
|
985 val arities = get_arities descr''; |
|
986 |
|
987 fun mk_funs_inv thm = |
|
988 let |
|
989 val {sign, prop, ...} = rep_thm thm; |
|
990 val _ $ (_ $ (Const (_, Type (_, [U, _])) $ _ $ S)) $ |
|
991 (_ $ (_ $ (r $ (a $ _)) $ _)) = Type.freeze prop; |
|
992 val used = add_term_tfree_names (a, []); |
|
993 |
|
994 fun mk_thm i = |
|
995 let |
|
996 val Ts = map (TFree o rpair HOLogic.typeS) |
|
997 (variantlist (replicate i "'t", used)); |
|
998 val f = Free ("f", Ts ---> U) |
|
999 in standard (Goal.prove sign [] [] (Logic.mk_implies |
|
1000 (HOLogic.mk_Trueprop (HOLogic.list_all |
|
1001 (map (pair "x") Ts, HOLogic.mk_mem (app_bnds f i, S))), |
|
1002 HOLogic.mk_Trueprop (HOLogic.mk_eq (list_abs (map (pair "x") Ts, |
|
1003 r $ (a $ app_bnds f i)), f)))) |
|
1004 (fn _ => EVERY [REPEAT (rtac ext 1), REPEAT (etac allE 1), rtac thm 1, atac 1])) |
|
1005 end |
|
1006 in map (fn r => r RS subst) (thm :: map mk_thm arities) end; |
|
1007 |
971 |
1008 fun mk_indrule_lemma ((prems, concls), (((i, _), T), U)) = |
972 fun mk_indrule_lemma ((prems, concls), (((i, _), T), U)) = |
1009 let |
973 let |
1010 val Rep_t = Const (List.nth (rep_names, i), T --> U) $ |
974 val Rep_t = Const (List.nth (rep_names, i), T --> U) $ |
1011 mk_Free "x" T i; |
975 mk_Free "x" T i; |