l3lab/ntp-mathlib huggingface dataset:
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' 

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) ((sec f z).1 * (↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * ↑x.2)) =
    (toMap f) (↑(sec f z).2 * (↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * x.1))

Next tactic:
rw [f.toMap.map_mul]
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' 

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) (sec f z).1 * (toMap f) (↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * ↑x.2) =
    (toMap f) (↑(sec f z).2 * (↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * x.1))

Next tactic:
rw [f.toMap.map_mul]
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' 

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) (sec f z).1 * ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) ↑x.2) =
    (toMap f) (↑(sec f z).2 * (↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * x.1))

Next tactic:
rw [f.toMap.map_mul]
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' 

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) (sec f z).1 * ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) ↑x.2) =
    (toMap f) ↑(sec f z).2 * (toMap f) (↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * x.1)

Next tactic:
rw [f.toMap.map_mul]
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' 

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) (sec f z).1 * ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) ↑x.2) =
    (toMap f) ↑(sec f z).2 * ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) x.1)

Next tactic:
rw [f.toMap.map_mul]
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' rw [f.toMap.map_mul]
  

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) (sec f z).1 * ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) ↑x.2) =
    (toMap f) ↑(sec f z).2 * ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) x.1)

Next tactic:
rw [sec_spec', ← hx]
/-- Given two Localization maps `f : M →* N, k : M →* P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`. -/
@[to_additive (attr := simp)
    "Given two Localization maps `f : M →+ N, k : M →+ P` for a Submonoid `S ⊆ M`, the hom
from `P` to `N` induced by `f` is left inverse to the hom from `N` to `P` induced by `k`."]
theorem lift_left_inverse {k : LocalizationMap S P} (z : N) :
    k.lift f.map_units (f.lift k.map_units z) = z := by
  rw [lift_spec]
  cases' f.surj z with x hx
  conv_rhs =>
    congr
    next => skip
    rw [f.eq_mk'_iff_mul_eq.2 hx]
  rw [mk', ← mul_assoc, mul_inv_right f.map_units, ← f.toMap.map_mul, ← f.toMap.map_mul]
  apply k.eq_of_eq f.map_units
  rw [k.toMap.map_mul, k.toMap.map_mul, ← sec_spec, mul_assoc, lift_spec_mul]
  repeat' rw [← k.toMap.map_mul]
  apply f.eq_of_eq k.map_units
  repeat' rw [f.toMap.map_mul]
  rw [sec_spec', ← hx]
  

Proof state:
case intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
k : LocalizationMap S P
z : N
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ (toMap f) ↑(sec f z).2 * z *
      ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (toMap f) ↑x.2) =
    (toMap f) ↑(sec f z).2 *
      ((toMap f) ↑(sec k ((lift f (_ : ∀ (y : ↥S), IsUnit ((toMap k) ↑y))) z)).2 * (z * (toMap f) ↑x.2))

Next tactic:
ac_rfl
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := 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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
⊢ Surjective ⇑(lift f hg) ↔ ∀ (v : P), ∃ x, v * g ↑x.2 = g x.1

Next tactic:
constructor
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · 

Proof state:
case mp
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
⊢ Surjective ⇑(lift f hg) → ∀ (v : P), ∃ x, v * g ↑x.2 = g x.1

Next tactic:
intro H v
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    

Proof state:
case mp
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Surjective ⇑(lift f hg)
v : P
⊢ ∃ x, v * g ↑x.2 = g x.1

Next tactic:
obtain ⟨z, hz⟩ := H v
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    

Proof state:
case mp.intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Surjective ⇑(lift f hg)
v : P
z : N
hz : (lift f hg) z = v
⊢ ∃ x, v * g ↑x.2 = g x.1

Next tactic:
obtain ⟨x, hx⟩ := f.surj z
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    

Proof state:
case mp.intro.intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Surjective ⇑(lift f hg)
v : P
z : N
hz : (lift f hg) z = v
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ ∃ x, v * g ↑x.2 = g x.1

Next tactic:
use x
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    use x
    

Proof state:
case h
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Surjective ⇑(lift f hg)
v : P
z : N
hz : (lift f hg) z = v
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ v * g ↑x.2 = g x.1

Next tactic:
rw [← hz, f.eq_mk'_iff_mul_eq.2 hx, lift_mk', mul_assoc, mul_comm _ (g ↑x.2)]
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    use x
    rw [← hz, f.eq_mk'_iff_mul_eq.2 hx, lift_mk', mul_assoc, mul_comm _ (g ↑x.2)]
    

Proof state:
case h
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Surjective ⇑(lift f hg)
v : P
z : N
hz : (lift f hg) z = v
x : M × ↥S
hx : z * (toMap f) ↑x.2 = (toMap f) x.1
⊢ g x.1 * (g ↑x.2 * ↑((IsUnit.liftRight (MonoidHom.restrict g S) hg) x.2)⁻¹) = g x.1

Next tactic:
erw [IsUnit.mul_liftRight_inv (g.restrict S) hg, mul_one]
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    use x
    rw [← hz, f.eq_mk'_iff_mul_eq.2 hx, lift_mk', mul_assoc, mul_comm _ (g ↑x.2)]
    erw [IsUnit.mul_liftRight_inv (g.restrict S) hg, mul_one]
  · 

Proof state:
case mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
⊢ (∀ (v : P), ∃ x, v * g ↑x.2 = g x.1) → Surjective ⇑(lift f hg)

Next tactic:
intro H v
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    use x
    rw [← hz, f.eq_mk'_iff_mul_eq.2 hx, lift_mk', mul_assoc, mul_comm _ (g ↑x.2)]
    erw [IsUnit.mul_liftRight_inv (g.restrict S) hg, mul_one]
  · intro H v
    

Proof state:
case mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : ∀ (v : P), ∃ x, v * g ↑x.2 = g x.1
v : P
⊢ ∃ a, (lift f hg) a = v

Next tactic:
obtain ⟨x, hx⟩ := H v
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    use x
    rw [← hz, f.eq_mk'_iff_mul_eq.2 hx, lift_mk', mul_assoc, mul_comm _ (g ↑x.2)]
    erw [IsUnit.mul_liftRight_inv (g.restrict S) hg, mul_one]
  · intro H v
    obtain ⟨x, hx⟩ := H v
    

Proof state:
case mpr.intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : ∀ (v : P), ∃ x, v * g ↑x.2 = g x.1
v : P
x : M × ↥S
hx : v * g ↑x.2 = g x.1
⊢ ∃ a, (lift f hg) a = v

Next tactic:
use f.mk' x.1 x.2
@[to_additive]
theorem lift_surjective_iff :
    Function.Surjective (f.lift hg) ↔ ∀ v : P, ∃ x : M × S, v * g x.2 = g x.1 := by
  constructor
  · intro H v
    obtain ⟨z, hz⟩ := H v
    obtain ⟨x, hx⟩ := f.surj z
    use x
    rw [← hz, f.eq_mk'_iff_mul_eq.2 hx, lift_mk', mul_assoc, mul_comm _ (g ↑x.2)]
    erw [IsUnit.mul_liftRight_inv (g.restrict S) hg, mul_one]
  · intro H v
    obtain ⟨x, hx⟩ := H v
    use f.mk' x.1 x.2
    

Proof state:
case h
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : ∀ (v : P), ∃ x, v * g ↑x.2 = g x.1
v : P
x : M × ↥S
hx : v * g ↑x.2 = g x.1
⊢ (lift f hg) (mk' f x.1 x.2) = v

Next tactic:
rw [lift_mk', mul_inv_left hg, mul_comm, ← hx]
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g 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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
⊢ Injective ⇑(lift f hg) ↔ ∀ (x y : M), (toMap f) x = (toMap f) y ↔ g x = g y

Next tactic:
constructor
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · 

Proof state:
case mp
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
⊢ Injective ⇑(lift f hg) → ∀ (x y : M), (toMap f) x = (toMap f) y ↔ g x = g y

Next tactic:
intro H x y
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    

Proof state:
case mp
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Injective ⇑(lift f hg)
x y : M
⊢ (toMap f) x = (toMap f) y ↔ g x = g y

Next tactic:
constructor
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · 

Proof state:
case mp.mp
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Injective ⇑(lift f hg)
x y : M
⊢ (toMap f) x = (toMap f) y → g x = g y

Next tactic:
exact f.eq_of_eq hg
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · 

Proof state:
case mp.mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Injective ⇑(lift f hg)
x y : M
⊢ g x = g y → (toMap f) x = (toMap f) y

Next tactic:
intro h
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · intro h
      

Proof state:
case mp.mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Injective ⇑(lift f hg)
x y : M
h : g x = g y
⊢ (toMap f) x = (toMap f) y

Next tactic:
rw [← f.lift_eq hg, ← f.lift_eq hg] at h
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · intro h
      rw [← f.lift_eq hg, ← f.lift_eq hg] at h
      

Proof state:
case mp.mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : Injective ⇑(lift f hg)
x y : M
h : (lift f hg) ((toMap f) x) = (lift f hg) ((toMap f) y)
⊢ (toMap f) x = (toMap f) y

Next tactic:
exact H h
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · intro h
      rw [← f.lift_eq hg, ← f.lift_eq hg] at h
      exact H h
  · 

Proof state:
case mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
⊢ (∀ (x y : M), (toMap f) x = (toMap f) y ↔ g x = g y) → Injective ⇑(lift f hg)

Next tactic:
intro H z w h
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · intro h
      rw [← f.lift_eq hg, ← f.lift_eq hg] at h
      exact H h
  · intro H z w h
    

Proof state:
case mpr
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : ∀ (x y : M), (toMap f) x = (toMap f) y ↔ g x = g y
z w : N
h : (lift f hg) z = (lift f hg) w
⊢ z = w

Next tactic:
obtain ⟨_, _⟩ := f.surj z
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · intro h
      rw [← f.lift_eq hg, ← f.lift_eq hg] at h
      exact H h
  · intro H z w h
    obtain ⟨_, _⟩ := f.surj z
    

Proof state:
case mpr.intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : ∀ (x y : M), (toMap f) x = (toMap f) y ↔ g x = g y
z w : N
h : (lift f hg) z = (lift f hg) w
w✝ : M × ↥S
h✝ : z * (toMap f) ↑w✝.2 = (toMap f) w✝.1
⊢ z = w

Next tactic:
obtain ⟨_, _⟩ := f.surj w
@[to_additive]
theorem lift_injective_iff :
    Function.Injective (f.lift hg) ↔ ∀ x y, f.toMap x = f.toMap y ↔ g x = g y := by
  constructor
  · intro H x y
    constructor
    · exact f.eq_of_eq hg
    · intro h
      rw [← f.lift_eq hg, ← f.lift_eq hg] at h
      exact H h
  · intro H z w h
    obtain ⟨_, _⟩ := f.surj z
    obtain ⟨_, _⟩ := f.surj w
    

Proof state:
case mpr.intro.intro
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
g : M →* P
hg : ∀ (y : ↥S), IsUnit (g ↑y)
H : ∀ (x y : M), (toMap f) x = (toMap f) y ↔ g x = g y
z w : N
h : (lift f hg) z = (lift f hg) w
w✝¹ : M × ↥S
h✝¹ : z * (toMap f) ↑w✝¹.2 = (toMap f) w✝¹.1
w✝ : M × ↥S
h✝ : w * (toMap f) ↑w✝.2 = (toMap f) w✝.1
⊢ z = w

Next tactic:
rw [← f.mk'_sec z, ← f.mk'_sec w]