diff -r 09a896d295bd -r 54e3847f1669 src/HOL/Rat.thy --- a/src/HOL/Rat.thy Thu May 10 21:18:41 2012 +0200 +++ b/src/HOL/Rat.thy Thu May 10 21:02:36 2012 +0200 @@ -400,200 +400,121 @@ subsubsection {* The ordered field of rational numbers *} -instantiation rat :: linorder +lift_definition positive :: "rat \ bool" + is "\x. 0 < fst x * snd x" +proof (clarsimp) + fix a b c d :: int + assume "b \ 0" and "d \ 0" and "a * d = c * b" + hence "a * d * b * d = c * b * b * d" + by simp + hence "a * b * d\ = c * d * b\" + unfolding power2_eq_square by (simp add: mult_ac) + hence "0 < a * b * d\ \ 0 < c * d * b\" + by simp + thus "0 < a * b \ 0 < c * d" + using `b \ 0` and `d \ 0` + by (simp add: zero_less_mult_iff) +qed + +lemma positive_zero: "\ positive 0" + by transfer simp + +lemma positive_add: + "positive x \ positive y \ positive (x + y)" +apply transfer +apply (simp add: zero_less_mult_iff) +apply (elim disjE, simp_all add: add_pos_pos add_neg_neg + mult_pos_pos mult_pos_neg mult_neg_pos mult_neg_neg) +done + +lemma positive_mult: + "positive x \ positive y \ positive (x * y)" +by transfer (drule (1) mult_pos_pos, simp add: mult_ac) + +lemma positive_minus: + "\ positive x \ x \ 0 \ positive (- x)" +by transfer (force simp: neq_iff zero_less_mult_iff mult_less_0_iff) + +instantiation rat :: linordered_field_inverse_zero begin -lift_definition less_eq_rat :: "rat \ rat \ bool" - is "\x y. (fst x * snd y) * (snd x * snd y) \ (fst y * snd x) * (snd x * snd y)" -proof (clarsimp) - fix a b a' b' c d c' d'::int - assume neq: "b \ 0" "b' \ 0" "d \ 0" "d' \ 0" - assume eq1: "a * b' = a' * b" - assume eq2: "c * d' = c' * d" +definition + "x < y \ positive (y - x)" + +definition + "x \ (y::rat) \ x < y \ x = y" + +definition + "abs (a::rat) = (if a < 0 then - a else a)" + +definition + "sgn (a::rat) = (if a = 0 then 0 else if 0 < a then 1 else - 1)" - let ?le = "\a b c d. ((a * d) * (b * d) \ (c * b) * (b * d))" - { - fix a b c d x :: int assume x: "x \ 0" - have "?le a b c d = ?le (a * x) (b * x) c d" - proof - - from x have "0 < x * x" by (auto simp add: zero_less_mult_iff) - hence "?le a b c d = - ((a * d) * (b * d) * (x * x) \ (c * b) * (b * d) * (x * x))" - by (simp add: mult_le_cancel_right) - also have "... = ?le (a * x) (b * x) c d" - by (simp add: mult_ac) - finally show ?thesis . - qed - } note le_factor = this - - let ?D = "b * d" and ?D' = "b' * d'" - from neq have D: "?D \ 0" by simp - from neq have "?D' \ 0" by simp - hence "?le a b c d = ?le (a * ?D') (b * ?D') c d" - by (rule le_factor) - also have "... = ((a * b') * ?D * ?D' * d * d' \ (c * d') * ?D * ?D' * b * b')" - by (simp add: mult_ac) - also have "... = ((a' * b) * ?D * ?D' * d * d' \ (c' * d) * ?D * ?D' * b * b')" - by (simp only: eq1 eq2) - also have "... = ?le (a' * ?D) (b' * ?D) c' d'" - by (simp add: mult_ac) - also from D have "... = ?le a' b' c' d'" - by (rule le_factor [symmetric]) - finally show "?le a b c d = ?le a' b' c' d'" . +instance proof + fix a b c :: rat + show "\a\ = (if a < 0 then - a else a)" + by (rule abs_rat_def) + show "a < b \ a \ b \ \ b \ a" + unfolding less_eq_rat_def less_rat_def + by (auto, drule (1) positive_add, simp_all add: positive_zero) + show "a \ a" + unfolding less_eq_rat_def by simp + show "a \ b \ b \ c \ a \ c" + unfolding less_eq_rat_def less_rat_def + by (auto, drule (1) positive_add, simp add: algebra_simps) + show "a \ b \ b \ a \ a = b" + unfolding less_eq_rat_def less_rat_def + by (auto, drule (1) positive_add, simp add: positive_zero) + show "a \ b \ c + a \ c + b" + unfolding less_eq_rat_def less_rat_def by (auto simp: diff_minus) + show "sgn a = (if a = 0 then 0 else if 0 < a then 1 else - 1)" + by (rule sgn_rat_def) + show "a \ b \ b \ a" + unfolding less_eq_rat_def less_rat_def + by (auto dest!: positive_minus) + show "a < b \ 0 < c \ c * a < c * b" + unfolding less_rat_def + by (drule (1) positive_mult, simp add: algebra_simps) qed -lemma le_rat [simp]: - assumes "b \ 0" and "d \ 0" - shows "Fract a b \ Fract c d \ (a * d) * (b * d) \ (c * b) * (b * d)" - using assms by transfer simp +end + +instantiation rat :: distrib_lattice +begin + +definition + "(inf :: rat \ rat \ rat) = min" definition - less_rat_def: "z < (w::rat) \ z \ w \ z \ w" + "(sup :: rat \ rat \ rat) = max" + +instance proof +qed (auto simp add: inf_rat_def sup_rat_def min_max.sup_inf_distrib1) + +end + +lemma positive_rat: "positive (Fract a b) \ 0 < a * b" + by transfer simp lemma less_rat [simp]: assumes "b \ 0" and "d \ 0" shows "Fract a b < Fract c d \ (a * d) * (b * d) < (c * b) * (b * d)" - using assms by (simp add: less_rat_def eq_rat order_less_le) + using assms unfolding less_rat_def + by (simp add: positive_rat algebra_simps) -instance proof - fix q r s :: rat - { - assume "q \ r" and "r \ s" - then show "q \ s" - proof (induct q, induct r, induct s) - fix a b c d e f :: int - assume neq: "b > 0" "d > 0" "f > 0" - assume 1: "Fract a b \ Fract c d" and 2: "Fract c d \ Fract e f" - show "Fract a b \ Fract e f" - proof - - from neq obtain bb: "0 < b * b" and dd: "0 < d * d" and ff: "0 < f * f" - by (auto simp add: zero_less_mult_iff linorder_neq_iff) - have "(a * d) * (b * d) * (f * f) \ (c * b) * (b * d) * (f * f)" - proof - - from neq 1 have "(a * d) * (b * d) \ (c * b) * (b * d)" - by simp - with ff show ?thesis by (simp add: mult_le_cancel_right) - qed - also have "... = (c * f) * (d * f) * (b * b)" by algebra - also have "... \ (e * d) * (d * f) * (b * b)" - proof - - from neq 2 have "(c * f) * (d * f) \ (e * d) * (d * f)" - by simp - with bb show ?thesis by (simp add: mult_le_cancel_right) - qed - finally have "(a * f) * (b * f) * (d * d) \ e * b * (b * f) * (d * d)" - by (simp only: mult_ac) - with dd have "(a * f) * (b * f) \ (e * b) * (b * f)" - by (simp add: mult_le_cancel_right) - with neq show ?thesis by simp - qed - qed - next - assume "q \ r" and "r \ q" - then show "q = r" - proof (induct q, induct r) - fix a b c d :: int - assume neq: "b > 0" "d > 0" - assume 1: "Fract a b \ Fract c d" and 2: "Fract c d \ Fract a b" - show "Fract a b = Fract c d" - proof - - from neq 1 have "(a * d) * (b * d) \ (c * b) * (b * d)" - by simp - also have "... \ (a * d) * (b * d)" - proof - - from neq 2 have "(c * b) * (d * b) \ (a * d) * (d * b)" - by simp - thus ?thesis by (simp only: mult_ac) - qed - finally have "(a * d) * (b * d) = (c * b) * (b * d)" . - moreover from neq have "b * d \ 0" by simp - ultimately have "a * d = c * b" by simp - with neq show ?thesis by (simp add: eq_rat) - qed - qed - next - show "q \ q" - by (induct q) simp - show "(q < r) = (q \ r \ \ r \ q)" - by (induct q, induct r) (auto simp add: le_less mult_commute) - show "q \ r \ r \ q" - by (induct q, induct r) - (simp add: mult_commute, rule linorder_linear) - } -qed - -end - -instantiation rat :: "{distrib_lattice, abs_if, sgn_if}" -begin - -definition - abs_rat_def: "\q\ = (if q < 0 then -q else (q::rat))" +lemma le_rat [simp]: + assumes "b \ 0" and "d \ 0" + shows "Fract a b \ Fract c d \ (a * d) * (b * d) \ (c * b) * (b * d)" + using assms unfolding le_less by (simp add: eq_rat) lemma abs_rat [simp, code]: "\Fract a b\ = Fract \a\ \b\" by (auto simp add: abs_rat_def zabs_def Zero_rat_def not_less le_less eq_rat zero_less_mult_iff) -definition - sgn_rat_def: "sgn (q::rat) = (if q = 0 then 0 else if 0 < q then 1 else - 1)" - lemma sgn_rat [simp, code]: "sgn (Fract a b) = of_int (sgn a * sgn b)" unfolding Fract_of_int_eq by (auto simp: zsgn_def sgn_rat_def Zero_rat_def eq_rat) (auto simp: rat_number_collapse not_less le_less zero_less_mult_iff) -definition - "(inf \ rat \ rat \ rat) = min" - -definition - "(sup \ rat \ rat \ rat) = max" - -instance by intro_classes - (auto simp add: abs_rat_def sgn_rat_def min_max.sup_inf_distrib1 inf_rat_def sup_rat_def) - -end - -instance rat :: linordered_field_inverse_zero -proof - fix q r s :: rat - show "q \ r ==> s + q \ s + r" - proof (induct q, induct r, induct s) - fix a b c d e f :: int - assume neq: "b > 0" "d > 0" "f > 0" - assume le: "Fract a b \ Fract c d" - show "Fract e f + Fract a b \ Fract e f + Fract c d" - proof - - let ?F = "f * f" from neq have F: "0 < ?F" - by (auto simp add: zero_less_mult_iff) - from neq le have "(a * d) * (b * d) \ (c * b) * (b * d)" - by simp - with F have "(a * d) * (b * d) * ?F * ?F \ (c * b) * (b * d) * ?F * ?F" - by (simp add: mult_le_cancel_right) - with neq show ?thesis by (simp add: mult_ac int_distrib) - qed - qed - show "q < r ==> 0 < s ==> s * q < s * r" - proof (induct q, induct r, induct s) - fix a b c d e f :: int - assume neq: "b > 0" "d > 0" "f > 0" - assume le: "Fract a b < Fract c d" - assume gt: "0 < Fract e f" - show "Fract e f * Fract a b < Fract e f * Fract c d" - proof - - let ?E = "e * f" and ?F = "f * f" - from neq gt have "0 < ?E" - by (auto simp add: Zero_rat_def order_less_le eq_rat) - moreover from neq have "0 < ?F" - by (auto simp add: zero_less_mult_iff) - moreover from neq le have "(a * d) * (b * d) < (c * b) * (b * d)" - by simp - ultimately have "(a * d) * (b * d) * ?E * ?F < (c * b) * (b * d) * ?E * ?F" - by (simp add: mult_less_cancel_right) - with neq show ?thesis - by (simp add: mult_ac) - qed - qed -qed auto - lemma Rat_induct_pos [case_names Fract, induct type: rat]: assumes step: "\a b. 0 < b \ P (Fract a b)" shows "P q" @@ -1194,13 +1115,13 @@ by simp -hide_const (open) normalize +hide_const (open) normalize positive lemmas [transfer_rule del] = rat.All_transfer rat.Ex_transfer rat.rel_eq_transfer forall_rat_transfer Fract.transfer zero_rat.transfer one_rat.transfer plus_rat.transfer uminus_rat.transfer times_rat.transfer inverse_rat.transfer - less_eq_rat.transfer of_rat.transfer + positive.transfer of_rat.transfer text {* De-register @{text "rat"} as a quotient type: *}