l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
theorem noncommProd_mem (S : Submonoid M) {ι : Type*} (t : Finset ι) (f : ι → M) (comm)
    (h : ∀ c ∈ t, f c ∈ S) : t.noncommProd f comm ∈ S := by
  apply multiset_noncommProd_mem
  

Proof state:
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ c ∈ t, f c ∈ S
⊢ ∀ x ∈ Multiset.map f t.val, x ∈ S

Next tactic:
intro y
@[to_additive]
theorem noncommProd_mem (S : Submonoid M) {ι : Type*} (t : Finset ι) (f : ι → M) (comm)
    (h : ∀ c ∈ t, f c ∈ S) : t.noncommProd f comm ∈ S := by
  apply multiset_noncommProd_mem
  intro y
  

Proof state:
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ c ∈ t, f c ∈ S
y : M
⊢ y ∈ Multiset.map f t.val → y ∈ S

Next tactic:
rw [Multiset.mem_map]
@[to_additive]
theorem noncommProd_mem (S : Submonoid M) {ι : Type*} (t : Finset ι) (f : ι → M) (comm)
    (h : ∀ c ∈ t, f c ∈ S) : t.noncommProd f comm ∈ S := by
  apply multiset_noncommProd_mem
  intro y
  rw [Multiset.mem_map]
  

Proof state:
case h
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ c ∈ t, f c ∈ S
y : M
⊢ (∃ a ∈ t.val, f a = y) → y ∈ S

Next tactic:
rintro ⟨x, ⟨hx, rfl⟩⟩
@[to_additive]
theorem noncommProd_mem (S : Submonoid M) {ι : Type*} (t : Finset ι) (f : ι → M) (comm)
    (h : ∀ c ∈ t, f c ∈ S) : t.noncommProd f comm ∈ S := by
  apply multiset_noncommProd_mem
  intro y
  rw [Multiset.mem_map]
  rintro ⟨x, ⟨hx, rfl⟩⟩
  

Proof state:
case h.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝² : Monoid M
inst✝¹ : SetLike B M
inst✝ : SubmonoidClass B M
S✝ : B
s S : Submonoid M
ι : Type u_4
t : Finset ι
f : ι → M
comm : Set.Pairwise ↑t fun a b => Commute (f a) (f b)
h : ∀ c ∈ t, f c ∈ S
x : ι
hx : x ∈ t.val
⊢ f x ∈ S

Next tactic:
exact h x hx
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ⨆ i, S i ↔ ∃ i, x ∈ S i

Next tactic:
refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ⨆ i, S i → ∃ i, x ∈ S i

Next tactic:
suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    simpa only [closure_iUnion, closure_eq (S _)] using this
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
this : x ∈ closure (⋃ i, ↑(S i)) → ∃ i, x ∈ S i
⊢ x ∈ ⨆ i, S i → ∃ i, x ∈ S i

Next tactic:
simpa only [closure_iUnion, closure_eq (S _)] using this
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    simpa only [closure_iUnion, closure_eq (S _)] using this
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ closure (⋃ i, ↑(S i)) → ∃ i, x ∈ S i

Next tactic:
refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) ?_ ?_
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    simpa only [closure_iUnion, closure_eq (S _)] using this
  refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) ?_ ?_
  · 

Proof state:
case refine_1
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
hx : x ∈ closure (⋃ i, ↑(S i))
⊢ ∃ i, 1 ∈ S i

Next tactic:
exact hι.elim fun i ↦ ⟨i, (S i).one_mem⟩
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    simpa only [closure_iUnion, closure_eq (S _)] using this
  refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) ?_ ?_
  · exact hι.elim fun i ↦ ⟨i, (S i).one_mem⟩
  · 

Proof state:
case refine_2
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
hx : x ∈ closure (⋃ i, ↑(S i))
⊢ ∀ (x y : M), (∃ i, x ∈ S i) → (∃ i, y ∈ S i) → ∃ i, x * y ∈ S i

Next tactic:
rintro x y ⟨i, hi⟩ ⟨j, hj⟩
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    simpa only [closure_iUnion, closure_eq (S _)] using this
  refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) ?_ ?_
  · exact hι.elim fun i ↦ ⟨i, (S i).one_mem⟩
  · rintro x y ⟨i, hi⟩ ⟨j, hj⟩
    

Proof state:
case refine_2.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x✝ : M
hx : x✝ ∈ closure (⋃ i, ↑(S i))
x y : M
i : ι
hi : x ∈ S i
j : ι
hj : y ∈ S j
⊢ ∃ i, x * y ∈ S i

Next tactic:
rcases hS i j with ⟨k, hki, hkj⟩
@[to_additive]
theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S)
    {x : M} : (x ∈ ⨆ i, S i) ↔ ∃ i, x ∈ S i := by
  refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩
  suffices x ∈ closure (⋃ i, (S i : Set M)) → ∃ i, x ∈ S i by
    simpa only [closure_iUnion, closure_eq (S _)] using this
  refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) ?_ ?_
  · exact hι.elim fun i ↦ ⟨i, (S i).one_mem⟩
  · rintro x y ⟨i, hi⟩ ⟨j, hj⟩
    rcases hS i j with ⟨k, hki, hkj⟩
    

Proof state:
case refine_2.intro.intro.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
hι : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x✝ : M
hx : x✝ ∈ closure (⋃ i, ↑(S i))
x y : M
i : ι
hi : x ∈ S i
j : ι
hj : y ∈ S j
k : ι
hki : S i ≤ S k
hkj : S j ≤ S k
⊢ ∃ i, x * y ∈ S i

Next tactic:
exact ⟨k, (S k).mul_mem (hki hi) (hkj hj)⟩
@[to_additive]
theorem coe_iSup_of_directed {ι} [Nonempty ι] {S : ι → Submonoid M} (hS : Directed (· ≤ ·) S) :
    ((⨆ i, S i : Submonoid M) : Set M) = ⋃ i, S i :=
  Set.ext fun x ↦ by 

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : MulOneClass M
ι : Sort u_4
inst✝ : Nonempty ι
S : ι → Submonoid M
hS : Directed (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ↑(⨆ i, S i) ↔ x ∈ ⋃ i, ↑(S i)

Next tactic:
simp [mem_iSup_of_directed hS]
@[to_additive]
theorem mem_sSup_of_directedOn {S : Set (Submonoid M)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) {x : M} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s

Next tactic:
haveI : Nonempty S := Sne.to_subtype
@[to_additive]
theorem mem_sSup_of_directedOn {S : Set (Submonoid M)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) {x : M} : x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s := by
  haveI : Nonempty S := Sne.to_subtype
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : M
this : Nonempty ↑S
⊢ x ∈ sSup S ↔ ∃ s ∈ S, x ∈ s

Next tactic:
simp [sSup_eq_iSup', mem_iSup_of_directed hS.directed_val, SetCoe.exists, Subtype.coe_mk]
@[to_additive]
theorem coe_sSup_of_directedOn {S : Set (Submonoid M)} (Sne : S.Nonempty)
    (hS : DirectedOn (· ≤ ·) S) : (↑(sSup S) : Set M) = ⋃ s ∈ S, ↑s :=
  Set.ext fun x => by 

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
Sne : Set.Nonempty S
hS : DirectedOn (fun x x_1 => x ≤ x_1) S
x : M
⊢ x ∈ ↑(sSup S) ↔ x ∈ ⋃ s ∈ S, ↑s

Next tactic:
simp [mem_sSup_of_directedOn Sne hS]
@[to_additive]
theorem mem_sup_left {S T : Submonoid M} : ∀ {x : M}, x ∈ S → x ∈ S ⊔ T := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ ∀ {x : M}, x ∈ S → x ∈ S ⊔ T

Next tactic:
rw [← SetLike.le_def]
@[to_additive]
theorem mem_sup_left {S T : Submonoid M} : ∀ {x : M}, x ∈ S → x ∈ S ⊔ T := by
  rw [← SetLike.le_def]
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ S ≤ S ⊔ T

Next tactic:
exact le_sup_left
@[to_additive]
theorem mem_sup_right {S T : Submonoid M} : ∀ {x : M}, x ∈ T → x ∈ S ⊔ T := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ ∀ {x : M}, x ∈ T → x ∈ S ⊔ T

Next tactic:
rw [← SetLike.le_def]
@[to_additive]
theorem mem_sup_right {S T : Submonoid M} : ∀ {x : M}, x ∈ T → x ∈ S ⊔ T := by
  rw [← SetLike.le_def]
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S T : Submonoid M
⊢ T ≤ S ⊔ T

Next tactic:
exact le_sup_right
@[to_additive]
theorem mem_iSup_of_mem {ι : Sort*} {S : ι → Submonoid M} (i : ι) :
    ∀ {x : M}, x ∈ S i → x ∈ iSup S := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
i : ι
⊢ ∀ {x : M}, x ∈ S i → x ∈ iSup S

Next tactic:
rw [← SetLike.le_def]
@[to_additive]
theorem mem_iSup_of_mem {ι : Sort*} {S : ι → Submonoid M} (i : ι) :
    ∀ {x : M}, x ∈ S i → x ∈ iSup S := by
  rw [← SetLike.le_def]
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
i : ι
⊢ S i ≤ iSup S

Next tactic:
exact le_iSup _ _
@[to_additive]
theorem mem_sSup_of_mem {S : Set (Submonoid M)} {s : Submonoid M} (hs : s ∈ S) :
    ∀ {x : M}, x ∈ s → x ∈ sSup S := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
s : Submonoid M
hs : s ∈ S
⊢ ∀ {x : M}, x ∈ s → x ∈ sSup S

Next tactic:
rw [← SetLike.le_def]
@[to_additive]
theorem mem_sSup_of_mem {S : Set (Submonoid M)} {s : Submonoid M} (hs : s ∈ S) :
    ∀ {x : M}, x ∈ s → x ∈ sSup S := by
  rw [← SetLike.le_def]
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
S : Set (Submonoid M)
s : Submonoid M
hs : s ∈ S
⊢ s ≤ sSup S

Next tactic:
exact le_sSup hs
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim)
      " An induction principle for elements of `⨆ i, S i`.
      If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
      then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Submonoid M) {C : M → Prop} {x : M} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x : M
hx : x ∈ ⨆ i, S i
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
⊢ C x

Next tactic:
rw [iSup_eq_closure] at hx
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim)
      " An induction principle for elements of `⨆ i, S i`.
      If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
      then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Submonoid M) {C : M → Prop} {x : M} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  rw [iSup_eq_closure] at hx
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x : M
hx : x ∈ closure (⋃ i, ↑(S i))
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
⊢ C x

Next tactic:
refine closure_induction hx (fun x hx => ?_) h1 hmul
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim)
      " An induction principle for elements of `⨆ i, S i`.
      If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
      then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Submonoid M) {C : M → Prop} {x : M} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  rw [iSup_eq_closure] at hx
  refine closure_induction hx (fun x hx => ?_) h1 hmul
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x✝ : M
hx✝ : x✝ ∈ closure (⋃ i, ↑(S i))
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
x : M
hx : x ∈ ⋃ i, ↑(S i)
⊢ C x

Next tactic:
obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
/-- An induction principle for elements of `⨆ i, S i`.
If `C` holds for `1` and all elements of `S i` for all `i`, and is preserved under multiplication,
then it holds for all elements of the supremum of `S`. -/
@[to_additive (attr := elab_as_elim)
      " An induction principle for elements of `⨆ i, S i`.
      If `C` holds for `0` and all elements of `S i` for all `i`, and is preserved under addition,
      then it holds for all elements of the supremum of `S`. "]
theorem iSup_induction {ι : Sort*} (S : ι → Submonoid M) {C : M → Prop} {x : M} (hx : x ∈ ⨆ i, S i)
    (hp : ∀ (i), ∀ x ∈ S i, C x) (h1 : C 1) (hmul : ∀ x y, C x → C y → C (x * y)) : C x := by
  rw [iSup_eq_closure] at hx
  refine closure_induction hx (fun x hx => ?_) h1 hmul
  obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx
  

Proof state:
case intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : M → Prop
x✝ : M
hx✝ : x✝ ∈ closure (⋃ i, ↑(S i))
hp : ∀ (i : ι), ∀ x ∈ S i, C x
h1 : C 1
hmul : ∀ (x y : M), C x → C y → C (x * y)
x : M
hx : x ∈ ⋃ i, ↑(S i)
i : ι
hi : x ∈ ↑(S i)
⊢ C x

Next tactic:
exact hp _ _ hi
/-- A dependent version of `Submonoid.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Submonoid M) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ (x) (hxS : x ∈ S i), C x (mem_iSup_of_mem i hxS)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : M}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : M) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : M
hx : x ∈ ⨆ i, S i
⊢ C x hx

Next tactic:
refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
/-- A dependent version of `Submonoid.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Submonoid M) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ (x) (hxS : x ∈ S i), C x (mem_iSup_of_mem i hxS)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : M}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : M) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : M
hx : x ∈ ⨆ i, S i
⊢ ∃ (Hx : x ∈ ⨆ i, S i), C x Hx

Next tactic:
refine' @iSup_induction _ _ ι S (fun m => ∃ hm, C m hm) _ hx (fun i x hx => _) _ fun x y => _
/-- A dependent version of `Submonoid.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Submonoid M) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ (x) (hxS : x ∈ S i), C x (mem_iSup_of_mem i hxS)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : M}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
  refine' @iSup_induction _ _ ι S (fun m => ∃ hm, C m hm) _ hx (fun i x hx => _) _ fun x y => _
  · 

Proof state:
case refine'_1
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : M) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x✝ : M
hx✝ : x✝ ∈ ⨆ i, S i
i : ι
x : M
hx : x ∈ S i
⊢ (fun m => ∃ (hm : m ∈ ⨆ i, S i), C m hm) x

Next tactic:
exact ⟨_, hp _ _ hx⟩
/-- A dependent version of `Submonoid.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Submonoid M) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ (x) (hxS : x ∈ S i), C x (mem_iSup_of_mem i hxS)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : M}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
  refine' @iSup_induction _ _ ι S (fun m => ∃ hm, C m hm) _ hx (fun i x hx => _) _ fun x y => _
  · exact ⟨_, hp _ _ hx⟩
  · 

Proof state:
case refine'_2
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : M) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x : M
hx : x ∈ ⨆ i, S i
⊢ (fun m => ∃ (hm : m ∈ ⨆ i, S i), C m hm) 1

Next tactic:
exact ⟨_, h1⟩
/-- A dependent version of `Submonoid.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Submonoid M) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ (x) (hxS : x ∈ S i), C x (mem_iSup_of_mem i hxS)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : M}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
  refine' @iSup_induction _ _ ι S (fun m => ∃ hm, C m hm) _ hx (fun i x hx => _) _ fun x y => _
  · exact ⟨_, hp _ _ hx⟩
  · exact ⟨_, h1⟩
  · 

Proof state:
case refine'_3
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : M) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x✝ : M
hx : x✝ ∈ ⨆ i, S i
x y : M
⊢ (fun m => ∃ (hm : m ∈ ⨆ i, S i), C m hm) x →
    (fun m => ∃ (hm : m ∈ ⨆ i, S i), C m hm) y → (fun m => ∃ (hm : m ∈ ⨆ i, S i), C m hm) (x * y)

Next tactic:
rintro ⟨_, Cx⟩ ⟨_, Cy⟩
/-- A dependent version of `Submonoid.iSup_induction`. -/
@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.iSup_induction`. "]
theorem iSup_induction' {ι : Sort*} (S : ι → Submonoid M) {C : ∀ x, (x ∈ ⨆ i, S i) → Prop}
    (hp : ∀ (i), ∀ (x) (hxS : x ∈ S i), C x (mem_iSup_of_mem i hxS)) (h1 : C 1 (one_mem _))
    (hmul : ∀ x y hx hy, C x hx → C y hy → C (x * y) (mul_mem ‹_› ‹_›)) {x : M}
    (hx : x ∈ ⨆ i, S i) : C x hx := by
  refine' Exists.elim (_ : ∃ Hx, C x Hx) fun (hx : x ∈ ⨆ i, S i) (hc : C x hx) => hc
  refine' @iSup_induction _ _ ι S (fun m => ∃ hm, C m hm) _ hx (fun i x hx => _) _ fun x y => _
  · exact ⟨_, hp _ _ hx⟩
  · exact ⟨_, h1⟩
  · rintro ⟨_, Cx⟩ ⟨_, Cy⟩
    

Proof state:
case refine'_3.intro.intro
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : MulOneClass M
ι : Sort u_4
S : ι → Submonoid M
C : (x : M) → x ∈ ⨆ i, S i → Prop
hp : ∀ (i : ι) (x : M) (hxS : x ∈ S i), C x (_ : x ∈ ⨆ i, S i)
h1 : C 1 (_ : 1 ∈ ⨆ i, S i)
hmul : ∀ (x y : M) (hx : x ∈ ⨆ i, S i) (hy : y ∈ ⨆ i, S i), C x hx → C y hy → C (x * y) (_ : x * y ∈ ⨆ i, S i)
x✝ : M
hx : x✝ ∈ ⨆ i, S i
x y : M
w✝¹ : x ∈ ⨆ i, S i
Cx : C x w✝¹
w✝ : y ∈ ⨆ i, S i
Cy : C y w✝
⊢ ∃ (hm : x * y ∈ ⨆ i, S i), C (x * y) hm

Next tactic:
refine' ⟨_, hmul _ _ _ _ Cx Cy⟩
/-- The submonoid generated by an element of a monoid equals the set of natural number powers of
    the element. -/
theorem mem_closure_singleton {x y : M} : y ∈ closure ({x} : Set M) ↔ ∃ n : ℕ, x ^ n = y := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
a x y : M
⊢ y ∈ closure {x} ↔ ∃ n, x ^ n = y

Next tactic:
rw [closure_singleton_eq, mem_mrange]
/-- The submonoid generated by an element of a monoid equals the set of natural number powers of
    the element. -/
theorem mem_closure_singleton {x y : M} : y ∈ closure ({x} : Set M) ↔ ∃ n : ℕ, x ^ n = y := by
  rw [closure_singleton_eq, mem_mrange]; 

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
a x y : M
⊢ (∃ x_1, ((powersHom M) x) x_1 = y) ↔ ∃ n, x ^ n = y

Next tactic:
rfl
theorem closure_singleton_one : closure ({1} : Set M) = ⊥ := by
  

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝ : Monoid M
a : M
⊢ closure {1} = ⊥

Next tactic:
simp [eq_bot_iff_forall, mem_closure_singleton]
@[to_additive card_le_one_iff_eq_bot]
theorem card_le_one_iff_eq_bot : card S ≤ 1 ↔ S = ⊥ :=
  ⟨fun h =>
    (eq_bot_iff_forall _).2 fun x hx => by
      

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : Monoid M
a : M
S : Submonoid M
inst✝ : Fintype ↥S
h : card ↥S ≤ 1
x : M
hx : x ∈ S
⊢ x = 1

Next tactic:
simpa [Subtype.ext_iff] using card_le_one_iff.1 h ⟨x, hx⟩ 1
@[to_additive card_le_one_iff_eq_bot]
theorem card_le_one_iff_eq_bot : card S ≤ 1 ↔ S = ⊥ :=
  ⟨fun h =>
    (eq_bot_iff_forall _).2 fun x hx => by
      simpa [Subtype.ext_iff] using card_le_one_iff.1 h ⟨x, hx⟩ 1,
    fun h => by 

Proof state:
M : Type u_1
A : Type u_2
B : Type u_3
inst✝¹ : Monoid M
a : M
S : Submonoid M
inst✝ : Fintype ↥S
h : S = ⊥
⊢ card ↥S ≤ 1

Next tactic:
simp [h]