113 then show "R a b" using R_sym by blast |
113 then show "R a b" using R_sym by blast |
114 qed |
114 qed |
115 |
115 |
116 lemma REPS_same: |
116 lemma REPS_same: |
117 shows "R (REP a) (REP b) \<equiv> (a = b)" |
117 shows "R (REP a) (REP b) \<equiv> (a = b)" |
118 apply (rule eq_reflection) |
118 proof - |
119 proof |
119 have "R (REP a) (REP b) = (a = b)" |
120 assume as: "R (REP a) (REP b)" |
120 proof |
121 from rep_prop |
121 assume as: "R (REP a) (REP b)" |
122 obtain x y |
122 from rep_prop |
123 where eqs: "Rep a = R x" "Rep b = R y" by blast |
123 obtain x y |
124 from eqs have "R (Eps (R x)) (Eps (R y))" using as unfolding REP_def by simp |
124 where eqs: "Rep a = R x" "Rep b = R y" by blast |
125 then have "R x (Eps (R y))" using lem9 by simp |
125 from eqs have "R (Eps (R x)) (Eps (R y))" using as unfolding REP_def by simp |
126 then have "R (Eps (R y)) x" using R_sym by blast |
126 then have "R x (Eps (R y))" using lem9 by simp |
127 then have "R y x" using lem9 by simp |
127 then have "R (Eps (R y)) x" using R_sym by blast |
128 then have "R x y" using R_sym by blast |
128 then have "R y x" using lem9 by simp |
129 then have "ABS x = ABS y" using thm11 by simp |
129 then have "R x y" using R_sym by blast |
130 then have "Abs (Rep a) = Abs (Rep b)" using eqs unfolding ABS_def by simp |
130 then have "ABS x = ABS y" using thm11 by simp |
131 then show "a = b" using rep_inverse by simp |
131 then have "Abs (Rep a) = Abs (Rep b)" using eqs unfolding ABS_def by simp |
132 next |
132 then show "a = b" using rep_inverse by simp |
133 assume ab: "a = b" |
133 next |
134 have "REFL R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp |
134 assume ab: "a = b" |
135 then show "R (REP a) (REP b)" unfolding REFL_def using ab by auto |
135 have "REFL R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp |
|
136 then show "R (REP a) (REP b)" unfolding REFL_def using ab by auto |
|
137 qed |
|
138 then show "R (REP a) (REP b) \<equiv> (a = b)" by simp |
136 qed |
139 qed |
137 |
140 |
138 end |
141 end |
139 |
142 |
140 section {* type definition for the quotient type *} |
143 section {* type definition for the quotient type *} |
146 val [x, c] = [("x", ty), ("c", ty --> @{typ bool})] |
149 val [x, c] = [("x", ty), ("c", ty --> @{typ bool})] |
147 |> Variable.variant_frees lthy [rel] |
150 |> Variable.variant_frees lthy [rel] |
148 |> map Free |
151 |> map Free |
149 in |
152 in |
150 lambda c |
153 lambda c |
151 (HOLogic.mk_exists |
154 (HOLogic.exists_const ty $ |
152 ("x", ty, HOLogic.mk_eq (c, (rel $ x)))) |
155 lambda x (HOLogic.mk_eq (c, (rel $ x)))) |
153 end |
156 end |
154 *} |
157 |
155 |
158 |
156 ML {* |
|
157 (* makes the new type definitions and proves non-emptyness*) |
159 (* makes the new type definitions and proves non-emptyness*) |
158 fun typedef_make (qty_name, rel, ty) lthy = |
160 fun typedef_make (qty_name, rel, ty) lthy = |
159 let |
161 let |
160 val typedef_tac = |
162 val typedef_tac = |
161 EVERY1 [rewrite_goal_tac @{thms mem_def}, |
163 EVERY1 [rewrite_goal_tac @{thms mem_def}, |
162 rtac @{thm exI}, |
164 rtac @{thm exI}, |
163 rtac @{thm exI}, |
165 rtac @{thm exI}, |
164 rtac @{thm refl}] |
166 rtac @{thm refl}] |
165 in |
167 in |
166 LocalTheory.theory_result |
168 LocalTheory.theory_result |
167 (Typedef.add_typedef false NONE |
169 (Typedef.add_typedef false NONE |
168 (qty_name, map fst (Term.add_tfreesT ty []), NoSyn) |
170 (qty_name, map fst (Term.add_tfreesT ty []), NoSyn) |
169 (typedef_term rel ty lthy) |
171 (typedef_term rel ty lthy) |
170 NONE typedef_tac) lthy |
172 NONE typedef_tac) lthy |
171 end |
173 end |
172 *} |
174 |
173 |
175 |
174 ML {* |
176 (* tactic to prove the QUOT_TYPE theorem for the new type *) |
175 (* proves the QUOT_TYPE theorem for the new type *) |
|
176 fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) = |
177 fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) = |
177 let |
178 let |
178 val rep_thm = #Rep typedef_info |
179 val rep_thm = #Rep typedef_info |
179 val rep_inv = #Rep_inverse typedef_info |
180 val rep_inv = #Rep_inverse typedef_info |
180 val abs_inv = #Abs_inverse typedef_info |
181 val abs_inv = #Abs_inverse typedef_info |
190 rtac rep_inv, |
191 rtac rep_inv, |
191 rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl}, |
192 rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl}, |
192 rtac rep_inj] |
193 rtac rep_inj] |
193 end |
194 end |
194 |
195 |
|
196 |
195 fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy = |
197 fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy = |
196 let |
198 let |
197 val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT) |
199 val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT) |
198 val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep) |
200 val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep) |
199 |> Syntax.check_term lthy |
201 |> Syntax.check_term lthy |
200 in |
202 in |
201 Goal.prove lthy [] [] goal |
203 Goal.prove lthy [] [] goal |
202 (K (typedef_quot_type_tac equiv_thm typedef_info)) |
204 (K (typedef_quot_type_tac equiv_thm typedef_info)) |
203 end |
205 end |
204 *} |
206 |
205 |
207 |
206 ML {* |
208 (* proves the quotient theorem *) |
207 fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy = |
209 fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy = |
208 let |
210 let |
209 val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT) |
211 val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT) |
210 val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep) |
212 val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep) |
211 |> Syntax.check_term lthy |
213 |> Syntax.check_term lthy |
213 val typedef_quotient_thm_tac = |
215 val typedef_quotient_thm_tac = |
214 EVERY1 [K (rewrite_goals_tac [abs_def, rep_def]), |
216 EVERY1 [K (rewrite_goals_tac [abs_def, rep_def]), |
215 rtac @{thm QUOT_TYPE.QUOTIENT}, |
217 rtac @{thm QUOT_TYPE.QUOTIENT}, |
216 rtac quot_type_thm] |
218 rtac quot_type_thm] |
217 in |
219 in |
218 Goal.prove lthy [] [] goal |
220 Goal.prove lthy [] [] goal |
219 (K typedef_quotient_thm_tac) |
221 (K typedef_quotient_thm_tac) |
220 end |
222 end |
221 *} |
223 *} |
222 |
224 |
223 text {* two wrappers for define and note *} |
225 text {* two wrappers for define and note *} |
424 val nty = Type (s, ntys) |
426 val nty = Type (s, ntys) |
425 val ftys = map (op -->) tys |
427 val ftys = map (op -->) tys |
426 in |
428 in |
427 (case (lookup (Context.Proof lthy) s) of |
429 (case (lookup (Context.Proof lthy) s) of |
428 SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty)) |
430 SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty)) |
429 | NONE => raise ERROR ("no map association for type " ^ s)) |
431 | NONE => raise ERROR ("no map association for type " ^ s)) |
430 end |
432 end |
431 |
433 |
432 fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty)) |
434 fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty)) |
433 | get_const rep = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty)) |
435 | get_const rep = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty)) |
|
436 |
|
437 fun mk_identity ty = Abs ("x", ty, Bound 0) |
|
438 |
434 in |
439 in |
435 if ty = qty |
440 if ty = qty |
436 then (get_const abs_or_rep) |
441 then (get_const abs_or_rep) |
437 else (case ty of |
442 else (case ty of |
438 TFree _ => (Abs ("x", ty, Bound 0), (ty, ty)) |
443 TFree _ => (mk_identity ty, (ty, ty)) |
439 | Type (_, []) => (Abs ("x", ty, Bound 0), (ty, ty)) |
444 | Type (_, []) => (mk_identity ty, (ty, ty)) |
440 | Type (s, tys) => get_fun_aux s (map (get_fun abs_or_rep rty qty lthy) tys) |
445 | Type (s, tys) => get_fun_aux s (map (get_fun abs_or_rep rty qty lthy) tys) |
441 | _ => raise ERROR ("no variables") |
446 | _ => raise ERROR ("no type variables") |
442 ) |
447 ) |
443 end |
448 end |
444 *} |
449 *} |
445 |
450 |
446 ML {* |
451 ML {* |
674 lemma mem_cons: |
672 lemma mem_cons: |
675 fixes x :: "'a" |
673 fixes x :: "'a" |
676 fixes xs :: "'a list" |
674 fixes xs :: "'a list" |
677 assumes a : "x memb xs" |
675 assumes a : "x memb xs" |
678 shows "x # xs \<approx> xs" |
676 shows "x # xs \<approx> xs" |
679 using a apply (induct xs) |
677 using a |
680 apply (simp_all) |
678 apply (induct xs) |
681 apply (meson) |
679 apply (auto intro: list_eq.intros) |
682 apply (simp_all add: list_eq.intros(4)) |
680 done |
683 proof - |
|
684 fix a :: "'a" |
|
685 fix xs :: "'a list" |
|
686 assume a1 : "x # xs \<approx> xs" |
|
687 assume a2 : "x memb xs" |
|
688 have a3 : "x # a # xs \<approx> a # x # xs" using list_eq.intros(1)[of "x"] by blast |
|
689 have a4 : "a # x # xs \<approx> a # xs" using a1 list_eq.intros(5)[of "x # xs" "xs"] by simp |
|
690 then show "x # a # xs \<approx> a # xs" using a3 list_eq.intros(6) by blast |
|
691 qed |
|
692 |
681 |
693 lemma card1_suc: |
682 lemma card1_suc: |
694 fixes xs :: "'a list" |
683 fixes xs :: "'a list" |
695 fixes n :: "nat" |
684 fixes n :: "nat" |
696 assumes c: "card1 xs = Suc n" |
685 assumes c: "card1 xs = Suc n" |
697 shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)" |
686 shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)" |
698 using c apply (induct xs) |
687 using c |
699 apply (simp) |
688 apply(induct xs) |
700 (* apply (rule allI)*) |
689 apply (metis Suc_neq_Zero card1_0) |
701 proof - |
690 apply (metis QUOT_TYPE_I_fset.R_trans QuotMain.card1_cons list_eq_sym mem_cons) |
702 fix a :: "'a" |
691 done |
703 fix xs :: "'a list" |
|
704 fix n :: "nat" |
|
705 assume a1: "card1 xs = Suc n \<Longrightarrow> \<exists>a ys. \<not> a memb ys \<and> xs \<approx> a # ys" |
|
706 assume a2: "card1 (a # xs) = Suc n" |
|
707 from a1 a2 show "\<exists>aa ys. \<not> aa memb ys \<and> a # xs \<approx> aa # ys" |
|
708 apply - |
|
709 apply (rule True_or_False [of "a memb xs", THEN disjE]) |
|
710 apply (simp_all add: card1_cons if_True simp_thms) |
|
711 proof - |
|
712 assume a1: "\<exists>a ys. \<not> a memb ys \<and> xs \<approx> a # ys" |
|
713 assume a2: "card1 xs = Suc n" |
|
714 assume a3: "a memb xs" |
|
715 from a1 obtain b ys where a5: "\<not> b memb ys \<and> xs \<approx> b # ys" by blast |
|
716 from a2 a3 a5 show "\<exists>aa ys. \<not> aa memb ys \<and> a # xs \<approx> aa # ys" |
|
717 apply - |
|
718 apply (rule_tac x = "b" in exI) |
|
719 apply (rule_tac x = "ys" in exI) |
|
720 apply (simp_all) |
|
721 proof - |
|
722 assume a1: "a memb xs" |
|
723 assume a2: "\<not> b memb ys \<and> xs \<approx> b # ys" |
|
724 then have a3: "xs \<approx> b # ys" by simp |
|
725 have "a # xs \<approx> xs" using a1 mem_cons[of "a" "xs"] by simp |
|
726 then show "a # xs \<approx> b # ys" using a3 list_eq.intros(6) by blast |
|
727 qed |
|
728 next |
|
729 assume a2: "\<not> a memb xs" |
|
730 from a2 show "\<exists>aa ys. \<not> aa memb ys \<and> a # xs \<approx> aa # ys" |
|
731 apply - |
|
732 apply (rule_tac x = "a" in exI) |
|
733 apply (rule_tac x = "xs" in exI) |
|
734 apply (simp) |
|
735 apply (rule list_eq_refl) |
|
736 done |
|
737 qed |
|
738 qed |
|
739 |
692 |
740 lemma cons_preserves: |
693 lemma cons_preserves: |
741 fixes z |
694 fixes z |
742 assumes a: "xs \<approx> ys" |
695 assumes a: "xs \<approx> ys" |
743 shows "(z # xs) \<approx> (z # ys)" |
696 shows "(z # xs) \<approx> (z # ys)" |
744 using a by (rule QuotMain.list_eq.intros(5)) |
697 using a by (rule QuotMain.list_eq.intros(5)) |
745 |
698 |
746 |
699 |
747 text {* |
700 text {* |
748 unlam_def converts a definition theorem given as 'a = \lambda x. \lambda y. f (x y)' |
701 Unlam_def converts a definition given as |
749 to a theorem 'a x y = f (x, y)'. These are needed to rewrite right-to-left. |
702 |
|
703 c \<equiv> %x. %y. f x y |
|
704 |
|
705 to a theorem of the form |
|
706 |
|
707 c x y \<equiv> f x y |
|
708 |
|
709 This function is needed to rewrite the right-hand |
|
710 side to the left-hand side. |
750 *} |
711 *} |
751 |
712 |
752 ML {* |
713 ML {* |
753 fun unlam_def_aux orig_ctxt ctxt t = |
714 fun unlam_def_aux orig_ctxt ctxt t = |
754 let val rhs = Thm.rhs_of t in |
715 let val rhs = Thm.rhs_of t in |
854 apply (simp add: QUOT_TYPE_I_fset.thm10) |
815 apply (simp add: QUOT_TYPE_I_fset.thm10) |
855 done |
816 done |
856 |
817 |
857 ML {* |
818 ML {* |
858 fun mk_rep_abs x = @{term REP_fset} $ (@{term ABS_fset} $ x) |
819 fun mk_rep_abs x = @{term REP_fset} $ (@{term ABS_fset} $ x) |
859 val consts = [@{const_name "Nil"}, @{const_name "append"}, @{const_name "Cons"}, @{const_name "membship"}, @{const_name "card1"}] |
820 val consts = [@{const_name "Nil"}, @{const_name "append"}, |
860 *} |
821 @{const_name "Cons"}, @{const_name "membship"}, |
861 |
822 @{const_name "card1"}] |
862 ML lambda |
823 *} |
863 |
824 |
864 ML {* |
825 ML {* |
865 fun build_goal ctxt thm constructors lifted_type mk_rep_abs = |
826 fun build_goal ctxt thm constructors lifted_type mk_rep_abs = |
866 let |
827 let |
867 fun is_constructor (Const (x, _)) = member (op =) constructors x |
828 fun is_constructor (Const (x, _)) = member (op =) constructors x |
955 val (bop_s, _) = Term.dest_Const (Thm.term_of bop); |
918 val (bop_s, _) = Term.dest_Const (Thm.term_of bop); |
956 in |
919 in |
957 if bop_s = "op =" then pair else (raise CTERM ("Not an equality", [t])) |
920 if bop_s = "op =" then pair else (raise CTERM ("Not an equality", [t])) |
958 end |
921 end |
959 *} |
922 *} |
|
923 |
960 ML Thm.instantiate |
924 ML Thm.instantiate |
961 ML {*@{thm arg_cong2}*} |
925 ML {*@{thm arg_cong2}*} |
962 ML {*@{thm arg_cong2[of _ _ _ _ "op ="]} *} |
926 ML {*@{thm arg_cong2[of _ _ _ _ "op ="]} *} |
963 ML {* val cT = @{cpat "op ="} |> Thm.ctyp_of_term |> Thm.dest_ctyp |> hd *} |
927 ML {* val cT = @{cpat "op ="} |> Thm.ctyp_of_term |> Thm.dest_ctyp |> hd *} |
964 ML {* |
928 ML {* |
965 Toplevel.program (fn () => |
929 Toplevel.program (fn () => |
966 Drule.instantiate' [SOME cT, SOME cT, SOME @{ctyp bool}] [NONE, NONE, NONE, NONE, SOME (@{cpat "op ="})] @{thm arg_cong2} |
930 Drule.instantiate' [SOME cT,SOME cT,SOME @{ctyp bool}] [NONE,NONE,NONE,NONE,SOME (@{cpat "op ="})] @{thm arg_cong2} |
967 ) |
931 ) |
968 *} |
932 *} |
969 |
933 |
970 ML {* |
934 ML {* |
971 fun split_binop_conv t = |
935 fun split_binop_conv t = |
972 let |
936 let |
973 val _ = tracing (Syntax.string_of_term @{context} (term_of t)) |
|
974 val (lhs, rhs) = dest_ceq t; |
937 val (lhs, rhs) = dest_ceq t; |
975 val (bop, _) = dest_cbinop lhs; |
938 val (bop, _) = dest_cbinop lhs; |
976 val [clT, cr2] = bop |> Thm.ctyp_of_term |> Thm.dest_ctyp; |
939 val [clT, cr2] = bop |> Thm.ctyp_of_term |> Thm.dest_ctyp; |
977 val [cmT, crT] = Thm.dest_ctyp cr2; |
940 val [cmT, crT] = Thm.dest_ctyp cr2; |
978 in |
941 in |
1039 CHANGED o (ObjectLogic.full_atomize_tac) |
1002 CHANGED o (ObjectLogic.full_atomize_tac) |
1040 ]) |
1003 ]) |
1041 *} |
1004 *} |
1042 |
1005 |
1043 ML {* |
1006 ML {* |
|
1007 <<<<<<< variant A |
1044 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1})) |
1008 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1})) |
1045 val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs |
1009 val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs |
|
1010 >>>>>>> variant B |
|
1011 val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm m1})) |
|
1012 val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs |
|
1013 ####### Ancestor |
|
1014 val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1})) |
|
1015 val goal = build_goal m1_novars consts @{typ "'a list"} mk_rep_abs |
|
1016 ======= end |
1046 val cgoal = cterm_of @{theory} goal |
1017 val cgoal = cterm_of @{theory} goal |
1047 val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal) |
1018 val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal) |
1048 *} |
1019 *} |
1049 |
1020 |
1050 (*notation ( output) "prop" ("#_" [1000] 1000) *) |
1021 (*notation ( output) "prop" ("#_" [1000] 1000) *) |