Theorem: CategoryTheory.finitaryExtensive_iff_of_isTerminal
File: Mathlib/CategoryTheory/Extensive.lean

tactic: refine' ⟨fun H => H.2 c₀ hc₀, fun H => _⟩
state_before: J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X Y : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
⊢ FinitaryExtensive C ↔ IsVanKampenColimit c₀

tactic: constructor
state_before: J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X Y : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H : IsVanKampenColimit c₀
⊢ FinitaryExtensive C

tactic: simp_rw [BinaryCofan.isVanKampen_iff] at H⊢
state_before: case van_kampen'
J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X Y : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H : IsVanKampenColimit c₀
⊢ ∀ {X Y : C} (c : BinaryCofan X Y), IsColimit c → IsVanKampenColimit c

tactic: intro X Y c hc X' Y' c' αX αY f hX hY
state_before: case van_kampen'
J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X Y : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
⊢ ∀ {X Y : C} (c : BinaryCofan X Y),
    IsColimit c →
      ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ X) (αY : Y' ⟶ Y) (f : c'.pt ⟶ c.pt),
        αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f →
          αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f →
            (Nonempty (IsColimit c') ↔
              IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c) ∧
                IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c))

tactic: obtain ⟨d, hd, hd'⟩ :=
  Limits.BinaryCofan.IsColimit.desc' hc (HT.from _ ≫ c₀.inl) (HT.from _ ≫ c₀.inr)
state_before: case van_kampen'
J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X✝ Y✝ : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
X Y : C
c : BinaryCofan X Y
hc : IsColimit c
X' Y' : C
c' : BinaryCofan X' Y'
αX : X' ⟶ X
αY : Y' ⟶ Y
f : c'.pt ⟶ c.pt
hX : αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f
hY : αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f
⊢ Nonempty (IsColimit c') ↔
    IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c) ∧ IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c)

tactic: rw [H c' (αX ≫ HT.from _) (αY ≫ HT.from _) (f ≫ d) (by rw [← reassoc_of% hX, hd, Category.assoc])
    (by rw [← reassoc_of% hY, hd', Category.assoc])]
state_before: case van_kampen'.mk.intro
J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X✝ Y✝ : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
X Y : C
c : BinaryCofan X Y
hc : IsColimit c
X' Y' : C
c' : BinaryCofan X' Y'
αX : X' ⟶ X
αY : Y' ⟶ Y
f : c'.pt ⟶ c.pt
hX : αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f
hY : αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f
d : c.pt ⟶ ((Functor.const (Discrete WalkingPair)).obj c₀.pt).obj { as := WalkingPair.left }
hd : BinaryCofan.inl c ≫ d = IsTerminal.from HT X ≫ BinaryCofan.inl c₀
hd' : BinaryCofan.inr c ≫ d = IsTerminal.from HT Y ≫ BinaryCofan.inr c₀
⊢ Nonempty (IsColimit c') ↔
    IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c) ∧ IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c)

tactic: obtain ⟨hl, hr⟩ := (H c (HT.from _) (HT.from _) d hd.symm hd'.symm).mp ⟨hc⟩
state_before: case van_kampen'.mk.intro
J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X✝ Y✝ : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
X Y : C
c : BinaryCofan X Y
hc : IsColimit c
X' Y' : C
c' : BinaryCofan X' Y'
αX : X' ⟶ X
αY : Y' ⟶ Y
f : c'.pt ⟶ c.pt
hX : αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f
hY : αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f
d : c.pt ⟶ ((Functor.const (Discrete WalkingPair)).obj c₀.pt).obj { as := WalkingPair.left }
hd : BinaryCofan.inl c ≫ d = IsTerminal.from HT X ≫ BinaryCofan.inl c₀
hd' : BinaryCofan.inr c ≫ d = IsTerminal.from HT Y ≫ BinaryCofan.inr c₀
⊢ IsPullback (BinaryCofan.inl c') (αX ≫ IsTerminal.from HT X) (f ≫ d) (BinaryCofan.inl c₀) ∧
      IsPullback (BinaryCofan.inr c') (αY ≫ IsTerminal.from HT Y) (f ≫ d) (BinaryCofan.inr c₀) ↔
    IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c) ∧ IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c)

tactic: rw [hl.paste_vert_iff hX.symm, hr.paste_vert_iff hY.symm]
state_before: case van_kampen'.mk.intro.intro
J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X✝ Y✝ : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
X Y : C
c : BinaryCofan X Y
hc : IsColimit c
X' Y' : C
c' : BinaryCofan X' Y'
αX : X' ⟶ X
αY : Y' ⟶ Y
f : c'.pt ⟶ c.pt
hX : αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f
hY : αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f
d : c.pt ⟶ ((Functor.const (Discrete WalkingPair)).obj c₀.pt).obj { as := WalkingPair.left }
hd : BinaryCofan.inl c ≫ d = IsTerminal.from HT X ≫ BinaryCofan.inl c₀
hd' : BinaryCofan.inr c ≫ d = IsTerminal.from HT Y ≫ BinaryCofan.inr c₀
hl : IsPullback (BinaryCofan.inl c) (IsTerminal.from HT X) d (BinaryCofan.inl c₀)
hr : IsPullback (BinaryCofan.inr c) (IsTerminal.from HT Y) d (BinaryCofan.inr c₀)
⊢ IsPullback (BinaryCofan.inl c') (αX ≫ IsTerminal.from HT X) (f ≫ d) (BinaryCofan.inl c₀) ∧
      IsPullback (BinaryCofan.inr c') (αY ≫ IsTerminal.from HT Y) (f ≫ d) (BinaryCofan.inr c₀) ↔
    IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c) ∧ IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c)

tactic: rw [← reassoc_of% hX, hd, Category.assoc]
state_before: J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X✝ Y✝ : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
X Y : C
c : BinaryCofan X Y
hc : IsColimit c
X' Y' : C
c' : BinaryCofan X' Y'
αX : X' ⟶ X
αY : Y' ⟶ Y
f : c'.pt ⟶ c.pt
hX : αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f
hY : αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f
d : c.pt ⟶ ((Functor.const (Discrete WalkingPair)).obj c₀.pt).obj { as := WalkingPair.left }
hd : BinaryCofan.inl c ≫ d = IsTerminal.from HT X ≫ BinaryCofan.inl c₀
hd' : BinaryCofan.inr c ≫ d = IsTerminal.from HT Y ≫ BinaryCofan.inr c₀
⊢ (αX ≫ IsTerminal.from HT X) ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f ≫ d

tactic: rw [← reassoc_of% hY, hd', Category.assoc]
state_before: J : Type v'
inst✝³ : Category J
C✝ : Type u
inst✝² : Category C✝
X✝ Y✝ : C✝
C : Type u
inst✝¹ : Category C
inst✝ : HasFiniteCoproducts C
T : C
HT : IsTerminal T
c₀ : BinaryCofan T T
hc₀ : IsColimit c₀
H :
  ∀ {X' Y' : C} (c' : BinaryCofan X' Y') (αX : X' ⟶ T) (αY : Y' ⟶ T) (f : c'.pt ⟶ c₀.pt),
    αX ≫ BinaryCofan.inl c₀ = BinaryCofan.inl c' ≫ f →
      αY ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f →
        (Nonempty (IsColimit c') ↔
          IsPullback (BinaryCofan.inl c') αX f (BinaryCofan.inl c₀) ∧
            IsPullback (BinaryCofan.inr c') αY f (BinaryCofan.inr c₀))
X Y : C
c : BinaryCofan X Y
hc : IsColimit c
X' Y' : C
c' : BinaryCofan X' Y'
αX : X' ⟶ X
αY : Y' ⟶ Y
f : c'.pt ⟶ c.pt
hX : αX ≫ BinaryCofan.inl c = BinaryCofan.inl c' ≫ f
hY : αY ≫ BinaryCofan.inr c = BinaryCofan.inr c' ≫ f
d : c.pt ⟶ ((Functor.const (Discrete WalkingPair)).obj c₀.pt).obj { as := WalkingPair.left }
hd : BinaryCofan.inl c ≫ d = IsTerminal.from HT X ≫ BinaryCofan.inl c₀
hd' : BinaryCofan.inr c ≫ d = IsTerminal.from HT Y ≫ BinaryCofan.inr c₀
⊢ (αY ≫ IsTerminal.from HT Y) ≫ BinaryCofan.inr c₀ = BinaryCofan.inr c' ≫ f ≫ d