l3lab/ntp-mathlib huggingface dataset:
theorem fromUnit_ker [hn : Fact <| 0 < n] :
    (@fromUnit R _ _ _ K _ _ _ n).ker = (powMonoidHom n : Rˣ →* Rˣ).range := by
  ext ⟨_, _, _, _⟩
  constructor
  · intro hx
    rcases (QuotientGroup.eq_one_iff _).mp (Subtype.mk.inj hx) with ⟨⟨v, i, vi, iv⟩, hx⟩
    have hv : ↑(_ ^ n : Kˣ) = algebraMap R K _ := by exact congr_arg Units.val hx
    have hi : ↑(_ ^ n : Kˣ)⁻¹ = algebraMap R K _ := by exact congr_arg Units.inv hx
    rw [Units.val_pow_eq_pow_val] at hv
    rw [← inv_pow, Units.inv_mk, Units.val_pow_eq_pow_val] at hi
    rcases IsIntegrallyClosed.exists_algebraMap_eq_of_isIntegral_pow (R := R) (x := v) hn.out
        (hv.symm ▸ isIntegral_algebraMap) with
      ⟨v', rfl⟩
    rcases IsIntegrallyClosed.exists_algebraMap_eq_of_isIntegral_pow (R := R) (x := i) hn.out
        (hi.symm ▸ isIntegral_algebraMap) with
      ⟨i', rfl⟩
    rw [← map_mul, map_eq_one_iff _ <| NoZeroSMulDivisors.algebraMap_injective R K] at vi
    rw [← map_mul, map_eq_one_iff _ <| NoZeroSMulDivisors.algebraMap_injective R K] at iv
    rw [Units.val_mk, ← map_pow] at hv
    exact ⟨⟨v', i', vi, iv⟩, by
      simpa only [Units.ext_iff, powMonoidHom_apply, Units.val_pow_eq_pow_val] using
         NoZeroSMulDivisors.algebraMap_injective R K hv⟩
  · rintro ⟨x, hx⟩
    rw [← hx]
    exact Subtype.mk_eq_mk.mpr <| (QuotientGroup.eq_one_iff _).mpr ⟨Units.map (algebraMap R K) x,
      by 

Proof state:
R : Type u
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type v
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
S S' : Set (HeightOneSpectrum R)
n : ℕ
hn : Fact (0 < n)
val✝ inv✝ : R
val_inv✝ : val✝ * inv✝ = 1
inv_val✝ : inv✝ * val✝ = 1
x : Rˣ
hx : (powMonoidHom n) x = { val := val✝, inv := inv✝, val_inv := val_inv✝, inv_val := inv_val✝ }
⊢ (powMonoidHom n) ((Units.map ↑(algebraMap R K)) x) = (Units.map ↑(algebraMap R K)) ((powMonoidHom n) x)

Next tactic:
simp only [powMonoidHom_apply, RingHom.toMonoidHom_eq_coe, map_pow]
theorem fromUnitLift_injective [Fact <| 0 < n] :
    Function.Injective <| @fromUnitLift R _ _ _ K _ _ _ n _ := by
  

Proof state:
R : Type u
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsDedekindDomain R
K : Type v
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : IsFractionRing R K
v : HeightOneSpectrum R
S S' : Set (HeightOneSpectrum R)
n : ℕ
inst✝ : Fact (0 < n)
⊢ Function.Injective ⇑fromUnitLift

Next tactic:
dsimp only [fromUnitLift, MonoidHom.coe_comp, MulEquiv.coe_toMonoidHom]
theorem fromUnitLift_injective [Fact <| 0 < n] :
    Function.Injective <| @fromUnitLift R _ _ _ K _ _ _ n _ := by
  dsimp only [fromUnitLift, MonoidHom.coe_comp, MulEquiv.coe_toMonoidHom]
  

Proof state:
R : Type u
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsDedekindDomain R
K : Type v
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : IsFractionRing R K
v : HeightOneSpectrum R
S S' : Set (HeightOneSpectrum R)
n : ℕ
inst✝ : Fact (0 < n)
⊢ Function.Injective
    (⇑(QuotientGroup.kerLift fromUnit) ∘
      ⇑(MulEquiv.symm
          (QuotientGroup.quotientMulEquivOfEq (_ : MonoidHom.ker fromUnit = MonoidHom.range (powMonoidHom n)))))

Next tactic:
exact Function.Injective.comp (QuotientGroup.kerLift_injective _) (MulEquiv.injective _)
@[to_additive]
instance : SetLike (Subsemigroup M) M :=
  ⟨Subsemigroup.carrier, fun p q h => by 

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
p q : Subsemigroup M
h : p.carrier = q.carrier
⊢ p = q

Next tactic:
cases p
@[to_additive]
instance : SetLike (Subsemigroup M) M :=
  ⟨Subsemigroup.carrier, fun p q h => by cases p; 

Proof state:
case mk
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
q : Subsemigroup M
carrier✝ : Set M
mul_mem'✝ : ∀ {a b : M}, a ∈ carrier✝ → b ∈ carrier✝ → a * b ∈ carrier✝
h : { carrier := carrier✝, mul_mem' := mul_mem'✝ }.carrier = q.carrier
⊢ { carrier := carrier✝, mul_mem' := mul_mem'✝ } = q

Next tactic:
cases q
@[to_additive]
instance : SetLike (Subsemigroup M) M :=
  ⟨Subsemigroup.carrier, fun p q h => by cases p; cases q; 

Proof state:
case mk.mk
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
carrier✝¹ : Set M
mul_mem'✝¹ : ∀ {a b : M}, a ∈ carrier✝¹ → b ∈ carrier✝¹ → a * b ∈ carrier✝¹
carrier✝ : Set M
mul_mem'✝ : ∀ {a b : M}, a ∈ carrier✝ → b ∈ carrier✝ → a * b ∈ carrier✝
h : { carrier := carrier✝¹, mul_mem' := mul_mem'✝¹ }.carrier = { carrier := carrier✝, mul_mem' := mul_mem'✝ }.carrier
⊢ { carrier := carrier✝¹, mul_mem' := mul_mem'✝¹ } = { carrier := carrier✝, mul_mem' := mul_mem'✝ }

Next tactic:
congr
@[to_additive]
instance : InfSet (Subsemigroup M) :=
  ⟨fun s =>
    { carrier := ⋂ t ∈ s, ↑t
      mul_mem' := fun hx hy =>
        Set.mem_biInter fun i h =>
          i.mul_mem (by 

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s✝ : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
s : Set (Subsemigroup M)
a✝ b✝ : M
hx : a✝ ∈ ⋂ t ∈ s, ↑t
hy : b✝ ∈ ⋂ t ∈ s, ↑t
i : Subsemigroup M
h : i ∈ s
⊢ a✝ ∈ i

Next tactic:
apply Set.mem_iInter₂.1 hx i h
@[to_additive]
instance : InfSet (Subsemigroup M) :=
  ⟨fun s =>
    { carrier := ⋂ t ∈ s, ↑t
      mul_mem' := fun hx hy =>
        Set.mem_biInter fun i h =>
          i.mul_mem (by apply Set.mem_iInter₂.1 hx i h) (by 

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s✝ : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
s : Set (Subsemigroup M)
a✝ b✝ : M
hx : a✝ ∈ ⋂ t ∈ s, ↑t
hy : b✝ ∈ ⋂ t ∈ s, ↑t
i : Subsemigroup M
h : i ∈ s
⊢ b✝ ∈ i

Next tactic:
apply Set.mem_iInter₂.1 hy i h
@[to_additive]
theorem mem_iInf {ι : Sort*} {S : ι → Subsemigroup M} {x : M} : (x ∈ ⨅ i, S i) ↔ ∀ i, x ∈ S i := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S✝ : Subsemigroup M
ι : Sort u_4
S : ι → Subsemigroup M
x : M
⊢ x ∈ ⨅ i, S i ↔ ∀ (i : ι), x ∈ S i

Next tactic:
simp only [iInf, mem_sInf, Set.forall_range_iff]
@[to_additive (attr := simp, norm_cast)]
theorem coe_iInf {ι : Sort*} {S : ι → Subsemigroup M} : (↑(⨅ i, S i) : Set M) = ⋂ i, S i := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S✝ : Subsemigroup M
ι : Sort u_4
S : ι → Subsemigroup M
⊢ ↑(⨅ i, S i) = ⋂ i, ↑(S i)

Next tactic:
simp only [iInf, coe_sInf, Set.biInter_range]
@[to_additive (attr := simp)]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝² : Mul M
s : Set M
inst✝¹ : Add A
t : Set A
S : Subsemigroup M
inst✝ : Subsingleton (Subsemigroup M)
⊢ Subsingleton M

Next tactic:
constructor
@[to_additive (attr := simp)]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by
  constructor; 

Proof state:
case allEq
M : Type u_1
N : Type u_2
A : Type u_3
inst✝² : Mul M
s : Set M
inst✝¹ : Add A
t : Set A
S : Subsemigroup M
inst✝ : Subsingleton (Subsemigroup M)
⊢ ∀ (a b : M), a = b

Next tactic:
intro x y
@[to_additive (attr := simp)]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by
  constructor; intro x y
  

Proof state:
case allEq
M : Type u_1
N : Type u_2
A : Type u_3
inst✝² : Mul M
s : Set M
inst✝¹ : Add A
t : Set A
S : Subsemigroup M
inst✝ : Subsingleton (Subsemigroup M)
x y : M
⊢ x = y

Next tactic:
have : ∀ a : M, a ∈ (⊥ : Subsemigroup M) := by simp [Subsingleton.elim (⊥ : Subsemigroup M) ⊤]
@[to_additive (attr := simp)]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by
  constructor; intro x y
  have : ∀ a : M, a ∈ (⊥ : Subsemigroup M) := by 

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝² : Mul M
s : Set M
inst✝¹ : Add A
t : Set A
S : Subsemigroup M
inst✝ : Subsingleton (Subsemigroup M)
x y : M
⊢ ∀ (a : M), a ∈ ⊥

Next tactic:
simp [Subsingleton.elim (⊥ : Subsemigroup M) ⊤]
@[to_additive (attr := simp)]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by
  constructor; intro x y
  have : ∀ a : M, a ∈ (⊥ : Subsemigroup M) := by simp [Subsingleton.elim (⊥ : Subsemigroup M) ⊤]
  

Proof state:
case allEq
M : Type u_1
N : Type u_2
A : Type u_3
inst✝² : Mul M
s : Set M
inst✝¹ : Add A
t : Set A
S : Subsemigroup M
inst✝ : Subsingleton (Subsemigroup M)
x y : M
this : ∀ (a : M), a ∈ ⊥
⊢ x = y

Next tactic:
exact absurd (this x) not_mem_bot
@[to_additive]
instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) :=
  ⟨⟨⊥, ⊤, fun h => by
      

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
hn : Nonempty M
h : ⊥ = ⊤
⊢ False

Next tactic:
obtain ⟨x⟩ := id hn
@[to_additive]
instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) :=
  ⟨⟨⊥, ⊤, fun h => by
      obtain ⟨x⟩ := id hn
      

Proof state:
case intro
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
hn : Nonempty M
h : ⊥ = ⊤
x : M
⊢ False

Next tactic:
refine' absurd (_ : x ∈ ⊥) not_mem_bot
@[to_additive]
instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) :=
  ⟨⟨⊥, ⊤, fun h => by
      obtain ⟨x⟩ := id hn
      refine' absurd (_ : x ∈ ⊥) not_mem_bot
      

Proof state:
case intro
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
hn : Nonempty M
h : ⊥ = ⊤
x : M
⊢ x ∈ ⊥

Next tactic:
simp [h]
/-- A dependent version of `Subsemigroup.closure_induction`.  -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubsemigroup.closure_induction`. "]
theorem closure_induction' (s : Set M) {p : ∀ x, x ∈ closure s → Prop}
    (Hs : ∀ (x) (h : x ∈ s), p x (subset_closure h))
    (Hmul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x} (hx : x ∈ closure s) :
    p x hx := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s✝ : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
s : Set M
p : (x : M) → x ∈ closure s → Prop
Hs : ∀ (x : M) (h : x ∈ s), p x (_ : x ∈ ↑(closure s))
Hmul : ∀ (x : M) (hx : x ∈ closure s) (y : M) (hy : y ∈ closure s), p x hx → p y hy → p (x * y) (_ : x * y ∈ closure s)
x : M
hx : x ∈ closure s
⊢ p x hx

Next tactic:
refine' Exists.elim _ fun (hx : x ∈ closure s) (hc : p x hx) => hc
/-- A dependent version of `Subsemigroup.closure_induction`.  -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubsemigroup.closure_induction`. "]
theorem closure_induction' (s : Set M) {p : ∀ x, x ∈ closure s → Prop}
    (Hs : ∀ (x) (h : x ∈ s), p x (subset_closure h))
    (Hmul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x} (hx : x ∈ closure s) :
    p x hx := by
  refine' Exists.elim _ fun (hx : x ∈ closure s) (hc : p x hx) => hc
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s✝ : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
s : Set M
p : (x : M) → x ∈ closure s → Prop
Hs : ∀ (x : M) (h : x ∈ s), p x (_ : x ∈ ↑(closure s))
Hmul : ∀ (x : M) (hx : x ∈ closure s) (y : M) (hy : y ∈ closure s), p x hx → p y hy → p (x * y) (_ : x * y ∈ closure s)
x : M
hx : x ∈ closure s
⊢ ∃ (x_1 : x ∈ closure s), p x x_1

Next tactic:
exact
    closure_induction hx (fun x hx => ⟨_, Hs x hx⟩) fun x y ⟨hx', hx⟩ ⟨hy', hy⟩ =>
      ⟨_, Hmul _ _ _ _ hx hy⟩
/-- If `s` is a dense set in a magma `M`, `Subsemigroup.closure s = ⊤`, then in order to prove that
some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`,
and verify that `p x` and `p y` imply `p (x * y)`. -/
@[to_additive (attr := elab_as_elim) "If `s` is a dense set in an additive monoid `M`,
  `AddSubsemigroup.closure s = ⊤`, then in order to prove that some predicate `p` holds
  for all `x : M` it suffices to verify `p x` for `x ∈ s`, and verify that `p x` and `p y` imply
  `p (x + y)`."]
theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure s = ⊤) (Hs : ∀ x ∈ s, p x)
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p x := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s✝ : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
p : M → Prop
x : M
s : Set M
hs : closure s = ⊤
Hs : ∀ x ∈ s, p x
Hmul : ∀ (x y : M), p x → p y → p (x * y)
⊢ p x

Next tactic:
have : ∀ x ∈ closure s, p x := fun x hx => closure_induction hx Hs Hmul
/-- If `s` is a dense set in a magma `M`, `Subsemigroup.closure s = ⊤`, then in order to prove that
some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`,
and verify that `p x` and `p y` imply `p (x * y)`. -/
@[to_additive (attr := elab_as_elim) "If `s` is a dense set in an additive monoid `M`,
  `AddSubsemigroup.closure s = ⊤`, then in order to prove that some predicate `p` holds
  for all `x : M` it suffices to verify `p x` for `x ∈ s`, and verify that `p x` and `p y` imply
  `p (x + y)`."]
theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure s = ⊤) (Hs : ∀ x ∈ s, p x)
    (Hmul : ∀ x y, p x → p y → p (x * y)) : p x := by
  have : ∀ x ∈ closure s, p x := fun x hx => closure_induction hx Hs Hmul
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s✝ : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
p : M → Prop
x : M
s : Set M
hs : closure s = ⊤
Hs : ∀ x ∈ s, p x
Hmul : ∀ (x y : M), p x → p y → p (x * y)
this : ∀ x ∈ closure s, p x
⊢ p x

Next tactic:
simpa [hs] using this x
@[to_additive]
theorem closure_singleton_le_iff_mem (m : M) (p : Subsemigroup M) : closure {m} ≤ p ↔ m ∈ p := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
m : M
p : Subsemigroup M
⊢ closure {m} ≤ p ↔ m ∈ p

Next tactic:
rw [closure_le, singleton_subset_iff, SetLike.mem_coe]
@[to_additive]
theorem mem_iSup {ι : Sort*} (p : ι → Subsemigroup M) {m : M} :
    (m ∈ ⨆ i, p i) ↔ ∀ N, (∀ i, p i ≤ N) → m ∈ N := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
ι : Sort u_4
p : ι → Subsemigroup M
m : M
⊢ m ∈ ⨆ i, p i ↔ ∀ (N : Subsemigroup M), (∀ (i : ι), p i ≤ N) → m ∈ N

Next tactic:
rw [← closure_singleton_le_iff_mem, le_iSup_iff]
@[to_additive]
theorem mem_iSup {ι : Sort*} (p : ι → Subsemigroup M) {m : M} :
    (m ∈ ⨆ i, p i) ↔ ∀ N, (∀ i, p i ≤ N) → m ∈ N := by
  rw [← closure_singleton_le_iff_mem, le_iSup_iff]
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
ι : Sort u_4
p : ι → Subsemigroup M
m : M
⊢ (∀ (b : Subsemigroup M), (∀ (i : ι), p i ≤ b) → closure {m} ≤ b) ↔
    ∀ (N : Subsemigroup M), (∀ (i : ι), p i ≤ N) → m ∈ N

Next tactic:
simp only [closure_singleton_le_iff_mem]
@[to_additive]
theorem iSup_eq_closure {ι : Sort*} (p : ι → Subsemigroup M) :
    ⨆ i, p i = Subsemigroup.closure (⋃ i, (p i : Set M)) := by
  

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝¹ : Mul M
s : Set M
inst✝ : Add A
t : Set A
S : Subsemigroup M
ι : Sort u_4
p : ι → Subsemigroup M
⊢ ⨆ i, p i = closure (⋃ i, ↑(p i))

Next tactic:
simp_rw [Subsemigroup.closure_iUnion, Subsemigroup.closure_eq]
/-- The subsemigroup of elements `x : M` such that `f x = g x` -/
@[to_additive "The additive subsemigroup of elements `x : M` such that `f x = g x`"]
def eqLocus (f g : M →ₙ* N) : Subsemigroup M where
  carrier := { x | f x = g x }
  mul_mem' (hx : _ = _) (hy : _ = _) := by 

Proof state:
M : Type u_1
N : Type u_2
A : Type u_3
inst✝² : Mul M
s : Set M
inst✝¹ : Add A
t : Set A
inst✝ : Mul N
f g : M →ₙ* N
a✝ b✝ : M
hx : f a✝ = g a✝
hy : f b✝ = g b✝
⊢ a✝ * b✝ ∈ {x | f x = g x}

Next tactic:
simp [*]
/-- Let `s` be a subset of a semigroup `M` such that the closure of `s` is the whole semigroup.
Then `MulHom.ofDense` defines a mul homomorphism from `M` asking for a proof
of `f (x * y) = f x * f y` only for `y ∈ s`. -/
@[to_additive]
def ofDense {M N} [Semigroup M] [Semigroup N] {s : Set M} (f : M → N) (hs : closure s = ⊤)
    (hmul : ∀ (x), ∀ y ∈ s, f (x * y) = f x * f y) :
    M →ₙ* N where
  toFun := f
  map_mul' x y :=
    dense_induction y hs (fun y hy x => hmul x y hy)
      (fun y₁ y₂ h₁ h₂ x => by 

Proof state:
M✝ : Type u_1
N✝ : Type u_2
A : Type u_3
M : Type ?u.25657
N : Type ?u.25660
inst✝¹ : Semigroup M
inst✝ : Semigroup N
s : Set M
f : M → N
hs : closure s = ⊤
hmul : ∀ (x y : M), y ∈ s → f (x * y) = f x * f y
x✝ y y₁ y₂ : M
h₁ : ∀ (x : M), f (x * y₁) = f x * f y₁
h₂ : ∀ (x : M), f (x * y₂) = f x * f y₂
x : M
⊢ f (x * (y₁ * y₂)) = f x * f (y₁ * y₂)

Next tactic:
simp only [← mul_assoc, h₁, h₂]
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
⊢ f =ᵐ[μ] 0

Next tactic:
let s := denseSeq E
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  let s := denseSeq E
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
s : ℕ → E := denseSeq E
⊢ f =ᵐ[μ] 0

Next tactic:
have hs : DenseRange s := denseRange_denseSeq E
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  let s := denseSeq E
  have hs : DenseRange s := denseRange_denseSeq E
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
s : ℕ → E := denseSeq E
hs : DenseRange s
⊢ f =ᵐ[μ] 0

Next tactic:
have hf' : ∀ᵐ x ∂μ, ∀ n : ℕ, inner (s n) (f x) = (0 : 𝕜) := ae_all_iff.mpr fun n => hf (s n)
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  let s := denseSeq E
  have hs : DenseRange s := denseRange_denseSeq E
  have hf' : ∀ᵐ x ∂μ, ∀ n : ℕ, inner (s n) (f x) = (0 : 𝕜) := ae_all_iff.mpr fun n => hf (s n)
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
s : ℕ → E := denseSeq E
hs : DenseRange s
hf' : ∀ᵐ (x : α) ∂μ, ∀ (n : ℕ), inner (s n) (f x) = 0
⊢ f =ᵐ[μ] 0

Next tactic:
refine' hf'.mono fun x hx => _
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  let s := denseSeq E
  have hs : DenseRange s := denseRange_denseSeq E
  have hf' : ∀ᵐ x ∂μ, ∀ n : ℕ, inner (s n) (f x) = (0 : 𝕜) := ae_all_iff.mpr fun n => hf (s n)
  refine' hf'.mono fun x hx => _
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
s : ℕ → E := denseSeq E
hs : DenseRange s
hf' : ∀ᵐ (x : α) ∂μ, ∀ (n : ℕ), inner (s n) (f x) = 0
x : α
hx : ∀ (n : ℕ), inner (s n) (f x) = 0
⊢ f x = OfNat.ofNat 0 x

Next tactic:
rw [Pi.zero_apply, ← @inner_self_eq_zero 𝕜]
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  let s := denseSeq E
  have hs : DenseRange s := denseRange_denseSeq E
  have hf' : ∀ᵐ x ∂μ, ∀ n : ℕ, inner (s n) (f x) = (0 : 𝕜) := ae_all_iff.mpr fun n => hf (s n)
  refine' hf'.mono fun x hx => _
  rw [Pi.zero_apply, ← @inner_self_eq_zero 𝕜]
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
s : ℕ → E := denseSeq E
hs : DenseRange s
hf' : ∀ᵐ (x : α) ∂μ, ∀ (n : ℕ), inner (s n) (f x) = 0
x : α
hx : ∀ (n : ℕ), inner (s n) (f x) = 0
⊢ inner (f x) (f x) = 0

Next tactic:
have h_closed : IsClosed {c : E | inner c (f x) = (0 : 𝕜)} :=
    isClosed_eq (continuous_id.inner continuous_const) continuous_const
theorem ae_eq_zero_of_forall_inner [NormedAddCommGroup E] [InnerProductSpace 𝕜 E]
    [SecondCountableTopology E] {f : α → E} (hf : ∀ c : E, (fun x => (inner c (f x) : 𝕜)) =ᵐ[μ] 0) :
    f =ᵐ[μ] 0 := by
  let s := denseSeq E
  have hs : DenseRange s := denseRange_denseSeq E
  have hf' : ∀ᵐ x ∂μ, ∀ n : ℕ, inner (s n) (f x) = (0 : 𝕜) := ae_all_iff.mpr fun n => hf (s n)
  refine' hf'.mono fun x hx => _
  rw [Pi.zero_apply, ← @inner_self_eq_zero 𝕜]
  have h_closed : IsClosed {c : E | inner c (f x) = (0 : 𝕜)} :=
    isClosed_eq (continuous_id.inner continuous_const) continuous_const
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : SecondCountableTopology E
f : α → E
hf : ∀ (c : E), (fun x => inner c (f x)) =ᵐ[μ] 0
s : ℕ → E := denseSeq E
hs : DenseRange s
hf' : ∀ᵐ (x : α) ∂μ, ∀ (n : ℕ), inner (s n) (f x) = 0
x : α
hx : ∀ (n : ℕ), inner (s n) (f x) = 0
h_closed : IsClosed {c | inner c (f x) = 0}
⊢ inner (f x) (f x) = 0

Next tactic:
exact @isClosed_property ℕ E _ s (fun c => inner c (f x) = (0 : 𝕜)) hs h_closed (fun n => hx n) _
theorem ae_eq_zero_of_forall_dual_of_isSeparable [NormedAddCommGroup E] [NormedSpace 𝕜 E]
    {t : Set E} (ht : TopologicalSpace.IsSeparable t) {f : α → E}
    (hf : ∀ c : Dual 𝕜 E, (fun x => ⟪f x, c⟫) =ᵐ[μ] 0) (h't : ∀ᵐ x ∂μ, f x ∈ t) : f =ᵐ[μ] 0 := by
  

Proof state:
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
t : Set E
ht : IsSeparable t
f : α → E
hf : ∀ (c : Dual 𝕜 E), (fun x => c (f x)) =ᵐ[μ] 0
h't : ∀ᵐ (x : α) ∂μ, f x ∈ t
⊢ f =ᵐ[μ] 0

Next tactic:
rcases ht with ⟨d, d_count, hd⟩
theorem ae_eq_zero_of_forall_dual_of_isSeparable [NormedAddCommGroup E] [NormedSpace 𝕜 E]
    {t : Set E} (ht : TopologicalSpace.IsSeparable t) {f : α → E}
    (hf : ∀ c : Dual 𝕜 E, (fun x => ⟪f x, c⟫) =ᵐ[μ] 0) (h't : ∀ᵐ x ∂μ, f x ∈ t) : f =ᵐ[μ] 0 := by
  rcases ht with ⟨d, d_count, hd⟩
  

Proof state:
case intro.intro
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
t : Set E
f : α → E
hf : ∀ (c : Dual 𝕜 E), (fun x => c (f x)) =ᵐ[μ] 0
h't : ∀ᵐ (x : α) ∂μ, f x ∈ t
d : Set E
d_count : Set.Countable d
hd : t ⊆ closure d
⊢ f =ᵐ[μ] 0

Next tactic:
haveI : Encodable d := d_count.toEncodable
theorem ae_eq_zero_of_forall_dual_of_isSeparable [NormedAddCommGroup E] [NormedSpace 𝕜 E]
    {t : Set E} (ht : TopologicalSpace.IsSeparable t) {f : α → E}
    (hf : ∀ c : Dual 𝕜 E, (fun x => ⟪f x, c⟫) =ᵐ[μ] 0) (h't : ∀ᵐ x ∂μ, f x ∈ t) : f =ᵐ[μ] 0 := by
  rcases ht with ⟨d, d_count, hd⟩
  haveI : Encodable d := d_count.toEncodable
  

Proof state:
case intro.intro
α : Type u_1
E : Type u_2
𝕜 : Type u_3
m : MeasurableSpace α
μ : Measure α
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
t : Set E
f : α → E
hf : ∀ (c : Dual 𝕜 E), (fun x => c (f x)) =ᵐ[μ] 0
h't : ∀ᵐ (x : α) ∂μ, f x ∈ t
d : Set E
d_count : Set.Countable d
hd : t ⊆ closure d
this : Encodable ↑d
⊢ f =ᵐ[μ] 0

Next tactic:
have : ∀ x : d, ∃ g : E →L[𝕜] 𝕜, ‖g‖ ≤ 1 ∧ g x = ‖(x : E)‖ :=
    fun x => exists_dual_vector'' 𝕜 (x : E)