l3lab/ntp-mathlib huggingface dataset:
/-- The negation on the morphisms in the category `Quotient r` when `r` is compatible
with the addition. -/
def neg {X Y : Quotient r} (f : X ⟶ Y) : X ⟶ Y :=
  Quot.liftOn f (fun a => Quot.mk _ (-a))
    (fun f g => by
      intro hfg
      

Proof state:
C : Type ?u.6214
inst✝² : Category.{?u.6218, ?u.6214} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
X Y : Quotient r
f✝ : X ⟶ Y
f g : X.as ⟶ Y.as
hfg : CompClosure r f g
⊢ (fun a => Quot.mk (CompClosure r) (-a)) f = (fun a => Quot.mk (CompClosure r) (-a)) g

Next tactic:
simp only [compClosure_iff_self] at hfg
/-- The negation on the morphisms in the category `Quotient r` when `r` is compatible
with the addition. -/
def neg {X Y : Quotient r} (f : X ⟶ Y) : X ⟶ Y :=
  Quot.liftOn f (fun a => Quot.mk _ (-a))
    (fun f g => by
      intro hfg
      simp only [compClosure_iff_self] at hfg
      

Proof state:
C : Type ?u.6214
inst✝² : Category.{?u.6218, ?u.6214} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
X Y : Quotient r
f✝ : X ⟶ Y
f g : X.as ⟶ Y.as
hfg : r f g
⊢ (fun a => Quot.mk (CompClosure r) (-a)) f = (fun a => Quot.mk (CompClosure r) (-a)) g

Next tactic:
erw [functor_map_eq_iff]
/-- The negation on the morphisms in the category `Quotient r` when `r` is compatible
with the addition. -/
def neg {X Y : Quotient r} (f : X ⟶ Y) : X ⟶ Y :=
  Quot.liftOn f (fun a => Quot.mk _ (-a))
    (fun f g => by
      intro hfg
      simp only [compClosure_iff_self] at hfg
      erw [functor_map_eq_iff]
      

Proof state:
C : Type ?u.6214
inst✝² : Category.{?u.6218, ?u.6214} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
X Y : Quotient r
f✝ : X ⟶ Y
f g : X.as ⟶ Y.as
hfg : r f g
⊢ r (-f) (-g)

Next tactic:
apply Congruence.equivalence.symm
/-- The negation on the morphisms in the category `Quotient r` when `r` is compatible
with the addition. -/
def neg {X Y : Quotient r} (f : X ⟶ Y) : X ⟶ Y :=
  Quot.liftOn f (fun a => Quot.mk _ (-a))
    (fun f g => by
      intro hfg
      simp only [compClosure_iff_self] at hfg
      erw [functor_map_eq_iff]
      apply Congruence.equivalence.symm
      

Proof state:
C : Type ?u.6214
inst✝² : Category.{?u.6218, ?u.6214} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
X Y : Quotient r
f✝ : X ⟶ Y
f g : X.as ⟶ Y.as
hfg : r f g
⊢ r (-g) (-f)

Next tactic:
convert hr f g _ _ hfg (Congruence.equivalence.refl (-f-g)) using 1
/-- The negation on the morphisms in the category `Quotient r` when `r` is compatible
with the addition. -/
def neg {X Y : Quotient r} (f : X ⟶ Y) : X ⟶ Y :=
  Quot.liftOn f (fun a => Quot.mk _ (-a))
    (fun f g => by
      intro hfg
      simp only [compClosure_iff_self] at hfg
      erw [functor_map_eq_iff]
      apply Congruence.equivalence.symm
      convert hr f g _ _ hfg (Congruence.equivalence.refl (-f-g)) using 1 <;> 

Proof state:
case h.e'_3
C : Type ?u.6214
inst✝² : Category.{?u.6218, ?u.6214} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
X Y : Quotient r
f✝ : X ⟶ Y
f g : X.as ⟶ Y.as
hfg : r f g
⊢ -g = f + (-f - g)

Next tactic:
abel
/-- The negation on the morphisms in the category `Quotient r` when `r` is compatible
with the addition. -/
def neg {X Y : Quotient r} (f : X ⟶ Y) : X ⟶ Y :=
  Quot.liftOn f (fun a => Quot.mk _ (-a))
    (fun f g => by
      intro hfg
      simp only [compClosure_iff_self] at hfg
      erw [functor_map_eq_iff]
      apply Congruence.equivalence.symm
      convert hr f g _ _ hfg (Congruence.equivalence.refl (-f-g)) using 1 <;> 

Proof state:
case h.e'_4
C : Type ?u.6214
inst✝² : Category.{?u.6218, ?u.6214} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
X Y : Quotient r
f✝ : X ⟶ Y
f g : X.as ⟶ Y.as
hfg : r f g
⊢ -f = g + (-f - g)

Next tactic:
abel
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
⊢ ∀ (a b c : P ⟶ Q), a + b + c = a + (b + c)

Next tactic:
rintro ⟨_⟩ ⟨_⟩ ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; 

Proof state:
case mk.mk.mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
a✝³ : P ⟶ Q
a✝² : P.as ⟶ Q.as
b✝ : P ⟶ Q
a✝¹ : P.as ⟶ Q.as
c✝ : P ⟶ Q
a✝ : P.as ⟶ Q.as
⊢ Quot.mk (CompClosure r) a✝² + Quot.mk (CompClosure r) a✝¹ + Quot.mk (CompClosure r) a✝ =
    Quot.mk (CompClosure r) a✝² + (Quot.mk (CompClosure r) a✝¹ + Quot.mk (CompClosure r) a✝)

Next tactic:
exact congr_arg (functor r).map (add_assoc _ _ _)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
⊢ ∀ (a : P ⟶ Q), 0 + a = a

Next tactic:
rintro ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; 

Proof state:
case mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
a✝¹ : P ⟶ Q
a✝ : P.as ⟶ Q.as
⊢ 0 + Quot.mk (CompClosure r) a✝ = Quot.mk (CompClosure r) a✝

Next tactic:
exact congr_arg (functor r).map (zero_add _)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
⊢ ∀ (a : P ⟶ Q), a + 0 = a

Next tactic:
rintro ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; 

Proof state:
case mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
a✝¹ : P ⟶ Q
a✝ : P.as ⟶ Q.as
⊢ Quot.mk (CompClosure r) a✝ + 0 = Quot.mk (CompClosure r) a✝

Next tactic:
exact congr_arg (functor r).map (add_zero _)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
⊢ ∀ (a : P ⟶ Q), -a + a = 0

Next tactic:
rintro ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; 

Proof state:
case mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
a✝¹ : P ⟶ Q
a✝ : P.as ⟶ Q.as
⊢ -Quot.mk (CompClosure r) a✝ + Quot.mk (CompClosure r) a✝ = 0

Next tactic:
exact congr_arg (functor r).map (add_left_neg _)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
⊢ ∀ (a b : P ⟶ Q), a + b = b + a

Next tactic:
rintro ⟨_⟩ ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; 

Proof state:
case mk.mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P Q : Quotient r
a✝² : P ⟶ Q
a✝¹ : P.as ⟶ Q.as
b✝ : P ⟶ Q
a✝ : P.as ⟶ Q.as
⊢ Quot.mk (CompClosure r) a✝¹ + Quot.mk (CompClosure r) a✝ = Quot.mk (CompClosure r) a✝ + Quot.mk (CompClosure r) a✝¹

Next tactic:
exact congr_arg (functor r).map (add_comm _ _)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_left_neg _) }
  add_comp := by
    

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
⊢ ∀ (P Q R : Quotient r) (f f' : P ⟶ Q) (g : Q ⟶ R), (f + f') ≫ g = f ≫ g + f' ≫ g

Next tactic:
rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_left_neg _) }
  add_comp := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    

Proof state:
case mk.mk.mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P✝ Q✝ R✝ : Quotient r
f✝ : P✝ ⟶ Q✝
a✝² : P✝.as ⟶ Q✝.as
f'✝ : P✝ ⟶ Q✝
a✝¹ : P✝.as ⟶ Q✝.as
g✝ : Q✝ ⟶ R✝
a✝ : Q✝.as ⟶ R✝.as
⊢ (Quot.mk (CompClosure r) a✝² + Quot.mk (CompClosure r) a✝¹) ≫ Quot.mk (CompClosure r) a✝ =
    Quot.mk (CompClosure r) a✝² ≫ Quot.mk (CompClosure r) a✝ + Quot.mk (CompClosure r) a✝¹ ≫ Quot.mk (CompClosure r) a✝

Next tactic:
exact congr_arg (functor r).map (by apply Preadditive.add_comp)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_left_neg _) }
  add_comp := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    exact congr_arg (functor r).map (by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P✝ Q✝ R✝ : Quotient r
f✝ : P✝ ⟶ Q✝
a✝² : P✝.as ⟶ Q✝.as
f'✝ : P✝ ⟶ Q✝
a✝¹ : P✝.as ⟶ Q✝.as
g✝ : Q✝ ⟶ R✝
a✝ : Q✝.as ⟶ R✝.as
⊢ (a✝² + a✝¹) ≫ a✝ = a✝² ≫ a✝ + a✝¹ ≫ a✝

Next tactic:
apply Preadditive.add_comp
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_left_neg _) }
  add_comp := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    exact congr_arg (functor r).map (by apply Preadditive.add_comp)
  comp_add := by
    

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
⊢ ∀ (P Q R : Quotient r) (f : P ⟶ Q) (g g' : Q ⟶ R), f ≫ (g + g') = f ≫ g + f ≫ g'

Next tactic:
rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_left_neg _) }
  add_comp := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    exact congr_arg (functor r).map (by apply Preadditive.add_comp)
  comp_add := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    

Proof state:
case mk.mk.mk
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P✝ Q✝ R✝ : Quotient r
f✝ : P✝ ⟶ Q✝
a✝² : P✝.as ⟶ Q✝.as
g✝ : Q✝ ⟶ R✝
a✝¹ : Q✝.as ⟶ R✝.as
g'✝ : Q✝ ⟶ R✝
a✝ : Q✝.as ⟶ R✝.as
⊢ Quot.mk (CompClosure r) a✝² ≫ (Quot.mk (CompClosure r) a✝¹ + Quot.mk (CompClosure r) a✝) =
    Quot.mk (CompClosure r) a✝² ≫ Quot.mk (CompClosure r) a✝¹ + Quot.mk (CompClosure r) a✝² ≫ Quot.mk (CompClosure r) a✝

Next tactic:
exact congr_arg (functor r).map (by apply Preadditive.comp_add)
/-- The preadditive structure on the category `Quotient r` when `r` is compatible
with the addition. -/
def preadditive : Preadditive (Quotient r) where
  homGroup P Q :=
    { add := Preadditive.add r hr
      add_assoc := by rintro ⟨_⟩ ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_assoc _ _ _)
      zero := Quot.mk _ 0
      zero_add := by rintro ⟨_⟩; exact congr_arg (functor r).map (zero_add _)
      add_zero := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_zero _)
      add_comm := by rintro ⟨_⟩ ⟨_⟩; exact congr_arg (functor r).map (add_comm _ _)
      neg := Preadditive.neg r hr
      add_left_neg := by rintro ⟨_⟩; exact congr_arg (functor r).map (add_left_neg _) }
  add_comp := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    exact congr_arg (functor r).map (by apply Preadditive.add_comp)
  comp_add := by
    rintro _ _ _ ⟨_⟩ ⟨_⟩ ⟨_⟩
    exact congr_arg (functor r).map (by 

Proof state:
C : Type ?u.12975
inst✝² : Category.{?u.15251, ?u.12975} C
inst✝¹ : Preadditive C
r : HomRel C
inst✝ : Congruence r
hr : ∀ ⦃X Y : C⦄ (f₁ f₂ g₁ g₂ : X ⟶ Y), r f₁ f₂ → r g₁ g₂ → r (f₁ + g₁) (f₂ + g₂)
P✝ Q✝ R✝ : Quotient r
f✝ : P✝ ⟶ Q✝
a✝² : P✝.as ⟶ Q✝.as
g✝ : Q✝ ⟶ R✝
a✝¹ : Q✝.as ⟶ R✝.as
g'✝ : Q✝ ⟶ R✝
a✝ : Q✝.as ⟶ R✝.as
⊢ a✝² ≫ (a✝¹ + a✝) = a✝² ≫ a✝¹ + a✝² ≫ a✝

Next tactic:
apply Preadditive.comp_add
/-- The midpoint of the segment AB is the same distance from A as it is from B. -/
theorem dist_left_midpoint_eq_dist_right_midpoint (p1 p2 : P) :
    dist p1 (midpoint ℝ p1 p2) = dist p2 (midpoint ℝ p1 p2) := by
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
p1 p2 : P
⊢ dist p1 (midpoint ℝ p1 p2) = dist p2 (midpoint ℝ p1 p2)

Next tactic:
rw [dist_left_midpoint (𝕜 := ℝ) p1 p2, dist_right_midpoint (𝕜 := ℝ) p1 p2]
/-- The inner product of two vectors given with `weightedVSub`, in
terms of the pairwise distances. -/
theorem inner_weightedVSub {ι₁ : Type*} {s₁ : Finset ι₁} {w₁ : ι₁ → ℝ} (p₁ : ι₁ → P)
    (h₁ : ∑ i in s₁, w₁ i = 0) {ι₂ : Type*} {s₂ : Finset ι₂} {w₂ : ι₂ → ℝ} (p₂ : ι₂ → P)
    (h₂ : ∑ i in s₂, w₂ i = 0) :
    ⟪s₁.weightedVSub p₁ w₁, s₂.weightedVSub p₂ w₂⟫ =
      (-∑ i₁ in s₁, ∑ i₂ in s₂, w₁ i₁ * w₂ i₂ * (dist (p₁ i₁) (p₂ i₂) * dist (p₁ i₁) (p₂ i₂))) /
        2 := by
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
ι₁ : Type u_3
s₁ : Finset ι₁
w₁ : ι₁ → ℝ
p₁ : ι₁ → P
h₁ : ∑ i in s₁, w₁ i = 0
ι₂ : Type u_4
s₂ : Finset ι₂
w₂ : ι₂ → ℝ
p₂ : ι₂ → P
h₂ : ∑ i in s₂, w₂ i = 0
⊢ inner ((Finset.weightedVSub s₁ p₁) w₁) ((Finset.weightedVSub s₂ p₂) w₂) =
    (-∑ i₁ in s₁, ∑ i₂ in s₂, w₁ i₁ * w₂ i₂ * (dist (p₁ i₁) (p₂ i₂) * dist (p₁ i₁) (p₂ i₂))) / 2

Next tactic:
rw [Finset.weightedVSub_apply, Finset.weightedVSub_apply,
    inner_sum_smul_sum_smul_of_sum_eq_zero _ h₁ _ h₂]
/-- The inner product of two vectors given with `weightedVSub`, in
terms of the pairwise distances. -/
theorem inner_weightedVSub {ι₁ : Type*} {s₁ : Finset ι₁} {w₁ : ι₁ → ℝ} (p₁ : ι₁ → P)
    (h₁ : ∑ i in s₁, w₁ i = 0) {ι₂ : Type*} {s₂ : Finset ι₂} {w₂ : ι₂ → ℝ} (p₂ : ι₂ → P)
    (h₂ : ∑ i in s₂, w₂ i = 0) :
    ⟪s₁.weightedVSub p₁ w₁, s₂.weightedVSub p₂ w₂⟫ =
      (-∑ i₁ in s₁, ∑ i₂ in s₂, w₁ i₁ * w₂ i₂ * (dist (p₁ i₁) (p₂ i₂) * dist (p₁ i₁) (p₂ i₂))) /
        2 := by
  rw [Finset.weightedVSub_apply, Finset.weightedVSub_apply,
    inner_sum_smul_sum_smul_of_sum_eq_zero _ h₁ _ h₂]
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
ι₁ : Type u_3
s₁ : Finset ι₁
w₁ : ι₁ → ℝ
p₁ : ι₁ → P
h₁ : ∑ i in s₁, w₁ i = 0
ι₂ : Type u_4
s₂ : Finset ι₂
w₂ : ι₂ → ℝ
p₂ : ι₂ → P
h₂ : ∑ i in s₂, w₂ i = 0
⊢ (-∑ i₁ in s₁,
          ∑ i₂ in s₂,
            w₁ i₁ * w₂ i₂ *
              (‖p₁ i₁ -ᵥ choice (_ : Nonempty P) - (p₂ i₂ -ᵥ choice (_ : Nonempty P))‖ *
                ‖p₁ i₁ -ᵥ choice (_ : Nonempty P) - (p₂ i₂ -ᵥ choice (_ : Nonempty P))‖)) /
      2 =
    (-∑ i₁ in s₁, ∑ i₂ in s₂, w₁ i₁ * w₂ i₂ * (dist (p₁ i₁) (p₂ i₂) * dist (p₁ i₁) (p₂ i₂))) / 2

Next tactic:
simp_rw [vsub_sub_vsub_cancel_right]
/-- The inner product of two vectors given with `weightedVSub`, in
terms of the pairwise distances. -/
theorem inner_weightedVSub {ι₁ : Type*} {s₁ : Finset ι₁} {w₁ : ι₁ → ℝ} (p₁ : ι₁ → P)
    (h₁ : ∑ i in s₁, w₁ i = 0) {ι₂ : Type*} {s₂ : Finset ι₂} {w₂ : ι₂ → ℝ} (p₂ : ι₂ → P)
    (h₂ : ∑ i in s₂, w₂ i = 0) :
    ⟪s₁.weightedVSub p₁ w₁, s₂.weightedVSub p₂ w₂⟫ =
      (-∑ i₁ in s₁, ∑ i₂ in s₂, w₁ i₁ * w₂ i₂ * (dist (p₁ i₁) (p₂ i₂) * dist (p₁ i₁) (p₂ i₂))) /
        2 := by
  rw [Finset.weightedVSub_apply, Finset.weightedVSub_apply,
    inner_sum_smul_sum_smul_of_sum_eq_zero _ h₁ _ h₂]
  simp_rw [vsub_sub_vsub_cancel_right]
  

Proof state:
V : Type u_1
P : Type u_2
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
ι₁ : Type u_3
s₁ : Finset ι₁
w₁ : ι₁ → ℝ
p₁ : ι₁ → P
h₁ : ∑ i in s₁, w₁ i = 0
ι₂ : Type u_4
s₂ : Finset ι₂
w₂ : ι₂ → ℝ
p₂ : ι₂ → P
h₂ : ∑ i in s₂, w₂ i = 0
⊢ (-∑ x in s₁, ∑ x_1 in s₂, w₁ x * w₂ x_1 * (‖p₁ x -ᵥ p₂ x_1‖ * ‖p₁ x -ᵥ p₂ x_1‖)) / 2 =
    (-∑ i₁ in s₁, ∑ i₂ in s₂, w₁ i₁ * w₂ i₂ * (dist (p₁ i₁) (p₂ i₂) * dist (p₁ i₁) (p₂ i₂))) / 2

Next tactic:
rcongr (i₁ i₂)