algebra.category.Group.injectiveMathlib.Algebra.Category.GroupCat.Injective

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)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(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)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2022 Jujian Zhang. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
 -/
-import Algebra.Category.Group.EpiMono
-import Algebra.Category.Module.EpiMono
+import Algebra.Category.GroupCat.EpiMono
+import Algebra.Category.ModuleCat.EpiMono
 import Algebra.Module.Injective
 import CategoryTheory.Preadditive.Injective
 import GroupTheory.Divisible
Diff
@@ -52,7 +52,7 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
           simp only [CategoryTheory.comp_apply, LinearMap.toAddMonoidHom_coe]
           simpa only [ModuleCat.coe_comp, LinearMap.coe_mk, Function.comp_apply] using
             DFunLike.congr_fun eq1 x
-        rw [cancel_mono] at eq2 
+        rw [cancel_mono] at eq2
         ext; simpa only using DFunLike.congr_fun eq2 x
       refine' ⟨(injective.factor_thru G F).toAddMonoidHom, _⟩
       ext; convert DFunLike.congr_fun (injective.comp_factor_thru G F) x }
@@ -97,7 +97,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
             simp only [map_zero, add_zero]
           · intro n1 n2
             simp only [map_zero, smul_zero]
-          · rw [submodule.span_singleton_eq_bot.mpr rfl, Submodule.mem_bot] at hn 
+          · rw [submodule.span_singleton_eq_bot.mpr rfl, Submodule.mem_bot] at hn
             simp only [hn, map_zero]
             symm
             convert map_zero _
@@ -111,7 +111,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
           · intro n1 n2; simp only [add_smul]
           · intro n1 n2
             rw [RingHom.id_apply, smul_eq_mul, mul_smul]
-          · rw [Submodule.mem_span_singleton] at hn 
+          · rw [Submodule.mem_span_singleton] at hn
             rcases hn with ⟨n, rfl⟩
             simp only [gm_eq, Algebra.id.smul_eq_mul, LinearMap.coe_mk]
             rw [mul_smul, DivisibleBy.div_cancel (g ⟨m, _⟩) m_eq_zero, ← LinearMap.map_smul]
Diff
@@ -51,11 +51,11 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
           ext
           simp only [CategoryTheory.comp_apply, LinearMap.toAddMonoidHom_coe]
           simpa only [ModuleCat.coe_comp, LinearMap.coe_mk, Function.comp_apply] using
-            FunLike.congr_fun eq1 x
+            DFunLike.congr_fun eq1 x
         rw [cancel_mono] at eq2 
-        ext; simpa only using FunLike.congr_fun eq2 x
+        ext; simpa only using DFunLike.congr_fun eq2 x
       refine' ⟨(injective.factor_thru G F).toAddMonoidHom, _⟩
-      ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
+      ext; convert DFunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
 
 theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGroupCat)] :
@@ -75,7 +75,7 @@ theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGrou
           convert zero_smul _ x
         · simp only [add_smul, map_add, hn, one_smul]
         · simp only [sub_smul, map_sub, hn, one_smul]
-      ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
+      ext; convert DFunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Ab
 
 #print AddCommGroupCat.injective_of_divisible /-
Diff
@@ -3,12 +3,12 @@ Copyright (c) 2022 Jujian Zhang. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
 -/
-import Mathbin.Algebra.Category.Group.EpiMono
-import Mathbin.Algebra.Category.Module.EpiMono
-import Mathbin.Algebra.Module.Injective
-import Mathbin.CategoryTheory.Preadditive.Injective
-import Mathbin.GroupTheory.Divisible
-import Mathbin.RingTheory.PrincipalIdealDomain
+import Algebra.Category.Group.EpiMono
+import Algebra.Category.Module.EpiMono
+import Algebra.Module.Injective
+import CategoryTheory.Preadditive.Injective
+import GroupTheory.Divisible
+import RingTheory.PrincipalIdealDomain
 
 #align_import algebra.category.Group.injective from "leanprover-community/mathlib"@"dbdf71cee7bb20367cb7e37279c08b0c218cf967"
 
Diff
@@ -34,7 +34,6 @@ variable (A : Type u) [AddCommGroup A]
 
 namespace AddCommGroupCat
 
-#print AddCommGroupCat.injective_of_injective_as_module /-
 theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
     CategoryTheory.Injective (⟨A⟩ : AddCommGroupCat) :=
   {
@@ -58,9 +57,7 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
       refine' ⟨(injective.factor_thru G F).toAddMonoidHom, _⟩
       ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
--/
 
-#print AddCommGroupCat.injective_as_module_of_injective_as_Ab /-
 theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGroupCat)] :
     Injective (⟨A⟩ : ModuleCat ℤ) :=
   {
@@ -80,7 +77,6 @@ theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGrou
         · simp only [sub_smul, map_sub, hn, one_smul]
       ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Ab
--/
 
 #print AddCommGroupCat.injective_of_divisible /-
 instance injective_of_divisible [DivisibleBy A ℤ] :
Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2022 Jujian Zhang. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
-
-! This file was ported from Lean 3 source module algebra.category.Group.injective
-! leanprover-community/mathlib commit dbdf71cee7bb20367cb7e37279c08b0c218cf967
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Algebra.Category.Group.EpiMono
 import Mathbin.Algebra.Category.Module.EpiMono
@@ -15,6 +10,8 @@ import Mathbin.CategoryTheory.Preadditive.Injective
 import Mathbin.GroupTheory.Divisible
 import Mathbin.RingTheory.PrincipalIdealDomain
 
+#align_import algebra.category.Group.injective from "leanprover-community/mathlib"@"dbdf71cee7bb20367cb7e37279c08b0c218cf967"
+
 /-!
 # Injective objects in the category of abelian groups
 
Diff
@@ -37,6 +37,7 @@ variable (A : Type u) [AddCommGroup A]
 
 namespace AddCommGroupCat
 
+#print AddCommGroupCat.injective_of_injective_as_module /-
 theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
     CategoryTheory.Injective (⟨A⟩ : AddCommGroupCat) :=
   {
@@ -60,7 +61,9 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
       refine' ⟨(injective.factor_thru G F).toAddMonoidHom, _⟩
       ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
+-/
 
+#print AddCommGroupCat.injective_as_module_of_injective_as_Ab /-
 theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGroupCat)] :
     Injective (⟨A⟩ : ModuleCat ℤ) :=
   {
@@ -80,6 +83,7 @@ theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGrou
         · simp only [sub_smul, map_sub, hn, one_smul]
       ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Ab
+-/
 
 #print AddCommGroupCat.injective_of_divisible /-
 instance injective_of_divisible [DivisibleBy A ℤ] :
Diff
@@ -43,9 +43,9 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
     Factors := fun X Y g f m => by
       skip
       let G : (⟨X⟩ : ModuleCat ℤ) ⟶ ⟨A⟩ :=
-        { g with map_smul' := by intros ; rw [RingHom.id_apply, g.to_fun_eq_coe, map_zsmul] }
+        { g with map_smul' := by intros; rw [RingHom.id_apply, g.to_fun_eq_coe, map_zsmul] }
       let F : (⟨X⟩ : ModuleCat ℤ) ⟶ ⟨Y⟩ :=
-        { f with map_smul' := by intros ; rw [RingHom.id_apply, f.to_fun_eq_coe, map_zsmul] }
+        { f with map_smul' := by intros; rw [RingHom.id_apply, f.to_fun_eq_coe, map_zsmul] }
       have : mono F := by
         refine' ⟨fun Z α β eq1 => _⟩
         let α' : AddCommGroupCat.of Z ⟶ X := α.to_add_monoid_hom
@@ -55,7 +55,7 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
           simp only [CategoryTheory.comp_apply, LinearMap.toAddMonoidHom_coe]
           simpa only [ModuleCat.coe_comp, LinearMap.coe_mk, Function.comp_apply] using
             FunLike.congr_fun eq1 x
-        rw [cancel_mono] at eq2
+        rw [cancel_mono] at eq2 
         ext; simpa only using FunLike.congr_fun eq2 x
       refine' ⟨(injective.factor_thru G F).toAddMonoidHom, _⟩
       ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
@@ -100,7 +100,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
             simp only [map_zero, add_zero]
           · intro n1 n2
             simp only [map_zero, smul_zero]
-          · rw [submodule.span_singleton_eq_bot.mpr rfl, Submodule.mem_bot] at hn
+          · rw [submodule.span_singleton_eq_bot.mpr rfl, Submodule.mem_bot] at hn 
             simp only [hn, map_zero]
             symm
             convert map_zero _
@@ -114,7 +114,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
           · intro n1 n2; simp only [add_smul]
           · intro n1 n2
             rw [RingHom.id_apply, smul_eq_mul, mul_smul]
-          · rw [Submodule.mem_span_singleton] at hn
+          · rw [Submodule.mem_span_singleton] at hn 
             rcases hn with ⟨n, rfl⟩
             simp only [gm_eq, Algebra.id.smul_eq_mul, LinearMap.coe_mk]
             rw [mul_smul, DivisibleBy.div_cancel (g ⟨m, _⟩) m_eq_zero, ← LinearMap.map_smul]
Diff
@@ -29,7 +29,7 @@ groups.
 
 open CategoryTheory
 
-open Pointwise
+open scoped Pointwise
 
 universe u
 
Diff
@@ -37,12 +37,6 @@ variable (A : Type u) [AddCommGroup A]
 
 namespace AddCommGroupCat
 
-/- warning: AddCommGroup.injective_of_injective_as_module -> AddCommGroupCat.injective_of_injective_as_module is a dubious translation:
-lean 3 declaration is
-  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.ring) (ModuleCat.moduleCategory.{u1, 0} Int Int.ring) (ModuleCat.mk.{u1, 0} Int Int.ring A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))], CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1} AddGroupCat.Group.ToMonoid.CategoryTheory.BundledHom.parentProjection.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.CommGroup.ToGroup.CategoryTheory.BundledHom.parentProjection.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A _inst_1)
-but is expected to have type
-  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.instRingInt) (ModuleCat.moduleCategory.{u1, 0} Int Int.instRingInt) (ModuleCat.mk.{u1, 0} Int Int.instRingInt A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))], CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h)) AddGroupCat.instParentProjectionTypeAddMonoidAddGroupToAddMonoidToSubNegAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.instParentProjectionTypeAddGroupAddCommGroupToAddGroup.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A (inferInstance.{succ u1} (AddCommGroup.{u1} A) _inst_1))
-Case conversion may be inaccurate. Consider using '#align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_moduleₓ'. -/
 theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
     CategoryTheory.Injective (⟨A⟩ : AddCommGroupCat) :=
   {
@@ -67,12 +61,6 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
       ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
 
-/- warning: AddCommGroup.injective_as_module_of_injective_as_Ab -> AddCommGroupCat.injective_as_module_of_injective_as_Ab is a dubious translation:
-lean 3 declaration is
-  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1} AddGroupCat.Group.ToMonoid.CategoryTheory.BundledHom.parentProjection.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.CommGroup.ToGroup.CategoryTheory.BundledHom.parentProjection.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A _inst_1)], CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.ring) (ModuleCat.moduleCategory.{u1, 0} Int Int.ring) (ModuleCat.mk.{u1, 0} Int Int.ring A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))
-but is expected to have type
-  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h)) AddGroupCat.instParentProjectionTypeAddMonoidAddGroupToAddMonoidToSubNegAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.instParentProjectionTypeAddGroupAddCommGroupToAddGroup.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A (inferInstance.{succ u1} (AddCommGroup.{u1} A) _inst_1))], CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.instRingInt) (ModuleCat.moduleCategory.{u1, 0} Int Int.instRingInt) (ModuleCat.mk.{u1, 0} Int Int.instRingInt A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))
-Case conversion may be inaccurate. Consider using '#align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Abₓ'. -/
 theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGroupCat)] :
     Injective (⟨A⟩ : ModuleCat ℤ) :=
   {
Diff
@@ -49,15 +49,9 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
     Factors := fun X Y g f m => by
       skip
       let G : (⟨X⟩ : ModuleCat ℤ) ⟶ ⟨A⟩ :=
-        { g with
-          map_smul' := by
-            intros
-            rw [RingHom.id_apply, g.to_fun_eq_coe, map_zsmul] }
+        { g with map_smul' := by intros ; rw [RingHom.id_apply, g.to_fun_eq_coe, map_zsmul] }
       let F : (⟨X⟩ : ModuleCat ℤ) ⟶ ⟨Y⟩ :=
-        { f with
-          map_smul' := by
-            intros
-            rw [RingHom.id_apply, f.to_fun_eq_coe, map_zsmul] }
+        { f with map_smul' := by intros ; rw [RingHom.id_apply, f.to_fun_eq_coe, map_zsmul] }
       have : mono F := by
         refine' ⟨fun Z α β eq1 => _⟩
         let α' : AddCommGroupCat.of Z ⟶ X := α.to_add_monoid_hom
@@ -68,11 +62,9 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
           simpa only [ModuleCat.coe_comp, LinearMap.coe_mk, Function.comp_apply] using
             FunLike.congr_fun eq1 x
         rw [cancel_mono] at eq2
-        ext
-        simpa only using FunLike.congr_fun eq2 x
+        ext; simpa only using FunLike.congr_fun eq2 x
       refine' ⟨(injective.factor_thru G F).toAddMonoidHom, _⟩
-      ext
-      convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
+      ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
 
 /- warning: AddCommGroup.injective_as_module_of_injective_as_Ab -> AddCommGroupCat.injective_as_module_of_injective_as_Ab is a dubious translation:
@@ -88,21 +80,17 @@ theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGrou
       skip
       let G : (⟨X⟩ : AddCommGroupCat) ⟶ ⟨A⟩ := g.to_add_monoid_hom
       let F : (⟨X⟩ : AddCommGroupCat) ⟶ ⟨Y⟩ := f.to_add_monoid_hom
-      have : mono F := by
-        rw [mono_iff_injective]
-        intro _ _ h
+      have : mono F := by rw [mono_iff_injective]; intro _ _ h;
         exact ((ModuleCat.mono_iff_injective f).mp m) h
       refine' ⟨{ injective.factor_thru G F with map_smul' := _ }, _⟩
-      · intro m x
-        rw [AddMonoidHom.toFun_eq_coe, RingHom.id_apply]
+      · intro m x; rw [AddMonoidHom.toFun_eq_coe, RingHom.id_apply]
         induction' m using Int.induction_on with n hn n hn
         · rw [zero_smul]
           convert map_zero _
           convert zero_smul _ x
         · simp only [add_smul, map_add, hn, one_smul]
         · simp only [sub_smul, map_sub, hn, one_smul]
-      ext
-      convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
+      ext; convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Ab
 
 #print AddCommGroupCat.injective_of_divisible /-
@@ -119,8 +107,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
             ⟨{  toFun := _
                 map_add' := _
                 map_smul' := _ }, fun n hn => _⟩
-          · intro n
-            exact g 0
+          · intro n; exact g 0
           · intro n1 n2
             simp only [map_zero, add_zero]
           · intro n1 n2
@@ -136,8 +123,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
                 map_smul' := _ }, fun n hn => _⟩
           · intro n
             exact n • DivisibleBy.div gₘ m
-          · intro n1 n2
-            simp only [add_smul]
+          · intro n1 n2; simp only [add_smul]
           · intro n1 n2
             rw [RingHom.id_apply, smul_eq_mul, mul_smul]
           · rw [Submodule.mem_span_singleton] at hn
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
 
 ! This file was ported from Lean 3 source module algebra.category.Group.injective
-! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a
+! leanprover-community/mathlib commit dbdf71cee7bb20367cb7e37279c08b0c218cf967
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -18,6 +18,9 @@ import Mathbin.RingTheory.PrincipalIdealDomain
 /-!
 # Injective objects in the category of abelian groups
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 In this file we prove that divisible groups are injective object in category of (additive) abelian
 groups.
 
Diff
@@ -34,6 +34,12 @@ variable (A : Type u) [AddCommGroup A]
 
 namespace AddCommGroupCat
 
+/- warning: AddCommGroup.injective_of_injective_as_module -> AddCommGroupCat.injective_of_injective_as_module is a dubious translation:
+lean 3 declaration is
+  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.ring) (ModuleCat.moduleCategory.{u1, 0} Int Int.ring) (ModuleCat.mk.{u1, 0} Int Int.ring A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))], CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1} AddGroupCat.Group.ToMonoid.CategoryTheory.BundledHom.parentProjection.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.CommGroup.ToGroup.CategoryTheory.BundledHom.parentProjection.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A _inst_1)
+but is expected to have type
+  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.instRingInt) (ModuleCat.moduleCategory.{u1, 0} Int Int.instRingInt) (ModuleCat.mk.{u1, 0} Int Int.instRingInt A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))], CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h)) AddGroupCat.instParentProjectionTypeAddMonoidAddGroupToAddMonoidToSubNegAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.instParentProjectionTypeAddGroupAddCommGroupToAddGroup.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A (inferInstance.{succ u1} (AddCommGroup.{u1} A) _inst_1))
+Case conversion may be inaccurate. Consider using '#align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_moduleₓ'. -/
 theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
     CategoryTheory.Injective (⟨A⟩ : AddCommGroupCat) :=
   {
@@ -66,6 +72,12 @@ theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
       convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
 
+/- warning: AddCommGroup.injective_as_module_of_injective_as_Ab -> AddCommGroupCat.injective_as_module_of_injective_as_Ab is a dubious translation:
+lean 3 declaration is
+  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) AddGroup.toAddMonoid.{u1} AddGroupCat.Group.ToMonoid.CategoryTheory.BundledHom.parentProjection.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.CommGroup.ToGroup.CategoryTheory.BundledHom.parentProjection.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A _inst_1)], CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.ring) (ModuleCat.moduleCategory.{u1, 0} Int Int.ring) (ModuleCat.mk.{u1, 0} Int Int.ring A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))
+but is expected to have type
+  forall (A : Type.{u1}) [_inst_1 : AddCommGroup.{u1} A] [_inst_2 : CategoryTheory.Injective.{u1, succ u1} (CategoryTheory.Bundled.{u1, u1} AddCommGroup.{u1}) (CategoryTheory.BundledHom.category.{u1} AddCommGroup.{u1} (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1}) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (CategoryTheory.BundledHom.MapHom.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h))) (CategoryTheory.BundledHom.bundledHomOfParentProjection.{u1} (fun (α : Type.{u1}) => AddMonoid.{u1} α) AddMonCat.AssocAddMonoidHom.{u1, u1} AddMonCat.bundledHom.{u1} (fun (α : Type.{u1}) => AddGroup.{u1} α) (fun {α : Type.{u1}} (h : AddGroup.{u1} α) => SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α h)) AddGroupCat.instParentProjectionTypeAddMonoidAddGroupToAddMonoidToSubNegAddMonoid.{u1}) (fun (α : Type.{u1}) => AddCommGroup.{u1} α) AddCommGroup.toAddGroup.{u1} AddCommGroupCat.instParentProjectionTypeAddGroupAddCommGroupToAddGroup.{u1})) (CategoryTheory.Bundled.mk.{u1, u1} AddCommGroup.{u1} A (inferInstance.{succ u1} (AddCommGroup.{u1} A) _inst_1))], CategoryTheory.Injective.{u1, succ u1} (ModuleCat.{u1, 0} Int Int.instRingInt) (ModuleCat.moduleCategory.{u1, 0} Int Int.instRingInt) (ModuleCat.mk.{u1, 0} Int Int.instRingInt A _inst_1 (AddCommGroup.intModule.{u1} A _inst_1))
+Case conversion may be inaccurate. Consider using '#align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Abₓ'. -/
 theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGroupCat)] :
     Injective (⟨A⟩ : ModuleCat ℤ) :=
   {
@@ -90,6 +102,7 @@ theorem injective_as_module_of_injective_as_Ab [Injective (⟨A⟩ : AddCommGrou
       convert FunLike.congr_fun (injective.comp_factor_thru G F) x }
 #align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Ab
 
+#print AddCommGroupCat.injective_of_divisible /-
 instance injective_of_divisible [DivisibleBy A ℤ] :
     CategoryTheory.Injective (⟨A⟩ : AddCommGroupCat) :=
   @injective_of_injective_as_module A _ <|
@@ -130,6 +143,7 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
             rw [mul_smul, DivisibleBy.div_cancel (g ⟨m, _⟩) m_eq_zero, ← LinearMap.map_smul]
             congr
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
+-/
 
 end AddCommGroupCat
 

Changes in mathlib4

mathlib3
mathlib4
chore: reduce proof dependencies for Nat.factors_count_eq (#12105)

This is a bit longer, partially duplicating the argument from UniqueFactorizationMonoid.multiplicity_eq_count_normalizedFactors, but it means we no longer need to depend on RingTheory.Int.Basic at this point.

The other added lemmas seem useful regardless.

Diff
@@ -5,6 +5,7 @@ Authors: Jujian Zhang
 -/
 import Mathlib.Algebra.Category.GroupCat.ZModuleEquivalence
 import Mathlib.Algebra.Module.Injective
+import Mathlib.RingTheory.PrincipalIdealDomain
 import Mathlib.Topology.Instances.AddCircle
 import Mathlib.Topology.Instances.Rat
 
feat(NumberTheory/ModularForms): Asymptotics of Jacobi theta functions (#12020)

This is a (rather boring) technical step in developing the theory of Hurwitz zeta functions: one needs to show that certain sums related to Jacobi theta series decay exponentially for large t.

Diff
@@ -71,7 +71,6 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
 
 instance injective_ratCircle : Injective <| of <| ULift.{u} <| AddCircle (1 : ℚ) :=
-  have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
   injective_of_divisible _
 
 end AddCommGroupCat
feat : rework enough-injectiveness proof of groups using character module (#8559)

For $R$-modules $M$ and $D$ where $D$ is injective, we can consider the dual module $M^\star := \mathrm{Hom}_R(M, D)$. $(\cdot^\star)$ can define a contravariant functor $R$-mod to $R$-mod by $L \mapsto L^\star$ where $L^\star f = f \circ L$ where $L \in \mathrm{Hom}_R(M, N)$ and $f \in N^\star$. This functor sends monomorphisms to epimorphisms.

For an abelian group $A$, it is useful to consider its character module in the unit rational circle. This construction appears in proof of enough-injectiveness of groups and it can be shown that a module is flat if and only if its character module is injective, reference. Hence we use Baer to relate ideals.

Also refactored enough-injectiveness of abelian groups. The refactor is not a separated PR because construction of character module needs some result from GroupCat/Injective.lean file.

Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>

Diff
@@ -3,13 +3,10 @@ Copyright (c) 2022 Jujian Zhang. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
 -/
-import Mathlib.Algebra.Category.GroupCat.EpiMono
 import Mathlib.Algebra.Category.GroupCat.ZModuleEquivalence
-import Mathlib.Algebra.Category.GroupCat.EquivalenceGroupAddGroup
 import Mathlib.Algebra.Module.Injective
 import Mathlib.Topology.Instances.AddCircle
 import Mathlib.Topology.Instances.Rat
-import Mathlib.LinearAlgebra.Isomorphisms
 
 #align_import algebra.category.Group.injective from "leanprover-community/mathlib"@"70fd9563a21e7b963887c9360bd29b2393e6225a"
 
@@ -77,109 +74,4 @@ instance injective_ratCircle : Injective <| of <| ULift.{u} <| AddCircle (1 : 
   have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
   injective_of_divisible _
 
-namespace enough_injectives_aux_proofs
-
-variable (A_ : AddCommGroupCat.{u})
-
-/-- The next term of `A`'s injective resolution is `∏_{A →+ ℚ/ℤ}, ℚ/ℤ`. -/
-def next : AddCommGroupCat.{u} := of <|
-  (A_ ⟶ of <| ULift.{u} <| AddCircle (1 : ℚ)) → ULift.{u} (AddCircle (1 : ℚ))
-
-instance : Injective <| next A_ :=
-  have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
-  injective_of_divisible _
-
-/-- The map into the next term of `A`'s injective resolution is coordinate-wise evaluation. -/
-@[simps] def toNext : A_ ⟶ next A_ where
-  toFun a i := i a
-  map_zero' := by simp only [map_zero]; rfl
-  map_add' _ _ := by simp only [map_add]; rfl
-
-variable {A_} (a : A_)
-
-lemma _root_.LinearMap.toSpanSingleton_ker :
-    LinearMap.ker (LinearMap.toSpanSingleton ℤ A_ a) = Ideal.span {(addOrderOf a : ℤ)} := by
-  ext1 x
-  rw [Ideal.mem_span_singleton, addOrderOf_dvd_iff_zsmul_eq_zero]
-  rfl
-
-/-- `ℤ ⧸ ⟨ord(a)⟩ ≃ aℤ` -/
-@[simps!] noncomputable def equivZModSpanAddOrderOf :
-    (ℤ ∙ a) ≃ₗ[ℤ] ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)} :=
-  (LinearEquiv.ofEq _ _ <| LinearMap.span_singleton_eq_range ℤ A_ a).trans <|
-    (LinearMap.quotKerEquivRange <| LinearMap.toSpanSingleton ℤ A_ a).symm.trans <|
-      Submodule.quotEquivOfEq _ _ <| LinearMap.toSpanSingleton_ker a
-
-lemma equivZModSpanAddOrderOf_apply_self :
-    equivZModSpanAddOrderOf a ⟨a, Submodule.mem_span_singleton_self a⟩ = Submodule.Quotient.mk 1 :=
-  (LinearEquiv.eq_symm_apply _).mp (one_zsmul _).symm
-
-/-- Given `n : ℕ`, the map `m ↦ m / n`. -/
-abbrev divBy (n : ℕ) : ℤ →ₗ[ℤ] AddCircle (1 : ℚ) :=
-  LinearMap.toSpanSingleton ℤ _ (QuotientAddGroup.mk (n : ℚ)⁻¹)
-
-lemma divBy_self (n : ℕ) : divBy n n = 0 := by
-  obtain rfl | h0 := eq_or_ne n 0
-  · apply map_zero
-  apply (AddCircle.coe_eq_zero_iff _).mpr ⟨1, _⟩
-  simp [mul_inv_cancel (Nat.cast_ne_zero (R := ℚ).mpr h0)]
-
-variable {a}
-
-/-- The map sending `n • a` to `n / 2` when `a` has infinite order,
-  and to `n / addOrderOf a` otherwise. -/
-@[simps!] noncomputable def toRatCircle : (ℤ ∙ a) →ₗ[ℤ] AddCircle (1 : ℚ) :=
-  let e : ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)} →ₗ[ℤ] AddCircle (1 : ℚ) :=
-    Submodule.liftQSpanSingleton _ (divBy <| if addOrderOf a = 0 then 2 else addOrderOf a) <| by
-      split_ifs with h
-      · rw [h, Nat.cast_zero, map_zero]
-      · apply divBy_self
-  e ∘ₗ equivZModSpanAddOrderOf a
-
-lemma eq_zero_of_toRatCircle_apply_self
-    (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
-  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
-  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
-    equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
-    LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
-  obtain ⟨n, hn⟩ := h
-  apply_fun Rat.den at hn
-  rw [zsmul_one, Rat.coe_int_den, Rat.inv_coe_nat_den_of_pos] at hn
-  · split_ifs at hn
-    · cases hn
-    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
-  · split_ifs with h
-    · norm_num
-    · exact Nat.pos_of_ne_zero h
-
-variable (A_)
-
-lemma toNext_inj : Function.Injective <| toNext A_ :=
-  (injective_iff_map_eq_zero _).mpr fun a h0 ↦
-    eq_zero_of_toRatCircle_apply_self <| ULift.up_injective <|
-      let f : of (ℤ ∙ a) ⟶ of (ULift.{u} <| AddCircle (1 : ℚ)) :=
-        AddMonoidHom.comp ⟨⟨ULift.up, rfl⟩, fun _ _ ↦ rfl⟩ toRatCircle.toAddMonoidHom
-      let g : of (ℤ ∙ a) ⟶ A_ := AddSubgroupClass.subtype _
-      have : Mono g := (mono_iff_injective _).mpr Subtype.val_injective
-      (DFunLike.congr_fun (Injective.comp_factorThru f g) _).symm.trans (congr_fun h0 _)
-
-/-- An injective presentation of `A`: `A → ∏_{A →+ ℚ/ℤ}, ℚ/ℤ`. -/
-@[simps] def presentation : InjectivePresentation A_ where
-  J := next A_
-  injective := inferInstance
-  f := toNext A_
-  mono := (AddCommGroupCat.mono_iff_injective _).mpr <| toNext_inj _
-
-end enough_injectives_aux_proofs
-
-instance enoughInjectives : EnoughInjectives AddCommGroupCat.{u} where
-  presentation A_ := ⟨enough_injectives_aux_proofs.presentation A_⟩
-
 end AddCommGroupCat
-
-namespace CommGroupCat
-
-instance enoughInjectives : EnoughInjectives CommGroupCat.{u} :=
-  EnoughInjectives.of_equivalence commGroupAddCommGroupEquivalence.functor
-
-end CommGroupCat
feat(Algebra/Module/Injective) : If $M$ is an injective $R$-module in some universe, it is also injective in higher universes (#8905)

This is because injective modules are Baer, and Baer modules do not concern universe levels

Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>

Diff
@@ -46,6 +46,19 @@ variable (A : Type u) [AddCommGroup A]
 
 set_option linter.uppercaseLean3 false
 
+theorem Module.Baer.of_divisible [DivisibleBy A ℤ] : Module.Baer ℤ A := fun I g ↦ by
+  rcases IsPrincipalIdealRing.principal I with ⟨m, rfl⟩
+  obtain rfl | h0 := eq_or_ne m 0
+  · refine ⟨0, fun n hn ↦ ?_⟩
+    rw [Submodule.span_zero_singleton] at hn
+    subst hn
+    exact (map_zero g).symm
+  let gₘ := g ⟨m, Submodule.subset_span (Set.mem_singleton _)⟩
+  refine ⟨LinearMap.toSpanSingleton ℤ A (DivisibleBy.div gₘ m), fun n hn ↦ ?_⟩
+  rcases Submodule.mem_span_singleton.mp hn with ⟨n, rfl⟩
+  rw [map_zsmul, LinearMap.toSpanSingleton_apply, DivisibleBy.div_cancel gₘ h0, ← map_zsmul g,
+    SetLike.mk_smul_mk]
+
 namespace AddCommGroupCat
 
 theorem injective_as_module_iff : Injective (⟨A⟩ : ModuleCat ℤ) ↔
@@ -57,19 +70,7 @@ theorem injective_as_module_iff : Injective (⟨A⟩ : ModuleCat ℤ) ↔
 instance injective_of_divisible [DivisibleBy A ℤ] :
     Injective (⟨A,inferInstance⟩ : AddCommGroupCat) :=
   (injective_as_module_iff A).mp <|
-    @Module.injective_object_of_injective_module ℤ _ A _ _ <|
-      Module.Baer.injective fun I g ↦ by
-        rcases IsPrincipalIdealRing.principal I with ⟨m, rfl⟩
-        obtain rfl | h0 := eq_or_ne m 0
-        · refine ⟨0, fun n hn ↦ ?_⟩
-          rw [Submodule.span_zero_singleton] at hn
-          subst hn
-          exact (map_zero g).symm
-        let gₘ := g ⟨m, Submodule.subset_span (Set.mem_singleton _)⟩
-        refine ⟨LinearMap.toSpanSingleton ℤ A (DivisibleBy.div gₘ m), fun n hn ↦ ?_⟩
-        rcases Submodule.mem_span_singleton.mp hn with ⟨n, rfl⟩
-        rw [map_zsmul, LinearMap.toSpanSingleton_apply, DivisibleBy.div_cancel gₘ h0, ← map_zsmul g,
-          SetLike.mk_smul_mk]
+    Module.injective_object_of_injective_module (inj := (Module.Baer.of_divisible A).injective)
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
 
 instance injective_ratCircle : Injective <| of <| ULift.{u} <| AddCircle (1 : ℚ) :=
chore(*): rename FunLike to DFunLike (#9785)

This prepares for the introduction of a non-dependent synonym of FunLike, which helps a lot with keeping #8386 readable.

This is entirely search-and-replace in 680197f combined with manual fixes in 4145626, e900597 and b8428f8. The commands that generated this change:

sed -i 's/\bFunLike\b/DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoFunLike\b/toDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/import Mathlib.Data.DFunLike/import Mathlib.Data.FunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bHom_FunLike\b/Hom_DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean     
sed -i 's/\binstFunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bfunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoo many metavariables to apply `fun_like.has_coe_to_fun`/too many metavariables to apply `DFunLike.hasCoeToFun`/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean

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

Diff
@@ -160,7 +160,7 @@ lemma toNext_inj : Function.Injective <| toNext A_ :=
         AddMonoidHom.comp ⟨⟨ULift.up, rfl⟩, fun _ _ ↦ rfl⟩ toRatCircle.toAddMonoidHom
       let g : of (ℤ ∙ a) ⟶ A_ := AddSubgroupClass.subtype _
       have : Mono g := (mono_iff_injective _).mpr Subtype.val_injective
-      (FunLike.congr_fun (Injective.comp_factorThru f g) _).symm.trans (congr_fun h0 _)
+      (DFunLike.congr_fun (Injective.comp_factorThru f g) _).symm.trans (congr_fun h0 _)
 
 /-- An injective presentation of `A`: `A → ∏_{A →+ ℚ/ℤ}, ℚ/ℤ`. -/
 @[simps] def presentation : InjectivePresentation A_ where
feat(Algebra/Category/GroupCat/Injective) : commutative multiplicative groups have enough injectives (#8819)

since commutative additive groups have enough injectives, multiplicative ones have enough injectives as well.

Diff
@@ -5,6 +5,7 @@ Authors: Jujian Zhang
 -/
 import Mathlib.Algebra.Category.GroupCat.EpiMono
 import Mathlib.Algebra.Category.GroupCat.ZModuleEquivalence
+import Mathlib.Algebra.Category.GroupCat.EquivalenceGroupAddGroup
 import Mathlib.Algebra.Module.Injective
 import Mathlib.Topology.Instances.AddCircle
 import Mathlib.Topology.Instances.Rat
@@ -21,7 +22,10 @@ groups and that the category of abelian groups has enough injective objects.
 ## Main results
 
 - `AddCommGroupCat.injective_of_divisible` : a divisible group is also an injective object.
-- `AddCommGroupCat.enoughInjectives` : the category of abelian groups has enough injectives.
+- `AddCommGroupCat.enoughInjectives` : the category of abelian groups (written additively) has
+  enough injectives.
+- `CommGroupCat.enoughInjectives` : the category of abelian group (written multiplicatively) has
+  enough injectives.
 
 ## Implementation notes
 
@@ -167,7 +171,14 @@ lemma toNext_inj : Function.Injective <| toNext A_ :=
 
 end enough_injectives_aux_proofs
 
-instance enoughInjectives : EnoughInjectives (AddCommGroupCat.{u}) where
+instance enoughInjectives : EnoughInjectives AddCommGroupCat.{u} where
   presentation A_ := ⟨enough_injectives_aux_proofs.presentation A_⟩
 
 end AddCommGroupCat
+
+namespace CommGroupCat
+
+instance enoughInjectives : EnoughInjectives CommGroupCat.{u} :=
+  EnoughInjectives.of_equivalence commGroupAddCommGroupEquivalence.functor
+
+end CommGroupCat
Revert "chore: revert #7703 (#7710)"

This reverts commit f3695eb2.

Diff
@@ -133,7 +133,8 @@ variable {a}
 
 lemma eq_zero_of_toRatCircle_apply_self
     (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
-  rw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
+  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
+  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
     equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
     LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
   obtain ⟨n, hn⟩ := h
chore: revert #7703 (#7710)

This reverts commit 26eb2b0a.

Diff
@@ -133,8 +133,7 @@ variable {a}
 
 lemma eq_zero_of_toRatCircle_apply_self
     (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
-  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
-  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
+  rw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
     equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
     LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
   obtain ⟨n, hn⟩ := h
chore: bump toolchain to v4.2.0-rc2 (#7703)

This includes all the changes from #7606.

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

Diff
@@ -133,7 +133,8 @@ variable {a}
 
 lemma eq_zero_of_toRatCircle_apply_self
     (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
-  rw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
+  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
+  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
     equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
     LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
   obtain ⟨n, hn⟩ := h
chore: tidy various files (#7359)
Diff
@@ -64,8 +64,8 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
         let gₘ := g ⟨m, Submodule.subset_span (Set.mem_singleton _)⟩
         refine ⟨LinearMap.toSpanSingleton ℤ A (DivisibleBy.div gₘ m), fun n hn ↦ ?_⟩
         rcases Submodule.mem_span_singleton.mp hn with ⟨n, rfl⟩
-        rw [map_zsmul, LinearMap.toSpanSingleton_apply, DivisibleBy.div_cancel gₘ h0, ← map_zsmul g]
-        rfl
+        rw [map_zsmul, LinearMap.toSpanSingleton_apply, DivisibleBy.div_cancel gₘ h0, ← map_zsmul g,
+          SetLike.mk_smul_mk]
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
 
 instance injective_ratCircle : Injective <| of <| ULift.{u} <| AddCircle (1 : ℚ) :=
chore(GroupCat/Injective): golf (#7204)

Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>

Diff
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
 -/
 import Mathlib.Algebra.Category.GroupCat.EpiMono
+import Mathlib.Algebra.Category.GroupCat.ZModuleEquivalence
 import Mathlib.Algebra.Module.Injective
 import Mathlib.Topology.Instances.AddCircle
 import Mathlib.Topology.Instances.Rat
@@ -43,384 +44,129 @@ set_option linter.uppercaseLean3 false
 
 namespace AddCommGroupCat
 
-theorem injective_of_injective_as_module [Injective (⟨A⟩ : ModuleCat ℤ)] :
-    CategoryTheory.Injective (⟨A,inferInstance⟩ : AddCommGroupCat) :=
-  { factors := fun {X} {Y} g f m => by
-      let G : (⟨X⟩ : ModuleCat ℤ) ⟶ ⟨A⟩ :=
-        { g with
-          map_smul' := by
-            intros
-            dsimp
-            rw [map_zsmul] }
-      let F : (⟨X⟩ : ModuleCat ℤ) ⟶ ⟨Y⟩ :=
-        { f with
-          map_smul' := by
-            intros
-            dsimp
-            rw [map_zsmul] }
-      have : Mono F := by
-        refine' ⟨fun {Z} α β eq1 => _⟩
-        -- Porting note: trouble getting to ℤ-module from ModuleCat ℤ
-        -- AddCommGroup.intModule not defeq to .isModule
-        let α' : AddCommGroupCat.of Z ⟶ X := @LinearMap.toAddMonoidHom _ _ _ _ _ _ _ _ (_) _ _ α
-        let β' : AddCommGroupCat.of Z ⟶ X := @LinearMap.toAddMonoidHom _ _ _ _ _ _ _ _ (_) _ _ β
-        have eq2 : α' ≫ f = β' ≫ f := by
-          ext x
-          simp only [CategoryTheory.comp_apply, LinearMap.toAddMonoidHom_coe]
-          simpa only [ModuleCat.coe_comp, LinearMap.coe_mk, Function.comp_apply] using
-            FunLike.congr_fun eq1 x
-        rw [cancel_mono] at eq2
-        have : ⇑α' = ⇑β' := congrArg _ eq2
-        ext x
-        apply congrFun this _
-      refine' ⟨(Injective.factorThru G F).toAddMonoidHom, _⟩
-      ext x
-      convert FunLike.congr_fun (Injective.comp_factorThru G F) x}
-#align AddCommGroup.injective_of_injective_as_module AddCommGroupCat.injective_of_injective_as_module
-
-theorem injective_as_module_of_injective_as_Ab [Injective (⟨A,inferInstance⟩ : AddCommGroupCat)] :
-    Injective (⟨A⟩ : ModuleCat ℤ) :=
-  { factors := fun {X} {Y} g f m => by
-      let G : (⟨X,inferInstance⟩ : AddCommGroupCat) ⟶ ⟨A,inferInstance⟩ :=
-        @LinearMap.toAddMonoidHom _ _ _ _ _ _ _ _ (_) _ _ g
-      let F : (⟨X,inferInstance⟩ : AddCommGroupCat) ⟶ ⟨Y,inferInstance⟩ :=
-        @LinearMap.toAddMonoidHom _ _ _ _ _ _ _ _ (_) (_) _ f
-      have : Mono F := by
-        rw [mono_iff_injective]
-        intro _ _ h
-        exact ((ModuleCat.mono_iff_injective f).mp m) h
-      refine ⟨ @LinearMap.mk _ _ _ _ _ _ _ _ _ (_) _ (Injective.factorThru G F).toAddHom ?_ , ?_⟩
-      change ∀ r, ∀ x, (Injective.factorThru G F).toFun _ = _ • (Injective.factorThru G F).toFun _
-      · intro m x
-        rw [AddMonoidHom.toFun_eq_coe, RingHom.id_apply]
-        induction' m using Int.induction_on with n hn n hn
-        · rw [zero_smul]
-          convert map_zero (M := Y) (N := A) (F := Y →+ A) _
-          -- Porting note: hell of non-defeq instances; somehow this worked
-          refine @zero_smul ℤ Y (MonoidWithZero.toZero) (AddMonoid.toZero) ?_ x
-          -- Porting note: was simp only [add_smul, map_add, hn, one_smul]
-        · conv_rhs => rw [add_smul]
-          rw [← hn, one_smul, ←map_add]
-          congr
-          convert @add_smul ℤ Y _ _ ?_ n 1 x
-          refine @one_smul ℤ Y _ ?_ x|>.symm
-          -- Porting note: was simp only [add_smul, map_add, hn, one_smul]
-        · conv_rhs => rw [sub_smul]
-          rw [← hn, one_smul, ←map_sub]
-          congr
-          convert @sub_smul ℤ Y _ _ ?_ (-n) 1 x
-          refine @one_smul ℤ Y _ ?_ x|>.symm
-      ext x
-      have := congrFun (congrArg (fun H => H.toFun) (Injective.comp_factorThru G F)) x
-      simp only [ModuleCat.coe_comp, Function.comp_apply] at this
-      apply this }
-#align AddCommGroup.injective_as_module_of_injective_as_Ab AddCommGroupCat.injective_as_module_of_injective_as_Ab
+theorem injective_as_module_iff : Injective (⟨A⟩ : ModuleCat ℤ) ↔
+    Injective (⟨A,inferInstance⟩ : AddCommGroupCat) :=
+  ((forget₂ (ModuleCat ℤ) AddCommGroupCat).asEquivalence.map_injective_iff ⟨A⟩).symm
+#noalign AddCommGroup.injective_of_injective_as_module
+#noalign AddCommGroup.injective_as_module_of_injective_as_Ab
 
 instance injective_of_divisible [DivisibleBy A ℤ] :
-    CategoryTheory.Injective (⟨A,inferInstance⟩ : AddCommGroupCat) :=
-  @injective_of_injective_as_module A _ <|
+    Injective (⟨A,inferInstance⟩ : AddCommGroupCat) :=
+  (injective_as_module_iff A).mp <|
     @Module.injective_object_of_injective_module ℤ _ A _ _ <|
-      Module.Baer.injective fun I g => by
+      Module.Baer.injective fun I g ↦ by
         rcases IsPrincipalIdealRing.principal I with ⟨m, rfl⟩
-        by_cases m_eq_zero : m = 0
-        · subst m_eq_zero
-          refine'
-            ⟨{  toFun := _
-                map_add' := _
-                map_smul' := _ }, fun n hn => _⟩
-          · intro _
-            exact g 0
-          · intro _ _
-            simp only [map_zero, add_zero]
-          · intro n1 _
-            simp only [map_zero, smul_zero]
-          · rw [Submodule.span_singleton_eq_bot.mpr rfl, Submodule.mem_bot] at hn
-            simp only [hn, map_zero]
-            symm
-            convert map_zero g
-        · set gₘ := g ⟨m, Submodule.subset_span (Set.mem_singleton _)⟩ with gm_eq
-          refine'
-            ⟨{  toFun := _
-                map_add' := _
-                map_smul' := _ }, fun n hn => _⟩
-          · intro n
-            exact n • DivisibleBy.div gₘ m
-          · intro n1 n2
-            simp only [add_smul]
-          · intro n1 n2
-            dsimp
-            rw [mul_smul]
-          · rw [Submodule.mem_span_singleton] at hn
-            rcases hn with ⟨n, rfl⟩
-            simp only [gm_eq, Algebra.id.smul_eq_mul, LinearMap.coe_mk]
-            dsimp
-            rw [mul_smul]
-            -- Porting note: used to be able to just rw [Div...]
-            have s := congrArg (fun l => n • l) <| DivisibleBy.div_cancel gₘ m_eq_zero
-            dsimp at s
-            rw [s, ← LinearMap.map_smul]
-            congr
+        obtain rfl | h0 := eq_or_ne m 0
+        · refine ⟨0, fun n hn ↦ ?_⟩
+          rw [Submodule.span_zero_singleton] at hn
+          subst hn
+          exact (map_zero g).symm
+        let gₘ := g ⟨m, Submodule.subset_span (Set.mem_singleton _)⟩
+        refine ⟨LinearMap.toSpanSingleton ℤ A (DivisibleBy.div gₘ m), fun n hn ↦ ?_⟩
+        rcases Submodule.mem_span_singleton.mp hn with ⟨n, rfl⟩
+        rw [map_zsmul, LinearMap.toSpanSingleton_apply, DivisibleBy.div_cancel gₘ h0, ← map_zsmul g]
+        rfl
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
 
-instance injective_ratCircle : CategoryTheory.Injective <| of <| ULift.{u} <| AddCircle (1 : ℚ) :=
+instance injective_ratCircle : Injective <| of <| ULift.{u} <| AddCircle (1 : ℚ) :=
   have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
-  @injective_of_divisible _ _ _
+  injective_of_divisible _
 
 namespace enough_injectives_aux_proofs
 
 variable (A_ : AddCommGroupCat.{u})
 
-/-- the next term of `A`'s injective resolution is `∏_{A → ℚ/ℤ}, ℚ/ℤ`.-/
+/-- The next term of `A`'s injective resolution is `∏_{A →+ ℚ/ℤ}, ℚ/ℤ`. -/
 def next : AddCommGroupCat.{u} := of <|
-  (A_ ⟶ of <| ULift <| AddCircle (1 : ℚ)) → AddCircle (1 : ℚ)
+  (A_ ⟶ of <| ULift.{u} <| AddCircle (1 : ℚ)) → ULift.{u} (AddCircle (1 : ℚ))
 
-instance : CategoryTheory.Injective <| next A_ :=
+instance : Injective <| next A_ :=
   have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
   injective_of_divisible _
 
-/-- the next term of `A`'s injective resolution is `∏_{A → ℚ/ℤ}, ℚ/ℤ`.-/
+/-- The map into the next term of `A`'s injective resolution is coordinate-wise evaluation. -/
 @[simps] def toNext : A_ ⟶ next A_ where
-  toFun := fun a i => (i a).down
-  map_zero' := by simp only [map_zero, ULift.zero_down]; rfl
-  map_add' := by intros; simp only [map_add]; rfl
-
-lemma toNext_inj_of_exists
-    (h : ∀ (a : A_), a ≠ 0 →
-      ∃ (f : ModuleCat.of ℤ (ℤ ∙ a) ⟶ ModuleCat.of ℤ (ULift <| AddCircle (1 : ℚ))),
-        f ⟨a, Submodule.subset_span rfl⟩ ≠ 0) :
-    Function.Injective $ toNext A_ :=
-  (injective_iff_map_eq_zero _).2 fun a h0 => not_not.1 fun ha => by
-    obtain ⟨f, hf⟩ := h a ha
-    let g : ModuleCat.of ℤ (ℤ ∙ a) ⟶ ModuleCat.of ℤ A_ := Submodule.subtype _
-    have hg : Mono g
-    · rw [ModuleCat.mono_iff_injective]
-      apply Submodule.injective_subtype
-    have i1 : CategoryTheory.Injective <| of (ULift.{u} $ AddCircle (1 : ℚ))
-    · infer_instance
-    have i2 := @injective_as_module_of_injective_as_Ab (of (ULift $ AddCircle (1 : ℚ))) _ i1
-    rw [← FunLike.congr_fun (@Injective.comp_factorThru (ModuleCat ℤ) _ _ _ _ i2 f g hg)
-      ⟨a, Submodule.mem_span_singleton_self a⟩] at hf
-    refine hf <| ULift.down_injective <| congr_fun h0
-      (@Injective.factorThru (ModuleCat ℤ) _ _ _ _ i2 f g hg).toAddMonoidHom
-
-section aux_defs
-
-variable {A_}
-variable (a : A_)
+  toFun a i := i a
+  map_zero' := by simp only [map_zero]; rfl
+  map_add' _ _ := by simp only [map_add]; rfl
+
+variable {A_} (a : A_)
 
 lemma _root_.LinearMap.toSpanSingleton_ker :
     LinearMap.ker (LinearMap.toSpanSingleton ℤ A_ a) = Ideal.span {(addOrderOf a : ℤ)} := by
   ext1 x
-  rw [Ideal.mem_span_singleton, LinearMap.mem_ker, addOrderOf_dvd_iff_zsmul_eq_zero,
-    LinearMap.toSpanSingleton_apply]
-
-/--
-ℤ ⧸ ⟨ord(a)⟩ ≃ aℤ
--/
-@[simps!] noncomputable def ZModSpanAddOrderOfEquiv :
-    (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) ≃ₗ[ℤ] ℤ ∙ a :=
-  letI e1 : (ℤ ⧸ (LinearMap.ker <| LinearMap.toSpanSingleton ℤ A_ a)) ≃ₗ[ℤ] (ℤ ∙ a) :=
-    (LinearMap.quotKerEquivRange <| LinearMap.toSpanSingleton ℤ A_ a).trans
-      (LinearEquiv.ofEq _ _ <| Eq.symm <| LinearMap.span_singleton_eq_range ℤ A_ a)
-  letI e2 : (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) ≃ₗ[ℤ]
-      (ℤ ⧸ (LinearMap.ker <| LinearMap.toSpanSingleton ℤ A_ a)) :=
-    Submodule.Quotient.equiv _ _ (LinearEquiv.refl (R := ℤ) (M := ℤ)) <| by
-      rw [LinearMap.toSpanSingleton_ker]
-      exact Submodule.map_id _
-  e2.trans e1
-
-end aux_defs
-
-/-- given `n : ℕ`, the map `m ↦ n / m`. -/
-@[simps] noncomputable def divBy (n : ℕ) : ℤ →ₗ[ℤ] AddCircle (1 : ℚ) where
-  toFun m := Quotient.mk _ <| (m : ℚ) * (n : ℚ)⁻¹
-  map_add' x y := by
-    dsimp
-    change _ = Quotient.mk _ (_ + _)
-    apply Quotient.sound'
-    rw [QuotientAddGroup.leftRel_eq, ← add_mul]
-    dsimp only
-    rw [neg_add_eq_sub, ← sub_mul]
-    simpa only [Int.cast_add, sub_self, zero_mul] using (AddSubgroup.zmultiples 1).zero_mem
-  map_smul' x y := by
-    dsimp
-    change _ = Quotient.mk _ (_ • _)
-    apply Quotient.sound'
-    rw [QuotientAddGroup.leftRel_eq]
-    dsimp only
-    rw [zsmul_eq_mul, ← mul_assoc, Int.cast_mul, neg_add_eq_sub, sub_self]
-    exact (AddSubgroup.zmultiples (1 : ℚ)).zero_mem
-
-namespace infinite_order
-
-variable {A_}
-variable {a : A_} (infinite_order : ¬IsOfFinAddOrder a)
-
-/-- the map sending `n • a` to `n/2` when `a` has infinite order-/
-@[simps!] noncomputable def toRatCircle : (ℤ ∙ a) →ₗ[ℤ] AddCircle (1 : ℚ) :=
-  let e : (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) →ₗ[ℤ] AddCircle (1 : ℚ) :=
-    Submodule.liftQSpanSingleton _ (divBy 2) <| by
-      rw [← addOrderOf_eq_zero_iff] at infinite_order
-      simp only [infinite_order, CharP.cast_eq_zero, map_zero]
-  e ∘ₗ (ZModSpanAddOrderOfEquiv a).symm.toLinearMap
-
-lemma toRatCircle_apply_self_eq_aux :
-    toRatCircle infinite_order ⟨LinearMap.toSpanSingleton ℤ A_ a 1, by
-      rw [LinearMap.toSpanSingleton_apply, one_smul]; exact Submodule.mem_span_singleton_self a⟩ =
-    Quotient.mk _ (2 : ℚ)⁻¹ := by
-  rw [toRatCircle_apply]
-  erw [LinearMap.quotKerEquivRange_symm_apply_image (LinearMap.toSpanSingleton ℤ A_ a),
-    LinearEquiv.coe_toEquiv]
-  rw [← Submodule.Quotient.equiv_refl, Submodule.Quotient.equiv_symm,
-    Submodule.Quotient.equiv_apply]
-  convert Submodule.liftQSpanSingleton_apply _ _ _ _ using 1
-  · convert (LinearMap.toSpanSingleton_ker a).symm using 1
-    exact Submodule.map_id _
-
-lemma toRatCircle_apply_self_eq :
-    toRatCircle infinite_order ⟨a, Submodule.mem_span_singleton_self a⟩ =
-    Quotient.mk _ (2 : ℚ)⁻¹ := by
-  rw [← toRatCircle_apply_self_eq_aux infinite_order]
-  simp
-
-lemma toRatCircle_apply_self_ne_zero :
-    toRatCircle infinite_order ⟨a, Submodule.mem_span_singleton_self a⟩ ≠ 0 := by
-  rw [toRatCircle_apply_self_eq infinite_order]
-  change _ ≠ Quotient.mk _ (0 : ℚ)
-  intro r
-  erw [QuotientAddGroup.mk'_eq_mk'] at r
-  obtain ⟨_, ⟨z, rfl⟩, H⟩ := r
-  simp only [zsmul_eq_mul, mul_one] at H
-  rw [add_comm, add_eq_zero_iff_eq_neg] at H
-  have ineq0 : |(z : ℚ)| < 1
-  · rw [H, abs_neg, abs_inv, inv_lt_one_iff]; right; norm_num
-  norm_cast at ineq0
-  rw [Int.abs_lt_one_iff] at ineq0
-  subst ineq0
-  norm_num at H
-
-end infinite_order
-
-namespace finite_order
-
-variable {A_}
-variable {a : A_} (finite_order : IsOfFinAddOrder a)
-
-lemma divBy_addOrderOf_addOrderOf : divBy (addOrderOf a) (addOrderOf a) = 0 := by
-  simp only [divBy_apply, Int.cast_ofNat, ne_eq, Nat.cast_eq_zero]
-  apply Quotient.sound'
-  rw [QuotientAddGroup.leftRel_eq]
-  simp only [ne_eq, Nat.cast_eq_zero, add_zero, neg_mem_iff]
-  rw [mul_inv_cancel]
-  · exact AddSubgroup.mem_zmultiples 1
-  · rw [← addOrderOf_pos_iff] at finite_order
-    norm_num
-    linarith
-
-/-- the map sending `n • a` to `n / ord(a)` when `a` has finite order. -/
+  rw [Ideal.mem_span_singleton, addOrderOf_dvd_iff_zsmul_eq_zero]
+  rfl
+
+/-- `ℤ ⧸ ⟨ord(a)⟩ ≃ aℤ` -/
+@[simps!] noncomputable def equivZModSpanAddOrderOf :
+    (ℤ ∙ a) ≃ₗ[ℤ] ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)} :=
+  (LinearEquiv.ofEq _ _ <| LinearMap.span_singleton_eq_range ℤ A_ a).trans <|
+    (LinearMap.quotKerEquivRange <| LinearMap.toSpanSingleton ℤ A_ a).symm.trans <|
+      Submodule.quotEquivOfEq _ _ <| LinearMap.toSpanSingleton_ker a
+
+lemma equivZModSpanAddOrderOf_apply_self :
+    equivZModSpanAddOrderOf a ⟨a, Submodule.mem_span_singleton_self a⟩ = Submodule.Quotient.mk 1 :=
+  (LinearEquiv.eq_symm_apply _).mp (one_zsmul _).symm
+
+/-- Given `n : ℕ`, the map `m ↦ m / n`. -/
+abbrev divBy (n : ℕ) : ℤ →ₗ[ℤ] AddCircle (1 : ℚ) :=
+  LinearMap.toSpanSingleton ℤ _ (QuotientAddGroup.mk (n : ℚ)⁻¹)
+
+lemma divBy_self (n : ℕ) : divBy n n = 0 := by
+  obtain rfl | h0 := eq_or_ne n 0
+  · apply map_zero
+  apply (AddCircle.coe_eq_zero_iff _).mpr ⟨1, _⟩
+  simp [mul_inv_cancel (Nat.cast_ne_zero (R := ℚ).mpr h0)]
+
+variable {a}
+
+/-- The map sending `n • a` to `n / 2` when `a` has infinite order,
+  and to `n / addOrderOf a` otherwise. -/
 @[simps!] noncomputable def toRatCircle : (ℤ ∙ a) →ₗ[ℤ] AddCircle (1 : ℚ) :=
-  let e : (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) →ₗ[ℤ] AddCircle (1 : ℚ) :=
-    Submodule.liftQSpanSingleton _ (divBy <| addOrderOf a) <|
-      divBy_addOrderOf_addOrderOf finite_order
-  e ∘ₗ (ZModSpanAddOrderOfEquiv a).symm.toLinearMap
-
-lemma toRatCircle_apply_self_eq_aux :
-    toRatCircle finite_order ⟨LinearMap.toSpanSingleton ℤ A_ a 1, by
-      rw [LinearMap.toSpanSingleton_apply, one_smul]; exact Submodule.mem_span_singleton_self a⟩ =
-    Quotient.mk _ (addOrderOf a : ℚ)⁻¹ := by
-  rw [toRatCircle_apply]
-  erw [LinearMap.quotKerEquivRange_symm_apply_image (LinearMap.toSpanSingleton ℤ A_ a),
-    LinearEquiv.coe_toEquiv]
-  rw [← Submodule.Quotient.equiv_refl, Submodule.Quotient.equiv_symm,
-    Submodule.Quotient.equiv_apply]
-  convert Submodule.liftQSpanSingleton_apply _ _ _ _ using 1
-  simp only [LinearMap.toSpanSingleton_apply, Eq.ndrec, id_eq, eq_mpr_eq_cast, cast_eq,
-    LinearEquiv.refl_symm, LinearEquiv.refl_toLinearMap, LinearMap.id_coe, divBy_apply,
-    Int.cast_one, one_mul]
-  · convert (LinearMap.toSpanSingleton_ker a).symm using 1
-    exact Submodule.map_id _
-
-lemma toRatCircle_apply_self_eq :
-    toRatCircle finite_order ⟨a, Submodule.mem_span_singleton_self a⟩ =
-    Quotient.mk _ (addOrderOf a : ℚ)⁻¹ := by
-  rw [← toRatCircle_apply_self_eq_aux finite_order]
-  simp
-
-lemma toRatCircle_apply_self_ne_zero (ne_zero : a ≠ 0) :
-    toRatCircle finite_order ⟨a, Submodule.mem_span_singleton_self a⟩ ≠ 0 := by
-  rw [toRatCircle_apply_self_eq finite_order]
-  change _ ≠ Quotient.mk _ (0 : ℚ)
-  intro r
-  erw [QuotientAddGroup.mk'_eq_mk'] at r
-  obtain ⟨_, ⟨z, rfl⟩, H⟩ := r
-  simp only [zsmul_eq_mul, mul_one] at H
-  -- This proof is a bit stupid:
-  -- we want to show that `ord(a)⁻¹ + z = 0` if contradiction
-  -- this should be easy because `ord(a) ∈ ℤ` is invertible in `ℚ`,
-  -- so `ord(a) = 1`, so `a = 0`, contradiction,
-  -- but I don't know how to say this.
-  replace H : addOrderOf a = 1
-  · rw [← addOrderOf_pos_iff] at finite_order
-    have eq0 : (addOrderOf a : ℚ) = -(z : ℚ)⁻¹
-    · rw [add_eq_zero_iff_eq_neg, inv_eq_iff_eq_inv] at H
-      rw [H, inv_neg]
-    have eq1 : |(addOrderOf a : ℚ)| = |(z : ℚ)|⁻¹
-    · rw [eq0, abs_neg, abs_inv]
-    have ineq0 : 1 ≤ |(addOrderOf a : ℚ)|
+  let e : ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)} →ₗ[ℤ] AddCircle (1 : ℚ) :=
+    Submodule.liftQSpanSingleton _ (divBy <| if addOrderOf a = 0 then 2 else addOrderOf a) <| by
+      split_ifs with h
+      · rw [h, Nat.cast_zero, map_zero]
+      · apply divBy_self
+  e ∘ₗ equivZModSpanAddOrderOf a
+
+lemma eq_zero_of_toRatCircle_apply_self
+    (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
+  rw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
+    equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
+    LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
+  obtain ⟨n, hn⟩ := h
+  apply_fun Rat.den at hn
+  rw [zsmul_one, Rat.coe_int_den, Rat.inv_coe_nat_den_of_pos] at hn
+  · split_ifs at hn
+    · cases hn
+    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
+  · split_ifs with h
     · norm_num
-      linarith
-    rw [eq1, le_inv, inv_one] at ineq0
-    norm_cast at ineq0
-    rw [Int.abs_le_one_iff] at ineq0
-    pick_goal 2
-    · norm_num
-    pick_goal 2
-    · simp only [abs_pos, ne_eq, Int.cast_eq_zero]
-      rintro rfl
-      simp only [Int.cast_zero, add_zero, inv_eq_zero, Nat.cast_eq_zero] at H
-      linarith only [finite_order, H]
-    obtain (rfl|rfl|rfl) := ineq0
-    · simp only [Int.cast_zero, inv_zero, neg_zero, Nat.cast_eq_zero] at eq0
-      linarith only [eq0, finite_order]
-    · simp only [Nat.abs_cast, Int.cast_one, abs_one, inv_one, Nat.cast_eq_one,
-        AddMonoid.addOrderOf_eq_one_iff] at eq1
-      exact (ne_zero eq1).elim
-    · rw [Int.cast_neg, Int.cast_one, ← sub_eq_add_neg, sub_eq_zero] at H
-      simp only [inv_eq_one, Nat.cast_eq_one, AddMonoid.addOrderOf_eq_one_iff] at H
-      exact (ne_zero H).elim
-
-  rw [AddMonoid.addOrderOf_eq_one_iff] at H
-  exact ne_zero H
-
-end finite_order
-
-lemma toNext_inj : Function.Injective $ toNext A_ := by
-  apply toNext_inj_of_exists
-  intro a ne_zero
-  by_cases order : IsOfFinAddOrder a
-  · let F := finite_order.toRatCircle order
-    refine ⟨⟨⟨ULift.up, by intros; rfl⟩, by intros; rfl⟩ ∘ₗ F, ?_⟩
-    change _ ≠ ULift.up 0
-    intro r
-    rw [LinearMap.comp_apply] at r
-    exact finite_order.toRatCircle_apply_self_ne_zero order ne_zero <| ULift.up_injective r
-  · let F := infinite_order.toRatCircle order
-    refine ⟨⟨⟨ULift.up, by intros; rfl⟩, by intros; rfl⟩ ∘ₗ F, ?_⟩
-    change _ ≠ ULift.up 0
-    intro r
-    rw [LinearMap.comp_apply] at r
-    exact infinite_order.toRatCircle_apply_self_ne_zero order <| ULift.up_injective r
-
-/-- An injective presentation of `A`: A -> ∏_{A ⟶ ℚ/ℤ}, ℚ/ℤ-/
-@[simps] def presentation : CategoryTheory.InjectivePresentation A_ where
+    · exact Nat.pos_of_ne_zero h
+
+variable (A_)
+
+lemma toNext_inj : Function.Injective <| toNext A_ :=
+  (injective_iff_map_eq_zero _).mpr fun a h0 ↦
+    eq_zero_of_toRatCircle_apply_self <| ULift.up_injective <|
+      let f : of (ℤ ∙ a) ⟶ of (ULift.{u} <| AddCircle (1 : ℚ)) :=
+        AddMonoidHom.comp ⟨⟨ULift.up, rfl⟩, fun _ _ ↦ rfl⟩ toRatCircle.toAddMonoidHom
+      let g : of (ℤ ∙ a) ⟶ A_ := AddSubgroupClass.subtype _
+      have : Mono g := (mono_iff_injective _).mpr Subtype.val_injective
+      (FunLike.congr_fun (Injective.comp_factorThru f g) _).symm.trans (congr_fun h0 _)
+
+/-- An injective presentation of `A`: `A → ∏_{A →+ ℚ/ℤ}, ℚ/ℤ`. -/
+@[simps] def presentation : InjectivePresentation A_ where
   J := next A_
   injective := inferInstance
   f := toNext A_
-  mono := (AddCommGroupCat.mono_iff_injective _).mpr $ toNext_inj _
+  mono := (AddCommGroupCat.mono_iff_injective _).mpr <| toNext_inj _
 
 end enough_injectives_aux_proofs
 
-instance enoughInjectives : CategoryTheory.EnoughInjectives (AddCommGroupCat.{u}) where
+instance enoughInjectives : EnoughInjectives (AddCommGroupCat.{u}) where
   presentation A_ := ⟨enough_injectives_aux_proofs.presentation A_⟩
 
 end AddCommGroupCat
feat : Abelian groups has enough injectives (#7157)
Diff
@@ -4,11 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
 -/
 import Mathlib.Algebra.Category.GroupCat.EpiMono
-import Mathlib.Algebra.Category.ModuleCat.EpiMono
 import Mathlib.Algebra.Module.Injective
-import Mathlib.CategoryTheory.Preadditive.Injective
-import Mathlib.GroupTheory.Divisible
-import Mathlib.RingTheory.PrincipalIdealDomain
+import Mathlib.Topology.Instances.AddCircle
+import Mathlib.Topology.Instances.Rat
+import Mathlib.LinearAlgebra.Isomorphisms
 
 #align_import algebra.category.Group.injective from "leanprover-community/mathlib"@"70fd9563a21e7b963887c9360bd29b2393e6225a"
 
@@ -16,7 +15,18 @@ import Mathlib.RingTheory.PrincipalIdealDomain
 # Injective objects in the category of abelian groups
 
 In this file we prove that divisible groups are injective object in category of (additive) abelian
-groups.
+groups and that the category of abelian groups has enough injective objects.
+
+## Main results
+
+- `AddCommGroupCat.injective_of_divisible` : a divisible group is also an injective object.
+- `AddCommGroupCat.enoughInjectives` : the category of abelian groups has enough injectives.
+
+## Implementation notes
+
+The details of the proof that the category of abelian groups has enough injectives is hidden
+inside the namespace `AddCommGroup.enough_injectives_aux_proofs`. These are not marked `private`,
+but are not supposed to be used directly.
 
 -/
 
@@ -152,4 +162,265 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
             congr
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
 
+instance injective_ratCircle : CategoryTheory.Injective <| of <| ULift.{u} <| AddCircle (1 : ℚ) :=
+  have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
+  @injective_of_divisible _ _ _
+
+namespace enough_injectives_aux_proofs
+
+variable (A_ : AddCommGroupCat.{u})
+
+/-- the next term of `A`'s injective resolution is `∏_{A → ℚ/ℤ}, ℚ/ℤ`.-/
+def next : AddCommGroupCat.{u} := of <|
+  (A_ ⟶ of <| ULift <| AddCircle (1 : ℚ)) → AddCircle (1 : ℚ)
+
+instance : CategoryTheory.Injective <| next A_ :=
+  have : Fact ((0 : ℚ) < 1) := ⟨by norm_num⟩
+  injective_of_divisible _
+
+/-- the next term of `A`'s injective resolution is `∏_{A → ℚ/ℤ}, ℚ/ℤ`.-/
+@[simps] def toNext : A_ ⟶ next A_ where
+  toFun := fun a i => (i a).down
+  map_zero' := by simp only [map_zero, ULift.zero_down]; rfl
+  map_add' := by intros; simp only [map_add]; rfl
+
+lemma toNext_inj_of_exists
+    (h : ∀ (a : A_), a ≠ 0 →
+      ∃ (f : ModuleCat.of ℤ (ℤ ∙ a) ⟶ ModuleCat.of ℤ (ULift <| AddCircle (1 : ℚ))),
+        f ⟨a, Submodule.subset_span rfl⟩ ≠ 0) :
+    Function.Injective $ toNext A_ :=
+  (injective_iff_map_eq_zero _).2 fun a h0 => not_not.1 fun ha => by
+    obtain ⟨f, hf⟩ := h a ha
+    let g : ModuleCat.of ℤ (ℤ ∙ a) ⟶ ModuleCat.of ℤ A_ := Submodule.subtype _
+    have hg : Mono g
+    · rw [ModuleCat.mono_iff_injective]
+      apply Submodule.injective_subtype
+    have i1 : CategoryTheory.Injective <| of (ULift.{u} $ AddCircle (1 : ℚ))
+    · infer_instance
+    have i2 := @injective_as_module_of_injective_as_Ab (of (ULift $ AddCircle (1 : ℚ))) _ i1
+    rw [← FunLike.congr_fun (@Injective.comp_factorThru (ModuleCat ℤ) _ _ _ _ i2 f g hg)
+      ⟨a, Submodule.mem_span_singleton_self a⟩] at hf
+    refine hf <| ULift.down_injective <| congr_fun h0
+      (@Injective.factorThru (ModuleCat ℤ) _ _ _ _ i2 f g hg).toAddMonoidHom
+
+section aux_defs
+
+variable {A_}
+variable (a : A_)
+
+lemma _root_.LinearMap.toSpanSingleton_ker :
+    LinearMap.ker (LinearMap.toSpanSingleton ℤ A_ a) = Ideal.span {(addOrderOf a : ℤ)} := by
+  ext1 x
+  rw [Ideal.mem_span_singleton, LinearMap.mem_ker, addOrderOf_dvd_iff_zsmul_eq_zero,
+    LinearMap.toSpanSingleton_apply]
+
+/--
+ℤ ⧸ ⟨ord(a)⟩ ≃ aℤ
+-/
+@[simps!] noncomputable def ZModSpanAddOrderOfEquiv :
+    (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) ≃ₗ[ℤ] ℤ ∙ a :=
+  letI e1 : (ℤ ⧸ (LinearMap.ker <| LinearMap.toSpanSingleton ℤ A_ a)) ≃ₗ[ℤ] (ℤ ∙ a) :=
+    (LinearMap.quotKerEquivRange <| LinearMap.toSpanSingleton ℤ A_ a).trans
+      (LinearEquiv.ofEq _ _ <| Eq.symm <| LinearMap.span_singleton_eq_range ℤ A_ a)
+  letI e2 : (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) ≃ₗ[ℤ]
+      (ℤ ⧸ (LinearMap.ker <| LinearMap.toSpanSingleton ℤ A_ a)) :=
+    Submodule.Quotient.equiv _ _ (LinearEquiv.refl (R := ℤ) (M := ℤ)) <| by
+      rw [LinearMap.toSpanSingleton_ker]
+      exact Submodule.map_id _
+  e2.trans e1
+
+end aux_defs
+
+/-- given `n : ℕ`, the map `m ↦ n / m`. -/
+@[simps] noncomputable def divBy (n : ℕ) : ℤ →ₗ[ℤ] AddCircle (1 : ℚ) where
+  toFun m := Quotient.mk _ <| (m : ℚ) * (n : ℚ)⁻¹
+  map_add' x y := by
+    dsimp
+    change _ = Quotient.mk _ (_ + _)
+    apply Quotient.sound'
+    rw [QuotientAddGroup.leftRel_eq, ← add_mul]
+    dsimp only
+    rw [neg_add_eq_sub, ← sub_mul]
+    simpa only [Int.cast_add, sub_self, zero_mul] using (AddSubgroup.zmultiples 1).zero_mem
+  map_smul' x y := by
+    dsimp
+    change _ = Quotient.mk _ (_ • _)
+    apply Quotient.sound'
+    rw [QuotientAddGroup.leftRel_eq]
+    dsimp only
+    rw [zsmul_eq_mul, ← mul_assoc, Int.cast_mul, neg_add_eq_sub, sub_self]
+    exact (AddSubgroup.zmultiples (1 : ℚ)).zero_mem
+
+namespace infinite_order
+
+variable {A_}
+variable {a : A_} (infinite_order : ¬IsOfFinAddOrder a)
+
+/-- the map sending `n • a` to `n/2` when `a` has infinite order-/
+@[simps!] noncomputable def toRatCircle : (ℤ ∙ a) →ₗ[ℤ] AddCircle (1 : ℚ) :=
+  let e : (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) →ₗ[ℤ] AddCircle (1 : ℚ) :=
+    Submodule.liftQSpanSingleton _ (divBy 2) <| by
+      rw [← addOrderOf_eq_zero_iff] at infinite_order
+      simp only [infinite_order, CharP.cast_eq_zero, map_zero]
+  e ∘ₗ (ZModSpanAddOrderOfEquiv a).symm.toLinearMap
+
+lemma toRatCircle_apply_self_eq_aux :
+    toRatCircle infinite_order ⟨LinearMap.toSpanSingleton ℤ A_ a 1, by
+      rw [LinearMap.toSpanSingleton_apply, one_smul]; exact Submodule.mem_span_singleton_self a⟩ =
+    Quotient.mk _ (2 : ℚ)⁻¹ := by
+  rw [toRatCircle_apply]
+  erw [LinearMap.quotKerEquivRange_symm_apply_image (LinearMap.toSpanSingleton ℤ A_ a),
+    LinearEquiv.coe_toEquiv]
+  rw [← Submodule.Quotient.equiv_refl, Submodule.Quotient.equiv_symm,
+    Submodule.Quotient.equiv_apply]
+  convert Submodule.liftQSpanSingleton_apply _ _ _ _ using 1
+  · convert (LinearMap.toSpanSingleton_ker a).symm using 1
+    exact Submodule.map_id _
+
+lemma toRatCircle_apply_self_eq :
+    toRatCircle infinite_order ⟨a, Submodule.mem_span_singleton_self a⟩ =
+    Quotient.mk _ (2 : ℚ)⁻¹ := by
+  rw [← toRatCircle_apply_self_eq_aux infinite_order]
+  simp
+
+lemma toRatCircle_apply_self_ne_zero :
+    toRatCircle infinite_order ⟨a, Submodule.mem_span_singleton_self a⟩ ≠ 0 := by
+  rw [toRatCircle_apply_self_eq infinite_order]
+  change _ ≠ Quotient.mk _ (0 : ℚ)
+  intro r
+  erw [QuotientAddGroup.mk'_eq_mk'] at r
+  obtain ⟨_, ⟨z, rfl⟩, H⟩ := r
+  simp only [zsmul_eq_mul, mul_one] at H
+  rw [add_comm, add_eq_zero_iff_eq_neg] at H
+  have ineq0 : |(z : ℚ)| < 1
+  · rw [H, abs_neg, abs_inv, inv_lt_one_iff]; right; norm_num
+  norm_cast at ineq0
+  rw [Int.abs_lt_one_iff] at ineq0
+  subst ineq0
+  norm_num at H
+
+end infinite_order
+
+namespace finite_order
+
+variable {A_}
+variable {a : A_} (finite_order : IsOfFinAddOrder a)
+
+lemma divBy_addOrderOf_addOrderOf : divBy (addOrderOf a) (addOrderOf a) = 0 := by
+  simp only [divBy_apply, Int.cast_ofNat, ne_eq, Nat.cast_eq_zero]
+  apply Quotient.sound'
+  rw [QuotientAddGroup.leftRel_eq]
+  simp only [ne_eq, Nat.cast_eq_zero, add_zero, neg_mem_iff]
+  rw [mul_inv_cancel]
+  · exact AddSubgroup.mem_zmultiples 1
+  · rw [← addOrderOf_pos_iff] at finite_order
+    norm_num
+    linarith
+
+/-- the map sending `n • a` to `n / ord(a)` when `a` has finite order. -/
+@[simps!] noncomputable def toRatCircle : (ℤ ∙ a) →ₗ[ℤ] AddCircle (1 : ℚ) :=
+  let e : (ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)}) →ₗ[ℤ] AddCircle (1 : ℚ) :=
+    Submodule.liftQSpanSingleton _ (divBy <| addOrderOf a) <|
+      divBy_addOrderOf_addOrderOf finite_order
+  e ∘ₗ (ZModSpanAddOrderOfEquiv a).symm.toLinearMap
+
+lemma toRatCircle_apply_self_eq_aux :
+    toRatCircle finite_order ⟨LinearMap.toSpanSingleton ℤ A_ a 1, by
+      rw [LinearMap.toSpanSingleton_apply, one_smul]; exact Submodule.mem_span_singleton_self a⟩ =
+    Quotient.mk _ (addOrderOf a : ℚ)⁻¹ := by
+  rw [toRatCircle_apply]
+  erw [LinearMap.quotKerEquivRange_symm_apply_image (LinearMap.toSpanSingleton ℤ A_ a),
+    LinearEquiv.coe_toEquiv]
+  rw [← Submodule.Quotient.equiv_refl, Submodule.Quotient.equiv_symm,
+    Submodule.Quotient.equiv_apply]
+  convert Submodule.liftQSpanSingleton_apply _ _ _ _ using 1
+  simp only [LinearMap.toSpanSingleton_apply, Eq.ndrec, id_eq, eq_mpr_eq_cast, cast_eq,
+    LinearEquiv.refl_symm, LinearEquiv.refl_toLinearMap, LinearMap.id_coe, divBy_apply,
+    Int.cast_one, one_mul]
+  · convert (LinearMap.toSpanSingleton_ker a).symm using 1
+    exact Submodule.map_id _
+
+lemma toRatCircle_apply_self_eq :
+    toRatCircle finite_order ⟨a, Submodule.mem_span_singleton_self a⟩ =
+    Quotient.mk _ (addOrderOf a : ℚ)⁻¹ := by
+  rw [← toRatCircle_apply_self_eq_aux finite_order]
+  simp
+
+lemma toRatCircle_apply_self_ne_zero (ne_zero : a ≠ 0) :
+    toRatCircle finite_order ⟨a, Submodule.mem_span_singleton_self a⟩ ≠ 0 := by
+  rw [toRatCircle_apply_self_eq finite_order]
+  change _ ≠ Quotient.mk _ (0 : ℚ)
+  intro r
+  erw [QuotientAddGroup.mk'_eq_mk'] at r
+  obtain ⟨_, ⟨z, rfl⟩, H⟩ := r
+  simp only [zsmul_eq_mul, mul_one] at H
+  -- This proof is a bit stupid:
+  -- we want to show that `ord(a)⁻¹ + z = 0` if contradiction
+  -- this should be easy because `ord(a) ∈ ℤ` is invertible in `ℚ`,
+  -- so `ord(a) = 1`, so `a = 0`, contradiction,
+  -- but I don't know how to say this.
+  replace H : addOrderOf a = 1
+  · rw [← addOrderOf_pos_iff] at finite_order
+    have eq0 : (addOrderOf a : ℚ) = -(z : ℚ)⁻¹
+    · rw [add_eq_zero_iff_eq_neg, inv_eq_iff_eq_inv] at H
+      rw [H, inv_neg]
+    have eq1 : |(addOrderOf a : ℚ)| = |(z : ℚ)|⁻¹
+    · rw [eq0, abs_neg, abs_inv]
+    have ineq0 : 1 ≤ |(addOrderOf a : ℚ)|
+    · norm_num
+      linarith
+    rw [eq1, le_inv, inv_one] at ineq0
+    norm_cast at ineq0
+    rw [Int.abs_le_one_iff] at ineq0
+    pick_goal 2
+    · norm_num
+    pick_goal 2
+    · simp only [abs_pos, ne_eq, Int.cast_eq_zero]
+      rintro rfl
+      simp only [Int.cast_zero, add_zero, inv_eq_zero, Nat.cast_eq_zero] at H
+      linarith only [finite_order, H]
+    obtain (rfl|rfl|rfl) := ineq0
+    · simp only [Int.cast_zero, inv_zero, neg_zero, Nat.cast_eq_zero] at eq0
+      linarith only [eq0, finite_order]
+    · simp only [Nat.abs_cast, Int.cast_one, abs_one, inv_one, Nat.cast_eq_one,
+        AddMonoid.addOrderOf_eq_one_iff] at eq1
+      exact (ne_zero eq1).elim
+    · rw [Int.cast_neg, Int.cast_one, ← sub_eq_add_neg, sub_eq_zero] at H
+      simp only [inv_eq_one, Nat.cast_eq_one, AddMonoid.addOrderOf_eq_one_iff] at H
+      exact (ne_zero H).elim
+
+  rw [AddMonoid.addOrderOf_eq_one_iff] at H
+  exact ne_zero H
+
+end finite_order
+
+lemma toNext_inj : Function.Injective $ toNext A_ := by
+  apply toNext_inj_of_exists
+  intro a ne_zero
+  by_cases order : IsOfFinAddOrder a
+  · let F := finite_order.toRatCircle order
+    refine ⟨⟨⟨ULift.up, by intros; rfl⟩, by intros; rfl⟩ ∘ₗ F, ?_⟩
+    change _ ≠ ULift.up 0
+    intro r
+    rw [LinearMap.comp_apply] at r
+    exact finite_order.toRatCircle_apply_self_ne_zero order ne_zero <| ULift.up_injective r
+  · let F := infinite_order.toRatCircle order
+    refine ⟨⟨⟨ULift.up, by intros; rfl⟩, by intros; rfl⟩ ∘ₗ F, ?_⟩
+    change _ ≠ ULift.up 0
+    intro r
+    rw [LinearMap.comp_apply] at r
+    exact infinite_order.toRatCircle_apply_self_ne_zero order <| ULift.up_injective r
+
+/-- An injective presentation of `A`: A -> ∏_{A ⟶ ℚ/ℤ}, ℚ/ℤ-/
+@[simps] def presentation : CategoryTheory.InjectivePresentation A_ where
+  J := next A_
+  injective := inferInstance
+  f := toNext A_
+  mono := (AddCommGroupCat.mono_iff_injective _).mpr $ toNext_inj _
+
+end enough_injectives_aux_proofs
+
+instance enoughInjectives : CategoryTheory.EnoughInjectives (AddCommGroupCat.{u}) where
+  presentation A_ := ⟨enough_injectives_aux_proofs.presentation A_⟩
+
 end AddCommGroupCat
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,11 +2,6 @@
 Copyright (c) 2022 Jujian Zhang. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Jujian Zhang
-
-! This file was ported from Lean 3 source module algebra.category.Group.injective
-! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Algebra.Category.GroupCat.EpiMono
 import Mathlib.Algebra.Category.ModuleCat.EpiMono
@@ -15,6 +10,8 @@ import Mathlib.CategoryTheory.Preadditive.Injective
 import Mathlib.GroupTheory.Divisible
 import Mathlib.RingTheory.PrincipalIdealDomain
 
+#align_import algebra.category.Group.injective from "leanprover-community/mathlib"@"70fd9563a21e7b963887c9360bd29b2393e6225a"
+
 /-!
 # Injective objects in the category of abelian groups
 
chore: cleanup some simp-related porting notes (#4954)

I was looking on https://github.com/leanprover-community/mathlib4/pull/4933 to see what simp related porting notes I could improve after https://github.com/leanprover/lean4/pull/2266 lands in Lean 4. Mostly things I found could be cleaned up in any case, and so I've moved those into this PR.

There is lots more work to do diagnosing all the simp-related porting notes!

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au>

Diff
@@ -156,4 +156,3 @@ instance injective_of_divisible [DivisibleBy A ℤ] :
 #align AddCommGroup.injective_of_divisible AddCommGroupCat.injective_of_divisible
 
 end AddCommGroupCat
-
feat: port Algebra.Category.Group.Injective (#3908)

Dependencies 8 + 593

594 files ported (98.7%)
233323 lines ported (98.7%)
Show graph

The unported dependencies are