(* Title: HOL/Quotient_Examples/Quotient_Rat.thy Author: Cezary Kaliszyk Rational numbers defined with the quotient package, based on 'HOL/Rat.thy' by Makarius. *)
theory Quotient_Rat imports HOL.Archimedean_Field "HOL-Library.Quotient_Product" begin
definition
ratrel :: "(int × int) ==> (int × int) ==> bool" (infix‹≈› 50) where
[simp]: "x ≈ y ⟷ snd x ≠ 0 ∧ snd y ≠ 0 ∧ fst x * snd y = fst y * snd x"
lemma ratrel_equivp: "part_equivp ratrel" proof (auto intro!: part_equivpI reflpI sympI transpI exI[of _ "1 :: int"]) fix a b c d e f :: int assume nz: "d ≠ 0""b ≠ 0" assume y: "a * d = c * b" assume x: "c * f = e * d" thenhave"c * b * f = e * d * b"using nz by simp thenhave"a * d * f = e * d * b"using y by simp thenshow"a * f = e * b"using nz by simp qed
quotient_type rat = "int × int" / partial: ratrel using ratrel_equivp .
instantiation rat :: "{zero, one, plus, uminus, minus, times, ord, abs, sgn}" begin
fun le_rat_raw where "le_rat_raw (a :: int, b) (c, d) ⟷ (a * d) * (b * d) ≤ (c * b) * (b * d)"
quotient_definition "(≤) :: rat ==> rat ==> bool"is"le_rat_raw" proof -
{ fix a b c d e f g h :: int assume"a * f * (b * f) ≤ e * b * (b * f)" thenhave le: "a * f * b * f ≤ e * b * b * f"by simp assume nz: "b ≠ 0""d ≠ 0""f ≠ 0""h ≠ 0" thenhave b2: "b * b > 0" by (metis linorder_neqE_linordered_idom mult_eq_0_iff not_square_less_zero) have f2: "f * f > 0"using nz(3) by (metis linorder_neqE_linordered_idom mult_eq_0_iff not_square_less_zero) assume eq: "a * d = c * b""e * h = g * f" have"a * f * b * f * d * d ≤ e * b * b * f * d * d"using le nz(2) by (metis linorder_le_cases mult_right_mono mult_right_mono_neg) thenhave"c * f * f * d * (b * b) ≤ e * f * d * d * (b * b)"using eq by (metis (no_types) mult.assoc mult.commute) thenhave"c * f * f * d ≤ e * f * d * d"using b2 by (metis leD linorder_le_less_linear mult_strict_right_mono) thenhave"c * f * f * d * h * h ≤ e * f * d * d * h * h"using nz(4) by (metis linorder_le_cases mult_right_mono mult_right_mono_neg) thenhave"c * h * (d * h) * (f * f) ≤ g * d * (d * h) * (f * f)"using eq by (metis (no_types) mult.assoc mult.commute) thenhave"c * h * (d * h) ≤ g * d * (d * h)"using f2 by (metis leD linorder_le_less_linear mult_strict_right_mono)
} thenshow"∧x y xa ya. x ≈ y ==> xa ≈ ya ==> le_rat_raw x xa = le_rat_raw y ya"by auto qed
definition
less_rat_def: "(z::rat) < w = (z ≤ w ∧ z ≠ w)"
definition
rabs_rat_def: "∣i::rat∣ = (if i < 0 then - i else i)"
definition
sgn_rat_def: "sgn (i::rat) = (if i = 0 then 0 else if 0 < i then 1 else - 1)"
instance ..
end
definition
Fract_raw :: "int ==> int ==> (int × int)" where [simp]: "Fract_raw a b = (if b = 0 then (0, 1) else (a, b))"
quotient_definition "Fract :: int ==> int ==> rat"is
Fract_raw by simp
lemmas [simp] = Respects_def
(* FIXME: (partiality_)descending raises exception TYPE_MATCH instantiation rat :: comm_ring_1 begin instance proof fix a b c :: rat show "a * b * c = a * (b * c)" by partiality_descending auto show "a * b = b * a" by partiality_descending auto show "1 * a = a" by partiality_descending auto show "a + b + c = a + (b + c)" by partiality_descending (auto simp add: mult.commute distrib_left) show "a + b = b + a" by partiality_descending auto show "0 + a = a" by partiality_descending auto show "- a + a = 0" by partiality_descending auto show "a - b = a + - b" by (simp add: minus_rat_def) show "(a + b) * c = a * c + b * c" by partiality_descending (auto simp add: mult.commute distrib_left) show "(0 :: rat) ≠ (1 :: rat)" by partiality_descending auto qed end lemma add_one_Fract: "1 + Fract (int k) 1 = Fract (1 + int k) 1" by descending auto lemma of_nat_rat: "of_nat k = Fract (of_nat k) 1" apply (induct k) apply (simp add: zero_rat_def Fract_def) apply (simp add: add_one_Fract) done lemma of_int_rat: "of_int k = Fract k 1" apply (cases k rule: int_diff_cases) apply (auto simp add: of_nat_rat minus_rat_def) apply descending apply auto done instantiation rat :: field begin fun rat_inverse_raw where "rat_inverse_raw (a :: int, b :: int) = (if a = 0 then (0, 1) else (b, a))" quotient_definition "inverse :: rat ==> rat" is rat_inverse_raw by (force simp add: mult.commute) definition divide_rat_def: "q / r = q * inverse (r::rat)" instance proof fix q :: rat assume "q ≠ 0" then show "inverse q * q = 1" by partiality_descending auto next fix q r :: rat show "q / r = q * inverse r" by (simp add: divide_rat_def) next show "inverse 0 = (0::rat)" by partiality_descending auto qed end instantiation rat :: linorder begin instance proof fix q r s :: rat { assume "q ≤ r" and "r ≤ s" then show "q ≤ s" proof (partiality_descending, auto simp add: mult.assoc[symmetric]) fix a b c d e f :: int assume nz: "b ≠ 0" "d ≠ 0" "f ≠ 0" then have d2: "d * d > 0" by (metis linorder_neqE_linordered_idom mult_eq_0_iff not_square_less_zero) assume le: "a * d * b * d ≤ c * b * b * d" "c * f * d * f ≤ e * d * d * f" then have a: "a * d * b * d * f * f ≤ c * b * b * d * f * f" using nz(3) by (metis linorder_le_cases mult_right_mono mult_right_mono_neg) have "c * f * d * f * b * b ≤ e * d * d * f * b * b" using nz(1) le by (metis linorder_le_cases mult_right_mono mult_right_mono_neg) then have "a * f * b * f * (d * d) ≤ e * b * b * f * (d * d)" using a by (simp add: algebra_simps) then show "a * f * b * f ≤ e * b * b * f" using d2 by (metis leD linorder_le_less_linear mult_strict_right_mono) qed next assume "q ≤ r" and "r ≤ q" then show "q = r" apply (partiality_descending, auto) apply (case_tac "b > 0", case_tac [!] "ba > 0") apply simp_all done next show "q ≤ q" by partiality_descending auto show "(q 🚫) = (q ≤ r ∧¬ r ≤ q)" unfolding less_rat_def by partiality_descending (auto simp add: le_less mult.commute) show "q ≤ r ∨ r ≤ q" by partiality_descending (auto simp add: mult.commute linorder_linear) } qed end instance rat :: archimedean_field proof fix q r s :: rat show "q ≤ r ==> s + q ≤ s + r" proof (partiality_descending, auto simp add: algebra_simps, simp add: mult.assoc[symmetric]) fix a b c d e :: int assume "e ≠ 0" then have e2: "e * e > 0" by (metis linorder_neqE_linordered_idom mult_eq_0_iff not_square_less_zero) assume "a * b * d * d ≤ b * b * c * d" then show "a * b * d * d * e * e * e * e ≤ b * b * c * d * e * e * e * e" using e2 by (metis mult_left_mono mult.commute linorder_le_cases mult_left_mono_neg) qed show "q 🚫 ==> 0 🚫 ==> s * q 🚫 * r" unfolding less_rat_def proof (partiality_descending, auto simp add: algebra_simps, simp add: mult.assoc[symmetric]) fix a b c d e f :: int assume a: "e ≠ 0" "f ≠ 0" "0 ≤ e * f" "a * b * d * d ≤ b * b * c * d" have "a * b * d * d * (e * f) ≤ b * b * c * d * (e * f)" using a by (simp add: mult_right_mono) then show "a * b * d * d * e * f * f * f ≤ b * b * c * d * e * f * f * f" by (simp add: mult.assoc[symmetric]) (metis a(3) mult_left_mono mult.commute mult_left_mono_neg zero_le_mult_iff) qed show "∃z. r ≤ of_int z" unfolding of_int_rat proof (partiality_descending, auto) fix a b :: int assume "b ≠ 0" then have "a * b ≤ (a div b + 1) * b * b" by (metis mult.commute nonzero_mult_div_cancel_left less_int_def linorder_le_cases zdiv_mono1 zdiv_mono1_neg zle_add1_eq_le) then show "∃z::int. a * b ≤ z * b * b" by auto qed qed *)
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.