Equivalence between types #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
In this file we continue the work on equivalences begun in logic/equiv/defs.lean, defining
-
canonical isomorphisms between various types: e.g.,
-
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.prod_congr ea eb : α₁ × β₁ ≃ α₂ × β₂: combine two equivalencesea : α₁ ≃ α₂andeb : β₁ ≃ β₂usingprod.map.
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
Combine two equivalences using pprod in the domain and prod in the codomain.
Equations
- ea.pprod_prod eb = (ea.pprod_congr eb).trans equiv.pprod_equiv_prod
Type product is associative up to an equivalence.
Four-way commutativity of prod. The name matches mul_mul_mul_comm.
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 α)
Any unique type is a right identity for type product up to equivalence.
Equations
- equiv.prod_unique α β = ((equiv.refl α).prod_congr (equiv.equiv_punit β)).trans (equiv.prod_punit α)
Any unique type is a left identity for type product up to equivalence.
Equations
- equiv.unique_prod α β = ((equiv.equiv_punit β).prod_congr (equiv.refl α)).trans (equiv.punit_prod α)
empty type is a right absorbing element for type product up to an equivalence.
Equations
- equiv.prod_empty α = equiv.equiv_empty (α × empty)
empty type is a left absorbing element for type product up to an equivalence.
Equations
- equiv.empty_prod α = equiv.equiv_empty (empty × α)
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
Combine a permutation of α and of β into a permutation of α ⊕ β.
Equations
- ea.sum_congr eb = equiv.sum_congr ea eb
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 α β).trans (equiv.sum_empty β α)
option α is equivalent to α ⊕ punit
Equations
- equiv.option_equiv_sum_punit α = {to_fun := λ (o : option α), option.elim (sum.inr punit.star) sum.inl o, inv_fun := λ (s : α ⊕ punit), sum.elim option.some (λ (_x : punit), option.none) s, left_inv := _, right_inv := _}
The set of x : option α such that is_some x is equivalent to α.
Equations
- equiv.option_is_some_equiv α = {to_fun := λ (o : {x // ↥(x.is_some)}), option.get _, inv_fun := λ (x : α), ⟨option.some x, _⟩, left_inv := _, right_inv := _}
The product over option α of β a is the binary product of the
product over α of β (some α) and β none
Equations
- equiv.pi_option_equiv_prod = {to_fun := λ (f : Π (a : option α), β a), (f option.none, λ (a : α), f (option.some a)), inv_fun := λ (x : β option.none × Π (a : α), β (option.some a)) (a : option α), a.cases_on x.fst x.snd, left_inv := _, right_inv := _}
α ⊕ β 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 : α), ⟨bool.tt, x⟩) (λ (x : β), ⟨bool.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 α β ⟨bool.tt, a⟩ = sum.inl a
- equiv.sum_equiv_sigma_bool._match_1 α β ⟨bool.ff, b⟩ = sum.inr b
sigma_fiber_equiv f for f : α → β is the natural equivalence between
the type of all fibres of f and the total space α.
For any predicate p on α,
the sum of the two subtypes {a // p a} and its complement {a // ¬ p a}
is naturally equivalent to α.
See subtype_or_equiv for sum types over subtypes {x // p x} and {x // q x}
that are not necessarily is_compl p q.
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} → β.
Given φ : α → β → Sort*, we have an equivalence between Π a b, φ a b and Π b a, φ a b.
This is function.swap as an equiv.
Equations
- equiv.Pi_comm φ = {to_fun := function.swap (λ (a : α) (b : β), φ a b), inv_fun := function.swap (λ (b : β) (a : α), φ a b), left_inv := _, right_inv := _}
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 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.
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 γ α))
An equivalence that separates out the 0th fiber of (Σ (n : ℕ), f n).
The product bool × α is equivalent to α ⊕ α.
The function type bool → α is equivalent to α × α.
The set of natural numbers is equivalent to ℕ ⊕ punit.
ℕ ⊕ punit is equivalent to ℕ.
The type of integer numbers is equivalent to ℕ ⊕ ℕ.
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 α ≃ β, 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
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.
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.
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_fiber_equiv f p h = (equiv.sigma_subtype_equiv_of_subset (λ (y : β), {x // f x = y}) p _).trans (equiv.sigma_fiber_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_fiber_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_fiber_equiv (λ (x : subtype p), ⟨f ↑x, _⟩))
A sigma type over an option is equivalent to the sigma set over the original type,
if the fiber is empty at none.
Equations
- equiv.sigma_option_equiv_of_some p h = (equiv.sigma_subtype_equiv_of_subset (λ (x : option α), p x) (λ (x : option α), ↥(x.is_some)) _).symm.trans (equiv.option_is_some_equiv α).sigma_congr_left'
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.
A subtype of a product defined by componentwise conditions is equivalent to a product of subtypes.
The type Π (i : α), β i can be split as a product by separating the indices in α
depending on whether they satisfy a predicate p or not.
Equations
- equiv.pi_equiv_pi_subtype_prod p β = {to_fun := λ (f : Π (i : α), β i), (λ (x : {x // p x}), f ↑x, λ (x : {x // ¬p x}), f ↑x), inv_fun := λ (f : (Π (i : {x // p x}), β ↑i) × Π (i : {x // ¬p x}), β ↑i) (x : α), dite (p x) (λ (h : p x), f.fst ⟨x, h⟩) (λ (h : ¬p x), f.snd ⟨x, h⟩), left_inv := _, right_inv := _}
A product of types can be split as the binary product of one of the types and the product of all the remaining types.
A product of copies of a type can be split as the binary product of one copy and the product of all the remaining copies.
Equations
- equiv.fun_split_at i β = equiv.pi_split_at i (λ (ᾰ : α), β)
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 f is a bijective function, then its domain is equivalent to its codomain.
Equations
- equiv.of_bijective f hf = {to_fun := f, inv_fun := function.surj_inv _, left_inv := _, right_inv := _}
Equations
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
Convert an involutive function f to a permutation with to_fun = inv_fun = f.
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₁)
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)
unique (unique α) is equivalent to unique α.
Equations
- unique_unique_equiv = equiv_of_subsingleton_of_subsingleton (λ (h : unique (unique α)), inhabited.default) (λ (h : unique α), {to_inhabited := {default := h}, uniq := _})