l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem map_eval_pi (f : ∀ i, Filter (α i)) [∀ i, NeBot (f i)] (i : ι) :
    map (eval i) (pi f) = f i := by
  refine' le_antisymm (tendsto_eval_pi f i) fun s hs => _
  rcases mem_pi.1 (mem_map.1 hs) with ⟨I, hIf, t, htf, hI⟩
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
f✝ f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
f : (i : ι) → Filter (α i)
inst✝ : ∀ (i : ι), NeBot (f i)
i : ι
s : Set (α i)
hs : s ∈ map (eval i) (pi f)
I : Set ι
hIf : Set.Finite I
t : (i : ι) → Set (α i)
htf : ∀ (i : ι), t i ∈ f i
hI : Set.pi I t ⊆ eval i ⁻¹' s
⊢ s ∈ f i

Next tactic:
rw [← image_subset_iff] at hI
@[simp]
theorem map_eval_pi (f : ∀ i, Filter (α i)) [∀ i, NeBot (f i)] (i : ι) :
    map (eval i) (pi f) = f i := by
  refine' le_antisymm (tendsto_eval_pi f i) fun s hs => _
  rcases mem_pi.1 (mem_map.1 hs) with ⟨I, hIf, t, htf, hI⟩
  rw [← image_subset_iff] at hI
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
f✝ f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
f : (i : ι) → Filter (α i)
inst✝ : ∀ (i : ι), NeBot (f i)
i : ι
s : Set (α i)
hs : s ∈ map (eval i) (pi f)
I : Set ι
hIf : Set.Finite I
t : (i : ι) → Set (α i)
htf : ∀ (i : ι), t i ∈ f i
hI : eval i '' Set.pi I t ⊆ s
⊢ s ∈ f i

Next tactic:
refine' mem_of_superset (htf i) ((subset_eval_image_pi _ _).trans hI)
@[simp]
theorem map_eval_pi (f : ∀ i, Filter (α i)) [∀ i, NeBot (f i)] (i : ι) :
    map (eval i) (pi f) = f i := by
  refine' le_antisymm (tendsto_eval_pi f i) fun s hs => _
  rcases mem_pi.1 (mem_map.1 hs) with ⟨I, hIf, t, htf, hI⟩
  rw [← image_subset_iff] at hI
  refine' mem_of_superset (htf i) ((subset_eval_image_pi _ _).trans hI)
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
f✝ f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
f : (i : ι) → Filter (α i)
inst✝ : ∀ (i : ι), NeBot (f i)
i : ι
s : Set (α i)
hs : s ∈ map (eval i) (pi f)
I : Set ι
hIf : Set.Finite I
t : (i : ι) → Set (α i)
htf : ∀ (i : ι), t i ∈ f i
hI : eval i '' Set.pi I t ⊆ s
⊢ Set.Nonempty (Set.pi I t)

Next tactic:
exact nonempty_of_mem (pi_mem_pi hIf fun i _ => htf i)
@[simp]
theorem pi_inj [∀ i, NeBot (f₁ i)] : pi f₁ = pi f₂ ↔ f₁ = f₂ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
inst✝ : ∀ (i : ι), NeBot (f₁ i)
⊢ pi f₁ = pi f₂ ↔ f₁ = f₂

Next tactic:
refine' ⟨fun h => _, congr_arg pi⟩
@[simp]
theorem pi_inj [∀ i, NeBot (f₁ i)] : pi f₁ = pi f₂ ↔ f₁ = f₂ := by
  refine' ⟨fun h => _, congr_arg pi⟩
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
inst✝ : ∀ (i : ι), NeBot (f₁ i)
h : pi f₁ = pi f₂
⊢ f₁ = f₂

Next tactic:
have hle : f₁ ≤ f₂ := pi_le_pi.1 h.le
@[simp]
theorem pi_inj [∀ i, NeBot (f₁ i)] : pi f₁ = pi f₂ ↔ f₁ = f₂ := by
  refine' ⟨fun h => _, congr_arg pi⟩
  have hle : f₁ ≤ f₂ := pi_le_pi.1 h.le
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
inst✝ : ∀ (i : ι), NeBot (f₁ i)
h : pi f₁ = pi f₂
hle : f₁ ≤ f₂
⊢ f₁ = f₂

Next tactic:
haveI : ∀ i, NeBot (f₂ i) := fun i => neBot_of_le (hle i)
@[simp]
theorem pi_inj [∀ i, NeBot (f₁ i)] : pi f₁ = pi f₂ ↔ f₁ = f₂ := by
  refine' ⟨fun h => _, congr_arg pi⟩
  have hle : f₁ ≤ f₂ := pi_le_pi.1 h.le
  haveI : ∀ i, NeBot (f₂ i) := fun i => neBot_of_le (hle i)
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
inst✝ : ∀ (i : ι), NeBot (f₁ i)
h : pi f₁ = pi f₂
hle : f₁ ≤ f₂
this : ∀ (i : ι), NeBot (f₂ i)
⊢ f₁ = f₂

Next tactic:
exact hle.antisymm (pi_le_pi.1 h.ge)
theorem mem_coprodᵢ_iff {s : Set (∀ i, α i)} :
    s ∈ Filter.coprodᵢ f ↔ ∀ i : ι, ∃ t₁ ∈ f i, eval i ⁻¹' t₁ ⊆ s := by 

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
s : Set ((i : ι) → α i)
⊢ s ∈ Filter.coprodᵢ f ↔ ∀ (i : ι), ∃ t₁ ∈ f i, eval i ⁻¹' t₁ ⊆ s

Next tactic:
simp [Filter.coprodᵢ]
theorem compl_mem_coprodᵢ {s : Set (∀ i, α i)} :
    sᶜ ∈ Filter.coprodᵢ f ↔ ∀ i, (eval i '' s)ᶜ ∈ f i := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
s : Set ((i : ι) → α i)
⊢ sᶜ ∈ Filter.coprodᵢ f ↔ ∀ (i : ι), (eval i '' s)ᶜ ∈ f i

Next tactic:
simp only [Filter.coprodᵢ, mem_iSup, compl_mem_comap]
theorem coprodᵢ_neBot_iff' :
    NeBot (Filter.coprodᵢ f) ↔ (∀ i, Nonempty (α i)) ∧ ∃ d, NeBot (f d) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
⊢ NeBot (Filter.coprodᵢ f) ↔ (∀ (i : ι), Nonempty (α i)) ∧ ∃ d, NeBot (f d)

Next tactic:
simp only [Filter.coprodᵢ, iSup_neBot, ← exists_and_left, ← comap_eval_neBot_iff']
@[simp]
theorem coprodᵢ_neBot_iff [∀ i, Nonempty (α i)] : NeBot (Filter.coprodᵢ f) ↔ ∃ d, NeBot (f d) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
inst✝ : ∀ (i : ι), Nonempty (α i)
⊢ NeBot (Filter.coprodᵢ f) ↔ ∃ d, NeBot (f d)

Next tactic:
simp [coprodᵢ_neBot_iff', *]
theorem coprodᵢ_eq_bot_iff' : Filter.coprodᵢ f = ⊥ ↔ (∃ i, IsEmpty (α i)) ∨ f = ⊥ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
⊢ Filter.coprodᵢ f = ⊥ ↔ (∃ i, IsEmpty (α i)) ∨ f = ⊥

Next tactic:
simpa only [not_neBot, not_and_or, funext_iff, not_forall, not_exists, not_nonempty_iff]
    using coprodᵢ_neBot_iff'.not
@[simp]
theorem coprodᵢ_eq_bot_iff [∀ i, Nonempty (α i)] : Filter.coprodᵢ f = ⊥ ↔ f = ⊥ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
inst✝ : ∀ (i : ι), Nonempty (α i)
⊢ Filter.coprodᵢ f = ⊥ ↔ f = ⊥

Next tactic:
simpa [funext_iff] using coprodᵢ_neBot_iff.not
theorem map_pi_map_coprodᵢ_le :
    map (fun k : ∀ i, α i => fun i => m i (k i)) (Filter.coprodᵢ f) ≤
      Filter.coprodᵢ fun i => map (m i) (f i) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
β : ι → Type u_3
m : (i : ι) → α i → β i
⊢ map (fun k i => m i (k i)) (Filter.coprodᵢ f) ≤ Filter.coprodᵢ fun i => map (m i) (f i)

Next tactic:
simp only [le_def, mem_map, mem_coprodᵢ_iff]
theorem map_pi_map_coprodᵢ_le :
    map (fun k : ∀ i, α i => fun i => m i (k i)) (Filter.coprodᵢ f) ≤
      Filter.coprodᵢ fun i => map (m i) (f i) := by
  simp only [le_def, mem_map, mem_coprodᵢ_iff]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
β : ι → Type u_3
m : (i : ι) → α i → β i
⊢ ∀ (x : Set ((i : ι) → β i)),
    (∀ (i : ι), ∃ t₁, m i ⁻¹' t₁ ∈ f i ∧ eval i ⁻¹' t₁ ⊆ x) →
      ∀ (i : ι), ∃ t₁ ∈ f i, eval i ⁻¹' t₁ ⊆ (fun k i => m i (k i)) ⁻¹' x

Next tactic:
intro s h i
theorem map_pi_map_coprodᵢ_le :
    map (fun k : ∀ i, α i => fun i => m i (k i)) (Filter.coprodᵢ f) ≤
      Filter.coprodᵢ fun i => map (m i) (f i) := by
  simp only [le_def, mem_map, mem_coprodᵢ_iff]
  intro s h i
  

Proof state:
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
β : ι → Type u_3
m : (i : ι) → α i → β i
s : Set ((i : ι) → β i)
h : ∀ (i : ι), ∃ t₁, m i ⁻¹' t₁ ∈ f i ∧ eval i ⁻¹' t₁ ⊆ s
i : ι
⊢ ∃ t₁ ∈ f i, eval i ⁻¹' t₁ ⊆ (fun k i => m i (k i)) ⁻¹' s

Next tactic:
obtain ⟨t, H, hH⟩ := h i
theorem map_pi_map_coprodᵢ_le :
    map (fun k : ∀ i, α i => fun i => m i (k i)) (Filter.coprodᵢ f) ≤
      Filter.coprodᵢ fun i => map (m i) (f i) := by
  simp only [le_def, mem_map, mem_coprodᵢ_iff]
  intro s h i
  obtain ⟨t, H, hH⟩ := h i
  

Proof state:
case intro.intro
ι : Type u_1
α : ι → Type u_2
f f₁ f₂ : (i : ι) → Filter (α i)
s✝ : (i : ι) → Set (α i)
p : (i : ι) → α i → Prop
β : ι → Type u_3
m : (i : ι) → α i → β i
s : Set ((i : ι) → β i)
h : ∀ (i : ι), ∃ t₁, m i ⁻¹' t₁ ∈ f i ∧ eval i ⁻¹' t₁ ⊆ s
i : ι
t : Set (β i)
H : m i ⁻¹' t ∈ f i
hH : eval i ⁻¹' t ⊆ s
⊢ ∃ t₁ ∈ f i, eval i ⁻¹' t₁ ⊆ (fun k i => m i (k i)) ⁻¹' s

Next tactic:
exact ⟨{ x : α i | m i x ∈ t }, H, fun x hx => hH hx⟩
@[simp]
theorem tfae_singleton (p) : TFAE [p] := by 

Proof state:
p : Prop
⊢ TFAE [p]

Next tactic:
simp [TFAE, -eq_iff_iff]
theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l :=
  ⟨fun H => ⟨H a (by 

Proof state:
a b : Prop
l : List Prop
h : b ∈ l
H : TFAE (a :: l)
⊢ a ∈ a :: l

Next tactic:
simp
theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l :=
  ⟨fun H => ⟨H a (by simp) b (Mem.tail a h),
    fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩,
      by
        

Proof state:
a b : Prop
l : List Prop
h : b ∈ l
⊢ (a ↔ b) ∧ TFAE l → TFAE (a :: l)

Next tactic:
rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩)
theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l :=
  ⟨fun H => ⟨H a (by simp) b (Mem.tail a h),
    fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩,
      by
        rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩)
        · 

Proof state:
case intro.head.head
a b : Prop
l : List Prop
h : b ∈ l
ab : a ↔ b
H : TFAE l
⊢ a ↔ a

Next tactic:
rfl
theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l :=
  ⟨fun H => ⟨H a (by simp) b (Mem.tail a h),
    fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩,
      by
        rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩)
        · rfl
        · 

Proof state:
case intro.head.tail
a b : Prop
l : List Prop
h : b ∈ l
ab : a ↔ b
H : TFAE l
q : Prop
hq : Mem q l
⊢ a ↔ q

Next tactic:
exact ab.trans (H _ h _ hq)
theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l :=
  ⟨fun H => ⟨H a (by simp) b (Mem.tail a h),
    fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩,
      by
        rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩)
        · rfl
        · exact ab.trans (H _ h _ hq)
        · 

Proof state:
case intro.tail.head
a b : Prop
l : List Prop
h : b ∈ l
ab : a ↔ b
H : TFAE l
p : Prop
hp : Mem p l
⊢ p ↔ a

Next tactic:
exact (ab.trans (H _ h _ hp)).symm
theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l :=
  ⟨fun H => ⟨H a (by simp) b (Mem.tail a h),
    fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩,
      by
        rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩)
        · rfl
        · exact ab.trans (H _ h _ hq)
        · exact (ab.trans (H _ h _ hp)).symm
        · 

Proof state:
case intro.tail.tail
a b : Prop
l : List Prop
h : b ∈ l
ab : a ↔ b
H : TFAE l
p : Prop
hp : Mem p l
q : Prop
hq : Mem q l
⊢ p ↔ q

Next tactic:
exact H _ hp _ hq
@[simp]
theorem tfae_cons_self {a} {l : List Prop} : TFAE (a :: a :: l) ↔ TFAE (a :: l) := by
  

Proof state:
a : Prop
l : List Prop
⊢ TFAE (a :: a :: l) ↔ TFAE (a :: l)

Next tactic:
simp [tfae_cons_cons]
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  

Proof state:
a b : Prop
l : List Prop
⊢ Chain (fun x x_1 => x → x_1) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l)

Next tactic:
induction' l with c l IH generalizing a b
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    

Proof state:
case nil
a b : Prop
⊢ Chain (fun x x_1 => x → x_1) a [b] → (ilast' b [] → a) → TFAE [a, b]

Next tactic:
simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    

Proof state:
case cons
c : Prop
l : List Prop
IH : ∀ {a b : Prop}, Chain (fun x x_1 => x → x_1) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l)
a b : Prop
⊢ Chain (fun x x_1 => x → x_1) a (b :: c :: l) → (ilast' b (c :: l) → a) → TFAE (a :: b :: c :: l)

Next tactic:
simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
  · 

Proof state:
case nil
a b : Prop
⊢ (a → b) → (ilast' b [] → a) → (a ↔ b)

Next tactic:
intro a b
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
  · intro a b
    

Proof state:
case nil
a✝ b✝ : Prop
a : a✝ → b✝
b : ilast' b✝ [] → a✝
⊢ a✝ ↔ b✝

Next tactic:
exact Iff.intro a b
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
  · intro a b
    exact Iff.intro a b
  

Proof state:
case cons
c : Prop
l : List Prop
a b : Prop
IH : ∀ {a b : Prop}, (a → b) ∧ Chain (fun x x_1 => x → x_1) b l → (ilast' b l → a) → (a ↔ b) ∧ TFAE (b :: l)
⊢ (a → b) ∧ (b → c) ∧ Chain (fun x x_1 => x → x_1) c l → (ilast' b (c :: l) → a) → (a ↔ b) ∧ (b ↔ c) ∧ TFAE (c :: l)

Next tactic:
rintro ⟨ab, ⟨bc, ch⟩⟩ la
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
  · intro a b
    exact Iff.intro a b
  rintro ⟨ab, ⟨bc, ch⟩⟩ la
  

Proof state:
case cons.intro.intro
c : Prop
l : List Prop
a b : Prop
IH : ∀ {a b : Prop}, (a → b) ∧ Chain (fun x x_1 => x → x_1) b l → (ilast' b l → a) → (a ↔ b) ∧ TFAE (b :: l)
ab : a → b
bc : b → c
ch : Chain (fun x x_1 => x → x_1) c l
la : ilast' b (c :: l) → a
⊢ (a ↔ b) ∧ (b ↔ c) ∧ TFAE (c :: l)

Next tactic:
have := IH ⟨bc, ch⟩ (ab ∘ la)
theorem tfae_of_cycle {a b} {l : List Prop} :
    List.Chain (· → ·) a (b :: l) → (ilast' b l → a) → TFAE (a :: b :: l) := by
  induction' l with c l IH generalizing a b <;>
    simp only [tfae_cons_cons, tfae_singleton, and_true_iff, chain_cons, Chain.nil] at *
  · intro a b
    exact Iff.intro a b
  rintro ⟨ab, ⟨bc, ch⟩⟩ la
  have := IH ⟨bc, ch⟩ (ab ∘ la)
  

Proof state:
case cons.intro.intro
c : Prop
l : List Prop
a b : Prop
IH : ∀ {a b : Prop}, (a → b) ∧ Chain (fun x x_1 => x → x_1) b l → (ilast' b l → a) → (a ↔ b) ∧ TFAE (b :: l)
ab : a → b
bc : b → c
ch : Chain (fun x x_1 => x → x_1) c l
la : ilast' b (c :: l) → a
this : (b ↔ c) ∧ TFAE (c :: l)
⊢ (a ↔ b) ∧ (b ↔ c) ∧ TFAE (c :: l)

Next tactic:
exact ⟨⟨ab, la ∘ (this.2 c (Mem.head _) _ (ilast'_mem _ _)).1 ∘ bc⟩, this⟩
/-- If `P₁ x ↔ ... ↔ Pₙ x` for all `x`, then `(∀ x, P₁ x) ↔ ... ↔ (∀ x, Pₙ x)`.
Note: in concrete cases, Lean has trouble finding the list `[P₁, ..., Pₙ]` from the list
`[(∀ x, P₁ x), ..., (∀ x, Pₙ x)]`, but simply providing a list of underscores with the right
length makes it happier.

Example:
```lean
example (P₁ P₂ P₃ : ℕ → Prop) (H : ∀ n, [P₁ n, P₂ n, P₃ n].TFAE) :
    [∀ n, P₁ n, ∀ n, P₂ n, ∀ n, P₃ n].TFAE :=
  forall_tfae [_, _, _] H
```
-/
theorem forall_tfae {α : Type*} (l : List (α → Prop)) (H : ∀ a : α, (l.map (fun p ↦ p a)).TFAE) :
    (l.map (fun p ↦ ∀ a, p a)).TFAE := by
  

Proof state:
α : Type u_1
l : List (α → Prop)
H : ∀ (a : α), TFAE (map (fun p => p a) l)
⊢ TFAE (map (fun p => ∀ (a : α), p a) l)

Next tactic:
simp_rw [TFAE, List.forall_mem_map_iff]
/-- If `P₁ x ↔ ... ↔ Pₙ x` for all `x`, then `(∀ x, P₁ x) ↔ ... ↔ (∀ x, Pₙ x)`.
Note: in concrete cases, Lean has trouble finding the list `[P₁, ..., Pₙ]` from the list
`[(∀ x, P₁ x), ..., (∀ x, Pₙ x)]`, but simply providing a list of underscores with the right
length makes it happier.

Example:
```lean
example (P₁ P₂ P₃ : ℕ → Prop) (H : ∀ n, [P₁ n, P₂ n, P₃ n].TFAE) :
    [∀ n, P₁ n, ∀ n, P₂ n, ∀ n, P₃ n].TFAE :=
  forall_tfae [_, _, _] H
```
-/
theorem forall_tfae {α : Type*} (l : List (α → Prop)) (H : ∀ a : α, (l.map (fun p ↦ p a)).TFAE) :
    (l.map (fun p ↦ ∀ a, p a)).TFAE := by
  simp_rw [TFAE, List.forall_mem_map_iff]
  

Proof state:
α : Type u_1
l : List (α → Prop)
H : ∀ (a : α), TFAE (map (fun p => p a) l)
⊢ ∀ (j : α → Prop), j ∈ l → ∀ (j_1 : α → Prop), j_1 ∈ l → ((∀ (a : α), j a) ↔ ∀ (a : α), j_1 a)

Next tactic:
intros p₁ hp₁ p₂ hp₂
/-- If `P₁ x ↔ ... ↔ Pₙ x` for all `x`, then `(∀ x, P₁ x) ↔ ... ↔ (∀ x, Pₙ x)`.
Note: in concrete cases, Lean has trouble finding the list `[P₁, ..., Pₙ]` from the list
`[(∀ x, P₁ x), ..., (∀ x, Pₙ x)]`, but simply providing a list of underscores with the right
length makes it happier.

Example:
```lean
example (P₁ P₂ P₃ : ℕ → Prop) (H : ∀ n, [P₁ n, P₂ n, P₃ n].TFAE) :
    [∀ n, P₁ n, ∀ n, P₂ n, ∀ n, P₃ n].TFAE :=
  forall_tfae [_, _, _] H
```
-/
theorem forall_tfae {α : Type*} (l : List (α → Prop)) (H : ∀ a : α, (l.map (fun p ↦ p a)).TFAE) :
    (l.map (fun p ↦ ∀ a, p a)).TFAE := by
  simp_rw [TFAE, List.forall_mem_map_iff]
  intros p₁ hp₁ p₂ hp₂
  

Proof state:
α : Type u_1
l : List (α → Prop)
H : ∀ (a : α), TFAE (map (fun p => p a) l)
p₁ : α → Prop
hp₁ : p₁ ∈ l
p₂ : α → Prop
hp₂ : p₂ ∈ l
⊢ (∀ (a : α), p₁ a) ↔ ∀ (a : α), p₂ a

Next tactic:
exact forall_congr' fun a ↦ H a (p₁ a) (mem_map_of_mem (fun p ↦ p a) hp₁)
    (p₂ a) (mem_map_of_mem (fun p ↦ p a) hp₂)
/-- If `P₁ x ↔ ... ↔ Pₙ x` for all `x`, then `(∃ x, P₁ x) ↔ ... ↔ (∃ x, Pₙ x)`.
Note: in concrete cases, Lean has trouble finding the list `[P₁, ..., Pₙ]` from the list
`[(∃ x, P₁ x), ..., (∃ x, Pₙ x)]`, but simply providing a list of underscores with the right
length makes it happier.

Example:
```lean
example (P₁ P₂ P₃ : ℕ → Prop) (H : ∀ n, [P₁ n, P₂ n, P₃ n].TFAE) :
    [∃ n, P₁ n, ∃ n, P₂ n, ∃ n, P₃ n].TFAE :=
  exists_tfae [_, _, _] H
```
-/
theorem exists_tfae {α : Type*} (l : List (α → Prop)) (H : ∀ a : α, (l.map (fun p ↦ p a)).TFAE) :
    (l.map (fun p ↦ ∃ a, p a)).TFAE := by
  

Proof state:
α : Type u_1
l : List (α → Prop)
H : ∀ (a : α), TFAE (map (fun p => p a) l)
⊢ TFAE (map (fun p => ∃ a, p a) l)

Next tactic:
simp_rw [TFAE, List.forall_mem_map_iff]
/-- If `P₁ x ↔ ... ↔ Pₙ x` for all `x`, then `(∃ x, P₁ x) ↔ ... ↔ (∃ x, Pₙ x)`.
Note: in concrete cases, Lean has trouble finding the list `[P₁, ..., Pₙ]` from the list
`[(∃ x, P₁ x), ..., (∃ x, Pₙ x)]`, but simply providing a list of underscores with the right
length makes it happier.

Example:
```lean
example (P₁ P₂ P₃ : ℕ → Prop) (H : ∀ n, [P₁ n, P₂ n, P₃ n].TFAE) :
    [∃ n, P₁ n, ∃ n, P₂ n, ∃ n, P₃ n].TFAE :=
  exists_tfae [_, _, _] H
```
-/
theorem exists_tfae {α : Type*} (l : List (α → Prop)) (H : ∀ a : α, (l.map (fun p ↦ p a)).TFAE) :
    (l.map (fun p ↦ ∃ a, p a)).TFAE := by
  simp_rw [TFAE, List.forall_mem_map_iff]
  

Proof state:
α : Type u_1
l : List (α → Prop)
H : ∀ (a : α), TFAE (map (fun p => p a) l)
⊢ ∀ (j : α → Prop), j ∈ l → ∀ (j_1 : α → Prop), j_1 ∈ l → ((∃ a, j a) ↔ ∃ a, j_1 a)

Next tactic:
intros p₁ hp₁ p₂ hp₂
/-- If `P₁ x ↔ ... ↔ Pₙ x` for all `x`, then `(∃ x, P₁ x) ↔ ... ↔ (∃ x, Pₙ x)`.
Note: in concrete cases, Lean has trouble finding the list `[P₁, ..., Pₙ]` from the list
`[(∃ x, P₁ x), ..., (∃ x, Pₙ x)]`, but simply providing a list of underscores with the right
length makes it happier.

Example:
```lean
example (P₁ P₂ P₃ : ℕ → Prop) (H : ∀ n, [P₁ n, P₂ n, P₃ n].TFAE) :
    [∃ n, P₁ n, ∃ n, P₂ n, ∃ n, P₃ n].TFAE :=
  exists_tfae [_, _, _] H
```
-/
theorem exists_tfae {α : Type*} (l : List (α → Prop)) (H : ∀ a : α, (l.map (fun p ↦ p a)).TFAE) :
    (l.map (fun p ↦ ∃ a, p a)).TFAE := by
  simp_rw [TFAE, List.forall_mem_map_iff]
  intros p₁ hp₁ p₂ hp₂
  

Proof state:
α : Type u_1
l : List (α → Prop)
H : ∀ (a : α), TFAE (map (fun p => p a) l)
p₁ : α → Prop
hp₁ : p₁ ∈ l
p₂ : α → Prop
hp₂ : p₂ ∈ l
⊢ (∃ a, p₁ a) ↔ ∃ a, p₂ a

Next tactic:
exact exists_congr fun a ↦ H a (p₁ a) (mem_map_of_mem (fun p ↦ p a) hp₁)
    (p₂ a) (mem_map_of_mem (fun p ↦ p a) hp₂)
/-- Given a function `U : ι → α` for `[CompleteLattice α]`,
`iInf U` provides a limit cone over `diagram U`.
-/
def coconeIsColimit : IsColimit (cocone U) where
  desc s := homOfLE
    (by
      

Proof state:
ι α : Type v
U : ι → α
inst✝ : CompleteLattice α
s : Cocone (diagram U)
⊢ (cocone U).pt ≤ s.pt

Next tactic:
apply CompleteSemilatticeSup.sSup_le
/-- Given a function `U : ι → α` for `[CompleteLattice α]`,
`iInf U` provides a limit cone over `diagram U`.
-/
def coconeIsColimit : IsColimit (cocone U) where
  desc s := homOfLE
    (by
      apply CompleteSemilatticeSup.sSup_le
      

Proof state:
case a
ι α : Type v
U : ι → α
inst✝ : CompleteLattice α
s : Cocone (diagram U)
⊢ ∀ b ∈ Set.range U, b ≤ s.pt

Next tactic:
rintro _ ⟨j, rfl⟩
/-- Given a function `U : ι → α` for `[CompleteLattice α]`,
`iInf U` provides a limit cone over `diagram U`.
-/
def coconeIsColimit : IsColimit (cocone U) where
  desc s := homOfLE
    (by
      apply CompleteSemilatticeSup.sSup_le
      rintro _ ⟨j, rfl⟩
      

Proof state:
case a.intro
ι α : Type v
U : ι → α
inst✝ : CompleteLattice α
s : Cocone (diagram U)
j : ι
⊢ U j ≤ s.pt

Next tactic:
exact (s.ι.app (single j)).le
/-- Auxiliary lemma for norm_cast to move the cast `-↑n` upwards to `↑-↑n`.

(The restriction to `DivisionRing` is necessary, otherwise this would also apply in the case where
`R = ℤ` and cause nontermination.)
-/
@[norm_cast]
theorem cast_neg_natCast {R} [DivisionRing R] (n : ℕ) : ((-n : ℤ) : R) = -n := by 

Proof state:
α : Type u_1
R : Type u_2
inst✝ : DivisionRing R
n : ℕ
⊢ ↑(-↑n) = -↑n

Next tactic:
simp
@[simp]
theorem cast_div [DivisionRing α] {m n : ℤ} (n_dvd : n ∣ m) (n_nonzero : (n : α) ≠ 0) :
    ((m / n : ℤ) : α) = m / n := by
  

Proof state:
α : Type u_1
inst✝ : DivisionRing α
m n : ℤ
n_dvd : n ∣ m
n_nonzero : ↑n ≠ 0
⊢ ↑(m / n) = ↑m / ↑n

Next tactic:
rcases n_dvd with ⟨k, rfl⟩
@[simp]
theorem cast_div [DivisionRing α] {m n : ℤ} (n_dvd : n ∣ m) (n_nonzero : (n : α) ≠ 0) :
    ((m / n : ℤ) : α) = m / n := by
  rcases n_dvd with ⟨k, rfl⟩
  

Proof state:
case intro
α : Type u_1
inst✝ : DivisionRing α
n : ℤ
n_nonzero : ↑n ≠ 0
k : ℤ
⊢ ↑(n * k / n) = ↑(n * k) / ↑n

Next tactic:
have : n ≠ 0 := by
    rintro rfl
    simp at n_nonzero
@[simp]
theorem cast_div [DivisionRing α] {m n : ℤ} (n_dvd : n ∣ m) (n_nonzero : (n : α) ≠ 0) :
    ((m / n : ℤ) : α) = m / n := by
  rcases n_dvd with ⟨k, rfl⟩
  have : n ≠ 0 := by
    

Proof state:
α : Type u_1
inst✝ : DivisionRing α
n : ℤ
n_nonzero : ↑n ≠ 0
k : ℤ
⊢ n ≠ 0

Next tactic:
rintro rfl
@[simp]
theorem cast_div [DivisionRing α] {m n : ℤ} (n_dvd : n ∣ m) (n_nonzero : (n : α) ≠ 0) :
    ((m / n : ℤ) : α) = m / n := by
  rcases n_dvd with ⟨k, rfl⟩
  have : n ≠ 0 := by
    rintro rfl
    

Proof state:
α : Type u_1
inst✝ : DivisionRing α
k : ℤ
n_nonzero : ↑0 ≠ 0
⊢ False

Next tactic:
simp at n_nonzero
@[simp]
theorem cast_div [DivisionRing α] {m n : ℤ} (n_dvd : n ∣ m) (n_nonzero : (n : α) ≠ 0) :
    ((m / n : ℤ) : α) = m / n := by
  rcases n_dvd with ⟨k, rfl⟩
  have : n ≠ 0 := by
    rintro rfl
    simp at n_nonzero
  

Proof state:
case intro
α : Type u_1
inst✝ : DivisionRing α
n : ℤ
n_nonzero : ↑n ≠ 0
k : ℤ
this : n ≠ 0
⊢ ↑(n * k / n) = ↑(n * k) / ↑n

Next tactic:
rw [Int.mul_ediv_cancel_left _ this, mul_comm n k, Int.cast_mul, mul_div_cancel _ n_nonzero]
/-- The dual cone is the cone consisting of all points `y` such that for
all points `x` in a given set `0 ≤ ⟪ x, y ⟫`. -/
def Set.innerDualCone (s : Set H) : ConvexCone ℝ H where
  carrier := { y | ∀ x ∈ s, 0 ≤ ⟪x, y⟫ }
  smul_mem' c hc y hy x hx := by
    

Proof state:
𝕜 : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
H : Type u_5
inst✝¹ : NormedAddCommGroup H
inst✝ : InnerProductSpace ℝ H
s✝ t s : Set H
c : ℝ
hc : 0 < c
y : H
hy : y ∈ {y | ∀ x ∈ s, 0 ≤ inner x y}
x : H
hx : x ∈ s
⊢ 0 ≤ inner x (c • y)

Next tactic:
rw [real_inner_smul_right]