Module docstring
{"# Submonoid of opposite monoids
For every monoid M, we construct an equivalence between submonoids of M and that of Mᵐᵒᵖ.
","### Lattice results "}
{"# Submonoid of opposite monoids
For every monoid M, we construct an equivalence between submonoids of M and that of Mᵐᵒᵖ.
","### Lattice results "}
Submonoid.op
      definition
     (x : Submonoid M) : Submonoid Mᵐᵒᵖ
        /-- Pull a submonoid back to an opposite submonoid along `MulOpposite.unop` -/
@[to_additive (attr := simps) "Pull an additive submonoid back to an opposite submonoid along
`AddOpposite.unop`"]
protected def op (x : Submonoid M) : Submonoid Mᵐᵒᵖ where
  carrier := MulOpposite.unopMulOpposite.unop ⁻¹' x
  mul_mem' ha hb := x.mul_mem hb ha
  one_mem' := Submonoid.one_mem' _
        Submonoid.mem_op
      theorem
     {x : Mᵐᵒᵖ} {S : Submonoid M} : x ∈ S.op ↔ x.unop ∈ S
        @[to_additive (attr := simp)]
theorem mem_op {x : Mᵐᵒᵖ} {S : Submonoid M} : x ∈ S.opx ∈ S.op ↔ x.unop ∈ S := Iff.rfl
        Submonoid.unop
      definition
     (x : Submonoid Mᵐᵒᵖ) : Submonoid M
        /-- Pull an opposite submonoid back to a submonoid along `MulOpposite.op` -/
@[to_additive (attr := simps) "Pull an opposite additive submonoid back to a submonoid along
`AddOpposite.op`"]
protected def unop (x : Submonoid Mᵐᵒᵖ) : Submonoid M where
  carrier := MulOpposite.opMulOpposite.op ⁻¹' x
  mul_mem' ha hb := x.mul_mem hb ha
  one_mem' := Submonoid.one_mem' _
        Submonoid.mem_unop
      theorem
     {x : M} {S : Submonoid Mᵐᵒᵖ} : x ∈ S.unop ↔ MulOpposite.op x ∈ S
        @[to_additive (attr := simp)]
theorem mem_unop {x : M} {S : Submonoid Mᵐᵒᵖ} : x ∈ S.unopx ∈ S.unop ↔ MulOpposite.op x ∈ S := Iff.rfl
        Submonoid.unop_op
      theorem
     (S : Submonoid M) : S.op.unop = S
        
      Submonoid.op_unop
      theorem
     (S : Submonoid Mᵐᵒᵖ) : S.unop.op = S
        
      Submonoid.op_le_iff
      theorem
     {S₁ : Submonoid M} {S₂ : Submonoid Mᵐᵒᵖ} : S₁.op ≤ S₂ ↔ S₁ ≤ S₂.unop
        @[to_additive]
theorem op_le_iff {S₁ : Submonoid M} {S₂ : Submonoid Mᵐᵒᵖ} : S₁.op ≤ S₂ ↔ S₁ ≤ S₂.unop :=
  MulOpposite.op_surjective.forall
        Submonoid.le_op_iff
      theorem
     {S₁ : Submonoid Mᵐᵒᵖ} {S₂ : Submonoid M} : S₁ ≤ S₂.op ↔ S₁.unop ≤ S₂
        @[to_additive]
theorem le_op_iff {S₁ : Submonoid Mᵐᵒᵖ} {S₂ : Submonoid M} : S₁ ≤ S₂.op ↔ S₁.unop ≤ S₂ :=
  MulOpposite.op_surjective.forall
        Submonoid.op_le_op_iff
      theorem
     {S₁ S₂ : Submonoid M} : S₁.op ≤ S₂.op ↔ S₁ ≤ S₂
        @[to_additive (attr := simp)]
theorem op_le_op_iff {S₁ S₂ : Submonoid M} : S₁.op ≤ S₂.op ↔ S₁ ≤ S₂ :=
  MulOpposite.op_surjective.forall
        Submonoid.unop_le_unop_iff
      theorem
     {S₁ S₂ : Submonoid Mᵐᵒᵖ} : S₁.unop ≤ S₂.unop ↔ S₁ ≤ S₂
        @[to_additive (attr := simp)]
theorem unop_le_unop_iff {S₁ S₂ : Submonoid Mᵐᵒᵖ} : S₁.unop ≤ S₂.unop ↔ S₁ ≤ S₂ :=
  MulOpposite.unop_surjective.forall
        Submonoid.opEquiv
      definition
     : Submonoid M ≃o Submonoid Mᵐᵒᵖ
        /-- A submonoid `H` of `G` determines a submonoid `H.op` of the opposite group `Gᵐᵒᵖ`. -/
@[to_additive (attr := simps) "A additive submonoid `H` of `G` determines an additive submonoid
`H.op` of the opposite group `Gᵐᵒᵖ`."]
def opEquiv : SubmonoidSubmonoid M ≃o Submonoid Mᵐᵒᵖ where
  toFun := Submonoid.op
  invFun := Submonoid.unop
  left_inv := unop_op
  right_inv := op_unop
  map_rel_iff' := op_le_op_iff
        Submonoid.op_injective
      theorem
     : (@Submonoid.op M _).Injective
        @[to_additive]
theorem op_injective : (@Submonoid.op M _).Injective := opEquiv.injective
        Submonoid.unop_injective
      theorem
     : (@Submonoid.unop M _).Injective
        @[to_additive]
theorem unop_injective : (@Submonoid.unop M _).Injective := opEquiv.symm.injective
        Submonoid.op_inj
      theorem
     {S T : Submonoid M} : S.op = T.op ↔ S = T
        @[to_additive (attr := simp)]
theorem op_inj {S T : Submonoid M} : S.op = T.op ↔ S = T := opEquiv.eq_iff_eq
        Submonoid.unop_inj
      theorem
     {S T : Submonoid Mᵐᵒᵖ} : S.unop = T.unop ↔ S = T
        @[to_additive (attr := simp)]
theorem unop_inj {S T : Submonoid Mᵐᵒᵖ} : S.unop = T.unop ↔ S = T := opEquiv.symm.eq_iff_eq
        Submonoid.op_bot
      theorem
     : (⊥ : Submonoid M).op = ⊥
        
      Submonoid.op_eq_bot
      theorem
     {S : Submonoid M} : S.op = ⊥ ↔ S = ⊥
        @[to_additive (attr := simp)]
theorem op_eq_bot {S : Submonoid M} : S.op = ⊥ ↔ S = ⊥ := op_injective.eq_iff' op_bot
        Submonoid.unop_bot
      theorem
     : (⊥ : Submonoid Mᵐᵒᵖ).unop = ⊥
        
      Submonoid.unop_eq_bot
      theorem
     {S : Submonoid Mᵐᵒᵖ} : S.unop = ⊥ ↔ S = ⊥
        @[to_additive (attr := simp)]
theorem unop_eq_bot {S : Submonoid Mᵐᵒᵖ} : S.unop = ⊥ ↔ S = ⊥ := unop_injective.eq_iff' unop_bot
        Submonoid.op_top
      theorem
     : (⊤ : Submonoid M).op = ⊤
        
      Submonoid.op_eq_top
      theorem
     {S : Submonoid M} : S.op = ⊤ ↔ S = ⊤
        @[to_additive (attr := simp)]
theorem op_eq_top {S : Submonoid M} : S.op = ⊤ ↔ S = ⊤ := op_injective.eq_iff' op_top
        Submonoid.unop_top
      theorem
     : (⊤ : Submonoid Mᵐᵒᵖ).unop = ⊤
        
      Submonoid.unop_eq_top
      theorem
     {S : Submonoid Mᵐᵒᵖ} : S.unop = ⊤ ↔ S = ⊤
        @[to_additive (attr := simp)]
theorem unop_eq_top {S : Submonoid Mᵐᵒᵖ} : S.unop = ⊤ ↔ S = ⊤ := unop_injective.eq_iff' unop_top
        Submonoid.op_sup
      theorem
     (S₁ S₂ : Submonoid M) : (S₁ ⊔ S₂).op = S₁.op ⊔ S₂.op
        @[to_additive]
theorem op_sup (S₁ S₂ : Submonoid M) : (S₁ ⊔ S₂).op = S₁.op ⊔ S₂.op :=
  opEquiv.map_sup _ _
        Submonoid.unop_sup
      theorem
     (S₁ S₂ : Submonoid Mᵐᵒᵖ) : (S₁ ⊔ S₂).unop = S₁.unop ⊔ S₂.unop
        @[to_additive]
theorem unop_sup (S₁ S₂ : Submonoid Mᵐᵒᵖ) : (S₁ ⊔ S₂).unop = S₁.unop ⊔ S₂.unop :=
  opEquiv.symm.map_sup _ _
        Submonoid.op_inf
      theorem
     (S₁ S₂ : Submonoid M) : (S₁ ⊓ S₂).op = S₁.op ⊓ S₂.op
        @[to_additive]
theorem op_inf (S₁ S₂ : Submonoid M) : (S₁ ⊓ S₂).op = S₁.op ⊓ S₂.op := rfl
        Submonoid.unop_inf
      theorem
     (S₁ S₂ : Submonoid Mᵐᵒᵖ) : (S₁ ⊓ S₂).unop = S₁.unop ⊓ S₂.unop
        @[to_additive]
theorem unop_inf (S₁ S₂ : Submonoid Mᵐᵒᵖ) : (S₁ ⊓ S₂).unop = S₁.unop ⊓ S₂.unop := rfl
        Submonoid.op_sSup
      theorem
     (S : Set (Submonoid M)) : (sSup S).op = sSup (.unop ⁻¹' S)
        @[to_additive]
theorem op_sSup (S : Set (Submonoid M)) : (sSup S).op = sSup (.unop.unop ⁻¹' S) :=
  opEquiv.map_sSup_eq_sSup_symm_preimage _
        Submonoid.unop_sSup
      theorem
     (S : Set (Submonoid Mᵐᵒᵖ)) : (sSup S).unop = sSup (.op ⁻¹' S)
        
      Submonoid.op_sInf
      theorem
     (S : Set (Submonoid M)) : (sInf S).op = sInf (.unop ⁻¹' S)
        @[to_additive]
theorem op_sInf (S : Set (Submonoid M)) : (sInf S).op = sInf (.unop.unop ⁻¹' S) :=
  opEquiv.map_sInf_eq_sInf_symm_preimage _
        Submonoid.unop_sInf
      theorem
     (S : Set (Submonoid Mᵐᵒᵖ)) : (sInf S).unop = sInf (.op ⁻¹' S)
        
      Submonoid.op_iSup
      theorem
     (S : ι → Submonoid M) : (iSup S).op = ⨆ i, (S i).op
        @[to_additive]
theorem op_iSup (S : ι → Submonoid M) : (iSup S).op = ⨆ i, (S i).op := opEquiv.map_iSup _
        Submonoid.unop_iSup
      theorem
     (S : ι → Submonoid Mᵐᵒᵖ) : (iSup S).unop = ⨆ i, (S i).unop
        @[to_additive]
theorem unop_iSup (S : ι → Submonoid Mᵐᵒᵖ) : (iSup S).unop = ⨆ i, (S i).unop :=
  opEquiv.symm.map_iSup _
        Submonoid.op_iInf
      theorem
     (S : ι → Submonoid M) : (iInf S).op = ⨅ i, (S i).op
        @[to_additive]
theorem op_iInf (S : ι → Submonoid M) : (iInf S).op = ⨅ i, (S i).op := opEquiv.map_iInf _
        Submonoid.unop_iInf
      theorem
     (S : ι → Submonoid Mᵐᵒᵖ) : (iInf S).unop = ⨅ i, (S i).unop
        @[to_additive]
theorem unop_iInf (S : ι → Submonoid Mᵐᵒᵖ) : (iInf S).unop = ⨅ i, (S i).unop :=
  opEquiv.symm.map_iInf _
        Submonoid.op_closure
      theorem
     (s : Set M) : (closure s).op = closure (MulOpposite.unop ⁻¹' s)
        @[to_additive]
theorem op_closure (s : Set M) : (closure s).op = closure (MulOpposite.unopMulOpposite.unop ⁻¹' s) := by
  simp_rw [closure, op_sInf, Set.preimage_setOf_eq, Submonoid.coe_unop]
  congr with a
  exact MulOpposite.unop_surjective.forall
        Submonoid.unop_closure
      theorem
     (s : Set Mᵐᵒᵖ) : (closure s).unop = closure (MulOpposite.op ⁻¹' s)
        @[to_additive]
theorem unop_closure (s : Set Mᵐᵒᵖ) : (closure s).unop = closure (MulOpposite.opMulOpposite.op ⁻¹' s) := by
  rw [← op_inj, op_unop, op_closure]
  simp_rw [Set.preimage_preimage, MulOpposite.op_unop, Set.preimage_id']
        Submonoid.equivOp
      definition
     (H : Submonoid M) : H ≃ H.op
        /-- Bijection between a submonoid `H` and its opposite. -/
@[to_additive (attr := simps!) "Bijection between an additive submonoid `H` and its opposite."]
def equivOp (H : Submonoid M) : H ≃ H.op :=
  MulOpposite.opEquiv.subtypeEquiv fun _ => Iff.rfl