3 uses ("quotient_info.ML") |
3 uses ("quotient_info.ML") |
4 ("quotient.ML") |
4 ("quotient.ML") |
5 ("quotient_def.ML") |
5 ("quotient_def.ML") |
6 begin |
6 begin |
7 |
7 |
|
8 |
8 locale QUOT_TYPE = |
9 locale QUOT_TYPE = |
9 fixes R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
10 fixes R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
10 and Abs :: "('a \<Rightarrow> bool) \<Rightarrow> 'b" |
11 and Abs :: "('a \<Rightarrow> bool) \<Rightarrow> 'b" |
11 and Rep :: "'b \<Rightarrow> ('a \<Rightarrow> bool)" |
12 and Rep :: "'b \<Rightarrow> ('a \<Rightarrow> bool)" |
12 assumes equiv: "equivp R" |
13 assumes equivp: "equivp R" |
13 and rep_prop: "\<And>y. \<exists>x. Rep y = R x" |
14 and rep_prop: "\<And>y. \<exists>x. Rep y = R x" |
14 and rep_inverse: "\<And>x. Abs (Rep x) = x" |
15 and rep_inverse: "\<And>x. Abs (Rep x) = x" |
15 and abs_inverse: "\<And>x. (Rep (Abs (R x))) = (R x)" |
16 and abs_inverse: "\<And>x. (Rep (Abs (R x))) = (R x)" |
16 and rep_inject: "\<And>x y. (Rep x = Rep y) = (x = y)" |
17 and rep_inject: "\<And>x y. (Rep x = Rep y) = (x = y)" |
17 begin |
18 begin |
27 "REP a = Eps (Rep a)" |
28 "REP a = Eps (Rep a)" |
28 |
29 |
29 lemma lem9: |
30 lemma lem9: |
30 shows "R (Eps (R x)) = R x" |
31 shows "R (Eps (R x)) = R x" |
31 proof - |
32 proof - |
32 have a: "R x x" using equiv by (simp add: equivp_reflp_symp_transp reflp_def) |
33 have a: "R x x" using equivp by (simp add: equivp_reflp_symp_transp reflp_def) |
33 then have "R x (Eps (R x))" by (rule someI) |
34 then have "R x (Eps (R x))" by (rule someI) |
34 then show "R (Eps (R x)) = R x" |
35 then show "R (Eps (R x)) = R x" |
35 using equiv unfolding equivp_def by simp |
36 using equivp unfolding equivp_def by simp |
36 qed |
37 qed |
37 |
38 |
38 theorem thm10: |
39 theorem thm10: |
39 shows "ABS (REP a) \<equiv> a" |
40 shows "ABS (REP a) \<equiv> a" |
40 apply (rule eq_reflection) |
41 apply (rule eq_reflection) |
78 "Quotient R ABS REP" |
79 "Quotient R ABS REP" |
79 apply(unfold Quotient_def) |
80 apply(unfold Quotient_def) |
80 apply(simp add: thm10) |
81 apply(simp add: thm10) |
81 apply(simp add: REP_refl) |
82 apply(simp add: REP_refl) |
82 apply(subst thm11[symmetric]) |
83 apply(subst thm11[symmetric]) |
83 apply(simp add: equiv[simplified equivp_def]) |
84 apply(simp add: equivp[simplified equivp_def]) |
84 done |
85 done |
85 |
86 |
86 lemma R_trans: |
87 lemma R_trans: |
87 assumes ab: "R a b" |
88 assumes ab: "R a b" |
88 and bc: "R b c" |
89 and bc: "R b c" |
89 shows "R a c" |
90 shows "R a c" |
90 proof - |
91 proof - |
91 have tr: "transp R" using equiv equivp_reflp_symp_transp[of R] by simp |
92 have tr: "transp R" using equivp equivp_reflp_symp_transp[of R] by simp |
92 moreover have ab: "R a b" by fact |
93 moreover have ab: "R a b" by fact |
93 moreover have bc: "R b c" by fact |
94 moreover have bc: "R b c" by fact |
94 ultimately show "R a c" unfolding transp_def by blast |
95 ultimately show "R a c" unfolding transp_def by blast |
95 qed |
96 qed |
96 |
97 |
97 lemma R_sym: |
98 lemma R_sym: |
98 assumes ab: "R a b" |
99 assumes ab: "R a b" |
99 shows "R b a" |
100 shows "R b a" |
100 proof - |
101 proof - |
101 have re: "symp R" using equiv equivp_reflp_symp_transp[of R] by simp |
102 have re: "symp R" using equivp equivp_reflp_symp_transp[of R] by simp |
102 then show "R b a" using ab unfolding symp_def by blast |
103 then show "R b a" using ab unfolding symp_def by blast |
103 qed |
104 qed |
104 |
105 |
105 lemma R_trans2: |
106 lemma R_trans2: |
106 assumes ac: "R a c" |
107 assumes ac: "R a c" |
126 then have "ABS x = ABS y" using thm11 by simp |
127 then have "ABS x = ABS y" using thm11 by simp |
127 then have "Abs (Rep a) = Abs (Rep b)" using eqs unfolding ABS_def by simp |
128 then have "Abs (Rep a) = Abs (Rep b)" using eqs unfolding ABS_def by simp |
128 then show "a = b" using rep_inverse by simp |
129 then show "a = b" using rep_inverse by simp |
129 next |
130 next |
130 assume ab: "a = b" |
131 assume ab: "a = b" |
131 have "reflp R" using equiv equivp_reflp_symp_transp[of R] by simp |
132 have "reflp R" using equivp equivp_reflp_symp_transp[of R] by simp |
132 then show "R (REP a) (REP b)" unfolding reflp_def using ab by auto |
133 then show "R (REP a) (REP b)" unfolding reflp_def using ab by auto |
133 qed |
134 qed |
134 then show "R (REP a) (REP b) \<equiv> (a = b)" by simp |
135 then show "R (REP a) (REP b) \<equiv> (a = b)" by simp |
135 qed |
136 qed |
136 |
137 |
149 fun_quotient list_quotient |
150 fun_quotient list_quotient |
150 |
151 |
151 lemmas [quotient_rsp] = |
152 lemmas [quotient_rsp] = |
152 quot_rel_rsp nil_rsp cons_rsp foldl_rsp |
153 quot_rel_rsp nil_rsp cons_rsp foldl_rsp |
153 |
154 |
|
155 (* OPTION, PRODUCTS *) |
|
156 lemmas [quotient_equiv] = |
|
157 identity_equivp list_equivp |
|
158 |
|
159 |
154 ML {* maps_lookup @{theory} "List.list" *} |
160 ML {* maps_lookup @{theory} "List.list" *} |
155 ML {* maps_lookup @{theory} "*" *} |
161 ML {* maps_lookup @{theory} "*" *} |
156 ML {* maps_lookup @{theory} "fun" *} |
162 ML {* maps_lookup @{theory} "fun" *} |
157 |
163 |
158 |
164 |
162 |
168 |
163 |
169 |
164 (* lifting of constants *) |
170 (* lifting of constants *) |
165 use "quotient_def.ML" |
171 use "quotient_def.ML" |
166 |
172 |
167 (* TODO: Consider defining it with an "if"; sth like: |
|
168 Babs p m = \<lambda>x. if x \<in> p then m x else undefined |
|
169 *) |
|
170 definition |
173 definition |
171 Babs :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow> 'b" |
174 Babs :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow> 'b" |
172 where |
175 where |
173 "(x \<in> p) \<Longrightarrow> (Babs p m x = m x)" |
176 "(x \<in> p) \<Longrightarrow> (Babs p m x = m x)" |
174 |
177 |
492 - Ball (Respects ?E) ?P = All ?P |
494 - Ball (Respects ?E) ?P = All ?P |
493 - (\<And>x. ?R x \<Longrightarrow> ?P x \<longrightarrow> ?Q x) \<Longrightarrow> All ?P \<longrightarrow> Ball ?R ?Q |
495 - (\<And>x. ?R x \<Longrightarrow> ?P x \<longrightarrow> ?Q x) \<Longrightarrow> All ?P \<longrightarrow> Ball ?R ?Q |
494 |
496 |
495 *) |
497 *) |
496 |
498 |
497 (* FIXME: OPTION_equivp, PAIR_equivp, ... *) |
499 ML {* |
498 ML {* |
500 fun equiv_tac ctxt = |
499 fun equiv_tac rel_eqvs = |
|
500 REPEAT_ALL_NEW (FIRST' |
501 REPEAT_ALL_NEW (FIRST' |
501 [resolve_tac rel_eqvs, |
502 [resolve_tac (equiv_rules_get ctxt)]) |
502 rtac @{thm identity_equivp}, |
503 *} |
503 rtac @{thm list_equivp}]) |
504 |
504 *} |
505 ML {* |
505 |
506 fun ball_reg_eqv_simproc ss redex = |
506 thm ball_reg_eqv |
|
507 |
|
508 ML {* |
|
509 fun ball_reg_eqv_simproc rel_eqvs ss redex = |
|
510 let |
507 let |
511 val ctxt = Simplifier.the_context ss |
508 val ctxt = Simplifier.the_context ss |
512 val thy = ProofContext.theory_of ctxt |
509 val thy = ProofContext.theory_of ctxt |
513 in |
510 in |
514 case redex of |
511 case redex of |
515 (ogl as ((Const (@{const_name "Ball"}, _)) $ |
512 (ogl as ((Const (@{const_name "Ball"}, _)) $ |
516 ((Const (@{const_name "Respects"}, _)) $ R) $ P1)) => |
513 ((Const (@{const_name "Respects"}, _)) $ R) $ P1)) => |
517 (let |
514 (let |
518 val gl = Const (@{const_name "equivp"}, dummyT) $ R; |
515 val gl = Const (@{const_name "equivp"}, dummyT) $ R; |
519 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
516 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
520 val eqv = Goal.prove ctxt [] [] glc (fn _ => equiv_tac rel_eqvs 1); |
517 val eqv = Goal.prove ctxt [] [] glc (fn {context,...} => equiv_tac context 1) |
521 val thm = (@{thm eq_reflection} OF [@{thm ball_reg_eqv} OF [eqv]]); |
518 val thm = (@{thm eq_reflection} OF [@{thm ball_reg_eqv} OF [eqv]]); |
522 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thm)); *) |
519 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thm)); *) |
523 in |
520 in |
524 SOME thm |
521 SOME thm |
525 end |
522 end |
528 | _ => NONE |
525 | _ => NONE |
529 end |
526 end |
530 *} |
527 *} |
531 |
528 |
532 ML {* |
529 ML {* |
533 fun bex_reg_eqv_simproc rel_eqvs ss redex = |
530 fun bex_reg_eqv_simproc ss redex = |
534 let |
531 let |
535 val ctxt = Simplifier.the_context ss |
532 val ctxt = Simplifier.the_context ss |
536 val thy = ProofContext.theory_of ctxt |
533 val thy = ProofContext.theory_of ctxt |
537 in |
534 in |
538 case redex of |
535 case redex of |
539 (ogl as ((Const (@{const_name "Bex"}, _)) $ |
536 (ogl as ((Const (@{const_name "Bex"}, _)) $ |
540 ((Const (@{const_name "Respects"}, _)) $ R) $ P1)) => |
537 ((Const (@{const_name "Respects"}, _)) $ R) $ P1)) => |
541 (let |
538 (let |
542 val gl = Const (@{const_name "equivp"}, dummyT) $ R; |
539 val gl = Const (@{const_name "equivp"}, dummyT) $ R; |
543 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
540 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
544 val eqv = Goal.prove ctxt [] [] glc (fn _ => equiv_tac rel_eqvs 1); |
541 val eqv = Goal.prove ctxt [] [] glc (fn {context,...} => equiv_tac context 1) |
545 val thm = (@{thm eq_reflection} OF [@{thm bex_reg_eqv} OF [eqv]]); |
542 val thm = (@{thm eq_reflection} OF [@{thm bex_reg_eqv} OF [eqv]]); |
546 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thm)); *) |
543 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thm)); *) |
547 in |
544 in |
548 SOME thm |
545 SOME thm |
549 end |
546 end |
584 ((Const (@{const_name "Respects"}, _)) $ ((Const (@{const_name "fun_rel"}, _)) $ R1 $ R2)) $ _)) => |
581 ((Const (@{const_name "Respects"}, _)) $ ((Const (@{const_name "fun_rel"}, _)) $ R1 $ R2)) $ _)) => |
585 (let |
582 (let |
586 val gl = Const (@{const_name "equivp"}, dummyT) $ R2; |
583 val gl = Const (@{const_name "equivp"}, dummyT) $ R2; |
587 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
584 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
588 (* val _ = tracing (Syntax.string_of_term ctxt glc);*) |
585 (* val _ = tracing (Syntax.string_of_term ctxt glc);*) |
589 val eqv = Goal.prove ctxt [] [] glc (fn _ => equiv_tac rel_eqvs 1); |
586 val eqv = Goal.prove ctxt [] [] glc (fn {context,...} => equiv_tac context 1) |
590 val thm = (@{thm eq_reflection} OF [@{thm ball_reg_eqv_range} OF [eqv]]); |
587 val thm = (@{thm eq_reflection} OF [@{thm ball_reg_eqv_range} OF [eqv]]); |
591 val R1c = cterm_of thy R1; |
588 val R1c = cterm_of thy R1; |
592 val thmi = Drule.instantiate' [] [SOME R1c] thm; |
589 val thmi = Drule.instantiate' [] [SOME R1c] thm; |
593 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thmi));*) |
590 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thmi));*) |
594 val inst = matching_prs thy (term_of (Thm.lhs_of thmi)) ogl |
591 val inst = matching_prs thy (term_of (Thm.lhs_of thmi)) ogl |
618 ((Const (@{const_name "Respects"}, _)) $ ((Const (@{const_name "fun_rel"}, _)) $ R1 $ R2)) $ _)) => |
615 ((Const (@{const_name "Respects"}, _)) $ ((Const (@{const_name "fun_rel"}, _)) $ R1 $ R2)) $ _)) => |
619 (let |
616 (let |
620 val gl = Const (@{const_name "equivp"}, dummyT) $ R2; |
617 val gl = Const (@{const_name "equivp"}, dummyT) $ R2; |
621 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
618 val glc = HOLogic.mk_Trueprop (Syntax.check_term ctxt gl); |
622 (* val _ = tracing (Syntax.string_of_term ctxt glc); *) |
619 (* val _ = tracing (Syntax.string_of_term ctxt glc); *) |
623 val eqv = Goal.prove ctxt [] [] glc (fn _ => equiv_tac rel_eqvs 1); |
620 val eqv = Goal.prove ctxt [] [] glc (fn {context,...} => equiv_tac context 1) |
624 val thm = (@{thm eq_reflection} OF [@{thm bex_reg_eqv_range} OF [eqv]]); |
621 val thm = (@{thm eq_reflection} OF [@{thm bex_reg_eqv_range} OF [eqv]]); |
625 val R1c = cterm_of thy R1; |
622 val R1c = cterm_of thy R1; |
626 val thmi = Drule.instantiate' [] [SOME R1c] thm; |
623 val thmi = Drule.instantiate' [] [SOME R1c] thm; |
627 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thmi)); *) |
624 (* val _ = tracing (Syntax.string_of_term ctxt (prop_of thmi)); *) |
628 val inst = matching_prs thy (term_of (Thm.lhs_of thmi)) ogl |
625 val inst = matching_prs thy (term_of (Thm.lhs_of thmi)) ogl |
640 |
637 |
641 lemma eq_imp_rel: "equivp R \<Longrightarrow> a = b \<longrightarrow> R a b" |
638 lemma eq_imp_rel: "equivp R \<Longrightarrow> a = b \<longrightarrow> R a b" |
642 by (simp add: equivp_reflp) |
639 by (simp add: equivp_reflp) |
643 |
640 |
644 ML {* |
641 ML {* |
645 fun regularize_tac ctxt rel_eqvs = |
642 fun regularize_tac ctxt = |
646 let |
643 let |
647 val pat1 = [@{term "Ball (Respects R) P"}]; |
644 val pat1 = [@{term "Ball (Respects R) P"}]; |
648 val pat2 = [@{term "Bex (Respects R) P"}]; |
645 val pat2 = [@{term "Bex (Respects R) P"}]; |
649 val pat3 = [@{term "Ball (Respects (R1 ===> R2)) P"}]; |
646 val pat3 = [@{term "Ball (Respects (R1 ===> R2)) P"}]; |
650 val pat4 = [@{term "Bex (Respects (R1 ===> R2)) P"}]; |
647 val pat4 = [@{term "Bex (Respects (R1 ===> R2)) P"}]; |
651 val thy = ProofContext.theory_of ctxt |
648 val thy = ProofContext.theory_of ctxt |
652 val simproc1 = Simplifier.simproc_i thy "" pat1 (K (ball_reg_eqv_simproc rel_eqvs)) |
649 val simproc1 = Simplifier.simproc_i thy "" pat1 (K (ball_reg_eqv_simproc)) |
653 val simproc2 = Simplifier.simproc_i thy "" pat2 (K (bex_reg_eqv_simproc rel_eqvs)) |
650 val simproc2 = Simplifier.simproc_i thy "" pat2 (K (bex_reg_eqv_simproc)) |
654 val simproc3 = Simplifier.simproc_i thy "" pat3 (K (ball_reg_eqv_range_simproc rel_eqvs)) |
651 val simproc3 = Simplifier.simproc_i thy "" pat3 (K (ball_reg_eqv_range_simproc)) |
655 val simproc4 = Simplifier.simproc_i thy "" pat4 (K (bex_reg_eqv_range_simproc rel_eqvs)) |
652 val simproc4 = Simplifier.simproc_i thy "" pat4 (K (bex_reg_eqv_range_simproc)) |
656 val simp_ctxt = (Simplifier.context ctxt empty_ss) addsimprocs [simproc1, simproc2, simproc3, simproc4] |
653 val simp_ctxt = (Simplifier.context ctxt empty_ss) addsimprocs [simproc1, simproc2, simproc3, simproc4] |
657 (* TODO: Make sure that there are no list_rel, pair_rel etc involved *) |
654 (* TODO: Make sure that there are no list_rel, pair_rel etc involved *) |
658 val eq_eqvs = map (fn x => @{thm eq_imp_rel} OF [x]) rel_eqvs |
655 val eq_eqvs = map (fn x => @{thm eq_imp_rel} OF [x]) (equiv_rules_get ctxt) |
659 in |
656 in |
660 ObjectLogic.full_atomize_tac THEN' |
657 ObjectLogic.full_atomize_tac THEN' |
661 simp_tac simp_ctxt THEN' |
658 simp_tac simp_ctxt THEN' |
662 REPEAT_ALL_NEW (FIRST' [ |
659 REPEAT_ALL_NEW (FIRST' [ |
663 rtac @{thm ball_reg_right}, |
660 rtac @{thm ball_reg_right}, |
1219 *} |
1216 *} |
1220 |
1217 |
1221 ML {* |
1218 ML {* |
1222 (* FIXME/TODO should only get as arguments the rthm like procedure_tac *) |
1219 (* FIXME/TODO should only get as arguments the rthm like procedure_tac *) |
1223 |
1220 |
1224 fun lift_tac ctxt rthm rel_eqv = |
1221 fun lift_tac ctxt rthm = |
1225 ObjectLogic.full_atomize_tac |
1222 ObjectLogic.full_atomize_tac |
1226 THEN' gen_frees_tac ctxt |
1223 THEN' gen_frees_tac ctxt |
1227 THEN' CSUBGOAL (fn (gl, i) => |
1224 THEN' CSUBGOAL (fn (gl, i) => |
1228 let |
1225 let |
1229 val rthm' = atomize_thm rthm |
1226 val rthm' = atomize_thm rthm |
1230 val rule = procedure_inst ctxt (prop_of rthm') (term_of gl) |
1227 val rule = procedure_inst ctxt (prop_of rthm') (term_of gl) |
1231 val rel_refl = map (fn x => @{thm equivp_reflp} OF [x]) rel_eqv |
1228 val rel_refl = map (fn x => @{thm equivp_reflp} OF [x]) (equiv_rules_get ctxt) |
1232 val quotients = quotient_rules_get ctxt |
1229 val quotients = quotient_rules_get ctxt |
1233 val trans2 = map (fn x => @{thm equals_rsp} OF [x]) quotients |
1230 val trans2 = map (fn x => @{thm equals_rsp} OF [x]) quotients |
1234 val thm = Drule.instantiate' [] [SOME (snd (Thm.dest_comb gl))] @{thm QUOT_TRUE_i} |
1231 val thm = Drule.instantiate' [] [SOME (snd (Thm.dest_comb gl))] @{thm QUOT_TRUE_i} |
1235 in |
1232 in |
1236 (rtac rule THEN' |
1233 (rtac rule THEN' |
1237 RANGE [rtac rthm', |
1234 RANGE [rtac rthm', |
1238 regularize_tac ctxt rel_eqv, |
1235 regularize_tac ctxt, |
1239 rtac thm THEN' all_inj_repabs_tac ctxt rel_refl trans2, |
1236 rtac thm THEN' all_inj_repabs_tac ctxt rel_refl trans2, |
1240 clean_tac ctxt]) i |
1237 clean_tac ctxt]) i |
1241 end) |
1238 end) |
1242 *} |
1239 *} |
1243 |
1240 |