algebra.oppositesMathlib.Algebra.Opposites

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)

(last sync)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

fix(algebra/opposites): fix types in unop_div (#17955)

This lemma only typechecked because of defeq abuse, which was presumably not intended. Remark: refactoring mul_opposite to be a structure in Lean 4 was what picked up on this error.

Diff
@@ -210,6 +210,6 @@ instance [has_involutive_inv α] : has_involutive_inv αᵃᵒᵖ :=
 instance [has_div α] : has_div αᵃᵒᵖ := { div := λ a b, op (unop a / unop b) }
 
 @[simp] lemma op_div [has_div α] (a b : α) : op (a / b) = op a / op b := rfl
-@[simp] lemma unop_div [has_div α] (a b : α) : unop (a / b) = unop a / unop b := rfl
+@[simp] lemma unop_div [has_div α] (a b : αᵃᵒᵖ) : unop (a / b) = unop a / unop b := rfl
 
 end add_opposite

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(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
@@ -5,7 +5,7 @@ Authors: Kenny Lau
 -/
 import Algebra.Group.Defs
 import Logic.Equiv.Defs
-import Logic.Nontrivial
+import Logic.Nontrivial.Defs
 
 #align_import algebra.opposites from "leanprover-community/mathlib"@"448144f7ae193a8990cb7473c9e9a01990f64ac7"
 
Diff
@@ -3,9 +3,9 @@ Copyright (c) 2018 Kenny Lau. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Kenny Lau
 -/
-import Mathbin.Algebra.Group.Defs
-import Mathbin.Logic.Equiv.Defs
-import Mathbin.Logic.Nontrivial
+import Algebra.Group.Defs
+import Logic.Equiv.Defs
+import Logic.Nontrivial
 
 #align_import algebra.opposites from "leanprover-community/mathlib"@"448144f7ae193a8990cb7473c9e9a01990f64ac7"
 
Diff
@@ -2,16 +2,13 @@
 Copyright (c) 2018 Kenny Lau. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Kenny Lau
-
-! This file was ported from Lean 3 source module algebra.opposites
-! 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.Equiv.Defs
 import Mathbin.Logic.Nontrivial
 
+#align_import algebra.opposites from "leanprover-community/mathlib"@"448144f7ae193a8990cb7473c9e9a01990f64ac7"
+
 /-!
 # Multiplicative opposite and algebraic operations on it
 
Diff
@@ -54,10 +54,8 @@ def MulOpposite (α : Type u) : Type u :=
 #align add_opposite AddOpposite
 -/
 
--- mathport name: «expr ᵐᵒᵖ»
 postfix:max "ᵐᵒᵖ" => MulOpposite
 
--- mathport name: «expr ᵃᵒᵖ»
 postfix:max "ᵃᵒᵖ" => AddOpposite
 
 variable {α : Type u}
@@ -116,11 +114,13 @@ theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
 #align add_opposite.unop_comp_op AddOpposite.unop_comp_op
 -/
 
+#print MulOpposite.rec' /-
 /-- A recursor for `mul_opposite`. Use as `induction x using mul_opposite.rec`. -/
 @[simp, to_additive "A recursor for `add_opposite`. Use as `induction x using add_opposite.rec`."]
 protected def rec' {F : ∀ X : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
 #align mul_opposite.rec MulOpposite.rec'
 #align add_opposite.rec AddOpposite.rec'
+-/
 
 #print MulOpposite.opEquiv /-
 /-- The canonical bijection between `α` and `αᵐᵒᵖ`. -/
Diff
@@ -116,12 +116,6 @@ theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
 #align add_opposite.unop_comp_op AddOpposite.unop_comp_op
 -/
 
-/- warning: mul_opposite.rec -> MulOpposite.rec' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {F : (MulOpposite.{u1} α) -> Sort.{u2}}, (forall (X : α), F (MulOpposite.op.{u1} α X)) -> (forall (X : MulOpposite.{u1} α), F X)
-but is expected to have type
-  forall {α : Type.{u2}} {F : (MulOpposite.{u2} α) -> Sort.{u1}}, (forall (X : α), F (MulOpposite.op.{u2} α X)) -> (forall (X : MulOpposite.{u2} α), F X)
-Case conversion may be inaccurate. Consider using '#align mul_opposite.rec MulOpposite.rec'ₓ'. -/
 /-- A recursor for `mul_opposite`. Use as `induction x using mul_opposite.rec`. -/
 @[simp, to_additive "A recursor for `add_opposite`. Use as `induction x using add_opposite.rec`."]
 protected def rec' {F : ∀ X : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)

Changes in mathlib4

mathlib3
mathlib4
style: replace '.-/' by '. -/' (#11938)

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

Diff
@@ -57,7 +57,7 @@ structure PreOpposite (α : Type*) : Type _ where
   /-- The element of `α` represented by `x : PreOpposite α`. -/ unop' : α
 
 /-- Multiplicative opposite of a type. This type inherits all additive structures on `α` and
-reverses left and right in multiplication.-/
+reverses left and right in multiplication. -/
 @[to_additive
       "Additive opposite of a type. This type inherits all multiplicative structures on `α` and
       reverses left and right in addition."]
chore: Homogenise instances for MulOpposite/AddOpposite (#11485)

by declaring them all in where style with implicit type assumptions and inst prefix

Here to reduce the diff from #11203

Diff
@@ -11,7 +11,6 @@ import Mathlib.Logic.IsEmpty
 #align_import algebra.opposites from "leanprover-community/mathlib"@"7a89b1aed52bcacbcc4a8ad515e72c5c07268940"
 
 /-!
-
 # Multiplicative opposite and algebraic operations on it
 
 In this file we define `MulOpposite α = αᵐᵒᵖ` to be the multiplicative opposite of `α`. It inherits
@@ -41,21 +40,19 @@ definitional eta reduction for structures (Lean 3 does not).
 multiplicative opposite, additive opposite
 -/
 
-universe u v
-
-variable {α : Type*}
+variable {α β : Type*}
 
 open Function
 
 /-- Auxiliary type to implement `MulOpposite` and `AddOpposite`.
 
-It turns out to be convenient to have `MulOpposite α= AddOpposite α` true by definition, in the
+It turns out to be convenient to have `MulOpposite α = AddOpposite α` true by definition, in the
 same way that it is convenient to have `Additive α = α`; this means that we also get the defeq
 `AddOpposite (Additive α) = MulOpposite α`, which is convenient when working with quotients.
 
 This is a compromise between making `MulOpposite α = AddOpposite α = α` (what we had in Lean 3) and
 having no defeqs within those three types (which we had as of mathlib4#1036). -/
-structure PreOpposite (α : Type u) : Type u where
+structure PreOpposite (α : Type*) : Type _ where
   /-- The element of `PreOpposite α` that represents `x : α`. -/ op' ::
   /-- The element of `α` represented by `x : PreOpposite α`. -/ unop' : α
 
@@ -64,8 +61,7 @@ reverses left and right in multiplication.-/
 @[to_additive
       "Additive opposite of a type. This type inherits all multiplicative structures on `α` and
       reverses left and right in addition."]
-def MulOpposite (α : Type u) : Type u :=
-  PreOpposite α
+def MulOpposite (α : Type*) : Type _ := PreOpposite α
 #align mul_opposite MulOpposite
 #align add_opposite AddOpposite
 -- Porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
@@ -120,7 +116,7 @@ theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
 /-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec'`. -/
 @[to_additive (attr := simp, elab_as_elim)
   "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec'`."]
-protected def rec' {F : αᵐᵒᵖ → Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
+protected def rec' {F : αᵐᵒᵖ → Sort*} (h : ∀ X, F (op X)) : ∀ X, F X := fun X ↦ h (unop X)
 #align mul_opposite.rec MulOpposite.rec'
 #align add_opposite.rec AddOpposite.rec'
 
@@ -183,154 +179,99 @@ theorem unop_inj {x y : αᵐᵒᵖ} : unop x = unop y ↔ x = y :=
 
 attribute [nolint simpComm] AddOpposite.unop_inj
 
-variable (α)
+@[to_additive] instance instNontrivial [Nontrivial α] : Nontrivial αᵐᵒᵖ := op_injective.nontrivial
 
-@[to_additive]
-instance nontrivial [Nontrivial α] : Nontrivial αᵐᵒᵖ :=
-  op_injective.nontrivial
+@[to_additive] instance instInhabited [Inhabited α] : Inhabited αᵐᵒᵖ := ⟨op default⟩
 
 @[to_additive]
-instance inhabited [Inhabited α] : Inhabited αᵐᵒᵖ :=
-  ⟨op default⟩
+instance instSubsingleton [Subsingleton α] : Subsingleton αᵐᵒᵖ := unop_injective.subsingleton
 
-@[to_additive]
-instance subsingleton [Subsingleton α] : Subsingleton αᵐᵒᵖ :=
-  unop_injective.subsingleton
+@[to_additive] instance instUnique [Unique α] : Unique αᵐᵒᵖ := Unique.mk' _
 
-@[to_additive]
-instance unique [Unique α] : Unique αᵐᵒᵖ :=
-  Unique.mk' _
-
-@[to_additive]
-instance isEmpty [IsEmpty α] : IsEmpty αᵐᵒᵖ :=
-  Function.isEmpty unop
+@[to_additive] instance instIsEmpty [IsEmpty α] : IsEmpty αᵐᵒᵖ := Function.isEmpty unop
 
 @[to_additive]
 instance instDecidableEq [DecidableEq α] : DecidableEq αᵐᵒᵖ := unop_injective.decidableEq
 
-instance zero [Zero α] : Zero αᵐᵒᵖ where zero := op 0
-
-@[to_additive]
-instance one [One α] : One αᵐᵒᵖ where one := op 1
+instance instZero [Zero α] : Zero αᵐᵒᵖ where zero := op 0
 
-instance add [Add α] : Add αᵐᵒᵖ where add x y := op (unop x + unop y)
+@[to_additive] instance instOne [One α] : One αᵐᵒᵖ where one := op 1
 
-instance sub [Sub α] : Sub αᵐᵒᵖ where sub x y := op (unop x - unop y)
+instance instAdd [Add α] : Add αᵐᵒᵖ where add x y := op (unop x + unop y)
+instance instSub [Sub α] : Sub αᵐᵒᵖ where sub x y := op (unop x - unop y)
+instance instNeg [Neg α] : Neg αᵐᵒᵖ where neg x := op <| -unop x
 
-instance neg [Neg α] : Neg αᵐᵒᵖ where neg x := op <| -unop x
+instance instInvolutiveNeg [InvolutiveNeg α] : InvolutiveNeg αᵐᵒᵖ where
+  neg_neg _ := unop_injective <| neg_neg _
 
-instance involutiveNeg [InvolutiveNeg α] : InvolutiveNeg αᵐᵒᵖ :=
-  { MulOpposite.neg α with neg_neg := fun _ => unop_injective <| neg_neg _ }
+@[to_additive] instance instMul [Mul α] : Mul αᵐᵒᵖ where mul x y := op (unop y * unop x)
+@[to_additive] instance instInv [Inv α] : Inv αᵐᵒᵖ where inv x := op <| (unop x)⁻¹
 
 @[to_additive]
-instance mul [Mul α] : Mul αᵐᵒᵖ where mul x y := op (unop y * unop x)
+instance instInvolutiveInv [InvolutiveInv α] : InvolutiveInv αᵐᵒᵖ where
+  inv_inv _ := unop_injective <| inv_inv _
 
-@[to_additive]
-instance inv [Inv α] : Inv αᵐᵒᵖ where inv x := op <| (unop x)⁻¹
-
-@[to_additive]
-instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵐᵒᵖ :=
-  { MulOpposite.inv α with inv_inv := fun _ => unop_injective <| inv_inv _ }
-
-@[to_additive]
-instance smul (R : Type*) [SMul R α] : SMul R αᵐᵒᵖ where smul c x := op (c • unop x)
-
-section
+@[to_additive] instance instSMul [SMul α β] : SMul α βᵐᵒᵖ where smul c x := op (c • unop x)
 
-@[simp]
-theorem op_zero [Zero α] : op (0 : α) = 0 :=
-  rfl
+@[simp] lemma op_zero [Zero α] : op (0 : α) = 0 := rfl
 #align mul_opposite.op_zero MulOpposite.op_zero
 
-@[simp]
-theorem unop_zero [Zero α] : unop (0 : αᵐᵒᵖ) = 0 :=
-  rfl
+@[simp] lemma unop_zero [Zero α] : unop (0 : αᵐᵒᵖ) = 0 := rfl
 #align mul_opposite.unop_zero MulOpposite.unop_zero
 
-@[to_additive (attr := simp)]
-theorem op_one [One α] : op (1 : α) = 1 :=
-  rfl
+@[to_additive (attr := simp)] lemma op_one [One α] : op (1 : α) = 1 := rfl
 #align mul_opposite.op_one MulOpposite.op_one
 #align add_opposite.op_zero AddOpposite.op_zero
 
-@[to_additive (attr := simp)]
-theorem unop_one [One α] : unop (1 : αᵐᵒᵖ) = 1 :=
-  rfl
+@[to_additive (attr := simp)] lemma unop_one [One α] : unop (1 : αᵐᵒᵖ) = 1 := rfl
 #align mul_opposite.unop_one MulOpposite.unop_one
 #align add_opposite.unop_zero AddOpposite.unop_zero
 
-variable {α}
-
-@[simp]
-theorem op_add [Add α] (x y : α) : op (x + y) = op x + op y :=
-  rfl
+@[simp] lemma op_add [Add α] (x y : α) : op (x + y) = op x + op y := rfl
 #align mul_opposite.op_add MulOpposite.op_add
 
-@[simp]
-theorem unop_add [Add α] (x y : αᵐᵒᵖ) : unop (x + y) = unop x + unop y :=
-  rfl
+@[simp] lemma unop_add [Add α] (x y : αᵐᵒᵖ) : unop (x + y) = unop x + unop y := rfl
 #align mul_opposite.unop_add MulOpposite.unop_add
 
-@[simp]
-theorem op_neg [Neg α] (x : α) : op (-x) = -op x :=
-  rfl
+@[simp] lemma op_neg [Neg α] (x : α) : op (-x) = -op x := rfl
 #align mul_opposite.op_neg MulOpposite.op_neg
 
-@[simp]
-theorem unop_neg [Neg α] (x : αᵐᵒᵖ) : unop (-x) = -unop x :=
-  rfl
+@[simp] lemma unop_neg [Neg α] (x : αᵐᵒᵖ) : unop (-x) = -unop x := rfl
 #align mul_opposite.unop_neg MulOpposite.unop_neg
 
-@[to_additive (attr := simp)]
-theorem op_mul [Mul α] (x y : α) : op (x * y) = op y * op x :=
-  rfl
+@[to_additive (attr := simp)] lemma op_mul [Mul α] (x y : α) : op (x * y) = op y * op x := rfl
 #align mul_opposite.op_mul MulOpposite.op_mul
 #align add_opposite.op_add AddOpposite.op_add
 
 @[to_additive (attr := simp)]
-theorem unop_mul [Mul α] (x y : αᵐᵒᵖ) : unop (x * y) = unop y * unop x :=
-  rfl
+lemma unop_mul [Mul α] (x y : αᵐᵒᵖ) : unop (x * y) = unop y * unop x := rfl
 #align mul_opposite.unop_mul MulOpposite.unop_mul
 #align add_opposite.unop_add AddOpposite.unop_add
 
-@[to_additive (attr := simp)]
-theorem op_inv [Inv α] (x : α) : op x⁻¹ = (op x)⁻¹ :=
-  rfl
+@[to_additive (attr := simp)] lemma op_inv [Inv α] (x : α) : op x⁻¹ = (op x)⁻¹ := rfl
 #align mul_opposite.op_inv MulOpposite.op_inv
 #align add_opposite.op_neg AddOpposite.op_neg
 
-@[to_additive (attr := simp)]
-theorem unop_inv [Inv α] (x : αᵐᵒᵖ) : unop x⁻¹ = (unop x)⁻¹ :=
-  rfl
+@[to_additive (attr := simp)] lemma unop_inv [Inv α] (x : αᵐᵒᵖ) : unop x⁻¹ = (unop x)⁻¹ := rfl
 #align mul_opposite.unop_inv MulOpposite.unop_inv
 #align add_opposite.unop_neg AddOpposite.unop_neg
 
-@[simp]
-theorem op_sub [Sub α] (x y : α) : op (x - y) = op x - op y :=
-  rfl
+@[simp] lemma op_sub [Sub α] (x y : α) : op (x - y) = op x - op y := rfl
 #align mul_opposite.op_sub MulOpposite.op_sub
 
-@[simp]
-theorem unop_sub [Sub α] (x y : αᵐᵒᵖ) : unop (x - y) = unop x - unop y :=
-  rfl
+@[simp] lemma unop_sub [Sub α] (x y : αᵐᵒᵖ) : unop (x - y) = unop x - unop y := rfl
 #align mul_opposite.unop_sub MulOpposite.unop_sub
 
 @[to_additive (attr := simp)]
-theorem op_smul {R : Type*} [SMul R α] (c : R) (a : α) : op (c • a) = c • op a :=
-  rfl
+lemma op_smul [SMul α β] (a : α) (b : β) : op (a • b) = a • op b := rfl
 #align mul_opposite.op_smul MulOpposite.op_smul
 #align add_opposite.op_vadd AddOpposite.op_vadd
 
 @[to_additive (attr := simp)]
-theorem unop_smul {R : Type*} [SMul R α] (c : R) (a : αᵐᵒᵖ) : unop (c • a) = c • unop a :=
-  rfl
+lemma unop_smul [SMul α β] (a : α) (b : βᵐᵒᵖ) : unop (a • b) = a • unop b := rfl
 #align mul_opposite.unop_smul MulOpposite.unop_smul
 #align add_opposite.unop_vadd AddOpposite.unop_vadd
 
-end
-
-variable {α}
-
 @[simp, nolint simpComm]
 theorem unop_eq_zero_iff [Zero α] (a : αᵐᵒᵖ) : a.unop = (0 : α) ↔ a = (0 : αᵐᵒᵖ) :=
   unop_injective.eq_iff' rfl
@@ -358,8 +299,7 @@ theorem unop_eq_one_iff [One α] (a : αᵐᵒᵖ) : a.unop = 1 ↔ a = 1 :=
 attribute [nolint simpComm] AddOpposite.unop_eq_zero_iff
 
 @[to_additive (attr := simp)]
-theorem op_eq_one_iff [One α] (a : α) : op a = 1 ↔ a = 1 :=
-  op_injective.eq_iff' rfl
+lemma op_eq_one_iff [One α] (a : α) : op a = 1 ↔ a = 1 := op_injective.eq_iff
 #align mul_opposite.op_eq_one_iff MulOpposite.op_eq_one_iff
 #align add_opposite.op_eq_zero_iff AddOpposite.op_eq_zero_iff
 
@@ -367,67 +307,47 @@ end MulOpposite
 
 namespace AddOpposite
 
-instance one [One α] : One αᵃᵒᵖ where one := op 1
+instance instOne [One α] : One αᵃᵒᵖ where one := op 1
 
-@[simp]
-theorem op_one [One α] : op (1 : α) = 1 :=
-  rfl
+@[simp] lemma op_one [One α] : op (1 : α) = 1 := rfl
 #align add_opposite.op_one AddOpposite.op_one
 
-@[simp]
-theorem unop_one [One α] : unop 1 = (1 : α) :=
-  rfl
+@[simp] lemma unop_one [One α] : unop 1 = (1 : α) := rfl
 #align add_opposite.unop_one AddOpposite.unop_one
 
-@[simp]
-theorem op_eq_one_iff [One α] {a : α} : op a = 1 ↔ a = 1 :=
-  op_injective.eq_iff' op_one
+@[simp] lemma op_eq_one_iff [One α] {a : α} : op a = 1 ↔ a = 1 := op_injective.eq_iff
 #align add_opposite.op_eq_one_iff AddOpposite.op_eq_one_iff
 
-@[simp]
-theorem unop_eq_one_iff [One α] {a : αᵃᵒᵖ} : unop a = 1 ↔ a = 1 :=
-  unop_injective.eq_iff' unop_one
+@[simp] lemma unop_eq_one_iff [One α] {a : αᵃᵒᵖ} : unop a = 1 ↔ a = 1 := unop_injective.eq_iff
 #align add_opposite.unop_eq_one_iff AddOpposite.unop_eq_one_iff
 
 attribute [nolint simpComm] unop_eq_one_iff
 
-instance mul [Mul α] : Mul αᵃᵒᵖ where mul a b := op (unop a * unop b)
+instance instMul [Mul α] : Mul αᵃᵒᵖ where mul a b := op (unop a * unop b)
 
-@[simp]
-theorem op_mul [Mul α] (a b : α) : op (a * b) = op a * op b :=
-  rfl
+@[simp] lemma op_mul [Mul α] (a b : α) : op (a * b) = op a * op b := rfl
 #align add_opposite.op_mul AddOpposite.op_mul
 
-@[simp]
-theorem unop_mul [Mul α] (a b : αᵃᵒᵖ) : unop (a * b) = unop a * unop b :=
-  rfl
+@[simp] lemma unop_mul [Mul α] (a b : αᵃᵒᵖ) : unop (a * b) = unop a * unop b := rfl
 #align add_opposite.unop_mul AddOpposite.unop_mul
 
-instance inv [Inv α] : Inv αᵃᵒᵖ where inv a := op (unop a)⁻¹
+instance instInv [Inv α] : Inv αᵃᵒᵖ where inv a := op (unop a)⁻¹
 
-instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵃᵒᵖ :=
-  { AddOpposite.inv with inv_inv := fun _ => unop_injective <| inv_inv _ }
+instance instInvolutiveInv [InvolutiveInv α] : InvolutiveInv αᵃᵒᵖ where
+  inv_inv _ := unop_injective <| inv_inv _
 
-@[simp]
-theorem op_inv [Inv α] (a : α) : op a⁻¹ = (op a)⁻¹ :=
-  rfl
+@[simp] lemma op_inv [Inv α] (a : α) : op a⁻¹ = (op a)⁻¹ := rfl
 #align add_opposite.op_inv AddOpposite.op_inv
 
-@[simp]
-theorem unop_inv [Inv α] (a : αᵃᵒᵖ) : unop a⁻¹ = (unop a)⁻¹ :=
-  rfl
+@[simp] lemma unop_inv [Inv α] (a : αᵃᵒᵖ) : unop a⁻¹ = (unop a)⁻¹ := rfl
 #align add_opposite.unop_inv AddOpposite.unop_inv
 
-instance div [Div α] : Div αᵃᵒᵖ where div a b := op (unop a / unop b)
+instance instDiv [Div α] : Div αᵃᵒᵖ where div a b := op (unop a / unop b)
 
-@[simp]
-theorem op_div [Div α] (a b : α) : op (a / b) = op a / op b :=
-  rfl
+@[simp] lemma op_div [Div α] (a b : α) : op (a / b) = op a / op b := rfl
 #align add_opposite.op_div AddOpposite.op_div
 
-@[simp]
-theorem unop_div [Div α] (a b : αᵃᵒᵖ) : unop (a / b) = unop a / unop b :=
-  rfl
+@[simp] lemma unop_div [Div α] (a b : αᵃᵒᵖ) : unop (a / b) = unop a / unop b := rfl
 #align add_opposite.unop_div AddOpposite.unop_div
 
 end AddOpposite
style: homogenise porting notes (#11145)

Homogenises porting notes via capitalisation and addition of whitespace.

It makes the following changes:

  • converts "--porting note" into "-- Porting note";
  • converts "porting note" into "Porting note".
Diff
@@ -68,7 +68,7 @@ def MulOpposite (α : Type u) : Type u :=
   PreOpposite α
 #align mul_opposite MulOpposite
 #align add_opposite AddOpposite
--- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
+-- Porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
 -- both tagged with it in mathlib3
 
 
chore(*): use α → β instead of ∀ _ : α, β (#9529)
Diff
@@ -120,7 +120,7 @@ theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
 /-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec'`. -/
 @[to_additive (attr := simp, elab_as_elim)
   "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec'`."]
-protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
+protected def rec' {F : αᵐᵒᵖ → Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
 #align mul_opposite.rec MulOpposite.rec'
 #align add_opposite.rec AddOpposite.rec'
 
chore(*): replace $ with <| (#9319)

See Zulip thread for the discussion.

Diff
@@ -171,7 +171,7 @@ theorem unop_surjective : Surjective (unop : αᵐᵒᵖ → α) :=
 #align add_opposite.unop_surjective AddOpposite.unop_surjective
 
 @[to_additive (attr := simp)]
-theorem op_inj {x y : α} : op x = op y ↔ x = y := iff_of_eq $ PreOpposite.op'.injEq _ _
+theorem op_inj {x y : α} : op x = op y ↔ x = y := iff_of_eq <| PreOpposite.op'.injEq _ _
 #align mul_opposite.op_inj MulOpposite.op_inj
 #align add_opposite.op_inj AddOpposite.op_inj
 
@@ -217,20 +217,20 @@ instance add [Add α] : Add αᵐᵒᵖ where add x y := op (unop x + unop y)
 
 instance sub [Sub α] : Sub αᵐᵒᵖ where sub x y := op (unop x - unop y)
 
-instance neg [Neg α] : Neg αᵐᵒᵖ where neg x := op $ -unop x
+instance neg [Neg α] : Neg αᵐᵒᵖ where neg x := op <| -unop x
 
 instance involutiveNeg [InvolutiveNeg α] : InvolutiveNeg αᵐᵒᵖ :=
-  { MulOpposite.neg α with neg_neg := fun _ => unop_injective $ neg_neg _ }
+  { MulOpposite.neg α with neg_neg := fun _ => unop_injective <| neg_neg _ }
 
 @[to_additive]
 instance mul [Mul α] : Mul αᵐᵒᵖ where mul x y := op (unop y * unop x)
 
 @[to_additive]
-instance inv [Inv α] : Inv αᵐᵒᵖ where inv x := op $ (unop x)⁻¹
+instance inv [Inv α] : Inv αᵐᵒᵖ where inv x := op <| (unop x)⁻¹
 
 @[to_additive]
 instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵐᵒᵖ :=
-  { MulOpposite.inv α with inv_inv := fun _ => unop_injective $ inv_inv _ }
+  { MulOpposite.inv α with inv_inv := fun _ => unop_injective <| inv_inv _ }
 
 @[to_additive]
 instance smul (R : Type*) [SMul R α] : SMul R αᵐᵒᵖ where smul c x := op (c • unop x)
@@ -342,11 +342,11 @@ theorem op_eq_zero_iff [Zero α] (a : α) : op a = (0 : αᵐᵒᵖ) ↔ a = (0
 #align mul_opposite.op_eq_zero_iff MulOpposite.op_eq_zero_iff
 
 theorem unop_ne_zero_iff [Zero α] (a : αᵐᵒᵖ) : a.unop ≠ (0 : α) ↔ a ≠ (0 : αᵐᵒᵖ) :=
-  not_congr $ unop_eq_zero_iff a
+  not_congr <| unop_eq_zero_iff a
 #align mul_opposite.unop_ne_zero_iff MulOpposite.unop_ne_zero_iff
 
 theorem op_ne_zero_iff [Zero α] (a : α) : op a ≠ (0 : αᵐᵒᵖ) ↔ a ≠ (0 : α) :=
-  not_congr $ op_eq_zero_iff a
+  not_congr <| op_eq_zero_iff a
 #align mul_opposite.op_ne_zero_iff MulOpposite.op_ne_zero_iff
 
 @[to_additive (attr := simp, nolint simpComm)]
@@ -406,7 +406,7 @@ theorem unop_mul [Mul α] (a b : αᵃᵒᵖ) : unop (a * b) = unop a * unop b :
 instance inv [Inv α] : Inv αᵃᵒᵖ where inv a := op (unop a)⁻¹
 
 instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵃᵒᵖ :=
-  { AddOpposite.inv with inv_inv := fun _ => unop_injective $ inv_inv _ }
+  { AddOpposite.inv with inv_inv := fun _ => unop_injective <| inv_inv _ }
 
 @[simp]
 theorem op_inv [Inv α] (a : α) : op a⁻¹ = (op a)⁻¹ :=
feat: (a • s)⁻¹ = s⁻¹ • a⁻¹ (#9199)

and other simple pointwise lemmas for Set and Finset. Also add supporting Fintype.piFinset lemmas and fix the names of two lemmas.

From LeanAPAP and LeanCamCombi

Diff
@@ -205,6 +205,9 @@ instance unique [Unique α] : Unique αᵐᵒᵖ :=
 instance isEmpty [IsEmpty α] : IsEmpty αᵐᵒᵖ :=
   Function.isEmpty unop
 
+@[to_additive]
+instance instDecidableEq [DecidableEq α] : DecidableEq αᵐᵒᵖ := unop_injective.decidableEq
+
 instance zero [Zero α] : Zero αᵐᵒᵖ where zero := op 0
 
 @[to_additive]
style: cleanup some autoImplicits (#8288)

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

Diff
@@ -41,11 +41,10 @@ definitional eta reduction for structures (Lean 3 does not).
 multiplicative opposite, additive opposite
 -/
 
-set_option autoImplicit true
-
-
 universe u v
 
+variable {α : Type*}
+
 open Function
 
 /-- Auxiliary type to implement `MulOpposite` and `AddOpposite`.
style: shorten simps configurations (#8296)

Use .asFn and .lemmasOnly as simps configuration options.

For reference, these are defined here:

https://github.com/leanprover-community/mathlib4/blob/4055c8b471380825f07416b12cb0cf266da44d84/Mathlib/Tactic/Simps/Basic.lean#L843-L851

Diff
@@ -126,7 +126,7 @@ protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀
 #align add_opposite.rec AddOpposite.rec'
 
 /-- The canonical bijection between `α` and `αᵐᵒᵖ`. -/
-@[to_additive (attr := simps (config := { fullyApplied := false }) apply symm_apply)
+@[to_additive (attr := simps (config := .asFn) apply symm_apply)
   "The canonical bijection between `α` and `αᵃᵒᵖ`."]
 def opEquiv : α ≃ αᵐᵒᵖ :=
   ⟨op, unop, unop_op, op_unop⟩
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
@@ -5,7 +5,7 @@ Authors: Kenny Lau
 -/
 import Mathlib.Algebra.Group.Defs
 import Mathlib.Logic.Equiv.Defs
-import Mathlib.Logic.Nontrivial
+import Mathlib.Logic.Nontrivial.Basic
 import Mathlib.Logic.IsEmpty
 
 #align_import algebra.opposites from "leanprover-community/mathlib"@"7a89b1aed52bcacbcc4a8ad515e72c5c07268940"
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
@@ -41,6 +41,8 @@ definitional eta reduction for structures (Lean 3 does not).
 multiplicative opposite, additive opposite
 -/
 
+set_option autoImplicit true
+
 
 universe u v
 
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
@@ -229,7 +229,7 @@ instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵐᵒᵖ :=
   { MulOpposite.inv α with inv_inv := fun _ => unop_injective $ inv_inv _ }
 
 @[to_additive]
-instance smul (R : Type _) [SMul R α] : SMul R αᵐᵒᵖ where smul c x := op (c • unop x)
+instance smul (R : Type*) [SMul R α] : SMul R αᵐᵒᵖ where smul c x := op (c • unop x)
 
 section
 
@@ -312,13 +312,13 @@ theorem unop_sub [Sub α] (x y : αᵐᵒᵖ) : unop (x - y) = unop x - unop y :
 #align mul_opposite.unop_sub MulOpposite.unop_sub
 
 @[to_additive (attr := simp)]
-theorem op_smul {R : Type _} [SMul R α] (c : R) (a : α) : op (c • a) = c • op a :=
+theorem op_smul {R : Type*} [SMul R α] (c : R) (a : α) : op (c • a) = c • op a :=
   rfl
 #align mul_opposite.op_smul MulOpposite.op_smul
 #align add_opposite.op_vadd AddOpposite.op_vadd
 
 @[to_additive (attr := simp)]
-theorem unop_smul {R : Type _} [SMul R α] (c : R) (a : αᵐᵒᵖ) : unop (c • a) = c • unop a :=
+theorem unop_smul {R : Type*} [SMul R α] (c : R) (a : αᵐᵒᵖ) : unop (c • a) = c • unop a :=
   rfl
 #align mul_opposite.unop_smul MulOpposite.unop_smul
 #align add_opposite.unop_vadd AddOpposite.unop_vadd
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,17 +2,14 @@
 Copyright (c) 2018 Kenny Lau. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Kenny Lau
-
-! This file was ported from Lean 3 source module algebra.opposites
-! leanprover-community/mathlib commit 7a89b1aed52bcacbcc4a8ad515e72c5c07268940
-! 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.Equiv.Defs
 import Mathlib.Logic.Nontrivial
 import Mathlib.Logic.IsEmpty
 
+#align_import algebra.opposites from "leanprover-community/mathlib"@"7a89b1aed52bcacbcc4a8ad515e72c5c07268940"
+
 /-!
 
 # Multiplicative opposite and algebraic operations on it
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
@@ -82,7 +82,7 @@ postfix:max "ᵃᵒᵖ" => AddOpposite
 
 namespace MulOpposite
 
-/-- The element of `mul_opposite α` that represents `x : α`. -/
+/-- The element of `MulOpposite α` that represents `x : α`. -/
 @[to_additive "The element of `αᵃᵒᵖ` that represents `x : α`."]
 def op : α → αᵐᵒᵖ :=
   PreOpposite.op'
refactor: make MulOpposite = AddOpposite (#4050)

It turns out to be convenient to have MulOpposite α = AddOpposite α true by definition, in the same way that it is convenient to have Additive α = α; this means that we also get the defeq AddOpposite (Additive α) = MulOpposite α, which is convenient when working with quotients. This is a compromise between making MulOpposite α = AddOpposite α = α (what we had in Lean 3) and having no defeqs within those three types (which we had as of #1036).

This is motivated by #3333

Diff
@@ -49,31 +49,30 @@ universe u v
 
 open Function
 
+/-- Auxiliary type to implement `MulOpposite` and `AddOpposite`.
+
+It turns out to be convenient to have `MulOpposite α= AddOpposite α` true by definition, in the
+same way that it is convenient to have `Additive α = α`; this means that we also get the defeq
+`AddOpposite (Additive α) = MulOpposite α`, which is convenient when working with quotients.
+
+This is a compromise between making `MulOpposite α = AddOpposite α = α` (what we had in Lean 3) and
+having no defeqs within those three types (which we had as of mathlib4#1036). -/
+structure PreOpposite (α : Type u) : Type u where
+  /-- The element of `PreOpposite α` that represents `x : α`. -/ op' ::
+  /-- The element of `α` represented by `x : PreOpposite α`. -/ unop' : α
+
 /-- Multiplicative opposite of a type. This type inherits all additive structures on `α` and
 reverses left and right in multiplication.-/
-structure MulOpposite (α : Type u) : Type u where
-  /-- The element of `MulOpposite α` that represents `x : α`. -/ op ::
-  /-- The element of `α` represented by `x : αᵐᵒᵖ`. -/ unop : α
-#align mul_opposite.op MulOpposite.op
-#align mul_opposite.unop MulOpposite.unop
+@[to_additive
+      "Additive opposite of a type. This type inherits all multiplicative structures on `α` and
+      reverses left and right in addition."]
+def MulOpposite (α : Type u) : Type u :=
+  PreOpposite α
 #align mul_opposite MulOpposite
-
--- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
--- both tagged with it in mathlib3
-
-/-- Additive opposite of a type. This type inherits all multiplicative structures on
-      `α` and reverses left and right in addition. -/
-structure AddOpposite (α : Type u) : Type u where
-  /-- The element of `αᵃᵒᵖ` that represents `x : α`. -/ op ::
-  /-- The element of `α` represented by `x : αᵃᵒᵖ`. -/ unop : α
-#align add_opposite.unop AddOpposite.unop
-#align add_opposite.op AddOpposite.op
 #align add_opposite AddOpposite
-
 -- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
 -- both tagged with it in mathlib3
 
-attribute [to_additive] MulOpposite
 
 /-- Multiplicative opposite of a type. -/
 postfix:max "ᵐᵒᵖ" => MulOpposite
@@ -83,8 +82,21 @@ postfix:max "ᵃᵒᵖ" => AddOpposite
 
 namespace MulOpposite
 
--- porting note: `simp` can prove this in Lean 4
-@[to_additive]
+/-- The element of `mul_opposite α` that represents `x : α`. -/
+@[to_additive "The element of `αᵃᵒᵖ` that represents `x : α`."]
+def op : α → αᵐᵒᵖ :=
+  PreOpposite.op'
+#align mul_opposite.op MulOpposite.op
+#align add_opposite.op AddOpposite.op
+
+/-- The element of `α` represented by `x : αᵐᵒᵖ`. -/
+@[to_additive "The element of `α` represented by `x : αᵃᵒᵖ`."]
+def unop : αᵐᵒᵖ → α :=
+  PreOpposite.unop'
+#align mul_opposite.unop MulOpposite.unop
+#align add_opposite.unop AddOpposite.unop
+
+@[to_additive (attr := simp)]
 theorem unop_op (x : α) : unop (op x) = x := rfl
 #align mul_opposite.unop_op MulOpposite.unop_op
 #align add_opposite.unop_op AddOpposite.unop_op
@@ -108,8 +120,8 @@ theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
 #align add_opposite.unop_comp_op AddOpposite.unop_comp_op
 
 /-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec'`. -/
-@[to_additive (attr := simp)
-  "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec`."]
+@[to_additive (attr := simp, elab_as_elim)
+  "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec'`."]
 protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
 #align mul_opposite.rec MulOpposite.rec'
 #align add_opposite.rec AddOpposite.rec'
@@ -160,9 +172,8 @@ theorem unop_surjective : Surjective (unop : αᵐᵒᵖ → α) :=
 #align mul_opposite.unop_surjective MulOpposite.unop_surjective
 #align add_opposite.unop_surjective AddOpposite.unop_surjective
 
--- porting note: `simp` can prove this
-@[to_additive]
-theorem op_inj {x y : α} : op x = op y ↔ x = y := by simp
+@[to_additive (attr := simp)]
+theorem op_inj {x y : α} : op x = op y ↔ x = y := iff_of_eq $ PreOpposite.op'.injEq _ _
 #align mul_opposite.op_inj MulOpposite.op_inj
 #align add_opposite.op_inj AddOpposite.op_inj
 
chore: add explicit instance names for MulOpposite (#3032)

Using explicit names makes it easier to refer to instances from docstrings and Zulip.

This probably isn't exhaustive, but does most of the algebra hierarchy.

Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -177,51 +177,51 @@ attribute [nolint simpComm] AddOpposite.unop_inj
 variable (α)
 
 @[to_additive]
-instance [Nontrivial α] : Nontrivial αᵐᵒᵖ :=
+instance nontrivial [Nontrivial α] : Nontrivial αᵐᵒᵖ :=
   op_injective.nontrivial
 
 @[to_additive]
-instance [Inhabited α] : Inhabited αᵐᵒᵖ :=
+instance inhabited [Inhabited α] : Inhabited αᵐᵒᵖ :=
   ⟨op default⟩
 
 @[to_additive]
-instance [Subsingleton α] : Subsingleton αᵐᵒᵖ :=
+instance subsingleton [Subsingleton α] : Subsingleton αᵐᵒᵖ :=
   unop_injective.subsingleton
 
 @[to_additive]
-instance [Unique α] : Unique αᵐᵒᵖ :=
+instance unique [Unique α] : Unique αᵐᵒᵖ :=
   Unique.mk' _
 
 @[to_additive]
-instance [IsEmpty α] : IsEmpty αᵐᵒᵖ :=
+instance isEmpty [IsEmpty α] : IsEmpty αᵐᵒᵖ :=
   Function.isEmpty unop
 
-instance [Zero α] : Zero αᵐᵒᵖ where zero := op 0
+instance zero [Zero α] : Zero αᵐᵒᵖ where zero := op 0
 
 @[to_additive]
-instance [One α] : One αᵐᵒᵖ where one := op 1
+instance one [One α] : One αᵐᵒᵖ where one := op 1
 
-instance [Add α] : Add αᵐᵒᵖ where add x y := op (unop x + unop y)
+instance add [Add α] : Add αᵐᵒᵖ where add x y := op (unop x + unop y)
 
-instance [Sub α] : Sub αᵐᵒᵖ where sub x y := op (unop x - unop y)
+instance sub [Sub α] : Sub αᵐᵒᵖ where sub x y := op (unop x - unop y)
 
-instance [Neg α] : Neg αᵐᵒᵖ where neg x := op $ -unop x
+instance neg [Neg α] : Neg αᵐᵒᵖ where neg x := op $ -unop x
 
-instance [InvolutiveNeg α] : InvolutiveNeg αᵐᵒᵖ :=
-  { MulOpposite.instNegMulOpposite α with neg_neg := fun _ => unop_injective $ neg_neg _ }
+instance involutiveNeg [InvolutiveNeg α] : InvolutiveNeg αᵐᵒᵖ :=
+  { MulOpposite.neg α with neg_neg := fun _ => unop_injective $ neg_neg _ }
 
 @[to_additive]
-instance [Mul α] : Mul αᵐᵒᵖ where mul x y := op (unop y * unop x)
+instance mul [Mul α] : Mul αᵐᵒᵖ where mul x y := op (unop y * unop x)
 
 @[to_additive]
-instance [Inv α] : Inv αᵐᵒᵖ where inv x := op $ (unop x)⁻¹
+instance inv [Inv α] : Inv αᵐᵒᵖ where inv x := op $ (unop x)⁻¹
 
 @[to_additive]
-instance [InvolutiveInv α] : InvolutiveInv αᵐᵒᵖ :=
-  { MulOpposite.instInvMulOpposite α with inv_inv := fun _ => unop_injective $ inv_inv _ }
+instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵐᵒᵖ :=
+  { MulOpposite.inv α with inv_inv := fun _ => unop_injective $ inv_inv _ }
 
 @[to_additive]
-instance (R : Type _) [SMul R α] : SMul R αᵐᵒᵖ where smul c x := op (c • unop x)
+instance smul (R : Type _) [SMul R α] : SMul R αᵐᵒᵖ where smul c x := op (c • unop x)
 
 section
 
@@ -355,7 +355,7 @@ end MulOpposite
 
 namespace AddOpposite
 
-instance [One α] : One αᵃᵒᵖ where one := op 1
+instance one [One α] : One αᵃᵒᵖ where one := op 1
 
 @[simp]
 theorem op_one [One α] : op (1 : α) = 1 :=
@@ -379,7 +379,7 @@ theorem unop_eq_one_iff [One α] {a : αᵃᵒᵖ} : unop a = 1 ↔ a = 1 :=
 
 attribute [nolint simpComm] unop_eq_one_iff
 
-instance [Mul α] : Mul αᵃᵒᵖ where mul a b := op (unop a * unop b)
+instance mul [Mul α] : Mul αᵃᵒᵖ where mul a b := op (unop a * unop b)
 
 @[simp]
 theorem op_mul [Mul α] (a b : α) : op (a * b) = op a * op b :=
@@ -391,10 +391,10 @@ theorem unop_mul [Mul α] (a b : αᵃᵒᵖ) : unop (a * b) = unop a * unop b :
   rfl
 #align add_opposite.unop_mul AddOpposite.unop_mul
 
-instance [Inv α] : Inv αᵃᵒᵖ where inv a := op (unop a)⁻¹
+instance inv [Inv α] : Inv αᵃᵒᵖ where inv a := op (unop a)⁻¹
 
-instance [InvolutiveInv α] : InvolutiveInv αᵃᵒᵖ :=
-  { AddOpposite.instInvAddOpposite with inv_inv := fun _ => unop_injective $ inv_inv _ }
+instance involutiveInv [InvolutiveInv α] : InvolutiveInv αᵃᵒᵖ :=
+  { AddOpposite.inv with inv_inv := fun _ => unop_injective $ inv_inv _ }
 
 @[simp]
 theorem op_inv [Inv α] (a : α) : op a⁻¹ = (op a)⁻¹ :=
@@ -406,7 +406,7 @@ theorem unop_inv [Inv α] (a : αᵃᵒᵖ) : unop a⁻¹ = (unop a)⁻¹ :=
   rfl
 #align add_opposite.unop_inv AddOpposite.unop_inv
 
-instance [Div α] : Div αᵃᵒᵖ where div a b := op (unop a / unop b)
+instance div [Div α] : Div αᵃᵒᵖ where div a b := op (unop a / unop b)
 
 @[simp]
 theorem op_div [Div α] (a b : α) : op (a / b) = op a / op b :=
fix: use to_additive (attr := _) here and there (#2073)
Diff
@@ -115,8 +115,8 @@ protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀
 #align add_opposite.rec AddOpposite.rec'
 
 /-- The canonical bijection between `α` and `αᵐᵒᵖ`. -/
-@[to_additive "The canonical bijection between `α` and `αᵃᵒᵖ`.",--]
-  simps (config := { fullyApplied := false }) apply symm_apply]
+@[to_additive (attr := simps (config := { fullyApplied := false }) apply symm_apply)
+  "The canonical bijection between `α` and `αᵃᵒᵖ`."]
 def opEquiv : α ≃ αᵐᵒᵖ :=
   ⟨op, unop, unop_op, op_unop⟩
 #align mul_opposite.op_equiv MulOpposite.opEquiv
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
@@ -55,6 +55,8 @@ structure MulOpposite (α : Type u) : Type u where
   /-- The element of `MulOpposite α` that represents `x : α`. -/ op ::
   /-- The element of `α` represented by `x : αᵐᵒᵖ`. -/ unop : α
 #align mul_opposite.op MulOpposite.op
+#align mul_opposite.unop MulOpposite.unop
+#align mul_opposite MulOpposite
 
 -- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
 -- both tagged with it in mathlib3
@@ -64,6 +66,9 @@ structure MulOpposite (α : Type u) : Type u where
 structure AddOpposite (α : Type u) : Type u where
   /-- The element of `αᵃᵒᵖ` that represents `x : α`. -/ op ::
   /-- The element of `α` represented by `x : αᵃᵒᵖ`. -/ unop : α
+#align add_opposite.unop AddOpposite.unop
+#align add_opposite.op AddOpposite.op
+#align add_opposite AddOpposite
 
 -- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
 -- both tagged with it in mathlib3
@@ -81,18 +86,26 @@ namespace MulOpposite
 -- porting note: `simp` can prove this in Lean 4
 @[to_additive]
 theorem unop_op (x : α) : unop (op x) = x := rfl
+#align mul_opposite.unop_op MulOpposite.unop_op
+#align add_opposite.unop_op AddOpposite.unop_op
 
 @[to_additive (attr := simp)]
 theorem op_unop (x : αᵐᵒᵖ) : op (unop x) = x :=
   rfl
+#align mul_opposite.op_unop MulOpposite.op_unop
+#align add_opposite.op_unop AddOpposite.op_unop
 
 @[to_additive (attr := simp)]
 theorem op_comp_unop : (op : α → αᵐᵒᵖ) ∘ unop = id :=
   rfl
+#align mul_opposite.op_comp_unop MulOpposite.op_comp_unop
+#align add_opposite.op_comp_unop AddOpposite.op_comp_unop
 
 @[to_additive (attr := simp)]
 theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
   rfl
+#align mul_opposite.unop_comp_op MulOpposite.unop_comp_op
+#align add_opposite.unop_comp_op AddOpposite.unop_comp_op
 
 /-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec'`. -/
 @[to_additive (attr := simp)
@@ -106,22 +119,34 @@ protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀
   simps (config := { fullyApplied := false }) apply symm_apply]
 def opEquiv : α ≃ αᵐᵒᵖ :=
   ⟨op, unop, unop_op, op_unop⟩
+#align mul_opposite.op_equiv MulOpposite.opEquiv
+#align mul_opposite.op_equiv_apply MulOpposite.opEquiv_apply
+#align mul_opposite.op_equiv_symm_apply MulOpposite.opEquiv_symm_apply
+#align add_opposite.op_equiv AddOpposite.opEquiv
 
 @[to_additive]
 theorem op_bijective : Bijective (op : α → αᵐᵒᵖ) :=
   opEquiv.bijective
+#align mul_opposite.op_bijective MulOpposite.op_bijective
+#align add_opposite.op_bijective AddOpposite.op_bijective
 
 @[to_additive]
 theorem unop_bijective : Bijective (unop : αᵐᵒᵖ → α) :=
   opEquiv.symm.bijective
+#align mul_opposite.unop_bijective MulOpposite.unop_bijective
+#align add_opposite.unop_bijective AddOpposite.unop_bijective
 
 @[to_additive]
 theorem op_injective : Injective (op : α → αᵐᵒᵖ) :=
   op_bijective.injective
+#align mul_opposite.op_injective MulOpposite.op_injective
+#align add_opposite.op_injective AddOpposite.op_injective
 
 @[to_additive]
 theorem op_surjective : Surjective (op : α → αᵐᵒᵖ) :=
   op_bijective.surjective
+#align mul_opposite.op_surjective MulOpposite.op_surjective
+#align add_opposite.op_surjective AddOpposite.op_surjective
 
 @[to_additive]
 theorem unop_injective : Injective (unop : αᵐᵒᵖ → α) :=
@@ -132,14 +157,20 @@ theorem unop_injective : Injective (unop : αᵐᵒᵖ → α) :=
 @[to_additive]
 theorem unop_surjective : Surjective (unop : αᵐᵒᵖ → α) :=
   unop_bijective.surjective
+#align mul_opposite.unop_surjective MulOpposite.unop_surjective
+#align add_opposite.unop_surjective AddOpposite.unop_surjective
 
 -- porting note: `simp` can prove this
 @[to_additive]
 theorem op_inj {x y : α} : op x = op y ↔ x = y := by simp
+#align mul_opposite.op_inj MulOpposite.op_inj
+#align add_opposite.op_inj AddOpposite.op_inj
 
 @[to_additive (attr := simp, nolint simpComm)]
 theorem unop_inj {x y : αᵐᵒᵖ} : unop x = unop y ↔ x = y :=
   unop_injective.eq_iff
+#align mul_opposite.unop_inj MulOpposite.unop_inj
+#align add_opposite.unop_inj AddOpposite.unop_inj
 
 attribute [nolint simpComm] AddOpposite.unop_inj
 
@@ -207,10 +238,14 @@ theorem unop_zero [Zero α] : unop (0 : αᵐᵒᵖ) = 0 :=
 @[to_additive (attr := simp)]
 theorem op_one [One α] : op (1 : α) = 1 :=
   rfl
+#align mul_opposite.op_one MulOpposite.op_one
+#align add_opposite.op_zero AddOpposite.op_zero
 
 @[to_additive (attr := simp)]
 theorem unop_one [One α] : unop (1 : αᵐᵒᵖ) = 1 :=
   rfl
+#align mul_opposite.unop_one MulOpposite.unop_one
+#align add_opposite.unop_zero AddOpposite.unop_zero
 
 variable {α}
 
@@ -237,19 +272,26 @@ theorem unop_neg [Neg α] (x : αᵐᵒᵖ) : unop (-x) = -unop x :=
 @[to_additive (attr := simp)]
 theorem op_mul [Mul α] (x y : α) : op (x * y) = op y * op x :=
   rfl
+#align mul_opposite.op_mul MulOpposite.op_mul
+#align add_opposite.op_add AddOpposite.op_add
 
 @[to_additive (attr := simp)]
 theorem unop_mul [Mul α] (x y : αᵐᵒᵖ) : unop (x * y) = unop y * unop x :=
   rfl
+#align mul_opposite.unop_mul MulOpposite.unop_mul
+#align add_opposite.unop_add AddOpposite.unop_add
 
 @[to_additive (attr := simp)]
 theorem op_inv [Inv α] (x : α) : op x⁻¹ = (op x)⁻¹ :=
   rfl
+#align mul_opposite.op_inv MulOpposite.op_inv
+#align add_opposite.op_neg AddOpposite.op_neg
 
 @[to_additive (attr := simp)]
 theorem unop_inv [Inv α] (x : αᵐᵒᵖ) : unop x⁻¹ = (unop x)⁻¹ :=
   rfl
 #align mul_opposite.unop_inv MulOpposite.unop_inv
+#align add_opposite.unop_neg AddOpposite.unop_neg
 
 @[simp]
 theorem op_sub [Sub α] (x y : α) : op (x - y) = op x - op y :=
@@ -264,10 +306,14 @@ theorem unop_sub [Sub α] (x y : αᵐᵒᵖ) : unop (x - y) = unop x - unop y :
 @[to_additive (attr := simp)]
 theorem op_smul {R : Type _} [SMul R α] (c : R) (a : α) : op (c • a) = c • op a :=
   rfl
+#align mul_opposite.op_smul MulOpposite.op_smul
+#align add_opposite.op_vadd AddOpposite.op_vadd
 
 @[to_additive (attr := simp)]
 theorem unop_smul {R : Type _} [SMul R α] (c : R) (a : αᵐᵒᵖ) : unop (c • a) = c • unop a :=
   rfl
+#align mul_opposite.unop_smul MulOpposite.unop_smul
+#align add_opposite.unop_vadd AddOpposite.unop_vadd
 
 end
 
@@ -294,12 +340,16 @@ theorem op_ne_zero_iff [Zero α] (a : α) : op a ≠ (0 : αᵐᵒᵖ) ↔ a ≠
 @[to_additive (attr := simp, nolint simpComm)]
 theorem unop_eq_one_iff [One α] (a : αᵐᵒᵖ) : a.unop = 1 ↔ a = 1 :=
   unop_injective.eq_iff' rfl
+#align mul_opposite.unop_eq_one_iff MulOpposite.unop_eq_one_iff
+#align add_opposite.unop_eq_zero_iff AddOpposite.unop_eq_zero_iff
 
 attribute [nolint simpComm] AddOpposite.unop_eq_zero_iff
 
 @[to_additive (attr := simp)]
 theorem op_eq_one_iff [One α] (a : α) : op a = 1 ↔ a = 1 :=
   op_injective.eq_iff' rfl
+#align mul_opposite.op_eq_one_iff MulOpposite.op_eq_one_iff
+#align add_opposite.op_eq_zero_iff AddOpposite.op_eq_zero_iff
 
 end MulOpposite
 
chore: add #align statements for to_additive decls (#1816)

Co-authored-by: Floris van Doorn <fpvdoorn@gmail.com>

Diff
@@ -99,6 +99,7 @@ theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
   "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec`."]
 protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
 #align mul_opposite.rec MulOpposite.rec'
+#align add_opposite.rec AddOpposite.rec'
 
 /-- The canonical bijection between `α` and `αᵐᵒᵖ`. -/
 @[to_additive "The canonical bijection between `α` and `αᵃᵒᵖ`.",--]
@@ -126,6 +127,7 @@ theorem op_surjective : Surjective (op : α → αᵐᵒᵖ) :=
 theorem unop_injective : Injective (unop : αᵐᵒᵖ → α) :=
   unop_bijective.injective
 #align mul_opposite.unop_injective MulOpposite.unop_injective
+#align add_opposite.unop_injective AddOpposite.unop_injective
 
 @[to_additive]
 theorem unop_surjective : Surjective (unop : αᵐᵒᵖ → α) :=
feat: improve the way to_additive deals with attributes (#1314)
  • The new syntax for any attributes that need to be copied by to_additive is @[to_additive (attrs := simp, ext, simps)]
  • Adds the auxiliary declarations generated by the simp and simps attributes to the to_additive-dictionary.
  • Future issue: Does not yet translate auxiliary declarations for other attributes (including custom simp-attributes). In particular it's possible that norm_cast might generate some auxiliary declarations.
  • Fixes #950
  • Fixes #953
  • Fixes #1149
  • This moves the interaction between to_additive and simps from the Simps file to the toAdditive file for uniformity.
  • Make the same changes to @[reassoc]

Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -82,20 +82,21 @@ namespace MulOpposite
 @[to_additive]
 theorem unop_op (x : α) : unop (op x) = x := rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_unop (x : αᵐᵒᵖ) : op (unop x) = x :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_comp_unop : (op : α → αᵐᵒᵖ) ∘ unop = id :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
   rfl
 
 /-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec'`. -/
-@[simp, to_additive "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec`."]
+@[to_additive (attr := simp)
+  "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec`."]
 protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
 #align mul_opposite.rec MulOpposite.rec'
 
@@ -134,7 +135,7 @@ theorem unop_surjective : Surjective (unop : αᵐᵒᵖ → α) :=
 @[to_additive]
 theorem op_inj {x y : α} : op x = op y ↔ x = y := by simp
 
-@[simp, nolint simpComm, to_additive]
+@[to_additive (attr := simp, nolint simpComm)]
 theorem unop_inj {x y : αᵐᵒᵖ} : unop x = unop y ↔ x = y :=
   unop_injective.eq_iff
 
@@ -201,11 +202,11 @@ theorem unop_zero [Zero α] : unop (0 : αᵐᵒᵖ) = 0 :=
   rfl
 #align mul_opposite.unop_zero MulOpposite.unop_zero
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_one [One α] : op (1 : α) = 1 :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem unop_one [One α] : unop (1 : αᵐᵒᵖ) = 1 :=
   rfl
 
@@ -231,19 +232,19 @@ theorem unop_neg [Neg α] (x : αᵐᵒᵖ) : unop (-x) = -unop x :=
   rfl
 #align mul_opposite.unop_neg MulOpposite.unop_neg
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_mul [Mul α] (x y : α) : op (x * y) = op y * op x :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem unop_mul [Mul α] (x y : αᵐᵒᵖ) : unop (x * y) = unop y * unop x :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_inv [Inv α] (x : α) : op x⁻¹ = (op x)⁻¹ :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem unop_inv [Inv α] (x : αᵐᵒᵖ) : unop x⁻¹ = (unop x)⁻¹ :=
   rfl
 #align mul_opposite.unop_inv MulOpposite.unop_inv
@@ -258,11 +259,11 @@ theorem unop_sub [Sub α] (x y : αᵐᵒᵖ) : unop (x - y) = unop x - unop y :
   rfl
 #align mul_opposite.unop_sub MulOpposite.unop_sub
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_smul {R : Type _} [SMul R α] (c : R) (a : α) : op (c • a) = c • op a :=
   rfl
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem unop_smul {R : Type _} [SMul R α] (c : R) (a : αᵐᵒᵖ) : unop (c • a) = c • unop a :=
   rfl
 
@@ -288,13 +289,13 @@ theorem op_ne_zero_iff [Zero α] (a : α) : op a ≠ (0 : αᵐᵒᵖ) ↔ a ≠
   not_congr $ op_eq_zero_iff a
 #align mul_opposite.op_ne_zero_iff MulOpposite.op_ne_zero_iff
 
-@[simp, nolint simpComm, to_additive]
+@[to_additive (attr := simp, nolint simpComm)]
 theorem unop_eq_one_iff [One α] (a : αᵐᵒᵖ) : a.unop = 1 ↔ a = 1 :=
   unop_injective.eq_iff' rfl
 
 attribute [nolint simpComm] AddOpposite.unop_eq_zero_iff
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem op_eq_one_iff [One α] (a : α) : op a = 1 ↔ a = 1 :=
   op_injective.eq_iff' rfl
 
feat: already synchronized with mathlib3 #17955 (#1379)

Currently we get a diff between the ported version and HEAD in mathlib. This corresponding change, i.e. https://github.com/leanprover-community/mathlib/pull/17955 is already present in mathlib4, since they were discovered when porting. Hence we update the hash and remove the corresponding porting comment.

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Kenny Lau
 
 ! This file was ported from Lean 3 source module algebra.opposites
-! leanprover-community/mathlib commit d6aae1bcbd04b8de2022b9b83a5b5b10e10c777d
+! leanprover-community/mathlib commit 7a89b1aed52bcacbcc4a8ad515e72c5c07268940
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -360,12 +360,9 @@ theorem op_div [Div α] (a b : α) : op (a / b) = op a / op b :=
   rfl
 #align add_opposite.op_div AddOpposite.op_div
 
--- porting note: this lemma looked wrong to me -- is it wrong in mathlib3?
--- The types of a and b were α not αᵃᵒᵖ.
 @[simp]
 theorem unop_div [Div α] (a b : αᵃᵒᵖ) : unop (a / b) = unop a / unop b :=
   rfl
 #align add_opposite.unop_div AddOpposite.unop_div
 
 end AddOpposite
-#lint
feat: make MulOpposite and AddOpposite structures (#1036)

This refactor makes αᵐᵒᵖ and αᵃᵒᵖ into structures with one field, an idea more appropriate in Lean 4 than the Lean 3 approach of type synonyms.

Diff
@@ -32,6 +32,13 @@ from `α` to `αᵃᵒᵖ`.
 * `αᵐᵒᵖ = MulOpposite α`
 * `αᵃᵒᵖ = AddOpposite α`
 
+## Implementation notes
+
+In mathlib3 `αᵐᵒᵖ` was just a type synonym for `α`, marked irreducible after the API
+was developed. In mathlib4 we use a structure with one field, because it is not possible
+to change the reducibility of a declaration after its definition, and because Lean 4 has
+definitional eta reduction for structures (Lean 3 does not).
+
 ## Tags
 
 multiplicative opposite, additive opposite
@@ -44,11 +51,24 @@ open Function
 
 /-- Multiplicative opposite of a type. This type inherits all additive structures on `α` and
 reverses left and right in multiplication.-/
-@[to_additive
-      "Additive opposite of a type. This type inherits all multiplicative structures on
-      `α` and reverses left and right in addition."]
-def MulOpposite (α : Type u) : Type u :=
-  α
+structure MulOpposite (α : Type u) : Type u where
+  /-- The element of `MulOpposite α` that represents `x : α`. -/ op ::
+  /-- The element of `α` represented by `x : αᵐᵒᵖ`. -/ unop : α
+#align mul_opposite.op MulOpposite.op
+
+-- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
+-- both tagged with it in mathlib3
+
+/-- Additive opposite of a type. This type inherits all multiplicative structures on
+      `α` and reverses left and right in addition. -/
+structure AddOpposite (α : Type u) : Type u where
+  /-- The element of `αᵃᵒᵖ` that represents `x : α`. -/ op ::
+  /-- The element of `α` represented by `x : αᵃᵒᵖ`. -/ unop : α
+
+-- porting note: the attribute `pp_nodot` does not exist yet; `op` and `unop` were
+-- both tagged with it in mathlib3
+
+attribute [to_additive] MulOpposite
 
 /-- Multiplicative opposite of a type. -/
 postfix:max "ᵐᵒᵖ" => MulOpposite
@@ -58,23 +78,9 @@ postfix:max "ᵃᵒᵖ" => AddOpposite
 
 namespace MulOpposite
 
-/-- The element of `MulOpposite α` that represents `x : α`. -/
--- porting note: the attribute `pp_nodot` does not exist yet
---@[pp_nodot,
-@[to_additive "The element of `αᵃᵒᵖ` that represents `x : α`."]
-def op : α → αᵐᵒᵖ :=
-  id
-#align mul_opposite.op MulOpposite.op
-
-/-- The element of `α` represented by `x : αᵐᵒᵖ`. -/
---@[pp_nodot,
-@[to_additive "The element of `α` represented by `x : αᵃᵒᵖ`."]
-def unop : αᵐᵒᵖ → α :=
-  id
-
-@[simp, to_additive]
-theorem unop_op (x : α) : unop (op x) = x :=
-  rfl
+-- porting note: `simp` can prove this in Lean 4
+@[to_additive]
+theorem unop_op (x : α) : unop (op x) = x := rfl
 
 @[simp, to_additive]
 theorem op_unop (x : αᵐᵒᵖ) : op (unop x) = x :=
@@ -88,10 +94,10 @@ theorem op_comp_unop : (op : α → αᵐᵒᵖ) ∘ unop = id :=
 theorem unop_comp_op : (unop : αᵐᵒᵖ → α) ∘ op = id :=
   rfl
 
-/-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec`. -/
+/-- A recursor for `MulOpposite`. Use as `induction x using MulOpposite.rec'`. -/
 @[simp, to_additive "A recursor for `AddOpposite`. Use as `induction x using AddOpposite.rec`."]
-protected def rec {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
-#align mul_opposite.rec MulOpposite.rec
+protected def rec' {F : ∀ _ : αᵐᵒᵖ, Sort v} (h : ∀ X, F (op X)) : ∀ X, F X := fun X => h (unop X)
+#align mul_opposite.rec MulOpposite.rec'
 
 /-- The canonical bijection between `α` and `αᵐᵒᵖ`. -/
 @[to_additive "The canonical bijection between `α` and `αᵃᵒᵖ`.",--]
@@ -124,14 +130,16 @@ theorem unop_injective : Injective (unop : αᵐᵒᵖ → α) :=
 theorem unop_surjective : Surjective (unop : αᵐᵒᵖ → α) :=
   unop_bijective.surjective
 
-@[simp, to_additive]
-theorem op_inj {x y : α} : op x = op y ↔ x = y :=
-  op_injective.eq_iff
+-- porting note: `simp` can prove this
+@[to_additive]
+theorem op_inj {x y : α} : op x = op y ↔ x = y := by simp
 
-@[simp, to_additive]
+@[simp, nolint simpComm, to_additive]
 theorem unop_inj {x y : αᵐᵒᵖ} : unop x = unop y ↔ x = y :=
   unop_injective.eq_iff
 
+attribute [nolint simpComm] AddOpposite.unop_inj
+
 variable (α)
 
 @[to_additive]
@@ -262,7 +270,7 @@ end
 
 variable {α}
 
-@[simp]
+@[simp, nolint simpComm]
 theorem unop_eq_zero_iff [Zero α] (a : αᵐᵒᵖ) : a.unop = (0 : α) ↔ a = (0 : αᵐᵒᵖ) :=
   unop_injective.eq_iff' rfl
 #align mul_opposite.unop_eq_zero_iff MulOpposite.unop_eq_zero_iff
@@ -280,10 +288,12 @@ theorem op_ne_zero_iff [Zero α] (a : α) : op a ≠ (0 : αᵐᵒᵖ) ↔ a ≠
   not_congr $ op_eq_zero_iff a
 #align mul_opposite.op_ne_zero_iff MulOpposite.op_ne_zero_iff
 
-@[simp, to_additive]
+@[simp, nolint simpComm, to_additive]
 theorem unop_eq_one_iff [One α] (a : αᵐᵒᵖ) : a.unop = 1 ↔ a = 1 :=
   unop_injective.eq_iff' rfl
 
+attribute [nolint simpComm] AddOpposite.unop_eq_zero_iff
+
 @[simp, to_additive]
 theorem op_eq_one_iff [One α] (a : α) : op a = 1 ↔ a = 1 :=
   op_injective.eq_iff' rfl
@@ -314,6 +324,8 @@ theorem unop_eq_one_iff [One α] {a : αᵃᵒᵖ} : unop a = 1 ↔ a = 1 :=
   unop_injective.eq_iff' unop_one
 #align add_opposite.unop_eq_one_iff AddOpposite.unop_eq_one_iff
 
+attribute [nolint simpComm] unop_eq_one_iff
+
 instance [Mul α] : Mul αᵃᵒᵖ where mul a b := op (unop a * unop b)
 
 @[simp]
@@ -348,9 +360,12 @@ theorem op_div [Div α] (a b : α) : op (a / b) = op a / op b :=
   rfl
 #align add_opposite.op_div AddOpposite.op_div
 
+-- porting note: this lemma looked wrong to me -- is it wrong in mathlib3?
+-- The types of a and b were α not αᵃᵒᵖ.
 @[simp]
-theorem unop_div [Div α] (a b : α) : unop (a / b) = unop a / unop b :=
+theorem unop_div [Div α] (a b : αᵃᵒᵖ) : unop (a / b) = unop a / unop b :=
   rfl
 #align add_opposite.unop_div AddOpposite.unop_div
 
 end AddOpposite
+#lint
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) 2018 Kenny Lau. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Kenny Lau
+
+! This file was ported from Lean 3 source module algebra.opposites
+! leanprover-community/mathlib commit d6aae1bcbd04b8de2022b9b83a5b5b10e10c777d
+! 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.Equiv.Defs

Dependencies 14

15 files ported (100.0%)
6433 lines ported (100.0%)

All dependencies are ported!