haftmann@35050: (* Title: HOL/Rings.thy wenzelm@32960: Author: Gertrud Bauer wenzelm@32960: Author: Steven Obua wenzelm@32960: Author: Tobias Nipkow wenzelm@32960: Author: Lawrence C Paulson wenzelm@32960: Author: Markus Wenzel wenzelm@32960: Author: Jeremy Avigad paulson@14265: *) paulson@14265: haftmann@35050: header {* Rings *} paulson@14265: haftmann@35050: theory Rings haftmann@35050: imports Groups nipkow@15131: begin paulson@14504: obua@14738: text {* obua@14738: The theory of partially ordered rings is taken from the books: obua@14738: \begin{itemize} obua@14738: \item \emph{Lattice Theory} by Garret Birkhoff, American Mathematical Society 1979 obua@14738: \item \emph{Partially Ordered Algebraic Systems}, Pergamon Press 1963 obua@14738: \end{itemize} obua@14738: Most of the used notions can also be looked up in obua@14738: \begin{itemize} wenzelm@14770: \item \url{http://www.mathworld.com} by Eric Weisstein et. al. obua@14738: \item \emph{Algebra I} by van der Waerden, Springer. obua@14738: \end{itemize} obua@14738: *} paulson@14504: haftmann@22390: class semiring = ab_semigroup_add + semigroup_mult + nipkow@29667: assumes left_distrib[algebra_simps]: "(a + b) * c = a * c + b * c" nipkow@29667: assumes right_distrib[algebra_simps]: "a * (b + c) = a * b + a * c" haftmann@25152: begin haftmann@25152: haftmann@25152: text{*For the @{text combine_numerals} simproc*} haftmann@25152: lemma combine_common_factor: haftmann@25152: "a * e + (b * e + c) = (a + b) * e + c" nipkow@29667: by (simp add: left_distrib add_ac) haftmann@25152: haftmann@25152: end paulson@14504: haftmann@22390: class mult_zero = times + zero + haftmann@25062: assumes mult_zero_left [simp]: "0 * a = 0" haftmann@25062: assumes mult_zero_right [simp]: "a * 0 = 0" krauss@21199: haftmann@22390: class semiring_0 = semiring + comm_monoid_add + mult_zero krauss@21199: huffman@29904: class semiring_0_cancel = semiring + cancel_comm_monoid_add haftmann@25186: begin paulson@14504: haftmann@25186: subclass semiring_0 haftmann@28823: proof krauss@21199: fix a :: 'a nipkow@29667: have "0 * a + 0 * a = 0 * a + 0" by (simp add: left_distrib [symmetric]) nipkow@29667: thus "0 * a = 0" by (simp only: add_left_cancel) haftmann@25152: next haftmann@25152: fix a :: 'a nipkow@29667: have "a * 0 + a * 0 = a * 0 + 0" by (simp add: right_distrib [symmetric]) nipkow@29667: thus "a * 0 = 0" by (simp only: add_left_cancel) krauss@21199: qed obua@14940: haftmann@25186: end haftmann@25152: haftmann@22390: class comm_semiring = ab_semigroup_add + ab_semigroup_mult + haftmann@25062: assumes distrib: "(a + b) * c = a * c + b * c" haftmann@25152: begin paulson@14504: haftmann@25152: subclass semiring haftmann@28823: proof obua@14738: fix a b c :: 'a obua@14738: show "(a + b) * c = a * c + b * c" by (simp add: distrib) obua@14738: have "a * (b + c) = (b + c) * a" by (simp add: mult_ac) obua@14738: also have "... = b * a + c * a" by (simp only: distrib) obua@14738: also have "... = a * b + a * c" by (simp add: mult_ac) obua@14738: finally show "a * (b + c) = a * b + a * c" by blast paulson@14504: qed paulson@14504: haftmann@25152: end paulson@14504: haftmann@25152: class comm_semiring_0 = comm_semiring + comm_monoid_add + mult_zero haftmann@25152: begin haftmann@25152: huffman@27516: subclass semiring_0 .. haftmann@25152: haftmann@25152: end paulson@14504: huffman@29904: class comm_semiring_0_cancel = comm_semiring + cancel_comm_monoid_add haftmann@25186: begin obua@14940: huffman@27516: subclass semiring_0_cancel .. obua@14940: huffman@28141: subclass comm_semiring_0 .. huffman@28141: haftmann@25186: end krauss@21199: haftmann@22390: class zero_neq_one = zero + one + haftmann@25062: assumes zero_neq_one [simp]: "0 \ 1" haftmann@26193: begin haftmann@26193: haftmann@26193: lemma one_neq_zero [simp]: "1 \ 0" nipkow@29667: by (rule not_sym) (rule zero_neq_one) haftmann@26193: haftmann@26193: end paulson@14265: haftmann@22390: class semiring_1 = zero_neq_one + semiring_0 + monoid_mult paulson@14504: haftmann@27651: text {* Abstract divisibility *} haftmann@27651: haftmann@27651: class dvd = times haftmann@27651: begin haftmann@27651: haftmann@28559: definition dvd :: "'a \ 'a \ bool" (infixl "dvd" 50) where haftmann@28559: [code del]: "b dvd a \ (\k. a = b * k)" haftmann@27651: haftmann@27651: lemma dvdI [intro?]: "a = b * k \ b dvd a" haftmann@27651: unfolding dvd_def .. haftmann@27651: haftmann@27651: lemma dvdE [elim?]: "b dvd a \ (\k. a = b * k \ P) \ P" haftmann@27651: unfolding dvd_def by blast haftmann@27651: haftmann@27651: end haftmann@27651: haftmann@27651: class comm_semiring_1 = zero_neq_one + comm_semiring_0 + comm_monoid_mult + dvd haftmann@22390: (*previously almost_semiring*) haftmann@25152: begin obua@14738: huffman@27516: subclass semiring_1 .. haftmann@25152: nipkow@29925: lemma dvd_refl[simp]: "a dvd a" haftmann@28559: proof haftmann@28559: show "a = a * 1" by simp haftmann@27651: qed haftmann@27651: haftmann@27651: lemma dvd_trans: haftmann@27651: assumes "a dvd b" and "b dvd c" haftmann@27651: shows "a dvd c" haftmann@27651: proof - haftmann@28559: from assms obtain v where "b = a * v" by (auto elim!: dvdE) haftmann@28559: moreover from assms obtain w where "c = b * w" by (auto elim!: dvdE) haftmann@27651: ultimately have "c = a * (v * w)" by (simp add: mult_assoc) haftmann@28559: then show ?thesis .. haftmann@27651: qed haftmann@27651: haftmann@27651: lemma dvd_0_left_iff [noatp, simp]: "0 dvd a \ a = 0" nipkow@29667: by (auto intro: dvd_refl elim!: dvdE) haftmann@28559: haftmann@28559: lemma dvd_0_right [iff]: "a dvd 0" haftmann@28559: proof haftmann@27651: show "0 = a * 0" by simp haftmann@27651: qed haftmann@27651: haftmann@27651: lemma one_dvd [simp]: "1 dvd a" nipkow@29667: by (auto intro!: dvdI) haftmann@27651: nipkow@30042: lemma dvd_mult[simp]: "a dvd c \ a dvd (b * c)" nipkow@29667: by (auto intro!: mult_left_commute dvdI elim!: dvdE) haftmann@27651: nipkow@30042: lemma dvd_mult2[simp]: "a dvd b \ a dvd (b * c)" haftmann@27651: apply (subst mult_commute) haftmann@27651: apply (erule dvd_mult) haftmann@27651: done haftmann@27651: haftmann@27651: lemma dvd_triv_right [simp]: "a dvd b * a" nipkow@29667: by (rule dvd_mult) (rule dvd_refl) haftmann@27651: haftmann@27651: lemma dvd_triv_left [simp]: "a dvd a * b" nipkow@29667: by (rule dvd_mult2) (rule dvd_refl) haftmann@27651: haftmann@27651: lemma mult_dvd_mono: nipkow@30042: assumes "a dvd b" nipkow@30042: and "c dvd d" haftmann@27651: shows "a * c dvd b * d" haftmann@27651: proof - nipkow@30042: from `a dvd b` obtain b' where "b = a * b'" .. nipkow@30042: moreover from `c dvd d` obtain d' where "d = c * d'" .. haftmann@27651: ultimately have "b * d = (a * c) * (b' * d')" by (simp add: mult_ac) haftmann@27651: then show ?thesis .. haftmann@27651: qed haftmann@27651: haftmann@27651: lemma dvd_mult_left: "a * b dvd c \ a dvd c" nipkow@29667: by (simp add: dvd_def mult_assoc, blast) haftmann@27651: haftmann@27651: lemma dvd_mult_right: "a * b dvd c \ b dvd c" haftmann@27651: unfolding mult_ac [of a] by (rule dvd_mult_left) haftmann@27651: haftmann@27651: lemma dvd_0_left: "0 dvd a \ a = 0" nipkow@29667: by simp haftmann@27651: nipkow@29925: lemma dvd_add[simp]: nipkow@29925: assumes "a dvd b" and "a dvd c" shows "a dvd (b + c)" haftmann@27651: proof - nipkow@29925: from `a dvd b` obtain b' where "b = a * b'" .. nipkow@29925: moreover from `a dvd c` obtain c' where "c = a * c'" .. haftmann@27651: ultimately have "b + c = a * (b' + c')" by (simp add: right_distrib) haftmann@27651: then show ?thesis .. haftmann@27651: qed haftmann@27651: haftmann@25152: end paulson@14421: nipkow@29925: haftmann@22390: class no_zero_divisors = zero + times + haftmann@25062: assumes no_zero_divisors: "a \ 0 \ b \ 0 \ a * b \ 0" paulson@14504: huffman@29904: class semiring_1_cancel = semiring + cancel_comm_monoid_add huffman@29904: + zero_neq_one + monoid_mult haftmann@25267: begin obua@14940: huffman@27516: subclass semiring_0_cancel .. haftmann@25512: huffman@27516: subclass semiring_1 .. haftmann@25267: haftmann@25267: end krauss@21199: huffman@29904: class comm_semiring_1_cancel = comm_semiring + cancel_comm_monoid_add huffman@29904: + zero_neq_one + comm_monoid_mult haftmann@25267: begin obua@14738: huffman@27516: subclass semiring_1_cancel .. huffman@27516: subclass comm_semiring_0_cancel .. huffman@27516: subclass comm_semiring_1 .. haftmann@25267: haftmann@25267: end haftmann@25152: haftmann@22390: class ring = semiring + ab_group_add haftmann@25267: begin haftmann@25152: huffman@27516: subclass semiring_0_cancel .. haftmann@25152: haftmann@25152: text {* Distribution rules *} haftmann@25152: haftmann@25152: lemma minus_mult_left: "- (a * b) = - a * b" huffman@34146: by (rule minus_unique) (simp add: left_distrib [symmetric]) haftmann@25152: haftmann@25152: lemma minus_mult_right: "- (a * b) = a * - b" huffman@34146: by (rule minus_unique) (simp add: right_distrib [symmetric]) haftmann@25152: huffman@29407: text{*Extract signs from products*} nipkow@29833: lemmas mult_minus_left [simp, noatp] = minus_mult_left [symmetric] nipkow@29833: lemmas mult_minus_right [simp,noatp] = minus_mult_right [symmetric] huffman@29407: haftmann@25152: lemma minus_mult_minus [simp]: "- a * - b = a * b" nipkow@29667: by simp haftmann@25152: haftmann@25152: lemma minus_mult_commute: "- a * b = a * - b" nipkow@29667: by simp nipkow@29667: nipkow@29667: lemma right_diff_distrib[algebra_simps]: "a * (b - c) = a * b - a * c" nipkow@29667: by (simp add: right_distrib diff_minus) nipkow@29667: nipkow@29667: lemma left_diff_distrib[algebra_simps]: "(a - b) * c = a * c - b * c" nipkow@29667: by (simp add: left_distrib diff_minus) haftmann@25152: nipkow@29833: lemmas ring_distribs[noatp] = haftmann@25152: right_distrib left_distrib left_diff_distrib right_diff_distrib haftmann@25152: nipkow@29667: text{*Legacy - use @{text algebra_simps} *} nipkow@29833: lemmas ring_simps[noatp] = algebra_simps haftmann@25230: haftmann@25230: lemma eq_add_iff1: haftmann@25230: "a * e + c = b * e + d \ (a - b) * e + c = d" nipkow@29667: by (simp add: algebra_simps) haftmann@25230: haftmann@25230: lemma eq_add_iff2: haftmann@25230: "a * e + c = b * e + d \ c = (b - a) * e + d" nipkow@29667: by (simp add: algebra_simps) haftmann@25230: haftmann@25152: end haftmann@25152: nipkow@29833: lemmas ring_distribs[noatp] = haftmann@25152: right_distrib left_distrib left_diff_distrib right_diff_distrib haftmann@25152: haftmann@22390: class comm_ring = comm_semiring + ab_group_add haftmann@25267: begin obua@14738: huffman@27516: subclass ring .. huffman@28141: subclass comm_semiring_0_cancel .. haftmann@25267: haftmann@25267: end obua@14738: haftmann@22390: class ring_1 = ring + zero_neq_one + monoid_mult haftmann@25267: begin paulson@14265: huffman@27516: subclass semiring_1_cancel .. haftmann@25267: haftmann@25267: end haftmann@25152: haftmann@22390: class comm_ring_1 = comm_ring + zero_neq_one + comm_monoid_mult haftmann@22390: (*previously ring*) haftmann@25267: begin obua@14738: huffman@27516: subclass ring_1 .. huffman@27516: subclass comm_semiring_1_cancel .. haftmann@25267: huffman@29465: lemma dvd_minus_iff [simp]: "x dvd - y \ x dvd y" huffman@29408: proof huffman@29408: assume "x dvd - y" huffman@29408: then have "x dvd - 1 * - y" by (rule dvd_mult) huffman@29408: then show "x dvd y" by simp huffman@29408: next huffman@29408: assume "x dvd y" huffman@29408: then have "x dvd - 1 * y" by (rule dvd_mult) huffman@29408: then show "x dvd - y" by simp huffman@29408: qed huffman@29408: huffman@29465: lemma minus_dvd_iff [simp]: "- x dvd y \ x dvd y" huffman@29408: proof huffman@29408: assume "- x dvd y" huffman@29408: then obtain k where "y = - x * k" .. huffman@29408: then have "y = x * - k" by simp huffman@29408: then show "x dvd y" .. huffman@29408: next huffman@29408: assume "x dvd y" huffman@29408: then obtain k where "y = x * k" .. huffman@29408: then have "y = - x * - k" by simp huffman@29408: then show "- x dvd y" .. huffman@29408: qed huffman@29408: nipkow@30042: lemma dvd_diff[simp]: "x dvd y \ x dvd z \ x dvd (y - z)" nipkow@30042: by (simp add: diff_minus dvd_minus_iff) huffman@29409: haftmann@25267: end haftmann@25152: huffman@22990: class ring_no_zero_divisors = ring + no_zero_divisors haftmann@25230: begin haftmann@25230: haftmann@25230: lemma mult_eq_0_iff [simp]: haftmann@25230: shows "a * b = 0 \ (a = 0 \ b = 0)" haftmann@25230: proof (cases "a = 0 \ b = 0") haftmann@25230: case False then have "a \ 0" and "b \ 0" by auto haftmann@25230: then show ?thesis using no_zero_divisors by simp haftmann@25230: next haftmann@25230: case True then show ?thesis by auto haftmann@25230: qed haftmann@25230: haftmann@26193: text{*Cancellation of equalities with a common factor*} haftmann@26193: lemma mult_cancel_right [simp, noatp]: haftmann@26193: "a * c = b * c \ c = 0 \ a = b" haftmann@26193: proof - haftmann@26193: have "(a * c = b * c) = ((a - b) * c = 0)" nipkow@29667: by (simp add: algebra_simps right_minus_eq) nipkow@29667: thus ?thesis by (simp add: disj_commute right_minus_eq) haftmann@26193: qed haftmann@26193: haftmann@26193: lemma mult_cancel_left [simp, noatp]: haftmann@26193: "c * a = c * b \ c = 0 \ a = b" haftmann@26193: proof - haftmann@26193: have "(c * a = c * b) = (c * (a - b) = 0)" nipkow@29667: by (simp add: algebra_simps right_minus_eq) nipkow@29667: thus ?thesis by (simp add: right_minus_eq) haftmann@26193: qed haftmann@26193: haftmann@25230: end huffman@22990: huffman@23544: class ring_1_no_zero_divisors = ring_1 + ring_no_zero_divisors haftmann@26274: begin haftmann@26274: haftmann@26274: lemma mult_cancel_right1 [simp]: haftmann@26274: "c = b * c \ c = 0 \ b = 1" nipkow@29667: by (insert mult_cancel_right [of 1 c b], force) haftmann@26274: haftmann@26274: lemma mult_cancel_right2 [simp]: haftmann@26274: "a * c = c \ c = 0 \ a = 1" nipkow@29667: by (insert mult_cancel_right [of a c 1], simp) haftmann@26274: haftmann@26274: lemma mult_cancel_left1 [simp]: haftmann@26274: "c = c * b \ c = 0 \ b = 1" nipkow@29667: by (insert mult_cancel_left [of c 1 b], force) haftmann@26274: haftmann@26274: lemma mult_cancel_left2 [simp]: haftmann@26274: "c * a = c \ c = 0 \ a = 1" nipkow@29667: by (insert mult_cancel_left [of c a 1], simp) haftmann@26274: haftmann@26274: end huffman@22990: haftmann@22390: class idom = comm_ring_1 + no_zero_divisors haftmann@25186: begin paulson@14421: huffman@27516: subclass ring_1_no_zero_divisors .. huffman@22990: huffman@29915: lemma square_eq_iff: "a * a = b * b \ (a = b \ a = - b)" huffman@29915: proof huffman@29915: assume "a * a = b * b" huffman@29915: then have "(a - b) * (a + b) = 0" huffman@29915: by (simp add: algebra_simps) huffman@29915: then show "a = b \ a = - b" huffman@29915: by (simp add: right_minus_eq eq_neg_iff_add_eq_0) huffman@29915: next huffman@29915: assume "a = b \ a = - b" huffman@29915: then show "a * a = b * b" by auto huffman@29915: qed huffman@29915: huffman@29981: lemma dvd_mult_cancel_right [simp]: huffman@29981: "a * c dvd b * c \ c = 0 \ a dvd b" huffman@29981: proof - huffman@29981: have "a * c dvd b * c \ (\k. b * c = (a * k) * c)" huffman@29981: unfolding dvd_def by (simp add: mult_ac) huffman@29981: also have "(\k. b * c = (a * k) * c) \ c = 0 \ a dvd b" huffman@29981: unfolding dvd_def by simp huffman@29981: finally show ?thesis . huffman@29981: qed huffman@29981: huffman@29981: lemma dvd_mult_cancel_left [simp]: huffman@29981: "c * a dvd c * b \ c = 0 \ a dvd b" huffman@29981: proof - huffman@29981: have "c * a dvd c * b \ (\k. b * c = (a * k) * c)" huffman@29981: unfolding dvd_def by (simp add: mult_ac) huffman@29981: also have "(\k. b * c = (a * k) * c) \ c = 0 \ a dvd b" huffman@29981: unfolding dvd_def by simp huffman@29981: finally show ?thesis . huffman@29981: qed huffman@29981: haftmann@25186: end haftmann@25152: haftmann@22390: class division_ring = ring_1 + inverse + haftmann@25062: assumes left_inverse [simp]: "a \ 0 \ inverse a * a = 1" haftmann@25062: assumes right_inverse [simp]: "a \ 0 \ a * inverse a = 1" haftmann@25186: begin huffman@20496: haftmann@25186: subclass ring_1_no_zero_divisors haftmann@28823: proof huffman@22987: fix a b :: 'a huffman@22987: assume a: "a \ 0" and b: "b \ 0" huffman@22987: show "a * b \ 0" huffman@22987: proof huffman@22987: assume ab: "a * b = 0" nipkow@29667: hence "0 = inverse a * (a * b) * inverse b" by simp huffman@22987: also have "\ = (inverse a * a) * (b * inverse b)" huffman@22987: by (simp only: mult_assoc) nipkow@29667: also have "\ = 1" using a b by simp nipkow@29667: finally show False by simp huffman@22987: qed huffman@22987: qed huffman@20496: haftmann@26274: lemma nonzero_imp_inverse_nonzero: haftmann@26274: "a \ 0 \ inverse a \ 0" haftmann@26274: proof haftmann@26274: assume ianz: "inverse a = 0" haftmann@26274: assume "a \ 0" haftmann@26274: hence "1 = a * inverse a" by simp haftmann@26274: also have "... = 0" by (simp add: ianz) haftmann@26274: finally have "1 = 0" . haftmann@26274: thus False by (simp add: eq_commute) haftmann@26274: qed haftmann@26274: haftmann@26274: lemma inverse_zero_imp_zero: haftmann@26274: "inverse a = 0 \ a = 0" haftmann@26274: apply (rule classical) haftmann@26274: apply (drule nonzero_imp_inverse_nonzero) haftmann@26274: apply auto haftmann@26274: done haftmann@26274: haftmann@26274: lemma inverse_unique: haftmann@26274: assumes ab: "a * b = 1" haftmann@26274: shows "inverse a = b" haftmann@26274: proof - haftmann@26274: have "a \ 0" using ab by (cases "a = 0") simp_all huffman@29406: moreover have "inverse a * (a * b) = inverse a" by (simp add: ab) huffman@29406: ultimately show ?thesis by (simp add: mult_assoc [symmetric]) haftmann@26274: qed haftmann@26274: huffman@29406: lemma nonzero_inverse_minus_eq: huffman@29406: "a \ 0 \ inverse (- a) = - inverse a" nipkow@29667: by (rule inverse_unique) simp huffman@29406: huffman@29406: lemma nonzero_inverse_inverse_eq: huffman@29406: "a \ 0 \ inverse (inverse a) = a" nipkow@29667: by (rule inverse_unique) simp huffman@29406: huffman@29406: lemma nonzero_inverse_eq_imp_eq: huffman@29406: assumes "inverse a = inverse b" and "a \ 0" and "b \ 0" huffman@29406: shows "a = b" huffman@29406: proof - huffman@29406: from `inverse a = inverse b` nipkow@29667: have "inverse (inverse a) = inverse (inverse b)" by (rule arg_cong) huffman@29406: with `a \ 0` and `b \ 0` show "a = b" huffman@29406: by (simp add: nonzero_inverse_inverse_eq) huffman@29406: qed huffman@29406: huffman@29406: lemma inverse_1 [simp]: "inverse 1 = 1" nipkow@29667: by (rule inverse_unique) simp huffman@29406: haftmann@26274: lemma nonzero_inverse_mult_distrib: huffman@29406: assumes "a \ 0" and "b \ 0" haftmann@26274: shows "inverse (a * b) = inverse b * inverse a" haftmann@26274: proof - nipkow@29667: have "a * (b * inverse b) * inverse a = 1" using assms by simp nipkow@29667: hence "a * b * (inverse b * inverse a) = 1" by (simp only: mult_assoc) nipkow@29667: thus ?thesis by (rule inverse_unique) haftmann@26274: qed haftmann@26274: haftmann@26274: lemma division_ring_inverse_add: haftmann@26274: "a \ 0 \ b \ 0 \ inverse a + inverse b = inverse a * (a + b) * inverse b" nipkow@29667: by (simp add: algebra_simps) haftmann@26274: haftmann@26274: lemma division_ring_inverse_diff: haftmann@26274: "a \ 0 \ b \ 0 \ inverse a - inverse b = inverse a * (b - a) * inverse b" nipkow@29667: by (simp add: algebra_simps) haftmann@26274: haftmann@25186: end haftmann@25152: haftmann@22390: class mult_mono = times + zero + ord + haftmann@25062: assumes mult_left_mono: "a \ b \ 0 \ c \ c * a \ c * b" haftmann@25062: assumes mult_right_mono: "a \ b \ 0 \ c \ a * c \ b * c" paulson@14267: haftmann@35028: class ordered_semiring = mult_mono + semiring_0 + ordered_ab_semigroup_add haftmann@25230: begin haftmann@25230: haftmann@25230: lemma mult_mono: haftmann@25230: "a \ b \ c \ d \ 0 \ b \ 0 \ c haftmann@25230: \ a * c \ b * d" haftmann@25230: apply (erule mult_right_mono [THEN order_trans], assumption) haftmann@25230: apply (erule mult_left_mono, assumption) haftmann@25230: done haftmann@25230: haftmann@25230: lemma mult_mono': haftmann@25230: "a \ b \ c \ d \ 0 \ a \ 0 \ c haftmann@25230: \ a * c \ b * d" haftmann@25230: apply (rule mult_mono) haftmann@25230: apply (fast intro: order_trans)+ haftmann@25230: done haftmann@25230: haftmann@25230: end krauss@21199: haftmann@35028: class ordered_cancel_semiring = mult_mono + ordered_ab_semigroup_add huffman@29904: + semiring + cancel_comm_monoid_add haftmann@25267: begin paulson@14268: huffman@27516: subclass semiring_0_cancel .. haftmann@35028: subclass ordered_semiring .. obua@23521: haftmann@25230: lemma mult_nonneg_nonneg: "0 \ a \ 0 \ b \ 0 \ a * b" huffman@30692: using mult_left_mono [of zero b a] by simp haftmann@25230: haftmann@25230: lemma mult_nonneg_nonpos: "0 \ a \ b \ 0 \ a * b \ 0" huffman@30692: using mult_left_mono [of b zero a] by simp huffman@30692: huffman@30692: lemma mult_nonpos_nonneg: "a \ 0 \ 0 \ b \ a * b \ 0" huffman@30692: using mult_right_mono [of a zero b] by simp huffman@30692: huffman@30692: text {* Legacy - use @{text mult_nonpos_nonneg} *} haftmann@25230: lemma mult_nonneg_nonpos2: "0 \ a \ b \ 0 \ b * a \ 0" nipkow@29667: by (drule mult_right_mono [of b zero], auto) haftmann@25230: haftmann@26234: lemma split_mult_neg_le: "(0 \ a & b \ 0) | (a \ 0 & 0 \ b) \ a * b \ 0" nipkow@29667: by (auto simp add: mult_nonneg_nonpos mult_nonneg_nonpos2) haftmann@25230: haftmann@25230: end haftmann@25230: haftmann@35028: class linordered_semiring = semiring + comm_monoid_add + linordered_cancel_ab_semigroup_add + mult_mono haftmann@25267: begin haftmann@25230: haftmann@35028: subclass ordered_cancel_semiring .. haftmann@35028: haftmann@35028: subclass ordered_comm_monoid_add .. haftmann@25304: haftmann@25230: lemma mult_left_less_imp_less: haftmann@25230: "c * a < c * b \ 0 \ c \ a < b" nipkow@29667: by (force simp add: mult_left_mono not_le [symmetric]) haftmann@25230: haftmann@25230: lemma mult_right_less_imp_less: haftmann@25230: "a * c < b * c \ 0 \ c \ a < b" nipkow@29667: by (force simp add: mult_right_mono not_le [symmetric]) obua@23521: haftmann@25186: end haftmann@25152: haftmann@35043: class linordered_semiring_1 = linordered_semiring + semiring_1 haftmann@35043: haftmann@35043: class linordered_semiring_strict = semiring + comm_monoid_add + linordered_cancel_ab_semigroup_add + haftmann@25062: assumes mult_strict_left_mono: "a < b \ 0 < c \ c * a < c * b" haftmann@25062: assumes mult_strict_right_mono: "a < b \ 0 < c \ a * c < b * c" haftmann@25267: begin paulson@14341: huffman@27516: subclass semiring_0_cancel .. obua@14940: haftmann@35028: subclass linordered_semiring haftmann@28823: proof huffman@23550: fix a b c :: 'a huffman@23550: assume A: "a \ b" "0 \ c" huffman@23550: from A show "c * a \ c * b" haftmann@25186: unfolding le_less haftmann@25186: using mult_strict_left_mono by (cases "c = 0") auto huffman@23550: from A show "a * c \ b * c" haftmann@25152: unfolding le_less haftmann@25186: using mult_strict_right_mono by (cases "c = 0") auto haftmann@25152: qed haftmann@25152: haftmann@25230: lemma mult_left_le_imp_le: haftmann@25230: "c * a \ c * b \ 0 < c \ a \ b" nipkow@29667: by (force simp add: mult_strict_left_mono _not_less [symmetric]) haftmann@25230: haftmann@25230: lemma mult_right_le_imp_le: haftmann@25230: "a * c \ b * c \ 0 < c \ a \ b" nipkow@29667: by (force simp add: mult_strict_right_mono not_less [symmetric]) haftmann@25230: huffman@30692: lemma mult_pos_pos: "0 < a \ 0 < b \ 0 < a * b" huffman@30692: using mult_strict_left_mono [of zero b a] by simp huffman@30692: huffman@30692: lemma mult_pos_neg: "0 < a \ b < 0 \ a * b < 0" huffman@30692: using mult_strict_left_mono [of b zero a] by simp huffman@30692: huffman@30692: lemma mult_neg_pos: "a < 0 \ 0 < b \ a * b < 0" huffman@30692: using mult_strict_right_mono [of a zero b] by simp huffman@30692: huffman@30692: text {* Legacy - use @{text mult_neg_pos} *} huffman@30692: lemma mult_pos_neg2: "0 < a \ b < 0 \ b * a < 0" nipkow@29667: by (drule mult_strict_right_mono [of b zero], auto) haftmann@25230: haftmann@25230: lemma zero_less_mult_pos: haftmann@25230: "0 < a * b \ 0 < a \ 0 < b" huffman@30692: apply (cases "b\0") haftmann@25230: apply (auto simp add: le_less not_less) huffman@30692: apply (drule_tac mult_pos_neg [of a b]) haftmann@25230: apply (auto dest: less_not_sym) haftmann@25230: done haftmann@25230: haftmann@25230: lemma zero_less_mult_pos2: haftmann@25230: "0 < b * a \ 0 < a \ 0 < b" huffman@30692: apply (cases "b\0") haftmann@25230: apply (auto simp add: le_less not_less) huffman@30692: apply (drule_tac mult_pos_neg2 [of a b]) haftmann@25230: apply (auto dest: less_not_sym) haftmann@25230: done haftmann@25230: haftmann@26193: text{*Strict monotonicity in both arguments*} haftmann@26193: lemma mult_strict_mono: haftmann@26193: assumes "a < b" and "c < d" and "0 < b" and "0 \ c" haftmann@26193: shows "a * c < b * d" haftmann@26193: using assms apply (cases "c=0") huffman@30692: apply (simp add: mult_pos_pos) haftmann@26193: apply (erule mult_strict_right_mono [THEN less_trans]) huffman@30692: apply (force simp add: le_less) haftmann@26193: apply (erule mult_strict_left_mono, assumption) haftmann@26193: done haftmann@26193: haftmann@26193: text{*This weaker variant has more natural premises*} haftmann@26193: lemma mult_strict_mono': haftmann@26193: assumes "a < b" and "c < d" and "0 \ a" and "0 \ c" haftmann@26193: shows "a * c < b * d" nipkow@29667: by (rule mult_strict_mono) (insert assms, auto) haftmann@26193: haftmann@26193: lemma mult_less_le_imp_less: haftmann@26193: assumes "a < b" and "c \ d" and "0 \ a" and "0 < c" haftmann@26193: shows "a * c < b * d" haftmann@26193: using assms apply (subgoal_tac "a * c < b * c") haftmann@26193: apply (erule less_le_trans) haftmann@26193: apply (erule mult_left_mono) haftmann@26193: apply simp haftmann@26193: apply (erule mult_strict_right_mono) haftmann@26193: apply assumption haftmann@26193: done haftmann@26193: haftmann@26193: lemma mult_le_less_imp_less: haftmann@26193: assumes "a \ b" and "c < d" and "0 < a" and "0 \ c" haftmann@26193: shows "a * c < b * d" haftmann@26193: using assms apply (subgoal_tac "a * c \ b * c") haftmann@26193: apply (erule le_less_trans) haftmann@26193: apply (erule mult_strict_left_mono) haftmann@26193: apply simp haftmann@26193: apply (erule mult_right_mono) haftmann@26193: apply simp haftmann@26193: done haftmann@26193: haftmann@26193: lemma mult_less_imp_less_left: haftmann@26193: assumes less: "c * a < c * b" and nonneg: "0 \ c" haftmann@26193: shows "a < b" haftmann@26193: proof (rule ccontr) haftmann@26193: assume "\ a < b" haftmann@26193: hence "b \ a" by (simp add: linorder_not_less) haftmann@26193: hence "c * b \ c * a" using nonneg by (rule mult_left_mono) nipkow@29667: with this and less show False by (simp add: not_less [symmetric]) haftmann@26193: qed haftmann@26193: haftmann@26193: lemma mult_less_imp_less_right: haftmann@26193: assumes less: "a * c < b * c" and nonneg: "0 \ c" haftmann@26193: shows "a < b" haftmann@26193: proof (rule ccontr) haftmann@26193: assume "\ a < b" haftmann@26193: hence "b \ a" by (simp add: linorder_not_less) haftmann@26193: hence "b * c \ a * c" using nonneg by (rule mult_right_mono) nipkow@29667: with this and less show False by (simp add: not_less [symmetric]) haftmann@26193: qed haftmann@26193: haftmann@25230: end haftmann@25230: haftmann@35043: class linlinordered_semiring_1_strict = linordered_semiring_strict + semiring_1 haftmann@33319: haftmann@22390: class mult_mono1 = times + zero + ord + haftmann@25230: assumes mult_mono1: "a \ b \ 0 \ c \ c * a \ c * b" paulson@14270: haftmann@35028: class ordered_comm_semiring = comm_semiring_0 haftmann@35028: + ordered_ab_semigroup_add + mult_mono1 haftmann@25186: begin haftmann@25152: haftmann@35028: subclass ordered_semiring haftmann@28823: proof krauss@21199: fix a b c :: 'a huffman@23550: assume "a \ b" "0 \ c" haftmann@25230: thus "c * a \ c * b" by (rule mult_mono1) huffman@23550: thus "a * c \ b * c" by (simp only: mult_commute) krauss@21199: qed paulson@14265: haftmann@25267: end haftmann@25267: haftmann@35028: class ordered_cancel_comm_semiring = comm_semiring_0_cancel haftmann@35028: + ordered_ab_semigroup_add + mult_mono1 haftmann@25267: begin paulson@14265: haftmann@35028: subclass ordered_comm_semiring .. haftmann@35028: subclass ordered_cancel_semiring .. haftmann@25267: haftmann@25267: end haftmann@25267: haftmann@35028: class linordered_comm_semiring_strict = comm_semiring_0 + linordered_cancel_ab_semigroup_add + haftmann@26193: assumes mult_strict_left_mono_comm: "a < b \ 0 < c \ c * a < c * b" haftmann@25267: begin haftmann@25267: haftmann@35043: subclass linordered_semiring_strict haftmann@28823: proof huffman@23550: fix a b c :: 'a huffman@23550: assume "a < b" "0 < c" haftmann@26193: thus "c * a < c * b" by (rule mult_strict_left_mono_comm) huffman@23550: thus "a * c < b * c" by (simp only: mult_commute) huffman@23550: qed paulson@14272: haftmann@35028: subclass ordered_cancel_comm_semiring haftmann@28823: proof huffman@23550: fix a b c :: 'a huffman@23550: assume "a \ b" "0 \ c" huffman@23550: thus "c * a \ c * b" haftmann@25186: unfolding le_less haftmann@26193: using mult_strict_left_mono by (cases "c = 0") auto huffman@23550: qed paulson@14272: haftmann@25267: end haftmann@25230: haftmann@35028: class ordered_ring = ring + ordered_cancel_semiring haftmann@25267: begin haftmann@25230: haftmann@35028: subclass ordered_ab_group_add .. paulson@14270: nipkow@29667: text{*Legacy - use @{text algebra_simps} *} nipkow@29833: lemmas ring_simps[noatp] = algebra_simps haftmann@25230: haftmann@25230: lemma less_add_iff1: haftmann@25230: "a * e + c < b * e + d \ (a - b) * e + c < d" nipkow@29667: by (simp add: algebra_simps) haftmann@25230: haftmann@25230: lemma less_add_iff2: haftmann@25230: "a * e + c < b * e + d \ c < (b - a) * e + d" nipkow@29667: by (simp add: algebra_simps) haftmann@25230: haftmann@25230: lemma le_add_iff1: haftmann@25230: "a * e + c \ b * e + d \ (a - b) * e + c \ d" nipkow@29667: by (simp add: algebra_simps) haftmann@25230: haftmann@25230: lemma le_add_iff2: haftmann@25230: "a * e + c \ b * e + d \ c \ (b - a) * e + d" nipkow@29667: by (simp add: algebra_simps) haftmann@25230: haftmann@25230: lemma mult_left_mono_neg: haftmann@25230: "b \ a \ c \ 0 \ c * a \ c * b" haftmann@25230: apply (drule mult_left_mono [of _ _ "uminus c"]) haftmann@25230: apply (simp_all add: minus_mult_left [symmetric]) haftmann@25230: done haftmann@25230: haftmann@25230: lemma mult_right_mono_neg: haftmann@25230: "b \ a \ c \ 0 \ a * c \ b * c" haftmann@25230: apply (drule mult_right_mono [of _ _ "uminus c"]) haftmann@25230: apply (simp_all add: minus_mult_right [symmetric]) haftmann@25230: done haftmann@25230: huffman@30692: lemma mult_nonpos_nonpos: "a \ 0 \ b \ 0 \ 0 \ a * b" huffman@30692: using mult_right_mono_neg [of a zero b] by simp haftmann@25230: haftmann@25230: lemma split_mult_pos_le: haftmann@25230: "(0 \ a \ 0 \ b) \ (a \ 0 \ b \ 0) \ 0 \ a * b" nipkow@29667: by (auto simp add: mult_nonneg_nonneg mult_nonpos_nonpos) haftmann@25186: haftmann@25186: end paulson@14270: haftmann@25762: class abs_if = minus + uminus + ord + zero + abs + haftmann@25762: assumes abs_if: "\a\ = (if a < 0 then - a else a)" haftmann@25762: haftmann@25762: class sgn_if = minus + uminus + zero + one + ord + sgn + haftmann@25186: assumes sgn_if: "sgn x = (if x = 0 then 0 else if 0 < x then 1 else - 1)" nipkow@24506: nipkow@25564: lemma (in sgn_if) sgn0[simp]: "sgn 0 = 0" nipkow@25564: by(simp add:sgn_if) nipkow@25564: haftmann@35028: class linordered_ring = ring + linordered_semiring + linordered_ab_group_add + abs_if haftmann@25304: begin haftmann@25304: haftmann@35028: subclass ordered_ring .. haftmann@35028: haftmann@35028: subclass ordered_ab_group_add_abs haftmann@28823: proof haftmann@25304: fix a b haftmann@25304: show "\a + b\ \ \a\ + \b\" haftmann@35028: by (auto simp add: abs_if not_less neg_less_eq_nonneg less_eq_neg_nonpos) haftmann@35028: (auto simp del: minus_add_distrib simp add: minus_add_distrib [symmetric] haftmann@25304: neg_less_eq_nonneg less_eq_neg_nonpos, auto intro: add_nonneg_nonneg, haftmann@25304: auto intro!: less_imp_le add_neg_neg) haftmann@25304: qed (auto simp add: abs_if less_eq_neg_nonpos neg_equal_zero) haftmann@25304: haftmann@25304: end obua@23521: haftmann@35028: (* The "strict" suffix can be seen as describing the combination of linordered_ring and no_zero_divisors. haftmann@35043: Basically, linordered_ring + no_zero_divisors = linordered_ring_strict. haftmann@25230: *) haftmann@35043: class linordered_ring_strict = ring + linordered_semiring_strict haftmann@25304: + ordered_ab_group_add + abs_if haftmann@25230: begin paulson@14348: haftmann@35028: subclass linordered_ring .. haftmann@25304: huffman@30692: lemma mult_strict_left_mono_neg: "b < a \ c < 0 \ c * a < c * b" huffman@30692: using mult_strict_left_mono [of b a "- c"] by simp huffman@30692: huffman@30692: lemma mult_strict_right_mono_neg: "b < a \ c < 0 \ a * c < b * c" huffman@30692: using mult_strict_right_mono [of b a "- c"] by simp huffman@30692: huffman@30692: lemma mult_neg_neg: "a < 0 \ b < 0 \ 0 < a * b" huffman@30692: using mult_strict_right_mono_neg [of a zero b] by simp obua@14738: haftmann@25917: subclass ring_no_zero_divisors haftmann@28823: proof haftmann@25917: fix a b haftmann@25917: assume "a \ 0" then have A: "a < 0 \ 0 < a" by (simp add: neq_iff) haftmann@25917: assume "b \ 0" then have B: "b < 0 \ 0 < b" by (simp add: neq_iff) haftmann@25917: have "a * b < 0 \ 0 < a * b" haftmann@25917: proof (cases "a < 0") haftmann@25917: case True note A' = this haftmann@25917: show ?thesis proof (cases "b < 0") haftmann@25917: case True with A' haftmann@25917: show ?thesis by (auto dest: mult_neg_neg) haftmann@25917: next haftmann@25917: case False with B have "0 < b" by auto haftmann@25917: with A' show ?thesis by (auto dest: mult_strict_right_mono) haftmann@25917: qed haftmann@25917: next haftmann@25917: case False with A have A': "0 < a" by auto haftmann@25917: show ?thesis proof (cases "b < 0") haftmann@25917: case True with A' haftmann@25917: show ?thesis by (auto dest: mult_strict_right_mono_neg) haftmann@25917: next haftmann@25917: case False with B have "0 < b" by auto haftmann@25917: with A' show ?thesis by (auto dest: mult_pos_pos) haftmann@25917: qed haftmann@25917: qed haftmann@25917: then show "a * b \ 0" by (simp add: neq_iff) haftmann@25917: qed haftmann@25304: paulson@14265: lemma zero_less_mult_iff: haftmann@25917: "0 < a * b \ 0 < a \ 0 < b \ a < 0 \ b < 0" haftmann@25917: apply (auto simp add: mult_pos_pos mult_neg_neg) haftmann@25917: apply (simp_all add: not_less le_less) haftmann@25917: apply (erule disjE) apply assumption defer haftmann@25917: apply (erule disjE) defer apply (drule sym) apply simp haftmann@25917: apply (erule disjE) defer apply (drule sym) apply simp haftmann@25917: apply (erule disjE) apply assumption apply (drule sym) apply simp haftmann@25917: apply (drule sym) apply simp haftmann@25917: apply (blast dest: zero_less_mult_pos) haftmann@25230: apply (blast dest: zero_less_mult_pos2) haftmann@25230: done huffman@22990: paulson@14265: lemma zero_le_mult_iff: haftmann@25917: "0 \ a * b \ 0 \ a \ 0 \ b \ a \ 0 \ b \ 0" nipkow@29667: by (auto simp add: eq_commute [of 0] le_less not_less zero_less_mult_iff) paulson@14265: paulson@14265: lemma mult_less_0_iff: haftmann@25917: "a * b < 0 \ 0 < a \ b < 0 \ a < 0 \ 0 < b" haftmann@25917: apply (insert zero_less_mult_iff [of "-a" b]) haftmann@25917: apply (force simp add: minus_mult_left[symmetric]) haftmann@25917: done paulson@14265: paulson@14265: lemma mult_le_0_iff: haftmann@25917: "a * b \ 0 \ 0 \ a \ b \ 0 \ a \ 0 \ 0 \ b" haftmann@25917: apply (insert zero_le_mult_iff [of "-a" b]) haftmann@25917: apply (force simp add: minus_mult_left[symmetric]) haftmann@25917: done haftmann@25917: haftmann@25917: lemma zero_le_square [simp]: "0 \ a * a" nipkow@29667: by (simp add: zero_le_mult_iff linear) haftmann@25917: haftmann@25917: lemma not_square_less_zero [simp]: "\ (a * a < 0)" nipkow@29667: by (simp add: not_less) haftmann@25917: haftmann@26193: text{*Cancellation laws for @{term "c*a < c*b"} and @{term "a*c < b*c"}, haftmann@26193: also with the relations @{text "\"} and equality.*} haftmann@26193: haftmann@26193: text{*These ``disjunction'' versions produce two cases when the comparison is haftmann@26193: an assumption, but effectively four when the comparison is a goal.*} haftmann@26193: haftmann@26193: lemma mult_less_cancel_right_disj: haftmann@26193: "a * c < b * c \ 0 < c \ a < b \ c < 0 \ b < a" haftmann@26193: apply (cases "c = 0") haftmann@26193: apply (auto simp add: neq_iff mult_strict_right_mono haftmann@26193: mult_strict_right_mono_neg) haftmann@26193: apply (auto simp add: not_less haftmann@26193: not_le [symmetric, of "a*c"] haftmann@26193: not_le [symmetric, of a]) haftmann@26193: apply (erule_tac [!] notE) haftmann@26193: apply (auto simp add: less_imp_le mult_right_mono haftmann@26193: mult_right_mono_neg) haftmann@26193: done haftmann@26193: haftmann@26193: lemma mult_less_cancel_left_disj: haftmann@26193: "c * a < c * b \ 0 < c \ a < b \ c < 0 \ b < a" haftmann@26193: apply (cases "c = 0") haftmann@26193: apply (auto simp add: neq_iff mult_strict_left_mono haftmann@26193: mult_strict_left_mono_neg) haftmann@26193: apply (auto simp add: not_less haftmann@26193: not_le [symmetric, of "c*a"] haftmann@26193: not_le [symmetric, of a]) haftmann@26193: apply (erule_tac [!] notE) haftmann@26193: apply (auto simp add: less_imp_le mult_left_mono haftmann@26193: mult_left_mono_neg) haftmann@26193: done haftmann@26193: haftmann@26193: text{*The ``conjunction of implication'' lemmas produce two cases when the haftmann@26193: comparison is a goal, but give four when the comparison is an assumption.*} haftmann@26193: haftmann@26193: lemma mult_less_cancel_right: haftmann@26193: "a * c < b * c \ (0 \ c \ a < b) \ (c \ 0 \ b < a)" haftmann@26193: using mult_less_cancel_right_disj [of a c b] by auto haftmann@26193: haftmann@26193: lemma mult_less_cancel_left: haftmann@26193: "c * a < c * b \ (0 \ c \ a < b) \ (c \ 0 \ b < a)" haftmann@26193: using mult_less_cancel_left_disj [of c a b] by auto haftmann@26193: haftmann@26193: lemma mult_le_cancel_right: haftmann@26193: "a * c \ b * c \ (0 < c \ a \ b) \ (c < 0 \ b \ a)" nipkow@29667: by (simp add: not_less [symmetric] mult_less_cancel_right_disj) haftmann@26193: haftmann@26193: lemma mult_le_cancel_left: haftmann@26193: "c * a \ c * b \ (0 < c \ a \ b) \ (c < 0 \ b \ a)" nipkow@29667: by (simp add: not_less [symmetric] mult_less_cancel_left_disj) haftmann@26193: nipkow@30649: lemma mult_le_cancel_left_pos: nipkow@30649: "0 < c \ c * a \ c * b \ a \ b" nipkow@30649: by (auto simp: mult_le_cancel_left) nipkow@30649: nipkow@30649: lemma mult_le_cancel_left_neg: nipkow@30649: "c < 0 \ c * a \ c * b \ b \ a" nipkow@30649: by (auto simp: mult_le_cancel_left) nipkow@30649: nipkow@30649: lemma mult_less_cancel_left_pos: nipkow@30649: "0 < c \ c * a < c * b \ a < b" nipkow@30649: by (auto simp: mult_less_cancel_left) nipkow@30649: nipkow@30649: lemma mult_less_cancel_left_neg: nipkow@30649: "c < 0 \ c * a < c * b \ b < a" nipkow@30649: by (auto simp: mult_less_cancel_left) nipkow@30649: haftmann@25917: end paulson@14265: nipkow@29667: text{*Legacy - use @{text algebra_simps} *} nipkow@29833: lemmas ring_simps[noatp] = algebra_simps haftmann@25230: huffman@30692: lemmas mult_sign_intros = huffman@30692: mult_nonneg_nonneg mult_nonneg_nonpos huffman@30692: mult_nonpos_nonneg mult_nonpos_nonpos huffman@30692: mult_pos_pos mult_pos_neg huffman@30692: mult_neg_pos mult_neg_neg haftmann@25230: haftmann@35028: class ordered_comm_ring = comm_ring + ordered_comm_semiring haftmann@25267: begin haftmann@25230: haftmann@35028: subclass ordered_ring .. haftmann@35028: subclass ordered_cancel_comm_semiring .. haftmann@25230: haftmann@25267: end haftmann@25230: haftmann@35028: class linordered_semidom = comm_semiring_1_cancel + linordered_comm_semiring_strict + haftmann@35028: (*previously linordered_semiring*) haftmann@25230: assumes zero_less_one [simp]: "0 < 1" haftmann@25230: begin haftmann@25230: haftmann@25230: lemma pos_add_strict: haftmann@25230: shows "0 < a \ b < c \ b < a + c" haftmann@25230: using add_strict_mono [of zero a b c] by simp haftmann@25230: haftmann@26193: lemma zero_le_one [simp]: "0 \ 1" nipkow@29667: by (rule zero_less_one [THEN less_imp_le]) haftmann@26193: haftmann@26193: lemma not_one_le_zero [simp]: "\ 1 \ 0" nipkow@29667: by (simp add: not_le) haftmann@26193: haftmann@26193: lemma not_one_less_zero [simp]: "\ 1 < 0" nipkow@29667: by (simp add: not_less) haftmann@26193: haftmann@26193: lemma less_1_mult: haftmann@26193: assumes "1 < m" and "1 < n" haftmann@26193: shows "1 < m * n" haftmann@26193: using assms mult_strict_mono [of 1 m 1 n] haftmann@26193: by (simp add: less_trans [OF zero_less_one]) haftmann@26193: haftmann@25230: end haftmann@25230: haftmann@35028: class linordered_idom = comm_ring_1 + haftmann@35028: linordered_comm_semiring_strict + ordered_ab_group_add + haftmann@25230: abs_if + sgn_if haftmann@35028: (*previously linordered_ring*) haftmann@25917: begin haftmann@25917: haftmann@35043: subclass linordered_ring_strict .. haftmann@35028: subclass ordered_comm_ring .. huffman@27516: subclass idom .. haftmann@25917: haftmann@35028: subclass linordered_semidom haftmann@28823: proof haftmann@26193: have "0 \ 1 * 1" by (rule zero_le_square) haftmann@26193: thus "0 < 1" by (simp add: le_less) haftmann@25917: qed haftmann@25917: haftmann@35028: lemma linorder_neqE_linordered_idom: haftmann@26193: assumes "x \ y" obtains "x < y" | "y < x" haftmann@26193: using assms by (rule neqE) haftmann@26193: haftmann@26274: text {* These cancellation simprules also produce two cases when the comparison is a goal. *} haftmann@26274: haftmann@26274: lemma mult_le_cancel_right1: haftmann@26274: "c \ b * c \ (0 < c \ 1 \ b) \ (c < 0 \ b \ 1)" nipkow@29667: by (insert mult_le_cancel_right [of 1 c b], simp) haftmann@26274: haftmann@26274: lemma mult_le_cancel_right2: haftmann@26274: "a * c \ c \ (0 < c \ a \ 1) \ (c < 0 \ 1 \ a)" nipkow@29667: by (insert mult_le_cancel_right [of a c 1], simp) haftmann@26274: haftmann@26274: lemma mult_le_cancel_left1: haftmann@26274: "c \ c * b \ (0 < c \ 1 \ b) \ (c < 0 \ b \ 1)" nipkow@29667: by (insert mult_le_cancel_left [of c 1 b], simp) haftmann@26274: haftmann@26274: lemma mult_le_cancel_left2: haftmann@26274: "c * a \ c \ (0 < c \ a \ 1) \ (c < 0 \ 1 \ a)" nipkow@29667: by (insert mult_le_cancel_left [of c a 1], simp) haftmann@26274: haftmann@26274: lemma mult_less_cancel_right1: haftmann@26274: "c < b * c \ (0 \ c \ 1 < b) \ (c \ 0 \ b < 1)" nipkow@29667: by (insert mult_less_cancel_right [of 1 c b], simp) haftmann@26274: haftmann@26274: lemma mult_less_cancel_right2: haftmann@26274: "a * c < c \ (0 \ c \ a < 1) \ (c \ 0 \ 1 < a)" nipkow@29667: by (insert mult_less_cancel_right [of a c 1], simp) haftmann@26274: haftmann@26274: lemma mult_less_cancel_left1: haftmann@26274: "c < c * b \ (0 \ c \ 1 < b) \ (c \ 0 \ b < 1)" nipkow@29667: by (insert mult_less_cancel_left [of c 1 b], simp) haftmann@26274: haftmann@26274: lemma mult_less_cancel_left2: haftmann@26274: "c * a < c \ (0 \ c \ a < 1) \ (c \ 0 \ 1 < a)" nipkow@29667: by (insert mult_less_cancel_left [of c a 1], simp) haftmann@26274: haftmann@27651: lemma sgn_sgn [simp]: haftmann@27651: "sgn (sgn a) = sgn a" nipkow@29700: unfolding sgn_if by simp haftmann@27651: haftmann@27651: lemma sgn_0_0: haftmann@27651: "sgn a = 0 \ a = 0" nipkow@29700: unfolding sgn_if by simp haftmann@27651: haftmann@27651: lemma sgn_1_pos: haftmann@27651: "sgn a = 1 \ a > 0" nipkow@29700: unfolding sgn_if by (simp add: neg_equal_zero) haftmann@27651: haftmann@27651: lemma sgn_1_neg: haftmann@27651: "sgn a = - 1 \ a < 0" nipkow@29700: unfolding sgn_if by (auto simp add: equal_neg_zero) haftmann@27651: haftmann@29940: lemma sgn_pos [simp]: haftmann@29940: "0 < a \ sgn a = 1" haftmann@29940: unfolding sgn_1_pos . haftmann@29940: haftmann@29940: lemma sgn_neg [simp]: haftmann@29940: "a < 0 \ sgn a = - 1" haftmann@29940: unfolding sgn_1_neg . haftmann@29940: haftmann@27651: lemma sgn_times: haftmann@27651: "sgn (a * b) = sgn a * sgn b" nipkow@29667: by (auto simp add: sgn_if zero_less_mult_iff) haftmann@27651: haftmann@29653: lemma abs_sgn: "abs k = k * sgn k" nipkow@29700: unfolding sgn_if abs_if by auto nipkow@29700: haftmann@29940: lemma sgn_greater [simp]: haftmann@29940: "0 < sgn a \ 0 < a" haftmann@29940: unfolding sgn_if by auto haftmann@29940: haftmann@29940: lemma sgn_less [simp]: haftmann@29940: "sgn a < 0 \ a < 0" haftmann@29940: unfolding sgn_if by auto haftmann@29940: huffman@29949: lemma abs_dvd_iff [simp]: "(abs m) dvd k \ m dvd k" huffman@29949: by (simp add: abs_if) huffman@29949: huffman@29949: lemma dvd_abs_iff [simp]: "m dvd (abs k) \ m dvd k" huffman@29949: by (simp add: abs_if) haftmann@29653: nipkow@33676: lemma dvd_if_abs_eq: nipkow@33676: "abs l = abs (k) \ l dvd k" nipkow@33676: by(subst abs_dvd_iff[symmetric]) simp nipkow@33676: haftmann@25917: end haftmann@25230: haftmann@26274: text {* Simprules for comparisons where common factors can be cancelled. *} paulson@15234: nipkow@29833: lemmas mult_compare_simps[noatp] = paulson@15234: mult_le_cancel_right mult_le_cancel_left paulson@15234: mult_le_cancel_right1 mult_le_cancel_right2 paulson@15234: mult_le_cancel_left1 mult_le_cancel_left2 paulson@15234: mult_less_cancel_right mult_less_cancel_left paulson@15234: mult_less_cancel_right1 mult_less_cancel_right2 paulson@15234: mult_less_cancel_left1 mult_less_cancel_left2 paulson@15234: mult_cancel_right mult_cancel_left paulson@15234: mult_cancel_right1 mult_cancel_right2 paulson@15234: mult_cancel_left1 mult_cancel_left2 paulson@15234: haftmann@26274: -- {* FIXME continue localization here *} paulson@14268: avigad@16775: subsection {* Reasoning about inequalities with division *} avigad@16775: haftmann@35028: lemma mult_right_le_one_le: "0 <= (x::'a::linordered_idom) ==> 0 <= y ==> y <= 1 avigad@16775: ==> x * y <= x" haftmann@33319: by (auto simp add: mult_compare_simps) avigad@16775: haftmann@35028: lemma mult_left_le_one_le: "0 <= (x::'a::linordered_idom) ==> 0 <= y ==> y <= 1 avigad@16775: ==> y * x <= x" haftmann@33319: by (auto simp add: mult_compare_simps) avigad@16775: haftmann@35028: context linordered_semidom haftmann@25193: begin haftmann@25193: haftmann@25193: lemma less_add_one: "a < a + 1" paulson@14293: proof - haftmann@25193: have "a + 0 < a + 1" nipkow@23482: by (blast intro: zero_less_one add_strict_left_mono) paulson@14293: thus ?thesis by simp paulson@14293: qed paulson@14293: haftmann@25193: lemma zero_less_two: "0 < 1 + 1" nipkow@29667: by (blast intro: less_trans zero_less_one less_add_one) haftmann@25193: haftmann@25193: end paulson@14365: paulson@15234: paulson@14293: subsection {* Absolute Value *} paulson@14293: haftmann@35028: context linordered_idom haftmann@25304: begin haftmann@25304: haftmann@25304: lemma mult_sgn_abs: "sgn x * abs x = x" haftmann@25304: unfolding abs_if sgn_if by auto haftmann@25304: haftmann@25304: end nipkow@24491: haftmann@35028: lemma abs_one [simp]: "abs 1 = (1::'a::linordered_idom)" nipkow@29667: by (simp add: abs_if zero_less_one [THEN order_less_not_sym]) haftmann@25304: haftmann@35028: class ordered_ring_abs = ordered_ring + ordered_ab_group_add_abs + haftmann@25304: assumes abs_eq_mult: haftmann@25304: "(0 \ a \ a \ 0) \ (0 \ b \ b \ 0) \ \a * b\ = \a\ * \b\" haftmann@25304: haftmann@35028: context linordered_idom haftmann@30961: begin haftmann@30961: haftmann@35028: subclass ordered_ring_abs proof haftmann@30961: qed (auto simp add: abs_if not_less equal_neg_zero neg_equal_zero mult_less_0_iff) haftmann@30961: haftmann@30961: lemma abs_mult: haftmann@30961: "abs (a * b) = abs a * abs b" haftmann@30961: by (rule abs_eq_mult) auto haftmann@30961: haftmann@30961: lemma abs_mult_self: haftmann@30961: "abs a * abs a = a * a" haftmann@30961: by (simp add: abs_if) haftmann@30961: haftmann@30961: end paulson@14294: paulson@14294: lemma abs_mult_less: haftmann@35028: "[| abs a < c; abs b < d |] ==> abs a * abs b < c*(d::'a::linordered_idom)" paulson@14294: proof - paulson@14294: assume ac: "abs a < c" paulson@14294: hence cpos: "0 haftmann@25304: (abs y) * x = abs (y * x)" haftmann@25304: apply (subst abs_mult) haftmann@25304: apply simp haftmann@25304: done avigad@16775: haftmann@33364: code_modulename SML haftmann@35050: Rings Arith haftmann@33364: haftmann@33364: code_modulename OCaml haftmann@35050: Rings Arith haftmann@33364: haftmann@33364: code_modulename Haskell haftmann@35050: Rings Arith haftmann@33364: paulson@14265: end