(* Title: HOL/Rings.thy Author: Gertrud Bauer Author: Steven Obua Author: Tobias Nipkow Author: Lawrence C Paulson Author: Markus Wenzel Author: Jeremy Avigad *) header {* Rings *} theory Rings imports Groups begin class semiring = ab_semigroup_add + semigroup_mult + assumes distrib_right[algebra_simps, field_simps]: "(a + b) * c = a * c + b * c" assumes distrib_left[algebra_simps, field_simps]: "a * (b + c) = a * b + a * c" begin text{*For the @{text combine_numerals} simproc*} lemma combine_common_factor: "a * e + (b * e + c) = (a + b) * e + c" by (simp add: distrib_right ac_simps) end class mult_zero = times + zero + assumes mult_zero_left [simp]: "0 * a = 0" assumes mult_zero_right [simp]: "a * 0 = 0" begin lemma mult_not_zero: "a * b \ 0 \ a \ 0 \ b \ 0" by auto end class semiring_0 = semiring + comm_monoid_add + mult_zero class semiring_0_cancel = semiring + cancel_comm_monoid_add begin subclass semiring_0 proof fix a :: 'a have "0 * a + 0 * a = 0 * a + 0" by (simp add: distrib_right [symmetric]) thus "0 * a = 0" by (simp only: add_left_cancel) next fix a :: 'a have "a * 0 + a * 0 = a * 0 + 0" by (simp add: distrib_left [symmetric]) thus "a * 0 = 0" by (simp only: add_left_cancel) qed end class comm_semiring = ab_semigroup_add + ab_semigroup_mult + assumes distrib: "(a + b) * c = a * c + b * c" begin subclass semiring proof fix a b c :: 'a show "(a + b) * c = a * c + b * c" by (simp add: distrib) have "a * (b + c) = (b + c) * a" by (simp add: ac_simps) also have "... = b * a + c * a" by (simp only: distrib) also have "... = a * b + a * c" by (simp add: ac_simps) finally show "a * (b + c) = a * b + a * c" by blast qed end class comm_semiring_0 = comm_semiring + comm_monoid_add + mult_zero begin subclass semiring_0 .. end class comm_semiring_0_cancel = comm_semiring + cancel_comm_monoid_add begin subclass semiring_0_cancel .. subclass comm_semiring_0 .. end class zero_neq_one = zero + one + assumes zero_neq_one [simp]: "0 \ 1" begin lemma one_neq_zero [simp]: "1 \ 0" by (rule not_sym) (rule zero_neq_one) definition of_bool :: "bool \ 'a" where "of_bool p = (if p then 1 else 0)" lemma of_bool_eq [simp, code]: "of_bool False = 0" "of_bool True = 1" by (simp_all add: of_bool_def) lemma of_bool_eq_iff: "of_bool p = of_bool q \ p = q" by (simp add: of_bool_def) lemma split_of_bool [split]: "P (of_bool p) \ (p \ P 1) \ (\ p \ P 0)" by (cases p) simp_all lemma split_of_bool_asm: "P (of_bool p) \ \ (p \ \ P 1 \ \ p \ \ P 0)" by (cases p) simp_all end class semiring_1 = zero_neq_one + semiring_0 + monoid_mult text {* Abstract divisibility *} class dvd = times begin definition dvd :: "'a \ 'a \ bool" (infix "dvd" 50) where "b dvd a \ (\k. a = b * k)" lemma dvdI [intro?]: "a = b * k \ b dvd a" unfolding dvd_def .. lemma dvdE [elim?]: "b dvd a \ (\k. a = b * k \ P) \ P" unfolding dvd_def by blast end class comm_semiring_1 = zero_neq_one + comm_semiring_0 + comm_monoid_mult + dvd (*previously almost_semiring*) begin subclass semiring_1 .. lemma dvd_refl[simp]: "a dvd a" proof show "a = a * 1" by simp qed lemma dvd_trans: assumes "a dvd b" and "b dvd c" shows "a dvd c" proof - from assms obtain v where "b = a * v" by (auto elim!: dvdE) moreover from assms obtain w where "c = b * w" by (auto elim!: dvdE) ultimately have "c = a * (v * w)" by (simp add: mult.assoc) then show ?thesis .. qed lemma dvd_0_left_iff [simp]: "0 dvd a \ a = 0" by (auto intro: dvd_refl elim!: dvdE) lemma dvd_0_right [iff]: "a dvd 0" proof show "0 = a * 0" by simp qed lemma one_dvd [simp]: "1 dvd a" by (auto intro!: dvdI) lemma dvd_mult[simp]: "a dvd c \ a dvd (b * c)" by (auto intro!: mult.left_commute dvdI elim!: dvdE) lemma dvd_mult2[simp]: "a dvd b \ a dvd (b * c)" apply (subst mult.commute) apply (erule dvd_mult) done lemma dvd_triv_right [simp]: "a dvd b * a" by (rule dvd_mult) (rule dvd_refl) lemma dvd_triv_left [simp]: "a dvd a * b" by (rule dvd_mult2) (rule dvd_refl) lemma mult_dvd_mono: assumes "a dvd b" and "c dvd d" shows "a * c dvd b * d" proof - from `a dvd b` obtain b' where "b = a * b'" .. moreover from `c dvd d` obtain d' where "d = c * d'" .. ultimately have "b * d = (a * c) * (b' * d')" by (simp add: ac_simps) then show ?thesis .. qed lemma dvd_mult_left: "a * b dvd c \ a dvd c" by (simp add: dvd_def mult.assoc, blast) lemma dvd_mult_right: "a * b dvd c \ b dvd c" unfolding mult.commute [of a] by (rule dvd_mult_left) lemma dvd_0_left: "0 dvd a \ a = 0" by simp lemma dvd_add[simp]: assumes "a dvd b" and "a dvd c" shows "a dvd (b + c)" proof - from `a dvd b` obtain b' where "b = a * b'" .. moreover from `a dvd c` obtain c' where "c = a * c'" .. ultimately have "b + c = a * (b' + c')" by (simp add: distrib_left) then show ?thesis .. qed end class no_zero_divisors = zero + times + assumes no_zero_divisors: "a \ 0 \ b \ 0 \ a * b \ 0" begin lemma divisors_zero: assumes "a * b = 0" shows "a = 0 \ b = 0" proof (rule classical) assume "\ (a = 0 \ b = 0)" then have "a \ 0" and "b \ 0" by auto with no_zero_divisors have "a * b \ 0" by blast with assms show ?thesis by simp qed end class semiring_1_cancel = semiring + cancel_comm_monoid_add + zero_neq_one + monoid_mult begin subclass semiring_0_cancel .. subclass semiring_1 .. end class comm_semiring_1_cancel = comm_semiring + cancel_comm_monoid_add + zero_neq_one + comm_monoid_mult begin subclass semiring_1_cancel .. subclass comm_semiring_0_cancel .. subclass comm_semiring_1 .. end class ring = semiring + ab_group_add begin subclass semiring_0_cancel .. text {* Distribution rules *} lemma minus_mult_left: "- (a * b) = - a * b" by (rule minus_unique) (simp add: distrib_right [symmetric]) lemma minus_mult_right: "- (a * b) = a * - b" by (rule minus_unique) (simp add: distrib_left [symmetric]) text{*Extract signs from products*} lemmas mult_minus_left [simp] = minus_mult_left [symmetric] lemmas mult_minus_right [simp] = minus_mult_right [symmetric] lemma minus_mult_minus [simp]: "- a * - b = a * b" by simp lemma minus_mult_commute: "- a * b = a * - b" by simp lemma right_diff_distrib [algebra_simps, field_simps]: "a * (b - c) = a * b - a * c" using distrib_left [of a b "-c "] by simp lemma left_diff_distrib [algebra_simps, field_simps]: "(a - b) * c = a * c - b * c" using distrib_right [of a "- b" c] by simp lemmas ring_distribs = distrib_left distrib_right left_diff_distrib right_diff_distrib lemma eq_add_iff1: "a * e + c = b * e + d \ (a - b) * e + c = d" by (simp add: algebra_simps) lemma eq_add_iff2: "a * e + c = b * e + d \ c = (b - a) * e + d" by (simp add: algebra_simps) end lemmas ring_distribs = distrib_left distrib_right left_diff_distrib right_diff_distrib class comm_ring = comm_semiring + ab_group_add begin subclass ring .. subclass comm_semiring_0_cancel .. lemma square_diff_square_factored: "x * x - y * y = (x + y) * (x - y)" by (simp add: algebra_simps) end class ring_1 = ring + zero_neq_one + monoid_mult begin subclass semiring_1_cancel .. lemma square_diff_one_factored: "x * x - 1 = (x + 1) * (x - 1)" by (simp add: algebra_simps) end class comm_ring_1 = comm_ring + zero_neq_one + comm_monoid_mult (*previously ring*) begin subclass ring_1 .. subclass comm_semiring_1_cancel .. lemma dvd_minus_iff [simp]: "x dvd - y \ x dvd y" proof assume "x dvd - y" then have "x dvd - 1 * - y" by (rule dvd_mult) then show "x dvd y" by simp next assume "x dvd y" then have "x dvd - 1 * y" by (rule dvd_mult) then show "x dvd - y" by simp qed lemma minus_dvd_iff [simp]: "- x dvd y \ x dvd y" proof assume "- x dvd y" then obtain k where "y = - x * k" .. then have "y = x * - k" by simp then show "x dvd y" .. next assume "x dvd y" then obtain k where "y = x * k" .. then have "y = - x * - k" by simp then show "- x dvd y" .. qed lemma dvd_diff [simp]: "x dvd y \ x dvd z \ x dvd (y - z)" using dvd_add [of x y "- z"] by simp end class ring_no_zero_divisors = ring + no_zero_divisors begin lemma mult_eq_0_iff [simp]: shows "a * b = 0 \ (a = 0 \ b = 0)" proof (cases "a = 0 \ b = 0") case False then have "a \ 0" and "b \ 0" by auto then show ?thesis using no_zero_divisors by simp next case True then show ?thesis by auto qed text{*Cancellation of equalities with a common factor*} lemma mult_cancel_right [simp]: "a * c = b * c \ c = 0 \ a = b" proof - have "(a * c = b * c) = ((a - b) * c = 0)" by (simp add: algebra_simps) thus ?thesis by (simp add: disj_commute) qed lemma mult_cancel_left [simp]: "c * a = c * b \ c = 0 \ a = b" proof - have "(c * a = c * b) = (c * (a - b) = 0)" by (simp add: algebra_simps) thus ?thesis by simp qed lemma mult_left_cancel: "c \ 0 \ (c*a=c*b) = (a=b)" by simp lemma mult_right_cancel: "c \ 0 \ (a*c=b*c) = (a=b)" by simp end class ring_1_no_zero_divisors = ring_1 + ring_no_zero_divisors begin lemma square_eq_1_iff: "x * x = 1 \ x = 1 \ x = - 1" proof - have "(x - 1) * (x + 1) = x * x - 1" by (simp add: algebra_simps) hence "x * x = 1 \ (x - 1) * (x + 1) = 0" by simp thus ?thesis by (simp add: eq_neg_iff_add_eq_0) qed lemma mult_cancel_right1 [simp]: "c = b * c \ c = 0 \ b = 1" by (insert mult_cancel_right [of 1 c b], force) lemma mult_cancel_right2 [simp]: "a * c = c \ c = 0 \ a = 1" by (insert mult_cancel_right [of a c 1], simp) lemma mult_cancel_left1 [simp]: "c = c * b \ c = 0 \ b = 1" by (insert mult_cancel_left [of c 1 b], force) lemma mult_cancel_left2 [simp]: "c * a = c \ c = 0 \ a = 1" by (insert mult_cancel_left [of c a 1], simp) end class idom = comm_ring_1 + no_zero_divisors begin subclass ring_1_no_zero_divisors .. lemma square_eq_iff: "a * a = b * b \ (a = b \ a = - b)" proof assume "a * a = b * b" then have "(a - b) * (a + b) = 0" by (simp add: algebra_simps) then show "a = b \ a = - b" by (simp add: eq_neg_iff_add_eq_0) next assume "a = b \ a = - b" then show "a * a = b * b" by auto qed lemma dvd_mult_cancel_right [simp]: "a * c dvd b * c \ c = 0 \ a dvd b" proof - have "a * c dvd b * c \ (\k. b * c = (a * k) * c)" unfolding dvd_def by (simp add: ac_simps) also have "(\k. b * c = (a * k) * c) \ c = 0 \ a dvd b" unfolding dvd_def by simp finally show ?thesis . qed lemma dvd_mult_cancel_left [simp]: "c * a dvd c * b \ c = 0 \ a dvd b" proof - have "c * a dvd c * b \ (\k. b * c = (a * k) * c)" unfolding dvd_def by (simp add: ac_simps) also have "(\k. b * c = (a * k) * c) \ c = 0 \ a dvd b" unfolding dvd_def by simp finally show ?thesis . qed end text {* The theory of partially ordered rings is taken from the books: \begin{itemize} \item \emph{Lattice Theory} by Garret Birkhoff, American Mathematical Society 1979 \item \emph{Partially Ordered Algebraic Systems}, Pergamon Press 1963 \end{itemize} Most of the used notions can also be looked up in \begin{itemize} \item @{url "http://www.mathworld.com"} by Eric Weisstein et. al. \item \emph{Algebra I} by van der Waerden, Springer. \end{itemize} *} class ordered_semiring = semiring + comm_monoid_add + ordered_ab_semigroup_add + assumes mult_left_mono: "a \ b \ 0 \ c \ c * a \ c * b" assumes mult_right_mono: "a \ b \ 0 \ c \ a * c \ b * c" begin lemma mult_mono: "a \ b \ c \ d \ 0 \ b \ 0 \ c \ a * c \ b * d" apply (erule mult_right_mono [THEN order_trans], assumption) apply (erule mult_left_mono, assumption) done lemma mult_mono': "a \ b \ c \ d \ 0 \ a \ 0 \ c \ a * c \ b * d" apply (rule mult_mono) apply (fast intro: order_trans)+ done end class ordered_cancel_semiring = ordered_semiring + cancel_comm_monoid_add begin subclass semiring_0_cancel .. lemma mult_nonneg_nonneg[simp]: "0 \ a \ 0 \ b \ 0 \ a * b" using mult_left_mono [of 0 b a] by simp lemma mult_nonneg_nonpos: "0 \ a \ b \ 0 \ a * b \ 0" using mult_left_mono [of b 0 a] by simp lemma mult_nonpos_nonneg: "a \ 0 \ 0 \ b \ a * b \ 0" using mult_right_mono [of a 0 b] by simp text {* Legacy - use @{text mult_nonpos_nonneg} *} lemma mult_nonneg_nonpos2: "0 \ a \ b \ 0 \ b * a \ 0" by (drule mult_right_mono [of b 0], auto) lemma split_mult_neg_le: "(0 \ a & b \ 0) | (a \ 0 & 0 \ b) \ a * b \ 0" by (auto simp add: mult_nonneg_nonpos mult_nonneg_nonpos2) end class linordered_semiring = ordered_semiring + linordered_cancel_ab_semigroup_add begin subclass ordered_cancel_semiring .. subclass ordered_comm_monoid_add .. lemma mult_left_less_imp_less: "c * a < c * b \ 0 \ c \ a < b" by (force simp add: mult_left_mono not_le [symmetric]) lemma mult_right_less_imp_less: "a * c < b * c \ 0 \ c \ a < b" by (force simp add: mult_right_mono not_le [symmetric]) end class linordered_semiring_1 = linordered_semiring + semiring_1 begin lemma convex_bound_le: assumes "x \ a" "y \ a" "0 \ u" "0 \ v" "u + v = 1" shows "u * x + v * y \ a" proof- from assms have "u * x + v * y \ u * a + v * a" by (simp add: add_mono mult_left_mono) thus ?thesis using assms unfolding distrib_right[symmetric] by simp qed end class linordered_semiring_strict = semiring + comm_monoid_add + linordered_cancel_ab_semigroup_add + assumes mult_strict_left_mono: "a < b \ 0 < c \ c * a < c * b" assumes mult_strict_right_mono: "a < b \ 0 < c \ a * c < b * c" begin subclass semiring_0_cancel .. subclass linordered_semiring proof fix a b c :: 'a assume A: "a \ b" "0 \ c" from A show "c * a \ c * b" unfolding le_less using mult_strict_left_mono by (cases "c = 0") auto from A show "a * c \ b * c" unfolding le_less using mult_strict_right_mono by (cases "c = 0") auto qed lemma mult_left_le_imp_le: "c * a \ c * b \ 0 < c \ a \ b" by (force simp add: mult_strict_left_mono _not_less [symmetric]) lemma mult_right_le_imp_le: "a * c \ b * c \ 0 < c \ a \ b" by (force simp add: mult_strict_right_mono not_less [symmetric]) lemma mult_pos_pos[simp]: "0 < a \ 0 < b \ 0 < a * b" using mult_strict_left_mono [of 0 b a] by simp lemma mult_pos_neg: "0 < a \ b < 0 \ a * b < 0" using mult_strict_left_mono [of b 0 a] by simp lemma mult_neg_pos: "a < 0 \ 0 < b \ a * b < 0" using mult_strict_right_mono [of a 0 b] by simp text {* Legacy - use @{text mult_neg_pos} *} lemma mult_pos_neg2: "0 < a \ b < 0 \ b * a < 0" by (drule mult_strict_right_mono [of b 0], auto) lemma zero_less_mult_pos: "0 < a * b \ 0 < a \ 0 < b" apply (cases "b\0") apply (auto simp add: le_less not_less) apply (drule_tac mult_pos_neg [of a b]) apply (auto dest: less_not_sym) done lemma zero_less_mult_pos2: "0 < b * a \ 0 < a \ 0 < b" apply (cases "b\0") apply (auto simp add: le_less not_less) apply (drule_tac mult_pos_neg2 [of a b]) apply (auto dest: less_not_sym) done text{*Strict monotonicity in both arguments*} lemma mult_strict_mono: assumes "a < b" and "c < d" and "0 < b" and "0 \ c" shows "a * c < b * d" using assms apply (cases "c=0") apply (simp) apply (erule mult_strict_right_mono [THEN less_trans]) apply (force simp add: le_less) apply (erule mult_strict_left_mono, assumption) done text{*This weaker variant has more natural premises*} lemma mult_strict_mono': assumes "a < b" and "c < d" and "0 \ a" and "0 \ c" shows "a * c < b * d" by (rule mult_strict_mono) (insert assms, auto) lemma mult_less_le_imp_less: assumes "a < b" and "c \ d" and "0 \ a" and "0 < c" shows "a * c < b * d" using assms apply (subgoal_tac "a * c < b * c") apply (erule less_le_trans) apply (erule mult_left_mono) apply simp apply (erule mult_strict_right_mono) apply assumption done lemma mult_le_less_imp_less: assumes "a \ b" and "c < d" and "0 < a" and "0 \ c" shows "a * c < b * d" using assms apply (subgoal_tac "a * c \ b * c") apply (erule le_less_trans) apply (erule mult_strict_left_mono) apply simp apply (erule mult_right_mono) apply simp done lemma mult_less_imp_less_left: assumes less: "c * a < c * b" and nonneg: "0 \ c" shows "a < b" proof (rule ccontr) assume "\ a < b" hence "b \ a" by (simp add: linorder_not_less) hence "c * b \ c * a" using nonneg by (rule mult_left_mono) with this and less show False by (simp add: not_less [symmetric]) qed lemma mult_less_imp_less_right: assumes less: "a * c < b * c" and nonneg: "0 \ c" shows "a < b" proof (rule ccontr) assume "\ a < b" hence "b \ a" by (simp add: linorder_not_less) hence "b * c \ a * c" using nonneg by (rule mult_right_mono) with this and less show False by (simp add: not_less [symmetric]) qed end class linordered_semiring_1_strict = linordered_semiring_strict + semiring_1 begin subclass linordered_semiring_1 .. lemma convex_bound_lt: assumes "x < a" "y < a" "0 \ u" "0 \ v" "u + v = 1" shows "u * x + v * y < a" proof - from assms have "u * x + v * y < u * a + v * a" by (cases "u = 0") (auto intro!: add_less_le_mono mult_strict_left_mono mult_left_mono) thus ?thesis using assms unfolding distrib_right[symmetric] by simp qed end class ordered_comm_semiring = comm_semiring_0 + ordered_ab_semigroup_add + assumes comm_mult_left_mono: "a \ b \ 0 \ c \ c * a \ c * b" begin subclass ordered_semiring proof fix a b c :: 'a assume "a \ b" "0 \ c" thus "c * a \ c * b" by (rule comm_mult_left_mono) thus "a * c \ b * c" by (simp only: mult.commute) qed end class ordered_cancel_comm_semiring = ordered_comm_semiring + cancel_comm_monoid_add begin subclass comm_semiring_0_cancel .. subclass ordered_comm_semiring .. subclass ordered_cancel_semiring .. end class linordered_comm_semiring_strict = comm_semiring_0 + linordered_cancel_ab_semigroup_add + assumes comm_mult_strict_left_mono: "a < b \ 0 < c \ c * a < c * b" begin subclass linordered_semiring_strict proof fix a b c :: 'a assume "a < b" "0 < c" thus "c * a < c * b" by (rule comm_mult_strict_left_mono) thus "a * c < b * c" by (simp only: mult.commute) qed subclass ordered_cancel_comm_semiring proof fix a b c :: 'a assume "a \ b" "0 \ c" thus "c * a \ c * b" unfolding le_less using mult_strict_left_mono by (cases "c = 0") auto qed end class ordered_ring = ring + ordered_cancel_semiring begin subclass ordered_ab_group_add .. lemma less_add_iff1: "a * e + c < b * e + d \ (a - b) * e + c < d" by (simp add: algebra_simps) lemma less_add_iff2: "a * e + c < b * e + d \ c < (b - a) * e + d" by (simp add: algebra_simps) lemma le_add_iff1: "a * e + c \ b * e + d \ (a - b) * e + c \ d" by (simp add: algebra_simps) lemma le_add_iff2: "a * e + c \ b * e + d \ c \ (b - a) * e + d" by (simp add: algebra_simps) lemma mult_left_mono_neg: "b \ a \ c \ 0 \ c * a \ c * b" apply (drule mult_left_mono [of _ _ "- c"]) apply simp_all done lemma mult_right_mono_neg: "b \ a \ c \ 0 \ a * c \ b * c" apply (drule mult_right_mono [of _ _ "- c"]) apply simp_all done lemma mult_nonpos_nonpos: "a \ 0 \ b \ 0 \ 0 \ a * b" using mult_right_mono_neg [of a 0 b] by simp lemma split_mult_pos_le: "(0 \ a \ 0 \ b) \ (a \ 0 \ b \ 0) \ 0 \ a * b" by (auto simp add: mult_nonpos_nonpos) end class linordered_ring = ring + linordered_semiring + linordered_ab_group_add + abs_if begin subclass ordered_ring .. subclass ordered_ab_group_add_abs proof fix a b show "\a + b\ \ \a\ + \b\" by (auto simp add: abs_if not_le not_less algebra_simps simp del: add.commute dest: add_neg_neg add_nonneg_nonneg) qed (auto simp add: abs_if) lemma zero_le_square [simp]: "0 \ a * a" using linear [of 0 a] by (auto simp add: mult_nonpos_nonpos) lemma not_square_less_zero [simp]: "\ (a * a < 0)" by (simp add: not_less) end (* The "strict" suffix can be seen as describing the combination of linordered_ring and no_zero_divisors. Basically, linordered_ring + no_zero_divisors = linordered_ring_strict. *) class linordered_ring_strict = ring + linordered_semiring_strict + ordered_ab_group_add + abs_if begin subclass linordered_ring .. lemma mult_strict_left_mono_neg: "b < a \ c < 0 \ c * a < c * b" using mult_strict_left_mono [of b a "- c"] by simp lemma mult_strict_right_mono_neg: "b < a \ c < 0 \ a * c < b * c" using mult_strict_right_mono [of b a "- c"] by simp lemma mult_neg_neg: "a < 0 \ b < 0 \ 0 < a * b" using mult_strict_right_mono_neg [of a 0 b] by simp subclass ring_no_zero_divisors proof fix a b assume "a \ 0" then have A: "a < 0 \ 0 < a" by (simp add: neq_iff) assume "b \ 0" then have B: "b < 0 \ 0 < b" by (simp add: neq_iff) have "a * b < 0 \ 0 < a * b" proof (cases "a < 0") case True note A' = this show ?thesis proof (cases "b < 0") case True with A' show ?thesis by (auto dest: mult_neg_neg) next case False with B have "0 < b" by auto with A' show ?thesis by (auto dest: mult_strict_right_mono) qed next case False with A have A': "0 < a" by auto show ?thesis proof (cases "b < 0") case True with A' show ?thesis by (auto dest: mult_strict_right_mono_neg) next case False with B have "0 < b" by auto with A' show ?thesis by auto qed qed then show "a * b \ 0" by (simp add: neq_iff) qed lemma zero_less_mult_iff: "0 < a * b \ 0 < a \ 0 < b \ a < 0 \ b < 0" by (cases a 0 b 0 rule: linorder_cases[case_product linorder_cases]) (auto simp add: mult_neg_neg not_less le_less dest: zero_less_mult_pos zero_less_mult_pos2) lemma zero_le_mult_iff: "0 \ a * b \ 0 \ a \ 0 \ b \ a \ 0 \ b \ 0" by (auto simp add: eq_commute [of 0] le_less not_less zero_less_mult_iff) lemma mult_less_0_iff: "a * b < 0 \ 0 < a \ b < 0 \ a < 0 \ 0 < b" apply (insert zero_less_mult_iff [of "-a" b]) apply force done lemma mult_le_0_iff: "a * b \ 0 \ 0 \ a \ b \ 0 \ a \ 0 \ 0 \ b" apply (insert zero_le_mult_iff [of "-a" b]) apply force done text{*Cancellation laws for @{term "c*a < c*b"} and @{term "a*c < b*c"}, also with the relations @{text "\"} and equality.*} text{*These ``disjunction'' versions produce two cases when the comparison is an assumption, but effectively four when the comparison is a goal.*} lemma mult_less_cancel_right_disj: "a * c < b * c \ 0 < c \ a < b \ c < 0 \ b < a" apply (cases "c = 0") apply (auto simp add: neq_iff mult_strict_right_mono mult_strict_right_mono_neg) apply (auto simp add: not_less not_le [symmetric, of "a*c"] not_le [symmetric, of a]) apply (erule_tac [!] notE) apply (auto simp add: less_imp_le mult_right_mono mult_right_mono_neg) done lemma mult_less_cancel_left_disj: "c * a < c * b \ 0 < c \ a < b \ c < 0 \ b < a" apply (cases "c = 0") apply (auto simp add: neq_iff mult_strict_left_mono mult_strict_left_mono_neg) apply (auto simp add: not_less not_le [symmetric, of "c*a"] not_le [symmetric, of a]) apply (erule_tac [!] notE) apply (auto simp add: less_imp_le mult_left_mono mult_left_mono_neg) done text{*The ``conjunction of implication'' lemmas produce two cases when the comparison is a goal, but give four when the comparison is an assumption.*} lemma mult_less_cancel_right: "a * c < b * c \ (0 \ c \ a < b) \ (c \ 0 \ b < a)" using mult_less_cancel_right_disj [of a c b] by auto lemma mult_less_cancel_left: "c * a < c * b \ (0 \ c \ a < b) \ (c \ 0 \ b < a)" using mult_less_cancel_left_disj [of c a b] by auto lemma mult_le_cancel_right: "a * c \ b * c \ (0 < c \ a \ b) \ (c < 0 \ b \ a)" by (simp add: not_less [symmetric] mult_less_cancel_right_disj) lemma mult_le_cancel_left: "c * a \ c * b \ (0 < c \ a \ b) \ (c < 0 \ b \ a)" by (simp add: not_less [symmetric] mult_less_cancel_left_disj) lemma mult_le_cancel_left_pos: "0 < c \ c * a \ c * b \ a \ b" by (auto simp: mult_le_cancel_left) lemma mult_le_cancel_left_neg: "c < 0 \ c * a \ c * b \ b \ a" by (auto simp: mult_le_cancel_left) lemma mult_less_cancel_left_pos: "0 < c \ c * a < c * b \ a < b" by (auto simp: mult_less_cancel_left) lemma mult_less_cancel_left_neg: "c < 0 \ c * a < c * b \ b < a" by (auto simp: mult_less_cancel_left) end lemmas mult_sign_intros = mult_nonneg_nonneg mult_nonneg_nonpos mult_nonpos_nonneg mult_nonpos_nonpos mult_pos_pos mult_pos_neg mult_neg_pos mult_neg_neg class ordered_comm_ring = comm_ring + ordered_comm_semiring begin subclass ordered_ring .. subclass ordered_cancel_comm_semiring .. end class linordered_semidom = comm_semiring_1_cancel + linordered_comm_semiring_strict + (*previously linordered_semiring*) assumes zero_less_one [simp]: "0 < 1" begin lemma pos_add_strict: shows "0 < a \ b < c \ b < a + c" using add_strict_mono [of 0 a b c] by simp lemma zero_le_one [simp]: "0 \ 1" by (rule zero_less_one [THEN less_imp_le]) lemma not_one_le_zero [simp]: "\ 1 \ 0" by (simp add: not_le) lemma not_one_less_zero [simp]: "\ 1 < 0" by (simp add: not_less) lemma less_1_mult: assumes "1 < m" and "1 < n" shows "1 < m * n" using assms mult_strict_mono [of 1 m 1 n] by (simp add: less_trans [OF zero_less_one]) end class linordered_idom = comm_ring_1 + linordered_comm_semiring_strict + ordered_ab_group_add + abs_if + sgn_if (*previously linordered_ring*) begin subclass linordered_semiring_1_strict .. subclass linordered_ring_strict .. subclass ordered_comm_ring .. subclass idom .. subclass linordered_semidom proof have "0 \ 1 * 1" by (rule zero_le_square) thus "0 < 1" by (simp add: le_less) qed lemma linorder_neqE_linordered_idom: assumes "x \ y" obtains "x < y" | "y < x" using assms by (rule neqE) text {* These cancellation simprules also produce two cases when the comparison is a goal. *} lemma mult_le_cancel_right1: "c \ b * c \ (0 < c \ 1 \ b) \ (c < 0 \ b \ 1)" by (insert mult_le_cancel_right [of 1 c b], simp) lemma mult_le_cancel_right2: "a * c \ c \ (0 < c \ a \ 1) \ (c < 0 \ 1 \ a)" by (insert mult_le_cancel_right [of a c 1], simp) lemma mult_le_cancel_left1: "c \ c * b \ (0 < c \ 1 \ b) \ (c < 0 \ b \ 1)" by (insert mult_le_cancel_left [of c 1 b], simp) lemma mult_le_cancel_left2: "c * a \ c \ (0 < c \ a \ 1) \ (c < 0 \ 1 \ a)" by (insert mult_le_cancel_left [of c a 1], simp) lemma mult_less_cancel_right1: "c < b * c \ (0 \ c \ 1 < b) \ (c \ 0 \ b < 1)" by (insert mult_less_cancel_right [of 1 c b], simp) lemma mult_less_cancel_right2: "a * c < c \ (0 \ c \ a < 1) \ (c \ 0 \ 1 < a)" by (insert mult_less_cancel_right [of a c 1], simp) lemma mult_less_cancel_left1: "c < c * b \ (0 \ c \ 1 < b) \ (c \ 0 \ b < 1)" by (insert mult_less_cancel_left [of c 1 b], simp) lemma mult_less_cancel_left2: "c * a < c \ (0 \ c \ a < 1) \ (c \ 0 \ 1 < a)" by (insert mult_less_cancel_left [of c a 1], simp) lemma sgn_sgn [simp]: "sgn (sgn a) = sgn a" unfolding sgn_if by simp lemma sgn_0_0: "sgn a = 0 \ a = 0" unfolding sgn_if by simp lemma sgn_1_pos: "sgn a = 1 \ a > 0" unfolding sgn_if by simp lemma sgn_1_neg: "sgn a = - 1 \ a < 0" unfolding sgn_if by auto lemma sgn_pos [simp]: "0 < a \ sgn a = 1" unfolding sgn_1_pos . lemma sgn_neg [simp]: "a < 0 \ sgn a = - 1" unfolding sgn_1_neg . lemma sgn_times: "sgn (a * b) = sgn a * sgn b" by (auto simp add: sgn_if zero_less_mult_iff) lemma abs_sgn: "\k\ = k * sgn k" unfolding sgn_if abs_if by auto lemma sgn_greater [simp]: "0 < sgn a \ 0 < a" unfolding sgn_if by auto lemma sgn_less [simp]: "sgn a < 0 \ a < 0" unfolding sgn_if by auto lemma abs_dvd_iff [simp]: "\m\ dvd k \ m dvd k" by (simp add: abs_if) lemma dvd_abs_iff [simp]: "m dvd \k\ \ m dvd k" by (simp add: abs_if) lemma dvd_if_abs_eq: "\l\ = \k\ \ l dvd k" by(subst abs_dvd_iff[symmetric]) simp text {* The following lemmas can be proven in more general structures, but are dangerous as simp rules in absence of @{thm neg_equal_zero}, @{thm neg_less_pos}, @{thm neg_less_eq_nonneg}. *} lemma equation_minus_iff_1 [simp, no_atp]: "1 = - a \ a = - 1" by (fact equation_minus_iff) lemma minus_equation_iff_1 [simp, no_atp]: "- a = 1 \ a = - 1" by (subst minus_equation_iff, auto) lemma le_minus_iff_1 [simp, no_atp]: "1 \ - b \ b \ - 1" by (fact le_minus_iff) lemma minus_le_iff_1 [simp, no_atp]: "- a \ 1 \ - 1 \ a" by (fact minus_le_iff) lemma less_minus_iff_1 [simp, no_atp]: "1 < - b \ b < - 1" by (fact less_minus_iff) lemma minus_less_iff_1 [simp, no_atp]: "- a < 1 \ - 1 < a" by (fact minus_less_iff) end text {* Simprules for comparisons where common factors can be cancelled. *} lemmas mult_compare_simps = mult_le_cancel_right mult_le_cancel_left mult_le_cancel_right1 mult_le_cancel_right2 mult_le_cancel_left1 mult_le_cancel_left2 mult_less_cancel_right mult_less_cancel_left mult_less_cancel_right1 mult_less_cancel_right2 mult_less_cancel_left1 mult_less_cancel_left2 mult_cancel_right mult_cancel_left mult_cancel_right1 mult_cancel_right2 mult_cancel_left1 mult_cancel_left2 text {* Reasoning about inequalities with division *} context linordered_semidom begin lemma less_add_one: "a < a + 1" proof - have "a + 0 < a + 1" by (blast intro: zero_less_one add_strict_left_mono) thus ?thesis by simp qed lemma zero_less_two: "0 < 1 + 1" by (blast intro: less_trans zero_less_one less_add_one) end context linordered_idom begin lemma mult_right_le_one_le: "0 \ x \ 0 \ y \ y \ 1 \ x * y \ x" by (auto simp add: mult_le_cancel_left2) lemma mult_left_le_one_le: "0 \ x \ 0 \ y \ y \ 1 \ y * x \ x" by (auto simp add: mult_le_cancel_right2) end text {* Absolute Value *} context linordered_idom begin lemma mult_sgn_abs: "sgn x * \x\ = x" unfolding abs_if sgn_if by auto lemma abs_one [simp]: "\1\ = 1" by (simp add: abs_if) end class ordered_ring_abs = ordered_ring + ordered_ab_group_add_abs + assumes abs_eq_mult: "(0 \ a \ a \ 0) \ (0 \ b \ b \ 0) \ \a * b\ = \a\ * \b\" context linordered_idom begin subclass ordered_ring_abs proof qed (auto simp add: abs_if not_less mult_less_0_iff) lemma abs_mult: "\a * b\ = \a\ * \b\" by (rule abs_eq_mult) auto lemma abs_mult_self: "\a\ * \a\ = a * a" by (simp add: abs_if) lemma abs_mult_less: "\a\ < c \ \b\ < d \ \a\ * \b\ < c * d" proof - assume ac: "\a\ < c" hence cpos: "0b\ < d" thus ?thesis by (simp add: ac cpos mult_strict_mono) qed lemma abs_less_iff: "\a\ < b \ a < b \ - a < b" by (simp add: less_le abs_le_iff) (auto simp add: abs_if) lemma abs_mult_pos: "0 \ x \ \y\ * x = \y * x\" by (simp add: abs_mult) lemma abs_diff_less_iff: "\x - a\ < r \ a - r < x \ x < a + r" by (auto simp add: diff_less_eq ac_simps abs_less_iff) end code_identifier code_module Rings \ (SML) Arith and (OCaml) Arith and (Haskell) Arith end