Covariants and contravariants #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
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, covariant_class
and
contravariant_class
:
covariant_class
models the implicationa ≤ b → c * a ≤ c * b
(multiplication is monotone),contravariant_class
models the implicationa * b < a * c → b < c
.
Since co(ntra)variant_class
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 [ordered_cancel_monoid M]
, into three typeclasses, e.g.
[left_cancel_semigroup M] [partial_order M] [covariant_class 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)variant_class assumptions together.
Indeed, the usual ordered typeclasses arise from assuming the pair
[covariant_class M M (*) (≤)] [contravariant_class M M (*) (<)]
on top of order/algebraic assumptions.
A formal remark is that normally covariant_class
uses the (≤)
-relation, while
contravariant_class
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 α] [partial_order α] [contravariant_class α α (*) (≤)] => left_cancel_semigroup α
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 succintly statements about the interactions between an
action of a Type on another one and a relation on the acted-upon Type.
See the covariant_class
doc-string for its meaning.
contravariant
is useful to formulate succintly statements about the interactions between an
action of a Type on another one and a relation on the acted-upon Type.
See the contravariant_class
doc-string for its meaning.
Equations
- contravariant M N μ r = ∀ (m : M) {n₁ n₂ : N}, r (μ m n₁) (μ m n₂) → r n₁ n₂
- elim : covariant M N μ r
Given an action μ
of a Type M
on a Type N
and a relation r
on N
, informally, the
covariant_class
says that "the action μ
preserves the relation r
."
More precisely, the covariant_class
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 covariant_class.elim m h : r (μ m n₁) (μ m n₂)
.
Instances of this typeclass
- pos_mul_strict_mono.to_pos_mul_mono
- mul_pos_strict_mono.to_mul_pos_mono
- canonically_ordered_comm_semiring.to_covariant_mul_le
- idem_semiring.to_covariant_class_mul_le
- idem_semiring.to_covariant_class_swap_mul_le
- ordered_semiring.to_pos_mul_mono
- ordered_semiring.to_mul_pos_mono
- strict_ordered_semiring.to_pos_mul_strict_mono
- strict_ordered_semiring.to_mul_pos_strict_mono
- covariant_mul_lt_of_contravariant_mul_le
- covariant_add_lt_of_contravariant_add_le
- covariant_swap_mul_le_of_covariant_mul_le
- covariant_swap_add_le_of_covariant_add_le
- covariant_swap_mul_lt_of_covariant_mul_lt
- covariant_swap_add_lt_of_covariant_add_lt
- left_cancel_semigroup.covariant_mul_lt_of_covariant_mul_le
- add_left_cancel_semigroup.covariant_add_lt_of_covariant_add_le
- right_cancel_semigroup.covariant_swap_mul_lt_of_covariant_swap_mul_le
- add_right_cancel_semigroup.covariant_swap_add_lt_of_covariant_swap_add_le
- ordered_comm_monoid.to_covariant_class_left
- ordered_add_comm_monoid.to_covariant_class_left
- ordered_comm_monoid.to_covariant_class_right
- ordered_add_comm_monoid.to_covariant_class_right
- ordered_comm_group.to_covariant_class_left_le
- ordered_add_comm_group.to_covariant_class_left_le
- with_zero.covariant_class_mul_le
- pos_mul_mono.to_covariant_class_pos_mul_le
- mul_pos_mono.to_covariant_class_pos_mul_le
- order_dual.covariant_class_mul_le
- order_dual.covariant_class_add_le
- order_dual.covariant_class_swap_mul_le
- order_dual.covariant_class_swap_add_le
- order_dual.covariant_class_mul_lt
- order_dual.covariant_class_add_lt
- order_dual.covariant_class_swap_mul_lt
- order_dual.covariant_class_swap_add_lt
- with_top.covariant_class_add_le
- with_top.covariant_class_swap_add_le
- with_bot.covariant_class_add_le
- with_bot.covariant_class_swap_add_le
- multiset.has_le.le.covariant_class
- positive.covariant_class_add_lt
- positive.covariant_class_swap_add_lt
- positive.covariant_class_add_le
- pnat.has_le.le.covariant_class
- pnat.has_lt.lt.covariant_class
- with_bot.pos_mul_mono
- with_bot.mul_pos_mono
- with_bot.pos_mul_strict_mono
- with_bot.mul_pos_strict_mono
- set_semiring.covariant_class_add
- set_semiring.covariant_class_mul_left
- set_semiring.covariant_class_mul_right
- cardinal.add_covariant_class
- cardinal.add_swap_covariant_class
- ordinal.add_covariant_class_le
- ordinal.add_swap_covariant_class_le
- ordinal.add_covariant_class_lt
- ordinal.mul_covariant_class_le
- ordinal.mul_swap_covariant_class_le
- filter.covariant_mul
- filter.covariant_add
- filter.covariant_swap_mul
- filter.covariant_swap_add
- filter.covariant_div
- filter.covariant_sub
- filter.covariant_swap_div
- filter.covariant_swap_sub
- filter.covariant_smul
- filter.covariant_vadd
- filter.covariant_smul_filter
- filter.covariant_vadd_filter
- nnreal.covariant_add
- nnreal.covariant_mul
- ennreal.covariant_class_mul_le
- ennreal.covariant_class_add_le
- elim : contravariant M N μ r
Given an action μ
of a Type M
on a Type N
and a relation r
on N
, informally, the
contravariant_class
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 contravariant_class
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 contravariant_class.elim m h : r n₁ n₂
.
Instances of this typeclass
- group.covconv
- add_group.covconv
- group.covconv_swap
- add_group.covconv_swap
- pos_mul_strict_mono.to_pos_mul_mono_rev
- mul_pos_strict_mono.to_mul_pos_mono_rev
- pos_mul_mono_rev.to_pos_mul_reflect_lt
- mul_pos_mono_rev.to_mul_pos_reflect_lt
- ordered_cancel_comm_monoid.to_contravariant_class_le_left
- ordered_cancel_add_comm_monoid.to_contravariant_class_le_left
- linear_ordered_semiring.to_pos_mul_reflect_lt
- linear_ordered_semiring.to_mul_pos_reflect_lt
- contravariant_mul_lt_of_covariant_mul_le
- contravariant_add_lt_of_covariant_add_le
- contravariant_swap_mul_le_of_contravariant_mul_le
- contravariant_swap_add_le_of_contravariant_add_le
- contravariant_swap_mul_lt_of_contravariant_mul_lt
- contravariant_swap_add_lt_of_contravariant_add_lt
- left_cancel_semigroup.contravariant_mul_le_of_contravariant_mul_lt
- add_left_cancel_semigroup.contravariant_add_le_of_contravariant_add_lt
- right_cancel_semigroup.contravariant_swap_mul_le_of_contravariant_swap_mul_lt
- add_right_cancel_semigroup.contravariant_swap_add_le_of_contravariant_swap_add_lt
- ordered_cancel_comm_monoid.to_contravariant_class_left
- ordered_cancel_add_comm_monoid.to_contravariant_class_left
- ordered_cancel_comm_monoid.to_contravariant_class_right
- ordered_cancel_add_comm_monoid.to_contravariant_class_right
- pos_mul_reflect_lt.to_contravariant_class_pos_mul_lt
- mul_pos_reflect_lt.to_contravariant_class_pos_mul_lt
- order_dual.contravariant_class_mul_le
- order_dual.contravariant_class_add_le
- order_dual.contravariant_class_swap_mul_le
- order_dual.contravariant_class_swap_add_le
- order_dual.contravariant_class_mul_lt
- order_dual.contravariant_class_add_lt
- order_dual.contravariant_class_swap_mul_lt
- order_dual.contravariant_class_swap_add_lt
- order_dual.ordered_cancel_comm_monoid.to_contravariant_class
- ordered_cancel_add_comm_monoid.to_contravariant_class
- with_zero.contravariant_class_mul_lt
- with_top.contravariant_class_add_lt
- with_top.contravariant_class_swap_add_lt
- with_bot.contravariant_class_add_lt
- with_bot.contravariant_class_swap_add_lt
- multiset.has_le.le.contravariant_class
- positive.contravariant_class_add_lt
- positive.contravariant_class_swap_add_lt
- positive.contravariant_class_add_le
- positive.contravariant_class_swap_add_le
- pnat.has_le.le.contravariant_class
- pnat.has_lt.lt.contravariant_class
- with_bot.pos_mul_reflect_lt
- with_bot.mul_pos_reflect_lt
- with_bot.pos_mul_mono_rev
- with_bot.mul_pos_mono_rev
- finsupp.has_le.le.contravariant_class
- ordinal.add_contravariant_class_le
- ordinal.add_contravariant_class_lt
- ordinal.add_swap_contravariant_class_lt
- nnreal.contravariant_add
- ennreal.contravariant_class_add_lt
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 (λ 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 (λ n, f (n + m))
.
Dual of monotone.covariant_of_const
Dual of monotone.covariant_of_const'