Equivalence between types #
In this file we define two types:
-
equiv α βa.k.a.α ≃ β: a bijective mapα → βbundled with its inverse map; we use this (and not equality!) to express that variousTypes orSorts are equivalent. -
equiv.perm α: the group of permutationsα ≃ α. More lemmas aboutequiv.permcan be found ingroup_theory/perm.
Then we define
-
canonical isomorphisms between various types: e.g.,
-
equiv.refl αis the identity map interpreted asα ≃ α; -
equiv.sum_equiv_sigma_boolis the canonical equivalence between the sum of two typesα ⊕ βand the sigma-typeΣ b : bool, cond b α β; -
equiv.prod_sum_distrib : α × (β ⊕ γ) ≃ (α × β) ⊕ (α × γ)shows that type product and type sum satisfy the distributive law up to a canonical equivalence;
-
-
operations on equivalences: e.g.,
-
equiv.symm e : β ≃ αis the inverse ofe : α ≃ β; -
equiv.trans e₁ e₂ : α ≃ γis the composition ofe₁ : α ≃ βande₂ : β ≃ γ(note the order of the arguments!); -
equiv.prod_congr ea eb : α₁ × β₁ ≃ α₂ × β₂: combine two equivalencesea : α₁ ≃ α₂andeb : β₁ ≃ β₂usingprod.map.
-
-
definitions that transfer some instances along an equivalence. By convention, we transfer instances from right to left.
equiv.inhabitedtakese : α ≃ βand[inhabited β]and returnsinhabited α;equiv.uniquetakese : α ≃ βand[unique β]and returnsunique α;equiv.decidable_eqtakese : α ≃ βand[decidable_eq β]and returnsdecidable_eq α.
More definitions of this kind can be found in other files. E.g.,
data/equiv/transfer_instancedoes it for many algebraic type classes likegroup,module, etc.
Tags #
equivalence, congruence, bijective map
- to_fun : α → β
- inv_fun : β → α
- left_inv : function.left_inverse c.inv_fun c.to_fun
- right_inv : function.right_inverse c.inv_fun c.to_fun
α ≃ β is the type of functions from α → β with a two-sided inverse.
Convert an involutive function f to an equivalence with to_fun = inv_fun = f.
perm α is the type of bijections from α to itself.
Equations
- equiv.perm α = (α ≃ α)
Equations
- equiv.has_coe_to_fun = {F := λ (x : α ≃ β), α → β, coe := equiv.to_fun β}
The map coe_fn : (r ≃ s) → (r → s) is injective.
Equations
- equiv.inhabited' = {default := equiv.refl α}
See Note [custom simps projection]
Equations
- equiv.simps.symm_apply e = ⇑(e.symm)
If α is equivalent to β and γ is equivalent to δ, then the type of equivalences α ≃ γ
is equivalent to the type of equivalences β ≃ δ.
If α is equivalent to β, then perm α is equivalent to perm β.
Equations
- e.perm_congr = e.equiv_congr e
Equations
If α is an empty type, then it is equivalent to the pempty type in any universe.
empty is equivalent to pempty.
Equations
- equiv.empty_equiv_pempty = equiv.equiv_pempty equiv.empty_equiv_pempty._proof_1
pempty types from any two universes are equivalent.
Equations
ulift α is equivalent to α.
Equations
- equiv.ulift = {to_fun := ulift.down α, inv_fun := ulift.up α, left_inv := _, right_inv := _}
plift α is equivalent to α.
Equations
- equiv.plift = {to_fun := plift.down α, inv_fun := plift.up α, left_inv := _, right_inv := _}
If α₁ is equivalent to α₂ and β₁ is equivalent to β₂, then the type of maps α₁ → β₁
is equivalent to the type of maps α₂ → β₂.
A version of equiv.arrow_congr in Type, rather than Sort.
The equiv_rw tactic is not able to use the default Sort level equiv.arrow_congr,
because Lean's universe rules will not unify ?l_1 with imax (1 ?m_1).
Equations
- hα.arrow_congr' hβ = hα.arrow_congr hβ
Conjugate a map f : α → α by an equivalence α ≃ β.
Equations
- e.conj = e.arrow_congr e
punit sorts in any two universes are equivalent.
Equations
- equiv.punit_equiv_punit = {to_fun := λ (_x : punit), punit.star, inv_fun := λ (_x : punit), punit.star, left_inv := equiv.punit_equiv_punit._proof_1, right_inv := equiv.punit_equiv_punit._proof_2}
The sort of maps to punit.{v} is equivalent to punit.{w}.
Equations
- equiv.arrow_punit_equiv_punit α = {to_fun := λ (f : α → punit), punit.star, inv_fun := λ (u : punit) (f : α), punit.star, left_inv := _, right_inv := _}
Product of two equivalences. If α₁ ≃ α₂ and β₁ ≃ β₂, then α₁ × β₁ ≃ α₂ × β₂.
Type product is associative up to an equivalence.
Functions on α × β are equivalent to functions α → β → γ.
Equations
- equiv.curry α β γ = {to_fun := function.curry γ, inv_fun := function.uncurry γ, left_inv := _, right_inv := _}
punit is a left identity for type product up to an equivalence.
Equations
- equiv.punit_prod α = (equiv.prod_comm punit α).trans (equiv.prod_punit α)
empty type is a right absorbing element for type product up to an equivalence.
Equations
empty type is a left absorbing element for type product up to an equivalence.
Equations
pempty type is a right absorbing element for type product up to an equivalence.
Equations
pempty type is a left absorbing element for type product up to an equivalence.
Equations
If α ≃ α' and β ≃ β', then α ⊕ β ≃ α' ⊕ β'.
Combine a permutation of α and of β into a permutation of α ⊕ β.
Equations
- ea.sum_congr eb = equiv.sum_congr ea eb
bool is equivalent the sum of two punits.
Equations
- equiv.bool_equiv_punit_sum_punit = {to_fun := λ (b : bool), cond b (sum.inr punit.star) (sum.inl punit.star), inv_fun := λ (s : punit ⊕ punit), s.rec_on (λ (_x : punit), ff) (λ (_x : punit), tt), left_inv := equiv.bool_equiv_punit_sum_punit._proof_1, right_inv := equiv.bool_equiv_punit_sum_punit._proof_2}
Sum of types is associative up to an equivalence.
The sum of empty with any Sort* is equivalent to the right summand.
Equations
- equiv.empty_sum α = (equiv.sum_comm empty α).trans (equiv.sum_empty α)
The sum of pempty with any Sort* is equivalent to the right summand.
Equations
- equiv.pempty_sum α = (equiv.sum_comm pempty α).trans (equiv.sum_pempty α)
option α is equivalent to α ⊕ punit
Equations
- equiv.option_equiv_sum_punit α = {to_fun := λ (o : option α), equiv.option_equiv_sum_punit._match_1 α o, inv_fun := λ (s : α ⊕ punit), equiv.option_equiv_sum_punit._match_2 α s, left_inv := _, right_inv := _}
- equiv.option_equiv_sum_punit._match_1 α (some a) = sum.inl a
- equiv.option_equiv_sum_punit._match_1 α none = sum.inr punit.star
- equiv.option_equiv_sum_punit._match_2 α (sum.inr _x) = none
- equiv.option_equiv_sum_punit._match_2 α (sum.inl a) = some a
The set of x : option α such that is_some x is equivalent to α.
α ⊕ β is equivalent to a sigma-type over bool. Note that this definition assumes α and
β to be types from the same universe, so it cannot by used directly to transfer theorems about
sigma types to theorems about sum types. In many cases one can use ulift to work around this
difficulty.
Equations
- equiv.sum_equiv_sigma_bool α β = {to_fun := λ (s : α ⊕ β), sum.elim (λ (x : α), ⟨tt, x⟩) (λ (x : β), ⟨ff, x⟩) s, inv_fun := λ (s : Σ (b : bool), cond b α β), equiv.sum_equiv_sigma_bool._match_1 α β s, left_inv := _, right_inv := _}
- equiv.sum_equiv_sigma_bool._match_1 α β ⟨tt, a⟩ = sum.inl a
- equiv.sum_equiv_sigma_bool._match_1 α β ⟨ff, b⟩ = sum.inr b
sigma_preimage_equiv f for f : α → β is the natural equivalence between
the type of all fibres of f and the total space α.
A set s in α × β is equivalent to the sigma-type Σ x, {y | (x, y) ∈ s}.
For any predicate p on α,
the sum of the two subtypes {a // p a} and its complement {a // ¬ p a}
is naturally equivalent to α.
Combines an equiv between two subtypes with an equiv between their complements to form a
permutation.
Equations
- e.subtype_congr f = (equiv.sum_compl p).symm.trans ((e.sum_congr f).trans (equiv.sum_compl q))
Combining permutations on ε that permute only inside or outside the subtype
split induced by p : ε → Prop constructs a permutation on ε.
Equations
- ep.subtype_congr en = ⇑((equiv.sum_compl p).perm_congr) (equiv.sum_congr ep en)
For a fixed function x₀ : {a // p a} → β defined on a subtype of α,
the subtype of functions x : α → β that agree with x₀ on the subtype {a // p a}
is naturally equivalent to the type of functions {a // ¬ p a} → β.
A family of equivalences Π a, β₁ a ≃ β₂ a generates an equivalence between Π a, β₁ a and
Π a, β₂ a.
Dependent curry equivalence: the type of dependent functions on Σ i, β i is equivalent
to the type of dependent functions of two arguments (i.e., functions to the space of functions).
This is sigma.curry and sigma.uncurry together as an equiv.
Equations
- equiv.Pi_curry γ = {to_fun := sigma.curry γ, inv_fun := sigma.uncurry (λ (a : α) (b : β a), γ a b), left_inv := _, right_inv := _}
A family of equivalences Π a, β₁ a ≃ β₂ a generates an equivalence between Σ a, β₁ a and
Σ a, β₂ a.
A family of permutations Π a, perm (β a) generates a permuation perm (Σ a, β₁ a).
Equations
An equivalence f : α₁ ≃ α₂ generates an equivalence between Σ a, β (f a) and Σ a, β a.
Transporting a sigma type through an equivalence of the base
Equations
Transporting a sigma type through an equivalence of the base and a family of equivalences of matching fibers
Equations
- f.sigma_congr F = (equiv.sigma_congr_right F).trans f.sigma_congr_left
sigma type with a constant fiber is equivalent to the product.
If each fiber of a sigma type is equivalent to a fixed type, then the sigma type
is equivalent to the product.
Equations
A family of equivalences Π (a : α₁), β₁ ≃ β₂ generates an equivalence
between β₁ × α₁ and β₂ × α₁.
A family of equivalences Π (a : α₁), β₁ ≃ β₂ generates an equivalence
between α₁ × β₁ and α₁ × β₂.
A variation on equiv.prod_congr where the equivalence in the second component can depend
on the first component. A typical example is a shear mapping, explaining the name of this
declaration.
prod_extend_right a e extends e : perm β to perm (α × β) by sending (a, b) to
(a, e b) and keeping the other (a', b) fixed.
The type of functions to a product α × β is equivalent to the type of pairs of functions
γ → α and γ → β.
The type of functions on a sum type α ⊕ β is equivalent to the type of pairs of functions
on α and on β.
Type product is right distributive with respect to type sum up to an equivalence.
Equations
- equiv.sum_prod_distrib α β γ = {to_fun := λ (p : (α ⊕ β) × γ), equiv.sum_prod_distrib._match_1 α β γ p, inv_fun := λ (s : α × γ ⊕ β × γ), equiv.sum_prod_distrib._match_2 α β γ s, left_inv := _, right_inv := _}
- equiv.sum_prod_distrib._match_1 α β γ (sum.inr b, c) = sum.inr (b, c)
- equiv.sum_prod_distrib._match_1 α β γ (sum.inl a, c) = sum.inl (a, c)
- equiv.sum_prod_distrib._match_2 α β γ (sum.inr q) = (sum.inr q.fst, q.snd)
- equiv.sum_prod_distrib._match_2 α β γ (sum.inl q) = (sum.inl q.fst, q.snd)
Type product is left distributive with respect to type sum up to an equivalence.
Equations
- equiv.prod_sum_distrib α β γ = ((equiv.prod_comm α (β ⊕ γ)).trans (equiv.sum_prod_distrib β γ α)).trans ((equiv.prod_comm β α).sum_congr (equiv.prod_comm γ α))
The product of an indexed sum of types (formally, a sigma-type Σ i, α i) by a type β is
equivalent to the sum of products Σ i, (α i × β).
The product bool × α is equivalent to α ⊕ α.
Equations
The function type bool → α is equivalent to α × α.
Equations
The set of natural numbers is equivalent to ℕ ⊕ punit.
Equations
- equiv.nat_equiv_nat_sum_punit = {to_fun := λ (n : ℕ), equiv.nat_equiv_nat_sum_punit._match_1 n, inv_fun := λ (s : ℕ ⊕ punit), equiv.nat_equiv_nat_sum_punit._match_2 s, left_inv := equiv.nat_equiv_nat_sum_punit._proof_1, right_inv := equiv.nat_equiv_nat_sum_punit._proof_2}
- equiv.nat_equiv_nat_sum_punit._match_1 a.succ = sum.inl a
- equiv.nat_equiv_nat_sum_punit._match_1 0 = sum.inr punit.star
- equiv.nat_equiv_nat_sum_punit._match_2 (sum.inr punit.star) = 0
- equiv.nat_equiv_nat_sum_punit._match_2 (sum.inl n) = n.succ
ℕ ⊕ punit is equivalent to ℕ.
The type of integer numbers is equivalent to ℕ ⊕ ℕ.
Equations
If α is equivalent to β and the predicates p : α → Prop and q : β → Prop are equivalent
at corresponding points, then {a // p a} is equivalent to {b // q b}.
For the statement where α = β, that is, e : perm α, see perm.subtype_perm.
If two predicates p and q are pointwise equivalent, then {x // p x} is equivalent to
{x // q x}.
Equations
If α ≃ β, then for any predicate p : β → Prop the subtype {a // p (e a)} is equivalent
to the subtype {b // p b}.
Equations
If α ≃ β, then for any predicate p : α → Prop the subtype {a // p a} is equivalent
to the subtype {b // p (e.symm b)}. This version is used by equiv_rw.
Equations
If two predicates are equal, then the corresponding subtypes are equivalent.
Equations
The subtypes corresponding to equal sets are equivalent.
Equations
A subtype of a subtype is equivalent to the subtype of elements satisfying both predicates. This
version allows the “inner” predicate to depend on h : p a.
Equations
- equiv.subtype_subtype_equiv_subtype_exists p q = {to_fun := λ (_x : subtype q), equiv.subtype_subtype_equiv_subtype_exists._match_1 p q _x, inv_fun := λ (_x : {a // ∃ (h : p a), q ⟨a, h⟩}), equiv.subtype_subtype_equiv_subtype_exists._match_2 p q _x, left_inv := _, right_inv := _}
- equiv.subtype_subtype_equiv_subtype_exists._match_1 p q ⟨⟨a, ha⟩, ha'⟩ = ⟨a, _⟩
- equiv.subtype_subtype_equiv_subtype_exists._match_2 p q ⟨a, ha⟩ = ⟨⟨a, _⟩, _⟩
A subtype of a subtype is equivalent to the subtype of elements satisfying both predicates.
Equations
- equiv.subtype_subtype_equiv_subtype_inter p q = (equiv.subtype_subtype_equiv_subtype_exists p (λ (x : subtype p), q x.val)).trans (equiv.subtype_equiv_right _)
If the outer subtype has more restrictive predicate than the inner one, then we can drop the latter.
If a proposition holds for all elements, then the subtype is equivalent to the original type.
A subtype of a sigma-type is a sigma-type over a subtype.
A sigma type over a subtype is equivalent to the sigma set over the original type, if the fiber is empty outside of the subset
Equations
If a predicate p : β → Prop is true on the range of a map f : α → β, then
Σ y : {y // p y}, {x // f x = y} is equivalent to α.
Equations
- equiv.sigma_subtype_preimage_equiv f p h = (equiv.sigma_subtype_equiv_of_subset (λ (y : β), {x // f x = y}) p _).trans (equiv.sigma_preimage_equiv f)
If for each x we have p x ↔ q (f x), then Σ y : {y // q y}, f ⁻¹' {y} is equivalent
to {x // p x}.
Equations
- equiv.sigma_subtype_preimage_equiv_subtype f h = (equiv.sigma_congr_right (λ (y : subtype q), ((equiv.subtype_subtype_equiv_subtype_exists p (λ (x : subtype p), ⟨f ↑x, _⟩ = y)).trans (equiv.subtype_equiv_right _)).symm)).trans (equiv.sigma_preimage_equiv (λ (x : subtype p), ⟨f ↑x, _⟩))
The pi-type Π i, π i is equivalent to the type of sections f : ι → Σ i, π i of the
sigma type such that for all i we have (f i).fst = i.
The set of functions f : Π a, β a such that for all a we have p a (f a) is equivalent
to the set of functions Π a, {b : β a // p a b}.
A subtype of a product defined by componentwise conditions is equivalent to a product of subtypes.
The type of all functions X → Y with prescribed values for all x' ≠ x
is equivalent to the codomain Y.
Equations
- equiv.subtype_equiv_codomain f = (equiv.subtype_preimage (λ (x' : X), x' ≠ x) f).trans (equiv.fun_unique {x' // ¬x' ≠ x} Y)
If sets s and t are separated by a decidable predicate, then s ∪ t is equivalent to
s ⊕ t.
Equations
- equiv.set.union' p hs ht = {to_fun := λ (x : ↥(s ∪ t)), dite (p ↑x) (λ (hp : p ↑x), sum.inl ⟨x.val, _⟩) (λ (hp : ¬p ↑x), sum.inr ⟨x.val, _⟩), inv_fun := λ (o : ↥s ⊕ ↥t), equiv.set.union'._match_1 o, left_inv := _, right_inv := _}
- equiv.set.union'._match_1 (sum.inr x) = ⟨↑x, _⟩
- equiv.set.union'._match_1 (sum.inl x) = ⟨↑x, _⟩
If sets s and t are disjoint, then s ∪ t is equivalent to s ⊕ t.
Equations
- equiv.set.union H = equiv.set.union' (λ (x : α), x ∈ s) equiv.set.union._proof_1 _
If a ∉ s, then insert a s is equivalent to s ⊕ punit.
Equations
- equiv.set.insert H = ((equiv.set.of_eq equiv.set.insert._proof_1).trans (equiv.set.union _)).trans ((equiv.refl ↥s).sum_congr (equiv.set.singleton a))
If s : set α is a set with decidable membership, then s ⊕ sᶜ is equivalent to α.
Equations
- equiv.set.sum_compl s = ((equiv.set.union _).symm.trans (equiv.set.of_eq _)).trans (equiv.set.univ α)
sum_diff_subset s t is the natural equivalence between
s ⊕ (t \ s) and t, where s and t are two sets.
Equations
- equiv.set.sum_diff_subset h = (equiv.set.union equiv.set.sum_diff_subset._proof_1).symm.trans (equiv.set.of_eq _)
If s is a set with decidable membership, then the sum of s ∪ t and s ∩ t is equivalent
to s ⊕ t.
Equations
- equiv.set.union_sum_inter s t = ((((_.mpr (equiv.refl (↥(s ∪ t) ⊕ ↥(s ∩ t)))).trans ((equiv.set.union _).sum_congr (equiv.refl ↥(s ∩ t)))).trans (equiv.sum_assoc ↥s ↥(t \ s) ↥(s ∩ t))).trans ((equiv.refl ↥s).sum_congr (equiv.set.union' (λ (_x : α), _x ∉ s) _ _).symm)).trans (_.mpr (equiv.refl (↥s ⊕ ↥t)))
Given an equivalence e₀ between sets s : set α and t : set β, the set of equivalences
e : α ≃ β such that e ↑x = ↑(e₀ x) for each x : s is equivalent to the set of equivalences
between sᶜ and tᶜ.
The set product of two sets is equivalent to the type product of their coercions to types.
Equations
If a function f is injective on a set s, then s is equivalent to f '' s.
If f is an injective function, then s is equivalent to f '' s.
Equations
- equiv.set.image f s H = equiv.set.image_of_inj_on f s _
The set {x ∈ s | t x} is equivalent to the set of x : s such that t x.
Equations
If f : α → β has a left-inverse when α is nonempty, then α is computably equivalent to the
range of f.
While awkward, the nonempty α hypothesis on f_inv and hf allows this to be used when α is
empty too. This hypothesis is absent on analogous definitions on stronger equivs like
linear_equiv.of_left_inverse and ring_equiv.of_left_inverse as their typeclass assumptions
are already sufficient to ensure non-emptiness.
If f : α → β has a left-inverse, then α is computably equivalent to the range of f.
Note that if α is empty, no such f_inv exists and so this definition can't be used, unlike
the stronger but less convenient of_left_inverse.
If f : α → β is an injective function, then domain α is equivalent to the range of f.
Equations
- equiv.of_injective f hf = equiv.of_left_inverse f (λ (h : nonempty α), function.inv_fun f) _
If f is a bijective function, then its domain is equivalent to its codomain.
Equations
- equiv.of_bijective f hf = (equiv.of_injective f _).trans ((equiv.set_congr _).trans (equiv.set.univ β))
Extend the domain of e : equiv.perm α to one that is over β via f : α → subtype p,
where p : β → Prop, permuting only the b : β that satisfy p b.
This can be used to extend the domain across a function f : α → β,
keeping everything outside of set.range f fixed. For this use-case equiv given by f can
be constructed by equiv.of_left_inverse' or equiv.of_left_inverse when there is a known
inverse, or equiv.of_injective in the general case.`.
Equations
- e.extend_domain f = (⇑(f.perm_congr) e).subtype_congr (equiv.refl {a // ¬p a})
Subtype of the quotient is equivalent to the quotient of the subtype. Let α be a setoid with
equivalence relation ~. Let p₂ be a predicate on the quotient type α/~, and p₁ be the lift
of this predicate to α: p₁ a ↔ p₂ ⟦a⟧. Let ~₂ be the restriction of ~ to {x // p₁ x}.
Then {x // p₂ x} is equivalent to the quotient of {x // p₁ x} by ~₂.
A helper function for equiv.swap.
swap a b is the permutation that swaps a and b and
leaves other values as is.
Equations
- equiv.swap a b = {to_fun := equiv.swap_core a b, inv_fun := equiv.swap_core a b, left_inv := _, right_inv := _}
A function is invariant to a swap if it is equal at both elements
Augment an equivalence with a prescribed mapping f a = b
Equations
- f.set_value a b = equiv.trans (equiv.swap a (⇑(f.symm) b)) f
Transport dependent functions through an equivalence of the base space.
Transporting dependent functions through an equivalence of the base, expressed as a "simplification".
Equations
- equiv.Pi_congr_left P e = (equiv.Pi_congr_left' P e.symm).symm
Transport dependent functions through an equivalence of the base spaces and a family of equivalences of the matching fibers.
Equations
- h₁.Pi_congr h₂ = (equiv.Pi_congr_right h₂).trans (equiv.Pi_congr_left Z h₁)
Equations
Equations
Equations
Equations
If α is a singleton, then it is equivalent to any punit.
Equations
If α is a subsingleton, then it is equivalent to α × α.
To give an equivalence between two subsingleton types, it is sufficient to give any two functions between them.
A nonempty subsingleton type is (noncomputably) equivalent to punit.
Equations
- equiv.punit_of_nonempty_of_subsingleton = equiv_of_subsingleton_of_subsingleton (λ (_x : α), punit.star) (λ (_x : punit), h.some)
Quotients are congruent on equivalences under equality of their relation.
An alternative is just to use rewriting with eq, but then computational proofs get stuck.
Equations
- quot.congr_right eq = quot.congr (equiv.refl α) eq
An equivalence e : α ≃ β generates an equivalence between the quotient space of α
by a relation ra and the quotient space of β by the image of this relation under e.
Equations
- quot.congr_left e = quot.congr e _
An equivalence e : α ≃ β generates an equivalence between quotient spaces,
if `ra a₁ a₂ ↔ rb (e a₁) (e a₂).
Equations
- quotient.congr e eq = quot.congr e eq
If a function is a bijection between two sets s and t, then it induces an
equivalence between the the types ↥s and ``↥t`.
Equations
- set.bij_on.equiv f h = equiv.of_bijective (set.cod_restrict (set.restrict f s) t _) _
The composition of an updated function with an equiv on a subset can be expressed as an updated function.