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:
CovariantClassmodels the implicationa ≤ b → c * a ≤ c * b(multiplication is monotone),ContravariantClassmodels 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 ∈ Mand all elementsn₁, n₂ ∈ N, if the relationrholds for the pair(n₁, n₂), then, the relationralso holds for the pair(μ m n₁, μ m n₂)
Instances
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 ∈ Mand all elementsn₁, n₂ ∈ N, if the relationrholds for the pair(μ m n₁, μ m n₂)obtained from(n₁, n₂)by acting upon it bym, then, the relationralso holds for the pair(n₁, n₂).
Instances
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 < x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 * x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 ≤ x2
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 (x1 x2 : M) => x1 + x2) fun (x1 x2 : M) => x1 ≤ x2
Instances For
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'