l3lab/ntp-mathlib huggingface dataset:
/-- `DFinsupp.mapRange.addMonoidHom` as an `AddEquiv`. -/
@[simps apply]
def mapRange.addEquiv (e : ∀ i, β₁ i ≃+ β₂ i) : (Π₀ i, β₁ i) ≃+ Π₀ i, β₂ i :=
  { mapRange.addMonoidHom fun i =>
      (e i).toAddMonoidHom with
    toFun := mapRange (fun i x => e i x) fun i => (e i).map_zero
    invFun := mapRange (fun i x => (e i).symm x) fun i => (e i).symm.map_zero
    left_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.symm_comp_self]
          simp
    right_inv := fun x => by
      

Proof state:
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
e : (i : ι) → β₁ i ≃+ β₂ i
src✝ : (Π₀ (i : ι), β₁ i) →+ Π₀ (i : ι), β₂ i := addMonoidHom fun i => AddEquiv.toAddMonoidHom (e i)
x : Π₀ (i : ι), β₂ i
⊢ mapRange (fun i x => (e i) x) (_ : ∀ (i : ι), (e i) 0 = 0)
      (mapRange (fun i x => (AddEquiv.symm (e i)) x) (_ : ∀ (i : ι), (AddEquiv.symm (e i)) 0 = 0) x) =
    x

Next tactic:
rw [← mapRange_comp]
/-- `DFinsupp.mapRange.addMonoidHom` as an `AddEquiv`. -/
@[simps apply]
def mapRange.addEquiv (e : ∀ i, β₁ i ≃+ β₂ i) : (Π₀ i, β₁ i) ≃+ Π₀ i, β₂ i :=
  { mapRange.addMonoidHom fun i =>
      (e i).toAddMonoidHom with
    toFun := mapRange (fun i x => e i x) fun i => (e i).map_zero
    invFun := mapRange (fun i x => (e i).symm x) fun i => (e i).symm.map_zero
    left_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.symm_comp_self]
          simp
    right_inv := fun x => by
      rw [← mapRange_comp] <;>
        · 

Proof state:
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
e : (i : ι) → β₁ i ≃+ β₂ i
src✝ : (Π₀ (i : ι), β₁ i) →+ Π₀ (i : ι), β₂ i := addMonoidHom fun i => AddEquiv.toAddMonoidHom (e i)
x : Π₀ (i : ι), β₂ i
⊢ mapRange (fun i => (fun x => (e i) x) ∘ fun x => (AddEquiv.symm (e i)) x) ?h x = x

Next tactic:
simp_rw [AddEquiv.self_comp_symm]
/-- `DFinsupp.mapRange.addMonoidHom` as an `AddEquiv`. -/
@[simps apply]
def mapRange.addEquiv (e : ∀ i, β₁ i ≃+ β₂ i) : (Π₀ i, β₁ i) ≃+ Π₀ i, β₂ i :=
  { mapRange.addMonoidHom fun i =>
      (e i).toAddMonoidHom with
    toFun := mapRange (fun i x => e i x) fun i => (e i).map_zero
    invFun := mapRange (fun i x => (e i).symm x) fun i => (e i).symm.map_zero
    left_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.symm_comp_self]
          simp
    right_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.self_comp_symm]
          

Proof state:
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
e : (i : ι) → β₁ i ≃+ β₂ i
src✝ : (Π₀ (i : ι), β₁ i) →+ Π₀ (i : ι), β₂ i := addMonoidHom fun i => AddEquiv.toAddMonoidHom (e i)
x : Π₀ (i : ι), β₂ i
⊢ mapRange (fun i => id) (_ : ∀ (i : ι), (fun i => id) i 0 = 0) x = x

Next tactic:
simp
/-- `DFinsupp.mapRange.addMonoidHom` as an `AddEquiv`. -/
@[simps apply]
def mapRange.addEquiv (e : ∀ i, β₁ i ≃+ β₂ i) : (Π₀ i, β₁ i) ≃+ Π₀ i, β₂ i :=
  { mapRange.addMonoidHom fun i =>
      (e i).toAddMonoidHom with
    toFun := mapRange (fun i x => e i x) fun i => (e i).map_zero
    invFun := mapRange (fun i x => (e i).symm x) fun i => (e i).symm.map_zero
    left_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.symm_comp_self]
          simp
    right_inv := fun x => by
      rw [← mapRange_comp] <;>
        · 

Proof state:
case h
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
e : (i : ι) → β₁ i ≃+ β₂ i
src✝ : (Π₀ (i : ι), β₁ i) →+ Π₀ (i : ι), β₂ i := addMonoidHom fun i => AddEquiv.toAddMonoidHom (e i)
x : Π₀ (i : ι), β₂ i
⊢ ∀ (i : ι), ((fun x => (e i) x) ∘ fun x => (AddEquiv.symm (e i)) x) 0 = 0

Next tactic:
simp_rw [AddEquiv.self_comp_symm]
/-- `DFinsupp.mapRange.addMonoidHom` as an `AddEquiv`. -/
@[simps apply]
def mapRange.addEquiv (e : ∀ i, β₁ i ≃+ β₂ i) : (Π₀ i, β₁ i) ≃+ Π₀ i, β₂ i :=
  { mapRange.addMonoidHom fun i =>
      (e i).toAddMonoidHom with
    toFun := mapRange (fun i x => e i x) fun i => (e i).map_zero
    invFun := mapRange (fun i x => (e i).symm x) fun i => (e i).symm.map_zero
    left_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.symm_comp_self]
          simp
    right_inv := fun x => by
      rw [← mapRange_comp] <;>
        · simp_rw [AddEquiv.self_comp_symm]
          

Proof state:
case h
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
e : (i : ι) → β₁ i ≃+ β₂ i
src✝ : (Π₀ (i : ι), β₁ i) →+ Π₀ (i : ι), β₂ i := addMonoidHom fun i => AddEquiv.toAddMonoidHom (e i)
x : Π₀ (i : ι), β₂ i
⊢ ∀ (i : ι), id 0 = 0

Next tactic:
simp
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  

Proof state:
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
⊢ (addEquiv fun i => AddEquiv.trans (f i) (f₂ i)) = AddEquiv.trans (addEquiv f) (addEquiv f₂)

Next tactic:
refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · 

Proof state:
case refine'_1
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
⊢ ∀ (i : ι), (fun i x => (f₂ i) x) i 0 = 0

Next tactic:
intros
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · intros; 

Proof state:
case refine'_1
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
i✝ : ι
⊢ (fun i x => (f₂ i) x) i✝ 0 = 0

Next tactic:
apply map_zero
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · intros; apply map_zero
  · 

Proof state:
case refine'_2
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
⊢ ∀ (i : ι), (fun i x => (f i) x) i 0 = 0

Next tactic:
intros
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · intros; apply map_zero
  · intros; 

Proof state:
case refine'_2
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
i✝ : ι
⊢ (fun i x => (f i) x) i✝ 0 = 0

Next tactic:
apply map_zero
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · intros; apply map_zero
  · intros; apply map_zero
  · 

Proof state:
case refine'_3
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
⊢ ∀ (i : ι), ((fun i x => (f₂ i) x) i ∘ (fun i x => (f i) x) i) 0 = 0

Next tactic:
intros
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · intros; apply map_zero
  · intros; apply map_zero
  · intros; 

Proof state:
case refine'_3
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
i✝ : ι
⊢ ((fun i x => (f₂ i) x) i✝ ∘ (fun i x => (f i) x) i✝) 0 = 0

Next tactic:
dsimp
theorem mapRange.addEquiv_trans (f : ∀ i, β i ≃+ β₁ i) (f₂ : ∀ i, β₁ i ≃+ β₂ i) :
    (mapRange.addEquiv fun i => (f i).trans (f₂ i)) =
      (mapRange.addEquiv f).trans (mapRange.addEquiv f₂) := by
  refine' AddEquiv.ext <| mapRange_comp (fun i x => f₂ i x) (fun i x => f i x) _ _ _
  · intros; apply map_zero
  · intros; apply map_zero
  · intros; dsimp; 

Proof state:
case refine'_3
ι : Type u
γ : Type w
β : ι → Type v
β₁ : ι → Type v₁
β₂ : ι → Type v₂
dec : DecidableEq ι
inst✝² : (i : ι) → AddZeroClass (β i)
inst✝¹ : (i : ι) → AddZeroClass (β₁ i)
inst✝ : (i : ι) → AddZeroClass (β₂ i)
f : (i : ι) → β i ≃+ β₁ i
f₂ : (i : ι) → β₁ i ≃+ β₂ i
i✝ : ι
⊢ (f₂ i✝) ((f i✝) 0) = 0

Next tactic:
simp only [map_zero]
instance DFinsupp.infinite_of_left {ι : Sort _} {π : ι → Sort _} [∀ i, Nontrivial (π i)]
    [∀ i, Zero (π i)] [Infinite ι] : Infinite (Π₀ i, π i) := by
  

Proof state:
ι✝ : Type u
γ : Type w
β : ι✝ → Type v
β₁ : ι✝ → Type v₁
β₂ : ι✝ → Type v₂
ι : Type ?u.1510734
π : ι → Type ?u.1510717
inst✝² : ∀ (i : ι), Nontrivial (π i)
inst✝¹ : (i : ι) → Zero (π i)
inst✝ : Infinite ι
⊢ Infinite (Π₀ (i : ι), π i)

Next tactic:
letI := Classical.decEq ι
instance DFinsupp.infinite_of_left {ι : Sort _} {π : ι → Sort _} [∀ i, Nontrivial (π i)]
    [∀ i, Zero (π i)] [Infinite ι] : Infinite (Π₀ i, π i) := by
  letI := Classical.decEq ι; 

Proof state:
ι✝ : Type u
γ : Type w
β : ι✝ → Type v
β₁ : ι✝ → Type v₁
β₂ : ι✝ → Type v₂
ι : Type ?u.1510734
π : ι → Type ?u.1510717
inst✝² : ∀ (i : ι), Nontrivial (π i)
inst✝¹ : (i : ι) → Zero (π i)
inst✝ : Infinite ι
this : DecidableEq ι := Classical.decEq ι
⊢ Infinite (Π₀ (i : ι), π i)

Next tactic:
choose m hm using fun i => exists_ne (0 : π i)
instance DFinsupp.infinite_of_left {ι : Sort _} {π : ι → Sort _} [∀ i, Nontrivial (π i)]
    [∀ i, Zero (π i)] [Infinite ι] : Infinite (Π₀ i, π i) := by
  letI := Classical.decEq ι; choose m hm using fun i => exists_ne (0 : π i);
    

Proof state:
ι✝ : Type u
γ : Type w
β : ι✝ → Type v
β₁ : ι✝ → Type v₁
β₂ : ι✝ → Type v₂
ι : Type ?u.1510734
π : ι → Type ?u.1510717
inst✝² : ∀ (i : ι), Nontrivial (π i)
inst✝¹ : (i : ι) → Zero (π i)
inst✝ : Infinite ι
this : DecidableEq ι := Classical.decEq ι
m : (i : ι) → π i
hm : ∀ (i : ι), m i ≠ 0
⊢ Infinite (Π₀ (i : ι), π i)

Next tactic:
exact Infinite.of_injective _ (DFinsupp.single_left_injective hm)
theorem exists_pair_lt (α : Type*) [Nontrivial α] [LinearOrder α] : ∃ x y : α, x < y := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
α : Type u_3
inst✝¹ : Nontrivial α
inst✝ : LinearOrder α
⊢ ∃ x y, x < y

Next tactic:
rcases exists_pair_ne α with ⟨x, y, hxy⟩
theorem exists_pair_lt (α : Type*) [Nontrivial α] [LinearOrder α] : ∃ x y : α, x < y := by
  rcases exists_pair_ne α with ⟨x, y, hxy⟩
  

Proof state:
case intro.intro
α✝ : Type u_1
β : Type u_2
α : Type u_3
inst✝¹ : Nontrivial α
inst✝ : LinearOrder α
x y : α
hxy : x ≠ y
⊢ ∃ x y, x < y

Next tactic:
cases lt_or_gt_of_ne hxy
theorem exists_pair_lt (α : Type*) [Nontrivial α] [LinearOrder α] : ∃ x y : α, x < y := by
  rcases exists_pair_ne α with ⟨x, y, hxy⟩
  cases lt_or_gt_of_ne hxy <;> 

Proof state:
case intro.intro.inl
α✝ : Type u_1
β : Type u_2
α : Type u_3
inst✝¹ : Nontrivial α
inst✝ : LinearOrder α
x y : α
hxy : x ≠ y
h✝ : x < y
⊢ ∃ x y, x < y

Next tactic:
exact ⟨_, _, ‹_›⟩
theorem exists_pair_lt (α : Type*) [Nontrivial α] [LinearOrder α] : ∃ x y : α, x < y := by
  rcases exists_pair_ne α with ⟨x, y, hxy⟩
  cases lt_or_gt_of_ne hxy <;> 

Proof state:
case intro.intro.inr
α✝ : Type u_1
β : Type u_2
α : Type u_3
inst✝¹ : Nontrivial α
inst✝ : LinearOrder α
x y : α
hxy : x ≠ y
h✝ : x > y
⊢ ∃ x y, x < y

Next tactic:
exact ⟨_, _, ‹_›⟩
theorem Subtype.nontrivial_iff_exists_ne (p : α → Prop) (x : Subtype p) :
    Nontrivial (Subtype p) ↔ ∃ (y : α) (_ : p y), y ≠ x := by
  

Proof state:
α : Type u_1
β : Type u_2
p : α → Prop
x : Subtype p
⊢ Nontrivial (Subtype p) ↔ ∃ y x_1, y ≠ ↑x

Next tactic:
simp only [_root_.nontrivial_iff_exists_ne x, Subtype.exists, Ne.def, Subtype.ext_iff]
/-- An inhabited type is either nontrivial, or has a unique element. -/
noncomputable def nontrivialPSumUnique (α : Type*) [Inhabited α] :
    PSum (Nontrivial α) (Unique α) :=
  if h : Nontrivial α then PSum.inl h
  else
    PSum.inr
      { default := default,
        uniq := fun x : α ↦ by
          

Proof state:
α✝ : Type u_1
β : Type u_2
α : Type u_3
inst✝ : Inhabited α
h : ¬Nontrivial α
x : α
⊢ x = default

Next tactic:
by_contra H
/-- An inhabited type is either nontrivial, or has a unique element. -/
noncomputable def nontrivialPSumUnique (α : Type*) [Inhabited α] :
    PSum (Nontrivial α) (Unique α) :=
  if h : Nontrivial α then PSum.inl h
  else
    PSum.inr
      { default := default,
        uniq := fun x : α ↦ by
          by_contra H
          

Proof state:
α✝ : Type u_1
β : Type u_2
α : Type u_3
inst✝ : Inhabited α
h : ¬Nontrivial α
x : α
H : ¬x = default
⊢ False

Next tactic:
exact h ⟨_, _, H⟩
instance Option.nontrivial [Nonempty α] : Nontrivial (Option α) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : Nonempty α
⊢ Nontrivial (Option α)

Next tactic:
inhabit α
instance Option.nontrivial [Nonempty α] : Nontrivial (Option α) := by
  inhabit α
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : Nonempty α
inhabited_h : Inhabited α
⊢ Nontrivial (Option α)

Next tactic:
exact ⟨none, some default, fun .⟩
/-- An injective function from a nontrivial type has an argument at
which it does not take a given value. -/
protected theorem Function.Injective.exists_ne [Nontrivial α] {f : α → β}
    (hf : Function.Injective f) (y : β) : ∃ x, f x ≠ y := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : Nontrivial α
f : α → β
hf : Injective f
y : β
⊢ ∃ x, f x ≠ y

Next tactic:
rcases exists_pair_ne α with ⟨x₁, x₂, hx⟩
/-- An injective function from a nontrivial type has an argument at
which it does not take a given value. -/
protected theorem Function.Injective.exists_ne [Nontrivial α] {f : α → β}
    (hf : Function.Injective f) (y : β) : ∃ x, f x ≠ y := by
  rcases exists_pair_ne α with ⟨x₁, x₂, hx⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
inst✝ : Nontrivial α
f : α → β
hf : Injective f
y : β
x₁ x₂ : α
hx : x₁ ≠ x₂
⊢ ∃ x, f x ≠ y

Next tactic:
by_cases h:f x₂ = y
/-- An injective function from a nontrivial type has an argument at
which it does not take a given value. -/
protected theorem Function.Injective.exists_ne [Nontrivial α] {f : α → β}
    (hf : Function.Injective f) (y : β) : ∃ x, f x ≠ y := by
  rcases exists_pair_ne α with ⟨x₁, x₂, hx⟩
  by_cases h:f x₂ = y
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : Nontrivial α
f : α → β
hf : Injective f
y : β
x₁ x₂ : α
hx : x₁ ≠ x₂
h : f x₂ = y
⊢ ∃ x, f x ≠ y

Next tactic:
exact ⟨x₁, (hf.ne_iff' h).2 hx⟩
/-- An injective function from a nontrivial type has an argument at
which it does not take a given value. -/
protected theorem Function.Injective.exists_ne [Nontrivial α] {f : α → β}
    (hf : Function.Injective f) (y : β) : ∃ x, f x ≠ y := by
  rcases exists_pair_ne α with ⟨x₁, x₂, hx⟩
  by_cases h:f x₂ = y
  · exact ⟨x₁, (hf.ne_iff' h).2 hx⟩
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝ : Nontrivial α
f : α → β
hf : Injective f
y : β
x₁ x₂ : α
hx : x₁ ≠ x₂
h : ¬f x₂ = y
⊢ ∃ x, f x ≠ y

Next tactic:
exact ⟨x₂, h⟩
/-- A pi type is nontrivial if it's nonempty everywhere and nontrivial somewhere. -/
theorem nontrivial_at (i' : I) [inst : ∀ i, Nonempty (f i)] [Nontrivial (f i')] :
    Nontrivial (∀ i : I, f i) := by
  

Proof state:
α : Type u_1
β : Type u_2
I : Type u_3
f : I → Type u_4
i' : I
inst : ∀ (i : I), Nonempty (f i)
inst✝ : Nontrivial (f i')
⊢ Nontrivial ((i : I) → f i)

Next tactic:
letI := Classical.decEq (∀ i : I, f i)
/-- A pi type is nontrivial if it's nonempty everywhere and nontrivial somewhere. -/
theorem nontrivial_at (i' : I) [inst : ∀ i, Nonempty (f i)] [Nontrivial (f i')] :
    Nontrivial (∀ i : I, f i) := by
  letI := Classical.decEq (∀ i : I, f i)
  

Proof state:
α : Type u_1
β : Type u_2
I : Type u_3
f : I → Type u_4
i' : I
inst : ∀ (i : I), Nonempty (f i)
inst✝ : Nontrivial (f i')
this : DecidableEq ((i : I) → f i) := Classical.decEq ((i : I) → f i)
⊢ Nontrivial ((i : I) → f i)

Next tactic:
exact (Function.update_injective (fun i ↦ Classical.choice (inst i)) i').nontrivial
theorem prod_iInter {s : Set α} {t : ι → Set β} [hι : Nonempty ι] :
    (s ×ˢ ⋂ i, t i) = ⋂ i, s ×ˢ t i := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
s : Set α
t : ι → Set β
hι : Nonempty ι
⊢ s ×ˢ ⋂ i, t i = ⋂ i, s ×ˢ t i

Next tactic:
ext x
theorem prod_iInter {s : Set α} {t : ι → Set β} [hι : Nonempty ι] :
    (s ×ˢ ⋂ i, t i) = ⋂ i, s ×ˢ t i := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Type u_3
s : Set α
t : ι → Set β
hι : Nonempty ι
x : α × β
⊢ x ∈ s ×ˢ ⋂ i, t i ↔ x ∈ ⋂ i, s ×ˢ t i

Next tactic:
simp only [mem_prod, mem_iInter]
theorem prod_iInter {s : Set α} {t : ι → Set β} [hι : Nonempty ι] :
    (s ×ˢ ⋂ i, t i) = ⋂ i, s ×ˢ t i := by
  ext x
  simp only [mem_prod, mem_iInter]
  

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Type u_3
s : Set α
t : ι → Set β
hι : Nonempty ι
x : α × β
⊢ (x.1 ∈ s ∧ ∀ (i : ι), x.2 ∈ t i) ↔ ∀ (i : ι), x.1 ∈ s ∧ x.2 ∈ t i

Next tactic:
exact ⟨fun h i => ⟨h.1, h.2 i⟩, fun h => ⟨(h hι.some).1, fun i => (h i).2⟩⟩
theorem Real.iUnion_Iic_rat : ⋃ r : ℚ, Iic (r : ℝ) = univ := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
⊢ ⋃ r, Iic ↑r = univ

Next tactic:
ext1 x
theorem Real.iUnion_Iic_rat : ⋃ r : ℚ, Iic (r : ℝ) = univ := by
  ext1 x
  

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Type u_3
x : ℝ
⊢ x ∈ ⋃ r, Iic ↑r ↔ x ∈ univ

Next tactic:
simp only [mem_iUnion, mem_Iic, mem_univ, iff_true_iff]
theorem Real.iUnion_Iic_rat : ⋃ r : ℚ, Iic (r : ℝ) = univ := by
  ext1 x
  simp only [mem_iUnion, mem_Iic, mem_univ, iff_true_iff]
  

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Type u_3
x : ℝ
⊢ ∃ i, x ≤ ↑i

Next tactic:
obtain ⟨r, hr⟩ := exists_rat_gt x
theorem Real.iUnion_Iic_rat : ⋃ r : ℚ, Iic (r : ℝ) = univ := by
  ext1 x
  simp only [mem_iUnion, mem_Iic, mem_univ, iff_true_iff]
  obtain ⟨r, hr⟩ := exists_rat_gt x
  

Proof state:
case h.intro
α : Type u_1
β : Type u_2
ι : Type u_3
x : ℝ
r : ℚ
hr : x < ↑r
⊢ ∃ i, x ≤ ↑i

Next tactic:
exact ⟨r, hr.le⟩
theorem Real.iInter_Iic_rat : ⋂ r : ℚ, Iic (r : ℝ) = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
⊢ ⋂ r, Iic ↑r = ∅

Next tactic:
ext1 x
theorem Real.iInter_Iic_rat : ⋂ r : ℚ, Iic (r : ℝ) = ∅ := by
  ext1 x
  

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Type u_3
x : ℝ
⊢ x ∈ ⋂ r, Iic ↑r ↔ x ∈ ∅

Next tactic:
simp only [mem_iInter, mem_Iic, mem_empty_iff_false, iff_false_iff, not_forall, not_le]
theorem Real.iInter_Iic_rat : ⋂ r : ℚ, Iic (r : ℝ) = ∅ := by
  ext1 x
  simp only [mem_iInter, mem_Iic, mem_empty_iff_false, iff_false_iff, not_forall, not_le]
  

Proof state:
case h
α : Type u_1
β : Type u_2
ι : Type u_3
x : ℝ
⊢ ∃ x_1, ↑x_1 < x

Next tactic:
exact exists_rat_lt x
theorem atBot_le_nhds_bot {α : Type*} [TopologicalSpace α] [LinearOrder α] [OrderBot α]
    [OrderTopology α] : (atBot : Filter α) ≤ 𝓝 ⊥ := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
ι : Type u_3
α : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : LinearOrder α
inst✝¹ : OrderBot α
inst✝ : OrderTopology α
⊢ atBot ≤ 𝓝 ⊥

Next tactic:
cases subsingleton_or_nontrivial α
theorem atBot_le_nhds_bot {α : Type*} [TopologicalSpace α] [LinearOrder α] [OrderBot α]
    [OrderTopology α] : (atBot : Filter α) ≤ 𝓝 ⊥ := by
  cases subsingleton_or_nontrivial α
  · 

Proof state:
case inl
α✝ : Type u_1
β : Type u_2
ι : Type u_3
α : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : LinearOrder α
inst✝¹ : OrderBot α
inst✝ : OrderTopology α
h✝ : Subsingleton α
⊢ atBot ≤ 𝓝 ⊥

Next tactic:
simp only [nhds_discrete, le_pure_iff, mem_atBot_sets, mem_singleton_iff,
      eq_iff_true_of_subsingleton, imp_true_iff, exists_const]
theorem atBot_le_nhds_bot {α : Type*} [TopologicalSpace α] [LinearOrder α] [OrderBot α]
    [OrderTopology α] : (atBot : Filter α) ≤ 𝓝 ⊥ := by
  cases subsingleton_or_nontrivial α
  · simp only [nhds_discrete, le_pure_iff, mem_atBot_sets, mem_singleton_iff,
      eq_iff_true_of_subsingleton, imp_true_iff, exists_const]
  

Proof state:
case inr
α✝ : Type u_1
β : Type u_2
ι : Type u_3
α : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : LinearOrder α
inst✝¹ : OrderBot α
inst✝ : OrderTopology α
h✝ : Nontrivial α
⊢ atBot ≤ 𝓝 ⊥

Next tactic:
have h : atBot.HasBasis (fun _ : α => True) Iic := @atBot_basis α _ _
theorem atBot_le_nhds_bot {α : Type*} [TopologicalSpace α] [LinearOrder α] [OrderBot α]
    [OrderTopology α] : (atBot : Filter α) ≤ 𝓝 ⊥ := by
  cases subsingleton_or_nontrivial α
  · simp only [nhds_discrete, le_pure_iff, mem_atBot_sets, mem_singleton_iff,
      eq_iff_true_of_subsingleton, imp_true_iff, exists_const]
  have h : atBot.HasBasis (fun _ : α => True) Iic := @atBot_basis α _ _
  

Proof state:
case inr
α✝ : Type u_1
β : Type u_2
ι : Type u_3
α : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : LinearOrder α
inst✝¹ : OrderBot α
inst✝ : OrderTopology α
h✝ : Nontrivial α
h : HasBasis atBot (fun x => True) Iic
⊢ atBot ≤ 𝓝 ⊥

Next tactic:
have h_nhds : (𝓝 ⊥).HasBasis (fun a : α => ⊥ < a) fun a => Iio a := @nhds_bot_basis α _ _ _ _ _
theorem atBot_le_nhds_bot {α : Type*} [TopologicalSpace α] [LinearOrder α] [OrderBot α]
    [OrderTopology α] : (atBot : Filter α) ≤ 𝓝 ⊥ := by
  cases subsingleton_or_nontrivial α
  · simp only [nhds_discrete, le_pure_iff, mem_atBot_sets, mem_singleton_iff,
      eq_iff_true_of_subsingleton, imp_true_iff, exists_const]
  have h : atBot.HasBasis (fun _ : α => True) Iic := @atBot_basis α _ _
  have h_nhds : (𝓝 ⊥).HasBasis (fun a : α => ⊥ < a) fun a => Iio a := @nhds_bot_basis α _ _ _ _ _
  

Proof state:
case inr
α✝ : Type u_1
β : Type u_2
ι : Type u_3
α : Type u_4
inst✝³ : TopologicalSpace α
inst✝² : LinearOrder α
inst✝¹ : OrderBot α
inst✝ : OrderTopology α
h✝ : Nontrivial α
h : HasBasis atBot (fun x => True) Iic
h_nhds : HasBasis (𝓝 ⊥) (fun a => ⊥ < a) fun a => Iio a
⊢ atBot ≤ 𝓝 ⊥

Next tactic:
intro s