l3lab/ntp-mathlib huggingface dataset:
@[simp] lemma coeff_charpolyRev_eq_neg_trace (M : Matrix n n R) :
    coeff M.charpolyRev 1 = - trace M := by
  nontriviality R
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
M : Matrix n n R
✝ : Nontrivial R
⊢ coeff (charpolyRev M) 1 = -trace M

Next tactic:
cases isEmpty_or_nonempty n
@[simp] lemma coeff_charpolyRev_eq_neg_trace (M : Matrix n n R) :
    coeff M.charpolyRev 1 = - trace M := by
  nontriviality R
  cases isEmpty_or_nonempty n
  · 

Proof state:
case inl
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
M : Matrix n n R
✝ : Nontrivial R
h✝ : IsEmpty n
⊢ coeff (charpolyRev M) 1 = -trace M

Next tactic:
simp [charpolyRev, coeff_one]
@[simp] lemma coeff_charpolyRev_eq_neg_trace (M : Matrix n n R) :
    coeff M.charpolyRev 1 = - trace M := by
  nontriviality R
  cases isEmpty_or_nonempty n
  · simp [charpolyRev, coeff_one]
  · 

Proof state:
case inr
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
M : Matrix n n R
✝ : Nontrivial R
h✝ : Nonempty n
⊢ coeff (charpolyRev M) 1 = -trace M

Next tactic:
simp [trace_eq_neg_charpoly_coeff M, ← M.reverse_charpoly, nextCoeff]
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
⊢ IsUnit (charpolyRev M)

Next tactic:
obtain ⟨k, hk⟩ := hM
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  obtain ⟨k, hk⟩ := hM
  

Proof state:
case intro
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
k : ℕ
hk : M ^ k = 0
⊢ IsUnit (charpolyRev M)

Next tactic:
replace hk : 1 - (X : R[X]) • M.map C ∣ 1 := by
    convert one_sub_dvd_one_sub_pow ((X : R[X]) • M.map C) k
    rw [← C.mapMatrix_apply, smul_pow, ← map_pow, hk, map_zero, smul_zero, sub_zero]
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  obtain ⟨k, hk⟩ := hM
  replace hk : 1 - (X : R[X]) • M.map C ∣ 1 := by
    

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
k : ℕ
hk : M ^ k = 0
⊢ 1 - X • map M ⇑C ∣ 1

Next tactic:
convert one_sub_dvd_one_sub_pow ((X : R[X]) • M.map C) k
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  obtain ⟨k, hk⟩ := hM
  replace hk : 1 - (X : R[X]) • M.map C ∣ 1 := by
    convert one_sub_dvd_one_sub_pow ((X : R[X]) • M.map C) k
    

Proof state:
case h.e'_4
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
k : ℕ
hk : M ^ k = 0
⊢ 1 = 1 - (X • map M ⇑C) ^ k

Next tactic:
rw [← C.mapMatrix_apply, smul_pow, ← map_pow, hk, map_zero, smul_zero, sub_zero]
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  obtain ⟨k, hk⟩ := hM
  replace hk : 1 - (X : R[X]) • M.map C ∣ 1 := by
    convert one_sub_dvd_one_sub_pow ((X : R[X]) • M.map C) k
    rw [← C.mapMatrix_apply, smul_pow, ← map_pow, hk, map_zero, smul_zero, sub_zero]
  

Proof state:
case intro
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
k : ℕ
hk : 1 - X • map M ⇑C ∣ 1
⊢ IsUnit (charpolyRev M)

Next tactic:
apply isUnit_of_dvd_one
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  obtain ⟨k, hk⟩ := hM
  replace hk : 1 - (X : R[X]) • M.map C ∣ 1 := by
    convert one_sub_dvd_one_sub_pow ((X : R[X]) • M.map C) k
    rw [← C.mapMatrix_apply, smul_pow, ← map_pow, hk, map_zero, smul_zero, sub_zero]
  apply isUnit_of_dvd_one
  

Proof state:
case intro.h
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
k : ℕ
hk : 1 - X • map M ⇑C ∣ 1
⊢ charpolyRev M ∣ 1

Next tactic:
rw [← det_one (R := R[X]) (n := n)]
lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev := by
  obtain ⟨k, hk⟩ := hM
  replace hk : 1 - (X : R[X]) • M.map C ∣ 1 := by
    convert one_sub_dvd_one_sub_pow ((X : R[X]) • M.map C) k
    rw [← C.mapMatrix_apply, smul_pow, ← map_pow, hk, map_zero, smul_zero, sub_zero]
  apply isUnit_of_dvd_one
  rw [← det_one (R := R[X]) (n := n)]
  

Proof state:
case intro.h
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
k : ℕ
hk : 1 - X • map M ⇑C ∣ 1
⊢ charpolyRev M ∣ det 1

Next tactic:
exact map_dvd detMonoidHom hk
lemma isNilpotent_trace_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (trace M) := by
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
⊢ IsNilpotent (trace M)

Next tactic:
cases isEmpty_or_nonempty n
lemma isNilpotent_trace_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (trace M) := by
  cases isEmpty_or_nonempty n
  · 

Proof state:
case inl
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
h✝ : IsEmpty n
⊢ IsNilpotent (trace M)

Next tactic:
simp
lemma isNilpotent_trace_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (trace M) := by
  cases isEmpty_or_nonempty n
  · simp
  

Proof state:
case inr
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
h✝ : Nonempty n
⊢ IsNilpotent (trace M)

Next tactic:
suffices IsNilpotent (coeff (charpolyRev M) 1) by simpa using this
lemma isNilpotent_trace_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (trace M) := by
  cases isEmpty_or_nonempty n
  · simp
  suffices IsNilpotent (coeff (charpolyRev M) 1) by 

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
h✝ : Nonempty n
this : IsNilpotent (coeff (charpolyRev M) 1)
⊢ IsNilpotent (trace M)

Next tactic:
simpa using this
lemma isNilpotent_trace_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (trace M) := by
  cases isEmpty_or_nonempty n
  · simp
  suffices IsNilpotent (coeff (charpolyRev M) 1) by simpa using this
  

Proof state:
case inr
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
h✝ : Nonempty n
⊢ IsNilpotent (coeff (charpolyRev M) 1)

Next tactic:
exact (isUnit_iff_coeff_isUnit_isNilpotent.mp (isUnit_charpolyRev_of_isNilpotent hM)).2
    _ one_ne_zero
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
⊢ IsNilpotent (charpoly M - X ^ Fintype.card n)

Next tactic:
nontriviality R
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hM : IsNilpotent M
✝ : Nontrivial R
⊢ IsNilpotent (charpoly M - X ^ Fintype.card n)

Next tactic:
let p : R[X] := M.charpolyRev
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
⊢ IsNilpotent (charpoly M - X ^ Fintype.card n)

Next tactic:
have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    simp [modByMonic_X]
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
⊢ p - 1 = X * (p /ₘ X)

Next tactic:
conv_lhs => rw [← modByMonic_add_div p monic_X]
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => 

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
| p - 1

Next tactic:
rw [← modByMonic_add_div p monic_X]
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
⊢ p %ₘ X + X * (p /ₘ X) - 1 = X * (p /ₘ X)

Next tactic:
simp [modByMonic_X]
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    simp [modByMonic_X]
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
hp : p - 1 = X * (p /ₘ X)
⊢ IsNilpotent (charpoly M - X ^ Fintype.card n)

Next tactic:
have : IsNilpotent (p /ₘ X) :=
    (Polynomial.isUnit_iff'.mp (isUnit_charpolyRev_of_isNilpotent hM)).2
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    simp [modByMonic_X]
  have : IsNilpotent (p /ₘ X) :=
    (Polynomial.isUnit_iff'.mp (isUnit_charpolyRev_of_isNilpotent hM)).2
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
hp : p - 1 = X * (p /ₘ X)
this : IsNilpotent (p /ₘ X)
⊢ IsNilpotent (charpoly M - X ^ Fintype.card n)

Next tactic:
have aux : (M.charpoly - X ^ (Fintype.card n)).natDegree ≤ M.charpoly.natDegree :=
    le_trans (natDegree_sub_le _ _) (by simp)
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    simp [modByMonic_X]
  have : IsNilpotent (p /ₘ X) :=
    (Polynomial.isUnit_iff'.mp (isUnit_charpolyRev_of_isNilpotent hM)).2
  have aux : (M.charpoly - X ^ (Fintype.card n)).natDegree ≤ M.charpoly.natDegree :=
    le_trans (natDegree_sub_le _ _) (by 

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
hp : p - 1 = X * (p /ₘ X)
this : IsNilpotent (p /ₘ X)
⊢ max (natDegree (charpoly M)) (natDegree (X ^ Fintype.card n)) ≤ natDegree (charpoly M)

Next tactic:
simp
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    simp [modByMonic_X]
  have : IsNilpotent (p /ₘ X) :=
    (Polynomial.isUnit_iff'.mp (isUnit_charpolyRev_of_isNilpotent hM)).2
  have aux : (M.charpoly - X ^ (Fintype.card n)).natDegree ≤ M.charpoly.natDegree :=
    le_trans (natDegree_sub_le _ _) (by simp)
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
hp : p - 1 = X * (p /ₘ X)
this : IsNilpotent (p /ₘ X)
aux : natDegree (charpoly M - X ^ Fintype.card n) ≤ natDegree (charpoly M)
⊢ IsNilpotent (charpoly M - X ^ Fintype.card n)

Next tactic:
rw [← isNilpotent_reflect_iff aux, reflect_sub, ← reverse, M.reverse_charpoly]
lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) := by
  nontriviality R
  let p : R[X] := M.charpolyRev
  have hp : p - 1 = X * (p /ₘ X) := by
    conv_lhs => rw [← modByMonic_add_div p monic_X]
    simp [modByMonic_X]
  have : IsNilpotent (p /ₘ X) :=
    (Polynomial.isUnit_iff'.mp (isUnit_charpolyRev_of_isNilpotent hM)).2
  have aux : (M.charpoly - X ^ (Fintype.card n)).natDegree ≤ M.charpoly.natDegree :=
    le_trans (natDegree_sub_le _ _) (by simp)
  rw [← isNilpotent_reflect_iff aux, reflect_sub, ← reverse, M.reverse_charpoly]
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M : Matrix n n R
p✝ : ℕ
inst✝ : Fact (Nat.Prime p✝)
hM : IsNilpotent M
✝ : Nontrivial R
p : R[X] := charpolyRev M
hp : p - 1 = X * (p /ₘ X)
this : IsNilpotent (p /ₘ X)
aux : natDegree (charpoly M - X ^ Fintype.card n) ≤ natDegree (charpoly M)
⊢ IsNilpotent (charpolyRev M - reflect (natDegree (charpoly M)) (X ^ Fintype.card n))

Next tactic:
simpa [hp]
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  

Proof state:
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X Y : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
⊢ IsVanKampenColimit c

Next tactic:
let X := F.obj ⟨WalkingPair.left⟩
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  

Proof state:
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
⊢ IsVanKampenColimit c

Next tactic:
let Y := F.obj ⟨WalkingPair.right⟩
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  

Proof state:
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ IsVanKampenColimit c

Next tactic:
have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> rfl
    · rintro ⟨⟨⟩⟩ ⟨j⟩ ⟨⟨rfl : _ = j⟩⟩ <;> simp
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    

Proof state:
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ F = pair X Y

Next tactic:
apply Functor.hext
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · 

Proof state:
case h_obj
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ ∀ (X_1 : Discrete WalkingPair), F.obj X_1 = (pair X Y).obj X_1

Next tactic:
rintro ⟨⟨⟩⟩
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> 

Proof state:
case h_obj.mk.left
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ F.obj { as := WalkingPair.left } = (pair X Y).obj { as := WalkingPair.left }

Next tactic:
rfl
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> 

Proof state:
case h_obj.mk.right
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ F.obj { as := WalkingPair.right } = (pair X Y).obj { as := WalkingPair.right }

Next tactic:
rfl
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> rfl
    · 

Proof state:
case h_map
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ ∀ (X_1 Y_1 : Discrete WalkingPair) (f : X_1 ⟶ Y_1), HEq (F.map f) ((pair X Y).map f)

Next tactic:
rintro ⟨⟨⟩⟩ ⟨j⟩ ⟨⟨rfl : _ = j⟩⟩
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> rfl
    · rintro ⟨⟨⟩⟩ ⟨j⟩ ⟨⟨rfl : _ = j⟩⟩ <;> 

Proof state:
case h_map.mk.left.mk.up.up
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ HEq (F.map { down := { down := (_ : { as := WalkingPair.left }.as = { as := WalkingPair.left }.as) } })
    ((pair X Y).map { down := { down := (_ : { as := WalkingPair.left }.as = { as := WalkingPair.left }.as) } })

Next tactic:
simp
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> rfl
    · rintro ⟨⟨⟩⟩ ⟨j⟩ ⟨⟨rfl : _ = j⟩⟩ <;> 

Proof state:
case h_map.mk.right.mk.up.up
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
⊢ HEq (F.map { down := { down := (_ : { as := WalkingPair.right }.as = { as := WalkingPair.right }.as) } })
    ((pair X Y).map { down := { down := (_ : { as := WalkingPair.right }.as = { as := WalkingPair.right }.as) } })

Next tactic:
simp
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> rfl
    · rintro ⟨⟨⟩⟩ ⟨j⟩ ⟨⟨rfl : _ = j⟩⟩ <;> simp
  

Proof state:
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
X : C := F.obj { as := WalkingPair.left }
Y : C := F.obj { as := WalkingPair.right }
this : F = pair X Y
⊢ IsVanKampenColimit c

Next tactic:
clear_value X Y
theorem FinitaryExtensive.vanKampen [FinitaryExtensive C] {F : Discrete WalkingPair ⥤ C}
    (c : Cocone F) (hc : IsColimit c) : IsVanKampenColimit c := by
  let X := F.obj ⟨WalkingPair.left⟩
  let Y := F.obj ⟨WalkingPair.right⟩
  have : F = pair X Y := by
    apply Functor.hext
    · rintro ⟨⟨⟩⟩ <;> rfl
    · rintro ⟨⟨⟩⟩ ⟨j⟩ ⟨⟨rfl : _ = j⟩⟩ <;> simp
  clear_value X Y
  

Proof state:
J : Type v'
inst✝³ : Category.{u', v'} J
C : Type u
inst✝² : Category.{v, u} C
D : Type u''
inst✝¹ : Category.{v'', u''} D
X✝ Y✝ : C
inst✝ : FinitaryExtensive C
F : Discrete WalkingPair ⥤ C
c : Cocone F
hc : IsColimit c
Y X : C
this : F = pair X Y
⊢ IsVanKampenColimit c

Next tactic:
subst this