/-
Copyright (c) 2018 Johan Commelin All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johan Commelin, Chris Hughes, Kevin Buzzard

! This file was ported from Lean 3 source module algebra.hom.units
! leanprover-community/mathlib commit dc6c365e751e34d100e80fe6e314c3c3e0fd2988
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Algebra.Hom.Group
import Mathbin.Algebra.Group.Units

/-!
# Monoid homomorphisms and units

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

This file allows to lift monoid homomorphisms to group homomorphisms of their units subgroups. It
also contains unrelated results about `units` that depend on `monoid_hom`.

## Main declarations

* `units.map`: Turn an homomorphism from `α` to `β` monoids into an homomorphism from `αˣ` to `βˣ`.
* `monoid_hom.to_hom_units`: Turn an homomorphism from a group `α` to `β` into an homomorphism from
  `α` to `βˣ`.

## TODO

The results that don't mention homomorphisms should be proved (earlier?) in a different file and be
used to golf the basic `group` lemmas.
-/

open Function

universe u v w

#print Group.isUnit /-
@[to_additive]
theorem Group.isUnit {G} [Group G] (g : G) : IsUnit g :=
  ⟨⟨g, g⁻¹, mul_inv_self g, inv_mul_self g⟩, rfl⟩
#align group.is_unit Group.isUnit
#align add_group.is_add_unit AddGroup.isAddUnit
-/

section MonoidHomClass

/- warning: is_unit.eq_on_inv -> IsUnit.eq_on_inv is a dubious translation:
lean 3 declaration is
  forall {F : Type.{u1}} {G : Type.{u2}} {N : Type.{u3}} [_inst_1 : DivisionMonoid.{u2} G] [_inst_2 : Monoid.{u3} N] [_inst_3 : MonoidHomClass.{u1, u2, u3} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} N _inst_2)] {x : G}, (IsUnit.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)) x) -> (forall (f : F) (g : F), (Eq.{succ u3} N (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> N) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => N) (MulHomClass.toFunLike.{u1, u2, u3} F G N (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} N (Monoid.toMulOneClass.{u3} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} N _inst_2) _inst_3))) f x) (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> N) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => N) (MulHomClass.toFunLike.{u1, u2, u3} F G N (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} N (Monoid.toMulOneClass.{u3} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} N _inst_2) _inst_3))) g x)) -> (Eq.{succ u3} N (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> N) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => N) (MulHomClass.toFunLike.{u1, u2, u3} F G N (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} N (Monoid.toMulOneClass.{u3} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} N _inst_2) _inst_3))) f (Inv.inv.{u2} G (DivInvMonoid.toHasInv.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)) x)) (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> N) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => N) (MulHomClass.toFunLike.{u1, u2, u3} F G N (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} N (Monoid.toMulOneClass.{u3} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} N _inst_2) _inst_3))) g (Inv.inv.{u2} G (DivInvMonoid.toHasInv.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)) x))))
but is expected to have type
  forall {F : Type.{u3}} {G : Type.{u2}} {N : Type.{u1}} [_inst_1 : DivisionMonoid.{u2} G] [_inst_2 : Monoid.{u1} N] [_inst_3 : MonoidHomClass.{u3, u2, u1} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} N _inst_2)] {x : G}, (IsUnit.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)) x) -> (forall (f : F) (g : F), (Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => N) x) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => N) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G N (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} N _inst_2) _inst_3)) f x) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => N) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G N (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} N _inst_2) _inst_3)) g x)) -> (Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => N) (Inv.inv.{u2} G (InvOneClass.toInv.{u2} G (DivInvOneMonoid.toInvOneClass.{u2} G (DivisionMonoid.toDivInvOneMonoid.{u2} G _inst_1))) x)) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => N) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G N (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} N _inst_2) _inst_3)) f (Inv.inv.{u2} G (InvOneClass.toInv.{u2} G (DivInvOneMonoid.toInvOneClass.{u2} G (DivisionMonoid.toDivInvOneMonoid.{u2} G _inst_1))) x)) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => N) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G N (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G N (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (DivisionMonoid.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} N _inst_2) _inst_3)) g (Inv.inv.{u2} G (InvOneClass.toInv.{u2} G (DivInvOneMonoid.toInvOneClass.{u2} G (DivisionMonoid.toDivInvOneMonoid.{u2} G _inst_1))) x))))
Case conversion may be inaccurate. Consider using '#align is_unit.eq_on_inv IsUnit.eq_on_invₓ'. -/
/-- If two homomorphisms from a division monoid to a monoid are equal at a unit `x`, then they are
equal at `x⁻¹`. -/
@[to_additive
      "If two homomorphisms from a subtraction monoid to an additive monoid are equal at an\nadditive unit `x`, then they are equal at `-x`."]
theorem IsUnit.eq_on_inv {F G N} [DivisionMonoid G] [Monoid N] [MonoidHomClass F G N] {x : G}
    (hx : IsUnit x) (f g : F) (h : f x = g x) : f x⁻¹ = g x⁻¹ :=
  left_inv_eq_right_inv (map_mul_eq_one f hx.inv_mul_cancel) <|
    h.symm ▸ map_mul_eq_one g <| hx.mul_inv_cancel
#align is_unit.eq_on_inv IsUnit.eq_on_inv
#align is_add_unit.eq_on_neg IsAddUnit.eq_on_neg

/- warning: eq_on_inv -> eq_on_inv is a dubious translation:
lean 3 declaration is
  forall {F : Type.{u1}} {G : Type.{u2}} {M : Type.{u3}} [_inst_1 : Group.{u2} G] [_inst_2 : Monoid.{u3} M] [_inst_3 : MonoidHomClass.{u1, u2, u3} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} M _inst_2)] (f : F) (g : F) {x : G}, (Eq.{succ u3} M (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> M) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => M) (MulHomClass.toFunLike.{u1, u2, u3} F G M (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} M _inst_2) _inst_3))) f x) (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> M) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => M) (MulHomClass.toFunLike.{u1, u2, u3} F G M (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} M _inst_2) _inst_3))) g x)) -> (Eq.{succ u3} M (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> M) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => M) (MulHomClass.toFunLike.{u1, u2, u3} F G M (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} M _inst_2) _inst_3))) f (Inv.inv.{u2} G (DivInvMonoid.toHasInv.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)) x)) (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => G -> M) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F G (fun (_x : G) => M) (MulHomClass.toFunLike.{u1, u2, u3} F G M (MulOneClass.toHasMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u3} M _inst_2) _inst_3))) g (Inv.inv.{u2} G (DivInvMonoid.toHasInv.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)) x)))
but is expected to have type
  forall {F : Type.{u3}} {G : Type.{u2}} {M : Type.{u1}} [_inst_1 : Group.{u2} G] [_inst_2 : Monoid.{u1} M] [_inst_3 : MonoidHomClass.{u3, u2, u1} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2)] (f : F) (g : F) {x : G}, (Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) x) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G M (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2) _inst_3)) f x) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G M (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2) _inst_3)) g x)) -> (Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) (Inv.inv.{u2} G (InvOneClass.toInv.{u2} G (DivInvOneMonoid.toInvOneClass.{u2} G (DivisionMonoid.toDivInvOneMonoid.{u2} G (Group.toDivisionMonoid.{u2} G _inst_1)))) x)) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G M (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2) _inst_3)) f (Inv.inv.{u2} G (InvOneClass.toInv.{u2} G (DivInvOneMonoid.toInvOneClass.{u2} G (DivisionMonoid.toDivInvOneMonoid.{u2} G (Group.toDivisionMonoid.{u2} G _inst_1)))) x)) (FunLike.coe.{succ u3, succ u2, succ u1} F G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) _x) (MulHomClass.toFunLike.{u3, u2, u1} F G M (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2) _inst_3)) g (Inv.inv.{u2} G (InvOneClass.toInv.{u2} G (DivInvOneMonoid.toInvOneClass.{u2} G (DivisionMonoid.toDivInvOneMonoid.{u2} G (Group.toDivisionMonoid.{u2} G _inst_1)))) x)))
Case conversion may be inaccurate. Consider using '#align eq_on_inv eq_on_invₓ'. -/
/-- If two homomorphism from a group to a monoid are equal at `x`, then they are equal at `x⁻¹`. -/
@[to_additive
      "If two homomorphism from an additive group to an additive monoid are equal at `x`,\nthen they are equal at `-x`."]
theorem eq_on_inv {F G M} [Group G] [Monoid M] [MonoidHomClass F G M] (f g : F) {x : G}
    (h : f x = g x) : f x⁻¹ = g x⁻¹ :=
  (Group.isUnit x).eq_on_inv f g h
#align eq_on_inv eq_on_inv
#align eq_on_neg eq_on_neg

end MonoidHomClass

namespace Units

variable {α : Type _} {M : Type u} {N : Type v} {P : Type w} [Monoid M] [Monoid N] [Monoid P]

/- warning: units.map -> Units.map is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N], (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) -> (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N], (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) -> (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2))
Case conversion may be inaccurate. Consider using '#align units.map Units.mapₓ'. -/
/-- The group homomorphism on units induced by a `monoid_hom`. -/
@[to_additive "The `add_group` homomorphism on `add_unit`s induced by an `add_monoid_hom`."]
def map (f : M →* N) : Mˣ →* Nˣ :=
  MonoidHom.mk'
    (fun u =>
      ⟨f u.val, f u.inv, by rw [← f.map_mul, u.val_inv, f.map_one], by
        rw [← f.map_mul, u.inv_val, f.map_one]⟩)
    fun x y => ext (f.map_mul x y)
#align units.map Units.map
#align add_units.map AddUnits.map

/- warning: units.coe_map -> Units.coe_map is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (x : Units.{u1} M _inst_1), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => (Units.{u1} M _inst_1) -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (Units.map.{u1, u2} M N _inst_1 _inst_2 f) x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) x))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (x : Units.{u1} M _inst_1), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) (Units.val.{u1} M _inst_1 x)) (Units.val.{u2} N _inst_2 (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) (Units.{u1} M _inst_1) (fun (_x : Units.{u1} M _inst_1) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Units.{u1} M _inst_1) => Units.{u2} N _inst_2) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (MulOneClass.toMul.{u1} (Units.{u1} M _inst_1) (Units.instMulOneClassUnits.{u1} M _inst_1)) (MulOneClass.toMul.{u2} (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)))) (Units.map.{u1, u2} M N _inst_1 _inst_2 f) x)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f (Units.val.{u1} M _inst_1 x))
Case conversion may be inaccurate. Consider using '#align units.coe_map Units.coe_mapₓ'. -/
@[simp, to_additive]
theorem coe_map (f : M →* N) (x : Mˣ) : ↑(map f x) = f x :=
  rfl
#align units.coe_map Units.coe_map
#align add_units.coe_map AddUnits.coe_map

/- warning: units.coe_map_inv -> Units.coe_map_inv is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (u : Units.{u1} M _inst_1), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (Inv.inv.{u2} (Units.{u2} N _inst_2) (Units.hasInv.{u2} N _inst_2) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => (Units.{u1} M _inst_1) -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (Units.map.{u1, u2} M N _inst_1 _inst_2 f) u))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) (Inv.inv.{u1} (Units.{u1} M _inst_1) (Units.hasInv.{u1} M _inst_1) u)))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (u : Units.{u1} M _inst_1), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) (Units.val.{u1} M _inst_1 (Inv.inv.{u1} (Units.{u1} M _inst_1) (Units.instInvUnits.{u1} M _inst_1) u))) (Units.val.{u2} N _inst_2 (Inv.inv.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Units.{u1} M _inst_1) => Units.{u2} N _inst_2) u) (Units.instInvUnits.{u2} N _inst_2) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) (Units.{u1} M _inst_1) (fun (_x : Units.{u1} M _inst_1) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Units.{u1} M _inst_1) => Units.{u2} N _inst_2) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (MulOneClass.toMul.{u1} (Units.{u1} M _inst_1) (Units.instMulOneClassUnits.{u1} M _inst_1)) (MulOneClass.toMul.{u2} (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)))) (Units.map.{u1, u2} M N _inst_1 _inst_2 f) u))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f (Units.val.{u1} M _inst_1 (Inv.inv.{u1} (Units.{u1} M _inst_1) (Units.instInvUnits.{u1} M _inst_1) u)))
Case conversion may be inaccurate. Consider using '#align units.coe_map_inv Units.coe_map_invₓ'. -/
@[simp, to_additive]
theorem coe_map_inv (f : M →* N) (u : Mˣ) : ↑(map f u)⁻¹ = f ↑u⁻¹ :=
  rfl
#align units.coe_map_inv Units.coe_map_inv
#align add_units.coe_map_neg AddUnits.coe_map_neg

/- warning: units.map_comp -> Units.map_comp is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} {P : Type.{u3}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] [_inst_3 : Monoid.{u3} P] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (g : MonoidHom.{u2, u3} N P (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} P _inst_3)), Eq.{max (succ u3) (succ u1)} (MonoidHom.{u1, u3} (Units.{u1} M _inst_1) (Units.{u3} P _inst_3) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u3} P _inst_3)) (Units.map.{u1, u3} M P _inst_1 _inst_3 (MonoidHom.comp.{u1, u2, u3} M N P (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} P _inst_3) g f)) (MonoidHom.comp.{u1, u2, u3} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.{u3} P _inst_3) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2) (Units.mulOneClass.{u3} P _inst_3) (Units.map.{u2, u3} N P _inst_2 _inst_3 g) (Units.map.{u1, u2} M N _inst_1 _inst_2 f))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} {P : Type.{u3}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] [_inst_3 : Monoid.{u3} P] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (g : MonoidHom.{u2, u3} N P (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} P _inst_3)), Eq.{max (succ u1) (succ u3)} (MonoidHom.{u1, u3} (Units.{u1} M _inst_1) (Units.{u3} P _inst_3) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u3} P _inst_3)) (Units.map.{u1, u3} M P _inst_1 _inst_3 (MonoidHom.comp.{u1, u2, u3} M N P (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} P _inst_3) g f)) (MonoidHom.comp.{u1, u2, u3} (Units.{u1} M _inst_1) (Units.{u2} N _inst_2) (Units.{u3} P _inst_3) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2) (Units.instMulOneClassUnits.{u3} P _inst_3) (Units.map.{u2, u3} N P _inst_2 _inst_3 g) (Units.map.{u1, u2} M N _inst_1 _inst_2 f))
Case conversion may be inaccurate. Consider using '#align units.map_comp Units.map_compₓ'. -/
@[simp, to_additive]
theorem map_comp (f : M →* N) (g : N →* P) : map (g.comp f) = (map g).comp (map f) :=
  rfl
#align units.map_comp Units.map_comp
#align add_units.map_comp AddUnits.map_comp

variable (M)

/- warning: units.map_id -> Units.map_id is a dubious translation:
lean 3 declaration is
  forall (M : Type.{u1}) [_inst_1 : Monoid.{u1} M], Eq.{succ u1} (MonoidHom.{u1, u1} (Units.{u1} M _inst_1) (Units.{u1} M _inst_1) (Units.mulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u1} M _inst_1)) (Units.map.{u1, u1} M M _inst_1 _inst_1 (MonoidHom.id.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1))) (MonoidHom.id.{u1} (Units.{u1} M _inst_1) (Units.mulOneClass.{u1} M _inst_1))
but is expected to have type
  forall (M : Type.{u1}) [_inst_1 : Monoid.{u1} M], Eq.{succ u1} (MonoidHom.{u1, u1} (Units.{u1} M _inst_1) (Units.{u1} M _inst_1) (Units.instMulOneClassUnits.{u1} M _inst_1) (Units.instMulOneClassUnits.{u1} M _inst_1)) (Units.map.{u1, u1} M M _inst_1 _inst_1 (MonoidHom.id.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1))) (MonoidHom.id.{u1} (Units.{u1} M _inst_1) (Units.instMulOneClassUnits.{u1} M _inst_1))
Case conversion may be inaccurate. Consider using '#align units.map_id Units.map_idₓ'. -/
@[simp, to_additive]
theorem map_id : map (MonoidHom.id M) = MonoidHom.id Mˣ := by ext <;> rfl
#align units.map_id Units.map_id
#align add_units.map_id AddUnits.map_id

/- warning: units.coe_hom -> Units.coeHom is a dubious translation:
lean 3 declaration is
  forall (M : Type.{u1}) [_inst_1 : Monoid.{u1} M], MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.mulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)
but is expected to have type
  forall (M : Type.{u1}) [_inst_1 : Monoid.{u1} M], MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.instMulOneClassUnits.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)
Case conversion may be inaccurate. Consider using '#align units.coe_hom Units.coeHomₓ'. -/
/-- Coercion `Mˣ → M` as a monoid homomorphism. -/
@[to_additive "Coercion `add_units M → M` as an add_monoid homomorphism."]
def coeHom : Mˣ →* M :=
  ⟨coe, val_one, val_mul⟩
#align units.coe_hom Units.coeHom
#align add_units.coe_hom AddUnits.coeHom

variable {M}

/- warning: units.coe_hom_apply -> Units.coeHom_apply is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} [_inst_1 : Monoid.{u1} M] (x : Units.{u1} M _inst_1), Eq.{succ u1} M (coeFn.{succ u1, succ u1} (MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.mulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)) (fun (_x : MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.mulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)) => (Units.{u1} M _inst_1) -> M) (MonoidHom.hasCoeToFun.{u1, u1} (Units.{u1} M _inst_1) M (Units.mulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)) (Units.coeHom.{u1} M _inst_1) x) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) x)
but is expected to have type
  forall {M : Type.{u1}} [_inst_1 : Monoid.{u1} M] (x : Units.{u1} M _inst_1), Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Units.{u1} M _inst_1) => M) x) (FunLike.coe.{succ u1, succ u1, succ u1} (MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.instMulOneClassUnits.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)) (Units.{u1} M _inst_1) (fun (_x : Units.{u1} M _inst_1) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Units.{u1} M _inst_1) => M) _x) (MulHomClass.toFunLike.{u1, u1, u1} (MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.instMulOneClassUnits.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)) (Units.{u1} M _inst_1) M (MulOneClass.toMul.{u1} (Units.{u1} M _inst_1) (Units.instMulOneClassUnits.{u1} M _inst_1)) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MonoidHomClass.toMulHomClass.{u1, u1, u1} (MonoidHom.{u1, u1} (Units.{u1} M _inst_1) M (Units.instMulOneClassUnits.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)) (Units.{u1} M _inst_1) M (Units.instMulOneClassUnits.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1) (MonoidHom.monoidHomClass.{u1, u1} (Units.{u1} M _inst_1) M (Units.instMulOneClassUnits.{u1} M _inst_1) (Monoid.toMulOneClass.{u1} M _inst_1)))) (Units.coeHom.{u1} M _inst_1) x) (Units.val.{u1} M _inst_1 x)
Case conversion may be inaccurate. Consider using '#align units.coe_hom_apply Units.coeHom_applyₓ'. -/
@[simp, to_additive]
theorem coeHom_apply (x : Mˣ) : coeHom M x = ↑x :=
  rfl
#align units.coe_hom_apply Units.coeHom_apply
#align add_units.coe_hom_apply AddUnits.coeHom_apply

/- warning: units.coe_pow -> Units.val_pow_eq_pow_val is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} [_inst_1 : Monoid.{u1} M] (u : Units.{u1} M _inst_1) (n : Nat), Eq.{succ u1} M ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) (HPow.hPow.{u1, 0, u1} (Units.{u1} M _inst_1) Nat (Units.{u1} M _inst_1) (instHPow.{u1, 0} (Units.{u1} M _inst_1) Nat (Monoid.Pow.{u1} (Units.{u1} M _inst_1) (DivInvMonoid.toMonoid.{u1} (Units.{u1} M _inst_1) (Group.toDivInvMonoid.{u1} (Units.{u1} M _inst_1) (Units.group.{u1} M _inst_1))))) u n)) (HPow.hPow.{u1, 0, u1} M Nat M (instHPow.{u1, 0} M Nat (Monoid.Pow.{u1} M _inst_1)) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) u) n)
but is expected to have type
  forall {M : Type.{u1}} [_inst_1 : Monoid.{u1} M] (u : Units.{u1} M _inst_1) (n : Nat), Eq.{succ u1} M (Units.val.{u1} M _inst_1 (HPow.hPow.{u1, 0, u1} (Units.{u1} M _inst_1) Nat (Units.{u1} M _inst_1) (instHPow.{u1, 0} (Units.{u1} M _inst_1) Nat (Monoid.Pow.{u1} (Units.{u1} M _inst_1) (DivInvMonoid.toMonoid.{u1} (Units.{u1} M _inst_1) (Group.toDivInvMonoid.{u1} (Units.{u1} M _inst_1) (Units.instGroupUnits.{u1} M _inst_1))))) u n)) (HPow.hPow.{u1, 0, u1} M Nat M (instHPow.{u1, 0} M Nat (Monoid.Pow.{u1} M _inst_1)) (Units.val.{u1} M _inst_1 u) n)
Case conversion may be inaccurate. Consider using '#align units.coe_pow Units.val_pow_eq_pow_valₓ'. -/
@[simp, norm_cast, to_additive]
theorem val_pow_eq_pow_val (u : Mˣ) (n : ℕ) : ((u ^ n : Mˣ) : M) = u ^ n :=
  (Units.coeHom M).map_pow u n
#align units.coe_pow Units.val_pow_eq_pow_val
#align add_units.coe_nsmul AddUnits.val_nsmul_eq_nsmul_val

section DivisionMonoid

variable [DivisionMonoid α]

/- warning: units.coe_div -> Units.val_div_eq_div_val is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_4 : DivisionMonoid.{u1} α] (u₁ : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (u₂ : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))), Eq.{succ u1} α ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (coeBase.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (Units.hasCoe.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) (HDiv.hDiv.{u1, u1, u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (instHDiv.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (DivInvMonoid.toHasDiv.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Group.toDivInvMonoid.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.group.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u₁ u₂)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (coeBase.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (Units.hasCoe.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u₁) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (coeBase.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (Units.hasCoe.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u₂))
but is expected to have type
  forall {α : Type.{u1}} [_inst_4 : DivisionMonoid.{u1} α] (u₁ : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (u₂ : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))), Eq.{succ u1} α (Units.val.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) (HDiv.hDiv.{u1, u1, u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (instHDiv.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (DivInvMonoid.toDiv.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Group.toDivInvMonoid.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.instGroupUnits.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u₁ u₂)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.val.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) u₁) (Units.val.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) u₂))
Case conversion may be inaccurate. Consider using '#align units.coe_div Units.val_div_eq_div_valₓ'. -/
@[simp, norm_cast, to_additive]
theorem val_div_eq_div_val : ∀ u₁ u₂ : αˣ, ↑(u₁ / u₂) = (u₁ / u₂ : α) :=
  (Units.coeHom α).map_div
#align units.coe_div Units.val_div_eq_div_val

/- warning: units.coe_zpow -> Units.val_zpow_eq_zpow_val is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_4 : DivisionMonoid.{u1} α] (u : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (n : Int), Eq.{succ u1} α ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (coeBase.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (Units.hasCoe.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) (HPow.hPow.{u1, 0, u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) Int (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (instHPow.{u1, 0} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) Int (DivInvMonoid.Pow.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Group.toDivInvMonoid.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.group.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u n)) (HPow.hPow.{u1, 0, u1} α Int α (instHPow.{u1, 0} α Int (DivInvMonoid.Pow.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (coeBase.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (Units.hasCoe.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u) n)
but is expected to have type
  forall {α : Type.{u1}} [_inst_4 : DivisionMonoid.{u1} α] (u : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (n : Int), Eq.{succ u1} α (Units.val.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) (HPow.hPow.{u1, 0, u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) Int (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (instHPow.{u1, 0} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) Int (DivInvMonoid.Pow.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Group.toDivInvMonoid.{u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.instGroupUnits.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u n)) (HPow.hPow.{u1, 0, u1} α Int α (instHPow.{u1, 0} α Int (DivInvMonoid.Pow.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) (Units.val.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) u) n)
Case conversion may be inaccurate. Consider using '#align units.coe_zpow Units.val_zpow_eq_zpow_valₓ'. -/
@[simp, norm_cast, to_additive]
theorem val_zpow_eq_zpow_val : ∀ (u : αˣ) (n : ℤ), ((u ^ n : αˣ) : α) = u ^ n :=
  (Units.coeHom α).map_zpow
#align units.coe_zpow Units.val_zpow_eq_zpow_val
#align add_units.coe_zsmul AddUnits.val_zsmul_eq_zsmul_val

/- warning: divp_eq_div -> divp_eq_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_4 : DivisionMonoid.{u1} α] (a : α) (u : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))), Eq.{succ u1} α (divp.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) a u) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) a ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (coeBase.{succ u1, succ u1} (Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) α (Units.hasCoe.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))))) u))
but is expected to have type
  forall {α : Type.{u1}} [_inst_4 : DivisionMonoid.{u1} α] (a : α) (u : Units.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))), Eq.{succ u1} α (divp.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) a u) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) a (Units.val.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)) u))
Case conversion may be inaccurate. Consider using '#align divp_eq_div divp_eq_divₓ'. -/
@[field_simps]
theorem divp_eq_div (a : α) (u : αˣ) : a /ₚ u = a / u := by rw [div_eq_mul_inv, divp, u.coe_inv]
#align divp_eq_div divp_eq_div

/- warning: map_units_inv -> map_units_inv is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u2}} {M : Type.{u1}} [_inst_1 : Monoid.{u1} M] [_inst_4 : DivisionMonoid.{u2} α] {F : Type.{u3}} [_inst_5 : MonoidHomClass.{u3, u1, u2} F M α (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} α (DivInvMonoid.toMonoid.{u2} α (DivisionMonoid.toDivInvMonoid.{u2} α _inst_4)))] (f : F) (u : Units.{u1} M _inst_1), Eq.{succ u2} α (coeFn.{succ u3, max (succ u1) (succ u2)} F (fun (_x : F) => M -> α) (FunLike.hasCoeToFun.{succ u3, succ u1, succ u2} F M (fun (_x : M) => α) (MulHomClass.toFunLike.{u3, u1, u2} F M α (MulOneClass.toHasMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toHasMul.{u2} α (Monoid.toMulOneClass.{u2} α (DivInvMonoid.toMonoid.{u2} α (DivisionMonoid.toDivInvMonoid.{u2} α _inst_4)))) (MonoidHomClass.toMulHomClass.{u3, u1, u2} F M α (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} α (DivInvMonoid.toMonoid.{u2} α (DivisionMonoid.toDivInvMonoid.{u2} α _inst_4))) _inst_5))) f ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) (Inv.inv.{u1} (Units.{u1} M _inst_1) (Units.hasInv.{u1} M _inst_1) u))) (Inv.inv.{u2} α (DivInvMonoid.toHasInv.{u2} α (DivisionMonoid.toDivInvMonoid.{u2} α _inst_4)) (coeFn.{succ u3, max (succ u1) (succ u2)} F (fun (_x : F) => M -> α) (FunLike.hasCoeToFun.{succ u3, succ u1, succ u2} F M (fun (_x : M) => α) (MulHomClass.toFunLike.{u3, u1, u2} F M α (MulOneClass.toHasMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toHasMul.{u2} α (Monoid.toMulOneClass.{u2} α (DivInvMonoid.toMonoid.{u2} α (DivisionMonoid.toDivInvMonoid.{u2} α _inst_4)))) (MonoidHomClass.toMulHomClass.{u3, u1, u2} F M α (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} α (DivInvMonoid.toMonoid.{u2} α (DivisionMonoid.toDivInvMonoid.{u2} α _inst_4))) _inst_5))) f ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Units.{u1} M _inst_1) M (HasLiftT.mk.{succ u1, succ u1} (Units.{u1} M _inst_1) M (CoeTCₓ.coe.{succ u1, succ u1} (Units.{u1} M _inst_1) M (coeBase.{succ u1, succ u1} (Units.{u1} M _inst_1) M (Units.hasCoe.{u1} M _inst_1)))) u)))
but is expected to have type
  forall {α : Type.{u1}} {M : Type.{u3}} [_inst_1 : Monoid.{u3} M] [_inst_4 : DivisionMonoid.{u1} α] {F : Type.{u2}} [_inst_5 : MonoidHomClass.{u2, u3, u1} F M α (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))] (f : F) (u : Units.{u3} M _inst_1), Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) (Units.val.{u3} M _inst_1 (Inv.inv.{u3} (Units.{u3} M _inst_1) (Units.instInvUnits.{u3} M _inst_1) u))) (FunLike.coe.{succ u2, succ u3, succ u1} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) _x) (MulHomClass.toFunLike.{u2, u3, u1} F M α (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))) (MonoidHomClass.toMulHomClass.{u2, u3, u1} F M α (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) _inst_5)) f (Units.val.{u3} M _inst_1 (Inv.inv.{u3} (Units.{u3} M _inst_1) (Units.instInvUnits.{u3} M _inst_1) u))) (Inv.inv.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) (Units.val.{u3} M _inst_1 u)) (InvOneClass.toInv.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) (Units.val.{u3} M _inst_1 u)) (DivInvOneMonoid.toInvOneClass.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) (Units.val.{u3} M _inst_1 u)) (DivisionMonoid.toDivInvOneMonoid.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) (Units.val.{u3} M _inst_1 u)) _inst_4))) (FunLike.coe.{succ u2, succ u3, succ u1} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => α) _x) (MulHomClass.toFunLike.{u2, u3, u1} F M α (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4)))) (MonoidHomClass.toMulHomClass.{u2, u3, u1} F M α (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_4))) _inst_5)) f (Units.val.{u3} M _inst_1 u)))
Case conversion may be inaccurate. Consider using '#align map_units_inv map_units_invₓ'. -/
@[simp, to_additive]
theorem map_units_inv {F : Type _} [MonoidHomClass F M α] (f : F) (u : Units M) :
    f ↑u⁻¹ = (f u)⁻¹ :=
  ((f : M →* α).comp (Units.coeHom M)).map_inv u
#align map_units_inv map_units_inv
#align map_add_units_neg map_addUnits_neg

end DivisionMonoid

/- warning: units.lift_right -> Units.liftRight is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (g : M -> (Units.{u2} N _inst_2)), (forall (x : M), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (g x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) -> (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (g : M -> (Units.{u2} N _inst_2)), (forall (x : M), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Units.val.{u2} N _inst_2 (g x)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)) -> (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2))
Case conversion may be inaccurate. Consider using '#align units.lift_right Units.liftRightₓ'. -/
/-- If a map `g : M → Nˣ` agrees with a homomorphism `f : M →* N`, then
this map is a monoid homomorphism too. -/
@[to_additive
      "If a map `g : M → add_units N` agrees with a homomorphism `f : M →+ N`, then this map\nis an add_monoid homomorphism too."]
def liftRight (f : M →* N) (g : M → Nˣ) (h : ∀ x, ↑(g x) = f x) : M →* Nˣ
    where
  toFun := g
  map_one' := Units.ext <| (h 1).symm ▸ f.map_one
  map_mul' x y := Units.ext <| by simp only [h, coe_mul, f.map_mul]
#align units.lift_right Units.liftRight
#align add_units.lift_right AddUnits.liftRight

/- warning: units.coe_lift_right -> Units.coe_liftRight is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] {f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)} {g : M -> (Units.{u2} N _inst_2)} (h : forall (x : M), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (g x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (x : M), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => M -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (Units.liftRight.{u1, u2} M N _inst_1 _inst_2 f g h) x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] {f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)} {g : M -> (Units.{u2} N _inst_2)} (h : forall (x : M), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Units.val.{u2} N _inst_2 (g x)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)) (x : M), Eq.{succ u2} N (Units.val.{u2} N _inst_2 (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u2} N _inst_2) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (Units.{u2} N _inst_2) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)))) (Units.liftRight.{u1, u2} M N _inst_1 _inst_2 f g h) x)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)
Case conversion may be inaccurate. Consider using '#align units.coe_lift_right Units.coe_liftRightₓ'. -/
@[simp, to_additive]
theorem coe_liftRight {f : M →* N} {g : M → Nˣ} (h : ∀ x, ↑(g x) = f x) (x) :
    (liftRight f g h x : N) = f x :=
  h x
#align units.coe_lift_right Units.coe_liftRight
#align add_units.coe_lift_right AddUnits.coe_liftRight

/- warning: units.mul_lift_right_inv -> Units.mul_liftRight_inv is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] {f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)} {g : M -> (Units.{u2} N _inst_2)} (h : forall (x : M), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (g x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (x : M), Eq.{succ u2} N (HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (MulOneClass.toHasMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x) ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (Inv.inv.{u2} (Units.{u2} N _inst_2) (Units.hasInv.{u2} N _inst_2) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => M -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (Units.liftRight.{u1, u2} M N _inst_1 _inst_2 f g h) x)))) (OfNat.ofNat.{u2} N 1 (OfNat.mk.{u2} N 1 (One.one.{u2} N (MulOneClass.toHasOne.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)))))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] {f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)} {g : M -> (Units.{u2} N _inst_2)} (h : forall (x : M), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Units.val.{u2} N _inst_2 (g x)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)) (x : M), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (MulOneClass.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toMulOneClass.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x) (Units.val.{u2} N _inst_2 (Inv.inv.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u2} N _inst_2) x) (Units.instInvUnits.{u2} N _inst_2) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u2} N _inst_2) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (Units.{u2} N _inst_2) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)))) (Units.liftRight.{u1, u2} M N _inst_1 _inst_2 f g h) x)))) (OfNat.ofNat.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) 1 (One.toOfNat1.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toOne.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2)))
Case conversion may be inaccurate. Consider using '#align units.mul_lift_right_inv Units.mul_liftRight_invₓ'. -/
@[simp, to_additive]
theorem mul_liftRight_inv {f : M →* N} {g : M → Nˣ} (h : ∀ x, ↑(g x) = f x) (x) :
    f x * ↑(liftRight f g h x)⁻¹ = 1 := by rw [Units.mul_inv_eq_iff_eq_mul, one_mul, coe_lift_right]
#align units.mul_lift_right_inv Units.mul_liftRight_inv
#align add_units.add_lift_right_neg AddUnits.add_liftRight_neg

/- warning: units.lift_right_inv_mul -> Units.liftRight_inv_mul is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] {f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)} {g : M -> (Units.{u2} N _inst_2)} (h : forall (x : M), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (g x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (x : M), Eq.{succ u2} N (HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (MulOneClass.toHasMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2))) ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (Inv.inv.{u2} (Units.{u2} N _inst_2) (Units.hasInv.{u2} N _inst_2) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => M -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (Units.liftRight.{u1, u2} M N _inst_1 _inst_2 f g h) x))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (OfNat.ofNat.{u2} N 1 (OfNat.mk.{u2} N 1 (One.one.{u2} N (MulOneClass.toHasOne.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)))))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] {f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)} {g : M -> (Units.{u2} N _inst_2)} (h : forall (x : M), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Units.val.{u2} N _inst_2 (g x)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)) (x : M), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (MulOneClass.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toMulOneClass.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2))) (Units.val.{u2} N _inst_2 (Inv.inv.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u2} N _inst_2) x) (Units.instInvUnits.{u2} N _inst_2) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u2} N _inst_2) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (Units.{u2} N _inst_2) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} (Units.{u2} N _inst_2) (Units.instMulOneClassUnits.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)) M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2)))) (Units.liftRight.{u1, u2} M N _inst_1 _inst_2 f g h) x))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)) (OfNat.ofNat.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) 1 (One.toOfNat1.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toOne.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2)))
Case conversion may be inaccurate. Consider using '#align units.lift_right_inv_mul Units.liftRight_inv_mulₓ'. -/
@[simp, to_additive]
theorem liftRight_inv_mul {f : M →* N} {g : M → Nˣ} (h : ∀ x, ↑(g x) = f x) (x) :
    ↑(liftRight f g h x)⁻¹ * f x = 1 := by rw [Units.inv_mul_eq_iff_eq_mul, mul_one, coe_lift_right]
#align units.lift_right_inv_mul Units.liftRight_inv_mul
#align add_units.lift_right_neg_add AddUnits.liftRight_neg_add

end Units

namespace MonoidHom

/- warning: monoid_hom.to_hom_units -> MonoidHom.toHomUnits is a dubious translation:
lean 3 declaration is
  forall {G : Type.{u1}} {M : Type.{u2}} [_inst_1 : Group.{u1} G] [_inst_2 : Monoid.{u2} M], (MonoidHom.{u1, u2} G M (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Monoid.toMulOneClass.{u2} M _inst_2)) -> (MonoidHom.{u1, u2} G (Units.{u2} M _inst_2) (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Units.mulOneClass.{u2} M _inst_2))
but is expected to have type
  forall {G : Type.{u1}} {M : Type.{u2}} [_inst_1 : Group.{u1} G] [_inst_2 : Monoid.{u2} M], (MonoidHom.{u1, u2} G M (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Monoid.toMulOneClass.{u2} M _inst_2)) -> (MonoidHom.{u1, u2} G (Units.{u2} M _inst_2) (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Units.instMulOneClassUnits.{u2} M _inst_2))
Case conversion may be inaccurate. Consider using '#align monoid_hom.to_hom_units MonoidHom.toHomUnitsₓ'. -/
/-- If `f` is a homomorphism from a group `G` to a monoid `M`,
then its image lies in the units of `M`,
and `f.to_hom_units` is the corresponding monoid homomorphism from `G` to `Mˣ`. -/
@[to_additive
      "If `f` is a homomorphism from an additive group `G` to an additive monoid `M`,\nthen its image lies in the `add_units` of `M`,\nand `f.to_hom_units` is the corresponding homomorphism from `G` to `add_units M`."]
def toHomUnits {G M : Type _} [Group G] [Monoid M] (f : G →* M) : G →* Mˣ :=
  Units.liftRight f
    (fun g => ⟨f g, f g⁻¹, map_mul_eq_one f (mul_inv_self _), map_mul_eq_one f (inv_mul_self _)⟩)
    fun g => rfl
#align monoid_hom.to_hom_units MonoidHom.toHomUnits
#align add_monoid_hom.to_hom_add_units AddMonoidHom.toHomAddUnits

/- warning: monoid_hom.coe_to_hom_units -> MonoidHom.coe_toHomUnits is a dubious translation:
lean 3 declaration is
  forall {G : Type.{u1}} {M : Type.{u2}} [_inst_1 : Group.{u1} G] [_inst_2 : Monoid.{u2} M] (f : MonoidHom.{u1, u2} G M (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Monoid.toMulOneClass.{u2} M _inst_2)) (g : G), Eq.{succ u2} M ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} M _inst_2) M (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} M _inst_2) M (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} M _inst_2) M (coeBase.{succ u2, succ u2} (Units.{u2} M _inst_2) M (Units.hasCoe.{u2} M _inst_2)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} G (Units.{u2} M _inst_2) (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Units.mulOneClass.{u2} M _inst_2)) (fun (_x : MonoidHom.{u1, u2} G (Units.{u2} M _inst_2) (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Units.mulOneClass.{u2} M _inst_2)) => G -> (Units.{u2} M _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} G (Units.{u2} M _inst_2) (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Units.mulOneClass.{u2} M _inst_2)) (MonoidHom.toHomUnits.{u1, u2} G M _inst_1 _inst_2 f) g)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} G M (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Monoid.toMulOneClass.{u2} M _inst_2)) (fun (_x : MonoidHom.{u1, u2} G M (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Monoid.toMulOneClass.{u2} M _inst_2)) => G -> M) (MonoidHom.hasCoeToFun.{u1, u2} G M (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_1))) (Monoid.toMulOneClass.{u2} M _inst_2)) f g)
but is expected to have type
  forall {G : Type.{u2}} {M : Type.{u1}} [_inst_1 : Group.{u2} G] [_inst_2 : Monoid.{u1} M] (f : MonoidHom.{u2, u1} G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2)) (g : G), Eq.{succ u1} M (Units.val.{u1} M _inst_2 (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} G (Units.{u1} M _inst_2) (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Units.instMulOneClassUnits.{u1} M _inst_2)) G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => Units.{u1} M _inst_2) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} G (Units.{u1} M _inst_2) (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Units.instMulOneClassUnits.{u1} M _inst_2)) G (Units.{u1} M _inst_2) (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} (Units.{u1} M _inst_2) (Units.instMulOneClassUnits.{u1} M _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} G (Units.{u1} M _inst_2) (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Units.instMulOneClassUnits.{u1} M _inst_2)) G (Units.{u1} M _inst_2) (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Units.instMulOneClassUnits.{u1} M _inst_2) (MonoidHom.monoidHomClass.{u2, u1} G (Units.{u1} M _inst_2) (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Units.instMulOneClassUnits.{u1} M _inst_2)))) (MonoidHom.toHomUnits.{u2, u1} G M _inst_1 _inst_2 f) g)) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2)) G (fun (_x : G) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : G) => M) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2)) G M (MulOneClass.toMul.{u2} G (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1)))) (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2)) G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2) (MonoidHom.monoidHomClass.{u2, u1} G M (Monoid.toMulOneClass.{u2} G (DivInvMonoid.toMonoid.{u2} G (Group.toDivInvMonoid.{u2} G _inst_1))) (Monoid.toMulOneClass.{u1} M _inst_2)))) f g)
Case conversion may be inaccurate. Consider using '#align monoid_hom.coe_to_hom_units MonoidHom.coe_toHomUnitsₓ'. -/
@[simp, to_additive]
theorem coe_toHomUnits {G M : Type _} [Group G] [Monoid M] (f : G →* M) (g : G) :
    (f.toHomUnits g : M) = f g :=
  rfl
#align monoid_hom.coe_to_hom_units MonoidHom.coe_toHomUnits
#align add_monoid_hom.coe_to_hom_add_units AddMonoidHom.coe_toHomAddUnits

end MonoidHom

namespace IsUnit

variable {F G α M N : Type _}

section Monoid

variable [Monoid M] [Monoid N]

/- warning: is_unit.map -> IsUnit.map is a dubious translation:
lean 3 declaration is
  forall {F : Type.{u1}} {M : Type.{u2}} {N : Type.{u3}} [_inst_1 : Monoid.{u2} M] [_inst_2 : Monoid.{u3} N] [_inst_3 : MonoidHomClass.{u1, u2, u3} F M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u3} N _inst_2)] (f : F) {x : M}, (IsUnit.{u2} M _inst_1 x) -> (IsUnit.{u3} N _inst_2 (coeFn.{succ u1, max (succ u2) (succ u3)} F (fun (_x : F) => M -> N) (FunLike.hasCoeToFun.{succ u1, succ u2, succ u3} F M (fun (_x : M) => N) (MulHomClass.toFunLike.{u1, u2, u3} F M N (MulOneClass.toHasMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toHasMul.{u3} N (Monoid.toMulOneClass.{u3} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} F M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u3} N _inst_2) _inst_3))) f x))
but is expected to have type
  forall {F : Type.{u3}} {M : Type.{u2}} {N : Type.{u1}} [_inst_1 : Monoid.{u2} M] [_inst_2 : Monoid.{u1} N] [_inst_3 : MonoidHomClass.{u3, u2, u1} F M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)] (f : F) {x : M}, (IsUnit.{u2} M _inst_1 x) -> (IsUnit.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{succ u3, succ u2, succ u1} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{u3, u2, u1} F M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{u3, u2, u1} F M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) _inst_3)) f x))
Case conversion may be inaccurate. Consider using '#align is_unit.map IsUnit.mapₓ'. -/
@[to_additive]
theorem map [MonoidHomClass F M N] (f : F) {x : M} (h : IsUnit x) : IsUnit (f x) := by
  rcases h with ⟨y, rfl⟩ <;> exact (Units.map (f : M →* N) y).IsUnit
#align is_unit.map IsUnit.map
#align is_add_unit.map IsAddUnit.map

/- warning: is_unit.of_left_inverse -> IsUnit.of_leftInverse is a dubious translation:
lean 3 declaration is
  forall {F : Type.{u1}} {G : Type.{u2}} {M : Type.{u3}} {N : Type.{u4}} [_inst_1 : Monoid.{u3} M] [_inst_2 : Monoid.{u4} N] [_inst_3 : MonoidHomClass.{u1, u3, u4} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u4} N _inst_2)] [_inst_4 : MonoidHomClass.{u2, u4, u3} G N M (Monoid.toMulOneClass.{u4} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1)] {f : F} {x : M} (g : G), (Function.LeftInverse.{succ u3, succ u4} M N (coeFn.{succ u2, max (succ u4) (succ u3)} G (fun (_x : G) => N -> M) (FunLike.hasCoeToFun.{succ u2, succ u4, succ u3} G N (fun (_x : N) => M) (MulHomClass.toFunLike.{u2, u4, u3} G N M (MulOneClass.toHasMul.{u4} N (Monoid.toMulOneClass.{u4} N _inst_2)) (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MonoidHomClass.toMulHomClass.{u2, u4, u3} G N M (Monoid.toMulOneClass.{u4} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1) _inst_4))) g) (coeFn.{succ u1, max (succ u3) (succ u4)} F (fun (_x : F) => M -> N) (FunLike.hasCoeToFun.{succ u1, succ u3, succ u4} F M (fun (_x : M) => N) (MulHomClass.toFunLike.{u1, u3, u4} F M N (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toHasMul.{u4} N (Monoid.toMulOneClass.{u4} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u3, u4} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u4} N _inst_2) _inst_3))) f)) -> (IsUnit.{u4} N _inst_2 (coeFn.{succ u1, max (succ u3) (succ u4)} F (fun (_x : F) => M -> N) (FunLike.hasCoeToFun.{succ u1, succ u3, succ u4} F M (fun (_x : M) => N) (MulHomClass.toFunLike.{u1, u3, u4} F M N (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toHasMul.{u4} N (Monoid.toMulOneClass.{u4} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u3, u4} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u4} N _inst_2) _inst_3))) f x)) -> (IsUnit.{u3} M _inst_1 x)
but is expected to have type
  forall {F : Type.{u4}} {G : Type.{u1}} {M : Type.{u3}} {N : Type.{u2}} [_inst_1 : Monoid.{u3} M] [_inst_2 : Monoid.{u2} N] [_inst_3 : MonoidHomClass.{u4, u3, u2} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)] [_inst_4 : MonoidHomClass.{u1, u2, u3} G N M (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1)] {f : F} {x : M} (g : G), (Function.LeftInverse.{succ u3, succ u2} M N (FunLike.coe.{succ u1, succ u2, succ u3} G N (fun (_x : N) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : N) => M) _x) (MulHomClass.toFunLike.{u1, u2, u3} G N M (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} G N M (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1) _inst_4)) g) (FunLike.coe.{succ u4, succ u3, succ u2} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{u4, u3, u2} F M N (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{u4, u3, u2} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) _inst_3)) f)) -> (IsUnit.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{succ u4, succ u3, succ u2} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{u4, u3, u2} F M N (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{u4, u3, u2} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) _inst_3)) f x)) -> (IsUnit.{u3} M _inst_1 x)
Case conversion may be inaccurate. Consider using '#align is_unit.of_left_inverse IsUnit.of_leftInverseₓ'. -/
@[to_additive]
theorem of_leftInverse [MonoidHomClass F M N] [MonoidHomClass G N M] {f : F} {x : M} (g : G)
    (hfg : Function.LeftInverse g f) (h : IsUnit (f x)) : IsUnit x := by
  simpa only [hfg x] using h.map g
#align is_unit.of_left_inverse IsUnit.of_leftInverse
#align is_add_unit.of_left_inverse IsAddUnit.of_leftInverse

/- warning: is_unit_map_of_left_inverse -> isUnit_map_of_leftInverse is a dubious translation:
lean 3 declaration is
  forall {F : Type.{u1}} {G : Type.{u2}} {M : Type.{u3}} {N : Type.{u4}} [_inst_1 : Monoid.{u3} M] [_inst_2 : Monoid.{u4} N] [_inst_3 : MonoidHomClass.{u1, u3, u4} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u4} N _inst_2)] [_inst_4 : MonoidHomClass.{u2, u4, u3} G N M (Monoid.toMulOneClass.{u4} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1)] {f : F} {x : M} (g : G), (Function.LeftInverse.{succ u3, succ u4} M N (coeFn.{succ u2, max (succ u4) (succ u3)} G (fun (_x : G) => N -> M) (FunLike.hasCoeToFun.{succ u2, succ u4, succ u3} G N (fun (_x : N) => M) (MulHomClass.toFunLike.{u2, u4, u3} G N M (MulOneClass.toHasMul.{u4} N (Monoid.toMulOneClass.{u4} N _inst_2)) (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MonoidHomClass.toMulHomClass.{u2, u4, u3} G N M (Monoid.toMulOneClass.{u4} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1) _inst_4))) g) (coeFn.{succ u1, max (succ u3) (succ u4)} F (fun (_x : F) => M -> N) (FunLike.hasCoeToFun.{succ u1, succ u3, succ u4} F M (fun (_x : M) => N) (MulHomClass.toFunLike.{u1, u3, u4} F M N (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toHasMul.{u4} N (Monoid.toMulOneClass.{u4} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u3, u4} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u4} N _inst_2) _inst_3))) f)) -> (Iff (IsUnit.{u4} N _inst_2 (coeFn.{succ u1, max (succ u3) (succ u4)} F (fun (_x : F) => M -> N) (FunLike.hasCoeToFun.{succ u1, succ u3, succ u4} F M (fun (_x : M) => N) (MulHomClass.toFunLike.{u1, u3, u4} F M N (MulOneClass.toHasMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toHasMul.{u4} N (Monoid.toMulOneClass.{u4} N _inst_2)) (MonoidHomClass.toMulHomClass.{u1, u3, u4} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u4} N _inst_2) _inst_3))) f x)) (IsUnit.{u3} M _inst_1 x))
but is expected to have type
  forall {F : Type.{u4}} {G : Type.{u1}} {M : Type.{u3}} {N : Type.{u2}} [_inst_1 : Monoid.{u3} M] [_inst_2 : Monoid.{u2} N] [_inst_3 : MonoidHomClass.{u4, u3, u2} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)] [_inst_4 : MonoidHomClass.{u1, u2, u3} G N M (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1)] {f : F} {x : M} (g : G), (Function.LeftInverse.{succ u3, succ u2} M N (FunLike.coe.{succ u1, succ u2, succ u3} G N (fun (_x : N) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : N) => M) _x) (MulHomClass.toFunLike.{u1, u2, u3} G N M (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MonoidHomClass.toMulHomClass.{u1, u2, u3} G N M (Monoid.toMulOneClass.{u2} N _inst_2) (Monoid.toMulOneClass.{u3} M _inst_1) _inst_4)) g) (FunLike.coe.{succ u4, succ u3, succ u2} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{u4, u3, u2} F M N (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{u4, u3, u2} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) _inst_3)) f)) -> (Iff (IsUnit.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{succ u4, succ u3, succ u2} F M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{u4, u3, u2} F M N (MulOneClass.toMul.{u3} M (Monoid.toMulOneClass.{u3} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{u4, u3, u2} F M N (Monoid.toMulOneClass.{u3} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) _inst_3)) f x)) (IsUnit.{u3} M _inst_1 x))
Case conversion may be inaccurate. Consider using '#align is_unit_map_of_left_inverse isUnit_map_of_leftInverseₓ'. -/
@[to_additive]
theorem isUnit_map_of_leftInverse [MonoidHomClass F M N] [MonoidHomClass G N M] {f : F} {x : M}
    (g : G) (hfg : Function.LeftInverse g f) : IsUnit (f x) ↔ IsUnit x :=
  ⟨of_leftInverse g hfg, map _⟩
#align is_unit_map_of_left_inverse isUnit_map_of_leftInverse
#align is_add_unit_map_of_left_inverse isAddUnit_map_of_leftInverse

/- warning: is_unit.lift_right -> IsUnit.liftRight is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)), (forall (x : M), IsUnit.{u2} N _inst_2 (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) -> (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2))
but is expected to have type
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)), (forall (x : M), IsUnit.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M _inst_1)) (MulOneClass.toMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u1 u2, u1, u2} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2) (MonoidHom.monoidHomClass.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)))) f x)) -> (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.instMulOneClassUnits.{u2} N _inst_2))
Case conversion may be inaccurate. Consider using '#align is_unit.lift_right IsUnit.liftRightₓ'. -/
/-- If a homomorphism `f : M →* N` sends each element to an `is_unit`, then it can be lifted
to `f : M →* Nˣ`. See also `units.lift_right` for a computable version. -/
@[to_additive
      "If a homomorphism `f : M →+ N` sends each element to an `is_add_unit`, then it can be\nlifted to `f : M →+ add_units N`. See also `add_units.lift_right` for a computable version."]
noncomputable def liftRight (f : M →* N) (hf : ∀ x, IsUnit (f x)) : M →* Nˣ :=
  Units.liftRight f (fun x => (hf x).Unit) fun x => rfl
#align is_unit.lift_right IsUnit.liftRight
#align is_add_unit.lift_right IsAddUnit.liftRight

/- warning: is_unit.coe_lift_right -> IsUnit.coe_liftRight is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (hf : forall (x : M), IsUnit.{u2} N _inst_2 (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (x : M), Eq.{succ u2} N ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => M -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (IsUnit.liftRight.{u1, u2} M N _inst_1 _inst_2 f hf) x)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)
but is expected to have type
  forall {M : Type.{u2}} {N : Type.{u1}} [_inst_1 : Monoid.{u2} M] [_inst_2 : Monoid.{u1} N] (f : MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) (hf : forall (x : M), IsUnit.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)))) f x)) (x : M), Eq.{succ u1} N (Units.val.{u1} N _inst_2 (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u1} N _inst_2) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (Units.{u1} N _inst_2) (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} (Units.{u1} N _inst_2) (Units.instMulOneClassUnits.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)))) (IsUnit.liftRight.{u2, u1} M N _inst_1 _inst_2 f hf) x)) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)))) f x)
Case conversion may be inaccurate. Consider using '#align is_unit.coe_lift_right IsUnit.coe_liftRightₓ'. -/
@[to_additive]
theorem coe_liftRight (f : M →* N) (hf : ∀ x, IsUnit (f x)) (x) :
    (IsUnit.liftRight f hf x : N) = f x :=
  rfl
#align is_unit.coe_lift_right IsUnit.coe_liftRight
#align is_add_unit.coe_lift_right IsAddUnit.coe_liftRight

/- warning: is_unit.mul_lift_right_inv -> IsUnit.mul_liftRight_inv is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (h : forall (x : M), IsUnit.{u2} N _inst_2 (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (x : M), Eq.{succ u2} N (HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (MulOneClass.toHasMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x) ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (Inv.inv.{u2} (Units.{u2} N _inst_2) (Units.hasInv.{u2} N _inst_2) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => M -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (IsUnit.liftRight.{u1, u2} M N _inst_1 _inst_2 f h) x)))) (OfNat.ofNat.{u2} N 1 (OfNat.mk.{u2} N 1 (One.one.{u2} N (MulOneClass.toHasOne.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)))))
but is expected to have type
  forall {M : Type.{u2}} {N : Type.{u1}} [_inst_1 : Monoid.{u2} M] [_inst_2 : Monoid.{u1} N] (f : MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) (h : forall (x : M), IsUnit.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)))) f x)) (x : M), Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (MulOneClass.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toMulOneClass.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)))) f x) (Units.val.{u1} N _inst_2 (Inv.inv.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u1} N _inst_2) x) (Units.instInvUnits.{u1} N _inst_2) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u1} N _inst_2) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (Units.{u1} N _inst_2) (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} (Units.{u1} N _inst_2) (Units.instMulOneClassUnits.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)))) (IsUnit.liftRight.{u2, u1} M N _inst_1 _inst_2 f h) x)))) (OfNat.ofNat.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) 1 (One.toOfNat1.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toOne.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2)))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_lift_right_inv IsUnit.mul_liftRight_invₓ'. -/
@[simp, to_additive]
theorem mul_liftRight_inv (f : M →* N) (h : ∀ x, IsUnit (f x)) (x) :
    f x * ↑(IsUnit.liftRight f h x)⁻¹ = 1 :=
  Units.mul_liftRight_inv (fun y => rfl) x
#align is_unit.mul_lift_right_inv IsUnit.mul_liftRight_inv
#align is_add_unit.add_lift_right_neg IsAddUnit.add_liftRight_neg

/- warning: is_unit.lift_right_inv_mul -> IsUnit.liftRight_inv_mul is a dubious translation:
lean 3 declaration is
  forall {M : Type.{u1}} {N : Type.{u2}} [_inst_1 : Monoid.{u1} M] [_inst_2 : Monoid.{u2} N] (f : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (h : forall (x : M), IsUnit.{u2} N _inst_2 (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (x : M), Eq.{succ u2} N (HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (MulOneClass.toHasMul.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2))) ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Units.{u2} N _inst_2) N (HasLiftT.mk.{succ u2, succ u2} (Units.{u2} N _inst_2) N (CoeTCₓ.coe.{succ u2, succ u2} (Units.{u2} N _inst_2) N (coeBase.{succ u2, succ u2} (Units.{u2} N _inst_2) N (Units.hasCoe.{u2} N _inst_2)))) (Inv.inv.{u2} (Units.{u2} N _inst_2) (Units.hasInv.{u2} N _inst_2) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) => M -> (Units.{u2} N _inst_2)) (MonoidHom.hasCoeToFun.{u1, u2} M (Units.{u2} N _inst_2) (Monoid.toMulOneClass.{u1} M _inst_1) (Units.mulOneClass.{u2} N _inst_2)) (IsUnit.liftRight.{u1, u2} M N _inst_1 _inst_2 f h) x))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) (fun (_x : MonoidHom.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) => M -> N) (MonoidHom.hasCoeToFun.{u1, u2} M N (Monoid.toMulOneClass.{u1} M _inst_1) (Monoid.toMulOneClass.{u2} N _inst_2)) f x)) (OfNat.ofNat.{u2} N 1 (OfNat.mk.{u2} N 1 (One.one.{u2} N (MulOneClass.toHasOne.{u2} N (Monoid.toMulOneClass.{u2} N _inst_2)))))
but is expected to have type
  forall {M : Type.{u2}} {N : Type.{u1}} [_inst_1 : Monoid.{u2} M] [_inst_2 : Monoid.{u1} N] (f : MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) (h : forall (x : M), IsUnit.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2 (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)))) f x)) (x : M), Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (MulOneClass.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toMulOneClass.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2))) (Units.val.{u1} N _inst_2 (Inv.inv.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u1} N _inst_2) x) (Units.instInvUnits.{u1} N _inst_2) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => Units.{u1} N _inst_2) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (Units.{u1} N _inst_2) (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} (Units.{u1} N _inst_2) (Units.instMulOneClassUnits.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)) M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M (Units.{u1} N _inst_2) (Monoid.toMulOneClass.{u2} M _inst_1) (Units.instMulOneClassUnits.{u1} N _inst_2)))) (IsUnit.liftRight.{u2, u1} M N _inst_1 _inst_2 f h) x))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (MulOneClass.toMul.{u2} M (Monoid.toMulOneClass.{u2} M _inst_1)) (MulOneClass.toMul.{u1} N (Monoid.toMulOneClass.{u1} N _inst_2)) (MonoidHomClass.toMulHomClass.{max u2 u1, u2, u1} (MonoidHom.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)) M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2) (MonoidHom.monoidHomClass.{u2, u1} M N (Monoid.toMulOneClass.{u2} M _inst_1) (Monoid.toMulOneClass.{u1} N _inst_2)))) f x)) (OfNat.ofNat.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) 1 (One.toOfNat1.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Monoid.toOne.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) _inst_2)))
Case conversion may be inaccurate. Consider using '#align is_unit.lift_right_inv_mul IsUnit.liftRight_inv_mulₓ'. -/
@[simp, to_additive]
theorem liftRight_inv_mul (f : M →* N) (h : ∀ x, IsUnit (f x)) (x) :
    ↑(IsUnit.liftRight f h x)⁻¹ * f x = 1 :=
  Units.liftRight_inv_mul (fun y => rfl) x
#align is_unit.lift_right_inv_mul IsUnit.liftRight_inv_mul
#align is_add_unit.lift_right_neg_add IsAddUnit.liftRight_neg_add

end Monoid

section DivisionMonoid

variable [DivisionMonoid α] {a b c : α}

#print IsUnit.unit' /-
/-- The element of the group of units, corresponding to an element of a monoid which is a unit. As
opposed to `is_unit.unit`, the inverse is computable and comes from the inversion on `α`. This is
useful to transfer properties of inversion in `units α` to `α`. See also `to_units`. -/
@[to_additive
      "The element of the additive group of additive units, corresponding to an element of\nan additive monoid which is an additive unit. As opposed to `is_add_unit.add_unit`, the negation is\ncomputable and comes from the negation on `α`. This is useful to transfer properties of negation in\n`add_units α` to `α`. See also `to_add_units`.",
  simps]
def unit' (h : IsUnit a) : αˣ :=
  ⟨a, a⁻¹, h.mul_inv_cancel, h.inv_mul_cancel⟩
#align is_unit.unit' IsUnit.unit'
#align is_add_unit.add_unit' IsAddUnit.addUnit'
-/

/- warning: is_unit.mul_inv_cancel_left -> IsUnit.mul_inv_cancel_left is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (forall (b : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) b)) b)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (forall (b : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) a) b)) b)
Case conversion may be inaccurate. Consider using '#align is_unit.mul_inv_cancel_left IsUnit.mul_inv_cancel_leftₓ'. -/
@[simp, to_additive]
protected theorem mul_inv_cancel_left (h : IsUnit a) : ∀ b, a * (a⁻¹ * b) = b :=
  h.unit'.mul_inv_cancel_left
#align is_unit.mul_inv_cancel_left IsUnit.mul_inv_cancel_left
#align is_add_unit.add_neg_cancel_left IsAddUnit.add_neg_cancel_left

/- warning: is_unit.inv_mul_cancel_left -> IsUnit.inv_mul_cancel_left is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (forall (b : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b)) b)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (forall (b : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) a) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b)) b)
Case conversion may be inaccurate. Consider using '#align is_unit.inv_mul_cancel_left IsUnit.inv_mul_cancel_leftₓ'. -/
@[simp, to_additive]
protected theorem inv_mul_cancel_left (h : IsUnit a) : ∀ b, a⁻¹ * (a * b) = b :=
  h.unit'.inv_mul_cancel_left
#align is_unit.inv_mul_cancel_left IsUnit.inv_mul_cancel_left
#align is_add_unit.neg_add_cancel_left IsAddUnit.neg_add_cancel_left

/- warning: is_unit.mul_inv_cancel_right -> IsUnit.mul_inv_cancel_right is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b)) a)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) b)) a)
Case conversion may be inaccurate. Consider using '#align is_unit.mul_inv_cancel_right IsUnit.mul_inv_cancel_rightₓ'. -/
@[simp, to_additive]
protected theorem mul_inv_cancel_right (h : IsUnit b) (a : α) : a * b * b⁻¹ = a :=
  h.unit'.mul_inv_cancel_right _
#align is_unit.mul_inv_cancel_right IsUnit.mul_inv_cancel_right
#align is_add_unit.add_neg_cancel_right IsAddUnit.add_neg_cancel_right

/- warning: is_unit.inv_mul_cancel_right -> IsUnit.inv_mul_cancel_right is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b)) b) a)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) b)) b) a)
Case conversion may be inaccurate. Consider using '#align is_unit.inv_mul_cancel_right IsUnit.inv_mul_cancel_rightₓ'. -/
@[simp, to_additive]
protected theorem inv_mul_cancel_right (h : IsUnit b) (a : α) : a * b⁻¹ * b = a :=
  h.unit'.inv_mul_cancel_right _
#align is_unit.inv_mul_cancel_right IsUnit.inv_mul_cancel_right
#align is_add_unit.neg_add_cancel_right IsAddUnit.neg_add_cancel_right

/- warning: is_unit.div_self -> IsUnit.div_self is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a a) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a a) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))))
Case conversion may be inaccurate. Consider using '#align is_unit.div_self IsUnit.div_selfₓ'. -/
@[to_additive]
protected theorem div_self (h : IsUnit a) : a / a = 1 := by rw [div_eq_mul_inv, h.mul_inv_cancel]
#align is_unit.div_self IsUnit.div_self
#align is_add_unit.sub_self IsAddUnit.sub_self

/- warning: is_unit.eq_mul_inv_iff_mul_eq -> IsUnit.eq_mul_inv_iff_mul_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Iff (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) b (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c))) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Iff (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) b (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) c))) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) b))
Case conversion may be inaccurate. Consider using '#align is_unit.eq_mul_inv_iff_mul_eq IsUnit.eq_mul_inv_iff_mul_eqₓ'. -/
@[to_additive]
protected theorem eq_mul_inv_iff_mul_eq (h : IsUnit c) : a = b * c⁻¹ ↔ a * c = b :=
  h.unit'.eq_mul_inv_iff_mul_eq
#align is_unit.eq_mul_inv_iff_mul_eq IsUnit.eq_mul_inv_iff_mul_eq
#align is_add_unit.eq_add_neg_iff_add_eq IsAddUnit.eq_add_neg_iff_add_eq

/- warning: is_unit.eq_inv_mul_iff_mul_eq -> IsUnit.eq_inv_mul_iff_mul_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) c)) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) b a) c))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) b) c)) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) b a) c))
Case conversion may be inaccurate. Consider using '#align is_unit.eq_inv_mul_iff_mul_eq IsUnit.eq_inv_mul_iff_mul_eqₓ'. -/
@[to_additive]
protected theorem eq_inv_mul_iff_mul_eq (h : IsUnit b) : a = b⁻¹ * c ↔ b * a = c :=
  h.unit'.eq_inv_mul_iff_mul_eq
#align is_unit.eq_inv_mul_iff_mul_eq IsUnit.eq_inv_mul_iff_mul_eq
#align is_add_unit.eq_neg_add_iff_add_eq IsAddUnit.eq_neg_add_iff_add_eq

/- warning: is_unit.inv_mul_eq_iff_eq_mul -> IsUnit.inv_mul_eq_iff_eq_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) b) c) (Eq.{succ u1} α b (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) a) b) c) (Eq.{succ u1} α b (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c)))
Case conversion may be inaccurate. Consider using '#align is_unit.inv_mul_eq_iff_eq_mul IsUnit.inv_mul_eq_iff_eq_mulₓ'. -/
@[to_additive]
protected theorem inv_mul_eq_iff_eq_mul (h : IsUnit a) : a⁻¹ * b = c ↔ b = a * c :=
  h.unit'.inv_mul_eq_iff_eq_mul
#align is_unit.inv_mul_eq_iff_eq_mul IsUnit.inv_mul_eq_iff_eq_mul
#align is_add_unit.neg_add_eq_iff_eq_add IsAddUnit.neg_add_eq_iff_eq_add

/- warning: is_unit.mul_inv_eq_iff_eq_mul -> IsUnit.mul_inv_eq_iff_eq_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b)) c) (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) c b)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) b)) c) (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) c b)))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_inv_eq_iff_eq_mul IsUnit.mul_inv_eq_iff_eq_mulₓ'. -/
@[to_additive]
protected theorem mul_inv_eq_iff_eq_mul (h : IsUnit b) : a * b⁻¹ = c ↔ a = c * b :=
  h.unit'.mul_inv_eq_iff_eq_mul
#align is_unit.mul_inv_eq_iff_eq_mul IsUnit.mul_inv_eq_iff_eq_mul
#align is_add_unit.add_neg_eq_iff_eq_add IsAddUnit.add_neg_eq_iff_eq_add

/- warning: is_unit.mul_inv_eq_one -> IsUnit.mul_inv_eq_one is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b)) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)))))))) (Eq.{succ u1} α a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) b)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1)))))) (Eq.{succ u1} α a b))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_inv_eq_one IsUnit.mul_inv_eq_oneₓ'. -/
@[to_additive]
protected theorem mul_inv_eq_one (h : IsUnit b) : a * b⁻¹ = 1 ↔ a = b :=
  @Units.mul_inv_eq_one _ _ h.unit' _
#align is_unit.mul_inv_eq_one IsUnit.mul_inv_eq_one
#align is_add_unit.add_neg_eq_zero IsAddUnit.add_neg_eq_zero

/- warning: is_unit.inv_mul_eq_one -> IsUnit.inv_mul_eq_one is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) b) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)))))))) (Eq.{succ u1} α a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) a) b) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1)))))) (Eq.{succ u1} α a b))
Case conversion may be inaccurate. Consider using '#align is_unit.inv_mul_eq_one IsUnit.inv_mul_eq_oneₓ'. -/
@[to_additive]
protected theorem inv_mul_eq_one (h : IsUnit a) : a⁻¹ * b = 1 ↔ a = b :=
  @Units.inv_mul_eq_one _ _ h.unit' _
#align is_unit.inv_mul_eq_one IsUnit.inv_mul_eq_one
#align is_add_unit.neg_add_eq_zero IsAddUnit.neg_add_eq_zero

/- warning: is_unit.mul_eq_one_iff_eq_inv -> IsUnit.mul_eq_one_iff_eq_inv is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)))))))) (Eq.{succ u1} α a (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1)))))) (Eq.{succ u1} α a (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) b)))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_eq_one_iff_eq_inv IsUnit.mul_eq_one_iff_eq_invₓ'. -/
@[to_additive]
protected theorem mul_eq_one_iff_eq_inv (h : IsUnit b) : a * b = 1 ↔ a = b⁻¹ :=
  @Units.mul_eq_one_iff_eq_inv _ _ h.unit' _
#align is_unit.mul_eq_one_iff_eq_inv IsUnit.mul_eq_one_iff_eq_inv
#align is_add_unit.add_eq_zero_iff_eq_neg IsAddUnit.add_eq_zero_iff_eq_neg

/- warning: is_unit.mul_eq_one_iff_inv_eq -> IsUnit.mul_eq_one_iff_inv_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)))))))) (Eq.{succ u1} α (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Iff (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1)))))) (Eq.{succ u1} α (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) a) b))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_eq_one_iff_inv_eq IsUnit.mul_eq_one_iff_inv_eqₓ'. -/
@[to_additive]
protected theorem mul_eq_one_iff_inv_eq (h : IsUnit a) : a * b = 1 ↔ a⁻¹ = b :=
  @Units.mul_eq_one_iff_inv_eq _ _ h.unit' _
#align is_unit.mul_eq_one_iff_inv_eq IsUnit.mul_eq_one_iff_inv_eq
#align is_add_unit.add_eq_zero_iff_neg_eq IsAddUnit.add_eq_zero_iff_neg_eq

/- warning: is_unit.div_mul_cancel -> IsUnit.div_mul_cancel is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) b) a)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) b) a)
Case conversion may be inaccurate. Consider using '#align is_unit.div_mul_cancel IsUnit.div_mul_cancelₓ'. -/
@[simp, to_additive]
protected theorem div_mul_cancel (h : IsUnit b) (a : α) : a / b * b = a := by
  rw [div_eq_mul_inv, h.inv_mul_cancel_right]
#align is_unit.div_mul_cancel IsUnit.div_mul_cancel
#align is_add_unit.sub_add_cancel IsAddUnit.sub_add_cancel

/- warning: is_unit.mul_div_cancel -> IsUnit.mul_div_cancel is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) b) a)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (forall (a : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) b) a)
Case conversion may be inaccurate. Consider using '#align is_unit.mul_div_cancel IsUnit.mul_div_cancelₓ'. -/
@[simp, to_additive]
protected theorem mul_div_cancel (h : IsUnit b) (a : α) : a * b / b = a := by
  rw [div_eq_mul_inv, h.mul_inv_cancel_right]
#align is_unit.mul_div_cancel IsUnit.mul_div_cancel
#align is_add_unit.add_sub_cancel IsAddUnit.add_sub_cancel

/- warning: is_unit.mul_one_div_cancel -> IsUnit.mul_one_div_cancel is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))) a)) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))) a)) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_one_div_cancel IsUnit.mul_one_div_cancelₓ'. -/
@[to_additive]
protected theorem mul_one_div_cancel (h : IsUnit a) : a * (1 / a) = 1 := by simp [h]
#align is_unit.mul_one_div_cancel IsUnit.mul_one_div_cancel
#align is_add_unit.add_zero_sub_cancel IsAddUnit.add_zero_sub_cancel

/- warning: is_unit.one_div_mul_cancel -> IsUnit.one_div_mul_cancel is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))) a) a) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))) a) a) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))))
Case conversion may be inaccurate. Consider using '#align is_unit.one_div_mul_cancel IsUnit.one_div_mul_cancelₓ'. -/
@[to_additive]
protected theorem one_div_mul_cancel (h : IsUnit a) : 1 / a * a = 1 := by simp [h]
#align is_unit.one_div_mul_cancel IsUnit.one_div_mul_cancel
#align is_add_unit.zero_sub_add_cancel IsAddUnit.zero_sub_add_cancel

/- warning: is_unit.inv -> IsUnit.inv is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))) a))
Case conversion may be inaccurate. Consider using '#align is_unit.inv IsUnit.invₓ'. -/
@[to_additive]
theorem inv : IsUnit a → IsUnit a⁻¹ := by
  rintro ⟨u, rfl⟩
  rw [← Units.val_inv_eq_inv_val]
  exact Units.isUnit _
#align is_unit.inv IsUnit.inv
#align is_add_unit.neg IsAddUnit.neg

/- warning: is_unit.div -> IsUnit.div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) a) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b))
Case conversion may be inaccurate. Consider using '#align is_unit.div IsUnit.divₓ'. -/
@[to_additive]
theorem div (ha : IsUnit a) (hb : IsUnit b) : IsUnit (a / b) :=
  by
  rw [div_eq_mul_inv]
  exact ha.mul hb.inv
#align is_unit.div IsUnit.div
#align is_add_unit.sub IsAddUnit.sub

/- warning: is_unit.div_left_inj -> IsUnit.div_left_inj is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a c) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b c)) (Eq.{succ u1} α a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a c) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b c)) (Eq.{succ u1} α a b))
Case conversion may be inaccurate. Consider using '#align is_unit.div_left_inj IsUnit.div_left_injₓ'. -/
@[to_additive]
protected theorem div_left_inj (h : IsUnit c) : a / c = b / c ↔ a = b :=
  by
  simp_rw [div_eq_mul_inv]
  exact Units.mul_left_inj h.inv.unit'
#align is_unit.div_left_inj IsUnit.div_left_inj
#align is_add_unit.sub_left_inj IsAddUnit.sub_left_inj

/- warning: is_unit.div_eq_iff -> IsUnit.div_eq_iff is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) c) (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) c b)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) c) (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) c b)))
Case conversion may be inaccurate. Consider using '#align is_unit.div_eq_iff IsUnit.div_eq_iffₓ'. -/
@[to_additive]
protected theorem div_eq_iff (h : IsUnit b) : a / b = c ↔ a = c * b := by
  rw [div_eq_mul_inv, h.mul_inv_eq_iff_eq_mul]
#align is_unit.div_eq_iff IsUnit.div_eq_iff
#align is_add_unit.sub_eq_iff IsAddUnit.sub_eq_iff

/- warning: is_unit.eq_div_iff -> IsUnit.eq_div_iff is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Iff (Eq.{succ u1} α a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b c)) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Iff (Eq.{succ u1} α a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b c)) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) b))
Case conversion may be inaccurate. Consider using '#align is_unit.eq_div_iff IsUnit.eq_div_iffₓ'. -/
@[to_additive]
protected theorem eq_div_iff (h : IsUnit c) : a = b / c ↔ a * c = b := by
  rw [div_eq_mul_inv, h.eq_mul_inv_iff_mul_eq]
#align is_unit.eq_div_iff IsUnit.eq_div_iff
#align is_add_unit.eq_sub_iff IsAddUnit.eq_sub_iff

/- warning: is_unit.div_eq_of_eq_mul -> IsUnit.div_eq_of_eq_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) c b)) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) c)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Eq.{succ u1} α a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) c b)) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) c)
Case conversion may be inaccurate. Consider using '#align is_unit.div_eq_of_eq_mul IsUnit.div_eq_of_eq_mulₓ'. -/
@[to_additive]
protected theorem div_eq_of_eq_mul (h : IsUnit b) : a = c * b → a / b = c :=
  h.div_eq_iff.2
#align is_unit.div_eq_of_eq_mul IsUnit.div_eq_of_eq_mul
#align is_add_unit.sub_eq_of_eq_add IsAddUnit.sub_eq_of_eq_add

/- warning: is_unit.eq_div_of_mul_eq -> IsUnit.eq_div_of_mul_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) b) -> (Eq.{succ u1} α a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b c))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α} {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) b) -> (Eq.{succ u1} α a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b c))
Case conversion may be inaccurate. Consider using '#align is_unit.eq_div_of_mul_eq IsUnit.eq_div_of_mul_eqₓ'. -/
@[to_additive]
protected theorem eq_div_of_mul_eq (h : IsUnit c) : a * c = b → a = b / c :=
  h.eq_div_iff.2
#align is_unit.eq_div_of_mul_eq IsUnit.eq_div_of_mul_eq
#align is_add_unit.eq_sub_of_add_eq IsAddUnit.eq_sub_of_add_eq

/- warning: is_unit.div_eq_one_iff_eq -> IsUnit.div_eq_one_iff_eq is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)))))))) (Eq.{succ u1} α a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1)))))) (Eq.{succ u1} α a b))
Case conversion may be inaccurate. Consider using '#align is_unit.div_eq_one_iff_eq IsUnit.div_eq_one_iff_eqₓ'. -/
@[to_additive]
protected theorem div_eq_one_iff_eq (h : IsUnit b) : a / b = 1 ↔ a = b :=
  ⟨eq_of_div_eq_one, fun hab => hab.symm ▸ h.div_self⟩
#align is_unit.div_eq_one_iff_eq IsUnit.div_eq_one_iff_eq
#align is_add_unit.sub_eq_zero_iff_eq IsAddUnit.sub_eq_zero_iff_eq

/- warning: is_unit.div_mul_left -> IsUnit.div_mul_left is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))) a))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) b (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))) a))
Case conversion may be inaccurate. Consider using '#align is_unit.div_mul_left IsUnit.div_mul_leftₓ'. -/
@[to_additive]
protected theorem div_mul_left (h : IsUnit b) : b / (a * b) = 1 / a := by
  rw [div_eq_mul_inv, mul_inv_rev, h.mul_inv_cancel_left, one_div]
#align is_unit.div_mul_left IsUnit.div_mul_left
#align is_add_unit.sub_add_left IsAddUnit.sub_add_left

/- warning: is_unit.mul_div_mul_right -> IsUnit.mul_div_mul_right is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (forall (a : α) (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) b c)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) c) -> (forall (a : α) (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a c) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) b c)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) a b))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_div_mul_right IsUnit.mul_div_mul_rightₓ'. -/
@[to_additive]
protected theorem mul_div_mul_right (h : IsUnit c) (a b : α) : a * c / (b * c) = a / b := by
  simp only [div_eq_mul_inv, mul_inv_rev, mul_assoc, h.mul_inv_cancel_left]
#align is_unit.mul_div_mul_right IsUnit.mul_div_mul_right
#align is_add_unit.add_sub_add_right IsAddUnit.add_sub_add_right

/- warning: is_unit.mul_mul_div -> IsUnit.mul_mul_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α} (a : α), (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))))) b)) a)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionMonoid.{u1} α] {b : α} (a : α), (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1)) b) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))))) a b) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α _inst_1))) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α _inst_1))))) b)) a)
Case conversion may be inaccurate. Consider using '#align is_unit.mul_mul_div IsUnit.mul_mul_divₓ'. -/
@[to_additive]
protected theorem mul_mul_div (a : α) (h : IsUnit b) : a * b * (1 / b) = a := by simp [h]
#align is_unit.mul_mul_div IsUnit.mul_mul_div
#align is_add_unit.add_add_sub IsAddUnit.add_add_sub

end DivisionMonoid

section DivisionCommMonoid

variable [DivisionCommMonoid α] {a b c d : α}

/- warning: is_unit.div_mul_right -> IsUnit.div_mul_right is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (forall (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a b)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))))) b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (forall (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a b)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) b))
Case conversion may be inaccurate. Consider using '#align is_unit.div_mul_right IsUnit.div_mul_rightₓ'. -/
@[to_additive]
protected theorem div_mul_right (h : IsUnit a) (b : α) : a / (a * b) = 1 / b := by
  rw [mul_comm, h.div_mul_left]
#align is_unit.div_mul_right IsUnit.div_mul_right
#align is_add_unit.sub_add_right IsAddUnit.sub_add_right

/- warning: is_unit.mul_div_cancel_left -> IsUnit.mul_div_cancel_left is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (forall (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a b) a) b)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (forall (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a b) a) b)
Case conversion may be inaccurate. Consider using '#align is_unit.mul_div_cancel_left IsUnit.mul_div_cancel_leftₓ'. -/
@[to_additive]
protected theorem mul_div_cancel_left (h : IsUnit a) (b : α) : a * b / a = b := by
  rw [mul_comm, h.mul_div_cancel]
#align is_unit.mul_div_cancel_left IsUnit.mul_div_cancel_left
#align is_add_unit.add_sub_cancel_left IsAddUnit.add_sub_cancel_left

/- warning: is_unit.mul_div_cancel' -> IsUnit.mul_div_cancel' is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (forall (b : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) b a)) b)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (forall (b : α), Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) b a)) b)
Case conversion may be inaccurate. Consider using '#align is_unit.mul_div_cancel' IsUnit.mul_div_cancel'ₓ'. -/
@[to_additive]
protected theorem mul_div_cancel' (h : IsUnit a) (b : α) : a * (b / a) = b := by
  rw [mul_comm, h.div_mul_cancel]
#align is_unit.mul_div_cancel' IsUnit.mul_div_cancel'
#align is_add_unit.add_sub_cancel' IsAddUnit.add_sub_cancel'

/- warning: is_unit.mul_div_mul_left -> IsUnit.mul_div_mul_left is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) c) -> (forall (a : α) (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c a) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c b)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {c : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) c) -> (forall (a : α) (b : α), Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c a) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c b)) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_div_mul_left IsUnit.mul_div_mul_leftₓ'. -/
@[to_additive]
protected theorem mul_div_mul_left (h : IsUnit c) (a b : α) : c * a / (c * b) = a / b := by
  rw [mul_comm c, mul_comm c, h.mul_div_mul_right]
#align is_unit.mul_div_mul_left IsUnit.mul_div_mul_left
#align is_add_unit.add_sub_add_left IsAddUnit.add_sub_add_left

/- warning: is_unit.mul_eq_mul_of_div_eq_div -> IsUnit.mul_eq_mul_of_div_eq_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {b : α} {d : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) b) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) d) -> (forall (a : α) (c : α), (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) c d)) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a d) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c b)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {b : α} {d : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) b) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) d) -> (forall (a : α) (c : α), (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) c d)) -> (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a d) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c b)))
Case conversion may be inaccurate. Consider using '#align is_unit.mul_eq_mul_of_div_eq_div IsUnit.mul_eq_mul_of_div_eq_divₓ'. -/
@[to_additive]
protected theorem mul_eq_mul_of_div_eq_div (hb : IsUnit b) (hd : IsUnit d) (a c : α)
    (h : a / b = c / d) : a * d = c * b := by
  rw [← mul_one a, ← hb.div_self, ← mul_comm_div, h, div_mul_eq_mul_div, hd.div_mul_cancel]
#align is_unit.mul_eq_mul_of_div_eq_div IsUnit.mul_eq_mul_of_div_eq_div
#align is_add_unit.add_eq_add_of_sub_eq_sub IsAddUnit.add_eq_add_of_sub_eq_sub

/- warning: is_unit.div_eq_div_iff -> IsUnit.div_eq_div_iff is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α} {b : α} {c : α} {d : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) b) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) d) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) c d)) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a d) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c b)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α} {b : α} {c : α} {d : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) b) -> (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) d) -> (Iff (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) c d)) (Eq.{succ u1} α (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) a d) (HMul.hMul.{u1, u1, u1} α α α (instHMul.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))))) c b)))
Case conversion may be inaccurate. Consider using '#align is_unit.div_eq_div_iff IsUnit.div_eq_div_iffₓ'. -/
@[to_additive]
protected theorem div_eq_div_iff (hb : IsUnit b) (hd : IsUnit d) : a / b = c / d ↔ a * d = c * b :=
  by
  rw [← (hb.mul hd).mul_left_inj, ← mul_assoc, hb.div_mul_cancel, ← mul_assoc, mul_right_comm,
    hd.div_mul_cancel]
#align is_unit.div_eq_div_iff IsUnit.div_eq_div_iff
#align is_add_unit.sub_eq_sub_iff IsAddUnit.sub_eq_sub_iff

/- warning: is_unit.div_div_cancel -> IsUnit.div_div_cancel is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b)) b)
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b)) b)
Case conversion may be inaccurate. Consider using '#align is_unit.div_div_cancel IsUnit.div_div_cancelₓ'. -/
@[to_additive]
protected theorem div_div_cancel (h : IsUnit a) : a / (a / b) = b := by
  rw [div_div_eq_mul_div, h.mul_div_cancel_left]
#align is_unit.div_div_cancel IsUnit.div_div_cancel
#align is_add_unit.sub_sub_cancel IsAddUnit.sub_sub_cancel

/- warning: is_unit.div_div_cancel_left -> IsUnit.div_div_cancel_left is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toHasDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b) a) (Inv.inv.{u1} α (DivInvMonoid.toHasInv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) b))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : DivisionCommMonoid.{u1} α] {a : α} {b : α}, (IsUnit.{u1} α (DivInvMonoid.toMonoid.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1))) a) -> (Eq.{succ u1} α (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) (HDiv.hDiv.{u1, u1, u1} α α α (instHDiv.{u1} α (DivInvMonoid.toDiv.{u1} α (DivisionMonoid.toDivInvMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) a b) a) (Inv.inv.{u1} α (InvOneClass.toInv.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α _inst_1)))) b))
Case conversion may be inaccurate. Consider using '#align is_unit.div_div_cancel_left IsUnit.div_div_cancel_leftₓ'. -/
@[to_additive]
protected theorem div_div_cancel_left (h : IsUnit a) : a / b / a = b⁻¹ := by
  rw [div_eq_mul_inv, div_eq_mul_inv, mul_right_comm, h.mul_inv_cancel, one_mul]
#align is_unit.div_div_cancel_left IsUnit.div_div_cancel_left
#align is_add_unit.sub_sub_cancel_left IsAddUnit.sub_sub_cancel_left

end DivisionCommMonoid

end IsUnit