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 variousType
s orSort
s are equivalent.Equiv.Perm α
: the group of permutationsα ≃ α
. More lemmas aboutEquiv.Perm
can be found inMathlib.GroupTheory.Perm
.
Then we define
canonical isomorphisms between various types: e.g.,
Equiv.refl α
is the identity map interpreted asα ≃ α
;
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!);
definitions that transfer some instances along an equivalence. By convention, we transfer instances from right to left.
Equiv.inhabited
takese : α ≃ β
and[Inhabited β]
and returnsInhabited α
;Equiv.unique
takese : α ≃ β
and[Unique β]
and returnsUnique α
;Equiv.decidableEq
takese : α ≃ β
and[DecidableEq β]
and returnsDecidableEq α
.
More definitions of this kind can be found in other files. E.g.,
Mathlib.Algebra.Equiv.TransferInstance
does it for many algebraic type classes likeGroup
,Module
, etc.
Many more such isomorphisms and operations are defined in Mathlib.Logic.Equiv.Basic
.
Tags #
equivalence, congruence, bijective map
α ≃ β
is the type of functions from α → β
with a two-sided inverse.
- toFun : α → β
- invFun : β → α
- left_inv : Function.LeftInverse self.invFun self.toFun
- right_inv : Function.RightInverse self.invFun self.toFun
Instances For
α ≃ β
is the type of functions from α → β
with a two-sided inverse.
Equations
- «term_≃_» = Lean.ParserDescr.trailingNode `«term_≃_» 25 25 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ≃ ") (Lean.ParserDescr.cat `term 26))
Instances For
Turn an element of a type F
satisfying EquivLike F α β
into an actual
Equiv
. This is declared as the default coercion from F
to α ≃ β
.
Equations
- ↑f = { toFun := ⇑f, invFun := EquivLike.inv f, left_inv := ⋯, right_inv := ⋯ }
Instances For
Perm α
is the type of bijections from α
to itself.
Equations
- Equiv.Perm α = (α ≃ α)
Instances For
The map (r ≃ s) → (r → s)
is injective.
Any type is equivalent to itself.
Equations
- Equiv.refl α = { toFun := id, invFun := id, left_inv := ⋯, right_inv := ⋯ }
Instances For
Equations
- Equiv.inhabited' = { default := Equiv.refl α }
Equations
- Equiv.permUnique = uniqueOfSubsingleton (Equiv.refl α)
If α ≃ β
and β
is a singleton type, then so is α
.
Equations
- e.unique = Function.Surjective.unique ⇑e.symm ⋯
Instances For
Equivalence between equal types.
Equations
- Equiv.cast h = { toFun := cast h, invFun := cast ⋯, left_inv := ⋯, right_inv := ⋯ }
Instances For
This cannot be a simp
lemmas as it incorrectly matches against e : α ≃ synonym α
, when
synonym α
is semireducible. This makes a mess of Multiplicative.ofAdd
etc.
Two empty types are equivalent.
Equations
- Equiv.equivOfIsEmpty α β = { toFun := fun (a : α) => isEmptyElim a, invFun := fun (a : β) => isEmptyElim a, left_inv := ⋯, right_inv := ⋯ }
Instances For
If α
is an empty type, then it is equivalent to the PEmpty
type in any universe.
Equations
Instances For
α
is equivalent to an empty type iff α
is empty.
Equations
- Equiv.equivEmptyEquiv α = { toFun := ⋯, invFun := @Equiv.equivEmpty α, left_inv := ⋯, right_inv := ⋯ }
Instances For
If both α
and β
have a unique element, then α ≃ β
.
Equations
- Equiv.equivOfUnique α β = { toFun := default, invFun := default, left_inv := ⋯, right_inv := ⋯ }
Instances For
equivalence of propositions is the same as iff
Equations
- Equiv.ofIff h = { toFun := ⋯, invFun := ⋯, left_inv := ⋯, right_inv := ⋯ }
Instances For
A version of Equiv.arrowCongr
in Type
, rather than Sort
.
The equiv_rw
tactic is not able to use the default Sort
level Equiv.arrowCongr
,
because Lean's universe rules will not unify ?l_1
with imax (1 ?m_1)
.
Equations
- hα.arrowCongr' hβ = hα.arrowCongr hβ
Instances For
Prop
is noncomputably equivalent to Bool
.
Equations
- Equiv.propEquivBool = { toFun := fun (p : Prop) => decide p, invFun := fun (b : Bool) => b = true, left_inv := Equiv.propEquivBool.proof_1, right_inv := Equiv.propEquivBool.proof_2 }
Instances For
The sort of maps to PUnit.{v}
is equivalent to PUnit.{w}
.
Equations
- Equiv.arrowPUnitEquivPUnit α = { toFun := fun (x : α → PUnit.{?u.17}) => PUnit.unit, invFun := fun (x : PUnit.{?u.16}) (x : α) => PUnit.unit, left_inv := ⋯, right_inv := ⋯ }
Instances For
The equivalence (∀ i, β i) ≃ β ⋆
when the domain of β
only contains ⋆
Equations
- Equiv.piUnique β = { toFun := fun (f : (i : α) → β i) => f default, invFun := uniqueElim, left_inv := ⋯, right_inv := ⋯ }
Instances For
If α
has a unique term, then the type of function α → β
is equivalent to β
.
Equations
- Equiv.funUnique α β = Equiv.piUnique fun (a : α) => β
Instances For
The sort of maps from a type that IsEmpty
is equivalent to PUnit
.
Equations
- Equiv.arrowPUnitOfIsEmpty α β = { toFun := fun (x : α → β) => PUnit.unit, invFun := fun (x : PUnit.{?u.28}) (a : α) => isEmptyElim a, left_inv := ⋯, right_inv := ⋯ }
Instances For
A PSigma
-type is equivalent to the corresponding Sigma
-type.
Equations
- Equiv.psigmaEquivSigma β = { toFun := fun (a : (i : α) ×' β i) => ⟨a.fst, a.snd⟩, invFun := fun (a : (i : α) × β i) => ⟨a.fst, a.snd⟩, left_inv := ⋯, right_inv := ⋯ }
Instances For
A family of equivalences Π a, β₁ a ≃ β₂ a
generates an equivalence between Σ' a, β₁ a
and
Σ' a, β₂ a
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A family of equivalences Π a, β₁ a ≃ β₂ a
generates an equivalence between Σ a, β₁ a
and
Σ a, β₂ a
.
Equations
- Equiv.sigmaCongrRight F = { toFun := fun (a : (a : α) × β₁ a) => ⟨a.fst, (F a.fst) a.snd⟩, invFun := fun (a : (a : α) × β₂ a) => ⟨a.fst, (F a.fst).symm a.snd⟩, left_inv := ⋯, right_inv := ⋯ }
Instances For
A PSigma
with Prop
fibers is equivalent to the subtype.
Equations
- Equiv.psigmaEquivSubtype P = { toFun := fun (x : (i : α) ×' P i) => ⟨x.fst, ⋯⟩, invFun := fun (x : Subtype P) => ⟨x.val, ⋯⟩, left_inv := ⋯, right_inv := ⋯ }
Instances For
A Sigma
with PLift
fibers is equivalent to the subtype.
Equations
- Equiv.sigmaPLiftEquivSubtype P = ((Equiv.psigmaEquivSigma fun (x : α) => PLift (P x)).symm.trans (Equiv.psigmaCongrRight fun (x : α) => Equiv.plift)).trans (Equiv.psigmaEquivSubtype P)
Instances For
A Sigma
with fun i ↦ ULift (PLift (P i))
fibers is equivalent to { x // P x }
.
Variant of sigmaPLiftEquivSubtype
.
Equations
- Equiv.sigmaULiftPLiftEquivSubtype P = (Equiv.sigmaCongrRight fun (x : α) => Equiv.ulift).trans (Equiv.sigmaPLiftEquivSubtype P)
Instances For
A family of permutations Π a, Perm (β a)
generates a permutation Perm (Σ a, β₁ a)
.
Equations
Instances For
An equivalence f : α₁ ≃ α₂
generates an equivalence between Σ a, β (f a)
and Σ a, β a
.
Equations
- e.sigmaCongrLeft = { toFun := fun (a : (a : α₁) × β (e a)) => ⟨e a.fst, a.snd⟩, invFun := fun (a : (a : α₂) × β a) => ⟨e.symm a.fst, ⋯ ▸ a.snd⟩, left_inv := ⋯, right_inv := ⋯ }
Instances For
Transporting a sigma type through an equivalence of the base and a family of equivalences of matching fibers
Equations
- f.sigmaCongr F = (Equiv.sigmaCongrRight F).trans f.sigmaCongrLeft
Instances For
Sigma
type with a constant fiber is equivalent to the product.
Equations
- Equiv.sigmaEquivProd α β = { toFun := fun (a : (_ : α) × β) => (a.fst, a.snd), invFun := fun (a : α × β) => ⟨a.fst, a.snd⟩, left_inv := ⋯, right_inv := ⋯ }
Instances For
If each fiber of a Sigma
type is equivalent to a fixed type, then the sigma type
is equivalent to the product.
Equations
- Equiv.sigmaEquivProdOfEquiv F = (Equiv.sigmaCongrRight F).trans (Equiv.sigmaEquivProd α β)
Instances For
Dependent product of types is associative up to an equivalence.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Alias of Equiv.forall_congr_left
.
Alias of Equiv.existsUnique_congr_right
.
Alias of Equiv.existsUnique_congr_left
.
Alias of Equiv.existsUnique_congr
.
If f
is a bijective function, then its domain is equivalent to its codomain.
Equations
- Equiv.ofBijective f hf = { toFun := f, invFun := Function.surjInv ⋯, left_inv := ⋯, right_inv := ⋯ }
Instances For
An equivalence e : α ≃ β
generates an equivalence between quotient spaces,
if ra a₁ a₂ ↔ rb (e a₁) (e a₂)
.
Equations
- Quot.congr e eq = { toFun := Quot.map ⇑e ⋯, invFun := Quot.map ⇑e.symm ⋯, left_inv := ⋯, right_inv := ⋯ }
Instances For
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.congrRight eq = Quot.congr (Equiv.refl α) eq
Instances For
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.congrLeft e = Quot.congr e ⋯
Instances For
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
Instances For
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
Instances For
Equivalence between Fin 2
and Bool
.
Equations
- finTwoEquiv = { toFun := fun (i : Fin 2) => i == 1, invFun := fun (b : Bool) => bif b then 1 else 0, left_inv := finTwoEquiv.proof_2, right_inv := finTwoEquiv.proof_3 }