/-
Copyright (c) 2020 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.PrePort
import Mathlib.Lean3Lib.init.default
import Mathlib.algebra.group_ring_action
import Mathlib.group_theory.group_action.default
import Mathlib.PostPort

universes u_1 u_2 u_3 l u_4 u_16 u_5 u_6 u_8 u_7 u_9 u_10 u_11 u_13 u_12 u_14 u_15

namespace Mathlib

/-!
# Equivariant homomorphisms

## Main definitions

* `mul_action_hom M X Y`, the type of equivariant functions from `X` to `Y`, where `M` is a monoid
  that acts on the types `X` and `Y`.
* `distrib_mul_action_hom M A B`, the type of equivariant additive monoid homomorphisms
  from `A` to `B`, where `M` is a monoid that acts on the additive monoids `A` and `B`.
* `mul_semiring_action_hom M R S`, the type of equivariant ring homomorphisms
  from `R` to `S`, where `M` is a monoid that acts on the rings `R` and `S`.

## Notations

* `X →[M] Y` is `mul_action_hom M X Y`.
* `A →+[M] B` is `distrib_mul_action_hom M X Y`.
* `R →+*[M] S` is `mul_semiring_action_hom M X Y`.

-/

/-- Equivariant functions. -/
structure mul_action_hom (M' : Type u_1) (X : Type u_2) [has_scalar M' X] (Y : Type u_3)
    [has_scalar M' Y]
    where
  to_fun : X → Y
  map_smul' : ∀ (m : M') (x : X), to_fun (m • x) = m • to_fun x

namespace mul_action_hom

protected instance has_coe_to_fun (M' : Type u_1) (X : Type u_2) [has_scalar M' X] (Y : Type u_3)
    [has_scalar M' Y] : has_coe_to_fun (mul_action_hom M' X Y) :=
  has_coe_to_fun.mk (fun (c : mul_action_hom M' X Y) => X → Y)
    fun (c : mul_action_hom M' X Y) => to_fun c

@[simp] theorem map_smul {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3}
    [has_scalar M' Y] (f : mul_action_hom M' X Y) (m : M') (x : X) :
    coe_fn f (m • x) = m • coe_fn f x :=
  map_smul' f m x

theorem ext {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3} [has_scalar M' Y]
    {f : mul_action_hom M' X Y} {g : mul_action_hom M' X Y} :
    (∀ (x : X), coe_fn f x = coe_fn g x) → f = g :=
  sorry

theorem ext_iff {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3} [has_scalar M' Y]
    {f : mul_action_hom M' X Y} {g : mul_action_hom M' X Y} :
    f = g ↔ ∀ (x : X), coe_fn f x = coe_fn g x :=
  { mp :=
      fun (H : f = g) (x : X) =>
        eq.mpr (id (Eq._oldrec (Eq.refl (coe_fn f x = coe_fn g x)) H)) (Eq.refl (coe_fn g x)),
    mpr := ext }

/-- The identity map as an equivariant map. -/
protected def id (M' : Type u_1) {X : Type u_2} [has_scalar M' X] : mul_action_hom M' X X :=
  mk id sorry

@[simp] theorem id_apply (M' : Type u_1) {X : Type u_2} [has_scalar M' X] (x : X) :
    coe_fn (mul_action_hom.id M') x = x :=
  rfl

/-- Composition of two equivariant maps. -/
def comp {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3} [has_scalar M' Y]
    {Z : Type u_4} [has_scalar M' Z] (g : mul_action_hom M' Y Z) (f : mul_action_hom M' X Y) :
    mul_action_hom M' X Z :=
  mk (⇑g ∘ ⇑f) sorry

@[simp] theorem comp_apply {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3}
    [has_scalar M' Y] {Z : Type u_4} [has_scalar M' Z] (g : mul_action_hom M' Y Z)
    (f : mul_action_hom M' X Y) (x : X) : coe_fn (comp g f) x = coe_fn g (coe_fn f x) :=
  rfl

@[simp] theorem id_comp {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3}
    [has_scalar M' Y] (f : mul_action_hom M' X Y) : comp (mul_action_hom.id M') f = f :=
  sorry

@[simp] theorem comp_id {M' : Type u_1} {X : Type u_2} [has_scalar M' X] {Y : Type u_3}
    [has_scalar M' Y] (f : mul_action_hom M' X Y) : comp f (mul_action_hom.id M') = f :=
  sorry

/-- The canonical map to the left cosets. -/
def to_quotient {G : Type u_16} [group G] (H : subgroup G) :
    mul_action_hom G G (quotient_group.quotient H) :=
  mk coe sorry

@[simp] theorem to_quotient_apply {G : Type u_16} [group G] (H : subgroup G) (g : G) :
    coe_fn (to_quotient H) g = ↑g :=
  rfl

end mul_action_hom

/-- Equivariant additive monoid homomorphisms. -/
structure distrib_mul_action_hom (M : Type u_5) [monoid M] (A : Type u_6) [add_monoid A]
    [distrib_mul_action M A] (B : Type u_8) [add_monoid B] [distrib_mul_action M B]
    extends A →+ B, mul_action_hom M A B where

/-- Reinterpret an equivariant additive monoid homomorphism as an additive monoid homomorphism. -/
/-- Reinterpret an equivariant additive monoid homomorphism as an equivariant function. -/
namespace distrib_mul_action_hom

protected instance has_coe (M : Type u_5) [monoid M] (A : Type u_6) [add_monoid A]
    [distrib_mul_action M A] (B : Type u_8) [add_monoid B] [distrib_mul_action M B] :
    has_coe (distrib_mul_action_hom M A B) (A →+ B) :=
  has_coe.mk to_add_monoid_hom

protected instance has_coe' (M : Type u_5) [monoid M] (A : Type u_6) [add_monoid A]
    [distrib_mul_action M A] (B : Type u_8) [add_monoid B] [distrib_mul_action M B] :
    has_coe (distrib_mul_action_hom M A B) (mul_action_hom M A B) :=
  has_coe.mk to_mul_action_hom

protected instance has_coe_to_fun (M : Type u_5) [monoid M] (A : Type u_6) [add_monoid A]
    [distrib_mul_action M A] (B : Type u_8) [add_monoid B] [distrib_mul_action M B] :
    has_coe_to_fun (distrib_mul_action_hom M A B) :=
  has_coe_to_fun.mk (fun (c : distrib_mul_action_hom M A B) => A → B)
    fun (c : distrib_mul_action_hom M A B) => to_fun c

theorem coe_fn_coe {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A] [distrib_mul_action M A]
    {B : Type u_8} [add_monoid B] [distrib_mul_action M B] (f : distrib_mul_action_hom M A B) :
    ⇑↑f = ⇑f :=
  rfl

theorem coe_fn_coe' {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A] [distrib_mul_action M A]
    {B : Type u_8} [add_monoid B] [distrib_mul_action M B] (f : distrib_mul_action_hom M A B) :
    ⇑↑f = ⇑f :=
  rfl

theorem ext {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A] [distrib_mul_action M A]
    {B : Type u_8} [add_monoid B] [distrib_mul_action M B] {f : distrib_mul_action_hom M A B}
    {g : distrib_mul_action_hom M A B} : (∀ (x : A), coe_fn f x = coe_fn g x) → f = g :=
  sorry

theorem ext_iff {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A] [distrib_mul_action M A]
    {B : Type u_8} [add_monoid B] [distrib_mul_action M B] {f : distrib_mul_action_hom M A B}
    {g : distrib_mul_action_hom M A B} : f = g ↔ ∀ (x : A), coe_fn f x = coe_fn g x :=
  { mp :=
      fun (H : f = g) (x : A) =>
        eq.mpr (id (Eq._oldrec (Eq.refl (coe_fn f x = coe_fn g x)) H)) (Eq.refl (coe_fn g x)),
    mpr := ext }

@[simp] theorem map_zero {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] {B : Type u_8} [add_monoid B] [distrib_mul_action M B]
    (f : distrib_mul_action_hom M A B) : coe_fn f 0 = 0 :=
  map_zero' f

@[simp] theorem map_add {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] {B : Type u_8} [add_monoid B] [distrib_mul_action M B]
    (f : distrib_mul_action_hom M A B) (x : A) (y : A) :
    coe_fn f (x + y) = coe_fn f x + coe_fn f y :=
  map_add' f x y

@[simp] theorem map_neg {M : Type u_5} [monoid M] (A' : Type u_7) [add_group A']
    [distrib_mul_action M A'] (B' : Type u_9) [add_group B'] [distrib_mul_action M B']
    (f : distrib_mul_action_hom M A' B') (x : A') : coe_fn f (-x) = -coe_fn f x :=
  add_monoid_hom.map_neg (↑f) x

@[simp] theorem map_sub {M : Type u_5} [monoid M] (A' : Type u_7) [add_group A']
    [distrib_mul_action M A'] (B' : Type u_9) [add_group B'] [distrib_mul_action M B']
    (f : distrib_mul_action_hom M A' B') (x : A') (y : A') :
    coe_fn f (x - y) = coe_fn f x - coe_fn f y :=
  add_monoid_hom.map_sub (↑f) x y

@[simp] theorem map_smul {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] {B : Type u_8} [add_monoid B] [distrib_mul_action M B]
    (f : distrib_mul_action_hom M A B) (m : M) (x : A) : coe_fn f (m • x) = m • coe_fn f x :=
  map_smul' f m x

/-- The identity map as an equivariant additive monoid homomorphism. -/
protected def id (M : Type u_5) [monoid M] {A : Type u_6} [add_monoid A] [distrib_mul_action M A] :
    distrib_mul_action_hom M A A :=
  mk id sorry sorry sorry

@[simp] theorem id_apply (M : Type u_5) [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] (x : A) : coe_fn (distrib_mul_action_hom.id M) x = x :=
  rfl

/-- Composition of two equivariant additive monoid homomorphisms. -/
def comp {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A] [distrib_mul_action M A]
    {B : Type u_8} [add_monoid B] [distrib_mul_action M B] {C : Type u_10} [add_monoid C]
    [distrib_mul_action M C] (g : distrib_mul_action_hom M B C) (f : distrib_mul_action_hom M A B) :
    distrib_mul_action_hom M A C :=
  mk (mul_action_hom.to_fun (mul_action_hom.comp ↑g ↑f)) sorry sorry sorry

@[simp] theorem comp_apply {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] {B : Type u_8} [add_monoid B] [distrib_mul_action M B] {C : Type u_10}
    [add_monoid C] [distrib_mul_action M C] (g : distrib_mul_action_hom M B C)
    (f : distrib_mul_action_hom M A B) (x : A) : coe_fn (comp g f) x = coe_fn g (coe_fn f x) :=
  rfl

@[simp] theorem id_comp {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] {B : Type u_8} [add_monoid B] [distrib_mul_action M B]
    (f : distrib_mul_action_hom M A B) : comp (distrib_mul_action_hom.id M) f = f :=
  sorry

@[simp] theorem comp_id {M : Type u_5} [monoid M] {A : Type u_6} [add_monoid A]
    [distrib_mul_action M A] {B : Type u_8} [add_monoid B] [distrib_mul_action M B]
    (f : distrib_mul_action_hom M A B) : comp f (distrib_mul_action_hom.id M) = f :=
  sorry

end distrib_mul_action_hom

/-- Equivariant ring homomorphisms. -/
structure mul_semiring_action_hom (M : Type u_5) [monoid M] (R : Type u_11) [semiring R]
    [mul_semiring_action M R] (S : Type u_13) [semiring S] [mul_semiring_action M S]
    extends distrib_mul_action_hom M R S, R →+* S where

/-- Reinterpret an equivariant ring homomorphism as a ring homomorphism. -/
/-- Reinterpret an equivariant ring homomorphism as an equivariant additive monoid homomorphism. -/
namespace mul_semiring_action_hom

protected instance has_coe (M : Type u_5) [monoid M] (R : Type u_11) [semiring R]
    [mul_semiring_action M R] (S : Type u_13) [semiring S] [mul_semiring_action M S] :
    has_coe (mul_semiring_action_hom M R S) (R →+* S) :=
  has_coe.mk to_ring_hom

protected instance has_coe' (M : Type u_5) [monoid M] (R : Type u_11) [semiring R]
    [mul_semiring_action M R] (S : Type u_13) [semiring S] [mul_semiring_action M S] :
    has_coe (mul_semiring_action_hom M R S) (distrib_mul_action_hom M R S) :=
  has_coe.mk to_distrib_mul_action_hom

protected instance has_coe_to_fun (M : Type u_5) [monoid M] (R : Type u_11) [semiring R]
    [mul_semiring_action M R] (S : Type u_13) [semiring S] [mul_semiring_action M S] :
    has_coe_to_fun (mul_semiring_action_hom M R S) :=
  has_coe_to_fun.mk (fun (c : mul_semiring_action_hom M R S) => R → S)
    fun (c : mul_semiring_action_hom M R S) => to_fun c

theorem coe_fn_coe {M : Type u_5} [monoid M] {R : Type u_11} [semiring R] [mul_semiring_action M R]
    {S : Type u_13} [semiring S] [mul_semiring_action M S] (f : mul_semiring_action_hom M R S) :
    ⇑↑f = ⇑f :=
  rfl

theorem coe_fn_coe' {M : Type u_5} [monoid M] {R : Type u_11} [semiring R] [mul_semiring_action M R]
    {S : Type u_13} [semiring S] [mul_semiring_action M S] (f : mul_semiring_action_hom M R S) :
    ⇑↑f = ⇑f :=
  rfl

theorem ext {M : Type u_5} [monoid M] {R : Type u_11} [semiring R] [mul_semiring_action M R]
    {S : Type u_13} [semiring S] [mul_semiring_action M S] {f : mul_semiring_action_hom M R S}
    {g : mul_semiring_action_hom M R S} : (∀ (x : R), coe_fn f x = coe_fn g x) → f = g :=
  sorry

theorem ext_iff {M : Type u_5} [monoid M] {R : Type u_11} [semiring R] [mul_semiring_action M R]
    {S : Type u_13} [semiring S] [mul_semiring_action M S] {f : mul_semiring_action_hom M R S}
    {g : mul_semiring_action_hom M R S} : f = g ↔ ∀ (x : R), coe_fn f x = coe_fn g x :=
  { mp :=
      fun (H : f = g) (x : R) =>
        eq.mpr (id (Eq._oldrec (Eq.refl (coe_fn f x = coe_fn g x)) H)) (Eq.refl (coe_fn g x)),
    mpr := ext }

@[simp] theorem map_zero {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) : coe_fn f 0 = 0 :=
  map_zero' f

@[simp] theorem map_add {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) (x : R) (y : R) :
    coe_fn f (x + y) = coe_fn f x + coe_fn f y :=
  map_add' f x y

@[simp] theorem map_neg {M : Type u_5} [monoid M] (R' : Type u_12) [ring R']
    [mul_semiring_action M R'] (S' : Type u_14) [ring S'] [mul_semiring_action M S']
    (f : mul_semiring_action_hom M R' S') (x : R') : coe_fn f (-x) = -coe_fn f x :=
  ring_hom.map_neg (↑f) x

@[simp] theorem map_sub {M : Type u_5} [monoid M] (R' : Type u_12) [ring R']
    [mul_semiring_action M R'] (S' : Type u_14) [ring S'] [mul_semiring_action M S']
    (f : mul_semiring_action_hom M R' S') (x : R') (y : R') :
    coe_fn f (x - y) = coe_fn f x - coe_fn f y :=
  ring_hom.map_sub (↑f) x y

@[simp] theorem map_one {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) : coe_fn f 1 = 1 :=
  map_one' f

@[simp] theorem map_mul {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) (x : R) (y : R) :
    coe_fn f (x * y) = coe_fn f x * coe_fn f y :=
  map_mul' f x y

@[simp] theorem map_smul {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) (m : M) (x : R) : coe_fn f (m • x) = m • coe_fn f x :=
  map_smul' f m x

/-- The identity map as an equivariant ring homomorphism. -/
protected def id (M : Type u_5) [monoid M] {R : Type u_11} [semiring R] [mul_semiring_action M R] :
    mul_semiring_action_hom M R R :=
  mk id sorry sorry sorry sorry sorry

@[simp] theorem id_apply (M : Type u_5) [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] (x : R) : coe_fn (mul_semiring_action_hom.id M) x = x :=
  rfl

/-- Composition of two equivariant additive monoid homomorphisms. -/
def comp {M : Type u_5} [monoid M] {R : Type u_11} [semiring R] [mul_semiring_action M R]
    {S : Type u_13} [semiring S] [mul_semiring_action M S] {T : Type u_15} [semiring T]
    [mul_semiring_action M T] (g : mul_semiring_action_hom M S T)
    (f : mul_semiring_action_hom M R S) : mul_semiring_action_hom M R T :=
  mk (distrib_mul_action_hom.to_fun (distrib_mul_action_hom.comp ↑g ↑f)) sorry sorry sorry sorry
    sorry

@[simp] theorem comp_apply {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S] {T : Type u_15}
    [semiring T] [mul_semiring_action M T] (g : mul_semiring_action_hom M S T)
    (f : mul_semiring_action_hom M R S) (x : R) : coe_fn (comp g f) x = coe_fn g (coe_fn f x) :=
  rfl

@[simp] theorem id_comp {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) : comp (mul_semiring_action_hom.id M) f = f :=
  sorry

@[simp] theorem comp_id {M : Type u_5} [monoid M] {R : Type u_11} [semiring R]
    [mul_semiring_action M R] {S : Type u_13} [semiring S] [mul_semiring_action M S]
    (f : mul_semiring_action_hom M R S) : comp f (mul_semiring_action_hom.id M) = f :=
  sorry

end mul_semiring_action_hom

/-- The canonical inclusion from an invariant subring. -/
def is_invariant_subring.subtype_hom (M : Type u_5) [monoid M] {R' : Type u_12} [ring R']
    [mul_semiring_action M R'] (U : set R') [is_subring U] [is_invariant_subring M U] :
    mul_semiring_action_hom M (↥U) R' :=
  mul_semiring_action_hom.mk (ring_hom.to_fun (is_subring.subtype U)) sorry sorry sorry sorry sorry

@[simp] theorem is_invariant_subring.coe_subtype_hom (M : Type u_5) [monoid M] {R' : Type u_12}
    [ring R'] [mul_semiring_action M R'] (U : set R') [is_subring U] [is_invariant_subring M U] :
    ⇑(is_invariant_subring.subtype_hom M U) = coe :=
  rfl

@[simp] theorem is_invariant_subring.coe_subtype_hom' (M : Type u_5) [monoid M] {R' : Type u_12}
    [ring R'] [mul_semiring_action M R'] (U : set R') [is_subring U] [is_invariant_subring M U] :
    ↑(is_invariant_subring.subtype_hom M U) = is_subring.subtype U :=
  rfl

end Mathlib


/-
Copyright (c) 2022 Yury G. Kudryashov. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yury G. Kudryashov
-/
import analysis.complex.abs_max
import analysis.complex.removable_singularity

/-!
# Schwarz lemma

In this file we prove several versions of the Schwarz lemma.

* `complex.norm_deriv_le_div_of_maps_to_ball`, `complex.abs_deriv_le_div_of_maps_to_ball`: if
  `f : ℂ → E` sends an open disk with center `c` and a positive radius `R₁` to an open ball with
  center `f c` and radius `R₂`, then the absolute value of the derivative of `f` at `c` is at most
  the ratio `R₂ / R₁`;

* `complex.dist_le_div_mul_dist_of_maps_to_ball`: if `f : ℂ → E` sends an open disk with center `c`
  and radius `R₁` to an open disk with center `f c` and radius `R₂`, then for any `z` in the former
  disk we have `dist (f z) (f c) ≤ (R₂ / R₁) * dist z c`;

* `complex.abs_deriv_le_one_of_maps_to_ball`: if `f : ℂ → ℂ` sends an open disk of positive radius
  to itself and the center of this disk to itself, then the absolute value of the derivative of `f`
  at the center of this disk is at most `1`;

* `complex.dist_le_dist_of_maps_to_ball`: if `f : ℂ → ℂ` sends an open disk to itself and the center
  `c` of this disk to itself, then for any point `z` of this disk we have `dist (f z) c ≤ dist z c`;

* `complex.abs_le_abs_of_maps_to_ball`: if `f : ℂ → ℂ` sends an open disk with center `0` to itself,
  then for any point `z` of this disk we have `abs (f z) ≤ abs z`.

## Implementation notes

We prove some versions of the Schwarz lemma for a map `f : ℂ → E` taking values in any normed space
over complex numbers.

## TODO

* Prove that these inequalities are strict unless `f` is an affine map.

* Prove that any diffeomorphism of the unit disk to itself is a Möbius map.

## Tags

Schwarz lemma
-/

open metric set function filter topological_space
open_locale topological_space

namespace complex

section space

variables {E : Type*} [normed_group E] [normed_space ℂ E] {R R₁ R₂ : ℝ} {f : ℂ → E} {c z : ℂ}

/-- An auxiliary lemma for `complex.norm_dslope_le_div_of_maps_to_ball`. -/
lemma schwarz_aux {f : ℂ → ℂ} (hd : differentiable_on ℂ f (ball c R₁))
  (h_maps : maps_to f (ball c R₁) (ball (f c) R₂)) (hz : z ∈ ball c R₁) :
  ∥dslope f c z∥ ≤ R₂ / R₁ :=
begin
  have hR₁ : 0 < R₁, from nonempty_ball.1 ⟨z, hz⟩,
  suffices : ∀ᶠ r in 𝓝[<] R₁, ∥dslope f c z∥ ≤ R₂ / r,
  { refine ge_of_tendsto _ this,
    exact (tendsto_const_nhds.div tendsto_id hR₁.ne').mono_left nhds_within_le_nhds },
  rw mem_ball at hz,
  filter_upwards [Ioo_mem_nhds_within_Iio ⟨hz, le_rfl⟩] with r hr,
  have hr₀ : 0 < r, from dist_nonneg.trans_lt hr.1,
  replace hd : differentiable_on ℂ (dslope f c) (closed_ball c r) :=
    ((differentiable_on_dslope $ ball_mem_nhds _ hR₁).mpr hd).mono (closed_ball_subset_ball hr.2),
  refine norm_le_of_forall_mem_frontier_norm_le (is_compact_closed_ball c r)
    hd.diff_on_int_cont _ hr.1.le,
  rw frontier_closed_ball',
  intros z hz,
  have hz' : z ≠ c, by { rintro rfl, simpa [hr₀.ne] using hz },
  rw [dslope_of_ne _ hz', slope_def_module, norm_smul, norm_inv,
    (mem_sphere_iff_norm _ _ _).1 hz, ← div_eq_inv_mul, div_le_div_right hr₀, ← dist_eq_norm],
  exact le_of_lt (h_maps (mem_ball.2 (by { rw mem_sphere.1 hz, exact hr.2 })))
end

/-- Two cases of the **Schwarz Lemma** (derivative and distance), merged together. -/
lemma norm_dslope_le_div_of_maps_to_ball (hd : differentiable_on ℂ f (ball c R₁))
  (h_maps : maps_to f (ball c R₁) (ball (f c) R₂)) (hz : z ∈ ball c R₁) :
  ∥dslope f c z∥ ≤ R₂ / R₁ :=
begin
  have hR₁ : 0 < R₁, from nonempty_ball.1 ⟨z, hz⟩,
  have hR₂ : 0 < R₂, from nonempty_ball.1 ⟨f z, h_maps hz⟩,
  cases eq_or_ne (dslope f c z) 0 with hc hc,
  { rw [hc, norm_zero], exact div_nonneg hR₂.le hR₁.le },
  rcases exists_dual_vector ℂ _ hc with ⟨g, hg, hgf⟩,
  have hg' : ∥g∥₊ = 1, from nnreal.eq hg,
  have hg₀ : ∥g∥₊ ≠ 0, by simpa only [hg'] using one_ne_zero,
  calc ∥dslope f c z∥ = ∥dslope (g ∘ f) c z∥ :
    begin
      rw [g.dslope_comp, hgf, is_R_or_C.norm_of_real, norm_norm],
      exact λ _, hd.differentiable_at (ball_mem_nhds _ hR₁)
    end
  ... ≤ R₂ / R₁ :
    begin
      refine schwarz_aux (g.differentiable.comp_differentiable_on hd)
        (maps_to.comp _ h_maps) hz,
      simpa only [hg', nnreal.coe_one, one_mul] using g.lipschitz.maps_to_ball hg₀ (f c) R₂
    end
end

/-- The **Schwarz Lemma**: if `f : ℂ → E` sends an open disk with center `c` and a positive radius
`R₁` to an open ball with center `f c` and radius `R₂`, then the absolute value of the derivative of
`f` at `c` is at most the ratio `R₂ / R₁`. -/
lemma norm_deriv_le_div_of_maps_to_ball (hd : differentiable_on ℂ f (ball c R₁))
  (h_maps : maps_to f (ball c R₁) (ball (f c) R₂)) (h₀ : 0 < R₁) :
  ∥deriv f c∥ ≤ R₂ / R₁ :=
by simpa only [dslope_same] using norm_dslope_le_div_of_maps_to_ball hd h_maps (mem_ball_self h₀)

/-- The **Schwarz Lemma**: if `f : ℂ → E` sends an open disk with center `c` and radius `R₁` to an
open ball with center `f c` and radius `R₂`, then for any `z` in the former disk we have
`dist (f z) (f c) ≤ (R₂ / R₁) * dist z c`. -/
lemma dist_le_div_mul_dist_of_maps_to_ball (hd : differentiable_on ℂ f (ball c R₁))
  (h_maps : maps_to f (ball c R₁) (ball (f c) R₂)) (hz : z ∈ ball c R₁) :
  dist (f z) (f c) ≤ (R₂ / R₁) * dist z c :=
begin
  rcases eq_or_ne z c with rfl|hne, { simp only [dist_self, mul_zero] },
  simpa only [dslope_of_ne _ hne, slope_def_module, norm_smul, norm_inv,
    ← div_eq_inv_mul, ← dist_eq_norm, div_le_iff (dist_pos.2 hne)]
    using norm_dslope_le_div_of_maps_to_ball hd h_maps hz
end

end space

variables {f : ℂ → ℂ} {c z : ℂ} {R R₁ R₂ : ℝ}

/-- The **Schwarz Lemma**: if `f : ℂ → ℂ` sends an open disk with center `c` and a positive radius
`R₁` to an open disk with center `f c` and radius `R₂`, then the absolute value of the derivative of
`f` at `c` is at most the ratio `R₂ / R₁`. -/
lemma abs_deriv_le_div_of_maps_to_ball (hd : differentiable_on ℂ f (ball c R₁))
  (h_maps : maps_to f (ball c R₁) (ball (f c) R₂)) (h₀ : 0 < R₁) :
  abs (deriv f c) ≤ R₂ / R₁ :=
norm_deriv_le_div_of_maps_to_ball hd h_maps h₀

/-- The **Schwarz Lemma**: if `f : ℂ → ℂ` sends an open disk of positive radius to itself and the
center of this disk to itself, then the absolute value of the derivative of `f` at the center of
this disk is at most `1`. -/
lemma abs_deriv_le_one_of_maps_to_ball (hd : differentiable_on ℂ f (ball c R))
  (h_maps : maps_to f (ball c R) (ball c R)) (hc : f c = c) (h₀ : 0 < R) :
  abs (deriv f c) ≤ 1 :=
(norm_deriv_le_div_of_maps_to_ball hd (by rwa hc) h₀).trans_eq (div_self h₀.ne')

/-- The **Schwarz Lemma**: if `f : ℂ → ℂ` sends an open disk to itself and the center `c` of this
disk to itself, then for any point `z` of this disk we have `dist (f z) c ≤ dist z c`. -/
lemma dist_le_dist_of_maps_to_ball_self (hd : differentiable_on ℂ f (ball c R))
  (h_maps : maps_to f (ball c R) (ball c R)) (hc : f c = c) (hz : z ∈ ball c R) :
  dist (f z) c ≤ dist z c :=
have hR : 0 < R, from nonempty_ball.1 ⟨z, hz⟩,
by simpa only [hc, div_self hR.ne', one_mul]
  using dist_le_div_mul_dist_of_maps_to_ball hd (by rwa hc) hz

/-- The **Schwarz Lemma**: if `f : ℂ → ℂ` sends an open disk with center `0` to itself, the for any
point `z` of this disk we have `abs (f z) ≤ abs z`. -/
lemma abs_le_abs_of_maps_to_ball_self (hd : differentiable_on ℂ f (ball 0 R))
  (h_maps : maps_to f (ball 0 R) (ball 0 R)) (h₀ : f 0 = 0) (hz : abs z < R) :
  abs (f z) ≤ abs z :=
begin
  replace hz : z ∈ ball (0 : ℂ) R, from mem_ball_zero_iff.2 hz,
  simpa only [dist_zero_right] using dist_le_dist_of_maps_to_ball_self hd h_maps h₀ hz
end

end complex


/-
Copyright (c) 2018 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import tactic.ring data.quot ring_theory.ideals group_theory.submonoid

universe u

namespace localization

variables (α : Type u) [comm_ring α] (S : set α) [is_submonoid S]

def r : α × S → α × S → Prop :=
λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩, ∃ t ∈ S, (s₁ * r₂ - s₂ * r₁) * t = 0

local infix ≈ := r α S

section
variables {α S}
theorem r_of_eq : ∀{a₀ a₁ : α × S} (h : a₀.2.1 * a₁.1 = a₁.2.1 * a₀.1), a₀ ≈ a₁
| ⟨r₀, s₀, hs₀⟩ ⟨r₁, s₁, hs₁⟩ h := ⟨1, is_submonoid.one_mem S, by simp [h] at h ⊢⟩
end

theorem refl (x : α × S) : x ≈ x := r_of_eq rfl

theorem symm : ∀ (x y : α × S), x ≈ y → y ≈ x :=
λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩ ⟨t, hts, ht⟩, ⟨t, hts,
  calc (s₂ * r₁ - s₁ * r₂) * t = -((s₁ * r₂ - s₂ * r₁) * t) : by simp [add_mul]
    ... = 0 : by rw ht; simp⟩

theorem trans : ∀ (x y z : α × S), x ≈ y → y ≈ z → x ≈ z :=
λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩ ⟨r₃, s₃, hs₃⟩ ⟨t, hts, ht⟩ ⟨t', hts', ht'⟩,
⟨s₂ * t' * t, is_submonoid.mul_mem (is_submonoid.mul_mem hs₂ hts') hts,
  calc (s₁ * r₃ - s₃ * r₁) * (s₂ * t' * t) =
    t' * s₃ * ((s₁ * r₂ - s₂ * r₁) * t) + t * s₁ * ((s₂ * r₃ - s₃ * r₂) * t') :
      by simp [mul_left_comm, mul_add, mul_comm]
    ... = 0 : by rw [ht, ht']; simp⟩

instance : setoid (α × S) :=
⟨r α S, refl α S, symm α S, trans α S⟩

def loc := quotient $ localization.setoid α S

instance : has_add (loc α S) :=
⟨quotient.lift₂
  (λ x y : α × S, (⟦⟨x.2 * y.1 + y.2 * x.1, _, is_submonoid.mul_mem x.2.2 y.2.2⟩⟧ : loc α S)) $
  λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩ ⟨r₃, s₃, hs₃⟩ ⟨r₄, s₄, hs₄⟩ ⟨t₅, hts₅, ht₅⟩ ⟨t₆, hts₆, ht₆⟩,
  quotient.sound ⟨t₆ * t₅, is_submonoid.mul_mem hts₆ hts₅,
    calc (s₁ * s₂ * (s₃ * r₄ + s₄ * r₃) - s₃ * s₄ * (s₁ * r₂ + s₂ * r₁)) * (t₆ * t₅) =
      s₁ * s₃ * ((s₂ * r₄ - s₄ * r₂) * t₆) * t₅ + s₂ * s₄ * ((s₁ * r₃ - s₃ * r₁) * t₅) * t₆ : by ring
      ... = 0 : by rw [ht₆, ht₅]; simp⟩⟩

instance : has_neg (loc α S) :=
⟨quotient.lift (λ x : α × S, (⟦⟨-x.1, x.2⟩⟧ : loc α S)) $
  λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩ ⟨t, hts, ht⟩,
  quotient.sound ⟨t, hts,
    calc (s₁ * -r₂ - s₂ * -r₁) * t = -((s₁ * r₂ - s₂ * r₁) * t) : by ring
      ... = 0 : by rw ht; simp⟩⟩

instance : has_mul (loc α S) :=
⟨quotient.lift₂
  (λ x y : α × S, (⟦⟨x.1 * y.1, _, is_submonoid.mul_mem x.2.2 y.2.2⟩⟧ : loc α S)) $
  λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩ ⟨r₃, s₃, hs₃⟩ ⟨r₄, s₄, hs₄⟩ ⟨t₅, hts₅, ht₅⟩ ⟨t₆, hts₆, ht₆⟩,
  quotient.sound ⟨t₆ * t₅, is_submonoid.mul_mem hts₆ hts₅,
    calc ((s₁ * s₂) * (r₃ * r₄) - (s₃ * s₄) * (r₁ * r₂)) * (t₆ * t₅) =
      t₆ * ((s₁ * r₃ - s₃ * r₁) * t₅) * r₂ * s₄ + t₅ * ((s₂ * r₄ - s₄ * r₂) * t₆) * r₃ * s₁ :
        by simp [mul_left_comm, mul_add, mul_comm]
      ... = 0 : by rw [ht₅, ht₆]; simp⟩⟩

def of_comm_ring : α → loc α S := λ r, ⟦⟨r, 1, is_submonoid.one_mem S⟩⟧

instance : comm_ring (loc α S) :=
by refine
{ add            := has_add.add,
  add_assoc      := λ m n k, quotient.induction_on₃ m n k _,
  zero           := of_comm_ring α S 0,
  zero_add       := quotient.ind _,
  add_zero       := quotient.ind _,
  neg            := has_neg.neg,
  add_left_neg   := quotient.ind _,
  add_comm       := quotient.ind₂ _,
  mul            := has_mul.mul,
  mul_assoc      := λ m n k, quotient.induction_on₃ m n k _,
  one            := of_comm_ring α S 1,
  one_mul        := quotient.ind _,
  mul_one        := quotient.ind _,
  left_distrib   := λ m n k, quotient.induction_on₃ m n k _,
  right_distrib  := λ m n k, quotient.induction_on₃ m n k _,
  mul_comm       := quotient.ind₂ _ };
{ intros,
  try {rcases a with ⟨r₁, s₁, hs₁⟩},
  try {rcases b with ⟨r₂, s₂, hs₂⟩},
  try {rcases c with ⟨r₃, s₃, hs₃⟩},
  refine (quotient.sound $ r_of_eq _),
  simp [mul_left_comm, mul_add, mul_comm] }

instance : is_ring_hom (of_comm_ring α S) :=
{ map_add := λ x y, quotient.sound $ by simp,
  map_mul := λ x y, quotient.sound $ by simp,
  map_one := rfl }

variable {α}

def away (x : α) := loc α (powers x)

instance away.comm_ring (x : α) : comm_ring (away x) :=
localization.comm_ring α (powers x)

section at_prime

variables (P : set α) [is_prime_ideal P]

instance prime.is_submonoid :
  is_submonoid (set.compl P) :=
{ one_mem := λ h, is_proper_ideal.ne_univ P $ is_submodule.univ_of_one_mem P h,
  mul_mem := λ x y hnx hny hxy, or.cases_on (is_prime_ideal.mem_or_mem_of_mul_mem hxy) hnx hny }

def at_prime := loc α (set.compl P)

instance at_prime.comm_ring : comm_ring (at_prime P) :=
localization.comm_ring α (set.compl P)

instance at_prime.local_ring : local_ring (at_prime P) :=
local_of_nonunits_ideal
  (λ hze,
    let ⟨t, hts, ht⟩ := quotient.exact hze in
    hts $ have htz : t = 0, by simpa using ht,
      suffices (0:α) ∈ P, by rwa htz,
      @is_submodule.zero _ _ _ _ P _)
  (λ x y hx hy ⟨z, hz⟩,
    let ⟨⟨r₁, s₁, hs₁⟩, hrs₁⟩ := quotient.exists_rep x,
        ⟨⟨r₂, s₂, hs₂⟩, hrs₂⟩ := quotient.exists_rep y,
        ⟨⟨r₃, s₃, hs₃⟩, hrs₃⟩ := quotient.exists_rep z in
    have _,
      by rw [← hrs₁, ← hrs₂, ← hrs₃] at hz; from quotient.exact hz,
    let ⟨t, hts, ht⟩ := this in
    have hr₁ : r₁ ∈ P,
      from classical.by_contradiction $ λ hnr₁, hx ⟨⟦⟨s₁, r₁, hnr₁⟩⟧,
        by rw ←hrs₁; from (quotient.sound $ r_of_eq $ by simp [mul_comm])⟩,
    have hr₂ : r₂ ∈ P,
      from classical.by_contradiction $ λ hnr₂, hy ⟨⟦⟨s₂, r₂, hnr₂⟩⟧,
        by rw ←hrs₂; from (quotient.sound $ r_of_eq $ by simp [mul_comm])⟩,
    have hr₃ : _ ,
      from or.resolve_right (mem_or_mem_of_mul_eq_zero P ht) hts,
    have h : s₃ * (s₁ * s₂) - r₃ * (s₁ * r₂ + s₂ * r₁) ∈ P,
      by simpa using hr₃,
    have h1 : r₃ * (s₁ * r₂ + s₂ * r₁) ∈ P,
      from is_submodule.smul r₃ $
        is_submodule.add (is_submodule.smul s₁ hr₂) (is_submodule.smul s₂ hr₁),
    have h2 : s₃ * (s₁ * s₂) ∈ P,
      from calc s₃ * (s₁ * s₂) =
          s₃ * (s₁ * s₂) - r₃ * (s₁ * r₂ + s₂ * r₁) + r₃ * (s₁ * r₂ + s₂ * r₁) :
            eq.symm $ sub_add_cancel _ _
        ... ∈ P : is_submodule.add h h1,
    have h3 : s₁ * s₂ ∈ P,
      from or.resolve_left (is_prime_ideal.mem_or_mem_of_mul_mem h2) hs₃,
    or.cases_on (is_prime_ideal.mem_or_mem_of_mul_mem h3) hs₁ hs₂)

end at_prime

variable (α)

def non_zero_divisors : set α := {x | ∀ z, z * x = 0 → z = 0}

instance non_zero_divisors.is_submonoid : is_submonoid (non_zero_divisors α) :=
{ one_mem := λ z hz, by simpa using hz,
  mul_mem := λ x₁ x₂ hx₁ hx₂ z hz,
    have z * x₁ * x₂ = 0, by rwa mul_assoc,
    hx₁ z $ hx₂ (z * x₁) this }

def quotient_ring := loc α (non_zero_divisors α)

instance quotient_ring.comm_ring : comm_ring (quotient_ring α) :=
localization.comm_ring α (non_zero_divisors α)

section quotient_ring

variables {β : Type u} [integral_domain β] [decidable_eq β]

lemma ne_zero_of_mem_non_zero_divisors {x : β} :
  x ∈ localization.non_zero_divisors β → x ≠ 0 :=
λ hm hz,
  have 1 * x = 0, by simp [hz],
  zero_ne_one (hm 1 this).symm

lemma eq_zero_of_ne_zero_of_mul_eq_zero {x y : β} :
  x ≠ 0 → y * x = 0 → y = 0 :=
λ hnx hxy, or.resolve_right (eq_zero_or_eq_zero_of_mul_eq_zero hxy) hnx

lemma mem_non_zero_divisors_of_ne_zero {x : β} :
  x ≠ 0 → x ∈ localization.non_zero_divisors β :=
λ hnx z, eq_zero_of_ne_zero_of_mul_eq_zero hnx

variable (β)

def inv_aux : β × (non_zero_divisors β) → quotient_ring β :=
λ ⟨r, s, hs⟩, if h : r = 0 then 0 else ⟦⟨s, r, mem_non_zero_divisors_of_ne_zero h⟩⟧

instance : has_inv (quotient_ring β) :=
⟨quotient.lift (inv_aux β) $
  λ ⟨r₁, s₁, hs₁⟩ ⟨r₂, s₂, hs₂⟩ ⟨t, hts, ht⟩,
  begin
    have hrs : s₁ * r₂ = 0 + s₂ * r₁,
      from sub_eq_iff_eq_add.1 (hts _ ht),
    by_cases hr₁ : r₁ = 0;
    by_cases hr₂ : r₂ = 0;
    simp [hr₁, hr₂] at hrs; simp [inv_aux, hr₁, hr₂],
    { exfalso,
      exact ne_zero_of_mem_non_zero_divisors hs₁ hrs },
    { exfalso,
      exact ne_zero_of_mem_non_zero_divisors hs₂ hrs },
    { apply r_of_eq,
      simpa [mul_comm] using hrs.symm }
  end⟩

def quotient_ring.field.of_integral_domain : field (quotient_ring β) :=
by refine
{ inv            := has_inv.inv,
  zero_ne_one    := λ hzo,
    let ⟨t, hts, ht⟩ := quotient.exact hzo in
    zero_ne_one (by simpa using hts _ ht : 0 = 1),
  mul_inv_cancel := quotient.ind _,
  inv_mul_cancel := quotient.ind _,
  ..localization.comm_ring β _ };
{ intros x hnx,
  rcases x with ⟨x, z, hz⟩,
  have : x ≠ 0,
    from assume hx, hnx (quotient.sound $ r_of_eq $ by simp [hx]),
  simp [has_inv.inv, inv_aux, inv_aux._match_1, this],
  exact (quotient.sound $ r_of_eq $ by simp; ring) }

end quotient_ring

end localization


/-
Copyright (c) 2019 Jan-David Salchow. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jan-David Salchow, Sébastien Gouëzel, Jean Lo
-/
import Mathlib.PrePort
import Mathlib.Lean3Lib.init.default
import Mathlib.linear_algebra.finite_dimensional
import Mathlib.analysis.normed_space.linear_isometry
import Mathlib.analysis.normed_space.riesz_lemma
import Mathlib.analysis.asymptotics
import Mathlib.PostPort

universes u_2 u_3 u_1 u_4 u_5 u_6 u_7 u_8

namespace Mathlib

/-!
# Operator norm on the space of continuous linear maps

Define the operator norm on the space of continuous linear maps between normed spaces, and prove
its basic properties. In particular, show that this space is itself a normed space.
-/

theorem exists_pos_bound_of_bound {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] {f : E → F} (M : ℝ) (h : ∀ (x : E), norm (f x) ≤ M * norm x) : ∃ (N : ℝ), 0 < N ∧ ∀ (x : E), norm (f x) ≤ N * norm x :=
  Exists.intro (max M 1)
    { left := lt_of_lt_of_le zero_lt_one (le_max_right M 1),
      right := fun (x : E) => le_trans (h x) (mul_le_mul_of_nonneg_right (le_max_left M 1) (norm_nonneg x)) }

/- Most statements in this file require the field to be non-discrete, as this is necessary
to deduce an inequality `∥f x∥ ≤ C ∥x∥` from the continuity of f. However, the other direction always
holds. In this section, we just assume that `𝕜` is a normed field. In the remainder of the file,
it will be non-discrete. -/

theorem linear_map.lipschitz_of_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (C : ℝ) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : lipschitz_with (nnreal.of_real C) ⇑f := sorry

theorem linear_map.antilipschitz_of_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) {K : nnreal} (h : ∀ (x : E), norm x ≤ ↑K * norm (coe_fn f x)) : antilipschitz_with K ⇑f := sorry

theorem linear_map.bound_of_antilipschitz {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) {K : nnreal} (h : antilipschitz_with K ⇑f) (x : E) : norm x ≤ ↑K * norm (coe_fn f x) := sorry

theorem linear_map.uniform_continuous_of_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (C : ℝ) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : uniform_continuous ⇑f :=
  lipschitz_with.uniform_continuous (linear_map.lipschitz_of_bound f C h)

theorem linear_map.continuous_of_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (C : ℝ) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : continuous ⇑f :=
  lipschitz_with.continuous (linear_map.lipschitz_of_bound f C h)

/-- Construct a continuous linear map from a linear map and a bound on this linear map.
The fact that the norm of the continuous linear map is then controlled is given in
`linear_map.mk_continuous_norm_le`. -/
def linear_map.mk_continuous {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (C : ℝ) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : continuous_linear_map 𝕜 E F :=
  continuous_linear_map.mk f

/-- Reinterpret a linear map `𝕜 →ₗ[𝕜] E` as a continuous linear map. This construction
is generalized to the case of any finite dimensional domain
in `linear_map.to_continuous_linear_map`. -/
def linear_map.to_continuous_linear_map₁ {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [normed_field 𝕜] [normed_space 𝕜 E] (f : linear_map 𝕜 𝕜 E) : continuous_linear_map 𝕜 𝕜 E :=
  linear_map.mk_continuous f (norm (coe_fn f 1)) sorry

/-- Construct a continuous linear map from a linear map and the existence of a bound on this linear
map. If you have an explicit bound, use `linear_map.mk_continuous` instead, as a norm estimate will
follow automatically in `linear_map.mk_continuous_norm_le`. -/
def linear_map.mk_continuous_of_exists_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (h : ∃ (C : ℝ), ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : continuous_linear_map 𝕜 E F :=
  continuous_linear_map.mk f

theorem continuous_of_linear_of_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : E → F} (h_add : ∀ (x y : E), f (x + y) = f x + f y) (h_smul : ∀ (c : 𝕜) (x : E), f (c • x) = c • f x) {C : ℝ} (h_bound : ∀ (x : E), norm (f x) ≤ C * norm x) : continuous f :=
  let φ : linear_map 𝕜 E F := linear_map.mk f h_add h_smul;
  linear_map.continuous_of_bound φ C h_bound

@[simp] theorem linear_map.mk_continuous_coe {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (C : ℝ) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : ↑(linear_map.mk_continuous f C h) = f :=
  rfl

@[simp] theorem linear_map.mk_continuous_apply {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (C : ℝ) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) (x : E) : coe_fn (linear_map.mk_continuous f C h) x = coe_fn f x :=
  rfl

@[simp] theorem linear_map.mk_continuous_of_exists_bound_coe {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (h : ∃ (C : ℝ), ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : ↑(linear_map.mk_continuous_of_exists_bound f h) = f :=
  rfl

@[simp] theorem linear_map.mk_continuous_of_exists_bound_apply {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (h : ∃ (C : ℝ), ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) (x : E) : coe_fn (linear_map.mk_continuous_of_exists_bound f h) x = coe_fn f x :=
  rfl

@[simp] theorem linear_map.to_continuous_linear_map₁_coe {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [normed_field 𝕜] [normed_space 𝕜 E] (f : linear_map 𝕜 𝕜 E) : ↑(linear_map.to_continuous_linear_map₁ f) = f :=
  rfl

@[simp] theorem linear_map.to_continuous_linear_map₁_apply {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [normed_field 𝕜] [normed_space 𝕜 E] (f : linear_map 𝕜 𝕜 E) (x : 𝕜) : coe_fn (linear_map.to_continuous_linear_map₁ f) x = coe_fn f x :=
  rfl

theorem linear_map.continuous_iff_is_closed_ker {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [normed_field 𝕜] [normed_space 𝕜 E] {f : linear_map 𝕜 E 𝕜} : continuous ⇑f ↔ is_closed ↑(linear_map.ker f) := sorry

theorem linear_map.bound_of_shell {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) {ε : ℝ} {C : ℝ} (ε_pos : 0 < ε) {c : 𝕜} (hc : 1 < norm c) (hf : ∀ (x : E), ε / norm c ≤ norm x → norm x < ε → norm (coe_fn f x) ≤ C * norm x) (x : E) : norm (coe_fn f x) ≤ C * norm x := sorry

/-- A continuous linear map between normed spaces is bounded when the field is nondiscrete. The
continuity ensures boundedness on a ball of some radius `ε`. The nondiscreteness is then used to
rescale any element into an element of norm in `[ε/C, ε]`, whose image has a controlled norm. The
norm control for the original element follows by rescaling. -/
theorem linear_map.bound_of_continuous {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (hf : continuous ⇑f) : ∃ (C : ℝ), 0 < C ∧ ∀ (x : E), norm (coe_fn f x) ≤ C * norm x := sorry

namespace continuous_linear_map

theorem bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : ∃ (C : ℝ), 0 < C ∧ ∀ (x : E), norm (coe_fn f x) ≤ C * norm x :=
  linear_map.bound_of_continuous (to_linear_map f) (cont f)

theorem is_O_id {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (l : filter E) : asymptotics.is_O (⇑f) (fun (x : E) => x) l := sorry

theorem is_O_comp {𝕜 : Type u_1} {F : Type u_3} {G : Type u_4} [normed_group F] [normed_group G] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 F] [normed_space 𝕜 G] {α : Type u_2} (g : continuous_linear_map 𝕜 F G) (f : α → F) (l : filter α) : asymptotics.is_O (fun (x' : α) => coe_fn g (f x')) f l :=
  asymptotics.is_O.comp_tendsto (is_O_id g ⊤) le_top

theorem is_O_sub {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (l : filter E) (x : E) : asymptotics.is_O (fun (x' : E) => coe_fn f (x' - x)) (fun (x' : E) => x' - x) l :=
  is_O_comp f (fun (x' : E) => x' - x) l

/-- A linear map which is a homothety is a continuous linear map.
    Since the field `𝕜` need not have `ℝ` as a subfield, this theorem is not directly deducible from
    the corresponding theorem about isometries plus a theorem about scalar multiplication.  Likewise
    for the other theorems about homotheties in this file.
 -/
def of_homothety {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) (a : ℝ) (hf : ∀ (x : E), norm (coe_fn f x) = a * norm x) : continuous_linear_map 𝕜 E F :=
  linear_map.mk_continuous f a sorry

theorem to_span_singleton_homothety (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) (c : 𝕜) : norm (coe_fn (linear_map.to_span_singleton 𝕜 E x) c) = norm x * norm c := sorry

/-- Given an element `x` of a normed space `E` over a field `𝕜`, the natural continuous
    linear map from `E` to the span of `x`.-/
def to_span_singleton (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) : continuous_linear_map 𝕜 𝕜 E :=
  of_homothety (linear_map.to_span_singleton 𝕜 E x) (norm x) (to_span_singleton_homothety 𝕜 x)

/-- The operator norm of a continuous linear map is the inf of all its bounds. -/
def op_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : ℝ :=
  Inf (set_of fun (c : ℝ) => 0 ≤ c ∧ ∀ (x : E), norm (coe_fn f x) ≤ c * norm x)

protected instance has_op_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] : has_norm (continuous_linear_map 𝕜 E F) :=
  has_norm.mk op_norm

theorem norm_def {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : norm f = Inf (set_of fun (c : ℝ) => 0 ≤ c ∧ ∀ (x : E), norm (coe_fn f x) ≤ c * norm x) :=
  rfl

-- So that invocations of `real.Inf_le` make sense: we show that the set of

-- bounds is nonempty and bounded below.

theorem bounds_nonempty {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} : ∃ (c : ℝ), c ∈ set_of fun (c : ℝ) => 0 ≤ c ∧ ∀ (x : E), norm (coe_fn f x) ≤ c * norm x := sorry

theorem bounds_bdd_below {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} : bdd_below (set_of fun (c : ℝ) => 0 ≤ c ∧ ∀ (x : E), norm (coe_fn f x) ≤ c * norm x) := sorry

theorem op_norm_nonneg {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : 0 ≤ norm f := sorry

/-- The fundamental property of the operator norm: `∥f x∥ ≤ ∥f∥ * ∥x∥`. -/
theorem le_op_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (x : E) : norm (coe_fn f x) ≤ norm f * norm x := sorry

theorem le_op_norm_of_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) {c : ℝ} {x : E} (h : norm x ≤ c) : norm (coe_fn f x) ≤ norm f * c :=
  le_trans (le_op_norm f x) (mul_le_mul_of_nonneg_left h (op_norm_nonneg f))

theorem le_of_op_norm_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) {c : ℝ} (h : norm f ≤ c) (x : E) : norm (coe_fn f x) ≤ c * norm x :=
  has_le.le.trans (le_op_norm f x) (mul_le_mul_of_nonneg_right h (norm_nonneg x))

/-- continuous linear maps are Lipschitz continuous. -/
theorem lipschitz {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : lipschitz_with { val := norm f, property := op_norm_nonneg f } ⇑f := sorry

theorem ratio_le_op_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (x : E) : norm (coe_fn f x) / norm x ≤ norm f :=
  div_le_of_nonneg_of_le_mul (norm_nonneg x) (op_norm_nonneg f) (le_op_norm f x)

/-- The image of the unit ball under a continuous linear map is bounded. -/
theorem unit_le_op_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (x : E) : norm x ≤ 1 → norm (coe_fn f x) ≤ norm f :=
  mul_one (norm f) ▸ le_op_norm_of_le f

/-- If one controls the norm of every `A x`, then one controls the norm of `A`. -/
theorem op_norm_le_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) {M : ℝ} (hMp : 0 ≤ M) (hM : ∀ (x : E), norm (coe_fn f x) ≤ M * norm x) : norm f ≤ M :=
  real.Inf_le (set_of fun (c : ℝ) => 0 ≤ c ∧ ∀ (x : E), norm (coe_fn f x) ≤ c * norm x) bounds_bdd_below
    { left := hMp, right := hM }

theorem op_norm_le_of_lipschitz {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} {K : nnreal} (hf : lipschitz_with K ⇑f) : norm f ≤ ↑K := sorry

theorem op_norm_le_of_shell {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} {ε : ℝ} {C : ℝ} (ε_pos : 0 < ε) (hC : 0 ≤ C) {c : 𝕜} (hc : 1 < norm c) (hf : ∀ (x : E), ε / norm c ≤ norm x → norm x < ε → norm (coe_fn f x) ≤ C * norm x) : norm f ≤ C :=
  op_norm_le_bound f hC (linear_map.bound_of_shell (↑f) ε_pos hc hf)

theorem op_norm_le_of_ball {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} {ε : ℝ} {C : ℝ} (ε_pos : 0 < ε) (hC : 0 ≤ C) (hf : ∀ (x : E), x ∈ metric.ball 0 ε → norm (coe_fn f x) ≤ C * norm x) : norm f ≤ C := sorry

theorem op_norm_le_of_nhds_zero {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} {C : ℝ} (hC : 0 ≤ C) (hf : filter.eventually (fun (x : E) => norm (coe_fn f x) ≤ C * norm x) (nhds 0)) : norm f ≤ C := sorry

theorem op_norm_le_of_shell' {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {f : continuous_linear_map 𝕜 E F} {ε : ℝ} {C : ℝ} (ε_pos : 0 < ε) (hC : 0 ≤ C) {c : 𝕜} (hc : norm c < 1) (hf : ∀ (x : E), ε * norm c ≤ norm x → norm x < ε → norm (coe_fn f x) ≤ C * norm x) : norm f ≤ C := sorry

theorem op_norm_eq_of_bounds {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] {φ : continuous_linear_map 𝕜 E F} {M : ℝ} (M_nonneg : 0 ≤ M) (h_above : ∀ (x : E), norm (coe_fn φ x) ≤ M * norm x) (h_below : ∀ (N : ℝ), N ≥ 0 → (∀ (x : E), norm (coe_fn φ x) ≤ N * norm x) → M ≤ N) : norm φ = M := sorry

/-- The operator norm satisfies the triangle inequality. -/
theorem op_norm_add_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (g : continuous_linear_map 𝕜 E F) : norm (f + g) ≤ norm f + norm g := sorry

/-- An operator is zero iff its norm vanishes. -/
theorem op_norm_zero_iff {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : norm f = 0 ↔ f = 0 := sorry

/-- The norm of the identity is at most `1`. It is in fact `1`, except when the space is trivial
where it is `0`. It means that one can not do better than an inequality in general. -/
theorem norm_id_le {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] : norm (id 𝕜 E) ≤ 1 := sorry

/-- If a space is non-trivial, then the norm of the identity equals `1`. -/
theorem norm_id {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [nontrivial E] : norm (id 𝕜 E) = 1 := sorry

@[simp] theorem norm_id_field {𝕜 : Type u_1} [nondiscrete_normed_field 𝕜] : norm (id 𝕜 𝕜) = 1 :=
  norm_id

@[simp] theorem norm_id_field' {𝕜 : Type u_1} [nondiscrete_normed_field 𝕜] : norm 1 = 1 :=
  norm_id_field

theorem op_norm_smul_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (c : 𝕜) (f : continuous_linear_map 𝕜 E F) : norm (c • f) ≤ norm c * norm f := sorry

theorem op_norm_neg {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : norm (-f) = norm f := sorry

/-- Continuous linear maps themselves form a normed space with respect to
    the operator norm. -/
protected instance to_normed_group {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] : normed_group (continuous_linear_map 𝕜 E F) :=
  normed_group.of_core (continuous_linear_map 𝕜 E F) sorry

protected instance to_normed_space {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] : normed_space 𝕜 (continuous_linear_map 𝕜 E F) :=
  normed_space.mk op_norm_smul_le

/-- The operator norm is submultiplicative. -/
theorem op_norm_comp_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} {G : Type u_4} [normed_group E] [normed_group F] [normed_group G] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [normed_space 𝕜 G] (h : continuous_linear_map 𝕜 F G) (f : continuous_linear_map 𝕜 E F) : norm (comp h f) ≤ norm h * norm f := sorry

/-- Continuous linear maps form a normed ring with respect to the operator norm. -/
protected instance to_normed_ring {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] : normed_ring (continuous_linear_map 𝕜 E E) :=
  normed_ring.mk sorry op_norm_comp_le

/-- For a nonzero normed space `E`, continuous linear endomorphisms form a normed algebra with
respect to the operator norm. -/
protected instance to_normed_algebra {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [nontrivial E] : normed_algebra 𝕜 (continuous_linear_map 𝕜 E E) :=
  normed_algebra.mk sorry

/-- A continuous linear map is automatically uniformly continuous. -/
protected theorem uniform_continuous {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : uniform_continuous ⇑f :=
  lipschitz_with.uniform_continuous (lipschitz f)

/-- A continuous linear map is an isometry if and only if it preserves the norm. -/
theorem isometry_iff_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) : isometry ⇑f ↔ ∀ (x : E), norm (coe_fn f x) = norm x :=
  add_monoid_hom.isometry_iff_norm (linear_map.to_add_monoid_hom (to_linear_map f))

theorem homothety_norm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [nontrivial E] (f : continuous_linear_map 𝕜 E F) {a : ℝ} (hf : ∀ (x : E), norm (coe_fn f x) = a * norm x) : norm f = a := sorry

theorem to_span_singleton_norm {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) : norm (to_span_singleton 𝕜 x) = norm x :=
  homothety_norm (to_span_singleton 𝕜 x) (to_span_singleton_homothety 𝕜 x)

theorem uniform_embedding_of_bound {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) {K : nnreal} (hf : ∀ (x : E), norm x ≤ ↑K * norm (coe_fn f x)) : uniform_embedding ⇑f :=
  antilipschitz_with.uniform_embedding (linear_map.antilipschitz_of_bound (to_linear_map f) hf)
    (continuous_linear_map.uniform_continuous f)

/-- If a continuous linear map is a uniform embedding, then it is expands the distances
by a positive factor.-/
theorem antilipschitz_of_uniform_embedding {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : continuous_linear_map 𝕜 E F) (hf : uniform_embedding ⇑f) : ∃ (K : nnreal), antilipschitz_with K ⇑f := sorry

/-- If the target space is complete, the space of continuous linear maps with its norm is also
complete. -/
protected instance complete_space {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [complete_space F] : complete_space (continuous_linear_map 𝕜 E F) := sorry

/-- Extension of a continuous linear map `f : E →L[𝕜] F`, with `E` a normed space and `F` a complete
    normed space, along a uniform and dense embedding `e : E →L[𝕜] G`.  -/
/- extension of `f` is continuous -/

def extend {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} {G : Type u_4} [normed_group E] [normed_group F] [normed_group G] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [normed_space 𝕜 G] (f : continuous_linear_map 𝕜 E F) [complete_space F] (e : continuous_linear_map 𝕜 E G) (h_dense : dense_range ⇑e) (h_e : uniform_inducing ⇑e) : continuous_linear_map 𝕜 G F :=
  (fun (cont : continuous (dense_inducing.extend sorry ⇑f)) =>
      (fun (eq : ∀ (b : E), dense_inducing.extend sorry (⇑f) (coe_fn e b) = coe_fn f b) =>
          mk (linear_map.mk (dense_inducing.extend sorry ⇑f) sorry sorry))
        sorry)
    sorry

/- extension of `f` agrees with `f` on the domain of the embedding `e` -/

theorem extend_unique {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} {G : Type u_4} [normed_group E] [normed_group F] [normed_group G] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [normed_space 𝕜 G] (f : continuous_linear_map 𝕜 E F) [complete_space F] (e : continuous_linear_map 𝕜 E G) (h_dense : dense_range ⇑e) (h_e : uniform_inducing ⇑e) (g : continuous_linear_map 𝕜 G F) (H : comp g e = f) : extend f e h_dense h_e = g :=
  injective_coe_fn (uniformly_extend_unique h_e h_dense (iff.mp ext_iff H) (continuous_linear_map.continuous g))

@[simp] theorem extend_zero {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} {G : Type u_4} [normed_group E] [normed_group F] [normed_group G] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [normed_space 𝕜 G] [complete_space F] (e : continuous_linear_map 𝕜 E G) (h_dense : dense_range ⇑e) (h_e : uniform_inducing ⇑e) : extend 0 e h_dense h_e = 0 :=
  extend_unique 0 e h_dense h_e 0 (zero_comp e)

/-- If a dense embedding `e : E →L[𝕜] G` expands the norm by a constant factor `N⁻¹`, then the norm
    of the extension of `f` along `e` is bounded by `N * ∥f∥`. -/
theorem op_norm_extend_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} {G : Type u_4} [normed_group E] [normed_group F] [normed_group G] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [normed_space 𝕜 G] (f : continuous_linear_map 𝕜 E F) [complete_space F] (e : continuous_linear_map 𝕜 E G) (h_dense : dense_range ⇑e) {N : nnreal} (h_e : ∀ (x : E), norm x ≤ ↑N * norm (coe_fn e x)) : norm (extend f e h_dense (uniform_embedding.to_uniform_inducing (uniform_embedding_of_bound e h_e))) ≤ ↑N * norm f := sorry

end continuous_linear_map

theorem linear_isometry.norm_to_continuous_linear_map {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] [nontrivial E] (f : linear_isometry 𝕜 E F) : norm (linear_isometry.to_continuous_linear_map f) = 1 := sorry

/-- If a continuous linear map is constructed from a linear map via the constructor `mk_continuous`,
then its norm is bounded by the bound given to the constructor if it is nonnegative. -/
theorem linear_map.mk_continuous_norm_le {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_map 𝕜 E F) {C : ℝ} (hC : 0 ≤ C) (h : ∀ (x : E), norm (coe_fn f x) ≤ C * norm x) : norm (linear_map.mk_continuous f C h) ≤ C :=
  continuous_linear_map.op_norm_le_bound (linear_map.mk_continuous f C h) hC h

namespace continuous_linear_map

/-- The norm of the tensor product of a scalar linear map and of an element of a normed space
is the product of the norms. -/
@[simp] theorem norm_smul_right_apply {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (c : continuous_linear_map 𝕜 E 𝕜) (f : F) : norm (smul_right c f) = norm c * norm f := sorry

/-- Given `c : c : E →L[𝕜] 𝕜`, `c.smul_rightL` is the continuous linear map from `F` to `E →L[𝕜] F`
sending `f` to `λ e, c e • f`. -/
def smul_rightL {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (c : continuous_linear_map 𝕜 E 𝕜) : continuous_linear_map 𝕜 F (continuous_linear_map 𝕜 E F) :=
  linear_map.mk_continuous (smul_rightₗ c) (norm c) sorry

@[simp] theorem norm_smul_rightL_apply {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (c : continuous_linear_map 𝕜 E 𝕜) (f : F) : norm (coe_fn (smul_rightL c) f) = norm c * norm f := sorry

@[simp] theorem norm_smul_rightL {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (c : continuous_linear_map 𝕜 E 𝕜) [nontrivial F] : norm (smul_rightL c) = norm c :=
  homothety_norm (smul_rightL c) (norm_smul_right_apply c)

/-- The linear map obtained by applying a continuous linear map at a given vector. -/
def applyₗ (𝕜 : Type u_1) {E : Type u_2} (F : Type u_3) [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (v : E) : linear_map 𝕜 (continuous_linear_map 𝕜 E F) F :=
  linear_map.mk (fun (f : continuous_linear_map 𝕜 E F) => coe_fn f v) sorry sorry

theorem continuous_applyₗ (𝕜 : Type u_1) {E : Type u_2} (F : Type u_3) [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (v : E) : continuous ⇑(applyₗ 𝕜 F v) := sorry

/-- The continuous linear map obtained by applying a continuous linear map at a given vector. -/
def apply (𝕜 : Type u_1) {E : Type u_2} (F : Type u_3) [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (v : E) : continuous_linear_map 𝕜 (continuous_linear_map 𝕜 E F) F :=
  mk (applyₗ 𝕜 F v)

@[simp] theorem apply_apply {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (v : E) (f : continuous_linear_map 𝕜 E F) : coe_fn (apply 𝕜 F v) f = coe_fn f v :=
  rfl

/-- Left-multiplication in a normed algebra, considered as a continuous linear map. -/
def lmul_left (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] : 𝕜' → continuous_linear_map 𝕜 𝕜' 𝕜' :=
  fun (x : 𝕜') => linear_map.mk_continuous (algebra.lmul_left 𝕜 x) (norm x) sorry

/-- Right-multiplication in a normed algebra, considered as a continuous linear map. -/
def lmul_right (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] : 𝕜' → continuous_linear_map 𝕜 𝕜' 𝕜' :=
  fun (x : 𝕜') => linear_map.mk_continuous (algebra.lmul_right 𝕜 x) (norm x) sorry

/-- Simultaneous left- and right-multiplication in a normed algebra, considered as a continuous
linear map. -/
def lmul_left_right (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (vw : 𝕜' × 𝕜') : continuous_linear_map 𝕜 𝕜' 𝕜' :=
  comp (lmul_right 𝕜 𝕜' (prod.snd vw)) (lmul_left 𝕜 𝕜' (prod.fst vw))

@[simp] theorem lmul_left_apply (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (x : 𝕜') (y : 𝕜') : coe_fn (lmul_left 𝕜 𝕜' x) y = x * y :=
  rfl

@[simp] theorem lmul_right_apply (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (x : 𝕜') (y : 𝕜') : coe_fn (lmul_right 𝕜 𝕜' x) y = y * x :=
  rfl

@[simp] theorem lmul_left_right_apply (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (vw : 𝕜' × 𝕜') (x : 𝕜') : coe_fn (lmul_left_right 𝕜 𝕜' vw) x = prod.fst vw * x * prod.snd vw :=
  rfl

/-- `𝕜`-linear continuous function induced by a `𝕜'`-linear continuous function when `𝕜'` is a
normed algebra over `𝕜`. -/
def restrict_scalars (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {E' : Type u_6} [normed_group E'] [normed_space 𝕜 E'] [normed_space 𝕜' E'] [is_scalar_tower 𝕜 𝕜' E'] {F' : Type u_7} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] (f : continuous_linear_map 𝕜' E' F') : continuous_linear_map 𝕜 E' F' :=
  mk (linear_map.mk (linear_map.to_fun (linear_map.restrict_scalars 𝕜 (to_linear_map f))) sorry sorry)

@[simp] theorem restrict_scalars_coe_eq_coe (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {E' : Type u_6} [normed_group E'] [normed_space 𝕜 E'] [normed_space 𝕜' E'] [is_scalar_tower 𝕜 𝕜' E'] {F' : Type u_7} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] (f : continuous_linear_map 𝕜' E' F') : ↑(restrict_scalars 𝕜 f) = linear_map.restrict_scalars 𝕜 ↑f :=
  rfl

@[simp] theorem restrict_scalars_coe_eq_coe' (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {E' : Type u_6} [normed_group E'] [normed_space 𝕜 E'] [normed_space 𝕜' E'] [is_scalar_tower 𝕜 𝕜' E'] {F' : Type u_7} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] (f : continuous_linear_map 𝕜' E' F') : ⇑(restrict_scalars 𝕜 f) = ⇑f :=
  rfl

protected instance has_scalar_extend_scalars {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {F' : Type u_6} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] : has_scalar 𝕜' (continuous_linear_map 𝕜 E F') :=
  has_scalar.mk
    fun (c : 𝕜') (f : continuous_linear_map 𝕜 E F') =>
      linear_map.mk_continuous (c • to_linear_map f) (norm c * norm f) sorry

protected instance module_extend_scalars {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {F' : Type u_6} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] : module 𝕜' (continuous_linear_map 𝕜 E F') :=
  semimodule.mk sorry sorry

protected instance normed_space_extend_scalars {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {F' : Type u_6} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] : normed_space 𝕜' (continuous_linear_map 𝕜 E F') :=
  normed_space.mk sorry

/-- When `f` is a continuous linear map taking values in `S`, then `λb, f b • x` is a
continuous linear map. -/
def smul_algebra_right {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {F' : Type u_6} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] (f : continuous_linear_map 𝕜 E 𝕜') (x : F') : continuous_linear_map 𝕜 E F' :=
  mk (linear_map.mk (linear_map.to_fun (linear_map.smul_algebra_right (to_linear_map f) x)) sorry sorry)

@[simp] theorem smul_algebra_right_apply {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] {𝕜' : Type u_5} [normed_field 𝕜'] [normed_algebra 𝕜 𝕜'] {F' : Type u_6} [normed_group F'] [normed_space 𝕜 F'] [normed_space 𝕜' F'] [is_scalar_tower 𝕜 𝕜' F'] (f : continuous_linear_map 𝕜 E 𝕜') (x : F') (c : E) : coe_fn (smul_algebra_right f x) c = coe_fn f c • x :=
  rfl

end continuous_linear_map

/-- The continuous linear map of inclusion from a submodule of `K` into `E`. -/
def submodule.subtype_continuous {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (K : submodule 𝕜 E) : continuous_linear_map 𝕜 (↥K) E :=
  linear_map.mk_continuous (submodule.subtype K) 1 sorry

@[simp] theorem submodule.subtype_continuous_apply {𝕜 : Type u_1} {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (K : submodule 𝕜 E) (v : ↥K) : coe_fn (submodule.subtype_continuous K) v = ↑v :=
  rfl

-- Results in this section hold for continuous additive monoid homomorphisms or equivalences but we

-- don't have bundled continuous additive homomorphisms.

/-- Applying a continuous linear map commutes with taking an (infinite) sum. -/
protected theorem continuous_linear_map.has_sum {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] {f : ι → M} (φ : continuous_linear_map R M M₂) {x : M} (hf : has_sum f x) : has_sum (fun (b : ι) => coe_fn φ (f b)) (coe_fn φ x) := sorry

theorem has_sum.mapL {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] {f : ι → M} (φ : continuous_linear_map R M M₂) {x : M} (hf : has_sum f x) : has_sum (fun (b : ι) => coe_fn φ (f b)) (coe_fn φ x) :=
  continuous_linear_map.has_sum

protected theorem continuous_linear_map.summable {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] {f : ι → M} (φ : continuous_linear_map R M M₂) (hf : summable f) : summable fun (b : ι) => coe_fn φ (f b) :=
  has_sum.summable (has_sum.mapL φ (summable.has_sum hf))

theorem summable.mapL {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] {f : ι → M} (φ : continuous_linear_map R M M₂) (hf : summable f) : summable fun (b : ι) => coe_fn φ (f b) :=
  continuous_linear_map.summable

protected theorem continuous_linear_map.map_tsum {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] [t2_space M₂] {f : ι → M} (φ : continuous_linear_map R M M₂) (hf : summable f) : coe_fn φ (tsum fun (z : ι) => f z) = tsum fun (z : ι) => coe_fn φ (f z) :=
  Eq.symm (has_sum.tsum_eq (has_sum.mapL φ (summable.has_sum hf)))

/-- Applying a continuous linear map commutes with taking an (infinite) sum. -/
protected theorem continuous_linear_equiv.has_sum {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] {f : ι → M} (e : continuous_linear_equiv R M M₂) {y : M₂} : has_sum (fun (b : ι) => coe_fn e (f b)) y ↔ has_sum f (coe_fn (continuous_linear_equiv.symm e) y) := sorry

protected theorem continuous_linear_equiv.summable {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] {f : ι → M} (e : continuous_linear_equiv R M M₂) : (summable fun (b : ι) => coe_fn e (f b)) ↔ summable f := sorry

theorem continuous_linear_equiv.tsum_eq_iff {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] [t2_space M] [t2_space M₂] {f : ι → M} (e : continuous_linear_equiv R M M₂) {y : M₂} : (tsum fun (z : ι) => coe_fn e (f z)) = y ↔ (tsum fun (z : ι) => f z) = coe_fn (continuous_linear_equiv.symm e) y := sorry

protected theorem continuous_linear_equiv.map_tsum {ι : Type u_5} {R : Type u_6} {M : Type u_7} {M₂ : Type u_8} [semiring R] [add_comm_monoid M] [semimodule R M] [add_comm_monoid M₂] [semimodule R M₂] [topological_space M] [topological_space M₂] [t2_space M] [t2_space M₂] {f : ι → M} (e : continuous_linear_equiv R M M₂) : coe_fn e (tsum fun (z : ι) => f z) = tsum fun (z : ι) => coe_fn e (f z) := sorry

namespace continuous_linear_equiv

protected theorem lipschitz {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) : lipschitz_with (nnnorm ↑e) ⇑e :=
  continuous_linear_map.lipschitz ↑e

protected theorem antilipschitz {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) : antilipschitz_with (nnnorm ↑(continuous_linear_equiv.symm e)) ⇑e :=
  lipschitz_with.to_right_inverse (continuous_linear_equiv.lipschitz (continuous_linear_equiv.symm e))
    (linear_equiv.left_inv (to_linear_equiv e))

theorem is_O_comp {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) {α : Type u_4} (f : α → E) (l : filter α) : asymptotics.is_O (fun (x' : α) => coe_fn e (f x')) f l :=
  continuous_linear_map.is_O_comp (↑e) f l

theorem is_O_sub {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) (l : filter E) (x : E) : asymptotics.is_O (fun (x' : E) => coe_fn e (x' - x)) (fun (x' : E) => x' - x) l :=
  continuous_linear_map.is_O_sub (↑e) l x

theorem is_O_comp_rev {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) {α : Type u_4} (f : α → E) (l : filter α) : asymptotics.is_O f (fun (x' : α) => coe_fn e (f x')) l :=
  asymptotics.is_O.congr_left (fun (_x : α) => symm_apply_apply e (f _x))
    (is_O_comp (continuous_linear_equiv.symm e) (fun (x' : α) => coe_fn e (f x')) l)

theorem is_O_sub_rev {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) (l : filter E) (x : E) : asymptotics.is_O (fun (x' : E) => x' - x) (fun (x' : E) => coe_fn e (x' - x)) l :=
  is_O_comp_rev e (fun (x' : E) => x' - x) l

/-- A continuous linear equiv is a uniform embedding. -/
theorem uniform_embedding {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) : uniform_embedding ⇑e :=
  antilipschitz_with.uniform_embedding (continuous_linear_equiv.antilipschitz e)
    (lipschitz_with.uniform_continuous (continuous_linear_equiv.lipschitz e))

theorem one_le_norm_mul_norm_symm {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) [nontrivial E] : 1 ≤ norm ↑e * norm ↑(continuous_linear_equiv.symm e) := sorry

theorem norm_pos {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) [nontrivial E] : 0 < norm ↑e :=
  pos_of_mul_pos_right (lt_of_lt_of_le zero_lt_one (one_le_norm_mul_norm_symm e))
    (norm_nonneg ↑(continuous_linear_equiv.symm e))

theorem norm_symm_pos {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) [nontrivial E] : 0 < norm ↑(continuous_linear_equiv.symm e) :=
  pos_of_mul_pos_left (lt_of_lt_of_le zero_lt_one (one_le_norm_mul_norm_symm e)) (norm_nonneg ↑e)

theorem subsingleton_or_norm_symm_pos {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) : subsingleton E ∨ 0 < norm ↑(continuous_linear_equiv.symm e) :=
  or.dcases_on (subsingleton_or_nontrivial E) (fun (_i : subsingleton E) => Or.inl _i)
    fun (_i : nontrivial E) => Or.inr (norm_symm_pos e)

theorem subsingleton_or_nnnorm_symm_pos {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : continuous_linear_equiv 𝕜 E F) : subsingleton E ∨ 0 < nnnorm ↑(continuous_linear_equiv.symm e) :=
  subsingleton_or_norm_symm_pos e

theorem homothety_inverse {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (a : ℝ) (ha : 0 < a) (f : linear_equiv 𝕜 E F) : (∀ (x : E), norm (coe_fn f x) = a * norm x) → ∀ (y : F), norm (coe_fn (linear_equiv.symm f) y) = a⁻¹ * norm y := sorry

/-- A linear equivalence which is a homothety is a continuous linear equivalence. -/
def of_homothety (𝕜 : Type u_1) {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (f : linear_equiv 𝕜 E F) (a : ℝ) (ha : 0 < a) (hf : ∀ (x : E), norm (coe_fn f x) = a * norm x) : continuous_linear_equiv 𝕜 E F :=
  mk f

theorem to_span_nonzero_singleton_homothety (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) (h : x ≠ 0) (c : 𝕜) : norm (coe_fn (linear_equiv.to_span_nonzero_singleton 𝕜 E x h) c) = norm x * norm c :=
  continuous_linear_map.to_span_singleton_homothety 𝕜 x c

/-- Given a nonzero element `x` of a normed space `E` over a field `𝕜`, the natural
    continuous linear equivalence from `E` to the span of `x`.-/
def to_span_nonzero_singleton (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) (h : x ≠ 0) : continuous_linear_equiv 𝕜 𝕜 ↥(submodule.span 𝕜 (singleton x)) :=
  of_homothety 𝕜 (linear_equiv.to_span_nonzero_singleton 𝕜 E x h) (norm x) sorry
    (to_span_nonzero_singleton_homothety 𝕜 x h)

/-- Given a nonzero element `x` of a normed space `E` over a field `𝕜`, the natural continuous
    linear map from the span of `x` to `𝕜`.-/
def coord (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) (h : x ≠ 0) : continuous_linear_map 𝕜 (↥(submodule.span 𝕜 (singleton x))) 𝕜 :=
  ↑(continuous_linear_equiv.symm (to_span_nonzero_singleton 𝕜 x h))

theorem coord_norm (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) (h : x ≠ 0) : norm (coord 𝕜 x h) = (norm x⁻¹) := sorry

theorem coord_self (𝕜 : Type u_1) {E : Type u_2} [normed_group E] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] (x : E) (h : x ≠ 0) : coe_fn (coord 𝕜 x h) { val := x, property := submodule.mem_span_singleton_self x } = 1 :=
  linear_equiv.coord_self 𝕜 E x h

end continuous_linear_equiv

theorem linear_equiv.uniform_embedding {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : linear_equiv 𝕜 E F) (h₁ : continuous ⇑e) (h₂ : continuous ⇑(linear_equiv.symm e)) : uniform_embedding ⇑e := sorry

/-- Construct a continuous linear equivalence from a linear equivalence together with
bounds in both directions. -/
def linear_equiv.to_continuous_linear_equiv_of_bounds {𝕜 : Type u_1} {E : Type u_2} {F : Type u_3} [normed_group E] [normed_group F] [nondiscrete_normed_field 𝕜] [normed_space 𝕜 E] [normed_space 𝕜 F] (e : linear_equiv 𝕜 E F) (C_to : ℝ) (C_inv : ℝ) (h_to : ∀ (x : E), norm (coe_fn e x) ≤ C_to * norm x) (h_inv : ∀ (x : F), norm (coe_fn (linear_equiv.symm e) x) ≤ C_inv * norm x) : continuous_linear_equiv 𝕜 E F :=
  continuous_linear_equiv.mk e

namespace continuous_linear_map

@[simp] theorem lmul_left_norm (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (v : 𝕜') : norm (lmul_left 𝕜 𝕜' v) = norm v := sorry

@[simp] theorem lmul_right_norm (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (v : 𝕜') : norm (lmul_right 𝕜 𝕜' v) = norm v := sorry

theorem lmul_left_right_norm_le (𝕜 : Type u_1) [nondiscrete_normed_field 𝕜] (𝕜' : Type u_5) [normed_ring 𝕜'] [normed_algebra 𝕜 𝕜'] (vw : 𝕜' × 𝕜') : norm (lmul_left_right 𝕜 𝕜' vw) ≤ norm (prod.fst vw) * norm (prod.snd vw) := sorry