l3lab/ntp-mathlib huggingface dataset:
/-- Turning an object into a complex supported at `j` then applying a functor is
the same as applying the functor then forming the complex.
-/
noncomputable def singleMapHomologicalComplex (F : V ⥤ W) [F.Additive] (c : ComplexShape ι)
    [DecidableEq ι] (j : ι) :
    single V c j ⋙ F.mapHomologicalComplex _ ≅ F ⋙ single W c j :=
  NatIso.ofComponents
    (fun X =>
      { hom := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        inv := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        hom_inv_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · rw [zero_comp, ← F.map_id,
              (isZero_single_obj_X c j X _ h).eq_of_src (𝟙 _) 0, F.map_zero]
        inv_hom_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · apply (isZero_single_obj_X c j _ _ h).eq_of_src })
    fun f => by
      

Proof state:
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c✝ : ComplexShape ι
C D E : HomologicalComplex V c✝
f✝ g : C ⟶ D
h k : D ⟶ E
i : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{?u.124701, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
c : ComplexShape ι
inst✝ : DecidableEq ι
j : ι
X✝ Y✝ : V
f : X✝ ⟶ Y✝
⊢ (single V c j ⋙ Functor.mapHomologicalComplex F c).map f ≫
      ((fun X =>
            Iso.mk
              (Hom.mk fun i =>
                if h : i = j then
                  eqToHom
                    (_ :
                      HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i =
                        HomologicalComplex.X ((single W c j).obj (F.obj X)) i)
                else 0)
              (Hom.mk fun i =>
                if h : i = j then
                  eqToHom
                    (_ :
                      HomologicalComplex.X ((single W c j).obj (F.obj X)) i =
                        HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i)
                else 0))
          Y✝).hom =
    ((fun X =>
            Iso.mk
              (Hom.mk fun i =>
                if h : i = j then
                  eqToHom
                    (_ :
                      HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i =
                        HomologicalComplex.X ((single W c j).obj (F.obj X)) i)
                else 0)
              (Hom.mk fun i =>
                if h : i = j then
                  eqToHom
                    (_ :
                      HomologicalComplex.X ((single W c j).obj (F.obj X)) i =
                        HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i)
                else 0))
          X✝).hom ≫
      (F ⋙ single W c j).map f

Next tactic:
ext i
/-- Turning an object into a complex supported at `j` then applying a functor is
the same as applying the functor then forming the complex.
-/
noncomputable def singleMapHomologicalComplex (F : V ⥤ W) [F.Additive] (c : ComplexShape ι)
    [DecidableEq ι] (j : ι) :
    single V c j ⋙ F.mapHomologicalComplex _ ≅ F ⋙ single W c j :=
  NatIso.ofComponents
    (fun X =>
      { hom := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        inv := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        hom_inv_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · rw [zero_comp, ← F.map_id,
              (isZero_single_obj_X c j X _ h).eq_of_src (𝟙 _) 0, F.map_zero]
        inv_hom_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · apply (isZero_single_obj_X c j _ _ h).eq_of_src })
    fun f => by
      ext i
      

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c✝ : ComplexShape ι
C D E : HomologicalComplex V c✝
f✝ g : C ⟶ D
h k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{?u.124701, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
c : ComplexShape ι
inst✝ : DecidableEq ι
j : ι
X✝ Y✝ : V
f : X✝ ⟶ Y✝
i : ι
⊢ Hom.f
      ((single V c j ⋙ Functor.mapHomologicalComplex F c).map f ≫
        ((fun X =>
              Iso.mk
                (Hom.mk fun i =>
                  if h : i = j then
                    eqToHom
                      (_ :
                        HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i =
                          HomologicalComplex.X ((single W c j).obj (F.obj X)) i)
                  else 0)
                (Hom.mk fun i =>
                  if h : i = j then
                    eqToHom
                      (_ :
                        HomologicalComplex.X ((single W c j).obj (F.obj X)) i =
                          HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i)
                  else 0))
            Y✝).hom)
      i =
    Hom.f
      (((fun X =>
              Iso.mk
                (Hom.mk fun i =>
                  if h : i = j then
                    eqToHom
                      (_ :
                        HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i =
                          HomologicalComplex.X ((single W c j).obj (F.obj X)) i)
                  else 0)
                (Hom.mk fun i =>
                  if h : i = j then
                    eqToHom
                      (_ :
                        HomologicalComplex.X ((single W c j).obj (F.obj X)) i =
                          HomologicalComplex.X ((Functor.mapHomologicalComplex F c).obj ((single V c j).obj X)) i)
                  else 0))
            X✝).hom ≫
        (F ⋙ single W c j).map f)
      i

Next tactic:
dsimp
/-- Turning an object into a complex supported at `j` then applying a functor is
the same as applying the functor then forming the complex.
-/
noncomputable def singleMapHomologicalComplex (F : V ⥤ W) [F.Additive] (c : ComplexShape ι)
    [DecidableEq ι] (j : ι) :
    single V c j ⋙ F.mapHomologicalComplex _ ≅ F ⋙ single W c j :=
  NatIso.ofComponents
    (fun X =>
      { hom := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        inv := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        hom_inv_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · rw [zero_comp, ← F.map_id,
              (isZero_single_obj_X c j X _ h).eq_of_src (𝟙 _) 0, F.map_zero]
        inv_hom_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · apply (isZero_single_obj_X c j _ _ h).eq_of_src })
    fun f => by
      ext i
      dsimp
      

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c✝ : ComplexShape ι
C D E : HomologicalComplex V c✝
f✝ g : C ⟶ D
h k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{?u.124701, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
c : ComplexShape ι
inst✝ : DecidableEq ι
j : ι
X✝ Y✝ : V
f : X✝ ⟶ Y✝
i : ι
⊢ (F.map (Hom.f ((single V c j).map f) i) ≫
      if h : i = j then eqToHom (_ : F.obj (X ((single V c j).obj Y✝) i) = X ((single W c j).obj (F.obj Y✝)) i)
      else 0) =
    (if h : i = j then eqToHom (_ : F.obj (X ((single V c j).obj X✝) i) = X ((single W c j).obj (F.obj X✝)) i) else 0) ≫
      Hom.f ((single W c j).map (F.map f)) i

Next tactic:
split_ifs with h
/-- Turning an object into a complex supported at `j` then applying a functor is
the same as applying the functor then forming the complex.
-/
noncomputable def singleMapHomologicalComplex (F : V ⥤ W) [F.Additive] (c : ComplexShape ι)
    [DecidableEq ι] (j : ι) :
    single V c j ⋙ F.mapHomologicalComplex _ ≅ F ⋙ single W c j :=
  NatIso.ofComponents
    (fun X =>
      { hom := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        inv := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        hom_inv_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · rw [zero_comp, ← F.map_id,
              (isZero_single_obj_X c j X _ h).eq_of_src (𝟙 _) 0, F.map_zero]
        inv_hom_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · apply (isZero_single_obj_X c j _ _ h).eq_of_src })
    fun f => by
      ext i
      dsimp
      split_ifs with h
      · 

Proof state:
case pos
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c✝ : ComplexShape ι
C D E : HomologicalComplex V c✝
f✝ g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{?u.124701, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
c : ComplexShape ι
inst✝ : DecidableEq ι
j : ι
X✝ Y✝ : V
f : X✝ ⟶ Y✝
i : ι
h : i = j
⊢ F.map (Hom.f ((single V c j).map f) i) ≫
      eqToHom (_ : F.obj (X ((single V c j).obj Y✝) i) = X ((single W c j).obj (F.obj Y✝)) i) =
    eqToHom (_ : F.obj (X ((single V c j).obj X✝) i) = X ((single W c j).obj (F.obj X✝)) i) ≫
      Hom.f ((single W c j).map (F.map f)) i

Next tactic:
subst h
/-- Turning an object into a complex supported at `j` then applying a functor is
the same as applying the functor then forming the complex.
-/
noncomputable def singleMapHomologicalComplex (F : V ⥤ W) [F.Additive] (c : ComplexShape ι)
    [DecidableEq ι] (j : ι) :
    single V c j ⋙ F.mapHomologicalComplex _ ≅ F ⋙ single W c j :=
  NatIso.ofComponents
    (fun X =>
      { hom := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        inv := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        hom_inv_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · rw [zero_comp, ← F.map_id,
              (isZero_single_obj_X c j X _ h).eq_of_src (𝟙 _) 0, F.map_zero]
        inv_hom_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · apply (isZero_single_obj_X c j _ _ h).eq_of_src })
    fun f => by
      ext i
      dsimp
      split_ifs with h
      · subst h
        

Proof state:
case pos
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c✝ : ComplexShape ι
C D E : HomologicalComplex V c✝
f✝ g : C ⟶ D
h k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{?u.124701, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
c : ComplexShape ι
inst✝ : DecidableEq ι
X✝ Y✝ : V
f : X✝ ⟶ Y✝
i : ι
⊢ F.map (Hom.f ((single V c i).map f) i) ≫
      eqToHom (_ : F.obj (X ((single V c i).obj Y✝) i) = X ((single W c i).obj (F.obj Y✝)) i) =
    eqToHom (_ : F.obj (X ((single V c i).obj X✝) i) = X ((single W c i).obj (F.obj X✝)) i) ≫
      Hom.f ((single W c i).map (F.map f)) i

Next tactic:
simp [single_map_f_self, singleObjXSelf, singleObjXIsoOfEq, eqToHom_map]
/-- Turning an object into a complex supported at `j` then applying a functor is
the same as applying the functor then forming the complex.
-/
noncomputable def singleMapHomologicalComplex (F : V ⥤ W) [F.Additive] (c : ComplexShape ι)
    [DecidableEq ι] (j : ι) :
    single V c j ⋙ F.mapHomologicalComplex _ ≅ F ⋙ single W c j :=
  NatIso.ofComponents
    (fun X =>
      { hom := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        inv := { f := fun i => if h : i = j then eqToHom (by simp [h]) else 0 }
        hom_inv_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · rw [zero_comp, ← F.map_id,
              (isZero_single_obj_X c j X _ h).eq_of_src (𝟙 _) 0, F.map_zero]
        inv_hom_id := by
          ext i
          dsimp
          split_ifs with h
          · simp [h]
          · apply (isZero_single_obj_X c j _ _ h).eq_of_src })
    fun f => by
      ext i
      dsimp
      split_ifs with h
      · subst h
        simp [single_map_f_self, singleObjXSelf, singleObjXIsoOfEq, eqToHom_map]
      · 

Proof state:
case neg
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c✝ : ComplexShape ι
C D E : HomologicalComplex V c✝
f✝ g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{?u.124701, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
c : ComplexShape ι
inst✝ : DecidableEq ι
j : ι
X✝ Y✝ : V
f : X✝ ⟶ Y✝
i : ι
h : ¬i = j
⊢ F.map (Hom.f ((single V c j).map f) i) ≫ 0 = 0 ≫ Hom.f ((single W c j).map (F.map f)) i

Next tactic:
apply (isZero_single_obj_X c j _ _ h).eq_of_tgt
@[simp]
theorem singleMapHomologicalComplex_hom_app_self (j : ι) (X : V) :
    ((singleMapHomologicalComplex F c j).hom.app X).f j =
      F.map (singleObjXSelf c j X).hom ≫ (singleObjXSelf c j (F.obj X)).inv := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{u_3, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
inst✝ : DecidableEq ι
j : ι
X : V
⊢ Hom.f ((singleMapHomologicalComplex F c j).hom.app X) j =
    F.map (singleObjXSelf c j X).hom ≫ (singleObjXSelf c j (F.obj X)).inv

Next tactic:
simp [singleMapHomologicalComplex, singleObjXSelf, singleObjXIsoOfEq, eqToHom_map]
@[simp]
theorem singleMapHomologicalComplex_hom_app_ne {i j : ι} (h : i ≠ j) (X : V) :
    ((singleMapHomologicalComplex F c j).hom.app X).f i = 0 := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{u_3, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
inst✝ : DecidableEq ι
i j : ι
h : i ≠ j
X : V
⊢ Hom.f ((singleMapHomologicalComplex F c j).hom.app X) i = 0

Next tactic:
simp [singleMapHomologicalComplex, h]
@[simp]
theorem singleMapHomologicalComplex_inv_app_self (j : ι) (X : V) :
    ((singleMapHomologicalComplex F c j).inv.app X).f j =
      (singleObjXSelf c j (F.obj X)).hom ≫ F.map (singleObjXSelf c j X).inv := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{u_3, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
inst✝ : DecidableEq ι
j : ι
X : V
⊢ Hom.f ((singleMapHomologicalComplex F c j).inv.app X) j =
    (singleObjXSelf c j (F.obj X)).hom ≫ F.map (singleObjXSelf c j X).inv

Next tactic:
simp [singleMapHomologicalComplex, singleObjXSelf, singleObjXIsoOfEq, eqToHom_map]
@[simp]
theorem singleMapHomologicalComplex_inv_app_ne {i j : ι} (h : i ≠ j) (X : V) :
    ((singleMapHomologicalComplex F c j).inv.app X).f i = 0 := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝⁵ : HasZeroObject V
W : Type u_2
inst✝⁴ : Category.{u_3, u_2} W
inst✝³ : Preadditive W
inst✝² : HasZeroObject W
F : V ⥤ W
inst✝¹ : Functor.Additive F
inst✝ : DecidableEq ι
i j : ι
h : i ≠ j
X : V
⊢ Hom.f ((singleMapHomologicalComplex F c j).inv.app X) i = 0

Next tactic:
simp [singleMapHomologicalComplex, h]
theorem numLeaves_eq_numNodes_succ (x : Tree α) : x.numLeaves = x.numNodes + 1 := by
  

Proof state:
α : Type u
x : Tree α
⊢ numLeaves x = numNodes x + 1

Next tactic:
induction x
theorem numLeaves_eq_numNodes_succ (x : Tree α) : x.numLeaves = x.numNodes + 1 := by
  induction x <;> 

Proof state:
case nil
α : Type u
⊢ numLeaves nil = numNodes nil + 1

Next tactic:
simp [*, Nat.add_comm, Nat.add_assoc, Nat.add_left_comm]
theorem numLeaves_eq_numNodes_succ (x : Tree α) : x.numLeaves = x.numNodes + 1 := by
  induction x <;> 

Proof state:
case node
α : Type u
a✝² : α
a✝¹ a✝ : Tree α
a_ih✝¹ : numLeaves a✝¹ = numNodes a✝¹ + 1
a_ih✝ : numLeaves a✝ = numNodes a✝ + 1
⊢ numLeaves (node a✝² a✝¹ a✝) = numNodes (node a✝² a✝¹ a✝) + 1

Next tactic:
simp [*, Nat.add_comm, Nat.add_assoc, Nat.add_left_comm]
theorem numLeaves_pos (x : Tree α) : 0 < x.numLeaves := by
  

Proof state:
α : Type u
x : Tree α
⊢ 0 < numLeaves x

Next tactic:
rw [numLeaves_eq_numNodes_succ]
theorem numLeaves_pos (x : Tree α) : 0 < x.numLeaves := by
  rw [numLeaves_eq_numNodes_succ]
  

Proof state:
α : Type u
x : Tree α
⊢ 0 < numNodes x + 1

Next tactic:
exact x.numNodes.zero_lt_succ
theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left △ x.right = x
  | nil, h => by 

Proof state:
α : Type u
h : nil ≠ nil
⊢ node () (left nil) (right nil) = nil

Next tactic:
trivial
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
⊢ Continuous fun p => p.1 * p.2

Next tactic:
let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
  

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
m : α →+ α →+ Completion α := AddMonoidHom.compr₂ AddMonoidHom.mul toCompl
⊢ Continuous fun p => p.1 * p.2

Next tactic:
have : Continuous fun p : α × α => m p.1 p.2 := by
    apply (continuous_coe α).comp _
    simp only [AddMonoidHom.coe_mul, AddMonoidHom.coe_mulLeft]
    exact _root_.continuous_mul
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
  have : Continuous fun p : α × α => m p.1 p.2 := by
    

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
m : α →+ α →+ Completion α := AddMonoidHom.compr₂ AddMonoidHom.mul toCompl
⊢ Continuous fun p => (m p.1) p.2

Next tactic:
apply (continuous_coe α).comp _
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
  have : Continuous fun p : α × α => m p.1 p.2 := by
    apply (continuous_coe α).comp _
    

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
m : α →+ α →+ Completion α := AddMonoidHom.compr₂ AddMonoidHom.mul toCompl
⊢ Continuous fun p => (AddMonoidHom.mul p.1) p.2

Next tactic:
simp only [AddMonoidHom.coe_mul, AddMonoidHom.coe_mulLeft]
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
  have : Continuous fun p : α × α => m p.1 p.2 := by
    apply (continuous_coe α).comp _
    simp only [AddMonoidHom.coe_mul, AddMonoidHom.coe_mulLeft]
    

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
m : α →+ α →+ Completion α := AddMonoidHom.compr₂ AddMonoidHom.mul toCompl
⊢ Continuous fun p => p.1 * p.2

Next tactic:
exact _root_.continuous_mul
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
  have : Continuous fun p : α × α => m p.1 p.2 := by
    apply (continuous_coe α).comp _
    simp only [AddMonoidHom.coe_mul, AddMonoidHom.coe_mulLeft]
    exact _root_.continuous_mul
  

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
m : α →+ α →+ Completion α := AddMonoidHom.compr₂ AddMonoidHom.mul toCompl
this : Continuous fun p => (m p.1) p.2
⊢ Continuous fun p => p.1 * p.2

Next tactic:
have di : DenseInducing (toCompl : α → Completion α) := denseInducing_coe
theorem continuous_mul : Continuous fun p : Completion α × Completion α => p.1 * p.2 := by
  let m := (AddMonoidHom.mul : α →+ α →+ α).compr₂ toCompl
  have : Continuous fun p : α × α => m p.1 p.2 := by
    apply (continuous_coe α).comp _
    simp only [AddMonoidHom.coe_mul, AddMonoidHom.coe_mulLeft]
    exact _root_.continuous_mul
  have di : DenseInducing (toCompl : α → Completion α) := denseInducing_coe
  

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
m : α →+ α →+ Completion α := AddMonoidHom.compr₂ AddMonoidHom.mul toCompl
this : Continuous fun p => (m p.1) p.2
di : DenseInducing ⇑toCompl
⊢ Continuous fun p => p.1 * p.2

Next tactic:
convert di.extend_Z_bilin di this
instance ring : Ring (Completion α) :=
  { AddMonoidWithOne.unary, (inferInstanceAs (AddCommGroup (Completion α))),
      (inferInstanceAs (Mul (Completion α))), (inferInstanceAs (One (Completion α))) with
    zero_mul := fun a =>
      Completion.induction_on a
        (isClosed_eq (Continuous.mul continuous_const continuous_id) continuous_const)
        fun a => by rw [← coe_zero, ← coe_mul, zero_mul]
    mul_zero := fun a =>
      Completion.induction_on a
        (isClosed_eq (Continuous.mul continuous_id continuous_const) continuous_const)
        fun a => by rw [← coe_zero, ← coe_mul, mul_zero]
    one_mul := fun a =>
      Completion.induction_on a
        (isClosed_eq (Continuous.mul continuous_const continuous_id) continuous_id) fun a => by
        rw [← coe_one, ← coe_mul, one_mul]
    mul_one := fun a =>
      Completion.induction_on a
        (isClosed_eq (Continuous.mul continuous_id continuous_const) continuous_id) fun a => by
        rw [← coe_one, ← coe_mul, mul_one]
    mul_assoc := fun a b c =>
      Completion.induction_on₃ a b c
        (isClosed_eq
          (Continuous.mul (Continuous.mul continuous_fst (continuous_fst.comp continuous_snd))
            (continuous_snd.comp continuous_snd))
          (Continuous.mul continuous_fst
            (Continuous.mul (continuous_fst.comp continuous_snd)
              (continuous_snd.comp continuous_snd))))
                fun a b c => by rw [← coe_mul, ← coe_mul, ← coe_mul, ← coe_mul, mul_assoc]
    left_distrib := fun a b c =>
      Completion.induction_on₃ a b c
        (isClosed_eq
          (Continuous.mul continuous_fst
            (Continuous.add (continuous_fst.comp continuous_snd)
              (continuous_snd.comp continuous_snd)))
          (Continuous.add (Continuous.mul continuous_fst (continuous_fst.comp continuous_snd))
            (Continuous.mul continuous_fst (continuous_snd.comp continuous_snd))))
        fun a b c => by 

Proof state:
α : Type u_1
inst✝³ : Ring α
inst✝² : UniformSpace α
inst✝¹ : TopologicalRing α
inst✝ : UniformAddGroup α
src✝³ : AddMonoidWithOne (Completion α) := AddMonoidWithOne.unary
src✝² : AddCommGroup (Completion α) := inferInstanceAs (AddCommGroup (Completion α))
src✝¹ : Mul (Completion α) := inferInstanceAs (Mul (Completion α))
src✝ : One (Completion α) := inferInstanceAs (One (Completion α))
a✝ b✝ c✝ : Completion α
a b c : α
⊢ ↑α a * (↑α b + ↑α c) = ↑α a * ↑α b + ↑α a * ↑α c

Next tactic:
rw [← coe_add, ← coe_mul, ← coe_mul, ← coe_mul, ← coe_add, mul_add]