l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem MulSalemSpencer.mul_right (hs : MulSalemSpencer s) : MulSalemSpencer ((· * a) '' s) := by
  rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
  rw [mul_mul_mul_comm, mul_mul_mul_comm d] at h
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝ : CancelCommMonoid α
s : Set α
a : α
hs : MulSalemSpencer s
b : α
hb : b ∈ s
c : α
hc : c ∈ s
d : α
hd : d ∈ s
h : b * c * (a * a) = d * d * (a * a)
⊢ (fun x => x * a) b = (fun x => x * a) c

Next tactic:
rw [hs hb hc hd (mul_right_cancel h)]
@[to_additive]
theorem mulSalemSpencer_mul_left_iff : MulSalemSpencer ((a * ·) '' s) ↔ MulSalemSpencer s :=
  ⟨fun hs b c d hb hc hd h =>
    mul_left_cancel
      (hs (mem_image_of_mem _ hb) (mem_image_of_mem _ hc) (mem_image_of_mem _ hd) <| by
        

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝ : CancelCommMonoid α
s : Set α
a : α
hs : MulSalemSpencer ((fun x => a * x) '' s)
b c d : α
hb : b ∈ s
hc : c ∈ s
hd : d ∈ s
h : b * c = d * d
⊢ a * b * (a * c) = a * d * (a * d)

Next tactic:
rw [mul_mul_mul_comm, h, mul_mul_mul_comm]
@[to_additive]
theorem mulSalemSpencer_mul_right_iff : MulSalemSpencer ((· * a) '' s) ↔ MulSalemSpencer s :=
  ⟨fun hs b c d hb hc hd h =>
    mul_right_cancel
      (hs (Set.mem_image_of_mem _ hb) (Set.mem_image_of_mem _ hc) (Set.mem_image_of_mem _ hd) <| by
        

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝ : CancelCommMonoid α
s : Set α
a : α
hs : MulSalemSpencer ((fun x => x * a) '' s)
b c d : α
hb : b ∈ s
hc : c ∈ s
hd : d ∈ s
h : b * c = d * d
⊢ b * a * (c * a) = d * a * (d * a)

Next tactic:
rw [mul_mul_mul_comm, h, mul_mul_mul_comm]
@[to_additive]
theorem mulSalemSpencer_insert_of_lt (hs : ∀ i ∈ s, i < a) :
    MulSalemSpencer (insert a s) ↔
      MulSalemSpencer s ∧ ∀ ⦃b c⦄, b ∈ s → c ∈ s → a * b = c * c → a = b := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝ : OrderedCancelCommMonoid α
s : Set α
a : α
hs : ∀ i ∈ s, i < a
⊢ MulSalemSpencer (insert a s) ↔ MulSalemSpencer s ∧ ∀ ⦃b c : α⦄, b ∈ s → c ∈ s → a * b = c * c → a = b

Next tactic:
refine' mulSalemSpencer_insert.trans _
@[to_additive]
theorem mulSalemSpencer_insert_of_lt (hs : ∀ i ∈ s, i < a) :
    MulSalemSpencer (insert a s) ↔
      MulSalemSpencer s ∧ ∀ ⦃b c⦄, b ∈ s → c ∈ s → a * b = c * c → a = b := by
  refine' mulSalemSpencer_insert.trans _
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝ : OrderedCancelCommMonoid α
s : Set α
a : α
hs : ∀ i ∈ s, i < a
⊢ (MulSalemSpencer s ∧
      (∀ ⦃b c : α⦄, b ∈ s → c ∈ s → a * b = c * c → a = b) ∧ ∀ ⦃b c : α⦄, b ∈ s → c ∈ s → b * c = a * a → b = c) ↔
    MulSalemSpencer s ∧ ∀ ⦃b c : α⦄, b ∈ s → c ∈ s → a * b = c * c → a = b

Next tactic:
rw [← and_assoc]
@[to_additive]
theorem mulSalemSpencer_insert_of_lt (hs : ∀ i ∈ s, i < a) :
    MulSalemSpencer (insert a s) ↔
      MulSalemSpencer s ∧ ∀ ⦃b c⦄, b ∈ s → c ∈ s → a * b = c * c → a = b := by
  refine' mulSalemSpencer_insert.trans _
  rw [← and_assoc]
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝ : OrderedCancelCommMonoid α
s : Set α
a : α
hs : ∀ i ∈ s, i < a
⊢ ((MulSalemSpencer s ∧ ∀ ⦃b c : α⦄, b ∈ s → c ∈ s → a * b = c * c → a = b) ∧
      ∀ ⦃b c : α⦄, b ∈ s → c ∈ s → b * c = a * a → b = c) ↔
    MulSalemSpencer s ∧ ∀ ⦃b c : α⦄, b ∈ s → c ∈ s → a * b = c * c → a = b

Next tactic:
exact and_iff_left fun b c hb hc h => ((mul_lt_mul_of_lt_of_lt (hs _ hb) (hs _ hc)).ne h).elim
theorem MulSalemSpencer.mul_left₀ (hs : MulSalemSpencer s) (ha : a ≠ 0) :
    MulSalemSpencer ((a * ·) '' s) := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
hs : MulSalemSpencer s
ha : a ≠ 0
⊢ MulSalemSpencer ((fun x => a * x) '' s)

Next tactic:
rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
theorem MulSalemSpencer.mul_left₀ (hs : MulSalemSpencer s) (ha : a ≠ 0) :
    MulSalemSpencer ((a * ·) '' s) := by
  rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
hs : MulSalemSpencer s
ha : a ≠ 0
b : α
hb : b ∈ s
c : α
hc : c ∈ s
d : α
hd : d ∈ s
h : (fun x => a * x) b * (fun x => a * x) c = (fun x => a * x) d * (fun x => a * x) d
⊢ (fun x => a * x) b = (fun x => a * x) c

Next tactic:
rw [mul_mul_mul_comm, mul_mul_mul_comm a d] at h
theorem MulSalemSpencer.mul_left₀ (hs : MulSalemSpencer s) (ha : a ≠ 0) :
    MulSalemSpencer ((a * ·) '' s) := by
  rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
  rw [mul_mul_mul_comm, mul_mul_mul_comm a d] at h
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
hs : MulSalemSpencer s
ha : a ≠ 0
b : α
hb : b ∈ s
c : α
hc : c ∈ s
d : α
hd : d ∈ s
h : a * a * (b * c) = a * a * (d * d)
⊢ (fun x => a * x) b = (fun x => a * x) c

Next tactic:
rw [hs hb hc hd (mul_left_cancel₀ (mul_ne_zero ha ha) h)]
theorem MulSalemSpencer.mul_right₀ (hs : MulSalemSpencer s) (ha : a ≠ 0) :
    MulSalemSpencer ((· * a) '' s) := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
hs : MulSalemSpencer s
ha : a ≠ 0
⊢ MulSalemSpencer ((fun x => x * a) '' s)

Next tactic:
rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
theorem MulSalemSpencer.mul_right₀ (hs : MulSalemSpencer s) (ha : a ≠ 0) :
    MulSalemSpencer ((· * a) '' s) := by
  rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
hs : MulSalemSpencer s
ha : a ≠ 0
b : α
hb : b ∈ s
c : α
hc : c ∈ s
d : α
hd : d ∈ s
h : (fun x => x * a) b * (fun x => x * a) c = (fun x => x * a) d * (fun x => x * a) d
⊢ (fun x => x * a) b = (fun x => x * a) c

Next tactic:
rw [mul_mul_mul_comm, mul_mul_mul_comm d] at h
theorem MulSalemSpencer.mul_right₀ (hs : MulSalemSpencer s) (ha : a ≠ 0) :
    MulSalemSpencer ((· * a) '' s) := by
  rintro _ _ _ ⟨b, hb, rfl⟩ ⟨c, hc, rfl⟩ ⟨d, hd, rfl⟩ h
  rw [mul_mul_mul_comm, mul_mul_mul_comm d] at h
  

Proof state:
case intro.intro.intro.intro.intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
hs : MulSalemSpencer s
ha : a ≠ 0
b : α
hb : b ∈ s
c : α
hc : c ∈ s
d : α
hd : d ∈ s
h : b * c * (a * a) = d * d * (a * a)
⊢ (fun x => x * a) b = (fun x => x * a) c

Next tactic:
rw [hs hb hc hd (mul_right_cancel₀ (mul_ne_zero ha ha) h)]
theorem mulSalemSpencer_mul_left_iff₀ (ha : a ≠ 0) :
    MulSalemSpencer ((a * ·) '' s) ↔ MulSalemSpencer s :=
  ⟨fun hs b c d hb hc hd h =>
    mul_left_cancel₀ ha
      (hs (Set.mem_image_of_mem _ hb) (Set.mem_image_of_mem _ hc) (Set.mem_image_of_mem _ hd) <| by
        

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
ha : a ≠ 0
hs : MulSalemSpencer ((fun x => a * x) '' s)
b c d : α
hb : b ∈ s
hc : c ∈ s
hd : d ∈ s
h : b * c = d * d
⊢ a * b * (a * c) = a * d * (a * d)

Next tactic:
rw [mul_mul_mul_comm, h, mul_mul_mul_comm]
theorem mulSalemSpencer_mul_right_iff₀ (ha : a ≠ 0) :
    MulSalemSpencer ((· * a) '' s) ↔ MulSalemSpencer s :=
  ⟨fun hs b c d hb hc hd h =>
    mul_right_cancel₀ ha
      (hs (Set.mem_image_of_mem _ hb) (Set.mem_image_of_mem _ hc) (Set.mem_image_of_mem _ hd) <| by
        

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : NoZeroDivisors α
s : Set α
a : α
ha : a ≠ 0
hs : MulSalemSpencer ((fun x => x * a) '' s)
b c d : α
hb : b ∈ s
hc : c ∈ s
hd : d ∈ s
h : b * c = d * d
⊢ b * a * (c * a) = d * a * (d * a)

Next tactic:
rw [mul_mul_mul_comm, h, mul_mul_mul_comm]
theorem addSalemSpencer_iff_eq_right {s : Set ℕ} :
    AddSalemSpencer s ↔ ∀ ⦃a b c⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
s : Set ℕ
⊢ AddSalemSpencer s ↔ ∀ ⦃a b c : ℕ⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c

Next tactic:
refine' forall₄_congr fun a b c _ => forall₃_congr fun _ _ habc => ⟨_, _⟩
theorem addSalemSpencer_iff_eq_right {s : Set ℕ} :
    AddSalemSpencer s ↔ ∀ ⦃a b c⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c := by
  refine' forall₄_congr fun a b c _ => forall₃_congr fun _ _ habc => ⟨_, _⟩
  · 

Proof state:
case refine'_1
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
s : Set ℕ
a b c : ℕ
x✝² : a ∈ s
x✝¹ : b ∈ s
x✝ : c ∈ s
habc : a + b = c + c
⊢ a = b → a = c

Next tactic:
rintro rfl
theorem addSalemSpencer_iff_eq_right {s : Set ℕ} :
    AddSalemSpencer s ↔ ∀ ⦃a b c⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c := by
  refine' forall₄_congr fun a b c _ => forall₃_congr fun _ _ habc => ⟨_, _⟩
  · rintro rfl
    

Proof state:
case refine'_1
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
s : Set ℕ
a c : ℕ
x✝² : a ∈ s
x✝¹ : c ∈ s
x✝ : a ∈ s
habc : a + a = c + c
⊢ a = c

Next tactic:
simp_rw [← two_mul] at habc
theorem addSalemSpencer_iff_eq_right {s : Set ℕ} :
    AddSalemSpencer s ↔ ∀ ⦃a b c⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c := by
  refine' forall₄_congr fun a b c _ => forall₃_congr fun _ _ habc => ⟨_, _⟩
  · rintro rfl
    simp_rw [← two_mul] at habc
    

Proof state:
case refine'_1
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
s : Set ℕ
a c : ℕ
x✝² : a ∈ s
x✝¹ : c ∈ s
x✝ : a ∈ s
habc : 2 * a = 2 * c
⊢ a = c

Next tactic:
exact mul_left_cancel₀ two_ne_zero habc
theorem addSalemSpencer_iff_eq_right {s : Set ℕ} :
    AddSalemSpencer s ↔ ∀ ⦃a b c⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c := by
  refine' forall₄_congr fun a b c _ => forall₃_congr fun _ _ habc => ⟨_, _⟩
  · rintro rfl
    simp_rw [← two_mul] at habc
    exact mul_left_cancel₀ two_ne_zero habc
  · 

Proof state:
case refine'_2
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
s : Set ℕ
a b c : ℕ
x✝² : a ∈ s
x✝¹ : b ∈ s
x✝ : c ∈ s
habc : a + b = c + c
⊢ a = c → a = b

Next tactic:
rintro rfl
theorem addSalemSpencer_iff_eq_right {s : Set ℕ} :
    AddSalemSpencer s ↔ ∀ ⦃a b c⦄, a ∈ s → b ∈ s → c ∈ s → a + b = c + c → a = c := by
  refine' forall₄_congr fun a b c _ => forall₃_congr fun _ _ habc => ⟨_, _⟩
  · rintro rfl
    simp_rw [← two_mul] at habc
    exact mul_left_cancel₀ two_ne_zero habc
  · rintro rfl
    

Proof state:
case refine'_2
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
s : Set ℕ
a b : ℕ
x✝² : a ∈ s
x✝¹ : b ∈ s
x✝ : a ∈ s
habc : a + b = a + a
⊢ a = b

Next tactic:
exact (add_left_cancel habc).symm
/-- The frontier of a closed strictly convex set only contains trivial arithmetic progressions.
The idea is that an arithmetic progression is contained on a line and the frontier of a strictly
convex set does not contain lines. -/
theorem addSalemSpencer_frontier [LinearOrderedField 𝕜] [TopologicalSpace E] [AddCommMonoid E]
    [Module 𝕜 E] {s : Set E} (hs₀ : IsClosed s) (hs₁ : StrictConvex 𝕜 s) :
    AddSalemSpencer (frontier s) := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : LinearOrderedField 𝕜
inst✝² : TopologicalSpace E
inst✝¹ : AddCommMonoid E
inst✝ : Module 𝕜 E
s : Set E
hs₀ : IsClosed s
hs₁ : StrictConvex 𝕜 s
⊢ AddSalemSpencer (frontier s)

Next tactic:
intro a b c ha hb hc habc
/-- The frontier of a closed strictly convex set only contains trivial arithmetic progressions.
The idea is that an arithmetic progression is contained on a line and the frontier of a strictly
convex set does not contain lines. -/
theorem addSalemSpencer_frontier [LinearOrderedField 𝕜] [TopologicalSpace E] [AddCommMonoid E]
    [Module 𝕜 E] {s : Set E} (hs₀ : IsClosed s) (hs₁ : StrictConvex 𝕜 s) :
    AddSalemSpencer (frontier s) := by
  intro a b c ha hb hc habc
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : LinearOrderedField 𝕜
inst✝² : TopologicalSpace E
inst✝¹ : AddCommMonoid E
inst✝ : Module 𝕜 E
s : Set E
hs₀ : IsClosed s
hs₁ : StrictConvex 𝕜 s
a b c : E
ha : a ∈ frontier s
hb : b ∈ frontier s
hc : c ∈ frontier s
habc : a + b = c + c
⊢ a = b

Next tactic:
obtain rfl : (1 / 2 : 𝕜) • a + (1 / 2 : 𝕜) • b = c := by
    rwa [← smul_add, one_div, inv_smul_eq_iff₀ (show (2 : 𝕜) ≠ 0 by norm_num), two_smul]
/-- The frontier of a closed strictly convex set only contains trivial arithmetic progressions.
The idea is that an arithmetic progression is contained on a line and the frontier of a strictly
convex set does not contain lines. -/
theorem addSalemSpencer_frontier [LinearOrderedField 𝕜] [TopologicalSpace E] [AddCommMonoid E]
    [Module 𝕜 E] {s : Set E} (hs₀ : IsClosed s) (hs₁ : StrictConvex 𝕜 s) :
    AddSalemSpencer (frontier s) := by
  intro a b c ha hb hc habc
  obtain rfl : (1 / 2 : 𝕜) • a + (1 / 2 : 𝕜) • b = c := by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : LinearOrderedField 𝕜
inst✝² : TopologicalSpace E
inst✝¹ : AddCommMonoid E
inst✝ : Module 𝕜 E
s : Set E
hs₀ : IsClosed s
hs₁ : StrictConvex 𝕜 s
a b c : E
ha : a ∈ frontier s
hb : b ∈ frontier s
hc : c ∈ frontier s
habc : a + b = c + c
⊢ (1 / 2) • a + (1 / 2) • b = c

Next tactic:
rwa [← smul_add, one_div, inv_smul_eq_iff₀ (show (2 : 𝕜) ≠ 0 by norm_num), two_smul]
/-- The frontier of a closed strictly convex set only contains trivial arithmetic progressions.
The idea is that an arithmetic progression is contained on a line and the frontier of a strictly
convex set does not contain lines. -/
theorem addSalemSpencer_frontier [LinearOrderedField 𝕜] [TopologicalSpace E] [AddCommMonoid E]
    [Module 𝕜 E] {s : Set E} (hs₀ : IsClosed s) (hs₁ : StrictConvex 𝕜 s) :
    AddSalemSpencer (frontier s) := by
  intro a b c ha hb hc habc
  obtain rfl : (1 / 2 : 𝕜) • a + (1 / 2 : 𝕜) • b = c := by
    rwa [← smul_add, one_div, inv_smul_eq_iff₀ (show (2 : 𝕜) ≠ 0 by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : LinearOrderedField 𝕜
inst✝² : TopologicalSpace E
inst✝¹ : AddCommMonoid E
inst✝ : Module 𝕜 E
s : Set E
hs₀ : IsClosed s
hs₁ : StrictConvex 𝕜 s
a b c : E
ha : a ∈ frontier s
hb : b ∈ frontier s
hc : c ∈ frontier s
habc : a + b = c + c
⊢ 2 ≠ 0

Next tactic:
norm_num
/-- The frontier of a closed strictly convex set only contains trivial arithmetic progressions.
The idea is that an arithmetic progression is contained on a line and the frontier of a strictly
convex set does not contain lines. -/
theorem addSalemSpencer_frontier [LinearOrderedField 𝕜] [TopologicalSpace E] [AddCommMonoid E]
    [Module 𝕜 E] {s : Set E} (hs₀ : IsClosed s) (hs₁ : StrictConvex 𝕜 s) :
    AddSalemSpencer (frontier s) := by
  intro a b c ha hb hc habc
  obtain rfl : (1 / 2 : 𝕜) • a + (1 / 2 : 𝕜) • b = c := by
    rwa [← smul_add, one_div, inv_smul_eq_iff₀ (show (2 : 𝕜) ≠ 0 by norm_num), two_smul]
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : LinearOrderedField 𝕜
inst✝² : TopologicalSpace E
inst✝¹ : AddCommMonoid E
inst✝ : Module 𝕜 E
s : Set E
hs₀ : IsClosed s
hs₁ : StrictConvex 𝕜 s
a b : E
ha : a ∈ frontier s
hb : b ∈ frontier s
hc : (1 / 2) • a + (1 / 2) • b ∈ frontier s
habc : a + b = (1 / 2) • a + (1 / 2) • b + ((1 / 2) • a + (1 / 2) • b)
⊢ a = b

Next tactic:
exact
    hs₁.eq (hs₀.frontier_subset ha) (hs₀.frontier_subset hb) one_half_pos one_half_pos
      (add_halves _) hc.2
theorem addSalemSpencer_sphere [NormedAddCommGroup E] [NormedSpace ℝ E] [StrictConvexSpace ℝ E]
    (x : E) (r : ℝ) : AddSalemSpencer (sphere x r) := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℝ E
inst✝ : StrictConvexSpace ℝ E
x : E
r : ℝ
⊢ AddSalemSpencer (sphere x r)

Next tactic:
obtain rfl | hr := eq_or_ne r 0
theorem addSalemSpencer_sphere [NormedAddCommGroup E] [NormedSpace ℝ E] [StrictConvexSpace ℝ E]
    (x : E) (r : ℝ) : AddSalemSpencer (sphere x r) := by
  obtain rfl | hr := eq_or_ne r 0
  · 

Proof state:
case inl
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℝ E
inst✝ : StrictConvexSpace ℝ E
x : E
⊢ AddSalemSpencer (sphere x 0)

Next tactic:
rw [sphere_zero]
theorem addSalemSpencer_sphere [NormedAddCommGroup E] [NormedSpace ℝ E] [StrictConvexSpace ℝ E]
    (x : E) (r : ℝ) : AddSalemSpencer (sphere x r) := by
  obtain rfl | hr := eq_or_ne r 0
  · rw [sphere_zero]
    

Proof state:
case inl
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℝ E
inst✝ : StrictConvexSpace ℝ E
x : E
⊢ AddSalemSpencer {x}

Next tactic:
exact addSalemSpencer_singleton _
theorem addSalemSpencer_sphere [NormedAddCommGroup E] [NormedSpace ℝ E] [StrictConvexSpace ℝ E]
    (x : E) (r : ℝ) : AddSalemSpencer (sphere x r) := by
  obtain rfl | hr := eq_or_ne r 0
  · rw [sphere_zero]
    exact addSalemSpencer_singleton _
  · 

Proof state:
case inr
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℝ E
inst✝ : StrictConvexSpace ℝ E
x : E
r : ℝ
hr : r ≠ 0
⊢ AddSalemSpencer (sphere x r)

Next tactic:
convert addSalemSpencer_frontier isClosed_ball (strictConvex_closedBall ℝ x r)
theorem addSalemSpencer_sphere [NormedAddCommGroup E] [NormedSpace ℝ E] [StrictConvexSpace ℝ E]
    (x : E) (r : ℝ) : AddSalemSpencer (sphere x r) := by
  obtain rfl | hr := eq_or_ne r 0
  · rw [sphere_zero]
    exact addSalemSpencer_singleton _
  · convert addSalemSpencer_frontier isClosed_ball (strictConvex_closedBall ℝ x r)
    

Proof state:
case h.e'_3
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℝ E
inst✝ : StrictConvexSpace ℝ E
x : E
r : ℝ
hr : r ≠ 0
⊢ sphere x r = frontier (closedBall x r)

Next tactic:
exact (frontier_closedBall _ hr).symm
/-- The multiplicative Roth number of a finset is the cardinality of its biggest multiplicative
Salem-Spencer subset. -/
@[to_additive "The additive Roth number of a finset is the cardinality of its biggest additive
Salem-Spencer subset. The usual Roth number corresponds to `addRothNumber (Finset.range n)`, see
`rothNumberNat`. "]
def mulRothNumber : Finset α →o ℕ :=
  ⟨fun s =>
    Nat.findGreatest (fun m => ∃ (t : _) (_ : t ⊆ s), t.card = m ∧ MulSalemSpencer (t : Set α))
      s.card, by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t : Finset α
⊢ Monotone fun s => Nat.findGreatest (fun m => ∃ t, ∃ (_ : t ⊆ s), card t = m ∧ MulSalemSpencer ↑t) (card s)

Next tactic:
rintro t u htu
/-- The multiplicative Roth number of a finset is the cardinality of its biggest multiplicative
Salem-Spencer subset. -/
@[to_additive "The additive Roth number of a finset is the cardinality of its biggest additive
Salem-Spencer subset. The usual Roth number corresponds to `addRothNumber (Finset.range n)`, see
`rothNumberNat`. "]
def mulRothNumber : Finset α →o ℕ :=
  ⟨fun s =>
    Nat.findGreatest (fun m => ∃ (t : _) (_ : t ⊆ s), t.card = m ∧ MulSalemSpencer (t : Set α))
      s.card, by
    rintro t u htu
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t✝ t u : Finset α
htu : t ≤ u
⊢ (fun s => Nat.findGreatest (fun m => ∃ t, ∃ (_ : t ⊆ s), card t = m ∧ MulSalemSpencer ↑t) (card s)) t ≤
    (fun s => Nat.findGreatest (fun m => ∃ t, ∃ (_ : t ⊆ s), card t = m ∧ MulSalemSpencer ↑t) (card s)) u

Next tactic:
refine' Nat.findGreatest_mono (fun m => _) (card_le_of_subset htu)
/-- The multiplicative Roth number of a finset is the cardinality of its biggest multiplicative
Salem-Spencer subset. -/
@[to_additive "The additive Roth number of a finset is the cardinality of its biggest additive
Salem-Spencer subset. The usual Roth number corresponds to `addRothNumber (Finset.range n)`, see
`rothNumberNat`. "]
def mulRothNumber : Finset α →o ℕ :=
  ⟨fun s =>
    Nat.findGreatest (fun m => ∃ (t : _) (_ : t ⊆ s), t.card = m ∧ MulSalemSpencer (t : Set α))
      s.card, by
    rintro t u htu
    refine' Nat.findGreatest_mono (fun m => _) (card_le_of_subset htu)
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t✝ t u : Finset α
htu : t ≤ u
m : ℕ
⊢ (∃ t_1, ∃ (_ : t_1 ⊆ t), card t_1 = m ∧ MulSalemSpencer ↑t_1) ≤ ∃ t, ∃ (_ : t ⊆ u), card t = m ∧ MulSalemSpencer ↑t

Next tactic:
rintro ⟨v, hvt, hv⟩
/-- The multiplicative Roth number of a finset is the cardinality of its biggest multiplicative
Salem-Spencer subset. -/
@[to_additive "The additive Roth number of a finset is the cardinality of its biggest additive
Salem-Spencer subset. The usual Roth number corresponds to `addRothNumber (Finset.range n)`, see
`rothNumberNat`. "]
def mulRothNumber : Finset α →o ℕ :=
  ⟨fun s =>
    Nat.findGreatest (fun m => ∃ (t : _) (_ : t ⊆ s), t.card = m ∧ MulSalemSpencer (t : Set α))
      s.card, by
    rintro t u htu
    refine' Nat.findGreatest_mono (fun m => _) (card_le_of_subset htu)
    rintro ⟨v, hvt, hv⟩
    

Proof state:
case intro.intro
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t✝ t u : Finset α
htu : t ≤ u
m : ℕ
v : Finset α
hvt : v ⊆ t
hv : card v = m ∧ MulSalemSpencer ↑v
⊢ ∃ t, ∃ (_ : t ⊆ u), card t = m ∧ MulSalemSpencer ↑t

Next tactic:
exact ⟨v, hvt.trans htu, hv⟩
@[to_additive]
theorem mulRothNumber_spec :
    ∃ (t : _) (_ : t ⊆ s), t.card = mulRothNumber s ∧ MulSalemSpencer (t : Set α) :=
  @Nat.findGreatest_spec _ _
    (fun m => ∃ (t : _) (_ : t ⊆ s), t.card = m ∧ MulSalemSpencer (t : Set α)) _ (Nat.zero_le _)
    ⟨∅, empty_subset _, card_empty, by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t : Finset α
⊢ MulSalemSpencer ↑∅

Next tactic:
norm_cast
@[to_additive]
theorem mulRothNumber_spec :
    ∃ (t : _) (_ : t ⊆ s), t.card = mulRothNumber s ∧ MulSalemSpencer (t : Set α) :=
  @Nat.findGreatest_spec _ _
    (fun m => ∃ (t : _) (_ : t ⊆ s), t.card = m ∧ MulSalemSpencer (t : Set α)) _ (Nat.zero_le _)
    ⟨∅, empty_subset _, card_empty, by norm_cast; 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t : Finset α
⊢ MulSalemSpencer ∅

Next tactic:
exact mulSalemSpencer_empty
@[to_additive (attr := simp)]
theorem mulRothNumber_singleton (a : α) : mulRothNumber ({a} : Finset α) = 1 := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t : Finset α
n : ℕ
a : α
⊢ mulRothNumber {a} = 1

Next tactic:
refine' MulSalemSpencer.roth_number_eq _
@[to_additive (attr := simp)]
theorem mulRothNumber_singleton (a : α) : mulRothNumber ({a} : Finset α) = 1 := by
  refine' MulSalemSpencer.roth_number_eq _
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
𝕜 : Type u_4
E : Type u_5
inst✝³ : DecidableEq α
inst✝² : Monoid α
inst✝¹ : DecidableEq β
inst✝ : Monoid β
s t : Finset α
n : ℕ
a : α
⊢ MulSalemSpencer ↑{a}

Next tactic:
rw [coe_singleton]