-- Mathlib/Topology/MetricSpace/PiNat.lean
theorem exists_lipschitz_retraction_of_isClosed {s : Set (∀ n, E n)} (hs : IsClosed s)
    (hne : s.Nonempty) :
    ∃ f : (∀ n, E n) → ∀ n, E n, (∀ x ∈ s, f x = x) ∧ range f = s ∧ LipschitzWith 1 f

Proof state:
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∈ s
A : (s ∩ cylinder x (longestPrefix x s)).Nonempty
fx : f x = A.some
⊢ A.some ∈ cylinder x (firstDiff x y)

Tactic:
apply cylinder_anti x _ A.some_mem.2

Result:
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∈ s
A : (s ∩ cylinder x (longestPrefix x s)).Nonempty
fx : f x = A.some
⊢ firstDiff x y ≤ longestPrefix x s

Proof state:
case refine_1.h₂
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x : (n : ℕ) → E n
hx : x ∈ s
⊢ x ∈ range f

Tactic:
rw [← fs x hx]

Result:
case refine_1.h₂
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x : (n : ℕ) → E n
hx : x ∈ s
⊢ f x ∈ range f

Proof state:
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∉ s
Ax : (s ∩ cylinder x (longestPrefix x s)).Nonempty
fx : f x = Ax.some
Ay : (s ∩ cylinder y (longestPrefix y s)).Nonempty
fy : f y = Ay.some
H : firstDiff x y ≤ longestPrefix x s ∧ firstDiff x y ≤ longestPrefix y s
I1 : cylinder Ax.some (firstDiff x y) = cylinder x (firstDiff x y)
I3 : cylinder y (firstDiff x y) = cylinder Ay.some (firstDiff x y)
⊢ cylinder Ax.some (firstDiff x y) = cylinder Ay.some (firstDiff x y)

Tactic:
rw [I1, I2, I3]

Result:
no goals

Proof state:
case refine_2.inr.inr
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
⊢ dist (f x) (f y) ≤ dist x y

Tactic:
have I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y) := by
  rw [← mem_cylinder_iff_eq]
  apply mem_cylinder_firstDiff

Result:
case refine_2.inr.inr
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
⊢ dist (f x) (f y) ≤ dist x y

Proof state:
case refine_1.h₁
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
⊢ range f ⊆ s

Tactic:
rintro x ⟨y, rfl⟩

Result:
case refine_1.h₁.intro
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
y : (n : ℕ) → E n
⊢ f y ∈ s

Proof state:
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∈ s
A : (s ∩ cylinder x (longestPrefix x s)).Nonempty
fx : f x = A.some
⊢ firstDiff x y ≤ longestPrefix x s

Tactic:
apply firstDiff_le_longestPrefix hs xs ys

Result:
no goals

Proof state:
case neg
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∈ s
ys : y ∉ s
A : (s ∩ cylinder y (longestPrefix y s)).Nonempty
fy : f y = A.some
I : cylinder A.some (firstDiff x y) = cylinder y (firstDiff x y)
⊢ firstDiff x y ≤ firstDiff x (f y)

Tactic:
rwa [← fy, ← I2, ← mem_cylinder_iff_eq, mem_cylinder_iff_le_firstDiff hfxfy.symm,
  firstDiff_comm _ x] at I

Result:
no goals

Proof state:
case inl
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∉ s
Ax : (s ∩ cylinder x (longestPrefix x s)).Nonempty
fx : f x = Ax.some
Ay : (s ∩ cylinder y (longestPrefix y s)).Nonempty
fy : f y = Ay.some
H : longestPrefix x s < firstDiff x y
⊢ cylinder x (longestPrefix x s) = cylinder y (longestPrefix y s)

Tactic:
exact cylinder_longestPrefix_eq_of_longestPrefix_lt_firstDiff hs hne H xs ys

Result:
no goals

Proof state:
case neg
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∉ s
⊢ firstDiff x y ≤ firstDiff (f x) (f y)

Tactic:
have Ax : (s ∩ cylinder x (longestPrefix x s)).Nonempty :=
  inter_cylinder_longestPrefix_nonempty hs hne x

Result:
case neg
E : ℕ → Type u_1
inst✝¹ : (n : ℕ) → TopologicalSpace (E n)
inst✝ : ∀ (n : ℕ), DiscreteTopology (E n)
s : Set ((n : ℕ) → E n)
hs : IsClosed s
hne : s.Nonempty
f : ((n : ℕ) → E n) → (n : ℕ) → E n := fun x => if x ∈ s then x else ⋯.some
fs : ∀ x ∈ s, f x = x
x y : (n : ℕ) → E n
hxy : x ≠ y
hfxfy : f x ≠ f y
I2 : cylinder x (firstDiff x y) = cylinder y (firstDiff x y)
xs : x ∉ s
ys : y ∉ s
Ax : (s ∩ cylinder x (longestPrefix x s)).Nonempty
⊢ firstDiff x y ≤ firstDiff (f x) (f y)