refactor(library/data/int,library/algebra): make int an instnance of ordered ring, rename theorems

This commit is contained in:
Jeremy Avigad 2014-12-26 16:25:05 -05:00
parent 25394dddb7
commit cecabbb401
9 changed files with 742 additions and 424 deletions

View file

@ -255,7 +255,7 @@ section group
theorem mul_eq_iff_eq_mul_inv (a b c : A) : a * b = c ↔ a = c * b⁻¹ := theorem mul_eq_iff_eq_mul_inv (a b c : A) : a * b = c ↔ a = c * b⁻¹ :=
iff.intro eq_mul_inv_of_mul_eq mul_eq_of_eq_mul_inv iff.intro eq_mul_inv_of_mul_eq mul_eq_of_eq_mul_inv
definition group.to_left_cancel_semigroup [instance] : left_cancel_semigroup A := definition group.to_left_cancel_semigroup [instance] [coercion] : left_cancel_semigroup A :=
left_cancel_semigroup.mk (@group.mul A s) (@group.mul_assoc A s) left_cancel_semigroup.mk (@group.mul A s) (@group.mul_assoc A s)
(take a b c, (take a b c,
assume H : a * b = a * c, assume H : a * b = a * c,
@ -264,7 +264,7 @@ section group
... = a⁻¹ * (a * c) : H ... = a⁻¹ * (a * c) : H
... = c : inv_mul_cancel_left) ... = c : inv_mul_cancel_left)
definition group.to_right_cancel_semigroup [instance] : right_cancel_semigroup A := definition group.to_right_cancel_semigroup [instance] [coercion] : right_cancel_semigroup A :=
right_cancel_semigroup.mk (@group.mul A s) (@group.mul_assoc A s) right_cancel_semigroup.mk (@group.mul A s) (@group.mul_assoc A s)
(take a b c, (take a b c,
assume H : a * b = c * b, assume H : a * b = c * b,
@ -383,7 +383,7 @@ section add_group
theorem add_eq_iff_eq_add_neg (a b c : A) : a + b = c ↔ a = c + -b := theorem add_eq_iff_eq_add_neg (a b c : A) : a + b = c ↔ a = c + -b :=
iff.intro eq_add_neg_of_add_eq add_eq_of_eq_add_neg iff.intro eq_add_neg_of_add_eq add_eq_of_eq_add_neg
definition add_group.to_left_cancel_semigroup [instance] : definition add_group.to_left_cancel_semigroup [instance] [coercion] :
add_left_cancel_semigroup A := add_left_cancel_semigroup A :=
add_left_cancel_semigroup.mk add_group.add add_group.add_assoc add_left_cancel_semigroup.mk add_group.add add_group.add_assoc
(take a b c, (take a b c,
@ -393,7 +393,7 @@ section add_group
... = -a + (a + c) : H ... = -a + (a + c) : H
... = c : neg_add_cancel_left) ... = c : neg_add_cancel_left)
definition add_group.to_add_right_cancel_semigroup [instance] : definition add_group.to_add_right_cancel_semigroup [instance] [coercion] :
add_right_cancel_semigroup A := add_right_cancel_semigroup A :=
add_right_cancel_semigroup.mk add_group.add add_group.add_assoc add_right_cancel_semigroup.mk add_group.add add_group.add_assoc
(take a b c, (take a b c,

View file

@ -5,7 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Module: algebra.order Module: algebra.order
Author: Jeremy Avigad Author: Jeremy Avigad
Various types of orders. We develop weak orders (<=) and strict orders (<) separately. We also Various types of orders. We develop weak orders "≤" and strict orders "<" separately. We also
consider structures with both, where the two are related by consider structures with both, where the two are related by
x < y ↔ (x ≤ y ∧ x ≠ y) (order_pair) x < y ↔ (x ≤ y ∧ x ≠ y) (order_pair)
@ -16,16 +16,12 @@ with both < and ≤ as needed.
-/ -/
import logic.eq logic.connectives import logic.eq logic.connectives
import data.unit data.sigma data.prod
import algebra.function algebra.binary
open eq eq.ops open eq eq.ops
namespace algebra namespace algebra
variable {A : Type} variable {A : Type}
/- overloaded symbols -/ /- overloaded symbols -/
structure has_le [class] (A : Type) := structure has_le [class] (A : Type) :=
@ -62,21 +58,24 @@ calc_trans le_of_le_of_eq
calc_trans lt_of_eq_of_lt calc_trans lt_of_eq_of_lt
calc_trans lt_of_lt_of_eq calc_trans lt_of_lt_of_eq
/- weak orders -/ /- weak orders -/
structure weak_order [class] (A : Type) extends has_le A := structure weak_order [class] (A : Type) extends has_le A :=
(le_refl : ∀a, le a a) (le_refl : ∀a, le a a)
(le_trans : ∀a b c, le a b → le b c → le a c) (le_trans : ∀a b c, le a b → le b c → le a c)
(le_antisym : ∀a b, le a b → le b a → a = b) (le_antisymm : ∀a b, le a b → le b a → a = b)
theorem le.refl [s : weak_order A] (a : A) : a ≤ a := !weak_order.le_refl section
variable [s : weak_order A]
include s
theorem le.trans [s : weak_order A] {a b c : A} : a ≤ b → b ≤ c → a ≤ c := !weak_order.le_trans theorem le.refl (a : A) : a ≤ a := !weak_order.le_refl
calc_trans le.trans theorem le.trans {a b c : A} : a ≤ b → b ≤ c → a ≤ c := !weak_order.le_trans
calc_trans le.trans
theorem le.antisym [s : weak_order A] {a b : A} : a ≤ b → b ≤ a → a = b := !weak_order.le_antisym theorem le.antisymm {a b : A} : a ≤ b → b ≤ a → a = b := !weak_order.le_antisymm
end
structure linear_weak_order [class] (A : Type) extends weak_order A := structure linear_weak_order [class] (A : Type) extends weak_order A :=
(le_total : ∀a b, le a b le b a) (le_total : ∀a b, le a b le b a)
@ -84,22 +83,28 @@ structure linear_weak_order [class] (A : Type) extends weak_order A :=
theorem le.total [s : linear_weak_order A] (a b : A) : a ≤ b b ≤ a := theorem le.total [s : linear_weak_order A] (a b : A) : a ≤ b b ≤ a :=
!linear_weak_order.le_total !linear_weak_order.le_total
/- strict orders -/ /- strict orders -/
structure strict_order [class] (A : Type) extends has_lt A := structure strict_order [class] (A : Type) extends has_lt A :=
(lt_irrefl : ∀a, ¬ lt a a) (lt_irrefl : ∀a, ¬ lt a a)
(lt_trans : ∀a b c, lt a b → lt b c → lt a c) (lt_trans : ∀a b c, lt a b → lt b c → lt a c)
theorem lt.irrefl [s : strict_order A] (a : A) : ¬ a < a := !strict_order.lt_irrefl section
variable [s : strict_order A]
include s
theorem lt.trans [s : strict_order A] {a b c : A} : a < b → b < c → a < c := !strict_order.lt_trans theorem lt.irrefl (a : A) : ¬ a < a := !strict_order.lt_irrefl
calc_trans lt.trans theorem lt.trans {a b c : A} : a < b → b < c → a < c := !strict_order.lt_trans
calc_trans lt.trans
theorem lt.ne [s : strict_order A] {a b : A} : a < b → a ≠ b := theorem ne_of_lt {a b : A} : a < b → a ≠ b :=
assume lt_ab : a < b, assume eq_ab : a = b, lt.irrefl a (eq_ab⁻¹ ▸ lt_ab) assume lt_ab : a < b, assume eq_ab : a = b,
show false, from lt.irrefl b (eq_ab ▸ lt_ab)
theorem lt.asymm {a b : A} (H : a < b) : ¬ b < a :=
assume H1 : b < a, lt.irrefl _ (lt.trans H H1)
end
/- well-founded orders -/ /- well-founded orders -/
@ -123,7 +128,6 @@ structure order_pair [class] (A : Type) extends weak_order A, has_lt A :=
(lt_iff_le_ne : ∀a b, lt a b ↔ (le a b ∧ a ≠ b)) (lt_iff_le_ne : ∀a b, lt a b ↔ (le a b ∧ a ≠ b))
section section
variable [s : order_pair A] variable [s : order_pair A]
variables {a b c : A} variables {a b c : A}
include s include s
@ -137,7 +141,7 @@ section
theorem lt_of_le_of_ne (H1 : a ≤ b) (H2 : a ≠ b) : a < b := theorem lt_of_le_of_ne (H1 : a ≤ b) (H2 : a ≠ b) : a < b :=
iff.mp (iff.symm lt_iff_le_and_ne) (and.intro H1 H2) iff.mp (iff.symm lt_iff_le_and_ne) (and.intro H1 H2)
definition order_pair.to_strict_order [instance] [s : order_pair A] : strict_order A := definition order_pair.to_strict_order [instance] [coercion] [s : order_pair A] : strict_order A :=
strict_order.mk strict_order.mk
order_pair.lt order_pair.lt
(show ∀a, ¬ a < a, from (show ∀a, ¬ a < a, from
@ -155,7 +159,7 @@ section
have ne_ac : a ≠ c, from have ne_ac : a ≠ c, from
assume eq_ac : a = c, assume eq_ac : a = c,
have le_ba : b ≤ a, from eq_ac⁻¹ ▸ le_bc, have le_ba : b ≤ a, from eq_ac⁻¹ ▸ le_bc,
have eq_ab : a = b, from le.antisym le_ab le_ba, have eq_ab : a = b, from le.antisymm le_ab le_ba,
have ne_ab : a ≠ b, from and.elim_right (iff.mp lt_iff_le_and_ne lt_ab), have ne_ab : a ≠ b, from and.elim_right (iff.mp lt_iff_le_and_ne lt_ab),
ne_ab eq_ab, ne_ab eq_ab,
show a < c, from lt_of_le_of_ne le_ac ne_ac) show a < c, from lt_of_le_of_ne le_ac ne_ac)
@ -167,8 +171,8 @@ section
have ne_ac : a ≠ c, from have ne_ac : a ≠ c, from
assume eq_ac : a = c, assume eq_ac : a = c,
have le_ba : b ≤ a, from eq_ac⁻¹ ▸ le_bc, have le_ba : b ≤ a, from eq_ac⁻¹ ▸ le_bc,
have eq_ab : a = b, from le.antisym (le_of_lt lt_ab) le_ba, have eq_ab : a = b, from le.antisymm (le_of_lt lt_ab) le_ba,
show false, from lt.ne lt_ab eq_ab, show false, from ne_of_lt lt_ab eq_ab,
show a < c, from lt_of_le_of_ne le_ac ne_ac show a < c, from lt_of_le_of_ne le_ac ne_ac
theorem lt_of_le_of_lt : a ≤ b → b < c → a < c := theorem lt_of_le_of_lt : a ≤ b → b < c → a < c :=
@ -178,8 +182,8 @@ section
have ne_ac : a ≠ c, from have ne_ac : a ≠ c, from
assume eq_ac : a = c, assume eq_ac : a = c,
have le_cb : c ≤ b, from eq_ac ▸ le_ab, have le_cb : c ≤ b, from eq_ac ▸ le_ab,
have eq_bc : b = c, from le.antisym (le_of_lt lt_bc) le_cb, have eq_bc : b = c, from le.antisymm (le_of_lt lt_bc) le_cb,
show false, from lt.ne lt_bc eq_bc, show false, from ne_of_lt lt_bc eq_bc,
show a < c, from lt_of_le_of_ne le_ac ne_ac show a < c, from lt_of_le_of_ne le_ac ne_ac
calc_trans lt_of_lt_of_le calc_trans lt_of_lt_of_le
@ -192,11 +196,6 @@ section
theorem not_lt_of_le (H : a ≤ b) : ¬ b < a := theorem not_lt_of_le (H : a ≤ b) : ¬ b < a :=
assume H1 : b < a, assume H1 : b < a,
lt.irrefl _ (lt_of_le_of_lt H H1) lt.irrefl _ (lt_of_le_of_lt H H1)
theorem not_lt_of_lt (H : a < b) : ¬ b < a :=
assume H1 : b < a,
lt.irrefl _ (lt.trans H1 H)
end end
structure strong_order_pair [class] (A : Type) extends order_pair A := structure strong_order_pair [class] (A : Type) extends order_pair A :=
@ -205,7 +204,7 @@ structure strong_order_pair [class] (A : Type) extends order_pair A :=
theorem le_iff_lt_or_eq [s : strong_order_pair A] {a b : A} : a ≤ b ↔ a < b a = b := theorem le_iff_lt_or_eq [s : strong_order_pair A] {a b : A} : a ≤ b ↔ a < b a = b :=
!strong_order_pair.le_iff_lt_or_eq !strong_order_pair.le_iff_lt_or_eq
theorem le_imp_lt_or_eq [s : strong_order_pair A] {a b : A} (le_ab : a ≤ b) : a < b a = b := theorem lt_or_eq_of_le [s : strong_order_pair A] {a b : A} (le_ab : a ≤ b) : a < b a = b :=
iff.mp le_iff_lt_or_eq le_ab iff.mp le_iff_lt_or_eq le_ab
-- We can also construct a strong order pair by defining a strict order, and then defining -- We can also construct a strong order pair by defining a strict order, and then defining
@ -214,7 +213,7 @@ iff.mp le_iff_lt_or_eq le_ab
structure strict_order_with_le [class] (A : Type) extends strict_order A, has_le A := structure strict_order_with_le [class] (A : Type) extends strict_order A, has_le A :=
(le_iff_lt_or_eq : ∀a b, le a b ↔ lt a b a = b) (le_iff_lt_or_eq : ∀a b, le a b ↔ lt a b a = b)
definition strict_order_with_le.to_order_pair [instance] [s : strict_order_with_le A] : definition strict_order_with_le.to_order_pair [instance] [coercion] [s : strict_order_with_le A] :
strong_order_pair A := strong_order_pair A :=
strong_order_pair.mk strict_order_with_le.le strong_order_pair.mk strict_order_with_le.le
(take a, (take a,
@ -248,57 +247,60 @@ strong_order_pair.mk strict_order_with_le.le
(assume lt_ab : a < b, (assume lt_ab : a < b,
have le_ab : a ≤ b, have le_ab : a ≤ b,
from iff.elim_right !strict_order_with_le.le_iff_lt_or_eq (or.intro_left _ lt_ab), from iff.elim_right !strict_order_with_le.le_iff_lt_or_eq (or.intro_left _ lt_ab),
show a ≤ b ∧ a ≠ b, from and.intro le_ab (lt.ne lt_ab)) show a ≤ b ∧ a ≠ b, from and.intro le_ab (ne_of_lt lt_ab))
(assume H : a ≤ b ∧ a ≠ b, (assume H : a ≤ b ∧ a ≠ b,
have H1 : a < b a = b, have H1 : a < b a = b,
from iff.mp !strict_order_with_le.le_iff_lt_or_eq (and.elim_left H), from iff.mp !strict_order_with_le.le_iff_lt_or_eq (and.elim_left H),
show a < b, from or_resolve_left H1 (and.elim_right H))) show a < b, from or_resolve_left H1 (and.elim_right H)))
strict_order_with_le.le_iff_lt_or_eq strict_order_with_le.le_iff_lt_or_eq
/- linear orders -/ /- linear orders -/
structure linear_order_pair [class] (A : Type) extends order_pair A, linear_weak_order A structure linear_order_pair [class] (A : Type) extends order_pair A, linear_weak_order A
structure linear_strong_order_pair [class] (A : Type) extends strong_order_pair A := structure linear_strong_order_pair [class] (A : Type) extends strong_order_pair A,
(lt_or_eq_or_lt : ∀a b, lt a b a = b lt b a) linear_weak_order A
section section
variable [s : linear_strong_order_pair A] variable [s : linear_strong_order_pair A]
variables (a b c : A) variables (a b c : A)
include s include s
theorem lt_or_eq_or_lt : a < b a = b b < a := !linear_strong_order_pair.lt_or_eq_or_lt theorem lt.trichotomy : a < b a = b b < a :=
or.elim (le.total a b)
(assume H : a ≤ b,
or.elim (iff.mp !le_iff_lt_or_eq H) (assume H1, or.inl H1) (assume H1, or.inr (or.inl H1)))
(assume H : b ≤ a,
or.elim (iff.mp !le_iff_lt_or_eq H)
(assume H1, or.inr (or.inr H1))
(assume H1, or.inr (or.inl (H1⁻¹))))
theorem lt_or_eq_or_lt_cases {a b : A} {P : Prop} theorem lt.by_cases {a b : A} {P : Prop}
(H1 : a < b → P) (H2 : a = b → P) (H3 : b < a → P) : P := (H1 : a < b → P) (H2 : a = b → P) (H3 : b < a → P) : P :=
or.elim !lt_or_eq_or_lt (assume H, H1 H) (assume H, or.elim H (assume H', H2 H') (assume H', H3 H')) or.elim !lt.trichotomy
(assume H, H1 H)
(assume H, or.elim H (assume H', H2 H') (assume H', H3 H'))
definition linear_strong_order_pair.to_linear_order_pair [instance] [s : linear_strong_order_pair A] : definition linear_strong_order_pair.to_linear_order_pair [instance] [coercion]
linear_order_pair A := [s : linear_strong_order_pair A] : linear_order_pair A :=
linear_order_pair.mk linear_strong_order_pair.le linear_strong_order_pair.le_refl linear_order_pair.mk linear_strong_order_pair.le linear_strong_order_pair.le_refl
linear_strong_order_pair.le_trans linear_strong_order_pair.le_antisym linear_strong_order_pair.lt linear_strong_order_pair.le_trans linear_strong_order_pair.le_antisymm
linear_strong_order_pair.lt
linear_strong_order_pair.lt_iff_le_ne linear_strong_order_pair.lt_iff_le_ne
(take a b : A, (take a b : A,
lt_or_eq_or_lt_cases lt.by_cases
(assume H : a < b, or.inl (le_of_lt H)) (assume H : a < b, or.inl (le_of_lt H))
(assume H1 : a = b, or.inl (H1 ▸ !le.refl)) (assume H1 : a = b, or.inl (H1 ▸ !le.refl))
(assume H1 : b < a, or.inr (le_of_lt H1))) (assume H1 : b < a, or.inr (le_of_lt H1)))
definition le_of_not_lt {a b : A} (H : ¬ a < b) : b ≤ a := definition le_of_not_lt {a b : A} (H : ¬ a < b) : b ≤ a :=
lt_or_eq_or_lt_cases (assume H', absurd H' H) (assume H', H' ▸ !le.refl) (assume H', le_of_lt H') lt.by_cases (assume H', absurd H' H) (assume H', H' ▸ !le.refl) (assume H', le_of_lt H')
definition lt_of_not_le {a b : A} (H : ¬ a ≤ b) : b < a := definition lt_of_not_le {a b : A} (H : ¬ a ≤ b) : b < a :=
lt_or_eq_or_lt_cases lt.by_cases
(assume H', absurd (le_of_lt H') H) (assume H', absurd (le_of_lt H') H)
(assume H', absurd (H' ▸ !le.refl) H) (assume H', absurd (H' ▸ !le.refl) H)
(assume H', H') (assume H', H')
end end
end algebra end algebra

View file

@ -5,114 +5,125 @@ Released under Apache 2.0 license as described in the file LICENSE.
Module: algebra.ordered_group Module: algebra.ordered_group
Authors: Jeremy Avigad Authors: Jeremy Avigad
Partially ordered additive groups. Modeled on Isabelle's library. The comments below indicate that Partially ordered additive groups, modeled on Isabelle's library. We could refine the structures,
we could refine the structures, though we would have to declare more inheritance paths. but we would have to declare more inheritance paths.
-/ -/
import logic.eq data.unit data.sigma data.prod import logic.eq data.unit data.sigma data.prod
import algebra.function algebra.binary import algebra.function algebra.binary
import algebra.group algebra.order import algebra.group algebra.order
open eq eq.ops -- note: ⁻¹ will be overloaded open eq eq.ops -- note: ⁻¹ will be overloaded
namespace algebra namespace algebra
variable {A : Type} variable {A : Type}
/- partially ordered monoids, such as the natural numbers -/
structure ordered_cancel_comm_monoid [class] (A : Type) extends add_comm_monoid A, structure ordered_cancel_comm_monoid [class] (A : Type) extends add_comm_monoid A,
add_left_cancel_semigroup A, add_right_cancel_semigroup A, order_pair A := add_left_cancel_semigroup A, add_right_cancel_semigroup A, order_pair A :=
(add_le_add_left : ∀a b, le a b → ∀c, le (add c a) (add c b)) (add_le_add_left : ∀a b, le a b → ∀c, le (add c a) (add c b))
(le_of_add_le_add_left : ∀a b c, le (add a b) (add a c) → le b c) (le_of_add_le_add_left : ∀a b c, le (add a b) (add a c) → le b c)
section section
variables [s : ordered_cancel_comm_monoid A]
variables [s : ordered_cancel_comm_monoid A] (a b c d e : A) variables {a b c d e : A}
include s include s
theorem add_le_add_left {a b : A} (H : a ≤ b) (c : A) : c + a ≤ c + b := theorem add_le_add_left (H : a ≤ b) (c : A) : c + a ≤ c + b :=
!ordered_cancel_comm_monoid.add_le_add_left H c !ordered_cancel_comm_monoid.add_le_add_left H c
theorem add_le_add_right {a b : A} (H : a ≤ b) (c : A) : a + c ≤ b + c := theorem add_le_add_right (H : a ≤ b) (c : A) : a + c ≤ b + c :=
(add.comm c a) ▸ (add.comm c b) ▸ (add_le_add_left H c) (add.comm c a) ▸ (add.comm c b) ▸ (add_le_add_left H c)
theorem add_le_add {a b c d : A} (Hab : a ≤ b) (Hcd : c ≤ d) : a + c ≤ b + d := theorem add_le_add (Hab : a ≤ b) (Hcd : c ≤ d) : a + c ≤ b + d :=
le.trans (add_le_add_right Hab c) (add_le_add_left Hcd b) le.trans (add_le_add_right Hab c) (add_le_add_left Hcd b)
theorem add_lt_add_left {a b : A} (H : a < b) (c : A) : c + a < c + b := theorem add_lt_add_left (H : a < b) (c : A) : c + a < c + b :=
have H1 : c + a ≤ c + b, from add_le_add_left (le_of_lt H) c, have H1 : c + a ≤ c + b, from add_le_add_left (le_of_lt H) c,
have H2 : c + a ≠ c + b, from have H2 : c + a ≠ c + b, from
take H3 : c + a = c + b, take H3 : c + a = c + b,
have H4 : a = b, from add.left_cancel H3, have H4 : a = b, from add.left_cancel H3,
lt.ne H H4, ne_of_lt H H4,
lt_of_le_of_ne H1 H2 lt_of_le_of_ne H1 H2
theorem add_lt_add_right {a b : A} (H : a < b) (c : A) : a + c < b + c := theorem add_lt_add_right (H : a < b) (c : A) : a + c < b + c :=
(add.comm c a) ▸ (add.comm c b) ▸ (add_lt_add_left H c) (add.comm c a) ▸ (add.comm c b) ▸ (add_lt_add_left H c)
theorem add_lt_add_of_lt_of_lt {a b c d : A} (Hab : a < b) (Hcd : c < d) : a + c < b + d := theorem le_add_of_nonneg_right (H : b ≥ 0) : a ≤ a + b :=
!add_zero ▸ add_le_add_left H a
theorem le_add_of_nonneg_left (H : b ≥ 0) : a ≤ b + a :=
!zero_add ▸ add_le_add_right H a
theorem add_lt_add (Hab : a < b) (Hcd : c < d) : a + c < b + d :=
lt.trans (add_lt_add_right Hab c) (add_lt_add_left Hcd b) lt.trans (add_lt_add_right Hab c) (add_lt_add_left Hcd b)
theorem add_lt_add_of_le_of_lt {a b c d : A} (Hab : a ≤ b) (Hcd : c < d) : a + c < b + d := theorem add_lt_add_of_le_of_lt (Hab : a ≤ b) (Hcd : c < d) : a + c < b + d :=
lt_of_le_of_lt (add_le_add_right Hab c) (add_lt_add_left Hcd b) lt_of_le_of_lt (add_le_add_right Hab c) (add_lt_add_left Hcd b)
theorem add_lt_add_of_lt_of_le {a b c d : A} (Hab : a < b) (Hcd : c ≤ d) : a + c < b + d := theorem add_lt_add_of_lt_of_le (Hab : a < b) (Hcd : c ≤ d) : a + c < b + d :=
lt_of_lt_of_le (add_lt_add_right Hab c) (add_le_add_left Hcd b) lt_of_lt_of_le (add_lt_add_right Hab c) (add_le_add_left Hcd b)
theorem lt_add_of_pos_right (H : b > 0) : a < a + b := !add_zero ▸ add_lt_add_left H a
theorem lt_add_of_pos_left (H : b > 0) : a < b + a := !zero_add ▸ add_lt_add_right H a
-- here we start using le_of_add_le_add_left. -- here we start using le_of_add_le_add_left.
theorem le_of_add_le_add_left {a b c : A} (H : a + b ≤ a + c) : b ≤ c := theorem le_of_add_le_add_left (H : a + b ≤ a + c) : b ≤ c :=
!ordered_cancel_comm_monoid.le_of_add_le_add_left H !ordered_cancel_comm_monoid.le_of_add_le_add_left H
theorem le_of_add_le_add_right {a b c : A} (H : a + b ≤ c + b) : a ≤ c := theorem le_of_add_le_add_right (H : a + b ≤ c + b) : a ≤ c :=
le_of_add_le_add_left ((add.comm a b) ▸ (add.comm c b) ▸ H) le_of_add_le_add_left ((add.comm a b) ▸ (add.comm c b) ▸ H)
theorem lt_of_add_lt_add_left {a b c : A} (H : a + b < a + c) : b < c := theorem lt_of_add_lt_add_left (H : a + b < a + c) : b < c :=
have H1 : b ≤ c, from le_of_add_le_add_left (le_of_lt H), have H1 : b ≤ c, from le_of_add_le_add_left (le_of_lt H),
have H2 : b ≠ c, from have H2 : b ≠ c, from
assume H3 : b = c, lt.irrefl _ (H3 ▸ H), assume H3 : b = c, lt.irrefl _ (H3 ▸ H),
lt_of_le_of_ne H1 H2 lt_of_le_of_ne H1 H2
theorem lt_of_add_lt_add_right {a b c : A} (H : a + b < c + b) : a < c := theorem lt_of_add_lt_add_right (H : a + b < c + b) : a < c :=
lt_of_add_lt_add_left ((add.comm a b) ▸ (add.comm c b) ▸ H) lt_of_add_lt_add_left ((add.comm a b) ▸ (add.comm c b) ▸ H)
theorem add_le_add_left_iff : a + b ≤ a + c ↔ b ≤ c := theorem add_le_add_left_iff (a b c : A) : a + b ≤ a + c ↔ b ≤ c :=
iff.intro le_of_add_le_add_left (assume H, add_le_add_left H _) iff.intro le_of_add_le_add_left (assume H, add_le_add_left H _)
theorem add_le_add_right_iff : a + b ≤ c + b ↔ a ≤ c := theorem add_le_add_right_iff (a b c : A) : a + b ≤ c + b ↔ a ≤ c :=
iff.intro le_of_add_le_add_right (assume H, add_le_add_right H _) iff.intro le_of_add_le_add_right (assume H, add_le_add_right H _)
theorem add_lt_add_left_iff : a + b < a + c ↔ b < c := theorem add_lt_add_left_iff (a b c : A) : a + b < a + c ↔ b < c :=
iff.intro lt_of_add_lt_add_left (assume H, add_lt_add_left H _) iff.intro lt_of_add_lt_add_left (assume H, add_lt_add_left H _)
theorem add_lt_add_right_iff : a + b < c + b ↔ a < c := theorem add_lt_add_right_iff (a b c : A) : a + b < c + b ↔ a < c :=
iff.intro lt_of_add_lt_add_right (assume H, add_lt_add_right H _) iff.intro lt_of_add_lt_add_right (assume H, add_lt_add_right H _)
-- here we start using properties of zero. -- here we start using properties of zero.
theorem add_nonneg {a b : A} (Ha : 0 ≤ a) (Hb : 0 ≤ b) : 0 ≤ a + b := theorem add_nonneg (Ha : 0 ≤ a) (Hb : 0 ≤ b) : 0 ≤ a + b :=
!zero_add ▸ (add_le_add Ha Hb) !zero_add ▸ (add_le_add Ha Hb)
theorem add_pos_of_pos_of_nonneg {a b : A} (Ha : 0 < a) (Hb : 0 ≤ b) : 0 < a + b := theorem add_pos (Ha : 0 < a) (Hb : 0 < b) : 0 < a + b :=
!zero_add ▸ (add_lt_add Ha Hb)
theorem add_pos_of_pos_of_nonneg (Ha : 0 < a) (Hb : 0 ≤ b) : 0 < a + b :=
!zero_add ▸ (add_lt_add_of_lt_of_le Ha Hb) !zero_add ▸ (add_lt_add_of_lt_of_le Ha Hb)
theorem add_pos_of_nonneg_of_pos {a b : A} (Ha : 0 ≤ a) (Hb : 0 < b) : 0 < a + b := theorem add_pos_of_nonneg_of_pos (Ha : 0 ≤ a) (Hb : 0 < b) : 0 < a + b :=
!zero_add ▸ (add_lt_add_of_le_of_lt Ha Hb) !zero_add ▸ (add_lt_add_of_le_of_lt Ha Hb)
theorem add_pos_of_pos_of_pos {a b : A} (Ha : 0 < a) (Hb : 0 < b) : 0 < a + b := theorem add_nonpos (Ha : a ≤ 0) (Hb : b ≤ 0) : a + b ≤ 0 :=
!zero_add ▸ (add_lt_add_of_lt_of_lt Ha Hb)
theorem add_nonpos {a b : A} (Ha : a ≤ 0) (Hb : b ≤ 0) : a + b ≤ 0 :=
!zero_add ▸ (add_le_add Ha Hb) !zero_add ▸ (add_le_add Ha Hb)
theorem add_neg_of_neg_of_nonpos {a b : A} (Ha : a < 0) (Hb : b ≤ 0) : a + b < 0 := theorem add_neg (Ha : a < 0) (Hb : b < 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add Ha Hb)
theorem add_neg_of_neg_of_nonpos (Ha : a < 0) (Hb : b ≤ 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add_of_lt_of_le Ha Hb) !zero_add ▸ (add_lt_add_of_lt_of_le Ha Hb)
theorem add_neg_of_nonpos_of_neg {a b : A} (Ha : a ≤ 0) (Hb : b < 0) : a + b < 0 := theorem add_neg_of_nonpos_of_neg (Ha : a ≤ 0) (Hb : b < 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add_of_le_of_lt Ha Hb) !zero_add ▸ (add_lt_add_of_le_of_lt Ha Hb)
theorem add_neg_of_neg_of_neg {a b : A} (Ha : a < 0) (Hb : b < 0) : a + b < 0 :=
!zero_add ▸ (add_lt_add_of_lt_of_lt Ha Hb)
-- TODO: add nonpos version (will be easier with simplifier) -- TODO: add nonpos version (will be easier with simplifier)
theorem add_eq_zero_iff_eq_zero_and_eq_zero_of_nonneg_of_noneng {a b : A} theorem add_eq_zero_iff_eq_zero_and_eq_zero_of_nonneg_of_nonneg
(Ha : 0 ≤ a) (Hb : 0 ≤ b) : a + b = 0 ↔ a = 0 ∧ b = 0 := (Ha : 0 ≤ a) (Hb : 0 ≤ b) : a + b = 0 ↔ a = 0 ∧ b = 0 :=
iff.intro iff.intro
(assume Hab : a + b = 0, (assume Hab : a + b = 0,
@ -121,13 +132,13 @@ section
a = a + 0 : add_zero a = a + 0 : add_zero
... ≤ a + b : add_le_add_left Hb ... ≤ a + b : add_le_add_left Hb
... = 0 : Hab, ... = 0 : Hab,
have Haz : a = 0, from le.antisym Ha' Ha, have Haz : a = 0, from le.antisymm Ha' Ha,
have Hb' : b ≤ 0, from have Hb' : b ≤ 0, from
calc calc
b = 0 + b : zero_add b = 0 + b : zero_add
... ≤ a + b : add_le_add_right Ha ... ≤ a + b : add_le_add_right Ha
... = 0 : Hab, ... = 0 : Hab,
have Hbz : b = 0, from le.antisym Hb' Hb, have Hbz : b = 0, from le.antisymm Hb' Hb,
and.intro Haz Hbz) and.intro Haz Hbz)
(assume Hab : a = 0 ∧ b = 0, (assume Hab : a = 0 ∧ b = 0,
(and.elim_left Hab)⁻¹ ▸ (and.elim_right Hab)⁻¹ ▸ (add_zero 0)) (and.elim_left Hab)⁻¹ ▸ (and.elim_right Hab)⁻¹ ▸ (add_zero 0))
@ -163,10 +174,10 @@ section
!add_zero ▸ add_lt_add_of_lt_of_le Hbc Ha !add_zero ▸ add_lt_add_of_lt_of_le Hbc Ha
theorem lt_add_of_pos_of_lt (Ha : 0 < a) (Hbc : b < c) : b < a + c := theorem lt_add_of_pos_of_lt (Ha : 0 < a) (Hbc : b < c) : b < a + c :=
!zero_add ▸ add_lt_add_of_lt_of_lt Ha Hbc !zero_add ▸ add_lt_add Ha Hbc
theorem lt_add_of_lt_of_pos (Hbc : b < c) (Ha : 0 < a) : b < c + a := theorem lt_add_of_lt_of_pos (Hbc : b < c) (Ha : 0 < a) : b < c + a :=
!add_zero ▸ add_lt_add_of_lt_of_lt Hbc Ha !add_zero ▸ add_lt_add Hbc Ha
theorem add_lt_of_nonpos_of_lt (Ha : a ≤ 0) (Hbc : b < c) : a + b < c := theorem add_lt_of_nonpos_of_lt (Ha : a ≤ 0) (Hbc : b < c) : a + b < c :=
!zero_add ▸ add_lt_add_of_le_of_lt Ha Hbc !zero_add ▸ add_lt_add_of_le_of_lt Ha Hbc
@ -175,28 +186,25 @@ section
!add_zero ▸ add_lt_add_of_lt_of_le Hbc Ha !add_zero ▸ add_lt_add_of_lt_of_le Hbc Ha
theorem add_lt_of_neg_of_lt (Ha : a < 0) (Hbc : b < c) : a + b < c := theorem add_lt_of_neg_of_lt (Ha : a < 0) (Hbc : b < c) : a + b < c :=
!zero_add ▸ add_lt_add_of_lt_of_lt Ha Hbc !zero_add ▸ add_lt_add Ha Hbc
theorem add_lt_of_lt_of_neg (Hbc : b < c) (Ha : a < 0) : b + a < c := theorem add_lt_of_lt_of_neg (Hbc : b < c) (Ha : a < 0) : b + a < c :=
!add_zero ▸ add_lt_add_of_lt_of_lt Hbc Ha !add_zero ▸ add_lt_add Hbc Ha
end end
-- TODO: there is more we can do if we have max and min (in order.lean as well) -- TODO: add properties of max and min
-- TODO: there is more we can do if we assume a ≤ b ↔ ∃c. a + c = b. /- partially ordered groups -/
-- This covers the natural numbers,
-- but it is not clear whether it provides any further useful generality.
structure ordered_comm_group [class] (A : Type) extends add_comm_group A, order_pair A := structure ordered_comm_group [class] (A : Type) extends add_comm_group A, order_pair A :=
(add_le_add_left : ∀a b, le a b → ∀c, le (add c a) (add c b)) (add_le_add_left : ∀a b, le a b → ∀c, le (add c a) (add c b))
definition ordered_comm_group.to_ordered_cancel_comm_monoid [instance] (A : Type) definition ordered_comm_group.to_ordered_cancel_comm_monoid [instance] [coercion]
[s : ordered_comm_group A] : ordered_cancel_comm_monoid A := [s : ordered_comm_group A] : ordered_cancel_comm_monoid A :=
ordered_cancel_comm_monoid.mk ordered_comm_group.add ordered_comm_group.add_assoc ordered_cancel_comm_monoid.mk ordered_comm_group.add ordered_comm_group.add_assoc
(@ordered_comm_group.zero A s) zero_add add_zero ordered_comm_group.add_comm (@ordered_comm_group.zero A s) zero_add add_zero ordered_comm_group.add_comm
(@add.left_cancel _ _) (@add.right_cancel _ _) (@add.left_cancel _ _) (@add.right_cancel _ _)
has_le.le le.refl (@le.trans _ _) (@le.antisym _ _) has_le.le le.refl (@le.trans _ _) (@le.antisymm _ _)
has_lt.lt (@lt_iff_le_and_ne _ _) ordered_comm_group.add_le_add_left has_lt.lt (@lt_iff_le_and_ne _ _) ordered_comm_group.add_le_add_left
proof proof
take a b c : A, take a b c : A,
@ -206,17 +214,16 @@ proof
qed qed
section section
variables [s : ordered_comm_group A] (a b c d e : A) variables [s : ordered_comm_group A] (a b c d e : A)
include s include s
theorem neg_le_neg_of_le {a b : A} (H : a ≤ b) : -b ≤ -a := theorem neg_le_neg {a b : A} (H : a ≤ b) : -b ≤ -a :=
have H1 : 0 ≤ -a + b, from !add.left_inv ▸ !(add_le_add_left H), have H1 : 0 ≤ -a + b, from !add.left_inv ▸ !(add_le_add_left H),
!add_neg_cancel_right ▸ !zero_add ▸ add_le_add_right H1 (-b) !add_neg_cancel_right ▸ !zero_add ▸ add_le_add_right H1 (-b)
-- !zero_add ▸ !add_neg_cancel_right ▸ add_le_add_right H1 (-b) -- doesn't work? -- !zero_add ▸ !add_neg_cancel_right ▸ add_le_add_right H1 (-b) -- doesn't work
theorem neg_le_neg_iff_le : -a ≤ -b ↔ b ≤ a := theorem neg_le_neg_iff_le : -a ≤ -b ↔ b ≤ a :=
iff.intro (take H, neg_neg a ▸ neg_neg b ▸ neg_le_neg_of_le H) neg_le_neg_of_le iff.intro (take H, neg_neg a ▸ neg_neg b ▸ neg_le_neg H) neg_le_neg
theorem neg_nonpos_iff_nonneg : -a ≤ 0 ↔ 0 ≤ a := theorem neg_nonpos_iff_nonneg : -a ≤ 0 ↔ 0 ≤ a :=
neg_zero ▸ neg_le_neg_iff_le a 0 neg_zero ▸ neg_le_neg_iff_le a 0
@ -224,12 +231,12 @@ section
theorem neg_nonneg_iff_nonpos : 0 ≤ -a ↔ a ≤ 0 := theorem neg_nonneg_iff_nonpos : 0 ≤ -a ↔ a ≤ 0 :=
neg_zero ▸ neg_le_neg_iff_le 0 a neg_zero ▸ neg_le_neg_iff_le 0 a
theorem neg_lt_neg_of_lt {a b : A} (H : a < b) : -b < -a := theorem neg_lt_neg {a b : A} (H : a < b) : -b < -a :=
have H1 : 0 < -a + b, from !add.left_inv ▸ !(add_lt_add_left H), have H1 : 0 < -a + b, from !add.left_inv ▸ !(add_lt_add_left H),
!add_neg_cancel_right ▸ !zero_add ▸ add_lt_add_right H1 (-b) !add_neg_cancel_right ▸ !zero_add ▸ add_lt_add_right H1 (-b)
theorem neg_lt_neg_iff_lt : -a < -b ↔ b < a := theorem neg_lt_neg_iff_lt : -a < -b ↔ b < a :=
iff.intro (take H, neg_neg a ▸ neg_neg b ▸ neg_lt_neg_of_lt H) neg_lt_neg_of_lt iff.intro (take H, neg_neg a ▸ neg_neg b ▸ neg_lt_neg H) neg_lt_neg
theorem neg_neg_iff_pos : -a < 0 ↔ 0 < a := theorem neg_neg_iff_pos : -a < 0 ↔ 0 < a :=
neg_zero ▸ neg_lt_neg_iff_lt a 0 neg_zero ▸ neg_lt_neg_iff_lt a 0
@ -275,27 +282,32 @@ section
have H: a ≤ b + c ↔ a - c ≤ b + c - c, from iff.symm (!add_le_add_right_iff), have H: a ≤ b + c ↔ a - c ≤ b + c - c, from iff.symm (!add_le_add_right_iff),
!add_neg_cancel_right ▸ H !add_neg_cancel_right ▸ H
theorem add_lt_add_iff_lt_neg_add : a + b < c ↔ b < -a + c := theorem add_lt_iff_lt_neg_add_left : a + b < c ↔ b < -a + c :=
have H: a + b < c ↔ -a + (a + b) < -a + c, from iff.symm (!add_lt_add_left_iff), have H: a + b < c ↔ -a + (a + b) < -a + c, from iff.symm (!add_lt_add_left_iff),
!neg_add_cancel_left ▸ H !neg_add_cancel_left ▸ H
theorem add_lt_add_iff_lt_sub_left : a + b < c ↔ b < c - a := theorem add_lt_iff_lt_neg_add_right : a + b < c ↔ a < -b + c :=
!add.comm ▸ !add_lt_add_iff_lt_neg_add !add.comm ▸ !add_lt_iff_lt_neg_add_left
theorem add_lt_iff_lt_sub_left : a + b < c ↔ b < c - a :=
!add.comm ▸ !add_lt_iff_lt_neg_add_left
theorem add_lt_add_iff_lt_sub_right : a + b < c ↔ a < c - b := theorem add_lt_add_iff_lt_sub_right : a + b < c ↔ a < c - b :=
have H: a + b < c ↔ a + b - b < c - b, from iff.symm (!add_lt_add_right_iff), have H: a + b < c ↔ a + b - b < c - b, from iff.symm (!add_lt_add_right_iff),
!add_neg_cancel_right ▸ H !add_neg_cancel_right ▸ H
theorem lt_add_iff_neg_add_lt_add : a < b + c ↔ -b + a < c := theorem lt_add_iff_neg_add_lt_left : a < b + c ↔ -b + a < c :=
have H: a < b + c ↔ -b + a < -b + (b + c), from iff.symm (!add_lt_add_left_iff), have H: a < b + c ↔ -b + a < -b + (b + c), from iff.symm (!add_lt_add_left_iff),
!neg_add_cancel_left ▸ H !neg_add_cancel_left ▸ H
theorem lt_add_iff_sub_left_lt : a < b + c ↔ a - b < c := theorem lt_add_iff_neg_add_lt_right : a < b + c ↔ -c + a < b :=
!add.comm ▸ !lt_add_iff_neg_add_lt_add !add.comm ▸ !lt_add_iff_neg_add_lt_left
theorem lt_add_iff_sub_right_lt : a < b + c ↔ a - c < b := theorem lt_add_iff_sub_lt_left : a < b + c ↔ a - b < c :=
have H: a < b + c ↔ a - c < b + c - c, from iff.symm (!add_lt_add_right_iff), !add.comm ▸ !lt_add_iff_neg_add_lt_left
!add_neg_cancel_right ▸ H
theorem lt_add_iff_sub_lt_right : a < b + c ↔ a - c < b :=
!add.comm ▸ !lt_add_iff_sub_lt_left
-- TODO: the Isabelle library has varations on a + b ≤ b ↔ a ≤ 0 -- TODO: the Isabelle library has varations on a + b ≤ b ↔ a ≤ 0
@ -312,31 +324,29 @@ section
... ↔ c < d : sub_neg_iff_lt c d ... ↔ c < d : sub_neg_iff_lt c d
theorem sub_le_sub_left {a b : A} (H : a ≤ b) (c : A) : c - b ≤ c - a := theorem sub_le_sub_left {a b : A} (H : a ≤ b) (c : A) : c - b ≤ c - a :=
add_le_add_left (neg_le_neg_of_le H) c add_le_add_left (neg_le_neg H) c
theorem sub_le_sub_right {a b : A} (H : a ≤ b) (c : A) : a - c ≤ b - c := add_le_add_right H (-c) theorem sub_le_sub_right {a b : A} (H : a ≤ b) (c : A) : a - c ≤ b - c := add_le_add_right H (-c)
theorem sub_le_sub {a b c d : A} (Hab : a ≤ b) (Hcd : c ≤ d) : a - d ≤ b - c := theorem sub_le_sub {a b c d : A} (Hab : a ≤ b) (Hcd : c ≤ d) : a - d ≤ b - c :=
add_le_add Hab (neg_le_neg_of_le Hcd) add_le_add Hab (neg_le_neg Hcd)
theorem sub_lt_sub_left {a b : A} (H : a < b) (c : A) : c - b < c - a := theorem sub_lt_sub_left {a b : A} (H : a < b) (c : A) : c - b < c - a :=
add_lt_add_left (neg_lt_neg_of_lt H) c add_lt_add_left (neg_lt_neg H) c
theorem sub_lt_sub_right {a b : A} (H : a < b) (c : A) : a - c < b - c := add_lt_add_right H (-c) theorem sub_lt_sub_right {a b : A} (H : a < b) (c : A) : a - c < b - c := add_lt_add_right H (-c)
theorem sub_lt_sub_of_lt_of_lt {a b c d : A} (Hab : a < b) (Hcd : c < d) : a - d < b - c := theorem sub_lt_sub {a b c d : A} (Hab : a < b) (Hcd : c < d) : a - d < b - c :=
add_lt_add_of_lt_of_lt Hab (neg_lt_neg_of_lt Hcd) add_lt_add Hab (neg_lt_neg Hcd)
theorem sub_lt_sub_of_le_of_lt {a b c d : A} (Hab : a ≤ b) (Hcd : c < d) : a - d < b - c := theorem sub_lt_sub_of_le_of_lt {a b c d : A} (Hab : a ≤ b) (Hcd : c < d) : a - d < b - c :=
add_lt_add_of_le_of_lt Hab (neg_lt_neg_of_lt Hcd) add_lt_add_of_le_of_lt Hab (neg_lt_neg Hcd)
theorem sub_lt_sub_of_lt_of_le {a b c d : A} (Hab : a < b) (Hcd : c ≤ d) : a - d < b - c := theorem sub_lt_sub_of_lt_of_le {a b c d : A} (Hab : a < b) (Hcd : c ≤ d) : a - d < b - c :=
add_lt_add_of_lt_of_le Hab (neg_le_neg_of_le Hcd) add_lt_add_of_lt_of_le Hab (neg_le_neg Hcd)
end end
-- TODO: additional facts if the ordering is a linear ordering (e.g. -a = a ↔ a = 0) -- TODO: additional facts if the ordering is a linear ordering (e.g. -a = a ↔ a = 0)
-- TODO: abs and sign
-- TODO: structures with abs
end algebra end algebra

View file

@ -5,17 +5,12 @@ Released under Apache 2.0 license as described in the file LICENSE.
Module: algebra.ordered_ring Module: algebra.ordered_ring
Authors: Jeremy Avigad Authors: Jeremy Avigad
Rather than multiply classes unnecessarily, we are aiming for the ones that are likely to be useful. Here an "ordered_ring" is partially ordered ring, which is ordered with respect to both a weak
We can always split them apart later if necessary. Here an "ordered_ring" is partial ordered ring (which order and an associated strict order. Our numeric structures (int, rat, and real) will be instances
is ordered with respect to both a weak order and an associated strict order). Our numeric structures will be of "linear_ordered_comm_ring". This development is modeled after Isabelle's library.
instances of "linear_ordered_comm_ring".
This development is modeled after Isabelle's library.
-/ -/
import logic.eq data.unit data.sigma data.prod import algebra.ordered_group algebra.ring
import algebra.function algebra.binary algebra.ordered_group algebra.ring
open eq eq.ops open eq eq.ops
namespace algebra namespace algebra
@ -23,13 +18,12 @@ namespace algebra
variable {A : Type} variable {A : Type}
structure ordered_semiring [class] (A : Type) extends semiring A, ordered_cancel_comm_monoid A := structure ordered_semiring [class] (A : Type) extends semiring A, ordered_cancel_comm_monoid A :=
(mul_le_mul_left: ∀a b c, le a b → le zero c → le (mul c a) (mul c b)) (mul_le_mul_of_nonneg_left: ∀a b c, le a b → le zero c → le (mul c a) (mul c b))
(mul_le_mul_right: ∀a b c, le a b → le zero c → le (mul a c) (mul b c)) (mul_le_mul_of_nonneg_right: ∀a b c, le a b → le zero c → le (mul a c) (mul b c))
(mul_lt_mul_left: ∀a b c, lt a b → lt zero c → lt (mul c a) (mul c b)) (mul_lt_mul_of_pos_left: ∀a b c, lt a b → lt zero c → lt (mul c a) (mul c b))
(mul_lt_mul_right: ∀a b c, lt a b → lt zero c → lt (mul a c) (mul b c)) (mul_lt_mul_of_pos_right: ∀a b c, lt a b → lt zero c → lt (mul a c) (mul b c))
section section
variable [s : ordered_semiring A] variable [s : ordered_semiring A]
variables (a b c d e : A) variables (a b c d e : A)
include s include s
@ -43,10 +37,10 @@ section
has_zero.mk (@ordered_semiring.zero A s) has_zero.mk (@ordered_semiring.zero A s)
theorem mul_le_mul_of_nonneg_left {a b c : A} (Hab : a ≤ b) (Hc : 0 ≤ c) : theorem mul_le_mul_of_nonneg_left {a b c : A} (Hab : a ≤ b) (Hc : 0 ≤ c) :
c * a ≤ c * b := !ordered_semiring.mul_le_mul_left Hab Hc c * a ≤ c * b := !ordered_semiring.mul_le_mul_of_nonneg_left Hab Hc
theorem mul_le_mul_of_nonneg_right {a b c : A} (Hab : a ≤ b) (Hc : 0 ≤ c) : theorem mul_le_mul_of_nonneg_right {a b c : A} (Hab : a ≤ b) (Hc : 0 ≤ c) :
a * c ≤ b * c := !ordered_semiring.mul_le_mul_right Hab Hc a * c ≤ b * c := !ordered_semiring.mul_le_mul_of_nonneg_right Hab Hc
-- TODO: there are four variations, depending on which variables we assume to be nonneg -- TODO: there are four variations, depending on which variables we assume to be nonneg
theorem mul_le_mul {a b c d : A} (Hac : a ≤ c) (Hbd : b ≤ d) (nn_b : 0 ≤ b) (nn_c : 0 ≤ c) : theorem mul_le_mul {a b c d : A} (Hac : a ≤ c) (Hbd : b ≤ d) (nn_b : 0 ≤ b) (nn_c : 0 ≤ c) :
@ -55,7 +49,7 @@ section
a * b ≤ c * b : mul_le_mul_of_nonneg_right Hac nn_b a * b ≤ c * b : mul_le_mul_of_nonneg_right Hac nn_b
... ≤ c * d : mul_le_mul_of_nonneg_left Hbd nn_c ... ≤ c * d : mul_le_mul_of_nonneg_left Hbd nn_c
theorem mul_nonneg_of_nonneg_of_nonneg {a b : A} (Ha : a ≥ 0) (Hb : b ≥ 0) : a * b ≥ 0 := theorem mul_nonneg {a b : A} (Ha : a ≥ 0) (Hb : b ≥ 0) : a * b ≥ 0 :=
have H : 0 * b ≤ a * b, from mul_le_mul_of_nonneg_right Ha Hb, have H : 0 * b ≤ a * b, from mul_le_mul_of_nonneg_right Ha Hb,
!zero_mul ▸ H !zero_mul ▸ H
@ -68,10 +62,10 @@ section
!zero_mul ▸ H !zero_mul ▸ H
theorem mul_lt_mul_of_pos_left {a b c : A} (Hab : a < b) (Hc : 0 < c) : theorem mul_lt_mul_of_pos_left {a b c : A} (Hab : a < b) (Hc : 0 < c) :
c * a < c * b := !ordered_semiring.mul_lt_mul_left Hab Hc c * a < c * b := !ordered_semiring.mul_lt_mul_of_pos_left Hab Hc
theorem mul_lt_mul_of_pos_right {a b c : A} (Hab : a < b) (Hc : 0 < c) : theorem mul_lt_mul_of_pos_right {a b c : A} (Hab : a < b) (Hc : 0 < c) :
a * c < b * c := !ordered_semiring.mul_lt_mul_right Hab Hc a * c < b * c := !ordered_semiring.mul_lt_mul_of_pos_right Hab Hc
-- TODO: once again, there are variations -- TODO: once again, there are variations
theorem mul_lt_mul {a b c d : A} (Hac : a < c) (Hbd : b ≤ d) (pos_b : 0 < b) (nn_c : 0 ≤ c) : theorem mul_lt_mul {a b c d : A} (Hac : a < c) (Hbd : b ≤ d) (pos_b : 0 < b) (nn_c : 0 ≤ c) :
@ -80,7 +74,7 @@ section
a * b < c * b : mul_lt_mul_of_pos_right Hac pos_b a * b < c * b : mul_lt_mul_of_pos_right Hac pos_b
... ≤ c * d : mul_le_mul_of_nonneg_left Hbd nn_c ... ≤ c * d : mul_le_mul_of_nonneg_left Hbd nn_c
theorem mul_pos_of_pos_of_pos {a b : A} (Ha : a > 0) (Hb : b > 0) : a * b > 0 := theorem mul_pos {a b : A} (Ha : a > 0) (Hb : b > 0) : a * b > 0 :=
have H : 0 * b < a * b, from mul_lt_mul_of_pos_right Ha Hb, have H : 0 * b < a * b, from mul_lt_mul_of_pos_right Ha Hb,
!zero_mul ▸ H !zero_mul ▸ H
@ -91,16 +85,14 @@ section
theorem mul_neg_of_neg_of_pos {a b : A} (Ha : a < 0) (Hb : b > 0) : a * b < 0 := theorem mul_neg_of_neg_of_pos {a b : A} (Ha : a < 0) (Hb : b > 0) : a * b < 0 :=
have H : a * b < 0 * b, from mul_lt_mul_of_pos_right Ha Hb, have H : a * b < 0 * b, from mul_lt_mul_of_pos_right Ha Hb,
!zero_mul ▸ H !zero_mul ▸ H
end end
structure linear_ordered_semiring [class] (A : Type) structure linear_ordered_semiring [class] (A : Type)
extends ordered_semiring A, linear_strong_order_pair A extends ordered_semiring A, linear_strong_order_pair A
section section
variable [s : linear_ordered_semiring A] variable [s : linear_ordered_semiring A]
variables (a b c : A) variables {a b c : A}
include s include s
-- TODO: remove after we short-circuit class-graph -- TODO: remove after we short-circuit class-graph
@ -111,25 +103,25 @@ section
definition linear_ordered_semiring.to_zero [instance] [priority 100000] : has_zero A := definition linear_ordered_semiring.to_zero [instance] [priority 100000] : has_zero A :=
has_zero.mk (@linear_ordered_semiring.zero A s) has_zero.mk (@linear_ordered_semiring.zero A s)
theorem lt_of_mul_lt_mul_left {a b c : A} (H : c * a < c * b) (Hc : c ≥ 0) : a < b := theorem lt_of_mul_lt_mul_left (H : c * a < c * b) (Hc : c ≥ 0) : a < b :=
lt_of_not_le lt_of_not_le
(assume H1 : b ≤ a, (assume H1 : b ≤ a,
have H2 : c * b ≤ c * a, from mul_le_mul_of_nonneg_left H1 Hc, have H2 : c * b ≤ c * a, from mul_le_mul_of_nonneg_left H1 Hc,
not_lt_of_le H2 H) not_lt_of_le H2 H)
theorem lt_of_mul_lt_mul_right {a b c : A} (H : a * c < b * c) (Hc : c ≥ 0) : a < b := theorem lt_of_mul_lt_mul_right (H : a * c < b * c) (Hc : c ≥ 0) : a < b :=
lt_of_not_le lt_of_not_le
(assume H1 : b ≤ a, (assume H1 : b ≤ a,
have H2 : b * c ≤ a * c, from mul_le_mul_of_nonneg_right H1 Hc, have H2 : b * c ≤ a * c, from mul_le_mul_of_nonneg_right H1 Hc,
not_lt_of_le H2 H) not_lt_of_le H2 H)
theorem le_of_mul_le_mul_left {a b c : A} (H : c * a ≤ c * b) (Hc : c > 0) : a ≤ b := theorem le_of_mul_le_mul_left (H : c * a ≤ c * b) (Hc : c > 0) : a ≤ b :=
le_of_not_lt le_of_not_lt
(assume H1 : b < a, (assume H1 : b < a,
have H2 : c * b < c * a, from mul_lt_mul_of_pos_left H1 Hc, have H2 : c * b < c * a, from mul_lt_mul_of_pos_left H1 Hc,
not_le_of_lt H2 H) not_le_of_lt H2 H)
theorem le_of_mul_le_mul_right {a b c : A} (H : a * c ≤ b * c) (Hc : c > 0) : a ≤ b := theorem le_of_mul_le_mul_right (H : a * c ≤ b * c) (Hc : c > 0) : a ≤ b :=
le_of_not_lt le_of_not_lt
(assume H1 : b < a, (assume H1 : b < a,
have H2 : b * c < a * c, from mul_lt_mul_of_pos_right H1 Hc, have H2 : b * c < a * c, from mul_lt_mul_of_pos_right H1 Hc,
@ -146,21 +138,21 @@ section
(assume H2 : a ≤ 0, (assume H2 : a ≤ 0,
have H3 : a * b ≤ 0, from mul_nonpos_of_nonpos_of_nonneg H2 H1, have H3 : a * b ≤ 0, from mul_nonpos_of_nonpos_of_nonneg H2 H1,
not_lt_of_le H3 H) not_lt_of_le H3 H)
end end
structure ordered_ring [class] (A : Type) extends ring A, ordered_comm_group A := structure ordered_ring [class] (A : Type) extends ring A, ordered_comm_group A :=
(mul_nonneg_of_nonneg_of_nonneg : ∀a b, le zero a → le zero b → le zero (mul a b)) (mul_nonneg : ∀a b, le zero a → le zero b → le zero (mul a b))
(mul_pos_of_pos_of_pos : ∀a b, lt zero a → lt zero b → lt zero (mul a b)) (mul_pos : ∀a b, lt zero a → lt zero b → lt zero (mul a b))
definition ordered_ring.to_ordered_semiring [instance] [s : ordered_ring A] : ordered_semiring A := definition ordered_ring.to_ordered_semiring [instance] [coercion] [s : ordered_ring A] :
ordered_semiring A :=
ordered_semiring.mk ordered_ring.add ordered_ring.add_assoc !ordered_ring.zero ordered_semiring.mk ordered_ring.add ordered_ring.add_assoc !ordered_ring.zero
ordered_ring.zero_add ordered_ring.add_zero ordered_ring.add_comm ordered_ring.mul ordered_ring.zero_add ordered_ring.add_zero ordered_ring.add_comm ordered_ring.mul
ordered_ring.mul_assoc !ordered_ring.one ordered_ring.one_mul ordered_ring.mul_one ordered_ring.mul_assoc !ordered_ring.one ordered_ring.one_mul ordered_ring.mul_one
ordered_ring.left_distrib ordered_ring.right_distrib ordered_ring.left_distrib ordered_ring.right_distrib
zero_mul mul_zero !ordered_ring.zero_ne_one zero_mul mul_zero !ordered_ring.zero_ne_one
(@add.left_cancel A _) (@add.right_cancel A _) (@add.left_cancel A _) (@add.right_cancel A _)
ordered_ring.le ordered_ring.le_refl ordered_ring.le_trans ordered_ring.le_antisym ordered_ring.le ordered_ring.le_refl ordered_ring.le_trans ordered_ring.le_antisymm
ordered_ring.lt ordered_ring.lt_iff_le_ne ordered_ring.add_le_add_left ordered_ring.lt ordered_ring.lt_iff_le_ne ordered_ring.add_le_add_left
(@le_of_add_le_add_left A _) (@le_of_add_le_add_left A _)
(take a b c, (take a b c,
@ -169,7 +161,7 @@ ordered_semiring.mk ordered_ring.add ordered_ring.add_assoc !ordered_ring.zero
show c * a ≤ c * b, show c * a ≤ c * b,
proof proof
have H1 : 0 ≤ b - a, from iff.elim_right !sub_nonneg_iff_le Hab, have H1 : 0 ≤ b - a, from iff.elim_right !sub_nonneg_iff_le Hab,
have H2 : 0 ≤ c * (b - a), from ordered_ring.mul_nonneg_of_nonneg_of_nonneg _ _ Hc H1, have H2 : 0 ≤ c * (b - a), from ordered_ring.mul_nonneg _ _ Hc H1,
iff.mp !sub_nonneg_iff_le (!mul_sub_left_distrib ▸ H2) iff.mp !sub_nonneg_iff_le (!mul_sub_left_distrib ▸ H2)
qed) qed)
(take a b c, (take a b c,
@ -178,7 +170,7 @@ ordered_semiring.mk ordered_ring.add ordered_ring.add_assoc !ordered_ring.zero
show a * c ≤ b * c, show a * c ≤ b * c,
proof proof
have H1 : 0 ≤ b - a, from iff.elim_right !sub_nonneg_iff_le Hab, have H1 : 0 ≤ b - a, from iff.elim_right !sub_nonneg_iff_le Hab,
have H2 : 0 ≤ (b - a) * c, from ordered_ring.mul_nonneg_of_nonneg_of_nonneg _ _ H1 Hc, have H2 : 0 ≤ (b - a) * c, from ordered_ring.mul_nonneg _ _ H1 Hc,
iff.mp !sub_nonneg_iff_le (!mul_sub_right_distrib ▸ H2) iff.mp !sub_nonneg_iff_le (!mul_sub_right_distrib ▸ H2)
qed) qed)
(take a b c, (take a b c,
@ -187,7 +179,7 @@ ordered_semiring.mk ordered_ring.add ordered_ring.add_assoc !ordered_ring.zero
show c * a < c * b, show c * a < c * b,
proof proof
have H1 : 0 < b - a, from iff.elim_right !sub_pos_iff_lt Hab, have H1 : 0 < b - a, from iff.elim_right !sub_pos_iff_lt Hab,
have H2 : 0 < c * (b - a), from ordered_ring.mul_pos_of_pos_of_pos _ _ Hc H1, have H2 : 0 < c * (b - a), from ordered_ring.mul_pos _ _ Hc H1,
iff.mp !sub_pos_iff_lt (!mul_sub_left_distrib ▸ H2) iff.mp !sub_pos_iff_lt (!mul_sub_left_distrib ▸ H2)
qed) qed)
(take a b c, (take a b c,
@ -196,14 +188,13 @@ ordered_semiring.mk ordered_ring.add ordered_ring.add_assoc !ordered_ring.zero
show a * c < b * c, show a * c < b * c,
proof proof
have H1 : 0 < b - a, from iff.elim_right !sub_pos_iff_lt Hab, have H1 : 0 < b - a, from iff.elim_right !sub_pos_iff_lt Hab,
have H2 : 0 < (b - a) * c, from ordered_ring.mul_pos_of_pos_of_pos _ _ H1 Hc, have H2 : 0 < (b - a) * c, from ordered_ring.mul_pos _ _ H1 Hc,
iff.mp !sub_pos_iff_lt (!mul_sub_right_distrib ▸ H2) iff.mp !sub_pos_iff_lt (!mul_sub_right_distrib ▸ H2)
qed) qed)
section section
variable [s : ordered_ring A] variable [s : ordered_ring A]
variables (a b c : A) variables {a b c : A}
include s include s
-- TODO: remove after we short-circuit class-graph -- TODO: remove after we short-circuit class-graph
@ -214,65 +205,107 @@ section
definition ordered_ring.to_zero [instance] [priority 100000] : has_zero A := definition ordered_ring.to_zero [instance] [priority 100000] : has_zero A :=
has_zero.mk (@ordered_ring.zero A s) has_zero.mk (@ordered_ring.zero A s)
theorem mul_le_mul_of_nonpos_left {a b c : A} (H : b ≤ a) (Hc : c ≤ 0) : c * a ≤ c * b := theorem mul_le_mul_of_nonpos_left (H : b ≤ a) (Hc : c ≤ 0) : c * a ≤ c * b :=
have Hc' : -c ≥ 0, from iff.mp' !neg_nonneg_iff_nonpos Hc, have Hc' : -c ≥ 0, from iff.mp' !neg_nonneg_iff_nonpos Hc,
have H1 : -c * b ≤ -c * a, from mul_le_mul_of_nonneg_left H Hc', have H1 : -c * b ≤ -c * a, from mul_le_mul_of_nonneg_left H Hc',
have H2 : -(c * b) ≤ -(c * a), from !neg_mul_eq_neg_mul⁻¹ ▸ !neg_mul_eq_neg_mul⁻¹ ▸ H1, have H2 : -(c * b) ≤ -(c * a), from !neg_mul_eq_neg_mul⁻¹ ▸ !neg_mul_eq_neg_mul⁻¹ ▸ H1,
iff.mp !neg_le_neg_iff_le H2 iff.mp !neg_le_neg_iff_le H2
theorem mul_le_mul_of_nonpos_right {a b c : A} (H : b ≤ a) (Hc : c ≤ 0) : a * c ≤ b * c := theorem mul_le_mul_of_nonpos_right (H : b ≤ a) (Hc : c ≤ 0) : a * c ≤ b * c :=
have Hc' : -c ≥ 0, from iff.mp' !neg_nonneg_iff_nonpos Hc, have Hc' : -c ≥ 0, from iff.mp' !neg_nonneg_iff_nonpos Hc,
have H1 : b * -c ≤ a * -c, from mul_le_mul_of_nonneg_right H Hc', have H1 : b * -c ≤ a * -c, from mul_le_mul_of_nonneg_right H Hc',
have H2 : -(b * c) ≤ -(a * c), from !neg_mul_eq_mul_neg⁻¹ ▸ !neg_mul_eq_mul_neg⁻¹ ▸ H1, have H2 : -(b * c) ≤ -(a * c), from !neg_mul_eq_mul_neg⁻¹ ▸ !neg_mul_eq_mul_neg⁻¹ ▸ H1,
iff.mp !neg_le_neg_iff_le H2 iff.mp !neg_le_neg_iff_le H2
theorem mul_nonneg_of_nonpos_of_nonpos {a b : A} (Ha : a ≤ 0) (Hb : b ≤ 0) : 0 ≤ a * b := theorem mul_nonneg_of_nonpos_of_nonpos (Ha : a ≤ 0) (Hb : b ≤ 0) : 0 ≤ a * b :=
!zero_mul ▸ mul_le_mul_of_nonpos_right Ha Hb !zero_mul ▸ mul_le_mul_of_nonpos_right Ha Hb
theorem mul_lt_mul_of_neg_left {a b c : A} (H : b < a) (Hc : c < 0) : c * a < c * b := theorem mul_lt_mul_of_neg_left (H : b < a) (Hc : c < 0) : c * a < c * b :=
have Hc' : -c > 0, from iff.mp' !neg_pos_iff_neg Hc, have Hc' : -c > 0, from iff.mp' !neg_pos_iff_neg Hc,
have H1 : -c * b < -c * a, from mul_lt_mul_of_pos_left H Hc', have H1 : -c * b < -c * a, from mul_lt_mul_of_pos_left H Hc',
have H2 : -(c * b) < -(c * a), from !neg_mul_eq_neg_mul⁻¹ ▸ !neg_mul_eq_neg_mul⁻¹ ▸ H1, have H2 : -(c * b) < -(c * a), from !neg_mul_eq_neg_mul⁻¹ ▸ !neg_mul_eq_neg_mul⁻¹ ▸ H1,
iff.mp !neg_lt_neg_iff_lt H2 iff.mp !neg_lt_neg_iff_lt H2
theorem mul_lt_mul_of_neg_right {a b c : A} (H : b < a) (Hc : c < 0) : a * c < b * c := theorem mul_lt_mul_of_neg_right (H : b < a) (Hc : c < 0) : a * c < b * c :=
have Hc' : -c > 0, from iff.mp' !neg_pos_iff_neg Hc, have Hc' : -c > 0, from iff.mp' !neg_pos_iff_neg Hc,
have H1 : b * -c < a * -c, from mul_lt_mul_of_pos_right H Hc', have H1 : b * -c < a * -c, from mul_lt_mul_of_pos_right H Hc',
have H2 : -(b * c) < -(a * c), from !neg_mul_eq_mul_neg⁻¹ ▸ !neg_mul_eq_mul_neg⁻¹ ▸ H1, have H2 : -(b * c) < -(a * c), from !neg_mul_eq_mul_neg⁻¹ ▸ !neg_mul_eq_mul_neg⁻¹ ▸ H1,
iff.mp !neg_lt_neg_iff_lt H2 iff.mp !neg_lt_neg_iff_lt H2
theorem mul_pos_of_neg_of_neg {a b : A} (Ha : a < 0) (Hb : b < 0) : 0 < a * b := theorem mul_pos_of_neg_of_neg (Ha : a < 0) (Hb : b < 0) : 0 < a * b :=
!zero_mul ▸ mul_lt_mul_of_neg_right Ha Hb !zero_mul ▸ mul_lt_mul_of_neg_right Ha Hb
end end
-- TODO: we can eliminate mul_pos_of_pos, but now it is not worth the effort to redeclare the class instance -- TODO: we can eliminate mul_pos_of_pos, but now it is not worth the effort to redeclare the
-- class instance
structure linear_ordered_ring [class] (A : Type) extends ordered_ring A, linear_strong_order_pair A structure linear_ordered_ring [class] (A : Type) extends ordered_ring A, linear_strong_order_pair A
-- TODO: after we break out definition of divides, show that this is an instance of integral domain, -- print fields linear_ordered_semiring
-- i.e no zero divisors
definition linear_ordered_ring.to_linear_ordered_semiring [instance] [coercion]
[s : linear_ordered_ring A] :
linear_ordered_semiring A :=
linear_ordered_semiring.mk linear_ordered_ring.add linear_ordered_ring.add_assoc
(@linear_ordered_ring.zero _ _) linear_ordered_ring.zero_add linear_ordered_ring.add_zero
linear_ordered_ring.add_comm linear_ordered_ring.mul linear_ordered_ring.mul_assoc
(@linear_ordered_ring.one _ _) linear_ordered_ring.one_mul linear_ordered_ring.mul_one
linear_ordered_ring.left_distrib linear_ordered_ring.right_distrib
zero_mul mul_zero !ordered_ring.zero_ne_one
(@add.left_cancel A _) (@add.right_cancel A _)
linear_ordered_ring.le linear_ordered_ring.le_refl linear_ordered_ring.le_trans
linear_ordered_ring.le_antisymm
linear_ordered_ring.lt linear_ordered_ring.lt_iff_le_ne linear_ordered_ring.add_le_add_left
(@le_of_add_le_add_left A _)
(@mul_le_mul_of_nonneg_left A _) (@mul_le_mul_of_nonneg_right A _)
(@mul_lt_mul_of_pos_left A _) (@mul_lt_mul_of_pos_right A _)
linear_ordered_ring.le_iff_lt_or_eq linear_ordered_ring.le_total
structure linear_ordered_comm_ring [class] (A : Type) extends linear_ordered_ring A, comm_monoid A
-- Linearity implies no zero divisors. Doesn't need commutativity.
definition linear_ordered_comm_ring.to_integral_domain [instance] [coercion]
[s: linear_ordered_comm_ring A] :
integral_domain A :=
integral_domain.mk linear_ordered_comm_ring.add linear_ordered_comm_ring.add_assoc
(@linear_ordered_comm_ring.zero _ _)
linear_ordered_comm_ring.zero_add linear_ordered_comm_ring.add_zero
linear_ordered_comm_ring.neg linear_ordered_comm_ring.add_left_inv
linear_ordered_comm_ring.add_comm
linear_ordered_comm_ring.mul linear_ordered_comm_ring.mul_assoc
(@linear_ordered_comm_ring.one _ _)
linear_ordered_comm_ring.one_mul linear_ordered_comm_ring.mul_one
linear_ordered_comm_ring.left_distrib linear_ordered_comm_ring.right_distrib
(@linear_ordered_comm_ring.zero_ne_one _ _)
linear_ordered_comm_ring.mul_comm
(take a b,
assume H : a * b = 0,
show a = 0 b = 0, from
lt.by_cases
(assume Ha : 0 < a,
lt.by_cases
(assume Hb : 0 < b, absurd (H ▸ mul_pos Ha Hb) (lt.irrefl 0))
(assume Hb : 0 = b, or.inr (Hb⁻¹))
(assume Hb : 0 > b, absurd (H ▸ mul_neg_of_pos_of_neg Ha Hb) (lt.irrefl 0)))
(assume Ha : 0 = a, or.inl (Ha⁻¹))
(assume Ha : 0 > a,
lt.by_cases
(assume Hb : 0 < b, absurd (H ▸ mul_neg_of_neg_of_pos Ha Hb) (lt.irrefl 0))
(assume Hb : 0 = b, or.inr (Hb⁻¹))
(assume Hb : 0 > b, absurd (H ▸ mul_pos_of_neg_of_neg Ha Hb) (lt.irrefl 0))))
section section
variable [s : linear_ordered_ring A] variable [s : linear_ordered_ring A]
variables (a b c : A) variables (a b c : A)
include s include s
theorem mul_self_nonneg : a * a ≥ 0 := theorem mul_self_nonneg : a * a ≥ 0 :=
or.elim (le.total 0 a) or.elim (le.total 0 a)
(assume H : a ≥ 0, mul_nonneg_of_nonneg_of_nonneg H H) (assume H : a ≥ 0, mul_nonneg H H)
(assume H : a ≤ 0, mul_nonneg_of_nonpos_of_nonpos H H) (assume H : a ≤ 0, mul_nonneg_of_nonpos_of_nonpos H H)
theorem zero_le_one : 0 ≤ 1 := one_mul 1 ▸ mul_self_nonneg 1 theorem zero_le_one : 0 ≤ 1 := one_mul 1 ▸ mul_self_nonneg 1
theorem zero_lt_one : 0 < 1 := lt_of_le_of_ne zero_le_one zero_ne_one theorem zero_lt_one : 0 < 1 := lt_of_le_of_ne zero_le_one zero_ne_one
-- TODO: move these to ordered_group.lean
theorem lt_add_of_pos_right {a b : A} (H : b > 0) : a < a + b := !add_zero ▸ add_lt_add_left H a
theorem lt_add_of_pos_left {a b : A} (H : b > 0) : a < b + a := !zero_add ▸ add_lt_add_right H a
theorem le_add_of_nonneg_right {a b : A} (H : b ≥ 0) : a ≤ a + b := !add_zero ▸ add_le_add_left H a
theorem le_add_of_nonneg_left {a b : A} (H : b ≥ 0) : a ≤ b + a := !zero_add ▸ add_le_add_right H a
-- TODO: remove after we short-circuit class-graph -- TODO: remove after we short-circuit class-graph
definition linear_ordered_ring.to_mul [instance] [priority 100000] : has_mul A := definition linear_ordered_ring.to_mul [instance] [priority 100000] : has_mul A :=
has_mul.mk (@linear_ordered_ring.mul A s) has_mul.mk (@linear_ordered_ring.mul A s)
@ -281,49 +314,25 @@ section
definition linear_ordered_ring.to_zero [instance] [priority 100000] : has_zero A := definition linear_ordered_ring.to_zero [instance] [priority 100000] : has_zero A :=
has_zero.mk (@linear_ordered_ring.zero A s) has_zero.mk (@linear_ordered_ring.zero A s)
/- TODO: a good example of a performance bottleneck. theorem pos_and_pos_or_neg_and_neg_of_mul_pos {a b : A} (Hab : a * b > 0) :
Without any of the "proof ... qed" pairs, it exceeds the unifier maximum number of steps.
It works with at least one "proof ... qed", but takes about two seconds on my laptop. I do not
know where the bottleneck is.
Adding the explicit arguments to lt_or_eq_or_lt_cases does not seem to help at all. (The proof
still works if all the instances are replaced by "lt_or_eq_or_lt_cases" alone.)
Adding an extra "proof ... qed" around "!mul_zero ▸ Hb⁻¹ ▸ Hab" fails with "value has
metavariables". I am not sure why.
-/
theorem pos_and_pos_or_neg_and_neg_of_mul_pos (Hab : a * b > 0) :
(a > 0 ∧ b > 0) (a < 0 ∧ b < 0) := (a > 0 ∧ b > 0) (a < 0 ∧ b < 0) :=
lt_or_eq_or_lt_cases lt.by_cases
(assume Ha : 0 < a, (assume Ha : 0 < a,
lt_or_eq_or_lt_cases lt.by_cases
(assume Hb : 0 < b, or.inl (and.intro Ha Hb)) (assume Hb : 0 < b, or.inl (and.intro Ha Hb))
(assume Hb : 0 = b, (assume Hb : 0 = b,
absurd (!mul_zero ▸ Hb⁻¹ ▸ Hab) (lt.irrefl 0)) absurd (!mul_zero ▸ Hb⁻¹ ▸ Hab) (lt.irrefl 0))
(assume Hb : b < 0, (assume Hb : b < 0,
absurd Hab (not_lt_of_lt (mul_neg_of_pos_of_neg Ha Hb)))) absurd Hab (lt.asymm (mul_neg_of_pos_of_neg Ha Hb))))
(assume Ha : 0 = a, (assume Ha : 0 = a,
absurd (!zero_mul ▸ Ha⁻¹ ▸ Hab) (lt.irrefl 0)) absurd (!zero_mul ▸ Ha⁻¹ ▸ Hab) (lt.irrefl 0))
(assume Ha : a < 0, (assume Ha : a < 0,
lt_or_eq_or_lt_cases lt.by_cases
(assume Hb : 0 < b, (assume Hb : 0 < b,
absurd Hab (not_lt_of_lt (mul_neg_of_neg_of_pos Ha Hb))) absurd Hab (lt.asymm (mul_neg_of_neg_of_pos Ha Hb)))
(assume Hb : 0 = b, (assume Hb : 0 = b,
absurd (!mul_zero ▸ Hb⁻¹ ▸ Hab) (lt.irrefl 0)) absurd (!mul_zero ▸ Hb⁻¹ ▸ Hab) (lt.irrefl 0))
(assume Hb : b < 0, or.inr (and.intro Ha Hb))) (assume Hb : b < 0, or.inr (and.intro Ha Hb)))
set_option pp.coercions true
set_option pp.implicit true
set_option pp.notation false
-- print definition pos_and_pos_or_neg_and_neg_of_mul_pos
-- TODO: use previous and integral domain
theorem noneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg (Hab : a * b ≥ 0) :
(a ≥ 0 ∧ b ≥ 0) (a ≤ 0 ∧ b ≤ 0) :=
sorry
end end
/- /-
@ -337,6 +346,4 @@ end
Multiplication and one, starting with mult_right_le_one_le. Multiplication and one, starting with mult_right_le_one_le.
-/ -/
structure linear_ordered_comm_ring [class] (A : Type) extends linear_ordered_ring A, comm_monoid A
end algebra end algebra

View file

@ -11,7 +11,6 @@ The development is modeled after Isabelle's library.
import logic.eq logic.connectives data.unit data.sigma data.prod import logic.eq logic.connectives data.unit data.sigma data.prod
import algebra.function algebra.binary algebra.group import algebra.function algebra.binary algebra.group
open eq eq.ops open eq eq.ops
namespace algebra namespace algebra
@ -48,7 +47,6 @@ structure semiring [class] (A : Type) extends add_comm_monoid A, monoid A, distr
mul_zero_class A, zero_ne_one_class A mul_zero_class A, zero_ne_one_class A
section semiring section semiring
variables [s : semiring A] (a b c : A) variables [s : semiring A] (a b c : A)
include s include s
@ -61,17 +59,15 @@ section semiring
assume H1 : b = 0, assume H1 : b = 0,
have H2 : a * b = 0, from H1⁻¹ ▸ mul_zero a, have H2 : a * b = 0, from H1⁻¹ ▸ mul_zero a,
H H2 H H2
end semiring end semiring
/- comm semiring -/ /- comm semiring -/
structure comm_semiring [class] (A : Type) extends semiring A, comm_semigroup A structure comm_semiring [class] (A : Type) extends semiring A, comm_semigroup A
-- TODO: we could also define a cancelative comm_semiring, i.e. satisfying
-- TODO: we could also define a cancelative comm_semiring, i.e. satisfying c ≠ 0 → c * a = c * b → a = b. -- c ≠ 0 → c * a = c * b → a = b.
section comm_semiring section comm_semiring
variables [s : comm_semiring A] (a b c : A) variables [s : comm_semiring A] (a b c : A)
include s include s
@ -81,6 +77,9 @@ section comm_semiring
theorem dvd.intro {a b c : A} (H : a * b = c) : a | c := theorem dvd.intro {a b c : A} (H : a * b = c) : a | c :=
exists.intro _ H exists.intro _ H
theorem dvd.intro_right {a b c : A} (H : a * b = c) : b | c :=
dvd.intro (!mul.comm ▸ H)
theorem dvd.ex {a b : A} (H : a | b) : ∃c, a * c = b := H theorem dvd.ex {a b : A} (H : a | b) : ∃c, a * c = b := H
theorem dvd.elim {P : Prop} {a b : A} (H₁ : a | b) (H₂ : ∀c, a * c = b → P) : P := theorem dvd.elim {P : Prop} {a b : A} (H₁ : a | b) (H₂ : ∀c, a * c = b → P) : P :=
@ -147,15 +146,13 @@ section comm_semiring
dvd.elim Hac dvd.elim Hac
(take e, assume Haec : a * e = c, (take e, assume Haec : a * e = c,
dvd.intro (show a * (d + e) = b + c, from Hadb ▸ Haec ▸ left_distrib a d e))) dvd.intro (show a * (d + e) = b + c, from Hadb ▸ Haec ▸ left_distrib a d e)))
end comm_semiring end comm_semiring
/- ring -/ /- ring -/
structure ring [class] (A : Type) extends add_comm_group A, monoid A, distrib A, zero_ne_one_class A structure ring [class] (A : Type) extends add_comm_group A, monoid A, distrib A, zero_ne_one_class A
definition ring.to_semiring [instance] [s : ring A] : semiring A := definition ring.to_semiring [instance] [coercion] [s : ring A] : semiring A :=
semiring.mk ring.add ring.add_assoc !ring.zero ring.zero_add semiring.mk ring.add ring.add_assoc !ring.zero ring.zero_add
add_zero -- note: we've shown that add_zero follows from zero_add in add_comm_group add_zero -- note: we've shown that add_zero follows from zero_add in add_comm_group
ring.add_comm ring.mul ring.mul_assoc !ring.one ring.one_mul ring.mul_one ring.add_comm ring.mul ring.mul_assoc !ring.one ring.one_mul ring.mul_one
@ -177,7 +174,6 @@ semiring.mk ring.add ring.add_assoc !ring.zero ring.zero_add
!ring.zero_ne_one !ring.zero_ne_one
section section
variables [s : ring A] (a b c d e : A) variables [s : ring A] (a b c d e : A)
include s include s
@ -225,12 +221,11 @@ section
... ↔ a * e + c - b * e = d : iff.symm !sub_eq_iff_eq_add ... ↔ a * e + c - b * e = d : iff.symm !sub_eq_iff_eq_add
... ↔ a * e - b * e + c = d : !sub_add_eq_add_sub ▸ !iff.refl ... ↔ a * e - b * e + c = d : !sub_add_eq_add_sub ▸ !iff.refl
... ↔ (a - b) * e + c = d : !mul_sub_right_distrib ▸ !iff.refl ... ↔ (a - b) * e + c = d : !mul_sub_right_distrib ▸ !iff.refl
end end
structure comm_ring [class] (A : Type) extends ring A, comm_semigroup A structure comm_ring [class] (A : Type) extends ring A, comm_semigroup A
definition comm_ring.to_comm_semiring [instance] [s : comm_ring A] : comm_semiring A := definition comm_ring.to_comm_semiring [instance] [coercion] [s : comm_ring A] : comm_semiring A :=
comm_semiring.mk comm_ring.add comm_ring.add_assoc (@comm_ring.zero A s) comm_semiring.mk comm_ring.add comm_ring.add_assoc (@comm_ring.zero A s)
comm_ring.zero_add comm_ring.add_zero comm_ring.add_comm comm_ring.mul comm_ring.mul_assoc comm_ring.zero_add comm_ring.add_zero comm_ring.add_comm comm_ring.mul comm_ring.mul_assoc
(@comm_ring.one A s) comm_ring.one_mul comm_ring.mul_one comm_ring.left_distrib (@comm_ring.one A s) comm_ring.one_mul comm_ring.mul_one comm_ring.left_distrib
@ -238,7 +233,6 @@ comm_semiring.mk comm_ring.add comm_ring.add_assoc (@comm_ring.zero A s)
comm_ring.mul_comm comm_ring.mul_comm
section section
variables [s : comm_ring A] (a b c d e : A) variables [s : comm_ring A] (a b c d e : A)
include s include s
@ -248,13 +242,6 @@ section
theorem mul_self_sub_one_eq : a * a - 1 = (a + 1) * (a - 1) := theorem mul_self_sub_one_eq : a * a - 1 = (a + 1) * (a - 1) :=
mul_one 1 ▸ mul_self_sub_mul_self_eq a 1 mul_one 1 ▸ mul_self_sub_mul_self_eq a 1
end
section
variables [s : comm_ring A] (a b c d e : A)
include s
theorem dvd_neg_iff_dvd : a | -b ↔ a | b := theorem dvd_neg_iff_dvd : a | -b ↔ a | b :=
iff.intro iff.intro
(assume H : a | -b, (assume H : a | -b,
@ -292,14 +279,10 @@ section
theorem dvd_sub (H₁ : a | b) (H₂ : a | c) : a | (b - c) := theorem dvd_sub (H₁ : a | b) (H₂ : a | c) : a | (b - c) :=
dvd_add H₁ (iff.elim_right !dvd_neg_iff_dvd H₂) dvd_add H₁ (iff.elim_right !dvd_neg_iff_dvd H₂)
end end
/- integral domains -/ /- integral domains -/
-- TODO: some properties here may extend to cancellative semirings. It is worth the effort?
structure no_zero_divisors [class] (A : Type) extends has_mul A, has_zero A := structure no_zero_divisors [class] (A : Type) extends has_mul A, has_zero A :=
(eq_zero_or_eq_zero_of_mul_eq_zero : ∀a b, mul a b = zero → a = zero b = zero) (eq_zero_or_eq_zero_of_mul_eq_zero : ∀a b, mul a b = zero → a = zero b = zero)
@ -353,7 +336,6 @@ section
have H1 : b * d * a = c * a, from eq.trans !mul.right_comm H, have H1 : b * d * a = c * a, from eq.trans !mul.right_comm H,
have H2 : b * d = c, from mul.cancel_right Ha H1, have H2 : b * d = c, from mul.cancel_right Ha H1,
dvd.intro H2) dvd.intro H2)
end end
end algebra end algebra

View file

@ -6,15 +6,15 @@ Module: int.basic
Authors: Floris van Doorn, Jeremy Avigad Authors: Floris van Doorn, Jeremy Avigad
The integers, with addition, multiplication, and subtraction. The representation of the integers is The integers, with addition, multiplication, and subtraction. The representation of the integers is
chosen to compute efficiently; see the examples in the comments at the end of this file. chosen to compute efficiently.
To faciliate proving things about these operations, we show that the integers are a quotient of To faciliate proving things about these operations, we show that the integers are a quotient of
× with the usual equivalence relation ≡, and functions × with the usual equivalence relation, ≡, and functions
abstr : × abstr : ×
repr : × repr : ×
satisfying satisfying:
abstr_repr (a : ) : abstr (repr a) = a abstr_repr (a : ) : abstr (repr a) = a
repr_abstr (p : × ) : repr (abstr p) ≡ p repr_abstr (p : × ) : repr (abstr p) ≡ p
@ -25,12 +25,12 @@ following:
repr_add (a b : ) : repr (a + b) = padd (repr a) (repr b) repr_add (a b : ) : repr (a + b) = padd (repr a) (repr b)
padd_congr (p p' q q' : × ) (H1 : p ≡ p') (H2 : q ≡ q') : padd p q ≡ p' q' padd_congr (p p' q q' : × ) (H1 : p ≡ p') (H2 : q ≡ q') : padd p q ≡ p' q'
-/ -/
import data.nat.basic data.nat.order data.nat.sub data.prod import data.nat.basic data.nat.order data.nat.sub data.prod
import algebra.relation algebra.binary algebra.ordered_ring import algebra.relation algebra.binary algebra.ordered_ring
import tools.fake_simplifier import tools.fake_simplifier
open eq.ops open eq.ops
open prod relation nat open prod relation nat
open decidable binary fake_simplifier open decidable binary fake_simplifier
@ -54,8 +54,8 @@ nat.cases_on m 0 (take m', neg_succ_of_nat m')
definition sub_nat_nat (m n : ) : := definition sub_nat_nat (m n : ) : :=
nat.cases_on (n - m) nat.cases_on (n - m)
(of_nat (m - n)) -- m ≥ n (of_nat (m - n)) -- m ≥ n
(take k, neg_succ_of_nat k) -- m < n, and n - m = succ k (take k, neg_succ_of_nat k) -- m < n, and n - m = succ k
definition neg (a : ) : := definition neg (a : ) : :=
cases_on a cases_on a
@ -144,11 +144,7 @@ cases_on a
(take m, assume H : nat_abs (of_nat m) = 0, congr_arg of_nat H) (take m, assume H : nat_abs (of_nat m) = 0, congr_arg of_nat H)
(take m', assume H : nat_abs (neg_succ_of_nat m') = 0, absurd H (succ_ne_zero _)) (take m', assume H : nat_abs (neg_succ_of_nat m') = 0, absurd H (succ_ne_zero _))
/- int is a quotient of ordered pairs of natural numbers -/
/-
Show int is a quotient of ordered pairs of natural numbers, with the usual
equivalence relation.
-/
definition equiv (p q : × ) : Prop := pr1 p + pr2 q = pr2 p + pr1 q definition equiv (p q : × ) : Prop := pr1 p + pr2 q = pr2 p + pr1 q
@ -319,7 +315,7 @@ or.elim (cases_of_nat_succ a)
(assume H, obtain (n : ) (H3 : a = -(succ n)), from H, H3⁻¹ ▸ H2 n) (assume H, obtain (n : ) (H3 : a = -(succ n)), from H, H3⁻¹ ▸ H2 n)
/- /-
Show int is a ring. int is a ring
-/ -/
/- addition -/ /- addition -/
@ -434,7 +430,7 @@ have H : repr (-a + a) ≡ repr 0, from
... ≡ repr 0 : padd_pneg, ... ≡ repr 0 : padd_pneg,
eq_of_repr_equiv_repr H eq_of_repr_equiv_repr H
/- nat -/ /- nat abs -/
definition pabs (p : × ) : := dist (pr1 p) (pr2 p) definition pabs (p : × ) : := dist (pr1 p) (pr2 p)
@ -595,24 +591,27 @@ have H2 : (nat_abs a) * (nat_abs b) = nat.zero, from
(nat_abs a) * (nat_abs b) = (nat_abs (a * b)) : (mul_nat_abs a b)⁻¹ (nat_abs a) * (nat_abs b) = (nat_abs (a * b)) : (mul_nat_abs a b)⁻¹
... = (nat_abs 0) : {H} ... = (nat_abs 0) : {H}
... = nat.zero : nat_abs_of_nat nat.zero, ... = nat.zero : nat_abs_of_nat nat.zero,
have H3 : (nat_abs a) = nat.zero (nat_abs b) = nat.zero, from eq_zero_or_eq_zero_of_mul_eq_zero H2, have H3 : (nat_abs a) = nat.zero (nat_abs b) = nat.zero,
from eq_zero_or_eq_zero_of_mul_eq_zero H2,
or_of_or_of_imp_of_imp H3 or_of_or_of_imp_of_imp H3
(assume H : (nat_abs a) = nat.zero, nat_abs_eq_zero H) (assume H : (nat_abs a) = nat.zero, nat_abs_eq_zero H)
(assume H : (nat_abs b) = nat.zero, nat_abs_eq_zero H) (assume H : (nat_abs b) = nat.zero, nat_abs_eq_zero H)
definition integral_domain : algebra.integral_domain int := protected definition integral_domain : algebra.integral_domain int :=
algebra.integral_domain.mk add add.assoc zero zero_add add_zero neg add.left_inv algebra.integral_domain.mk add add.assoc zero zero_add add_zero neg add.left_inv
add.comm mul mul.assoc (of_num 1) one_mul mul_one mul.left_distrib mul.right_distrib add.comm mul mul.assoc (of_num 1) one_mul mul_one mul.left_distrib mul.right_distrib
zero_ne_one mul.comm @eq_zero_or_eq_zero_of_mul_eq_zero zero_ne_one mul.comm @eq_zero_or_eq_zero_of_mul_eq_zero
/- --namespace algebra
Instantiate ring theorems to int -- open algebra -- TODO: why do we have to do this?
-/ -- instance [persistent] int.integral_domain
--end algebra
-- TODO: make this "section" when scoping bug is fixed /- instantiate ring theorems to int -/
context port_algebra
section port_algebra
open algebra open algebra
instance integral_domain instance int.integral_domain -- TODO: why didn't the setting above persist?
theorem mul.left_comm : ∀a b c : , a * (b * c) = b * (a * c) := algebra.mul.left_comm theorem mul.left_comm : ∀a b c : , a * (b * c) = b * (a * c) := algebra.mul.left_comm
theorem mul.right_comm : ∀a b c : , (a * b) * c = (a * c) * b := algebra.mul.right_comm theorem mul.right_comm : ∀a b c : , (a * b) * c = (a * c) * b := algebra.mul.right_comm
@ -687,6 +686,7 @@ context port_algebra
definition dvd (a b : ) : Prop := algebra.dvd a b definition dvd (a b : ) : Prop := algebra.dvd a b
infix `|` := dvd infix `|` := dvd
theorem dvd.intro : ∀{a b c : } (H : a * b = c), a | c := @algebra.dvd.intro _ _ theorem dvd.intro : ∀{a b c : } (H : a * b = c), a | c := @algebra.dvd.intro _ _
theorem dvd.intro_right : ∀{a b c : } (H : a * b = c), b | c := @algebra.dvd.intro_right _ _
theorem dvd.ex : ∀{a b : } (H : a | b), ∃c, a * c = b := @algebra.dvd.ex _ _ theorem dvd.ex : ∀{a b : } (H : a | b), ∃c, a * c = b := @algebra.dvd.ex _ _
theorem dvd.elim : ∀{P : Prop} {a b : } (H₁ : a | b) (H₂ : ∀c, a * c = b → P), P := theorem dvd.elim : ∀{P : Prop} {a b : } (H₁ : a | b) (H₂ : ∀c, a * c = b → P), P :=
@algebra.dvd.elim _ _ @algebra.dvd.elim _ _
@ -741,54 +741,6 @@ context port_algebra
@algebra.dvd_of_mul_dvd_mul_left _ _ @algebra.dvd_of_mul_dvd_mul_left _ _
theorem dvd_of_mul_dvd_mul_right : ∀{a b c : }, a ≠ 0 → b * a | c * a → b | c := theorem dvd_of_mul_dvd_mul_right : ∀{a b c : }, a ≠ 0 → b * a | c * a → b | c :=
@algebra.dvd_of_mul_dvd_mul_right _ _ @algebra.dvd_of_mul_dvd_mul_right _ _
end port_algebra end port_algebra
-- TODO: declare appropriate rewrite rules
-- add_rewrite zero_add add_zero
-- add_rewrite add_comm add.assoc add_left_comm
-- add_rewrite sub_def add_inverse_right add_inverse_left
-- add_rewrite neg_add_distr
---- add_rewrite sub_sub_assoc sub_add_assoc add_sub_assoc
---- add_rewrite add_neg_right add_neg_left
---- add_rewrite sub_self
end int end int
/- tests -/
/- open int
eval -100
eval -(-100)
eval #int (5 + 7)
eval -5 + 7
eval 5 + -7
eval -5 + -7
eval #int 155 + 277
eval -155 + 277
eval 155 + -277
eval -155 + -277
eval #int 155 - 277
eval #int 277 - 155
eval #int 2 * 3
eval -2 * 3
eval 2 * -3
eval -2 * -3
eval 22 * 33
eval -22 * 33
eval 22 * -33
eval -22 * -33
eval #int 22 ≤ 33
eval #int 33 ≤ 22
example : #int 22 ≤ 33 := true.intro
example : #int -5 < 7 := true.intro
-/

View file

@ -5,10 +5,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
Module: data.int.order Module: data.int.order
Authors: Floris van Doorn, Jeremy Avigad Authors: Floris van Doorn, Jeremy Avigad
The order relation on the integers, and the sign function. The order relation on the integers. We show that int is an instance of linear_comm_ordered_ring
and transfer the results.
-/ -/
import .basic import .basic algebra.ordered_ring
open nat open nat
open decidable open decidable
@ -17,7 +18,7 @@ open int eq.ops
namespace int namespace int
definition nonneg (a : ) : Prop := cases_on a (take n, true) (take n, false) private definition nonneg (a : ) : Prop := cases_on a (take n, true) (take n, false)
definition le (a b : ) : Prop := nonneg (sub b a) definition le (a b : ) : Prop := nonneg (sub b a)
definition lt (a b : ) : Prop := le (add a 1) b definition lt (a b : ) : Prop := le (add a 1) b
@ -26,52 +27,88 @@ infix <= := int.le
infix ≤ := int.le infix ≤ := int.le
infix < := int.lt infix < := int.lt
definition decidable_nonneg [instance] (a : ) : decidable (nonneg a) := cases_on a _ _ private definition decidable_nonneg [instance] (a : ) : decidable (nonneg a) := cases_on a _ _
definition decidable_le [instance] (a b : ) : decidable (a ≤ b) := decidable_nonneg _ definition decidable_le [instance] (a b : ) : decidable (a ≤ b) := decidable_nonneg _
definition decidable_lt [instance] (a b : ) : decidable (a < b) := decidable_nonneg _ definition decidable_lt [instance] (a b : ) : decidable (a < b) := decidable_nonneg _
theorem nonneg_elim {a : } : nonneg a → ∃n : , a = n := private theorem nonneg.elim {a : } : nonneg a → ∃n : , a = n :=
cases_on a (take n H, exists.intro n rfl) (take n' H, false.elim H) cases_on a (take n H, exists.intro n rfl) (take n' H, false.elim H)
theorem le_intro {a b : } {n : } (H : a + n = b) : a ≤ b := private theorem nonneg_or_nonneg_neg (a : ) : nonneg a nonneg (-a) :=
cases_on a (take n, or.inl trivial) (take n, or.inr trivial)
theorem le.intro {a b : } {n : } (H : a + n = b) : a ≤ b :=
have H1 : b - a = n, from (eq_add_neg_of_add_eq (!add.comm ▸ H))⁻¹, have H1 : b - a = n, from (eq_add_neg_of_add_eq (!add.comm ▸ H))⁻¹,
have H2 : nonneg n, from true.intro, have H2 : nonneg n, from true.intro,
show nonneg (b - a), from H1⁻¹ ▸ H2 show nonneg (b - a), from H1⁻¹ ▸ H2
theorem le_elim {a b : } (H : a ≤ b) : ∃n : , a + n = b := theorem le.elim {a b : } (H : a ≤ b) : ∃n : , a + n = b :=
obtain (n : ) (H1 : b - a = n), from nonneg_elim H, obtain (n : ) (H1 : b - a = n), from nonneg.elim H,
exists.intro n (!add.comm ▸ iff.mp' !add_eq_iff_eq_add_neg (H1⁻¹)) exists.intro n (!add.comm ▸ iff.mp' !add_eq_iff_eq_add_neg (H1⁻¹))
-- ### partial order theorem le.total (a b : ) : a ≤ b b ≤ a :=
or.elim (nonneg_or_nonneg_neg (b - a))
(assume H, or.inl H)
(assume H : nonneg (-(b - a)),
have H0 : -(b - a) = a - b, from neg_sub_eq b a,
have H1 : nonneg (a - b), from H0 ▸ H, -- too bad: can't do it in one step
or.inr H1)
theorem le_refl (a : ) : a ≤ a := theorem of_nat_le_of_nat (n m : ) : of_nat n ≤ of_nat m ↔ n ≤ m :=
le_intro (add_zero a)
theorem le_of_nat (n m : ) : (of_nat n ≤ of_nat m) ↔ (n ≤ m) :=
iff.intro iff.intro
(assume H : of_nat n ≤ of_nat m, (assume H : of_nat n ≤ of_nat m,
obtain (k : ) (Hk : of_nat n + of_nat k = of_nat m), from le_elim H, obtain (k : ) (Hk : of_nat n + of_nat k = of_nat m), from le.elim H,
have H2 : n + k = m, from of_nat_inj ((add_of_nat n k)⁻¹ ⬝ Hk), have H2 : n + k = m, from of_nat_inj ((add_of_nat n k)⁻¹ ⬝ Hk),
nat.le_intro H2) nat.le_intro H2)
(assume H : n ≤ m, (assume H : n ≤ m,
obtain (k : ) (Hk : n + k = m), from nat.le_elim H, obtain (k : ) (Hk : n + k = m), from nat.le_elim H,
have H2 : of_nat n + of_nat k = of_nat m, from Hk ▸ add_of_nat n k, have H2 : of_nat n + of_nat k = of_nat m, from Hk ▸ add_of_nat n k,
le_intro H2) le.intro H2)
theorem le_trans {a b c : } (H1 : a ≤ b) (H2 : b ≤ c) : a ≤ c := theorem lt_add_succ (a : ) (n : ) : a < a + succ n :=
obtain (n : ) (Hn : a + n = b), from le_elim H1, le.intro (show a + 1 + n = a + succ n, from
obtain (m : ) (Hm : b + m = c), from le_elim H2, calc
a + 1 + n = a + (1 + n) : add.assoc
... = a + (n + 1) : add.comm
... = a + succ n : rfl)
theorem lt.intro {a b : } {n : } (H : a + succ n = b) : a < b :=
H ▸ lt_add_succ a n
theorem lt.elim {a b : } (H : a < b) : ∃n : , a + succ n = b :=
obtain (n : ) (Hn : a + 1 + n = b), from le.elim H,
have H2 : a + succ n = b, from
calc
a + succ n = a + 1 + n : by simp
... = b : Hn,
exists.intro n H2
theorem of_nat_lt_of_nat (n m : ) : of_nat n < of_nat m ↔ n < m :=
calc
of_nat n < of_nat m ↔ of_nat n + 1 ≤ of_nat m : iff.refl
... ↔ of_nat (succ n) ≤ of_nat m : of_nat_succ n ▸ !iff.refl
... ↔ succ n ≤ m : of_nat_le_of_nat
... ↔ n < m : iff.symm (lt_iff_succ_le _ _)
/- show that the integers form an ordered additive group -/
theorem le.refl (a : ) : a ≤ a :=
le.intro (add_zero a)
theorem le.trans {a b c : } (H1 : a ≤ b) (H2 : b ≤ c) : a ≤ c :=
obtain (n : ) (Hn : a + n = b), from le.elim H1,
obtain (m : ) (Hm : b + m = c), from le.elim H2,
have H3 : a + of_nat (n + m) = c, from have H3 : a + of_nat (n + m) = c, from
calc calc
a + of_nat (n + m) = a + (of_nat n + m) : {(add_of_nat n m)⁻¹} a + of_nat (n + m) = a + (of_nat n + m) : {(add_of_nat n m)⁻¹}
... = a + n + m : (add.assoc a n m)⁻¹ ... = a + n + m : (add.assoc a n m)⁻¹
... = b + m : {Hn} ... = b + m : {Hn}
... = c : Hm, ... = c : Hm,
le_intro H3 le.intro H3
theorem le_antisym {a b : } (H1 : a ≤ b) (H2 : b ≤ a) : a = b := theorem le.antisymm {a b : } (H1 : a ≤ b) (H2 : b ≤ a) : a = b :=
obtain (n : ) (Hn : a + n = b), from le_elim H1, obtain (n : ) (Hn : a + n = b), from le.elim H1,
obtain (m : ) (Hm : b + m = a), from le_elim H2, obtain (m : ) (Hm : b + m = a), from le.elim H2,
have H3 : a + of_nat (n + m) = a + 0, from have H3 : a + of_nat (n + m) = a + 0, from
calc calc
a + of_nat (n + m) = a + (of_nat n + m) : {(add_of_nat n m)⁻¹} a + of_nat (n + m) = a + (of_nat n + m) : {(add_of_nat n m)⁻¹}
@ -88,27 +125,388 @@ show a = b, from
... = a + n : {H6⁻¹} ... = a + n : {H6⁻¹}
... = b : Hn ... = b : Hn
-- ### interaction with add theorem lt.irrefl (a : ) : ¬ a < a :=
(assume H : a < a,
obtain (n : ) (Hn : a + succ n = a), from lt.elim H,
have H2 : a + succ n = a + 0, from
calc
a + succ n = a : Hn
... = a + 0 : by simp,
have H3 : succ n = 0, from add.left_cancel H2,
have H4 : succ n = 0, from of_nat_inj H3,
absurd H4 !succ_ne_zero)
theorem le_add_of_nat_right (a : ) (n : ) : a ≤ a + n := theorem ne_of_lt {a b : } (H : a < b) : a ≠ b :=
le_intro (eq.refl (a + n)) (assume H2 : a = b, absurd (H2 ▸ H) (lt.irrefl b))
theorem le_add_of_nat_left (a : ) (n : ) : a ≤ n + a := theorem succ_le_of_lt {a b : } (H : a < b) : a + 1 ≤ b := H
le_intro (add.comm a n)
theorem add_le_left {a b : } (H : a ≤ b) (c : ) : c + a ≤ c + b := theorem lt_of_le_succ {a b : } (H : a + 1 ≤ b) : a < b := H
obtain (n : ) (Hn : a + n = b), from le_elim H,
theorem le_of_lt {a b : } (H : a < b) : a ≤ b :=
obtain (n : ) (Hn : a + succ n = b), from lt.elim H,
le.intro Hn
theorem lt_iff_le_and_ne (a b : ) : a < b ↔ (a ≤ b ∧ a ≠ b) :=
iff.intro
(assume H, and.intro (le_of_lt H) (ne_of_lt H))
(assume H,
have H1 : a ≤ b, from and.elim_left H,
have H2 : a ≠ b, from and.elim_right H,
obtain (n : ) (Hn : a + n = b), from le.elim H1,
have H3 : n ≠ 0, from (assume H' : n = 0, H2 (!add_zero ▸ H' ▸ Hn)),
obtain (k : ) (Hk : n = succ k), from nat.exists_eq_succ_of_ne_zero H3,
lt.intro (Hk ▸ Hn))
theorem le_iff_lt_or_eq (a b : ) : a ≤ b ↔ (a < b a = b) :=
iff.intro
(assume H,
by_cases
(assume H1 : a = b, or.inr H1)
(assume H1 : a ≠ b,
obtain (n : ) (Hn : a + n = b), from le.elim H,
have H2 : n ≠ 0, from (assume H' : n = 0, H1 (!add_zero ▸ H' ▸ Hn)),
obtain (k : ) (Hk : n = succ k), from nat.exists_eq_succ_of_ne_zero H2,
or.inl (lt.intro (Hk ▸ Hn))))
(assume H,
or.elim H
(assume H1, le_of_lt H1)
(assume H1, H1 ▸ !le.refl))
theorem lt_succ (a : ) : a < a + 1 :=
le.refl (a + 1)
theorem add_le_add_left {a b : } (H : a ≤ b) (c : ) : c + a ≤ c + b :=
obtain (n : ) (Hn : a + n = b), from le.elim H,
have H2 : c + a + n = c + b, from have H2 : c + a + n = c + b, from
calc calc
c + a + n = c + (a + n) : add.assoc c a n c + a + n = c + (a + n) : add.assoc c a n
... = c + b : {Hn}, ... = c + b : {Hn},
le_intro H2 le.intro H2
theorem mul_nonneg {a b : } (Ha : 0 ≤ a) (Hb : 0 ≤ b) : 0 ≤ a * b :=
obtain (n : ) (Hn : 0 + n = a), from le.elim Ha,
obtain (m : ) (Hm : 0 + m = b), from le.elim Hb,
le.intro
(eq.symm
(calc
a * b = (0 + n) * b : Hn
... = n * b : zero_add
... = n * (0 + m) : Hm
... = n * m : zero_add
... = 0 + n * m : zero_add))
theorem mul_pos {a b : } (Ha : 0 < a) (Hb : 0 < b) : 0 < a * b :=
obtain (n : ) (Hn : 0 + succ n = a), from lt.elim Ha,
obtain (m : ) (Hm : 0 + succ m = b), from lt.elim Hb,
lt.intro
(eq.symm
(calc
a * b = (0 + succ n) * b : Hn
... = succ n * b : zero_add
... = succ n * (0 + succ m) : Hm
... = succ n * succ m : zero_add
... = of_nat (succ n * succ m) : mul_of_nat
... = of_nat (succ n * m + succ n) : nat.mul_succ
... = of_nat (succ (succ n * m + n)) : nat.add_succ
... = 0 + succ (succ n * m + n) : zero_add))
protected definition linear_ordered_comm_ring : algebra.linear_ordered_comm_ring int :=
algebra.linear_ordered_comm_ring.mk add add.assoc zero zero_add add_zero neg add.left_inv
add.comm mul mul.assoc (of_num 1) one_mul mul_one mul.left_distrib mul.right_distrib
zero_ne_one le le.refl @le.trans @le.antisymm lt lt_iff_le_and_ne @add_le_add_left
@mul_nonneg @mul_pos le_iff_lt_or_eq le.total mul.comm
/- instantiate ordered ring theorems to int -/
namespace algebra
open algebra
instance [persistent] int.linear_ordered_comm_ring
end algebra
section port_algebra
open algebra
instance int.linear_ordered_comm_ring
definition ge (a b : ) := algebra.has_le.ge a b
definition gt (a b : ) := algebra.has_lt.gt a b
infix >= := int.ge
infix ≥ := int.ge
infix > := int.gt
definition decidable_ge [instance] (a b : ) : decidable (a ≥ b) := _
definition decidable_gt [instance] (a b : ) : decidable (a > b) := _
theorem le_of_eq_of_le : ∀{a b c : }, a = b → b ≤ c → a ≤ c := @algebra.le_of_eq_of_le _ _
theorem le_of_le_of_eq : ∀{a b c : }, a ≤ b → b = c → a ≤ c := @algebra.le_of_le_of_eq _ _
theorem lt_of_eq_of_lt : ∀{a b c : }, a = b → b < c → a < c := @algebra.lt_of_eq_of_lt _ _
theorem lt_of_lt_of_eq : ∀{a b c : }, a < b → b = c → a < c := @algebra.lt_of_lt_of_eq _ _
calc_trans int.le_of_eq_of_le
calc_trans int.le_of_le_of_eq
calc_trans int.lt_of_eq_of_lt
calc_trans int.lt_of_lt_of_eq
theorem lt.asymm : ∀{a b : }, a < b → ¬ b < a := @algebra.lt.asymm _ _
theorem lt_of_le_of_ne : ∀{a b : }, a ≤ b → a ≠ b → a < b := @algebra.lt_of_le_of_ne _ _
theorem lt_of_lt_of_le : ∀{a b c : }, a < b → b ≤ c → a < c := @algebra.lt_of_lt_of_le _ _
theorem lt_of_le_of_lt : ∀{a b c : }, a ≤ b → b < c → a < c := @algebra.lt_of_le_of_lt _ _
theorem not_le_of_lt : ∀{a b : }, a < b → ¬ b ≤ a := @algebra.not_le_of_lt _ _
theorem not_lt_of_le : ∀{a b : }, a ≤ b → ¬ b < a := @algebra.not_lt_of_le _ _
theorem lt_or_eq_of_le : ∀{a b : }, a ≤ b → a < b a = b := @algebra.lt_or_eq_of_le _ _
theorem lt.trichotomy : ∀a b : , a < b a = b b < a := algebra.lt.trichotomy
theorem lt.by_cases : ∀{a b : } {P : Prop}, (a < b → P) → (a = b → P) → (b < a → P) → P :=
@algebra.lt.by_cases _ _
definition le_of_not_lt : ∀{a b : }, ¬ a < b → b ≤ a := @algebra.le_of_not_lt _ _
definition lt_of_not_le : ∀{a b : }, ¬ a ≤ b → b < a := @algebra.lt_of_not_le _ _
theorem add_le_add_right : ∀{a b : }, a ≤ b → ∀c : , a + c ≤ b + c :=
@algebra.add_le_add_right _ _
theorem add_le_add : ∀{a b c d : }, a ≤ b → c ≤ d → a + c ≤ b + d := @algebra.add_le_add _ _
theorem add_lt_add_left : ∀{a b : }, a < b → ∀c : , c + a < c + b :=
@algebra.add_lt_add_left _ _
theorem add_lt_add_right : ∀{a b : }, a < b → ∀c : , a + c < b + c :=
@algebra.add_lt_add_right _ _
theorem le_add_of_nonneg_right : ∀{a b : }, b ≥ 0 → a ≤ a + b :=
@algebra.le_add_of_nonneg_right _ _
theorem le_add_of_nonneg_left : ∀{a b : }, b ≥ 0 → a ≤ b + a :=
@algebra.le_add_of_nonneg_left _ _
theorem add_lt_add : ∀{a b c d : }, a < b → c < d → a + c < b + d := @algebra.add_lt_add _ _
theorem add_lt_add_of_le_of_lt : ∀{a b c d : }, a ≤ b → c < d → a + c < b + d :=
@algebra.add_lt_add_of_le_of_lt _ _
theorem add_lt_add_of_lt_of_le : ∀{a b c d : }, a < b → c ≤ d → a + c < b + d :=
@algebra.add_lt_add_of_lt_of_le _ _
theorem lt_add_of_pos_right : ∀{a b : }, b > 0 → a < a + b := @algebra.lt_add_of_pos_right _ _
theorem lt_add_of_pos_left : ∀{a b : }, b > 0 → a < b + a := @algebra.lt_add_of_pos_left _ _
theorem le_of_add_le_add_left : ∀{a b c : }, a + b ≤ a + c → b ≤ c :=
@algebra.le_of_add_le_add_left _ _
theorem le_of_add_le_add_right : ∀{a b c : }, a + b ≤ c + b → a ≤ c :=
@algebra.le_of_add_le_add_right _ _
theorem lt_of_add_lt_add_left : ∀{a b c : }, a + b < a + c → b < c :=
@algebra.lt_of_add_lt_add_left _ _
theorem lt_of_add_lt_add_right : ∀{a b c : }, a + b < c + b → a < c :=
@algebra.lt_of_add_lt_add_right _ _
theorem add_le_add_left_iff : ∀a b c : , a + b ≤ a + c ↔ b ≤ c := algebra.add_le_add_left_iff
theorem add_le_add_right_iff : ∀a b c : , a + b ≤ c + b ↔ a ≤ c := algebra.add_le_add_right_iff
theorem add_lt_add_left_iff : ∀a b c : , a + b < a + c ↔ b < c := algebra.add_lt_add_left_iff
theorem add_lt_add_right_iff : ∀a b c : , a + b < c + b ↔ a < c := algebra.add_lt_add_right_iff
theorem add_nonneg : ∀{a b : }, 0 ≤ a → 0 ≤ b → 0 ≤ a + b := @algebra.add_nonneg _ _
theorem add_pos : ∀{a b : }, 0 < a → 0 < b → 0 < a + b := @algebra.add_pos _ _
theorem add_pos_of_pos_of_nonneg : ∀{a b : }, 0 < a → 0 ≤ b → 0 < a + b :=
@algebra.add_pos_of_pos_of_nonneg _ _
theorem add_pos_of_nonneg_of_pos : ∀{a b : }, 0 ≤ a → 0 < b → 0 < a + b :=
@algebra.add_pos_of_nonneg_of_pos _ _
theorem add_nonpos : ∀{a b : }, a ≤ 0 → b ≤ 0 → a + b ≤ 0 :=
@algebra.add_nonpos _ _
theorem add_neg : ∀{a b : }, a < 0 → b < 0 → a + b < 0 :=
@algebra.add_neg _ _
theorem add_neg_of_neg_of_nonpos : ∀{a b : }, a < 0 → b ≤ 0 → a + b < 0 :=
@algebra.add_neg_of_neg_of_nonpos _ _
theorem add_neg_of_nonpos_of_neg : ∀{a b : }, a ≤ 0 → b < 0 → a + b < 0 :=
@algebra.add_neg_of_nonpos_of_neg _ _
theorem add_eq_zero_iff_eq_zero_and_eq_zero_of_nonneg_of_nonneg : ∀{a b : },
0 ≤ a → 0 ≤ b → a + b = 0 ↔ a = 0 ∧ b = 0 :=
@algebra.add_eq_zero_iff_eq_zero_and_eq_zero_of_nonneg_of_nonneg _ _
theorem le_add_of_nonneg_of_le : ∀{a b c : }, 0 ≤ a → b ≤ c → b ≤ a + c :=
@algebra.le_add_of_nonneg_of_le _ _
theorem le_add_of_le_of_nonneg : ∀{a b c : }, b ≤ c → 0 ≤ a → b ≤ c + a :=
@algebra.le_add_of_le_of_nonneg _ _
theorem lt_add_of_pos_of_le : ∀{a b c : }, 0 < a → b ≤ c → b < a + c :=
@algebra.lt_add_of_pos_of_le _ _
theorem lt_add_of_le_of_pos : ∀{a b c : }, b ≤ c → 0 < a → b < c + a :=
@algebra.lt_add_of_le_of_pos _ _
theorem add_le_of_nonpos_of_le : ∀{a b c : }, a ≤ 0 → b ≤ c → a + b ≤ c :=
@algebra.add_le_of_nonpos_of_le _ _
theorem add_le_of_le_of_nonpos : ∀{a b c : }, b ≤ c → a ≤ 0 → b + a ≤ c :=
@algebra.add_le_of_le_of_nonpos _ _
theorem add_lt_of_neg_of_le : ∀{a b c : }, a < 0 → b ≤ c → a + b < c :=
@algebra.add_lt_of_neg_of_le _ _
theorem add_lt_of_le_of_neg : ∀{a b c : }, b ≤ c → a < 0 → b + a < c :=
@algebra.add_lt_of_le_of_neg _ _
theorem lt_add_of_nonneg_of_lt : ∀{a b c : }, 0 ≤ a → b < c → b < a + c :=
@algebra.lt_add_of_nonneg_of_lt _ _
theorem lt_add_of_lt_of_nonneg : ∀{a b c : }, b < c → 0 ≤ a → b < c + a :=
@algebra.lt_add_of_lt_of_nonneg _ _
theorem lt_add_of_pos_of_lt : ∀{a b c : }, 0 < a → b < c → b < a + c :=
@algebra.lt_add_of_pos_of_lt _ _
theorem lt_add_of_lt_of_pos : ∀{a b c : }, b < c → 0 < a → b < c + a :=
@algebra.lt_add_of_lt_of_pos _ _
theorem add_lt_of_nonpos_of_lt : ∀{a b c : }, a ≤ 0 → b < c → a + b < c :=
@algebra.add_lt_of_nonpos_of_lt _ _
theorem add_lt_of_lt_of_nonpos : ∀{a b c : }, b < c → a ≤ 0 → b + a < c :=
@algebra.add_lt_of_lt_of_nonpos _ _
theorem add_lt_of_neg_of_lt : ∀{a b c : }, a < 0 → b < c → a + b < c :=
@algebra.add_lt_of_neg_of_lt _ _
theorem add_lt_of_lt_of_neg : ∀{a b c : }, b < c → a < 0 → b + a < c :=
@algebra.add_lt_of_lt_of_neg _ _
theorem neg_le_neg : ∀{a b : }, a ≤ b → -b ≤ -a := @algebra.neg_le_neg _ _
theorem neg_le_neg_iff_le : ∀a b : , -a ≤ -b ↔ b ≤ a := algebra.neg_le_neg_iff_le
theorem neg_nonpos_iff_nonneg : ∀a : , -a ≤ 0 ↔ 0 ≤ a := algebra.neg_nonpos_iff_nonneg
theorem neg_nonneg_iff_nonpos : ∀a : , 0 ≤ -a ↔ a ≤ 0 := algebra.neg_nonneg_iff_nonpos
theorem neg_lt_neg : ∀{a b : }, a < b → -b < -a := @algebra.neg_lt_neg _ _
theorem neg_lt_neg_iff_lt : ∀a b : , -a < -b ↔ b < a := algebra.neg_lt_neg_iff_lt
theorem neg_neg_iff_pos : ∀a : , -a < 0 ↔ 0 < a := algebra.neg_neg_iff_pos
theorem neg_pos_iff_neg : ∀a : , 0 < -a ↔ a < 0 := algebra.neg_pos_iff_neg
theorem le_neg_iff_le_neg : ∀a b : , a ≤ -b ↔ b ≤ -a := algebra.le_neg_iff_le_neg
theorem neg_le_iff_neg_le : ∀a b : , -a ≤ b ↔ -b ≤ a := algebra.neg_le_iff_neg_le
theorem lt_neg_iff_lt_neg : ∀a b : , a < -b ↔ b < -a := algebra.lt_neg_iff_lt_neg
theorem neg_lt_iff_neg_lt : ∀a b : , -a < b ↔ -b < a := algebra.neg_lt_iff_neg_lt
theorem sub_nonneg_iff_le : ∀a b : , 0 ≤ a - b ↔ b ≤ a := algebra.sub_nonneg_iff_le
theorem sub_nonpos_iff_le : ∀a b : , a - b ≤ 0 ↔ a ≤ b := algebra.sub_nonpos_iff_le
theorem sub_pos_iff_lt : ∀a b : , 0 < a - b ↔ b < a := algebra.sub_pos_iff_lt
theorem sub_neg_iff_lt : ∀a b : , a - b < 0 ↔ a < b := algebra.sub_neg_iff_lt
theorem add_le_iff_le_neg_add : ∀a b c : , a + b ≤ c ↔ b ≤ -a + c :=
algebra.add_le_iff_le_neg_add
theorem add_le_iff_le_sub_left : ∀a b c : , a + b ≤ c ↔ b ≤ c - a :=
algebra.add_le_iff_le_sub_left
theorem add_le_iff_le_sub_right : ∀a b c : , a + b ≤ c ↔ a ≤ c - b :=
algebra.add_le_iff_le_sub_right
theorem le_add_iff_neg_add_le : ∀a b c : , a ≤ b + c ↔ -b + a ≤ c :=
algebra.le_add_iff_neg_add_le
theorem le_add_iff_sub_left_le : ∀a b c : , a ≤ b + c ↔ a - b ≤ c :=
algebra.le_add_iff_sub_left_le
theorem le_add_iff_sub_right_le : ∀a b c : , a ≤ b + c ↔ a - c ≤ b :=
algebra.le_add_iff_sub_right_le
theorem add_lt_iff_lt_neg_add_left : ∀a b c : , a + b < c ↔ b < -a + c :=
algebra.add_lt_iff_lt_neg_add_left
theorem add_lt_iff_lt_neg_add_right : ∀a b c : , a + b < c ↔ a < -b + c :=
algebra.add_lt_iff_lt_neg_add_right
theorem add_lt_iff_lt_sub_left : ∀a b c : , a + b < c ↔ b < c - a :=
algebra.add_lt_iff_lt_sub_left
theorem add_lt_add_iff_lt_sub_right : ∀a b c : , a + b < c ↔ a < c - b :=
algebra.add_lt_add_iff_lt_sub_right
theorem lt_add_iff_neg_add_lt_left : ∀a b c : , a < b + c ↔ -b + a < c :=
algebra.lt_add_iff_neg_add_lt_left
theorem lt_add_iff_neg_add_lt_right : ∀a b c : , a < b + c ↔ -c + a < b :=
algebra.lt_add_iff_neg_add_lt_right
theorem lt_add_iff_sub_lt_left : ∀a b c : , a < b + c ↔ a - b < c :=
algebra.lt_add_iff_sub_lt_left
theorem lt_add_iff_sub_lt_right : ∀a b c : , a < b + c ↔ a - c < b :=
algebra.lt_add_iff_sub_lt_right
theorem le_iff_le_of_sub_eq_sub : ∀{a b c d : }, a - b = c - d → a ≤ b ↔ c ≤ d :=
@algebra.le_iff_le_of_sub_eq_sub _ _
theorem lt_iff_lt_of_sub_eq_sub : ∀{a b c d : }, a - b = c - d → a < b ↔ c < d :=
@algebra.lt_iff_lt_of_sub_eq_sub _ _
theorem sub_le_sub_left : ∀{a b : }, a ≤ b → ∀c : , c - b ≤ c - a :=
@algebra.sub_le_sub_left _ _
theorem sub_le_sub_right : ∀{a b : }, a ≤ b → ∀c : , a - c ≤ b - c :=
@algebra.sub_le_sub_right _ _
theorem sub_le_sub : ∀{a b c d : }, a ≤ b → c ≤ d → a - d ≤ b - c :=
@algebra.sub_le_sub _ _
theorem sub_lt_sub_left : ∀{a b : }, a < b → ∀c : , c - b < c - a :=
@algebra.sub_lt_sub_left _ _
theorem sub_lt_sub_right : ∀{a b : }, a < b → ∀c : , a - c < b - c :=
@algebra.sub_lt_sub_right _ _
theorem sub_lt_sub : ∀{a b c d : }, a < b → c < d → a - d < b - c :=
@algebra.sub_lt_sub _ _
theorem sub_lt_sub_of_le_of_lt : ∀{a b c d : }, a ≤ b → c < d → a - d < b - c :=
@algebra.sub_lt_sub_of_le_of_lt _ _
theorem sub_lt_sub_of_lt_of_le : ∀{a b c d : }, a < b → c ≤ d → a - d < b - c :=
@algebra.sub_lt_sub_of_lt_of_le _ _
theorem mul_le_mul_of_nonneg_left : ∀{a b c : }, a ≤ b → 0 ≤ c → c * a ≤ c * b :=
@algebra.mul_le_mul_of_nonneg_left _ _
theorem mul_le_mul_of_nonneg_right : ∀{a b c : }, a ≤ b → 0 ≤ c → a * c ≤ b * c :=
@algebra.mul_le_mul_of_nonneg_right _ _
theorem mul_le_mul : ∀{a b c d : }, a ≤ c → b ≤ d → 0 ≤ b → 0 ≤ c → a * b ≤ c * d :=
@algebra.mul_le_mul _ _
theorem mul_nonpos_of_nonneg_of_nonpos : ∀{a b : }, a ≥ 0 → b ≤ 0 → a * b ≤ 0 :=
@algebra.mul_nonpos_of_nonneg_of_nonpos _ _
theorem mul_nonpos_of_nonpos_of_nonneg : ∀{a b : }, a ≤ 0 → b ≥ 0 → a * b ≤ 0 :=
@algebra.mul_nonpos_of_nonpos_of_nonneg _ _
theorem mul_lt_mul_of_pos_left : ∀{a b c : }, a < b → 0 < c → c * a < c * b :=
@algebra.mul_lt_mul_of_pos_left _ _
theorem mul_lt_mul_of_pos_right : ∀{a b c : }, a < b → 0 < c → a * c < b * c :=
@algebra.mul_lt_mul_of_pos_right _ _
theorem mul_lt_mul : ∀{a b c d : }, a < c → b ≤ d → 0 < b → 0 ≤ c → a * b < c * d :=
@algebra.mul_lt_mul _ _
theorem mul_neg_of_pos_of_neg : ∀{a b : }, a > 0 → b < 0 → a * b < 0 :=
@algebra.mul_neg_of_pos_of_neg _ _
theorem mul_neg_of_neg_of_pos : ∀{a b : }, a < 0 → b > 0 → a * b < 0 :=
@algebra.mul_neg_of_neg_of_pos _ _
theorem lt_of_mul_lt_mul_left : ∀{a b c : }, c * a < c * b → c ≥ zero → a < b :=
@algebra.lt_of_mul_lt_mul_left int _
theorem lt_of_mul_lt_mul_right : ∀{a b c : }, a * c < b * c → c ≥ 0 → a < b :=
@algebra.lt_of_mul_lt_mul_right _ _
theorem le_of_mul_le_mul_left : ∀{a b c : }, c * a ≤ c * b → c > 0 → a ≤ b :=
@algebra.le_of_mul_le_mul_left _ _
theorem le_of_mul_le_mul_right : ∀{a b c : }, a * c ≤ b * c → c > 0 → a ≤ b :=
@algebra.le_of_mul_le_mul_right _ _
theorem pos_of_mul_pos_left : ∀{a b : }, 0 < a * b → 0 ≤ a → 0 < b :=
@algebra.pos_of_mul_pos_left _ _
theorem pos_of_mul_pos_right : ∀{a b : }, 0 < a * b → 0 ≤ b → 0 < a :=
@algebra.pos_of_mul_pos_right _ _
theorem mul_le_mul_of_nonpos_left : ∀{a b c : }, b ≤ a → c ≤ 0 → c * a ≤ c * b :=
@algebra.mul_le_mul_of_nonpos_left _ _
theorem mul_le_mul_of_nonpos_right : ∀{a b c : }, b ≤ a → c ≤ 0 → a * c ≤ b * c :=
@algebra.mul_le_mul_of_nonpos_right _ _
theorem mul_nonneg_of_nonpos_of_nonpos : ∀{a b : }, a ≤ 0 → b ≤ 0 → 0 ≤ a * b :=
@algebra.mul_nonneg_of_nonpos_of_nonpos _ _
theorem mul_lt_mul_of_neg_left : ∀{a b c : }, b < a → c < 0 → c * a < c * b :=
@algebra.mul_lt_mul_of_neg_left _ _
theorem mul_lt_mul_of_neg_right : ∀{a b c : }, b < a → c < 0 → a * c < b * c :=
@algebra.mul_lt_mul_of_neg_right _ _
theorem mul_pos_of_neg_of_neg : ∀{a b : }, a < 0 → b < 0 → 0 < a * b :=
@algebra.mul_pos_of_neg_of_neg _ _
theorem mul_self_nonneg : ∀a : , a * a ≥ 0 := algebra.mul_self_nonneg
theorem zero_le_one : #int 0 ≤ 1 := @algebra.zero_le_one int int.linear_ordered_comm_ring
theorem zero_lt_one : #int 0 < 1 := @algebra.zero_lt_one int int.linear_ordered_comm_ring
theorem pos_and_pos_or_neg_and_neg_of_mul_pos : ∀{a b : }, a * b > 0 →
(a > 0 ∧ b > 0) (a < 0 ∧ b < 0) := @algebra.pos_and_pos_or_neg_and_neg_of_mul_pos _ _
end port_algebra
/- more facts specific to int -/
theorem nonneg_of_nat (n : ) : 0 ≤ of_nat n := trivial
theorem exists_eq_of_nat {a : } (H : 0 ≤ a) : ∃n : , a = of_nat n :=
obtain (n : ) (H1 : 0 + of_nat n = a), from le.elim H,
exists.intro n (!zero_add ▸ (H1⁻¹))
theorem exists_eq_neg_of_nat {a : } (H : a ≤ 0) : ∃n : , a = -(of_nat n) :=
have H2 : -a ≥ 0, from iff.mp' !neg_nonneg_iff_nonpos H,
obtain (n : ) (Hn : -a = of_nat n), from exists_eq_of_nat H2,
exists.intro n (eq_neg_of_eq_neg (Hn⁻¹))
theorem of_nat_nat_abs_of_nonneg {a : } (H : a ≥ 0) : of_nat (nat_abs a) = a :=
obtain (n : ) (Hn : a = of_nat n), from exists_eq_of_nat H,
Hn⁻¹ ▸ congr_arg of_nat (nat_abs_of_nat n)
theorem of_nat_nat_abs_of_nonpos {a : } (H : a ≤ 0) : of_nat (nat_abs a) = -a :=
have H1 : (-a) ≥ 0, from iff.mp' !neg_nonneg_iff_nonpos H,
calc
of_nat (nat_abs a) = of_nat (nat_abs (-a)) : nat_abs_neg
... = -a : of_nat_nat_abs_of_nonneg H1
exit
-- ### interaction with add
theorem le_add_of_nat_right (a : ) (n : ) : a ≤ a + n :=
le.intro (eq.refl (a + n))
theorem le_add_of_nat_left (a : ) (n : ) : a ≤ n + a :=
le.intro (add.comm a n)
theorem add_le_right {a b : } (H : a ≤ b) (c : ) : a + c ≤ b + c := theorem add_le_right {a b : } (H : a ≤ b) (c : ) : a + c ≤ b + c :=
add.comm c b ▸ add.comm c a ▸ add_le_left H c add.comm c b ▸ add.comm c a ▸ add_le_add_left H c
theorem add_le {a b c d : } (H1 : a ≤ b) (H2 : c ≤ d) : a + c ≤ b + d := theorem add_le {a b c d : } (H1 : a ≤ b) (H2 : c ≤ d) : a + c ≤ b + d :=
le_trans (add_le_right H1 c) (add_le_left H2 b) le_trans (add_le_right H1 c) (add_le_add_left H2 b)
theorem add_le_cancel_right {a b c : } (H : a + c ≤ b + c) : a ≤ b := theorem add_le_cancel_right {a b c : } (H : a + c ≤ b + c) : a ≤ b :=
have H1 : a + c + -c ≤ b + c + -c, from add_le_right H (-c), have H1 : a + c + -c ≤ b + c + -c, from add_le_right H (-c),
@ -118,7 +516,7 @@ theorem add_le_cancel_left {a b c : } (H : c + a ≤ c + b) : a ≤ b :=
add_le_cancel_right (add.comm c b ▸ add.comm c a ▸ H) add_le_cancel_right (add.comm c b ▸ add.comm c a ▸ H)
theorem add_le_inv {a b c d : } (H1 : a + b ≤ c + d) (H2 : c ≤ a) : b ≤ d := theorem add_le_inv {a b c d : } (H1 : a + b ≤ c + d) (H2 : c ≤ a) : b ≤ d :=
obtain (n : ) (Hn : c + n = a), from le_elim H2, obtain (n : ) (Hn : c + n = a), from le.elim H2,
have H3 : c + (n + b) ≤ c + d, from add.assoc c n b ▸ Hn⁻¹ ▸ H1, have H3 : c + (n + b) ≤ c + d, from add.assoc c n b ▸ Hn⁻¹ ▸ H1,
have H4 : n + b ≤ d, from add_le_cancel_left H3, have H4 : n + b ≤ d, from add_le_cancel_left H3,
show b ≤ d, from le_trans (le_add_of_nat_left b n) H4 show b ≤ d, from le_trans (le_add_of_nat_left b n) H4
@ -127,7 +525,7 @@ theorem le_add_of_nat_right_trans {a b : } (H : a ≤ b) (n : ) : a ≤ b
le_trans H (le_add_of_nat_right b n) le_trans H (le_add_of_nat_right b n)
theorem le_imp_succ_le_or_eq {a b : } (H : a ≤ b) : a + 1 ≤ b a = b := theorem le_imp_succ_le_or_eq {a b : } (H : a ≤ b) : a + 1 ≤ b a = b :=
obtain (n : ) (Hn : a + n = b), from le_elim H, obtain (n : ) (Hn : a + n = b), from le.elim H,
discriminate discriminate
(assume H2 : n = 0, (assume H2 : n = 0,
have H3 : a = b, from have H3 : a = b, from
@ -143,19 +541,19 @@ discriminate
a + 1 + k = a + succ k : by simp a + 1 + k = a + succ k : by simp
... = a + n : by simp ... = a + n : by simp
... = b : Hn, ... = b : Hn,
or.inl (le_intro H3)) or.inl (le.intro H3))
-- ### interaction with neg and sub -- ### interaction with neg and sub
theorem le_neg {a b : } (H : a ≤ b) : -b ≤ -a := theorem le_neg {a b : } (H : a ≤ b) : -b ≤ -a :=
obtain (n : ) (Hn : a + n = b), from le_elim H, obtain (n : ) (Hn : a + n = b), from le.elim H,
have H2 : b - n = a, from (iff.mp !add_eq_iff_eq_add_neg Hn)⁻¹, have H2 : b - n = a, from (iff.mp !add_eq_iff_eq_add_neg Hn)⁻¹,
have H3 : -b + n = -a, from have H3 : -b + n = -a, from
calc calc
-b + n = -b + -(-n) : {(neg_neg n)⁻¹} -b + n = -b + -(-n) : {(neg_neg n)⁻¹}
... = -(b + -n) : (neg_add_distrib b (-n))⁻¹ ... = -(b + -n) : (neg_add_distrib b (-n))⁻¹
... = -a : {H2}, ... = -a : {H2},
le_intro H3 le.intro H3
theorem neg_le_zero {a : } (H : 0 ≤ a) : -a ≤ 0 := theorem neg_le_zero {a : } (H : 0 ≤ a) : -a ≤ 0 :=
neg_zero ▸ (le_neg H) neg_zero ▸ (le_neg H)
@ -167,13 +565,13 @@ theorem le_neg_inv {a b : } (H : -a ≤ -b) : b ≤ a :=
neg_neg b ▸ neg_neg a ▸ le_neg H neg_neg b ▸ neg_neg a ▸ le_neg H
theorem le_sub_of_nat (a : ) (n : ) : a - n ≤ a := theorem le_sub_of_nat (a : ) (n : ) : a - n ≤ a :=
le_intro (neg_add_cancel_right a n) le.intro (neg_add_cancel_right a n)
theorem sub_le_right {a b : } (H : a ≤ b) (c : ) : a - c ≤ b - c := theorem sub_le_right {a b : } (H : a ≤ b) (c : ) : a - c ≤ b - c :=
add_le_right H _ add_le_right H _
theorem sub_le_left {a b : } (H : a ≤ b) (c : ) : c - b ≤ c - a := theorem sub_le_left {a b : } (H : a ≤ b) (c : ) : c - b ≤ c - a :=
add_le_left (le_neg H) _ add_le_add_left (le_neg H) _
theorem sub_le {a b c d : } (H1 : a ≤ b) (H2 : d ≤ c) : a - c ≤ b - d := theorem sub_le {a b c d : } (H1 : a ≤ b) (H2 : d ≤ c) : a - c ≤ b - d :=
add_le H1 (le_neg H2) add_le H1 (le_neg H2)
@ -213,59 +611,14 @@ iff.refl (n ≥ m)
-- add_rewrite gt_def ge_def --it might be possible to remove this in Lean 0.2 -- add_rewrite gt_def ge_def --it might be possible to remove this in Lean 0.2
theorem lt_add_succ (a : ) (n : ) : a < a + succ n :=
le_intro (show a + 1 + n = a + succ n, by simp)
theorem lt_intro {a b : } {n : } (H : a + succ n = b) : a < b :=
H ▸ lt_add_succ a n
theorem lt_elim {a b : } (H : a < b) : ∃n : , a + succ n = b :=
obtain (n : ) (Hn : a + 1 + n = b), from le_elim H,
have H2 : a + succ n = b, from
calc
a + succ n = a + 1 + n : by simp
... = b : Hn,
exists.intro n H2
-- -- ### basic facts -- -- ### basic facts
theorem lt_irrefl (a : ) : ¬ a < a :=
(assume H : a < a,
obtain (n : ) (Hn : a + succ n = a), from lt_elim H,
have H2 : a + succ n = a + 0, from
calc
a + succ n = a : Hn
... = a + 0 : by simp,
have H3 : succ n = 0, from add.left_cancel H2,
have H4 : succ n = 0, from of_nat_inj H3,
absurd H4 !succ_ne_zero)
theorem lt_imp_ne {a b : } (H : a < b) : a ≠ b :=
(assume H2 : a = b, absurd (H2 ▸ H) (lt_irrefl b))
theorem lt_of_nat (n m : ) : (of_nat n < of_nat m) ↔ (n < m) :=
calc
(of_nat n + 1 ≤ of_nat m) ↔ (of_nat (succ n) ≤ of_nat m) : by simp
... ↔ (succ n ≤ m) : le_of_nat (succ n) m
... ↔ (n < m) : iff.symm (nat.lt_def n m)
theorem gt_of_nat (n m : ) : (of_nat n > of_nat m) ↔ (n > m) := theorem gt_of_nat (n m : ) : (of_nat n > of_nat m) ↔ (n > m) :=
lt_of_nat m n of_nat_lt_of_nat m n
-- ### interaction with le -- ### interaction with le
theorem lt_imp_le_succ {a b : } (H : a < b) : a + 1 ≤ b :=
H
theorem le_succ_imp_lt {a b : } (H : a + 1 ≤ b) : a < b :=
H
theorem self_lt_succ (a : ) : a < a + 1 :=
le_refl (a + 1)
theorem lt_imp_le {a b : } (H : a < b) : a ≤ b :=
obtain (n : ) (Hn : a + succ n = b), from lt_elim H,
le_intro Hn
theorem le_imp_lt_or_eq {a b : } (H : a ≤ b) : a < b a = b := theorem le_imp_lt_or_eq {a b : } (H : a ≤ b) : a < b a = b :=
le_imp_succ_le_or_eq H le_imp_succ_le_or_eq H
@ -289,22 +642,22 @@ theorem le_lt_trans {a b c : } (H1 : a ≤ b) (H2 : b < c) : a < c :=
le_trans (add_le_right H1 1) H2 le_trans (add_le_right H1 1) H2
theorem lt_trans {a b c : } (H1 : a < b) (H2 : b < c) : a < c := theorem lt_trans {a b c : } (H1 : a < b) (H2 : b < c) : a < c :=
lt_le_trans H1 (lt_imp_le H2) lt_le_trans H1 (le_of_lt H2)
theorem le_imp_not_gt {a b : } (H : a ≤ b) : ¬ a > b := theorem le_imp_not_gt {a b : } (H : a ≤ b) : ¬ a > b :=
(assume H2 : a > b, absurd (le_lt_trans H H2) (lt_irrefl a)) (assume H2 : a > b, absurd (le_lt_trans H H2) (lt.irrefl a))
theorem lt_imp_not_ge {a b : } (H : a < b) : ¬ a ≥ b := theorem lt_imp_not_ge {a b : } (H : a < b) : ¬ a ≥ b :=
(assume H2 : a ≥ b, absurd (lt_le_trans H H2) (lt_irrefl a)) (assume H2 : a ≥ b, absurd (lt_le_trans H H2) (lt.irrefl a))
theorem lt_antisym {a b : } (H : a < b) : ¬ b < a := theorem lt_antisym {a b : } (H : a < b) : ¬ b < a :=
le_imp_not_gt (lt_imp_le H) le_imp_not_gt (le_of_lt H)
-- ### interaction with addition -- ### interaction with addition
-- TODO: note: no longer works without the "show" -- TODO: note: no longer works without the "show"
theorem add_lt_left {a b : } (H : a < b) (c : ) : c + a < c + b := theorem add_lt_left {a b : } (H : a < b) (c : ) : c + a < c + b :=
show (c + a) + 1 ≤ c + b, from (add.assoc c a 1)⁻¹ ▸ add_le_left H c show (c + a) + 1 ≤ c + b, from (add.assoc c a 1)⁻¹ ▸ add_le_add_left H c
theorem add_lt_right {a b : } (H : a < b) (c : ) : a + c < b + c := theorem add_lt_right {a b : } (H : a < b) (c : ) : a + c < b + c :=
add.comm c b ▸ add.comm c a ▸ add_lt_left H c add.comm c b ▸ add.comm c a ▸ add_lt_left H c
@ -313,10 +666,10 @@ theorem add_le_lt {a b c d : } (H1 : a ≤ c) (H2 : b < d) : a + b < c + d :=
le_lt_trans (add_le_right H1 b) (add_lt_left H2 c) le_lt_trans (add_le_right H1 b) (add_lt_left H2 c)
theorem add_lt_le {a b c d : } (H1 : a < c) (H2 : b ≤ d) : a + b < c + d := theorem add_lt_le {a b c d : } (H1 : a < c) (H2 : b ≤ d) : a + b < c + d :=
lt_le_trans (add_lt_right H1 b) (add_le_left H2 c) lt_le_trans (add_lt_right H1 b) (add_le_add_left H2 c)
theorem add_lt {a b c d : } (H1 : a < c) (H2 : b < d) : a + b < c + d := theorem add_lt {a b c d : } (H1 : a < c) (H2 : b < d) : a + b < c + d :=
add_lt_le H1 (lt_imp_le H2) add_lt_le H1 (le_of_lt H2)
theorem add_lt_cancel_left {a b c : } (H : c + a < c + b) : a < b := theorem add_lt_cancel_left {a b c : } (H : c + a < c + b) : a < b :=
show a + 1 ≤ b, from add_le_cancel_left (add.assoc c a 1 ▸ H) show a + 1 ≤ b, from add_le_cancel_left (add.assoc c a 1 ▸ H)
@ -342,7 +695,7 @@ theorem lt_neg_inv {a b : } (H : -a < -b) : b < a :=
neg_neg b ▸ neg_neg a ▸ lt_neg H neg_neg b ▸ neg_neg a ▸ lt_neg H
theorem lt_sub_of_nat_succ (a : ) (n : ) : a - succ n < a := theorem lt_sub_of_nat_succ (a : ) (n : ) : a - succ n < a :=
lt_intro (neg_add_cancel_right a (succ n)) lt.intro (neg_add_cancel_right a (succ n))
theorem sub_lt_right {a b : } (H : a < b) (c : ) : a - c < b - c := theorem sub_lt_right {a b : } (H : a < b) (c : ) : a - c < b - c :=
add_lt_right H _ add_lt_right H _
@ -375,10 +728,15 @@ by_cases_of_nat a
(take n : , (take n : ,
by_cases_of_nat_succ b by_cases_of_nat_succ b
(take m : , (take m : ,
show of_nat n ≤ m of_nat n > m, by simp) -- from (by simp) ◂ (le_or_gt n m)) show of_nat n ≤ m of_nat n > m, from
proof
or.elim (@nat.le_or_gt n m)
(assume H : n ≤ m, or.inl (iff.mp' !of_nat_le_of_nat H))
(assume H : n > m, or.inr (iff.mp' !of_nat_lt_of_nat H))
qed)
(take m : , (take m : ,
show n ≤ -succ m n > -succ m, from show n ≤ -succ m n > -succ m, from
have H0 : -succ m < -m, from lt_neg ((of_nat_succ m)⁻¹ ▸ self_lt_succ m), have H0 : -succ m < -m, from lt_neg ((of_nat_succ m)⁻¹ ▸ lt_succ m),
have H : -succ m < n, from lt_le_trans H0 (neg_le_pos m n), have H : -succ m < n, from lt_le_trans H0 (neg_le_pos m n),
or.inr H)) or.inr H))
(take n : , (take n : ,
@ -390,9 +748,9 @@ by_cases_of_nat a
show -n ≤ -succ m -n > -succ m, from show -n ≤ -succ m -n > -succ m, from
or_of_or_of_imp_of_imp le_or_gt or_of_or_of_imp_of_imp le_or_gt
(assume H : succ m ≤ n, (assume H : succ m ≤ n,
le_neg (iff.elim_left (iff.symm (le_of_nat (succ m) n)) H)) le_neg (iff.elim_left (iff.symm (of_nat_le_of_nat (succ m) n)) H))
(assume H : succ m > n, (assume H : succ m > n,
lt_neg (iff.elim_left (iff.symm (lt_of_nat n (succ m))) H)))) lt_neg (iff.elim_left (iff.symm (of_nat_lt_of_nat n (succ m))) H))))
theorem trichotomy_alt (a b : ) : (a < b a = b) a > b := theorem trichotomy_alt (a b : ) : (a < b a = b) a > b :=
or_of_or_of_imp_left (le_or_gt a b) (assume H : a ≤ b, le_imp_lt_or_eq H) or_of_or_of_imp_left (le_or_gt a b) (assume H : a ≤ b, le_imp_lt_or_eq H)
@ -401,9 +759,9 @@ theorem trichotomy (a b : ) : a < b a = b a > b :=
iff.elim_left or.assoc (trichotomy_alt a b) iff.elim_left or.assoc (trichotomy_alt a b)
theorem le_total (a b : ) : a ≤ b b ≤ a := theorem le_total (a b : ) : a ≤ b b ≤ a :=
or_of_or_of_imp_right (le_or_gt a b) (assume H : b < a, lt_imp_le H) or_of_or_of_imp_right (le_or_gt a b) (assume H : b < a, le_of_lt H)
theorem not_lt_imp_le {a b : } (H : ¬ a < b) : b ≤ a := theorem not_le_of_lt {a b : } (H : ¬ a < b) : b ≤ a :=
or_resolve_left (le_or_gt b a) H or_resolve_left (le_or_gt b a) H
theorem not_le_imp_lt {a b : } (H : ¬ a ≤ b) : b < a := theorem not_le_imp_lt {a b : } (H : ¬ a ≤ b) : b < a :=
@ -417,7 +775,7 @@ or_resolve_right (le_or_gt a b) H
-- see also "int_by_cases" and similar theorems -- see also "int_by_cases" and similar theorems
theorem pos_imp_exists_nat {a : } (H : a ≥ 0) : ∃n : , a = n := theorem pos_imp_exists_nat {a : } (H : a ≥ 0) : ∃n : , a = n :=
obtain (n : ) (Hn : of_nat 0 + n = a), from le_elim H, obtain (n : ) (Hn : of_nat 0 + n = a), from le.elim H,
exists.intro n (Hn⁻¹ ⬝ zero_add n) exists.intro n (Hn⁻¹ ⬝ zero_add n)
theorem neg_imp_exists_nat {a : } (H : a ≤ 0) : ∃n : , a = -n := theorem neg_imp_exists_nat {a : } (H : a ≤ 0) : ∃n : , a = -n :=
@ -431,7 +789,7 @@ obtain (n : ) (Hn : a = n), from pos_imp_exists_nat H,
Hn⁻¹ ▸ congr_arg of_nat (nat_abs_of_nat n) Hn⁻¹ ▸ congr_arg of_nat (nat_abs_of_nat n)
theorem of_nat_nonneg (n : ) : of_nat n ≥ 0 := theorem of_nat_nonneg (n : ) : of_nat n ≥ 0 :=
iff.mp (iff.symm !le_of_nat) !zero_le iff.mp (iff.symm !of_nat_le_of_nat) !zero_le
definition ge_decidable [instance] {a b : } : decidable (a ≥ b) := _ definition ge_decidable [instance] {a b : } : decidable (a ≥ b) := _
definition lt_decidable [instance] {a b : } : decidable (a < b) := _ definition lt_decidable [instance] {a b : } : decidable (a < b) := _
@ -454,14 +812,14 @@ or_of_or_of_imp_of_imp (le_total 0 a)
-- ### interaction of mul with le and lt -- ### interaction of mul with le and lt
theorem mul_le_left_nonneg {a b c : } (Ha : a ≥ 0) (H : b ≤ c) : a * b ≤ a * c := theorem mul_le_left_nonneg {a b c : } (Ha : a ≥ 0) (H : b ≤ c) : a * b ≤ a * c :=
obtain (n : ) (Hn : b + n = c), from le_elim H, obtain (n : ) (Hn : b + n = c), from le.elim H,
have H2 : a * b + of_nat ((nat_abs a) * n) = a * c, from have H2 : a * b + of_nat ((nat_abs a) * n) = a * c, from
calc calc
a * b + of_nat ((nat_abs a) * n) = a * b + (nat_abs a) * of_nat n : by simp a * b + of_nat ((nat_abs a) * n) = a * b + (nat_abs a) * of_nat n : by simp
... = a * b + a * n : {nat_abs_nonneg_eq Ha} ... = a * b + a * n : {nat_abs_nonneg_eq Ha}
... = a * (b + n) : by simp ... = a * (b + n) : by simp
... = a * c : by simp, ... = a * c : by simp,
le_intro H2 le.intro H2
theorem mul_le_right_nonneg {a b c : } (Hb : b ≥ 0) (H : a ≤ c) : a * b ≤ c * b := theorem mul_le_right_nonneg {a b c : } (Hb : b ≥ 0) (H : a ≤ c) : a * b ≤ c * b :=
!mul.comm ▸ !mul.comm ▸ mul_le_left_nonneg Hb H !mul.comm ▸ !mul.comm ▸ mul_le_left_nonneg Hb H
@ -479,13 +837,13 @@ theorem mul_le_nonneg {a b c d : } (Ha : a ≥ 0) (Hb : b ≥ 0) (Hc : a ≤
: a * b ≤ c * d := : a * b ≤ c * d :=
le_trans (mul_le_right_nonneg Hb Hc) (mul_le_left_nonneg (le_trans Ha Hc) Hd) le_trans (mul_le_right_nonneg Hb Hc) (mul_le_left_nonneg (le_trans Ha Hc) Hd)
theorem mul_le_nonpos {a b c d : } (Ha : a ≤ 0) (Hb : b ≤ 0) (Hc : c ≤ a) (Hd : d ≤ b) theorem mul_le_nonpos {a b c d : } (Ha : a ≤ 0) (Hb :b ≤ 0) (Hc : c ≤ a) (Hd : d ≤ b)
: a * b ≤ c * d := : a * b ≤ c * d :=
le_trans (mul_le_right_nonpos Hb Hc) (mul_le_left_nonpos (le_trans Hc Ha) Hd) le_trans (mul_le_right_nonpos Hb Hc) (mul_le_left_nonpos (le_trans Hc Ha) Hd)
theorem mul_lt_left_pos {a b c : } (Ha : a > 0) (H : b < c) : a * b < a * c := theorem mul_lt_left_pos {a b c : } (Ha : a > 0) (H : b < c) : a * b < a * c :=
have H2 : a * b < a * b + a, from add_zero (a * b) ▸ add_lt_left Ha (a * b), have H2 : a * b < a * b + a, from add_zero (a * b) ▸ add_lt_left Ha (a * b),
have H3 : a * b + a ≤ a * c, from (by simp) ▸ mul_le_left_nonneg (lt_imp_le Ha) H, have H3 : a * b + a ≤ a * c, from (by simp) ▸ mul_le_left_nonneg (le_of_lt Ha) H,
lt_le_trans H2 H3 lt_le_trans H2 H3
theorem mul_lt_right_pos {a b c : } (Hb : b > 0) (H : a < c) : a * b < c * b := theorem mul_lt_right_pos {a b c : } (Hb : b > 0) (H : a < c) : a * b < c * b :=
@ -505,11 +863,11 @@ le_lt_trans (mul_le_right_nonneg Hb Hc) (mul_lt_left_pos (lt_le_trans Ha Hc) Hd)
theorem mul_lt_le_pos {a b c d : } (Ha : a ≥ 0) (Hb : b > 0) (Hc : a < c) (Hd : b ≤ d) theorem mul_lt_le_pos {a b c d : } (Ha : a ≥ 0) (Hb : b > 0) (Hc : a < c) (Hd : b ≤ d)
: a * b < c * d := : a * b < c * d :=
lt_le_trans (mul_lt_right_pos Hb Hc) (mul_le_left_nonneg (le_trans Ha (lt_imp_le Hc)) Hd) lt_le_trans (mul_lt_right_pos Hb Hc) (mul_le_left_nonneg (le_trans Ha (le_of_lt Hc)) Hd)
theorem mul_lt_pos {a b c d : } (Ha : a > 0) (Hb : b > 0) (Hc : a < c) (Hd : b < d) theorem mul_lt_pos {a b c d : } (Ha : a > 0) (Hb : b > 0) (Hc : a < c) (Hd : b < d)
: a * b < c * d := : a * b < c * d :=
mul_lt_le_pos (lt_imp_le Ha) Hb Hc (lt_imp_le Hd) mul_lt_le_pos (le_of_lt Ha) Hb Hc (le_of_lt Hd)
theorem mul_lt_neg {a b c d : } (Ha : a < 0) (Hb : b < 0) (Hc : c < a) (Hd : d < b) theorem mul_lt_neg {a b c d : } (Ha : a < 0) (Hb : b < 0) (Hc : c < a) (Hd : d < b)
: a * b < c * d := : a * b < c * d :=
@ -583,13 +941,13 @@ theorem sign_negative {a : } (H : a < 0) : sign a = - 1 :=
if_neg (lt_antisym H) ⬝ if_pos H if_neg (lt_antisym H) ⬝ if_pos H
theorem sign_zero : sign 0 = 0 := theorem sign_zero : sign 0 = 0 :=
if_neg (lt_irrefl 0) ⬝ if_neg (lt_irrefl 0) if_neg (lt.irrefl 0) ⬝ if_neg (lt.irrefl 0)
-- add_rewrite sign_negative sign_pos nat_abs_negative nat_abs_nonneg_eq sign_zero mul_nat_abs -- add_rewrite sign_negative sign_pos nat_abs_negative nat_abs_nonneg_eq sign_zero mul_nat_abs
theorem mul_sign_nat_abs (a : ) : sign a * (nat_abs a) = a := theorem mul_sign_nat_abs (a : ) : sign a * (nat_abs a) = a :=
have temp1 : ∀a : , a < 0 → a ≤ 0, from take a, lt_imp_le, have temp1 : ∀a : , a < 0 → a ≤ 0, from take a, le_of_lt,
have temp2 : ∀a : , a > 0 → a ≥ 0, from take a, lt_imp_le, have temp2 : ∀a : , a > 0 → a ≥ 0, from take a, le_of_lt,
or.elim3 (trichotomy a 0) or.elim3 (trichotomy a 0)
(assume H : a < 0, by simp) (assume H : a < 0, by simp)
(assume H : a = 0, by simp) (assume H : a = 0, by simp)
@ -615,7 +973,7 @@ or.elim (em (a = 0))
mul.cancel_right H3 H)) mul.cancel_right H3 H))
theorem sign_idempotent (a : ) : sign (sign a) = sign a := theorem sign_idempotent (a : ) : sign (sign a) = sign a :=
have temp : of_nat 1 > 0, from iff.elim_left (iff.symm (lt_of_nat 0 1)) !succ_pos, have temp : of_nat 1 > 0, from iff.elim_left (iff.symm (of_nat_lt_of_nat 0 1)) !succ_pos,
--this should be done with simp --this should be done with simp
or.elim3 (trichotomy a 0) sorry sorry sorry or.elim3 (trichotomy a 0) sorry sorry sorry
-- (by simp) -- (by simp)
@ -623,7 +981,7 @@ or.elim3 (trichotomy a 0) sorry sorry sorry
-- (by simp) -- (by simp)
theorem sign_succ (n : ) : sign (succ n) = 1 := theorem sign_succ (n : ) : sign (succ n) = 1 :=
sign_pos (iff.elim_left (iff.symm (lt_of_nat 0 (succ n))) !succ_pos) sign_pos (iff.elim_left (iff.symm (of_nat_lt_of_nat 0 (succ n))) !succ_pos)
--this should be done with simp --this should be done with simp
theorem sign_neg (a : ) : sign (-a) = - sign a := theorem sign_neg (a : ) : sign (-a) = - sign a :=
@ -644,8 +1002,8 @@ or.elim3 (trichotomy a 0) sorry
-- (by simp) -- (by simp)
theorem sign_nat_abs (a : ) : sign (nat_abs a) = nat_abs (sign a) := theorem sign_nat_abs (a : ) : sign (nat_abs a) = nat_abs (sign a) :=
have temp1 : ∀a : , a < 0 → a ≤ 0, from take a, lt_imp_le, have temp1 : ∀a : , a < 0 → a ≤ 0, from take a, le_of_lt,
have temp2 : ∀a : , a > 0 → a ≥ 0, from take a, lt_imp_le, have temp2 : ∀a : , a > 0 → a ≥ 0, from take a, le_of_lt,
or.elim3 (trichotomy a 0) sorry sorry sorry or.elim3 (trichotomy a 0) sorry sorry sorry
-- (by simp) -- (by simp)
-- (by simp) -- (by simp)

View file

@ -65,6 +65,9 @@ induction_on n
(take m IH, or.inr (take m IH, or.inr
(show succ m = succ (pred (succ m)), from congr_arg succ !pred.succ⁻¹)) (show succ m = succ (pred (succ m)), from congr_arg succ !pred.succ⁻¹))
theorem exists_eq_succ_of_ne_zero {n : } (H : n ≠ 0) : ∃k : , n = succ k :=
exists.intro _ (or_resolve_right !eq_zero_or_eq_succ_pred H)
theorem succ.inj {n m : } (H : succ n = succ m) : n = m := theorem succ.inj {n m : } (H : succ n = succ m) : n = m :=
no_confusion H (λe, e) no_confusion H (λe, e)

View file

@ -13,6 +13,10 @@ open eq.ops
namespace nat namespace nat
-- TODO: move this
theorem lt_iff_succ_le (m n : nat) : m < n ↔ succ m ≤ n :=
iff.intro succ_le_of_lt lt_of_succ_le
-- Less than or equal -- Less than or equal
-- ------------------ -- ------------------