l3lab/ntp-mathlib huggingface dataset:
theorem smul_mk [SMul R M] [IsScalarTower R M M] (c : R) (a b) :
    c • (mk a b : Localization S) = mk (c • a) b := by
 simp only [HSMul.hSMul, instHSMul, SMul.smul, instSMulLocalization, Localization.smul]
 show liftOn (mk a b) (fun a b => mk (c • a) b) _ = _
 

Proof state:
M : Type u_1
inst✝⁴ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝³ : CommMonoid N
P : Type u_3
inst✝² : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝¹ : SMul R M
inst✝ : IsScalarTower R M M
c : R
a : M
b : ↥S
⊢ liftOn (mk a b) (fun a b => mk (c • a) b)
      (_ :
        ∀ {a c_1 : M} {b d : ↥S},
          (r S) (a, b) (c_1, d) → (fun a b => mk (SMul.smul c a) b) a b = (fun a b => mk (SMul.smul c a) b) c_1 d) =
    mk (SMul.smul c a) b

Next tactic:
exact liftOn_mk (fun a b => mk (c • a) b) _ a b
instance [SMul R₁ M] [SMul R₂ M] [IsScalarTower R₁ M M] [IsScalarTower R₂ M M]
  [SMulCommClass R₁ R₂ M] : SMulCommClass R₁ R₂ (Localization S) where
  smul_comm s t := Localization.ind <| Prod.rec fun r x ↦ by 

Proof state:
M : Type u_1
inst✝⁷ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁶ : CommMonoid N
P : Type u_3
inst✝⁵ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝⁴ : SMul R₁ M
inst✝³ : SMul R₂ M
inst✝² : IsScalarTower R₁ M M
inst✝¹ : IsScalarTower R₂ M M
inst✝ : SMulCommClass R₁ R₂ M
s : R₁
t : R₂
r : M
x : ↥S
⊢ s • t • mk (r, x).1 (r, x).2 = t • s • mk (r, x).1 (r, x).2

Next tactic:
simp only [smul_mk, smul_comm s t r]
instance [SMul R₁ M] [SMul R₂ M] [IsScalarTower R₁ M M] [IsScalarTower R₂ M M] [SMul R₁ R₂]
  [IsScalarTower R₁ R₂ M] : IsScalarTower R₁ R₂ (Localization S) where
  smul_assoc s t := Localization.ind <| Prod.rec fun r x ↦ by 

Proof state:
M : Type u_1
inst✝⁸ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁷ : CommMonoid N
P : Type u_3
inst✝⁶ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝⁵ : SMul R₁ M
inst✝⁴ : SMul R₂ M
inst✝³ : IsScalarTower R₁ M M
inst✝² : IsScalarTower R₂ M M
inst✝¹ : SMul R₁ R₂
inst✝ : IsScalarTower R₁ R₂ M
s : R₁
t : R₂
r : M
x : ↥S
⊢ (s • t) • mk (r, x).1 (r, x).2 = s • t • mk (r, x).1 (r, x).2

Next tactic:
simp only [smul_mk, smul_assoc s t r]
instance smulCommClass_right {R : Type*} [SMul R M] [IsScalarTower R M M] :
  SMulCommClass R (Localization S) (Localization S) where
  smul_comm s :=
      Localization.ind <|
        Prod.rec fun r₁ x₁ ↦
          Localization.ind <|
            Prod.rec fun r₂ x₂ ↦ by
              

Proof state:
M : Type u_1
inst✝⁴ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝³ : CommMonoid N
P : Type u_3
inst✝² : CommMonoid P
R✝ : Type u_4
R₁ : Type u_5
R₂ : Type u_6
R : Type u_7
inst✝¹ : SMul R M
inst✝ : IsScalarTower R M M
s : R
r₁ : M
x₁ : ↥S
r₂ : M
x₂ : ↥S
⊢ s • mk (r₁, x₁).1 (r₁, x₁).2 • mk (r₂, x₂).1 (r₂, x₂).2 = mk (r₁, x₁).1 (r₁, x₁).2 • s • mk (r₂, x₂).1 (r₂, x₂).2

Next tactic:
simp only [smul_mk, smul_eq_mul, mk_mul, mul_comm r₁, smul_mul_assoc]
instance isScalarTower_right {R : Type*} [SMul R M] [IsScalarTower R M M] :
  IsScalarTower R (Localization S) (Localization S) where
  smul_assoc s :=
    Localization.ind <|
      Prod.rec fun r₁ x₁ ↦
        Localization.ind <|
          Prod.rec fun r₂ x₂ ↦ by 

Proof state:
M : Type u_1
inst✝⁴ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝³ : CommMonoid N
P : Type u_3
inst✝² : CommMonoid P
R✝ : Type u_4
R₁ : Type u_5
R₂ : Type u_6
R : Type u_7
inst✝¹ : SMul R M
inst✝ : IsScalarTower R M M
s : R
r₁ : M
x₁ : ↥S
r₂ : M
x₂ : ↥S
⊢ (s • mk (r₁, x₁).1 (r₁, x₁).2) • mk (r₂, x₂).1 (r₂, x₂).2 = s • mk (r₁, x₁).1 (r₁, x₁).2 • mk (r₂, x₂).1 (r₂, x₂).2

Next tactic:
simp only [smul_mk, smul_eq_mul, mk_mul, smul_mul_assoc]
instance [SMul R M] [SMul Rᵐᵒᵖ M] [IsScalarTower R M M] [IsScalarTower Rᵐᵒᵖ M M]
  [IsCentralScalar R M] : IsCentralScalar R (Localization S) where
  op_smul_eq_smul s :=
    Localization.ind <| Prod.rec fun r x ↦ by 

Proof state:
M : Type u_1
inst✝⁷ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁶ : CommMonoid N
P : Type u_3
inst✝⁵ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝⁴ : SMul R M
inst✝³ : SMul Rᵐᵒᵖ M
inst✝² : IsScalarTower R M M
inst✝¹ : IsScalarTower Rᵐᵒᵖ M M
inst✝ : IsCentralScalar R M
s : R
r : M
x : ↥S
⊢ MulOpposite.op s • mk (r, x).1 (r, x).2 = s • mk (r, x).1 (r, x).2

Next tactic:
simp only [smul_mk, op_smul_eq_smul]
instance [Monoid R] [MulAction R M] [IsScalarTower R M M] : MulAction R (Localization S) where
  one_smul :=
    Localization.ind <|
      Prod.rec <| by
        

Proof state:
M : Type u_1
inst✝⁵ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁴ : CommMonoid N
P : Type u_3
inst✝³ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝² : Monoid R
inst✝¹ : MulAction R M
inst✝ : IsScalarTower R M M
⊢ ∀ (fst : M) (snd : ↥S), 1 • mk (fst, snd).1 (fst, snd).2 = mk (fst, snd).1 (fst, snd).2

Next tactic:
intros
instance [Monoid R] [MulAction R M] [IsScalarTower R M M] : MulAction R (Localization S) where
  one_smul :=
    Localization.ind <|
      Prod.rec <| by
        intros
        

Proof state:
M : Type u_1
inst✝⁵ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁴ : CommMonoid N
P : Type u_3
inst✝³ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝² : Monoid R
inst✝¹ : MulAction R M
inst✝ : IsScalarTower R M M
fst✝ : M
snd✝ : ↥S
⊢ 1 • mk (fst✝, snd✝).1 (fst✝, snd✝).2 = mk (fst✝, snd✝).1 (fst✝, snd✝).2

Next tactic:
simp only [Localization.smul_mk, one_smul]
instance [Monoid R] [MulAction R M] [IsScalarTower R M M] : MulAction R (Localization S) where
  one_smul :=
    Localization.ind <|
      Prod.rec <| by
        intros
        simp only [Localization.smul_mk, one_smul]
  mul_smul s₁ s₂ :=
    Localization.ind <|
      Prod.rec <| by
        

Proof state:
M : Type u_1
inst✝⁵ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁴ : CommMonoid N
P : Type u_3
inst✝³ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝² : Monoid R
inst✝¹ : MulAction R M
inst✝ : IsScalarTower R M M
s₁ s₂ : R
⊢ ∀ (fst : M) (snd : ↥S), (s₁ * s₂) • mk (fst, snd).1 (fst, snd).2 = s₁ • s₂ • mk (fst, snd).1 (fst, snd).2

Next tactic:
intros
instance [Monoid R] [MulAction R M] [IsScalarTower R M M] : MulAction R (Localization S) where
  one_smul :=
    Localization.ind <|
      Prod.rec <| by
        intros
        simp only [Localization.smul_mk, one_smul]
  mul_smul s₁ s₂ :=
    Localization.ind <|
      Prod.rec <| by
        intros
        

Proof state:
M : Type u_1
inst✝⁵ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁴ : CommMonoid N
P : Type u_3
inst✝³ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝² : Monoid R
inst✝¹ : MulAction R M
inst✝ : IsScalarTower R M M
s₁ s₂ : R
fst✝ : M
snd✝ : ↥S
⊢ (s₁ * s₂) • mk (fst✝, snd✝).1 (fst✝, snd✝).2 = s₁ • s₂ • mk (fst✝, snd✝).1 (fst✝, snd✝).2

Next tactic:
simp only [Localization.smul_mk, mul_smul]
instance [Monoid R] [MulDistribMulAction R M] [IsScalarTower R M M] :
    MulDistribMulAction R (Localization S) where
  smul_one s := by simp only [← Localization.mk_one, Localization.smul_mk, smul_one]
  smul_mul s x y :=
    Localization.induction_on₂ x y <|
      Prod.rec fun r₁ x₁ ↦
        Prod.rec fun r₂ x₂ ↦ by 

Proof state:
M : Type u_1
inst✝⁵ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁴ : CommMonoid N
P : Type u_3
inst✝³ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝² : Monoid R
inst✝¹ : MulDistribMulAction R M
inst✝ : IsScalarTower R M M
s : R
x y : Localization S
r₁ : M
x₁ : ↥S
r₂ : M
x₂ : ↥S
⊢ s • (mk (r₁, x₁).1 (r₁, x₁).2 * mk (r₂, x₂).1 (r₂, x₂).2) =
    s • mk (r₁, x₁).1 (r₁, x₁).2 * s • mk (r₂, x₂).1 (r₂, x₂).2

Next tactic:
simp only [Localization.smul_mk, Localization.mk_mul, smul_mul']
instance [Monoid R] [MulDistribMulAction R M] [IsScalarTower R M M] :
    MulDistribMulAction R (Localization S) where
  smul_one s := by 

Proof state:
M : Type u_1
inst✝⁵ : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝⁴ : CommMonoid N
P : Type u_3
inst✝³ : CommMonoid P
R : Type u_4
R₁ : Type u_5
R₂ : Type u_6
inst✝² : Monoid R
inst✝¹ : MulDistribMulAction R M
inst✝ : IsScalarTower R M M
s : R
⊢ s • 1 = 1

Next tactic:
simp only [← Localization.mk_one, Localization.smul_mk, smul_one]
@[to_additive (attr := ext)]
theorem ext {f g : LocalizationMap S N} (h : ∀ x, f.toMap x = g.toMap x) : f = g := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f g : LocalizationMap S N
h : ∀ (x : M), (toMap f) x = (toMap g) x
⊢ f = g

Next tactic:
rcases f with ⟨⟨⟩⟩
@[to_additive (attr := ext)]
theorem ext {f g : LocalizationMap S N} (h : ∀ x, f.toMap x = g.toMap x) : f = g := by
  rcases f with ⟨⟨⟩⟩
  

Proof state:
case mk.mk
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
g : LocalizationMap S N
toOneHom✝ : OneHom M N
map_mul'✝ : ∀ (x y : M), OneHom.toFun toOneHom✝ (x * y) = OneHom.toFun toOneHom✝ x * OneHom.toFun toOneHom✝ y
map_units'✝ : ∀ (y : ↥S), IsUnit (OneHom.toFun ↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ } ↑y)
surj'✝ :
  ∀ (z : N),
    ∃ x,
      z * OneHom.toFun ↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ } ↑x.2 =
        OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) x.1
exists_of_eq✝ :
  ∀ (x y : M),
    OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) x =
        OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) y →
      ∃ c, ↑c * x = ↑c * y
h :
  ∀ (x : M),
    (toMap
          { toMonoidHom := { toOneHom := toOneHom✝, map_mul' := map_mul'✝ }, map_units' := map_units'✝, surj' := surj'✝,
            exists_of_eq := exists_of_eq✝ })
        x =
      (toMap g) x
⊢ { toMonoidHom := { toOneHom := toOneHom✝, map_mul' := map_mul'✝ }, map_units' := map_units'✝, surj' := surj'✝,
      exists_of_eq := exists_of_eq✝ } =
    g

Next tactic:
rcases g with ⟨⟨⟩⟩
@[to_additive (attr := ext)]
theorem ext {f g : LocalizationMap S N} (h : ∀ x, f.toMap x = g.toMap x) : f = g := by
  rcases f with ⟨⟨⟩⟩
  rcases g with ⟨⟨⟩⟩
  

Proof state:
case mk.mk.mk.mk
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
toOneHom✝¹ : OneHom M N
map_mul'✝¹ : ∀ (x y : M), OneHom.toFun toOneHom✝¹ (x * y) = OneHom.toFun toOneHom✝¹ x * OneHom.toFun toOneHom✝¹ y
map_units'✝¹ : ∀ (y : ↥S), IsUnit (OneHom.toFun ↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ } ↑y)
surj'✝¹ :
  ∀ (z : N),
    ∃ x,
      z * OneHom.toFun ↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ } ↑x.2 =
        OneHom.toFun (↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }) x.1
exists_of_eq✝¹ :
  ∀ (x y : M),
    OneHom.toFun (↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }) x =
        OneHom.toFun (↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }) y →
      ∃ c, ↑c * x = ↑c * y
toOneHom✝ : OneHom M N
map_mul'✝ : ∀ (x y : M), OneHom.toFun toOneHom✝ (x * y) = OneHom.toFun toOneHom✝ x * OneHom.toFun toOneHom✝ y
map_units'✝ : ∀ (y : ↥S), IsUnit (OneHom.toFun ↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ } ↑y)
surj'✝ :
  ∀ (z : N),
    ∃ x,
      z * OneHom.toFun ↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ } ↑x.2 =
        OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) x.1
exists_of_eq✝ :
  ∀ (x y : M),
    OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) x =
        OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) y →
      ∃ c, ↑c * x = ↑c * y
h :
  ∀ (x : M),
    (toMap
          { toMonoidHom := { toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }, map_units' := map_units'✝¹,
            surj' := surj'✝¹, exists_of_eq := exists_of_eq✝¹ })
        x =
      (toMap
          { toMonoidHom := { toOneHom := toOneHom✝, map_mul' := map_mul'✝ }, map_units' := map_units'✝, surj' := surj'✝,
            exists_of_eq := exists_of_eq✝ })
        x
⊢ { toMonoidHom := { toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }, map_units' := map_units'✝¹, surj' := surj'✝¹,
      exists_of_eq := exists_of_eq✝¹ } =
    { toMonoidHom := { toOneHom := toOneHom✝, map_mul' := map_mul'✝ }, map_units' := map_units'✝, surj' := surj'✝,
      exists_of_eq := exists_of_eq✝ }

Next tactic:
simp only [mk.injEq, MonoidHom.mk.injEq]
@[to_additive (attr := ext)]
theorem ext {f g : LocalizationMap S N} (h : ∀ x, f.toMap x = g.toMap x) : f = g := by
  rcases f with ⟨⟨⟩⟩
  rcases g with ⟨⟨⟩⟩
  simp only [mk.injEq, MonoidHom.mk.injEq]
  

Proof state:
case mk.mk.mk.mk
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
toOneHom✝¹ : OneHom M N
map_mul'✝¹ : ∀ (x y : M), OneHom.toFun toOneHom✝¹ (x * y) = OneHom.toFun toOneHom✝¹ x * OneHom.toFun toOneHom✝¹ y
map_units'✝¹ : ∀ (y : ↥S), IsUnit (OneHom.toFun ↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ } ↑y)
surj'✝¹ :
  ∀ (z : N),
    ∃ x,
      z * OneHom.toFun ↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ } ↑x.2 =
        OneHom.toFun (↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }) x.1
exists_of_eq✝¹ :
  ∀ (x y : M),
    OneHom.toFun (↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }) x =
        OneHom.toFun (↑{ toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }) y →
      ∃ c, ↑c * x = ↑c * y
toOneHom✝ : OneHom M N
map_mul'✝ : ∀ (x y : M), OneHom.toFun toOneHom✝ (x * y) = OneHom.toFun toOneHom✝ x * OneHom.toFun toOneHom✝ y
map_units'✝ : ∀ (y : ↥S), IsUnit (OneHom.toFun ↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ } ↑y)
surj'✝ :
  ∀ (z : N),
    ∃ x,
      z * OneHom.toFun ↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ } ↑x.2 =
        OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) x.1
exists_of_eq✝ :
  ∀ (x y : M),
    OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) x =
        OneHom.toFun (↑{ toOneHom := toOneHom✝, map_mul' := map_mul'✝ }) y →
      ∃ c, ↑c * x = ↑c * y
h :
  ∀ (x : M),
    (toMap
          { toMonoidHom := { toOneHom := toOneHom✝¹, map_mul' := map_mul'✝¹ }, map_units' := map_units'✝¹,
            surj' := surj'✝¹, exists_of_eq := exists_of_eq✝¹ })
        x =
      (toMap
          { toMonoidHom := { toOneHom := toOneHom✝, map_mul' := map_mul'✝ }, map_units' := map_units'✝, surj' := surj'✝,
            exists_of_eq := exists_of_eq✝ })
        x
⊢ toOneHom✝¹ = toOneHom✝

Next tactic:
exact OneHom.ext h
@[to_additive]
theorem eq_iff_exists (f : LocalizationMap S N) {x y} :
    f.toMap x = f.toMap y ↔ ∃ c : S, ↑c * x = c * y := Iff.intro (f.4 x y)
  fun ⟨c, h⟩ ↦ by
    

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : LocalizationMap S N
x y : M
x✝ : ∃ c, ↑c * x = ↑c * y
c : ↥S
h : ↑c * x = ↑c * y
⊢ (toMap f) x = (toMap f) y

Next tactic:
replace h := congr_arg f.toMap h
@[to_additive]
theorem eq_iff_exists (f : LocalizationMap S N) {x y} :
    f.toMap x = f.toMap y ↔ ∃ c : S, ↑c * x = c * y := Iff.intro (f.4 x y)
  fun ⟨c, h⟩ ↦ by
    replace h := congr_arg f.toMap h
    

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : LocalizationMap S N
x y : M
x✝ : ∃ c, ↑c * x = ↑c * y
c : ↥S
h : (toMap f) (↑c * x) = (toMap f) (↑c * y)
⊢ (toMap f) x = (toMap f) y

Next tactic:
rw [map_mul, map_mul] at h
@[to_additive]
theorem eq_iff_exists (f : LocalizationMap S N) {x y} :
    f.toMap x = f.toMap y ↔ ∃ c : S, ↑c * x = c * y := Iff.intro (f.4 x y)
  fun ⟨c, h⟩ ↦ by
    replace h := congr_arg f.toMap h
    rw [map_mul, map_mul] at h
    

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : LocalizationMap S N
x y : M
x✝ : ∃ c, ↑c * x = ↑c * y
c : ↥S
h : (toMap f) ↑c * (toMap f) x = (toMap f) ↑c * (toMap f) y
⊢ (toMap f) x = (toMap f) y

Next tactic:
exact (f.map_units c).mul_right_inj.mp h
@[to_additive]
theorem sec_spec' {f : LocalizationMap S N} (z : N) :
    f.toMap (f.sec z).1 = f.toMap (f.sec z).2 * z := by 

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : LocalizationMap S N
z : N
⊢ (toMap f) (sec f z).1 = (toMap f) ↑(sec f z).2 * z

Next tactic:
rw [mul_comm, sec_spec]
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`w, z : N` and `y ∈ S`, we have `w * (f y)⁻¹ = z ↔ w = f y * z`. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `w, z : N` and `y ∈ S`, we have `w - f y = z ↔ w = f y + z`."]
theorem mul_inv_left {f : M →* N} (h : ∀ y : S, IsUnit (f y)) (y : S) (w z : N) :
    w * (IsUnit.liftRight (f.restrict S) h y)⁻¹ = z ↔ w = f y * z := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
h : ∀ (y : ↥S), IsUnit (f ↑y)
y : ↥S
w z : N
⊢ w * ↑((IsUnit.liftRight (MonoidHom.restrict f S) h) y)⁻¹ = z ↔ w = f ↑y * z

Next tactic:
rw [mul_comm]
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`w, z : N` and `y ∈ S`, we have `w * (f y)⁻¹ = z ↔ w = f y * z`. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `w, z : N` and `y ∈ S`, we have `w - f y = z ↔ w = f y + z`."]
theorem mul_inv_left {f : M →* N} (h : ∀ y : S, IsUnit (f y)) (y : S) (w z : N) :
    w * (IsUnit.liftRight (f.restrict S) h y)⁻¹ = z ↔ w = f y * z := by
  rw [mul_comm]
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
h : ∀ (y : ↥S), IsUnit (f ↑y)
y : ↥S
w z : N
⊢ ↑((IsUnit.liftRight (MonoidHom.restrict f S) h) y)⁻¹ * w = z ↔ w = f ↑y * z

Next tactic:
exact Units.inv_mul_eq_iff_eq_mul (IsUnit.liftRight (f.restrict S) h y)
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`w, z : N` and `y ∈ S`, we have `z = w * (f y)⁻¹ ↔ z * f y = w`. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `w, z : N` and `y ∈ S`, we have `z = w - f y ↔ z + f y = w`."]
theorem mul_inv_right {f : M →* N} (h : ∀ y : S, IsUnit (f y)) (y : S) (w z : N) :
    z = w * (IsUnit.liftRight (f.restrict S) h y)⁻¹ ↔ z * f y = w := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
h : ∀ (y : ↥S), IsUnit (f ↑y)
y : ↥S
w z : N
⊢ z = w * ↑((IsUnit.liftRight (MonoidHom.restrict f S) h) y)⁻¹ ↔ z * f ↑y = w

Next tactic:
rw [eq_comm, mul_inv_left h, mul_comm, eq_comm]
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ Nˣ`, for all `x₁ x₂ : M` and `y₁, y₂ ∈ S`, we have
`f x₁ * (f y₁)⁻¹ = f x₂ * (f y₂)⁻¹ ↔ f (x₁ * y₂) = f (x₂ * y₁)`. -/
@[to_additive (attr := simp)
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `x₁ x₂ : M` and `y₁, y₂ ∈ S`, we have
`f x₁ - f y₁ = f x₂ - f y₂ ↔ f (x₁ + y₂) = f (x₂ + y₁)`."]
theorem mul_inv {f : M →* N} (h : ∀ y : S, IsUnit (f y)) {x₁ x₂} {y₁ y₂ : S} :
    f x₁ * (IsUnit.liftRight (f.restrict S) h y₁)⁻¹ =
        f x₂ * (IsUnit.liftRight (f.restrict S) h y₂)⁻¹ ↔
      f (x₁ * y₂) = f (x₂ * y₁) := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
h : ∀ (y : ↥S), IsUnit (f ↑y)
x₁ x₂ : M
y₁ y₂ : ↥S
⊢ f x₁ * ↑((IsUnit.liftRight (MonoidHom.restrict f S) h) y₁)⁻¹ =
      f x₂ * ↑((IsUnit.liftRight (MonoidHom.restrict f S) h) y₂)⁻¹ ↔
    f (x₁ * ↑y₂) = f (x₂ * ↑y₁)

Next tactic:
rw [mul_inv_right h, mul_assoc, mul_comm _ (f y₂), ← mul_assoc, mul_inv_left h, mul_comm x₂,
    f.map_mul, f.map_mul]
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`y, z ∈ S`, we have `(f y)⁻¹ = (f z)⁻¹ → f y = f z`. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `y, z ∈ S`, we have `- (f y) = - (f z) → f y = f z`."]
theorem inv_inj {f : M →* N} (hf : ∀ y : S, IsUnit (f y)) {y z : S}
    (h : (IsUnit.liftRight (f.restrict S) hf y)⁻¹ = (IsUnit.liftRight (f.restrict S) hf z)⁻¹) :
      f y = f z := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
hf : ∀ (y : ↥S), IsUnit (f ↑y)
y z : ↥S
h : ((IsUnit.liftRight (MonoidHom.restrict f S) hf) y)⁻¹ = ((IsUnit.liftRight (MonoidHom.restrict f S) hf) z)⁻¹
⊢ f ↑y = f ↑z

Next tactic:
rw [← mul_one (f y), eq_comm, ← mul_inv_left hf y (f z) 1, h]
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`y, z ∈ S`, we have `(f y)⁻¹ = (f z)⁻¹ → f y = f z`. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `y, z ∈ S`, we have `- (f y) = - (f z) → f y = f z`."]
theorem inv_inj {f : M →* N} (hf : ∀ y : S, IsUnit (f y)) {y z : S}
    (h : (IsUnit.liftRight (f.restrict S) hf y)⁻¹ = (IsUnit.liftRight (f.restrict S) hf z)⁻¹) :
      f y = f z := by
  rw [← mul_one (f y), eq_comm, ← mul_inv_left hf y (f z) 1, h]
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
hf : ∀ (y : ↥S), IsUnit (f ↑y)
y z : ↥S
h : ((IsUnit.liftRight (MonoidHom.restrict f S) hf) y)⁻¹ = ((IsUnit.liftRight (MonoidHom.restrict f S) hf) z)⁻¹
⊢ f ↑z * ↑((IsUnit.liftRight (MonoidHom.restrict f S) hf) z)⁻¹ = 1

Next tactic:
exact Units.inv_mul (IsUnit.liftRight (f.restrict S) hf z)⁻¹
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`y ∈ S`, `(f y)⁻¹` is unique. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `y ∈ S`, `- (f y)` is unique."]
theorem inv_unique {f : M →* N} (h : ∀ y : S, IsUnit (f y)) {y : S} {z : N} (H : f y * z = 1) :
    (IsUnit.liftRight (f.restrict S) h y)⁻¹ = z := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
h : ∀ (y : ↥S), IsUnit (f ↑y)
y : ↥S
z : N
H : f ↑y * z = 1
⊢ ↑((IsUnit.liftRight (MonoidHom.restrict f S) h) y)⁻¹ = z

Next tactic:
rw [← one_mul _⁻¹, Units.val_mul, mul_inv_left]
/-- Given a MonoidHom `f : M →* N` and Submonoid `S ⊆ M` such that `f(S) ⊆ Nˣ`, for all
`y ∈ S`, `(f y)⁻¹` is unique. -/
@[to_additive
    "Given an AddMonoidHom `f : M →+ N` and Submonoid `S ⊆ M` such that
`f(S) ⊆ AddUnits N`, for all `y ∈ S`, `- (f y)` is unique."]
theorem inv_unique {f : M →* N} (h : ∀ y : S, IsUnit (f y)) {y : S} {z : N} (H : f y * z = 1) :
    (IsUnit.liftRight (f.restrict S) h y)⁻¹ = z := by
  rw [← one_mul _⁻¹, Units.val_mul, mul_inv_left]
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : M →* N
h : ∀ (y : ↥S), IsUnit (f ↑y)
y : ↥S
z : N
H : f ↑y * z = 1
⊢ ↑1 = f ↑y * z

Next tactic:
exact H.symm
@[to_additive]
theorem map_right_cancel {x y} {c : S} (h : f.toMap (c * x) = f.toMap (c * y)) :
    f.toMap x = f.toMap y := by
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : LocalizationMap S N
x y : M
c : ↥S
h : (toMap f) (↑c * x) = (toMap f) (↑c * y)
⊢ (toMap f) x = (toMap f) y

Next tactic:
rw [f.toMap.map_mul, f.toMap.map_mul] at h
@[to_additive]
theorem map_right_cancel {x y} {c : S} (h : f.toMap (c * x) = f.toMap (c * y)) :
    f.toMap x = f.toMap y := by
  rw [f.toMap.map_mul, f.toMap.map_mul] at h
  

Proof state:
M : Type u_1
inst✝² : CommMonoid M
S : Submonoid M
N : Type u_2
inst✝¹ : CommMonoid N
P : Type u_3
inst✝ : CommMonoid P
f : LocalizationMap S N
x y : M
c : ↥S
h : (toMap f) ↑c * (toMap f) x = (toMap f) ↑c * (toMap f) y
⊢ (toMap f) x = (toMap f) y

Next tactic:
cases' f.map_units c with u hu