l3lab/ntp-mathlib huggingface dataset:
/-- Given `f, g` with `f ≫ g = 0`, the homology of `g.op, f.op` is the opposite of the homology of
`f, g`. -/
def homology'Op {X Y Z : V} (f : X ⟶ Y) (g : Y ⟶ Z) (w : f ≫ g = 0) :
    homology' g.op f.op (by rw [← op_comp, w, op_zero]) ≅ Opposite.op (homology' f g w) :=
  cokernelIsoOfEq (imageToKernel_op _ _ w) ≪≫ cokernelEpiComp _ _ ≪≫ cokernelCompIsIso _ _ ≪≫
    cokernelOpOp _ ≪≫ (homology'IsoKernelDesc _ _ _ ≪≫
    kernelIsoOfEq (by ext; 

Proof state:
case h
V : Type u_1
inst✝¹ : Category.{?u.23271, u_1} V
inst✝ : Abelian V
X Y Z : V
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ coequalizer.π f 0 ≫ cokernel.desc f g w =
    coequalizer.π f 0 ≫ cokernel.desc f (factorThruImage g) (_ : f ≫ factorThruImage g = 0) ≫ image.ι g

Next tactic:
simp only [image.fac, cokernel.π_desc, cokernel.π_desc_assoc]
/-- Given morphisms `f, g` in `Vᵒᵖ` with `f ≫ g = 0`, the homology of `g.unop, f.unop` is the
opposite of the homology of `f, g`. -/
def homology'Unop {X Y Z : Vᵒᵖ} (f : X ⟶ Y) (g : Y ⟶ Z) (w : f ≫ g = 0) :
    homology' g.unop f.unop (by 

Proof state:
V : Type u_1
inst✝¹ : Category.{?u.44782, u_1} V
inst✝ : Abelian V
X Y Z : Vᵒᵖ
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ g.unop ≫ f.unop = 0

Next tactic:
rw [← unop_comp, w, unop_zero]
/-- Given morphisms `f, g` in `Vᵒᵖ` with `f ≫ g = 0`, the homology of `g.unop, f.unop` is the
opposite of the homology of `f, g`. -/
def homology'Unop {X Y Z : Vᵒᵖ} (f : X ⟶ Y) (g : Y ⟶ Z) (w : f ≫ g = 0) :
    homology' g.unop f.unop (by rw [← unop_comp, w, unop_zero]) ≅
      Opposite.unop (homology' f g w) :=
  cokernelIsoOfEq (imageToKernel_unop _ _ w) ≪≫ cokernelEpiComp _ _ ≪≫ cokernelCompIsIso _ _ ≪≫
    cokernelUnopUnop _ ≪≫ (homology'IsoKernelDesc _ _ _ ≪≫
    kernelIsoOfEq (by 

Proof state:
V : Type u_1
inst✝¹ : Category.{?u.44782, u_1} V
inst✝ : Abelian V
X Y Z : Vᵒᵖ
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ cokernel.desc f g w = cokernel.desc f (factorThruImage g) (_ : f ≫ factorThruImage g = 0) ≫ image.ι g

Next tactic:
ext
/-- Given morphisms `f, g` in `Vᵒᵖ` with `f ≫ g = 0`, the homology of `g.unop, f.unop` is the
opposite of the homology of `f, g`. -/
def homology'Unop {X Y Z : Vᵒᵖ} (f : X ⟶ Y) (g : Y ⟶ Z) (w : f ≫ g = 0) :
    homology' g.unop f.unop (by rw [← unop_comp, w, unop_zero]) ≅
      Opposite.unop (homology' f g w) :=
  cokernelIsoOfEq (imageToKernel_unop _ _ w) ≪≫ cokernelEpiComp _ _ ≪≫ cokernelCompIsIso _ _ ≪≫
    cokernelUnopUnop _ ≪≫ (homology'IsoKernelDesc _ _ _ ≪≫
    kernelIsoOfEq (by ext; 

Proof state:
case h
V : Type u_1
inst✝¹ : Category.{?u.44782, u_1} V
inst✝ : Abelian V
X Y Z : Vᵒᵖ
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ coequalizer.π f 0 ≫ cokernel.desc f g w =
    coequalizer.π f 0 ≫ cokernel.desc f (factorThruImage g) (_ : f ≫ factorThruImage g = 0) ≫ image.ι g

Next tactic:
simp only [image.fac, cokernel.π_desc, cokernel.π_desc_assoc]
/-- Sends a complex `X` with objects in `V` to the corresponding complex with objects in `Vᵒᵖ`. -/
@[simps]
protected def op (X : HomologicalComplex V c) : HomologicalComplex Vᵒᵖ c.symm where
  X i := op (X.X i)
  d i j := (X.d j i).op
  shape i j hij := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.66749, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex V c
i j : ι
hij : ¬ComplexShape.Rel (ComplexShape.symm c) i j
⊢ (fun i j => (d X j i).op) i j = 0

Next tactic:
simp only
/-- Sends a complex `X` with objects in `V` to the corresponding complex with objects in `Vᵒᵖ`. -/
@[simps]
protected def op (X : HomologicalComplex V c) : HomologicalComplex Vᵒᵖ c.symm where
  X i := op (X.X i)
  d i j := (X.d j i).op
  shape i j hij := by simp only; 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.66749, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex V c
i j : ι
hij : ¬ComplexShape.Rel (ComplexShape.symm c) i j
⊢ (d X j i).op = 0

Next tactic:
rw [X.shape j i hij, op_zero]
/-- Sends a complex `X` with objects in `V` to the corresponding complex with objects in `Vᵒᵖ`. -/
@[simps]
protected def op (X : HomologicalComplex V c) : HomologicalComplex Vᵒᵖ c.symm where
  X i := op (X.X i)
  d i j := (X.d j i).op
  shape i j hij := by simp only; rw [X.shape j i hij, op_zero]
  d_comp_d' _ _ _ _ _ := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.66749, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex V c
x✝⁴ x✝³ x✝² : ι
x✝¹ : ComplexShape.Rel (ComplexShape.symm c) x✝⁴ x✝³
x✝ : ComplexShape.Rel (ComplexShape.symm c) x✝³ x✝²
⊢ (fun i j => (d X j i).op) x✝⁴ x✝³ ≫ (fun i j => (d X j i).op) x✝³ x✝² = 0

Next tactic:
rw [← op_comp, X.d_comp_d, op_zero]
/-- Sends a complex `X` with objects in `V` to the corresponding complex with objects in `Vᵒᵖ`. -/
@[simps]
protected def opSymm (X : HomologicalComplex V c.symm) : HomologicalComplex Vᵒᵖ c where
  X i := op (X.X i)
  d i j := (X.d j i).op
  shape i j hij := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.68583, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex V (ComplexShape.symm c)
i j : ι
hij : ¬ComplexShape.Rel c i j
⊢ (fun i j => (d X j i).op) i j = 0

Next tactic:
simp only
/-- Sends a complex `X` with objects in `V` to the corresponding complex with objects in `Vᵒᵖ`. -/
@[simps]
protected def opSymm (X : HomologicalComplex V c.symm) : HomologicalComplex Vᵒᵖ c where
  X i := op (X.X i)
  d i j := (X.d j i).op
  shape i j hij := by simp only; 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.68583, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex V (ComplexShape.symm c)
i j : ι
hij : ¬ComplexShape.Rel c i j
⊢ (d X j i).op = 0

Next tactic:
rw [X.shape j i hij, op_zero]
/-- Sends a complex `X` with objects in `V` to the corresponding complex with objects in `Vᵒᵖ`. -/
@[simps]
protected def opSymm (X : HomologicalComplex V c.symm) : HomologicalComplex Vᵒᵖ c where
  X i := op (X.X i)
  d i j := (X.d j i).op
  shape i j hij := by simp only; rw [X.shape j i hij, op_zero]
  d_comp_d' _ _ _ _ _ := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.68583, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex V (ComplexShape.symm c)
x✝⁴ x✝³ x✝² : ι
x✝¹ : ComplexShape.Rel c x✝⁴ x✝³
x✝ : ComplexShape.Rel c x✝³ x✝²
⊢ (fun i j => (d X j i).op) x✝⁴ x✝³ ≫ (fun i j => (d X j i).op) x✝³ x✝² = 0

Next tactic:
rw [← op_comp, X.d_comp_d, op_zero]
/-- Sends a complex `X` with objects in `Vᵒᵖ` to the corresponding complex with objects in `V`. -/
@[simps]
protected def unop (X : HomologicalComplex Vᵒᵖ c) : HomologicalComplex V c.symm where
  X i := unop (X.X i)
  d i j := (X.d j i).unop
  shape i j hij := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.70387, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex Vᵒᵖ c
i j : ι
hij : ¬ComplexShape.Rel (ComplexShape.symm c) i j
⊢ (fun i j => (d X j i).unop) i j = 0

Next tactic:
simp only
/-- Sends a complex `X` with objects in `Vᵒᵖ` to the corresponding complex with objects in `V`. -/
@[simps]
protected def unop (X : HomologicalComplex Vᵒᵖ c) : HomologicalComplex V c.symm where
  X i := unop (X.X i)
  d i j := (X.d j i).unop
  shape i j hij := by simp only; 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.70387, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex Vᵒᵖ c
i j : ι
hij : ¬ComplexShape.Rel (ComplexShape.symm c) i j
⊢ (d X j i).unop = 0

Next tactic:
rw [X.shape j i hij, unop_zero]
/-- Sends a complex `X` with objects in `Vᵒᵖ` to the corresponding complex with objects in `V`. -/
@[simps]
protected def unop (X : HomologicalComplex Vᵒᵖ c) : HomologicalComplex V c.symm where
  X i := unop (X.X i)
  d i j := (X.d j i).unop
  shape i j hij := by simp only; rw [X.shape j i hij, unop_zero]
  d_comp_d' _ _ _ _ _ := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.70387, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex Vᵒᵖ c
x✝⁴ x✝³ x✝² : ι
x✝¹ : ComplexShape.Rel (ComplexShape.symm c) x✝⁴ x✝³
x✝ : ComplexShape.Rel (ComplexShape.symm c) x✝³ x✝²
⊢ (fun i j => (d X j i).unop) x✝⁴ x✝³ ≫ (fun i j => (d X j i).unop) x✝³ x✝² = 0

Next tactic:
rw [← unop_comp, X.d_comp_d, unop_zero]
/-- Sends a complex `X` with objects in `Vᵒᵖ` to the corresponding complex with objects in `V`. -/
@[simps]
protected def unopSymm (X : HomologicalComplex Vᵒᵖ c.symm) : HomologicalComplex V c where
  X i := unop (X.X i)
  d i j := (X.d j i).unop
  shape i j hij := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.72203, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex Vᵒᵖ (ComplexShape.symm c)
i j : ι
hij : ¬ComplexShape.Rel c i j
⊢ (fun i j => (d X j i).unop) i j = 0

Next tactic:
simp only
/-- Sends a complex `X` with objects in `Vᵒᵖ` to the corresponding complex with objects in `V`. -/
@[simps]
protected def unopSymm (X : HomologicalComplex Vᵒᵖ c.symm) : HomologicalComplex V c where
  X i := unop (X.X i)
  d i j := (X.d j i).unop
  shape i j hij := by simp only; 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.72203, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex Vᵒᵖ (ComplexShape.symm c)
i j : ι
hij : ¬ComplexShape.Rel c i j
⊢ (d X j i).unop = 0

Next tactic:
rw [X.shape j i hij, unop_zero]
/-- Sends a complex `X` with objects in `Vᵒᵖ` to the corresponding complex with objects in `V`. -/
@[simps]
protected def unopSymm (X : HomologicalComplex Vᵒᵖ c.symm) : HomologicalComplex V c where
  X i := unop (X.X i)
  d i j := (X.d j i).unop
  shape i j hij := by simp only; rw [X.shape j i hij, unop_zero]
  d_comp_d' _ _ _ _ _ := by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.72203, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : HomologicalComplex Vᵒᵖ (ComplexShape.symm c)
x✝⁴ x✝³ x✝² : ι
x✝¹ : ComplexShape.Rel c x✝⁴ x✝³
x✝ : ComplexShape.Rel c x✝³ x✝²
⊢ (fun i j => (d X j i).unop) x✝⁴ x✝³ ≫ (fun i j => (d X j i).unop) x✝³ x✝² = 0

Next tactic:
rw [← unop_comp, X.d_comp_d, unop_zero]
/-- Auxiliary definition for `opEquivalence`. -/
@[simps]
def opFunctor : (HomologicalComplex V c)ᵒᵖ ⥤ HomologicalComplex Vᵒᵖ c.symm where
  obj X := (unop X).op
  map f :=
    { f := fun i => (f.unop.f i).op
      comm' := fun i j _ => by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.74051, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X✝ Y✝ : (HomologicalComplex V c)ᵒᵖ
f : X✝ ⟶ Y✝
i j : ι
x✝ : ComplexShape.Rel (ComplexShape.symm c) i j
⊢ (fun i => (Hom.f f.unop i).op) i ≫ d ((fun X => HomologicalComplex.op X.unop) Y✝) i j =
    d ((fun X => HomologicalComplex.op X.unop) X✝) i j ≫ (fun i => (Hom.f f.unop i).op) j

Next tactic:
simp only [op_d, ← op_comp, f.unop.comm]
/-- Auxiliary definition for `opEquivalence`. -/
@[simps]
def opInverse : HomologicalComplex Vᵒᵖ c.symm ⥤ (HomologicalComplex V c)ᵒᵖ where
  obj X := op X.unopSymm
  map f := Quiver.Hom.op
    { f := fun i => (f.f i).unop
      comm' := fun i j _ => by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.82677, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X✝ Y✝ : HomologicalComplex Vᵒᵖ (ComplexShape.symm c)
f : X✝ ⟶ Y✝
i j : ι
x✝ : ComplexShape.Rel c i j
⊢ (fun i => (Hom.f f i).unop) i ≫ d (HomologicalComplex.unopSymm X✝) i j =
    d (HomologicalComplex.unopSymm Y✝) i j ≫ (fun i => (Hom.f f i).unop) j

Next tactic:
simp only [unopSymm_d, ← unop_comp, f.comm]
/-- Auxiliary definition for `opEquivalence`. -/
def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.90768, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : (HomologicalComplex V c)ᵒᵖ
i j : ι
x✝ : ComplexShape.Rel c i j
⊢ ((fun i => Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)) i).hom ≫
      d X.unop i j =
    d (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i j ≫
      ((fun i => Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)) j).hom

Next tactic:
simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id]
/-- Auxiliary definition for `opEquivalence`. -/
def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id] :
          (Opposite.unop X).op.unopSymm ≅ unop X).op)
    (by
      

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.90768, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
⊢ ∀ {X Y : (HomologicalComplex V c)ᵒᵖ} (f : X ⟶ Y),
    (𝟭 (HomologicalComplex V c)ᵒᵖ).map f ≫
        ((fun X =>
              Iso.op
                (Hom.isoOfComponents fun i =>
                  Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
            Y).hom =
      ((fun X =>
              Iso.op
                (Hom.isoOfComponents fun i =>
                  Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
            X).hom ≫
        (opFunctor V c ⋙ opInverse V c).map f

Next tactic:
intro X Y f
/-- Auxiliary definition for `opEquivalence`. -/
def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id] :
          (Opposite.unop X).op.unopSymm ≅ unop X).op)
    (by
      intro X Y f
      

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.90768, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X Y : (HomologicalComplex V c)ᵒᵖ
f : X ⟶ Y
⊢ (𝟭 (HomologicalComplex V c)ᵒᵖ).map f ≫
      ((fun X =>
            Iso.op
              (Hom.isoOfComponents fun i =>
                Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
          Y).hom =
    ((fun X =>
            Iso.op
              (Hom.isoOfComponents fun i =>
                Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
          X).hom ≫
      (opFunctor V c ⋙ opInverse V c).map f

Next tactic:
refine' Quiver.Hom.unop_inj _
/-- Auxiliary definition for `opEquivalence`. -/
def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id] :
          (Opposite.unop X).op.unopSymm ≅ unop X).op)
    (by
      intro X Y f
      refine' Quiver.Hom.unop_inj _
      

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.90768, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X Y : (HomologicalComplex V c)ᵒᵖ
f : X ⟶ Y
⊢ ((𝟭 (HomologicalComplex V c)ᵒᵖ).map f ≫
        ((fun X =>
              Iso.op
                (Hom.isoOfComponents fun i =>
                  Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
            Y).hom).unop =
    (((fun X =>
              Iso.op
                (Hom.isoOfComponents fun i =>
                  Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
            X).hom ≫
        (opFunctor V c ⋙ opInverse V c).map f).unop

Next tactic:
ext x
/-- Auxiliary definition for `opEquivalence`. -/
def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id] :
          (Opposite.unop X).op.unopSymm ≅ unop X).op)
    (by
      intro X Y f
      refine' Quiver.Hom.unop_inj _
      ext x
      

Proof state:
case h
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.90768, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X Y : (HomologicalComplex V c)ᵒᵖ
f : X ⟶ Y
x : ι
⊢ Hom.f
      ((𝟭 (HomologicalComplex V c)ᵒᵖ).map f ≫
          ((fun X =>
                Iso.op
                  (Hom.isoOfComponents fun i =>
                    Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
              Y).hom).unop
      x =
    Hom.f
      (((fun X =>
                Iso.op
                  (Hom.isoOfComponents fun i =>
                    Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)))
              X).hom ≫
          (opFunctor V c ⋙ opInverse V c).map f).unop
      x

Next tactic:
simp only [Quiver.Hom.unop_op, Functor.id_map, Iso.op_hom, Functor.comp_map, unop_comp,
        comp_f, Hom.isoOfComponents_hom_f]
/-- Auxiliary definition for `opEquivalence`. -/
def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id] :
          (Opposite.unop X).op.unopSymm ≅ unop X).op)
    (by
      intro X Y f
      refine' Quiver.Hom.unop_inj _
      ext x
      simp only [Quiver.Hom.unop_op, Functor.id_map, Iso.op_hom, Functor.comp_map, unop_comp,
        comp_f, Hom.isoOfComponents_hom_f]
      

Proof state:
case h
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.90768, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X Y : (HomologicalComplex V c)ᵒᵖ
f : X ⟶ Y
x : ι
⊢ (Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op Y.unop)) x)).hom ≫
      Hom.f f.unop x =
    Hom.f ((opInverse V c).map ((opFunctor V c).map f)).unop x ≫
      (Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) x)).hom

Next tactic:
erw [Category.id_comp, Category.comp_id (f.unop.f x)]
/-- Given a category of complexes with objects in `V`, there is a natural equivalence between its
opposite category and a category of complexes with objects in `Vᵒᵖ`. -/
@[simps]
def opEquivalence : (HomologicalComplex V c)ᵒᵖ ≌ HomologicalComplex Vᵒᵖ c.symm where
  functor := opFunctor V c
  inverse := opInverse V c
  unitIso := opUnitIso V c
  counitIso := opCounitIso V c
  functor_unitIso_comp X := by
    

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.110202, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : (HomologicalComplex V c)ᵒᵖ
⊢ (opFunctor V c).map ((opUnitIso V c).hom.app X) ≫ (opCounitIso V c).hom.app ((opFunctor V c).obj X) =
    𝟙 ((opFunctor V c).obj X)

Next tactic:
ext
/-- Given a category of complexes with objects in `V`, there is a natural equivalence between its
opposite category and a category of complexes with objects in `Vᵒᵖ`. -/
@[simps]
def opEquivalence : (HomologicalComplex V c)ᵒᵖ ≌ HomologicalComplex Vᵒᵖ c.symm where
  functor := opFunctor V c
  inverse := opInverse V c
  unitIso := opUnitIso V c
  counitIso := opCounitIso V c
  functor_unitIso_comp X := by
    ext
    

Proof state:
case h
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.110202, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : (HomologicalComplex V c)ᵒᵖ
i✝ : ι
⊢ Hom.f ((opFunctor V c).map ((opUnitIso V c).hom.app X) ≫ (opCounitIso V c).hom.app ((opFunctor V c).obj X)) i✝ =
    Hom.f (𝟙 ((opFunctor V c).obj X)) i✝

Next tactic:
simp only [opUnitIso, opCounitIso, NatIso.ofComponents_hom_app, Iso.op_hom, comp_f,
      opFunctor_map_f, Quiver.Hom.unop_op, Hom.isoOfComponents_hom_f]
/-- Given a category of complexes with objects in `V`, there is a natural equivalence between its
opposite category and a category of complexes with objects in `Vᵒᵖ`. -/
@[simps]
def opEquivalence : (HomologicalComplex V c)ᵒᵖ ≌ HomologicalComplex Vᵒᵖ c.symm where
  functor := opFunctor V c
  inverse := opInverse V c
  unitIso := opUnitIso V c
  counitIso := opCounitIso V c
  functor_unitIso_comp X := by
    ext
    simp only [opUnitIso, opCounitIso, NatIso.ofComponents_hom_app, Iso.op_hom, comp_f,
      opFunctor_map_f, Quiver.Hom.unop_op, Hom.isoOfComponents_hom_f]
    

Proof state:
case h
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.110202, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : (HomologicalComplex V c)ᵒᵖ
i✝ : ι
⊢ (Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i✝)).hom.op ≫
      (Iso.refl (HomologicalComplex.X ((opInverse V c ⋙ opFunctor V c).obj ((opFunctor V c).obj X)) i✝)).hom =
    Hom.f (𝟙 ((opFunctor V c).obj X)) i✝

Next tactic:
exact Category.comp_id _
/-- Auxiliary definition for `unopEquivalence`. -/
@[simps]
def unopFunctor : (HomologicalComplex Vᵒᵖ c)ᵒᵖ ⥤ HomologicalComplex V c.symm where
  obj X := (unop X).unop
  map f :=
    { f := fun i => (f.unop.f i).unop
      comm' := fun i j _ => by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.112048, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X✝ Y✝ : (HomologicalComplex Vᵒᵖ c)ᵒᵖ
f : X✝ ⟶ Y✝
i j : ι
x✝ : ComplexShape.Rel (ComplexShape.symm c) i j
⊢ (fun i => (Hom.f f.unop i).unop) i ≫ d ((fun X => HomologicalComplex.unop X.unop) Y✝) i j =
    d ((fun X => HomologicalComplex.unop X.unop) X✝) i j ≫ (fun i => (Hom.f f.unop i).unop) j

Next tactic:
simp only [unop_d, ← unop_comp, f.unop.comm]
/-- Auxiliary definition for `unopEquivalence`. -/
@[simps]
def unopInverse : HomologicalComplex V c.symm ⥤ (HomologicalComplex Vᵒᵖ c)ᵒᵖ where
  obj X := op X.opSymm
  map f := Quiver.Hom.op
    { f := fun i => (f.f i).op
      comm' := fun i j _ => by 

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.120694, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X✝ Y✝ : HomologicalComplex V (ComplexShape.symm c)
f : X✝ ⟶ Y✝
i j : ι
x✝ : ComplexShape.Rel c i j
⊢ (fun i => (Hom.f f i).op) i ≫ d (HomologicalComplex.opSymm X✝) i j =
    d (HomologicalComplex.opSymm Y✝) i j ≫ (fun i => (Hom.f f i).op) j

Next tactic:
simp only [opSymm_d, ← op_comp, f.comm]
/-- Auxiliary definition for `unopEquivalence`. -/
def unopUnitIso : 𝟭 (HomologicalComplex Vᵒᵖ c)ᵒᵖ ≅ unopFunctor V c ⋙ unopInverse V c :=
  NatIso.ofComponents
    (fun X =>
      (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by
            

Proof state:
ι : Type u_1
V : Type u_2
inst✝¹ : Category.{?u.128766, u_2} V
c : ComplexShape ι
inst✝ : Preadditive V
X : (HomologicalComplex Vᵒᵖ c)ᵒᵖ
i j : ι
x✝ : ComplexShape.Rel c i j
⊢ ((fun i => Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)) i).hom ≫
      d X.unop i j =
    d (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i j ≫
      ((fun i => Iso.refl (HomologicalComplex.X (HomologicalComplex.unopSymm (HomologicalComplex.op X.unop)) i)) j).hom

Next tactic:
simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op,
              Category.comp_id]