/-
Copyright (c) 2022 Scott Morrison. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Scott Morrison, Joël Riou

! This file was ported from Lean 3 source module category_theory.comm_sq
! leanprover-community/mathlib commit 23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.CategoryTheory.Arrow

/-!
# Commutative squares

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

This file provide an API for commutative squares in categories.
If `top`, `left`, `right` and `bottom` are four morphisms which are the edges
of a square, `comm_sq top left right bottom` is the predicate that this
square is commutative.

The structure `comm_sq` is extended in `category_theory/shapes/limits/comm_sq.lean`
as `is_pullback` and `is_pushout` in order to define pullback and pushout squares.

## Future work

Refactor `lift_struct` from `arrow.lean` and lifting properties using `comm_sq.lean`.

-/

namespace CategoryTheory

variable {C : Type _} [Category C]

#print CategoryTheory.CommSq /-
/-- The proposition that a square
```
  W ---f---> X
  |          |
  g          h
  |          |
  v          v
  Y ---i---> Z

```
is a commuting square.
-/
structure CommSq {W X Y Z : C} (f : W ⟶ X) (g : W ⟶ Y) (h : X ⟶ Z) (i : Y ⟶ Z) : Prop where
  w : f ≫ h = g ≫ i
#align category_theory.comm_sq CategoryTheory.CommSq
-/

attribute [reassoc.1] comm_sq.w

namespace CommSq

variable {W X Y Z : C} {f : W ⟶ X} {g : W ⟶ Y} {h : X ⟶ Z} {i : Y ⟶ Z}

/- warning: category_theory.comm_sq.flip -> CategoryTheory.CommSq.flip is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W X} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W Y} {h : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u1, u2} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u1, u2} C _inst_1 W Y X Z g f i h)
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W X} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W Y} {h : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Z} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u2, u1} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u2, u1} C _inst_1 W Y X Z g f i h)
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.flip CategoryTheory.CommSq.flipₓ'. -/
theorem flip (p : CommSq f g h i) : CommSq g f i h :=
  ⟨p.w.symm⟩
#align category_theory.comm_sq.flip CategoryTheory.CommSq.flip

/- warning: category_theory.comm_sq.of_arrow -> CategoryTheory.CommSq.of_arrow is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {f : CategoryTheory.Arrow.{u2, u1} C _inst_1} {g : CategoryTheory.Arrow.{u2, u1} C _inst_1} (h : Quiver.Hom.{succ u2, max u1 u2} (CategoryTheory.Arrow.{u2, u1} C _inst_1) (CategoryTheory.CategoryStruct.toQuiver.{u2, max u1 u2} (CategoryTheory.Arrow.{u2, u1} C _inst_1) (CategoryTheory.Category.toCategoryStruct.{u2, max u1 u2} (CategoryTheory.Arrow.{u2, u1} C _inst_1) (CategoryTheory.Arrow.category.{u2, u1} C _inst_1))) f g), CategoryTheory.CommSq.{u1, u2} C _inst_1 (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Comma.left.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f)) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Comma.right.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f)) (CategoryTheory.Comma.left.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) g) (CategoryTheory.Comma.right.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) g) (CategoryTheory.Comma.hom.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f) (CategoryTheory.CommaMorphism.left.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f g h) (CategoryTheory.CommaMorphism.right.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f g h) (CategoryTheory.Comma.hom.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) g)
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {f : CategoryTheory.Arrow.{u2, u1} C _inst_1} {g : CategoryTheory.Arrow.{u2, u1} C _inst_1} (h : Quiver.Hom.{succ u2, max u1 u2} (CategoryTheory.Arrow.{u2, u1} C _inst_1) (CategoryTheory.CategoryStruct.toQuiver.{u2, max u1 u2} (CategoryTheory.Arrow.{u2, u1} C _inst_1) (CategoryTheory.Category.toCategoryStruct.{u2, max u1 u2} (CategoryTheory.Arrow.{u2, u1} C _inst_1) (CategoryTheory.instCategoryArrow.{u2, u1} C _inst_1))) f g), CategoryTheory.CommSq.{u1, u2} C _inst_1 (Prefunctor.obj.{succ u2, succ u2, u1, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, u1} C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1)) (CategoryTheory.Comma.left.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f)) (Prefunctor.obj.{succ u2, succ u2, u1, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, u1} C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1)) (CategoryTheory.Comma.right.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f)) (CategoryTheory.Comma.left.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) g) (CategoryTheory.Comma.right.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) g) (CategoryTheory.Comma.hom.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f) (CategoryTheory.CommaMorphism.left.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f g h) (CategoryTheory.CommaMorphism.right.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) f g h) (CategoryTheory.Comma.hom.{u2, u2, u2, u1, u1, u1} C _inst_1 C _inst_1 C _inst_1 (CategoryTheory.Functor.id.{u2, u1} C _inst_1) (CategoryTheory.Functor.id.{u2, u1} C _inst_1) g)
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.of_arrow CategoryTheory.CommSq.of_arrowₓ'. -/
theorem of_arrow {f g : Arrow C} (h : f ⟶ g) : CommSq f.Hom h.left h.right g.Hom :=
  ⟨h.w.symm⟩
#align category_theory.comm_sq.of_arrow CategoryTheory.CommSq.of_arrow

/- warning: category_theory.comm_sq.op -> CategoryTheory.CommSq.op is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W X} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W Y} {h : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u1, u2} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) (Opposite.op.{succ u1} C Z) (Opposite.op.{succ u1} C Y) (Opposite.op.{succ u1} C X) (Opposite.op.{succ u1} C W) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z i) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z h) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W Y g) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W X f))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W X} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W Y} {h : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Z} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u2, u1} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u2, u1} (Opposite.{succ u2} C) (CategoryTheory.Category.opposite.{u1, u2} C _inst_1) (Opposite.op.{succ u2} C Z) (Opposite.op.{succ u2} C Y) (Opposite.op.{succ u2} C X) (Opposite.op.{succ u2} C W) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) Y Z i) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Z h) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W Y g) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W X f))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.op CategoryTheory.CommSq.opₓ'. -/
/-- The commutative square in the opposite category associated to a commutative square. -/
theorem op (p : CommSq f g h i) : CommSq i.op h.op g.op f.op :=
  ⟨by simp only [← op_comp, p.w]⟩
#align category_theory.comm_sq.op CategoryTheory.CommSq.op

/- warning: category_theory.comm_sq.unop -> CategoryTheory.CommSq.unop is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {W : Opposite.{succ u1} C} {X : Opposite.{succ u1} C} {Y : Opposite.{succ u1} C} {Z : Opposite.{succ u1} C} {f : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) W X} {g : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) W Y} {h : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) X Z} {i : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) Y Z}, (CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) W X Y Z f g h i) -> (CategoryTheory.CommSq.{u1, u2} C _inst_1 (Opposite.unop.{succ u1} C Z) (Opposite.unop.{succ u1} C Y) (Opposite.unop.{succ u1} C X) (Opposite.unop.{succ u1} C W) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z i) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z h) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W Y g) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W X f))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {W : Opposite.{succ u2} C} {X : Opposite.{succ u2} C} {Y : Opposite.{succ u2} C} {Z : Opposite.{succ u2} C} {f : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) W X} {g : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) W Y} {h : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) X Z} {i : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) Y Z}, (CategoryTheory.CommSq.{u2, u1} (Opposite.{succ u2} C) (CategoryTheory.Category.opposite.{u1, u2} C _inst_1) W X Y Z f g h i) -> (CategoryTheory.CommSq.{u2, u1} C _inst_1 (Opposite.unop.{succ u2} C Z) (Opposite.unop.{succ u2} C Y) (Opposite.unop.{succ u2} C X) (Opposite.unop.{succ u2} C W) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) Y Z i) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Z h) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W Y g) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) W X f))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.unop CategoryTheory.CommSq.unopₓ'. -/
/-- The commutative square associated to a commutative square in the opposite category. -/
theorem unop {W X Y Z : Cᵒᵖ} {f : W ⟶ X} {g : W ⟶ Y} {h : X ⟶ Z} {i : Y ⟶ Z} (p : CommSq f g h i) :
    CommSq i.unop h.unop g.unop f.unop :=
  ⟨by simp only [← unop_comp, p.w]⟩
#align category_theory.comm_sq.unop CategoryTheory.CommSq.unop

end CommSq

namespace Functor

variable {D : Type _} [Category D]

variable (F : C ⥤ D) {W X Y Z : C} {f : W ⟶ X} {g : W ⟶ Y} {h : X ⟶ Z} {i : Y ⟶ Z}

/- warning: category_theory.functor.map_comm_sq -> CategoryTheory.Functor.map_commSq is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W X} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W Y} {h : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u1, u2} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u3, u4} D _inst_2 (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F W) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F Y) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F Z) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F W X f) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F W Y g) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X Z h) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F Y Z i))
but is expected to have type
  forall {C : Type.{u4}} [_inst_1 : CategoryTheory.Category.{u3, u4} C] {D : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u3, u1, u4, u2} C _inst_1 D _inst_2) {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) W X} {g : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) W Y} {h : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) X Z} {i : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u4, u3} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u2, u1} D _inst_2 (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) W) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) X) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) Y) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) Z) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) W X f) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) W Y g) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) X Z h) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) Y Z i))
Case conversion may be inaccurate. Consider using '#align category_theory.functor.map_comm_sq CategoryTheory.Functor.map_commSqₓ'. -/
theorem map_commSq (s : CommSq f g h i) : CommSq (F.map f) (F.map g) (F.map h) (F.map i) :=
  ⟨by simpa using congr_arg (fun k : W ⟶ Z => F.map k) s.w⟩
#align category_theory.functor.map_comm_sq CategoryTheory.Functor.map_commSq

end Functor

/- warning: category_theory.comm_sq.map -> CategoryTheory.CommSq.map is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W X} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) W Y} {h : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u1, u2} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u3, u4} D _inst_2 (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F W) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F Y) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F Z) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F W X f) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F W Y g) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X Z h) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F Y Z i))
but is expected to have type
  forall {C : Type.{u4}} [_inst_1 : CategoryTheory.Category.{u3, u4} C] {D : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u3, u1, u4, u2} C _inst_1 D _inst_2) {W : C} {X : C} {Y : C} {Z : C} {f : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) W X} {g : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) W Y} {h : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) X Z} {i : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) Y Z}, (CategoryTheory.CommSq.{u4, u3} C _inst_1 W X Y Z f g h i) -> (CategoryTheory.CommSq.{u2, u1} D _inst_2 (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) W) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) X) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) Y) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) Z) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) W X f) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) W Y g) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) X Z h) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) Y Z i))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.map CategoryTheory.CommSq.mapₓ'. -/
alias functor.map_comm_sq ← comm_sq.map
#align category_theory.comm_sq.map CategoryTheory.CommSq.map

namespace CommSq

variable {A B X Y : C} {f : A ⟶ X} {i : A ⟶ B} {p : X ⟶ Y} {g : B ⟶ Y}

#print CategoryTheory.CommSq.LiftStruct /-
/-- The datum of a lift in a commutative square, i.e. a up-right-diagonal
morphism which makes both triangles commute. -/
@[ext, nolint has_nonempty_instance]
structure LiftStruct (sq : CommSq f i p g) where
  l : B ⟶ X
  fac_left' : i ≫ l = f
  fac_right' : l ≫ p = g
#align category_theory.comm_sq.lift_struct CategoryTheory.CommSq.LiftStruct
-/

namespace LiftStruct

restate_axiom fac_left'

restate_axiom fac_right'

/- warning: category_theory.comm_sq.lift_struct.op -> CategoryTheory.CommSq.LiftStruct.op is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} {sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g}, (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 A B X Y f i p g sq) -> (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) (Opposite.op.{succ u1} C Y) (Opposite.op.{succ u1} C X) (Opposite.op.{succ u1} C B) (Opposite.op.{succ u1} C A) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.op.{u1, u2} C _inst_1 A X B Y f i p g sq))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} {sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g}, (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 A B X Y f i p g sq) -> (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) (Opposite.op.{succ u1} C Y) (Opposite.op.{succ u1} C X) (Opposite.op.{succ u1} C B) (Opposite.op.{succ u1} C A) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.op.{u2, u1} C _inst_1 A X B Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.lift_struct.op CategoryTheory.CommSq.LiftStruct.opₓ'. -/
/-- A `lift_struct` for a commutative square gives a `lift_struct` for the
corresponding square in the opposite category. -/
@[simps]
def op {sq : CommSq f i p g} (l : LiftStruct sq) : LiftStruct sq.op
    where
  l := l.l.op
  fac_left' := by rw [← op_comp, l.fac_right]
  fac_right' := by rw [← op_comp, l.fac_left]
#align category_theory.comm_sq.lift_struct.op CategoryTheory.CommSq.LiftStruct.op

/- warning: category_theory.comm_sq.lift_struct.unop -> CategoryTheory.CommSq.LiftStruct.unop is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : Opposite.{succ u1} C} {B : Opposite.{succ u1} C} {X : Opposite.{succ u1} C} {Y : Opposite.{succ u1} C} {f : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A X} {i : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A B} {p : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) X Y} {g : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) B Y} {sq : CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A X B Y f i p g}, (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A B X Y f i p g sq) -> (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 (Opposite.unop.{succ u1} C Y) (Opposite.unop.{succ u1} C X) (Opposite.unop.{succ u1} C B) (Opposite.unop.{succ u1} C A) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.unop.{u1, u2} C _inst_1 A X B Y f i p g sq))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : Opposite.{succ u1} C} {B : Opposite.{succ u1} C} {X : Opposite.{succ u1} C} {Y : Opposite.{succ u1} C} {f : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A X} {i : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A B} {p : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) X Y} {g : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) B Y} {sq : CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A X B Y f i p g}, (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A B X Y f i p g sq) -> (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 (Opposite.unop.{succ u1} C Y) (Opposite.unop.{succ u1} C X) (Opposite.unop.{succ u1} C B) (Opposite.unop.{succ u1} C A) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.unop.{u2, u1} C _inst_1 A X B Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.lift_struct.unop CategoryTheory.CommSq.LiftStruct.unopₓ'. -/
/-- A `lift_struct` for a commutative square in the opposite category
gives a `lift_struct` for the corresponding square in the original category. -/
@[simps]
def unop {A B X Y : Cᵒᵖ} {f : A ⟶ X} {i : A ⟶ B} {p : X ⟶ Y} {g : B ⟶ Y} {sq : CommSq f i p g}
    (l : LiftStruct sq) : LiftStruct sq.unop
    where
  l := l.l.unop
  fac_left' := by rw [← unop_comp, l.fac_right]
  fac_right' := by rw [← unop_comp, l.fac_left]
#align category_theory.comm_sq.lift_struct.unop CategoryTheory.CommSq.LiftStruct.unop

/- warning: category_theory.comm_sq.lift_struct.op_equiv -> CategoryTheory.CommSq.LiftStruct.opEquiv is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g), Equiv.{succ u2, succ u2} (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 A B X Y f i p g sq) (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) (Opposite.op.{succ u1} C Y) (Opposite.op.{succ u1} C X) (Opposite.op.{succ u1} C B) (Opposite.op.{succ u1} C A) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.op.{u1, u2} C _inst_1 A X B Y f i p g sq))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g), Equiv.{succ u2, succ u2} (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 A B X Y f i p g sq) (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) (Opposite.op.{succ u1} C Y) (Opposite.op.{succ u1} C X) (Opposite.op.{succ u1} C B) (Opposite.op.{succ u1} C A) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.op.{u2, u1} C _inst_1 A X B Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.lift_struct.op_equiv CategoryTheory.CommSq.LiftStruct.opEquivₓ'. -/
/-- Equivalences of `lift_struct` for a square and the corresponding square
in the opposite category. -/
@[simps]
def opEquiv (sq : CommSq f i p g) : LiftStruct sq ≃ LiftStruct sq.op
    where
  toFun := op
  invFun := unop
  left_inv := by tidy
  right_inv := by tidy
#align category_theory.comm_sq.lift_struct.op_equiv CategoryTheory.CommSq.LiftStruct.opEquiv

/- warning: category_theory.comm_sq.lift_struct.unop_equiv -> CategoryTheory.CommSq.LiftStruct.unopEquiv is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : Opposite.{succ u1} C} {B : Opposite.{succ u1} C} {X : Opposite.{succ u1} C} {Y : Opposite.{succ u1} C} {f : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A X} {i : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A B} {p : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) X Y} {g : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) B Y} (sq : CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A X B Y f i p g), Equiv.{succ u2, succ u2} (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A B X Y f i p g sq) (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 (Opposite.unop.{succ u1} C Y) (Opposite.unop.{succ u1} C X) (Opposite.unop.{succ u1} C B) (Opposite.unop.{succ u1} C A) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.unop.{u1, u2} C _inst_1 A X B Y f i p g sq))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : Opposite.{succ u1} C} {B : Opposite.{succ u1} C} {X : Opposite.{succ u1} C} {Y : Opposite.{succ u1} C} {f : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A X} {i : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A B} {p : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) X Y} {g : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) B Y} (sq : CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A X B Y f i p g), Equiv.{succ u2, succ u2} (CategoryTheory.CommSq.LiftStruct.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A B X Y f i p g sq) (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 (Opposite.unop.{succ u1} C Y) (Opposite.unop.{succ u1} C X) (Opposite.unop.{succ u1} C B) (Opposite.unop.{succ u1} C A) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.unop.{u2, u1} C _inst_1 A X B Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.lift_struct.unop_equiv CategoryTheory.CommSq.LiftStruct.unopEquivₓ'. -/
/-- Equivalences of `lift_struct` for a square in the oppositive category and
the corresponding square in the original category. -/
def unopEquiv {A B X Y : Cᵒᵖ} {f : A ⟶ X} {i : A ⟶ B} {p : X ⟶ Y} {g : B ⟶ Y}
    (sq : CommSq f i p g) : LiftStruct sq ≃ LiftStruct sq.unop
    where
  toFun := unop
  invFun := op
  left_inv := by tidy
  right_inv := by tidy
#align category_theory.comm_sq.lift_struct.unop_equiv CategoryTheory.CommSq.LiftStruct.unopEquiv

end LiftStruct

#print CategoryTheory.CommSq.subsingleton_liftStruct_of_epi /-
instance subsingleton_liftStruct_of_epi (sq : CommSq f i p g) [Epi i] :
    Subsingleton (LiftStruct sq) :=
  ⟨fun l₁ l₂ => by
    ext
    simp only [← cancel_epi i, lift_struct.fac_left]⟩
#align category_theory.comm_sq.subsingleton_lift_struct_of_epi CategoryTheory.CommSq.subsingleton_liftStruct_of_epi
-/

#print CategoryTheory.CommSq.subsingleton_liftStruct_of_mono /-
instance subsingleton_liftStruct_of_mono (sq : CommSq f i p g) [Mono p] :
    Subsingleton (LiftStruct sq) :=
  ⟨fun l₁ l₂ => by
    ext
    simp only [← cancel_mono p, lift_struct.fac_right]⟩
#align category_theory.comm_sq.subsingleton_lift_struct_of_mono CategoryTheory.CommSq.subsingleton_liftStruct_of_mono
-/

variable (sq : CommSq f i p g)

#print CategoryTheory.CommSq.HasLift /-
/-- The assertion that a square has a `lift_struct`. -/
class HasLift : Prop where
  exists_lift : Nonempty sq.LiftStruct
#align category_theory.comm_sq.has_lift CategoryTheory.CommSq.HasLift
-/

namespace HasLift

variable {sq}

/- warning: category_theory.comm_sq.has_lift.mk' -> CategoryTheory.CommSq.HasLift.mk' is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} {sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g}, (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 A B X Y f i p g sq) -> (CategoryTheory.CommSq.HasLift.{u1, u2} C _inst_1 A B X Y f i p g sq)
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B} {p : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y} {sq : CategoryTheory.CommSq.{u2, u1} C _inst_1 A X B Y f i p g}, (CategoryTheory.CommSq.LiftStruct.{u2, u1} C _inst_1 A B X Y f i p g sq) -> (CategoryTheory.CommSq.HasLift.{u2, u1} C _inst_1 A B X Y f i p g sq)
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.has_lift.mk' CategoryTheory.CommSq.HasLift.mk'ₓ'. -/
theorem mk' (l : sq.LiftStruct) : HasLift sq :=
  ⟨Nonempty.intro l⟩
#align category_theory.comm_sq.has_lift.mk' CategoryTheory.CommSq.HasLift.mk'

variable (sq)

/- warning: category_theory.comm_sq.has_lift.iff -> CategoryTheory.CommSq.HasLift.iff is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g), Iff (CategoryTheory.CommSq.HasLift.{u1, u2} C _inst_1 A B X Y f i p g sq) (Nonempty.{succ u2} (CategoryTheory.CommSq.LiftStruct.{u1, u2} C _inst_1 A B X Y f i p g sq))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B} {p : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u2, u1} C _inst_1 A X B Y f i p g), Iff (CategoryTheory.CommSq.HasLift.{u2, u1} C _inst_1 A B X Y f i p g sq) (Nonempty.{succ u1} (CategoryTheory.CommSq.LiftStruct.{u2, u1} C _inst_1 A B X Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.has_lift.iff CategoryTheory.CommSq.HasLift.iffₓ'. -/
theorem iff : HasLift sq ↔ Nonempty sq.LiftStruct :=
  by
  constructor
  exacts[fun h => h.exists_lift, fun h => mk h]
#align category_theory.comm_sq.has_lift.iff CategoryTheory.CommSq.HasLift.iff

/- warning: category_theory.comm_sq.has_lift.iff_op -> CategoryTheory.CommSq.HasLift.iff_op is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g), Iff (CategoryTheory.CommSq.HasLift.{u1, u2} C _inst_1 A B X Y f i p g sq) (CategoryTheory.CommSq.HasLift.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) (Opposite.op.{succ u1} C Y) (Opposite.op.{succ u1} C X) (Opposite.op.{succ u1} C B) (Opposite.op.{succ u1} C A) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.op.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.op.{u1, u2} C _inst_1 A X B Y f i p g sq))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B} {p : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u2, u1} C _inst_1 A X B Y f i p g), Iff (CategoryTheory.CommSq.HasLift.{u2, u1} C _inst_1 A B X Y f i p g sq) (CategoryTheory.CommSq.HasLift.{u2, u1} (Opposite.{succ u2} C) (CategoryTheory.Category.opposite.{u1, u2} C _inst_1) (Opposite.op.{succ u2} C Y) (Opposite.op.{succ u2} C X) (Opposite.op.{succ u2} C B) (Opposite.op.{succ u2} C A) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y g) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y p) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B i) (Quiver.Hom.op.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X f) (CategoryTheory.CommSq.op.{u1, u2} C _inst_1 A X B Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.has_lift.iff_op CategoryTheory.CommSq.HasLift.iff_opₓ'. -/
theorem iff_op : HasLift sq ↔ HasLift sq.op :=
  by
  rw [Iff, Iff]
  exact Nonempty.congr (lift_struct.op_equiv sq).toFun (lift_struct.op_equiv sq).invFun
#align category_theory.comm_sq.has_lift.iff_op CategoryTheory.CommSq.HasLift.iff_op

/- warning: category_theory.comm_sq.has_lift.iff_unop -> CategoryTheory.CommSq.HasLift.iff_unop is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : Opposite.{succ u1} C} {B : Opposite.{succ u1} C} {X : Opposite.{succ u1} C} {Y : Opposite.{succ u1} C} {f : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A X} {i : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) A B} {p : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) X Y} {g : Quiver.Hom.{succ u2, u1} (Opposite.{succ u1} C) (Quiver.opposite.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) B Y} (sq : CategoryTheory.CommSq.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A X B Y f i p g), Iff (CategoryTheory.CommSq.HasLift.{u1, u2} (Opposite.{succ u1} C) (CategoryTheory.Category.opposite.{u2, u1} C _inst_1) A B X Y f i p g sq) (CategoryTheory.CommSq.HasLift.{u1, u2} C _inst_1 (Opposite.unop.{succ u1} C Y) (Opposite.unop.{succ u1} C X) (Opposite.unop.{succ u1} C B) (Opposite.unop.{succ u1} C A) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y g) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y p) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B i) (Quiver.Hom.unop.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X f) (CategoryTheory.CommSq.unop.{u1, u2} C _inst_1 A X B Y f i p g sq))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {A : Opposite.{succ u2} C} {B : Opposite.{succ u2} C} {X : Opposite.{succ u2} C} {Y : Opposite.{succ u2} C} {f : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) A X} {i : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) A B} {p : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) X Y} {g : Quiver.Hom.{succ u1, u2} (Opposite.{succ u2} C) (Quiver.opposite.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) B Y} (sq : CategoryTheory.CommSq.{u2, u1} (Opposite.{succ u2} C) (CategoryTheory.Category.opposite.{u1, u2} C _inst_1) A X B Y f i p g), Iff (CategoryTheory.CommSq.HasLift.{u2, u1} (Opposite.{succ u2} C) (CategoryTheory.Category.opposite.{u1, u2} C _inst_1) A B X Y f i p g sq) (CategoryTheory.CommSq.HasLift.{u2, u1} C _inst_1 (Opposite.unop.{succ u2} C Y) (Opposite.unop.{succ u2} C X) (Opposite.unop.{succ u2} C B) (Opposite.unop.{succ u2} C A) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y g) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y p) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B i) (Quiver.Hom.unop.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X f) (CategoryTheory.CommSq.unop.{u1, u2} C _inst_1 A X B Y f i p g sq))
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.has_lift.iff_unop CategoryTheory.CommSq.HasLift.iff_unopₓ'. -/
theorem iff_unop {A B X Y : Cᵒᵖ} {f : A ⟶ X} {i : A ⟶ B} {p : X ⟶ Y} {g : B ⟶ Y}
    (sq : CommSq f i p g) : HasLift sq ↔ HasLift sq.unop :=
  by
  rw [Iff, Iff]
  exact Nonempty.congr (lift_struct.unop_equiv sq).toFun (lift_struct.unop_equiv sq).invFun
#align category_theory.comm_sq.has_lift.iff_unop CategoryTheory.CommSq.HasLift.iff_unop

end HasLift

#print CategoryTheory.CommSq.lift /-
/-- A choice of a diagonal morphism that is part of a `lift_struct` when
the square has a lift. -/
noncomputable def lift [hsq : HasLift sq] : B ⟶ X :=
  hsq.exists_lift.some.l
#align category_theory.comm_sq.lift CategoryTheory.CommSq.lift
-/

/- warning: category_theory.comm_sq.fac_left -> CategoryTheory.CommSq.fac_left is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g) [hsq : CategoryTheory.CommSq.HasLift.{u1, u2} C _inst_1 A B X Y f i p g sq], Eq.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X) (CategoryTheory.CategoryStruct.comp.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) A B X i (CategoryTheory.CommSq.lift.{u1, u2} C _inst_1 A B X Y f i p g sq hsq)) f
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B} {p : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u2, u1} C _inst_1 A X B Y f i p g) [hsq : CategoryTheory.CommSq.HasLift.{u2, u1} C _inst_1 A B X Y f i p g sq], Eq.{succ u1} (Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X) (CategoryTheory.CategoryStruct.comp.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1) A B X i (CategoryTheory.CommSq.lift.{u2, u1} C _inst_1 A B X Y f i p g sq hsq)) f
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.fac_left CategoryTheory.CommSq.fac_leftₓ'. -/
@[simp, reassoc.1]
theorem fac_left [hsq : HasLift sq] : i ≫ sq.lift = f :=
  hsq.exists_lift.some.fac_left
#align category_theory.comm_sq.fac_left CategoryTheory.CommSq.fac_left

/- warning: category_theory.comm_sq.fac_right -> CategoryTheory.CommSq.fac_right is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A X} {i : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) A B} {p : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u1, u2} C _inst_1 A X B Y f i p g) [hsq : CategoryTheory.CommSq.HasLift.{u1, u2} C _inst_1 A B X Y f i p g sq], Eq.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) B Y) (CategoryTheory.CategoryStruct.comp.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) B X Y (CategoryTheory.CommSq.lift.{u1, u2} C _inst_1 A B X Y f i p g sq hsq) p) g
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] {A : C} {B : C} {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A X} {i : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) A B} {p : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y} (sq : CategoryTheory.CommSq.{u2, u1} C _inst_1 A X B Y f i p g) [hsq : CategoryTheory.CommSq.HasLift.{u2, u1} C _inst_1 A B X Y f i p g sq], Eq.{succ u1} (Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) B Y) (CategoryTheory.CategoryStruct.comp.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1) B X Y (CategoryTheory.CommSq.lift.{u2, u1} C _inst_1 A B X Y f i p g sq hsq) p) g
Case conversion may be inaccurate. Consider using '#align category_theory.comm_sq.fac_right CategoryTheory.CommSq.fac_rightₓ'. -/
@[simp, reassoc.1]
theorem fac_right [hsq : HasLift sq] : sq.lift ≫ p = g :=
  hsq.exists_lift.some.fac_right
#align category_theory.comm_sq.fac_right CategoryTheory.CommSq.fac_right

end CommSq

end CategoryTheory