l3lab/ntp-mathlib huggingface dataset:
theorem pi_if {p : ι → Prop} [h : DecidablePred p] (s : Set ι) (t₁ t₂ : ∀ i, Set (α i)) :
    (pi s fun i => if p i then t₁ i else t₂ i) =
      pi ({ i ∈ s | p i }) t₁ ∩ pi ({ i ∈ s | ¬p i }) t₂ := by
  ext f
  refine' ⟨fun h => _, _⟩
  · constructor <;>
      · rintro i ⟨his, hpi⟩
        simpa [*] using h i
  · 

Proof state:
case h.refine'_2
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
⊢ f ∈ pi {i | i ∈ s ∧ p i} t₁ ∩ pi {i | i ∈ s ∧ ¬p i} t₂ → f ∈ pi s fun i => if p i then t₁ i else t₂ i

Next tactic:
rintro ⟨ht₁, ht₂⟩ i his
theorem pi_if {p : ι → Prop} [h : DecidablePred p] (s : Set ι) (t₁ t₂ : ∀ i, Set (α i)) :
    (pi s fun i => if p i then t₁ i else t₂ i) =
      pi ({ i ∈ s | p i }) t₁ ∩ pi ({ i ∈ s | ¬p i }) t₂ := by
  ext f
  refine' ⟨fun h => _, _⟩
  · constructor <;>
      · rintro i ⟨his, hpi⟩
        simpa [*] using h i
  · rintro ⟨ht₁, ht₂⟩ i his
    

Proof state:
case h.refine'_2.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i

Next tactic:
by_cases p i
theorem pi_if {p : ι → Prop} [h : DecidablePred p] (s : Set ι) (t₁ t₂ : ∀ i, Set (α i)) :
    (pi s fun i => if p i then t₁ i else t₂ i) =
      pi ({ i ∈ s | p i }) t₁ ∩ pi ({ i ∈ s | ¬p i }) t₂ := by
  ext f
  refine' ⟨fun h => _, _⟩
  · constructor <;>
      · rintro i ⟨his, hpi⟩
        simpa [*] using h i
  · rintro ⟨ht₁, ht₂⟩ i his
    by_cases p i <;> 

Proof state:
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
h✝ : p i
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i

Next tactic:
simp_all
theorem pi_if {p : ι → Prop} [h : DecidablePred p] (s : Set ι) (t₁ t₂ : ∀ i, Set (α i)) :
    (pi s fun i => if p i then t₁ i else t₂ i) =
      pi ({ i ∈ s | p i }) t₁ ∩ pi ({ i ∈ s | ¬p i }) t₂ := by
  ext f
  refine' ⟨fun h => _, _⟩
  · constructor <;>
      · rintro i ⟨his, hpi⟩
        simpa [*] using h i
  · rintro ⟨ht₁, ht₂⟩ i his
    by_cases p i <;> 

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁✝ t₂✝ : (i : ι) → Set (α i)
i✝ : ι
p : ι → Prop
h : DecidablePred p
s : Set ι
t₁ t₂ : (i : ι) → Set (α i)
f : (i : ι) → α i
ht₁ : f ∈ pi {i | i ∈ s ∧ p i} t₁
ht₂ : f ∈ pi {i | i ∈ s ∧ ¬p i} t₂
i : ι
his : i ∈ s
h✝ : ¬p i
⊢ f i ∈ (fun i => if p i then t₁ i else t₂ i) i

Next tactic:
simp_all
theorem union_pi : (s₁ ∪ s₂).pi t = s₁.pi t ∩ s₂.pi t := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi (s₁ ∪ s₂) t = pi s₁ t ∩ pi s₂ t

Next tactic:
simp [pi, or_imp, forall_and, setOf_and]
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
⊢ (pi (s₁ ∪ s₂) fun i => t₁ i ∩ t₂ i) = pi s₁ t₁ ∩ pi s₂ t₂

Next tactic:
ext x
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
⊢ (x ∈ pi (s₁ ∪ s₂) fun i => t₁ i ∩ t₂ i) ↔ x ∈ pi s₁ t₁ ∩ pi s₂ t₂

Next tactic:
simp only [mem_pi, mem_union, mem_inter_iff]
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
⊢ (∀ (i : ι), i ∈ s₁ ∨ i ∈ s₂ → x i ∈ t₁ i ∧ x i ∈ t₂ i) ↔ (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i

Next tactic:
refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₁ ∨ i ∈ s₂
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
cases' hi with hi hi
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · 

Proof state:
case h.inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₁
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
by_cases hi2 : i ∈ s₂
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · 

Proof state:
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₁
hi2 : i ∈ s₂
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
exact ⟨h.1 i hi, h.2 i hi2⟩
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · 

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₁
hi2 : i ∉ s₂
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
refine ⟨h.1 i hi, ?_⟩
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₁
hi2 : i ∉ s₂
⊢ x i ∈ t₂ i

Next tactic:
rw [ht₂ i hi2]
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      rw [ht₂ i hi2]
      

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₁
hi2 : i ∉ s₂
⊢ x i ∈ univ

Next tactic:
exact mem_univ _
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      rw [ht₂ i hi2]
      exact mem_univ _
  · 

Proof state:
case h.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₂
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
by_cases hi1 : i ∈ s₁
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      rw [ht₂ i hi2]
      exact mem_univ _
  · by_cases hi1 : i ∈ s₁
    · 

Proof state:
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₂
hi1 : i ∈ s₁
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
exact ⟨h.1 i hi1, h.2 i hi⟩
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      rw [ht₂ i hi2]
      exact mem_univ _
  · by_cases hi1 : i ∈ s₁
    · exact ⟨h.1 i hi1, h.2 i hi⟩
    · 

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₂
hi1 : i ∉ s₁
⊢ x i ∈ t₁ i ∧ x i ∈ t₂ i

Next tactic:
refine ⟨?_, h.2 i hi⟩
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      rw [ht₂ i hi2]
      exact mem_univ _
  · by_cases hi1 : i ∈ s₁
    · exact ⟨h.1 i hi1, h.2 i hi⟩
    · refine ⟨?_, h.2 i hi⟩
      

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₂
hi1 : i ∉ s₁
⊢ x i ∈ t₁ i

Next tactic:
rw [ht₁ i hi1]
theorem union_pi_inter
    (ht₁ : ∀ i ∉ s₁, t₁ i = univ) (ht₂ : ∀ i ∉ s₂, t₂ i = univ) :
    (s₁ ∪ s₂).pi (fun i ↦ t₁ i ∩ t₂ i) = s₁.pi t₁ ∩ s₂.pi t₂ := by
  ext x
  simp only [mem_pi, mem_union, mem_inter_iff]
  refine ⟨fun h ↦ ⟨fun i his₁ ↦ (h i (Or.inl his₁)).1, fun i his₂ ↦ (h i (Or.inr his₂)).2⟩,
    fun h i hi ↦ ?_⟩
  cases' hi with hi hi
  · by_cases hi2 : i ∈ s₂
    · exact ⟨h.1 i hi, h.2 i hi2⟩
    · refine ⟨h.1 i hi, ?_⟩
      rw [ht₂ i hi2]
      exact mem_univ _
  · by_cases hi1 : i ∈ s₁
    · exact ⟨h.1 i hi1, h.2 i hi⟩
    · refine ⟨?_, h.2 i hi⟩
      rw [ht₁ i hi1]
      

Proof state:
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht₁ : ∀ i ∉ s₁, t₁ i = univ
ht₂ : ∀ i ∉ s₂, t₂ i = univ
x : (i : ι) → α i
h : (∀ i ∈ s₁, x i ∈ t₁ i) ∧ ∀ i ∈ s₂, x i ∈ t₂ i
i : ι
hi : i ∈ s₂
hi1 : i ∉ s₁
⊢ x i ∈ univ

Next tactic:
exact mem_univ _
@[simp]
theorem pi_inter_compl (s : Set ι) : pi s t ∩ pi sᶜ t = pi univ t := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
s : Set ι
⊢ pi s t ∩ pi sᶜ t = pi univ t

Next tactic:
rw [← union_pi, union_compl_self]
theorem pi_update_of_not_mem [DecidableEq ι] (hi : i ∉ s) (f : ∀ j, α j) (a : α i)
    (t : ∀ j, α j → Set (β j)) : (s.pi fun j => t j (update f i a j)) = s.pi fun j => t j (f j) :=
  (pi_congr rfl) fun j hj => by
    

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∉ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
j : ι
hj : j ∈ s
⊢ t j (update f i a j) = t j (f j)

Next tactic:
rw [update_noteq]
theorem pi_update_of_not_mem [DecidableEq ι] (hi : i ∉ s) (f : ∀ j, α j) (a : α i)
    (t : ∀ j, α j → Set (β j)) : (s.pi fun j => t j (update f i a j)) = s.pi fun j => t j (f j) :=
  (pi_congr rfl) fun j hj => by
    rw [update_noteq]
    

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∉ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
j : ι
hj : j ∈ s
⊢ j ≠ i

Next tactic:
exact fun h => hi (h ▸ hj)
theorem pi_update_of_mem [DecidableEq ι] (hi : i ∈ s) (f : ∀ j, α j) (a : α i)
    (t : ∀ j, α j → Set (β j)) :
    (s.pi fun j => t j (update f i a j)) = { x | x i ∈ t i a } ∩ (s \ {i}).pi fun j => t j (f j) :=
  calc
    (s.pi fun j => t j (update f i a j)) = ({i} ∪ s \ {i}).pi fun j => t j (update f i a j) :=
        by 

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ (pi s fun j => t j (update f i a j)) = pi ({i} ∪ s \ {i}) fun j => t j (update f i a j)

Next tactic:
rw [union_diff_self, union_eq_self_of_subset_left (singleton_subset_iff.2 hi)]
theorem pi_update_of_mem [DecidableEq ι] (hi : i ∈ s) (f : ∀ j, α j) (a : α i)
    (t : ∀ j, α j → Set (β j)) :
    (s.pi fun j => t j (update f i a j)) = { x | x i ∈ t i a } ∩ (s \ {i}).pi fun j => t j (f j) :=
  calc
    (s.pi fun j => t j (update f i a j)) = ({i} ∪ s \ {i}).pi fun j => t j (update f i a j) :=
        by rw [union_diff_self, union_eq_self_of_subset_left (singleton_subset_iff.2 hi)]
    _ = { x | x i ∈ t i a } ∩ (s \ {i}).pi fun j => t j (f j) :=
        by 

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ (pi ({i} ∪ s \ {i}) fun j => t j (update f i a j)) = {x | x i ∈ t i a} ∩ pi (s \ {i}) fun j => t j (f j)

Next tactic:
rw [union_pi, singleton_pi', update_same, pi_update_of_not_mem]
theorem pi_update_of_mem [DecidableEq ι] (hi : i ∈ s) (f : ∀ j, α j) (a : α i)
    (t : ∀ j, α j → Set (β j)) :
    (s.pi fun j => t j (update f i a j)) = { x | x i ∈ t i a } ∩ (s \ {i}).pi fun j => t j (f j) :=
  calc
    (s.pi fun j => t j (update f i a j)) = ({i} ∪ s \ {i}).pi fun j => t j (update f i a j) :=
        by rw [union_diff_self, union_eq_self_of_subset_left (singleton_subset_iff.2 hi)]
    _ = { x | x i ∈ t i a } ∩ (s \ {i}).pi fun j => t j (f j) :=
        by rw [union_pi, singleton_pi', update_same, pi_update_of_not_mem]; 

Proof state:
case hi
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
hi : i ∈ s
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ i ∉ s \ {i}

Next tactic:
simp
theorem univ_pi_update [DecidableEq ι] {β : ∀ _, Type*} (i : ι) (f : ∀ j, α j) (a : α i)
    (t : ∀ j, α j → Set (β j)) :
    (pi univ fun j => t j (update f i a j)) = { x | x i ∈ t i a } ∩ pi {i}ᶜ fun j => t j (f j) :=
  by 

Proof state:
ι : Type u_1
α : ι → Type u_2
β✝ : ι → Type u_3
s s₁ s₂ : Set ι
t✝ t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
inst✝ : DecidableEq ι
β : ι → Type u_4
i : ι
f : (j : ι) → α j
a : α i
t : (j : ι) → α j → Set (β j)
⊢ (pi univ fun j => t j (update f i a j)) = {x | x i ∈ t i a} ∩ pi {i}ᶜ fun j => t j (f j)

Next tactic:
rw [compl_eq_univ_diff, ← pi_update_of_mem (mem_univ _)]
theorem univ_pi_update_univ [DecidableEq ι] (i : ι) (s : Set (α i)) :
    pi univ (update (fun j : ι => (univ : Set (α j))) i s) = eval i ⁻¹' s := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
inst✝ : DecidableEq ι
i : ι
s : Set (α i)
⊢ pi univ (update (fun j => univ) i s) = eval i ⁻¹' s

Next tactic:
rw [univ_pi_update i (fun j => (univ : Set (α j))) s fun j t => t, pi_univ, inter_univ, preimage]
theorem subset_eval_image_pi (ht : (s.pi t).Nonempty) (i : ι) : t i ⊆ eval i '' s.pi t := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht : Set.Nonempty (pi s t)
i : ι
⊢ t i ⊆ eval i '' pi s t

Next tactic:
classical
  obtain ⟨f, hf⟩ := ht
  refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
  obtain rfl | hji := eq_or_ne j i <;> simp [*, hf _ hj]
theorem subset_eval_image_pi (ht : (s.pi t).Nonempty) (i : ι) : t i ⊆ eval i '' s.pi t := by
  classical
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
ht : Set.Nonempty (pi s t)
i : ι
⊢ t i ⊆ eval i '' pi s t

Next tactic:
obtain ⟨f, hf⟩ := ht
theorem subset_eval_image_pi (ht : (s.pi t).Nonempty) (i : ι) : t i ⊆ eval i '' s.pi t := by
  classical
  obtain ⟨f, hf⟩ := ht
  

Proof state:
case intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
⊢ t i ⊆ eval i '' pi s t

Next tactic:
refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
theorem subset_eval_image_pi (ht : (s.pi t).Nonempty) (i : ι) : t i ⊆ eval i '' s.pi t := by
  classical
  obtain ⟨f, hf⟩ := ht
  refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
  

Proof state:
case intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
y : α i
hy : y ∈ t i
j : ι
hj : j ∈ s
⊢ update f i y j ∈ t j

Next tactic:
obtain rfl | hji := eq_or_ne j i
theorem subset_eval_image_pi (ht : (s.pi t).Nonempty) (i : ι) : t i ⊆ eval i '' s.pi t := by
  classical
  obtain ⟨f, hf⟩ := ht
  refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
  obtain rfl | hji := eq_or_ne j i <;> 

Proof state:
case intro.inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
j : ι
hj : j ∈ s
y : α j
hy : y ∈ t j
⊢ update f j y j ∈ t j

Next tactic:
simp [*, hf _ hj]
theorem subset_eval_image_pi (ht : (s.pi t).Nonempty) (i : ι) : t i ⊆ eval i '' s.pi t := by
  classical
  obtain ⟨f, hf⟩ := ht
  refine' fun y hy => ⟨update f i y, fun j hj => _, update_same _ _ _⟩
  obtain rfl | hji := eq_or_ne j i <;> 

Proof state:
case intro.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ i : ι
f : (i : ι) → α i
hf : f ∈ pi s t
y : α i
hy : y ∈ t i
j : ι
hj : j ∈ s
hji : j ≠ i
⊢ update f i y j ∈ t j

Next tactic:
simp [*, hf _ hj]
theorem pi_subset_pi_iff : pi s t₁ ⊆ pi s t₂ ↔ (∀ i ∈ s, t₁ i ⊆ t₂ i) ∨ pi s t₁ = ∅ := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi s t₁ ⊆ pi s t₂ ↔ (∀ i ∈ s, t₁ i ⊆ t₂ i) ∨ pi s t₁ = ∅

Next tactic:
refine'
    ⟨fun h => or_iff_not_imp_right.2 _, fun h => h.elim pi_mono fun h' => h'.symm ▸ empty_subset _⟩
theorem pi_subset_pi_iff : pi s t₁ ⊆ pi s t₂ ↔ (∀ i ∈ s, t₁ i ⊆ t₂ i) ∨ pi s t₁ = ∅ := by
  refine'
    ⟨fun h => or_iff_not_imp_right.2 _, fun h => h.elim pi_mono fun h' => h'.symm ▸ empty_subset _⟩
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
h : pi s t₁ ⊆ pi s t₂
⊢ ¬pi s t₁ = ∅ → ∀ i ∈ s, t₁ i ⊆ t₂ i

Next tactic:
rw [← Ne.def, ← nonempty_iff_ne_empty]
theorem pi_subset_pi_iff : pi s t₁ ⊆ pi s t₂ ↔ (∀ i ∈ s, t₁ i ⊆ t₂ i) ∨ pi s t₁ = ∅ := by
  refine'
    ⟨fun h => or_iff_not_imp_right.2 _, fun h => h.elim pi_mono fun h' => h'.symm ▸ empty_subset _⟩
  rw [← Ne.def, ← nonempty_iff_ne_empty]
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
h : pi s t₁ ⊆ pi s t₂
⊢ Set.Nonempty (pi s t₁) → ∀ i ∈ s, t₁ i ⊆ t₂ i

Next tactic:
intro hne i hi
theorem pi_subset_pi_iff : pi s t₁ ⊆ pi s t₂ ↔ (∀ i ∈ s, t₁ i ⊆ t₂ i) ∨ pi s t₁ = ∅ := by
  refine'
    ⟨fun h => or_iff_not_imp_right.2 _, fun h => h.elim pi_mono fun h' => h'.symm ▸ empty_subset _⟩
  rw [← Ne.def, ← nonempty_iff_ne_empty]
  intro hne i hi
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i✝ : ι
h : pi s t₁ ⊆ pi s t₂
hne : Set.Nonempty (pi s t₁)
i : ι
hi : i ∈ s
⊢ t₁ i ⊆ t₂ i

Next tactic:
simpa only [eval_image_pi hi hne, eval_image_pi hi (hne.mono h)] using
    image_subset (fun f : ∀ i, α i => f i) h
theorem univ_pi_subset_univ_pi_iff : pi univ t₁ ⊆ pi univ t₂ ↔ (∀ i, t₁ i ⊆ t₂ i) ∨ ∃ i, t₁ i = ∅ :=
  by 

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
⊢ pi univ t₁ ⊆ pi univ t₂ ↔ (∀ (i : ι), t₁ i ⊆ t₂ i) ∨ ∃ i, t₁ i = ∅

Next tactic:
simp [pi_subset_pi_iff]
theorem eval_preimage [DecidableEq ι] {s : Set (α i)} :
    eval i ⁻¹' s = pi univ (update (fun i => univ) i s) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
⊢ eval i ⁻¹' s = pi univ (update (fun i => univ) i s)

Next tactic:
ext x
theorem eval_preimage [DecidableEq ι] {s : Set (α i)} :
    eval i ⁻¹' s = pi univ (update (fun i => univ) i s) := by
  ext x
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
x : (x : ι) → α x
⊢ x ∈ eval i ⁻¹' s ↔ x ∈ pi univ (update (fun i => univ) i s)

Next tactic:
simp [@forall_update_iff _ (fun i => Set (α i)) _ _ _ _ fun i' y => x i' ∈ y]
theorem eval_preimage' [DecidableEq ι] {s : Set (α i)} :
    eval i ⁻¹' s = pi {i} (update (fun i => univ) i s) := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
s✝ s₁ s₂ : Set ι
t t₁ t₂ : (i : ι) → Set (α i)
i : ι
inst✝ : DecidableEq ι
s : Set (α i)
⊢ eval i ⁻¹' s = pi {i} (update (fun i => univ) i s)

Next tactic:
ext