-- Mathlib/Data/Set/Lattice.lean
theorem iUnion_range_eq_iUnion (C : ι → Set α) {f : ∀ x : ι, β → C x}
    (hf : ∀ x : ι, Surjective (f x)) : ⋃ y : β, range (fun x : ι => (f x y).val) = ⋃ x, C x

Proof state:
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
⊢ (⋃ y, range fun x => ↑(f x y)) = ⋃ x, C x

Tactic:
ext x

Result:
case h
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (x ∈ ⋃ y, range fun x => ↑(f x y)) ↔ x ∈ ⋃ x, C x

Proof state:
case h.mpr
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (∃ i, x ∈ C i) → ∃ i, x ∈ range fun x => ↑(f x i)

Tactic:
rintro ⟨i, hx⟩

Result:
case h.mpr.intro
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
i : ι
hx : x ∈ C i
⊢ ∃ i, x ∈ range fun x => ↑(f x i)

Proof state:
case h.mp
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (∃ i, x ∈ range fun x => ↑(f x i)) → ∃ i, x ∈ C i

Tactic:
rintro ⟨y, i, rfl⟩

Result:
case h.mp.intro.intro
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
y : β
i : ι
⊢ ∃ i_1, (fun x => ↑(f x y)) i ∈ C i_1

Proof state:
case h.mpr.intro.intro
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
i : ι
hx : x ∈ C i
y : β
hy : f i y = ⟨x, hx⟩
⊢ ∃ i, x ∈ range fun x => ↑(f x i)

Tactic:
exact ⟨y, i, congr_arg Subtype.val hy⟩

Result:
no goals

Proof state:
case h.mp.intro.intro
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
y : β
i : ι
⊢ ∃ i_1, (fun x => ↑(f x y)) i ∈ C i_1

Tactic:
exact ⟨i, (f i y).2⟩

Result:
no goals

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (∃ i, x ∈ range fun x => ↑(f x i)) ↔ ∃ i, x ∈ C i

Tactic:
constructor

Result:
case h.mp
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (∃ i, x ∈ range fun x => ↑(f x i)) → ∃ i, x ∈ C i

case h.mpr
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (∃ i, x ∈ C i) → ∃ i, x ∈ range fun x => ↑(f x i)

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (x ∈ ⋃ y, range fun x => ↑(f x y)) ↔ x ∈ ⋃ x, C x

Tactic:
rw [mem_iUnion, mem_iUnion]

Result:
case h
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
⊢ (∃ i, x ∈ range fun x => ↑(f x i)) ↔ ∃ i, x ∈ C i

Proof state:
case h.mpr.intro
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
i : ι
hx : x ∈ C i
⊢ ∃ i, x ∈ range fun x => ↑(f x i)

Tactic:
obtain ⟨y, hy⟩ := hf i ⟨x, hx⟩

Result:
case h.mpr.intro.intro
α : Type u_1
β : Type u_2
ι : Sort u_5
C : ι → Set α
f : (x : ι) → β → ↑(C x)
hf : ∀ (x : ι), Surjective (f x)
x : α
i : ι
hx : x ∈ C i
y : β
hy : f i y = ⟨x, hx⟩
⊢ ∃ i, x ∈ range fun x => ↑(f x i)