l3lab/ntp-mathlib huggingface dataset:
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> 

Proof state:
case none.some.init
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
val✝ : J
⊢ F.map (Hom.init val✝) ≫
      (fun j =>
          match j with
          | none => f
          | some j => ι j)
        (some val✝) =
    (fun j =>
          match j with
          | none => f
          | some j => ι j)
        none ≫
      ((Functor.const (WidePushoutShape J)).obj X).map (Hom.init val✝)

Next tactic:
refine id _
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> 

Proof state:
case some.some.id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
val✝ : J
⊢ F.map (Hom.id (some val✝)) ≫
      (fun j =>
          match j with
          | none => f
          | some j => ι j)
        (some val✝) =
    (fun j =>
          match j with
          | none => f
          | some j => ι j)
        (some val✝) ≫
      ((Functor.const (WidePushoutShape J)).obj X).map (Hom.id (some val✝))

Next tactic:
refine id _
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> refine id _ <;> 

Proof state:
case none.none.id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
⊢ F.map (Hom.id none) ≫
      (fun j =>
          match j with
          | none => f
          | some j => ι j)
        none =
    (fun j =>
          match j with
          | none => f
          | some j => ι j)
        none ≫
      ((Functor.const (WidePushoutShape J)).obj X).map (Hom.id none)

Next tactic:
dsimp
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> refine id _ <;> 

Proof state:
case none.some.init
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
val✝ : J
⊢ F.map (Hom.init val✝) ≫
      (fun j =>
          match j with
          | none => f
          | some j => ι j)
        (some val✝) =
    (fun j =>
          match j with
          | none => f
          | some j => ι j)
        none ≫
      ((Functor.const (WidePushoutShape J)).obj X).map (Hom.init val✝)

Next tactic:
dsimp
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> refine id _ <;> 

Proof state:
case some.some.id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
val✝ : J
⊢ F.map (Hom.id (some val✝)) ≫
      (fun j =>
          match j with
          | none => f
          | some j => ι j)
        (some val✝) =
    (fun j =>
          match j with
          | none => f
          | some j => ι j)
        (some val✝) ≫
      ((Functor.const (WidePushoutShape J)).obj X).map (Hom.id (some val✝))

Next tactic:
dsimp
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> refine id _ <;> dsimp <;> 

Proof state:
case none.none.id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
⊢ F.map (𝟙 none) ≫ f = f ≫ 𝟙 X

Next tactic:
simp [w]
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> refine id _ <;> dsimp <;> 

Proof state:
case none.some.init
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
val✝ : J
⊢ F.map (Hom.init val✝) ≫ ι val✝ = f ≫ 𝟙 X

Next tactic:
simp [w]
/-- Construct a cocone over a wide span. -/
@[simps]
def mkCocone {F : WidePushoutShape J ⥤ C} {X : C} (f : F.obj none ⟶ X) (ι : ∀ j, F.obj (some j) ⟶ X)
    (w : ∀ j, F.map (Hom.init j) ≫ ι j = f) : Cocone F :=
  { pt := X
    ι :=
      { app := fun j =>
          match j with
          | none => f
          | some j => ι j
        naturality := fun j j' f => by
          cases j <;> cases j' <;> cases f <;> refine id _ <;> dsimp <;> 

Proof state:
case some.some.id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
F : WidePushoutShape J ⥤ C
X : C
f : F.obj none ⟶ X
ι : (j : J) → F.obj (some j) ⟶ X
w : ∀ (j : J), F.map (Hom.init j) ≫ ι j = f
val✝ : J
⊢ F.map (𝟙 (some val✝)) ≫ ι val✝ = ι val✝ ≫ 𝟙 X

Next tactic:
simp [w]
/-- Wide pushout diagrams of equivalent index types are equivalent. -/
def equivalenceOfEquiv (J' : Type w') (h : J ≃ J') : WidePushoutShape J ≌ WidePushoutShape J'
    where
  functor := wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)
  inverse := wideSpan none (fun j => some (h.invFun j)) fun j => Hom.init (h.invFun j)
  unitIso :=
    NatIso.ofComponents (fun j => by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
J' : Type w'
h : J ≃ J'
j : WidePushoutShape J
⊢ (𝟭 (WidePushoutShape J)).obj j ≅
    ((wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)) ⋙
          wideSpan none (fun j => some (Equiv.invFun h j)) fun j => Hom.init (Equiv.invFun h j)).obj
      j

Next tactic:
aesop_cat
/-- Wide pushout diagrams of equivalent index types are equivalent. -/
def equivalenceOfEquiv (J' : Type w') (h : J ≃ J') : WidePushoutShape J ≌ WidePushoutShape J'
    where
  functor := wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)
  inverse := wideSpan none (fun j => some (h.invFun j)) fun j => Hom.init (h.invFun j)
  unitIso :=
    NatIso.ofComponents (fun j => by aesop_cat) fun f => by
      

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
J' : Type w'
h : J ≃ J'
X✝ Y✝ : WidePushoutShape J
f : X✝ ⟶ Y✝
⊢ (𝟭 (WidePushoutShape J)).map f ≫
      ((fun j =>
            id
              (Option.casesOn j (id (Iso.refl none)) fun val =>
                Eq.mpr
                  (_ :
                    (some val ≅
                        Option.rec none (fun val => some (h.symm val))
                          (Option.rec none (fun val => some (h val)) (some val))) =
                      (some val ≅ some val))
                  (Iso.refl (some val))))
          Y✝).hom =
    ((fun j =>
            id
              (Option.casesOn j (id (Iso.refl none)) fun val =>
                Eq.mpr
                  (_ :
                    (some val ≅
                        Option.rec none (fun val => some (h.symm val))
                          (Option.rec none (fun val => some (h val)) (some val))) =
                      (some val ≅ some val))
                  (Iso.refl (some val))))
          X✝).hom ≫
      ((wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)) ⋙
            wideSpan none (fun j => some (Equiv.invFun h j)) fun j => Hom.init (Equiv.invFun h j)).map
        f

Next tactic:
simp only [eq_iff_true_of_subsingleton]
/-- Wide pushout diagrams of equivalent index types are equivalent. -/
def equivalenceOfEquiv (J' : Type w') (h : J ≃ J') : WidePushoutShape J ≌ WidePushoutShape J'
    where
  functor := wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)
  inverse := wideSpan none (fun j => some (h.invFun j)) fun j => Hom.init (h.invFun j)
  unitIso :=
    NatIso.ofComponents (fun j => by aesop_cat) fun f => by
      simp only [eq_iff_true_of_subsingleton]
  counitIso :=
    NatIso.ofComponents (fun j => by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
J' : Type w'
h : J ≃ J'
j : WidePushoutShape J'
⊢ ((wideSpan none (fun j => some (Equiv.invFun h j)) fun j => Hom.init (Equiv.invFun h j)) ⋙
          wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)).obj
      j ≅
    (𝟭 (WidePushoutShape J')).obj j

Next tactic:
aesop_cat
/-- Wide pushout diagrams of equivalent index types are equivalent. -/
def equivalenceOfEquiv (J' : Type w') (h : J ≃ J') : WidePushoutShape J ≌ WidePushoutShape J'
    where
  functor := wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)
  inverse := wideSpan none (fun j => some (h.invFun j)) fun j => Hom.init (h.invFun j)
  unitIso :=
    NatIso.ofComponents (fun j => by aesop_cat) fun f => by
      simp only [eq_iff_true_of_subsingleton]
  counitIso :=
    NatIso.ofComponents (fun j => by aesop_cat) fun f => by
      

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
J' : Type w'
h : J ≃ J'
X✝ Y✝ : WidePushoutShape J'
f : X✝ ⟶ Y✝
⊢ ((wideSpan none (fun j => some (Equiv.invFun h j)) fun j => Hom.init (Equiv.invFun h j)) ⋙
            wideSpan none (fun j => some (h j)) fun j => Hom.init (h j)).map
        f ≫
      ((fun j =>
            id
              (Option.casesOn j (id (Iso.refl none)) fun val =>
                Eq.mpr
                  (_ :
                    (Option.rec none (fun val => some (h val))
                          (Option.rec none (fun val => some (h.symm val)) (some val)) ≅
                        some val) =
                      (some val ≅ some val))
                  (Iso.refl (some val))))
          Y✝).hom =
    ((fun j =>
            id
              (Option.casesOn j (id (Iso.refl none)) fun val =>
                Eq.mpr
                  (_ :
                    (Option.rec none (fun val => some (h val))
                          (Option.rec none (fun val => some (h.symm val)) (some val)) ≅
                        some val) =
                      (some val ≅ some val))
                  (Iso.refl (some val))))
          X✝).hom ≫
      (𝟭 (WidePushoutShape J')).map f

Next tactic:
simp only [eq_iff_true_of_subsingleton]
@[reassoc (attr := simp)]
theorem π_arrow (j : J) : π arrows j ≫ arrows _ = base arrows := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
j : J
⊢ π arrows j ≫ arrows j = base arrows

Next tactic:
apply limit.w (WidePullbackShape.wideCospan _ _ _) (WidePullbackShape.Hom.term j)
@[reassoc]
theorem lift_π (j : J) : lift f fs w ≫ π arrows j = fs _ := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
j : J
⊢ lift f fs w ≫ π arrows j = fs j

Next tactic:
simp only [limit.lift_π, WidePullbackShape.mkCone_pt, WidePullbackShape.mkCone_π_app]
@[reassoc]
theorem lift_base : lift f fs w ≫ base arrows = f := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
⊢ lift f fs w ≫ base arrows = f

Next tactic:
simp only [limit.lift_π, WidePullbackShape.mkCone_pt, WidePullbackShape.mkCone_π_app]
theorem eq_lift_of_comp_eq (g : X ⟶ widePullback _ _ arrows) :
    (∀ j : J, g ≫ π arrows j = fs j) → g ≫ base arrows = f → g = lift f fs w := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
⊢ (∀ (j : J), g ≫ π arrows j = fs j) → g ≫ base arrows = f → g = lift f fs w

Next tactic:
intro h1 h2
theorem eq_lift_of_comp_eq (g : X ⟶ widePullback _ _ arrows) :
    (∀ j : J, g ≫ π arrows j = fs j) → g ≫ base arrows = f → g = lift f fs w := by
  intro h1 h2
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g ≫ π arrows j = fs j
h2 : g ≫ base arrows = f
⊢ g = lift f fs w

Next tactic:
apply
    (limit.isLimit (WidePullbackShape.wideCospan B objs arrows)).uniq
      (WidePullbackShape.mkCone f fs <| w)
theorem eq_lift_of_comp_eq (g : X ⟶ widePullback _ _ arrows) :
    (∀ j : J, g ≫ π arrows j = fs j) → g ≫ base arrows = f → g = lift f fs w := by
  intro h1 h2
  apply
    (limit.isLimit (WidePullbackShape.wideCospan B objs arrows)).uniq
      (WidePullbackShape.mkCone f fs <| w)
  

Proof state:
case x
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g ≫ π arrows j = fs j
h2 : g ≫ base arrows = f
⊢ ∀ (j : WidePullbackShape J),
    g ≫ (limit.cone (WidePullbackShape.wideCospan B objs arrows)).π.app j = (WidePullbackShape.mkCone f fs w).π.app j

Next tactic:
rintro (_ | _)
theorem eq_lift_of_comp_eq (g : X ⟶ widePullback _ _ arrows) :
    (∀ j : J, g ≫ π arrows j = fs j) → g ≫ base arrows = f → g = lift f fs w := by
  intro h1 h2
  apply
    (limit.isLimit (WidePullbackShape.wideCospan B objs arrows)).uniq
      (WidePullbackShape.mkCone f fs <| w)
  rintro (_ | _)
  · 

Proof state:
case x.none
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g ≫ π arrows j = fs j
h2 : g ≫ base arrows = f
⊢ g ≫ (limit.cone (WidePullbackShape.wideCospan B objs arrows)).π.app none =
    (WidePullbackShape.mkCone f fs w).π.app none

Next tactic:
apply h2
theorem eq_lift_of_comp_eq (g : X ⟶ widePullback _ _ arrows) :
    (∀ j : J, g ≫ π arrows j = fs j) → g ≫ base arrows = f → g = lift f fs w := by
  intro h1 h2
  apply
    (limit.isLimit (WidePullbackShape.wideCospan B objs arrows)).uniq
      (WidePullbackShape.mkCone f fs <| w)
  rintro (_ | _)
  · apply h2
  · 

Proof state:
case x.some
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g ≫ π arrows j = fs j
h2 : g ≫ base arrows = f
val✝ : J
⊢ g ≫ (limit.cone (WidePullbackShape.wideCospan B objs arrows)).π.app (some val✝) =
    (WidePullbackShape.mkCone f fs w).π.app (some val✝)

Next tactic:
apply h1
theorem hom_eq_lift (g : X ⟶ widePullback _ _ arrows) :
    g = lift (g ≫ base arrows) (fun j => g ≫ π arrows j) (by 

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type ?u.193529
inst✝¹ : Category.{v₂, ?u.193529} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
⊢ ∀ (j : J), (fun j => g ≫ π arrows j) j ≫ arrows j = g ≫ base arrows

Next tactic:
aesop_cat
theorem hom_eq_lift (g : X ⟶ widePullback _ _ arrows) :
    g = lift (g ≫ base arrows) (fun j => g ≫ π arrows j) (by aesop_cat) := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
⊢ g = lift (g ≫ base arrows) (fun j => g ≫ π arrows j) (_ : ∀ (j : J), (g ≫ π arrows j) ≫ arrows j = g ≫ base arrows)

Next tactic:
apply eq_lift_of_comp_eq
theorem hom_eq_lift (g : X ⟶ widePullback _ _ arrows) :
    g = lift (g ≫ base arrows) (fun j => g ≫ π arrows j) (by aesop_cat) := by
  apply eq_lift_of_comp_eq
  

Proof state:
case a
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
⊢ ∀ (j : J), g ≫ π arrows j = g ≫ π arrows j
case a
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
⊢ g ≫ base arrows = g ≫ base arrows

Next tactic:
aesop_cat
theorem hom_eq_lift (g : X ⟶ widePullback _ _ arrows) :
    g = lift (g ≫ base arrows) (fun j => g ≫ π arrows j) (by aesop_cat) := by
  apply eq_lift_of_comp_eq
  aesop_cat
  

Proof state:
case a
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g : X ⟶ widePullback B (fun j => objs j) arrows
⊢ g ≫ base arrows = g ≫ base arrows

Next tactic:
rfl
@[ext 1100]
theorem hom_ext (g1 g2 : X ⟶ widePullback _ _ arrows) : (∀ j : J,
    g1 ≫ π arrows j = g2 ≫ π arrows j) → g1 ≫ base arrows = g2 ≫ base arrows → g1 = g2 := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g1 g2 : X ⟶ widePullback B (fun j => objs j) arrows
⊢ (∀ (j : J), g1 ≫ π arrows j = g2 ≫ π arrows j) → g1 ≫ base arrows = g2 ≫ base arrows → g1 = g2

Next tactic:
intro h1 h2
@[ext 1100]
theorem hom_ext (g1 g2 : X ⟶ widePullback _ _ arrows) : (∀ j : J,
    g1 ≫ π arrows j = g2 ≫ π arrows j) → g1 ≫ base arrows = g2 ≫ base arrows → g1 = g2 := by
  intro h1 h2
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g1 g2 : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g1 ≫ π arrows j = g2 ≫ π arrows j
h2 : g1 ≫ base arrows = g2 ≫ base arrows
⊢ g1 = g2

Next tactic:
apply limit.hom_ext
@[ext 1100]
theorem hom_ext (g1 g2 : X ⟶ widePullback _ _ arrows) : (∀ j : J,
    g1 ≫ π arrows j = g2 ≫ π arrows j) → g1 ≫ base arrows = g2 ≫ base arrows → g1 = g2 := by
  intro h1 h2
  apply limit.hom_ext
  

Proof state:
case w
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g1 g2 : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g1 ≫ π arrows j = g2 ≫ π arrows j
h2 : g1 ≫ base arrows = g2 ≫ base arrows
⊢ ∀ (j : WidePullbackShape J),
    g1 ≫ limit.π (WidePullbackShape.wideCospan B (fun j => objs j) arrows) j =
      g2 ≫ limit.π (WidePullbackShape.wideCospan B (fun j => objs j) arrows) j

Next tactic:
rintro (_ | _)
@[ext 1100]
theorem hom_ext (g1 g2 : X ⟶ widePullback _ _ arrows) : (∀ j : J,
    g1 ≫ π arrows j = g2 ≫ π arrows j) → g1 ≫ base arrows = g2 ≫ base arrows → g1 = g2 := by
  intro h1 h2
  apply limit.hom_ext
  rintro (_ | _)
  · 

Proof state:
case w.none
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g1 g2 : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g1 ≫ π arrows j = g2 ≫ π arrows j
h2 : g1 ≫ base arrows = g2 ≫ base arrows
⊢ g1 ≫ limit.π (WidePullbackShape.wideCospan B (fun j => objs j) arrows) none =
    g2 ≫ limit.π (WidePullbackShape.wideCospan B (fun j => objs j) arrows) none

Next tactic:
apply h2
@[ext 1100]
theorem hom_ext (g1 g2 : X ⟶ widePullback _ _ arrows) : (∀ j : J,
    g1 ≫ π arrows j = g2 ≫ π arrows j) → g1 ≫ base arrows = g2 ≫ base arrows → g1 = g2 := by
  intro h1 h2
  apply limit.hom_ext
  rintro (_ | _)
  · apply h2
  · 

Proof state:
case w.some
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → objs j ⟶ B
inst✝ : HasWidePullback B objs arrows
X : D
f : X ⟶ B
fs : (j : J) → X ⟶ objs j
w : ∀ (j : J), fs j ≫ arrows j = f
g1 g2 : X ⟶ widePullback B (fun j => objs j) arrows
h1 : ∀ (j : J), g1 ≫ π arrows j = g2 ≫ π arrows j
h2 : g1 ≫ base arrows = g2 ≫ base arrows
val✝ : J
⊢ g1 ≫ limit.π (WidePullbackShape.wideCospan B (fun j => objs j) arrows) (some val✝) =
    g2 ≫ limit.π (WidePullbackShape.wideCospan B (fun j => objs j) arrows) (some val✝)

Next tactic:
apply h1
@[reassoc (attr := simp)]
theorem arrow_ι (j : J) : arrows j ≫ ι arrows j = head arrows := by
  

Proof state:
J : Type w
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{v₂, u_1} D
B : D
objs : J → D
arrows : (j : J) → B ⟶ objs j
inst✝ : HasWidePushout B objs arrows
j : J
⊢ arrows j ≫ ι arrows j = head arrows

Next tactic:
apply colimit.w (WidePushoutShape.wideSpan _ _ _) (WidePushoutShape.Hom.init j)