algebra.group_with_zero.defsMathlib.Algebra.GroupWithZero.NeZero

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

refactor(algebra/group_with_zero/defs): use is_*cancel_mul_zero (#17963)
Diff
@@ -38,29 +38,75 @@ class mul_zero_class (M₀ : Type*) extends has_mul M₀, has_zero M₀ :=
 (zero_mul : ∀ a : M₀, 0 * a = 0)
 (mul_zero : ∀ a : M₀, a * 0 = 0)
 
+section mul_zero_class
+
+variables [mul_zero_class M₀] {a b : M₀}
+
+@[ematch, simp] lemma zero_mul (a : M₀) : 0 * a = 0 :=
+mul_zero_class.zero_mul a
+
+@[ematch, simp] lemma mul_zero (a : M₀) : a * 0 = 0 :=
+mul_zero_class.mul_zero a
+
+end mul_zero_class
+
 /-- A mixin for left cancellative multiplication by nonzero elements. -/
 @[protect_proj] class is_left_cancel_mul_zero (M₀ : Type u) [has_mul M₀] [has_zero M₀] : Prop :=
 (mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c)
 
+section is_left_cancel_mul_zero
+
+variables [has_mul M₀] [has_zero M₀] [is_left_cancel_mul_zero M₀] {a b c : M₀}
+
+lemma mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
+is_left_cancel_mul_zero.mul_left_cancel_of_ne_zero ha h
+
+lemma mul_right_injective₀ (ha : a ≠ 0) : function.injective ((*) a) :=
+λ b c, mul_left_cancel₀ ha
+
+end is_left_cancel_mul_zero
+
 /-- A mixin for right cancellative multiplication by nonzero elements. -/
 @[protect_proj] class is_right_cancel_mul_zero (M₀ : Type u) [has_mul M₀] [has_zero M₀] : Prop :=
 (mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c)
 
+section is_right_cancel_mul_zero
+
+variables [has_mul M₀] [has_zero M₀] [is_right_cancel_mul_zero M₀] {a b c : M₀}
+
+lemma mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
+is_right_cancel_mul_zero.mul_right_cancel_of_ne_zero hb h
+
+lemma mul_left_injective₀ (hb : b ≠ 0) : function.injective (λ a, a * b) :=
+λ a c, mul_right_cancel₀ hb
+
+end is_right_cancel_mul_zero
+
 /-- A mixin for cancellative multiplication by nonzero elements. -/
 @[protect_proj] class is_cancel_mul_zero (M₀ : Type u) [has_mul M₀] [has_zero M₀]
   extends is_left_cancel_mul_zero M₀, is_right_cancel_mul_zero M₀ : Prop
 
-section mul_zero_class
+section comm_semigroup_with_zero
 
-variables [mul_zero_class M₀] {a b : M₀}
+variables [comm_semigroup M₀] [has_zero M₀]
 
-@[ematch, simp] lemma zero_mul (a : M₀) : 0 * a = 0 :=
-mul_zero_class.zero_mul a
+lemma is_left_cancel_mul_zero.to_is_right_cancel_mul_zero [is_left_cancel_mul_zero M₀] :
+  is_right_cancel_mul_zero M₀ :=
+⟨λ a b c ha h, mul_left_cancel₀ ha $ (mul_comm _ _).trans $ (h.trans (mul_comm _ _))⟩
 
-@[ematch, simp] lemma mul_zero (a : M₀) : a * 0 = 0 :=
-mul_zero_class.mul_zero a
+lemma is_right_cancel_mul_zero.to_is_left_cancel_mul_zero [is_right_cancel_mul_zero M₀] :
+  is_left_cancel_mul_zero M₀ :=
+⟨λ a b c ha h, mul_right_cancel₀ ha $ (mul_comm _ _).trans $ (h.trans (mul_comm _ _))⟩
 
-end mul_zero_class
+lemma is_left_cancel_mul_zero.to_is_cancel_mul_zero [is_left_cancel_mul_zero M₀] :
+  is_cancel_mul_zero M₀ :=
+{ .. ‹is_left_cancel_mul_zero M₀›, .. is_left_cancel_mul_zero.to_is_right_cancel_mul_zero }
+
+lemma is_right_cancel_mul_zero.to_is_cancel_mul_zero [is_right_cancel_mul_zero M₀] :
+  is_cancel_mul_zero M₀ :=
+{ .. ‹is_right_cancel_mul_zero M₀›, .. is_right_cancel_mul_zero.to_is_left_cancel_mul_zero }
+
+end comm_semigroup_with_zero
 
 /-- Predicate typeclass for expressing that `a * b = 0` implies `a = 0` or `b = 0`
 for all `a` and `b` of type `G₀`. -/
@@ -97,31 +143,11 @@ class cancel_monoid_with_zero (M₀ : Type*) extends monoid_with_zero M₀ :=
 (mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c)
 (mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c)
 
-section cancel_monoid_with_zero
-
-variables [cancel_monoid_with_zero M₀] {a b c : M₀}
-
-lemma mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
-cancel_monoid_with_zero.mul_left_cancel_of_ne_zero ha h
-
-lemma mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
-cancel_monoid_with_zero.mul_right_cancel_of_ne_zero hb h
-
-lemma mul_right_injective₀ (ha : a ≠ 0) : function.injective ((*) a) :=
-λ b c, mul_left_cancel₀ ha
-
-lemma mul_left_injective₀ (hb : b ≠ 0) : function.injective (λ a, a * b) :=
-λ a c, mul_right_cancel₀ hb
-
 /-- A `cancel_monoid_with_zero` satisfies `is_cancel_mul_zero`. -/
 @[priority 100]
-instance cancel_monoid_with_zero.to_is_cancel_mul_zero : is_cancel_mul_zero M₀ :=
-{ mul_left_cancel_of_ne_zero := λ a b c ha h,
-    cancel_monoid_with_zero.mul_left_cancel_of_ne_zero ha h,
-  mul_right_cancel_of_ne_zero :=  λ a b c hb h,
-    cancel_monoid_with_zero.mul_right_cancel_of_ne_zero hb h, }
-
-end cancel_monoid_with_zero
+instance cancel_monoid_with_zero.to_is_cancel_mul_zero [cancel_monoid_with_zero M₀] :
+  is_cancel_mul_zero M₀ :=
+{ .. ‹cancel_monoid_with_zero M₀› }
 
 /-- A type `M` is a commutative “monoid with zero” if it is a commutative monoid with zero
 element, and `0` is left and right absorbing. -/
@@ -132,8 +158,13 @@ class comm_monoid_with_zero (M₀ : Type*) extends comm_monoid M₀, monoid_with
  `0` is left and right absorbing,
   and left/right multiplication by a non-zero element is injective. -/
 @[protect_proj, ancestor comm_monoid_with_zero cancel_monoid_with_zero]
-class cancel_comm_monoid_with_zero (M₀ : Type*) extends
-  comm_monoid_with_zero M₀, cancel_monoid_with_zero M₀.
+class cancel_comm_monoid_with_zero (M₀ : Type*) extends comm_monoid_with_zero M₀ :=
+(mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c)
+
+@[priority 100]
+instance cancel_comm_monoid_with_zero.to_cancel_monoid_with_zero
+  [h : cancel_comm_monoid_with_zero M₀] : cancel_monoid_with_zero M₀ :=
+{ .. h, .. @is_left_cancel_mul_zero.to_is_right_cancel_mul_zero M₀ _ _ { .. h } }
 
 /-- A type `G₀` is a “group with zero” if it is a monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
@@ -147,42 +178,6 @@ class group_with_zero (G₀ : Type u) extends
 (inv_zero : (0 : G₀)⁻¹ = 0)
 (mul_inv_cancel : ∀ a:G₀, a ≠ 0 → a * a⁻¹ = 1)
 
-namespace comm_monoid_with_zero
-
-variable [comm_monoid_with_zero M₀]
-
-lemma is_left_cancel_mul_zero.to_is_right_cancel_mul_zero [is_left_cancel_mul_zero M₀] :
-  is_right_cancel_mul_zero M₀ :=
-{ mul_right_cancel_of_ne_zero := λ a b c ha h,
-  begin
-    rw [mul_comm, mul_comm c] at h,
-    exact is_left_cancel_mul_zero.mul_left_cancel_of_ne_zero ha h,
-  end }
-
-lemma is_right_cancel_mul_zero.to_is_left_cancel_mul_zero [is_right_cancel_mul_zero M₀] :
-  is_left_cancel_mul_zero M₀ :=
-{ mul_left_cancel_of_ne_zero := λ a b c ha h,
-  begin
-    rw [mul_comm a, mul_comm a c] at h,
-    exact is_right_cancel_mul_zero.mul_right_cancel_of_ne_zero ha h,
-  end }
-
-lemma is_left_cancel_mul_zero.to_is_cancel_mul_zero [is_left_cancel_mul_zero M₀] :
-  is_cancel_mul_zero M₀ :=
-{ mul_left_cancel_of_ne_zero := λ _ _ _,
-    is_left_cancel_mul_zero.mul_left_cancel_of_ne_zero,
-  mul_right_cancel_of_ne_zero := λ _ _ _,
-    is_left_cancel_mul_zero.to_is_right_cancel_mul_zero.mul_right_cancel_of_ne_zero }
-
-lemma is_right_cancel_mul_zero.to_is_cancel_mul_zero [is_right_cancel_mul_zero M₀] :
-  is_cancel_mul_zero M₀ :=
-{ mul_left_cancel_of_ne_zero := λ _ _ _,
-    is_right_cancel_mul_zero.to_is_left_cancel_mul_zero.mul_left_cancel_of_ne_zero,
-  mul_right_cancel_of_ne_zero := λ _ _ _,
-    is_right_cancel_mul_zero.mul_right_cancel_of_ne_zero }
-
-end comm_monoid_with_zero
-
 section group_with_zero
 
 variables [group_with_zero G₀]

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(first ported)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -362,7 +362,7 @@ theorem mul_ne_zero_iff : a * b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 :=
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` equals zero iff so is
 `b * a`. -/
 theorem mul_eq_zero_comm : a * b = 0 ↔ b * a = 0 :=
-  mul_eq_zero.trans <| (or_comm' _ _).trans mul_eq_zero.symm
+  mul_eq_zero.trans <| (or_comm _ _).trans mul_eq_zero.symm
 #align mul_eq_zero_comm mul_eq_zero_comm
 -/
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 -/
 import Algebra.Group.Defs
-import Logic.Nontrivial
+import Logic.Nontrivial.Defs
 import Algebra.NeZero
 
 #align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"448144f7ae193a8990cb7473c9e9a01990f64ac7"
Diff
@@ -3,9 +3,9 @@ Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 -/
-import Mathbin.Algebra.Group.Defs
-import Mathbin.Logic.Nontrivial
-import Mathbin.Algebra.NeZero
+import Algebra.Group.Defs
+import Logic.Nontrivial
+import Algebra.NeZero
 
 #align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"448144f7ae193a8990cb7473c9e9a01990f64ac7"
 
Diff
@@ -48,14 +48,14 @@ variable [MulZeroClass M₀] {a b : M₀}
 #print MulZeroClass.zero_mul /-
 @[ematch, simp]
 theorem MulZeroClass.zero_mul (a : M₀) : 0 * a = 0 :=
-  MulZeroClass.zero_mul a
+  MulZeroClass.zero_hMul a
 #align zero_mul MulZeroClass.zero_mul
 -/
 
 #print MulZeroClass.mul_zero /-
 @[ematch, simp]
 theorem MulZeroClass.mul_zero (a : M₀) : a * 0 = 0 :=
-  MulZeroClass.mul_zero a
+  MulZeroClass.hMul_zero a
 #align mul_zero MulZeroClass.mul_zero
 -/
 
@@ -65,7 +65,7 @@ end MulZeroClass
 /-- A mixin for left cancellative multiplication by nonzero elements. -/
 @[protect_proj]
 class IsLeftCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
-  mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
+  hMul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
 #align is_left_cancel_mul_zero IsLeftCancelMulZero
 -/
 
@@ -75,7 +75,7 @@ variable [Mul M₀] [Zero M₀] [IsLeftCancelMulZero M₀] {a b c : M₀}
 
 #print mul_left_cancel₀ /-
 theorem mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
-  IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h
+  IsLeftCancelMulZero.hMul_left_cancel_of_ne_zero ha h
 #align mul_left_cancel₀ mul_left_cancel₀
 -/
 
@@ -91,7 +91,7 @@ end IsLeftCancelMulZero
 /-- A mixin for right cancellative multiplication by nonzero elements. -/
 @[protect_proj]
 class IsRightCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
-  mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
+  hMul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
 #align is_right_cancel_mul_zero IsRightCancelMulZero
 -/
 
@@ -101,7 +101,7 @@ variable [Mul M₀] [Zero M₀] [IsRightCancelMulZero M₀] {a b c : M₀}
 
 #print mul_right_cancel₀ /-
 theorem mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
-  IsRightCancelMulZero.mul_right_cancel_of_ne_zero hb h
+  IsRightCancelMulZero.hMul_right_cancel_of_ne_zero hb h
 #align mul_right_cancel₀ mul_right_cancel₀
 -/
 
@@ -201,8 +201,8 @@ instance (priority := 100) MonoidWithZero.toSemigroupWithZero (M₀ : Type _) [M
 and right absorbing, and left/right multiplication by a non-zero element is injective. -/
 @[protect_proj]
 class CancelMonoidWithZero (M₀ : Type _) extends MonoidWithZero M₀ where
-  mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
-  mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
+  hMul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
+  hMul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
 #align cancel_monoid_with_zero CancelMonoidWithZero
 -/
 
@@ -226,7 +226,7 @@ class CommMonoidWithZero (M₀ : Type _) extends CommMonoid M₀, MonoidWithZero
   and left/right multiplication by a non-zero element is injective. -/
 @[protect_proj]
 class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀ where
-  mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
+  hMul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
 #align cancel_comm_monoid_with_zero CancelCommMonoidWithZero
 -/
 
@@ -337,7 +337,7 @@ variable [NoZeroDivisors M₀] {a b : M₀}
 equals zero. -/
 @[simp]
 theorem mul_eq_zero : a * b = 0 ↔ a = 0 ∨ b = 0 :=
-  ⟨eq_zero_or_eq_zero_of_mul_eq_zero, fun o =>
+  ⟨eq_zero_or_eq_zero_of_hMul_eq_zero, fun o =>
     o.elim (fun h => mul_eq_zero_of_left h b) (mul_eq_zero_of_right a)⟩
 #align mul_eq_zero mul_eq_zero
 -/
Diff
@@ -2,16 +2,13 @@
 Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
-
-! This file was ported from Lean 3 source module algebra.group_with_zero.defs
-! leanprover-community/mathlib commit 448144f7ae193a8990cb7473c9e9a01990f64ac7
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Algebra.Group.Defs
 import Mathbin.Logic.Nontrivial
 import Mathbin.Algebra.NeZero
 
+#align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"448144f7ae193a8990cb7473c9e9a01990f64ac7"
+
 /-!
 # Typeclasses for groups with an adjoined zero element
 
Diff
@@ -48,15 +48,19 @@ section MulZeroClass
 
 variable [MulZeroClass M₀] {a b : M₀}
 
+#print MulZeroClass.zero_mul /-
 @[ematch, simp]
 theorem MulZeroClass.zero_mul (a : M₀) : 0 * a = 0 :=
   MulZeroClass.zero_mul a
 #align zero_mul MulZeroClass.zero_mul
+-/
 
+#print MulZeroClass.mul_zero /-
 @[ematch, simp]
 theorem MulZeroClass.mul_zero (a : M₀) : a * 0 = 0 :=
   MulZeroClass.mul_zero a
 #align mul_zero MulZeroClass.mul_zero
+-/
 
 end MulZeroClass
 
@@ -124,23 +128,31 @@ section CommSemigroupWithZero
 
 variable [CommSemigroup M₀] [Zero M₀]
 
+#print IsLeftCancelMulZero.to_isRightCancelMulZero /-
 theorem IsLeftCancelMulZero.to_isRightCancelMulZero [IsLeftCancelMulZero M₀] :
     IsRightCancelMulZero M₀ :=
   ⟨fun a b c ha h => mul_left_cancel₀ ha <| (mul_comm _ _).trans <| h.trans (mul_comm _ _)⟩
 #align is_left_cancel_mul_zero.to_is_right_cancel_mul_zero IsLeftCancelMulZero.to_isRightCancelMulZero
+-/
 
+#print IsRightCancelMulZero.to_isLeftCancelMulZero /-
 theorem IsRightCancelMulZero.to_isLeftCancelMulZero [IsRightCancelMulZero M₀] :
     IsLeftCancelMulZero M₀ :=
   ⟨fun a b c ha h => mul_right_cancel₀ ha <| (mul_comm _ _).trans <| h.trans (mul_comm _ _)⟩
 #align is_right_cancel_mul_zero.to_is_left_cancel_mul_zero IsRightCancelMulZero.to_isLeftCancelMulZero
+-/
 
+#print IsLeftCancelMulZero.to_isCancelMulZero /-
 theorem IsLeftCancelMulZero.to_isCancelMulZero [IsLeftCancelMulZero M₀] : IsCancelMulZero M₀ :=
   { ‹IsLeftCancelMulZero M₀›, IsLeftCancelMulZero.to_isRightCancelMulZero with }
 #align is_left_cancel_mul_zero.to_is_cancel_mul_zero IsLeftCancelMulZero.to_isCancelMulZero
+-/
 
+#print IsRightCancelMulZero.to_isCancelMulZero /-
 theorem IsRightCancelMulZero.to_isCancelMulZero [IsRightCancelMulZero M₀] : IsCancelMulZero M₀ :=
   { ‹IsRightCancelMulZero M₀›, IsRightCancelMulZero.to_isLeftCancelMulZero with }
 #align is_right_cancel_mul_zero.to_is_cancel_mul_zero IsRightCancelMulZero.to_isCancelMulZero
+-/
 
 end CommSemigroupWithZero
 
@@ -251,10 +263,12 @@ theorem inv_zero : (0 : G₀)⁻¹ = 0 :=
   GroupWithZero.inv_zero
 #align inv_zero inv_zero
 
+#print mul_inv_cancel /-
 @[simp]
 theorem mul_inv_cancel {a : G₀} (h : a ≠ 0) : a * a⁻¹ = 1 :=
   GroupWithZero.mul_inv_cancel a h
 #align mul_inv_cancel mul_inv_cancel
+-/
 
 end GroupWithZero
 
@@ -276,6 +290,7 @@ variable [MulZeroOneClass M₀] [Nontrivial M₀] {a b : M₀}
 
 variable (M₀)
 
+#print NeZero.one /-
 /-- In a nontrivial monoid with zero, zero and one are different. -/
 instance NeZero.one : NeZero (1 : M₀) :=
   ⟨by
@@ -288,14 +303,17 @@ instance NeZero.one : NeZero (1 : M₀) :=
       _ = 1 * y := by rw [h, MulZeroClass.zero_mul]
       _ = y := by rw [one_mul]⟩
 #align ne_zero.one NeZero.one
+-/
 
 variable {M₀}
 
+#print pullback_nonzero /-
 /-- Pullback a `nontrivial` instance along a function sending `0` to `0` and `1` to `1`. -/
 theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f 0 = 0) (one : f 1 = 1) :
     Nontrivial M₀' :=
   ⟨⟨0, 1, mt (congr_arg f) <| by rw [zero, one]; exact zero_ne_one⟩⟩
 #align pullback_nonzero pullback_nonzero
+-/
 
 end NeZero
 
@@ -303,16 +321,21 @@ section MulZeroClass
 
 variable [MulZeroClass M₀]
 
+#print mul_eq_zero_of_left /-
 theorem mul_eq_zero_of_left {a : M₀} (h : a = 0) (b : M₀) : a * b = 0 :=
   h.symm ▸ MulZeroClass.zero_mul b
 #align mul_eq_zero_of_left mul_eq_zero_of_left
+-/
 
+#print mul_eq_zero_of_right /-
 theorem mul_eq_zero_of_right (a : M₀) {b : M₀} (h : b = 0) : a * b = 0 :=
   h.symm ▸ MulZeroClass.mul_zero a
 #align mul_eq_zero_of_right mul_eq_zero_of_right
+-/
 
 variable [NoZeroDivisors M₀] {a b : M₀}
 
+#print mul_eq_zero /-
 /-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
 equals zero. -/
 @[simp]
@@ -320,44 +343,61 @@ theorem mul_eq_zero : a * b = 0 ↔ a = 0 ∨ b = 0 :=
   ⟨eq_zero_or_eq_zero_of_mul_eq_zero, fun o =>
     o.elim (fun h => mul_eq_zero_of_left h b) (mul_eq_zero_of_right a)⟩
 #align mul_eq_zero mul_eq_zero
+-/
 
+#print zero_eq_mul /-
 /-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
 equals zero. -/
 @[simp]
 theorem zero_eq_mul : 0 = a * b ↔ a = 0 ∨ b = 0 := by rw [eq_comm, mul_eq_zero]
 #align zero_eq_mul zero_eq_mul
+-/
 
+#print mul_ne_zero_iff /-
 /-- If `α` has no zero divisors, then the product of two elements is nonzero iff both of them
 are nonzero. -/
 theorem mul_ne_zero_iff : a * b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 :=
   mul_eq_zero.Not.trans not_or
 #align mul_ne_zero_iff mul_ne_zero_iff
+-/
 
+#print mul_eq_zero_comm /-
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` equals zero iff so is
 `b * a`. -/
 theorem mul_eq_zero_comm : a * b = 0 ↔ b * a = 0 :=
   mul_eq_zero.trans <| (or_comm' _ _).trans mul_eq_zero.symm
 #align mul_eq_zero_comm mul_eq_zero_comm
+-/
 
+#print mul_ne_zero_comm /-
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` is nonzero iff so is
 `b * a`. -/
 theorem mul_ne_zero_comm : a * b ≠ 0 ↔ b * a ≠ 0 :=
   mul_eq_zero_comm.Not
 #align mul_ne_zero_comm mul_ne_zero_comm
+-/
 
+#print mul_self_eq_zero /-
 theorem mul_self_eq_zero : a * a = 0 ↔ a = 0 := by simp
 #align mul_self_eq_zero mul_self_eq_zero
+-/
 
+#print zero_eq_mul_self /-
 theorem zero_eq_mul_self : 0 = a * a ↔ a = 0 := by simp
 #align zero_eq_mul_self zero_eq_mul_self
+-/
 
+#print mul_self_ne_zero /-
 theorem mul_self_ne_zero : a * a ≠ 0 ↔ a ≠ 0 :=
   mul_self_eq_zero.Not
 #align mul_self_ne_zero mul_self_ne_zero
+-/
 
+#print zero_ne_mul_self /-
 theorem zero_ne_mul_self : 0 ≠ a * a ↔ a ≠ 0 :=
   zero_eq_mul_self.Not
 #align zero_ne_mul_self zero_ne_mul_self
+-/
 
 end MulZeroClass
 
Diff
@@ -286,8 +286,7 @@ instance NeZero.one : NeZero (1 : M₀) :=
       x = 1 * x := by rw [one_mul]
       _ = 0 := by rw [h, MulZeroClass.zero_mul]
       _ = 1 * y := by rw [h, MulZeroClass.zero_mul]
-      _ = y := by rw [one_mul]
-      ⟩
+      _ = y := by rw [one_mul]⟩
 #align ne_zero.one NeZero.one
 
 variable {M₀}
Diff
@@ -116,7 +116,7 @@ end IsRightCancelMulZero
 /-- A mixin for cancellative multiplication by nonzero elements. -/
 @[protect_proj]
 class IsCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] extends IsLeftCancelMulZero M₀,
-  IsRightCancelMulZero M₀ : Prop
+    IsRightCancelMulZero M₀ : Prop
 #align is_cancel_mul_zero IsCancelMulZero
 -/
 
Diff
@@ -48,23 +48,11 @@ section MulZeroClass
 
 variable [MulZeroClass M₀] {a b : M₀}
 
-/- warning: zero_mul -> MulZeroClass.zero_mul is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))) a) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))) a) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))
-Case conversion may be inaccurate. Consider using '#align zero_mul MulZeroClass.zero_mulₓ'. -/
 @[ematch, simp]
 theorem MulZeroClass.zero_mul (a : M₀) : 0 * a = 0 :=
   MulZeroClass.zero_mul a
 #align zero_mul MulZeroClass.zero_mul
 
-/- warning: mul_zero -> MulZeroClass.mul_zero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))
-Case conversion may be inaccurate. Consider using '#align mul_zero MulZeroClass.mul_zeroₓ'. -/
 @[ematch, simp]
 theorem MulZeroClass.mul_zero (a : M₀) : a * 0 = 0 :=
   MulZeroClass.mul_zero a
@@ -136,44 +124,20 @@ section CommSemigroupWithZero
 
 variable [CommSemigroup M₀] [Zero M₀]
 
-/- warning: is_left_cancel_mul_zero.to_is_right_cancel_mul_zero -> IsLeftCancelMulZero.to_isRightCancelMulZero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsLeftCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsRightCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsLeftCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsRightCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-Case conversion may be inaccurate. Consider using '#align is_left_cancel_mul_zero.to_is_right_cancel_mul_zero IsLeftCancelMulZero.to_isRightCancelMulZeroₓ'. -/
 theorem IsLeftCancelMulZero.to_isRightCancelMulZero [IsLeftCancelMulZero M₀] :
     IsRightCancelMulZero M₀ :=
   ⟨fun a b c ha h => mul_left_cancel₀ ha <| (mul_comm _ _).trans <| h.trans (mul_comm _ _)⟩
 #align is_left_cancel_mul_zero.to_is_right_cancel_mul_zero IsLeftCancelMulZero.to_isRightCancelMulZero
 
-/- warning: is_right_cancel_mul_zero.to_is_left_cancel_mul_zero -> IsRightCancelMulZero.to_isLeftCancelMulZero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsRightCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsLeftCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsRightCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsLeftCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-Case conversion may be inaccurate. Consider using '#align is_right_cancel_mul_zero.to_is_left_cancel_mul_zero IsRightCancelMulZero.to_isLeftCancelMulZeroₓ'. -/
 theorem IsRightCancelMulZero.to_isLeftCancelMulZero [IsRightCancelMulZero M₀] :
     IsLeftCancelMulZero M₀ :=
   ⟨fun a b c ha h => mul_right_cancel₀ ha <| (mul_comm _ _).trans <| h.trans (mul_comm _ _)⟩
 #align is_right_cancel_mul_zero.to_is_left_cancel_mul_zero IsRightCancelMulZero.to_isLeftCancelMulZero
 
-/- warning: is_left_cancel_mul_zero.to_is_cancel_mul_zero -> IsLeftCancelMulZero.to_isCancelMulZero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsLeftCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsLeftCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-Case conversion may be inaccurate. Consider using '#align is_left_cancel_mul_zero.to_is_cancel_mul_zero IsLeftCancelMulZero.to_isCancelMulZeroₓ'. -/
 theorem IsLeftCancelMulZero.to_isCancelMulZero [IsLeftCancelMulZero M₀] : IsCancelMulZero M₀ :=
   { ‹IsLeftCancelMulZero M₀›, IsLeftCancelMulZero.to_isRightCancelMulZero with }
 #align is_left_cancel_mul_zero.to_is_cancel_mul_zero IsLeftCancelMulZero.to_isCancelMulZero
 
-/- warning: is_right_cancel_mul_zero.to_is_cancel_mul_zero -> IsRightCancelMulZero.to_isCancelMulZero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsRightCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsCancelMulZero.{u1} M₀ (Semigroup.toHasMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : CommSemigroup.{u1} M₀] [_inst_2 : Zero.{u1} M₀] [_inst_3 : IsRightCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2], IsCancelMulZero.{u1} M₀ (Semigroup.toMul.{u1} M₀ (CommSemigroup.toSemigroup.{u1} M₀ _inst_1)) _inst_2
-Case conversion may be inaccurate. Consider using '#align is_right_cancel_mul_zero.to_is_cancel_mul_zero IsRightCancelMulZero.to_isCancelMulZeroₓ'. -/
 theorem IsRightCancelMulZero.to_isCancelMulZero [IsRightCancelMulZero M₀] : IsCancelMulZero M₀ :=
   { ‹IsRightCancelMulZero M₀›, IsRightCancelMulZero.to_isLeftCancelMulZero with }
 #align is_right_cancel_mul_zero.to_is_cancel_mul_zero IsRightCancelMulZero.to_isCancelMulZero
@@ -287,12 +251,6 @@ theorem inv_zero : (0 : G₀)⁻¹ = 0 :=
   GroupWithZero.inv_zero
 #align inv_zero inv_zero
 
-/- warning: mul_inv_cancel -> mul_inv_cancel is a dubious translation:
-lean 3 declaration is
-  forall {G₀ : Type.{u1}} [_inst_1 : GroupWithZero.{u1} G₀] {a : G₀}, (Ne.{succ u1} G₀ a (OfNat.ofNat.{u1} G₀ 0 (OfNat.mk.{u1} G₀ 0 (Zero.zero.{u1} G₀ (MulZeroClass.toHasZero.{u1} G₀ (MulZeroOneClass.toMulZeroClass.{u1} G₀ (MonoidWithZero.toMulZeroOneClass.{u1} G₀ (GroupWithZero.toMonoidWithZero.{u1} G₀ _inst_1)))))))) -> (Eq.{succ u1} G₀ (HMul.hMul.{u1, u1, u1} G₀ G₀ G₀ (instHMul.{u1} G₀ (MulZeroClass.toHasMul.{u1} G₀ (MulZeroOneClass.toMulZeroClass.{u1} G₀ (MonoidWithZero.toMulZeroOneClass.{u1} G₀ (GroupWithZero.toMonoidWithZero.{u1} G₀ _inst_1))))) a (Inv.inv.{u1} G₀ (DivInvMonoid.toHasInv.{u1} G₀ (GroupWithZero.toDivInvMonoid.{u1} G₀ _inst_1)) a)) (OfNat.ofNat.{u1} G₀ 1 (OfNat.mk.{u1} G₀ 1 (One.one.{u1} G₀ (MulOneClass.toHasOne.{u1} G₀ (MulZeroOneClass.toMulOneClass.{u1} G₀ (MonoidWithZero.toMulZeroOneClass.{u1} G₀ (GroupWithZero.toMonoidWithZero.{u1} G₀ _inst_1))))))))
-but is expected to have type
-  forall {G₀ : Type.{u1}} [_inst_1 : GroupWithZero.{u1} G₀] {a : G₀}, (Ne.{succ u1} G₀ a (OfNat.ofNat.{u1} G₀ 0 (Zero.toOfNat0.{u1} G₀ (MonoidWithZero.toZero.{u1} G₀ (GroupWithZero.toMonoidWithZero.{u1} G₀ _inst_1))))) -> (Eq.{succ u1} G₀ (HMul.hMul.{u1, u1, u1} G₀ G₀ G₀ (instHMul.{u1} G₀ (MulZeroClass.toMul.{u1} G₀ (MulZeroOneClass.toMulZeroClass.{u1} G₀ (MonoidWithZero.toMulZeroOneClass.{u1} G₀ (GroupWithZero.toMonoidWithZero.{u1} G₀ _inst_1))))) a (Inv.inv.{u1} G₀ (GroupWithZero.toInv.{u1} G₀ _inst_1) a)) (OfNat.ofNat.{u1} G₀ 1 (One.toOfNat1.{u1} G₀ (Monoid.toOne.{u1} G₀ (MonoidWithZero.toMonoid.{u1} G₀ (GroupWithZero.toMonoidWithZero.{u1} G₀ _inst_1))))))
-Case conversion may be inaccurate. Consider using '#align mul_inv_cancel mul_inv_cancelₓ'. -/
 @[simp]
 theorem mul_inv_cancel {a : G₀} (h : a ≠ 0) : a * a⁻¹ = 1 :=
   GroupWithZero.mul_inv_cancel a h
@@ -318,12 +276,6 @@ variable [MulZeroOneClass M₀] [Nontrivial M₀] {a b : M₀}
 
 variable (M₀)
 
-/- warning: ne_zero.one -> NeZero.one is a dubious translation:
-lean 3 declaration is
-  forall (M₀ : Type.{u1}) [_inst_1 : MulZeroOneClass.{u1} M₀] [_inst_2 : Nontrivial.{u1} M₀], NeZero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ (MulZeroOneClass.toMulZeroClass.{u1} M₀ _inst_1)) (OfNat.ofNat.{u1} M₀ 1 (OfNat.mk.{u1} M₀ 1 (One.one.{u1} M₀ (MulOneClass.toHasOne.{u1} M₀ (MulZeroOneClass.toMulOneClass.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall (M₀ : Type.{u1}) [_inst_1 : MulZeroOneClass.{u1} M₀] [_inst_2 : Nontrivial.{u1} M₀], NeZero.{u1} M₀ (MulZeroOneClass.toZero.{u1} M₀ _inst_1) (OfNat.ofNat.{u1} M₀ 1 (One.toOfNat1.{u1} M₀ (MulOneClass.toOne.{u1} M₀ (MulZeroOneClass.toMulOneClass.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align ne_zero.one NeZero.oneₓ'. -/
 /-- In a nontrivial monoid with zero, zero and one are different. -/
 instance NeZero.one : NeZero (1 : M₀) :=
   ⟨by
@@ -340,12 +292,6 @@ instance NeZero.one : NeZero (1 : M₀) :=
 
 variable {M₀}
 
-/- warning: pullback_nonzero -> pullback_nonzero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} {M₀' : Type.{u2}} [_inst_1 : MulZeroOneClass.{u1} M₀] [_inst_2 : Nontrivial.{u1} M₀] [_inst_3 : Zero.{u2} M₀'] [_inst_4 : One.{u2} M₀'] (f : M₀' -> M₀), (Eq.{succ u1} M₀ (f (OfNat.ofNat.{u2} M₀' 0 (OfNat.mk.{u2} M₀' 0 (Zero.zero.{u2} M₀' _inst_3)))) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ (MulZeroOneClass.toMulZeroClass.{u1} M₀ _inst_1)))))) -> (Eq.{succ u1} M₀ (f (OfNat.ofNat.{u2} M₀' 1 (OfNat.mk.{u2} M₀' 1 (One.one.{u2} M₀' _inst_4)))) (OfNat.ofNat.{u1} M₀ 1 (OfNat.mk.{u1} M₀ 1 (One.one.{u1} M₀ (MulOneClass.toHasOne.{u1} M₀ (MulZeroOneClass.toMulOneClass.{u1} M₀ _inst_1)))))) -> (Nontrivial.{u2} M₀')
-but is expected to have type
-  forall {M₀ : Type.{u1}} {M₀' : Type.{u2}} [_inst_1 : MulZeroOneClass.{u1} M₀] [_inst_2 : Nontrivial.{u1} M₀] [_inst_3 : Zero.{u2} M₀'] [_inst_4 : One.{u2} M₀'] (f : M₀' -> M₀), (Eq.{succ u1} M₀ (f (OfNat.ofNat.{u2} M₀' 0 (Zero.toOfNat0.{u2} M₀' _inst_3))) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroOneClass.toZero.{u1} M₀ _inst_1)))) -> (Eq.{succ u1} M₀ (f (OfNat.ofNat.{u2} M₀' 1 (One.toOfNat1.{u2} M₀' _inst_4))) (OfNat.ofNat.{u1} M₀ 1 (One.toOfNat1.{u1} M₀ (MulOneClass.toOne.{u1} M₀ (MulZeroOneClass.toMulOneClass.{u1} M₀ _inst_1))))) -> (Nontrivial.{u2} M₀')
-Case conversion may be inaccurate. Consider using '#align pullback_nonzero pullback_nonzeroₓ'. -/
 /-- Pullback a `nontrivial` instance along a function sending `0` to `0` and `1` to `1`. -/
 theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f 0 = 0) (one : f 1 = 1) :
     Nontrivial M₀' :=
@@ -358,34 +304,16 @@ section MulZeroClass
 
 variable [MulZeroClass M₀]
 
-/- warning: mul_eq_zero_of_left -> mul_eq_zero_of_left is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] {a : M₀}, (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) -> (forall (b : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] {a : M₀}, (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) -> (forall (b : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align mul_eq_zero_of_left mul_eq_zero_of_leftₓ'. -/
 theorem mul_eq_zero_of_left {a : M₀} (h : a = 0) (b : M₀) : a * b = 0 :=
   h.symm ▸ MulZeroClass.zero_mul b
 #align mul_eq_zero_of_left mul_eq_zero_of_left
 
-/- warning: mul_eq_zero_of_right -> mul_eq_zero_of_right is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀) {b : M₀}, (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) -> (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀) {b : M₀}, (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) -> (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align mul_eq_zero_of_right mul_eq_zero_of_rightₓ'. -/
 theorem mul_eq_zero_of_right (a : M₀) {b : M₀} (h : b = 0) : a * b = 0 :=
   h.symm ▸ MulZeroClass.mul_zero a
 #align mul_eq_zero_of_right mul_eq_zero_of_right
 
 variable [NoZeroDivisors M₀] {a b : M₀}
 
-/- warning: mul_eq_zero -> mul_eq_zero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Or (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Or (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))))
-Case conversion may be inaccurate. Consider using '#align mul_eq_zero mul_eq_zeroₓ'. -/
 /-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
 equals zero. -/
 @[simp]
@@ -394,88 +322,40 @@ theorem mul_eq_zero : a * b = 0 ↔ a = 0 ∨ b = 0 :=
     o.elim (fun h => mul_eq_zero_of_left h b) (mul_eq_zero_of_right a)⟩
 #align mul_eq_zero mul_eq_zero
 
-/- warning: zero_eq_mul -> zero_eq_mul is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Eq.{succ u1} M₀ (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))) (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b)) (Or (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Eq.{succ u1} M₀ (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))) (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b)) (Or (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))))
-Case conversion may be inaccurate. Consider using '#align zero_eq_mul zero_eq_mulₓ'. -/
 /-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
 equals zero. -/
 @[simp]
 theorem zero_eq_mul : 0 = a * b ↔ a = 0 ∨ b = 0 := by rw [eq_comm, mul_eq_zero]
 #align zero_eq_mul zero_eq_mul
 
-/- warning: mul_ne_zero_iff -> mul_ne_zero_iff is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (And (Ne.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Ne.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (And (Ne.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Ne.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))))
-Case conversion may be inaccurate. Consider using '#align mul_ne_zero_iff mul_ne_zero_iffₓ'. -/
 /-- If `α` has no zero divisors, then the product of two elements is nonzero iff both of them
 are nonzero. -/
 theorem mul_ne_zero_iff : a * b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 :=
   mul_eq_zero.Not.trans not_or
 #align mul_ne_zero_iff mul_ne_zero_iff
 
-/- warning: mul_eq_zero_comm -> mul_eq_zero_comm is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) b a) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) b a) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align mul_eq_zero_comm mul_eq_zero_commₓ'. -/
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` equals zero iff so is
 `b * a`. -/
 theorem mul_eq_zero_comm : a * b = 0 ↔ b * a = 0 :=
   mul_eq_zero.trans <| (or_comm' _ _).trans mul_eq_zero.symm
 #align mul_eq_zero_comm mul_eq_zero_comm
 
-/- warning: mul_ne_zero_comm -> mul_ne_zero_comm is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) b a) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀} {b : M₀}, Iff (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) b a) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align mul_ne_zero_comm mul_ne_zero_commₓ'. -/
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` is nonzero iff so is
 `b * a`. -/
 theorem mul_ne_zero_comm : a * b ≠ 0 ↔ b * a ≠ 0 :=
   mul_eq_zero_comm.Not
 #align mul_ne_zero_comm mul_ne_zero_comm
 
-/- warning: mul_self_eq_zero -> mul_self_eq_zero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a a) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a a) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align mul_self_eq_zero mul_self_eq_zeroₓ'. -/
 theorem mul_self_eq_zero : a * a = 0 ↔ a = 0 := by simp
 #align mul_self_eq_zero mul_self_eq_zero
 
-/- warning: zero_eq_mul_self -> zero_eq_mul_self is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Eq.{succ u1} M₀ (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))) (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a a)) (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Eq.{succ u1} M₀ (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))) (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a a)) (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align zero_eq_mul_self zero_eq_mul_selfₓ'. -/
 theorem zero_eq_mul_self : 0 = a * a ↔ a = 0 := by simp
 #align zero_eq_mul_self zero_eq_mul_self
 
-/- warning: mul_self_ne_zero -> mul_self_ne_zero is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a a) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (Ne.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Ne.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a a) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (Ne.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align mul_self_ne_zero mul_self_ne_zeroₓ'. -/
 theorem mul_self_ne_zero : a * a ≠ 0 ↔ a ≠ 0 :=
   mul_self_eq_zero.Not
 #align mul_self_ne_zero mul_self_ne_zero
 
-/- warning: zero_ne_mul_self -> zero_ne_mul_self is a dubious translation:
-lean 3 declaration is
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1) (MulZeroClass.toHasZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Ne.{succ u1} M₀ (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))) (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a a)) (Ne.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))))
-but is expected to have type
-  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] [_inst_2 : NoZeroDivisors.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1) (MulZeroClass.toZero.{u1} M₀ _inst_1)] {a : M₀}, Iff (Ne.{succ u1} M₀ (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))) (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a a)) (Ne.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
-Case conversion may be inaccurate. Consider using '#align zero_ne_mul_self zero_ne_mul_selfₓ'. -/
 theorem zero_ne_mul_self : 0 ≠ a * a ↔ a ≠ 0 :=
   zero_eq_mul_self.Not
 #align zero_ne_mul_self zero_ne_mul_self
Diff
@@ -349,10 +349,7 @@ Case conversion may be inaccurate. Consider using '#align pullback_nonzero pullb
 /-- Pullback a `nontrivial` instance along a function sending `0` to `0` and `1` to `1`. -/
 theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f 0 = 0) (one : f 1 = 1) :
     Nontrivial M₀' :=
-  ⟨⟨0, 1,
-      mt (congr_arg f) <| by
-        rw [zero, one]
-        exact zero_ne_one⟩⟩
+  ⟨⟨0, 1, mt (congr_arg f) <| by rw [zero, one]; exact zero_ne_one⟩⟩
 #align pullback_nonzero pullback_nonzero
 
 end NeZero
Diff
@@ -48,15 +48,27 @@ section MulZeroClass
 
 variable [MulZeroClass M₀] {a b : M₀}
 
+/- warning: zero_mul -> MulZeroClass.zero_mul is a dubious translation:
+lean 3 declaration is
+  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1)))) a) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))
+but is expected to have type
+  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))) a) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))
+Case conversion may be inaccurate. Consider using '#align zero_mul MulZeroClass.zero_mulₓ'. -/
 @[ematch, simp]
-theorem zero_mul (a : M₀) : 0 * a = 0 :=
+theorem MulZeroClass.zero_mul (a : M₀) : 0 * a = 0 :=
   MulZeroClass.zero_mul a
-#align zero_mul zero_mul
+#align zero_mul MulZeroClass.zero_mul
 
+/- warning: mul_zero -> MulZeroClass.mul_zero is a dubious translation:
+lean 3 declaration is
+  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toHasMul.{u1} M₀ _inst_1)) a (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))) (OfNat.ofNat.{u1} M₀ 0 (OfNat.mk.{u1} M₀ 0 (Zero.zero.{u1} M₀ (MulZeroClass.toHasZero.{u1} M₀ _inst_1))))
+but is expected to have type
+  forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))
+Case conversion may be inaccurate. Consider using '#align mul_zero MulZeroClass.mul_zeroₓ'. -/
 @[ematch, simp]
-theorem mul_zero (a : M₀) : a * 0 = 0 :=
+theorem MulZeroClass.mul_zero (a : M₀) : a * 0 = 0 :=
   MulZeroClass.mul_zero a
-#align mul_zero mul_zero
+#align mul_zero MulZeroClass.mul_zero
 
 end MulZeroClass
 
@@ -320,8 +332,8 @@ instance NeZero.one : NeZero (1 : M₀) :=
     apply hx
     calc
       x = 1 * x := by rw [one_mul]
-      _ = 0 := by rw [h, zero_mul]
-      _ = 1 * y := by rw [h, zero_mul]
+      _ = 0 := by rw [h, MulZeroClass.zero_mul]
+      _ = 1 * y := by rw [h, MulZeroClass.zero_mul]
       _ = y := by rw [one_mul]
       ⟩
 #align ne_zero.one NeZero.one
@@ -356,7 +368,7 @@ but is expected to have type
   forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] {a : M₀}, (Eq.{succ u1} M₀ a (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) -> (forall (b : M₀), Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
 Case conversion may be inaccurate. Consider using '#align mul_eq_zero_of_left mul_eq_zero_of_leftₓ'. -/
 theorem mul_eq_zero_of_left {a : M₀} (h : a = 0) (b : M₀) : a * b = 0 :=
-  h.symm ▸ zero_mul b
+  h.symm ▸ MulZeroClass.zero_mul b
 #align mul_eq_zero_of_left mul_eq_zero_of_left
 
 /- warning: mul_eq_zero_of_right -> mul_eq_zero_of_right is a dubious translation:
@@ -366,7 +378,7 @@ but is expected to have type
   forall {M₀ : Type.{u1}} [_inst_1 : MulZeroClass.{u1} M₀] (a : M₀) {b : M₀}, (Eq.{succ u1} M₀ b (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1)))) -> (Eq.{succ u1} M₀ (HMul.hMul.{u1, u1, u1} M₀ M₀ M₀ (instHMul.{u1} M₀ (MulZeroClass.toMul.{u1} M₀ _inst_1)) a b) (OfNat.ofNat.{u1} M₀ 0 (Zero.toOfNat0.{u1} M₀ (MulZeroClass.toZero.{u1} M₀ _inst_1))))
 Case conversion may be inaccurate. Consider using '#align mul_eq_zero_of_right mul_eq_zero_of_rightₓ'. -/
 theorem mul_eq_zero_of_right (a : M₀) {b : M₀} (h : b = 0) : a * b = 0 :=
-  h.symm ▸ mul_zero a
+  h.symm ▸ MulZeroClass.mul_zero a
 #align mul_eq_zero_of_right mul_eq_zero_of_right
 
 variable [NoZeroDivisors M₀] {a b : M₀}

Changes in mathlib4

mathlib3
mathlib4
feat: Axiomatise b ≠ 0 → a * b / b = a (#12424)

This lets us unify a few lemmas between GroupWithZero and EuclideanDomain and two lemmas that were previously proved separately for Nat, Int, Polynomial.

Diff
@@ -174,6 +174,31 @@ instance (priority := 100) CancelCommMonoidWithZero.toCancelMonoidWithZero
     [CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
 { IsLeftCancelMulZero.to_isCancelMulZero (M₀ := M₀) with }
 
+/-- Prop-valued mixin for a monoid with zero to be equipped with a cancelling division.
+
+The obvious use case is groups with zero, but this condition is also satisfied by `ℕ`, `ℤ` and, more
+generally, any euclidean domain. -/
+class MulDivCancelClass (M₀ : Type*) [MonoidWithZero M₀] [Div M₀] : Prop where
+  protected mul_div_cancel (a b : M₀) : b ≠ 0 → a * b / b = a
+
+section MulDivCancelClass
+variable [MonoidWithZero M₀] [Div M₀] [MulDivCancelClass M₀] {a b : M₀}
+
+@[simp] lemma mul_div_cancel_right₀ (a : M₀) (hb : b ≠ 0) : a * b / b = a :=
+  MulDivCancelClass.mul_div_cancel _ _ hb
+#align mul_div_cancel mul_div_cancel_right₀
+
+end MulDivCancelClass
+
+section MulDivCancelClass
+variable [CommMonoidWithZero M₀] [Div M₀] [MulDivCancelClass M₀] {a b : M₀}
+
+@[simp] lemma mul_div_cancel_left₀ (b : M₀) (ha : a ≠ 0) : a * b / a = b := by
+  rw [mul_comm, mul_div_cancel_right₀ _ ha]
+#align mul_div_cancel_left mul_div_cancel_left₀
+
+end MulDivCancelClass
+
 /-- A type `G₀` is a “group with zero” if it is a monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
 The type is required to come with an “inverse” function, and the inverse of `0` must be `0`.
@@ -184,16 +209,24 @@ class GroupWithZero (G₀ : Type u) extends MonoidWithZero G₀, DivInvMonoid G
   /-- The inverse of `0` in a group with zero is `0`. -/
   inv_zero : (0 : G₀)⁻¹ = 0
   /-- Every nonzero element of a group with zero is invertible. -/
-  mul_inv_cancel (a : G₀) : a ≠ 0 → a * a⁻¹ = 1
+  protected mul_inv_cancel (a : G₀) : a ≠ 0 → a * a⁻¹ = 1
 #align group_with_zero GroupWithZero
 
 export GroupWithZero (inv_zero)
 attribute [simp] inv_zero
 
-@[simp] lemma mul_inv_cancel [GroupWithZero G₀] {a : G₀} (h : a ≠ 0) : a * a⁻¹ = 1 :=
-  GroupWithZero.mul_inv_cancel a h
+section GroupWithZero
+variable [GroupWithZero G₀] {a : G₀}
+
+@[simp] lemma mul_inv_cancel (h : a ≠ 0) : a * a⁻¹ = 1 := GroupWithZero.mul_inv_cancel a h
 #align mul_inv_cancel mul_inv_cancel
 
+-- See note [lower instance priority]
+instance (priority := 100) GroupWithZero.toMulDivCancelClass : MulDivCancelClass G₀ where
+  mul_div_cancel a b hb := by rw [div_eq_mul_inv, mul_assoc, mul_inv_cancel hb, mul_one]
+
+end GroupWithZero
+
 /-- A type `G₀` is a commutative “group with zero”
 if it is a commutative monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
style: replace '.-/' by '. -/' (#11938)

Purely automatic replacement. If this is in any way controversial; I'm happy to just close this PR.

Diff
@@ -179,7 +179,7 @@ such that every nonzero element is invertible.
 The type is required to come with an “inverse” function, and the inverse of `0` must be `0`.
 
 Examples include division rings and the ordered monoids that are the
-target of valuations in general valuation theory.-/
+target of valuations in general valuation theory. -/
 class GroupWithZero (G₀ : Type u) extends MonoidWithZero G₀, DivInvMonoid G₀, Nontrivial G₀ where
   /-- The inverse of `0` in a group with zero is `0`. -/
   inv_zero : (0 : G₀)⁻¹ = 0
feat: The support of f ^ n (#9617)

This involves moving lemmas from Algebra.GroupPower.Ring to Algebra.GroupWithZero.Basic and changing some 0 < n assumptions to n ≠ 0.

From LeanAPAP

Diff
@@ -6,6 +6,7 @@ Authors: Johan Commelin
 import Mathlib.Algebra.Group.Defs
 import Mathlib.Logic.Function.Basic
 import Mathlib.Logic.Nontrivial.Defs
+import Mathlib.Tactic.SplitIfs
 
 #align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
 
chore: refactor of Algebra/Group/Defs to reduce imports (#9606)

We are not that far from the point that Algebra/Group/Defs depends on nothing significant besides simps and to_additive.

This removes from Mathlib.Algebra.Group.Defs the dependencies on

  • Mathlib.Tactic.Basic (which is a grab-bag of random stuff)
  • Mathlib.Init.Algebra.Classes (which is ancient and half-baked)
  • Mathlib.Logic.Function.Basic (not particularly important, but it is barely used in this file)

The goal is to avoid all unnecessary imports to set up the definitions of basic algebraic structures.

We also separate out Mathlib.Tactic.TypeStar and Mathlib.Tactic.Lemma as prerequisites to Mathlib.Tactic.Basic, but which can be imported separately when the rest of Mathlib.Tactic.Basic is not needed.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 -/
 import Mathlib.Algebra.Group.Defs
+import Mathlib.Logic.Function.Basic
 import Mathlib.Logic.Nontrivial.Defs
 
 #align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
chore: Replace (· op ·) a by (a op ·) (#8843)

I used the regex \(\(· (.) ·\) (.)\), replacing with ($2 $1 ·).

Diff
@@ -49,7 +49,7 @@ theorem mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
   IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h
 #align mul_left_cancel₀ mul_left_cancel₀
 
-theorem mul_right_injective₀ (ha : a ≠ 0) : Function.Injective ((· * ·) a) :=
+theorem mul_right_injective₀ (ha : a ≠ 0) : Function.Injective (a * ·) :=
   fun _ _ => mul_left_cancel₀ ha
 #align mul_right_injective₀ mul_right_injective₀
 
style: cleanup some autoImplicits (#8288)

In some cases adding the arguments manually results in a more obvious argument order anyway

Diff
@@ -17,9 +17,7 @@ which is a part of the algebraic hierarchy used by basic tactics.
 
 universe u
 
-set_option autoImplicit true
-
-variable [MulZeroOneClass M₀] [Nontrivial M₀] {a b : M₀}
+variable {M₀ M₀' : Type*} [MulZeroOneClass M₀] [Nontrivial M₀]
 
 /-- In a nontrivial monoid with zero, zero and one are different. -/
 instance NeZero.one : NeZero (1 : M₀) := ⟨by
@@ -43,7 +41,7 @@ theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f
 
 section GroupWithZero
 
-variable [GroupWithZero G₀] {a b c g h x : G₀}
+variable {G₀ : Type*} [GroupWithZero G₀] {a : G₀}
 
 -- Porting note: used `simpa` to prove `False` in lean3
 theorem inv_ne_zero (h : a ≠ 0) : a⁻¹ ≠ 0 := fun a_eq_0 => by
style: cleanup some autoImplicits (#8288)

In some cases adding the arguments manually results in a more obvious argument order anyway

Diff
@@ -20,11 +20,8 @@ members.
 * `CommGroupWithZero`
 -/
 
-
 universe u
 
-set_option autoImplicit true
-
 -- We have to fix the universe of `G₀` here, since the default argument to
 -- `GroupWithZero.div'` cannot contain a universe metavariable.
 variable {G₀ : Type u} {M₀ M₀' G₀' : Type*}
chore: reduce imports of Data.Nat.Basic (#6974)

Slightly delay the import of Mathlib.Algebra.Group.Basic, to reduce imports for tactics.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -120,6 +120,20 @@ element, and `0` is left and right absorbing. -/
 class CommMonoidWithZero (M₀ : Type*) extends CommMonoid M₀, MonoidWithZero M₀
 #align comm_monoid_with_zero CommMonoidWithZero
 
+section CancelMonoidWithZero
+
+variable [CancelMonoidWithZero M₀] {a b c : M₀}
+
+theorem mul_left_inj' (hc : c ≠ 0) : a * c = b * c ↔ a = b :=
+  (mul_left_injective₀ hc).eq_iff
+#align mul_left_inj' mul_left_inj'
+
+theorem mul_right_inj' (ha : a ≠ 0) : a * b = a * c ↔ b = c :=
+  (mul_right_injective₀ ha).eq_iff
+#align mul_right_inj' mul_right_inj'
+
+end CancelMonoidWithZero
+
 section CommSemigroup
 
 variable [CommSemigroup M₀] [Zero M₀]
chore: split Mathlib.Algebra.Invertible (#6973)

Mathlib.Algebra.Invertible is used by fundamental tactics, and this essentially splits it into the part used by NormNum, and everything else.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -40,3 +40,23 @@ theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f
     rw [zero, one]
     exact zero_ne_one⟩⟩
 #align pullback_nonzero pullback_nonzero
+
+section GroupWithZero
+
+variable [GroupWithZero G₀] {a b c g h x : G₀}
+
+-- Porting note: used `simpa` to prove `False` in lean3
+theorem inv_ne_zero (h : a ≠ 0) : a⁻¹ ≠ 0 := fun a_eq_0 => by
+  have := mul_inv_cancel h
+  simp only [a_eq_0, mul_zero, zero_ne_one] at this
+#align inv_ne_zero inv_ne_zero
+
+@[simp]
+theorem inv_mul_cancel (h : a ≠ 0) : a⁻¹ * a = 1 :=
+  calc
+    a⁻¹ * a = a⁻¹ * a * a⁻¹ * a⁻¹⁻¹ := by simp [inv_ne_zero h]
+    _ = a⁻¹ * a⁻¹⁻¹ := by simp [h]
+    _ = 1 := by simp [inv_ne_zero h]
+#align inv_mul_cancel inv_mul_cancel
+
+end GroupWithZero
chore: split Mathlib.Algebra.Invertible (#6973)

Mathlib.Algebra.Invertible is used by fundamental tactics, and this essentially splits it into the part used by NormNum, and everything else.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -188,6 +188,26 @@ The type is required to come with an “inverse” function, and the inverse of
 class CommGroupWithZero (G₀ : Type*) extends CommMonoidWithZero G₀, GroupWithZero G₀
 #align comm_group_with_zero CommGroupWithZero
 
+section GroupWithZero
+
+variable [GroupWithZero G₀] {a b c g h x : G₀}
+
+@[simp]
+theorem mul_inv_cancel_right₀ (h : b ≠ 0) (a : G₀) : a * b * b⁻¹ = a :=
+  calc
+    a * b * b⁻¹ = a * (b * b⁻¹) := mul_assoc _ _ _
+    _ = a := by simp [h]
+#align mul_inv_cancel_right₀ mul_inv_cancel_right₀
+
+@[simp]
+theorem mul_inv_cancel_left₀ (h : a ≠ 0) (b : G₀) : a * (a⁻¹ * b) = b :=
+  calc
+    a * (a⁻¹ * b) = a * a⁻¹ * b := (mul_assoc _ _ _).symm
+    _ = b := by simp [h]
+#align mul_inv_cancel_left₀ mul_inv_cancel_left₀
+
+end GroupWithZero
+
 section MulZeroClass
 
 variable [MulZeroClass M₀]
chore: delay import of NeZero until after basic hierarchy (#6970)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

chore: delay import of NeZero until after basic hierarchy (#6970)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -5,7 +5,6 @@ Authors: Johan Commelin
 -/
 import Mathlib.Algebra.Group.Defs
 import Mathlib.Logic.Nontrivial.Defs
-import Mathlib.Algebra.NeZero
 
 #align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
 
@@ -189,36 +188,6 @@ The type is required to come with an “inverse” function, and the inverse of
 class CommGroupWithZero (G₀ : Type*) extends CommMonoidWithZero G₀, GroupWithZero G₀
 #align comm_group_with_zero CommGroupWithZero
 
-section NeZero
-
-variable [MulZeroOneClass M₀] [Nontrivial M₀] {a b : M₀}
-
-variable (M₀)
-
-/-- In a nontrivial monoid with zero, zero and one are different. -/
-instance NeZero.one : NeZero (1 : M₀) := ⟨by
-  intro h
-  rcases exists_pair_ne M₀ with ⟨x, y, hx⟩
-  apply hx
-  calc
-    x = 1 * x := by rw [one_mul]
-    _ = 0 := by rw [h, zero_mul]
-    _ = 1 * y := by rw [h, zero_mul]
-    _ = y := by rw [one_mul]⟩
-#align ne_zero.one NeZero.one
-
-variable {M₀}
-
-/-- Pullback a `Nontrivial` instance along a function sending `0` to `0` and `1` to `1`. -/
-theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f 0 = 0) (one : f 1 = 1) :
-    Nontrivial M₀' :=
-  ⟨⟨0, 1, mt (congr_arg f) <| by
-    rw [zero, one]
-    exact zero_ne_one⟩⟩
-#align pullback_nonzero pullback_nonzero
-
-end NeZero
-
 section MulZeroClass
 
 variable [MulZeroClass M₀]
chore: ensure Ring/Defs doesn't depend on Group/Basic (#6956)

In the basic algebraic hierarchy, the Defs files should ideally only depend on earlier Defs files, importing as little theory as possible.

This PR makes some rearrangements so Ring.Defs can depend on Group.Defs rather than requiring Group.Basic.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -30,18 +30,6 @@ set_option autoImplicit true
 -- `GroupWithZero.div'` cannot contain a universe metavariable.
 variable {G₀ : Type u} {M₀ M₀' G₀' : Type*}
 
--- Porting note:
--- This theorem was introduced during ad-hoc porting
--- and hopefully can be removed again after `Mathlib.Algebra.Ring.Basic` is fully ported.
-theorem eq_of_sub_eq_zero' [AddGroup R] {a b : R} (h : a - b = 0) : a = b :=
-  add_right_cancel <| show a + (-b) = b + (-b) by rw [← sub_eq_add_neg, h, add_neg_self]
-
--- Porting note:
--- This theorem was introduced during ad-hoc porting
--- and hopefully can be removed again after `Mathlib.Algebra.Ring.Basic` is fully ported.
-theorem pow_succ'' [Monoid M] : ∀ (n : ℕ) (a : M), a ^ n.succ = a * a ^ n :=
-  Monoid.npow_succ
-
 /-- Typeclass for expressing that a type `M₀` with multiplication and a zero satisfies
 `0 * a = 0` and `a * 0 = 0` for all `a : M₀`. -/
 class MulZeroClass (M₀ : Type u) extends Mul M₀, Zero M₀ where
feat: split Logic.Nontrivial (#6959)

This continues reducing the import requirements for the basic algebraic hierarchy.

In combination with #6954 #6955 #6956 #6957, this reduces the imports for Mathlib.Algebra.Field.Defs from

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 -/
 import Mathlib.Algebra.Group.Defs
-import Mathlib.Logic.Nontrivial
+import Mathlib.Logic.Nontrivial.Defs
 import Mathlib.Algebra.NeZero
 
 #align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
fix: disable autoImplicit globally (#6528)

Autoimplicits are highly controversial and also defeat the performance-improving work in #6474.

The intent of this PR is to make autoImplicit opt-in on a per-file basis, by disabling it in the lakefile and enabling it again with set_option autoImplicit true in the few files that rely on it.

That also keeps this PR small, as opposed to attempting to "fix" files to not need it any more.

I claim that many of the uses of autoImplicit in these files are accidental; situations such as:

  • Assuming variables are in scope, but pasting the lemma in the wrong section
  • Pasting in a lemma from a scratch file without checking to see if the variable names are consistent with the rest of the file
  • Making a copy-paste error between lemmas and forgetting to add an explicit arguments.

Having set_option autoImplicit false as the default prevents these types of mistake being made in the 90% of files where autoImplicits are not used at all, and causes them to be caught by CI during review.

I think there were various points during the port where we encouraged porters to delete the universes u v lines; I think having autoparams for universe variables only would cover a lot of the cases we actually use them, while avoiding any real shortcomings.

A Zulip poll (after combining overlapping votes accordingly) was in favor of this change with 5:5:18 as the no:dontcare:yes vote ratio.

While this PR was being reviewed, a handful of files gained some more likely-accidental autoImplicits. In these places, set_option autoImplicit true has been placed locally within a section, rather than at the top of the file.

Diff
@@ -24,6 +24,8 @@ members.
 
 universe u
 
+set_option autoImplicit true
+
 -- We have to fix the universe of `G₀` here, since the default argument to
 -- `GroupWithZero.div'` cannot contain a universe metavariable.
 variable {G₀ : Type u} {M₀ M₀' G₀' : Type*}
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -26,7 +26,7 @@ universe u
 
 -- We have to fix the universe of `G₀` here, since the default argument to
 -- `GroupWithZero.div'` cannot contain a universe metavariable.
-variable {G₀ : Type u} {M₀ M₀' G₀' : Type _}
+variable {G₀ : Type u} {M₀ M₀' G₀' : Type*}
 
 -- Porting note:
 -- This theorem was introduced during ad-hoc porting
@@ -101,7 +101,7 @@ attribute [simp] zero_mul mul_zero
 
 /-- Predicate typeclass for expressing that `a * b = 0` implies `a = 0` or `b = 0`
 for all `a` and `b` of type `G₀`. -/
-class NoZeroDivisors (M₀ : Type _) [Mul M₀] [Zero M₀] : Prop where
+class NoZeroDivisors (M₀ : Type*) [Mul M₀] [Zero M₀] : Prop where
   /-- For all `a` and `b` of `G₀`, `a * b = 0` implies `a = 0` or `b = 0`. -/
   eq_zero_or_eq_zero_of_mul_eq_zero : ∀ {a b : M₀}, a * b = 0 → a = 0 ∨ b = 0
 #align no_zero_divisors NoZeroDivisors
@@ -123,12 +123,12 @@ class MonoidWithZero (M₀ : Type u) extends Monoid M₀, MulZeroOneClass M₀,
 
 /-- A type `M` is a `CancelMonoidWithZero` if it is a monoid with zero element, `0` is left
 and right absorbing, and left/right multiplication by a non-zero element is injective. -/
-class CancelMonoidWithZero (M₀ : Type _) extends MonoidWithZero M₀, IsCancelMulZero M₀
+class CancelMonoidWithZero (M₀ : Type*) extends MonoidWithZero M₀, IsCancelMulZero M₀
 #align cancel_monoid_with_zero CancelMonoidWithZero
 
 /-- A type `M` is a commutative “monoid with zero” if it is a commutative monoid with zero
 element, and `0` is left and right absorbing. -/
-class CommMonoidWithZero (M₀ : Type _) extends CommMonoid M₀, MonoidWithZero M₀
+class CommMonoidWithZero (M₀ : Type*) extends CommMonoid M₀, MonoidWithZero M₀
 #align comm_monoid_with_zero CommMonoidWithZero
 
 section CommSemigroup
@@ -162,7 +162,7 @@ end CommSemigroup
 /-- A type `M` is a `CancelCommMonoidWithZero` if it is a commutative monoid with zero element,
  `0` is left and right absorbing,
   and left/right multiplication by a non-zero element is injective. -/
-class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
+class CancelCommMonoidWithZero (M₀ : Type*) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
 #align cancel_comm_monoid_with_zero CancelCommMonoidWithZero
 
 -- See note [lower cancel priority]
@@ -196,7 +196,7 @@ attribute [simp] inv_zero
 if it is a commutative monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
 The type is required to come with an “inverse” function, and the inverse of `0` must be `0`. -/
-class CommGroupWithZero (G₀ : Type _) extends CommMonoidWithZero G₀, GroupWithZero G₀
+class CommGroupWithZero (G₀ : Type*) extends CommMonoidWithZero G₀, GroupWithZero G₀
 #align comm_group_with_zero CommGroupWithZero
 
 section NeZero
chore: lower instance priority of CancelMonoid.toMonoid etc (#6145)

This PR lowers the instance priority of inheritance going to cancellative structures, specifically those matching the regular expression (Add)?(Left|Right)?Cancel(Comm)?(Monoid|Semigroup)(WithZero)?.

Most of these cancellative structures either derive from group structures or from (integral) domain structures (including fields). Thus we should be going through the group and semiring hierarchy before going through the cancellative hierarchy. In particular, IsDomain is a mixin depending on Semiring so trying to synthesize an IsDomain instance to satisfy Monoid before even trying Semiring makes no sense.

We came across this issue when adding an extra way to find an IsDomain instance, because this slows down the failing cancellative search path enough to cause timeouts.

Zulip thread: https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Why.20is.20.60simpNF.60.20complaining.20here.3F

Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>

Diff
@@ -165,6 +165,9 @@ end CommSemigroup
 class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
 #align cancel_comm_monoid_with_zero CancelCommMonoidWithZero
 
+-- See note [lower cancel priority]
+attribute [instance 75] CancelCommMonoidWithZero.toCommMonoidWithZero
+
 instance (priority := 100) CancelCommMonoidWithZero.toCancelMonoidWithZero
     [CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
 { IsLeftCancelMulZero.to_isCancelMulZero (M₀ := M₀) with }
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,16 +2,13 @@
 Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
-
-! This file was ported from Lean 3 source module algebra.group_with_zero.defs
-! leanprover-community/mathlib commit 2f3994e1b117b1e1da49bcfb67334f33460c3ce4
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Algebra.Group.Defs
 import Mathlib.Logic.Nontrivial
 import Mathlib.Algebra.NeZero
 
+#align_import algebra.group_with_zero.defs from "leanprover-community/mathlib"@"2f3994e1b117b1e1da49bcfb67334f33460c3ce4"
+
 /-!
 # Typeclasses for groups with an adjoined zero element
 
refactor: move all register_simp_attrs to 1 file (#5681)

There are slight differences between mathlib3 and mathlib4 (different set of attributes, different lemmas are in core/std), so I redid the same refactor instead of forward-porting changes.

mathlib3 PR: leanprover-community/mathlib#19223

Diff
@@ -201,8 +201,6 @@ class CommGroupWithZero (G₀ : Type _) extends CommMonoidWithZero G₀, GroupWi
 
 section NeZero
 
-attribute [field_simps] two_ne_zero three_ne_zero four_ne_zero
-
 variable [MulZeroOneClass M₀] [Nontrivial M₀] {a b : M₀}
 
 variable (M₀)
chore: fix many typos (#4983)

These are all doc fixes

Diff
@@ -54,7 +54,7 @@ class MulZeroClass (M₀ : Type u) extends Mul M₀, Zero M₀ where
 
 /-- A mixin for left cancellative multiplication by nonzero elements. -/
 class IsLeftCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
-  /-- Multiplicatin by a nonzero element is left cancellative. -/
+  /-- Multiplication by a nonzero element is left cancellative. -/
   protected mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
 #align is_left_cancel_mul_zero IsLeftCancelMulZero
 
chore: formatting issues (#4947)

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>

Diff
@@ -41,7 +41,7 @@ theorem eq_of_sub_eq_zero' [AddGroup R] {a b : R} (h : a - b = 0) : a = b :=
 -- This theorem was introduced during ad-hoc porting
 -- and hopefully can be removed again after `Mathlib.Algebra.Ring.Basic` is fully ported.
 theorem pow_succ'' [Monoid M] : ∀ (n : ℕ) (a : M), a ^ n.succ = a * a ^ n :=
-Monoid.npow_succ
+  Monoid.npow_succ
 
 /-- Typeclass for expressing that a type `M₀` with multiplication and a zero satisfies
 `0 * a = 0` and `a * 0 = 0` for all `a : M₀`. -/
@@ -189,7 +189,7 @@ export GroupWithZero (inv_zero)
 attribute [simp] inv_zero
 
 @[simp] lemma mul_inv_cancel [GroupWithZero G₀] {a : G₀} (h : a ≠ 0) : a * a⁻¹ = 1 :=
-GroupWithZero.mul_inv_cancel a h
+  GroupWithZero.mul_inv_cancel a h
 #align mul_inv_cancel mul_inv_cancel
 
 /-- A type `G₀` is a commutative “group with zero”
chore: fix upper/lowercase in comments (#4360)
  • Run a non-interactive version of fix-comments.py on all files.
  • Go through the diff and manually add/discard/edit chunks.
Diff
@@ -221,7 +221,7 @@ instance NeZero.one : NeZero (1 : M₀) := ⟨by
 
 variable {M₀}
 
-/-- Pullback a `nontrivial` instance along a function sending `0` to `0` and `1` to `1`. -/
+/-- Pullback a `Nontrivial` instance along a function sending `0` to `0` and `1` to `1`. -/
 theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f 0 = 0) (one : f 1 = 1) :
     Nontrivial M₀' :=
   ⟨⟨0, 1, mt (congr_arg f) <| by
fix: Fix aligns (#2781)
Diff
@@ -99,6 +99,8 @@ class IsCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀]
 
 export MulZeroClass (zero_mul mul_zero)
 attribute [simp] zero_mul mul_zero
+#align zero_mul MulZeroClass.zero_mul
+#align mul_zero MulZeroClass.mul_zero
 
 /-- Predicate typeclass for expressing that `a * b = 0` implies `a = 0` or `b = 0`
 for all `a` and `b` of type `G₀`. -/
chore: bump to leanprover/lean4:nightly-2023-02-10 (#2188)
Diff
@@ -168,7 +168,7 @@ class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀,
 
 instance (priority := 100) CancelCommMonoidWithZero.toCancelMonoidWithZero
     [CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
-{ IsLeftCancelMulZero.to_isCancelMulZero with }
+{ IsLeftCancelMulZero.to_isCancelMulZero (M₀ := M₀) with }
 
 /-- A type `G₀` is a “group with zero” if it is a monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
chore: add missing #align statements (#1902)

This PR is the result of a slight variant on the following "algorithm"

  • take all mathlib 3 names, remove _ and make all uppercase letters into lowercase
  • take all mathlib 4 names, remove _ and make all uppercase letters into lowercase
  • look for matches, and create pairs (original_lean3_name, OriginalLean4Name)
  • for pairs that do not have an align statement:
    • use Lean 4 to lookup the file + position of the Lean 4 name
    • add an #align statement just before the next empty line
  • manually fix some tiny mistakes (e.g., empty lines in proofs might cause the #align statement to have been inserted too early)
Diff
@@ -50,11 +50,13 @@ class MulZeroClass (M₀ : Type u) extends Mul M₀, Zero M₀ where
   zero_mul : ∀ a : M₀, 0 * a = 0
   /-- Zero is a right absorbing element for multiplication -/
   mul_zero : ∀ a : M₀, a * 0 = 0
+#align mul_zero_class MulZeroClass
 
 /-- A mixin for left cancellative multiplication by nonzero elements. -/
 class IsLeftCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
   /-- Multiplicatin by a nonzero element is left cancellative. -/
   protected mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
+#align is_left_cancel_mul_zero IsLeftCancelMulZero
 
 section IsLeftCancelMulZero
 
@@ -62,9 +64,11 @@ variable [Mul M₀] [Zero M₀] [IsLeftCancelMulZero M₀] {a b c : M₀}
 
 theorem mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
   IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h
+#align mul_left_cancel₀ mul_left_cancel₀
 
 theorem mul_right_injective₀ (ha : a ≠ 0) : Function.Injective ((· * ·) a) :=
   fun _ _ => mul_left_cancel₀ ha
+#align mul_right_injective₀ mul_right_injective₀
 
 end IsLeftCancelMulZero
 
@@ -72,6 +76,7 @@ end IsLeftCancelMulZero
 class IsRightCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
   /-- Multiplicatin by a nonzero element is right cancellative. -/
   protected mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
+#align is_right_cancel_mul_zero IsRightCancelMulZero
 
 section IsRightCancelMulZero
 
@@ -79,15 +84,18 @@ variable [Mul M₀] [Zero M₀] [IsRightCancelMulZero M₀] {a b c : M₀}
 
 theorem mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
   IsRightCancelMulZero.mul_right_cancel_of_ne_zero hb h
+#align mul_right_cancel₀ mul_right_cancel₀
 
 theorem mul_left_injective₀ (hb : b ≠ 0) : Function.Injective fun a => a * b :=
   fun _ _ => mul_right_cancel₀ hb
+#align mul_left_injective₀ mul_left_injective₀
 
 end IsRightCancelMulZero
 
 /-- A mixin for cancellative multiplication by nonzero elements. -/
 class IsCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀]
   extends IsLeftCancelMulZero M₀, IsRightCancelMulZero M₀ : Prop
+#align is_cancel_mul_zero IsCancelMulZero
 
 export MulZeroClass (zero_mul mul_zero)
 attribute [simp] zero_mul mul_zero
@@ -97,26 +105,32 @@ for all `a` and `b` of type `G₀`. -/
 class NoZeroDivisors (M₀ : Type _) [Mul M₀] [Zero M₀] : Prop where
   /-- For all `a` and `b` of `G₀`, `a * b = 0` implies `a = 0` or `b = 0`. -/
   eq_zero_or_eq_zero_of_mul_eq_zero : ∀ {a b : M₀}, a * b = 0 → a = 0 ∨ b = 0
+#align no_zero_divisors NoZeroDivisors
 
 export NoZeroDivisors (eq_zero_or_eq_zero_of_mul_eq_zero)
 /-- A type `S₀` is a "semigroup with zero” if it is a semigroup with zero element, and `0` is left
 and right absorbing. -/
 class SemigroupWithZero (S₀ : Type u) extends Semigroup S₀, MulZeroClass S₀
+#align semigroup_with_zero SemigroupWithZero
 
 /-- A typeclass for non-associative monoids with zero elements. -/
 class MulZeroOneClass (M₀ : Type u) extends MulOneClass M₀, MulZeroClass M₀
+#align mul_zero_one_class MulZeroOneClass
 
 /-- A type `M₀` is a “monoid with zero” if it is a monoid with zero element, and `0` is left
 and right absorbing. -/
 class MonoidWithZero (M₀ : Type u) extends Monoid M₀, MulZeroOneClass M₀, SemigroupWithZero M₀
+#align monoid_with_zero MonoidWithZero
 
 /-- A type `M` is a `CancelMonoidWithZero` if it is a monoid with zero element, `0` is left
 and right absorbing, and left/right multiplication by a non-zero element is injective. -/
 class CancelMonoidWithZero (M₀ : Type _) extends MonoidWithZero M₀, IsCancelMulZero M₀
+#align cancel_monoid_with_zero CancelMonoidWithZero
 
 /-- A type `M` is a commutative “monoid with zero” if it is a commutative monoid with zero
 element, and `0` is left and right absorbing. -/
 class CommMonoidWithZero (M₀ : Type _) extends CommMonoid M₀, MonoidWithZero M₀
+#align comm_monoid_with_zero CommMonoidWithZero
 
 section CommSemigroup
 
@@ -126,19 +140,23 @@ lemma IsLeftCancelMulZero.to_isRightCancelMulZero [IsLeftCancelMulZero M₀] :
     IsRightCancelMulZero M₀ :=
 { mul_right_cancel_of_ne_zero :=
     fun hb h => mul_left_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
+#align is_left_cancel_mul_zero.to_is_right_cancel_mul_zero IsLeftCancelMulZero.to_isRightCancelMulZero
 
 lemma IsRightCancelMulZero.to_isLeftCancelMulZero [IsRightCancelMulZero M₀] :
     IsLeftCancelMulZero M₀ :=
 { mul_left_cancel_of_ne_zero :=
     fun hb h => mul_right_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
+#align is_right_cancel_mul_zero.to_is_left_cancel_mul_zero IsRightCancelMulZero.to_isLeftCancelMulZero
 
 lemma IsLeftCancelMulZero.to_isCancelMulZero [IsLeftCancelMulZero M₀] :
     IsCancelMulZero M₀ :=
 { IsLeftCancelMulZero.to_isRightCancelMulZero with }
+#align is_left_cancel_mul_zero.to_is_cancel_mul_zero IsLeftCancelMulZero.to_isCancelMulZero
 
 lemma IsRightCancelMulZero.to_isCancelMulZero [IsRightCancelMulZero M₀] :
     IsCancelMulZero M₀ :=
 { IsRightCancelMulZero.to_isLeftCancelMulZero with }
+#align is_right_cancel_mul_zero.to_is_cancel_mul_zero IsRightCancelMulZero.to_isCancelMulZero
 
 end CommSemigroup
 
@@ -146,6 +164,7 @@ end CommSemigroup
  `0` is left and right absorbing,
   and left/right multiplication by a non-zero element is injective. -/
 class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
+#align cancel_comm_monoid_with_zero CancelCommMonoidWithZero
 
 instance (priority := 100) CancelCommMonoidWithZero.toCancelMonoidWithZero
     [CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
@@ -162,18 +181,21 @@ class GroupWithZero (G₀ : Type u) extends MonoidWithZero G₀, DivInvMonoid G
   inv_zero : (0 : G₀)⁻¹ = 0
   /-- Every nonzero element of a group with zero is invertible. -/
   mul_inv_cancel (a : G₀) : a ≠ 0 → a * a⁻¹ = 1
+#align group_with_zero GroupWithZero
 
 export GroupWithZero (inv_zero)
 attribute [simp] inv_zero
 
 @[simp] lemma mul_inv_cancel [GroupWithZero G₀] {a : G₀} (h : a ≠ 0) : a * a⁻¹ = 1 :=
 GroupWithZero.mul_inv_cancel a h
+#align mul_inv_cancel mul_inv_cancel
 
 /-- A type `G₀` is a commutative “group with zero”
 if it is a commutative monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
 The type is required to come with an “inverse” function, and the inverse of `0` must be `0`. -/
 class CommGroupWithZero (G₀ : Type _) extends CommMonoidWithZero G₀, GroupWithZero G₀
+#align comm_group_with_zero CommGroupWithZero
 
 section NeZero
 
@@ -203,6 +225,7 @@ theorem pullback_nonzero [Zero M₀'] [One M₀'] (f : M₀' → M₀) (zero : f
   ⟨⟨0, 1, mt (congr_arg f) <| by
     rw [zero, one]
     exact zero_ne_one⟩⟩
+#align pullback_nonzero pullback_nonzero
 
 end NeZero
 
@@ -211,8 +234,10 @@ section MulZeroClass
 variable [MulZeroClass M₀]
 
 theorem mul_eq_zero_of_left {a : M₀} (h : a = 0) (b : M₀) : a * b = 0 := h.symm ▸ zero_mul b
+#align mul_eq_zero_of_left mul_eq_zero_of_left
 
 theorem mul_eq_zero_of_right (a : M₀) {b : M₀} (h : b = 0) : a * b = 0 := h.symm ▸ mul_zero a
+#align mul_eq_zero_of_right mul_eq_zero_of_right
 
 variable [NoZeroDivisors M₀] {a b : M₀}
 
@@ -222,31 +247,40 @@ equals zero. -/
 theorem mul_eq_zero : a * b = 0 ↔ a = 0 ∨ b = 0 :=
   ⟨eq_zero_or_eq_zero_of_mul_eq_zero,
     fun o => o.elim (fun h => mul_eq_zero_of_left h b) (mul_eq_zero_of_right a)⟩
+#align mul_eq_zero mul_eq_zero
 
 /-- If `α` has no zero divisors, then the product of two elements equals zero iff one of them
 equals zero. -/
 @[simp]
 theorem zero_eq_mul : 0 = a * b ↔ a = 0 ∨ b = 0 := by rw [eq_comm, mul_eq_zero]
+#align zero_eq_mul zero_eq_mul
 
 /-- If `α` has no zero divisors, then the product of two elements is nonzero iff both of them
 are nonzero. -/
 theorem mul_ne_zero_iff : a * b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 := mul_eq_zero.not.trans not_or
+#align mul_ne_zero_iff mul_ne_zero_iff
 
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` equals zero iff so is
 `b * a`. -/
 theorem mul_eq_zero_comm : a * b = 0 ↔ b * a = 0 :=
   mul_eq_zero.trans <| or_comm.trans mul_eq_zero.symm
+#align mul_eq_zero_comm mul_eq_zero_comm
 
 /-- If `α` has no zero divisors, then for elements `a, b : α`, `a * b` is nonzero iff so is
 `b * a`. -/
 theorem mul_ne_zero_comm : a * b ≠ 0 ↔ b * a ≠ 0 := mul_eq_zero_comm.not
+#align mul_ne_zero_comm mul_ne_zero_comm
 
 theorem mul_self_eq_zero : a * a = 0 ↔ a = 0 := by simp
+#align mul_self_eq_zero mul_self_eq_zero
 
 theorem zero_eq_mul_self : 0 = a * a ↔ a = 0 := by simp
+#align zero_eq_mul_self zero_eq_mul_self
 
 theorem mul_self_ne_zero : a * a ≠ 0 ↔ a ≠ 0 := mul_self_eq_zero.not
+#align mul_self_ne_zero mul_self_ne_zero
 
 theorem zero_ne_mul_self : 0 ≠ a * a ↔ a ≠ 0 := zero_eq_mul_self.not
+#align zero_ne_mul_self zero_ne_mul_self
 
 end MulZeroClass
chore: fix more casing errors per naming scheme (#1232)

I've avoided anything under Tactic or test.

In correcting the names, I found Option.isNone_iff_eq_none duplicated between Std and Mathlib, so the Mathlib one has been removed.

Co-authored-by: Reid Barton <rwbarton@gmail.com>

Diff
@@ -122,23 +122,23 @@ section CommSemigroup
 
 variable [CommSemigroup M₀] [Zero M₀]
 
-lemma IsLeftCancelMulZero.to_IsRightCancelMulZero [IsLeftCancelMulZero M₀] :
+lemma IsLeftCancelMulZero.to_isRightCancelMulZero [IsLeftCancelMulZero M₀] :
     IsRightCancelMulZero M₀ :=
 { mul_right_cancel_of_ne_zero :=
     fun hb h => mul_left_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
 
-lemma IsRightCancelMulZero.to_IsLeftCancelMulZero [IsRightCancelMulZero M₀] :
+lemma IsRightCancelMulZero.to_isLeftCancelMulZero [IsRightCancelMulZero M₀] :
     IsLeftCancelMulZero M₀ :=
 { mul_left_cancel_of_ne_zero :=
     fun hb h => mul_right_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
 
-lemma IsLeftCancelMulZero.to_IsCancelMulZero [IsLeftCancelMulZero M₀] :
+lemma IsLeftCancelMulZero.to_isCancelMulZero [IsLeftCancelMulZero M₀] :
     IsCancelMulZero M₀ :=
-{ IsLeftCancelMulZero.to_IsRightCancelMulZero with }
+{ IsLeftCancelMulZero.to_isRightCancelMulZero with }
 
-lemma IsRightCancelMulZero.to_IsCancelMulZero [IsRightCancelMulZero M₀] :
+lemma IsRightCancelMulZero.to_isCancelMulZero [IsRightCancelMulZero M₀] :
     IsCancelMulZero M₀ :=
-{ IsRightCancelMulZero.to_IsLeftCancelMulZero with }
+{ IsRightCancelMulZero.to_isLeftCancelMulZero with }
 
 end CommSemigroup
 
@@ -147,9 +147,9 @@ end CommSemigroup
   and left/right multiplication by a non-zero element is injective. -/
 class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
 
-instance (priority := 100) CancelCommMonoidWithZero.to_CancelMonoidWithZero
+instance (priority := 100) CancelCommMonoidWithZero.toCancelMonoidWithZero
     [CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
-{ IsLeftCancelMulZero.to_IsCancelMulZero with }
+{ IsLeftCancelMulZero.to_isCancelMulZero with }
 
 /-- A type `G₀` is a “group with zero” if it is a monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
refactor: use Is*CancelMulZero (#1137)

This is a Lean 4 version of leanprover-community/mathlib#17963

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
 
 ! This file was ported from Lean 3 source module algebra.group_with_zero.defs
-! leanprover-community/mathlib commit 2aa04f651209dc8f37b9937a8c4c20c79571ac52
+! leanprover-community/mathlib commit 2f3994e1b117b1e1da49bcfb67334f33460c3ce4
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -56,11 +56,35 @@ class IsLeftCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
   /-- Multiplicatin by a nonzero element is left cancellative. -/
   protected mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
 
+section IsLeftCancelMulZero
+
+variable [Mul M₀] [Zero M₀] [IsLeftCancelMulZero M₀] {a b c : M₀}
+
+theorem mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
+  IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h
+
+theorem mul_right_injective₀ (ha : a ≠ 0) : Function.Injective ((· * ·) a) :=
+  fun _ _ => mul_left_cancel₀ ha
+
+end IsLeftCancelMulZero
+
 /-- A mixin for right cancellative multiplication by nonzero elements. -/
 class IsRightCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀] : Prop where
   /-- Multiplicatin by a nonzero element is right cancellative. -/
   protected mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
 
+section IsRightCancelMulZero
+
+variable [Mul M₀] [Zero M₀] [IsRightCancelMulZero M₀] {a b c : M₀}
+
+theorem mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
+  IsRightCancelMulZero.mul_right_cancel_of_ne_zero hb h
+
+theorem mul_left_injective₀ (hb : b ≠ 0) : Function.Injective fun a => a * b :=
+  fun _ _ => mul_right_cancel₀ hb
+
+end IsRightCancelMulZero
+
 /-- A mixin for cancellative multiplication by nonzero elements. -/
 class IsCancelMulZero (M₀ : Type u) [Mul M₀] [Zero M₀]
   extends IsLeftCancelMulZero M₀, IsRightCancelMulZero M₀ : Prop
@@ -88,75 +112,44 @@ class MonoidWithZero (M₀ : Type u) extends Monoid M₀, MulZeroOneClass M₀,
 
 /-- A type `M` is a `CancelMonoidWithZero` if it is a monoid with zero element, `0` is left
 and right absorbing, and left/right multiplication by a non-zero element is injective. -/
-class CancelMonoidWithZero (M₀ : Type _) extends MonoidWithZero M₀ where
-  /-- Left multiplication by a non-zero element is injective. -/
-  protected mul_left_cancel_of_ne_zero : ∀ {a b c : M₀}, a ≠ 0 → a * b = a * c → b = c
-  /-- Right multiplication by a non-zero element is injective. -/
-  protected mul_right_cancel_of_ne_zero : ∀ {a b c : M₀}, b ≠ 0 → a * b = c * b → a = c
-
-section CancelMonoidWithZero
-
-variable [CancelMonoidWithZero M₀] {a b c : M₀}
-
-theorem mul_left_cancel₀ (ha : a ≠ 0) (h : a * b = a * c) : b = c :=
-  CancelMonoidWithZero.mul_left_cancel_of_ne_zero ha h
-
-theorem mul_right_cancel₀ (hb : b ≠ 0) (h : a * b = c * b) : a = c :=
-  CancelMonoidWithZero.mul_right_cancel_of_ne_zero hb h
-
-theorem mul_right_injective₀ (ha : a ≠ 0) : Function.Injective ((· * ·) a) :=
-  fun _ _ => mul_left_cancel₀ ha
-
-theorem mul_left_injective₀ (hb : b ≠ 0) : Function.Injective fun a => a * b :=
-  fun _ _ => mul_right_cancel₀ hb
-
-/-- A `CancelMonoidWithZero` satisfies `IsCancelMulZero`. -/
-instance (priority := 100) CancelMonoidWithZero.to_IsCancelMulZero : IsCancelMulZero M₀ :=
-{ mul_left_cancel_of_ne_zero := fun ha h ↦
-    CancelMonoidWithZero.mul_left_cancel_of_ne_zero ha h
-  mul_right_cancel_of_ne_zero :=  fun hb h ↦
-    CancelMonoidWithZero.mul_right_cancel_of_ne_zero hb h, }
-
-end CancelMonoidWithZero
+class CancelMonoidWithZero (M₀ : Type _) extends MonoidWithZero M₀, IsCancelMulZero M₀
 
 /-- A type `M` is a commutative “monoid with zero” if it is a commutative monoid with zero
 element, and `0` is left and right absorbing. -/
 class CommMonoidWithZero (M₀ : Type _) extends CommMonoid M₀, MonoidWithZero M₀
 
-namespace CommMonoidWithZero
+section CommSemigroup
 
-variable [CommMonoidWithZero M₀]
+variable [CommSemigroup M₀] [Zero M₀]
 
 lemma IsLeftCancelMulZero.to_IsRightCancelMulZero [IsLeftCancelMulZero M₀] :
     IsRightCancelMulZero M₀ :=
-{ mul_right_cancel_of_ne_zero := by
-    intros a b c ha h
-    rw [mul_comm, mul_comm c] at h
-    exact IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h }
+{ mul_right_cancel_of_ne_zero :=
+    fun hb h => mul_left_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
 
 lemma IsRightCancelMulZero.to_IsLeftCancelMulZero [IsRightCancelMulZero M₀] :
     IsLeftCancelMulZero M₀ :=
-{ mul_left_cancel_of_ne_zero := by
-    intros a b c ha h
-    rw [mul_comm a, mul_comm a c] at h
-    exact IsRightCancelMulZero.mul_right_cancel_of_ne_zero ha h }
+{ mul_left_cancel_of_ne_zero :=
+    fun hb h => mul_right_cancel₀ hb <| (mul_comm _ _).trans (h.trans (mul_comm _ _)) }
 
 lemma IsLeftCancelMulZero.to_IsCancelMulZero [IsLeftCancelMulZero M₀] :
     IsCancelMulZero M₀ :=
-{ mul_right_cancel_of_ne_zero := fun ha h ↦
-    IsLeftCancelMulZero.to_IsRightCancelMulZero.mul_right_cancel_of_ne_zero ha h }
+{ IsLeftCancelMulZero.to_IsRightCancelMulZero with }
 
 lemma IsRightCancelMulZero.to_IsCancelMulZero [IsRightCancelMulZero M₀] :
     IsCancelMulZero M₀ :=
-{ mul_left_cancel_of_ne_zero := fun ha h ↦
-    IsRightCancelMulZero.to_IsLeftCancelMulZero.mul_left_cancel_of_ne_zero ha h }
+{ IsRightCancelMulZero.to_IsLeftCancelMulZero with }
 
-end CommMonoidWithZero
+end CommSemigroup
 
 /-- A type `M` is a `CancelCommMonoidWithZero` if it is a commutative monoid with zero element,
  `0` is left and right absorbing,
   and left/right multiplication by a non-zero element is injective. -/
-class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀, CancelMonoidWithZero M₀
+class CancelCommMonoidWithZero (M₀ : Type _) extends CommMonoidWithZero M₀, IsLeftCancelMulZero M₀
+
+instance (priority := 100) CancelCommMonoidWithZero.to_CancelMonoidWithZero
+    [CancelCommMonoidWithZero M₀] : CancelMonoidWithZero M₀ :=
+{ IsLeftCancelMulZero.to_IsCancelMulZero with }
 
 /-- A type `G₀` is a “group with zero” if it is a monoid with zero element (distinct from `1`)
 such that every nonzero element is invertible.
chore: add source headers to ported theory files (#1094)

The script used to do this is included. The yaml file was obtained from https://raw.githubusercontent.com/wiki/leanprover-community/mathlib/mathlib4-port-status.md

Diff
@@ -2,6 +2,11 @@
 Copyright (c) 2020 Johan Commelin. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johan Commelin
+
+! This file was ported from Lean 3 source module algebra.group_with_zero.defs
+! leanprover-community/mathlib commit 2aa04f651209dc8f37b9937a8c4c20c79571ac52
+! Please do not edit these lines, except to modify the commit id
+! if you have ported upstream changes.
 -/
 import Mathlib.Algebra.Group.Defs
 import Mathlib.Logic.Nontrivial

Dependencies 11

12 files ported (100.0%)
5167 lines ported (100.0%)

All dependencies are ported!