l3lab/ntp-mathlib huggingface dataset:
/-- `Multicofork.ofSigmaCofork` as a functor. -/
@[simps]
noncomputable def ofSigmaCoforkFunctor : Cofork I.fstSigmaMap I.sndSigmaMap ⥤ Multicofork I where
  obj := Multicofork.ofSigmaCofork I
  map {K₁ K₂} f :=
    { hom := f.hom
      w := by --sorry --by rintro (_ | _) <;> simp
        rintro (_ | _)
        -- porting note; in mathlib3, `simp` worked. What seems to be happening is that
        -- the `simp` set is not confluent, and mathlib3 found
        -- `Multicofork.ofSigmaCofork_ι_app_left` before `Multicofork.fst_app_right`,
        -- but mathlib4 finds `Multicofork.fst_app_right` first.
        

Proof state:
case left
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K₁ K₂ : Cofork (fstSigmaMap I) (sndSigmaMap I)
f : K₁ ⟶ K₂
a✝ : I.L
⊢ (Multicofork.ofSigmaCofork I K₁).ι.app (WalkingMultispan.left a✝) ≫ f.hom =
    (Multicofork.ofSigmaCofork I K₂).ι.app (WalkingMultispan.left a✝)
case right
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K₁ K₂ : Cofork (fstSigmaMap I) (sndSigmaMap I)
f : K₁ ⟶ K₂
a✝ : I.R
⊢ (Multicofork.ofSigmaCofork I K₁).ι.app (WalkingMultispan.right a✝) ≫ f.hom =
    (Multicofork.ofSigmaCofork I K₂).ι.app (WalkingMultispan.right a✝)

Next tactic:
{ simp [-Multicofork.fst_app_right] }
/-- `Multicofork.ofSigmaCofork` as a functor. -/
@[simps]
noncomputable def ofSigmaCoforkFunctor : Cofork I.fstSigmaMap I.sndSigmaMap ⥤ Multicofork I where
  obj := Multicofork.ofSigmaCofork I
  map {K₁ K₂} f :=
    { hom := f.hom
      w := by --sorry --by rintro (_ | _) <;> simp
        rintro (_ | _)
        -- porting note; in mathlib3, `simp` worked. What seems to be happening is that
        -- the `simp` set is not confluent, and mathlib3 found
        -- `Multicofork.ofSigmaCofork_ι_app_left` before `Multicofork.fst_app_right`,
        -- but mathlib4 finds `Multicofork.fst_app_right` first.
        { 

Proof state:
case left
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K₁ K₂ : Cofork (fstSigmaMap I) (sndSigmaMap I)
f : K₁ ⟶ K₂
a✝ : I.L
⊢ (Multicofork.ofSigmaCofork I K₁).ι.app (WalkingMultispan.left a✝) ≫ f.hom =
    (Multicofork.ofSigmaCofork I K₂).ι.app (WalkingMultispan.left a✝)

Next tactic:
simp [-Multicofork.fst_app_right]
/-- `Multicofork.ofSigmaCofork` as a functor. -/
@[simps]
noncomputable def ofSigmaCoforkFunctor : Cofork I.fstSigmaMap I.sndSigmaMap ⥤ Multicofork I where
  obj := Multicofork.ofSigmaCofork I
  map {K₁ K₂} f :=
    { hom := f.hom
      w := by --sorry --by rintro (_ | _) <;> simp
        rintro (_ | _)
        -- porting note; in mathlib3, `simp` worked. What seems to be happening is that
        -- the `simp` set is not confluent, and mathlib3 found
        -- `Multicofork.ofSigmaCofork_ι_app_left` before `Multicofork.fst_app_right`,
        -- but mathlib4 finds `Multicofork.fst_app_right` first.
        { simp [-Multicofork.fst_app_right] }
        -- porting note: similarly here, the `simp` set seems to be non-confluent
        

Proof state:
case right
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K₁ K₂ : Cofork (fstSigmaMap I) (sndSigmaMap I)
f : K₁ ⟶ K₂
a✝ : I.R
⊢ (Multicofork.ofSigmaCofork I K₁).ι.app (WalkingMultispan.right a✝) ≫ f.hom =
    (Multicofork.ofSigmaCofork I K₂).ι.app (WalkingMultispan.right a✝)

Next tactic:
{ simp [-Multicofork.ofSigmaCofork_pt] }
/-- `Multicofork.ofSigmaCofork` as a functor. -/
@[simps]
noncomputable def ofSigmaCoforkFunctor : Cofork I.fstSigmaMap I.sndSigmaMap ⥤ Multicofork I where
  obj := Multicofork.ofSigmaCofork I
  map {K₁ K₂} f :=
    { hom := f.hom
      w := by --sorry --by rintro (_ | _) <;> simp
        rintro (_ | _)
        -- porting note; in mathlib3, `simp` worked. What seems to be happening is that
        -- the `simp` set is not confluent, and mathlib3 found
        -- `Multicofork.ofSigmaCofork_ι_app_left` before `Multicofork.fst_app_right`,
        -- but mathlib4 finds `Multicofork.fst_app_right` first.
        { simp [-Multicofork.fst_app_right] }
        -- porting note: similarly here, the `simp` set seems to be non-confluent
        { 

Proof state:
case right
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K₁ K₂ : Cofork (fstSigmaMap I) (sndSigmaMap I)
f : K₁ ⟶ K₂
a✝ : I.R
⊢ (Multicofork.ofSigmaCofork I K₁).ι.app (WalkingMultispan.right a✝) ≫ f.hom =
    (Multicofork.ofSigmaCofork I K₂).ι.app (WalkingMultispan.right a✝)

Next tactic:
simp [-Multicofork.ofSigmaCofork_pt]
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Multicofork I
⊢ ∀ (j : WalkingMultispan I.fstFrom I.sndFrom),
    ((𝟭 (Multicofork I)).obj K).ι.app j ≫ (Iso.refl ((𝟭 (Multicofork I)).obj K).pt).hom =
      ((toSigmaCoforkFunctor I ⋙ ofSigmaCoforkFunctor I).obj K).ι.app j

Next tactic:
rintro (_ | _)
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> 

Proof state:
case left
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Multicofork I
a✝ : I.L
⊢ ((𝟭 (Multicofork I)).obj K).ι.app (WalkingMultispan.left a✝) ≫ (Iso.refl ((𝟭 (Multicofork I)).obj K).pt).hom =
    ((toSigmaCoforkFunctor I ⋙ ofSigmaCoforkFunctor I).obj K).ι.app (WalkingMultispan.left a✝)

Next tactic:
simp
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> 

Proof state:
case right
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Multicofork I
a✝ : I.R
⊢ ((𝟭 (Multicofork I)).obj K).ι.app (WalkingMultispan.right a✝) ≫ (Iso.refl ((𝟭 (Multicofork I)).obj K).pt).hom =
    ((toSigmaCoforkFunctor I ⋙ ofSigmaCoforkFunctor I).obj K).ι.app (WalkingMultispan.right a✝)

Next tactic:
simp
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> simp)
  counitIso := NatIso.ofComponents fun K =>
    Cofork.ext (Iso.refl _)
      (by
        -- porting note: in mathlib3 this was just `ext` and I don't know why it's not here
        

Proof state:
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Cofork (fstSigmaMap I) (sndSigmaMap I)
⊢ Cofork.π ((ofSigmaCoforkFunctor I ⋙ toSigmaCoforkFunctor I).obj K) ≫
      (Iso.refl ((ofSigmaCoforkFunctor I ⋙ toSigmaCoforkFunctor I).obj K).pt).hom =
    Cofork.π ((𝟭 (Cofork (fstSigmaMap I) (sndSigmaMap I))).obj K)

Next tactic:
apply Limits.colimit.hom_ext
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> simp)
  counitIso := NatIso.ofComponents fun K =>
    Cofork.ext (Iso.refl _)
      (by
        -- porting note: in mathlib3 this was just `ext` and I don't know why it's not here
        apply Limits.colimit.hom_ext
        

Proof state:
case w
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Cofork (fstSigmaMap I) (sndSigmaMap I)
⊢ ∀ (j : Discrete I.R),
    colimit.ι (Discrete.functor I.right) j ≫
        Cofork.π ((ofSigmaCoforkFunctor I ⋙ toSigmaCoforkFunctor I).obj K) ≫
          (Iso.refl ((ofSigmaCoforkFunctor I ⋙ toSigmaCoforkFunctor I).obj K).pt).hom =
      colimit.ι (Discrete.functor I.right) j ≫ Cofork.π ((𝟭 (Cofork (fstSigmaMap I) (sndSigmaMap I))).obj K)

Next tactic:
rintro ⟨j⟩
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> simp)
  counitIso := NatIso.ofComponents fun K =>
    Cofork.ext (Iso.refl _)
      (by
        -- porting note: in mathlib3 this was just `ext` and I don't know why it's not here
        apply Limits.colimit.hom_ext
        rintro ⟨j⟩
        

Proof state:
case w.mk
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Cofork (fstSigmaMap I) (sndSigmaMap I)
j : I.R
⊢ colimit.ι (Discrete.functor I.right) { as := j } ≫
      Cofork.π ((ofSigmaCoforkFunctor I ⋙ toSigmaCoforkFunctor I).obj K) ≫
        (Iso.refl ((ofSigmaCoforkFunctor I ⋙ toSigmaCoforkFunctor I).obj K).pt).hom =
    colimit.ι (Discrete.functor I.right) { as := j } ≫ Cofork.π ((𝟭 (Cofork (fstSigmaMap I) (sndSigmaMap I))).obj K)

Next tactic:
dsimp
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> simp)
  counitIso := NatIso.ofComponents fun K =>
    Cofork.ext (Iso.refl _)
      (by
        -- porting note: in mathlib3 this was just `ext` and I don't know why it's not here
        apply Limits.colimit.hom_ext
        rintro ⟨j⟩
        dsimp
        

Proof state:
case w.mk
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Cofork (fstSigmaMap I) (sndSigmaMap I)
j : I.R
⊢ colimit.ι (Discrete.functor I.right) { as := j } ≫
      Sigma.desc (Multicofork.π (Multicofork.ofSigmaCofork I K)) ≫ 𝟙 K.pt =
    colimit.ι (Discrete.functor I.right) { as := j } ≫ Cofork.π K

Next tactic:
simp only [Category.comp_id, colimit.ι_desc, Cofan.mk_ι_app]
/--
The category of multicoforks is equivalent to the category of coforks over `∐ I.left ⇉ ∐ I.right`.
It then follows from `CategoryTheory.IsColimit.ofPreservesCoconeInitial` (or `reflects`) that
it preserves and reflects colimit cocones.
-/
@[simps]
noncomputable def multicoforkEquivSigmaCofork :
    Multicofork I ≌ Cofork I.fstSigmaMap I.sndSigmaMap where
  functor := toSigmaCoforkFunctor I
  inverse := ofSigmaCoforkFunctor I
  unitIso := NatIso.ofComponents fun K => Cocones.ext (Iso.refl _) (by
      rintro (_ | _) <;> simp)
  counitIso := NatIso.ofComponents fun K =>
    Cofork.ext (Iso.refl _)
      (by
        -- porting note: in mathlib3 this was just `ext` and I don't know why it's not here
        apply Limits.colimit.hom_ext
        rintro ⟨j⟩
        dsimp
        simp only [Category.comp_id, colimit.ι_desc, Cofan.mk_ι_app]
        

Proof state:
case w.mk
C : Type u
inst✝² : Category.{v, u} C
I : MultispanIndex C
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
K : Cofork (fstSigmaMap I) (sndSigmaMap I)
j : I.R
⊢ Multicofork.π (Multicofork.ofSigmaCofork I K) j = colimit.ι (Discrete.functor I.right) { as := j } ≫ Cofork.π K

Next tactic:
rfl
@[ext]
theorem hom_ext {W : C} (i j : W ⟶ multiequalizer I)
    (h : ∀ a, i ≫ Multiequalizer.ι I a = j ≫ Multiequalizer.ι I a) : i = j :=
  limit.hom_ext
    (by
      

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
I : MulticospanIndex C
inst✝ : HasMultiequalizer I
W : C
i j : W ⟶ multiequalizer I
h : ∀ (a : I.L), i ≫ ι I a = j ≫ ι I a
⊢ ∀ (j_1 : WalkingMulticospan I.fstTo I.sndTo),
    i ≫ limit.π (MulticospanIndex.multicospan I) j_1 = j ≫ limit.π (MulticospanIndex.multicospan I) j_1

Next tactic:
rintro (a | b)
@[ext]
theorem hom_ext {W : C} (i j : W ⟶ multiequalizer I)
    (h : ∀ a, i ≫ Multiequalizer.ι I a = j ≫ Multiequalizer.ι I a) : i = j :=
  limit.hom_ext
    (by
      rintro (a | b)
      · 

Proof state:
case left
C : Type u
inst✝¹ : Category.{v, u} C
I : MulticospanIndex C
inst✝ : HasMultiequalizer I
W : C
i j : W ⟶ multiequalizer I
h : ∀ (a : I.L), i ≫ ι I a = j ≫ ι I a
a : I.L
⊢ i ≫ limit.π (MulticospanIndex.multicospan I) (WalkingMulticospan.left a) =
    j ≫ limit.π (MulticospanIndex.multicospan I) (WalkingMulticospan.left a)

Next tactic:
apply h
@[ext]
theorem hom_ext {W : C} (i j : W ⟶ multiequalizer I)
    (h : ∀ a, i ≫ Multiequalizer.ι I a = j ≫ Multiequalizer.ι I a) : i = j :=
  limit.hom_ext
    (by
      rintro (a | b)
      · apply h
      

Proof state:
case right
C : Type u
inst✝¹ : Category.{v, u} C
I : MulticospanIndex C
inst✝ : HasMultiequalizer I
W : C
i j : W ⟶ multiequalizer I
h : ∀ (a : I.L), i ≫ ι I a = j ≫ ι I a
b : I.R
⊢ i ≫ limit.π (MulticospanIndex.multicospan I) (WalkingMulticospan.right b) =
    j ≫ limit.π (MulticospanIndex.multicospan I) (WalkingMulticospan.right b)

Next tactic:
simp_rw [← limit.w I.multicospan (WalkingMulticospan.Hom.fst b), ← Category.assoc, h]
@[reassoc (attr := simp)]
theorem ιPi_π (a) : ιPi I ≫ Pi.π I.left a = ι I a := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : MulticospanIndex C
inst✝² : HasMultiequalizer I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
a : I.L
⊢ ιPi I ≫ Pi.π I.left a = ι I a

Next tactic:
rw [ιPi, Category.assoc, ← Iso.eq_inv_comp, isoEqualizer]
@[reassoc (attr := simp)]
theorem ιPi_π (a) : ιPi I ≫ Pi.π I.left a = ι I a := by
  rw [ιPi, Category.assoc, ← Iso.eq_inv_comp, isoEqualizer]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : MulticospanIndex C
inst✝² : HasMultiequalizer I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
a : I.L
⊢ equalizer.ι (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I) ≫ Pi.π I.left a =
    (limit.isoLimitCone
          {
            cone :=
              (MulticospanIndex.multiforkEquivPiFork I).inverse.obj
                (limit.cone (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I))),
            isLimit :=
              IsLimit.ofPreservesConeTerminal (MulticospanIndex.multiforkEquivPiFork I).inverse
                (limit.isLimit (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I))) }).inv ≫
      ι I a

Next tactic:
simp
@[ext]
theorem hom_ext {W : C} (i j : multicoequalizer I ⟶ W)
    (h : ∀ b, Multicoequalizer.π I b ≫ i = Multicoequalizer.π I b ≫ j) : i = j :=
  colimit.hom_ext
    (by
      

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
I : MultispanIndex C
inst✝ : HasMulticoequalizer I
W : C
i j : multicoequalizer I ⟶ W
h : ∀ (b : I.R), π I b ≫ i = π I b ≫ j
⊢ ∀ (j_1 : WalkingMultispan I.fstFrom I.sndFrom),
    colimit.ι (MultispanIndex.multispan I) j_1 ≫ i = colimit.ι (MultispanIndex.multispan I) j_1 ≫ j

Next tactic:
rintro (a | b)
@[ext]
theorem hom_ext {W : C} (i j : multicoequalizer I ⟶ W)
    (h : ∀ b, Multicoequalizer.π I b ≫ i = Multicoequalizer.π I b ≫ j) : i = j :=
  colimit.hom_ext
    (by
      rintro (a | b)
      · 

Proof state:
case left
C : Type u
inst✝¹ : Category.{v, u} C
I : MultispanIndex C
inst✝ : HasMulticoequalizer I
W : C
i j : multicoequalizer I ⟶ W
h : ∀ (b : I.R), π I b ≫ i = π I b ≫ j
a : I.L
⊢ colimit.ι (MultispanIndex.multispan I) (WalkingMultispan.left a) ≫ i =
    colimit.ι (MultispanIndex.multispan I) (WalkingMultispan.left a) ≫ j

Next tactic:
simp_rw [← colimit.w I.multispan (WalkingMultispan.Hom.fst a), Category.assoc, h]
@[ext]
theorem hom_ext {W : C} (i j : multicoequalizer I ⟶ W)
    (h : ∀ b, Multicoequalizer.π I b ≫ i = Multicoequalizer.π I b ≫ j) : i = j :=
  colimit.hom_ext
    (by
      rintro (a | b)
      · simp_rw [← colimit.w I.multispan (WalkingMultispan.Hom.fst a), Category.assoc, h]
      · 

Proof state:
case right
C : Type u
inst✝¹ : Category.{v, u} C
I : MultispanIndex C
inst✝ : HasMulticoequalizer I
W : C
i j : multicoequalizer I ⟶ W
h : ∀ (b : I.R), π I b ≫ i = π I b ≫ j
b : I.R
⊢ colimit.ι (MultispanIndex.multispan I) (WalkingMultispan.right b) ≫ i =
    colimit.ι (MultispanIndex.multispan I) (WalkingMultispan.right b) ≫ j

Next tactic:
apply h
@[reassoc (attr := simp)]
theorem ι_sigmaπ (b) : Sigma.ι I.right b ≫ sigmaπ I = π I b := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : MultispanIndex C
inst✝² : HasMulticoequalizer I
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
b : I.R
⊢ Sigma.ι I.right b ≫ sigmaπ I = π I b

Next tactic:
rw [sigmaπ, ← Category.assoc, Iso.comp_inv_eq, isoCoequalizer]
@[reassoc (attr := simp)]
theorem ι_sigmaπ (b) : Sigma.ι I.right b ≫ sigmaπ I = π I b := by
  rw [sigmaπ, ← Category.assoc, Iso.comp_inv_eq, isoCoequalizer]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : MultispanIndex C
inst✝² : HasMulticoequalizer I
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
b : I.R
⊢ Sigma.ι I.right b ≫ coequalizer.π (MultispanIndex.fstSigmaMap I) (MultispanIndex.sndSigmaMap I) =
    π I b ≫
      (colimit.isoColimitCocone
          {
            cocone :=
              (MultispanIndex.multicoforkEquivSigmaCofork I).inverse.obj
                (colimit.cocone (parallelPair (MultispanIndex.fstSigmaMap I) (MultispanIndex.sndSigmaMap I))),
            isColimit :=
              IsColimit.ofPreservesCoconeInitial (MultispanIndex.multicoforkEquivSigmaCofork I).inverse
                (colimit.isColimit (parallelPair (MultispanIndex.fstSigmaMap I) (MultispanIndex.sndSigmaMap I))) }).hom

Next tactic:
simp only [MultispanIndex.multicoforkEquivSigmaCofork_inverse,
    MultispanIndex.ofSigmaCoforkFunctor_obj, colimit.isoColimitCocone_ι_hom,
    Multicofork.ofSigmaCofork_pt, colimit.cocone_x, Multicofork.π_eq_app_right]
@[reassoc (attr := simp)]
theorem ι_sigmaπ (b) : Sigma.ι I.right b ≫ sigmaπ I = π I b := by
  rw [sigmaπ, ← Category.assoc, Iso.comp_inv_eq, isoCoequalizer]
  simp only [MultispanIndex.multicoforkEquivSigmaCofork_inverse,
    MultispanIndex.ofSigmaCoforkFunctor_obj, colimit.isoColimitCocone_ι_hom,
    Multicofork.ofSigmaCofork_pt, colimit.cocone_x, Multicofork.π_eq_app_right]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : MultispanIndex C
inst✝² : HasMulticoequalizer I
inst✝¹ : HasCoproduct I.left
inst✝ : HasCoproduct I.right
b : I.R
⊢ Sigma.ι I.right b ≫ coequalizer.π (MultispanIndex.fstSigmaMap I) (MultispanIndex.sndSigmaMap I) =
    Multicofork.π
      (Multicofork.ofSigmaCofork I
        (colimit.cocone (parallelPair (MultispanIndex.fstSigmaMap I) (MultispanIndex.sndSigmaMap I))))
      b

Next tactic:
rfl
@[simp]
theorem mem_powerset {s t : Finset α} : s ∈ powerset t ↔ s ⊆ t := by
  

Proof state:
α : Type u_1
s✝ t✝ s t : Finset α
⊢ s ∈ powerset t ↔ s ⊆ t

Next tactic:
cases s
@[simp]
theorem mem_powerset {s t : Finset α} : s ∈ powerset t ↔ s ⊆ t := by
  cases s
  

Proof state:
case mk
α : Type u_1
s t✝ t : Finset α
val✝ : Multiset α
nodup✝ : Nodup val✝
⊢ { val := val✝, nodup := nodup✝ } ∈ powerset t ↔ { val := val✝, nodup := nodup✝ } ⊆ t

Next tactic:
simp [powerset, mem_mk, mem_pmap, mk.injEq, mem_powerset, exists_prop, exists_eq_right,
    ← val_le_iff]
@[simp, norm_cast]
theorem coe_powerset (s : Finset α) :
    (s.powerset : Set (Finset α)) = ((↑) : Finset α → Set α) ⁻¹' (s : Set α).powerset := by
  

Proof state:
α : Type u_1
s✝ t s : Finset α
⊢ ↑(powerset s) = toSet ⁻¹' 𝒫↑s

Next tactic:
ext
@[simp, norm_cast]
theorem coe_powerset (s : Finset α) :
    (s.powerset : Set (Finset α)) = ((↑) : Finset α → Set α) ⁻¹' (s : Set α).powerset := by
  ext
  

Proof state:
case h
α : Type u_1
s✝ t s x✝ : Finset α
⊢ x✝ ∈ ↑(powerset s) ↔ x✝ ∈ toSet ⁻¹' 𝒫↑s

Next tactic:
simp
@[simp]
theorem powerset_eq_singleton_empty : s.powerset = {∅} ↔ s = ∅ := by
  

Proof state:
α : Type u_1
s t : Finset α
⊢ powerset s = {∅} ↔ s = ∅

Next tactic:
rw [← powerset_empty, powerset_inj]
theorem not_mem_of_mem_powerset_of_not_mem {s t : Finset α} {a : α} (ht : t ∈ s.powerset)
    (h : a ∉ s) : a ∉ t := by
  

Proof state:
α : Type u_1
s✝ t✝ s t : Finset α
a : α
ht : t ∈ powerset s
h : a ∉ s
⊢ a ∉ t

Next tactic:
apply mt _ h
theorem not_mem_of_mem_powerset_of_not_mem {s t : Finset α} {a : α} (ht : t ∈ s.powerset)
    (h : a ∉ s) : a ∉ t := by
  apply mt _ h
  

Proof state:
α : Type u_1
s✝ t✝ s t : Finset α
a : α
ht : t ∈ powerset s
h : a ∉ s
⊢ a ∈ t → a ∈ s

Next tactic:
apply mem_powerset.1 ht
theorem powerset_insert [DecidableEq α] (s : Finset α) (a : α) :
    powerset (insert a s) = s.powerset ∪ s.powerset.image (insert a) := by
  

Proof state:
α : Type u_1
s✝ t : Finset α
inst✝ : DecidableEq α
s : Finset α
a : α
⊢ powerset (insert a s) = powerset s ∪ image (insert a) (powerset s)

Next tactic:
ext t
theorem powerset_insert [DecidableEq α] (s : Finset α) (a : α) :
    powerset (insert a s) = s.powerset ∪ s.powerset.image (insert a) := by
  ext t
  

Proof state:
case a
α : Type u_1
s✝ t✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
a : α
t : Finset α
⊢ t ∈ powerset (insert a s) ↔ t ∈ powerset s ∪ image (insert a) (powerset s)

Next tactic:
simp only [exists_prop, mem_powerset, mem_image, mem_union, subset_insert_iff]
theorem powerset_insert [DecidableEq α] (s : Finset α) (a : α) :
    powerset (insert a s) = s.powerset ∪ s.powerset.image (insert a) := by
  ext t
  simp only [exists_prop, mem_powerset, mem_image, mem_union, subset_insert_iff]
  

Proof state:
case a
α : Type u_1
s✝ t✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
a : α
t : Finset α
⊢ erase t a ⊆ s ↔ t ⊆ s ∨ ∃ a_1 ⊆ s, insert a a_1 = t

Next tactic:
by_cases h : a ∈ t
theorem powerset_insert [DecidableEq α] (s : Finset α) (a : α) :
    powerset (insert a s) = s.powerset ∪ s.powerset.image (insert a) := by
  ext t
  simp only [exists_prop, mem_powerset, mem_image, mem_union, subset_insert_iff]
  by_cases h : a ∈ t
  · 

Proof state:
case pos
α : Type u_1
s✝ t✝ : Finset α
inst✝ : DecidableEq α
s : Finset α
a : α
t : Finset α
h : a ∈ t
⊢ erase t a ⊆ s ↔ t ⊆ s ∨ ∃ a_1 ⊆ s, insert a a_1 = t

Next tactic:
constructor