559 | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs" |
559 | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs" |
560 | "a#a#xs \<approx> a#xs" |
560 | "a#a#xs \<approx> a#xs" |
561 | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys" |
561 | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys" |
562 | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3" |
562 | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3" |
563 |
563 |
564 lemma list_eq_sym: |
564 lemma list_eq_refl: |
565 shows "xs \<approx> xs" |
565 shows "xs \<approx> xs" |
566 apply (induct xs) |
566 apply (induct xs) |
567 apply (auto intro: list_eq.intros) |
567 apply (auto intro: list_eq.intros) |
568 done |
568 done |
569 |
569 |
570 lemma equiv_list_eq: |
570 lemma equiv_list_eq: |
571 shows "EQUIV list_eq" |
571 shows "EQUIV list_eq" |
572 unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def |
572 unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def |
573 apply(auto intro: list_eq.intros list_eq_sym) |
573 apply(auto intro: list_eq.intros list_eq_refl) |
574 done |
574 done |
575 |
575 |
576 local_setup {* |
576 local_setup {* |
577 typedef_main (@{binding "fset"}, @{term "list_eq"}, @{typ "'a list"}, @{thm "equiv_list_eq"}) #> snd |
577 typedef_main (@{binding "fset"}, @{term "list_eq"}, @{typ "'a list"}, @{thm "equiv_list_eq"}) #> snd |
578 *} |
578 *} |
804 apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong) |
804 apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong) |
805 apply(rule mem_respects) |
805 apply(rule mem_respects) |
806 apply(rule list_eq.intros(3)) |
806 apply(rule list_eq.intros(3)) |
807 apply(unfold REP_fset_def ABS_fset_def) |
807 apply(unfold REP_fset_def ABS_fset_def) |
808 apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset]) |
808 apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset]) |
809 apply(rule list_eq_sym) |
809 apply(rule list_eq_refl) |
810 done |
810 done |
811 |
811 |
812 lemma append_respects_fst: |
812 lemma append_respects_fst: |
813 assumes a : "list_eq l1 l2" |
813 assumes a : "list_eq l1 l2" |
814 shows "list_eq (l1 @ s) (l2 @ s)" |
814 shows "list_eq (l1 @ s) (l2 @ s)" |
815 using a |
815 using a |
816 apply(induct) |
816 apply(induct) |
817 apply(auto intro: list_eq.intros) |
817 apply(auto intro: list_eq.intros) |
818 apply(simp add: list_eq_sym) |
818 apply(simp add: list_eq_refl) |
819 done |
819 done |
820 |
820 |
821 lemma yyy: |
821 lemma yyy: |
822 shows " |
822 shows " |
823 ( |
823 ( |
831 apply(rule_tac f="(op &)" in arg_cong2) |
831 apply(rule_tac f="(op &)" in arg_cong2) |
832 apply(rule_tac f="(op =)" in arg_cong2) |
832 apply(rule_tac f="(op =)" in arg_cong2) |
833 apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric]) |
833 apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric]) |
834 apply(rule append_respects_fst) |
834 apply(rule append_respects_fst) |
835 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp) |
835 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp) |
836 apply(rule list_eq_sym) |
836 apply(rule list_eq_refl) |
837 apply(simp) |
837 apply(simp) |
838 apply(rule_tac f="(op =)" in arg_cong2) |
838 apply(rule_tac f="(op =)" in arg_cong2) |
839 apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric]) |
839 apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric]) |
840 apply(rule append_respects_fst) |
840 apply(rule append_respects_fst) |
841 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp) |
841 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp) |
842 apply(rule list_eq_sym) |
842 apply(rule list_eq_refl) |
843 apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric]) |
843 apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric]) |
844 apply(rule list_eq.intros(5)) |
844 apply(rule list_eq.intros(5)) |
845 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp) |
845 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp) |
846 apply(rule list_eq_sym) |
846 apply(rule list_eq_refl) |
847 done |
847 done |
848 |
848 |
849 lemma |
849 lemma |
850 shows " |
850 shows " |
851 (UNION EMPTY s = s) & |
851 (UNION EMPTY s = s) & |
860 *} |
860 *} |
861 |
861 |
862 ML lambda |
862 ML lambda |
863 |
863 |
864 ML {* |
864 ML {* |
865 fun build_goal thm constructors lifted_type mk_rep_abs = |
865 fun build_goal ctxt thm constructors lifted_type mk_rep_abs = |
866 let |
866 let |
867 fun is_const (Const (x, t)) = x mem constructors |
867 fun is_constructor (Const (x, _)) = member (op =) constructors x |
|
868 | is_constructor _ = false; |
|
869 |
|
870 fun maybe_mk_rep_abs t = |
|
871 let |
|
872 val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t) |
|
873 in |
|
874 if type_of t = lifted_type then mk_rep_abs t else t |
|
875 end; |
|
876 |
|
877 fun build_aux ctxt1 tm = |
|
878 let |
|
879 val (head, args) = Term.strip_comb tm; |
|
880 val args' = map (build_aux ctxt1) args; |
|
881 in |
|
882 (case head of |
|
883 Abs (x, T, t) => |
|
884 let |
|
885 val ([x'], ctxt2) = Variable.variant_fixes [x] ctxt1; |
|
886 val v = Free (x', T); |
|
887 val t' = subst_bound (v, t); |
|
888 val rec_term = build_aux ctxt2 t'; |
|
889 in Term.lambda_name (x, v) rec_term end |
|
890 | _ => |
|
891 if is_constructor head then |
|
892 maybe_mk_rep_abs (list_comb (head, map maybe_mk_rep_abs args')) |
|
893 else list_comb (head, args')) |
|
894 end; |
|
895 |
|
896 val concl2 = Thm.prop_of thm; |
|
897 in |
|
898 Logic.mk_equals (build_aux ctxt concl2, concl2) |
|
899 end |
|
900 *} |
|
901 |
|
902 ML {* |
|
903 fun build_goal' ctxt thm constructors lifted_type mk_rep_abs = |
|
904 let |
|
905 fun is_const (Const (x, t)) = member (op =) constructors x |
868 | is_const _ = false |
906 | is_const _ = false |
869 fun maybe_mk_rep_abs t = |
907 fun maybe_mk_rep_abs t = |
870 let |
908 let |
871 val _ = writeln ("Maybe: " ^ Syntax.string_of_term @{context} t) |
909 val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t) |
872 in |
910 in |
873 if type_of t = lifted_type then mk_rep_abs t else t |
911 if type_of t = lifted_type then mk_rep_abs t else t |
874 end |
912 end |
875 (* handle TYPE _ => t*) |
913 (* handle TYPE _ => t*) |
876 fun build_aux (Abs (s, t, tr)) = |
914 fun build_aux ctxt1 (Abs (x, T, t)) = |
877 let |
915 let |
878 val [(fresh_s, _)] = Variable.variant_frees @{context} [] [(s, ())]; |
916 val ([x'], ctxt2) = Variable.variant_fixes [x] ctxt1; |
879 val newv = Free (fresh_s, t); |
917 val v = Free (x', T); |
880 val str = subst_bound (newv, tr); |
918 val t' = subst_bound (v, t); |
881 val rec_term = build_aux str; |
919 val rec_term = build_aux ctxt2 t'; |
882 val bound_term = lambda newv rec_term |
920 in Term.lambda_name (x, v) rec_term end |
883 in |
921 | build_aux ctxt1 (f $ a) = |
884 bound_term |
|
885 end |
|
886 | build_aux (f $ a) = |
|
887 let |
922 let |
888 val (f, args) = strip_comb (f $ a) |
923 val (f, args) = strip_comb (f $ a) |
889 val _ = writeln (Syntax.string_of_term @{context} f) |
924 val _ = writeln (Syntax.string_of_term ctxt f) |
890 in |
925 in |
891 (if is_const f then maybe_mk_rep_abs (list_comb (f, (map maybe_mk_rep_abs (map build_aux args)))) |
926 if is_const f then |
892 else list_comb ((build_aux f), (map build_aux args))) |
927 maybe_mk_rep_abs |
|
928 (list_comb (f, map maybe_mk_rep_abs (map (build_aux ctxt1) args))) |
|
929 else list_comb (build_aux ctxt1 f, map (build_aux ctxt1) args) |
893 end |
930 end |
894 | build_aux x = |
931 | build_aux _ x = |
895 if is_const x then maybe_mk_rep_abs x else x |
932 if is_const x then maybe_mk_rep_abs x else x |
896 val concl2 = term_of (#prop (crep_thm thm)) |
933 val concl2 = term_of (#prop (crep_thm thm)) |
897 in |
934 in |
898 Logic.mk_equals ((build_aux concl2), concl2) |
935 Logic.mk_equals (build_aux ctxt concl2, concl2) |
899 end *} |
936 end *} |
900 |
937 |
901 ML {* val fset_defs = @{thms EMPTY_def IN_def UNION_def card_def INSERT_def} *} |
938 ML {* val fset_defs = @{thms EMPTY_def IN_def UNION_def card_def INSERT_def} *} |
902 ML {* val fset_defs_sym = map (fn t => symmetric (unlam_def @{context} t)) fset_defs *} |
939 ML {* val fset_defs_sym = map (fn t => symmetric (unlam_def @{context} t)) fset_defs *} |
903 |
940 |
982 |
1019 |
983 lemma trueprop_cong: |
1020 lemma trueprop_cong: |
984 shows "(a \<equiv> b) \<Longrightarrow> (Trueprop a \<equiv> Trueprop b)" |
1021 shows "(a \<equiv> b) \<Longrightarrow> (Trueprop a \<equiv> Trueprop b)" |
985 by auto |
1022 by auto |
986 |
1023 |
|
1024 |
|
1025 thm QUOT_TYPE_I_fset.R_trans2 |
987 ML {* |
1026 ML {* |
988 fun foo_tac' ctxt = |
1027 fun foo_tac' ctxt = |
989 REPEAT_ALL_NEW (FIRST' [ |
1028 REPEAT_ALL_NEW (FIRST' [ |
990 rtac @{thm trueprop_cong}, |
1029 (* rtac @{thm trueprop_cong},*) |
991 rtac @{thm list_eq_sym}, |
1030 rtac @{thm list_eq_refl}, |
992 rtac @{thm cons_preserves}, |
1031 rtac @{thm cons_preserves}, |
993 rtac @{thm mem_respects}, |
1032 rtac @{thm mem_respects}, |
994 rtac @{thm card1_rsp}, |
1033 rtac @{thm card1_rsp}, |
995 rtac @{thm QUOT_TYPE_I_fset.R_trans2}, |
1034 rtac @{thm QUOT_TYPE_I_fset.R_trans2}, |
996 CHANGED o (simp_tac ((Simplifier.context ctxt HOL_ss) addsimps @{thms QUOT_TYPE_I_fset.REP_ABS_rsp})), |
1035 CHANGED o (simp_tac ((Simplifier.context ctxt HOL_ss) addsimps @{thms QUOT_TYPE_I_fset.REP_ABS_rsp})), |
997 DatatypeAux.cong_tac, |
1036 DatatypeAux.cong_tac, |
998 rtac @{thm ext}, |
1037 rtac @{thm ext}, |
999 (* rtac @{thm eq_reflection}*) |
1038 rtac @{thm eq_reflection}, |
1000 CHANGED o (ObjectLogic.full_atomize_tac) |
1039 CHANGED o (ObjectLogic.full_atomize_tac) |
1001 ]) |
1040 ]) |
1002 *} |
1041 *} |
1003 |
1042 |
1004 ML {* |
1043 ML {* |
1005 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1})) |
1044 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1})) |
1006 val goal = build_goal m1_novars consts @{typ "'a list"} mk_rep_abs |
1045 val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs |
1007 val cgoal = cterm_of @{theory} goal |
1046 val cgoal = cterm_of @{theory} goal |
1008 val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal) |
1047 val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal) |
1009 *} |
1048 *} |
1010 |
1049 |
1011 (*notation ( output) "prop" ("#_" [1000] 1000) *) |
1050 (*notation ( output) "prop" ("#_" [1000] 1000) *) |
1012 notation ( output) "Trueprop" ("#_" [1000] 1000) |
1051 notation ( output) "Trueprop" ("#_" [1000] 1000) |
1013 |
1052 |
|
1053 lemma atomize_eqv [atomize]: "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)" |
|
1054 (is "?rhs \<equiv> ?lhs") |
|
1055 proof |
|
1056 assume "PROP ?lhs" then show "PROP ?rhs" by unfold |
|
1057 next |
|
1058 assume *: "PROP ?rhs" |
|
1059 have "A = B" |
|
1060 proof (cases A) |
|
1061 case True |
|
1062 with * have B by unfold |
|
1063 with `A` show ?thesis by simp |
|
1064 next |
|
1065 case False |
|
1066 with * have "~ B" by auto |
|
1067 with `~ A` show ?thesis by simp |
|
1068 qed |
|
1069 then show "PROP ?lhs" by (rule eq_reflection) |
|
1070 qed |
|
1071 |
|
1072 |
1014 prove {* (Thm.term_of cgoal2) *} |
1073 prove {* (Thm.term_of cgoal2) *} |
1015 apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} ) |
1074 apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} ) |
|
1075 apply (atomize (full)) |
|
1076 |
|
1077 apply (rule trueprop_cong) |
1016 apply (tactic {* foo_tac' @{context} 1 *}) |
1078 apply (tactic {* foo_tac' @{context} 1 *}) |
|
1079 thm eq_reflection |
1017 done |
1080 done |
1018 |
1081 |
1019 thm length_append (* Not true but worth checking that the goal is correct *) |
1082 thm length_append (* Not true but worth checking that the goal is correct *) |
1020 ML {* |
1083 ML {* |
1021 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm length_append})) |
1084 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm length_append})) |