[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
⊢ Function.Injective (colimitLimitToLimitColimit F)
[PROOFSTEP]
classical
cases nonempty_fintype J
intro x y h
obtain ⟨kx, x, rfl⟩ := jointly_surjective'.{v, v} x
obtain ⟨ky, y, rfl⟩ := jointly_surjective'.{v, v} y
dsimp at x y 
replace h := fun j => congr_arg (limit.π (curry.obj F ⋙ colim) j) h
simp [colimit_eq_iff.{v, v}] at h 
let k j := (h j).choose
let f : ∀ j, kx ⟶ k j := fun j => (h j).choose_spec.choose
let g : ∀ j, ky ⟶ k j := fun j => (h j).choose_spec.choose_spec.choose
have w :
  ∀ j,
    F.map ((𝟙 j, f j) : (j, kx) ⟶ (j, k j)) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map ((𝟙 j, g j) : (j, ky) ⟶ (j, k j)) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y) :=
  fun j => (h j).choose_spec.choose_spec.choose_spec
let O : Finset K := Finset.univ.image k ∪ { kx, ky }
have kxO : kx ∈ O := Finset.mem_union.mpr (Or.inr (by simp))
have kyO : ky ∈ O := Finset.mem_union.mpr (Or.inr (by simp))
have kjO : ∀ j, k j ∈ O := fun j => Finset.mem_union.mpr (Or.inl (by simp))
let H : Finset (Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) :=
  (Finset.univ.image fun j : J => ⟨kx, k j, kxO, Finset.mem_union.mpr (Or.inl (by simp)), f j⟩) ∪
    Finset.univ.image fun j : J => ⟨ky, k j, kyO, Finset.mem_union.mpr (Or.inl (by simp)), g j⟩
obtain ⟨S, T, W⟩ := IsFiltered.sup_exists O H
have fH : ∀ j, (⟨kx, k j, kxO, kjO j, f j⟩ : Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) ∈ H := fun j =>
  Finset.mem_union.mpr
    (Or.inl
      (by
        simp only [true_and_iff, Finset.mem_univ, eq_self_iff_true, exists_prop_of_true, Finset.mem_image, heq_iff_eq]
        refine' ⟨j, _⟩
        simp only [heq_iff_eq]))
have gH : ∀ j, (⟨ky, k j, kyO, kjO j, g j⟩ : Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) ∈ H := fun j =>
  Finset.mem_union.mpr
    (Or.inr
      (by
        simp only [true_and_iff, Finset.mem_univ, eq_self_iff_true, exists_prop_of_true, Finset.mem_image, heq_iff_eq]
        refine' ⟨j, _⟩
        simp only [heq_iff_eq]))
      -- Our goal is now an equation between equivalence classes of representatives of a colimit,
          -- and so it suffices to show those representative become equal somewhere, in particular at `S`.
apply
  colimit_sound'.{v, v} (T kxO)
    (T kyO)
      -- We can check if two elements of a limit (in `Type`)
          -- are equal by comparing them componentwise.
ext j
simp only [Functor.comp_map, Limit.map_π_apply, curry_obj_map_app, swap_map]
rw [← W _ _ (fH j)]
rw [← W _ _ (gH j)]
  -- porting note: this was `simp [w]` in lean 3; this is presumably a confluence issue
rw [lim_map, lim_map, Limit.map_π_apply', Limit.map_π_apply', Functor.map_comp, Functor.map_comp, FunctorToTypes.comp,
  FunctorToTypes.comp, curry_obj_map_app, curry_obj_map_app, curry_obj_map_app, Functor.comp_map, Functor.comp_map,
  Functor.comp_map, swap_map, swap_map, swap_map, w]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
⊢ Function.Injective (colimitLimitToLimitColimit F)
[PROOFSTEP]
cases nonempty_fintype J
[GOAL]
case intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
⊢ Function.Injective (colimitLimitToLimitColimit F)
[PROOFSTEP]
intro x y h
[GOAL]
case intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
x y : colimit (curry.obj (swap K J ⋙ F) ⋙ lim)
h : colimitLimitToLimitColimit F x = colimitLimitToLimitColimit F y
⊢ x = y
[PROOFSTEP]
obtain ⟨kx, x, rfl⟩ := jointly_surjective'.{v, v} x
[GOAL]
case intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
y : colimit (curry.obj (swap K J ⋙ F) ⋙ lim)
kx : K
x : (curry.obj (swap K J ⋙ F) ⋙ lim).obj kx
h : colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x) = colimitLimitToLimitColimit F y
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = y
[PROOFSTEP]
obtain ⟨ky, y, rfl⟩ := jointly_surjective'.{v, v} y
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : (curry.obj (swap K J ⋙ F) ⋙ lim).obj kx
ky : K
y : (curry.obj (swap K J ⋙ F) ⋙ lim).obj ky
h :
  colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x) =
    colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y)
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
dsimp at x y 
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x) =
    colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y)
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
replace h := fun j => congr_arg (limit.π (curry.obj F ⋙ colim) j) h
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    limit.π (curry.obj F ⋙ colim) j (colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x)) =
      limit.π (curry.obj F ⋙ colim) j (colimitLimitToLimitColimit F (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y))
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
simp [colimit_eq_iff.{v, v}] at h 
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
let k j := (h j).choose
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
let f : ∀ j, kx ⟶ k j := fun j => (h j).choose_spec.choose
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
let g : ∀ j, ky ⟶ k j := fun j => (h j).choose_spec.choose_spec.choose
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
have w :
  ∀ j,
    F.map ((𝟙 j, f j) : (j, kx) ⟶ (j, k j)) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map ((𝟙 j, g j) : (j, ky) ⟶ (j, k j)) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y) :=
  fun j => (h j).choose_spec.choose_spec.choose_spec
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
let O : Finset K := Finset.univ.image k ∪ { kx, ky }
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
have kxO : kx ∈ O := Finset.mem_union.mpr (Or.inr (by simp))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
⊢ kx ∈ {kx, ky}
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
have kyO : ky ∈ O := Finset.mem_union.mpr (Or.inr (by simp))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
⊢ ky ∈ {kx, ky}
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
have kjO : ∀ j, k j ∈ O := fun j => Finset.mem_union.mpr (Or.inl (by simp))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
j : J
⊢ k j ∈ Finset.image k Finset.univ
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
let H : Finset (Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) :=
  (Finset.univ.image fun j : J => ⟨kx, k j, kxO, Finset.mem_union.mpr (Or.inl (by simp)), f j⟩) ∪
    Finset.univ.image fun j : J => ⟨ky, k j, kyO, Finset.mem_union.mpr (Or.inl (by simp)), g j⟩
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
j : J
⊢ k j ∈ Finset.image k Finset.univ
[PROOFSTEP]
simp
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
j : J
⊢ k j ∈ Finset.image k Finset.univ
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
obtain ⟨S, T, W⟩ := IsFiltered.sup_exists O H
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
have fH : ∀ j, (⟨kx, k j, kxO, kjO j, f j⟩ : Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) ∈ H := fun j =>
  Finset.mem_union.mpr
    (Or.inl
      (by
        simp only [true_and_iff, Finset.mem_univ, eq_self_iff_true, exists_prop_of_true, Finset.mem_image, heq_iff_eq]
        refine' ⟨j, _⟩
        simp only [heq_iff_eq]))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
j : J
⊢ { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈
    Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ
[PROOFSTEP]
simp only [true_and_iff, Finset.mem_univ, eq_self_iff_true, exists_prop_of_true, Finset.mem_image, heq_iff_eq]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
j : J
⊢ ∃ a,
    { fst := kx,
        snd :=
          {
            fst :=
              Exists.choose
                (_ :
                  ∃ k f g,
                    F.map (𝟙 a, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) a x) =
                      F.map (𝟙 a, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) a y)),
            snd :=
              { fst := kxO,
                snd :=
                  { fst := (_ : k a ∈ Finset.image k Finset.univ ∪ {kx, ky}),
                    snd :=
                      Exists.choose
                        (_ :
                          ∃ f g,
                            F.map (𝟙 a, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) a x) =
                              F.map (𝟙 a, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) a y)) } } } } =
      { fst := kx,
        snd :=
          {
            fst :=
              Exists.choose
                (_ :
                  ∃ k f g,
                    F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                      F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)),
            snd :=
              { fst := kxO,
                snd :=
                  { fst := (_ : k j ∈ O),
                    snd :=
                      Exists.choose
                        (_ :
                          ∃ f g,
                            F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                              F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)) } } } }
[PROOFSTEP]
refine' ⟨j, _⟩
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
j : J
⊢ { fst := kx,
      snd :=
        {
          fst :=
            Exists.choose
              (_ :
                ∃ k f g,
                  F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                    F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)),
          snd :=
            { fst := kxO,
              snd :=
                { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}),
                  snd :=
                    Exists.choose
                      (_ :
                        ∃ f g,
                          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)) } } } } =
    { fst := kx,
      snd :=
        {
          fst :=
            Exists.choose
              (_ :
                ∃ k f g,
                  F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                    F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)),
          snd :=
            { fst := kxO,
              snd :=
                { fst := (_ : k j ∈ O),
                  snd :=
                    Exists.choose
                      (_ :
                        ∃ f g,
                          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)) } } } }
[PROOFSTEP]
simp only [heq_iff_eq]
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
have gH : ∀ j, (⟨ky, k j, kyO, kjO j, g j⟩ : Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) ∈ H := fun j =>
  Finset.mem_union.mpr
    (Or.inr
      (by
        simp only [true_and_iff, Finset.mem_univ, eq_self_iff_true, exists_prop_of_true, Finset.mem_image, heq_iff_eq]
        refine' ⟨j, _⟩
        simp only [heq_iff_eq]))
      -- Our goal is now an equation between equivalence classes of representatives of a colimit,
          -- and so it suffices to show those representative become equal somewhere, in particular at `S`.
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
j : J
⊢ { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
[PROOFSTEP]
simp only [true_and_iff, Finset.mem_univ, eq_self_iff_true, exists_prop_of_true, Finset.mem_image, heq_iff_eq]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
j : J
⊢ ∃ a,
    { fst := ky,
        snd :=
          {
            fst :=
              Exists.choose
                (_ :
                  ∃ k f g,
                    F.map (𝟙 a, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) a x) =
                      F.map (𝟙 a, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) a y)),
            snd :=
              { fst := kyO,
                snd :=
                  { fst := (_ : k a ∈ Finset.image k Finset.univ ∪ {kx, ky}),
                    snd :=
                      Exists.choose
                        (_ :
                          ∃ g,
                            F.map
                                (𝟙 a,
                                  Exists.choose
                                    (_ :
                                      ∃ f g,
                                        F.map (𝟙 a, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) a x) =
                                          F.map (𝟙 a, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) a y)))
                                (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) a x) =
                              F.map (𝟙 a, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) a y)) } } } } =
      { fst := ky,
        snd :=
          {
            fst :=
              Exists.choose
                (_ :
                  ∃ k f g,
                    F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                      F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)),
            snd :=
              { fst := kyO,
                snd :=
                  { fst := (_ : k j ∈ O),
                    snd :=
                      Exists.choose
                        (_ :
                          ∃ g,
                            F.map
                                (𝟙 j,
                                  Exists.choose
                                    (_ :
                                      ∃ f g,
                                        F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                                          F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
                                (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                              F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)) } } } }
[PROOFSTEP]
refine' ⟨j, _⟩
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
j : J
⊢ { fst := ky,
      snd :=
        {
          fst :=
            Exists.choose
              (_ :
                ∃ k f g,
                  F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                    F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)),
          snd :=
            { fst := kyO,
              snd :=
                { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}),
                  snd :=
                    Exists.choose
                      (_ :
                        ∃ g,
                          F.map
                              (𝟙 j,
                                Exists.choose
                                  (_ :
                                    ∃ f g,
                                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
                              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)) } } } } =
    { fst := ky,
      snd :=
        {
          fst :=
            Exists.choose
              (_ :
                ∃ k f g,
                  F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                    F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)),
          snd :=
            { fst := kyO,
              snd :=
                { fst := (_ : k j ∈ O),
                  snd :=
                    Exists.choose
                      (_ :
                        ∃ g,
                          F.map
                              (𝟙 j,
                                Exists.choose
                                  (_ :
                                    ∃ f g,
                                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
                              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)) } } } }
[PROOFSTEP]
simp only [heq_iff_eq]
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
gH :
  ∀ (j : J),
    { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈ H
⊢ colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) kx x = colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) ky y
[PROOFSTEP]
apply
  colimit_sound'.{v, v} (T kxO)
    (T kyO)
      -- We can check if two elements of a limit (in `Type`)
          -- are equal by comparing them componentwise.
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
gH :
  ∀ (j : J),
    { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈ H
⊢ (curry.obj (swap K J ⋙ F) ⋙ lim).map (T kxO) x = (curry.obj (swap K J ⋙ F) ⋙ lim).map (T kyO) y
[PROOFSTEP]
ext j
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
gH :
  ∀ (j : J),
    { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈ H
j : J
⊢ limit.π ((curry.obj (swap K J ⋙ F)).obj S) j ((curry.obj (swap K J ⋙ F) ⋙ lim).map (T kxO) x) =
    limit.π ((curry.obj (swap K J ⋙ F)).obj S) j ((curry.obj (swap K J ⋙ F) ⋙ lim).map (T kyO) y)
[PROOFSTEP]
simp only [Functor.comp_map, Limit.map_π_apply, curry_obj_map_app, swap_map]
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
gH :
  ∀ (j : J),
    { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈ H
j : J
⊢ limit.π ((curry.obj (swap K J ⋙ F)).obj S) j (lim.map ((curry.obj (swap K J ⋙ F)).map (T kxO)) x) =
    limit.π ((curry.obj (swap K J ⋙ F)).obj S) j (lim.map ((curry.obj (swap K J ⋙ F)).map (T kyO)) y)
[PROOFSTEP]
rw [← W _ _ (fH j)]
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
gH :
  ∀ (j : J),
    { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈ H
j : J
⊢ limit.π ((curry.obj (swap K J ⋙ F)).obj S) j (lim.map ((curry.obj (swap K J ⋙ F)).map (f j ≫ T (_ : k j ∈ O))) x) =
    limit.π ((curry.obj (swap K J ⋙ F)).obj S) j (lim.map ((curry.obj (swap K J ⋙ F)).map (T kyO)) y)
[PROOFSTEP]
rw [← W _ _ (gH j)]
  -- porting note: this was `simp [w]` in lean 3; this is presumably a confluence issue
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : Finite J
val✝ : Fintype J
kx : K
x : limit ((curry.obj (swap K J ⋙ F)).obj kx)
ky : K
y : limit ((curry.obj (swap K J ⋙ F)).obj ky)
h :
  ∀ (j : J),
    ∃ k f g,
      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
k : J → K :=
  fun j =>
    Exists.choose
      (_ :
        ∃ k f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
f : (j : J) → kx ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ f g,
          F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
g : (j : J) → ky ⟶ k j :=
  fun j =>
    Exists.choose
      (_ :
        ∃ g,
          F.map
              (𝟙 j,
                Exists.choose
                  (_ :
                    ∃ f g,
                      F.map (𝟙 j, f) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
                        F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)))
              (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
            F.map (𝟙 j, g) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y))
w :
  ∀ (j : J),
    F.map (𝟙 j, f j) (limit.π ((curry.obj (swap K J ⋙ F)).obj kx) j x) =
      F.map (𝟙 j, g j) (limit.π ((curry.obj (swap K J ⋙ F)).obj ky) j y)
O : Finset K := Finset.image k Finset.univ ∪ {kx, ky}
kxO : kx ∈ O
kyO : ky ∈ O
kjO : ∀ (j : J), k j ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.image
      (fun j =>
        { fst := kx,
          snd :=
            { fst := k j,
              snd :=
                { fst := kxO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := f j } } } })
      Finset.univ ∪
    Finset.image
      (fun j =>
        { fst := ky,
          snd :=
            { fst := k j,
              snd :=
                { fst := kyO, snd := { fst := (_ : k j ∈ Finset.image k Finset.univ ∪ {kx, ky}), snd := g j } } } })
      Finset.univ
S : K
T : {X : K} → X ∈ O → (X ⟶ S)
W :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ T mY = T mX
fH :
  ∀ (j : J),
    { fst := kx, snd := { fst := k j, snd := { fst := kxO, snd := { fst := (_ : k j ∈ O), snd := f j } } } } ∈ H
gH :
  ∀ (j : J),
    { fst := ky, snd := { fst := k j, snd := { fst := kyO, snd := { fst := (_ : k j ∈ O), snd := g j } } } } ∈ H
j : J
⊢ limit.π ((curry.obj (swap K J ⋙ F)).obj S) j (lim.map ((curry.obj (swap K J ⋙ F)).map (f j ≫ T (_ : k j ∈ O))) x) =
    limit.π ((curry.obj (swap K J ⋙ F)).obj S) j (lim.map ((curry.obj (swap K J ⋙ F)).map (g j ≫ T (_ : k j ∈ O))) y)
[PROOFSTEP]
rw [lim_map, lim_map, Limit.map_π_apply', Limit.map_π_apply', Functor.map_comp, Functor.map_comp, FunctorToTypes.comp,
  FunctorToTypes.comp, curry_obj_map_app, curry_obj_map_app, curry_obj_map_app, Functor.comp_map, Functor.comp_map,
  Functor.comp_map, swap_map, swap_map, swap_map, w]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
⊢ Function.Surjective (colimitLimitToLimitColimit F)
[PROOFSTEP]
classical
  -- We begin with some element `x` in the limit (over J) over the colimits (over K),
intro x
have z := fun j =>
  jointly_surjective'.{v, v}
    (limit.π (curry.obj F ⋙ Limits.colim) j x)
      -- `k : J ⟶ K` records where the representative of the
          -- element in the `j`-th element of `x` lives
let k : J → K := fun j => (z j).choose
let y : ∀ j, F.obj (j, k j) := fun j => (z j).choose_spec.choose
have e : ∀ j, colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ Limits.colim) j x := fun j =>
  (z j).choose_spec.choose_spec
clear_value k y
clear z
let k' : K :=
  IsFiltered.sup (Finset.univ.image k)
    ∅
      -- and name the morphisms as `g j : k j ⟶ k'`.
have g : ∀ j, k j ⟶ k' := fun j => IsFiltered.toSup (Finset.univ.image k) ∅ (by simp)
clear_value k'
have w :
  ∀ {j j' : J} (f : j ⟶ j'),
    colimit.ι ((curry.obj F).obj j') k' (F.map ((𝟙 j', g j') : (j', k j') ⟶ (j', k')) (y j')) =
      colimit.ι ((curry.obj F).obj j') k' (F.map ((f, g j) : (j, k j) ⟶ (j', k')) (y j)) :=
  by
  intro j j' f
  have t : (f, g j) = (((f, 𝟙 (k j)) : (j, k j) ⟶ (j', k j)) ≫ (𝟙 j', g j) : (j, k j) ⟶ (j', k')) := by
    simp only [id_comp, comp_id, prod_comp]
  erw [Colimit.w_apply', t, FunctorToTypes.map_comp_apply, Colimit.w_apply', e, ← Limit.w_apply' f, ← e]
  simp
    -- Because `K` is filtered, we can restate this as saying that
        -- for each such `f`, there is some place to the right of `k'`
        -- where these images of `y j` and `y j'` become equal.
simp_rw [colimit_eq_iff.{v, v}] at w 
let kf : ∀ {j j'} (_ : j ⟶ j'), K := fun f => (w f).choose
let gf : ∀ {j j'} (f : j ⟶ j'), k' ⟶ kf f := fun f => (w f).choose_spec.choose
let hf : ∀ {j j'} (f : j ⟶ j'), k' ⟶ kf f := fun f => (w f).choose_spec.choose_spec.choose
have wf :
  ∀ {j j'} (f : j ⟶ j'),
    F.map ((𝟙 j', g j' ≫ gf f) : (j', k j') ⟶ (j', kf f)) (y j') =
      F.map ((f, g j ≫ hf f) : (j, k j) ⟶ (j', kf f)) (y j) :=
  fun {j j'} f =>
  by
  have q :
    ((curry.obj F).obj j').map (gf f) (F.map ((𝟙 j', g j') : (j', k j') ⟶ (j', k')) (y j')) =
      ((curry.obj F).obj j').map (hf f) (F.map ((f, g j) : (j, k j) ⟶ (j', k')) (y j)) :=
    (w f).choose_spec.choose_spec.choose_spec
  rw [curry_obj_obj_map, curry_obj_obj_map] at q 
  simp_rw [← FunctorToTypes.map_comp_apply, CategoryStruct.comp] at q 
  convert q <;> simp only [comp_id]
clear_value kf gf hf
clear w
let O := (Finset.univ.biUnion fun j => Finset.univ.biUnion fun j' => Finset.univ.image (@kf j j')) ∪ { k' }
have kfO : ∀ {j j'} (f : j ⟶ j'), kf f ∈ O := fun {j} {j'} f =>
  Finset.mem_union.mpr
    (Or.inl
      (by
        rw [Finset.mem_biUnion]
        refine' ⟨j, Finset.mem_univ j, _⟩
        rw [Finset.mem_biUnion]
        refine' ⟨j', Finset.mem_univ j', _⟩
        rw [Finset.mem_image]
        refine' ⟨f, Finset.mem_univ _, _⟩
        rfl))
have k'O : k' ∈ O := Finset.mem_union.mpr (Or.inr (Finset.mem_singleton.mpr rfl))
let H : Finset (Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) :=
  Finset.univ.biUnion fun j : J =>
    Finset.univ.biUnion fun j' : J =>
      Finset.univ.biUnion fun f : j ⟶ j' => {⟨k', kf f, k'O, kfO f, gf f⟩, ⟨k', kf f, k'O, kfO f, hf f⟩}
obtain ⟨k'', i', s'⟩ := IsFiltered.sup_exists O H
let i : ∀ {j j'} (f : j ⟶ j'), kf f ⟶ k'' := fun {j} {j'} f => i' (kfO f)
have s : ∀ {j₁ j₂ j₃ j₄} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f' :=
  by
  intros j₁ j₂ j₃ j₄ f f'
  rw [s', s']
    -- porting note: the three goals here in Lean 3 were in a different order
  exact k'O
  swap
  · rw [Finset.mem_biUnion]
    refine' ⟨j₁, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨j₂, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨f, Finset.mem_univ _, _⟩
    simp only [true_or_iff, eq_self_iff_true, and_self_iff, Finset.mem_insert, heq_iff_eq]
  · rw [Finset.mem_biUnion]
    refine' ⟨j₃, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨j₄, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨f', Finset.mem_univ _, _⟩
    simp only [eq_self_iff_true, or_true_iff, and_self_iff, Finset.mem_insert, Finset.mem_singleton, heq_iff_eq]
clear_value i
clear s' i' H kfO k'O O
fconstructor
·
  -- We construct the pre-image (which, recall is meant to be a point
        -- in the colimit (over `K`) of the limits (over `J`)) via a representative at `k''`.
  apply colimit.ι (curry.obj (swap K J ⋙ F) ⋙ Limits.lim) k'' _
  dsimp
    -- This representative is meant to be an element of a limit,
          -- so we need to construct a family of elements in `F.obj (j, k'')` for varying `j`,
          -- then show that are coherent with respect to morphisms in the `j` direction.
  apply Limit.mk.{v, v}
  swap
  ·
    -- We construct the elements as the images of the `y j`.exact fun j =>
      F.map (⟨𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)⟩ : (j, k j) ⟶ (j, k'')) (y j)
  ·
    -- After which it's just a calculation, using `s` and `wf`, to see they are coherent.
    dsimp
    intro j j' f
    simp only [← FunctorToTypes.map_comp_apply, prod_comp, id_comp, comp_id]
    calc
      F.map ((f, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) : (j, k j) ⟶ (j', k'')) (y j) =
          F.map ((f, g j ≫ hf f ≫ i f) : (j, k j) ⟶ (j', k'')) (y j) :=
        by rw [s (𝟙 j) f]
      _ = F.map ((𝟙 j', i f) : (j', kf f) ⟶ (j', k'')) (F.map ((f, g j ≫ hf f) : (j, k j) ⟶ (j', kf f)) (y j)) := by
        rw [← FunctorToTypes.map_comp_apply, prod_comp, comp_id, assoc]
      _ = F.map ((𝟙 j', i f) : (j', kf f) ⟶ (j', k'')) (F.map ((𝟙 j', g j' ≫ gf f) : (j', k j') ⟶ (j', kf f)) (y j')) :=
        by rw [← wf f]
      _ = F.map ((𝟙 j', g j' ≫ gf f ≫ i f) : (j', k j') ⟶ (j', k'')) (y j') := by
        rw [← FunctorToTypes.map_comp_apply, prod_comp, id_comp, assoc]
      _ = F.map ((𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) : (j', k j') ⟶ (j', k'')) (y j') := by
        rw [s f (𝟙 j'), ← s (𝟙 j') (𝟙 j')]
          -- Finally we check that this maps to `x`.
·
  -- We can do this componentwise:
  apply limit_ext'
  intro j
  simp only [id.def, ← e, Limits.ι_colimitLimitToLimitColimit_π_apply, colimit_eq_iff.{v, v}, Bifunctor.map_id_comp,
    types_comp_apply, curry_obj_obj_map, Functor.comp_obj, colim_obj, Limit.π_mk]
  refine'
    ⟨k'', 𝟙 k'', g j ≫ gf (𝟙 j) ≫ i (𝟙 j), _⟩
      -- porting note: the lean 3 proof finished with
            -- `simp only [Bifunctor.map_id_comp, types_comp_apply, Bifunctor.map_id, types_id_apply]`
            -- which doesn't work; the corresponding `rw` works fine:
  rw [Bifunctor.map_id_comp, Bifunctor.map_id_comp, types_comp_apply, types_comp_apply, Bifunctor.map_id,
    types_id_apply]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
⊢ Function.Surjective (colimitLimitToLimitColimit F)
[PROOFSTEP]
intro x
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have z := fun j =>
  jointly_surjective'.{v, v}
    (limit.π (curry.obj F ⋙ Limits.colim) j x)
      -- `k : J ⟶ K` records where the representative of the
          -- element in the `j`-th element of `x` lives
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
z : ∀ (j : J), ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let k : J → K := fun j => (z j).choose
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
z : ∀ (j : J), ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x
k : J → K :=
  fun j => Exists.choose (_ : ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let y : ∀ j, F.obj (j, k j) := fun j => (z j).choose_spec.choose
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
z : ∀ (j : J), ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x
k : J → K :=
  fun j => Exists.choose (_ : ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x)
y : (j : J) → F.obj (j, k j) :=
  fun j =>
    Exists.choose
      (_ :
        ∃ y,
          colimit.ι ((curry.obj F).obj j)
              (Exists.choose (_ : ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x))
              y =
            limit.π (curry.obj F ⋙ colim) j x)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have e : ∀ j, colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ Limits.colim) j x := fun j =>
  (z j).choose_spec.choose_spec
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
z : ∀ (j : J), ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x
k : J → K :=
  fun j => Exists.choose (_ : ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x)
y : (j : J) → F.obj (j, k j) :=
  fun j =>
    Exists.choose
      (_ :
        ∃ y,
          colimit.ι ((curry.obj F).obj j)
              (Exists.choose (_ : ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x))
              y =
            limit.π (curry.obj F ⋙ colim) j x)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear_value k y
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
z : ∀ (j : J), ∃ j_1 y, colimit.ι ((curry.obj F).obj j) j_1 y = limit.π (curry.obj F ⋙ colim) j x
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear z
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let k' : K :=
  IsFiltered.sup (Finset.univ.image k)
    ∅
      -- and name the morphisms as `g j : k j ⟶ k'`.
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K := IsFiltered.sup (Finset.image k Finset.univ) ∅
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have g : ∀ j, k j ⟶ k' := fun j => IsFiltered.toSup (Finset.univ.image k) ∅ (by simp)
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K := IsFiltered.sup (Finset.image k Finset.univ) ∅
j : J
⊢ k j ∈ Finset.image k Finset.univ
[PROOFSTEP]
simp
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K := IsFiltered.sup (Finset.image k Finset.univ) ∅
g : (j : J) → k j ⟶ k'
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear_value k'
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have w :
  ∀ {j j' : J} (f : j ⟶ j'),
    colimit.ι ((curry.obj F).obj j') k' (F.map ((𝟙 j', g j') : (j', k j') ⟶ (j', k')) (y j')) =
      colimit.ι ((curry.obj F).obj j') k' (F.map ((f, g j) : (j, k j) ⟶ (j', k')) (y j)) :=
  by
  intro j j' f
  have t : (f, g j) = (((f, 𝟙 (k j)) : (j, k j) ⟶ (j', k j)) ≫ (𝟙 j', g j) : (j, k j) ⟶ (j', k')) := by
    simp only [id_comp, comp_id, prod_comp]
  erw [Colimit.w_apply', t, FunctorToTypes.map_comp_apply, Colimit.w_apply', e, ← Limit.w_apply' f, ← e]
  simp
    -- Because `K` is filtered, we can restate this as saying that
        -- for each such `f`, there is some place to the right of `k'`
        -- where these images of `y j` and `y j'` become equal.
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
⊢ ∀ {j j' : J} (f : j ⟶ j'),
    colimit.ι ((curry.obj F).obj j') k' (F.map (𝟙 j', g j') (y j')) =
      colimit.ι ((curry.obj F).obj j') k' (F.map (f, g j) (y j))
[PROOFSTEP]
intro j j' f
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
j j' : J
f : j ⟶ j'
⊢ colimit.ι ((curry.obj F).obj j') k' (F.map (𝟙 j', g j') (y j')) =
    colimit.ι ((curry.obj F).obj j') k' (F.map (f, g j) (y j))
[PROOFSTEP]
have t : (f, g j) = (((f, 𝟙 (k j)) : (j, k j) ⟶ (j', k j)) ≫ (𝟙 j', g j) : (j, k j) ⟶ (j', k')) := by
  simp only [id_comp, comp_id, prod_comp]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
j j' : J
f : j ⟶ j'
⊢ (f, g j) = (f, 𝟙 (k j)) ≫ (𝟙 j', g j)
[PROOFSTEP]
simp only [id_comp, comp_id, prod_comp]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
j j' : J
f : j ⟶ j'
t : (f, g j) = (f, 𝟙 (k j)) ≫ (𝟙 j', g j)
⊢ colimit.ι ((curry.obj F).obj j') k' (F.map (𝟙 j', g j') (y j')) =
    colimit.ι ((curry.obj F).obj j') k' (F.map (f, g j) (y j))
[PROOFSTEP]
erw [Colimit.w_apply', t, FunctorToTypes.map_comp_apply, Colimit.w_apply', e, ← Limit.w_apply' f, ← e]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
j j' : J
f : j ⟶ j'
t : (f, g j) = (f, 𝟙 (k j)) ≫ (𝟙 j', g j)
⊢ (curry.obj F ⋙ colim).map f (colimit.ι ((curry.obj F).obj j) (k j) (y j)) =
    colimit.ι ((curry.obj F).obj j') (k j) (F.map (f, 𝟙 (k j)) (y j))
[PROOFSTEP]
simp
  -- Because `K` is filtered, we can restate this as saying that
      -- for each such `f`, there is some place to the right of `k'`
      -- where these images of `y j` and `y j'` become equal.
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    colimit.ι ((curry.obj F).obj j') k' (F.map (𝟙 j', g j') (y j')) =
      colimit.ι ((curry.obj F).obj j') k' (F.map (f, g j) (y j))
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
simp_rw [colimit_eq_iff.{v, v}] at w 
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let kf : ∀ {j j'} (_ : j ⟶ j'), K := fun f => (w f).choose
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let gf : ∀ {j j'} (f : j ⟶ j'), k' ⟶ kf f := fun f => (w f).choose_spec.choose
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let hf : ∀ {j j'} (f : j ⟶ j'), k' ⟶ kf f := fun f => (w f).choose_spec.choose_spec.choose
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have wf :
  ∀ {j j'} (f : j ⟶ j'),
    F.map ((𝟙 j', g j' ≫ gf f) : (j', k j') ⟶ (j', kf f)) (y j') =
      F.map ((f, g j ≫ hf f) : (j, k j) ⟶ (j', kf f)) (y j) :=
  fun {j j'} f =>
  by
  have q :
    ((curry.obj F).obj j').map (gf f) (F.map ((𝟙 j', g j') : (j', k j') ⟶ (j', k')) (y j')) =
      ((curry.obj F).obj j').map (hf f) (F.map ((f, g j) : (j, k j) ⟶ (j', k')) (y j)) :=
    (w f).choose_spec.choose_spec.choose_spec
  rw [curry_obj_obj_map, curry_obj_obj_map] at q 
  simp_rw [← FunctorToTypes.map_comp_apply, CategoryStruct.comp] at q 
  convert q <;> simp only [comp_id]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
j j' : J
f : j ⟶ j'
⊢ F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
[PROOFSTEP]
have q :
  ((curry.obj F).obj j').map (gf f) (F.map ((𝟙 j', g j') : (j', k j') ⟶ (j', k')) (y j')) =
    ((curry.obj F).obj j').map (hf f) (F.map ((f, g j) : (j, k j) ⟶ (j', k')) (y j)) :=
  (w f).choose_spec.choose_spec.choose_spec
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
j j' : J
f : j ⟶ j'
q :
  ((curry.obj F).obj j').map (gf f) (F.map (𝟙 j', g j') (y j')) =
    ((curry.obj F).obj j').map (hf f) (F.map (f, g j) (y j))
⊢ F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
[PROOFSTEP]
rw [curry_obj_obj_map, curry_obj_obj_map] at q 
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
j j' : J
f : j ⟶ j'
q : F.map (𝟙 j', gf f) (F.map (𝟙 j', g j') (y j')) = F.map (𝟙 j', hf f) (F.map (f, g j) (y j))
⊢ F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
[PROOFSTEP]
simp_rw [← FunctorToTypes.map_comp_apply, CategoryStruct.comp] at q 
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
j j' : J
f : j ⟶ j'
q :
  F.map
      (𝟙 j' ≫ 𝟙 j',
        g j' ≫
          Exists.choose
            (_ :
              ∃ f_1 g_1,
                ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                  ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
      (y j') =
    F.map
      (f ≫ 𝟙 j',
        g j ≫
          Exists.choose
            (_ :
              ∃ g_1,
                ((curry.obj F).obj j').map
                    (Exists.choose
                      (_ :
                        ∃ f_1 g_2,
                          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                            ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
                    (F.map (𝟙 j', g j') (y j')) =
                  ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
      (y j)
⊢ F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
[PROOFSTEP]
convert q
[GOAL]
case h.e'_2.h.h.e'_4.h.e'_3
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
j j' : J
f : j ⟶ j'
q :
  F.map
      (𝟙 j' ≫ 𝟙 j',
        g j' ≫
          Exists.choose
            (_ :
              ∃ f_1 g_1,
                ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                  ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
      (y j') =
    F.map
      (f ≫ 𝟙 j',
        g j ≫
          Exists.choose
            (_ :
              ∃ g_1,
                ((curry.obj F).obj j').map
                    (Exists.choose
                      (_ :
                        ∃ f_1 g_2,
                          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                            ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
                    (F.map (𝟙 j', g j') (y j')) =
                  ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
      (y j)
e_1✝ :
  F.obj (j', kf f) =
    ((curry.obj F).obj j').obj
      (Exists.choose
        (_ :
          ∃ k_1 f_1 g_1,
            ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
              ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
⊢ 𝟙 j' = 𝟙 j' ≫ 𝟙 j'
[PROOFSTEP]
simp only [comp_id]
[GOAL]
case h.e'_3.h.h.e'_4.h.e'_3
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
j j' : J
f : j ⟶ j'
q :
  F.map
      (𝟙 j' ≫ 𝟙 j',
        g j' ≫
          Exists.choose
            (_ :
              ∃ f_1 g_1,
                ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                  ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
      (y j') =
    F.map
      (f ≫ 𝟙 j',
        g j ≫
          Exists.choose
            (_ :
              ∃ g_1,
                ((curry.obj F).obj j').map
                    (Exists.choose
                      (_ :
                        ∃ f_1 g_2,
                          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                            ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
                    (F.map (𝟙 j', g j') (y j')) =
                  ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
      (y j)
e_1✝ :
  F.obj (j', kf f) =
    ((curry.obj F).obj j').obj
      (Exists.choose
        (_ :
          ∃ k_1 f_1 g_1,
            ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
              ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))))
⊢ f = f ≫ 𝟙 j'
[PROOFSTEP]
simp only [comp_id]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ k_1 f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ f_1 g_1,
          ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
hf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f :=
  fun {j j'} f =>
    Exists.choose
      (_ :
        ∃ g_1,
          ((curry.obj F).obj j').map
              (Exists.choose
                (_ :
                  ∃ f_1 g_2,
                    ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) =
                      ((curry.obj F).obj j').map g_2 (F.map (f, g j) (y j))))
              (F.map (𝟙 j', g j') (y j')) =
            ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j)))
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear_value kf gf hf
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
w :
  ∀ {j j' : J} (f : j ⟶ j'),
    ∃ k_1 f_1 g_1,
      ((curry.obj F).obj j').map f_1 (F.map (𝟙 j', g j') (y j')) = ((curry.obj F).obj j').map g_1 (F.map (f, g j) (y j))
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear w
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let O := (Finset.univ.biUnion fun j => Finset.univ.biUnion fun j' => Finset.univ.image (@kf j j')) ∪ { k' }
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have kfO : ∀ {j j'} (f : j ⟶ j'), kf f ∈ O := fun {j} {j'} f =>
  Finset.mem_union.mpr
    (Or.inl
      (by
        rw [Finset.mem_biUnion]
        refine' ⟨j, Finset.mem_univ j, _⟩
        rw [Finset.mem_biUnion]
        refine' ⟨j', Finset.mem_univ j', _⟩
        rw [Finset.mem_image]
        refine' ⟨f, Finset.mem_univ _, _⟩
        rfl))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ kf f ∈ Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ ∃ a, a ∈ Finset.univ ∧ kf f ∈ Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ
[PROOFSTEP]
refine' ⟨j, Finset.mem_univ j, _⟩
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ kf f ∈ Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ ∃ a, a ∈ Finset.univ ∧ kf f ∈ Finset.image kf Finset.univ
[PROOFSTEP]
refine' ⟨j', Finset.mem_univ j', _⟩
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ kf f ∈ Finset.image kf Finset.univ
[PROOFSTEP]
rw [Finset.mem_image]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ ∃ a, a ∈ Finset.univ ∧ kf a = kf f
[PROOFSTEP]
refine' ⟨f, Finset.mem_univ _, _⟩
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
j j' : J
f : j ⟶ j'
⊢ kf f = kf f
[PROOFSTEP]
rfl
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have k'O : k' ∈ O := Finset.mem_union.mpr (Or.inr (Finset.mem_singleton.mpr rfl))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let H : Finset (Σ' (X Y : K) (_ : X ∈ O) (_ : Y ∈ O), X ⟶ Y) :=
  Finset.univ.biUnion fun j : J =>
    Finset.univ.biUnion fun j' : J =>
      Finset.univ.biUnion fun f : j ⟶ j' => {⟨k', kf f, k'O, kfO f, gf f⟩, ⟨k', kf f, k'O, kfO f, hf f⟩}
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
obtain ⟨k'', i', s'⟩ := IsFiltered.sup_exists O H
[GOAL]
case intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
let i : ∀ {j j'} (f : j ⟶ j'), kf f ⟶ k'' := fun {j} {j'} f => i' (kfO f)
[GOAL]
case intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
have s : ∀ {j₁ j₂ j₃ j₄} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f' :=
  by
  intros j₁ j₂ j₃ j₄ f f'
  rw [s', s']
    -- porting note: the three goals here in Lean 3 were in a different order
  exact k'O
  swap
  · rw [Finset.mem_biUnion]
    refine' ⟨j₁, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨j₂, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨f, Finset.mem_univ _, _⟩
    simp only [true_or_iff, eq_self_iff_true, and_self_iff, Finset.mem_insert, heq_iff_eq]
  · rw [Finset.mem_biUnion]
    refine' ⟨j₃, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨j₄, Finset.mem_univ _, _⟩
    rw [Finset.mem_biUnion]
    refine' ⟨f', Finset.mem_univ _, _⟩
    simp only [eq_self_iff_true, or_true_iff, and_self_iff, Finset.mem_insert, Finset.mem_singleton, heq_iff_eq]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
⊢ ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
[PROOFSTEP]
intros j₁ j₂ j₃ j₄ f f'
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ gf f ≫ i f = hf f' ≫ i f'
[PROOFSTEP]
rw [s', s']
  -- porting note: the three goals here in Lean 3 were in a different order
[GOAL]
case mX
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ k' ∈ O
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f', snd := { fst := ?mX, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈ H
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f, snd := { fst := ?mX, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈ H
[PROOFSTEP]
exact k'O
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈ H
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈ H
[PROOFSTEP]
swap
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈ H
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ ∃ a,
    a ∈ Finset.univ ∧
      { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈
        Finset.biUnion Finset.univ fun j' =>
          Finset.biUnion Finset.univ fun f =>
            {{ fst := k',
                snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
              { fst := k',
                snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
refine' ⟨j₁, Finset.mem_univ _, _⟩
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ ∃ a,
    a ∈ Finset.univ ∧
      { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈
        Finset.biUnion Finset.univ fun f =>
          {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
            { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
refine' ⟨j₂, Finset.mem_univ _, _⟩
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈
    Finset.biUnion Finset.univ fun f =>
      {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
        { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ ∃ a,
    a ∈ Finset.univ ∧
      { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈
        {{ fst := k', snd := { fst := kf a, snd := { fst := k'O, snd := { fst := (_ : kf a ∈ O), snd := gf a } } } },
          { fst := k', snd := { fst := kf a, snd := { fst := k'O, snd := { fst := (_ : kf a ∈ O), snd := hf a } } } }}
[PROOFSTEP]
refine' ⟨f, Finset.mem_univ _, _⟩
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } } ∈
    {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
      { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
simp only [true_or_iff, eq_self_iff_true, and_self_iff, Finset.mem_insert, heq_iff_eq]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈ H
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ ∃ a,
    a ∈ Finset.univ ∧
      { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈
        Finset.biUnion Finset.univ fun j' =>
          Finset.biUnion Finset.univ fun f =>
            {{ fst := k',
                snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
              { fst := k',
                snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
refine' ⟨j₃, Finset.mem_univ _, _⟩
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ ∃ a,
    a ∈ Finset.univ ∧
      { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈
        Finset.biUnion Finset.univ fun f =>
          {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
            { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
refine' ⟨j₄, Finset.mem_univ _, _⟩
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈
    Finset.biUnion Finset.univ fun f =>
      {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
        { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
[PROOFSTEP]
rw [Finset.mem_biUnion]
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ ∃ a,
    a ∈ Finset.univ ∧
      { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈
        {{ fst := k', snd := { fst := kf a, snd := { fst := k'O, snd := { fst := (_ : kf a ∈ O), snd := gf a } } } },
          { fst := k', snd := { fst := kf a, snd := { fst := k'O, snd := { fst := (_ : kf a ∈ O), snd := hf a } } } }}
[PROOFSTEP]
refine' ⟨f', Finset.mem_univ _, _⟩
[GOAL]
case a
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
j₁ j₂ j₃ j₄ : J
f : j₁ ⟶ j₂
f' : j₃ ⟶ j₄
⊢ { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } } ∈
    {{ fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := gf f' } } } },
      { fst := k', snd := { fst := kf f', snd := { fst := k'O, snd := { fst := (_ : kf f' ∈ O), snd := hf f' } } } }}
[PROOFSTEP]
simp only [eq_self_iff_true, or_true_iff, and_self_iff, Finset.mem_insert, Finset.mem_singleton, heq_iff_eq]
[GOAL]
case intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k'' := fun {j j'} f => i' (_ : kf f ∈ O)
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear_value i
[GOAL]
case intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
O : Finset K :=
  (Finset.biUnion Finset.univ fun j => Finset.biUnion Finset.univ fun j' => Finset.image kf Finset.univ) ∪ {k'}
kfO : ∀ {j j' : J} (f : j ⟶ j'), kf f ∈ O
k'O : k' ∈ O
H : Finset ((X : K) ×' (Y : K) ×' (_ : X ∈ O) ×' (_ : Y ∈ O) ×' (X ⟶ Y)) :=
  Finset.biUnion Finset.univ fun j =>
    Finset.biUnion Finset.univ fun j' =>
      Finset.biUnion Finset.univ fun f =>
        {{ fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := gf f } } } },
          { fst := k', snd := { fst := kf f, snd := { fst := k'O, snd := { fst := (_ : kf f ∈ O), snd := hf f } } } }}
k'' : K
i' : {X : K} → X ∈ O → (X ⟶ k'')
s' :
  ∀ {X Y : K} (mX : X ∈ O) (mY : Y ∈ O) {f : X ⟶ Y},
    { fst := X, snd := { fst := Y, snd := { fst := mX, snd := { fst := mY, snd := f } } } } ∈ H → f ≫ i' mY = i' mX
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
clear s' i' H kfO k'O O
[GOAL]
case intro.intro
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∃ a, colimitLimitToLimitColimit F a = x
[PROOFSTEP]
fconstructor
[GOAL]
case intro.intro.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ colimit (curry.obj (swap K J ⋙ F) ⋙ lim)
[PROOFSTEP]
apply colimit.ι (curry.obj (swap K J ⋙ F) ⋙ Limits.lim) k'' _
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ (curry.obj (swap K J ⋙ F) ⋙ lim).obj k''
[PROOFSTEP]
dsimp
  -- This representative is meant to be an element of a limit,
        -- so we need to construct a family of elements in `F.obj (j, k'')` for varying `j`,
        -- then show that are coherent with respect to morphisms in the `j` direction.
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ limit ((curry.obj (swap K J ⋙ F)).obj k'')
[PROOFSTEP]
apply Limit.mk.{v, v}
[GOAL]
case h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∀ (j j' : J) (f : j ⟶ j'), ((curry.obj (swap K J ⋙ F)).obj k'').map f (?x j) = ?x j'
case x
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ (j : J) → ((curry.obj (swap K J ⋙ F)).obj k'').obj j
[PROOFSTEP]
swap
[GOAL]
case x
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ (j : J) → ((curry.obj (swap K J ⋙ F)).obj k'').obj j
[PROOFSTEP]
exact fun j => F.map (⟨𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)⟩ : (j, k j) ⟶ (j, k'')) (y j)
[GOAL]
case h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∀ (j j' : J) (f : j ⟶ j'),
    ((curry.obj (swap K J ⋙ F)).obj k'').map f (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) =
      F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')
[PROOFSTEP]
dsimp
[GOAL]
case h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∀ (j j' : J) (f : j ⟶ j'),
    F.map (f, 𝟙 k'') (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) = F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')
[PROOFSTEP]
intro j j' f
[GOAL]
case h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (f, 𝟙 k'') (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) = F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')
[PROOFSTEP]
simp only [← FunctorToTypes.map_comp_apply, prod_comp, id_comp, comp_id]
[GOAL]
case h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (f, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j) = F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')
[PROOFSTEP]
calc
  F.map ((f, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) : (j, k j) ⟶ (j', k'')) (y j) =
      F.map ((f, g j ≫ hf f ≫ i f) : (j, k j) ⟶ (j', k'')) (y j) :=
    by rw [s (𝟙 j) f]
  _ = F.map ((𝟙 j', i f) : (j', kf f) ⟶ (j', k'')) (F.map ((f, g j ≫ hf f) : (j, k j) ⟶ (j', kf f)) (y j)) := by
    rw [← FunctorToTypes.map_comp_apply, prod_comp, comp_id, assoc]
  _ = F.map ((𝟙 j', i f) : (j', kf f) ⟶ (j', k'')) (F.map ((𝟙 j', g j' ≫ gf f) : (j', k j') ⟶ (j', kf f)) (y j')) := by
    rw [← wf f]
  _ = F.map ((𝟙 j', g j' ≫ gf f ≫ i f) : (j', k j') ⟶ (j', k'')) (y j') := by
    rw [← FunctorToTypes.map_comp_apply, prod_comp, id_comp, assoc]
  _ = F.map ((𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) : (j', k j') ⟶ (j', k'')) (y j') := by
    rw [s f (𝟙 j'), ← s (𝟙 j') (𝟙 j')]
      -- Finally we check that this maps to `x`.
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (f, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j) = F.map (f, g j ≫ hf f ≫ i f) (y j)
[PROOFSTEP]
rw [s (𝟙 j) f]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (f, g j ≫ hf f ≫ i f) (y j) = F.map (𝟙 j', i f) (F.map (f, g j ≫ hf f) (y j))
[PROOFSTEP]
rw [← FunctorToTypes.map_comp_apply, prod_comp, comp_id, assoc]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (𝟙 j', i f) (F.map (f, g j ≫ hf f) (y j)) = F.map (𝟙 j', i f) (F.map (𝟙 j', g j' ≫ gf f) (y j'))
[PROOFSTEP]
rw [← wf f]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (𝟙 j', i f) (F.map (𝟙 j', g j' ≫ gf f) (y j')) = F.map (𝟙 j', g j' ≫ gf f ≫ i f) (y j')
[PROOFSTEP]
rw [← FunctorToTypes.map_comp_apply, prod_comp, id_comp, assoc]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j j' : J
f : j ⟶ j'
⊢ F.map (𝟙 j', g j' ≫ gf f ≫ i f) (y j') = F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')
[PROOFSTEP]
rw [s f (𝟙 j'), ← s (𝟙 j') (𝟙 j')]
  -- Finally we check that this maps to `x`.
[GOAL]
case intro.intro.h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ colimitLimitToLimitColimit F
      (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) k''
        (id
          (Limit.mk ((curry.obj (swap K J ⋙ F)).obj k'') (fun j => F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j))
            (_ :
              ∀ (j j' : J) (f : j ⟶ j'),
                ((curry.obj (swap K J ⋙ F)).obj k'').map f (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) =
                  F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j'))))) =
    x
[PROOFSTEP]
apply limit_ext'
[GOAL]
case intro.intro.h.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
⊢ ∀ (j : J),
    limit.π (curry.obj F ⋙ colim) j
        (colimitLimitToLimitColimit F
          (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) k''
            (id
              (Limit.mk ((curry.obj (swap K J ⋙ F)).obj k'') (fun j => F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j))
                (_ :
                  ∀ (j j' : J) (f : j ⟶ j'),
                    ((curry.obj (swap K J ⋙ F)).obj k'').map f (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) =
                      F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')))))) =
      limit.π (curry.obj F ⋙ colim) j x
[PROOFSTEP]
intro j
[GOAL]
case intro.intro.h.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j : J
⊢ limit.π (curry.obj F ⋙ colim) j
      (colimitLimitToLimitColimit F
        (colimit.ι (curry.obj (swap K J ⋙ F) ⋙ lim) k''
          (id
            (Limit.mk ((curry.obj (swap K J ⋙ F)).obj k'') (fun j => F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j))
              (_ :
                ∀ (j j' : J) (f : j ⟶ j'),
                  ((curry.obj (swap K J ⋙ F)).obj k'').map f (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) =
                    F.map (𝟙 j', g j' ≫ gf (𝟙 j') ≫ i (𝟙 j')) (y j')))))) =
    limit.π (curry.obj F ⋙ colim) j x
[PROOFSTEP]
simp only [id.def, ← e, Limits.ι_colimitLimitToLimitColimit_π_apply, colimit_eq_iff.{v, v}, Bifunctor.map_id_comp,
  types_comp_apply, curry_obj_obj_map, Functor.comp_obj, colim_obj, Limit.π_mk]
[GOAL]
case intro.intro.h.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j : J
⊢ ∃ k_1 f g_1, F.map (𝟙 j, f) (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) = F.map (𝟙 j, g_1) (y j)
[PROOFSTEP]
refine'
  ⟨k'', 𝟙 k'', g j ≫ gf (𝟙 j) ≫ i (𝟙 j), _⟩
    -- porting note: the lean 3 proof finished with
          -- `simp only [Bifunctor.map_id_comp, types_comp_apply, Bifunctor.map_id, types_id_apply]`
          -- which doesn't work; the corresponding `rw` works fine:
[GOAL]
case intro.intro.h.w
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
x : limit (curry.obj F ⋙ colim)
k : J → K
y : (j : J) → F.obj (j, k j)
e : ∀ (j : J), colimit.ι ((curry.obj F).obj j) (k j) (y j) = limit.π (curry.obj F ⋙ colim) j x
k' : K
g : (j : J) → k j ⟶ k'
kf : {j j' : J} → (j ⟶ j') → K
hf gf : {j j' : J} → (f : j ⟶ j') → k' ⟶ kf f
wf : ∀ {j j' : J} (f : j ⟶ j'), F.map (𝟙 j', g j' ≫ gf f) (y j') = F.map (f, g j ≫ hf f) (y j)
k'' : K
i : {j j' : J} → (f : j ⟶ j') → kf f ⟶ k''
s : ∀ {j₁ j₂ j₃ j₄ : J} (f : j₁ ⟶ j₂) (f' : j₃ ⟶ j₄), gf f ≫ i f = hf f' ≫ i f'
j : J
⊢ F.map (𝟙 j, 𝟙 k'') (F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)) = F.map (𝟙 j, g j ≫ gf (𝟙 j) ≫ i (𝟙 j)) (y j)
[PROOFSTEP]
rw [Bifunctor.map_id_comp, Bifunctor.map_id_comp, types_comp_apply, types_comp_apply, Bifunctor.map_id, types_id_apply]
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
F : J ⥤ K ⥤ Type v
⊢ IsIso (colimitLimitToLimitColimitCone F)
[PROOFSTEP]
have : IsIso (colimitLimitToLimitColimitCone F).Hom :=
  by
  suffices :
    IsIso (colimitLimitToLimitColimit (uncurry.obj F) ≫ lim.map (whiskerRight (currying.unitIso.app F).inv colim))
  apply IsIso.comp_isIso
  infer_instance
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
F : J ⥤ K ⥤ Type v
⊢ IsIso (colimitLimitToLimitColimitCone F).Hom
[PROOFSTEP]
suffices :
  IsIso (colimitLimitToLimitColimit (uncurry.obj F) ≫ lim.map (whiskerRight (currying.unitIso.app F).inv colim))
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
F : J ⥤ K ⥤ Type v
this : IsIso (colimitLimitToLimitColimit (uncurry.obj F) ≫ lim.map (whiskerRight (currying.unitIso.app F).inv colim))
⊢ IsIso (colimitLimitToLimitColimitCone F).Hom
case this
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
F : J ⥤ K ⥤ Type v
⊢ IsIso (colimitLimitToLimitColimit (uncurry.obj F) ≫ lim.map (whiskerRight (currying.unitIso.app F).inv colim))
[PROOFSTEP]
apply IsIso.comp_isIso
[GOAL]
case this
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
F : J ⥤ K ⥤ Type v
⊢ IsIso (colimitLimitToLimitColimit (uncurry.obj F) ≫ lim.map (whiskerRight (currying.unitIso.app F).inv colim))
[PROOFSTEP]
infer_instance
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
F : J ⥤ K ⥤ Type v
this : IsIso (colimitLimitToLimitColimitCone F).Hom
⊢ IsIso (colimitLimitToLimitColimitCone F)
[PROOFSTEP]
apply Cones.cone_iso_of_hom_iso
[GOAL]
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
⊢ PreservesFiniteLimits colim
[PROOFSTEP]
apply preservesFiniteLimitsOfPreservesFiniteLimitsOfSize.{v}
[GOAL]
case h
J K : Type v
inst✝³ : SmallCategory J
inst✝² : SmallCategory K
F : J × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J
⊢ (J : Type v) → {𝒥 : SmallCategory J} → FinCategory J → PreservesLimitsOfShape J colim
[PROOFSTEP]
intro J _ _
[GOAL]
case h
J✝ K : Type v
inst✝³ : SmallCategory J✝
inst✝² : SmallCategory K
F : J✝ × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J✝
J : Type v
𝒥✝ : SmallCategory J
x✝ : FinCategory J
⊢ PreservesLimitsOfShape J colim
[PROOFSTEP]
refine ⟨fun {F} => ⟨fun {c} hc => IsLimit.ofIsoLimit (limit.isLimit _) ?_⟩⟩
[GOAL]
case h
J✝ K : Type v
inst✝³ : SmallCategory J✝
inst✝² : SmallCategory K
F✝ : J✝ × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J✝
J : Type v
𝒥✝ : SmallCategory J
x✝ : FinCategory J
F : J ⥤ K ⥤ Type v
c : Cone F
hc : IsLimit c
⊢ limit.cone (F ⋙ colim) ≅ colim.mapCone c
[PROOFSTEP]
symm
[GOAL]
case h
J✝ K : Type v
inst✝³ : SmallCategory J✝
inst✝² : SmallCategory K
F✝ : J✝ × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J✝
J : Type v
𝒥✝ : SmallCategory J
x✝ : FinCategory J
F : J ⥤ K ⥤ Type v
c : Cone F
hc : IsLimit c
⊢ colim.mapCone c ≅ limit.cone (F ⋙ colim)
[PROOFSTEP]
trans colim.mapCone (limit.cone F)
[GOAL]
J✝ K : Type v
inst✝³ : SmallCategory J✝
inst✝² : SmallCategory K
F✝ : J✝ × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J✝
J : Type v
𝒥✝ : SmallCategory J
x✝ : FinCategory J
F : J ⥤ K ⥤ Type v
c : Cone F
hc : IsLimit c
⊢ colim.mapCone c ≅ colim.mapCone (limit.cone F)
[PROOFSTEP]
exact Functor.mapIso _ (hc.uniqueUpToIso (limit.isLimit F))
[GOAL]
J✝ K : Type v
inst✝³ : SmallCategory J✝
inst✝² : SmallCategory K
F✝ : J✝ × K ⥤ Type v
inst✝¹ : IsFiltered K
inst✝ : FinCategory J✝
J : Type v
𝒥✝ : SmallCategory J
x✝ : FinCategory J
F : J ⥤ K ⥤ Type v
c : Cone F
hc : IsLimit c
⊢ colim.mapCone (limit.cone F) ≅ limit.cone (F ⋙ colim)
[PROOFSTEP]
exact asIso (colimitLimitToLimitColimitCone.{v, v + 1} F)
[GOAL]
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : PreservesFiniteLimits (forget C)
inst✝³ : PreservesFilteredColimits (forget C)
inst✝² : HasFiniteLimits C
inst✝¹ : HasColimitsOfShape K C
inst✝ : ReflectsIsomorphisms (forget C)
⊢ PreservesFiniteLimits colim
[PROOFSTEP]
apply preservesFiniteLimitsOfPreservesFiniteLimitsOfSize.{v}
[GOAL]
case h
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : PreservesFiniteLimits (forget C)
inst✝³ : PreservesFilteredColimits (forget C)
inst✝² : HasFiniteLimits C
inst✝¹ : HasColimitsOfShape K C
inst✝ : ReflectsIsomorphisms (forget C)
⊢ (J : Type v) → {𝒥 : SmallCategory J} → FinCategory J → PreservesLimitsOfShape J colim
[PROOFSTEP]
intro J _ _
[GOAL]
case h
J✝ K : Type v
inst✝¹⁰ : SmallCategory J✝
inst✝⁹ : SmallCategory K
F : J✝ × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J✝
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : PreservesFiniteLimits (forget C)
inst✝³ : PreservesFilteredColimits (forget C)
inst✝² : HasFiniteLimits C
inst✝¹ : HasColimitsOfShape K C
inst✝ : ReflectsIsomorphisms (forget C)
J : Type v
𝒥✝ : SmallCategory J
x✝ : FinCategory J
⊢ PreservesLimitsOfShape J colim
[PROOFSTEP]
infer_instance
[GOAL]
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasLimitsOfShape J C
inst✝³ : HasColimitsOfShape K C
inst✝² : ReflectsLimitsOfShape J (forget C)
inst✝¹ : PreservesColimitsOfShape K (forget C)
inst✝ : PreservesLimitsOfShape J (forget C)
F : J ⥤ K ⥤ C
a : K
b : J
⊢ colimit.ι (limit F) a ≫ (colimitLimitIso F).hom ≫ limit.π (colimit (Functor.flip F)) b =
    NatTrans.app (limit.π F b) a ≫ NatTrans.app (colimit.ι (Functor.flip F) a) b
[PROOFSTEP]
dsimp [colimitLimitIso]
[GOAL]
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasLimitsOfShape J C
inst✝³ : HasColimitsOfShape K C
inst✝² : ReflectsLimitsOfShape J (forget C)
inst✝¹ : PreservesColimitsOfShape K (forget C)
inst✝ : PreservesLimitsOfShape J (forget C)
F : J ⥤ K ⥤ C
a : K
b : J
⊢ colimit.ι (limit F) a ≫
      ((IsLimit.conePointUniqueUpToIso (isLimitOfPreserves colim (limit.isLimit F)) (limit.isLimit (F ⋙ colim))).hom ≫
          (HasLimit.isoOfNatIso (colimitFlipIsoCompColim F).symm).hom) ≫
        limit.π (colimit (Functor.flip F)) b =
    NatTrans.app (limit.π F b) a ≫ NatTrans.app (colimit.ι (Functor.flip F) a) b
[PROOFSTEP]
simp only [Functor.mapCone_π_app, Iso.symm_hom, Limits.limit.conePointUniqueUpToIso_hom_comp_assoc, Limits.limit.cone_π,
  Limits.colimit.ι_map_assoc, Limits.colimitFlipIsoCompColim_inv_app, assoc, Limits.HasLimit.isoOfNatIso_hom_π]
[GOAL]
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasLimitsOfShape J C
inst✝³ : HasColimitsOfShape K C
inst✝² : ReflectsLimitsOfShape J (forget C)
inst✝¹ : PreservesColimitsOfShape K (forget C)
inst✝ : PreservesLimitsOfShape J (forget C)
F : J ⥤ K ⥤ C
a : K
b : J
⊢ NatTrans.app (limit.π F b) a ≫
      colimit.ι (F.obj b) a ≫
        (HasColimit.isoOfNatIso (flipCompEvaluation F b)).inv ≫
          (colimitObjIsoColimitCompEvaluation (Functor.flip F) b).inv =
    NatTrans.app (limit.π F b) a ≫ NatTrans.app (colimit.ι (Functor.flip F) a) b
[PROOFSTEP]
congr 1
[GOAL]
case e_a
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasLimitsOfShape J C
inst✝³ : HasColimitsOfShape K C
inst✝² : ReflectsLimitsOfShape J (forget C)
inst✝¹ : PreservesColimitsOfShape K (forget C)
inst✝ : PreservesLimitsOfShape J (forget C)
F : J ⥤ K ⥤ C
a : K
b : J
⊢ colimit.ι (F.obj b) a ≫
      (HasColimit.isoOfNatIso (flipCompEvaluation F b)).inv ≫
        (colimitObjIsoColimitCompEvaluation (Functor.flip F) b).inv =
    NatTrans.app (colimit.ι (Functor.flip F) a) b
[PROOFSTEP]
simp only [← Category.assoc, Iso.comp_inv_eq, Limits.colimitObjIsoColimitCompEvaluation_ι_app_hom,
  Limits.HasColimit.isoOfNatIso_ι_hom, NatIso.ofComponents_hom_app]
[GOAL]
case e_a
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasLimitsOfShape J C
inst✝³ : HasColimitsOfShape K C
inst✝² : ReflectsLimitsOfShape J (forget C)
inst✝¹ : PreservesColimitsOfShape K (forget C)
inst✝ : PreservesLimitsOfShape J (forget C)
F : J ⥤ K ⥤ C
a : K
b : J
⊢ colimit.ι (F.obj b) a = NatTrans.app (flipCompEvaluation F b).hom a ≫ colimit.ι (F.obj b) a
[PROOFSTEP]
dsimp
[GOAL]
case e_a
J K : Type v
inst✝¹⁰ : SmallCategory J
inst✝⁹ : SmallCategory K
F✝ : J × K ⥤ Type v
inst✝⁸ : IsFiltered K
inst✝⁷ : FinCategory J
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasLimitsOfShape J C
inst✝³ : HasColimitsOfShape K C
inst✝² : ReflectsLimitsOfShape J (forget C)
inst✝¹ : PreservesColimitsOfShape K (forget C)
inst✝ : PreservesLimitsOfShape J (forget C)
F : J ⥤ K ⥤ C
a : K
b : J
⊢ colimit.ι (F.obj b) a = 𝟙 ((F.obj b).obj a) ≫ colimit.ι (F.obj b) a
[PROOFSTEP]
simp
