l3lab/ntp-mathlib huggingface dataset:
theorem r.isEquiv : IsEquiv _ (r S M) :=
  { refl := fun ⟨m, s⟩ => ⟨1, by rw [one_smul]⟩
    trans := fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m3, s3⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ => by
      use u1 * u2 * s2
      -- Put everything in the same shape, sorting the terms using `simp`
      have hu1' := congr_arg ((u2 * s3) • ·) hu1.symm
      

Proof state:
case h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
x✝¹ : r S M (m1, s1) (m2, s2)
m3 : M
s3 : ↥S
x✝ : r S M (m2, s2) (m3, s3)
u1 : ↥S
hu1 : u1 • (m2, s2).2 • (m1, s1).1 = u1 • (m1, s1).2 • (m2, s2).1
u2 : ↥S
hu2 : u2 • (m3, s3).2 • (m2, s2).1 = u2 • (m2, s2).2 • (m3, s3).1
hu1' : (fun x => (u2 * s3) • x) (u1 • (m1, s1).2 • (m2, s2).1) = (fun x => (u2 * s3) • x) (u1 • (m2, s2).2 • (m1, s1).1)
⊢ (u1 * u2 * s2) • (m3, s3).2 • (m1, s1).1 = (u1 * u2 * s2) • (m1, s1).2 • (m3, s3).1

Next tactic:
have hu2' := congr_arg ((u1 * s1) • ·) hu2.symm
theorem r.isEquiv : IsEquiv _ (r S M) :=
  { refl := fun ⟨m, s⟩ => ⟨1, by rw [one_smul]⟩
    trans := fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m3, s3⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ => by
      use u1 * u2 * s2
      -- Put everything in the same shape, sorting the terms using `simp`
      have hu1' := congr_arg ((u2 * s3) • ·) hu1.symm
      have hu2' := congr_arg ((u1 * s1) • ·) hu2.symm
      

Proof state:
case h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
x✝¹ : r S M (m1, s1) (m2, s2)
m3 : M
s3 : ↥S
x✝ : r S M (m2, s2) (m3, s3)
u1 : ↥S
hu1 : u1 • (m2, s2).2 • (m1, s1).1 = u1 • (m1, s1).2 • (m2, s2).1
u2 : ↥S
hu2 : u2 • (m3, s3).2 • (m2, s2).1 = u2 • (m2, s2).2 • (m3, s3).1
hu1' : (fun x => (u2 * s3) • x) (u1 • (m1, s1).2 • (m2, s2).1) = (fun x => (u2 * s3) • x) (u1 • (m2, s2).2 • (m1, s1).1)
hu2' : (fun x => (u1 * s1) • x) (u2 • (m2, s2).2 • (m3, s3).1) = (fun x => (u1 * s1) • x) (u2 • (m3, s3).2 • (m2, s2).1)
⊢ (u1 * u2 * s2) • (m3, s3).2 • (m1, s1).1 = (u1 * u2 * s2) • (m1, s1).2 • (m3, s3).1

Next tactic:
simp only [← mul_smul, smul_assoc, mul_assoc, mul_comm, mul_left_comm] at hu1' hu2' ⊢
theorem r.isEquiv : IsEquiv _ (r S M) :=
  { refl := fun ⟨m, s⟩ => ⟨1, by rw [one_smul]⟩
    trans := fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m3, s3⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ => by
      use u1 * u2 * s2
      -- Put everything in the same shape, sorting the terms using `simp`
      have hu1' := congr_arg ((u2 * s3) • ·) hu1.symm
      have hu2' := congr_arg ((u1 * s1) • ·) hu2.symm
      simp only [← mul_smul, smul_assoc, mul_assoc, mul_comm, mul_left_comm] at hu1' hu2' ⊢
      

Proof state:
case h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
x✝¹ : r S M (m1, s1) (m2, s2)
m3 : M
s3 : ↥S
x✝ : r S M (m2, s2) (m3, s3)
u1 : ↥S
hu1 : u1 • (m2, s2).2 • (m1, s1).1 = u1 • (m1, s1).2 • (m2, s2).1
u2 : ↥S
hu2 : u2 • (m3, s3).2 • (m2, s2).1 = u2 • (m2, s2).2 • (m3, s3).1
hu1' : (s1 * (s3 * (u1 * u2))) • m2 = (s2 * (s3 * (u1 * u2))) • m1
hu2' : (s1 * (s2 * (u1 * u2))) • m3 = (s1 * (s3 * (u1 * u2))) • m2
⊢ (s2 * (s3 * (u1 * u2))) • m1 = (s1 * (s2 * (u1 * u2))) • m3

Next tactic:
rw [hu2', hu1']
@[elab_as_elim]
theorem induction_on {β : LocalizedModule S M → Prop} (h : ∀ (m : M) (s : S), β (mk m s)) :
    ∀ x : LocalizedModule S M, β x := by
  

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
β : LocalizedModule S M → Prop
h : ∀ (m : M) (s : ↥S), β (mk m s)
⊢ ∀ (x : LocalizedModule S M), β x

Next tactic:
rintro ⟨⟨m, s⟩⟩
@[elab_as_elim]
theorem induction_on {β : LocalizedModule S M → Prop} (h : ∀ (m : M) (s : S), β (mk m s)) :
    ∀ x : LocalizedModule S M, β x := by
  rintro ⟨⟨m, s⟩⟩
  

Proof state:
case mk.mk
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
β : LocalizedModule S M → Prop
h : ∀ (m : M) (s : ↥S), β (mk m s)
x✝ : LocalizedModule S M
m : M
s : ↥S
⊢ β (Quot.mk Setoid.r (m, s))

Next tactic:
exact h m s
@[elab_as_elim]
theorem induction_on₂ {β : LocalizedModule S M → LocalizedModule S M → Prop}
    (h : ∀ (m m' : M) (s s' : S), β (mk m s) (mk m' s')) : ∀ x y, β x y := by
  

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
β : LocalizedModule S M → LocalizedModule S M → Prop
h : ∀ (m m' : M) (s s' : ↥S), β (mk m s) (mk m' s')
⊢ ∀ (x y : LocalizedModule S M), β x y

Next tactic:
rintro ⟨⟨m, s⟩⟩ ⟨⟨m', s'⟩⟩
@[elab_as_elim]
theorem induction_on₂ {β : LocalizedModule S M → LocalizedModule S M → Prop}
    (h : ∀ (m m' : M) (s s' : S), β (mk m s) (mk m' s')) : ∀ x y, β x y := by
  rintro ⟨⟨m, s⟩⟩ ⟨⟨m', s'⟩⟩
  

Proof state:
case mk.mk.mk.mk
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
β : LocalizedModule S M → LocalizedModule S M → Prop
h : ∀ (m m' : M) (s s' : ↥S), β (mk m s) (mk m' s')
x✝ : LocalizedModule S M
m : M
s : ↥S
y✝ : LocalizedModule S M
m' : M
s' : ↥S
⊢ β (Quot.mk Setoid.r (m, s)) (Quot.mk Setoid.r (m', s'))

Next tactic:
exact h m m' s s'
theorem liftOn_mk {α : Type*} {f : M × S → α} (wd : ∀ (p p' : M × S), p ≈ p' → f p = f p')
    (m : M) (s : S) : liftOn (mk m s) f wd = f ⟨m, s⟩ := by 

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
α : Type u_1
f : M × ↥S → α
wd : ∀ (p p' : M × ↥S), p ≈ p' → f p = f p'
m : M
s : ↥S
⊢ liftOn (mk m s) f wd = f (m, s)

Next tactic:
convert Quotient.liftOn_mk f wd ⟨m, s⟩
theorem liftOn₂_mk {α : Type*} (f : M × S → M × S → α)
    (wd : ∀ (p q p' q' : M × S), p ≈ p' → q ≈ q' → f p q = f p' q') (m m' : M)
    (s s' : S) : liftOn₂ (mk m s) (mk m' s') f wd = f ⟨m, s⟩ ⟨m', s'⟩ := by
  

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
α : Type u_1
f : M × ↥S → M × ↥S → α
wd : ∀ (p q p' q' : M × ↥S), p ≈ p' → q ≈ q' → f p q = f p' q'
m m' : M
s s' : ↥S
⊢ liftOn₂ (mk m s) (mk m' s') f wd = f (m, s) (m', s')

Next tactic:
convert Quotient.liftOn₂_mk f wd _ _
@[simp]
theorem zero_mk (s : S) : mk (0 : M) s = 0 :=
  mk_eq.mpr ⟨1, by 

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
s : ↥S
⊢ 1 • 1 • 0 = 1 • s • 0

Next tactic:
rw [one_smul, smul_zero, smul_zero, one_smul]
instance : Add (LocalizedModule S M) where
  add p1 p2 :=
    liftOn₂ p1 p2 (fun x y => mk (y.2 • x.1 + x.2 • y.1) (x.2 * y.2)) <|
      fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m1', s1'⟩ ⟨m2', s2'⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ =>
          mk_eq.mpr
            ⟨u1 * u2, by
              -- Put everything in the same shape, sorting the terms using `simp`
              

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p1 p2 : LocalizedModule S M
x✝⁵ x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
m1' : M
s1' : ↥S
x✝¹ : (m1, s1) ≈ (m1', s1')
m2' : M
s2' : ↥S
x✝ : (m2, s2) ≈ (m2', s2')
u1 : ↥S
hu1 : u1 • (m1', s1').2 • (m1, s1).1 = u1 • (m1, s1).2 • (m1', s1').1
u2 : ↥S
hu2 : u2 • (m2', s2').2 • (m2, s2).1 = u2 • (m2, s2).2 • (m2', s2').1
⊢ (u1 * u2) • ((m1', s1').2 * (m2', s2').2) • ((m2, s2).2 • (m1, s1).1 + (m1, s1).2 • (m2, s2).1) =
    (u1 * u2) • ((m1, s1).2 * (m2, s2).2) • ((m2', s2').2 • (m1', s1').1 + (m1', s1').2 • (m2', s2').1)

Next tactic:
have hu1' := congr_arg ((u2 * s2 * s2') • ·) hu1
instance : Add (LocalizedModule S M) where
  add p1 p2 :=
    liftOn₂ p1 p2 (fun x y => mk (y.2 • x.1 + x.2 • y.1) (x.2 * y.2)) <|
      fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m1', s1'⟩ ⟨m2', s2'⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ =>
          mk_eq.mpr
            ⟨u1 * u2, by
              -- Put everything in the same shape, sorting the terms using `simp`
              have hu1' := congr_arg ((u2 * s2 * s2') • ·) hu1
              

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p1 p2 : LocalizedModule S M
x✝⁵ x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
m1' : M
s1' : ↥S
x✝¹ : (m1, s1) ≈ (m1', s1')
m2' : M
s2' : ↥S
x✝ : (m2, s2) ≈ (m2', s2')
u1 : ↥S
hu1 : u1 • (m1', s1').2 • (m1, s1).1 = u1 • (m1, s1).2 • (m1', s1').1
u2 : ↥S
hu2 : u2 • (m2', s2').2 • (m2, s2).1 = u2 • (m2, s2).2 • (m2', s2').1
hu1' :
  (fun x => (u2 * s2 * s2') • x) (u1 • (m1', s1').2 • (m1, s1).1) =
    (fun x => (u2 * s2 * s2') • x) (u1 • (m1, s1).2 • (m1', s1').1)
⊢ (u1 * u2) • ((m1', s1').2 * (m2', s2').2) • ((m2, s2).2 • (m1, s1).1 + (m1, s1).2 • (m2, s2).1) =
    (u1 * u2) • ((m1, s1).2 * (m2, s2).2) • ((m2', s2').2 • (m1', s1').1 + (m1', s1').2 • (m2', s2').1)

Next tactic:
have hu2' := congr_arg ((u1 * s1 * s1') • ·) hu2
instance : Add (LocalizedModule S M) where
  add p1 p2 :=
    liftOn₂ p1 p2 (fun x y => mk (y.2 • x.1 + x.2 • y.1) (x.2 * y.2)) <|
      fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m1', s1'⟩ ⟨m2', s2'⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ =>
          mk_eq.mpr
            ⟨u1 * u2, by
              -- Put everything in the same shape, sorting the terms using `simp`
              have hu1' := congr_arg ((u2 * s2 * s2') • ·) hu1
              have hu2' := congr_arg ((u1 * s1 * s1') • ·) hu2
              

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p1 p2 : LocalizedModule S M
x✝⁵ x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
m1' : M
s1' : ↥S
x✝¹ : (m1, s1) ≈ (m1', s1')
m2' : M
s2' : ↥S
x✝ : (m2, s2) ≈ (m2', s2')
u1 : ↥S
hu1 : u1 • (m1', s1').2 • (m1, s1).1 = u1 • (m1, s1).2 • (m1', s1').1
u2 : ↥S
hu2 : u2 • (m2', s2').2 • (m2, s2).1 = u2 • (m2, s2).2 • (m2', s2').1
hu1' :
  (fun x => (u2 * s2 * s2') • x) (u1 • (m1', s1').2 • (m1, s1).1) =
    (fun x => (u2 * s2 * s2') • x) (u1 • (m1, s1).2 • (m1', s1').1)
hu2' :
  (fun x => (u1 * s1 * s1') • x) (u2 • (m2', s2').2 • (m2, s2).1) =
    (fun x => (u1 * s1 * s1') • x) (u2 • (m2, s2).2 • (m2', s2').1)
⊢ (u1 * u2) • ((m1', s1').2 * (m2', s2').2) • ((m2, s2).2 • (m1, s1).1 + (m1, s1).2 • (m2, s2).1) =
    (u1 * u2) • ((m1, s1).2 * (m2, s2).2) • ((m2', s2').2 • (m1', s1').1 + (m1', s1').2 • (m2', s2').1)

Next tactic:
simp only [smul_add, ← mul_smul, smul_assoc, mul_assoc, mul_comm,
                mul_left_comm] at hu1' hu2' ⊢
instance : Add (LocalizedModule S M) where
  add p1 p2 :=
    liftOn₂ p1 p2 (fun x y => mk (y.2 • x.1 + x.2 • y.1) (x.2 * y.2)) <|
      fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨m1', s1'⟩ ⟨m2', s2'⟩ ⟨u1, hu1⟩ ⟨u2, hu2⟩ =>
          mk_eq.mpr
            ⟨u1 * u2, by
              -- Put everything in the same shape, sorting the terms using `simp`
              have hu1' := congr_arg ((u2 * s2 * s2') • ·) hu1
              have hu2' := congr_arg ((u1 * s1 * s1') • ·) hu2
              simp only [smul_add, ← mul_smul, smul_assoc, mul_assoc, mul_comm,
                mul_left_comm] at hu1' hu2' ⊢
              

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
p1 p2 : LocalizedModule S M
x✝⁵ x✝⁴ x✝³ x✝² : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
m1' : M
s1' : ↥S
x✝¹ : (m1, s1) ≈ (m1', s1')
m2' : M
s2' : ↥S
x✝ : (m2, s2) ≈ (m2', s2')
u1 : ↥S
hu1 : u1 • (m1', s1').2 • (m1, s1).1 = u1 • (m1, s1).2 • (m1', s1').1
u2 : ↥S
hu2 : u2 • (m2', s2').2 • (m2, s2).1 = u2 • (m2, s2).2 • (m2', s2').1
hu1' : (s2 * (s1' * (s2' * (u1 * u2)))) • m1 = (s1 * (s2 * (s2' * (u1 * u2)))) • m1'
hu2' : (s1 * (s1' * (s2' * (u1 * u2)))) • m2 = (s1 * (s2 * (s1' * (u1 * u2)))) • m2'
⊢ (s2 * (s1' * (s2' * (u1 * u2)))) • m1 + (s1 * (s1' * (s2' * (u1 * u2)))) • m2 =
    (s1 * (s2 * (s2' * (u1 * u2)))) • m1' + (s1 * (s2 * (s1' * (u1 * u2)))) • m2'

Next tactic:
rw [hu1', hu2']
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x y z : LocalizedModule S M
⊢ x + y + z = x + (y + z)

Next tactic:
induction' x using LocalizedModule.induction_on with mx sx
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  

Proof state:
case h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
y z : LocalizedModule S M
mx : M
sx : ↥S
⊢ mk mx sx + y + z = mk mx sx + (y + z)

Next tactic:
induction' y using LocalizedModule.induction_on with my sy
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  

Proof state:
case h.h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
z : LocalizedModule S M
mx : M
sx : ↥S
my : M
sy : ↥S
⊢ mk mx sx + mk my sy + z = mk mx sx + (mk my sy + z)

Next tactic:
induction' z using LocalizedModule.induction_on with mz sz
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  induction' z using LocalizedModule.induction_on with mz sz
  

Proof state:
case h.h.h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
mx : M
sx : ↥S
my : M
sy : ↥S
mz : M
sz : ↥S
⊢ mk mx sx + mk my sy + mk mz sz = mk mx sx + (mk my sy + mk mz sz)

Next tactic:
simp only [mk_add_mk, smul_add]
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  induction' z using LocalizedModule.induction_on with mz sz
  simp only [mk_add_mk, smul_add]
  

Proof state:
case h.h.h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
mx : M
sx : ↥S
my : M
sy : ↥S
mz : M
sz : ↥S
⊢ mk (sz • sy • mx + sz • sx • my + (sx * sy) • mz) (sx * sy * sz) =
    mk ((sy * sz) • mx + (sx • sz • my + sx • sy • mz)) (sx * (sy * sz))

Next tactic:
refine' mk_eq.mpr ⟨1, _⟩
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  induction' z using LocalizedModule.induction_on with mz sz
  simp only [mk_add_mk, smul_add]
  refine' mk_eq.mpr ⟨1, _⟩
  

Proof state:
case h.h.h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
mx : M
sx : ↥S
my : M
sy : ↥S
mz : M
sz : ↥S
⊢ 1 • (sx * (sy * sz)) • (sz • sy • mx + sz • sx • my + (sx * sy) • mz) =
    1 • (sx * sy * sz) • ((sy * sz) • mx + (sx • sz • my + sx • sy • mz))

Next tactic:
rw [one_smul, one_smul]
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  induction' z using LocalizedModule.induction_on with mz sz
  simp only [mk_add_mk, smul_add]
  refine' mk_eq.mpr ⟨1, _⟩
  rw [one_smul, one_smul]
  

Proof state:
case h.h.h
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
mx : M
sx : ↥S
my : M
sy : ↥S
mz : M
sz : ↥S
⊢ (sx * (sy * sz)) • (sz • sy • mx + sz • sx • my + (sx * sy) • mz) =
    (sx * sy * sz) • ((sy * sz) • mx + (sx • sz • my + sx • sy • mz))

Next tactic:
congr 1
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  induction' z using LocalizedModule.induction_on with mz sz
  simp only [mk_add_mk, smul_add]
  refine' mk_eq.mpr ⟨1, _⟩
  rw [one_smul, one_smul]
  congr 1
  · 

Proof state:
case h.h.h.e_a
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
mx : M
sx : ↥S
my : M
sy : ↥S
mz : M
sz : ↥S
⊢ sx * (sy * sz) = sx * sy * sz

Next tactic:
rw [mul_assoc]
/-- Porting note: Some auxiliary lemmas are declared with `private` in the original mathlib3 file.
We take that policy here as well, and remove the `#align` lines accordingly. -/
private theorem add_assoc' (x y z : LocalizedModule S M) : x + y + z = x + (y + z) := by
  induction' x using LocalizedModule.induction_on with mx sx
  induction' y using LocalizedModule.induction_on with my sy
  induction' z using LocalizedModule.induction_on with mz sz
  simp only [mk_add_mk, smul_add]
  refine' mk_eq.mpr ⟨1, _⟩
  rw [one_smul, one_smul]
  congr 1
  · rw [mul_assoc]
  · 

Proof state:
case h.h.h.e_a
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
mx : M
sx : ↥S
my : M
sy : ↥S
mz : M
sz : ↥S
⊢ sz • sy • mx + sz • sx • my + (sx * sy) • mz = (sy * sz) • mx + (sx • sz • my + sx • sy • mz)

Next tactic:
rw [eq_comm, mul_comm, add_assoc, mul_smul, mul_smul, ← mul_smul sx sz, mul_comm, mul_smul]
private theorem add_comm' (x y : LocalizedModule S M) : x + y = y + x :=
  LocalizedModule.induction_on₂ (fun m m' s s' => by 

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x y : LocalizedModule S M
m m' : M
s s' : ↥S
⊢ mk m s + mk m' s' = mk m' s' + mk m s

Next tactic:
rw [mk_add_mk, mk_add_mk, add_comm, mul_comm]
private theorem zero_add' (x : LocalizedModule S M) : 0 + x = x :=
  induction_on
    (fun m s => by
      

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x : LocalizedModule S M
m : M
s : ↥S
⊢ 0 + mk m s = mk m s

Next tactic:
rw [← zero_mk s, mk_add_mk, smul_zero, zero_add, mk_eq]
private theorem zero_add' (x : LocalizedModule S M) : 0 + x = x :=
  induction_on
    (fun m s => by
      rw [← zero_mk s, mk_add_mk, smul_zero, zero_add, mk_eq];
        

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x : LocalizedModule S M
m : M
s : ↥S
⊢ ∃ u, u • s • s • m = u • (s * s) • m

Next tactic:
exact ⟨1, by rw [one_smul, mul_smul, one_smul]⟩
private theorem zero_add' (x : LocalizedModule S M) : 0 + x = x :=
  induction_on
    (fun m s => by
      rw [← zero_mk s, mk_add_mk, smul_zero, zero_add, mk_eq];
        exact ⟨1, by 

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x : LocalizedModule S M
m : M
s : ↥S
⊢ 1 • s • s • m = 1 • (s * s) • m

Next tactic:
rw [one_smul, mul_smul, one_smul]
private theorem add_zero' (x : LocalizedModule S M) : x + 0 = x :=
  induction_on
    (fun m s => by
      

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x : LocalizedModule S M
m : M
s : ↥S
⊢ mk m s + 0 = mk m s

Next tactic:
rw [← zero_mk s, mk_add_mk, smul_zero, add_zero, mk_eq]
private theorem add_zero' (x : LocalizedModule S M) : x + 0 = x :=
  induction_on
    (fun m s => by
      rw [← zero_mk s, mk_add_mk, smul_zero, add_zero, mk_eq];
        

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x : LocalizedModule S M
m : M
s : ↥S
⊢ ∃ u, u • s • s • m = u • (s * s) • m

Next tactic:
exact ⟨1, by rw [one_smul, mul_smul, one_smul]⟩
private theorem add_zero' (x : LocalizedModule S M) : x + 0 = x :=
  induction_on
    (fun m s => by
      rw [← zero_mk s, mk_add_mk, smul_zero, add_zero, mk_eq];
        exact ⟨1, by 

Proof state:
R : Type u
inst✝² : CommSemiring R
S : Submonoid R
M : Type v
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x : LocalizedModule S M
m : M
s : ↥S
⊢ 1 • s • s • m = 1 • (s * s) • m

Next tactic:
rw [one_smul, mul_smul, one_smul]
instance {M : Type*} [AddCommGroup M] [Module R M] : AddCommGroup (LocalizedModule S M) :=
  { show AddCommMonoid (LocalizedModule S M) by 

Proof state:
R : Type u
inst✝⁴ : CommSemiring R
S : Submonoid R
M✝ : Type v
inst✝³ : AddCommMonoid M✝
inst✝² : Module R M✝
M : Type u_1
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ AddCommMonoid (LocalizedModule S M)

Next tactic:
infer_instance
instance {M : Type*} [AddCommGroup M] [Module R M] : AddCommGroup (LocalizedModule S M) :=
  { show AddCommMonoid (LocalizedModule S M) by infer_instance with
    neg := fun p =>
      liftOn p (fun x => LocalizedModule.mk (-x.1) x.2) fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨u, hu⟩ => by
        

Proof state:
R : Type u
inst✝⁴ : CommSemiring R
S : Submonoid R
M✝ : Type v
inst✝³ : AddCommMonoid M✝
inst✝² : Module R M✝
M : Type u_1
inst✝¹ : AddCommGroup M
inst✝ : Module R M
src✝ : AddCommMonoid (LocalizedModule S M) :=
  let_fun this := inferInstance;
  this
p : LocalizedModule S M
x✝² x✝¹ : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
x✝ : (m1, s1) ≈ (m2, s2)
u : ↥S
hu : u • (m2, s2).2 • (m1, s1).1 = u • (m1, s1).2 • (m2, s2).1
⊢ (fun x => mk (-x.1) x.2) (m1, s1) = (fun x => mk (-x.1) x.2) (m2, s2)

Next tactic:
rw [mk_eq]
instance {M : Type*} [AddCommGroup M] [Module R M] : AddCommGroup (LocalizedModule S M) :=
  { show AddCommMonoid (LocalizedModule S M) by infer_instance with
    neg := fun p =>
      liftOn p (fun x => LocalizedModule.mk (-x.1) x.2) fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨u, hu⟩ => by
        rw [mk_eq]
        

Proof state:
R : Type u
inst✝⁴ : CommSemiring R
S : Submonoid R
M✝ : Type v
inst✝³ : AddCommMonoid M✝
inst✝² : Module R M✝
M : Type u_1
inst✝¹ : AddCommGroup M
inst✝ : Module R M
src✝ : AddCommMonoid (LocalizedModule S M) :=
  let_fun this := inferInstance;
  this
p : LocalizedModule S M
x✝² x✝¹ : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
x✝ : (m1, s1) ≈ (m2, s2)
u : ↥S
hu : u • (m2, s2).2 • (m1, s1).1 = u • (m1, s1).2 • (m2, s2).1
⊢ ∃ u, u • (m2, s2).2 • -(m1, s1).1 = u • (m1, s1).2 • -(m2, s2).1

Next tactic:
exact ⟨u, by simpa⟩
instance {M : Type*} [AddCommGroup M] [Module R M] : AddCommGroup (LocalizedModule S M) :=
  { show AddCommMonoid (LocalizedModule S M) by infer_instance with
    neg := fun p =>
      liftOn p (fun x => LocalizedModule.mk (-x.1) x.2) fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨u, hu⟩ => by
        rw [mk_eq]
        exact ⟨u, by 

Proof state:
R : Type u
inst✝⁴ : CommSemiring R
S : Submonoid R
M✝ : Type v
inst✝³ : AddCommMonoid M✝
inst✝² : Module R M✝
M : Type u_1
inst✝¹ : AddCommGroup M
inst✝ : Module R M
src✝ : AddCommMonoid (LocalizedModule S M) :=
  let_fun this := inferInstance;
  this
p : LocalizedModule S M
x✝² x✝¹ : M × ↥S
m1 : M
s1 : ↥S
m2 : M
s2 : ↥S
x✝ : (m1, s1) ≈ (m2, s2)
u : ↥S
hu : u • (m2, s2).2 • (m1, s1).1 = u • (m1, s1).2 • (m2, s2).1
⊢ u • (m2, s2).2 • -(m1, s1).1 = u • (m1, s1).2 • -(m2, s2).1

Next tactic:
simpa