Covariants and contravariants #
This file contains general lemmas and instances to work with the interactions between a relation and an action on a Type.
The intended application is the splitting of the ordering from the algebraic assumptions on the
operations in the Ordered[...]
hierarchy.
The strategy is to introduce two more flexible typeclasses, CovariantClass
and
ContravariantClass
:
CovariantClass
models the implicationa ≤ b → c * a ≤ c * b
(multiplication is monotone),ContravariantClass
models the implicationa * b < a * c → b < c
.
Since Co(ntra)variantClass
takes as input the operation (typically (+)
or (*)
) and the order
relation (typically (≤)
or (<)
), these are the only two typeclasses that I have used.
The general approach is to formulate the lemma that you are interested in and prove it, with the
Ordered[...]
typeclass of your liking. After that, you convert the single typeclass,
say [OrderedCancelMonoid M]
, into three typeclasses, e.g.
[CancelMonoid M] [PartialOrder M] [CovariantClass M M (Function.swap (*)) (≤)]
and have a go at seeing if the proof still works!
Note that it is possible to combine several Co(ntra)variantClass
assumptions together.
Indeed, the usual ordered typeclasses arise from assuming the pair
[CovariantClass M M (*) (≤)] [ContravariantClass M M (*) (<)]
on top of order/algebraic assumptions.
A formal remark is that normally CovariantClass
uses the (≤)
-relation, while
ContravariantClass
uses the (<)
-relation. This need not be the case in general, but seems to be
the most common usage. In the opposite direction, the implication
[Semigroup α] [PartialOrder α] [ContravariantClass α α (*) (≤)] → LeftCancelSemigroup α
holds -- note the Co*ntra*
assumption on the (≤)
-relation.
Formalization notes #
We stick to the convention of using Function.swap (*)
(or Function.swap (+)
), for the
typeclass assumptions, since Function.swap
is slightly better behaved than flip
.
However, sometimes as a non-typeclass assumption, we prefer flip (*)
(or flip (+)
),
as it is easier to use.
Covariant
is useful to formulate succinctly statements about the interactions between an
action of a Type on another one and a relation on the acted-upon Type.
See the CovariantClass
doc-string for its meaning.
Instances For
Contravariant
is useful to formulate succinctly statements about the interactions between an
action of a Type on another one and a relation on the acted-upon Type.
See the ContravariantClass
doc-string for its meaning.
Equations
- Contravariant M N μ r = ∀ (m : M) {n₁ n₂ : N}, r (μ m n₁) (μ m n₂) → r n₁ n₂
Instances For
Given an action μ
of a Type M
on a Type N
and a relation r
on N
, informally, the
CovariantClass
says that "the action μ
preserves the relation r
."
More precisely, the CovariantClass
is a class taking two Types M N
, together with an "action"
μ : M → N → N
and a relation r : N → N → Prop
. Its unique field elim
is the assertion that
for all m ∈ M
and all elements n₁, n₂ ∈ N
, if the relation r
holds for the pair
(n₁, n₂)
, then, the relation r
also holds for the pair (μ m n₁, μ m n₂)
,
obtained from (n₁, n₂)
by acting upon it by m
.
If m : M
and h : r n₁ n₂
, then CovariantClass.elim m h : r (μ m n₁) (μ m n₂)
.
- elim : Covariant M N μ r
For all
m ∈ M
and all elementsn₁, n₂ ∈ N
, if the relationr
holds for the pair(n₁, n₂)
, then, the relationr
also holds for the pair(μ m n₁, μ m n₂)
Instances
For all m ∈ M
and all elements n₁, n₂ ∈ N
, if the relation r
holds for the pair
(n₁, n₂)
, then, the relation r
also holds for the pair (μ m n₁, μ m n₂)
Given an action μ
of a Type M
on a Type N
and a relation r
on N
, informally, the
ContravariantClass
says that "if the result of the action μ
on a pair satisfies the
relation r
, then the initial pair satisfied the relation r
."
More precisely, the ContravariantClass
is a class taking two Types M N
, together with an
"action" μ : M → N → N
and a relation r : N → N → Prop
. Its unique field elim
is the
assertion that for all m ∈ M
and all elements n₁, n₂ ∈ N
, if the relation r
holds for the
pair (μ m n₁, μ m n₂)
obtained from (n₁, n₂)
by acting upon it by m
, then, the relation
r
also holds for the pair (n₁, n₂)
.
If m : M
and h : r (μ m n₁) (μ m n₂)
, then ContravariantClass.elim m h : r n₁ n₂
.
- elim : Contravariant M N μ r
For all
m ∈ M
and all elementsn₁, n₂ ∈ N
, if the relationr
holds for the pair(μ m n₁, μ m n₂)
obtained from(n₁, n₂)
by acting upon it bym
, then, the relationr
also holds for the pair(n₁, n₂)
.
Instances
For all m ∈ M
and all elements n₁, n₂ ∈ N
, if the relation r
holds for the
pair (μ m n₁, μ m n₂)
obtained from (n₁, n₂)
by acting upon it by m
, then, the relation
r
also holds for the pair (n₁, n₂)
.
Typeclass for monotonicity of multiplication on the left,
namely b₁ ≤ b₂ → a * b₁ ≤ a * b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCommMonoid
.
Equations
- MulLeftMono M = CovariantClass M M (fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for monotonicity of multiplication on the right,
namely a₁ ≤ a₂ → a₁ * b ≤ a₂ * b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCommMonoid
.
Equations
- MulRightMono M = CovariantClass M M (Function.swap fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for monotonicity of addition on the left,
namely b₁ ≤ b₂ → a + b₁ ≤ a + b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedAddCommMonoid
.
Equations
- AddLeftMono M = CovariantClass M M (fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for monotonicity of addition on the right,
namely a₁ ≤ a₂ → a₁ + b ≤ a₂ + b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedAddCommMonoid
.
Equations
- AddRightMono M = CovariantClass M M (Function.swap fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for monotonicity of multiplication on the left,
namely b₁ < b₂ → a * b₁ < a * b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCommGroup
.
Equations
- MulLeftStrictMono M = CovariantClass M M (fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for monotonicity of multiplication on the right,
namely a₁ < a₂ → a₁ * b < a₂ * b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCommGroup
.
Equations
- MulRightStrictMono M = CovariantClass M M (Function.swap fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for monotonicity of addition on the left,
namely b₁ < b₂ → a + b₁ < a + b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedAddCommGroup
.
Equations
- AddLeftStrictMono M = CovariantClass M M (fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for monotonicity of addition on the right,
namely a₁ < a₂ → a₁ + b < a₂ + b
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedAddCommGroup
.
Equations
- AddRightStrictMono M = CovariantClass M M (Function.swap fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for strict reverse monotonicity of multiplication on the left,
namely a * b₁ < a * b₂ → b₁ < b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCommGroup
.
Equations
- MulLeftReflectLT M = ContravariantClass M M (fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for strict reverse monotonicity of multiplication on the right,
namely a₁ * b < a₂ * b → a₁ < a₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCommGroup
.
Equations
- MulRightReflectLT M = ContravariantClass M M (Function.swap fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for strict reverse monotonicity of addition on the left,
namely a + b₁ < a + b₂ → b₁ < b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedAddCommGroup
.
Equations
- AddLeftReflectLT M = ContravariantClass M M (fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for strict reverse monotonicity of addition on the right,
namely a₁ * b < a₂ * b → a₁ < a₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedAddCommGroup
.
Equations
- AddRightReflectLT M = ContravariantClass M M (Function.swap fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x < x_1
Instances For
Typeclass for reverse monotonicity of multiplication on the left,
namely a * b₁ ≤ a * b₂ → b₁ ≤ b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCancelCommMonoid
.
Equations
- MulLeftReflectLE M = ContravariantClass M M (fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for reverse monotonicity of multiplication on the right,
namely a₁ * b ≤ a₂ * b → a₁ ≤ a₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCancelCommMonoid
.
Equations
- MulRightReflectLE M = ContravariantClass M M (Function.swap fun (x x_1 : M) => x * x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for reverse monotonicity of addition on the left,
namely a + b₁ ≤ a + b₂ → b₁ ≤ b₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCancelAddCommMonoid
.
Equations
- AddLeftReflectLE M = ContravariantClass M M (fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Typeclass for reverse monotonicity of addition on the right,
namely a₁ + b ≤ a₂ + b → a₁ ≤ a₂
.
You should usually not use this very granular typeclass directly, but rather a typeclass like
OrderedCancelAddCommMonoid
.
Equations
- AddRightReflectLE M = ContravariantClass M M (Function.swap fun (x x_1 : M) => x + x_1) fun (x x_1 : M) => x ≤ x_1
Instances For
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
The partial application of a constant to a covariant operator is monotone.
A monotone function remains monotone when composed with the partial application
of a covariant operator. E.g., ∀ (m : ℕ), Monotone f → Monotone (fun n ↦ f (m + n))
.
Same as Monotone.covariant_of_const
, but with the constant on the other side of
the operator. E.g., ∀ (m : ℕ), Monotone f → Monotone (fun n ↦ f (n + m))
.
Dual of Monotone.covariant_of_const
Dual of Monotone.covariant_of_const'
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯
Equations
- ⋯ = ⋯