l3lab/ntp-mathlib huggingface dataset:
/-- If `K / E / F` is a field extension tower, such that `K / E` is algebraic, then
$[E:F]_s [K:E]_s = [K:F]_s$. See also `lift_rank_mul_lift_rank`. -/
theorem lift_sepDegree_mul_lift_sepDegree_of_isAlgebraic
    [Algebra E K] [IsScalarTower F E K] (halg : Algebra.IsAlgebraic E K) :
    Cardinal.lift.{w} (sepDegree F E) * Cardinal.lift.{v} (sepDegree E K) =
      Cardinal.lift.{v} (sepDegree F K) := by
  have := (embProdEmbOfIsAlgebraic F E K halg).trans
    (Equiv.ulift.{v} (α := Emb F K)).symm |>.cardinal_eq
  

Proof state:
F : Type u
E : Type v
inst✝⁶ : Field F
inst✝⁵ : Field E
inst✝⁴ : Algebra F E
K : Type w
inst✝³ : Field K
inst✝² : Algebra F K
inst✝¹ : Algebra E K
inst✝ : IsScalarTower F E K
halg : Algebra.IsAlgebraic E K
this : Cardinal.mk (Emb F E × Emb E K) = Cardinal.mk (ULift.{v, w} (Emb F K))
⊢ Cardinal.lift.{w, v} (sepDegree F E) * Cardinal.lift.{v, w} (sepDegree E K) = Cardinal.lift.{v, w} (sepDegree F K)

Next tactic:
simpa only [Cardinal.mk_prod, Cardinal.mk_uLift] using this
/-- The same-universe version of `Field.lift_sepDegree_mul_lift_sepDegree_of_isAlgebraic`.
See also `rank_mul_rank`. -/
theorem sepDegree_mul_sepDegree_of_isAlgebraic
    (A : Type u) (B : Type u) [Field A] [Field B] [Algebra A B]
    (C : Type u) [Field C] [Algebra A C] [Algebra B C]
    [IsScalarTower A B C] (halg : Algebra.IsAlgebraic B C) :
    sepDegree A B * sepDegree B C = sepDegree A C := by
  

Proof state:
F : Type u
E : Type v
inst✝¹¹ : Field F
inst✝¹⁰ : Field E
inst✝⁹ : Algebra F E
K : Type w
inst✝⁸ : Field K
inst✝⁷ : Algebra F K
A B : Type u
inst✝⁶ : Field A
inst✝⁵ : Field B
inst✝⁴ : Algebra A B
C : Type u
inst✝³ : Field C
inst✝² : Algebra A C
inst✝¹ : Algebra B C
inst✝ : IsScalarTower A B C
halg : Algebra.IsAlgebraic B C
⊢ sepDegree A B * sepDegree B C = sepDegree A C

Next tactic:
simpa only [Cardinal.lift_id] using lift_sepDegree_mul_lift_sepDegree_of_isAlgebraic A B C halg
/-- The `Field.finSepDegree` version of `Field.lift_sepDegree_mul_lift_sepDegree_of_isAlgebraic`.
See also `FiniteDimensional.finrank_mul_finrank'`. -/
theorem finSepDegree_mul_finSepDegree_of_isAlgebraic
    [Algebra E K] [IsScalarTower F E K] (halg : Algebra.IsAlgebraic E K) :
    finSepDegree F E * finSepDegree E K = finSepDegree F K := by
  

Proof state:
F : Type u
E : Type v
inst✝⁶ : Field F
inst✝⁵ : Field E
inst✝⁴ : Algebra F E
K : Type w
inst✝³ : Field K
inst✝² : Algebra F K
inst✝¹ : Algebra E K
inst✝ : IsScalarTower F E K
halg : Algebra.IsAlgebraic E K
⊢ finSepDegree F E * finSepDegree E K = finSepDegree F K

Next tactic:
simpa only [Cardinal.toNat_mul, Cardinal.toNat_lift] using congr_arg Cardinal.toNat
    (lift_sepDegree_mul_lift_sepDegree_of_isAlgebraic F E K halg)
lemma cocomplex_exactAt_succ (n : ℕ) :
    I.cocomplex.ExactAt (n + 1) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ ExactAt I.cocomplex (n + 1)

Next tactic:
rw [← quasiIsoAt_iff_exactAt I.ι (n + 1) (exactAt_succ_single_obj _ _)]
lemma cocomplex_exactAt_succ (n : ℕ) :
    I.cocomplex.ExactAt (n + 1) := by
  rw [← quasiIsoAt_iff_exactAt I.ι (n + 1) (exactAt_succ_single_obj _ _)]
  · 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ QuasiIsoAt I.ι (n + 1)

Next tactic:
infer_instance
lemma exact_succ (n : ℕ):
    (ShortComplex.mk _ _ (I.cocomplex.d_comp_d n (n + 1) (n + 2))).Exact :=
  (HomologicalComplex.exactAt_iff' _ n (n + 1) (n + 2) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ ComplexShape.prev (ComplexShape.up ℕ) (n + 1) = n

Next tactic:
simp
lemma exact_succ (n : ℕ):
    (ShortComplex.mk _ _ (I.cocomplex.d_comp_d n (n + 1) (n + 2))).Exact :=
  (HomologicalComplex.exactAt_iff' _ n (n + 1) (n + 2) (by simp)
    (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ ComplexShape.next (ComplexShape.up ℕ) (n + 1) = n + 2

Next tactic:
simp only [CochainComplex.next]
lemma exact_succ (n : ℕ):
    (ShortComplex.mk _ _ (I.cocomplex.d_comp_d n (n + 1) (n + 2))).Exact :=
  (HomologicalComplex.exactAt_iff' _ n (n + 1) (n + 2) (by simp)
    (by simp only [CochainComplex.next]; 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ n + 1 + 1 = n + 2

Next tactic:
rfl
@[simp]
theorem ι_f_succ (n : ℕ) : I.ι.f (n + 1) = 0 :=
  (isZero_single_obj_X _ _ _ _ (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ n + 1 ≠ 0

Next tactic:
simp
@[reassoc]
theorem ι_f_zero_comp_complex_d :
    I.ι.f 0 ≫ I.cocomplex.d 0 1 = 0 := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ Hom.f I.ι 0 ≫ d I.cocomplex 0 1 = 0

Next tactic:
simp
theorem complex_d_comp (n : ℕ) :
    I.cocomplex.d n (n + 1) ≫ I.cocomplex.d (n + 1) (n + 2) = 0 := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ d I.cocomplex n (n + 1) ≫ d I.cocomplex (n + 1) (n + 2) = 0

Next tactic:
simp
/-- `Z` is the kernel of `I.cocomplex.X 0 ⟶ I.cocomplex.X 1` when `I : InjectiveResolution Z`. -/
def isLimitKernelFork : IsLimit (I.kernelFork) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ IsLimit (kernelFork I)

Next tactic:
refine IsLimit.ofIsoLimit (I.cocomplex.cyclesIsKernel 0 1 (by simp)) (Iso.symm ?_)
/-- `Z` is the kernel of `I.cocomplex.X 0 ⟶ I.cocomplex.X 1` when `I : InjectiveResolution Z`. -/
def isLimitKernelFork : IsLimit (I.kernelFork) := by
  refine IsLimit.ofIsoLimit (I.cocomplex.cyclesIsKernel 0 1 (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ ComplexShape.next (ComplexShape.up ℕ) 0 = 1

Next tactic:
simp
/-- `Z` is the kernel of `I.cocomplex.X 0 ⟶ I.cocomplex.X 1` when `I : InjectiveResolution Z`. -/
def isLimitKernelFork : IsLimit (I.kernelFork) := by
  refine IsLimit.ofIsoLimit (I.cocomplex.cyclesIsKernel 0 1 (by simp)) (Iso.symm ?_)
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ kernelFork I ≅ KernelFork.ofι (iCycles I.cocomplex 0) (_ : iCycles I.cocomplex 0 ≫ d I.cocomplex 0 1 = 0)

Next tactic:
refine Fork.ext ((singleObjHomologySelfIso _ _ _).symm ≪≫
    isoOfQuasiIsoAt I.ι 0 ≪≫ I.cocomplex.isoHomologyπ₀.symm) ?_
/-- `Z` is the kernel of `I.cocomplex.X 0 ⟶ I.cocomplex.X 1` when `I : InjectiveResolution Z`. -/
def isLimitKernelFork : IsLimit (I.kernelFork) := by
  refine IsLimit.ofIsoLimit (I.cocomplex.cyclesIsKernel 0 1 (by simp)) (Iso.symm ?_)
  refine Fork.ext ((singleObjHomologySelfIso _ _ _).symm ≪≫
    isoOfQuasiIsoAt I.ι 0 ≪≫ I.cocomplex.isoHomologyπ₀.symm) ?_
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ ((singleObjHomologySelfIso (ComplexShape.up ℕ) 0 (kernelFork I).pt).symm ≪≫
          isoOfQuasiIsoAt I.ι 0 ≪≫ (isoHomologyπ₀ I.cocomplex).symm).hom ≫
      Fork.ι (KernelFork.ofι (iCycles I.cocomplex 0) (_ : iCycles I.cocomplex 0 ≫ d I.cocomplex 0 1 = 0)) =
    Fork.ι (kernelFork I)

Next tactic:
rw [← cancel_epi (singleObjHomologySelfIso (ComplexShape.up ℕ) _ _).hom,
    ← cancel_epi (isoHomologyπ₀ _).hom,
    ← cancel_epi (singleObjCyclesSelfIso (ComplexShape.up ℕ) _ _).inv]
/-- `Z` is the kernel of `I.cocomplex.X 0 ⟶ I.cocomplex.X 1` when `I : InjectiveResolution Z`. -/
def isLimitKernelFork : IsLimit (I.kernelFork) := by
  refine IsLimit.ofIsoLimit (I.cocomplex.cyclesIsKernel 0 1 (by simp)) (Iso.symm ?_)
  refine Fork.ext ((singleObjHomologySelfIso _ _ _).symm ≪≫
    isoOfQuasiIsoAt I.ι 0 ≪≫ I.cocomplex.isoHomologyπ₀.symm) ?_
  rw [← cancel_epi (singleObjHomologySelfIso (ComplexShape.up ℕ) _ _).hom,
    ← cancel_epi (isoHomologyπ₀ _).hom,
    ← cancel_epi (singleObjCyclesSelfIso (ComplexShape.up ℕ) _ _).inv]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ (singleObjCyclesSelfIso (ComplexShape.up ℕ) 0 (kernelFork I).pt).inv ≫
      (isoHomologyπ₀ ((single C (ComplexShape.up ℕ) 0).obj (kernelFork I).pt)).hom ≫
        (singleObjHomologySelfIso (ComplexShape.up ℕ) 0 (kernelFork I).pt).hom ≫
          ((singleObjHomologySelfIso (ComplexShape.up ℕ) 0 (kernelFork I).pt).symm ≪≫
                isoOfQuasiIsoAt I.ι 0 ≪≫ (isoHomologyπ₀ I.cocomplex).symm).hom ≫
            Fork.ι (KernelFork.ofι (iCycles I.cocomplex 0) (_ : iCycles I.cocomplex 0 ≫ d I.cocomplex 0 1 = 0)) =
    (singleObjCyclesSelfIso (ComplexShape.up ℕ) 0 (kernelFork I).pt).inv ≫
      (isoHomologyπ₀ ((single C (ComplexShape.up ℕ) 0).obj (kernelFork I).pt)).hom ≫
        (singleObjHomologySelfIso (ComplexShape.up ℕ) 0 (kernelFork I).pt).hom ≫ Fork.ι (kernelFork I)

Next tactic:
simp
instance (n : ℕ) : Mono (I.ι.f n) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n : ℕ
⊢ Mono (Hom.f I.ι n)

Next tactic:
cases n
instance (n : ℕ) : Mono (I.ι.f n) := by
  cases n
  · 

Proof state:
case zero
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
⊢ Mono (Hom.f I.ι Nat.zero)

Next tactic:
exact mono_of_isLimit_fork I.isLimitKernelFork
instance (n : ℕ) : Mono (I.ι.f n) := by
  cases n
  · exact mono_of_isLimit_fork I.isLimitKernelFork
  · 

Proof state:
case succ
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n✝ : ℕ
⊢ Mono (Hom.f I.ι (Nat.succ n✝))

Next tactic:
rw [ι_f_succ]
instance (n : ℕ) : Mono (I.ι.f n) := by
  cases n
  · exact mono_of_isLimit_fork I.isLimitKernelFork
  · rw [ι_f_succ]; 

Proof state:
case succ
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroObject C
inst✝ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
n✝ : ℕ
⊢ Mono 0

Next tactic:
infer_instance
/-- An injective object admits a trivial injective resolution: itself in degree 0. -/
@[simps]
def self [Injective Z] : InjectiveResolution Z where
  cocomplex := (CochainComplex.single₀ C).obj Z
  ι := 𝟙 ((CochainComplex.single₀ C).obj Z)
  injective n := by
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
inst✝ : Injective Z
n : ℕ
⊢ Injective (X ((single₀ C).obj Z) n)

Next tactic:
cases n
/-- An injective object admits a trivial injective resolution: itself in degree 0. -/
@[simps]
def self [Injective Z] : InjectiveResolution Z where
  cocomplex := (CochainComplex.single₀ C).obj Z
  ι := 𝟙 ((CochainComplex.single₀ C).obj Z)
  injective n := by
    cases n
    · 

Proof state:
case zero
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
inst✝ : Injective Z
⊢ Injective (X ((single₀ C).obj Z) Nat.zero)

Next tactic:
simpa
/-- An injective object admits a trivial injective resolution: itself in degree 0. -/
@[simps]
def self [Injective Z] : InjectiveResolution Z where
  cocomplex := (CochainComplex.single₀ C).obj Z
  ι := 𝟙 ((CochainComplex.single₀ C).obj Z)
  injective n := by
    cases n
    · simpa
    · 

Proof state:
case succ
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
inst✝ : Injective Z
n✝ : ℕ
⊢ Injective (X ((single₀ C).obj Z) (Nat.succ n✝))

Next tactic:
apply IsZero.injective
/-- An injective object admits a trivial injective resolution: itself in degree 0. -/
@[simps]
def self [Injective Z] : InjectiveResolution Z where
  cocomplex := (CochainComplex.single₀ C).obj Z
  ι := 𝟙 ((CochainComplex.single₀ C).obj Z)
  injective n := by
    cases n
    · simpa
    · apply IsZero.injective
      

Proof state:
case succ.h
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
inst✝ : Injective Z
n✝ : ℕ
⊢ IsZero (X ((single₀ C).obj Z) (Nat.succ n✝))

Next tactic:
apply HomologicalComplex.isZero_single_obj_X
/-- An injective object admits a trivial injective resolution: itself in degree 0. -/
@[simps]
def self [Injective Z] : InjectiveResolution Z where
  cocomplex := (CochainComplex.single₀ C).obj Z
  ι := 𝟙 ((CochainComplex.single₀ C).obj Z)
  injective n := by
    cases n
    · simpa
    · apply IsZero.injective
      apply HomologicalComplex.isZero_single_obj_X
      

Proof state:
case succ.h.hi
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : HasZeroObject C
inst✝¹ : HasZeroMorphisms C
Z : C
I : InjectiveResolution Z
inst✝ : Injective Z
n✝ : ℕ
⊢ Nat.succ n✝ ≠ 0

Next tactic:
simp
@[simp]
theorem sub_top {a : WithTop α} : a - ⊤ = 0 := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
a : WithTop α
⊢ a - ⊤ = 0

Next tactic:
cases a
@[simp]
theorem sub_top {a : WithTop α} : a - ⊤ = 0 := by cases a <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
⊢ none - ⊤ = 0

Next tactic:
rfl
@[simp]
theorem sub_top {a : WithTop α} : a - ⊤ = 0 := by cases a <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
val✝ : α
⊢ Option.some val✝ - ⊤ = 0

Next tactic:
rfl
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
a b : WithTop α
⊢ a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤

Next tactic:
induction a using recTopCoe
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  induction a using recTopCoe <;> 

Proof state:
case top
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
b : WithTop α
⊢ ⊤ - b = ⊤ ↔ ⊤ = ⊤ ∧ b ≠ ⊤

Next tactic:
induction b using recTopCoe
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  induction a using recTopCoe <;> 

Proof state:
case coe
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
b : WithTop α
a✝ : α
⊢ ↑a✝ - b = ⊤ ↔ ↑a✝ = ⊤ ∧ b ≠ ⊤

Next tactic:
induction b using recTopCoe
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  induction a using recTopCoe <;> induction b using recTopCoe <;>
    

Proof state:
case top.top
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
⊢ ⊤ - ⊤ = ⊤ ↔ ⊤ = ⊤ ∧ ⊤ ≠ ⊤

Next tactic:
simp only [← coe_sub, coe_ne_top, sub_top, zero_ne_top, top_sub_coe, false_and,
      Ne.def, not_true_eq_false, not_false_eq_true, and_false, and_self]
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  induction a using recTopCoe <;> induction b using recTopCoe <;>
    

Proof state:
case top.coe
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
a✝ : α
⊢ ⊤ - ↑a✝ = ⊤ ↔ ⊤ = ⊤ ∧ ↑a✝ ≠ ⊤

Next tactic:
simp only [← coe_sub, coe_ne_top, sub_top, zero_ne_top, top_sub_coe, false_and,
      Ne.def, not_true_eq_false, not_false_eq_true, and_false, and_self]
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  induction a using recTopCoe <;> induction b using recTopCoe <;>
    

Proof state:
case coe.top
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
a✝ : α
⊢ ↑a✝ - ⊤ = ⊤ ↔ ↑a✝ = ⊤ ∧ ⊤ ≠ ⊤

Next tactic:
simp only [← coe_sub, coe_ne_top, sub_top, zero_ne_top, top_sub_coe, false_and,
      Ne.def, not_true_eq_false, not_false_eq_true, and_false, and_self]
@[simp] theorem sub_eq_top_iff {a b : WithTop α} : a - b = ⊤ ↔ a = ⊤ ∧ b ≠ ⊤ := by
  induction a using recTopCoe <;> induction b using recTopCoe <;>
    

Proof state:
case coe.coe
α : Type u_1
β : Type u_2
inst✝¹ : Sub α
inst✝ : Zero α
a✝¹ a✝ : α
⊢ ↑a✝¹ - ↑a✝ = ⊤ ↔ ↑a✝¹ = ⊤ ∧ ↑a✝ ≠ ⊤

Next tactic:
simp only [← coe_sub, coe_ne_top, sub_top, zero_ne_top, top_sub_coe, false_and,
      Ne.def, not_true_eq_false, not_false_eq_true, and_false, and_self]
theorem map_sub [Sub β] [Zero β] {f : α → β} (h : ∀ x y, f (x - y) = f x - f y) (h₀ : f 0 = 0) :
    ∀ x y : WithTop α, (x - y).map f = x.map f - y.map f
  | _, ⊤ => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Sub α
inst✝² : Zero α
inst✝¹ : Sub β
inst✝ : Zero β
f : α → β
h : ∀ (x y : α), f (x - y) = f x - f y
h₀ : f 0 = 0
x✝ : WithTop α
⊢ map f (x✝ - ⊤) = map f x✝ - map f ⊤

Next tactic:
simp only [h₀, sub_top, WithTop.map_zero, coe_zero, map_top]
theorem map_sub [Sub β] [Zero β] {f : α → β} (h : ∀ x y, f (x - y) = f x - f y) (h₀ : f 0 = 0) :
    ∀ x y : WithTop α, (x - y).map f = x.map f - y.map f
  | _, ⊤ => by simp only [h₀, sub_top, WithTop.map_zero, coe_zero, map_top]
  | ⊤, (x : α) => rfl
  | (x : α), (y : α) => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝³ : Sub α
inst✝² : Zero α
inst✝¹ : Sub β
inst✝ : Zero β
f : α → β
h : ∀ (x y : α), f (x - y) = f x - f y
h₀ : f 0 = 0
x y : α
⊢ map f (↑x - ↑y) = map f ↑x - map f ↑y

Next tactic:
simp only [← coe_sub, map_coe, h]
instance : OrderedSub (WithTop α) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
⊢ OrderedSub (WithTop α)

Next tactic:
constructor
instance : OrderedSub (WithTop α) := by
  constructor
  

Proof state:
case tsub_le_iff_right
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
⊢ ∀ (a b c : WithTop α), a - b ≤ c ↔ a ≤ c + b

Next tactic:
rintro x y z
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  

Proof state:
case tsub_le_iff_right
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
x y z : WithTop α
⊢ x - y ≤ z ↔ x ≤ z + y

Next tactic:
induction y using WithTop.recTopCoe
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · 

Proof state:
case tsub_le_iff_right.top
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
x z : WithTop α
⊢ x - ⊤ ≤ z ↔ x ≤ z + ⊤

Next tactic:
simp
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · simp
  

Proof state:
case tsub_le_iff_right.coe
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
x z : WithTop α
a✝ : α
⊢ x - ↑a✝ ≤ z ↔ x ≤ z + ↑a✝

Next tactic:
induction x using WithTop.recTopCoe
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · simp
  induction x using WithTop.recTopCoe; · 

Proof state:
case tsub_le_iff_right.coe.top
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
z : WithTop α
a✝ : α
⊢ ⊤ - ↑a✝ ≤ z ↔ ⊤ ≤ z + ↑a✝

Next tactic:
simp
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · simp
  induction x using WithTop.recTopCoe; · simp
  

Proof state:
case tsub_le_iff_right.coe.coe
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
z : WithTop α
a✝¹ a✝ : α
⊢ ↑a✝ - ↑a✝¹ ≤ z ↔ ↑a✝ ≤ z + ↑a✝¹

Next tactic:
induction z using WithTop.recTopCoe
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · simp
  induction x using WithTop.recTopCoe; · simp
  induction z using WithTop.recTopCoe; · 

Proof state:
case tsub_le_iff_right.coe.coe.top
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
a✝¹ a✝ : α
⊢ ↑a✝ - ↑a✝¹ ≤ ⊤ ↔ ↑a✝ ≤ ⊤ + ↑a✝¹

Next tactic:
simp
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · simp
  induction x using WithTop.recTopCoe; · simp
  induction z using WithTop.recTopCoe; · simp
  

Proof state:
case tsub_le_iff_right.coe.coe.coe
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
a✝² a✝¹ a✝ : α
⊢ ↑a✝¹ - ↑a✝² ≤ ↑a✝ ↔ ↑a✝¹ ≤ ↑a✝ + ↑a✝²

Next tactic:
norm_cast
instance : OrderedSub (WithTop α) := by
  constructor
  rintro x y z
  induction y using WithTop.recTopCoe; · simp
  induction x using WithTop.recTopCoe; · simp
  induction z using WithTop.recTopCoe; · simp
  norm_cast; 

Proof state:
case tsub_le_iff_right.coe.coe.coe
α : Type u_1
β : Type u_2
inst✝² : CanonicallyOrderedAddCommMonoid α
inst✝¹ : Sub α
inst✝ : OrderedSub α
a✝² a✝¹ a✝ : α
⊢ a✝¹ - a✝² ≤ a✝ ↔ a✝¹ ≤ a✝ + a✝²

Next tactic:
exact tsub_le_iff_right
theorem isConformalMap_id : IsConformalMap (id R M) :=
  ⟨1, one_ne_zero, id, by 

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
G : Type u_4
M' : Type u_5
inst✝⁸ : NormedField R
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
inst✝⁵ : SeminormedAddCommGroup G
inst✝⁴ : NormedSpace R M
inst✝³ : NormedSpace R N
inst✝² : NormedSpace R G
inst✝¹ : NormedAddCommGroup M'
inst✝ : NormedSpace R M'
f : M →L[R] N
g : N →L[R] G
c : R
⊢ ContinuousLinearMap.id R M = 1 • toContinuousLinearMap LinearIsometry.id

Next tactic:
simp
theorem IsConformalMap.smul (hf : IsConformalMap f) {c : R} (hc : c ≠ 0) :
    IsConformalMap (c • f) := by
  

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
G : Type u_4
M' : Type u_5
inst✝⁸ : NormedField R
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
inst✝⁵ : SeminormedAddCommGroup G
inst✝⁴ : NormedSpace R M
inst✝³ : NormedSpace R N
inst✝² : NormedSpace R G
inst✝¹ : NormedAddCommGroup M'
inst✝ : NormedSpace R M'
f : M →L[R] N
g : N →L[R] G
c✝ : R
hf : IsConformalMap f
c : R
hc : c ≠ 0
⊢ IsConformalMap (c • f)

Next tactic:
rcases hf with ⟨c', hc', li, rfl⟩
theorem IsConformalMap.smul (hf : IsConformalMap f) {c : R} (hc : c ≠ 0) :
    IsConformalMap (c • f) := by
  rcases hf with ⟨c', hc', li, rfl⟩
  

Proof state:
case intro.intro.intro
R : Type u_1
M : Type u_2
N : Type u_3
G : Type u_4
M' : Type u_5
inst✝⁸ : NormedField R
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
inst✝⁵ : SeminormedAddCommGroup G
inst✝⁴ : NormedSpace R M
inst✝³ : NormedSpace R N
inst✝² : NormedSpace R G
inst✝¹ : NormedAddCommGroup M'
inst✝ : NormedSpace R M'
g : N →L[R] G
c✝ c : R
hc : c ≠ 0
c' : R
hc' : c' ≠ 0
li : M →ₗᵢ[R] N
⊢ IsConformalMap (c • c' • toContinuousLinearMap li)

Next tactic:
exact ⟨c * c', mul_ne_zero hc hc', li, smul_smul _ _ _⟩
@[nontriviality]
theorem isConformalMap_of_subsingleton [Subsingleton M] (f' : M →L[R] N) : IsConformalMap f' :=
  ⟨1, one_ne_zero, ⟨0, fun x => by 

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
G : Type u_4
M' : Type u_5
inst✝⁹ : NormedField R
inst✝⁸ : SeminormedAddCommGroup M
inst✝⁷ : SeminormedAddCommGroup N
inst✝⁶ : SeminormedAddCommGroup G
inst✝⁵ : NormedSpace R M
inst✝⁴ : NormedSpace R N
inst✝³ : NormedSpace R G
inst✝² : NormedAddCommGroup M'
inst✝¹ : NormedSpace R M'
f : M →L[R] N
g : N →L[R] G
c : R
inst✝ : Subsingleton M
f' : M →L[R] N
x : M
⊢ ‖0 x‖ = ‖x‖

Next tactic:
simp [Subsingleton.elim x 0]
theorem comp (hg : IsConformalMap g) (hf : IsConformalMap f) : IsConformalMap (g.comp f) := by
  

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
G : Type u_4
M' : Type u_5
inst✝⁸ : NormedField R
inst✝⁷ : SeminormedAddCommGroup M
inst✝⁶ : SeminormedAddCommGroup N
inst✝⁵ : SeminormedAddCommGroup G
inst✝⁴ : NormedSpace R M
inst✝³ : NormedSpace R N
inst✝² : NormedSpace R G
inst✝¹ : NormedAddCommGroup M'
inst✝ : NormedSpace R M'
f : M →L[R] N
g : N →L[R] G
c : R
hg : IsConformalMap g
hf : IsConformalMap f
⊢ IsConformalMap (ContinuousLinearMap.comp g f)

Next tactic:
rcases hf with ⟨cf, hcf, lif, rfl⟩