File: Mathlib/Algebra/Group/Subsemigroup/Basic.lean

full_name: MulMemClass
code: /-- `MulMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(*)` -/
class MulMemClass (S : Type*) (M : Type*) [Mul M] [SetLike S M] : Prop where
  /-- A substructure satisfying `MulMemClass` is closed under multiplication. -/
  mul_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a * b ∈ s
goal: Prop

full_name: MulMemClass.mul_mem
code: /-- `MulMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(*)` -/
class MulMemClass (S : Type*) (M : Type*) [Mul M] [SetLike S M] : Prop where
  /-- A substructure satisfying `MulMemClass` is closed under multiplication. -/
  mul_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a * b ∈ s
goal: a ∈ s → b ∈ s → a * b ∈ s

full_name: AddMemClass
code: /-- `AddMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(+)` -/
class AddMemClass (S : Type*) (M : Type*) [Add M] [SetLike S M] : Prop where
  /-- A substructure satisfying `AddMemClass` is closed under addition. -/
  add_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a + b ∈ s
goal: Prop

full_name: AddMemClass.add_mem
code: /-- `AddMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(+)` -/
class AddMemClass (S : Type*) (M : Type*) [Add M] [SetLike S M] : Prop where
  /-- A substructure satisfying `AddMemClass` is closed under addition. -/
  add_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a + b ∈ s
goal: a ∈ s → b ∈ s → a + b ∈ s

full_name: Subsemigroup.mul_mem'
code: /-- A subsemigroup of a magma `M` is a subset closed under multiplication. -/
structure Subsemigroup (M : Type*) [Mul M] where
  /-- The carrier of a subsemigroup. -/
  carrier : Set M
  /-- The product of two elements of a subsemigroup belongs to the subsemigroup. -/
  mul_mem' {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier
goal: a ∈ self.carrier → b ∈ self.carrier → a * b ∈ self.carrier

full_name: Subsemigroup.carrier
code: /-- A subsemigroup of a magma `M` is a subset closed under multiplication. -/
structure Subsemigroup (M : Type*) [Mul M] where
  /-- The carrier of a subsemigroup. -/
  carrier : Set M
  /-- The product of two elements of a subsemigroup belongs to the subsemigroup. -/
  mul_mem' {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier
goal: Set M

full_name: Subsemigroup
code: /-- A subsemigroup of a magma `M` is a subset closed under multiplication. -/
structure Subsemigroup (M : Type*) [Mul M] where
  /-- The carrier of a subsemigroup. -/
  carrier : Set M
  /-- The product of two elements of a subsemigroup belongs to the subsemigroup. -/
  mul_mem' {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier
goal: Type u_4

full_name: AddSubsemigroup.carrier
code: /-- An additive subsemigroup of an additive magma `M` is a subset closed under addition. -/
structure AddSubsemigroup (M : Type*) [Add M] where
  /-- The carrier of an additive subsemigroup. -/
  carrier : Set M
  /-- The sum of two elements of an additive subsemigroup belongs to the subsemigroup. -/
  add_mem' {a b} : a ∈ carrier → b ∈ carrier → a + b ∈ carrier
goal: Set M

full_name: AddSubsemigroup.add_mem'
code: /-- An additive subsemigroup of an additive magma `M` is a subset closed under addition. -/
structure AddSubsemigroup (M : Type*) [Add M] where
  /-- The carrier of an additive subsemigroup. -/
  carrier : Set M
  /-- The sum of two elements of an additive subsemigroup belongs to the subsemigroup. -/
  add_mem' {a b} : a ∈ carrier → b ∈ carrier → a + b ∈ carrier
goal: a ∈ self.carrier → b ∈ self.carrier → a + b ∈ self.carrier

full_name: AddSubsemigroup
code: /-- An additive subsemigroup of an additive magma `M` is a subset closed under addition. -/
structure AddSubsemigroup (M : Type*) [Add M] where
  /-- The carrier of an additive subsemigroup. -/
  carrier : Set M
  /-- The sum of two elements of an additive subsemigroup belongs to the subsemigroup. -/
  add_mem' {a b} : a ∈ carrier → b ∈ carrier → a + b ∈ carrier
goal: Type u_4

full_name: AddSubsemigroup.instSetLike
code: @[to_additive]
instance : SetLike (Subsemigroup M) M 
goal: SetLike (AddSubsemigroup M) M

full_name: Subsemigroup.instSetLike
code: @[to_additive]
instance : SetLike (Subsemigroup M) M 
goal: SetLike (Subsemigroup M) M

full_name: Subsemigroup.instMulMemClass
code: @[to_additive]
instance : MulMemClass (Subsemigroup M) M 
goal: MulMemClass (Subsemigroup M) M

full_name: AddSubsemigroup.instAddMemClass
code: @[to_additive]
instance : MulMemClass (Subsemigroup M) M 
goal: AddMemClass (AddSubsemigroup M) M

full_name: Subsemigroup.mem_carrier
code: @[to_additive (attr := simp)]
theorem mem_carrier {s : Subsemigroup M} {x : M} : x ∈ s.carrier ↔ x ∈ s 
goal: x ∈ s.carrier ↔ x ∈ s

full_name: AddSubsemigroup.mem_carrier
code: @[to_additive (attr := simp)]
theorem mem_carrier {s : Subsemigroup M} {x : M} : x ∈ s.carrier ↔ x ∈ s 
goal: x ∈ s.carrier ↔ x ∈ s

full_name: Subsemigroup.mem_mk
code: @[to_additive (attr := simp)]
theorem mem_mk {s : Set M} {x : M} (h_mul) : x ∈ mk s h_mul ↔ x ∈ s 
goal: x ∈ { carrier := s, mul_mem' := h_mul } ↔ x ∈ s

full_name: AddSubsemigroup.mem_mk
code: @[to_additive (attr := simp)]
theorem mem_mk {s : Set M} {x : M} (h_mul) : x ∈ mk s h_mul ↔ x ∈ s 
goal: x ∈ { carrier := s, add_mem' := h_mul } ↔ x ∈ s

full_name: Subsemigroup.coe_set_mk
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_set_mk {s : Set M} (h_mul) : (mk s h_mul : Set M) = s 
goal: ↑{ carrier := s, mul_mem' := h_mul } = s

full_name: AddSubsemigroup.coe_set_mk
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_set_mk {s : Set M} (h_mul) : (mk s h_mul : Set M) = s 
goal: ↑{ carrier := s, add_mem' := h_mul } = s

full_name: AddSubsemigroup.mk_le_mk
code: @[to_additive (attr := simp)]
theorem mk_le_mk {s t : Set M} (h_mul) (h_mul') : mk s h_mul ≤ mk t h_mul' ↔ s ⊆ t 
goal: { carrier := s, add_mem' := h_mul } ≤ { carrier := t, add_mem' := h_mul' } ↔ s ⊆ t

full_name: Subsemigroup.mk_le_mk
code: @[to_additive (attr := simp)]
theorem mk_le_mk {s t : Set M} (h_mul) (h_mul') : mk s h_mul ≤ mk t h_mul' ↔ s ⊆ t 
goal: { carrier := s, mul_mem' := h_mul } ≤ { carrier := t, mul_mem' := h_mul' } ↔ s ⊆ t

full_name: AddSubsemigroup.ext
code: /-- Two subsemigroups are equal if they have the same elements. -/
@[to_additive (attr := ext) "Two `AddSubsemigroup`s are equal if they have the same elements."]
theorem ext {S T : Subsemigroup M} (h : ∀ x, x ∈ S ↔ x ∈ T) : S = T 
goal: S = T

full_name: Subsemigroup.ext
code: /-- Two subsemigroups are equal if they have the same elements. -/
@[to_additive (attr := ext) "Two `AddSubsemigroup`s are equal if they have the same elements."]
theorem ext {S T : Subsemigroup M} (h : ∀ x, x ∈ S ↔ x ∈ T) : S = T 
goal: S = T

full_name: AddSubsemigroup.copy
code: /-- Copy a subsemigroup replacing `carrier` with a set that is equal to it. -/
@[to_additive "Copy an additive subsemigroup replacing `carrier` with a set that is equal to it."]
protected def copy (S : Subsemigroup M) (s : Set M) (hs : s = S) :
    Subsemigroup M 
goal: AddSubsemigroup M

full_name: Subsemigroup.copy
code: /-- Copy a subsemigroup replacing `carrier` with a set that is equal to it. -/
@[to_additive "Copy an additive subsemigroup replacing `carrier` with a set that is equal to it."]
protected def copy (S : Subsemigroup M) (s : Set M) (hs : s = S) :
    Subsemigroup M 
goal: Subsemigroup M

full_name: AddSubsemigroup.coe_copy
code: @[to_additive (attr := simp)]
theorem coe_copy {s : Set M} (hs : s = S) : (S.copy s hs : Set M) = s 
goal: ↑(S.copy s hs) = s

full_name: Subsemigroup.coe_copy
code: @[to_additive (attr := simp)]
theorem coe_copy {s : Set M} (hs : s = S) : (S.copy s hs : Set M) = s 
goal: ↑(S.copy s hs) = s

full_name: AddSubsemigroup.copy_eq
code: @[to_additive]
theorem copy_eq {s : Set M} (hs : s = S) : S.copy s hs = S 
goal: S.copy s hs = S

full_name: Subsemigroup.copy_eq
code: @[to_additive]
theorem copy_eq {s : Set M} (hs : s = S) : S.copy s hs = S 
goal: S.copy s hs = S

full_name: AddSubsemigroup.add_mem
code: /-- A subsemigroup is closed under multiplication. -/
@[to_additive "An `AddSubsemigroup` is closed under addition."]
protected theorem mul_mem {x y : M} : x ∈ S → y ∈ S → x * y ∈ S 
goal: x ∈ S → y ∈ S → x + y ∈ S

full_name: Subsemigroup.mul_mem
code: /-- A subsemigroup is closed under multiplication. -/
@[to_additive "An `AddSubsemigroup` is closed under addition."]
protected theorem mul_mem {x y : M} : x ∈ S → y ∈ S → x * y ∈ S 
goal: x ∈ S → y ∈ S → x * y ∈ S

full_name: Subsemigroup.instTop
code: /-- The subsemigroup `M` of the magma `M`. -/
@[to_additive "The additive subsemigroup `M` of the magma `M`."]
instance : Top (Subsemigroup M) 
goal: Top (Subsemigroup M)

full_name: AddSubsemigroup.instTop
code: /-- The subsemigroup `M` of the magma `M`. -/
@[to_additive "The additive subsemigroup `M` of the magma `M`."]
instance : Top (Subsemigroup M) 
goal: Top (AddSubsemigroup M)

full_name: Subsemigroup.instBot
code: /-- The trivial subsemigroup `∅` of a magma `M`. -/
@[to_additive "The trivial `AddSubsemigroup` `∅` of an additive magma `M`."]
instance : Bot (Subsemigroup M) 
goal: Bot (Subsemigroup M)

full_name: AddSubsemigroup.instBot
code: /-- The trivial subsemigroup `∅` of a magma `M`. -/
@[to_additive "The trivial `AddSubsemigroup` `∅` of an additive magma `M`."]
instance : Bot (Subsemigroup M) 
goal: Bot (AddSubsemigroup M)

full_name: Subsemigroup.instInhabited
code: @[to_additive]
instance : Inhabited (Subsemigroup M) 
goal: Inhabited (Subsemigroup M)

full_name: AddSubsemigroup.instInhabited
code: @[to_additive]
instance : Inhabited (Subsemigroup M) 
goal: Inhabited (AddSubsemigroup M)

full_name: AddSubsemigroup.not_mem_bot
code: @[to_additive]
theorem not_mem_bot {x : M} : x ∉ (⊥ : Subsemigroup M) 
goal: x ∉ ⊥

full_name: Subsemigroup.not_mem_bot
code: @[to_additive]
theorem not_mem_bot {x : M} : x ∉ (⊥ : Subsemigroup M) 
goal: x ∉ ⊥

full_name: Subsemigroup.mem_top
code: @[to_additive (attr := simp)]
theorem mem_top (x : M) : x ∈ (⊤ : Subsemigroup M) 
goal: x ∈ ⊤

full_name: AddSubsemigroup.mem_top
code: @[to_additive (attr := simp)]
theorem mem_top (x : M) : x ∈ (⊤ : Subsemigroup M) 
goal: x ∈ ⊤

full_name: AddSubsemigroup.coe_top
code: @[to_additive (attr := simp)]
theorem coe_top : ((⊤ : Subsemigroup M) : Set M) = Set.univ 
goal: ↑⊤ = Set.univ

full_name: Subsemigroup.coe_top
code: @[to_additive (attr := simp)]
theorem coe_top : ((⊤ : Subsemigroup M) : Set M) = Set.univ 
goal: ↑⊤ = Set.univ

full_name: AddSubsemigroup.coe_bot
code: @[to_additive (attr := simp)]
theorem coe_bot : ((⊥ : Subsemigroup M) : Set M) = ∅ 
goal: ↑⊥ = ∅

full_name: Subsemigroup.coe_bot
code: @[to_additive (attr := simp)]
theorem coe_bot : ((⊥ : Subsemigroup M) : Set M) = ∅ 
goal: ↑⊥ = ∅

full_name: AddSubsemigroup.instInf
code: /-- The inf of two subsemigroups is their intersection. -/
@[to_additive "The inf of two `AddSubsemigroup`s is their intersection."]
instance : Inf (Subsemigroup M) 
goal: Inf (AddSubsemigroup M)

full_name: Subsemigroup.instInf
code: /-- The inf of two subsemigroups is their intersection. -/
@[to_additive "The inf of two `AddSubsemigroup`s is their intersection."]
instance : Inf (Subsemigroup M) 
goal: Inf (Subsemigroup M)

full_name: Subsemigroup.coe_inf
code: @[to_additive (attr := simp)]
theorem coe_inf (p p' : Subsemigroup M) : ((p ⊓ p' : Subsemigroup M) : Set M) = (p : Set M) ∩ p' 
goal: ↑(p ⊓ p') = ↑p ∩ ↑p'

full_name: AddSubsemigroup.coe_inf
code: @[to_additive (attr := simp)]
theorem coe_inf (p p' : Subsemigroup M) : ((p ⊓ p' : Subsemigroup M) : Set M) = (p : Set M) ∩ p' 
goal: ↑(p ⊓ p') = ↑p ∩ ↑p'

full_name: Subsemigroup.mem_inf
code: @[to_additive (attr := simp)]
theorem mem_inf {p p' : Subsemigroup M} {x : M} : x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p' 
goal: x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p'

full_name: AddSubsemigroup.mem_inf
code: @[to_additive (attr := simp)]
theorem mem_inf {p p' : Subsemigroup M} {x : M} : x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p' 
goal: x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p'

full_name: Subsemigroup.instInfSet
code: @[to_additive]
instance : InfSet (Subsemigroup M) 
goal: InfSet (Subsemigroup M)

full_name: AddSubsemigroup.instInfSet
code: @[to_additive]
instance : InfSet (Subsemigroup M) 
goal: InfSet (AddSubsemigroup M)

full_name: AddSubsemigroup.coe_sInf
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_sInf (S : Set (Subsemigroup M)) : ((sInf S : Subsemigroup M) : Set M) = ⋂ s ∈ S, ↑s 
goal: ↑(sInf S) = ⋂ s ∈ S, ↑s

full_name: Subsemigroup.coe_sInf
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_sInf (S : Set (Subsemigroup M)) : ((sInf S : Subsemigroup M) : Set M) = ⋂ s ∈ S, ↑s 
goal: ↑(sInf S) = ⋂ s ∈ S, ↑s

full_name: AddSubsemigroup.mem_sInf
code: @[to_additive]
theorem mem_sInf {S : Set (Subsemigroup M)} {x : M} : x ∈ sInf S ↔ ∀ p ∈ S, x ∈ p 
goal: x ∈ sInf S ↔ ∀ p ∈ S, x ∈ p

full_name: Subsemigroup.mem_sInf
code: @[to_additive]
theorem mem_sInf {S : Set (Subsemigroup M)} {x : M} : x ∈ sInf S ↔ ∀ p ∈ S, x ∈ p 
goal: x ∈ sInf S ↔ ∀ p ∈ S, x ∈ p

full_name: Subsemigroup.mem_iInf
code: @[to_additive]
theorem mem_iInf {ι : Sort*} {S : ι → Subsemigroup M} {x : M} : (x ∈ ⨅ i, S i) ↔ ∀ i, x ∈ S i 
goal: x ∈ ⨅ i, S i ↔ ∀ (i : ι), x ∈ S i

full_name: AddSubsemigroup.mem_iInf
code: @[to_additive]
theorem mem_iInf {ι : Sort*} {S : ι → Subsemigroup M} {x : M} : (x ∈ ⨅ i, S i) ↔ ∀ i, x ∈ S i 
goal: x ∈ ⨅ i, S i ↔ ∀ (i : ι), x ∈ S i

full_name: Subsemigroup.coe_iInf
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_iInf {ι : Sort*} {S : ι → Subsemigroup M} : (↑(⨅ i, S i) : Set M) = ⋂ i, S i 
goal: ↑(⨅ i, S i) = ⋂ i, ↑(S i)

full_name: AddSubsemigroup.coe_iInf
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_iInf {ι : Sort*} {S : ι → Subsemigroup M} : (↑(⨅ i, S i) : Set M) = ⋂ i, S i 
goal: ↑(⨅ i, S i) = ⋂ i, ↑(S i)

full_name: Subsemigroup.instCompleteLattice
code: /-- subsemigroups of a monoid form a complete lattice. -/
@[to_additive "The `AddSubsemigroup`s of an `AddMonoid` form a complete lattice."]
instance : CompleteLattice (Subsemigroup M) 
goal: CompleteLattice (Subsemigroup M)

full_name: AddSubsemigroup.instCompleteLattice
code: /-- subsemigroups of a monoid form a complete lattice. -/
@[to_additive "The `AddSubsemigroup`s of an `AddMonoid` form a complete lattice."]
instance : CompleteLattice (Subsemigroup M) 
goal: CompleteLattice (AddSubsemigroup M)

full_name: Subsemigroup.subsingleton_of_subsingleton
code: @[to_additive]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M 
goal: Subsingleton M

full_name: AddSubsemigroup.subsingleton_of_subsingleton
code: @[to_additive]
theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M 
goal: Subsingleton M

full_name: AddSubsemigroup.instNontrivialOfNonempty
code: @[to_additive]
instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) 
goal: Nontrivial (AddSubsemigroup M)

full_name: Subsemigroup.instNontrivialOfNonempty
code: @[to_additive]
instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) 
goal: Nontrivial (Subsemigroup M)

full_name: AddSubsemigroup.closure
code: /-- The `Subsemigroup` generated by a set. -/
@[to_additive "The `AddSubsemigroup` generated by a set"]
def closure (s : Set M) : Subsemigroup M 
goal: AddSubsemigroup M

full_name: Subsemigroup.closure
code: /-- The `Subsemigroup` generated by a set. -/
@[to_additive "The `AddSubsemigroup` generated by a set"]
def closure (s : Set M) : Subsemigroup M 
goal: Subsemigroup M

full_name: Subsemigroup.mem_closure
code: @[to_additive]
theorem mem_closure {x : M} : x ∈ closure s ↔ ∀ S : Subsemigroup M, s ⊆ S → x ∈ S 
goal: x ∈ Subsemigroup.closure s ↔ ∀ (S : Subsemigroup M), s ⊆ ↑S → x ∈ S

full_name: AddSubsemigroup.mem_closure
code: @[to_additive]
theorem mem_closure {x : M} : x ∈ closure s ↔ ∀ S : Subsemigroup M, s ⊆ S → x ∈ S 
goal: x ∈ AddSubsemigroup.closure s ↔ ∀ (S : AddSubsemigroup M), s ⊆ ↑S → x ∈ S

full_name: AddSubsemigroup.subset_closure
code: /-- The subsemigroup generated by a set includes the set. -/
@[to_additive (attr := simp, aesop safe 20 apply (rule_sets := [SetLike]))
  "The `AddSubsemigroup` generated by a set includes the set."]
theorem subset_closure : s ⊆ closure s 
goal: s ⊆ ↑(AddSubsemigroup.closure s)

full_name: Subsemigroup.subset_closure
code: /-- The subsemigroup generated by a set includes the set. -/
@[to_additive (attr := simp, aesop safe 20 apply (rule_sets := [SetLike]))
  "The `AddSubsemigroup` generated by a set includes the set."]
theorem subset_closure : s ⊆ closure s 
goal: s ⊆ ↑(Subsemigroup.closure s)

full_name: Subsemigroup.not_mem_of_not_mem_closure
code: @[to_additive]
theorem not_mem_of_not_mem_closure {P : M} (hP : P ∉ closure s) : P ∉ s 
goal: P ∉ s

full_name: AddSubsemigroup.not_mem_of_not_mem_closure
code: @[to_additive]
theorem not_mem_of_not_mem_closure {P : M} (hP : P ∉ closure s) : P ∉ s 
goal: P ∉ s

full_name: AddSubsemigroup.closure_le
code: /-- A subsemigroup `S` includes `closure s` if and only if it includes `s`. -/
@[to_additive (attr := simp)
  "An additive subsemigroup `S` includes `closure s` if and only if it includes `s`"]
theorem closure_le : closure s ≤ S ↔ s ⊆ S 
goal: AddSubsemigroup.closure s ≤ S ↔ s ⊆ ↑S

full_name: Subsemigroup.closure_le
code: /-- A subsemigroup `S` includes `closure s` if and only if it includes `s`. -/
@[to_additive (attr := simp)
  "An additive subsemigroup `S` includes `closure s` if and only if it includes `s`"]
theorem closure_le : closure s ≤ S ↔ s ⊆ S 
goal: Subsemigroup.closure s ≤ S ↔ s ⊆ ↑S

full_name: Subsemigroup.closure_mono
code: /-- subsemigroup closure of a set is monotone in its argument: if `s ⊆ t`,
then `closure s ≤ closure t`. -/
@[to_additive "Additive subsemigroup closure of a set is monotone in its argument: if `s ⊆ t`,
  then `closure s ≤ closure t`"]
theorem closure_mono ⦃s t : Set M⦄ (h : s ⊆ t) : closure s ≤ closure t 
goal: Subsemigroup.closure s ≤ Subsemigroup.closure t

full_name: AddSubsemigroup.closure_mono
code: /-- subsemigroup closure of a set is monotone in its argument: if `s ⊆ t`,
then `closure s ≤ closure t`. -/
@[to_additive "Additive subsemigroup closure of a set is monotone in its argument: if `s ⊆ t`,
  then `closure s ≤ closure t`"]
theorem closure_mono ⦃s t : Set M⦄ (h : s ⊆ t) : closure s ≤ closure t 
goal: AddSubsemigroup.closure s ≤ AddSubsemigroup.closure t

full_name: AddSubsemigroup.closure_eq_of_le
code: @[to_additive]
theorem closure_eq_of_le (h₁ : s ⊆ S) (h₂ : S ≤ closure s) : closure s = S 
goal: AddSubsemigroup.closure s = S

full_name: Subsemigroup.closure_eq_of_le
code: @[to_additive]
theorem closure_eq_of_le (h₁ : s ⊆ S) (h₂ : S ≤ closure s) : closure s = S 
goal: Subsemigroup.closure s = S

full_name: AddSubsemigroup.closure_induction
code: /-- An induction principle for closure membership. If `p` holds for all elements of `s`, and
is preserved under multiplication, then `p` holds for all elements of the closure of `s`. -/
@[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership. If `p`
  holds for all elements of `s`, and is preserved under addition, then `p` holds for all
  elements of the additive closure of `s`."]
theorem closure_induction {p : M → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x)
    (mul : ∀ x y, p x → p y → p (x * y)) : p x 
goal: p x

full_name: Subsemigroup.closure_induction
code: /-- An induction principle for closure membership. If `p` holds for all elements of `s`, and
is preserved under multiplication, then `p` holds for all elements of the closure of `s`. -/
@[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership. If `p`
  holds for all elements of `s`, and is preserved under addition, then `p` holds for all
  elements of the additive closure of `s`."]
theorem closure_induction {p : M → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x)
    (mul : ∀ x y, p x → p y → p (x * y)) : p x 
goal: p x

full_name: Subsemigroup.closure_induction'
code: /-- 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}
    (mem : ∀ (x) (h : x ∈ s), p x (subset_closure h))
    (mul : ∀ 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 
goal: p x hx

full_name: AddSubsemigroup.closure_induction'
code: /-- 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}
    (mem : ∀ (x) (h : x ∈ s), p x (subset_closure h))
    (mul : ∀ 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 
goal: p x hx

full_name: AddSubsemigroup.closure_induction₂
code: /-- An induction principle for closure membership for predicates with two arguments.  -/
@[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership for
  predicates with two arguments."]
theorem closure_induction₂ {p : M → M → Prop} {x} {y : M} (hx : x ∈ closure s) (hy : y ∈ closure s)
    (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (Hmul_left : ∀ x y z, p x z → p y z → p (x * y) z)
    (Hmul_right : ∀ x y z, p z x → p z y → p z (x * y)) : p x y 
goal: p x y

full_name: Subsemigroup.closure_induction₂
code: /-- An induction principle for closure membership for predicates with two arguments.  -/
@[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership for
  predicates with two arguments."]
theorem closure_induction₂ {p : M → M → Prop} {x} {y : M} (hx : x ∈ closure s) (hy : y ∈ closure s)
    (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (Hmul_left : ∀ x y z, p x z → p y z → p (x * y) z)
    (Hmul_right : ∀ x y z, p z x → p z y → p z (x * y)) : p x y 
goal: p x y

full_name: Subsemigroup.dense_induction
code: /-- 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 = ⊤)
    (mem : ∀ x ∈ s, p x)
    (mul : ∀ x y, p x → p y → p (x * y)) : p x 
goal: p x

full_name: AddSubsemigroup.dense_induction
code: /-- 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 = ⊤)
    (mem : ∀ x ∈ s, p x)
    (mul : ∀ x y, p x → p y → p (x * y)) : p x 
goal: p x

full_name: AddSubsemigroup.gi
code: /-- `closure` forms a Galois insertion with the coercion to set. -/
@[to_additive "`closure` forms a Galois insertion with the coercion to set."]
protected def gi : GaloisInsertion (@closure M _) SetLike.coe 
goal: GaloisInsertion AddSubsemigroup.closure SetLike.coe

full_name: Subsemigroup.gi
code: /-- `closure` forms a Galois insertion with the coercion to set. -/
@[to_additive "`closure` forms a Galois insertion with the coercion to set."]
protected def gi : GaloisInsertion (@closure M _) SetLike.coe 
goal: GaloisInsertion Subsemigroup.closure SetLike.coe

full_name: Subsemigroup.closure_eq
code: /-- Closure of a subsemigroup `S` equals `S`. -/
@[to_additive (attr := simp) "Additive closure of an additive subsemigroup `S` equals `S`"]
theorem closure_eq : closure (S : Set M) = S 
goal: Subsemigroup.closure ↑S = S

full_name: AddSubsemigroup.closure_eq
code: /-- Closure of a subsemigroup `S` equals `S`. -/
@[to_additive (attr := simp) "Additive closure of an additive subsemigroup `S` equals `S`"]
theorem closure_eq : closure (S : Set M) = S 
goal: AddSubsemigroup.closure ↑S = S

full_name: AddSubsemigroup.closure_empty
code: @[to_additive (attr := simp)]
theorem closure_empty : closure (∅ : Set M) = ⊥ 
goal: AddSubsemigroup.closure ∅ = ⊥

full_name: Subsemigroup.closure_empty
code: @[to_additive (attr := simp)]
theorem closure_empty : closure (∅ : Set M) = ⊥ 
goal: Subsemigroup.closure ∅ = ⊥

full_name: AddSubsemigroup.closure_univ
code: @[to_additive (attr := simp)]
theorem closure_univ : closure (univ : Set M) = ⊤ 
goal: AddSubsemigroup.closure Set.univ = ⊤

full_name: Subsemigroup.closure_univ
code: @[to_additive (attr := simp)]
theorem closure_univ : closure (univ : Set M) = ⊤ 
goal: Subsemigroup.closure Set.univ = ⊤

full_name: AddSubsemigroup.closure_union
code: @[to_additive]
theorem closure_union (s t : Set M) : closure (s ∪ t) = closure s ⊔ closure t 
goal: AddSubsemigroup.closure (s ∪ t) = AddSubsemigroup.closure s ⊔ AddSubsemigroup.closure t

full_name: Subsemigroup.closure_union
code: @[to_additive]
theorem closure_union (s t : Set M) : closure (s ∪ t) = closure s ⊔ closure t 
goal: Subsemigroup.closure (s ∪ t) = Subsemigroup.closure s ⊔ Subsemigroup.closure t

full_name: Subsemigroup.closure_iUnion
code: @[to_additive]
theorem closure_iUnion {ι} (s : ι → Set M) : closure (⋃ i, s i) = ⨆ i, closure (s i) 
goal: Subsemigroup.closure (⋃ i, s i) = ⨆ i, Subsemigroup.closure (s i)

full_name: AddSubsemigroup.closure_iUnion
code: @[to_additive]
theorem closure_iUnion {ι} (s : ι → Set M) : closure (⋃ i, s i) = ⨆ i, closure (s i) 
goal: AddSubsemigroup.closure (⋃ i, s i) = ⨆ i, AddSubsemigroup.closure (s i)

full_name: Subsemigroup.closure_singleton_le_iff_mem
code: @[to_additive]
theorem closure_singleton_le_iff_mem (m : M) (p : Subsemigroup M) : closure {m} ≤ p ↔ m ∈ p 
goal: Subsemigroup.closure {m} ≤ p ↔ m ∈ p

full_name: AddSubsemigroup.closure_singleton_le_iff_mem
code: @[to_additive]
theorem closure_singleton_le_iff_mem (m : M) (p : Subsemigroup M) : closure {m} ≤ p ↔ m ∈ p 
goal: AddSubsemigroup.closure {m} ≤ p ↔ m ∈ p

full_name: AddSubsemigroup.mem_iSup
code: @[to_additive]
theorem mem_iSup {ι : Sort*} (p : ι → Subsemigroup M) {m : M} :
    (m ∈ ⨆ i, p i) ↔ ∀ N, (∀ i, p i ≤ N) → m ∈ N 
goal: m ∈ ⨆ i, p i ↔ ∀ (N : AddSubsemigroup M), (∀ (i : ι), p i ≤ N) → m ∈ N

full_name: Subsemigroup.mem_iSup
code: @[to_additive]
theorem mem_iSup {ι : Sort*} (p : ι → Subsemigroup M) {m : M} :
    (m ∈ ⨆ i, p i) ↔ ∀ N, (∀ i, p i ≤ N) → m ∈ N 
goal: m ∈ ⨆ i, p i ↔ ∀ (N : Subsemigroup M), (∀ (i : ι), p i ≤ N) → m ∈ N

full_name: AddSubsemigroup.iSup_eq_closure
code: @[to_additive]
theorem iSup_eq_closure {ι : Sort*} (p : ι → Subsemigroup M) :
    ⨆ i, p i = Subsemigroup.closure (⋃ i, (p i : Set M)) 
goal: ⨆ i, p i = AddSubsemigroup.closure (⋃ i, ↑(p i))

full_name: Subsemigroup.iSup_eq_closure
code: @[to_additive]
theorem iSup_eq_closure {ι : Sort*} (p : ι → Subsemigroup M) :
    ⨆ i, p i = Subsemigroup.closure (⋃ i, (p i : Set M)) 
goal: ⨆ i, p i = Subsemigroup.closure (⋃ i, ↑(p i))

full_name: MulHom.eqLocus
code: /-- 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 
goal: Subsemigroup M

full_name: AddHom.eqLocus
code: /-- 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 
goal: AddSubsemigroup M

full_name: AddHom.eqOn_closure
code: /-- If two mul homomorphisms are equal on a set, then they are equal on its subsemigroup closure. -/
@[to_additive "If two add homomorphisms are equal on a set,
  then they are equal on its additive subsemigroup closure."]
theorem eqOn_closure {f g : M →ₙ* N} {s : Set M} (h : Set.EqOn f g s) :
    Set.EqOn f g (closure s) 
goal: Set.EqOn ⇑f ⇑g ↑(AddSubsemigroup.closure s)

full_name: MulHom.eqOn_closure
code: /-- If two mul homomorphisms are equal on a set, then they are equal on its subsemigroup closure. -/
@[to_additive "If two add homomorphisms are equal on a set,
  then they are equal on its additive subsemigroup closure."]
theorem eqOn_closure {f g : M →ₙ* N} {s : Set M} (h : Set.EqOn f g s) :
    Set.EqOn f g (closure s) 
goal: Set.EqOn ⇑f ⇑g ↑(Subsemigroup.closure s)

full_name: AddHom.eq_of_eqOn_top
code: @[to_additive]
theorem eq_of_eqOn_top {f g : M →ₙ* N} (h : Set.EqOn f g (⊤ : Subsemigroup M)) : f = g 
goal: f = g

full_name: MulHom.eq_of_eqOn_top
code: @[to_additive]
theorem eq_of_eqOn_top {f g : M →ₙ* N} (h : Set.EqOn f g (⊤ : Subsemigroup M)) : f = g 
goal: f = g

full_name: MulHom.eq_of_eqOn_dense
code: @[to_additive]
theorem eq_of_eqOn_dense {s : Set M} (hs : closure s = ⊤) {f g : M →ₙ* N} (h : s.EqOn f g) :
    f = g 
goal: f = g

full_name: AddHom.eq_of_eqOn_dense
code: @[to_additive]
theorem eq_of_eqOn_dense {s : Set M} (hs : closure s = ⊤) {f g : M →ₙ* N} (h : s.EqOn f g) :
    f = g 
goal: f = g

full_name: AddHom.ofDense
code: /-- 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 
goal: AddHom M N

full_name: MulHom.ofDense
code: /-- 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 
goal: M →ₙ* N

full_name: MulHom.coe_ofDense
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_ofDense [Semigroup M] [Semigroup N] {s : Set M} (f : M → N) (hs : closure s = ⊤)
    (hmul) : (ofDense f hs hmul : M → N) = f 
goal: ⇑(MulHom.ofDense f hs hmul) = f

full_name: AddHom.coe_ofDense
code: @[to_additive (attr := simp, norm_cast)]
theorem coe_ofDense [Semigroup M] [Semigroup N] {s : Set M} (f : M → N) (hs : closure s = ⊤)
    (hmul) : (ofDense f hs hmul : M → N) = f 
goal: ⇑(AddHom.ofDense f hs hmul) = f