l3lab/ntp-mathlib huggingface dataset:
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · exact of_fixedField_eq_bot F E
  tfae_have 3 → 1
  · 

Proof state:
case tfae_3_to_1
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
tfae_2_to_1 : IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E
⊢ Fintype.card (E ≃ₐ[F] E) = finrank F E → IsGalois F E

Next tactic:
exact of_card_aut_eq_finrank F E
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · exact of_fixedField_eq_bot F E
  tfae_have 3 → 1
  · exact of_card_aut_eq_finrank F E
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
tfae_2_to_1 : IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E
tfae_3_to_1 : Fintype.card (E ≃ₐ[F] E) = finrank F E → IsGalois F E
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_have 4 → 1
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · exact of_fixedField_eq_bot F E
  tfae_have 3 → 1
  · exact of_card_aut_eq_finrank F E
  tfae_have 4 → 1
  · 

Proof state:
case tfae_4_to_1
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
tfae_2_to_1 : IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E
tfae_3_to_1 : Fintype.card (E ≃ₐ[F] E) = finrank F E → IsGalois F E
⊢ (∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p) → IsGalois F E

Next tactic:
rintro ⟨h, hp1, _⟩
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · exact of_fixedField_eq_bot F E
  tfae_have 3 → 1
  · exact of_card_aut_eq_finrank F E
  tfae_have 4 → 1
  · rintro ⟨h, hp1, _⟩; 

Proof state:
case tfae_4_to_1.intro.intro
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
tfae_2_to_1 : IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E
tfae_3_to_1 : Fintype.card (E ≃ₐ[F] E) = finrank F E → IsGalois F E
h : F[X]
hp1 : Polynomial.Separable h
right✝ : Polynomial.IsSplittingField F E h
⊢ IsGalois F E

Next tactic:
exact of_separable_splitting_field hp1
/-- Equivalent characterizations of a Galois extension of finite degree-/
theorem tfae [FiniteDimensional F E] :
    List.TFAE [IsGalois F E, IntermediateField.fixedField (⊤ : Subgroup (E ≃ₐ[F] E)) = ⊥,
      Fintype.card (E ≃ₐ[F] E) = finrank F E, ∃ p: F[X], p.Separable ∧ p.IsSplittingField F E] := by
  tfae_have 1 → 2
  · exact fun h => OrderIso.map_bot (@intermediateFieldEquivSubgroup F _ E _ _ _ h).symm
  tfae_have 1 → 3
  · intro; exact card_aut_eq_finrank F E
  tfae_have 1 → 4
  · intro; exact is_separable_splitting_field F E
  tfae_have 2 → 1
  · exact of_fixedField_eq_bot F E
  tfae_have 3 → 1
  · exact of_card_aut_eq_finrank F E
  tfae_have 4 → 1
  · rintro ⟨h, hp1, _⟩; exact of_separable_splitting_field hp1
  

Proof state:
F : Type u_1
inst✝³ : Field F
E : Type u_2
inst✝² : Field E
inst✝¹ : Algebra F E
p : F[X]
inst✝ : FiniteDimensional F E
tfae_1_to_2 : IsGalois F E → IntermediateField.fixedField ⊤ = ⊥
tfae_1_to_3 : IsGalois F E → Fintype.card (E ≃ₐ[F] E) = finrank F E
tfae_1_to_4 : IsGalois F E → ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p
tfae_2_to_1 : IntermediateField.fixedField ⊤ = ⊥ → IsGalois F E
tfae_3_to_1 : Fintype.card (E ≃ₐ[F] E) = finrank F E → IsGalois F E
tfae_4_to_1 : (∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p) → IsGalois F E
⊢ List.TFAE
    [IsGalois F E, IntermediateField.fixedField ⊤ = ⊥, Fintype.card (E ≃ₐ[F] E) = finrank F E,
      ∃ p, Polynomial.Separable p ∧ Polynomial.IsSplittingField F E p]

Next tactic:
tfae_finish
@[simp]
theorem mem_toFinset {a : α} {o : Option α} : a ∈ o.toFinset ↔ a ∈ o := by
  

Proof state:
α : Type u_1
β : Type u_2
a : α
o : Option α
⊢ a ∈ toFinset o ↔ a ∈ o

Next tactic:
cases o
@[simp]
theorem mem_toFinset {a : α} {o : Option α} : a ∈ o.toFinset ↔ a ∈ o := by
  cases o <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
a : α
⊢ a ∈ toFinset none ↔ a ∈ none

Next tactic:
simp [eq_comm]
@[simp]
theorem mem_toFinset {a : α} {o : Option α} : a ∈ o.toFinset ↔ a ∈ o := by
  cases o <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
a val✝ : α
⊢ a ∈ toFinset (some val✝) ↔ a ∈ some val✝

Next tactic:
simp [eq_comm]
theorem card_toFinset (o : Option α) : o.toFinset.card = o.elim 0 1 := by 

Proof state:
α : Type u_1
β : Type u_2
o : Option α
⊢ Finset.card (toFinset o) = Option.elim o 0 1

Next tactic:
cases o
theorem card_toFinset (o : Option α) : o.toFinset.card = o.elim 0 1 := by cases o <;> 

Proof state:
case none
α : Type u_1
β : Type u_2
⊢ Finset.card (toFinset none) = Option.elim none 0 1

Next tactic:
rfl
theorem card_toFinset (o : Option α) : o.toFinset.card = o.elim 0 1 := by cases o <;> 

Proof state:
case some
α : Type u_1
β : Type u_2
val✝ : α
⊢ Finset.card (toFinset (some val✝)) = Option.elim (some val✝) 0 1

Next tactic:
rfl
/-- Given a finset on `α`, lift it to being a finset on `Option α`
using `Option.some` and then insert `Option.none`. -/
def insertNone : Finset α ↪o Finset (Option α) :=
  (OrderEmbedding.ofMapLEIff fun s => cons none (s.map Embedding.some) <| by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
⊢ none ∉ map Embedding.some s

Next tactic:
simp
/-- Given a finset on `α`, lift it to being a finset on `Option α`
using `Option.some` and then insert `Option.none`. -/
def insertNone : Finset α ↪o Finset (Option α) :=
  (OrderEmbedding.ofMapLEIff fun s => cons none (s.map Embedding.some) <| by simp) fun s t => by
    

Proof state:
α : Type u_1
β : Type u_2
s t : Finset α
⊢ cons none (map Embedding.some s) (_ : none ∉ map Embedding.some s) ≤
      cons none (map Embedding.some t) (_ : none ∉ map Embedding.some t) ↔
    s ≤ t

Next tactic:
rw [le_iff_subset, cons_subset_cons, map_subset_map, le_iff_subset]
@[simp]
theorem mem_insertNone {s : Finset α} : ∀ {o : Option α}, o ∈ insertNone s ↔ ∀ a ∈ o, a ∈ s
  | none => iff_of_true (Multiset.mem_cons_self _ _) fun a h => by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
a : α
h : a ∈ none
⊢ a ∈ s

Next tactic:
cases h
@[simp]
theorem mem_insertNone {s : Finset α} : ∀ {o : Option α}, o ∈ insertNone s ↔ ∀ a ∈ o, a ∈ s
  | none => iff_of_true (Multiset.mem_cons_self _ _) fun a h => by cases h
  | some a => Multiset.mem_cons.trans <| by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
a : α
⊢ some a = none ∨ some a ∈ (map Embedding.some s).val ↔ ∀ a_1 ∈ some a, a_1 ∈ s

Next tactic:
simp
lemma forall_mem_insertNone {s : Finset α} {p : Option α → Prop} :
    (∀ a ∈ insertNone s, p a) ↔ p none ∧ ∀ a ∈ s, p a := by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
p : Option α → Prop
⊢ (∀ a ∈ insertNone s, p a) ↔ p none ∧ ∀ a ∈ s, p (some a)

Next tactic:
simp [Option.forall]
theorem some_mem_insertNone {s : Finset α} {a : α} : some a ∈ insertNone s ↔ a ∈ s := by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
a : α
⊢ some a ∈ insertNone s ↔ a ∈ s

Next tactic:
simp
lemma none_mem_insertNone {s : Finset α} : none ∈ insertNone s := by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
⊢ none ∈ insertNone s

Next tactic:
simp
@[simp]
theorem card_insertNone (s : Finset α) : s.insertNone.card = s.card + 1 := by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
⊢ card (insertNone s) = card s + 1

Next tactic:
simp [insertNone]
@[simp]
theorem mem_eraseNone {s : Finset (Option α)} {x : α} : x ∈ eraseNone s ↔ some x ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Finset (Option α)
x : α
⊢ x ∈ eraseNone s ↔ some x ∈ s

Next tactic:
simp [eraseNone]
lemma forall_mem_eraseNone {s : Finset (Option α)} {p : Option α → Prop} :
    (∀ a ∈ eraseNone s, p a) ↔ ∀ a : α, (a : Option α) ∈ s → p a := by 

Proof state:
α : Type u_1
β : Type u_2
s : Finset (Option α)
p : Option α → Prop
⊢ (∀ a ∈ eraseNone s, p (some a)) ↔ ∀ (a : α), some a ∈ s → p (some a)

Next tactic:
simp [Option.forall]
theorem eraseNone_eq_biUnion [DecidableEq α] (s : Finset (Option α)) :
    eraseNone s = s.biUnion Option.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Finset (Option α)
⊢ eraseNone s = Finset.biUnion s Option.toFinset

Next tactic:
ext
theorem eraseNone_eq_biUnion [DecidableEq α] (s : Finset (Option α)) :
    eraseNone s = s.biUnion Option.toFinset := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Finset (Option α)
a✝ : α
⊢ a✝ ∈ eraseNone s ↔ a✝ ∈ Finset.biUnion s Option.toFinset

Next tactic:
simp
@[simp]
theorem eraseNone_map_some (s : Finset α) : eraseNone (s.map Embedding.some) = s := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
⊢ eraseNone (map Embedding.some s) = s

Next tactic:
ext
@[simp]
theorem eraseNone_map_some (s : Finset α) : eraseNone (s.map Embedding.some) = s := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
s : Finset α
a✝ : α
⊢ a✝ ∈ eraseNone (map Embedding.some s) ↔ a✝ ∈ s

Next tactic:
simp
@[simp]
theorem eraseNone_image_some [DecidableEq (Option α)] (s : Finset α) :
    eraseNone (s.image some) = s := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset α
⊢ eraseNone (image some s) = s

Next tactic:
simpa only [map_eq_image] using eraseNone_map_some s
@[simp]
theorem eraseNone_union [DecidableEq (Option α)] [DecidableEq α] (s t : Finset (Option α)) :
    eraseNone (s ∪ t) = eraseNone s ∪ eraseNone t := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq (Option α)
inst✝ : DecidableEq α
s t : Finset (Option α)
⊢ eraseNone (s ∪ t) = eraseNone s ∪ eraseNone t

Next tactic:
ext
@[simp]
theorem eraseNone_union [DecidableEq (Option α)] [DecidableEq α] (s t : Finset (Option α)) :
    eraseNone (s ∪ t) = eraseNone s ∪ eraseNone t := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq (Option α)
inst✝ : DecidableEq α
s t : Finset (Option α)
a✝ : α
⊢ a✝ ∈ eraseNone (s ∪ t) ↔ a✝ ∈ eraseNone s ∪ eraseNone t

Next tactic:
simp
@[simp]
theorem eraseNone_inter [DecidableEq (Option α)] [DecidableEq α] (s t : Finset (Option α)) :
    eraseNone (s ∩ t) = eraseNone s ∩ eraseNone t := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq (Option α)
inst✝ : DecidableEq α
s t : Finset (Option α)
⊢ eraseNone (s ∩ t) = eraseNone s ∩ eraseNone t

Next tactic:
ext
@[simp]
theorem eraseNone_inter [DecidableEq (Option α)] [DecidableEq α] (s t : Finset (Option α)) :
    eraseNone (s ∩ t) = eraseNone s ∩ eraseNone t := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq (Option α)
inst✝ : DecidableEq α
s t : Finset (Option α)
a✝ : α
⊢ a✝ ∈ eraseNone (s ∩ t) ↔ a✝ ∈ eraseNone s ∩ eraseNone t

Next tactic:
simp
@[simp]
theorem eraseNone_empty : eraseNone (∅ : Finset (Option α)) = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
⊢ eraseNone ∅ = ∅

Next tactic:
ext
@[simp]
theorem eraseNone_empty : eraseNone (∅ : Finset (Option α)) = ∅ := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
a✝ : α
⊢ a✝ ∈ eraseNone ∅ ↔ a✝ ∈ ∅

Next tactic:
simp
@[simp]
theorem eraseNone_none : eraseNone ({none} : Finset (Option α)) = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
⊢ eraseNone {none} = ∅

Next tactic:
ext
@[simp]
theorem eraseNone_none : eraseNone ({none} : Finset (Option α)) = ∅ := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
a✝ : α
⊢ a✝ ∈ eraseNone {none} ↔ a✝ ∈ ∅

Next tactic:
simp
@[simp]
theorem image_some_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    (eraseNone s).image some = s.erase none := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
⊢ image some (eraseNone s) = erase s none

Next tactic:
ext (_ | x)
@[simp]
theorem image_some_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    (eraseNone s).image some = s.erase none := by ext (_ | x) <;> 

Proof state:
case a.none
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
⊢ none ∈ image some (eraseNone s) ↔ none ∈ erase s none

Next tactic:
simp
@[simp]
theorem image_some_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    (eraseNone s).image some = s.erase none := by ext (_ | x) <;> 

Proof state:
case a.some
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
x : α
⊢ some x ∈ image some (eraseNone s) ↔ some x ∈ erase s none

Next tactic:
simp
@[simp]
theorem map_some_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    (eraseNone s).map Embedding.some = s.erase none := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
⊢ map Embedding.some (eraseNone s) = erase s none

Next tactic:
rw [map_eq_image, Embedding.some_apply, image_some_eraseNone]
@[simp]
theorem insertNone_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    insertNone (eraseNone s) = insert none s := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
⊢ insertNone (eraseNone s) = insert none s

Next tactic:
ext (_ | x)
@[simp]
theorem insertNone_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    insertNone (eraseNone s) = insert none s := by ext (_ | x) <;> 

Proof state:
case a.none
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
⊢ none ∈ insertNone (eraseNone s) ↔ none ∈ insert none s

Next tactic:
simp
@[simp]
theorem insertNone_eraseNone [DecidableEq (Option α)] (s : Finset (Option α)) :
    insertNone (eraseNone s) = insert none s := by ext (_ | x) <;> 

Proof state:
case a.some
α : Type u_1
β : Type u_2
inst✝ : DecidableEq (Option α)
s : Finset (Option α)
x : α
⊢ some x ∈ insertNone (eraseNone s) ↔ some x ∈ insert none s

Next tactic:
simp
@[simp]
theorem eraseNone_insertNone (s : Finset α) : eraseNone (insertNone s) = s := by
  

Proof state:
α : Type u_1
β : Type u_2
s : Finset α
⊢ eraseNone (insertNone s) = s

Next tactic:
ext
@[simp]
theorem eraseNone_insertNone (s : Finset α) : eraseNone (insertNone s) = s := by
  ext
  

Proof state:
case a
α : Type u_1
β : Type u_2
s : Finset α
a✝ : α
⊢ a✝ ∈ eraseNone (insertNone s) ↔ a✝ ∈ s

Next tactic:
simp
/-- Given a diagram `D` of limit cones over the `F.obj j`, and a cone over `uncurry.obj F`,
we can construct a cone over the diagram consisting of the cone points from `D`.
-/
@[simps]
def coneOfConeUncurry {D : DiagramOfCones F} (Q : ∀ j, IsLimit (D.obj j))
    (c : Cone (uncurry.obj F)) : Cone D.conePoints where
  pt := c.pt
  π :=
    { app := fun j =>
        (Q j).lift
          { pt := c.pt
            π :=
              { app := fun k => c.π.app (j, k)
                naturality := fun k k' f => by
                  

Proof state:
J K : Type v
inst✝² : SmallCategory J
inst✝¹ : SmallCategory K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ K ⥤ C
D : DiagramOfCones F
Q : (j : J) → IsLimit (DiagramOfCones.obj D j)
c : Cone (uncurry.obj F)
j : J
k k' : K
f : k ⟶ k'
⊢ ((Functor.const K).obj c.pt).map f ≫ (fun k => c.π.app (j, k)) k' = (fun k => c.π.app (j, k)) k ≫ (F.obj j).map f

Next tactic:
dsimp
/-- Given a diagram `D` of limit cones over the `F.obj j`, and a cone over `uncurry.obj F`,
we can construct a cone over the diagram consisting of the cone points from `D`.
-/
@[simps]
def coneOfConeUncurry {D : DiagramOfCones F} (Q : ∀ j, IsLimit (D.obj j))
    (c : Cone (uncurry.obj F)) : Cone D.conePoints where
  pt := c.pt
  π :=
    { app := fun j =>
        (Q j).lift
          { pt := c.pt
            π :=
              { app := fun k => c.π.app (j, k)
                naturality := fun k k' f => by
                  dsimp; 

Proof state:
J K : Type v
inst✝² : SmallCategory J
inst✝¹ : SmallCategory K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ K ⥤ C
D : DiagramOfCones F
Q : (j : J) → IsLimit (DiagramOfCones.obj D j)
c : Cone (uncurry.obj F)
j : J
k k' : K
f : k ⟶ k'
⊢ 𝟙 c.pt ≫ c.π.app (j, k') = c.π.app (j, k) ≫ (F.obj j).map f

Next tactic:
simp only [Category.id_comp]
/-- Given a diagram `D` of limit cones over the `F.obj j`, and a cone over `uncurry.obj F`,
we can construct a cone over the diagram consisting of the cone points from `D`.
-/
@[simps]
def coneOfConeUncurry {D : DiagramOfCones F} (Q : ∀ j, IsLimit (D.obj j))
    (c : Cone (uncurry.obj F)) : Cone D.conePoints where
  pt := c.pt
  π :=
    { app := fun j =>
        (Q j).lift
          { pt := c.pt
            π :=
              { app := fun k => c.π.app (j, k)
                naturality := fun k k' f => by
                  dsimp; simp only [Category.id_comp]
                  

Proof state:
J K : Type v
inst✝² : SmallCategory J
inst✝¹ : SmallCategory K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ K ⥤ C
D : DiagramOfCones F
Q : (j : J) → IsLimit (DiagramOfCones.obj D j)
c : Cone (uncurry.obj F)
j : J
k k' : K
f : k ⟶ k'
⊢ c.π.app (j, k') = c.π.app (j, k) ≫ (F.obj j).map f

Next tactic:
have := @NatTrans.naturality _ _ _ _ _ _ c.π (j, k) (j, k') (𝟙 j, f)
/-- Given a diagram `D` of limit cones over the `F.obj j`, and a cone over `uncurry.obj F`,
we can construct a cone over the diagram consisting of the cone points from `D`.
-/
@[simps]
def coneOfConeUncurry {D : DiagramOfCones F} (Q : ∀ j, IsLimit (D.obj j))
    (c : Cone (uncurry.obj F)) : Cone D.conePoints where
  pt := c.pt
  π :=
    { app := fun j =>
        (Q j).lift
          { pt := c.pt
            π :=
              { app := fun k => c.π.app (j, k)
                naturality := fun k k' f => by
                  dsimp; simp only [Category.id_comp]
                  have := @NatTrans.naturality _ _ _ _ _ _ c.π (j, k) (j, k') (𝟙 j, f)
                  

Proof state:
J K : Type v
inst✝² : SmallCategory J
inst✝¹ : SmallCategory K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ K ⥤ C
D : DiagramOfCones F
Q : (j : J) → IsLimit (DiagramOfCones.obj D j)
c : Cone (uncurry.obj F)
j : J
k k' : K
f : k ⟶ k'
this : ((Functor.const (J × K)).obj c.pt).map (𝟙 j, f) ≫ c.π.app (j, k') = c.π.app (j, k) ≫ (uncurry.obj F).map (𝟙 j, f)
⊢ c.π.app (j, k') = c.π.app (j, k) ≫ (F.obj j).map f

Next tactic:
dsimp at this
/-- Given a diagram `D` of limit cones over the `F.obj j`, and a cone over `uncurry.obj F`,
we can construct a cone over the diagram consisting of the cone points from `D`.
-/
@[simps]
def coneOfConeUncurry {D : DiagramOfCones F} (Q : ∀ j, IsLimit (D.obj j))
    (c : Cone (uncurry.obj F)) : Cone D.conePoints where
  pt := c.pt
  π :=
    { app := fun j =>
        (Q j).lift
          { pt := c.pt
            π :=
              { app := fun k => c.π.app (j, k)
                naturality := fun k k' f => by
                  dsimp; simp only [Category.id_comp]
                  have := @NatTrans.naturality _ _ _ _ _ _ c.π (j, k) (j, k') (𝟙 j, f)
                  dsimp at this
                  

Proof state:
J K : Type v
inst✝² : SmallCategory J
inst✝¹ : SmallCategory K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ K ⥤ C
D : DiagramOfCones F
Q : (j : J) → IsLimit (DiagramOfCones.obj D j)
c : Cone (uncurry.obj F)
j : J
k k' : K
f : k ⟶ k'
this : 𝟙 c.pt ≫ c.π.app (j, k') = c.π.app (j, k) ≫ (F.map (𝟙 j)).app k ≫ (F.obj j).map f
⊢ c.π.app (j, k') = c.π.app (j, k) ≫ (F.obj j).map f

Next tactic:
simp? at this says
                    simp only [Category.id_comp, Functor.map_id, NatTrans.id_app] at this
/-- Given a diagram `D` of limit cones over the `F.obj j`, and a cone over `uncurry.obj F`,
we can construct a cone over the diagram consisting of the cone points from `D`.
-/
@[simps]
def coneOfConeUncurry {D : DiagramOfCones F} (Q : ∀ j, IsLimit (D.obj j))
    (c : Cone (uncurry.obj F)) : Cone D.conePoints where
  pt := c.pt
  π :=
    { app := fun j =>
        (Q j).lift
          { pt := c.pt
            π :=
              { app := fun k => c.π.app (j, k)
                naturality := fun k k' f => by
                  dsimp; simp only [Category.id_comp]
                  have := @NatTrans.naturality _ _ _ _ _ _ c.π (j, k) (j, k') (𝟙 j, f)
                  dsimp at this
                  simp? at this says
                    

Proof state:
J K : Type v
inst✝² : SmallCategory J
inst✝¹ : SmallCategory K
C : Type u
inst✝ : Category.{v, u} C
F : J ⥤ K ⥤ C
D : DiagramOfCones F
Q : (j : J) → IsLimit (DiagramOfCones.obj D j)
c : Cone (uncurry.obj F)
j : J
k k' : K
f : k ⟶ k'
this : 𝟙 c.pt ≫ c.π.app (j, k') = c.π.app (j, k) ≫ (F.map (𝟙 j)).app k ≫ (F.obj j).map f
⊢ c.π.app (j, k') = c.π.app (j, k) ≫ (F.obj j).map f

Next tactic:
simp only [Category.id_comp, Functor.map_id, NatTrans.id_app] at this