l3lab/ntp-mathlib huggingface dataset:
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  

Proof state:
case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
⊢ ∀ ⦃Y : C⦄ (f : G.obj Y ⟶ X), ℱ.val.map f.op (ℱ.val.map f₁.op (x g₁ hg₁)) = ℱ.val.map f.op (ℱ.val.map f₂.op (x g₂ hg₂))

Next tactic:
intro W i
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  intro W i
  

Proof state:
case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ ℱ.val.map i.op (ℱ.val.map f₁.op (x g₁ hg₁)) = ℱ.val.map i.op (ℱ.val.map f₂.op (x g₂ hg₂))

Next tactic:
simp only [← FunctorToTypes.map_comp_apply, ← op_comp]
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  intro W i
  simp only [← FunctorToTypes.map_comp_apply, ← op_comp]
  

Proof state:
case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ ℱ.val.map (i ≫ f₁).op (x g₁ hg₁) = ℱ.val.map (i ≫ f₂).op (x g₂ hg₂)

Next tactic:
rw [← G.image_preimage (i ≫ f₁)]
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  intro W i
  simp only [← FunctorToTypes.map_comp_apply, ← op_comp]
  rw [← G.image_preimage (i ≫ f₁)]
  

Proof state:
case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ ℱ.val.map (G.map (G.preimage (i ≫ f₁))).op (x g₁ hg₁) = ℱ.val.map (i ≫ f₂).op (x g₂ hg₂)

Next tactic:
rw [← G.image_preimage (i ≫ f₂)]
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  intro W i
  simp only [← FunctorToTypes.map_comp_apply, ← op_comp]
  rw [← G.image_preimage (i ≫ f₁)]
  rw [← G.image_preimage (i ≫ f₂)]
  

Proof state:
case compatible.h
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ ℱ.val.map (G.map (G.preimage (i ≫ f₁))).op (x g₁ hg₁) = ℱ.val.map (G.map (G.preimage (i ≫ f₂))).op (x g₂ hg₂)

Next tactic:
apply hx
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  intro W i
  simp only [← FunctorToTypes.map_comp_apply, ← op_comp]
  rw [← G.image_preimage (i ≫ f₁)]
  rw [← G.image_preimage (i ≫ f₂)]
  apply hx
  

Proof state:
case compatible.h.a
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ Full.preimage (i ≫ f₁) ≫ g₁ = Full.preimage (i ≫ f₂) ≫ g₂

Next tactic:
apply G.map_injective
/-- A fully faithful cover-dense functor preserves compatible families. -/
lemma compatiblePreserving [Faithful G] : CompatiblePreserving K G := by
  constructor
  intro ℱ Z T x hx Y₁ Y₂ X f₁ f₂ g₁ g₂ hg₁ hg₂ eq
  apply Functor.IsCoverDense.ext G
  intro W i
  simp only [← FunctorToTypes.map_comp_apply, ← op_comp]
  rw [← G.image_preimage (i ≫ f₁)]
  rw [← G.image_preimage (i ≫ f₂)]
  apply hx
  apply G.map_injective
  

Proof state:
case compatible.h.a.a
C : Type u_1
inst✝⁶ : Category.{u_5, u_1} C
D : Type u_2
inst✝⁵ : Category.{u_6, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.144116, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.144168, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : Faithful G
ℱ : SheafOfTypes K
Z : C
T : Presieve Z
x : FamilyOfElements (G.op ⋙ ℱ.val) T
hx : FamilyOfElements.Compatible x
Y₁ Y₂ : C
X : D
f₁ : X ⟶ G.obj Y₁
f₂ : X ⟶ G.obj Y₂
g₁ : Y₁ ⟶ Z
g₂ : Y₂ ⟶ Z
hg₁ : T g₁
hg₂ : T g₂
eq : f₁ ≫ G.map g₁ = f₂ ≫ G.map g₂
W : C
i : G.obj W ⟶ X
⊢ G.map (Full.preimage (i ≫ f₁) ≫ g₁) = G.map (Full.preimage (i ≫ f₂) ≫ g₂)

Next tactic:
simp [eq]
instance faithful_sheafPushforwardContinuous [G.IsContinuous J K] :
    Faithful (G.sheafPushforwardContinuous A J K) where
  map_injective := by
    

Proof state:
C : Type u_1
inst✝⁶ : Category.{?u.150817, u_1} C
D : Type u_2
inst✝⁵ : Category.{?u.150824, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.150831, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.151420, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ : Dᵒᵖ ⥤ A
ℱ' : Sheaf K A
inst✝ : IsContinuous G J K
⊢ ∀ {X Y : Sheaf K A}, Function.Injective (sheafPushforwardContinuous G A J K).map

Next tactic:
intro ℱ ℱ' α β e
instance faithful_sheafPushforwardContinuous [G.IsContinuous J K] :
    Faithful (G.sheafPushforwardContinuous A J K) where
  map_injective := by
    intro ℱ ℱ' α β e
    

Proof state:
C : Type u_1
inst✝⁶ : Category.{?u.150817, u_1} C
D : Type u_2
inst✝⁵ : Category.{?u.150824, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.150831, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.151420, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ'✝ : Sheaf K A
inst✝ : IsContinuous G J K
ℱ ℱ' : Sheaf K A
α β : ℱ ⟶ ℱ'
e : (sheafPushforwardContinuous G A J K).map α = (sheafPushforwardContinuous G A J K).map β
⊢ α = β

Next tactic:
ext1
instance faithful_sheafPushforwardContinuous [G.IsContinuous J K] :
    Faithful (G.sheafPushforwardContinuous A J K) where
  map_injective := by
    intro ℱ ℱ' α β e
    ext1
    

Proof state:
case h
C : Type u_1
inst✝⁶ : Category.{?u.150817, u_1} C
D : Type u_2
inst✝⁵ : Category.{?u.150824, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.150831, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.151420, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ'✝ : Sheaf K A
inst✝ : IsContinuous G J K
ℱ ℱ' : Sheaf K A
α β : ℱ ⟶ ℱ'
e : (sheafPushforwardContinuous G A J K).map α = (sheafPushforwardContinuous G A J K).map β
⊢ α.val = β.val

Next tactic:
apply_fun fun e => e.val at e
instance faithful_sheafPushforwardContinuous [G.IsContinuous J K] :
    Faithful (G.sheafPushforwardContinuous A J K) where
  map_injective := by
    intro ℱ ℱ' α β e
    ext1
    apply_fun fun e => e.val at e
    

Proof state:
case h
C : Type u_1
inst✝⁶ : Category.{?u.150817, u_1} C
D : Type u_2
inst✝⁵ : Category.{?u.150824, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.150831, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.151420, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ'✝ : Sheaf K A
inst✝ : IsContinuous G J K
ℱ ℱ' : Sheaf K A
α β : ℱ ⟶ ℱ'
e : ((sheafPushforwardContinuous G A J K).map α).val = ((sheafPushforwardContinuous G A J K).map β).val
⊢ α.val = β.val

Next tactic:
dsimp [sheafPushforwardContinuous] at e
instance faithful_sheafPushforwardContinuous [G.IsContinuous J K] :
    Faithful (G.sheafPushforwardContinuous A J K) where
  map_injective := by
    intro ℱ ℱ' α β e
    ext1
    apply_fun fun e => e.val at e
    dsimp [sheafPushforwardContinuous] at e
    

Proof state:
case h
C : Type u_1
inst✝⁶ : Category.{?u.150817, u_1} C
D : Type u_2
inst✝⁵ : Category.{?u.150824, u_2} D
E : Type u_3
inst✝⁴ : Category.{?u.150831, u_3} E
J : GrothendieckTopology C
K : GrothendieckTopology D
L : GrothendieckTopology E
A : Type u_4
inst✝³ : Category.{?u.151420, u_4} A
G : C ⥤ D
inst✝² : IsCoverDense G K
inst✝¹ : Full G
ℱ✝ : Dᵒᵖ ⥤ A
ℱ'✝ : Sheaf K A
inst✝ : IsContinuous G J K
ℱ ℱ' : Sheaf K A
α β : ℱ ⟶ ℱ'
e : whiskerLeft G.op α.val = whiskerLeft G.op β.val
⊢ α.val = β.val

Next tactic:
rw [← sheafHom_eq G α.val, ← sheafHom_eq G β.val, e]
instance (Y : Sheaf J A) : IsIso ((G.sheafAdjunctionCocontinuous A J K).counit.app Y) := by
    

Proof state:
C D : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : Category.{v, u} D
G : C ⥤ D
inst✝⁶ : Full G
inst✝⁵ : Faithful G
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type w
inst✝⁴ : Category.{max u v, w} A
inst✝³ : Limits.HasLimits A
inst✝² : IsCoverDense G K
inst✝¹ : IsContinuous G J K
inst✝ : IsCocontinuous G J K
Y : Sheaf J A
⊢ IsIso ((sheafAdjunctionCocontinuous G A J K).counit.app Y)

Next tactic:
let α := G.sheafAdjunctionCocontinuous A J K
instance (Y : Sheaf J A) : IsIso ((G.sheafAdjunctionCocontinuous A J K).counit.app Y) := by
    let α := G.sheafAdjunctionCocontinuous A J K
    

Proof state:
C D : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : Category.{v, u} D
G : C ⥤ D
inst✝⁶ : Full G
inst✝⁵ : Faithful G
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type w
inst✝⁴ : Category.{max u v, w} A
inst✝³ : Limits.HasLimits A
inst✝² : IsCoverDense G K
inst✝¹ : IsContinuous G J K
inst✝ : IsCocontinuous G J K
Y : Sheaf J A
α : sheafPushforwardContinuous G A J K ⊣ sheafPushforwardCocontinuous G A J K := sheafAdjunctionCocontinuous G A J K
⊢ IsIso ((sheafAdjunctionCocontinuous G A J K).counit.app Y)

Next tactic:
haveI : IsIso ((sheafToPresheaf J A).map (α.counit.app Y)) :=
      IsIso.of_iso ((@asIso _ _ _ _ _ (Ran.reflective A G.op)).app Y.val)
instance (Y : Sheaf J A) : IsIso ((G.sheafAdjunctionCocontinuous A J K).counit.app Y) := by
    let α := G.sheafAdjunctionCocontinuous A J K
    haveI : IsIso ((sheafToPresheaf J A).map (α.counit.app Y)) :=
      IsIso.of_iso ((@asIso _ _ _ _ _ (Ran.reflective A G.op)).app Y.val)
    

Proof state:
C D : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : Category.{v, u} D
G : C ⥤ D
inst✝⁶ : Full G
inst✝⁵ : Faithful G
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type w
inst✝⁴ : Category.{max u v, w} A
inst✝³ : Limits.HasLimits A
inst✝² : IsCoverDense G K
inst✝¹ : IsContinuous G J K
inst✝ : IsCocontinuous G J K
Y : Sheaf J A
α : sheafPushforwardContinuous G A J K ⊣ sheafPushforwardCocontinuous G A J K := sheafAdjunctionCocontinuous G A J K
this : IsIso ((sheafToPresheaf J A).map (α.counit.app Y))
⊢ IsIso ((sheafAdjunctionCocontinuous G A J K).counit.app Y)

Next tactic:
apply ReflectsIsomorphisms.reflects (sheafToPresheaf J A)
/-- The natural isomorphism exhibiting the compatibility of
`sheafEquivOfCoverPreservingCoverLifting` with sheafification. -/
noncomputable
abbrev sheafEquivOfCoverPreservingCoverLiftingSheafificationCompatibility :
    (whiskeringLeft _ _ A).obj G.op ⋙ presheafToSheaf _ _ ≅
      presheafToSheaf _ _ ⋙ (sheafEquivOfCoverPreservingCoverLifting G J K A).inverse := by
  

Proof state:
C D : Type u
inst✝¹⁵ : Category.{v, u} C
inst✝¹⁴ : Category.{v, u} D
G : C ⥤ D
inst✝¹³ : Full G
inst✝¹² : Faithful G
J : GrothendieckTopology C
K : GrothendieckTopology D
A : Type w
inst✝¹¹ : Category.{max u v, w} A
inst✝¹⁰ : Limits.HasLimits A
inst✝⁹ : IsCoverDense G K
inst✝⁸ : IsContinuous G J K
inst✝⁷ : IsCocontinuous G J K
inst✝⁶ : ConcreteCategory A
inst✝⁵ : Limits.PreservesLimits (forget A)
inst✝⁴ : ReflectsIsomorphisms (forget A)
inst✝³ : (X : C) → Limits.PreservesColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ (forget A)
inst✝² : ∀ (X : C), Limits.HasColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ A
inst✝¹ : (X : D) → Limits.PreservesColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ (forget A)
inst✝ : ∀ (X : D), Limits.HasColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ A
⊢ (whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op ⋙ presheafToSheaf J A ≅
    presheafToSheaf K A ⋙ (sheafEquivOfCoverPreservingCoverLifting G J K A).inverse

Next tactic:
apply Functor.pushforwardContinuousSheafificationCompatibility
instance Int.euclideanDomain : EuclideanDomain ℤ :=
  { inferInstanceAs (CommRing Int), inferInstanceAs (Nontrivial Int) with
    quotient := (· / ·), quotient_zero := Int.ediv_zero, remainder := (· % ·),
    quotient_mul_add_remainder_eq := Int.ediv_add_emod,
    r := fun a b => a.natAbs < b.natAbs,
    r_wellFounded := (measure natAbs).wf
    remainder_lt := fun a b b0 => Int.ofNat_lt.1 <| by
      

Proof state:
src✝¹ : CommRing ℤ := inferInstanceAs (CommRing ℤ)
src✝ : Nontrivial ℤ := inferInstanceAs (Nontrivial ℤ)
a b : ℤ
b0 : b ≠ 0
⊢ ↑(natAbs ((fun x x_1 => x % x_1) a b)) < ↑(natAbs b)

Next tactic:
rw [Int.natAbs_of_nonneg (Int.emod_nonneg _ b0), ← Int.abs_eq_natAbs]
instance Int.euclideanDomain : EuclideanDomain ℤ :=
  { inferInstanceAs (CommRing Int), inferInstanceAs (Nontrivial Int) with
    quotient := (· / ·), quotient_zero := Int.ediv_zero, remainder := (· % ·),
    quotient_mul_add_remainder_eq := Int.ediv_add_emod,
    r := fun a b => a.natAbs < b.natAbs,
    r_wellFounded := (measure natAbs).wf
    remainder_lt := fun a b b0 => Int.ofNat_lt.1 <| by
      rw [Int.natAbs_of_nonneg (Int.emod_nonneg _ b0), ← Int.abs_eq_natAbs]
      

Proof state:
src✝¹ : CommRing ℤ := inferInstanceAs (CommRing ℤ)
src✝ : Nontrivial ℤ := inferInstanceAs (Nontrivial ℤ)
a b : ℤ
b0 : b ≠ 0
⊢ a % b < |b|

Next tactic:
exact Int.emod_lt _ b0
instance Int.euclideanDomain : EuclideanDomain ℤ :=
  { inferInstanceAs (CommRing Int), inferInstanceAs (Nontrivial Int) with
    quotient := (· / ·), quotient_zero := Int.ediv_zero, remainder := (· % ·),
    quotient_mul_add_remainder_eq := Int.ediv_add_emod,
    r := fun a b => a.natAbs < b.natAbs,
    r_wellFounded := (measure natAbs).wf
    remainder_lt := fun a b b0 => Int.ofNat_lt.1 <| by
      rw [Int.natAbs_of_nonneg (Int.emod_nonneg _ b0), ← Int.abs_eq_natAbs]
      exact Int.emod_lt _ b0
    mul_left_not_lt := fun a b b0 =>
      not_lt_of_ge <| by
        

Proof state:
src✝¹ : CommRing ℤ := inferInstanceAs (CommRing ℤ)
src✝ : Nontrivial ℤ := inferInstanceAs (Nontrivial ℤ)
a b : ℤ
b0 : b ≠ 0
⊢ natAbs (a * b) ≥ natAbs a

Next tactic:
rw [← mul_one a.natAbs, Int.natAbs_mul]
instance Int.euclideanDomain : EuclideanDomain ℤ :=
  { inferInstanceAs (CommRing Int), inferInstanceAs (Nontrivial Int) with
    quotient := (· / ·), quotient_zero := Int.ediv_zero, remainder := (· % ·),
    quotient_mul_add_remainder_eq := Int.ediv_add_emod,
    r := fun a b => a.natAbs < b.natAbs,
    r_wellFounded := (measure natAbs).wf
    remainder_lt := fun a b b0 => Int.ofNat_lt.1 <| by
      rw [Int.natAbs_of_nonneg (Int.emod_nonneg _ b0), ← Int.abs_eq_natAbs]
      exact Int.emod_lt _ b0
    mul_left_not_lt := fun a b b0 =>
      not_lt_of_ge <| by
        rw [← mul_one a.natAbs, Int.natAbs_mul]
        

Proof state:
src✝¹ : CommRing ℤ := inferInstanceAs (CommRing ℤ)
src✝ : Nontrivial ℤ := inferInstanceAs (Nontrivial ℤ)
a b : ℤ
b0 : b ≠ 0
⊢ natAbs a * natAbs b ≥ natAbs a * 1

Next tactic:
rw [← Int.natAbs_pos] at b0
instance Int.euclideanDomain : EuclideanDomain ℤ :=
  { inferInstanceAs (CommRing Int), inferInstanceAs (Nontrivial Int) with
    quotient := (· / ·), quotient_zero := Int.ediv_zero, remainder := (· % ·),
    quotient_mul_add_remainder_eq := Int.ediv_add_emod,
    r := fun a b => a.natAbs < b.natAbs,
    r_wellFounded := (measure natAbs).wf
    remainder_lt := fun a b b0 => Int.ofNat_lt.1 <| by
      rw [Int.natAbs_of_nonneg (Int.emod_nonneg _ b0), ← Int.abs_eq_natAbs]
      exact Int.emod_lt _ b0
    mul_left_not_lt := fun a b b0 =>
      not_lt_of_ge <| by
        rw [← mul_one a.natAbs, Int.natAbs_mul]
        rw [← Int.natAbs_pos] at b0
        

Proof state:
src✝¹ : CommRing ℤ := inferInstanceAs (CommRing ℤ)
src✝ : Nontrivial ℤ := inferInstanceAs (Nontrivial ℤ)
a b : ℤ
b0 : 0 < natAbs b
⊢ natAbs a * natAbs b ≥ natAbs a * 1

Next tactic:
exact Nat.mul_le_mul_of_nonneg_left b0
instance (priority := 100) Field.toEuclideanDomain {K : Type*} [Field K] : EuclideanDomain K :=
{ toCommRing := Field.toCommRing
  quotient := (· / ·), remainder := fun a b => a - a * b / b, quotient_zero := div_zero,
  quotient_mul_add_remainder_eq := fun a b => by
    

Proof state:
K : Type u_1
inst✝ : Field K
a b : K
⊢ b * (fun x x_1 => x / x_1) a b + (fun a b => a - a * b / b) a b = a

Next tactic:
by_cases h : b = 0
instance (priority := 100) Field.toEuclideanDomain {K : Type*} [Field K] : EuclideanDomain K :=
{ toCommRing := Field.toCommRing
  quotient := (· / ·), remainder := fun a b => a - a * b / b, quotient_zero := div_zero,
  quotient_mul_add_remainder_eq := fun a b => by
    by_cases h : b = 0 <;> 

Proof state:
case pos
K : Type u_1
inst✝ : Field K
a b : K
h : b = 0
⊢ b * (fun x x_1 => x / x_1) a b + (fun a b => a - a * b / b) a b = a

Next tactic:
simp [h, mul_div_cancel']
instance (priority := 100) Field.toEuclideanDomain {K : Type*} [Field K] : EuclideanDomain K :=
{ toCommRing := Field.toCommRing
  quotient := (· / ·), remainder := fun a b => a - a * b / b, quotient_zero := div_zero,
  quotient_mul_add_remainder_eq := fun a b => by
    by_cases h : b = 0 <;> 

Proof state:
case neg
K : Type u_1
inst✝ : Field K
a b : K
h : ¬b = 0
⊢ b * (fun x x_1 => x / x_1) a b + (fun a b => a - a * b / b) a b = a

Next tactic:
simp [h, mul_div_cancel']
instance (priority := 100) Field.toEuclideanDomain {K : Type*} [Field K] : EuclideanDomain K :=
{ toCommRing := Field.toCommRing
  quotient := (· / ·), remainder := fun a b => a - a * b / b, quotient_zero := div_zero,
  quotient_mul_add_remainder_eq := fun a b => by
    by_cases h : b = 0 <;> simp [h, mul_div_cancel']
  r := fun a b => a = 0 ∧ b ≠ 0,
  r_wellFounded :=
    WellFounded.intro fun a =>
      (Acc.intro _) fun b ⟨hb, _⟩ => (Acc.intro _) fun c ⟨_, hnb⟩ => False.elim <| hnb hb,
  remainder_lt := fun a b hnb => by 

Proof state:
K : Type u_1
inst✝ : Field K
a b : K
hnb : b ≠ 0
⊢ (fun a b => a = 0 ∧ b ≠ 0) ((fun a b => a - a * b / b) a b) b

Next tactic:
simp [hnb]
@[simp]
theorem inversion_self (c : P) (R : ℝ) : inversion c R c = c := by 

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a b c✝ d x y z : P
r R✝ : ℝ
c : P
R : ℝ
⊢ inversion c R c = c

Next tactic:
simp [inversion]
@[simp]
theorem inversion_zero_radius (c x : P) : inversion c 0 x = c := by 

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a b c✝ d x✝ y z : P
r R : ℝ
c x : P
⊢ inversion c 0 x = c

Next tactic:
simp [inversion]
theorem inversion_mul (c : P) (a R : ℝ) (x : P) :
    inversion c (a * R) x = homothety c (a ^ 2) (inversion c R x) := by
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a✝ b c✝ d x✝ y z : P
r R✝ : ℝ
c : P
a R : ℝ
x : P
⊢ inversion c (a * R) x = (homothety c (a ^ 2)) (inversion c R x)

Next tactic:
simp only [inversion_eq_lineMap, ← homothety_eq_lineMap, ← homothety_mul_apply, mul_div_assoc,
    mul_pow]
@[simp]
theorem inversion_dist_center (c x : P) : inversion c (dist x c) x = x := by
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a b c✝ d x✝ y z : P
r R : ℝ
c x : P
⊢ inversion c (dist x c) x = x

Next tactic:
rcases eq_or_ne x c with (rfl | hne)
@[simp]
theorem inversion_dist_center (c x : P) : inversion c (dist x c) x = x := by
  rcases eq_or_ne x c with (rfl | hne)
  · 

Proof state:
case inl
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a b c d x✝ y z : P
r R : ℝ
x : P
⊢ inversion x (dist x x) x = x

Next tactic:
apply inversion_self
@[simp]
theorem inversion_dist_center (c x : P) : inversion c (dist x c) x = x := by
  rcases eq_or_ne x c with (rfl | hne)
  · apply inversion_self
  · 

Proof state:
case inr
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a b c✝ d x✝ y z : P
r R : ℝ
c x : P
hne : x ≠ c
⊢ inversion c (dist x c) x = x

Next tactic:
rw [inversion, div_self, one_pow, one_smul, vsub_vadd]
@[simp]
theorem inversion_dist_center (c x : P) : inversion c (dist x c) x = x := by
  rcases eq_or_ne x c with (rfl | hne)
  · apply inversion_self
  · rw [inversion, div_self, one_pow, one_smul, vsub_vadd]
    

Proof state:
case inr
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
a b c✝ d x✝ y z : P
r R : ℝ
c x : P
hne : x ≠ c
⊢ dist x c ≠ 0

Next tactic:
rwa [dist_ne_zero]