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: haftmann@22390: class semiring = ab_semigroup_add + semigroup_mult + webertj@49962: assumes distrib_right[algebra_simps, field_simps]: "(a + b) * c = a * c + b * c" webertj@49962: assumes distrib_left[algebra_simps, field_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" webertj@49962: by (simp add: distrib_right 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 webertj@49962: have "0 * a + 0 * a = 0 * a + 0" by (simp add: distrib_right [symmetric]) nipkow@29667: thus "0 * a = 0" by (simp only: add_left_cancel) haftmann@25152: next haftmann@25152: fix a :: 'a webertj@49962: have "a * 0 + a * 0 = a * 0 + 0" by (simp add: distrib_left [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: nipkow@50420: definition dvd :: "'a \ 'a \ bool" (infix "dvd" 50) where haftmann@37767: "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: blanchet@35828: lemma dvd_0_left_iff [no_atp, 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'" .. webertj@49962: ultimately have "b + c = a * (b' + c')" by (simp add: distrib_left) haftmann@27651: then show ?thesis .. haftmann@27651: qed haftmann@27651: haftmann@25152: end paulson@14421: haftmann@22390: class no_zero_divisors = zero + times + haftmann@25062: assumes no_zero_divisors: "a \ 0 \ b \ 0 \ a * b \ 0" haftmann@36719: begin haftmann@36719: haftmann@36719: lemma divisors_zero: haftmann@36719: assumes "a * b = 0" haftmann@36719: shows "a = 0 \ b = 0" haftmann@36719: proof (rule classical) haftmann@36719: assume "\ (a = 0 \ b = 0)" haftmann@36719: then have "a \ 0" and "b \ 0" by auto haftmann@36719: with no_zero_divisors have "a * b \ 0" by blast haftmann@36719: with assms show ?thesis by simp haftmann@36719: qed haftmann@36719: haftmann@36719: end 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" webertj@49962: by (rule minus_unique) (simp add: distrib_right [symmetric]) haftmann@25152: haftmann@25152: lemma minus_mult_right: "- (a * b) = a * - b" webertj@49962: by (rule minus_unique) (simp add: distrib_left [symmetric]) haftmann@25152: huffman@29407: text{*Extract signs from products*} blanchet@35828: lemmas mult_minus_left [simp, no_atp] = minus_mult_left [symmetric] blanchet@35828: lemmas mult_minus_right [simp,no_atp] = 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: haftmann@36348: lemma right_diff_distrib[algebra_simps, field_simps]: "a * (b - c) = a * b - a * c" webertj@49962: by (simp add: distrib_left diff_minus) nipkow@29667: haftmann@36348: lemma left_diff_distrib[algebra_simps, field_simps]: "(a - b) * c = a * c - b * c" webertj@49962: by (simp add: distrib_right diff_minus) haftmann@25152: blanchet@35828: lemmas ring_distribs[no_atp] = webertj@49962: distrib_left distrib_right left_diff_distrib right_diff_distrib haftmann@25152: 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: blanchet@35828: lemmas ring_distribs[no_atp] = webertj@49962: distrib_left distrib_right 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: huffman@44350: lemma square_diff_square_factored: huffman@44350: "x * x - y * y = (x + y) * (x - y)" huffman@44350: by (simp add: algebra_simps) huffman@44350: 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: huffman@44346: lemma square_diff_one_factored: huffman@44346: "x * x - 1 = (x + 1) * (x - 1)" huffman@44346: by (simp add: algebra_simps) huffman@44346: 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)" huffman@35216: by (simp only: diff_minus dvd_add 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*} blanchet@35828: lemma mult_cancel_right [simp, no_atp]: haftmann@26193: "a * c = b * c \ c = 0 \ a = b" haftmann@26193: proof - haftmann@26193: have "(a * c = b * c) = ((a - b) * c = 0)" huffman@35216: by (simp add: algebra_simps) huffman@35216: thus ?thesis by (simp add: disj_commute) haftmann@26193: qed haftmann@26193: blanchet@35828: lemma mult_cancel_left [simp, no_atp]: haftmann@26193: "c * a = c * b \ c = 0 \ a = b" haftmann@26193: proof - haftmann@26193: have "(c * a = c * b) = (c * (a - b) = 0)" huffman@35216: by (simp add: algebra_simps) huffman@35216: thus ?thesis by simp 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: huffman@36970: lemma square_eq_1_iff: huffman@36821: "x * x = 1 \ x = 1 \ x = - 1" huffman@36821: proof - huffman@36821: have "(x - 1) * (x + 1) = x * x - 1" huffman@36821: by (simp add: algebra_simps) huffman@36821: hence "x * x = 1 \ (x - 1) * (x + 1) = 0" huffman@36821: by simp huffman@36821: thus ?thesis huffman@36821: by (simp add: eq_neg_iff_add_eq_0) huffman@36821: qed huffman@36821: 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@35216: by (simp add: 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@35302: text {* haftmann@35302: The theory of partially ordered rings is taken from the books: haftmann@35302: \begin{itemize} haftmann@35302: \item \emph{Lattice Theory} by Garret Birkhoff, American Mathematical Society 1979 haftmann@35302: \item \emph{Partially Ordered Algebraic Systems}, Pergamon Press 1963 haftmann@35302: \end{itemize} haftmann@35302: Most of the used notions can also be looked up in haftmann@35302: \begin{itemize} haftmann@35302: \item \url{http://www.mathworld.com} by Eric Weisstein et. al. haftmann@35302: \item \emph{Algebra I} by van der Waerden, Springer. haftmann@35302: \end{itemize} haftmann@35302: *} haftmann@35302: haftmann@38642: class ordered_semiring = semiring + comm_monoid_add + ordered_ab_semigroup_add + haftmann@38642: assumes mult_left_mono: "a \ b \ 0 \ c \ c * a \ c * b" haftmann@38642: assumes mult_right_mono: "a \ b \ 0 \ c \ a * c \ b * c" haftmann@25230: begin haftmann@25230: haftmann@25230: lemma mult_mono: haftmann@38642: "a \ b \ c \ d \ 0 \ b \ 0 \ c \ 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@38642: "a \ b \ c \ d \ 0 \ a \ 0 \ c \ 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@38642: class ordered_cancel_semiring = ordered_semiring + cancel_comm_monoid_add haftmann@25267: begin paulson@14268: huffman@27516: subclass semiring_0_cancel .. obua@23521: haftmann@25230: lemma mult_nonneg_nonneg: "0 \ a \ 0 \ b \ 0 \ a * b" haftmann@36301: using mult_left_mono [of 0 b a] by simp haftmann@25230: haftmann@25230: lemma mult_nonneg_nonpos: "0 \ a \ b \ 0 \ a * b \ 0" haftmann@36301: using mult_left_mono [of b 0 a] by simp huffman@30692: huffman@30692: lemma mult_nonpos_nonneg: "a \ 0 \ 0 \ b \ a * b \ 0" haftmann@36301: using mult_right_mono [of a 0 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" haftmann@36301: by (drule mult_right_mono [of b 0], 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@38642: class linordered_semiring = ordered_semiring + linordered_cancel_ab_semigroup_add 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 hoelzl@36622: begin hoelzl@36622: hoelzl@36622: lemma convex_bound_le: hoelzl@36622: assumes "x \ a" "y \ a" "0 \ u" "0 \ v" "u + v = 1" hoelzl@36622: shows "u * x + v * y \ a" hoelzl@36622: proof- hoelzl@36622: from assms have "u * x + v * y \ u * a + v * a" hoelzl@36622: by (simp add: add_mono mult_left_mono) webertj@49962: thus ?thesis using assms unfolding distrib_right[symmetric] by simp hoelzl@36622: qed hoelzl@36622: hoelzl@36622: end 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" haftmann@36301: using mult_strict_left_mono [of 0 b a] by simp huffman@30692: huffman@30692: lemma mult_pos_neg: "0 < a \ b < 0 \ a * b < 0" haftmann@36301: using mult_strict_left_mono [of b 0 a] by simp huffman@30692: huffman@30692: lemma mult_neg_pos: "a < 0 \ 0 < b \ a * b < 0" haftmann@36301: using mult_strict_right_mono [of a 0 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" haftmann@36301: by (drule mult_strict_right_mono [of b 0], 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@35097: class linordered_semiring_1_strict = linordered_semiring_strict + semiring_1 hoelzl@36622: begin hoelzl@36622: hoelzl@36622: subclass linordered_semiring_1 .. hoelzl@36622: hoelzl@36622: lemma convex_bound_lt: hoelzl@36622: assumes "x < a" "y < a" "0 \ u" "0 \ v" "u + v = 1" hoelzl@36622: shows "u * x + v * y < a" hoelzl@36622: proof - hoelzl@36622: from assms have "u * x + v * y < u * a + v * a" hoelzl@36622: by (cases "u = 0") hoelzl@36622: (auto intro!: add_less_le_mono mult_strict_left_mono mult_left_mono) webertj@49962: thus ?thesis using assms unfolding distrib_right[symmetric] by simp hoelzl@36622: qed hoelzl@36622: hoelzl@36622: end haftmann@33319: haftmann@38642: class ordered_comm_semiring = comm_semiring_0 + ordered_ab_semigroup_add + haftmann@38642: assumes comm_mult_left_mono: "a \ b \ 0 \ c \ c * a \ c * b" 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@38642: thus "c * a \ c * b" by (rule comm_mult_left_mono) huffman@23550: thus "a * c \ b * c" by (simp only: mult_commute) krauss@21199: qed paulson@14265: haftmann@25267: end haftmann@25267: haftmann@38642: class ordered_cancel_comm_semiring = ordered_comm_semiring + cancel_comm_monoid_add haftmann@25267: begin paulson@14265: haftmann@38642: subclass comm_semiring_0_cancel .. 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@38642: assumes comm_mult_strict_left_mono: "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@38642: thus "c * a < c * b" by (rule comm_mult_strict_left_mono) 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: 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@36301: apply (drule mult_left_mono [of _ _ "- c"]) huffman@35216: apply simp_all haftmann@25230: done haftmann@25230: haftmann@25230: lemma mult_right_mono_neg: haftmann@25230: "b \ a \ c \ 0 \ a * c \ b * c" haftmann@36301: apply (drule mult_right_mono [of _ _ "- c"]) huffman@35216: apply simp_all haftmann@25230: done haftmann@25230: huffman@30692: lemma mult_nonpos_nonpos: "a \ 0 \ b \ 0 \ 0 \ a * b" haftmann@36301: using mult_right_mono_neg [of a 0 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@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\" huffman@35216: by (auto simp add: abs_if not_less) huffman@35216: (auto simp del: minus_add_distrib simp add: minus_add_distrib [symmetric], huffman@36977: auto intro!: less_imp_le add_neg_neg) huffman@35216: qed (auto simp add: abs_if) haftmann@25304: huffman@35631: lemma zero_le_square [simp]: "0 \ a * a" huffman@35631: using linear [of 0 a] huffman@35631: by (auto simp add: mult_nonneg_nonneg mult_nonpos_nonpos) huffman@35631: huffman@35631: lemma not_square_less_zero [simp]: "\ (a * a < 0)" huffman@35631: by (simp add: not_less) huffman@35631: 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" haftmann@36301: using mult_strict_right_mono_neg [of a 0 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" huffman@35216: apply (insert zero_less_mult_iff [of "-a" b]) huffman@35216: apply force 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]) huffman@35216: apply force haftmann@25917: done 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: 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@36301: using add_strict_mono [of 0 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: hoelzl@36622: subclass linordered_semiring_1_strict .. 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" huffman@35216: unfolding sgn_if by simp haftmann@27651: haftmann@27651: lemma sgn_1_neg: haftmann@27651: "sgn a = - 1 \ a < 0" huffman@35216: unfolding sgn_if by auto 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@36301: lemma abs_sgn: "\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: haftmann@36301: lemma abs_dvd_iff [simp]: "\m\ dvd k \ m dvd k" huffman@29949: by (simp add: abs_if) huffman@29949: haftmann@36301: lemma dvd_abs_iff [simp]: "m dvd \k\ \ m dvd k" huffman@29949: by (simp add: abs_if) haftmann@29653: nipkow@33676: lemma dvd_if_abs_eq: haftmann@36301: "\l\ = \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: blanchet@35828: lemmas mult_compare_simps[no_atp] = 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@36301: text {* Reasoning about inequalities with division *} 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: haftmann@36301: context linordered_idom haftmann@36301: begin paulson@15234: haftmann@36301: lemma mult_right_le_one_le: haftmann@36301: "0 \ x \ 0 \ y \ y \ 1 \ x * y \ x" haftmann@36301: by (auto simp add: mult_le_cancel_left2) haftmann@36301: haftmann@36301: lemma mult_left_le_one_le: haftmann@36301: "0 \ x \ 0 \ y \ y \ 1 \ y * x \ x" haftmann@36301: by (auto simp add: mult_le_cancel_right2) haftmann@36301: haftmann@36301: end haftmann@36301: haftmann@36301: text {* Absolute Value *} paulson@14293: haftmann@35028: context linordered_idom haftmann@25304: begin haftmann@25304: haftmann@36301: lemma mult_sgn_abs: haftmann@36301: "sgn x * \x\ = x" haftmann@25304: unfolding abs_if sgn_if by auto haftmann@25304: haftmann@36301: lemma abs_one [simp]: haftmann@36301: "\1\ = 1" huffman@44921: by (simp add: abs_if) haftmann@36301: haftmann@25304: end nipkow@24491: 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 huffman@35216: qed (auto simp add: abs_if not_less mult_less_0_iff) haftmann@30961: haftmann@30961: lemma abs_mult: haftmann@36301: "\a * b\ = \a\ * \b\" haftmann@30961: by (rule abs_eq_mult) auto haftmann@30961: haftmann@30961: lemma abs_mult_self: haftmann@36301: "\a\ * \a\ = a * a" haftmann@30961: by (simp add: abs_if) haftmann@30961: paulson@14294: lemma abs_mult_less: haftmann@36301: "\a\ < c \ \b\ < d \ \a\ * \b\ < c * d" paulson@14294: proof - haftmann@36301: assume ac: "\a\ < c" haftmann@36301: hence cpos: "0b\ < d" paulson@14294: thus ?thesis by (simp add: ac cpos mult_strict_mono) paulson@14294: qed paulson@14293: haftmann@36301: lemma less_minus_self_iff: haftmann@36301: "a < - a \ a < 0" haftmann@36301: by (simp only: less_le less_eq_neg_nonpos equal_neg_zero) obua@14738: haftmann@36301: lemma abs_less_iff: haftmann@36301: "\a\ < b \ a < b \ - a < b" haftmann@36301: by (simp add: less_le abs_le_iff) (auto simp add: abs_if) obua@14738: haftmann@36301: lemma abs_mult_pos: haftmann@36301: "0 \ x \ \y\ * x = \y * x\" haftmann@36301: by (simp add: abs_mult) haftmann@36301: hoelzl@51520: lemma abs_diff_less_iff: hoelzl@51520: "\x - a\ < r \ a - r < x \ x < a + r" hoelzl@51520: by (auto simp add: diff_less_eq ac_simps abs_less_iff) hoelzl@51520: haftmann@36301: end avigad@16775: haftmann@52435: code_identifier haftmann@52435: code_module Rings \ (SML) Arith and (OCaml) Arith and (Haskell) Arith haftmann@33364: paulson@14265: end haftmann@52435: