File: Mathlib/Logic/Equiv/Defs.lean

full_name: Equiv
code: /-- `α ≃ β` is the type of functions from `α → β` with a two-sided inverse. -/
structure Equiv (α : Sort*) (β : Sort _) where
  protected toFun : α → β
  protected invFun : β → α
  protected left_inv : LeftInverse invFun toFun
  protected right_inv : RightInverse invFun toFun
goal: Sort (max (max 1 u_1) u_2)

full_name: Equiv.right_inv
code: /-- `α ≃ β` is the type of functions from `α → β` with a two-sided inverse. -/
structure Equiv (α : Sort*) (β : Sort _) where
  protected toFun : α → β
  protected invFun : β → α
  protected left_inv : LeftInverse invFun toFun
  protected right_inv : RightInverse invFun toFun
goal: Function.RightInverse self.invFun self.toFun

full_name: Equiv.toFun
code: /-- `α ≃ β` is the type of functions from `α → β` with a two-sided inverse. -/
structure Equiv (α : Sort*) (β : Sort _) where
  protected toFun : α → β
  protected invFun : β → α
  protected left_inv : LeftInverse invFun toFun
  protected right_inv : RightInverse invFun toFun
goal: α → β

full_name: Equiv.invFun
code: /-- `α ≃ β` is the type of functions from `α → β` with a two-sided inverse. -/
structure Equiv (α : Sort*) (β : Sort _) where
  protected toFun : α → β
  protected invFun : β → α
  protected left_inv : LeftInverse invFun toFun
  protected right_inv : RightInverse invFun toFun
goal: β → α

full_name: Equiv.left_inv
code: /-- `α ≃ β` is the type of functions from `α → β` with a two-sided inverse. -/
structure Equiv (α : Sort*) (β : Sort _) where
  protected toFun : α → β
  protected invFun : β → α
  protected left_inv : LeftInverse invFun toFun
  protected right_inv : RightInverse invFun toFun
goal: Function.LeftInverse self.invFun self.toFun

full_name: _aux_Mathlib_Logic_Equiv_Defs___unexpand_Equiv_1
code: @[inherit_doc]
infixl:25 " ≃ " => Equiv
goal: Lean.PrettyPrinter.Unexpander

full_name: «_aux_Mathlib_Logic_Equiv_Defs___macroRules_term_≃__1»
code: @[inherit_doc]
infixl:25 " ≃ " => Equiv
goal: Lean.Macro

full_name: EquivLike.toEquiv
code: /-- Turn an element of a type `F` satisfying `EquivLike F α β` into an actual
`Equiv`. This is declared as the default coercion from `F` to `α ≃ β`. -/
@[coe]
def EquivLike.toEquiv {F} [EquivLike F α β] (f : F) : α ≃ β 
goal: α ≃ β

full_name: instCoeTCEquivOfEquivLike
code: /-- Any type satisfying `EquivLike` can be cast into `Equiv` via `EquivLike.toEquiv`. -/
instance {F} [EquivLike F α β] : CoeTC F (α ≃ β) 
goal: CoeTC F (α ≃ β)

full_name: Equiv.Perm
code: /-- `Perm α` is the type of bijections from `α` to itself. -/
abbrev Equiv.Perm (α : Sort*) 
goal: Sort (max 1 u_1)

full_name: Equiv.instEquivLike
code: instance : EquivLike (α ≃ β) α β 
goal: EquivLike (α ≃ β) α β

full_name: Equiv.instFunLike
code: /-- Helper instance when inference gets stuck on following the normal chain
`EquivLike → FunLike`.

TODO: this instance doesn't appear to be necessary: remove it (after benchmarking?)
-/
instance : FunLike (α ≃ β) α β 
goal: FunLike (α ≃ β) α β

full_name: EquivLike.coe_coe
code: @[simp, norm_cast]
lemma _root_.EquivLike.coe_coe {F} [EquivLike F α β] (e : F) :
    ((e : α ≃ β) : α → β) = e 
goal: ⇑↑e = ⇑e

full_name: Equiv.coe_fn_mk
code: @[simp] theorem coe_fn_mk (f : α → β) (g l r) : (Equiv.mk f g l r : α → β) = f 
goal: ⇑{ toFun := f, invFun := g, left_inv := l, right_inv := r } = f

full_name: Equiv.coe_fn_injective
code: /-- The map `(r ≃ s) → (r → s)` is injective. -/
theorem coe_fn_injective : @Function.Injective (α ≃ β) (α → β) (fun e => e) 
goal: Function.Injective fun e => ⇑e

full_name: Equiv.coe_inj
code: protected theorem coe_inj {e₁ e₂ : α ≃ β} : (e₁ : α → β) = e₂ ↔ e₁ = e₂ 
goal: ⇑e₁ = ⇑e₂ ↔ e₁ = e₂

full_name: Equiv.ext
code: @[ext] theorem ext {f g : Equiv α β} (H : ∀ x, f x = g x) : f = g 
goal: f = g

full_name: Equiv.congr_arg
code: protected theorem congr_arg {f : Equiv α β} {x x' : α} : x = x' → f x = f x' 
goal: x = x' → f x = f x'

full_name: Equiv.congr_fun
code: protected theorem congr_fun {f g : Equiv α β} (h : f = g) (x : α) : f x = g x 
goal: f x = g x

full_name: Equiv.ext_iff
code: theorem ext_iff {f g : Equiv α β} : f = g ↔ ∀ x, f x = g x 
goal: f = g ↔ ∀ (x : α), f x = g x

full_name: Equiv.Perm.ext
code: @[ext] theorem Perm.ext {σ τ : Equiv.Perm α} (H : ∀ x, σ x = τ x) : σ = τ 
goal: σ = τ

full_name: Equiv.Perm.congr_arg
code: protected theorem Perm.congr_arg {f : Equiv.Perm α} {x x' : α} : x = x' → f x = f x' 
goal: x = x' → f x = f x'

full_name: Equiv.Perm.congr_fun
code: protected theorem Perm.congr_fun {f g : Equiv.Perm α} (h : f = g) (x : α) : f x = g x 
goal: f x = g x

full_name: Equiv.Perm.ext_iff
code: protected theorem Perm.ext_iff {σ τ : Equiv.Perm α} : σ = τ ↔ ∀ x, σ x = τ x 
goal: σ = τ ↔ ∀ (x : α), σ x = τ x

full_name: Equiv.refl
code: /-- Any type is equivalent to itself. -/
@[refl] protected def refl (α : Sort*) : α ≃ α 
goal: α ≃ α

full_name: Equiv.inhabited'
code: instance inhabited' : Inhabited (α ≃ α) 
goal: Inhabited (α ≃ α)

full_name: Equiv.symm
code: /-- Inverse of an equivalence `e : α ≃ β`. -/
@[symm]
protected def symm (e : α ≃ β) : β ≃ α 
goal: β ≃ α

full_name: Equiv.Simps.symm_apply
code: /-- See Note [custom simps projection] -/
def Simps.symm_apply (e : α ≃ β) : β → α 
goal: β → α

full_name: Equiv.left_inv'
code: theorem left_inv' (e : α ≃ β) : Function.LeftInverse e.symm e 
goal: Function.LeftInverse ⇑e.symm ⇑e

full_name: Equiv.right_inv'
code: theorem right_inv' (e : α ≃ β) : Function.RightInverse e.symm e 
goal: Function.RightInverse ⇑e.symm ⇑e

full_name: Equiv.trans
code: /-- Composition of equivalences `e₁ : α ≃ β` and `e₂ : β ≃ γ`. -/
@[trans]
protected def trans (e₁ : α ≃ β) (e₂ : β ≃ γ) : α ≃ γ 
goal: α ≃ γ

full_name: Equiv.instTrans_trans
code: @[simps]
instance : Trans Equiv Equiv Equiv 
goal: ∀ {a : Sort u_2} {b : Sort u_1} {c : Sort u_3} (e₁ : a ≃ b) (e₂ : b ≃ c), Trans.trans e₁ e₂ = e₁.trans e₂

full_name: Equiv.instTrans
code: @[simps]
instance : Trans Equiv Equiv Equiv 
goal: Trans Equiv Equiv Equiv

full_name: Equiv.toFun_as_coe
code: @[simp, mfld_simps] theorem toFun_as_coe (e : α ≃ β) : e.toFun = e 
goal: e.toFun = ⇑e

full_name: Equiv.invFun_as_coe
code: @[simp, mfld_simps] theorem invFun_as_coe (e : α ≃ β) : e.invFun = e.symm 
goal: e.invFun = ⇑e.symm

full_name: Equiv.injective
code: protected theorem injective (e : α ≃ β) : Injective e 
goal: Function.Injective ⇑e

full_name: Equiv.surjective
code: protected theorem surjective (e : α ≃ β) : Surjective e 
goal: Function.Surjective ⇑e

full_name: Equiv.bijective
code: protected theorem bijective (e : α ≃ β) : Bijective e 
goal: Function.Bijective ⇑e

full_name: Equiv.subsingleton
code: protected theorem subsingleton (e : α ≃ β) [Subsingleton β] : Subsingleton α 
goal: Subsingleton α

full_name: Equiv.subsingleton.symm
code: protected theorem subsingleton.symm (e : α ≃ β) [Subsingleton α] : Subsingleton β 
goal: Subsingleton β

full_name: Equiv.subsingleton_congr
code: theorem subsingleton_congr (e : α ≃ β) : Subsingleton α ↔ Subsingleton β 
goal: Subsingleton α ↔ Subsingleton β

full_name: Equiv.equiv_subsingleton_cod
code: instance equiv_subsingleton_cod [Subsingleton β] : Subsingleton (α ≃ β) 
goal: Subsingleton (α ≃ β)

full_name: Equiv.equiv_subsingleton_dom
code: instance equiv_subsingleton_dom [Subsingleton α] : Subsingleton (α ≃ β) 
goal: Subsingleton (α ≃ β)

full_name: Equiv.permUnique
code: instance permUnique [Subsingleton α] : Unique (Perm α) 
goal: Unique (Equiv.Perm α)

full_name: Equiv.Perm.subsingleton_eq_refl
code: theorem Perm.subsingleton_eq_refl [Subsingleton α] (e : Perm α) : e = Equiv.refl α 
goal: e = Equiv.refl α

full_name: Equiv.decidableEq
code: /-- Transfer `DecidableEq` across an equivalence. -/
protected def decidableEq (e : α ≃ β) [DecidableEq β] : DecidableEq α 
goal: DecidableEq α

full_name: Equiv.nonempty_congr
code: theorem nonempty_congr (e : α ≃ β) : Nonempty α ↔ Nonempty β 
goal: Nonempty α ↔ Nonempty β

full_name: Equiv.nonempty
code: protected theorem nonempty (e : α ≃ β) [Nonempty β] : Nonempty α 
goal: Nonempty α

full_name: Equiv.inhabited
code: /-- If `α ≃ β` and `β` is inhabited, then so is `α`. -/
protected def inhabited [Inhabited β] (e : α ≃ β) : Inhabited α 
goal: Inhabited α

full_name: Equiv.unique
code: /-- If `α ≃ β` and `β` is a singleton type, then so is `α`. -/
protected def unique [Unique β] (e : α ≃ β) : Unique α 
goal: Unique α

full_name: Equiv.cast
code: /-- Equivalence between equal types. -/
protected def cast {α β : Sort _} (h : α = β) : α ≃ β 
goal: α ≃ β

full_name: Equiv.coe_fn_symm_mk
code: @[simp] theorem coe_fn_symm_mk (f : α → β) (g l r) : ((Equiv.mk f g l r).symm : β → α) = g 
goal: ⇑{ toFun := f, invFun := g, left_inv := l, right_inv := r }.symm = g

full_name: Equiv.coe_refl
code: @[simp] theorem coe_refl : (Equiv.refl α : α → α) = id 
goal: ⇑(Equiv.refl α) = id

full_name: Equiv.Perm.coe_subsingleton
code: /-- 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. -/
theorem Perm.coe_subsingleton {α : Type*} [Subsingleton α] (e : Perm α) : (e : α → α) = id 
goal: ⇑e = id

full_name: Equiv.refl_apply
code: @[simp] theorem refl_apply (x : α) : Equiv.refl α x = x 
goal: (Equiv.refl α) x = x

full_name: Equiv.coe_trans
code: @[simp] theorem coe_trans (f : α ≃ β) (g : β ≃ γ) : (f.trans g : α → γ) = g ∘ f 
goal: ⇑(f.trans g) = ⇑g ∘ ⇑f

full_name: Equiv.trans_apply
code: @[simp] theorem trans_apply (f : α ≃ β) (g : β ≃ γ) (a : α) : (f.trans g) a = g (f a) 
goal: (f.trans g) a = g (f a)

full_name: Equiv.apply_symm_apply
code: @[simp] theorem apply_symm_apply (e : α ≃ β) (x : β) : e (e.symm x) = x 
goal: e (e.symm x) = x

full_name: Equiv.symm_apply_apply
code: @[simp] theorem symm_apply_apply (e : α ≃ β) (x : α) : e.symm (e x) = x 
goal: e.symm (e x) = x

full_name: Equiv.symm_comp_self
code: @[simp] theorem symm_comp_self (e : α ≃ β) : e.symm ∘ e = id 
goal: ⇑e.symm ∘ ⇑e = id

full_name: Equiv.self_comp_symm
code: @[simp] theorem self_comp_symm (e : α ≃ β) : e ∘ e.symm = id 
goal: ⇑e ∘ ⇑e.symm = id

full_name: EquivLike.apply_coe_symm_apply
code: @[simp] lemma _root_.EquivLike.apply_coe_symm_apply {F} [EquivLike F α β] (e : F) (x : β) :
    e ((e : α ≃ β).symm x) = x 
goal: e ((↑e).symm x) = x

full_name: EquivLike.coe_symm_apply_apply
code: @[simp] lemma _root_.EquivLike.coe_symm_apply_apply {F} [EquivLike F α β] (e : F) (x : α) :
    (e : α ≃ β).symm (e x) = x 
goal: (↑e).symm (e x) = x

full_name: EquivLike.coe_symm_comp_self
code: @[simp] lemma _root_.EquivLike.coe_symm_comp_self {F} [EquivLike F α β] (e : F) :
    (e : α ≃ β).symm ∘ e = id 
goal: ⇑(↑e).symm ∘ ⇑e = id

full_name: EquivLike.self_comp_coe_symm
code: @[simp] lemma _root_.EquivLike.self_comp_coe_symm {F} [EquivLike F α β] (e : F) :
    e ∘ (e : α ≃ β).symm = id 
goal: ⇑e ∘ ⇑(↑e).symm = id

full_name: Equiv.symm_trans_apply
code: @[simp] theorem symm_trans_apply (f : α ≃ β) (g : β ≃ γ) (a : γ) :
    (f.trans g).symm a = f.symm (g.symm a) 
goal: (f.trans g).symm a = f.symm (g.symm a)

full_name: Equiv.symm_symm_apply
code: @[simp, nolint simpNF] theorem symm_symm_apply (f : α ≃ β) (b : α) : f.symm.symm b = f b 
goal: f.symm.symm b = f b

full_name: Equiv.apply_eq_iff_eq
code: theorem apply_eq_iff_eq (f : α ≃ β) {x y : α} : f x = f y ↔ x = y 
goal: f x = f y ↔ x = y

full_name: Equiv.apply_eq_iff_eq_symm_apply
code: theorem apply_eq_iff_eq_symm_apply {x : α} {y : β} (f : α ≃ β) : f x = y ↔ x = f.symm y 
goal: f x = y ↔ x = f.symm y

full_name: Equiv.cast_apply
code: @[simp] theorem cast_apply {α β} (h : α = β) (x : α) : Equiv.cast h x = cast h x 
goal: (Equiv.cast h) x = cast h x

full_name: Equiv.cast_symm
code: @[simp] theorem cast_symm {α β} (h : α = β) : (Equiv.cast h).symm = Equiv.cast h.symm 
goal: (Equiv.cast h).symm = Equiv.cast ⋯

full_name: Equiv.cast_refl
code: @[simp] theorem cast_refl {α} (h : α = α := rfl) : Equiv.cast h = Equiv.refl α 
goal: Equiv.cast h = Equiv.refl α

full_name: Equiv.cast_trans
code: @[simp] theorem cast_trans {α β γ} (h : α = β) (h2 : β = γ) :
    (Equiv.cast h).trans (Equiv.cast h2) = Equiv.cast (h.trans h2) 
goal: (Equiv.cast h).trans (Equiv.cast h2) = Equiv.cast ⋯

full_name: Equiv.cast_eq_iff_heq
code: theorem cast_eq_iff_heq {α β} (h : α = β) {a : α} {b : β} : Equiv.cast h a = b ↔ HEq a b 
goal: (Equiv.cast h) a = b ↔ HEq a b

full_name: Equiv.symm_apply_eq
code: theorem symm_apply_eq {α β} (e : α ≃ β) {x y} : e.symm x = y ↔ x = e y 
goal: e.symm x = y ↔ x = e y

full_name: Equiv.eq_symm_apply
code: theorem eq_symm_apply {α β} (e : α ≃ β) {x y} : y = e.symm x ↔ e y = x 
goal: y = e.symm x ↔ e y = x

full_name: Equiv.symm_symm
code: @[simp] theorem symm_symm (e : α ≃ β) : e.symm.symm = e 
goal: e.symm.symm = e

full_name: Equiv.symm_bijective
code: theorem symm_bijective : Function.Bijective (Equiv.symm : (α ≃ β) → β ≃ α) 
goal: Function.Bijective Equiv.symm

full_name: Equiv.trans_refl
code: @[simp] theorem trans_refl (e : α ≃ β) : e.trans (Equiv.refl β) = e 
goal: e.trans (Equiv.refl β) = e

full_name: Equiv.refl_symm
code: @[simp] theorem refl_symm : (Equiv.refl α).symm = Equiv.refl α 
goal: (Equiv.refl α).symm = Equiv.refl α

full_name: Equiv.refl_trans
code: @[simp] theorem refl_trans (e : α ≃ β) : (Equiv.refl α).trans e = e 
goal: (Equiv.refl α).trans e = e

full_name: Equiv.symm_trans_self
code: @[simp] theorem symm_trans_self (e : α ≃ β) : e.symm.trans e = Equiv.refl β 
goal: e.symm.trans e = Equiv.refl β

full_name: Equiv.self_trans_symm
code: @[simp] theorem self_trans_symm (e : α ≃ β) : e.trans e.symm = Equiv.refl α 
goal: e.trans e.symm = Equiv.refl α

full_name: Equiv.trans_assoc
code: theorem trans_assoc {δ} (ab : α ≃ β) (bc : β ≃ γ) (cd : γ ≃ δ) :
    (ab.trans bc).trans cd = ab.trans (bc.trans cd) 
goal: (ab.trans bc).trans cd = ab.trans (bc.trans cd)

full_name: Equiv.leftInverse_symm
code: theorem leftInverse_symm (f : Equiv α β) : LeftInverse f.symm f 
goal: Function.LeftInverse ⇑f.symm ⇑f

full_name: Equiv.rightInverse_symm
code: theorem rightInverse_symm (f : Equiv α β) : Function.RightInverse f.symm f 
goal: Function.RightInverse ⇑f.symm ⇑f

full_name: Equiv.injective_comp
code: theorem injective_comp (e : α ≃ β) (f : β → γ) : Injective (f ∘ e) ↔ Injective f 
goal: Function.Injective (f ∘ ⇑e) ↔ Function.Injective f

full_name: Equiv.comp_injective
code: theorem comp_injective (f : α → β) (e : β ≃ γ) : Injective (e ∘ f) ↔ Injective f 
goal: Function.Injective (⇑e ∘ f) ↔ Function.Injective f

full_name: Equiv.surjective_comp
code: theorem surjective_comp (e : α ≃ β) (f : β → γ) : Surjective (f ∘ e) ↔ Surjective f 
goal: Function.Surjective (f ∘ ⇑e) ↔ Function.Surjective f

full_name: Equiv.comp_surjective
code: theorem comp_surjective (f : α → β) (e : β ≃ γ) : Surjective (e ∘ f) ↔ Surjective f 
goal: Function.Surjective (⇑e ∘ f) ↔ Function.Surjective f

full_name: Equiv.bijective_comp
code: theorem bijective_comp (e : α ≃ β) (f : β → γ) : Bijective (f ∘ e) ↔ Bijective f 
goal: Function.Bijective (f ∘ ⇑e) ↔ Function.Bijective f

full_name: Equiv.comp_bijective
code: theorem comp_bijective (f : α → β) (e : β ≃ γ) : Bijective (e ∘ f) ↔ Bijective f 
goal: Function.Bijective (⇑e ∘ f) ↔ Function.Bijective f

full_name: Equiv.equivCongr
code: /-- If `α` is equivalent to `β` and `γ` is equivalent to `δ`, then the type of equivalences `α ≃ γ`
is equivalent to the type of equivalences `β ≃ δ`. -/
def equivCongr {δ : Sort*} (ab : α ≃ β) (cd : γ ≃ δ) : (α ≃ γ) ≃ (β ≃ δ) 
goal: α ≃ γ ≃ (β ≃ δ)

full_name: Equiv.equivCongr_refl
code: @[simp] theorem equivCongr_refl {α β} :
    (Equiv.refl α).equivCongr (Equiv.refl β) = Equiv.refl (α ≃ β) 
goal: (Equiv.refl α).equivCongr (Equiv.refl β) = Equiv.refl (α ≃ β)

full_name: Equiv.equivCongr_symm
code: @[simp] theorem equivCongr_symm {δ} (ab : α ≃ β) (cd : γ ≃ δ) :
    (ab.equivCongr cd).symm = ab.symm.equivCongr cd.symm 
goal: (ab.equivCongr cd).symm = ab.symm.equivCongr cd.symm

full_name: Equiv.equivCongr_trans
code: @[simp] theorem equivCongr_trans {δ ε ζ} (ab : α ≃ β) (de : δ ≃ ε) (bc : β ≃ γ) (ef : ε ≃ ζ) :
    (ab.equivCongr de).trans (bc.equivCongr ef) = (ab.trans bc).equivCongr (de.trans ef) 
goal: (ab.equivCongr de).trans (bc.equivCongr ef) = (ab.trans bc).equivCongr (de.trans ef)

full_name: Equiv.equivCongr_refl_left
code: @[simp] theorem equivCongr_refl_left {α β γ} (bg : β ≃ γ) (e : α ≃ β) :
    (Equiv.refl α).equivCongr bg e = e.trans bg 
goal: ((Equiv.refl α).equivCongr bg) e = e.trans bg

full_name: Equiv.equivCongr_refl_right
code: @[simp] theorem equivCongr_refl_right {α β} (ab e : α ≃ β) :
    ab.equivCongr (Equiv.refl β) e = ab.symm.trans e 
goal: (ab.equivCongr (Equiv.refl β)) e = ab.symm.trans e

full_name: Equiv.equivCongr_apply_apply
code: @[simp] theorem equivCongr_apply_apply {δ} (ab : α ≃ β) (cd : γ ≃ δ) (e : α ≃ γ) (x) :
    ab.equivCongr cd e x = cd (e (ab.symm x)) 
goal: ((ab.equivCongr cd) e) x = cd (e (ab.symm x))

full_name: Equiv.permCongr
code: /-- If `α` is equivalent to `β`, then `Perm α` is equivalent to `Perm β`. -/
def permCongr : Perm α' ≃ Perm β' 
goal: Equiv.Perm α' ≃ Equiv.Perm β'

full_name: Equiv.permCongr_def
code: theorem permCongr_def (p : Equiv.Perm α') : e.permCongr p = (e.symm.trans p).trans e 
goal: e.permCongr p = (e.symm.trans p).trans e

full_name: Equiv.permCongr_refl
code: @[simp] theorem permCongr_refl : e.permCongr (Equiv.refl _) = Equiv.refl _ 
goal: e.permCongr (Equiv.refl α') = Equiv.refl β'

full_name: Equiv.permCongr_symm
code: @[simp] theorem permCongr_symm : e.permCongr.symm = e.symm.permCongr 
goal: e.permCongr.symm = e.symm.permCongr

full_name: Equiv.permCongr_apply
code: @[simp] theorem permCongr_apply (p : Equiv.Perm α') (x) : e.permCongr p x = e (p (e.symm x)) 
goal: (e.permCongr p) x = e (p (e.symm x))

full_name: Equiv.permCongr_symm_apply
code: theorem permCongr_symm_apply (p : Equiv.Perm β') (x) :
    e.permCongr.symm p x = e.symm (p (e x)) 
goal: (e.permCongr.symm p) x = e.symm (p (e x))

full_name: Equiv.permCongr_trans
code: theorem permCongr_trans (p p' : Equiv.Perm α') :
    (e.permCongr p).trans (e.permCongr p') = e.permCongr (p.trans p') 
goal: Equiv.trans (e.permCongr p) (e.permCongr p') = e.permCongr (Equiv.trans p p')

full_name: Equiv.equivOfIsEmpty
code: /-- Two empty types are equivalent. -/
def equivOfIsEmpty (α β : Sort*) [IsEmpty α] [IsEmpty β] : α ≃ β 
goal: α ≃ β

full_name: Equiv.equivEmpty
code: /-- If `α` is an empty type, then it is equivalent to the `Empty` type. -/
def equivEmpty (α : Sort u) [IsEmpty α] : α ≃ Empty 
goal: α ≃ Empty

full_name: Equiv.equivPEmpty
code: /-- If `α` is an empty type, then it is equivalent to the `PEmpty` type in any universe. -/
def equivPEmpty (α : Sort v) [IsEmpty α] : α ≃ PEmpty.{u} 
goal: α ≃ PEmpty.{u}

full_name: Equiv.equivEmptyEquiv
code: /-- `α` is equivalent to an empty type iff `α` is empty. -/
def equivEmptyEquiv (α : Sort u) : α ≃ Empty ≃ IsEmpty α 
goal: α ≃ Empty ≃ IsEmpty α

full_name: Equiv.propEquivPEmpty
code: /-- The `Sort` of proofs of a false proposition is equivalent to `PEmpty`. -/
def propEquivPEmpty {p : Prop} (h : ¬p) : p ≃ PEmpty 
goal: p ≃ PEmpty.{u_1}

full_name: Equiv.equivOfUnique
code: /-- If both `α` and `β` have a unique element, then `α ≃ β`. -/
def equivOfUnique (α β : Sort _) [Unique.{u} α] [Unique.{v} β] : α ≃ β 
goal: α ≃ β

full_name: Equiv.equivPUnit
code: /-- If `α` has a unique element, then it is equivalent to any `PUnit`. -/
def equivPUnit (α : Sort u) [Unique α] : α ≃ PUnit.{v} 
goal: α ≃ PUnit.{v}

full_name: Equiv.propEquivPUnit
code: /-- The `Sort` of proofs of a true proposition is equivalent to `PUnit`. -/
def propEquivPUnit {p : Prop} (h : p) : p ≃ PUnit.{0} 
goal: p ≃ PUnit.{0}

full_name: Equiv.ulift_apply
code: /-- `ULift α` is equivalent to `α`. -/
@[simps (config := .asFn) apply]
protected def ulift {α : Type v} : ULift.{u} α ≃ α 
goal: ⇑Equiv.ulift = ULift.down

full_name: Equiv.ulift
code: /-- `ULift α` is equivalent to `α`. -/
@[simps (config := .asFn) apply]
protected def ulift {α : Type v} : ULift.{u} α ≃ α 
goal: ULift.{u, v} α ≃ α

full_name: Equiv.plift
code: /-- `PLift α` is equivalent to `α`. -/
@[simps (config := .asFn) apply]
protected def plift : PLift α ≃ α 
goal: PLift α ≃ α

full_name: Equiv.plift_apply
code: /-- `PLift α` is equivalent to `α`. -/
@[simps (config := .asFn) apply]
protected def plift : PLift α ≃ α 
goal: ⇑Equiv.plift = PLift.down

full_name: Equiv.ofIff
code: /-- equivalence of propositions is the same as iff -/
def ofIff {P Q : Prop} (h : P ↔ Q) : P ≃ Q 
goal: P ≃ Q

full_name: Equiv.arrowCongr
code: /-- If `α₁` is equivalent to `α₂` and `β₁` is equivalent to `β₂`, then the type of maps `α₁ → β₁`
is equivalent to the type of maps `α₂ → β₂`. -/
-- Porting note: removing `congr` attribute
@[simps apply]
def arrowCongr {α₁ β₁ α₂ β₂ : Sort*} (e₁ : α₁ ≃ α₂) (e₂ : β₁ ≃ β₂) : (α₁ → β₁) ≃ (α₂ → β₂) 
goal: (α₁ → β₁) ≃ (α₂ → β₂)

full_name: Equiv.arrowCongr_apply
code: /-- If `α₁` is equivalent to `α₂` and `β₁` is equivalent to `β₂`, then the type of maps `α₁ → β₁`
is equivalent to the type of maps `α₂ → β₂`. -/
-- Porting note: removing `congr` attribute
@[simps apply]
def arrowCongr {α₁ β₁ α₂ β₂ : Sort*} (e₁ : α₁ ≃ α₂) (e₂ : β₁ ≃ β₂) : (α₁ → β₁) ≃ (α₂ → β₂) 
goal: ∀ (a : α₂), (e₁.arrowCongr e₂) f a = (⇑e₂ ∘ f ∘ ⇑e₁.symm) a

full_name: Equiv.arrowCongr_comp
code: theorem arrowCongr_comp {α₁ β₁ γ₁ α₂ β₂ γ₂ : Sort*} (ea : α₁ ≃ α₂) (eb : β₁ ≃ β₂) (ec : γ₁ ≃ γ₂)
    (f : α₁ → β₁) (g : β₁ → γ₁) :
    arrowCongr ea ec (g ∘ f) = arrowCongr eb ec g ∘ arrowCongr ea eb f 
goal: (ea.arrowCongr ec) (g ∘ f) = (eb.arrowCongr ec) g ∘ (ea.arrowCongr eb) f

full_name: Equiv.arrowCongr_refl
code: @[simp] theorem arrowCongr_refl {α β : Sort*} :
    arrowCongr (Equiv.refl α) (Equiv.refl β) = Equiv.refl (α → β) 
goal: (Equiv.refl α).arrowCongr (Equiv.refl β) = Equiv.refl (α → β)

full_name: Equiv.arrowCongr_trans
code: @[simp] theorem arrowCongr_trans {α₁ α₂ α₃ β₁ β₂ β₃ : Sort*}
    (e₁ : α₁ ≃ α₂) (e₁' : β₁ ≃ β₂) (e₂ : α₂ ≃ α₃) (e₂' : β₂ ≃ β₃) :
    arrowCongr (e₁.trans e₂) (e₁'.trans e₂') = (arrowCongr e₁ e₁').trans (arrowCongr e₂ e₂') 
goal: (e₁.trans e₂).arrowCongr (e₁'.trans e₂') = (e₁.arrowCongr e₁').trans (e₂.arrowCongr e₂')

full_name: Equiv.arrowCongr_symm
code: @[simp] theorem arrowCongr_symm {α₁ α₂ β₁ β₂ : Sort*} (e₁ : α₁ ≃ α₂) (e₂ : β₁ ≃ β₂) :
    (arrowCongr e₁ e₂).symm = arrowCongr e₁.symm e₂.symm 
goal: (e₁.arrowCongr e₂).symm = e₁.symm.arrowCongr e₂.symm

full_name: Equiv.arrowCongr'
code: /-- 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)`.
-/
-- Porting note: removing `congr` attribute
@[simps! apply]
def arrowCongr' {α₁ β₁ α₂ β₂ : Type*} (hα : α₁ ≃ α₂) (hβ : β₁ ≃ β₂) : (α₁ → β₁) ≃ (α₂ → β₂) 
goal: (α₁ → β₁) ≃ (α₂ → β₂)

full_name: Equiv.arrowCongr'_apply
code: /-- 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)`.
-/
-- Porting note: removing `congr` attribute
@[simps! apply]
def arrowCongr' {α₁ β₁ α₂ β₂ : Type*} (hα : α₁ ≃ α₂) (hβ : β₁ ≃ β₂) : (α₁ → β₁) ≃ (α₂ → β₂) 
goal: ∀ (a : α₂), (hα.arrowCongr' hβ) f a = hβ (f (hα.symm a))

full_name: Equiv.arrowCongr'_refl
code: @[simp] theorem arrowCongr'_refl {α β : Type*} :
    arrowCongr' (Equiv.refl α) (Equiv.refl β) = Equiv.refl (α → β) 
goal: (Equiv.refl α).arrowCongr' (Equiv.refl β) = Equiv.refl (α → β)

full_name: Equiv.arrowCongr'_trans
code: @[simp] theorem arrowCongr'_trans {α₁ α₂ β₁ β₂ α₃ β₃ : Type*}
    (e₁ : α₁ ≃ α₂) (e₁' : β₁ ≃ β₂) (e₂ : α₂ ≃ α₃) (e₂' : β₂ ≃ β₃) :
    arrowCongr' (e₁.trans e₂) (e₁'.trans e₂') = (arrowCongr' e₁ e₁').trans (arrowCongr' e₂ e₂') 
goal: (e₁.trans e₂).arrowCongr' (e₁'.trans e₂') = (e₁.arrowCongr' e₁').trans (e₂.arrowCongr' e₂')

full_name: Equiv.arrowCongr'_symm
code: @[simp] theorem arrowCongr'_symm {α₁ α₂ β₁ β₂ : Type*} (e₁ : α₁ ≃ α₂) (e₂ : β₁ ≃ β₂) :
    (arrowCongr' e₁ e₂).symm = arrowCongr' e₁.symm e₂.symm 
goal: (e₁.arrowCongr' e₂).symm = e₁.symm.arrowCongr' e₂.symm

full_name: Equiv.conj_apply
code: /-- Conjugate a map `f : α → α` by an equivalence `α ≃ β`. -/
@[simps! apply] def conj (e : α ≃ β) : (α → α) ≃ (β → β) 
goal: ∀ (a : β), e.conj f a = e (f (e.symm a))

full_name: Equiv.conj
code: /-- Conjugate a map `f : α → α` by an equivalence `α ≃ β`. -/
@[simps! apply] def conj (e : α ≃ β) : (α → α) ≃ (β → β) 
goal: (α → α) ≃ (β → β)

full_name: Equiv.conj_refl
code: @[simp] theorem conj_refl : conj (Equiv.refl α) = Equiv.refl (α → α) 
goal: (Equiv.refl α).conj = Equiv.refl (α → α)

full_name: Equiv.conj_symm
code: @[simp] theorem conj_symm (e : α ≃ β) : e.conj.symm = e.symm.conj 
goal: e.conj.symm = e.symm.conj

full_name: Equiv.conj_trans
code: @[simp] theorem conj_trans (e₁ : α ≃ β) (e₂ : β ≃ γ) :
    (e₁.trans e₂).conj = e₁.conj.trans e₂.conj 
goal: (e₁.trans e₂).conj = e₁.conj.trans e₂.conj

full_name: Equiv.conj_comp
code: theorem conj_comp (e : α ≃ β) (f₁ f₂ : α → α) : e.conj (f₁ ∘ f₂) = e.conj f₁ ∘ e.conj f₂ 
goal: e.conj (f₁ ∘ f₂) = e.conj f₁ ∘ e.conj f₂

full_name: Equiv.eq_comp_symm
code: theorem eq_comp_symm {α β γ} (e : α ≃ β) (f : β → γ) (g : α → γ) : f = g ∘ e.symm ↔ f ∘ e = g 
goal: f = g ∘ ⇑e.symm ↔ f ∘ ⇑e = g

full_name: Equiv.comp_symm_eq
code: theorem comp_symm_eq {α β γ} (e : α ≃ β) (f : β → γ) (g : α → γ) : g ∘ e.symm = f ↔ g = f ∘ e 
goal: g ∘ ⇑e.symm = f ↔ g = f ∘ ⇑e

full_name: Equiv.eq_symm_comp
code: theorem eq_symm_comp {α β γ} (e : α ≃ β) (f : γ → α) (g : γ → β) : f = e.symm ∘ g ↔ e ∘ f = g 
goal: f = ⇑e.symm ∘ g ↔ ⇑e ∘ f = g

full_name: Equiv.symm_comp_eq
code: theorem symm_comp_eq {α β γ} (e : α ≃ β) (f : γ → α) (g : γ → β) : e.symm ∘ g = f ↔ g = e ∘ f 
goal: ⇑e.symm ∘ g = f ↔ g = ⇑e ∘ f

full_name: Equiv.punitEquivPUnit
code: /-- `PUnit` sorts in any two universes are equivalent. -/
def punitEquivPUnit : PUnit.{v} ≃ PUnit.{w} 
goal: PUnit.{v} ≃ PUnit.{w}

full_name: Equiv.propEquivBool
code: /-- `Prop` is noncomputably equivalent to `Bool`. -/
noncomputable def propEquivBool : Prop ≃ Bool 
goal: Prop ≃ Bool

full_name: Equiv.arrowPUnitEquivPUnit
code: /-- The sort of maps to `PUnit.{v}` is equivalent to `PUnit.{w}`. -/
def arrowPUnitEquivPUnit (α : Sort*) : (α → PUnit.{v}) ≃ PUnit.{w} 
goal: (α → PUnit.{v}) ≃ PUnit.{w}

full_name: Equiv.piUnique_apply
code: /-- The equivalence `(∀ i, β i) ≃ β ⋆` when the domain of `β` only contains `⋆` -/
@[simps (config := .asFn)]
def piUnique [Unique α] (β : α → Sort*) : (∀ i, β i) ≃ β default 
goal: ⇑(Equiv.piUnique β) = fun f => f default

full_name: Equiv.piUnique_symm_apply
code: /-- The equivalence `(∀ i, β i) ≃ β ⋆` when the domain of `β` only contains `⋆` -/
@[simps (config := .asFn)]
def piUnique [Unique α] (β : α → Sort*) : (∀ i, β i) ≃ β default 
goal: ⇑(Equiv.piUnique β).symm = uniqueElim

full_name: Equiv.piUnique
code: /-- The equivalence `(∀ i, β i) ≃ β ⋆` when the domain of `β` only contains `⋆` -/
@[simps (config := .asFn)]
def piUnique [Unique α] (β : α → Sort*) : (∀ i, β i) ≃ β default 
goal: ((i : α) → β i) ≃ β default

full_name: Equiv.funUnique
code: /-- If `α` has a unique term, then the type of function `α → β` is equivalent to `β`. -/
@[simps! (config := .asFn) apply symm_apply]
def funUnique (α β) [Unique.{u} α] : (α → β) ≃ β 
goal: (α → β) ≃ β

full_name: Equiv.funUnique_symm_apply
code: /-- If `α` has a unique term, then the type of function `α → β` is equivalent to `β`. -/
@[simps! (config := .asFn) apply symm_apply]
def funUnique (α β) [Unique.{u} α] : (α → β) ≃ β 
goal: ⇑(Equiv.funUnique α β).symm = uniqueElim

full_name: Equiv.funUnique_apply
code: /-- If `α` has a unique term, then the type of function `α → β` is equivalent to `β`. -/
@[simps! (config := .asFn) apply symm_apply]
def funUnique (α β) [Unique.{u} α] : (α → β) ≃ β 
goal: ⇑(Equiv.funUnique α β) = fun f => f default

full_name: Equiv.punitArrowEquiv
code: /-- The sort of maps from `PUnit` is equivalent to the codomain. -/
def punitArrowEquiv (α : Sort*) : (PUnit.{u} → α) ≃ α 
goal: (PUnit.{u} → α) ≃ α

full_name: Equiv.trueArrowEquiv
code: /-- The sort of maps from `True` is equivalent to the codomain. -/
def trueArrowEquiv (α : Sort*) : (True → α) ≃ α 
goal: (True → α) ≃ α

full_name: Equiv.arrowPUnitOfIsEmpty
code: /-- The sort of maps from a type that `IsEmpty` is equivalent to `PUnit`. -/
def arrowPUnitOfIsEmpty (α β : Sort*) [IsEmpty α] : (α → β) ≃ PUnit.{u} 
goal: (α → β) ≃ PUnit.{u}

full_name: Equiv.emptyArrowEquivPUnit
code: /-- The sort of maps from `Empty` is equivalent to `PUnit`. -/
def emptyArrowEquivPUnit (α : Sort*) : (Empty → α) ≃ PUnit.{u} 
goal: (Empty → α) ≃ PUnit.{u}

full_name: Equiv.pemptyArrowEquivPUnit
code: /-- The sort of maps from `PEmpty` is equivalent to `PUnit`. -/
def pemptyArrowEquivPUnit (α : Sort*) : (PEmpty → α) ≃ PUnit.{u} 
goal: (PEmpty.{u_2} → α) ≃ PUnit.{u}

full_name: Equiv.falseArrowEquivPUnit
code: /-- The sort of maps from `False` is equivalent to `PUnit`. -/
def falseArrowEquivPUnit (α : Sort*) : (False → α) ≃ PUnit.{u} 
goal: (False → α) ≃ PUnit.{u}

full_name: Equiv.psigmaEquivSigma
code: /-- A `PSigma`-type is equivalent to the corresponding `Sigma`-type. -/
@[simps apply symm_apply]
def psigmaEquivSigma {α} (β : α → Type*) : (Σ' i, β i) ≃ Σ i, β i 
goal: (i : α) ×' β i ≃ (i : α) × β i

full_name: Equiv.psigmaEquivSigma_symm_apply
code: /-- A `PSigma`-type is equivalent to the corresponding `Sigma`-type. -/
@[simps apply symm_apply]
def psigmaEquivSigma {α} (β : α → Type*) : (Σ' i, β i) ≃ Σ i, β i 
goal: (Equiv.psigmaEquivSigma β).symm a = ⟨a.fst, a.snd⟩

full_name: Equiv.psigmaEquivSigma_apply
code: /-- A `PSigma`-type is equivalent to the corresponding `Sigma`-type. -/
@[simps apply symm_apply]
def psigmaEquivSigma {α} (β : α → Type*) : (Σ' i, β i) ≃ Σ i, β i 
goal: (Equiv.psigmaEquivSigma β) a = ⟨a.fst, a.snd⟩

full_name: Equiv.psigmaEquivSigmaPLift_apply
code: /-- A `PSigma`-type is equivalent to the corresponding `Sigma`-type. -/
@[simps apply symm_apply]
def psigmaEquivSigmaPLift {α} (β : α → Sort*) : (Σ' i, β i) ≃ Σ i : PLift α, PLift (β i.down) 
goal: (Equiv.psigmaEquivSigmaPLift β) a = ⟨{ down := a.fst }, { down := a.snd }⟩

full_name: Equiv.psigmaEquivSigmaPLift_symm_apply
code: /-- A `PSigma`-type is equivalent to the corresponding `Sigma`-type. -/
@[simps apply symm_apply]
def psigmaEquivSigmaPLift {α} (β : α → Sort*) : (Σ' i, β i) ≃ Σ i : PLift α, PLift (β i.down) 
goal: (Equiv.psigmaEquivSigmaPLift β).symm a = ⟨a.fst.down, a.snd.down⟩

full_name: Equiv.psigmaEquivSigmaPLift
code: /-- A `PSigma`-type is equivalent to the corresponding `Sigma`-type. -/
@[simps apply symm_apply]
def psigmaEquivSigmaPLift {α} (β : α → Sort*) : (Σ' i, β i) ≃ Σ i : PLift α, PLift (β i.down) 
goal: (i : α) ×' β i ≃ (i : PLift α) × PLift (β i.down)

full_name: Equiv.psigmaCongrRight
code: /-- A family of equivalences `Π a, β₁ a ≃ β₂ a` generates an equivalence between `Σ' a, β₁ a` and
`Σ' a, β₂ a`. -/
@[simps apply]
def psigmaCongrRight {β₁ β₂ : α → Sort*} (F : ∀ a, β₁ a ≃ β₂ a) : (Σ' a, β₁ a) ≃ Σ' a, β₂ a 
goal: (a : α) ×' β₁ a ≃ (a : α) ×' β₂ a

full_name: Equiv.psigmaCongrRight_apply
code: /-- A family of equivalences `Π a, β₁ a ≃ β₂ a` generates an equivalence between `Σ' a, β₁ a` and
`Σ' a, β₂ a`. -/
@[simps apply]
def psigmaCongrRight {β₁ β₂ : α → Sort*} (F : ∀ a, β₁ a ≃ β₂ a) : (Σ' a, β₁ a) ≃ Σ' a, β₂ a 
goal: (Equiv.psigmaCongrRight F) a = ⟨a.fst, (F a.fst) a.snd⟩

full_name: Equiv.psigmaCongrRight_trans
code: theorem psigmaCongrRight_trans {α} {β₁ β₂ β₃ : α → Sort*}
    (F : ∀ a, β₁ a ≃ β₂ a) (G : ∀ a, β₂ a ≃ β₃ a) :
    (psigmaCongrRight F).trans (psigmaCongrRight G) =
      psigmaCongrRight fun a => (F a).trans (G a) 
goal: (Equiv.psigmaCongrRight F).trans (Equiv.psigmaCongrRight G) = Equiv.psigmaCongrRight fun a => (F a).trans (G a)

full_name: Equiv.psigmaCongrRight_symm
code: theorem psigmaCongrRight_symm {α} {β₁ β₂ : α → Sort*} (F : ∀ a, β₁ a ≃ β₂ a) :
    (psigmaCongrRight F).symm = psigmaCongrRight fun a => (F a).symm 
goal: (Equiv.psigmaCongrRight F).symm = Equiv.psigmaCongrRight fun a => (F a).symm

full_name: Equiv.psigmaCongrRight_refl
code: theorem psigmaCongrRight_refl {α} {β : α → Sort*} :
    (psigmaCongrRight fun a => Equiv.refl (β a)) = Equiv.refl (Σ' a, β a) 
goal: (Equiv.psigmaCongrRight fun a => Equiv.refl (β a)) = Equiv.refl ((a : α) ×' β a)

full_name: Equiv.sigmaCongrRight
code: /-- A family of equivalences `Π a, β₁ a ≃ β₂ a` generates an equivalence between `Σ a, β₁ a` and
`Σ a, β₂ a`. -/
@[simps apply]
def sigmaCongrRight {α} {β₁ β₂ : α → Type*} (F : ∀ a, β₁ a ≃ β₂ a) : (Σ a, β₁ a) ≃ Σ a, β₂ a 
goal: (a : α) × β₁ a ≃ (a : α) × β₂ a

full_name: Equiv.sigmaCongrRight_apply
code: /-- A family of equivalences `Π a, β₁ a ≃ β₂ a` generates an equivalence between `Σ a, β₁ a` and
`Σ a, β₂ a`. -/
@[simps apply]
def sigmaCongrRight {α} {β₁ β₂ : α → Type*} (F : ∀ a, β₁ a ≃ β₂ a) : (Σ a, β₁ a) ≃ Σ a, β₂ a 
goal: (Equiv.sigmaCongrRight F) a = ⟨a.fst, (F a.fst) a.snd⟩

full_name: Equiv.sigmaCongrRight_trans
code: theorem sigmaCongrRight_trans {α} {β₁ β₂ β₃ : α → Type*}
    (F : ∀ a, β₁ a ≃ β₂ a) (G : ∀ a, β₂ a ≃ β₃ a) :
    (sigmaCongrRight F).trans (sigmaCongrRight G) =
      sigmaCongrRight fun a => (F a).trans (G a) 
goal: (Equiv.sigmaCongrRight F).trans (Equiv.sigmaCongrRight G) = Equiv.sigmaCongrRight fun a => (F a).trans (G a)

full_name: Equiv.sigmaCongrRight_symm
code: theorem sigmaCongrRight_symm {α} {β₁ β₂ : α → Type*} (F : ∀ a, β₁ a ≃ β₂ a) :
    (sigmaCongrRight F).symm = sigmaCongrRight fun a => (F a).symm 
goal: (Equiv.sigmaCongrRight F).symm = Equiv.sigmaCongrRight fun a => (F a).symm

full_name: Equiv.sigmaCongrRight_refl
code: theorem sigmaCongrRight_refl {α} {β : α → Type*} :
    (sigmaCongrRight fun a => Equiv.refl (β a)) = Equiv.refl (Σ a, β a) 
goal: (Equiv.sigmaCongrRight fun a => Equiv.refl (β a)) = Equiv.refl ((a : α) × β a)

full_name: Equiv.psigmaEquivSubtype
code: /-- A `PSigma` with `Prop` fibers is equivalent to the subtype.  -/
def psigmaEquivSubtype {α : Type v} (P : α → Prop) : (Σ' i, P i) ≃ Subtype P 
goal: (i : α) ×' P i ≃ Subtype P

full_name: Equiv.sigmaPLiftEquivSubtype
code: /-- A `Sigma` with `PLift` fibers is equivalent to the subtype. -/
def sigmaPLiftEquivSubtype {α : Type v} (P : α → Prop) : (Σ i, PLift (P i)) ≃ Subtype P 
goal: (i : α) × PLift (P i) ≃ Subtype P

full_name: Equiv.sigmaULiftPLiftEquivSubtype
code: /-- A `Sigma` with `fun i ↦ ULift (PLift (P i))` fibers is equivalent to `{ x // P x }`.
Variant of `sigmaPLiftEquivSubtype`.
-/
def sigmaULiftPLiftEquivSubtype {α : Type v} (P : α → Prop) :
    (Σ i, ULift (PLift (P i))) ≃ Subtype P 
goal: (i : α) × ULift.{u_1, 0} (PLift (P i)) ≃ Subtype P

full_name: Equiv.Perm.sigmaCongrRight
code: /-- A family of permutations `Π a, Perm (β a)` generates a permutation `Perm (Σ a, β₁ a)`. -/
abbrev sigmaCongrRight {α} {β : α → Sort _} (F : ∀ a, Perm (β a)) : Perm (Σ a, β a) 
goal: Equiv.Perm ((a : α) × β a)

full_name: Equiv.Perm.sigmaCongrRight_trans
code: @[simp] theorem sigmaCongrRight_trans {α} {β : α → Sort _}
    (F : ∀ a, Perm (β a)) (G : ∀ a, Perm (β a)) :
    (sigmaCongrRight F).trans (sigmaCongrRight G) = sigmaCongrRight fun a => (F a).trans (G a) 
goal: Equiv.trans (Equiv.Perm.sigmaCongrRight F) (Equiv.Perm.sigmaCongrRight G) =
  Equiv.Perm.sigmaCongrRight fun a => Equiv.trans (F a) (G a)

full_name: Equiv.Perm.sigmaCongrRight_symm
code: @[simp] theorem sigmaCongrRight_symm {α} {β : α → Sort _} (F : ∀ a, Perm (β a)) :
    (sigmaCongrRight F).symm = sigmaCongrRight fun a => (F a).symm 
goal: Equiv.symm (Equiv.Perm.sigmaCongrRight F) = Equiv.Perm.sigmaCongrRight fun a => Equiv.symm (F a)

full_name: Equiv.Perm.sigmaCongrRight_refl
code: @[simp] theorem sigmaCongrRight_refl {α} {β : α → Sort _} :
    (sigmaCongrRight fun a => Equiv.refl (β a)) = Equiv.refl (Σ a, β a) 
goal: (Equiv.Perm.sigmaCongrRight fun a => Equiv.refl (β a)) = Equiv.refl ((a : α) × β a)

full_name: Equiv.sigmaCongrLeft
code: /-- An equivalence `f : α₁ ≃ α₂` generates an equivalence between `Σ a, β (f a)` and `Σ a, β a`. -/
@[simps apply] def sigmaCongrLeft {α₁ α₂ : Type*} {β : α₂ → Sort _} (e : α₁ ≃ α₂) :
    (Σ a : α₁, β (e a)) ≃ Σ a : α₂, β a 
goal: (a : α₁) × β (e a) ≃ (a : α₂) × β a

full_name: Equiv.sigmaCongrLeft_apply
code: /-- An equivalence `f : α₁ ≃ α₂` generates an equivalence between `Σ a, β (f a)` and `Σ a, β a`. -/
@[simps apply] def sigmaCongrLeft {α₁ α₂ : Type*} {β : α₂ → Sort _} (e : α₁ ≃ α₂) :
    (Σ a : α₁, β (e a)) ≃ Σ a : α₂, β a 
goal: e.sigmaCongrLeft a = ⟨e a.fst, a.snd⟩

full_name: Equiv.sigmaCongrLeft'
code: /-- Transporting a sigma type through an equivalence of the base -/
def sigmaCongrLeft' {α₁ α₂} {β : α₁ → Sort _} (f : α₁ ≃ α₂) :
    (Σ a : α₁, β a) ≃ Σ a : α₂, β (f.symm a) 
goal: (a : α₁) × β a ≃ (a : α₂) × β (f.symm a)

full_name: Equiv.sigmaCongr
code: /-- Transporting a sigma type through an equivalence of the base and a family of equivalences
of matching fibers -/
def sigmaCongr {α₁ α₂} {β₁ : α₁ → Sort _} {β₂ : α₂ → Sort _} (f : α₁ ≃ α₂)
    (F : ∀ a, β₁ a ≃ β₂ (f a)) : Sigma β₁ ≃ Sigma β₂ 
goal: Sigma β₁ ≃ Sigma β₂

full_name: Equiv.sigmaEquivProd_apply
code: /-- `Sigma` type with a constant fiber is equivalent to the product. -/
@[simps (config := { attrs := [`mfld_simps] }) apply symm_apply]
def sigmaEquivProd (α β : Type*) : (Σ _ : α, β) ≃ α × β 
goal: (Equiv.sigmaEquivProd α β) a = (a.fst, a.snd)

full_name: Equiv.sigmaEquivProd
code: /-- `Sigma` type with a constant fiber is equivalent to the product. -/
@[simps (config := { attrs := [`mfld_simps] }) apply symm_apply]
def sigmaEquivProd (α β : Type*) : (Σ _ : α, β) ≃ α × β 
goal: (_ : α) × β ≃ α × β

full_name: Equiv.sigmaEquivProd_symm_apply
code: /-- `Sigma` type with a constant fiber is equivalent to the product. -/
@[simps (config := { attrs := [`mfld_simps] }) apply symm_apply]
def sigmaEquivProd (α β : Type*) : (Σ _ : α, β) ≃ α × β 
goal: (Equiv.sigmaEquivProd α β).symm a = ⟨a.fst, a.snd⟩

full_name: Equiv.sigmaEquivProdOfEquiv
code: /-- If each fiber of a `Sigma` type is equivalent to a fixed type, then the sigma type
is equivalent to the product. -/
def sigmaEquivProdOfEquiv {α β} {β₁ : α → Sort _} (F : ∀ a, β₁ a ≃ β) : Sigma β₁ ≃ α × β 
goal: Sigma β₁ ≃ α × β

full_name: Equiv.sigmaAssoc
code: /-- Dependent product of types is associative up to an equivalence. -/
def sigmaAssoc {α : Type*} {β : α → Type*} (γ : ∀ a : α, β a → Type*) :
    (Σ ab : Σ a : α, β a, γ ab.1 ab.2) ≃ Σ a : α, Σ b : β a, γ a b 
goal: (ab : (a : α) × β a) × γ ab.fst ab.snd ≃ (a : α) × (b : β a) × γ a b

full_name: Equiv.forall_congr_right
code: protected lemma forall_congr_right : (∀ a, q (e a)) ↔ ∀ b, q b 
goal: (∀ (a : α), q (e a)) ↔ ∀ (b : β), q b

full_name: Equiv.forall_congr_left
code: protected lemma forall_congr_left : (∀ a, p a) ↔ ∀ b, p (e.symm b) 
goal: (∀ (a : α), p a) ↔ ∀ (b : β), p (e.symm b)

full_name: Equiv.forall_congr
code: protected lemma forall_congr (h : ∀ a, p a ↔ q (e a)) : (∀ a, p a) ↔ ∀ b, q b 
goal: (∀ (a : α), p a) ↔ ∀ (b : β), q b

full_name: Equiv.forall_congr'
code: protected lemma forall_congr' (h : ∀ b, p (e.symm b) ↔ q b) : (∀ a, p a) ↔ ∀ b, q b 
goal: (∀ (a : α), p a) ↔ ∀ (b : β), q b

full_name: Equiv.exists_congr_right
code: protected lemma exists_congr_right : (∃ a, q (e a)) ↔ ∃ b, q b 
goal: (∃ a, q (e a)) ↔ ∃ b, q b

full_name: Equiv.exists_congr_left
code: protected lemma exists_congr_left : (∃ a, p a) ↔ ∃ b, p (e.symm b) 
goal: (∃ a, p a) ↔ ∃ b, p (e.symm b)

full_name: Equiv.exists_congr
code: protected lemma exists_congr (h : ∀ a, p a ↔ q (e a)) : (∃ a, p a) ↔ ∃ b, q b 
goal: (∃ a, p a) ↔ ∃ b, q b

full_name: Equiv.exists_congr'
code: protected lemma exists_congr' (h : ∀ b, p (e.symm b) ↔ q b) : (∃ a, p a) ↔ ∃ b, q b 
goal: (∃ a, p a) ↔ ∃ b, q b

full_name: Equiv.existsUnique_congr_right
code: protected lemma existsUnique_congr_right : (∃! a, q (e a)) ↔ ∃! b, q b 
goal: (∃! a, q (e a)) ↔ ∃! b, q b

full_name: Equiv.existsUnique_congr_left
code: protected lemma existsUnique_congr_left : (∃! a, p a) ↔ ∃! b, p (e.symm b) 
goal: (∃! a, p a) ↔ ∃! b, p (e.symm b)

full_name: Equiv.existsUnique_congr
code: protected lemma existsUnique_congr (h : ∀ a, p a ↔ q (e a)) : (∃! a, p a) ↔ ∃! b, q b 
goal: (∃! a, p a) ↔ ∃! b, q b

full_name: Equiv.existsUnique_congr'
code: protected lemma existsUnique_congr' (h : ∀ b, p (e.symm b) ↔ q b) : (∃! a, p a) ↔ ∃! b, q b 
goal: (∃! a, p a) ↔ ∃! b, q b

full_name: Equiv.forall₂_congr
code: protected theorem forall₂_congr {α₁ α₂ β₁ β₂ : Sort*} {p : α₁ → β₁ → Prop} {q : α₂ → β₂ → Prop}
    (eα : α₁ ≃ α₂) (eβ : β₁ ≃ β₂) (h : ∀ {x y}, p x y ↔ q (eα x) (eβ y)) :
    (∀ x y, p x y) ↔ ∀ x y, q x y 
goal: (∀ (x : α₁) (y : β₁), p x y) ↔ ∀ (x : α₂) (y : β₂), q x y

full_name: Equiv.forall₂_congr'
code: protected theorem forall₂_congr' {α₁ α₂ β₁ β₂ : Sort*} {p : α₁ → β₁ → Prop} {q : α₂ → β₂ → Prop}
    (eα : α₁ ≃ α₂) (eβ : β₁ ≃ β₂) (h : ∀ {x y}, p (eα.symm x) (eβ.symm y) ↔ q x y) :
    (∀ x y, p x y) ↔ ∀ x y, q x y 
goal: (∀ (x : α₁) (y : β₁), p x y) ↔ ∀ (x : α₂) (y : β₂), q x y

full_name: Equiv.forall₃_congr
code: protected theorem forall₃_congr
    {α₁ α₂ β₁ β₂ γ₁ γ₂ : Sort*} {p : α₁ → β₁ → γ₁ → Prop} {q : α₂ → β₂ → γ₂ → Prop}
    (eα : α₁ ≃ α₂) (eβ : β₁ ≃ β₂) (eγ : γ₁ ≃ γ₂) (h : ∀ {x y z}, p x y z ↔ q (eα x) (eβ y) (eγ z)) :
    (∀ x y z, p x y z) ↔ ∀ x y z, q x y z 
goal: (∀ (x : α₁) (y : β₁) (z : γ₁), p x y z) ↔ ∀ (x : α₂) (y : β₂) (z : γ₂), q x y z

full_name: Equiv.forall₃_congr'
code: protected theorem forall₃_congr'
    {α₁ α₂ β₁ β₂ γ₁ γ₂ : Sort*} {p : α₁ → β₁ → γ₁ → Prop} {q : α₂ → β₂ → γ₂ → Prop}
    (eα : α₁ ≃ α₂) (eβ : β₁ ≃ β₂) (eγ : γ₁ ≃ γ₂)
    (h : ∀ {x y z}, p (eα.symm x) (eβ.symm y) (eγ.symm z) ↔ q x y z) :
    (∀ x y z, p x y z) ↔ ∀ x y z, q x y z 
goal: (∀ (x : α₁) (y : β₁) (z : γ₁), p x y z) ↔ ∀ (x : α₂) (y : β₂) (z : γ₂), q x y z

full_name: Equiv.ofBijective
code: /-- If `f` is a bijective function, then its domain is equivalent to its codomain. -/
@[simps apply]
noncomputable def ofBijective (f : α → β) (hf : Bijective f) : α ≃ β 
goal: α ≃ β

full_name: Equiv.ofBijective_apply
code: /-- If `f` is a bijective function, then its domain is equivalent to its codomain. -/
@[simps apply]
noncomputable def ofBijective (f : α → β) (hf : Bijective f) : α ≃ β 
goal: ∀ (a : α), (Equiv.ofBijective f hf) a = f a

full_name: Equiv.ofBijective_apply_symm_apply
code: lemma ofBijective_apply_symm_apply (f : α → β) (hf : Bijective f) (x : β) :
    f ((ofBijective f hf).symm x) = x 
goal: f ((Equiv.ofBijective f hf).symm x) = x

full_name: Equiv.ofBijective_symm_apply_apply
code: @[simp]
lemma ofBijective_symm_apply_apply (f : α → β) (hf : Bijective f) (x : α) :
    (ofBijective f hf).symm (f x) = x 
goal: (Equiv.ofBijective f hf).symm (f x) = x

full_name: Quot.congr
code: /-- An equivalence `e : α ≃ β` generates an equivalence between quotient spaces,
if `ra a₁ a₂ ↔ rb (e a₁) (e a₂)`. -/
protected def congr {ra : α → α → Prop} {rb : β → β → Prop} (e : α ≃ β)
    (eq : ∀ a₁ a₂, ra a₁ a₂ ↔ rb (e a₁) (e a₂)) : Quot ra ≃ Quot rb 
goal: Quot ra ≃ Quot rb

full_name: Quot.congr_mk
code: @[simp] theorem congr_mk {ra : α → α → Prop} {rb : β → β → Prop} (e : α ≃ β)
    (eq : ∀ a₁ a₂ : α, ra a₁ a₂ ↔ rb (e a₁) (e a₂)) (a : α) :
    Quot.congr e eq (Quot.mk ra a) = Quot.mk rb (e a) 
goal: (Quot.congr e eq) (Quot.mk ra a) = Quot.mk rb (e a)

full_name: Quot.congrRight
code: /-- 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. -/
protected def congrRight {r r' : α → α → Prop} (eq : ∀ a₁ a₂, r a₁ a₂ ↔ r' a₁ a₂) :
    Quot r ≃ Quot r' 
goal: Quot r ≃ Quot r'

full_name: Quot.congrLeft
code: /-- 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`. -/
protected def congrLeft {r : α → α → Prop} (e : α ≃ β) :
    Quot r ≃ Quot fun b b' => r (e.symm b) (e.symm b') 
goal: Quot r ≃ Quot fun b b' => r (e.symm b) (e.symm b')

full_name: Quotient.congr
code: /-- An equivalence `e : α ≃ β` generates an equivalence between quotient spaces,
if `ra a₁ a₂ ↔ rb (e a₁) (e a₂)`. -/
protected def congr {ra : Setoid α} {rb : Setoid β} (e : α ≃ β)
    (eq : ∀ a₁ a₂, @Setoid.r α ra a₁ a₂ ↔ @Setoid.r β rb (e a₁) (e a₂)) :
    Quotient ra ≃ Quotient rb 
goal: Quotient ra ≃ Quotient rb

full_name: Quotient.congr_mk
code: @[simp] theorem congr_mk {ra : Setoid α} {rb : Setoid β} (e : α ≃ β)
    (eq : ∀ a₁ a₂ : α, Setoid.r a₁ a₂ ↔ Setoid.r (e a₁) (e a₂)) (a : α) :
    Quotient.congr e eq (Quotient.mk ra a) = Quotient.mk rb (e a) 
goal: (Quotient.congr e eq) ⟦a⟧ = ⟦e a⟧

full_name: Quotient.congrRight
code: /-- 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. -/
protected def congrRight {r r' : Setoid α}
    (eq : ∀ a₁ a₂, @Setoid.r α r a₁ a₂ ↔ @Setoid.r α r' a₁ a₂) : Quotient r ≃ Quotient r' 
goal: Quotient r ≃ Quotient r'