l3lab/ntp-mathlib huggingface dataset:
theorem IsLocallySurjective.comp {F₁ F₂ F₃ : Cᵒᵖ ⥤ A} {f₁ : F₁ ⟶ F₂} {f₂ : F₂ ⟶ F₃}
    (h₁ : IsLocallySurjective J f₁) (h₂ : IsLocallySurjective J f₂) :
    IsLocallySurjective J (f₁ ≫ f₂) := by
  intro U s
  have : (Sieve.bind (imageSieve f₂ s) fun _ _ h => imageSieve f₁ h.choose) ≤
      imageSieve (f₁ ≫ f₂) s := by
    rintro V i ⟨W, i, j, H, ⟨t', ht'⟩, rfl⟩
    refine' ⟨t', _⟩
    rw [op_comp, F₃.map_comp, NatTrans.comp_app, comp_apply, comp_apply, ht',
      elementwise_of% f₂.naturality, H.choose_spec]
  apply J.superset_covering this
  apply J.bind_covering
  · apply h₂
  · 

Proof state:
case hR
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
h₁ : IsLocallySurjective J f₁
h₂ : IsLocallySurjective J f₂
U : C
s : (forget A).obj (F₃.obj (op U))
this : (Sieve.bind (imageSieve f₂ s).arrows fun x x_1 h => imageSieve f₁ (Exists.choose h)) ≤ imageSieve (f₁ ≫ f₂) s
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ U⦄ (H : (imageSieve f₂ s).arrows f), imageSieve f₁ (Exists.choose H) ∈ sieves J Y

Next tactic:
intros
theorem IsLocallySurjective.comp {F₁ F₂ F₃ : Cᵒᵖ ⥤ A} {f₁ : F₁ ⟶ F₂} {f₂ : F₂ ⟶ F₃}
    (h₁ : IsLocallySurjective J f₁) (h₂ : IsLocallySurjective J f₂) :
    IsLocallySurjective J (f₁ ≫ f₂) := by
  intro U s
  have : (Sieve.bind (imageSieve f₂ s) fun _ _ h => imageSieve f₁ h.choose) ≤
      imageSieve (f₁ ≫ f₂) s := by
    rintro V i ⟨W, i, j, H, ⟨t', ht'⟩, rfl⟩
    refine' ⟨t', _⟩
    rw [op_comp, F₃.map_comp, NatTrans.comp_app, comp_apply, comp_apply, ht',
      elementwise_of% f₂.naturality, H.choose_spec]
  apply J.superset_covering this
  apply J.bind_covering
  · apply h₂
  · intros; 

Proof state:
case hR
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
h₁ : IsLocallySurjective J f₁
h₂ : IsLocallySurjective J f₂
U : C
s : (forget A).obj (F₃.obj (op U))
this : (Sieve.bind (imageSieve f₂ s).arrows fun x x_1 h => imageSieve f₁ (Exists.choose h)) ≤ imageSieve (f₁ ≫ f₂) s
Y✝ : C
f✝ : Y✝ ⟶ U
H✝ : (imageSieve f₂ s).arrows f✝
⊢ imageSieve f₁ (Exists.choose H✝) ∈ sieves J Y✝

Next tactic:
apply h₁
/-- The image of `F` in `J.sheafify F` is isomorphic to the sheafification. -/
noncomputable def sheafificationIsoImagePresheaf :
    J.sheafify F ≅ ((imagePresheaf (J.toSheafify F)).sheafify J).toPresheaf where
  hom :=
    J.sheafifyLift (toImagePresheafSheafify J _)
      ((isSheaf_iff_isSheaf_of_type J _).mpr <|
        Subpresheaf.sheafify_isSheaf _ <|
          (isSheaf_iff_isSheaf_of_type J _).mp <| sheafify_isSheaf J _)
  inv := Subpresheaf.ι _
  hom_inv_id :=
    J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F : Cᵒᵖ ⥤ Type (max u v)
⊢ toSheafify J F ≫
      sheafifyLift J (toImagePresheafSheafify J (toSheafify J F))
          (_ : Presheaf.IsSheaf J (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))) ≫
        Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) =
    toSheafify J F ≫ 𝟙 (sheafify J F)

Next tactic:
simp [toImagePresheafSheafify]
/-- The image of `F` in `J.sheafify F` is isomorphic to the sheafification. -/
noncomputable def sheafificationIsoImagePresheaf :
    J.sheafify F ≅ ((imagePresheaf (J.toSheafify F)).sheafify J).toPresheaf where
  hom :=
    J.sheafifyLift (toImagePresheafSheafify J _)
      ((isSheaf_iff_isSheaf_of_type J _).mpr <|
        Subpresheaf.sheafify_isSheaf _ <|
          (isSheaf_iff_isSheaf_of_type J _).mp <| sheafify_isSheaf J _)
  inv := Subpresheaf.ι _
  hom_inv_id :=
    J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by simp [toImagePresheafSheafify])
  inv_hom_id := by
    

Proof state:
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F : Cᵒᵖ ⥤ Type (max u v)
⊢ Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) ≫
      sheafifyLift J (toImagePresheafSheafify J (toSheafify J F))
        (_ : Presheaf.IsSheaf J (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))) =
    𝟙 (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))

Next tactic:
rw [← cancel_mono (Subpresheaf.ι _), Category.id_comp, Category.assoc]
/-- The image of `F` in `J.sheafify F` is isomorphic to the sheafification. -/
noncomputable def sheafificationIsoImagePresheaf :
    J.sheafify F ≅ ((imagePresheaf (J.toSheafify F)).sheafify J).toPresheaf where
  hom :=
    J.sheafifyLift (toImagePresheafSheafify J _)
      ((isSheaf_iff_isSheaf_of_type J _).mpr <|
        Subpresheaf.sheafify_isSheaf _ <|
          (isSheaf_iff_isSheaf_of_type J _).mp <| sheafify_isSheaf J _)
  inv := Subpresheaf.ι _
  hom_inv_id :=
    J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by simp [toImagePresheafSheafify])
  inv_hom_id := by
    rw [← cancel_mono (Subpresheaf.ι _), Category.id_comp, Category.assoc]
    

Proof state:
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F : Cᵒᵖ ⥤ Type (max u v)
⊢ Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) ≫
      sheafifyLift J (toImagePresheafSheafify J (toSheafify J F))
          (_ : Presheaf.IsSheaf J (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))) ≫
        Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) =
    Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F)))

Next tactic:
refine' Eq.trans _ (Category.comp_id _)
/-- The image of `F` in `J.sheafify F` is isomorphic to the sheafification. -/
noncomputable def sheafificationIsoImagePresheaf :
    J.sheafify F ≅ ((imagePresheaf (J.toSheafify F)).sheafify J).toPresheaf where
  hom :=
    J.sheafifyLift (toImagePresheafSheafify J _)
      ((isSheaf_iff_isSheaf_of_type J _).mpr <|
        Subpresheaf.sheafify_isSheaf _ <|
          (isSheaf_iff_isSheaf_of_type J _).mp <| sheafify_isSheaf J _)
  inv := Subpresheaf.ι _
  hom_inv_id :=
    J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by simp [toImagePresheafSheafify])
  inv_hom_id := by
    rw [← cancel_mono (Subpresheaf.ι _), Category.id_comp, Category.assoc]
    refine' Eq.trans _ (Category.comp_id _)
    

Proof state:
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F : Cᵒᵖ ⥤ Type (max u v)
⊢ Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) ≫
      sheafifyLift J (toImagePresheafSheafify J (toSheafify J F))
          (_ : Presheaf.IsSheaf J (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))) ≫
        Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) =
    Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) ≫ 𝟙 (sheafify J F)

Next tactic:
congr 1
/-- The image of `F` in `J.sheafify F` is isomorphic to the sheafification. -/
noncomputable def sheafificationIsoImagePresheaf :
    J.sheafify F ≅ ((imagePresheaf (J.toSheafify F)).sheafify J).toPresheaf where
  hom :=
    J.sheafifyLift (toImagePresheafSheafify J _)
      ((isSheaf_iff_isSheaf_of_type J _).mpr <|
        Subpresheaf.sheafify_isSheaf _ <|
          (isSheaf_iff_isSheaf_of_type J _).mp <| sheafify_isSheaf J _)
  inv := Subpresheaf.ι _
  hom_inv_id :=
    J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by simp [toImagePresheafSheafify])
  inv_hom_id := by
    rw [← cancel_mono (Subpresheaf.ι _), Category.id_comp, Category.assoc]
    refine' Eq.trans _ (Category.comp_id _)
    congr 1
    

Proof state:
case e_a
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F : Cᵒᵖ ⥤ Type (max u v)
⊢ sheafifyLift J (toImagePresheafSheafify J (toSheafify J F))
        (_ : Presheaf.IsSheaf J (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))) ≫
      Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) =
    𝟙 (sheafify J F)

Next tactic:
exact J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by simp [toImagePresheafSheafify])
/-- The image of `F` in `J.sheafify F` is isomorphic to the sheafification. -/
noncomputable def sheafificationIsoImagePresheaf :
    J.sheafify F ≅ ((imagePresheaf (J.toSheafify F)).sheafify J).toPresheaf where
  hom :=
    J.sheafifyLift (toImagePresheafSheafify J _)
      ((isSheaf_iff_isSheaf_of_type J _).mpr <|
        Subpresheaf.sheafify_isSheaf _ <|
          (isSheaf_iff_isSheaf_of_type J _).mp <| sheafify_isSheaf J _)
  inv := Subpresheaf.ι _
  hom_inv_id :=
    J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by simp [toImagePresheafSheafify])
  inv_hom_id := by
    rw [← cancel_mono (Subpresheaf.ι _), Category.id_comp, Category.assoc]
    refine' Eq.trans _ (Category.comp_id _)
    congr 1
    exact J.sheafify_hom_ext _ _ (J.sheafify_isSheaf _) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝¹ : Category.{v', u'} A
inst✝ : ConcreteCategory A
F : Cᵒᵖ ⥤ Type (max u v)
⊢ toSheafify J F ≫
      sheafifyLift J (toImagePresheafSheafify J (toSheafify J F))
          (_ : Presheaf.IsSheaf J (Subpresheaf.toPresheaf (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))))) ≫
        Subpresheaf.ι (Subpresheaf.sheafify J (imagePresheaf (toSheafify J F))) =
    toSheafify J F ≫ 𝟙 (sheafify J F)

Next tactic:
simp [toImagePresheafSheafify]
theorem toSheafify_isLocallySurjective (F : Cᵒᵖ ⥤ B) : IsLocallySurjective J (J.toSheafify F) := by
  

Proof state:
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝⁸ : Category.{v', u'} A
inst✝⁷ : ConcreteCategory A
F✝ : Cᵒᵖ ⥤ Type (max u v)
B : Type w
inst✝⁶ : Category.{max u v, w} B
inst✝⁵ : ConcreteCategory B
inst✝⁴ : ∀ (X : C), Limits.HasColimitsOfShape (Cover J X)ᵒᵖ B
inst✝³ : ∀ (P : Cᵒᵖ ⥤ B) (X : C) (S : Cover J X), Limits.HasMultiequalizer (Cover.index S P)
inst✝² :
  (X : C) →
    (W : Cover J X) →
      (P : Cᵒᵖ ⥤ B) → Limits.PreservesLimit (Limits.MulticospanIndex.multicospan (Cover.index W P)) (forget B)
inst✝¹ : (X : C) → Limits.PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget B)
inst✝ : ∀ (α β : Type (max u v)) (fst snd : β → α), Limits.HasLimitsOfShape (Limits.WalkingMulticospan fst snd) B
F : Cᵒᵖ ⥤ B
⊢ IsLocallySurjective J (toSheafify J F)

Next tactic:
rw [isLocallySurjective_iff_whisker_forget, ← toSheafify_comp_sheafifyCompIso_inv]
theorem toSheafify_isLocallySurjective (F : Cᵒᵖ ⥤ B) : IsLocallySurjective J (J.toSheafify F) := by
  rw [isLocallySurjective_iff_whisker_forget, ← toSheafify_comp_sheafifyCompIso_inv]
  

Proof state:
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝⁸ : Category.{v', u'} A
inst✝⁷ : ConcreteCategory A
F✝ : Cᵒᵖ ⥤ Type (max u v)
B : Type w
inst✝⁶ : Category.{max u v, w} B
inst✝⁵ : ConcreteCategory B
inst✝⁴ : ∀ (X : C), Limits.HasColimitsOfShape (Cover J X)ᵒᵖ B
inst✝³ : ∀ (P : Cᵒᵖ ⥤ B) (X : C) (S : Cover J X), Limits.HasMultiequalizer (Cover.index S P)
inst✝² :
  (X : C) →
    (W : Cover J X) →
      (P : Cᵒᵖ ⥤ B) → Limits.PreservesLimit (Limits.MulticospanIndex.multicospan (Cover.index W P)) (forget B)
inst✝¹ : (X : C) → Limits.PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget B)
inst✝ : ∀ (α β : Type (max u v)) (fst snd : β → α), Limits.HasLimitsOfShape (Limits.WalkingMulticospan fst snd) B
F : Cᵒᵖ ⥤ B
⊢ IsLocallySurjective J (toSheafify J (F ⋙ forget B) ≫ (sheafifyCompIso J (forget B) F).inv)

Next tactic:
apply IsLocallySurjective.comp
theorem toSheafify_isLocallySurjective (F : Cᵒᵖ ⥤ B) : IsLocallySurjective J (J.toSheafify F) := by
  rw [isLocallySurjective_iff_whisker_forget, ← toSheafify_comp_sheafifyCompIso_inv]
  apply IsLocallySurjective.comp
  · 

Proof state:
case h₁
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝⁸ : Category.{v', u'} A
inst✝⁷ : ConcreteCategory A
F✝ : Cᵒᵖ ⥤ Type (max u v)
B : Type w
inst✝⁶ : Category.{max u v, w} B
inst✝⁵ : ConcreteCategory B
inst✝⁴ : ∀ (X : C), Limits.HasColimitsOfShape (Cover J X)ᵒᵖ B
inst✝³ : ∀ (P : Cᵒᵖ ⥤ B) (X : C) (S : Cover J X), Limits.HasMultiequalizer (Cover.index S P)
inst✝² :
  (X : C) →
    (W : Cover J X) →
      (P : Cᵒᵖ ⥤ B) → Limits.PreservesLimit (Limits.MulticospanIndex.multicospan (Cover.index W P)) (forget B)
inst✝¹ : (X : C) → Limits.PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget B)
inst✝ : ∀ (α β : Type (max u v)) (fst snd : β → α), Limits.HasLimitsOfShape (Limits.WalkingMulticospan fst snd) B
F : Cᵒᵖ ⥤ B
⊢ IsLocallySurjective J (toSheafify J (F ⋙ forget B))

Next tactic:
rw [isLocallySurjective_iff_imagePresheaf_sheafify_eq_top, Subpresheaf.eq_top_iff_isIso]
theorem toSheafify_isLocallySurjective (F : Cᵒᵖ ⥤ B) : IsLocallySurjective J (J.toSheafify F) := by
  rw [isLocallySurjective_iff_whisker_forget, ← toSheafify_comp_sheafifyCompIso_inv]
  apply IsLocallySurjective.comp
  · rw [isLocallySurjective_iff_imagePresheaf_sheafify_eq_top, Subpresheaf.eq_top_iff_isIso]
    

Proof state:
case h₁
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝⁸ : Category.{v', u'} A
inst✝⁷ : ConcreteCategory A
F✝ : Cᵒᵖ ⥤ Type (max u v)
B : Type w
inst✝⁶ : Category.{max u v, w} B
inst✝⁵ : ConcreteCategory B
inst✝⁴ : ∀ (X : C), Limits.HasColimitsOfShape (Cover J X)ᵒᵖ B
inst✝³ : ∀ (P : Cᵒᵖ ⥤ B) (X : C) (S : Cover J X), Limits.HasMultiequalizer (Cover.index S P)
inst✝² :
  (X : C) →
    (W : Cover J X) →
      (P : Cᵒᵖ ⥤ B) → Limits.PreservesLimit (Limits.MulticospanIndex.multicospan (Cover.index W P)) (forget B)
inst✝¹ : (X : C) → Limits.PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget B)
inst✝ : ∀ (α β : Type (max u v)) (fst snd : β → α), Limits.HasLimitsOfShape (Limits.WalkingMulticospan fst snd) B
F : Cᵒᵖ ⥤ B
⊢ IsIso
    (Subpresheaf.ι
      (Subpresheaf.sheafify J (imagePresheaf (whiskerRight (toSheafify J (F ⋙ forget B)) (forget (Type (max u v)))))))

Next tactic:
exact IsIso.of_iso_inv (sheafificationIsoImagePresheaf J (F ⋙ forget B))
theorem toSheafify_isLocallySurjective (F : Cᵒᵖ ⥤ B) : IsLocallySurjective J (J.toSheafify F) := by
  rw [isLocallySurjective_iff_whisker_forget, ← toSheafify_comp_sheafifyCompIso_inv]
  apply IsLocallySurjective.comp
  · rw [isLocallySurjective_iff_imagePresheaf_sheafify_eq_top, Subpresheaf.eq_top_iff_isIso]
    exact IsIso.of_iso_inv (sheafificationIsoImagePresheaf J (F ⋙ forget B))
  · 

Proof state:
case h₂
C : Type u
inst✝⁹ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝⁸ : Category.{v', u'} A
inst✝⁷ : ConcreteCategory A
F✝ : Cᵒᵖ ⥤ Type (max u v)
B : Type w
inst✝⁶ : Category.{max u v, w} B
inst✝⁵ : ConcreteCategory B
inst✝⁴ : ∀ (X : C), Limits.HasColimitsOfShape (Cover J X)ᵒᵖ B
inst✝³ : ∀ (P : Cᵒᵖ ⥤ B) (X : C) (S : Cover J X), Limits.HasMultiequalizer (Cover.index S P)
inst✝² :
  (X : C) →
    (W : Cover J X) →
      (P : Cᵒᵖ ⥤ B) → Limits.PreservesLimit (Limits.MulticospanIndex.multicospan (Cover.index W P)) (forget B)
inst✝¹ : (X : C) → Limits.PreservesColimitsOfShape (Cover J X)ᵒᵖ (forget B)
inst✝ : ∀ (α β : Type (max u v)) (fst snd : β → α), Limits.HasLimitsOfShape (Limits.WalkingMulticospan fst snd) B
F : Cᵒᵖ ⥤ B
⊢ IsLocallySurjective J (sheafifyCompIso J (forget B) F).inv

Next tactic:
exact isLocallySurjective_of_iso _ _
@[simp]
theorem sqrt_eq_zero : sqrt x = 0 ↔ x = 0 :=
  sqrt_eq_iff_sq_eq.trans <| by 

Proof state:
x y : ℝ≥0
⊢ 0 ^ 2 = x ↔ x = 0

Next tactic:
rw [eq_comm, sq, zero_mul]
@[simp]
theorem mul_self_sqrt (x : ℝ≥0) : sqrt x * sqrt x = x := by 

Proof state:
x✝ y x : ℝ≥0
⊢ sqrt x * sqrt x = x

Next tactic:
rw [← sq, sq_sqrt]
@[simp]
theorem sqrt_mul_self (x : ℝ≥0) : sqrt (x * x) = x := by 

Proof state:
x✝ y x : ℝ≥0
⊢ sqrt (x * x) = x

Next tactic:
rw [← sq, sqrt_sq x]
theorem sqrt_mul (x y : ℝ≥0) : sqrt (x * y) = sqrt x * sqrt y := by
  

Proof state:
x✝ y✝ x y : ℝ≥0
⊢ sqrt (x * y) = sqrt x * sqrt y

Next tactic:
rw [sqrt_eq_iff_sq_eq, mul_pow, sq_sqrt, sq_sqrt]
@[simp] theorem sqrt_pos : 0 < sqrt x ↔ 0 < x := by 

Proof state:
x y : ℝ≥0
⊢ 0 < sqrt x ↔ 0 < x

Next tactic:
simp [pos_iff_ne_zero]
theorem sqrtAux_nonneg (f : CauSeq ℚ abs) : ∀ i : ℕ, 0 ≤ sqrtAux f i
  | 0 => by
    

Proof state:
f : CauSeq ℚ abs
⊢ 0 ≤ sqrtAux f 0

Next tactic:
rw [sqrtAux, Rat.mkRat_eq, Rat.divInt_eq_div]
theorem sqrtAux_nonneg (f : CauSeq ℚ abs) : ∀ i : ℕ, 0 ≤ sqrtAux f i
  | 0 => by
    rw [sqrtAux, Rat.mkRat_eq, Rat.divInt_eq_div]; 

Proof state:
f : CauSeq ℚ abs
⊢ 0 ≤ ↑↑(Nat.sqrt (Int.toNat (↑f 0).num)) / ↑↑(Nat.sqrt (↑f 0).den)

Next tactic:
apply div_nonneg
theorem sqrtAux_nonneg (f : CauSeq ℚ abs) : ∀ i : ℕ, 0 ≤ sqrtAux f i
  | 0 => by
    rw [sqrtAux, Rat.mkRat_eq, Rat.divInt_eq_div]; apply div_nonneg <;>
      

Proof state:
case ha
f : CauSeq ℚ abs
⊢ 0 ≤ ↑↑(Nat.sqrt (Int.toNat (↑f 0).num))

Next tactic:
exact Int.cast_nonneg.2 (Int.ofNat_nonneg _)
theorem sqrtAux_nonneg (f : CauSeq ℚ abs) : ∀ i : ℕ, 0 ≤ sqrtAux f i
  | 0 => by
    rw [sqrtAux, Rat.mkRat_eq, Rat.divInt_eq_div]; apply div_nonneg <;>
      

Proof state:
case hb
f : CauSeq ℚ abs
⊢ 0 ≤ ↑↑(Nat.sqrt (↑f 0).den)

Next tactic:
exact Int.cast_nonneg.2 (Int.ofNat_nonneg _)
@[simp, norm_cast]
theorem coe_sqrt {x : ℝ≥0} : (NNReal.sqrt x : ℝ) = Real.sqrt x := by
  

Proof state:
x✝ y : ℝ
x : ℝ≥0
⊢ ↑(NNReal.sqrt x) = sqrt ↑x

Next tactic:
rw [Real.sqrt, Real.toNNReal_coe]
theorem sqrt_eq_zero_of_nonpos (h : x ≤ 0) : sqrt x = 0 := by 

Proof state:
x y : ℝ
h : x ≤ 0
⊢ sqrt x = 0

Next tactic:
simp [sqrt, Real.toNNReal_eq_zero.2 h]
@[simp]
theorem mul_self_sqrt (h : 0 ≤ x) : sqrt x * sqrt x = x := by
  

Proof state:
x y : ℝ
h : 0 ≤ x
⊢ sqrt x * sqrt x = x

Next tactic:
rw [sqrt, ← NNReal.coe_mul, NNReal.mul_self_sqrt, Real.coe_toNNReal _ h]
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  

Proof state:
x y : ℝ
⊢ sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0

Next tactic:
constructor
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  constructor
  · 

Proof state:
case mp
x y : ℝ
⊢ sqrt x = y → y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0

Next tactic:
rintro rfl
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  constructor
  · rintro rfl
    

Proof state:
case mp
x : ℝ
⊢ sqrt x * sqrt x = x ∧ 0 ≤ sqrt x ∨ x < 0 ∧ sqrt x = 0

Next tactic:
rcases le_or_lt 0 x with hle | hlt
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  constructor
  · rintro rfl
    rcases le_or_lt 0 x with hle | hlt
    · 

Proof state:
case mp.inl
x : ℝ
hle : 0 ≤ x
⊢ sqrt x * sqrt x = x ∧ 0 ≤ sqrt x ∨ x < 0 ∧ sqrt x = 0

Next tactic:
exact Or.inl ⟨mul_self_sqrt hle, sqrt_nonneg x⟩
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  constructor
  · rintro rfl
    rcases le_or_lt 0 x with hle | hlt
    · exact Or.inl ⟨mul_self_sqrt hle, sqrt_nonneg x⟩
    · 

Proof state:
case mp.inr
x : ℝ
hlt : x < 0
⊢ sqrt x * sqrt x = x ∧ 0 ≤ sqrt x ∨ x < 0 ∧ sqrt x = 0

Next tactic:
exact Or.inr ⟨hlt, sqrt_eq_zero_of_nonpos hlt.le⟩
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  constructor
  · rintro rfl
    rcases le_or_lt 0 x with hle | hlt
    · exact Or.inl ⟨mul_self_sqrt hle, sqrt_nonneg x⟩
    · exact Or.inr ⟨hlt, sqrt_eq_zero_of_nonpos hlt.le⟩
  · 

Proof state:
case mpr
x y : ℝ
⊢ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 → sqrt x = y

Next tactic:
rintro (⟨rfl, hy⟩ | ⟨hx, rfl⟩)
theorem sqrt_eq_cases : sqrt x = y ↔ y * y = x ∧ 0 ≤ y ∨ x < 0 ∧ y = 0 := by
  constructor
  · rintro rfl
    rcases le_or_lt 0 x with hle | hlt
    · exact Or.inl ⟨mul_self_sqrt hle, sqrt_nonneg x⟩
    · exact Or.inr ⟨hlt, sqrt_eq_zero_of_nonpos hlt.le⟩
  · rintro (⟨rfl, hy⟩ | ⟨hx, rfl⟩)
    

Proof state:
case mpr.inl.intro
y : ℝ
hy : 0 ≤ y
⊢ sqrt (y * y) = y
case mpr.inr.intro x : ℝ hx : x < 0 ⊢ sqrt x = 0

Next tactic:
exacts [sqrt_mul_self hy, sqrt_eq_zero_of_nonpos hx.le]
theorem sqrt_eq_iff_mul_self_eq (hx : 0 ≤ x) (hy : 0 ≤ y) : sqrt x = y ↔ y * y = x :=
  ⟨fun h => by 

Proof state:
x y : ℝ
hx : 0 ≤ x
hy : 0 ≤ y
h : sqrt x = y
⊢ y * y = x

Next tactic:
rw [← h, mul_self_sqrt hx]
theorem sqrt_eq_iff_mul_self_eq (hx : 0 ≤ x) (hy : 0 ≤ y) : sqrt x = y ↔ y * y = x :=
  ⟨fun h => by rw [← h, mul_self_sqrt hx], fun h => by 

Proof state:
x y : ℝ
hx : 0 ≤ x
hy : 0 ≤ y
h : y * y = x
⊢ sqrt x = y

Next tactic:
rw [← h, sqrt_mul_self hy]
theorem sqrt_eq_iff_mul_self_eq_of_pos (h : 0 < y) : sqrt x = y ↔ y * y = x := by
  

Proof state:
x y : ℝ
h : 0 < y
⊢ sqrt x = y ↔ y * y = x

Next tactic:
simp [sqrt_eq_cases, h.ne', h.le]
@[simp]
theorem sqrt_eq_one : sqrt x = 1 ↔ x = 1 :=
  calc
    sqrt x = 1 ↔ 1 * 1 = x := sqrt_eq_iff_mul_self_eq_of_pos zero_lt_one
    _ ↔ x = 1 := by 

Proof state:
x y : ℝ
⊢ 1 * 1 = x ↔ x = 1

Next tactic:
rw [eq_comm, mul_one]
@[simp]
theorem sq_sqrt (h : 0 ≤ x) : sqrt x ^ 2 = x := by 

Proof state:
x y : ℝ
h : 0 ≤ x
⊢ sqrt x ^ 2 = x

Next tactic:
rw [sq, mul_self_sqrt h]
@[simp]
theorem sqrt_sq (h : 0 ≤ x) : sqrt (x ^ 2) = x := by 

Proof state:
x y : ℝ
h : 0 ≤ x
⊢ sqrt (x ^ 2) = x

Next tactic:
rw [sq, sqrt_mul_self h]
theorem sqrt_eq_iff_sq_eq (hx : 0 ≤ x) (hy : 0 ≤ y) : sqrt x = y ↔ y ^ 2 = x := by
  

Proof state:
x y : ℝ
hx : 0 ≤ x
hy : 0 ≤ y
⊢ sqrt x = y ↔ y ^ 2 = x

Next tactic:
rw [sq, sqrt_eq_iff_mul_self_eq hx hy]
theorem sqrt_mul_self_eq_abs (x : ℝ) : sqrt (x * x) = |x| := by
  

Proof state:
x✝ y x : ℝ
⊢ sqrt (x * x) = |x|

Next tactic:
rw [← abs_mul_abs_self x, sqrt_mul_self (abs_nonneg _)]
theorem sqrt_sq_eq_abs (x : ℝ) : sqrt (x ^ 2) = |x| := by 

Proof state:
x✝ y x : ℝ
⊢ sqrt (x ^ 2) = |x|

Next tactic:
rw [sq, sqrt_mul_self_eq_abs]
@[simp]
theorem sqrt_zero : sqrt 0 = 0 := by 

Proof state:
x y : ℝ
⊢ sqrt 0 = 0

Next tactic:
simp [sqrt]
@[simp]
theorem sqrt_one : sqrt 1 = 1 := by 

Proof state:
x y : ℝ
⊢ sqrt 1 = 1

Next tactic:
simp [sqrt]
@[simp]
theorem sqrt_le_sqrt_iff (hy : 0 ≤ y) : sqrt x ≤ sqrt y ↔ x ≤ y := by
  

Proof state:
x y : ℝ
hy : 0 ≤ y
⊢ sqrt x ≤ sqrt y ↔ x ≤ y

Next tactic:
rw [sqrt, sqrt, NNReal.coe_le_coe, NNReal.sqrt_le_sqrt_iff, Real.toNNReal_le_toNNReal_iff hy]
theorem sqrt_lt_sqrt_iff_of_pos (hy : 0 < y) : sqrt x < sqrt y ↔ x < y := by
  

Proof state:
x y : ℝ
hy : 0 < y
⊢ sqrt x < sqrt y ↔ x < y

Next tactic:
rw [sqrt, sqrt, NNReal.coe_lt_coe, NNReal.sqrt_lt_sqrt_iff, toNNReal_lt_toNNReal_iff hy]
theorem sqrt_le_sqrt (h : x ≤ y) : sqrt x ≤ sqrt y := by
  

Proof state:
x y : ℝ
h : x ≤ y
⊢ sqrt x ≤ sqrt y

Next tactic:
rw [sqrt, sqrt, NNReal.coe_le_coe, NNReal.sqrt_le_sqrt_iff]
theorem sqrt_le_sqrt (h : x ≤ y) : sqrt x ≤ sqrt y := by
  rw [sqrt, sqrt, NNReal.coe_le_coe, NNReal.sqrt_le_sqrt_iff]
  

Proof state:
x y : ℝ
h : x ≤ y
⊢ toNNReal x ≤ toNNReal y

Next tactic:
exact toNNReal_le_toNNReal h
theorem sqrt_le_left (hy : 0 ≤ y) : sqrt x ≤ y ↔ x ≤ y ^ 2 := by
  

Proof state:
x y : ℝ
hy : 0 ≤ y
⊢ sqrt x ≤ y ↔ x ≤ y ^ 2

Next tactic:
rw [sqrt, ← Real.le_toNNReal_iff_coe_le hy, NNReal.sqrt_le_iff, sq, ← Real.toNNReal_mul hy,
    Real.toNNReal_le_toNNReal_iff (mul_self_nonneg y), sq]
theorem sqrt_le_iff : sqrt x ≤ y ↔ 0 ≤ y ∧ x ≤ y ^ 2 := by
  

Proof state:
x y : ℝ
⊢ sqrt x ≤ y ↔ 0 ≤ y ∧ x ≤ y ^ 2

Next tactic:
rw [← and_iff_right_of_imp fun h => (sqrt_nonneg x).trans h, and_congr_right_iff]
theorem sqrt_le_iff : sqrt x ≤ y ↔ 0 ≤ y ∧ x ≤ y ^ 2 := by
  rw [← and_iff_right_of_imp fun h => (sqrt_nonneg x).trans h, and_congr_right_iff]
  

Proof state:
x y : ℝ
⊢ 0 ≤ y → (sqrt x ≤ y ↔ x ≤ y ^ 2)

Next tactic:
exact sqrt_le_left
theorem sqrt_lt (hx : 0 ≤ x) (hy : 0 ≤ y) : sqrt x < y ↔ x < y ^ 2 := by
  

Proof state:
x y : ℝ
hx : 0 ≤ x
hy : 0 ≤ y
⊢ sqrt x < y ↔ x < y ^ 2

Next tactic:
rw [← sqrt_lt_sqrt_iff hx, sqrt_sq hy]
theorem sqrt_lt' (hy : 0 < y) : sqrt x < y ↔ x < y ^ 2 := by
  

Proof state:
x y : ℝ
hy : 0 < y
⊢ sqrt x < y ↔ x < y ^ 2

Next tactic:
rw [← sqrt_lt_sqrt_iff_of_pos (pow_pos hy _), sqrt_sq hy.le]
theorem abs_le_sqrt (h : x ^ 2 ≤ y) : |x| ≤ sqrt y := by
  

Proof state:
x y : ℝ
h : x ^ 2 ≤ y
⊢ |x| ≤ sqrt y

Next tactic:
rw [← sqrt_sq_eq_abs]
theorem abs_le_sqrt (h : x ^ 2 ≤ y) : |x| ≤ sqrt y := by
  rw [← sqrt_sq_eq_abs]; 

Proof state:
x y : ℝ
h : x ^ 2 ≤ y
⊢ sqrt (x ^ 2) ≤ sqrt y

Next tactic:
exact sqrt_le_sqrt h