Monotonicity of multiplication by positive elements #
This file defines typeclasses to reason about monotonicity of the operations
b ↦ a * b
, "left multiplication"a ↦ a * b
, "right multiplication"
We use eight typeclasses to encode the various properties we care about for those two operations. These typeclasses are meant to be mostly internal to this file, to set up each lemma in the appropriate generality.
Less granular typeclasses like OrderedAddCommMonoid
, `LinearOrderedField`` should be enough for
most purposes, and the system is set up so that they imply the correct granular typeclasses here.
If those are enough for you, you may stop reading here! Else, beware that what follows is a bit
technical.
Definitions #
In all that follows, α
is an orders which has a 0
and a multiplication. Note however that we do
not use lawfulness of this action in most of the file. Hence *
should be considered here as a
mostly arbitrary function α → α → α
.
We use the following four typeclasses to reason about left multiplication (b ↦ a * b
):
PosMulMono
: Ifa ≥ 0
, thenb₁ ≤ b₂ → a * b₁ ≤ a * b₂
.PosMulStrictMono
: Ifa > 0
, thenb₁ < b₂ → a * b₁ < a * b₂
.PosMulReflectLT
: Ifa ≥ 0
, thena * b₁ < a * b₂ → b₁ < b₂
.PosMulReflectLE
: Ifa > 0
, thena * b₁ ≤ a * b₂ → b₁ ≤ b₂
.
We use the following four typeclasses to reason about right multiplication (a ↦ a * b
):
MulPosMono
: Ifb ≥ 0
, thena₁ ≤ a₂ → a₁ * b ≤ a₂ * b
.MulPosStrictMono
: Ifb > 0
, thena₁ < a₂ → a₁ * b < a₂ * b
.MulPosReflectLT
: Ifb ≥ 0
, thena₁ * b < a₂ * b → a₁ < a₂
.MulPosReflectLE
: Ifb > 0
, thena₁ * b ≤ a₂ * b → a₁ ≤ a₂
.
Implications #
As α
gets more and more structure, those typeclasses end up being equivalent. The commonly used
implications are:
- When
α
is a partial order: PosMulStrictMono → PosMulMono
MulPosStrictMono → MulPosMono
PosMulReflectLE → PosMulReflectLT
MulPosReflectLE → MulPosReflectLT
- When
α
is a linear order: - When the multiplication of
α
is commutative:
Further, the bundled non-granular typeclasses imply the granular ones like so:
OrderedSemiring → PosMulMono
OrderedSemiring → MulPosMono
StrictOrderedSemiring → PosMulStrictMono
StrictOrderedSemiring → MulPosStrictMono
All these are registered as instances, which means that in practice you should not worry about these implications. However, if you encounter a case where you think a statement is true but not covered by the current implications, please bring it up on Zulip!
Notation #
The following is local notation in this file:
α≥0
:{x : α // 0 ≤ x}
α>0
:{x : α // 0 < x}
See https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/notation.20for.20positive.20elements for a discussion about this notation, and whether to enable it globally (note that the notation is currently global but broken, hence actually only works locally).
Local notation for the nonnegative elements of a type α
. TODO: actually make local.
Equations
- «termα≥0» = Lean.ParserDescr.node `termα≥0 1024 (Lean.ParserDescr.symbol "α≥0")
Instances For
Local notation for the positive elements of a type α
. TODO: actually make local.
Equations
- «termα>0» = Lean.ParserDescr.node `termα>0 1024 (Lean.ParserDescr.symbol "α>0")
Instances For
Typeclass for monotonicity of multiplication by nonnegative elements on the left,
namely b₁ ≤ b₂ → a * b₁ ≤ a * b₂
if 0 ≤ a
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedSemiring
.
Equations
- PosMulMono α = CovariantClass { x : α // 0 ≤ x } α (fun (x : { x : α // 0 ≤ x }) (y : α) => ↑x * y) fun (x x_1 : α) => x ≤ x_1
Instances For
Typeclass for monotonicity of multiplication by nonnegative elements on the right,
namely a₁ ≤ a₂ → a₁ * b ≤ a₂ * b
if 0 ≤ b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedSemiring
.
Equations
- MulPosMono α = CovariantClass { x : α // 0 ≤ x } α (fun (x : { x : α // 0 ≤ x }) (y : α) => y * ↑x) fun (x x_1 : α) => x ≤ x_1
Instances For
Typeclass for strict monotonicity of multiplication by positive elements on the left,
namely b₁ < b₂ → a * b₁ < a * b₂
if 0 < a
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
StrictOrderedSemiring
.
Equations
- PosMulStrictMono α = CovariantClass { x : α // 0 < x } α (fun (x : { x : α // 0 < x }) (y : α) => ↑x * y) fun (x x_1 : α) => x < x_1
Instances For
Typeclass for strict monotonicity of multiplication by positive elements on the right,
namely a₁ < a₂ → a₁ * b < a₂ * b
if 0 < b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
StrictOrderedSemiring
.
Equations
- MulPosStrictMono α = CovariantClass { x : α // 0 < x } α (fun (x : { x : α // 0 < x }) (y : α) => y * ↑x) fun (x x_1 : α) => x < x_1
Instances For
Typeclass for strict reverse monotonicity of multiplication by nonnegative elements on
the left, namely a * b₁ < a * b₂ → b₁ < b₂
if 0 ≤ a
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
LinearOrderedSemiring
.
Equations
- PosMulReflectLT α = ContravariantClass { x : α // 0 ≤ x } α (fun (x : { x : α // 0 ≤ x }) (y : α) => ↑x * y) fun (x x_1 : α) => x < x_1
Instances For
Typeclass for strict reverse monotonicity of multiplication by nonnegative elements on
the right, namely a₁ * b < a₂ * b → a₁ < a₂
if 0 ≤ b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
LinearOrderedSemiring
.
Equations
- MulPosReflectLT α = ContravariantClass { x : α // 0 ≤ x } α (fun (x : { x : α // 0 ≤ x }) (y : α) => y * ↑x) fun (x x_1 : α) => x < x_1
Instances For
Typeclass for reverse monotonicity of multiplication by positive elements on the left,
namely a * b₁ ≤ a * b₂ → b₁ ≤ b₂
if 0 < a
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
LinearOrderedSemiring
.
Equations
- PosMulReflectLE α = ContravariantClass { x : α // 0 < x } α (fun (x : { x : α // 0 < x }) (y : α) => ↑x * y) fun (x x_1 : α) => x ≤ x_1
Instances For
Typeclass for reverse monotonicity of multiplication by positive elements on the right,
namely a₁ * b ≤ a₂ * b → a₁ ≤ a₂
if 0 < b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
LinearOrderedSemiring
.
Equations
- MulPosReflectLE α = ContravariantClass { x : α // 0 < x } α (fun (x : { x : α // 0 < x }) (y : α) => y * ↑x) fun (x x_1 : α) => x ≤ x_1
Instances For
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Alias of lt_of_mul_lt_mul_left
.
Alias of lt_of_mul_lt_mul_right
.
Alias of le_of_mul_le_mul_left
.
Alias of le_of_mul_le_mul_right
.
Alias of mul_le_mul_left
.
Alias of mul_le_mul_right
.
Alias of mul_lt_mul_left
.
Alias of mul_lt_mul_right
.
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Assumes left covariance.
Alias of Left.mul_pos
.
Assumes left covariance.
Assumes right covariance.
Assumes left covariance.
Alias of Left.mul_nonneg
.
Assumes left covariance.
Assumes right covariance.
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Lemmas of the form a ≤ a * b ↔ 1 ≤ b
and a * b ≤ a ↔ b ≤ 1
,
which assume left covariance.
Lemmas of the form a ≤ b * a ↔ 1 ≤ b
and a * b ≤ b ↔ a ≤ 1
,
which assume right covariance.
Lemmas of the form 1 ≤ b → a ≤ a * b
.
Variants with < 0
and ≤ 0
instead of 0 <
and 0 ≤
appear in Mathlib/Algebra/Order/Ring/Defs
(which imports this file) as they need additional results which are not yet available here.
Lemmas of the form b ≤ c → a ≤ 1 → b * a ≤ c
.
Assumes left covariance.
Assumes left covariance.
Assumes left covariance.
Lemmas of the form b ≤ c → 1 ≤ a → b ≤ c * a
.
Assumes left covariance.
Assumes left covariance.
Assumes left covariance.
Lemmas of the form a ≤ 1 → b ≤ c → a * b ≤ c
.
Assumes right covariance.
Assumes right covariance.
Assumes right covariance.
Lemmas of the form 1 ≤ a → b ≤ c → b ≤ a * c
.
Assumes right covariance.
Assumes right covariance.
Assumes right covariance.
Assumes right covariance.