l3lab/ntp-mathlib huggingface dataset:
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> 

Proof state:
case some.left.none
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
f : some WalkingPair.left ⟶ none
⊢ (cospan f✝.op g.op).map f ≫
      (Option.casesOn none (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f✝ g).op).map f

Next tactic:
cases f
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> 

Proof state:
case some.left.some.left
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
f : some WalkingPair.left ⟶ some WalkingPair.left
⊢ (cospan f✝.op g.op).map f ≫
      (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f✝ g).op).map f

Next tactic:
cases f
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> 

Proof state:
case some.left.some.right
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
f : some WalkingPair.left ⟶ some WalkingPair.right
⊢ (cospan f✝.op g.op).map f ≫
      (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f✝ g).op).map f

Next tactic:
cases f
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> 

Proof state:
case some.right.none
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
f : some WalkingPair.right ⟶ none
⊢ (cospan f✝.op g.op).map f ≫
      (Option.casesOn none (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f✝ g).op).map f

Next tactic:
cases f
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> 

Proof state:
case some.right.some.left
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
f : some WalkingPair.right ⟶ some WalkingPair.left
⊢ (cospan f✝.op g.op).map f ≫
      (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f✝ g).op).map f

Next tactic:
cases f
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> 

Proof state:
case some.right.some.right
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f✝ : X ⟶ Y
g : X ⟶ Z
f : some WalkingPair.right ⟶ some WalkingPair.right
⊢ (cospan f✝.op g.op).map f ≫
      (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f✝.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f✝.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f✝ g).op).map f

Next tactic:
cases f
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> 

Proof state:
case none.none.id
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
⊢ (cospan f.op g.op).map (WidePullbackShape.Hom.id none) ≫
      (Option.casesOn none (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn none (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f g).op).map (WidePullbackShape.Hom.id none)

Next tactic:
aesop_cat
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> 

Proof state:
case some.left.none.term
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
⊢ (cospan f.op g.op).map (WidePullbackShape.Hom.term WalkingPair.left) ≫
      (Option.casesOn none (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f g).op).map (WidePullbackShape.Hom.term WalkingPair.left)

Next tactic:
aesop_cat
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> 

Proof state:
case some.left.some.left.id
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
⊢ (cospan f.op g.op).map (WidePullbackShape.Hom.id (some WalkingPair.left)) ≫
      (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.left) (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f g).op).map (WidePullbackShape.Hom.id (some WalkingPair.left))

Next tactic:
aesop_cat
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> 

Proof state:
case some.right.none.term
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
⊢ (cospan f.op g.op).map (WidePullbackShape.Hom.term WalkingPair.right) ≫
      (Option.casesOn none (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f g).op).map (WidePullbackShape.Hom.term WalkingPair.right)

Next tactic:
aesop_cat
/-- The canonical isomorphism relating `Cospan f.op g.op` and `(Span f g).op` -/
@[simps!]
def cospanOp {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    cospan f.op g.op ≅ walkingSpanOpEquiv.inverse ⋙ (span f g).op :=
  NatIso.ofComponents (by rintro (_ | _ | _) <;> rfl)
    (by rintro (_ | _ | _) (_ | _ | _) f <;> cases f <;> 

Proof state:
case some.right.some.right.id
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
⊢ (cospan f.op g.op).map (WidePullbackShape.Hom.id (some WalkingPair.right)) ≫
      (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom =
    (Option.casesOn (some WalkingPair.right) (Iso.refl ((cospan f.op g.op).obj none)) fun val =>
          WalkingPair.casesOn val (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.left)))
            (Iso.refl ((cospan f.op g.op).obj (some WalkingPair.right)))).hom ≫
      (walkingSpanOpEquiv.inverse ⋙ (span f g).op).map (WidePullbackShape.Hom.id (some WalkingPair.right))

Next tactic:
aesop_cat
/-- The canonical isomorphism relating `(Span f g).op` and `Cospan f.op g.op` -/
@[simps!]
def opSpan {X Y Z : C} (f : X ⟶ Y) (g : X ⟶ Z) :
    (span f g).op ≅ walkingSpanOpEquiv.functor ⋙ cospan f.op g.op :=
  calc
    (span f g).op ≅ 𝟭 _ ⋙ (span f g).op := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
⊢ (span f g).op ≅ 𝟭 WalkingSpanᵒᵖ ⋙ (span f g).op

Next tactic:
rfl
theorem unop_fst {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    c.unop.fst = c.inl.unop := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ PullbackCone.fst (unop c) = (inl c).unop

Next tactic:
simp
theorem unop_snd {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    c.unop.snd = c.inr.unop := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ PullbackCone.snd (unop c) = (inr c).unop

Next tactic:
aesop_cat
theorem op_fst {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.fst = c.inl.op :=
  by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ PullbackCone.fst (op c) = (inl c).op

Next tactic:
aesop_cat
theorem op_snd {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.snd = c.inr.op :=
  by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ PullbackCone.snd (op c) = (inr c).op

Next tactic:
aesop_cat
theorem unop_inl {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) :
    c.unop.inl = c.fst.unop := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ PushoutCocone.inl (unop c) = (fst c).unop

Next tactic:
aesop_cat
theorem unop_inr {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) :
    c.unop.inr = c.snd.unop := by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ PushoutCocone.inr (unop c) = (snd c).unop

Next tactic:
aesop_cat
theorem op_inl {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.inl = c.fst.op :=
  by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ PushoutCocone.inl (op c) = (fst c).op

Next tactic:
aesop_cat
theorem op_inr {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.inr = c.snd.op :=
  by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ PushoutCocone.inr (op c) = (snd c).op

Next tactic:
aesop_cat
/-- If `c` is a pullback cone, then `c.op.unop` is isomorphic to `c`. -/
def opUnop {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.unop ≅ c :=
  PullbackCone.ext (Iso.refl _) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ fst (PushoutCocone.unop (op c)) = (Iso.refl (PushoutCocone.unop (op c)).pt).hom ≫ fst c

Next tactic:
simp
/-- If `c` is a pullback cone, then `c.op.unop` is isomorphic to `c`. -/
def opUnop {X Y Z : C} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.op.unop ≅ c :=
  PullbackCone.ext (Iso.refl _) (by simp) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ snd (PushoutCocone.unop (op c)) = (Iso.refl (PushoutCocone.unop (op c)).pt).hom ≫ snd c

Next tactic:
simp
/-- If `c` is a pullback cone in `Cᵒᵖ`, then `c.unop.op` is isomorphic to `c`. -/
def unopOp {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.unop.op ≅ c :=
  PullbackCone.ext (Iso.refl _) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ fst (PushoutCocone.op (unop c)) = (Iso.refl (PushoutCocone.op (unop c)).pt).hom ≫ fst c

Next tactic:
simp
/-- If `c` is a pullback cone in `Cᵒᵖ`, then `c.unop.op` is isomorphic to `c`. -/
def unopOp {X Y Z : Cᵒᵖ} {f : X ⟶ Z} {g : Y ⟶ Z} (c : PullbackCone f g) : c.unop.op ≅ c :=
  PullbackCone.ext (Iso.refl _) (by simp) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Z
g : Y ⟶ Z
c : PullbackCone f g
⊢ snd (PushoutCocone.op (unop c)) = (Iso.refl (PushoutCocone.op (unop c)).pt).hom ≫ snd c

Next tactic:
simp
/-- If `c` is a pushout cocone, then `c.op.unop` is isomorphic to `c`. -/
def opUnop {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.unop ≅ c :=
  PushoutCocone.ext (Iso.refl _) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ inl (PullbackCone.unop (op c)) ≫ (Iso.refl (PullbackCone.unop (op c)).pt).hom = inl c

Next tactic:
simp
/-- If `c` is a pushout cocone, then `c.op.unop` is isomorphic to `c`. -/
def opUnop {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.op.unop ≅ c :=
  PushoutCocone.ext (Iso.refl _) (by simp) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ inr (PullbackCone.unop (op c)) ≫ (Iso.refl (PullbackCone.unop (op c)).pt).hom = inr c

Next tactic:
simp
/-- If `c` is a pushout cocone in `Cᵒᵖ`, then `c.unop.op` is isomorphic to `c`. -/
def unopOp {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.unop.op ≅ c :=
  PushoutCocone.ext (Iso.refl _) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ inl (PullbackCone.op (unop c)) ≫ (Iso.refl (PullbackCone.op (unop c)).pt).hom = inl c

Next tactic:
simp
/-- If `c` is a pushout cocone in `Cᵒᵖ`, then `c.unop.op` is isomorphic to `c`. -/
def unopOp {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) : c.unop.op ≅ c :=
  PushoutCocone.ext (Iso.refl _) (by simp) (by 

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ inr (PullbackCone.op (unop c)) ≫ (Iso.refl (PullbackCone.op (unop c)).pt).hom = inr c

Next tactic:
simp
/-- A pushout cone is a colimit cocone if and only if the corresponding pullback cone
in the opposite category is a limit cone. -/
def isColimitEquivIsLimitOp {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.op := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ IsColimit c ≃ IsLimit (op c)

Next tactic:
apply equivOfSubsingletonOfSubsingleton
/-- A pushout cone is a colimit cocone if and only if the corresponding pullback cone
in the opposite category is a limit cone. -/
def isColimitEquivIsLimitOp {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.op := by
  apply equivOfSubsingletonOfSubsingleton
  · 

Proof state:
case f
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ IsColimit c → IsLimit (op c)

Next tactic:
intro h
/-- A pushout cone is a colimit cocone if and only if the corresponding pullback cone
in the opposite category is a limit cone. -/
def isColimitEquivIsLimitOp {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.op := by
  apply equivOfSubsingletonOfSubsingleton
  · intro h
    

Proof state:
case f
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
h : IsColimit c
⊢ IsLimit (op c)

Next tactic:
exact (IsLimit.postcomposeHomEquiv _ _).invFun
      ((IsLimit.whiskerEquivalenceEquiv walkingSpanOpEquiv.symm).toFun (isLimitCoconeOp _ h))
/-- A pushout cone is a colimit cocone if and only if the corresponding pullback cone
in the opposite category is a limit cone. -/
def isColimitEquivIsLimitOp {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.op := by
  apply equivOfSubsingletonOfSubsingleton
  · intro h
    exact (IsLimit.postcomposeHomEquiv _ _).invFun
      ((IsLimit.whiskerEquivalenceEquiv walkingSpanOpEquiv.symm).toFun (isLimitCoconeOp _ h))
  · 

Proof state:
case g
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ IsLimit (op c) → IsColimit c

Next tactic:
intro h
/-- A pushout cone is a colimit cocone if and only if the corresponding pullback cone
in the opposite category is a limit cone. -/
def isColimitEquivIsLimitOp {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.op := by
  apply equivOfSubsingletonOfSubsingleton
  · intro h
    exact (IsLimit.postcomposeHomEquiv _ _).invFun
      ((IsLimit.whiskerEquivalenceEquiv walkingSpanOpEquiv.symm).toFun (isLimitCoconeOp _ h))
  · intro h
    

Proof state:
case g
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : C
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
h : IsLimit (op c)
⊢ IsColimit c

Next tactic:
exact (IsColimit.equivIsoColimit c.opUnop).toFun
      (isColimitConeUnop _ ((IsLimit.postcomposeHomEquiv _ _).invFun
        ((IsLimit.whiskerEquivalenceEquiv _).toFun h)))
/-- A pushout cone is a colimit cocone in `Cᵒᵖ` if and only if the corresponding pullback cone
in `C` is a limit cone. -/
def isColimitEquivIsLimitUnop {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.unop := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ IsColimit c ≃ IsLimit (unop c)

Next tactic:
apply equivOfSubsingletonOfSubsingleton
/-- A pushout cone is a colimit cocone in `Cᵒᵖ` if and only if the corresponding pullback cone
in `C` is a limit cone. -/
def isColimitEquivIsLimitUnop {X Y Z : Cᵒᵖ} {f : X ⟶ Y} {g : X ⟶ Z} (c : PushoutCocone f g) :
    IsColimit c ≃ IsLimit c.unop := by
  apply equivOfSubsingletonOfSubsingleton
  · 

Proof state:
case f
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
J : Type u₂
inst✝ : Category.{v₂, u₂} J
X✝ : Type v₂
X Y Z : Cᵒᵖ
f : X ⟶ Y
g : X ⟶ Z
c : PushoutCocone f g
⊢ IsColimit c → IsLimit (unop c)

Next tactic:
intro h