l3lab/ntp-mathlib huggingface dataset:
/-- Construct a multifork using a collection `ι` of morphisms. -/
@[simps]
def ofι (I : MulticospanIndex.{w} C) (P : C) (ι : ∀ a, P ⟶ I.left a)
    (w : ∀ b, ι (I.fstTo b) ≫ I.fst b = ι (I.sndTo b) ≫ I.snd b) : Multifork I where
  pt := P
  π :=
    { app := fun x =>
        match x with
        | WalkingMulticospan.left a => ι _
        | WalkingMulticospan.right b => ι (I.fstTo b) ≫ I.fst b
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          

Proof state:
case left.right.snd
C : Type u
inst✝ : Category.{v, u} C
I✝ : MulticospanIndex C
K : Multifork I✝
I : MulticospanIndex C
P : C
ι : (a : I.L) → P ⟶ MulticospanIndex.left I a
w :
  ∀ (b : I.R),
    ι (MulticospanIndex.fstTo I b) ≫ MulticospanIndex.fst I b =
      ι (MulticospanIndex.sndTo I b) ≫ MulticospanIndex.snd I b
a✝ : I.R
⊢ 𝟙 P ≫ ι (MulticospanIndex.fstTo I a✝) ≫ MulticospanIndex.fst I a✝ =
    ι (MulticospanIndex.sndTo I a✝) ≫ MulticospanIndex.snd I a✝

Next tactic:
simp only [Category.id_comp, Category.comp_id, Functor.map_id,
            MulticospanIndex.multicospan_obj_left, MulticospanIndex.multicospan_obj_right]
/-- Construct a multifork using a collection `ι` of morphisms. -/
@[simps]
def ofι (I : MulticospanIndex.{w} C) (P : C) (ι : ∀ a, P ⟶ I.left a)
    (w : ∀ b, ι (I.fstTo b) ≫ I.fst b = ι (I.sndTo b) ≫ I.snd b) : Multifork I where
  pt := P
  π :=
    { app := fun x =>
        match x with
        | WalkingMulticospan.left a => ι _
        | WalkingMulticospan.right b => ι (I.fstTo b) ≫ I.fst b
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          

Proof state:
case right.right.id
C : Type u
inst✝ : Category.{v, u} C
I✝ : MulticospanIndex C
K : Multifork I✝
I : MulticospanIndex C
P : C
ι : (a : I.L) → P ⟶ MulticospanIndex.left I a
w :
  ∀ (b : I.R),
    ι (MulticospanIndex.fstTo I b) ≫ MulticospanIndex.fst I b =
      ι (MulticospanIndex.sndTo I b) ≫ MulticospanIndex.snd I b
a✝ : I.R
⊢ 𝟙 P ≫ ι (MulticospanIndex.fstTo I a✝) ≫ MulticospanIndex.fst I a✝ =
    (ι (MulticospanIndex.fstTo I a✝) ≫ MulticospanIndex.fst I a✝) ≫
      (MulticospanIndex.multicospan I).map (𝟙 (WalkingMulticospan.right a✝))

Next tactic:
simp only [Category.id_comp, Category.comp_id, Functor.map_id,
            MulticospanIndex.multicospan_obj_left, MulticospanIndex.multicospan_obj_right]
/-- Construct a multifork using a collection `ι` of morphisms. -/
@[simps]
def ofι (I : MulticospanIndex.{w} C) (P : C) (ι : ∀ a, P ⟶ I.left a)
    (w : ∀ b, ι (I.fstTo b) ≫ I.fst b = ι (I.sndTo b) ≫ I.snd b) : Multifork I where
  pt := P
  π :=
    { app := fun x =>
        match x with
        | WalkingMulticospan.left a => ι _
        | WalkingMulticospan.right b => ι (I.fstTo b) ≫ I.fst b
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          simp only [Category.id_comp, Category.comp_id, Functor.map_id,
            MulticospanIndex.multicospan_obj_left, MulticospanIndex.multicospan_obj_right]
        

Proof state:
case left.right.snd
C : Type u
inst✝ : Category.{v, u} C
I✝ : MulticospanIndex C
K : Multifork I✝
I : MulticospanIndex C
P : C
ι : (a : I.L) → P ⟶ MulticospanIndex.left I a
w :
  ∀ (b : I.R),
    ι (MulticospanIndex.fstTo I b) ≫ MulticospanIndex.fst I b =
      ι (MulticospanIndex.sndTo I b) ≫ MulticospanIndex.snd I b
a✝ : I.R
⊢ ι (MulticospanIndex.fstTo I a✝) ≫ MulticospanIndex.fst I a✝ =
    ι (MulticospanIndex.sndTo I a✝) ≫ MulticospanIndex.snd I a✝

Next tactic:
apply w
@[reassoc (attr := simp)]
theorem condition (b) : K.ι (I.fstTo b) ≫ I.fst b = K.ι (I.sndTo b) ≫ I.snd b := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
b : I.R
⊢ ι K (MulticospanIndex.fstTo I b) ≫ MulticospanIndex.fst I b =
    ι K (MulticospanIndex.sndTo I b) ≫ MulticospanIndex.snd I b

Next tactic:
rw [← app_right_eq_ι_comp_fst, ← app_right_eq_ι_comp_snd]
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
⊢ ∀ (s : Cone (MulticospanIndex.multicospan I)) (j : WalkingMulticospan I.fstTo I.sndTo), lift s ≫ K.π.app j = s.π.app j

Next tactic:
rintro E (a | b)
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · 

Proof state:
case left
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
a : I.L
⊢ lift E ≫ K.π.app (WalkingMulticospan.left a) = E.π.app (WalkingMulticospan.left a)

Next tactic:
apply fac
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · 

Proof state:
case right
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
b : I.R
⊢ lift E ≫ K.π.app (WalkingMulticospan.right b) = E.π.app (WalkingMulticospan.right b)

Next tactic:
rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
        

Proof state:
case right
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
b : I.R
⊢ (lift E ≫ K.π.app (WalkingMulticospan.left (MulticospanIndex.fstTo I b))) ≫
      (MulticospanIndex.multicospan I).map (WalkingMulticospan.Hom.fst b) =
    E.π.app (WalkingMulticospan.left (MulticospanIndex.fstTo I b)) ≫
      (MulticospanIndex.multicospan I).map (WalkingMulticospan.Hom.fst b)

Next tactic:
congr 1
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
        congr 1
        

Proof state:
case right.e_a
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
b : I.R
⊢ lift E ≫ K.π.app (WalkingMulticospan.left (MulticospanIndex.fstTo I b)) =
    E.π.app (WalkingMulticospan.left (MulticospanIndex.fstTo I b))

Next tactic:
apply fac
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
        congr 1
        apply fac
    uniq := by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
⊢ ∀ (s : Cone (MulticospanIndex.multicospan I)) (m : s.pt ⟶ K.pt),
    (∀ (j : WalkingMulticospan I.fstTo I.sndTo), m ≫ K.π.app j = s.π.app j) → m = lift s

Next tactic:
rintro E m hm
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
        congr 1
        apply fac
    uniq := by
      rintro E m hm
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
m : E.pt ⟶ K.pt
hm : ∀ (j : WalkingMulticospan I.fstTo I.sndTo), m ≫ K.π.app j = E.π.app j
⊢ m = lift E

Next tactic:
apply uniq
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
        congr 1
        apply fac
    uniq := by
      rintro E m hm
      apply uniq
      

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
m : E.pt ⟶ K.pt
hm : ∀ (j : WalkingMulticospan I.fstTo I.sndTo), m ≫ K.π.app j = E.π.app j
⊢ ∀ (i : I.L), m ≫ ι K i = ι E i

Next tactic:
intro i
/-- This definition provides a convenient way to show that a multifork is a limit. -/
@[simps]
def IsLimit.mk (lift : ∀ E : Multifork I, E.pt ⟶ K.pt)
    (fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ K.ι i = E.ι i)
    (uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ i : I.L, m ≫ K.ι i = E.ι i) → m = lift E) :
    IsLimit K :=
  { lift
    fac := by
      rintro E (a | b)
      · apply fac
      · rw [← E.w (WalkingMulticospan.Hom.fst b), ← K.w (WalkingMulticospan.Hom.fst b), ←
          Category.assoc]
        congr 1
        apply fac
    uniq := by
      rintro E m hm
      apply uniq
      intro i
      

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
lift : (E : Multifork I) → E.pt ⟶ K.pt
fac : ∀ (E : Multifork I) (i : I.L), lift E ≫ ι K i = ι E i
uniq : ∀ (E : Multifork I) (m : E.pt ⟶ K.pt), (∀ (i : I.L), m ≫ ι K i = ι E i) → m = lift E
E : Cone (MulticospanIndex.multicospan I)
m : E.pt ⟶ K.pt
hm : ∀ (j : WalkingMulticospan I.fstTo I.sndTo), m ≫ K.π.app j = E.π.app j
i : I.L
⊢ m ≫ ι K i = ι E i

Next tactic:
apply hm
@[reassoc (attr := simp)]
theorem pi_condition : Pi.lift K.ι ≫ I.fstPiMap = Pi.lift K.ι ≫ I.sndPiMap := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
⊢ Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I = Pi.lift (ι K) ≫ MulticospanIndex.sndPiMap I

Next tactic:
ext
@[reassoc (attr := simp)]
theorem pi_condition : Pi.lift K.ι ≫ I.fstPiMap = Pi.lift K.ι ≫ I.sndPiMap := by
  ext
  

Proof state:
case h
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
b✝ : I.R
⊢ (Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I) ≫ Pi.π I.right b✝ =
    (Pi.lift (ι K) ≫ MulticospanIndex.sndPiMap I) ≫ Pi.π I.right b✝

Next tactic:
simp
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        

Proof state:
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ ∀ ⦃X Y : WalkingParallelPair⦄ (f : X ⟶ Y),
    ((Functor.const WalkingParallelPair).obj K.pt).map f ≫
        (fun x =>
            match x with
            | WalkingParallelPair.zero => Pi.lift (ι K)
            | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
          Y =
      (fun x =>
            match x with
            | WalkingParallelPair.zero => Pi.lift (ι K)
            | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
          X ≫
        (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map f

Next tactic:
rintro (_ | _) (_ | _) (_ | _ | _)
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          

Proof state:
case zero.zero.id
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ ((Functor.const WalkingParallelPair).obj K.pt).map (WalkingParallelPairHom.id WalkingParallelPair.zero) ≫
      (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.zero =
    (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.zero ≫
      (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map
        (WalkingParallelPairHom.id WalkingParallelPair.zero)

Next tactic:
dsimp
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          

Proof state:
case zero.one.left
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ ((Functor.const WalkingParallelPair).obj K.pt).map WalkingParallelPairHom.left ≫
      (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.one =
    (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.zero ≫
      (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map WalkingParallelPairHom.left

Next tactic:
dsimp
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          

Proof state:
case zero.one.right
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ ((Functor.const WalkingParallelPair).obj K.pt).map WalkingParallelPairHom.right ≫
      (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.one =
    (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.zero ≫
      (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map WalkingParallelPairHom.right

Next tactic:
dsimp
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          

Proof state:
case one.one.id
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ ((Functor.const WalkingParallelPair).obj K.pt).map (WalkingParallelPairHom.id WalkingParallelPair.one) ≫
      (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.one =
    (fun x =>
          match x with
          | WalkingParallelPair.zero => Pi.lift (ι K)
          | WalkingParallelPair.one => Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I)
        WalkingParallelPair.one ≫
      (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map
        (WalkingParallelPairHom.id WalkingParallelPair.one)

Next tactic:
dsimp
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          

Proof state:
case zero.zero.id
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ 𝟙 K.pt ≫ Pi.lift (ι K) =
    Pi.lift (ι K) ≫
      (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map (𝟙 WalkingParallelPair.zero)

Next tactic:
simp only [Category.id_comp, Functor.map_id, parallelPair_obj_zero, Category.comp_id,
            pi_condition, parallelPair_obj_one]
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          

Proof state:
case zero.one.left
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ 𝟙 K.pt ≫ Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I = Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I

Next tactic:
simp only [Category.id_comp, Functor.map_id, parallelPair_obj_zero, Category.comp_id,
            pi_condition, parallelPair_obj_one]
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          

Proof state:
case zero.one.right
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ 𝟙 K.pt ≫ Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I = Pi.lift (ι K) ≫ MulticospanIndex.sndPiMap I

Next tactic:
simp only [Category.id_comp, Functor.map_id, parallelPair_obj_zero, Category.comp_id,
            pi_condition, parallelPair_obj_one]
/-- Given a multifork, we may obtain a fork over `∏ I.left ⇉ ∏ I.right`. -/
@[simps pt]
noncomputable def toPiFork (K : Multifork I) : Fork I.fstPiMap I.sndPiMap where
  pt := K.pt
  π :=
    { app := fun x =>
        match x with
        | WalkingParallelPair.zero => Pi.lift K.ι
        | WalkingParallelPair.one => Pi.lift K.ι ≫ I.fstPiMap
      naturality := by
        rintro (_ | _) (_ | _) (_ | _ | _) <;>
          dsimp <;>
          

Proof state:
case one.one.id
C : Type u
inst✝² : Category.{v, u} C
I : MulticospanIndex C
K✝ : Multifork I
inst✝¹ : HasProduct I.left
inst✝ : HasProduct I.right
K : Multifork I
⊢ 𝟙 K.pt ≫ Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I =
    (Pi.lift (ι K) ≫ MulticospanIndex.fstPiMap I) ≫
      (parallelPair (MulticospanIndex.fstPiMap I) (MulticospanIndex.sndPiMap I)).map (𝟙 WalkingParallelPair.one)

Next tactic:
simp only [Category.id_comp, Functor.map_id, parallelPair_obj_zero, Category.comp_id,
            pi_condition, parallelPair_obj_one]