l3lab/ntp-mathlib huggingface dataset:
/-- Transport dependent functions through an equivalence of the base space.
-/
@[simps]
def piCongrLeft' (P : α → Sort*) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b) where
  toFun f x := f (e.symm x)
  invFun f x := (e.symm_apply_apply x).ndrec (f (e x))
  left_inv f := funext fun x =>
    (by 

Proof state:
α : Sort ?u.125534
β : Sort ?u.125538
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
x : α
⊢ ∀ {y : α} (h : y = x), h ▸ f y = f x

Next tactic:
rintro _ rfl
/-- Transport dependent functions through an equivalence of the base space.
-/
@[simps]
def piCongrLeft' (P : α → Sort*) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b) where
  toFun f x := f (e.symm x)
  invFun f x := (e.symm_apply_apply x).ndrec (f (e x))
  left_inv f := funext fun x =>
    (by rintro _ rfl; 

Proof state:
α : Sort ?u.125534
β : Sort ?u.125538
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
y✝ : α
⊢ (_ : y✝ = y✝) ▸ f y✝ = f y✝

Next tactic:
rfl
/-- Transport dependent functions through an equivalence of the base space.
-/
@[simps]
def piCongrLeft' (P : α → Sort*) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b) where
  toFun f x := f (e.symm x)
  invFun f x := (e.symm_apply_apply x).ndrec (f (e x))
  left_inv f := funext fun x =>
    (by rintro _ rfl; rfl : ∀ {y} (h : y = x), h.ndrec (f y) = f x) (e.symm_apply_apply x)
  right_inv f := funext fun x =>
    (by 

Proof state:
α : Sort ?u.125534
β : Sort ?u.125538
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
f : (b : β) → P (e.symm b)
x : β
⊢ ∀ {y : β} (h : y = x), (_ : e.symm y = e.symm x) ▸ f y = f x

Next tactic:
rintro _ rfl
/-- Transport dependent functions through an equivalence of the base space.
-/
@[simps]
def piCongrLeft' (P : α → Sort*) (e : α ≃ β) : (∀ a, P a) ≃ ∀ b, P (e.symm b) where
  toFun f x := f (e.symm x)
  invFun f x := (e.symm_apply_apply x).ndrec (f (e x))
  left_inv f := funext fun x =>
    (by rintro _ rfl; rfl : ∀ {y} (h : y = x), h.ndrec (f y) = f x) (e.symm_apply_apply x)
  right_inv f := funext fun x =>
    (by rintro _ rfl; 

Proof state:
α : Sort ?u.125534
β : Sort ?u.125538
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
f : (b : β) → P (e.symm b)
y✝ : β
⊢ (_ : e.symm y✝ = e.symm y✝) ▸ f y✝ = f y✝

Next tactic:
rfl
/-- Note: the "obvious" statement `(piCongrLeft' P e).symm g a = g (e a)` doesn't typecheck: the
LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. This lemma is a way
around it in the case where `a` is of the form `e.symm b`, so we can use `g b` instead of
`g (e (e.symm b))`. -/
lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) :
    (piCongrLeft' P e).symm g (e.symm b) = g b := by
  

Proof state:
α : Sort u_2
β : Sort u_3
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
g : (b : β) → P (e.symm b)
b : β
⊢ (piCongrLeft' P e).symm g (e.symm b) = g b

Next tactic:
change Eq.ndrec _ _ = _
/-- Note: the "obvious" statement `(piCongrLeft' P e).symm g a = g (e a)` doesn't typecheck: the
LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. This lemma is a way
around it in the case where `a` is of the form `e.symm b`, so we can use `g b` instead of
`g (e (e.symm b))`. -/
lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) :
    (piCongrLeft' P e).symm g (e.symm b) = g b := by
  change Eq.ndrec _ _ = _
  

Proof state:
α : Sort u_2
β : Sort u_3
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
g : (b : β) → P (e.symm b)
b : β
⊢ (_ : e.symm (e (e.symm b)) = e.symm b) ▸ g (e (e.symm b)) = g b

Next tactic:
generalize_proofs hZa
/-- Note: the "obvious" statement `(piCongrLeft' P e).symm g a = g (e a)` doesn't typecheck: the
LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. This lemma is a way
around it in the case where `a` is of the form `e.symm b`, so we can use `g b` instead of
`g (e (e.symm b))`. -/
lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) :
    (piCongrLeft' P e).symm g (e.symm b) = g b := by
  change Eq.ndrec _ _ = _
  generalize_proofs hZa
  

Proof state:
α : Sort u_2
β : Sort u_3
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
g : (b : β) → P (e.symm b)
b : β
hZa : e.symm (e (e.symm b)) = e.symm b
⊢ hZa ▸ g (e (e.symm b)) = g b

Next tactic:
revert hZa
/-- Note: the "obvious" statement `(piCongrLeft' P e).symm g a = g (e a)` doesn't typecheck: the
LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. This lemma is a way
around it in the case where `a` is of the form `e.symm b`, so we can use `g b` instead of
`g (e (e.symm b))`. -/
lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) :
    (piCongrLeft' P e).symm g (e.symm b) = g b := by
  change Eq.ndrec _ _ = _
  generalize_proofs hZa
  revert hZa
  

Proof state:
α : Sort u_2
β : Sort u_3
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
g : (b : β) → P (e.symm b)
b : β
⊢ ∀ (hZa : e.symm (e (e.symm b)) = e.symm b), hZa ▸ g (e (e.symm b)) = g b

Next tactic:
rw [e.apply_symm_apply b]
/-- Note: the "obvious" statement `(piCongrLeft' P e).symm g a = g (e a)` doesn't typecheck: the
LHS would have type `P a` while the RHS would have type `P (e.symm (e a))`. This lemma is a way
around it in the case where `a` is of the form `e.symm b`, so we can use `g b` instead of
`g (e (e.symm b))`. -/
lemma piCongrLeft'_symm_apply_apply (P : α → Sort*) (e : α ≃ β) (g : ∀ b, P (e.symm b)) (b : β) :
    (piCongrLeft' P e).symm g (e.symm b) = g b := by
  change Eq.ndrec _ _ = _
  generalize_proofs hZa
  revert hZa
  rw [e.apply_symm_apply b]
  

Proof state:
α : Sort u_2
β : Sort u_3
P✝ : α → Sort w
e✝ : α ≃ β
P : α → Sort u_1
e : α ≃ β
g : (b : β) → P (e.symm b)
b : β
⊢ ∀ (hZa : e.symm b = e.symm b), hZa ▸ g b = g b

Next tactic:
simp
theorem piCongrLeft_sum_inl (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i)))
    (g : ∀ i, π (e (inr i))) (i : ι) :
    piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inl i)) = f i := by
  

Proof state:
β : Sort ?u.128405
α : Sort ?u.128410
P : β → Sort w
e✝ : α ≃ β
ι'' : Sort u_2
ι : Type u_3
ι' : Type u_4
π : ι'' → Type u_1
e : ι ⊕ ι' ≃ ι''
f : (i : ι) → π (e (inl i))
g : (i : ι') → π (e (inr i))
i : ι
⊢ (piCongrLeft π e) ((sumPiEquivProdPi fun x => π (e x)).symm (f, g)) (e (inl i)) = f i

Next tactic:
simp_rw [piCongrLeft_apply_eq_cast, sumPiEquivProdPi_symm_apply,
    sum_rec_congr _ _ _ (e.symm_apply_apply (inl i)), cast_cast, cast_eq]
theorem piCongrLeft_sum_inr (π : ι'' → Type*) (e : ι ⊕ ι' ≃ ι'') (f : ∀ i, π (e (inl i)))
    (g : ∀ i, π (e (inr i))) (j : ι') :
    piCongrLeft π e (sumPiEquivProdPi (fun x => π (e x)) |>.symm (f, g)) (e (inr j)) = g j := by
  

Proof state:
β : Sort ?u.129932
α : Sort ?u.129937
P : β → Sort w
e✝ : α ≃ β
ι'' : Sort u_2
ι : Type u_3
ι' : Type u_4
π : ι'' → Type u_1
e : ι ⊕ ι' ≃ ι''
f : (i : ι) → π (e (inl i))
g : (i : ι') → π (e (inr i))
j : ι'
⊢ (piCongrLeft π e) ((sumPiEquivProdPi fun x => π (e x)).symm (f, g)) (e (inr j)) = g j

Next tactic:
simp_rw [piCongrLeft_apply_eq_cast, sumPiEquivProdPi_symm_apply,
    sum_rec_congr _ _ _ (e.symm_apply_apply (inr j)), cast_cast, cast_eq]
@[simp]
theorem piCongr_apply_apply (f : ∀ a, W a) (a : α) : h₁.piCongr h₂ f (h₁ a) = h₂ a (f a) := by
  

Proof state:
α : Sort u_2
β : Sort u_1
W : α → Sort w
Z : β → Sort z
h₁ : α ≃ β
h₂ : (a : α) → W a ≃ Z (h₁ a)
f : (a : α) → W a
a : α
⊢ (piCongr h₁ h₂) f (h₁ a) = (h₂ a) (f a)

Next tactic:
simp only [piCongr, piCongrRight, trans_apply, coe_fn_mk, piCongrLeft_apply_apply]
@[simp]
theorem piCongr'_symm_apply_symm_apply (f : ∀ b, Z b) (b : β) :
    (h₁.piCongr' h₂).symm f (h₁.symm b) = (h₂ b).symm (f b) := by
  

Proof state:
α : Sort u_1
β : Sort u_2
W : α → Sort w
Z : β → Sort z
h₁ : α ≃ β
h₂ : (b : β) → W (h₁.symm b) ≃ Z b
f : (b : β) → Z b
b : β
⊢ (piCongr' h₁ h₂).symm f (h₁.symm b) = (h₂ b).symm (f b)

Next tactic:
simp [piCongr', piCongr_apply_apply]
theorem semiconj_conj (f : α₁ → α₁) : Semiconj e f (e.conj f) := fun x => by 

Proof state:
α₁ : Type u_2
β₁ : Type u_1
e : α₁ ≃ β₁
f✝ : α₁ → α₁ → α₁
f : α₁ → α₁
x : α₁
⊢ e (f x) = (conj e) f (e x)

Next tactic:
simp
theorem semiconj₂_conj : Semiconj₂ e f (e.arrowCongr e.conj f) := fun x y => by 

Proof state:
α₁ : Type u_2
β₁ : Type u_1
e : α₁ ≃ β₁
f : α₁ → α₁ → α₁
x y : α₁
⊢ e (f x y) = (arrowCongr e (conj e)) f (e x) (e y)

Next tactic:
simp [arrowCongr]
instance [IsLeftCancel α₁ f] : IsLeftCancel β₁ (e.arrowCongr (e.arrowCongr e) f) :=
  ⟨e.surjective.forall₃.2 fun x y z => by 

Proof state:
α₁ : Type ?u.139033
β₁ : Type ?u.139038
e : α₁ ≃ β₁
f : α₁ → α₁ → α₁
inst✝ : IsLeftCancel α₁ f
x y z : α₁
⊢ (arrowCongr e (arrowCongr e e)) f (e x) (e y) = (arrowCongr e (arrowCongr e e)) f (e x) (e z) → e y = e z

Next tactic:
simpa using @IsLeftCancel.left_cancel _ f _ x y z
instance [IsRightCancel α₁ f] : IsRightCancel β₁ (e.arrowCongr (e.arrowCongr e) f) :=
  ⟨e.surjective.forall₃.2 fun x y z => by 

Proof state:
α₁ : Type ?u.140628
β₁ : Type ?u.140633
e : α₁ ≃ β₁
f : α₁ → α₁ → α₁
inst✝ : IsRightCancel α₁ f
x y z : α₁
⊢ (arrowCongr e (arrowCongr e e)) f (e x) (e y) = (arrowCongr e (arrowCongr e e)) f (e z) (e y) → e x = e z

Next tactic:
simpa using @IsRightCancel.right_cancel _ f _ x y z
theorem Function.Injective.swap_apply
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) :
    Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z) := by
  

Proof state:
α : Sort u_1
β : Sort u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y z : α
⊢ (Equiv.swap (f x) (f y)) (f z) = f ((Equiv.swap x y) z)

Next tactic:
by_cases hx:z = x
theorem Function.Injective.swap_apply
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) :
    Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z) := by
  by_cases hx:z = x
  · 

Proof state:
case pos
α : Sort u_1
β : Sort u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y z : α
hx : z = x
⊢ (Equiv.swap (f x) (f y)) (f z) = f ((Equiv.swap x y) z)

Next tactic:
simp [hx]
theorem Function.Injective.swap_apply
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) :
    Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z) := by
  by_cases hx:z = x
  · simp [hx]

  

Proof state:
case neg
α : Sort u_1
β : Sort u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y z : α
hx : ¬z = x
⊢ (Equiv.swap (f x) (f y)) (f z) = f ((Equiv.swap x y) z)

Next tactic:
by_cases hy:z = y
theorem Function.Injective.swap_apply
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) :
    Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z) := by
  by_cases hx:z = x
  · simp [hx]

  by_cases hy:z = y
  · 

Proof state:
case pos
α : Sort u_1
β : Sort u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y z : α
hx : ¬z = x
hy : z = y
⊢ (Equiv.swap (f x) (f y)) (f z) = f ((Equiv.swap x y) z)

Next tactic:
simp [hy]
theorem Function.Injective.swap_apply
    [DecidableEq α] [DecidableEq β] {f : α → β} (hf : Function.Injective f) (x y z : α) :
    Equiv.swap (f x) (f y) (f z) = f (Equiv.swap x y z) := by
  by_cases hx:z = x
  · simp [hx]

  by_cases hy:z = y
  · simp [hy]

  

Proof state:
case neg
α : Sort u_1
β : Sort u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
hf : Injective f
x y z : α
hx : ¬z = x
hy : ¬z = y
⊢ (Equiv.swap (f x) (f y)) (f z) = f ((Equiv.swap x y) z)

Next tactic:
rw [Equiv.swap_apply_of_ne_of_ne hx hy, Equiv.swap_apply_of_ne_of_ne (hf.ne hx) (hf.ne hy)]
theorem update_comp_equiv [DecidableEq α'] [DecidableEq α] (f : α → β)
    (g : α' ≃ α) (a : α) (v : β) :
    update f a v ∘ g = update (f ∘ g) (g.symm a) v := by
  

Proof state:
α' : Sort u_1
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α'
inst✝ : DecidableEq α
f : α → β
g : α' ≃ α
a : α
v : β
⊢ update f a v ∘ ⇑g = update (f ∘ ⇑g) (g.symm a) v

Next tactic:
rw [← update_comp_eq_of_injective _ g.injective, g.apply_symm_apply]
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  

Proof state:
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
⊢ (Equiv.piCongrLeft' P e) (update f (e.symm b) x) = update ((Equiv.piCongrLeft' P e) f) b x

Next tactic:
ext b'
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  

Proof state:
case h
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
b' : β
⊢ (Equiv.piCongrLeft' P e) (update f (e.symm b) x) b' = update ((Equiv.piCongrLeft' P e) f) b x b'

Next tactic:
rcases eq_or_ne b' b with (rfl | h)
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h)
  · 

Proof state:
case h.inl
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b' : β
x : P (e.symm b')
⊢ (Equiv.piCongrLeft' P e) (update f (e.symm b') x) b' = update ((Equiv.piCongrLeft' P e) f) b' x b'

Next tactic:
simp
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h)
  · simp
  · 

Proof state:
case h.inr
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
b' : β
h : b' ≠ b
⊢ (Equiv.piCongrLeft' P e) (update f (e.symm b) x) b' = update ((Equiv.piCongrLeft' P e) f) b x b'

Next tactic:
simp only [Equiv.piCongrLeft'_apply, ne_eq, h, not_false_iff, update_noteq]
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h)
  · simp
  · simp only [Equiv.piCongrLeft'_apply, ne_eq, h, not_false_iff, update_noteq]
    

Proof state:
case h.inr
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
b' : β
h : b' ≠ b
⊢ update f (e.symm b) x (e.symm b') = f (e.symm b')

Next tactic:
rw [update_noteq _]
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h)
  · simp
  · simp only [Equiv.piCongrLeft'_apply, ne_eq, h, not_false_iff, update_noteq]
    rw [update_noteq _]
    

Proof state:
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
b' : β
h : b' ≠ b
⊢ e.symm b' ≠ e.symm b

Next tactic:
rw [ne_eq]
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h)
  · simp
  · simp only [Equiv.piCongrLeft'_apply, ne_eq, h, not_false_iff, update_noteq]
    rw [update_noteq _]
    rw [ne_eq]
    

Proof state:
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
b' : β
h : b' ≠ b
⊢ ¬e.symm b' = e.symm b

Next tactic:
intro h'
theorem piCongrLeft'_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ a, P a) (b : β) (x : P (e.symm b)) :
    e.piCongrLeft' P (update f (e.symm b) x) = update (e.piCongrLeft' P f) b x := by
  ext b'
  rcases eq_or_ne b' b with (rfl | h)
  · simp
  · simp only [Equiv.piCongrLeft'_apply, ne_eq, h, not_false_iff, update_noteq]
    rw [update_noteq _]
    rw [ne_eq]
    intro h'
    /- an example of something that should work, or also putting `EmbeddingLike.apply_eq_iff_eq`
      in the `simp` should too:
    have := (EmbeddingLike.apply_eq_iff_eq e).mp h' -/
    

Proof state:
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (a : α) → P a
b : β
x : P (e.symm b)
b' : β
h : b' ≠ b
h' : e.symm b' = e.symm b
⊢ False

Next tactic:
cases e.symm.injective h' |> h
theorem piCongrLeft'_symm_update [DecidableEq α] [DecidableEq β] (P : α → Sort*) (e : α ≃ β)
    (f : ∀ b, P (e.symm b)) (b : β) (x : P (e.symm b)) :
    (e.piCongrLeft' P).symm (update f b x) = update ((e.piCongrLeft' P).symm f) (e.symm b) x := by
  

Proof state:
α : Sort u_2
β : Sort u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
P : α → Sort u_1
e : α ≃ β
f : (b : β) → P (e.symm b)
b : β
x : P (e.symm b)
⊢ (Equiv.piCongrLeft' P e).symm (update f b x) = update ((Equiv.piCongrLeft' P e).symm f) (e.symm b) x

Next tactic:
simp [(e.piCongrLeft' P).symm_apply_eq, piCongrLeft'_update]
theorem memℓp_zero_iff {f : ∀ i, E i} : Memℓp f 0 ↔ Set.Finite { i | f i ≠ 0 } := by
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
⊢ Memℓp f 0 ↔ Set.Finite {i | f i ≠ 0}

Next tactic:
dsimp [Memℓp]
theorem memℓp_zero_iff {f : ∀ i, E i} : Memℓp f 0 ↔ Set.Finite { i | f i ≠ 0 } := by
  dsimp [Memℓp]
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
⊢ (if 0 = 0 then Set.Finite {i | ¬f i = 0}
    else if 0 = ⊤ then BddAbove (Set.range fun i => ‖f i‖) else Summable fun i => ‖f i‖ ^ 0) ↔
    Set.Finite {i | ¬f i = 0}

Next tactic:
rw [if_pos rfl]
theorem memℓp_infty_iff {f : ∀ i, E i} : Memℓp f ∞ ↔ BddAbove (Set.range fun i => ‖f i‖) := by
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
⊢ Memℓp f ⊤ ↔ BddAbove (Set.range fun i => ‖f i‖)

Next tactic:
dsimp [Memℓp]
theorem memℓp_infty_iff {f : ∀ i, E i} : Memℓp f ∞ ↔ BddAbove (Set.range fun i => ‖f i‖) := by
  dsimp [Memℓp]
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
⊢ (if ⊤ = 0 then Set.Finite {i | ¬f i = 0}
    else if ⊤ = ⊤ then BddAbove (Set.range fun i => ‖f i‖) else Summable fun i => ‖f i‖ ^ 0) ↔
    BddAbove (Set.range fun i => ‖f i‖)

Next tactic:
rw [if_neg ENNReal.top_ne_zero, if_pos rfl]
theorem memℓp_gen_iff (hp : 0 < p.toReal) {f : ∀ i, E i} :
    Memℓp f p ↔ Summable fun i => ‖f i‖ ^ p.toReal := by
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
hp : 0 < ENNReal.toReal p
f : (i : α) → E i
⊢ Memℓp f p ↔ Summable fun i => ‖f i‖ ^ ENNReal.toReal p

Next tactic:
rw [ENNReal.toReal_pos_iff] at hp
theorem memℓp_gen_iff (hp : 0 < p.toReal) {f : ∀ i, E i} :
    Memℓp f p ↔ Summable fun i => ‖f i‖ ^ p.toReal := by
  rw [ENNReal.toReal_pos_iff] at hp
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
hp : 0 < p ∧ p < ⊤
f : (i : α) → E i
⊢ Memℓp f p ↔ Summable fun i => ‖f i‖ ^ ENNReal.toReal p

Next tactic:
dsimp [Memℓp]
theorem memℓp_gen_iff (hp : 0 < p.toReal) {f : ∀ i, E i} :
    Memℓp f p ↔ Summable fun i => ‖f i‖ ^ p.toReal := by
  rw [ENNReal.toReal_pos_iff] at hp
  dsimp [Memℓp]
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
hp : 0 < p ∧ p < ⊤
f : (i : α) → E i
⊢ (if p = 0 then Set.Finite {i | ¬f i = 0}
    else if p = ⊤ then BddAbove (Set.range fun i => ‖f i‖) else Summable fun i => ‖f i‖ ^ ENNReal.toReal p) ↔
    Summable fun i => ‖f i‖ ^ ENNReal.toReal p

Next tactic:
rw [if_neg hp.1.ne', if_neg hp.2.ne]
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  

Proof state:
α : Type u_1
E : α → Type u_2
p q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal p
⊢ Memℓp f p

Next tactic:
rcases p.trichotomy with (rfl | rfl | hp)
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · 

Proof state:
case inl
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal 0
⊢ Memℓp f 0

Next tactic:
apply memℓp_zero
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · apply memℓp_zero
    

Proof state:
case inl.hf
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal 0
⊢ Set.Finite {i | f i ≠ 0}

Next tactic:
have H : Summable fun _ : α => (1 : ℝ) := by simpa using hf
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · apply memℓp_zero
    have H : Summable fun _ : α => (1 : ℝ) := by 

Proof state:
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal 0
⊢ Summable fun x => 1

Next tactic:
simpa using hf
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · apply memℓp_zero
    have H : Summable fun _ : α => (1 : ℝ) := by simpa using hf
    

Proof state:
case inl.hf
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal 0
H : Summable fun x => 1
⊢ Set.Finite {i | f i ≠ 0}

Next tactic:
exact (Set.Finite.of_summable_const (by norm_num) H).subset (Set.subset_univ _)
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · apply memℓp_zero
    have H : Summable fun _ : α => (1 : ℝ) := by simpa using hf
    exact (Set.Finite.of_summable_const (by 

Proof state:
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal 0
H : Summable fun x => 1
⊢ 0 < 1

Next tactic:
norm_num
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · apply memℓp_zero
    have H : Summable fun _ : α => (1 : ℝ) := by simpa using hf
    exact (Set.Finite.of_summable_const (by norm_num) H).subset (Set.subset_univ _)
  · 

Proof state:
case inr.inl
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal ⊤
⊢ Memℓp f ⊤

Next tactic:
apply memℓp_infty
theorem memℓp_gen {f : ∀ i, E i} (hf : Summable fun i => ‖f i‖ ^ p.toReal) : Memℓp f p := by
  rcases p.trichotomy with (rfl | rfl | hp)
  · apply memℓp_zero
    have H : Summable fun _ : α => (1 : ℝ) := by simpa using hf
    exact (Set.Finite.of_summable_const (by norm_num) H).subset (Set.subset_univ _)
  · apply memℓp_infty
    

Proof state:
case inr.inl.hf
α : Type u_1
E : α → Type u_2
q : ℝ≥0∞
inst✝ : (i : α) → NormedAddCommGroup (E i)
f : (i : α) → E i
hf : Summable fun i => ‖f i‖ ^ ENNReal.toReal ⊤
⊢ BddAbove (Set.range fun i => ‖f i‖)

Next tactic:
have H : Summable fun _ : α => (1 : ℝ) := by simpa using hf