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
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
Equations
- (_ : ContravariantClass N N (fun (x x_1 : N) => x + x_1) r) = (_ : ContravariantClass N N (fun (x x_1 : N) => x + x_1) r)
Equations
- (_ : ContravariantClass N N (fun (x x_1 : N) => x * x_1) r) = (_ : ContravariantClass N N (fun (x x_1 : N) => x * x_1) r)
Equations
- (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x + x_1) r) = (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x + x_1) r)
Equations
- (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x * x_1) r) = (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x * x_1) r)
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
- (_ : ContravariantClass N N mu fun (x x_1 : N) => x < x_1) = (_ : ContravariantClass N N mu fun (x x_1 : N) => x < x_1)
Equations
- (_ : CovariantClass N N mu fun (x x_1 : N) => x < x_1) = (_ : CovariantClass N N mu fun (x x_1 : N) => x < x_1)
Equations
- (_ : CovariantClass N N (Function.swap fun (x x_1 : N) => x + x_1) r) = (_ : CovariantClass N N (Function.swap fun (x x_1 : N) => x + x_1) r)
Equations
- (_ : CovariantClass N N (Function.swap fun (x x_1 : N) => x * x_1) r) = (_ : CovariantClass N N (Function.swap fun (x x_1 : N) => x * x_1) r)
Equations
- (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x + x_1) r) = (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x + x_1) r)
Equations
- (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x * x_1) r) = (_ : ContravariantClass N N (Function.swap fun (x x_1 : N) => x * x_1) r)
Equations
- (_ : CovariantClass N N (fun (x x_1 : N) => x + x_1) fun (x x_1 : N) => x < x_1) = (_ : CovariantClass N N (fun (x x_1 : N) => x + x_1) fun (x x_1 : N) => x < x_1)
Equations
- (_ : CovariantClass N N (fun (x x_1 : N) => x * x_1) fun (x x_1 : N) => x < x_1) = (_ : CovariantClass N N (fun (x x_1 : N) => x * x_1) fun (x x_1 : N) => x < x_1)
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- (_ : ContravariantClass N N (fun (x x_1 : N) => x + x_1) fun (x x_1 : N) => x ≤ x_1) = (_ : ContravariantClass N N (fun (x x_1 : N) => x + x_1) fun (x x_1 : N) => x ≤ x_1)
Equations
- (_ : ContravariantClass N N (fun (x x_1 : N) => x * x_1) fun (x x_1 : N) => x ≤ x_1) = (_ : ContravariantClass N N (fun (x x_1 : N) => x * x_1) fun (x x_1 : N) => x ≤ x_1)
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.