wenzelm@41959: (* Title: HOL/Quotient.thy kaliszyk@35222: Author: Cezary Kaliszyk and Christian Urban kaliszyk@35222: *) kaliszyk@35222: huffman@35294: header {* Definition of Quotient Types *} huffman@35294: kaliszyk@35222: theory Quotient haftmann@51112: imports Hilbert_Choice Equiv_Relations Lifting wenzelm@46950: keywords kuncar@47308: "print_quotmapsQ3" "print_quotientsQ3" "print_quotconsts" :: diag and wenzelm@46950: "quotient_type" :: thy_goal and "/" and kuncar@47091: "quotient_definition" :: thy_goal kaliszyk@35222: begin kaliszyk@35222: kaliszyk@35222: text {* kaliszyk@35222: Basic definition for equivalence relations kaliszyk@35222: that are represented by predicates. kaliszyk@35222: *} kaliszyk@35222: kaliszyk@35222: text {* Composition of Relations *} kaliszyk@35222: kaliszyk@35222: abbreviation haftmann@40818: rel_conj :: "('a \ 'b \ bool) \ ('b \ 'a \ bool) \ 'a \ 'b \ bool" (infixr "OOO" 75) kaliszyk@35222: where kaliszyk@35222: "r1 OOO r2 \ r1 OO r2 OO r1" kaliszyk@35222: kaliszyk@35222: lemma eq_comp_r: kaliszyk@35222: shows "((op =) OOO R) = R" nipkow@39302: by (auto simp add: fun_eq_iff) kaliszyk@35222: kuncar@53011: context kuncar@53011: begin kuncar@53011: interpretation lifting_syntax . kuncar@53011: huffman@35294: subsection {* Quotient Predicate *} kaliszyk@35222: kaliszyk@35222: definition kuncar@47308: "Quotient3 R Abs Rep \ haftmann@40814: (\a. Abs (Rep a) = a) \ (\a. R (Rep a) (Rep a)) \ haftmann@40818: (\r s. R r s \ R r r \ R s s \ Abs r = Abs s)" haftmann@40818: kuncar@47308: lemma Quotient3I: haftmann@40818: assumes "\a. Abs (Rep a) = a" haftmann@40818: and "\a. R (Rep a) (Rep a)" haftmann@40818: and "\r s. R r s \ R r r \ R s s \ Abs r = Abs s" kuncar@47308: shows "Quotient3 R Abs Rep" kuncar@47308: using assms unfolding Quotient3_def by blast kaliszyk@35222: kuncar@47308: lemma Quotient3_abs_rep: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kaliszyk@35222: shows "Abs (Rep a) = a" kaliszyk@35222: using a kuncar@47308: unfolding Quotient3_def kaliszyk@35222: by simp kaliszyk@35222: kuncar@47308: lemma Quotient3_rep_reflp: kuncar@47308: assumes a: "Quotient3 R Abs Rep" haftmann@40814: shows "R (Rep a) (Rep a)" kaliszyk@35222: using a kuncar@47308: unfolding Quotient3_def kaliszyk@35222: by blast kaliszyk@35222: kuncar@47308: lemma Quotient3_rel: kuncar@47308: assumes a: "Quotient3 R Abs Rep" haftmann@40818: shows "R r r \ R s s \ Abs r = Abs s \ R r s" -- {* orientation does not loop on rewriting *} kaliszyk@35222: using a kuncar@47308: unfolding Quotient3_def kaliszyk@35222: by blast kaliszyk@35222: kuncar@47308: lemma Quotient3_refl1: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kuncar@47096: shows "R r s \ R r r" kuncar@47308: using a unfolding Quotient3_def kuncar@47096: by fast kuncar@47096: kuncar@47308: lemma Quotient3_refl2: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kuncar@47096: shows "R r s \ R s s" kuncar@47308: using a unfolding Quotient3_def kuncar@47096: by fast kuncar@47096: kuncar@47308: lemma Quotient3_rel_rep: kuncar@47308: assumes a: "Quotient3 R Abs Rep" haftmann@40818: shows "R (Rep a) (Rep b) \ a = b" kaliszyk@35222: using a kuncar@47308: unfolding Quotient3_def kaliszyk@35222: by metis kaliszyk@35222: kuncar@47308: lemma Quotient3_rep_abs: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kaliszyk@35222: shows "R r r \ R (Rep (Abs r)) r" kuncar@47308: using a unfolding Quotient3_def kuncar@47308: by blast kuncar@47308: kuncar@47308: lemma Quotient3_rel_abs: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kuncar@47308: shows "R r s \ Abs r = Abs s" kuncar@47308: using a unfolding Quotient3_def kaliszyk@35222: by blast kaliszyk@35222: kuncar@47308: lemma Quotient3_symp: kuncar@47308: assumes a: "Quotient3 R Abs Rep" haftmann@40814: shows "symp R" kuncar@47308: using a unfolding Quotient3_def using sympI by metis kaliszyk@35222: kuncar@47308: lemma Quotient3_transp: kuncar@47308: assumes a: "Quotient3 R Abs Rep" haftmann@40814: shows "transp R" kuncar@47308: using a unfolding Quotient3_def using transpI by (metis (full_types)) kaliszyk@35222: kuncar@47308: lemma Quotient3_part_equivp: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kuncar@47308: shows "part_equivp R" kuncar@47308: by (metis Quotient3_rep_reflp Quotient3_symp Quotient3_transp a part_equivpI) kuncar@47308: kuncar@47308: lemma identity_quotient3: kuncar@47308: shows "Quotient3 (op =) id id" kuncar@47308: unfolding Quotient3_def id_def kaliszyk@35222: by blast kaliszyk@35222: kuncar@47308: lemma fun_quotient3: kuncar@47308: assumes q1: "Quotient3 R1 abs1 rep1" kuncar@47308: and q2: "Quotient3 R2 abs2 rep2" kuncar@47308: shows "Quotient3 (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2)" kaliszyk@35222: proof - kuncar@47308: have "\a.(rep1 ---> abs2) ((abs1 ---> rep2) a) = a" kuncar@47308: using q1 q2 by (simp add: Quotient3_def fun_eq_iff) kaliszyk@35222: moreover kuncar@47308: have "\a.(R1 ===> R2) ((abs1 ---> rep2) a) ((abs1 ---> rep2) a)" haftmann@40466: by (rule fun_relI) kuncar@47308: (insert q1 q2 Quotient3_rel_abs [of R1 abs1 rep1] Quotient3_rel_rep [of R2 abs2 rep2], kuncar@47308: simp (no_asm) add: Quotient3_def, simp) kuncar@47308: kaliszyk@35222: moreover kuncar@47308: { kuncar@47308: fix r s kuncar@47308: have "(R1 ===> R2) r s = ((R1 ===> R2) r r \ (R1 ===> R2) s s \ kaliszyk@35222: (rep1 ---> abs2) r = (rep1 ---> abs2) s)" kuncar@47308: proof - kuncar@47308: kuncar@47308: have "(R1 ===> R2) r s \ (R1 ===> R2) r r" unfolding fun_rel_def kuncar@47308: using Quotient3_part_equivp[OF q1] Quotient3_part_equivp[OF q2] kuncar@47308: by (metis (full_types) part_equivp_def) kuncar@47308: moreover have "(R1 ===> R2) r s \ (R1 ===> R2) s s" unfolding fun_rel_def kuncar@47308: using Quotient3_part_equivp[OF q1] Quotient3_part_equivp[OF q2] kuncar@47308: by (metis (full_types) part_equivp_def) kuncar@47308: moreover have "(R1 ===> R2) r s \ (rep1 ---> abs2) r = (rep1 ---> abs2) s" kuncar@47308: apply(auto simp add: fun_rel_def fun_eq_iff) using q1 q2 unfolding Quotient3_def by metis kuncar@47308: moreover have "((R1 ===> R2) r r \ (R1 ===> R2) s s \ kuncar@47308: (rep1 ---> abs2) r = (rep1 ---> abs2) s) \ (R1 ===> R2) r s" kuncar@47308: apply(auto simp add: fun_rel_def fun_eq_iff) using q1 q2 unfolding Quotient3_def kuncar@47308: by (metis map_fun_apply) kuncar@47308: kuncar@47308: ultimately show ?thesis by blast kuncar@47308: qed kuncar@47308: } kuncar@47308: ultimately show ?thesis by (intro Quotient3I) (assumption+) kaliszyk@35222: qed kaliszyk@35222: kaliszyk@35222: lemma abs_o_rep: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kaliszyk@35222: shows "Abs o Rep = id" nipkow@39302: unfolding fun_eq_iff kuncar@47308: by (simp add: Quotient3_abs_rep[OF a]) kaliszyk@35222: kaliszyk@35222: lemma equals_rsp: kuncar@47308: assumes q: "Quotient3 R Abs Rep" kaliszyk@35222: and a: "R xa xb" "R ya yb" kaliszyk@35222: shows "R xa ya = R xb yb" kuncar@47308: using a Quotient3_symp[OF q] Quotient3_transp[OF q] haftmann@40814: by (blast elim: sympE transpE) kaliszyk@35222: kaliszyk@35222: lemma lambda_prs: kuncar@47308: assumes q1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: and q2: "Quotient3 R2 Abs2 Rep2" kaliszyk@35222: shows "(Rep1 ---> Abs2) (\x. Rep2 (f (Abs1 x))) = (\x. f x)" nipkow@39302: unfolding fun_eq_iff kuncar@47308: using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] haftmann@40814: by simp kaliszyk@35222: kaliszyk@35222: lemma lambda_prs1: kuncar@47308: assumes q1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: and q2: "Quotient3 R2 Abs2 Rep2" kaliszyk@35222: shows "(Rep1 ---> Abs2) (\x. (Abs1 ---> Rep2) f x) = (\x. f x)" nipkow@39302: unfolding fun_eq_iff kuncar@47308: using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] haftmann@40814: by simp kaliszyk@35222: kaliszyk@35222: lemma rep_abs_rsp: kuncar@47308: assumes q: "Quotient3 R Abs Rep" kaliszyk@35222: and a: "R x1 x2" kaliszyk@35222: shows "R x1 (Rep (Abs x2))" kuncar@47308: using a Quotient3_rel[OF q] Quotient3_abs_rep[OF q] Quotient3_rep_reflp[OF q] kaliszyk@35222: by metis kaliszyk@35222: kaliszyk@35222: lemma rep_abs_rsp_left: kuncar@47308: assumes q: "Quotient3 R Abs Rep" kaliszyk@35222: and a: "R x1 x2" kaliszyk@35222: shows "R (Rep (Abs x1)) x2" kuncar@47308: using a Quotient3_rel[OF q] Quotient3_abs_rep[OF q] Quotient3_rep_reflp[OF q] kaliszyk@35222: by metis kaliszyk@35222: kaliszyk@35222: text{* kaliszyk@35222: In the following theorem R1 can be instantiated with anything, kaliszyk@35222: but we know some of the types of the Rep and Abs functions; kaliszyk@35222: so by solving Quotient assumptions we can get a unique R1 that kaliszyk@35236: will be provable; which is why we need to use @{text apply_rsp} and kaliszyk@35222: not the primed version *} kaliszyk@35222: kuncar@47308: lemma apply_rspQ3: kaliszyk@35222: fixes f g::"'a \ 'c" kuncar@47308: assumes q: "Quotient3 R1 Abs1 Rep1" kaliszyk@35222: and a: "(R1 ===> R2) f g" "R1 x y" kaliszyk@35222: shows "R2 (f x) (g y)" haftmann@40466: using a by (auto elim: fun_relE) kaliszyk@35222: kuncar@47308: lemma apply_rspQ3'': kuncar@47308: assumes "Quotient3 R Abs Rep" kuncar@47096: and "(R ===> S) f f" kuncar@47096: shows "S (f (Rep x)) (f (Rep x))" kuncar@47096: proof - kuncar@47308: from assms(1) have "R (Rep x) (Rep x)" by (rule Quotient3_rep_reflp) kuncar@47096: then show ?thesis using assms(2) by (auto intro: apply_rsp') kuncar@47096: qed kuncar@47096: huffman@35294: subsection {* lemmas for regularisation of ball and bex *} kaliszyk@35222: kaliszyk@35222: lemma ball_reg_eqv: kaliszyk@35222: fixes P :: "'a \ bool" kaliszyk@35222: assumes a: "equivp R" kaliszyk@35222: shows "Ball (Respects R) P = (All P)" kaliszyk@35222: using a kaliszyk@35222: unfolding equivp_def kaliszyk@35222: by (auto simp add: in_respects) kaliszyk@35222: kaliszyk@35222: lemma bex_reg_eqv: kaliszyk@35222: fixes P :: "'a \ bool" kaliszyk@35222: assumes a: "equivp R" kaliszyk@35222: shows "Bex (Respects R) P = (Ex P)" kaliszyk@35222: using a kaliszyk@35222: unfolding equivp_def kaliszyk@35222: by (auto simp add: in_respects) kaliszyk@35222: kaliszyk@35222: lemma ball_reg_right: haftmann@44553: assumes a: "\x. x \ R \ P x \ Q x" kaliszyk@35222: shows "All P \ Ball R Q" huffman@44921: using a by fast kaliszyk@35222: kaliszyk@35222: lemma bex_reg_left: haftmann@44553: assumes a: "\x. x \ R \ Q x \ P x" kaliszyk@35222: shows "Bex R Q \ Ex P" huffman@44921: using a by fast kaliszyk@35222: kaliszyk@35222: lemma ball_reg_left: kaliszyk@35222: assumes a: "equivp R" kaliszyk@35222: shows "(\x. (Q x \ P x)) \ Ball (Respects R) Q \ All P" kaliszyk@35222: using a by (metis equivp_reflp in_respects) kaliszyk@35222: kaliszyk@35222: lemma bex_reg_right: kaliszyk@35222: assumes a: "equivp R" kaliszyk@35222: shows "(\x. (Q x \ P x)) \ Ex Q \ Bex (Respects R) P" kaliszyk@35222: using a by (metis equivp_reflp in_respects) kaliszyk@35222: kaliszyk@35222: lemma ball_reg_eqv_range: kaliszyk@35222: fixes P::"'a \ bool" kaliszyk@35222: and x::"'a" kaliszyk@35222: assumes a: "equivp R2" kaliszyk@35222: shows "(Ball (Respects (R1 ===> R2)) (\f. P (f x)) = All (\f. P (f x)))" kaliszyk@35222: apply(rule iffI) kaliszyk@35222: apply(rule allI) kaliszyk@35222: apply(drule_tac x="\y. f x" in bspec) haftmann@40466: apply(simp add: in_respects fun_rel_def) kaliszyk@35222: apply(rule impI) kaliszyk@35222: using a equivp_reflp_symp_transp[of "R2"] haftmann@40814: apply (auto elim: equivpE reflpE) kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: lemma bex_reg_eqv_range: kaliszyk@35222: assumes a: "equivp R2" kaliszyk@35222: shows "(Bex (Respects (R1 ===> R2)) (\f. P (f x)) = Ex (\f. P (f x)))" kaliszyk@35222: apply(auto) kaliszyk@35222: apply(rule_tac x="\y. f x" in bexI) kaliszyk@35222: apply(simp) haftmann@40466: apply(simp add: Respects_def in_respects fun_rel_def) kaliszyk@35222: apply(rule impI) kaliszyk@35222: using a equivp_reflp_symp_transp[of "R2"] haftmann@40814: apply (auto elim: equivpE reflpE) kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: (* Next four lemmas are unused *) kaliszyk@35222: lemma all_reg: kaliszyk@35222: assumes a: "!x :: 'a. (P x --> Q x)" kaliszyk@35222: and b: "All P" kaliszyk@35222: shows "All Q" huffman@44921: using a b by fast kaliszyk@35222: kaliszyk@35222: lemma ex_reg: kaliszyk@35222: assumes a: "!x :: 'a. (P x --> Q x)" kaliszyk@35222: and b: "Ex P" kaliszyk@35222: shows "Ex Q" huffman@44921: using a b by fast kaliszyk@35222: kaliszyk@35222: lemma ball_reg: haftmann@44553: assumes a: "!x :: 'a. (x \ R --> P x --> Q x)" kaliszyk@35222: and b: "Ball R P" kaliszyk@35222: shows "Ball R Q" huffman@44921: using a b by fast kaliszyk@35222: kaliszyk@35222: lemma bex_reg: haftmann@44553: assumes a: "!x :: 'a. (x \ R --> P x --> Q x)" kaliszyk@35222: and b: "Bex R P" kaliszyk@35222: shows "Bex R Q" huffman@44921: using a b by fast kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: lemma ball_all_comm: kaliszyk@35222: assumes "\y. (\x\P. A x y) \ (\x. B x y)" kaliszyk@35222: shows "(\x\P. \y. A x y) \ (\x. \y. B x y)" kaliszyk@35222: using assms by auto kaliszyk@35222: kaliszyk@35222: lemma bex_ex_comm: kaliszyk@35222: assumes "(\y. \x. A x y) \ (\y. \x\P. B x y)" kaliszyk@35222: shows "(\x. \y. A x y) \ (\x\P. \y. B x y)" kaliszyk@35222: using assms by auto kaliszyk@35222: huffman@35294: subsection {* Bounded abstraction *} kaliszyk@35222: kaliszyk@35222: definition haftmann@40466: Babs :: "'a set \ ('a \ 'b) \ 'a \ 'b" kaliszyk@35222: where kaliszyk@35222: "x \ p \ Babs p m x = m x" kaliszyk@35222: kaliszyk@35222: lemma babs_rsp: kuncar@47308: assumes q: "Quotient3 R1 Abs1 Rep1" kaliszyk@35222: and a: "(R1 ===> R2) f g" kaliszyk@35222: shows "(R1 ===> R2) (Babs (Respects R1) f) (Babs (Respects R1) g)" haftmann@40466: apply (auto simp add: Babs_def in_respects fun_rel_def) kaliszyk@35222: apply (subgoal_tac "x \ Respects R1 \ y \ Respects R1") haftmann@40466: using a apply (simp add: Babs_def fun_rel_def) haftmann@40466: apply (simp add: in_respects fun_rel_def) kuncar@47308: using Quotient3_rel[OF q] kaliszyk@35222: by metis kaliszyk@35222: kaliszyk@35222: lemma babs_prs: kuncar@47308: assumes q1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: and q2: "Quotient3 R2 Abs2 Rep2" kaliszyk@35222: shows "((Rep1 ---> Abs2) (Babs (Respects R1) ((Abs1 ---> Rep2) f))) = f" kaliszyk@35222: apply (rule ext) haftmann@40466: apply (simp add:) kaliszyk@35222: apply (subgoal_tac "Rep1 x \ Respects R1") kuncar@47308: apply (simp add: Babs_def Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2]) kuncar@47308: apply (simp add: in_respects Quotient3_rel_rep[OF q1]) kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: lemma babs_simp: kuncar@47308: assumes q: "Quotient3 R1 Abs Rep" kaliszyk@35222: shows "((R1 ===> R2) (Babs (Respects R1) f) (Babs (Respects R1) g)) = ((R1 ===> R2) f g)" kaliszyk@35222: apply(rule iffI) kaliszyk@35222: apply(simp_all only: babs_rsp[OF q]) haftmann@40466: apply(auto simp add: Babs_def fun_rel_def) kaliszyk@35222: apply (subgoal_tac "x \ Respects R1 \ y \ Respects R1") kaliszyk@35222: apply(metis Babs_def) kaliszyk@35222: apply (simp add: in_respects) kuncar@47308: using Quotient3_rel[OF q] kaliszyk@35222: by metis kaliszyk@35222: kaliszyk@35222: (* If a user proves that a particular functional relation kaliszyk@35222: is an equivalence this may be useful in regularising *) kaliszyk@35222: lemma babs_reg_eqv: kaliszyk@35222: shows "equivp R \ Babs (Respects R) P = P" nipkow@39302: by (simp add: fun_eq_iff Babs_def in_respects equivp_reflp) kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: (* 3 lemmas needed for proving repabs_inj *) kaliszyk@35222: lemma ball_rsp: kaliszyk@35222: assumes a: "(R ===> (op =)) f g" kaliszyk@35222: shows "Ball (Respects R) f = Ball (Respects R) g" haftmann@40466: using a by (auto simp add: Ball_def in_respects elim: fun_relE) kaliszyk@35222: kaliszyk@35222: lemma bex_rsp: kaliszyk@35222: assumes a: "(R ===> (op =)) f g" kaliszyk@35222: shows "(Bex (Respects R) f = Bex (Respects R) g)" haftmann@40466: using a by (auto simp add: Bex_def in_respects elim: fun_relE) kaliszyk@35222: kaliszyk@35222: lemma bex1_rsp: kaliszyk@35222: assumes a: "(R ===> (op =)) f g" kaliszyk@35222: shows "Ex1 (\x. x \ Respects R \ f x) = Ex1 (\x. x \ Respects R \ g x)" haftmann@40466: using a by (auto elim: fun_relE simp add: Ex1_def in_respects) kaliszyk@35222: kaliszyk@35222: (* 2 lemmas needed for cleaning of quantifiers *) kaliszyk@35222: lemma all_prs: kuncar@47308: assumes a: "Quotient3 R absf repf" kaliszyk@35222: shows "Ball (Respects R) ((absf ---> id) f) = All f" kuncar@47308: using a unfolding Quotient3_def Ball_def in_respects id_apply comp_def map_fun_def kaliszyk@35222: by metis kaliszyk@35222: kaliszyk@35222: lemma ex_prs: kuncar@47308: assumes a: "Quotient3 R absf repf" kaliszyk@35222: shows "Bex (Respects R) ((absf ---> id) f) = Ex f" kuncar@47308: using a unfolding Quotient3_def Bex_def in_respects id_apply comp_def map_fun_def kaliszyk@35222: by metis kaliszyk@35222: huffman@35294: subsection {* @{text Bex1_rel} quantifier *} kaliszyk@35222: kaliszyk@35222: definition kaliszyk@35222: Bex1_rel :: "('a \ 'a \ bool) \ ('a \ bool) \ bool" kaliszyk@35222: where kaliszyk@35222: "Bex1_rel R P \ (\x \ Respects R. P x) \ (\x \ Respects R. \y \ Respects R. ((P x \ P y) \ (R x y)))" kaliszyk@35222: kaliszyk@35222: lemma bex1_rel_aux: kaliszyk@35222: "\\xa ya. R xa ya \ x xa = y ya; Bex1_rel R x\ \ Bex1_rel R y" kaliszyk@35222: unfolding Bex1_rel_def kaliszyk@35222: apply (erule conjE)+ kaliszyk@35222: apply (erule bexE) kaliszyk@35222: apply rule kaliszyk@35222: apply (rule_tac x="xa" in bexI) kaliszyk@35222: apply metis kaliszyk@35222: apply metis kaliszyk@35222: apply rule+ kaliszyk@35222: apply (erule_tac x="xaa" in ballE) kaliszyk@35222: prefer 2 kaliszyk@35222: apply (metis) kaliszyk@35222: apply (erule_tac x="ya" in ballE) kaliszyk@35222: prefer 2 kaliszyk@35222: apply (metis) kaliszyk@35222: apply (metis in_respects) kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: lemma bex1_rel_aux2: kaliszyk@35222: "\\xa ya. R xa ya \ x xa = y ya; Bex1_rel R y\ \ Bex1_rel R x" kaliszyk@35222: unfolding Bex1_rel_def kaliszyk@35222: apply (erule conjE)+ kaliszyk@35222: apply (erule bexE) kaliszyk@35222: apply rule kaliszyk@35222: apply (rule_tac x="xa" in bexI) kaliszyk@35222: apply metis kaliszyk@35222: apply metis kaliszyk@35222: apply rule+ kaliszyk@35222: apply (erule_tac x="xaa" in ballE) kaliszyk@35222: prefer 2 kaliszyk@35222: apply (metis) kaliszyk@35222: apply (erule_tac x="ya" in ballE) kaliszyk@35222: prefer 2 kaliszyk@35222: apply (metis) kaliszyk@35222: apply (metis in_respects) kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: lemma bex1_rel_rsp: kuncar@47308: assumes a: "Quotient3 R absf repf" kaliszyk@35222: shows "((R ===> op =) ===> op =) (Bex1_rel R) (Bex1_rel R)" haftmann@40466: apply (simp add: fun_rel_def) kaliszyk@35222: apply clarify kaliszyk@35222: apply rule kaliszyk@35222: apply (simp_all add: bex1_rel_aux bex1_rel_aux2) kaliszyk@35222: apply (erule bex1_rel_aux2) kaliszyk@35222: apply assumption kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: lemma ex1_prs: kuncar@47308: assumes a: "Quotient3 R absf repf" kaliszyk@35222: shows "((absf ---> id) ---> id) (Bex1_rel R) f = Ex1 f" haftmann@40466: apply (simp add:) kaliszyk@35222: apply (subst Bex1_rel_def) kaliszyk@35222: apply (subst Bex_def) kaliszyk@35222: apply (subst Ex1_def) kaliszyk@35222: apply simp kaliszyk@35222: apply rule kaliszyk@35222: apply (erule conjE)+ kaliszyk@35222: apply (erule_tac exE) kaliszyk@35222: apply (erule conjE) kaliszyk@35222: apply (subgoal_tac "\y. R y y \ f (absf y) \ R x y") kaliszyk@35222: apply (rule_tac x="absf x" in exI) kaliszyk@35222: apply (simp) kaliszyk@35222: apply rule+ kuncar@47308: using a unfolding Quotient3_def kaliszyk@35222: apply metis kaliszyk@35222: apply rule+ kaliszyk@35222: apply (erule_tac x="x" in ballE) kaliszyk@35222: apply (erule_tac x="y" in ballE) kaliszyk@35222: apply simp kaliszyk@35222: apply (simp add: in_respects) kaliszyk@35222: apply (simp add: in_respects) kaliszyk@35222: apply (erule_tac exE) kaliszyk@35222: apply rule kaliszyk@35222: apply (rule_tac x="repf x" in exI) kaliszyk@35222: apply (simp only: in_respects) kaliszyk@35222: apply rule kuncar@47308: apply (metis Quotient3_rel_rep[OF a]) kuncar@47308: using a unfolding Quotient3_def apply (simp) kaliszyk@35222: apply rule+ kuncar@47308: using a unfolding Quotient3_def in_respects kaliszyk@35222: apply metis kaliszyk@35222: done kaliszyk@35222: kaliszyk@38702: lemma bex1_bexeq_reg: kaliszyk@38702: shows "(\!x\Respects R. P x) \ (Bex1_rel R (\x. P x))" kaliszyk@35222: apply (simp add: Ex1_def Bex1_rel_def in_respects) kaliszyk@35222: apply clarify kaliszyk@35222: apply auto kaliszyk@35222: apply (rule bexI) kaliszyk@35222: apply assumption kaliszyk@35222: apply (simp add: in_respects) kaliszyk@35222: apply (simp add: in_respects) kaliszyk@35222: apply auto kaliszyk@35222: done kaliszyk@35222: kaliszyk@38702: lemma bex1_bexeq_reg_eqv: kaliszyk@38702: assumes a: "equivp R" kaliszyk@38702: shows "(\!x. P x) \ Bex1_rel R P" kaliszyk@38702: using equivp_reflp[OF a] kaliszyk@38702: apply (intro impI) kaliszyk@38702: apply (elim ex1E) kaliszyk@38702: apply (rule mp[OF bex1_bexeq_reg]) kaliszyk@38702: apply (rule_tac a="x" in ex1I) kaliszyk@38702: apply (subst in_respects) kaliszyk@38702: apply (rule conjI) kaliszyk@38702: apply assumption kaliszyk@38702: apply assumption kaliszyk@38702: apply clarify kaliszyk@38702: apply (erule_tac x="xa" in allE) kaliszyk@38702: apply simp kaliszyk@38702: done kaliszyk@38702: huffman@35294: subsection {* Various respects and preserve lemmas *} kaliszyk@35222: kaliszyk@35222: lemma quot_rel_rsp: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kaliszyk@35222: shows "(R ===> R ===> op =) R R" urbanc@38317: apply(rule fun_relI)+ kaliszyk@35222: apply(rule equals_rsp[OF a]) kaliszyk@35222: apply(assumption)+ kaliszyk@35222: done kaliszyk@35222: kaliszyk@35222: lemma o_prs: kuncar@47308: assumes q1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: and q2: "Quotient3 R2 Abs2 Rep2" kuncar@47308: and q3: "Quotient3 R3 Abs3 Rep3" kaliszyk@36215: shows "((Abs2 ---> Rep3) ---> (Abs1 ---> Rep2) ---> (Rep1 ---> Abs3)) op \ = op \" kaliszyk@36215: and "(id ---> (Abs1 ---> id) ---> Rep1 ---> id) op \ = op \" kuncar@47308: using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] Quotient3_abs_rep[OF q3] haftmann@40466: by (simp_all add: fun_eq_iff) kaliszyk@35222: kaliszyk@35222: lemma o_rsp: kaliszyk@36215: "((R2 ===> R3) ===> (R1 ===> R2) ===> (R1 ===> R3)) op \ op \" kaliszyk@36215: "(op = ===> (R1 ===> op =) ===> R1 ===> op =) op \ op \" huffman@44921: by (force elim: fun_relE)+ kaliszyk@35222: kaliszyk@35222: lemma cond_prs: kuncar@47308: assumes a: "Quotient3 R absf repf" kaliszyk@35222: shows "absf (if a then repf b else repf c) = (if a then b else c)" kuncar@47308: using a unfolding Quotient3_def by auto kaliszyk@35222: kaliszyk@35222: lemma if_prs: kuncar@47308: assumes q: "Quotient3 R Abs Rep" kaliszyk@36123: shows "(id ---> Rep ---> Rep ---> Abs) If = If" kuncar@47308: using Quotient3_abs_rep[OF q] nipkow@39302: by (auto simp add: fun_eq_iff) kaliszyk@35222: kaliszyk@35222: lemma if_rsp: kuncar@47308: assumes q: "Quotient3 R Abs Rep" kaliszyk@36123: shows "(op = ===> R ===> R ===> R) If If" huffman@44921: by force kaliszyk@35222: kaliszyk@35222: lemma let_prs: kuncar@47308: assumes q1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: and q2: "Quotient3 R2 Abs2 Rep2" kaliszyk@37049: shows "(Rep2 ---> (Abs2 ---> Rep1) ---> Abs1) Let = Let" kuncar@47308: using Quotient3_abs_rep[OF q1] Quotient3_abs_rep[OF q2] nipkow@39302: by (auto simp add: fun_eq_iff) kaliszyk@35222: kaliszyk@35222: lemma let_rsp: kaliszyk@37049: shows "(R1 ===> (R1 ===> R2) ===> R2) Let Let" huffman@44921: by (force elim: fun_relE) kaliszyk@35222: kaliszyk@39669: lemma id_rsp: kaliszyk@39669: shows "(R ===> R) id id" huffman@44921: by auto kaliszyk@39669: kaliszyk@39669: lemma id_prs: kuncar@47308: assumes a: "Quotient3 R Abs Rep" kaliszyk@39669: shows "(Rep ---> Abs) id = id" kuncar@47308: by (simp add: fun_eq_iff Quotient3_abs_rep [OF a]) kaliszyk@39669: kuncar@53011: end kaliszyk@39669: kaliszyk@35222: locale quot_type = kaliszyk@35222: fixes R :: "'a \ 'a \ bool" kaliszyk@44204: and Abs :: "'a set \ 'b" kaliszyk@44204: and Rep :: "'b \ 'a set" kaliszyk@37493: assumes equivp: "part_equivp R" kaliszyk@44204: and rep_prop: "\y. \x. R x x \ Rep y = Collect (R x)" kaliszyk@35222: and rep_inverse: "\x. Abs (Rep x) = x" kaliszyk@44204: and abs_inverse: "\c. (\x. ((R x x) \ (c = Collect (R x)))) \ (Rep (Abs c)) = c" kaliszyk@35222: and rep_inject: "\x y. (Rep x = Rep y) = (x = y)" kaliszyk@35222: begin kaliszyk@35222: kaliszyk@35222: definition haftmann@40466: abs :: "'a \ 'b" kaliszyk@35222: where kaliszyk@44204: "abs x = Abs (Collect (R x))" kaliszyk@35222: kaliszyk@35222: definition haftmann@40466: rep :: "'b \ 'a" kaliszyk@35222: where kaliszyk@44204: "rep a = (SOME x. x \ Rep a)" kaliszyk@35222: kaliszyk@44204: lemma some_collect: kaliszyk@37493: assumes "R r r" kaliszyk@44204: shows "R (SOME x. x \ Collect (R r)) = R r" kaliszyk@44204: apply simp kaliszyk@44204: by (metis assms exE_some equivp[simplified part_equivp_def]) kaliszyk@35222: kaliszyk@35222: lemma Quotient: kuncar@47308: shows "Quotient3 R abs rep" kuncar@47308: unfolding Quotient3_def abs_def rep_def kaliszyk@37493: proof (intro conjI allI) kaliszyk@37493: fix a r s kaliszyk@44204: show x: "R (SOME x. x \ Rep a) (SOME x. x \ Rep a)" proof - kaliszyk@44204: obtain x where r: "R x x" and rep: "Rep a = Collect (R x)" using rep_prop[of a] by auto kaliszyk@44204: have "R (SOME x. x \ Rep a) x" using r rep some_collect by metis kaliszyk@44204: then have "R x (SOME x. x \ Rep a)" using part_equivp_symp[OF equivp] by fast kaliszyk@44204: then show "R (SOME x. x \ Rep a) (SOME x. x \ Rep a)" kaliszyk@44204: using part_equivp_transp[OF equivp] by (metis `R (SOME x. x \ Rep a) x`) kaliszyk@37493: qed kaliszyk@44204: have "Collect (R (SOME x. x \ Rep a)) = (Rep a)" by (metis some_collect rep_prop) kaliszyk@44204: then show "Abs (Collect (R (SOME x. x \ Rep a))) = a" using rep_inverse by auto kaliszyk@44204: have "R r r \ R s s \ Abs (Collect (R r)) = Abs (Collect (R s)) \ R r = R s" haftmann@44242: proof - haftmann@44242: assume "R r r" and "R s s" haftmann@44242: then have "Abs (Collect (R r)) = Abs (Collect (R s)) \ Collect (R r) = Collect (R s)" haftmann@44242: by (metis abs_inverse) haftmann@44242: also have "Collect (R r) = Collect (R s) \ (\A x. x \ A) (Collect (R r)) = (\A x. x \ A) (Collect (R s))" haftmann@44242: by rule simp_all haftmann@44242: finally show "Abs (Collect (R r)) = Abs (Collect (R s)) \ R r = R s" by simp haftmann@44242: qed kaliszyk@44204: then show "R r s \ R r r \ R s s \ (Abs (Collect (R r)) = Abs (Collect (R s)))" kaliszyk@44204: using equivp[simplified part_equivp_def] by metis kaliszyk@44204: qed haftmann@44242: kaliszyk@35222: end kaliszyk@35222: kuncar@47096: subsection {* Quotient composition *} kuncar@47096: kuncar@47308: lemma OOO_quotient3: kuncar@47096: fixes R1 :: "'a \ 'a \ bool" kuncar@47096: fixes Abs1 :: "'a \ 'b" and Rep1 :: "'b \ 'a" kuncar@47096: fixes Abs2 :: "'b \ 'c" and Rep2 :: "'c \ 'b" kuncar@47096: fixes R2' :: "'a \ 'a \ bool" kuncar@47096: fixes R2 :: "'b \ 'b \ bool" kuncar@47308: assumes R1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: assumes R2: "Quotient3 R2 Abs2 Rep2" kuncar@47096: assumes Abs1: "\x y. R2' x y \ R1 x x \ R1 y y \ R2 (Abs1 x) (Abs1 y)" kuncar@47096: assumes Rep1: "\x y. R2 x y \ R2' (Rep1 x) (Rep1 y)" kuncar@47308: shows "Quotient3 (R1 OO R2' OO R1) (Abs2 \ Abs1) (Rep1 \ Rep2)" kuncar@47308: apply (rule Quotient3I) kuncar@47308: apply (simp add: o_def Quotient3_abs_rep [OF R2] Quotient3_abs_rep [OF R1]) kuncar@47096: apply simp griff@47434: apply (rule_tac b="Rep1 (Rep2 a)" in relcomppI) kuncar@47308: apply (rule Quotient3_rep_reflp [OF R1]) griff@47434: apply (rule_tac b="Rep1 (Rep2 a)" in relcomppI [rotated]) kuncar@47308: apply (rule Quotient3_rep_reflp [OF R1]) kuncar@47096: apply (rule Rep1) kuncar@47308: apply (rule Quotient3_rep_reflp [OF R2]) kuncar@47096: apply safe kuncar@47096: apply (rename_tac x y) kuncar@47096: apply (drule Abs1) kuncar@47308: apply (erule Quotient3_refl2 [OF R1]) kuncar@47308: apply (erule Quotient3_refl1 [OF R1]) kuncar@47308: apply (drule Quotient3_refl1 [OF R2], drule Rep1) kuncar@47096: apply (subgoal_tac "R1 r (Rep1 (Abs1 x))") griff@47434: apply (rule_tac b="Rep1 (Abs1 x)" in relcomppI, assumption) griff@47434: apply (erule relcomppI) kuncar@47308: apply (erule Quotient3_symp [OF R1, THEN sympD]) kuncar@47308: apply (rule Quotient3_rel[symmetric, OF R1, THEN iffD2]) kuncar@47308: apply (rule conjI, erule Quotient3_refl1 [OF R1]) kuncar@47308: apply (rule conjI, rule Quotient3_rep_reflp [OF R1]) kuncar@47308: apply (subst Quotient3_abs_rep [OF R1]) kuncar@47308: apply (erule Quotient3_rel_abs [OF R1]) kuncar@47096: apply (rename_tac x y) kuncar@47096: apply (drule Abs1) kuncar@47308: apply (erule Quotient3_refl2 [OF R1]) kuncar@47308: apply (erule Quotient3_refl1 [OF R1]) kuncar@47308: apply (drule Quotient3_refl2 [OF R2], drule Rep1) kuncar@47096: apply (subgoal_tac "R1 s (Rep1 (Abs1 y))") griff@47434: apply (rule_tac b="Rep1 (Abs1 y)" in relcomppI, assumption) griff@47434: apply (erule relcomppI) kuncar@47308: apply (erule Quotient3_symp [OF R1, THEN sympD]) kuncar@47308: apply (rule Quotient3_rel[symmetric, OF R1, THEN iffD2]) kuncar@47308: apply (rule conjI, erule Quotient3_refl2 [OF R1]) kuncar@47308: apply (rule conjI, rule Quotient3_rep_reflp [OF R1]) kuncar@47308: apply (subst Quotient3_abs_rep [OF R1]) kuncar@47308: apply (erule Quotient3_rel_abs [OF R1, THEN sym]) kuncar@47096: apply simp kuncar@47308: apply (rule Quotient3_rel_abs [OF R2]) kuncar@47308: apply (rule Quotient3_rel_abs [OF R1, THEN ssubst], assumption) kuncar@47308: apply (rule Quotient3_rel_abs [OF R1, THEN subst], assumption) kuncar@47096: apply (erule Abs1) kuncar@47308: apply (erule Quotient3_refl2 [OF R1]) kuncar@47308: apply (erule Quotient3_refl1 [OF R1]) kuncar@47096: apply (rename_tac a b c d) kuncar@47096: apply simp griff@47434: apply (rule_tac b="Rep1 (Abs1 r)" in relcomppI) kuncar@47308: apply (rule Quotient3_rel[symmetric, OF R1, THEN iffD2]) kuncar@47308: apply (rule conjI, erule Quotient3_refl1 [OF R1]) kuncar@47308: apply (simp add: Quotient3_abs_rep [OF R1] Quotient3_rep_reflp [OF R1]) griff@47434: apply (rule_tac b="Rep1 (Abs1 s)" in relcomppI [rotated]) kuncar@47308: apply (rule Quotient3_rel[symmetric, OF R1, THEN iffD2]) kuncar@47308: apply (simp add: Quotient3_abs_rep [OF R1] Quotient3_rep_reflp [OF R1]) kuncar@47308: apply (erule Quotient3_refl2 [OF R1]) kuncar@47096: apply (rule Rep1) kuncar@47096: apply (drule Abs1) kuncar@47308: apply (erule Quotient3_refl2 [OF R1]) kuncar@47308: apply (erule Quotient3_refl1 [OF R1]) kuncar@47096: apply (drule Abs1) kuncar@47308: apply (erule Quotient3_refl2 [OF R1]) kuncar@47308: apply (erule Quotient3_refl1 [OF R1]) kuncar@47308: apply (drule Quotient3_rel_abs [OF R1]) kuncar@47308: apply (drule Quotient3_rel_abs [OF R1]) kuncar@47308: apply (drule Quotient3_rel_abs [OF R1]) kuncar@47308: apply (drule Quotient3_rel_abs [OF R1]) kuncar@47096: apply simp kuncar@47308: apply (rule Quotient3_rel[symmetric, OF R2, THEN iffD2]) kuncar@47096: apply simp kuncar@47096: done kuncar@47096: kuncar@47308: lemma OOO_eq_quotient3: kuncar@47096: fixes R1 :: "'a \ 'a \ bool" kuncar@47096: fixes Abs1 :: "'a \ 'b" and Rep1 :: "'b \ 'a" kuncar@47096: fixes Abs2 :: "'b \ 'c" and Rep2 :: "'c \ 'b" kuncar@47308: assumes R1: "Quotient3 R1 Abs1 Rep1" kuncar@47308: assumes R2: "Quotient3 op= Abs2 Rep2" kuncar@47308: shows "Quotient3 (R1 OOO op=) (Abs2 \ Abs1) (Rep1 \ Rep2)" kuncar@47096: using assms kuncar@47308: by (rule OOO_quotient3) auto kuncar@47096: kuncar@47362: subsection {* Quotient3 to Quotient *} kuncar@47362: kuncar@47362: lemma Quotient3_to_Quotient: kuncar@47362: assumes "Quotient3 R Abs Rep" kuncar@47362: and "T \ \x y. R x x \ Abs x = y" kuncar@47362: shows "Quotient R Abs Rep T" kuncar@47362: using assms unfolding Quotient3_def by (intro QuotientI) blast+ kuncar@47096: kuncar@47362: lemma Quotient3_to_Quotient_equivp: kuncar@47362: assumes q: "Quotient3 R Abs Rep" kuncar@47362: and T_def: "T \ \x y. Abs x = y" kuncar@47362: and eR: "equivp R" kuncar@47362: shows "Quotient R Abs Rep T" kuncar@47362: proof (intro QuotientI) kuncar@47362: fix a kuncar@47362: show "Abs (Rep a) = a" using q by(rule Quotient3_abs_rep) kuncar@47362: next kuncar@47362: fix a kuncar@47362: show "R (Rep a) (Rep a)" using q by(rule Quotient3_rep_reflp) kuncar@47362: next kuncar@47362: fix r s kuncar@47362: show "R r s = (R r r \ R s s \ Abs r = Abs s)" using q by(rule Quotient3_rel[symmetric]) kuncar@47362: next kuncar@47362: show "T = (\x y. R x x \ Abs x = y)" using T_def equivp_reflp[OF eR] by simp kuncar@47096: qed kuncar@47096: huffman@35294: subsection {* ML setup *} kaliszyk@35222: kaliszyk@35222: text {* Auxiliary data for the quotient package *} kaliszyk@35222: wenzelm@48891: ML_file "Tools/Quotient/quotient_info.ML" wenzelm@41452: setup Quotient_Info.setup kaliszyk@35222: kuncar@47308: declare [[mapQ3 "fun" = (fun_rel, fun_quotient3)]] kaliszyk@35222: kuncar@47308: lemmas [quot_thm] = fun_quotient3 haftmann@44553: lemmas [quot_respect] = quot_rel_rsp if_rsp o_rsp let_rsp id_rsp haftmann@44553: lemmas [quot_preserve] = if_prs o_prs let_prs id_prs kaliszyk@35222: lemmas [quot_equiv] = identity_equivp kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: text {* Lemmas about simplifying id's. *} kaliszyk@35222: lemmas [id_simps] = kaliszyk@35222: id_def[symmetric] haftmann@40602: map_fun_id kaliszyk@35222: id_apply kaliszyk@35222: id_o kaliszyk@35222: o_id kaliszyk@35222: eq_comp_r kaliszyk@44413: vimage_id kaliszyk@35222: kaliszyk@35222: text {* Translation functions for the lifting process. *} wenzelm@48891: ML_file "Tools/Quotient/quotient_term.ML" kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: text {* Definitions of the quotient types. *} wenzelm@48891: ML_file "Tools/Quotient/quotient_type.ML" kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: text {* Definitions for quotient constants. *} wenzelm@48891: ML_file "Tools/Quotient/quotient_def.ML" kaliszyk@35222: kaliszyk@35222: kaliszyk@35222: text {* kaliszyk@35222: An auxiliary constant for recording some information kaliszyk@35222: about the lifted theorem in a tactic. kaliszyk@35222: *} kaliszyk@35222: definition haftmann@40466: Quot_True :: "'a \ bool" haftmann@40466: where haftmann@40466: "Quot_True x \ True" kaliszyk@35222: kaliszyk@35222: lemma kaliszyk@35222: shows QT_all: "Quot_True (All P) \ Quot_True P" kaliszyk@35222: and QT_ex: "Quot_True (Ex P) \ Quot_True P" kaliszyk@35222: and QT_ex1: "Quot_True (Ex1 P) \ Quot_True P" kaliszyk@35222: and QT_lam: "Quot_True (\x. P x) \ (\x. Quot_True (P x))" kaliszyk@35222: and QT_ext: "(\x. Quot_True (a x) \ f x = g x) \ (Quot_True a \ f = g)" kaliszyk@35222: by (simp_all add: Quot_True_def ext) kaliszyk@35222: kaliszyk@35222: lemma QT_imp: "Quot_True a \ Quot_True b" kaliszyk@35222: by (simp add: Quot_True_def) kaliszyk@35222: kuncar@53011: context kuncar@53011: begin kuncar@53011: interpretation lifting_syntax . kaliszyk@35222: kaliszyk@35222: text {* Tactics for proving the lifted theorems *} wenzelm@48891: ML_file "Tools/Quotient/quotient_tacs.ML" kaliszyk@35222: kuncar@53011: end kuncar@53011: huffman@35294: subsection {* Methods / Interface *} kaliszyk@35222: kaliszyk@35222: method_setup lifting = urbanc@37593: {* Attrib.thms >> (fn thms => fn ctxt => wenzelm@46468: SIMPLE_METHOD' (Quotient_Tacs.lift_tac ctxt [] thms)) *} wenzelm@42814: {* lift theorems to quotient types *} kaliszyk@35222: kaliszyk@35222: method_setup lifting_setup = urbanc@37593: {* Attrib.thm >> (fn thm => fn ctxt => wenzelm@46468: SIMPLE_METHOD' (Quotient_Tacs.lift_procedure_tac ctxt [] thm)) *} wenzelm@42814: {* set up the three goals for the quotient lifting procedure *} kaliszyk@35222: urbanc@37593: method_setup descending = wenzelm@46468: {* Scan.succeed (fn ctxt => SIMPLE_METHOD' (Quotient_Tacs.descend_tac ctxt [])) *} wenzelm@42814: {* decend theorems to the raw level *} urbanc@37593: urbanc@37593: method_setup descending_setup = wenzelm@46468: {* Scan.succeed (fn ctxt => SIMPLE_METHOD' (Quotient_Tacs.descend_procedure_tac ctxt [])) *} wenzelm@42814: {* set up the three goals for the decending theorems *} urbanc@37593: urbanc@45782: method_setup partiality_descending = wenzelm@46468: {* Scan.succeed (fn ctxt => SIMPLE_METHOD' (Quotient_Tacs.partiality_descend_tac ctxt [])) *} urbanc@45782: {* decend theorems to the raw level *} urbanc@45782: urbanc@45782: method_setup partiality_descending_setup = urbanc@45782: {* Scan.succeed (fn ctxt => wenzelm@46468: SIMPLE_METHOD' (Quotient_Tacs.partiality_descend_procedure_tac ctxt [])) *} urbanc@45782: {* set up the three goals for the decending theorems *} urbanc@45782: kaliszyk@35222: method_setup regularize = wenzelm@46468: {* Scan.succeed (fn ctxt => SIMPLE_METHOD' (Quotient_Tacs.regularize_tac ctxt)) *} wenzelm@42814: {* prove the regularization goals from the quotient lifting procedure *} kaliszyk@35222: kaliszyk@35222: method_setup injection = wenzelm@46468: {* Scan.succeed (fn ctxt => SIMPLE_METHOD' (Quotient_Tacs.all_injection_tac ctxt)) *} wenzelm@42814: {* prove the rep/abs injection goals from the quotient lifting procedure *} kaliszyk@35222: kaliszyk@35222: method_setup cleaning = wenzelm@46468: {* Scan.succeed (fn ctxt => SIMPLE_METHOD' (Quotient_Tacs.clean_tac ctxt)) *} wenzelm@42814: {* prove the cleaning goals from the quotient lifting procedure *} kaliszyk@35222: kaliszyk@35222: attribute_setup quot_lifted = kaliszyk@35222: {* Scan.succeed Quotient_Tacs.lifted_attrib *} wenzelm@42814: {* lift theorems to quotient types *} kaliszyk@35222: kaliszyk@35222: no_notation kuncar@53011: rel_conj (infixr "OOO" 75) kaliszyk@35222: kaliszyk@35222: end haftmann@47488: