l3lab/ntp-mathlib huggingface dataset:
/-- The operator norm of the projection is `0` if the subspace is dense. -/
theorem norm_trivial_quotient_mk (S : AddSubgroup M)
    (h : (S.topologicalClosure : Set M) = Set.univ) : ‖S.normedMk‖ = 0 := by
  refine' le_antisymm (opNorm_le_bound _ le_rfl fun x => _) (norm_nonneg _)
  have hker : x ∈ S.normedMk.ker.topologicalClosure := by
    rw [S.ker_normedMk, ← SetLike.mem_coe, h]
    

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
h : ↑(topologicalClosure S) = univ
x : M
⊢ x ∈ univ

Next tactic:
trivial
/-- The operator norm of the projection is `0` if the subspace is dense. -/
theorem norm_trivial_quotient_mk (S : AddSubgroup M)
    (h : (S.topologicalClosure : Set M) = Set.univ) : ‖S.normedMk‖ = 0 := by
  refine' le_antisymm (opNorm_le_bound _ le_rfl fun x => _) (norm_nonneg _)
  have hker : x ∈ S.normedMk.ker.topologicalClosure := by
    rw [S.ker_normedMk, ← SetLike.mem_coe, h]
    trivial
  

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
h : ↑(topologicalClosure S) = univ
x : M
hker : x ∈ topologicalClosure (ker (normedMk S))
⊢ ‖(normedMk S) x‖ ≤ 0 * ‖x‖

Next tactic:
rw [ker_normedMk] at hker
/-- The operator norm of the projection is `0` if the subspace is dense. -/
theorem norm_trivial_quotient_mk (S : AddSubgroup M)
    (h : (S.topologicalClosure : Set M) = Set.univ) : ‖S.normedMk‖ = 0 := by
  refine' le_antisymm (opNorm_le_bound _ le_rfl fun x => _) (norm_nonneg _)
  have hker : x ∈ S.normedMk.ker.topologicalClosure := by
    rw [S.ker_normedMk, ← SetLike.mem_coe, h]
    trivial
  rw [ker_normedMk] at hker
  

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
h : ↑(topologicalClosure S) = univ
x : M
hker : x ∈ topologicalClosure S
⊢ ‖(normedMk S) x‖ ≤ 0 * ‖x‖

Next tactic:
simp only [(quotient_norm_eq_zero_iff S x).mpr hker, normedMk.apply, zero_mul, le_rfl]
theorem lift_unique {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (g : NormedAddGroupHom (M ⧸ S) N)
    (h : g.comp S.normedMk = f) : g = lift S f hf := by
  

Proof state:
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
g : NormedAddGroupHom (M ⧸ S) N
h : NormedAddGroupHom.comp g (AddSubgroup.normedMk S) = f
⊢ g = lift S f hf

Next tactic:
ext x
theorem lift_unique {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (g : NormedAddGroupHom (M ⧸ S) N)
    (h : g.comp S.normedMk = f) : g = lift S f hf := by
  ext x
  

Proof state:
case H
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
g : NormedAddGroupHom (M ⧸ S) N
h : NormedAddGroupHom.comp g (AddSubgroup.normedMk S) = f
x : M ⧸ S
⊢ g x = (lift S f hf) x

Next tactic:
rcases AddSubgroup.surjective_normedMk _ x with ⟨x, rfl⟩
theorem lift_unique {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (g : NormedAddGroupHom (M ⧸ S) N)
    (h : g.comp S.normedMk = f) : g = lift S f hf := by
  ext x
  rcases AddSubgroup.surjective_normedMk _ x with ⟨x, rfl⟩
  

Proof state:
case H.intro
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
g : NormedAddGroupHom (M ⧸ S) N
h : NormedAddGroupHom.comp g (AddSubgroup.normedMk S) = f
x : M
⊢ g ((AddSubgroup.normedMk S) x) = (lift S f hf) ((AddSubgroup.normedMk S) x)

Next tactic:
change g.comp S.normedMk x = _
theorem lift_unique {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (g : NormedAddGroupHom (M ⧸ S) N)
    (h : g.comp S.normedMk = f) : g = lift S f hf := by
  ext x
  rcases AddSubgroup.surjective_normedMk _ x with ⟨x, rfl⟩
  change g.comp S.normedMk x = _
  

Proof state:
case H.intro
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
g : NormedAddGroupHom (M ⧸ S) N
h : NormedAddGroupHom.comp g (AddSubgroup.normedMk S) = f
x : M
⊢ (NormedAddGroupHom.comp g (AddSubgroup.normedMk S)) x = (lift S f hf) ((AddSubgroup.normedMk S) x)

Next tactic:
simp only [h]
theorem lift_unique {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (g : NormedAddGroupHom (M ⧸ S) N)
    (h : g.comp S.normedMk = f) : g = lift S f hf := by
  ext x
  rcases AddSubgroup.surjective_normedMk _ x with ⟨x, rfl⟩
  change g.comp S.normedMk x = _
  simp only [h]
  

Proof state:
case H.intro
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
g : NormedAddGroupHom (M ⧸ S) N
h : NormedAddGroupHom.comp g (AddSubgroup.normedMk S) = f
x : M
⊢ f x = (lift S f hf) ((AddSubgroup.normedMk S) x)

Next tactic:
rfl
/-- `S.normedMk` satisfies `IsQuotient`. -/
theorem isQuotientQuotient (S : AddSubgroup M) : IsQuotient S.normedMk :=
  ⟨S.surjective_normedMk, fun m => by 

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
m : M
⊢ ‖(AddSubgroup.normedMk S) m‖ = sInf ((fun m_1 => ‖m + m_1‖) '' ↑(ker (AddSubgroup.normedMk S)))

Next tactic:
simpa [S.ker_normedMk] using quotient_norm_mk_eq _ m
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
n : N
⊢ ∃ m, f m = n ∧ ‖m‖ < ‖n‖ + ε

Next tactic:
obtain ⟨m, rfl⟩ := hquot.surjective n
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  

Proof state:
case intro
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
⊢ ∃ m_1, f m_1 = f m ∧ ‖m_1‖ < ‖f m‖ + ε

Next tactic:
have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    rw [Set.nonempty_image_iff]
    exact ⟨0, f.ker.zero_mem⟩
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
⊢ Set.Nonempty ((fun m' => ‖m + m'‖) '' ↑(ker f))

Next tactic:
rw [Set.nonempty_image_iff]
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    rw [Set.nonempty_image_iff]
    

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
⊢ Set.Nonempty ↑(ker f)

Next tactic:
exact ⟨0, f.ker.zero_mem⟩
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    rw [Set.nonempty_image_iff]
    exact ⟨0, f.ker.zero_mem⟩
  

Proof state:
case intro
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
nonemp : Set.Nonempty ((fun m' => ‖m + m'‖) '' ↑(ker f))
⊢ ∃ m_1, f m_1 = f m ∧ ‖m_1‖ < ‖f m‖ + ε

Next tactic:
rcases Real.lt_sInf_add_pos nonemp hε
    with ⟨_, ⟨⟨x, hx, rfl⟩, H : ‖m + x‖ < sInf ((fun m' : M => ‖m + m'‖) '' f.ker) + ε⟩⟩
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    rw [Set.nonempty_image_iff]
    exact ⟨0, f.ker.zero_mem⟩
  rcases Real.lt_sInf_add_pos nonemp hε
    with ⟨_, ⟨⟨x, hx, rfl⟩, H : ‖m + x‖ < sInf ((fun m' : M => ‖m + m'‖) '' f.ker) + ε⟩⟩
  

Proof state:
case intro.intro.intro.intro.intro
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
nonemp : Set.Nonempty ((fun m' => ‖m + m'‖) '' ↑(ker f))
x : M
hx : x ∈ ↑(ker f)
H : ‖m + x‖ < sInf ((fun m' => ‖m + m'‖) '' ↑(ker f)) + ε
⊢ ∃ m_1, f m_1 = f m ∧ ‖m_1‖ < ‖f m‖ + ε

Next tactic:
exact ⟨m + x, by rw [map_add, (NormedAddGroupHom.mem_ker f x).mp hx, add_zero], by
    rwa [hquot.norm]⟩
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    rw [Set.nonempty_image_iff]
    exact ⟨0, f.ker.zero_mem⟩
  rcases Real.lt_sInf_add_pos nonemp hε
    with ⟨_, ⟨⟨x, hx, rfl⟩, H : ‖m + x‖ < sInf ((fun m' : M => ‖m + m'‖) '' f.ker) + ε⟩⟩
  exact ⟨m + x, by 

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
nonemp : Set.Nonempty ((fun m' => ‖m + m'‖) '' ↑(ker f))
x : M
hx : x ∈ ↑(ker f)
H : ‖m + x‖ < sInf ((fun m' => ‖m + m'‖) '' ↑(ker f)) + ε
⊢ f (m + x) = f m

Next tactic:
rw [map_add, (NormedAddGroupHom.mem_ker f x).mp hx, add_zero]
theorem IsQuotient.norm_lift {f : NormedAddGroupHom M N} (hquot : IsQuotient f) {ε : ℝ} (hε : 0 < ε)
    (n : N) : ∃ m : M, f m = n ∧ ‖m‖ < ‖n‖ + ε := by
  obtain ⟨m, rfl⟩ := hquot.surjective n
  have nonemp : ((fun m' => ‖m + m'‖) '' f.ker).Nonempty := by
    rw [Set.nonempty_image_iff]
    exact ⟨0, f.ker.zero_mem⟩
  rcases Real.lt_sInf_add_pos nonemp hε
    with ⟨_, ⟨⟨x, hx, rfl⟩, H : ‖m + x‖ < sInf ((fun m' : M => ‖m + m'‖) '' f.ker) + ε⟩⟩
  exact ⟨m + x, by rw [map_add, (NormedAddGroupHom.mem_ker f x).mp hx, add_zero], by
    

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
ε : ℝ
hε : 0 < ε
m : M
nonemp : Set.Nonempty ((fun m' => ‖m + m'‖) '' ↑(ker f))
x : M
hx : x ∈ ↑(ker f)
H : ‖m + x‖ < sInf ((fun m' => ‖m + m'‖) '' ↑(ker f)) + ε
⊢ ‖m + x‖ < ‖f m‖ + ε

Next tactic:
rwa [hquot.norm]
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m : M
⊢ ‖f m‖ ≤ ‖m‖

Next tactic:
rw [hquot.norm]
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  rw [hquot.norm]
  

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m : M
⊢ sInf ((fun m_1 => ‖m + m_1‖) '' ↑(ker f)) ≤ ‖m‖

Next tactic:
apply csInf_le
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  rw [hquot.norm]
  apply csInf_le
  · 

Proof state:
case h₁
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m : M
⊢ BddBelow ((fun m_1 => ‖m + m_1‖) '' ↑(ker f))

Next tactic:
use 0
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  rw [hquot.norm]
  apply csInf_le
  · use 0
    

Proof state:
case h
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m : M
⊢ 0 ∈ lowerBounds ((fun m_1 => ‖m + m_1‖) '' ↑(ker f))

Next tactic:
rintro _ ⟨m', -, rfl⟩
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  rw [hquot.norm]
  apply csInf_le
  · use 0
    rintro _ ⟨m', -, rfl⟩
    

Proof state:
case h.intro.intro
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m m' : M
⊢ 0 ≤ (fun m_1 => ‖m + m_1‖) m'

Next tactic:
apply norm_nonneg
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  rw [hquot.norm]
  apply csInf_le
  · use 0
    rintro _ ⟨m', -, rfl⟩
    apply norm_nonneg
  · 

Proof state:
case h₂
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m : M
⊢ ‖m‖ ∈ (fun m_1 => ‖m + m_1‖) '' ↑(ker f)

Next tactic:
exact ⟨0, f.ker.zero_mem, by simp⟩
theorem IsQuotient.norm_le {f : NormedAddGroupHom M N} (hquot : IsQuotient f) (m : M) :
    ‖f m‖ ≤ ‖m‖ := by
  rw [hquot.norm]
  apply csInf_le
  · use 0
    rintro _ ⟨m', -, rfl⟩
    apply norm_nonneg
  · exact ⟨0, f.ker.zero_mem, by 

Proof state:
M : Type u_1
N : Type u_2
inst✝¹ : SeminormedAddCommGroup M
inst✝ : SeminormedAddCommGroup N
f : NormedAddGroupHom M N
hquot : IsQuotient f
m : M
⊢ (fun m_1 => ‖m + m_1‖) 0 = ‖m‖

Next tactic:
simp
theorem lift_normNoninc {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (fb : f.NormNoninc) :
    (lift S f hf).NormNoninc := fun x => by
  

Proof state:
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
fb : NormNoninc f
x : M ⧸ S
⊢ ‖(lift S f hf) x‖ ≤ ‖x‖

Next tactic:
have fb' : ‖f‖ ≤ (1 : ℝ≥0) := NormNoninc.normNoninc_iff_norm_le_one.mp fb
theorem lift_normNoninc {N : Type*} [SeminormedAddCommGroup N] (S : AddSubgroup M)
    (f : NormedAddGroupHom M N) (hf : ∀ s ∈ S, f s = 0) (fb : f.NormNoninc) :
    (lift S f hf).NormNoninc := fun x => by
  have fb' : ‖f‖ ≤ (1 : ℝ≥0) := NormNoninc.normNoninc_iff_norm_le_one.mp fb
  

Proof state:
M : Type u_1
N✝ : Type u_2
inst✝² : SeminormedAddCommGroup M
inst✝¹ : SeminormedAddCommGroup N✝
N : Type u_3
inst✝ : SeminormedAddCommGroup N
S : AddSubgroup M
f : NormedAddGroupHom M N
hf : ∀ s ∈ S, f s = 0
fb : NormNoninc f
x : M ⧸ S
fb' : ‖f‖ ≤ ↑1
⊢ ‖(lift S f hf) x‖ ≤ ‖x‖

Next tactic:
simpa using le_of_opNorm_le _ (f.lift_norm_le _ _ fb') _
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        

Proof state:
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
x : M ⧸ S
ε : ℝ
hε : 0 < ε
⊢ ‖k • x‖ ≤ ‖k‖ * ‖x‖ + ε

Next tactic:
have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
        

Proof state:
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
x : M ⧸ S
ε : ℝ
hε : 0 < ε
this : ∃ ia, 0 < ia ∧ ∀ x_1 ∈ ball ‖x‖ ia, ‖k‖ * x_1 ∈ ball (‖k‖ * ‖x‖) ε
⊢ ‖k • x‖ ≤ ‖k‖ * ‖x‖ + ε

Next tactic:
simp only [mem_ball, exists_prop, dist, abs_sub_lt_iff] at this
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
        simp only [mem_ball, exists_prop, dist, abs_sub_lt_iff] at this
        

Proof state:
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
x : M ⧸ S
ε : ℝ
hε : 0 < ε
this :
  ∃ ia, 0 < ia ∧ ∀ (x_1 : ℝ), x_1 - ‖x‖ < ia ∧ ‖x‖ - x_1 < ia → ‖k‖ * x_1 - ‖k‖ * ‖x‖ < ε ∧ ‖k‖ * ‖x‖ - ‖k‖ * x_1 < ε
⊢ ‖k • x‖ ≤ ‖k‖ * ‖x‖ + ε

Next tactic:
rcases this with ⟨δ, hδ, h⟩
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
        simp only [mem_ball, exists_prop, dist, abs_sub_lt_iff] at this
        rcases this with ⟨δ, hδ, h⟩
        

Proof state:
case intro.intro
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
x : M ⧸ S
ε : ℝ
hε : 0 < ε
δ : ℝ
hδ : 0 < δ
h : ∀ (x_1 : ℝ), x_1 - ‖x‖ < δ ∧ ‖x‖ - x_1 < δ → ‖k‖ * x_1 - ‖k‖ * ‖x‖ < ε ∧ ‖k‖ * ‖x‖ - ‖k‖ * x_1 < ε
⊢ ‖k • x‖ ≤ ‖k‖ * ‖x‖ + ε

Next tactic:
obtain ⟨a, rfl, ha⟩ := Submodule.Quotient.norm_mk_lt x hδ
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
        simp only [mem_ball, exists_prop, dist, abs_sub_lt_iff] at this
        rcases this with ⟨δ, hδ, h⟩
        obtain ⟨a, rfl, ha⟩ := Submodule.Quotient.norm_mk_lt x hδ
        

Proof state:
case intro.intro.intro.intro
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
ε : ℝ
hε : 0 < ε
δ : ℝ
hδ : 0 < δ
a : M
h : ∀ (x : ℝ), x - ‖mk a‖ < δ ∧ ‖mk a‖ - x < δ → ‖k‖ * x - ‖k‖ * ‖mk a‖ < ε ∧ ‖k‖ * ‖mk a‖ - ‖k‖ * x < ε
ha : ‖a‖ < ‖mk a‖ + δ
⊢ ‖k • mk a‖ ≤ ‖k‖ * ‖mk a‖ + ε

Next tactic:
specialize h ‖a‖ ⟨by linarith, by linarith [Submodule.Quotient.norm_mk_le S a]⟩
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
        simp only [mem_ball, exists_prop, dist, abs_sub_lt_iff] at this
        rcases this with ⟨δ, hδ, h⟩
        obtain ⟨a, rfl, ha⟩ := Submodule.Quotient.norm_mk_lt x hδ
        specialize h ‖a‖ ⟨by 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
ε : ℝ
hε : 0 < ε
δ : ℝ
hδ : 0 < δ
a : M
h : ∀ (x : ℝ), x - ‖mk a‖ < δ ∧ ‖mk a‖ - x < δ → ‖k‖ * x - ‖k‖ * ‖mk a‖ < ε ∧ ‖k‖ * ‖mk a‖ - ‖k‖ * x < ε
ha : ‖a‖ < ‖mk a‖ + δ
⊢ ‖a‖ - ‖mk a‖ < δ

Next tactic:
linarith
instance Submodule.Quotient.normedSpace (𝕜 : Type*) [NormedField 𝕜] [NormedSpace 𝕜 M] [SMul 𝕜 R]
    [IsScalarTower 𝕜 R M] : NormedSpace 𝕜 (M ⧸ S) :=
  { Submodule.Quotient.module' S with
    norm_smul_le := fun k x =>
      -- porting note: this is `QuotientAddGroup.norm_lift_apply_le` for `f : M → M ⧸ S` given by
      -- `x ↦ mk (k • x)`; todo: add scalar multiplication as `NormedAddGroupHom`, use it here
      le_of_forall_pos_le_add fun ε hε => by
        have := (nhds_basis_ball.tendsto_iff nhds_basis_ball).mp
          ((@Real.uniformContinuous_const_mul ‖k‖).continuous.tendsto ‖x‖) ε hε
        simp only [mem_ball, exists_prop, dist, abs_sub_lt_iff] at this
        rcases this with ⟨δ, hδ, h⟩
        obtain ⟨a, rfl, ha⟩ := Submodule.Quotient.norm_mk_lt x hδ
        specialize h ‖a‖ ⟨by linarith, by 

Proof state:
M : Type u_1
N : Type u_2
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
R : Type u_3
inst✝⁵ : Ring R
inst✝⁴ : Module R M
S : Submodule R M
𝕜 : Type u_4
inst✝³ : NormedField 𝕜
inst✝² : NormedSpace 𝕜 M
inst✝¹ : SMul 𝕜 R
inst✝ : IsScalarTower 𝕜 R M
src✝ : Module 𝕜 (M ⧸ S) := module' S
k : 𝕜
ε : ℝ
hε : 0 < ε
δ : ℝ
hδ : 0 < δ
a : M
h : ∀ (x : ℝ), x - ‖mk a‖ < δ ∧ ‖mk a‖ - x < δ → ‖k‖ * x - ‖k‖ * ‖mk a‖ < ε ∧ ‖k‖ * ‖mk a‖ - ‖k‖ * x < ε
ha : ‖a‖ < ‖mk a‖ + δ
⊢ ‖mk a‖ - ‖a‖ < δ

Next tactic:
linarith [Submodule.Quotient.norm_mk_le S a]