group_theory.commuting_probabilityMathlib.GroupTheory.CommutingProbability

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)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -125,7 +125,7 @@ theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2
   /- After rewriting with `comm_prob_def`, we reduce to showing that `G` has at least as many
       commuting pairs as `H`. -/
   rw [commProb_def, commProb_def, div_le_iff, mul_assoc, ← mul_pow, ← Nat.cast_mul,
-    mul_comm H.index, H.card_mul_index, div_mul_cancel, Nat.cast_le]
+    mul_comm H.index, H.card_mul_index, div_mul_cancel₀, Nat.cast_le]
   · refine' Finite.card_le_of_injective (fun p => ⟨⟨p.1.1, p.1.2⟩, subtype.ext_iff.mp p.2⟩) _
     exact fun p q h => by simpa only [Subtype.ext_iff, Prod.ext_iff] using h
   · exact pow_ne_zero 2 (nat.cast_ne_zero.mpr finite.card_pos.ne')
@@ -139,7 +139,7 @@ theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commPr
   /- After rewriting with `comm_prob_def'`, we reduce to showing that `G` has at least as many
       conjugacy classes as `G ⧸ H`. -/
   rw [commProb_def', commProb_def', div_le_iff, mul_assoc, ← Nat.cast_mul, ← Subgroup.index,
-    H.card_mul_index, div_mul_cancel, Nat.cast_le]
+    H.card_mul_index, div_mul_cancel₀, Nat.cast_le]
   · apply Finite.card_le_of_surjective
     show Function.Surjective (ConjClasses.map (QuotientGroup.mk' H))
     exact ConjClasses.map_surjective Quotient.surjective_Quotient_mk''
Diff
@@ -3,11 +3,11 @@ Copyright (c) 2022 Thomas Browning. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Thomas Browning
 -/
-import Mathbin.Algebra.Group.ConjFinite
-import Mathbin.GroupTheory.Abelianization
-import Mathbin.GroupTheory.GroupAction.ConjAct
-import Mathbin.GroupTheory.GroupAction.Quotient
-import Mathbin.GroupTheory.Index
+import Algebra.Group.ConjFinite
+import GroupTheory.Abelianization
+import GroupTheory.GroupAction.ConjAct
+import GroupTheory.GroupAction.Quotient
+import GroupTheory.Index
 
 #align_import group_theory.commuting_probability from "leanprover-community/mathlib"@"23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6"
 
Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2022 Thomas Browning. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Thomas Browning
-
-! This file was ported from Lean 3 source module group_theory.commuting_probability
-! leanprover-community/mathlib commit 23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Algebra.Group.ConjFinite
 import Mathbin.GroupTheory.Abelianization
@@ -14,6 +9,8 @@ import Mathbin.GroupTheory.GroupAction.ConjAct
 import Mathbin.GroupTheory.GroupAction.Quotient
 import Mathbin.GroupTheory.Index
 
+#align_import group_theory.commuting_probability from "leanprover-community/mathlib"@"23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6"
+
 /-!
 # Commuting Probability
 
Diff
@@ -46,10 +46,12 @@ def commProb : ℚ :=
 #align comm_prob commProb
 -/
 
+#print commProb_def /-
 theorem commProb_def :
     commProb M = Nat.card { p : M × M // p.1 * p.2 = p.2 * p.1 } / Nat.card M ^ 2 :=
   rfl
 #align comm_prob_def commProb_def
+-/
 
 variable [Finite M]
 
@@ -61,12 +63,14 @@ theorem commProb_pos [h : Nonempty M] : 0 < commProb M :=
 #align comm_prob_pos commProb_pos
 -/
 
+#print commProb_le_one /-
 theorem commProb_le_one : commProb M ≤ 1 :=
   by
   refine' div_le_one_of_le _ (sq_nonneg (Nat.card M))
   rw [← Nat.cast_pow, Nat.cast_le, sq, ← Nat.card_prod]
   apply Finite.card_subtype_le
 #align comm_prob_le_one commProb_le_one
+-/
 
 variable {M}
 
@@ -84,6 +88,7 @@ theorem commProb_eq_one_iff [h : Nonempty M] : commProb M = 1 ↔ Commutative ((
 
 variable (G : Type _) [Group G] [Finite G]
 
+#print card_comm_eq_card_conjClasses_mul_card /-
 theorem card_comm_eq_card_conjClasses_mul_card :
     Nat.card { p : G × G // p.1 * p.2 = p.2 * p.1 } = Nat.card (ConjClasses G) * Nat.card G :=
   by
@@ -105,15 +110,19 @@ theorem card_comm_eq_card_conjClasses_mul_card :
           Setoid.ext fun g h => (Setoid.comm' _).trans is_conj_iff.symm
         cc
 #align card_comm_eq_card_conj_classes_mul_card card_comm_eq_card_conjClasses_mul_card
+-/
 
+#print commProb_def' /-
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G :=
   by
   rw [commProb, card_comm_eq_card_conjClasses_mul_card, Nat.cast_mul, sq]
   exact mul_div_mul_right _ _ (nat.cast_ne_zero.mpr finite.card_pos.ne')
 #align comm_prob_def' commProb_def'
+-/
 
 variable {G} (H : Subgroup G)
 
+#print Subgroup.commProb_subgroup_le /-
 theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2 :=
   by
   /- After rewriting with `comm_prob_def`, we reduce to showing that `G` has at least as many
@@ -125,7 +134,9 @@ theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2
   · exact pow_ne_zero 2 (nat.cast_ne_zero.mpr finite.card_pos.ne')
   · exact pow_pos (nat.cast_pos.mpr Finite.card_pos) 2
 #align subgroup.comm_prob_subgroup_le Subgroup.commProb_subgroup_le
+-/
 
+#print Subgroup.commProb_quotient_le /-
 theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commProb G * Nat.card H :=
   by
   /- After rewriting with `comm_prob_def'`, we reduce to showing that `G` has at least as many
@@ -138,12 +149,15 @@ theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commPr
   · exact nat.cast_ne_zero.mpr finite.card_pos.ne'
   · exact nat.cast_pos.mpr Finite.card_pos
 #align subgroup.comm_prob_quotient_le Subgroup.commProb_quotient_le
+-/
 
 variable (G)
 
+#print inv_card_commutator_le_commProb /-
 theorem inv_card_commutator_le_commProb : (↑(Nat.card (commutator G)))⁻¹ ≤ commProb G :=
   (inv_pos_le_iff_one_le_mul (nat.cast_pos.mpr Finite.card_pos)).mpr
     (le_trans (ge_of_eq (commProb_eq_one_iff.mpr (Abelianization.commGroup G).mul_comm))
       (commutator G).commProb_quotient_le)
 #align inv_card_commutator_le_comm_prob inv_card_commutator_le_commProb
+-/
 
Diff
@@ -104,7 +104,6 @@ theorem card_comm_eq_card_conjClasses_mul_card :
         have this : MulAction.orbitRel (ConjAct G) G = IsConj.setoid G :=
           Setoid.ext fun g h => (Setoid.comm' _).trans is_conj_iff.symm
         cc
-      
 #align card_comm_eq_card_conj_classes_mul_card card_comm_eq_card_conjClasses_mul_card
 
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G :=
Diff
@@ -89,7 +89,8 @@ theorem card_comm_eq_card_conjClasses_mul_card :
   by
   haveI := Fintype.ofFinite G
   simp only [Nat.card_eq_fintype_card]
-  convert calc
+  convert
+    calc
       card { p : G × G // p.1 * p.2 = p.2 * p.1 } = card (Σ g, { h // g * h = h * g }) :=
         card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G => g * h = h * g)
       _ = ∑ g, card { h // g * h = h * g } := (card_sigma _)
Diff
@@ -90,7 +90,7 @@ theorem card_comm_eq_card_conjClasses_mul_card :
   haveI := Fintype.ofFinite G
   simp only [Nat.card_eq_fintype_card]
   convert calc
-      card { p : G × G // p.1 * p.2 = p.2 * p.1 } = card (Σg, { h // g * h = h * g }) :=
+      card { p : G × G // p.1 * p.2 = p.2 * p.1 } = card (Σ g, { h // g * h = h * g }) :=
         card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G => g * h = h * g)
       _ = ∑ g, card { h // g * h = h * g } := (card_sigma _)
       _ = ∑ g, card (MulAction.fixedBy (ConjAct G) G g) :=
Diff
@@ -31,9 +31,9 @@ This file introduces the commuting probability of finite groups.
 
 noncomputable section
 
-open Classical
+open scoped Classical
 
-open BigOperators
+open scoped BigOperators
 
 open Fintype
 
@@ -53,11 +53,13 @@ theorem commProb_def :
 
 variable [Finite M]
 
+#print commProb_pos /-
 theorem commProb_pos [h : Nonempty M] : 0 < commProb M :=
   h.elim fun x =>
     div_pos (Nat.cast_pos.mpr (Finite.card_pos_iff.mpr ⟨⟨(x, x), rfl⟩⟩))
       (pow_pos (Nat.cast_pos.mpr Finite.card_pos) 2)
 #align comm_prob_pos commProb_pos
+-/
 
 theorem commProb_le_one : commProb M ≤ 1 :=
   by
Diff
@@ -46,12 +46,6 @@ def commProb : ℚ :=
 #align comm_prob commProb
 -/
 
-/- warning: comm_prob_def -> commProb_def is a dubious translation:
-lean 3 declaration is
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
-but is expected to have type
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
-Case conversion may be inaccurate. Consider using '#align comm_prob_def commProb_defₓ'. -/
 theorem commProb_def :
     commProb M = Nat.card { p : M × M // p.1 * p.2 = p.2 * p.1 } / Nat.card M ^ 2 :=
   rfl
@@ -59,24 +53,12 @@ theorem commProb_def :
 
 variable [Finite M]
 
-/- warning: comm_prob_pos -> commProb_pos is a dubious translation:
-lean 3 declaration is
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M] [_inst_2 : Finite.{succ u1} M] [h : Nonempty.{succ u1} M], LT.lt.{0} Rat Rat.hasLt (OfNat.ofNat.{0} Rat 0 (OfNat.mk.{0} Rat 0 (Zero.zero.{0} Rat Rat.hasZero))) (commProb.{u1} M _inst_1)
-but is expected to have type
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M] [_inst_2 : Finite.{succ u1} M] [h : Nonempty.{succ u1} M], LT.lt.{0} Rat Rat.instLTRat_1 (OfNat.ofNat.{0} Rat 0 (Rat.instOfNatRat 0)) (commProb.{u1} M _inst_1)
-Case conversion may be inaccurate. Consider using '#align comm_prob_pos commProb_posₓ'. -/
 theorem commProb_pos [h : Nonempty M] : 0 < commProb M :=
   h.elim fun x =>
     div_pos (Nat.cast_pos.mpr (Finite.card_pos_iff.mpr ⟨⟨(x, x), rfl⟩⟩))
       (pow_pos (Nat.cast_pos.mpr Finite.card_pos) 2)
 #align comm_prob_pos commProb_pos
 
-/- warning: comm_prob_le_one -> commProb_le_one is a dubious translation:
-lean 3 declaration is
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M] [_inst_2 : Finite.{succ u1} M], LE.le.{0} Rat Rat.hasLe (commProb.{u1} M _inst_1) (OfNat.ofNat.{0} Rat 1 (OfNat.mk.{0} Rat 1 (One.one.{0} Rat Rat.hasOne)))
-but is expected to have type
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M] [_inst_2 : Finite.{succ u1} M], LE.le.{0} Rat Rat.instLERat (commProb.{u1} M _inst_1) (OfNat.ofNat.{0} Rat 1 (Rat.instOfNatRat 1))
-Case conversion may be inaccurate. Consider using '#align comm_prob_le_one commProb_le_oneₓ'. -/
 theorem commProb_le_one : commProb M ≤ 1 :=
   by
   refine' div_le_one_of_le _ (sq_nonneg (Nat.card M))
@@ -100,12 +82,6 @@ theorem commProb_eq_one_iff [h : Nonempty M] : commProb M = 1 ↔ Commutative ((
 
 variable (G : Type _) [Group G] [Finite G]
 
-/- warning: card_comm_eq_card_conj_classes_mul_card -> card_comm_eq_card_conjClasses_mul_card is a dubious translation:
-lean 3 declaration is
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Nat (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} G G) (fun (p : Prod.{u1, u1} G G) => Eq.{succ u1} G (HMul.hMul.{u1, u1, u1} G G G (instHMul.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Prod.fst.{u1, u1} G G p) (Prod.snd.{u1, u1} G G p)) (HMul.hMul.{u1, u1, u1} G G G (instHMul.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Prod.snd.{u1, u1} G G p) (Prod.fst.{u1, u1} G G p))))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3)))) (Nat.card.{u1} G))
-but is expected to have type
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Nat (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} G G) (fun (p : Prod.{u1, u1} G G) => Eq.{succ u1} G (HMul.hMul.{u1, u1, u1} G G G (instHMul.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Prod.fst.{u1, u1} G G p) (Prod.snd.{u1, u1} G G p)) (HMul.hMul.{u1, u1, u1} G G G (instHMul.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Prod.snd.{u1, u1} G G p) (Prod.fst.{u1, u1} G G p))))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3)))) (Nat.card.{u1} G))
-Case conversion may be inaccurate. Consider using '#align card_comm_eq_card_conj_classes_mul_card card_comm_eq_card_conjClasses_mul_cardₓ'. -/
 theorem card_comm_eq_card_conjClasses_mul_card :
     Nat.card { p : G × G // p.1 * p.2 = p.2 * p.1 } = Nat.card (ConjClasses G) * Nat.card G :=
   by
@@ -128,12 +104,6 @@ theorem card_comm_eq_card_conjClasses_mul_card :
       
 #align card_comm_eq_card_conj_classes_mul_card card_comm_eq_card_conjClasses_mul_card
 
-/- warning: comm_prob_def' -> commProb_def' is a dubious translation:
-lean 3 declaration is
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} G)))
-but is expected to have type
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} G)))
-Case conversion may be inaccurate. Consider using '#align comm_prob_def' commProb_def'ₓ'. -/
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G :=
   by
   rw [commProb, card_comm_eq_card_conjClasses_mul_card, Nat.cast_mul, sq]
@@ -142,12 +112,6 @@ theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G :=
 
 variable {G} (H : Subgroup G)
 
-/- warning: subgroup.comm_prob_subgroup_le -> Subgroup.commProb_subgroup_le is a dubious translation:
-lean 3 declaration is
-  forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3), LE.le.{0} Rat Rat.hasLe (commProb.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H) (Subgroup.mul.{u1} G _inst_3 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Subgroup.index.{u1} G _inst_3 H)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
-but is expected to have type
-  forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4), LE.le.{0} Rat Rat.instLERat (commProb.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)) (Subgroup.mul.{u1} G _inst_4 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Subgroup.index.{u1} G _inst_4 H)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
-Case conversion may be inaccurate. Consider using '#align subgroup.comm_prob_subgroup_le Subgroup.commProb_subgroup_leₓ'. -/
 theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2 :=
   by
   /- After rewriting with `comm_prob_def`, we reduce to showing that `G` has at least as many
@@ -160,12 +124,6 @@ theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2
   · exact pow_pos (nat.cast_pos.mpr Finite.card_pos) 2
 #align subgroup.comm_prob_subgroup_le Subgroup.commProb_subgroup_le
 
-/- warning: subgroup.comm_prob_quotient_le -> Subgroup.commProb_quotient_le is a dubious translation:
-lean 3 declaration is
-  forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3) [_inst_5 : Subgroup.Normal.{u1} G _inst_3 H], LE.le.{0} Rat Rat.hasLe (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (MulOneClass.toHasMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (QuotientGroup.Quotient.group.{u1} G _inst_3 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H))))
-but is expected to have type
-  forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4) [_inst_5 : Subgroup.Normal.{u1} G _inst_4 H], LE.le.{0} Rat Rat.instLERat (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (MulOneClass.toMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (QuotientGroup.Quotient.group.{u1} G _inst_4 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)))))
-Case conversion may be inaccurate. Consider using '#align subgroup.comm_prob_quotient_le Subgroup.commProb_quotient_leₓ'. -/
 theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commProb G * Nat.card H :=
   by
   /- After rewriting with `comm_prob_def'`, we reduce to showing that `G` has at least as many
@@ -181,12 +139,6 @@ theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commPr
 
 variable (G)
 
-/- warning: inv_card_commutator_le_comm_prob -> inv_card_commutator_le_commProb is a dubious translation:
-lean 3 declaration is
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], LE.le.{0} Rat Rat.hasLe (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) (commutator.{u1} G _inst_3))))) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3)))))
-but is expected to have type
-  forall (G : Type.{u1}) [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G], LE.le.{0} Rat Rat.instLERat (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x (commutator.{u1} G _inst_4)))))) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4)))))
-Case conversion may be inaccurate. Consider using '#align inv_card_commutator_le_comm_prob inv_card_commutator_le_commProbₓ'. -/
 theorem inv_card_commutator_le_commProb : (↑(Nat.card (commutator G)))⁻¹ ≤ commProb G :=
   (inv_pos_le_iff_one_le_mul (nat.cast_pos.mpr Finite.card_pos)).mpr
     (le_trans (ge_of_eq (commProb_eq_one_iff.mpr (Abelianization.commGroup G).mul_comm))
Diff
@@ -59,13 +59,17 @@ theorem commProb_def :
 
 variable [Finite M]
 
-#print commProb_pos /-
+/- warning: comm_prob_pos -> commProb_pos is a dubious translation:
+lean 3 declaration is
+  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M] [_inst_2 : Finite.{succ u1} M] [h : Nonempty.{succ u1} M], LT.lt.{0} Rat Rat.hasLt (OfNat.ofNat.{0} Rat 0 (OfNat.mk.{0} Rat 0 (Zero.zero.{0} Rat Rat.hasZero))) (commProb.{u1} M _inst_1)
+but is expected to have type
+  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M] [_inst_2 : Finite.{succ u1} M] [h : Nonempty.{succ u1} M], LT.lt.{0} Rat Rat.instLTRat_1 (OfNat.ofNat.{0} Rat 0 (Rat.instOfNatRat 0)) (commProb.{u1} M _inst_1)
+Case conversion may be inaccurate. Consider using '#align comm_prob_pos commProb_posₓ'. -/
 theorem commProb_pos [h : Nonempty M] : 0 < commProb M :=
   h.elim fun x =>
     div_pos (Nat.cast_pos.mpr (Finite.card_pos_iff.mpr ⟨⟨(x, x), rfl⟩⟩))
       (pow_pos (Nat.cast_pos.mpr Finite.card_pos) 2)
 #align comm_prob_pos commProb_pos
--/
 
 /- warning: comm_prob_le_one -> commProb_le_one is a dubious translation:
 lean 3 declaration is
Diff
@@ -50,7 +50,7 @@ def commProb : ℚ :=
 lean 3 declaration is
   forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
 but is expected to have type
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
+  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
 Case conversion may be inaccurate. Consider using '#align comm_prob_def commProb_defₓ'. -/
 theorem commProb_def :
     commProb M = Nat.card { p : M × M // p.1 * p.2 = p.2 * p.1 } / Nat.card M ^ 2 :=
@@ -128,7 +128,7 @@ theorem card_comm_eq_card_conjClasses_mul_card :
 lean 3 declaration is
   forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} G)))
 but is expected to have type
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} G)))
+  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} G)))
 Case conversion may be inaccurate. Consider using '#align comm_prob_def' commProb_def'ₓ'. -/
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G :=
   by
@@ -142,7 +142,7 @@ variable {G} (H : Subgroup G)
 lean 3 declaration is
   forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3), LE.le.{0} Rat Rat.hasLe (commProb.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H) (Subgroup.mul.{u1} G _inst_3 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Subgroup.index.{u1} G _inst_3 H)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
 but is expected to have type
-  forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4), LE.le.{0} Rat Rat.instLERat (commProb.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)) (Subgroup.mul.{u1} G _inst_4 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Subgroup.index.{u1} G _inst_4 H)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
+  forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4), LE.le.{0} Rat Rat.instLERat (commProb.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)) (Subgroup.mul.{u1} G _inst_4 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Subgroup.index.{u1} G _inst_4 H)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
 Case conversion may be inaccurate. Consider using '#align subgroup.comm_prob_subgroup_le Subgroup.commProb_subgroup_leₓ'. -/
 theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2 :=
   by
@@ -160,7 +160,7 @@ theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2
 lean 3 declaration is
   forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3) [_inst_5 : Subgroup.Normal.{u1} G _inst_3 H], LE.le.{0} Rat Rat.hasLe (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (MulOneClass.toHasMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (QuotientGroup.Quotient.group.{u1} G _inst_3 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H))))
 but is expected to have type
-  forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4) [_inst_5 : Subgroup.Normal.{u1} G _inst_4 H], LE.le.{0} Rat Rat.instLERat (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (MulOneClass.toMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (QuotientGroup.Quotient.group.{u1} G _inst_4 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)))))
+  forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4) [_inst_5 : Subgroup.Normal.{u1} G _inst_4 H], LE.le.{0} Rat Rat.instLERat (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (MulOneClass.toMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (QuotientGroup.Quotient.group.{u1} G _inst_4 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)))))
 Case conversion may be inaccurate. Consider using '#align subgroup.comm_prob_quotient_le Subgroup.commProb_quotient_leₓ'. -/
 theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commProb G * Nat.card H :=
   by
@@ -181,7 +181,7 @@ variable (G)
 lean 3 declaration is
   forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], LE.le.{0} Rat Rat.hasLe (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) (commutator.{u1} G _inst_3))))) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3)))))
 but is expected to have type
-  forall (G : Type.{u1}) [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G], LE.le.{0} Rat Rat.instLERat (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x (commutator.{u1} G _inst_4)))))) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4)))))
+  forall (G : Type.{u1}) [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G], LE.le.{0} Rat Rat.instLERat (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (Semiring.toNatCast.{0} Rat Rat.semiring) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x (commutator.{u1} G _inst_4)))))) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4)))))
 Case conversion may be inaccurate. Consider using '#align inv_card_commutator_le_comm_prob inv_card_commutator_le_commProbₓ'. -/
 theorem inv_card_commutator_le_commProb : (↑(Nat.card (commutator G)))⁻¹ ≤ commProb G :=
   (inv_pos_le_iff_one_le_mul (nat.cast_pos.mpr Finite.card_pos)).mpr
Diff
@@ -48,7 +48,7 @@ def commProb : ℚ :=
 
 /- warning: comm_prob_def -> commProb_def is a dubious translation:
 lean 3 declaration is
-  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
+  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
 but is expected to have type
   forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
 Case conversion may be inaccurate. Consider using '#align comm_prob_def commProb_defₓ'. -/
@@ -126,7 +126,7 @@ theorem card_comm_eq_card_conjClasses_mul_card :
 
 /- warning: comm_prob_def' -> commProb_def' is a dubious translation:
 lean 3 declaration is
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} G)))
+  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} G)))
 but is expected to have type
   forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], Eq.{1} Rat (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (ConjClasses.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} G)))
 Case conversion may be inaccurate. Consider using '#align comm_prob_def' commProb_def'ₓ'. -/
@@ -140,7 +140,7 @@ variable {G} (H : Subgroup G)
 
 /- warning: subgroup.comm_prob_subgroup_le -> Subgroup.commProb_subgroup_le is a dubious translation:
 lean 3 declaration is
-  forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3), LE.le.{0} Rat Rat.hasLe (commProb.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H) (Subgroup.mul.{u1} G _inst_3 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Subgroup.index.{u1} G _inst_3 H)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
+  forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3), LE.le.{0} Rat Rat.hasLe (commProb.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H) (Subgroup.mul.{u1} G _inst_3 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Subgroup.index.{u1} G _inst_3 H)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
 but is expected to have type
   forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4), LE.le.{0} Rat Rat.instLERat (commProb.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)) (Subgroup.mul.{u1} G _inst_4 H)) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Subgroup.index.{u1} G _inst_4 H)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
 Case conversion may be inaccurate. Consider using '#align subgroup.comm_prob_subgroup_le Subgroup.commProb_subgroup_leₓ'. -/
@@ -158,7 +158,7 @@ theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * H.index ^ 2
 
 /- warning: subgroup.comm_prob_quotient_le -> Subgroup.commProb_quotient_le is a dubious translation:
 lean 3 declaration is
-  forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3) [_inst_5 : Subgroup.Normal.{u1} G _inst_3 H], LE.le.{0} Rat Rat.hasLe (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (MulOneClass.toHasMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (QuotientGroup.Quotient.group.{u1} G _inst_3 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H))))
+  forall {G : Type.{u1}} [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G] (H : Subgroup.{u1} G _inst_3) [_inst_5 : Subgroup.Normal.{u1} G _inst_3 H], LE.le.{0} Rat Rat.hasLe (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (MulOneClass.toHasMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_3) (QuotientGroup.Subgroup.hasQuotient.{u1} G _inst_3) H) (QuotientGroup.Quotient.group.{u1} G _inst_3 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.hasMul) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) H))))
 but is expected to have type
   forall {G : Type.{u1}} [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G] (H : Subgroup.{u1} G _inst_4) [_inst_5 : Subgroup.Normal.{u1} G _inst_4 H], LE.le.{0} Rat Rat.instLERat (commProb.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (MulOneClass.toMul.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Monoid.toMulOneClass.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (DivInvMonoid.toMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (Group.toDivInvMonoid.{u1} (HasQuotient.Quotient.{u1, u1} G (Subgroup.{u1} G _inst_4) (QuotientGroup.instHasQuotientSubgroup.{u1} G _inst_4) H) (QuotientGroup.Quotient.group.{u1} G _inst_4 H _inst_5)))))) (HMul.hMul.{0, 0, 0} Rat Rat Rat (instHMul.{0} Rat Rat.instMulRat) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4))))) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x H)))))
 Case conversion may be inaccurate. Consider using '#align subgroup.comm_prob_quotient_le Subgroup.commProb_quotient_leₓ'. -/
@@ -179,7 +179,7 @@ variable (G)
 
 /- warning: inv_card_commutator_le_comm_prob -> inv_card_commutator_le_commProb is a dubious translation:
 lean 3 declaration is
-  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], LE.le.{0} Rat Rat.hasLe (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) (commutator.{u1} G _inst_3))))) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3)))))
+  forall (G : Type.{u1}) [_inst_3 : Group.{u1} G] [_inst_4 : Finite.{succ u1} G], LE.le.{0} Rat Rat.hasLe (Inv.inv.{0} Rat Rat.hasInv ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (AddCommGroupWithOne.toAddGroupWithOne.{0} Rat (Ring.toAddCommGroupWithOne.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_3) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_3) G (Subgroup.setLike.{u1} G _inst_3)) (commutator.{u1} G _inst_3))))) (commProb.{u1} G (MulOneClass.toHasMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_3)))))
 but is expected to have type
   forall (G : Type.{u1}) [_inst_3 : Finite.{succ u1} G] [_inst_4 : Group.{u1} G], LE.le.{0} Rat Rat.instLERat (Inv.inv.{0} Rat Rat.instInvRat (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_4) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_4) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_4)) x (commutator.{u1} G _inst_4)))))) (commProb.{u1} G (MulOneClass.toMul.{u1} G (Monoid.toMulOneClass.{u1} G (DivInvMonoid.toMonoid.{u1} G (Group.toDivInvMonoid.{u1} G _inst_4)))))
 Case conversion may be inaccurate. Consider using '#align inv_card_commutator_le_comm_prob inv_card_commutator_le_commProbₓ'. -/
Diff
@@ -46,12 +46,16 @@ def commProb : ℚ :=
 #align comm_prob commProb
 -/
 
-#print commProb_def /-
+/- warning: comm_prob_def -> commProb_def is a dubious translation:
+lean 3 declaration is
+  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.hasDiv) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat Rat (HasLiftT.mk.{1, 1} Nat Rat (CoeTCₓ.coe.{1, 1} Nat Rat (Nat.castCoe.{0} Rat (AddMonoidWithOne.toNatCast.{0} Rat (AddGroupWithOne.toAddMonoidWithOne.{0} Rat (NonAssocRing.toAddGroupWithOne.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing)))))))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (OfNat.mk.{0} Nat 2 (bit0.{0} Nat Nat.hasAdd (One.one.{0} Nat Nat.hasOne))))))
+but is expected to have type
+  forall (M : Type.{u1}) [_inst_1 : Mul.{u1} M], Eq.{1} Rat (commProb.{u1} M _inst_1) (HDiv.hDiv.{0, 0, 0} Rat Rat Rat (instHDiv.{0} Rat Rat.instDivRat) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} (Subtype.{succ u1} (Prod.{u1, u1} M M) (fun (p : Prod.{u1, u1} M M) => Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.fst.{u1, u1} M M p) (Prod.snd.{u1, u1} M M p)) (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M _inst_1) (Prod.snd.{u1, u1} M M p) (Prod.fst.{u1, u1} M M p)))))) (HPow.hPow.{0, 0, 0} Rat Nat Rat (instHPow.{0, 0} Rat Nat (Monoid.Pow.{0} Rat Rat.monoid)) (Nat.cast.{0} Rat (NonAssocRing.toNatCast.{0} Rat (Ring.toNonAssocRing.{0} Rat (DivisionRing.toRing.{0} Rat Rat.divisionRing))) (Nat.card.{u1} M)) (OfNat.ofNat.{0} Nat 2 (instOfNatNat 2))))
+Case conversion may be inaccurate. Consider using '#align comm_prob_def commProb_defₓ'. -/
 theorem commProb_def :
     commProb M = Nat.card { p : M × M // p.1 * p.2 = p.2 * p.1 } / Nat.card M ^ 2 :=
   rfl
 #align comm_prob_def commProb_def
--/
 
 variable [Finite M]
 
Diff
@@ -103,8 +103,7 @@ theorem card_comm_eq_card_conjClasses_mul_card :
   by
   haveI := Fintype.ofFinite G
   simp only [Nat.card_eq_fintype_card]
-  convert
-    calc
+  convert calc
       card { p : G × G // p.1 * p.2 = p.2 * p.1 } = card (Σg, { h // g * h = h * g }) :=
         card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G => g * h = h * g)
       _ = ∑ g, card { h // g * h = h * g } := (card_sigma _)
Diff
@@ -107,12 +107,12 @@ theorem card_comm_eq_card_conjClasses_mul_card :
     calc
       card { p : G × G // p.1 * p.2 = p.2 * p.1 } = card (Σg, { h // g * h = h * g }) :=
         card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G => g * h = h * g)
-      _ = ∑ g, card { h // g * h = h * g } := card_sigma _
+      _ = ∑ g, card { h // g * h = h * g } := (card_sigma _)
       _ = ∑ g, card (MulAction.fixedBy (ConjAct G) G g) :=
-        sum_equiv conj_act.to_conj_act.to_equiv _ _ fun g =>
-          card_congr' <| congr_arg _ <| funext fun h => mul_inv_eq_iff_eq_mul.symm.to_eq
+        (sum_equiv conj_act.to_conj_act.to_equiv _ _ fun g =>
+          card_congr' <| congr_arg _ <| funext fun h => mul_inv_eq_iff_eq_mul.symm.to_eq)
       _ = card (Quotient (MulAction.orbitRel (ConjAct G) G)) * card G :=
-        MulAction.sum_card_fixedBy_eq_card_orbits_mul_card_group (ConjAct G) G
+        (MulAction.sum_card_fixedBy_eq_card_orbits_mul_card_group (ConjAct G) G)
       _ = card (Quotient (IsConj.setoid G)) * card G :=
         by
         have this : MulAction.orbitRel (ConjAct G) G = IsConj.setoid G :=
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Thomas Browning
 
 ! This file was ported from Lean 3 source module group_theory.commuting_probability
-! leanprover-community/mathlib commit d4ebdc81f3cb3c2659a6e7e6ec6cde1d542b4aca
+! leanprover-community/mathlib commit 23aa88e32dcc9d2a24cca7bc23268567ed4cd7d6
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -16,6 +16,9 @@ import Mathbin.GroupTheory.Index
 
 /-!
 # Commuting Probability
+
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
 This file introduces the commuting probability of finite groups.
 
 ## Main definitions

Changes in mathlib4

mathlib3
mathlib4
chore(GroupTheory): remove autoImplicit (#12134)
Diff
@@ -26,8 +26,6 @@ This file introduces the commuting probability of finite groups.
 * Neumann's theorem.
 -/
 
-set_option autoImplicit true
-
 noncomputable section
 
 open scoped Classical
@@ -55,7 +53,7 @@ theorem commProb_prod (M' : Type*) [Mul M'] : commProb (M × M') = commProb M *
   exact Nat.card_congr ⟨fun x => ⟨⟨⟨x.1.1.1, x.1.2.1⟩, x.2.1⟩, ⟨⟨x.1.1.2, x.1.2.2⟩, x.2.2⟩⟩,
     fun x => ⟨⟨⟨x.1.1.1, x.2.1.1⟩, ⟨x.1.1.2, x.2.1.2⟩⟩, ⟨x.1.2, x.2.2⟩⟩, fun x => rfl, fun x => rfl⟩
 
-theorem commProb_pi (i : α → Type*) [Fintype α] [∀ a, Mul (i a)] :
+theorem commProb_pi {α : Type*} (i : α → Type*) [Fintype α] [∀ a, Mul (i a)] :
     commProb (∀ a, i a) = ∏ a, commProb (i a) := by
   simp_rw [commProb_def, Finset.prod_div_distrib, Finset.prod_pow, ← Nat.cast_prod,
     ← Nat.card_pi, Commute, SemiconjBy, Function.funext_iff]
@@ -63,7 +61,7 @@ theorem commProb_pi (i : α → Type*) [Fintype α] [∀ a, Mul (i a)] :
   exact Nat.card_congr ⟨fun x a => ⟨⟨x.1.1 a, x.1.2 a⟩, x.2 a⟩, fun x => ⟨⟨fun a => (x a).1.1,
     fun a => (x a).1.2⟩, fun a => (x a).2⟩, fun x => rfl, fun x => rfl⟩
 
-theorem commProb_function [Fintype α] [Mul β] :
+theorem commProb_function {α β : Type*} [Fintype α] [Mul β] :
     commProb (α → β) = (commProb β) ^ Fintype.card α := by
   rw [commProb_pi, Finset.prod_const, Finset.card_univ]
 
chore: Rename mul-div cancellation lemmas (#11530)

Lemma names around cancellation of multiplication and division are a mess.

This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero lemma name, the Group lemma, the AddGroup lemma name).

| Statement | New name | Old name | |

Diff
@@ -113,7 +113,7 @@ theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * (H.index : 
   /- After rewriting with `commProb_def`, we reduce to showing that `G` has at least as many
       commuting pairs as `H`. -/
   rw [commProb_def, commProb_def, div_le_iff, mul_assoc, ← mul_pow, ← Nat.cast_mul,
-    mul_comm H.index, H.card_mul_index, div_mul_cancel, Nat.cast_le]
+    mul_comm H.index, H.card_mul_index, div_mul_cancel₀, Nat.cast_le]
   · refine' Finite.card_le_of_injective (fun p ↦ ⟨⟨p.1.1, p.1.2⟩, Subtype.ext_iff.mp p.2⟩) _
     exact fun p q h ↦ by simpa only [Subtype.ext_iff, Prod.ext_iff] using h
   · exact pow_ne_zero 2 (Nat.cast_ne_zero.mpr Finite.card_pos.ne')
@@ -124,7 +124,7 @@ theorem Subgroup.commProb_quotient_le [H.Normal] : commProb (G ⧸ H) ≤ commPr
   /- After rewriting with `commProb_def'`, we reduce to showing that `G` has at least as many
       conjugacy classes as `G ⧸ H`. -/
   rw [commProb_def', commProb_def', div_le_iff, mul_assoc, ← Nat.cast_mul, ← Subgroup.index,
-    H.card_mul_index, div_mul_cancel, Nat.cast_le]
+    H.card_mul_index, div_mul_cancel₀, Nat.cast_le]
   · apply Finite.card_le_of_surjective
     show Function.Surjective (ConjClasses.map (QuotientGroup.mk' H))
     exact ConjClasses.map_surjective Quotient.surjective_Quotient_mk''
chore: remove unneeded decreasing_by and termination_by (#11386)

The termination checker has been getting more capable, and many of the termination_by or decreasing_by clauses in Mathlib are no longer needed.

(Note that termination_by? will show the automatically derived termination expression, so no information is being lost by removing these.)

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

Diff
@@ -165,7 +165,6 @@ def reciprocalFactors (n : ℕ) : List ℕ :=
     3 :: reciprocalFactors (n / 2)
   else
     n % 4 * n :: reciprocalFactors (n / 4 + 1)
-decreasing_by all_goals { simp_wf; omega }
 
 @[simp] lemma reciprocalFactors_zero : reciprocalFactors 0 = [0] := rfl
 
chore: scope open Classical (#11199)

We remove all but one open Classicals, instead preferring to use open scoped Classical. The only real side-effect this led to is moving a couple declarations to use Exists.choose instead of Classical.choose.

The first few commits are explicitly labelled regex replaces for ease of review.

Diff
@@ -30,7 +30,7 @@ set_option autoImplicit true
 
 noncomputable section
 
-open Classical
+open scoped Classical
 
 open BigOperators
 
chore: move Mathlib to v4.7.0-rc1 (#11162)

This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0 branch as we update to intermediate nightlies.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>

Diff
@@ -146,7 +146,7 @@ namespace DihedralGroup
 lemma commProb_odd {n : ℕ} (hn : Odd n) :
     commProb (DihedralGroup n) = (n + 3) / (4 * n) := by
   rw [commProb_def', DihedralGroup.card_conjClasses_odd hn, nat_card]
-  qify [show 2 ∣ n + 3 by rw [Nat.dvd_iff_mod_eq_zero, Nat.add_mod, Nat.odd_iff.mp hn]; rfl]
+  qify [show 2 ∣ n + 3 by rw [Nat.dvd_iff_mod_eq_zero, Nat.add_mod, Nat.odd_iff.mp hn]]
   rw [div_div, ← mul_assoc]
   congr
 
refactor: optimize proofs with omega (#11093)

I ran tryAtEachStep on all files under Mathlib to find all locations where omega succeeds. For each that was a linarith without an only, I tried replacing it with omega, and I verified that elaboration time got smaller. (In almost all cases, there was a noticeable speedup.) I also replaced some slow aesops along the way.

Diff
@@ -155,7 +155,7 @@ private lemma div_two_lt {n : ℕ} (h0 : n ≠ 0) : n / 2 < n :=
 
 private lemma div_four_lt : {n : ℕ} → (h0 : n ≠ 0) → (h1 : n ≠ 1) → n / 4 + 1 < n
   | 0 | 1 | 2 | 3 => by decide
-  | n + 4 => by intros; linarith [n.add_div_right four_pos, n.div_le_self 4]
+  | n + 4 => by omega
 
 /-- A list of Dihedral groups whose product will have commuting probability `1 / n`. -/
 def reciprocalFactors (n : ℕ) : List ℕ :=
chore: remove stream-of-consciousness uses of have, replace and suffices (#10640)

No changes to tactic file, it's just boring fixes throughout the library.

This follows on from #6964.

Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -173,15 +173,15 @@ decreasing_by all_goals { simp_wf; omega }
 
 lemma reciprocalFactors_even {n : ℕ} (h0 : n ≠ 0) (h2 : Even n) :
     reciprocalFactors n = 3 :: reciprocalFactors (n / 2) := by
-  have h1 : n ≠ 1
-  · rintro rfl
+  have h1 : n ≠ 1 := by
+    rintro rfl
     norm_num at h2
   rw [reciprocalFactors, dif_neg h0, dif_neg h1, if_pos h2]
 
 lemma reciprocalFactors_odd {n : ℕ} (h1 : n ≠ 1) (h2 : Odd n) :
     reciprocalFactors n = n % 4 * n :: reciprocalFactors (n / 4 + 1) := by
-  have h0 : n ≠ 0
-  · rintro rfl
+  have h0 : n ≠ 0 := by
+    rintro rfl
     norm_num at h2
   rw [reciprocalFactors, dif_neg h0, dif_neg h1, if_neg (Nat.odd_iff_not_even.mp h2)]
 
chore: move to v4.6.0-rc1, merging adaptations from bump/v4.6.0 (#10176)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>

Diff
@@ -165,7 +165,7 @@ def reciprocalFactors (n : ℕ) : List ℕ :=
     3 :: reciprocalFactors (n / 2)
   else
     n % 4 * n :: reciprocalFactors (n / 4 + 1)
-decreasing_by simp_wf; omega
+decreasing_by all_goals { simp_wf; omega }
 
 @[simp] lemma reciprocalFactors_zero : reciprocalFactors 0 = [0] := rfl
 
chore: use omega in decreasing_by proofs (#9688)

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

Diff
@@ -165,9 +165,7 @@ def reciprocalFactors (n : ℕ) : List ℕ :=
     3 :: reciprocalFactors (n / 2)
   else
     n % 4 * n :: reciprocalFactors (n / 4 + 1)
-decreasing_by
-  simp_wf
-  first | exact div_two_lt h0 | exact div_four_lt h0 h1
+decreasing_by simp_wf; omega
 
 @[simp] lemma reciprocalFactors_zero : reciprocalFactors 0 = [0] := rfl
 
chore: space after (#8178)

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

Diff
@@ -49,16 +49,16 @@ theorem commProb_def :
 #align comm_prob_def commProb_def
 
 theorem commProb_prod (M' : Type*) [Mul M'] : commProb (M × M') = commProb M * commProb M' := by
-  simp_rw [commProb_def, div_mul_div_comm, Nat.card_prod, Nat.cast_mul, mul_pow, ←Nat.cast_mul,
-    ←Nat.card_prod, Commute, SemiconjBy, Prod.ext_iff]
+  simp_rw [commProb_def, div_mul_div_comm, Nat.card_prod, Nat.cast_mul, mul_pow, ← Nat.cast_mul,
+    ← Nat.card_prod, Commute, SemiconjBy, Prod.ext_iff]
   congr 2
   exact Nat.card_congr ⟨fun x => ⟨⟨⟨x.1.1.1, x.1.2.1⟩, x.2.1⟩, ⟨⟨x.1.1.2, x.1.2.2⟩, x.2.2⟩⟩,
     fun x => ⟨⟨⟨x.1.1.1, x.2.1.1⟩, ⟨x.1.1.2, x.2.1.2⟩⟩, ⟨x.1.2, x.2.2⟩⟩, fun x => rfl, fun x => rfl⟩
 
 theorem commProb_pi (i : α → Type*) [Fintype α] [∀ a, Mul (i a)] :
     commProb (∀ a, i a) = ∏ a, commProb (i a) := by
-  simp_rw [commProb_def, Finset.prod_div_distrib, Finset.prod_pow, ←Nat.cast_prod,
-    ←Nat.card_pi, Commute, SemiconjBy, Function.funext_iff]
+  simp_rw [commProb_def, Finset.prod_div_distrib, Finset.prod_pow, ← Nat.cast_prod,
+    ← Nat.card_pi, Commute, SemiconjBy, Function.funext_iff]
   congr 2
   exact Nat.card_congr ⟨fun x a => ⟨⟨x.1.1 a, x.1.2 a⟩, x.2 a⟩, fun x => ⟨⟨fun a => (x a).1.1,
     fun a => (x a).1.2⟩, fun a => (x a).2⟩, fun x => rfl, fun x => rfl⟩
chore: bump to v4.3.0-rc2 (#8366)

PR contents

This is the supremum of

along with some minor fixes from failures on nightly-testing as Mathlib master is merged into it.

Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.

I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0 branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.

Lean PRs involved in this bump

In particular this includes adjustments for the Lean PRs

leanprover/lean4#2778

We can get rid of all the

local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)

macros across Mathlib (and in any projects that want to write natural number powers of reals).

leanprover/lean4#2722

Changes the default behaviour of simp to (config := {decide := false}). This makes simp (and consequentially norm_num) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp or norm_num to decide or rfl, or adding (config := {decide := true}).

leanprover/lean4#2783

This changed the behaviour of simp so that simp [f] will only unfold "fully applied" occurrences of f. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true }). We may in future add a syntax for this, e.g. simp [!f]; please provide feedback! In the meantime, we have made the following changes:

  • switching to using explicit lemmas that have the intended level of application
  • (config := { unfoldPartialApp := true }) in some places, to recover the old behaviour
  • Using @[eqns] to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp and Function.flip.

This change in Lean may require further changes down the line (e.g. adding the !f syntax, and/or upstreaming the special treatment for Function.comp and Function.flip, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!

Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>

Diff
@@ -209,13 +209,13 @@ theorem commProb_reciprocal (n : ℕ) :
   rcases Nat.even_or_odd n with h2 | h2
   · have := div_two_lt h0
     rw [reciprocalFactors_even h0 h2, commProb_cons, commProb_reciprocal (n / 2),
-        commProb_odd (by norm_num)]
+        commProb_odd (by decide)]
     field_simp [h0, h2.two_dvd]
     norm_num
   · have := div_four_lt h0 h1
     rw [reciprocalFactors_odd h1 h2, commProb_cons, commProb_reciprocal (n / 4 + 1)]
     have key : n % 4 = 1 ∨ n % 4 = 3 := Nat.odd_mod_four_iff.mp (Nat.odd_iff.mp h2)
-    have hn : Odd (n % 4) := by rcases key with h | h <;> rw [h] <;> norm_num
+    have hn : Odd (n % 4) := by rcases key with h | h <;> rw [h] <;> decide
     rw [commProb_odd (hn.mul h2), div_mul_div_comm, mul_one, div_eq_div_iff, one_mul] <;> norm_cast
     · have h0 : (n % 4) ^ 2 + 3 = n % 4 * 4 := by rcases key with h | h <;> rw [h] <;> norm_num
       have h1 := (Nat.div_add_mod n 4).symm
feat(GroupTheory/CommutingProbability): Group with commuting probability exactly 1/n (#6582)

This PR constructs a group with commuting probability exactly 1/n as a product of dihedral groups.

Besides independent interest, this construction is useful for handling factors of 1/n (e.g., the end of this blog post: https://randompermutations.com/2015/02/06/commuting-probability-of-compact-groups/).

Diff
@@ -8,6 +8,10 @@ import Mathlib.GroupTheory.Abelianization
 import Mathlib.GroupTheory.GroupAction.ConjAct
 import Mathlib.GroupTheory.GroupAction.Quotient
 import Mathlib.GroupTheory.Index
+import Mathlib.GroupTheory.SpecificGroups.Dihedral
+import Mathlib.Tactic.FieldSimp
+import Mathlib.Tactic.LinearCombination
+import Mathlib.Tactic.Qify
 
 #align_import group_theory.commuting_probability from "leanprover-community/mathlib"@"dc6c365e751e34d100e80fe6e314c3c3e0fd2988"
 
@@ -135,3 +139,89 @@ theorem inv_card_commutator_le_commProb : (↑(Nat.card (commutator G)))⁻¹ 
     (le_trans (ge_of_eq (commProb_eq_one_iff.mpr (Abelianization.commGroup G).mul_comm))
       (commutator G).commProb_quotient_le)
 #align inv_card_commutator_le_comm_prob inv_card_commutator_le_commProb
+
+-- Construction of group with commuting probability 1/n
+namespace DihedralGroup
+
+lemma commProb_odd {n : ℕ} (hn : Odd n) :
+    commProb (DihedralGroup n) = (n + 3) / (4 * n) := by
+  rw [commProb_def', DihedralGroup.card_conjClasses_odd hn, nat_card]
+  qify [show 2 ∣ n + 3 by rw [Nat.dvd_iff_mod_eq_zero, Nat.add_mod, Nat.odd_iff.mp hn]; rfl]
+  rw [div_div, ← mul_assoc]
+  congr
+
+private lemma div_two_lt {n : ℕ} (h0 : n ≠ 0) : n / 2 < n :=
+  Nat.div_lt_self (Nat.pos_of_ne_zero h0) (lt_add_one 1)
+
+private lemma div_four_lt : {n : ℕ} → (h0 : n ≠ 0) → (h1 : n ≠ 1) → n / 4 + 1 < n
+  | 0 | 1 | 2 | 3 => by decide
+  | n + 4 => by intros; linarith [n.add_div_right four_pos, n.div_le_self 4]
+
+/-- A list of Dihedral groups whose product will have commuting probability `1 / n`. -/
+def reciprocalFactors (n : ℕ) : List ℕ :=
+  if h0 : n = 0 then [0]
+  else if h1 : n = 1 then []
+  else if Even n then
+    3 :: reciprocalFactors (n / 2)
+  else
+    n % 4 * n :: reciprocalFactors (n / 4 + 1)
+decreasing_by
+  simp_wf
+  first | exact div_two_lt h0 | exact div_four_lt h0 h1
+
+@[simp] lemma reciprocalFactors_zero : reciprocalFactors 0 = [0] := rfl
+
+@[simp] lemma reciprocalFactors_one : reciprocalFactors 1 = [] := rfl
+
+lemma reciprocalFactors_even {n : ℕ} (h0 : n ≠ 0) (h2 : Even n) :
+    reciprocalFactors n = 3 :: reciprocalFactors (n / 2) := by
+  have h1 : n ≠ 1
+  · rintro rfl
+    norm_num at h2
+  rw [reciprocalFactors, dif_neg h0, dif_neg h1, if_pos h2]
+
+lemma reciprocalFactors_odd {n : ℕ} (h1 : n ≠ 1) (h2 : Odd n) :
+    reciprocalFactors n = n % 4 * n :: reciprocalFactors (n / 4 + 1) := by
+  have h0 : n ≠ 0
+  · rintro rfl
+    norm_num at h2
+  rw [reciprocalFactors, dif_neg h0, dif_neg h1, if_neg (Nat.odd_iff_not_even.mp h2)]
+
+/-- A finite product of Dihedral groups. -/
+abbrev Product (l : List ℕ) : Type :=
+  ∀ i : Fin l.length, DihedralGroup l[i]
+
+lemma commProb_nil : commProb (Product []) = 1 := by
+  simp [Product, commProb_pi]
+
+lemma commProb_cons (n : ℕ) (l : List ℕ) :
+    commProb (Product (n :: l)) = commProb (DihedralGroup n) * commProb (Product l) := by
+  simp [Product, commProb_pi, Fin.prod_univ_succ]
+
+/-- Construction of a group with commuting probability `1 / n`. -/
+theorem commProb_reciprocal (n : ℕ) :
+    commProb (Product (reciprocalFactors n)) = 1 / n := by
+  by_cases h0 : n = 0
+  · rw [h0, reciprocalFactors_zero, commProb_cons, commProb_nil, mul_one, Nat.cast_zero, div_zero]
+    apply commProb_eq_zero_of_infinite
+  by_cases h1 : n = 1
+  · rw [h1, reciprocalFactors_one, commProb_nil, Nat.cast_one, div_one]
+  rcases Nat.even_or_odd n with h2 | h2
+  · have := div_two_lt h0
+    rw [reciprocalFactors_even h0 h2, commProb_cons, commProb_reciprocal (n / 2),
+        commProb_odd (by norm_num)]
+    field_simp [h0, h2.two_dvd]
+    norm_num
+  · have := div_four_lt h0 h1
+    rw [reciprocalFactors_odd h1 h2, commProb_cons, commProb_reciprocal (n / 4 + 1)]
+    have key : n % 4 = 1 ∨ n % 4 = 3 := Nat.odd_mod_four_iff.mp (Nat.odd_iff.mp h2)
+    have hn : Odd (n % 4) := by rcases key with h | h <;> rw [h] <;> norm_num
+    rw [commProb_odd (hn.mul h2), div_mul_div_comm, mul_one, div_eq_div_iff, one_mul] <;> norm_cast
+    · have h0 : (n % 4) ^ 2 + 3 = n % 4 * 4 := by rcases key with h | h <;> rw [h] <;> norm_num
+      have h1 := (Nat.div_add_mod n 4).symm
+      zify at h0 h1 ⊢
+      linear_combination (h0 + h1 * (n % 4)) * n
+    · have := hn.pos.ne'
+      positivity
+
+end DihedralGroup
fix: disable autoImplicit globally (#6528)

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

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

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

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

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

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

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

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

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

Diff
@@ -21,6 +21,9 @@ This file introduces the commuting probability of finite groups.
 ## Todo
 * Neumann's theorem.
 -/
+
+set_option autoImplicit true
+
 noncomputable section
 
 open Classical
chore: banish Type _ and Sort _ (#6499)

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

This has nice performance benefits.

Diff
@@ -29,7 +29,7 @@ open BigOperators
 
 open Fintype
 
-variable (M : Type _) [Mul M]
+variable (M : Type*) [Mul M]
 
 /-- The commuting probability of a finite type with a multiplication operation. -/
 def commProb : ℚ :=
@@ -41,14 +41,14 @@ theorem commProb_def :
   rfl
 #align comm_prob_def commProb_def
 
-theorem commProb_prod (M' : Type _) [Mul M'] : commProb (M × M') = commProb M * commProb M' := by
+theorem commProb_prod (M' : Type*) [Mul M'] : commProb (M × M') = commProb M * commProb M' := by
   simp_rw [commProb_def, div_mul_div_comm, Nat.card_prod, Nat.cast_mul, mul_pow, ←Nat.cast_mul,
     ←Nat.card_prod, Commute, SemiconjBy, Prod.ext_iff]
   congr 2
   exact Nat.card_congr ⟨fun x => ⟨⟨⟨x.1.1.1, x.1.2.1⟩, x.2.1⟩, ⟨⟨x.1.1.2, x.1.2.2⟩, x.2.2⟩⟩,
     fun x => ⟨⟨⟨x.1.1.1, x.2.1.1⟩, ⟨x.1.1.2, x.2.1.2⟩⟩, ⟨x.1.2, x.2.2⟩⟩, fun x => rfl, fun x => rfl⟩
 
-theorem commProb_pi (i : α → Type _) [Fintype α] [∀ a, Mul (i a)] :
+theorem commProb_pi (i : α → Type*) [Fintype α] [∀ a, Mul (i a)] :
     commProb (∀ a, i a) = ∏ a, commProb (i a) := by
   simp_rw [commProb_def, Finset.prod_div_distrib, Finset.prod_pow, ←Nat.cast_prod,
     ←Nat.card_pi, Commute, SemiconjBy, Function.funext_iff]
@@ -90,7 +90,7 @@ theorem commProb_eq_one_iff [h : Nonempty M] :
   · exact pow_ne_zero 2 (Nat.cast_ne_zero.mpr card_ne_zero)
 #align comm_prob_eq_one_iff commProb_eq_one_iff
 
-variable (G : Type _) [Group G]
+variable (G : Type*) [Group G]
 
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G := by
   rw [commProb, card_comm_eq_card_conjClasses_mul_card, Nat.cast_mul, sq]
refactor(GroupTheory/GroupAction/Quotient): Move conjugacy class formula earlier (#6290)

This PR moves a formula for the number of conjugacy classes earlier. The proof uses Burnside's theorem, so it cannot be moved any earlier than GroupTheory/GroupAction/Quotient.

Diff
@@ -60,9 +60,6 @@ theorem commProb_function [Fintype α] [Mul β] :
     commProb (α → β) = (commProb β) ^ Fintype.card α := by
   rw [commProb_pi, Finset.prod_const, Finset.card_univ]
 
-instance instInfiniteProdSubtypeCommute [Infinite M] : Infinite { p : M × M // Commute p.1 p.2 } :=
-  Infinite.of_injective (fun m => ⟨⟨m, m⟩, rfl⟩) (by intro; simp)
-
 @[simp]
 theorem commProb_eq_zero_of_infinite [Infinite M] : commProb M = 0 :=
   div_eq_zero_iff.2 (Or.inl (Nat.cast_eq_zero.2 Nat.card_eq_zero_of_infinite))
@@ -95,22 +92,6 @@ theorem commProb_eq_one_iff [h : Nonempty M] :
 
 variable (G : Type _) [Group G]
 
-theorem card_comm_eq_card_conjClasses_mul_card :
-    Nat.card { p : G × G // Commute p.1 p.2 } = Nat.card (ConjClasses G) * Nat.card G := by
-  rcases fintypeOrInfinite G; swap
-  · rw [Nat.card_eq_zero_of_infinite, @Nat.card_eq_zero_of_infinite G, mul_zero]
-  simp only [Nat.card_eq_fintype_card]
-  -- Porting note: Changed `calc` proof into a `rw` proof.
-  rw [card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G ↦ Commute g h), card_sigma,
-    sum_equiv ConjAct.toConjAct.toEquiv (fun a ↦ card { b // Commute a b })
-      (fun g ↦ card (MulAction.fixedBy (ConjAct G) G g))
-      fun g ↦ card_congr' <| congr_arg _ <| funext fun h ↦ mul_inv_eq_iff_eq_mul.symm.to_eq,
-    MulAction.sum_card_fixedBy_eq_card_orbits_mul_card_group, ConjAct.card,
-    (Setoid.ext fun g h ↦ (Setoid.comm' _).trans isConj_iff.symm :
-      MulAction.orbitRel (ConjAct G) G = IsConj.setoid G),
-    @card_congr' (Quotient (IsConj.setoid G)) (ConjClasses G) _ _ rfl]
-#align card_comm_eq_card_conj_classes_mul_card card_comm_eq_card_conjClasses_mul_card
-
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G := by
   rw [commProb, card_comm_eq_card_conjClasses_mul_card, Nat.cast_mul, sq]
   by_cases h : (Nat.card G : ℚ) = 0
refactor(GroupTheory/CommutingProbability): Remove finite assumption (#6224)

This PR removes the finite assumption on a couple lemmas.

Diff
@@ -93,11 +93,12 @@ theorem commProb_eq_one_iff [h : Nonempty M] :
   · exact pow_ne_zero 2 (Nat.cast_ne_zero.mpr card_ne_zero)
 #align comm_prob_eq_one_iff commProb_eq_one_iff
 
-variable (G : Type _) [Group G] [Finite G]
+variable (G : Type _) [Group G]
 
 theorem card_comm_eq_card_conjClasses_mul_card :
     Nat.card { p : G × G // Commute p.1 p.2 } = Nat.card (ConjClasses G) * Nat.card G := by
-  haveI := Fintype.ofFinite G
+  rcases fintypeOrInfinite G; swap
+  · rw [Nat.card_eq_zero_of_infinite, @Nat.card_eq_zero_of_infinite G, mul_zero]
   simp only [Nat.card_eq_fintype_card]
   -- Porting note: Changed `calc` proof into a `rw` proof.
   rw [card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G ↦ Commute g h), card_sigma,
@@ -112,11 +113,13 @@ theorem card_comm_eq_card_conjClasses_mul_card :
 
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G := by
   rw [commProb, card_comm_eq_card_conjClasses_mul_card, Nat.cast_mul, sq]
-  exact mul_div_mul_right _ _ (Nat.cast_ne_zero.mpr Finite.card_pos.ne')
+  by_cases h : (Nat.card G : ℚ) = 0
+  · rw [h, zero_mul, div_zero, div_zero]
+  · exact mul_div_mul_right _ _ h
 #align comm_prob_def' commProb_def'
 
--- porting note: inserted [Group G]
-variable {G} [Group G] (H : Subgroup G)
+variable {G}
+variable [Finite G] (H : Subgroup G)
 
 theorem Subgroup.commProb_subgroup_le : commProb H ≤ commProb G * (H.index : ℚ) ^ 2 := by
   /- After rewriting with `commProb_def`, we reduce to showing that `G` has at least as many
feat: Lemmas about commuting probabilities of groups (#6104)

This PR adds lemmas about commuting probabilities of products of groups and about commuting probabilities of infinite groups.

It also changes some definitions and lemmas to use Commute.

Diff
@@ -33,14 +33,40 @@ variable (M : Type _) [Mul M]
 
 /-- The commuting probability of a finite type with a multiplication operation. -/
 def commProb : ℚ :=
-  Nat.card { p : M × M // p.1 * p.2 = p.2 * p.1 } / (Nat.card M : ℚ) ^ 2
+  Nat.card { p : M × M // Commute p.1 p.2 } / (Nat.card M : ℚ) ^ 2
 #align comm_prob commProb
 
 theorem commProb_def :
-    commProb M = Nat.card { p : M × M // p.1 * p.2 = p.2 * p.1 } / (Nat.card M : ℚ) ^ 2 :=
+    commProb M = Nat.card { p : M × M // Commute p.1 p.2 } / (Nat.card M : ℚ) ^ 2 :=
   rfl
 #align comm_prob_def commProb_def
 
+theorem commProb_prod (M' : Type _) [Mul M'] : commProb (M × M') = commProb M * commProb M' := by
+  simp_rw [commProb_def, div_mul_div_comm, Nat.card_prod, Nat.cast_mul, mul_pow, ←Nat.cast_mul,
+    ←Nat.card_prod, Commute, SemiconjBy, Prod.ext_iff]
+  congr 2
+  exact Nat.card_congr ⟨fun x => ⟨⟨⟨x.1.1.1, x.1.2.1⟩, x.2.1⟩, ⟨⟨x.1.1.2, x.1.2.2⟩, x.2.2⟩⟩,
+    fun x => ⟨⟨⟨x.1.1.1, x.2.1.1⟩, ⟨x.1.1.2, x.2.1.2⟩⟩, ⟨x.1.2, x.2.2⟩⟩, fun x => rfl, fun x => rfl⟩
+
+theorem commProb_pi (i : α → Type _) [Fintype α] [∀ a, Mul (i a)] :
+    commProb (∀ a, i a) = ∏ a, commProb (i a) := by
+  simp_rw [commProb_def, Finset.prod_div_distrib, Finset.prod_pow, ←Nat.cast_prod,
+    ←Nat.card_pi, Commute, SemiconjBy, Function.funext_iff]
+  congr 2
+  exact Nat.card_congr ⟨fun x a => ⟨⟨x.1.1 a, x.1.2 a⟩, x.2 a⟩, fun x => ⟨⟨fun a => (x a).1.1,
+    fun a => (x a).1.2⟩, fun a => (x a).2⟩, fun x => rfl, fun x => rfl⟩
+
+theorem commProb_function [Fintype α] [Mul β] :
+    commProb (α → β) = (commProb β) ^ Fintype.card α := by
+  rw [commProb_pi, Finset.prod_const, Finset.card_univ]
+
+instance instInfiniteProdSubtypeCommute [Infinite M] : Infinite { p : M × M // Commute p.1 p.2 } :=
+  Infinite.of_injective (fun m => ⟨⟨m, m⟩, rfl⟩) (by intro; simp)
+
+@[simp]
+theorem commProb_eq_zero_of_infinite [Infinite M] : commProb M = 0 :=
+  div_eq_zero_iff.2 (Or.inl (Nat.cast_eq_zero.2 Nat.card_eq_zero_of_infinite))
+
 variable [Finite M]
 
 theorem commProb_pos [h : Nonempty M] : 0 < commProb M :=
@@ -70,12 +96,12 @@ theorem commProb_eq_one_iff [h : Nonempty M] :
 variable (G : Type _) [Group G] [Finite G]
 
 theorem card_comm_eq_card_conjClasses_mul_card :
-    Nat.card { p : G × G // p.1 * p.2 = p.2 * p.1 } = Nat.card (ConjClasses G) * Nat.card G := by
+    Nat.card { p : G × G // Commute p.1 p.2 } = Nat.card (ConjClasses G) * Nat.card G := by
   haveI := Fintype.ofFinite G
   simp only [Nat.card_eq_fintype_card]
   -- Porting note: Changed `calc` proof into a `rw` proof.
-  rw [card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G ↦ g * h = h * g), card_sigma,
-    sum_equiv ConjAct.toConjAct.toEquiv (fun a ↦ card { b // a * b = b * a })
+  rw [card_congr (Equiv.subtypeProdEquivSigmaSubtype fun g h : G ↦ Commute g h), card_sigma,
+    sum_equiv ConjAct.toConjAct.toEquiv (fun a ↦ card { b // Commute a b })
       (fun g ↦ card (MulAction.fixedBy (ConjAct G) G g))
       fun g ↦ card_congr' <| congr_arg _ <| funext fun h ↦ mul_inv_eq_iff_eq_mul.symm.to_eq,
     MulAction.sum_card_fixedBy_eq_card_orbits_mul_card_group, ConjAct.card,
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 Thomas Browning. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Thomas Browning
-
-! This file was ported from Lean 3 source module group_theory.commuting_probability
-! leanprover-community/mathlib commit dc6c365e751e34d100e80fe6e314c3c3e0fd2988
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Algebra.Group.ConjFinite
 import Mathlib.GroupTheory.Abelianization
@@ -14,6 +9,8 @@ import Mathlib.GroupTheory.GroupAction.ConjAct
 import Mathlib.GroupTheory.GroupAction.Quotient
 import Mathlib.GroupTheory.Index
 
+#align_import group_theory.commuting_probability from "leanprover-community/mathlib"@"dc6c365e751e34d100e80fe6e314c3c3e0fd2988"
+
 /-!
 # Commuting Probability
 This file introduces the commuting probability of finite groups.
chore: fix #align lines (#3640)

This PR fixes two things:

  • Most align statements for definitions and theorems and instances that are separated by two newlines from the relevant declaration (s/\n\n#align/\n#align). This is often seen in the mathport output after ending calc blocks.
  • All remaining more-than-one-line #align statements. (This was needed for a script I wrote for #3630.)
Diff
@@ -85,7 +85,6 @@ theorem card_comm_eq_card_conjClasses_mul_card :
     (Setoid.ext fun g h ↦ (Setoid.comm' _).trans isConj_iff.symm :
       MulAction.orbitRel (ConjAct G) G = IsConj.setoid G),
     @card_congr' (Quotient (IsConj.setoid G)) (ConjClasses G) _ _ rfl]
-
 #align card_comm_eq_card_conj_classes_mul_card card_comm_eq_card_conjClasses_mul_card
 
 theorem commProb_def' : commProb G = Nat.card (ConjClasses G) / Nat.card G := by
feat: port GroupTheory.CommutingProbability (#2284)

Co-authored-by: Moritz Firsching <firsching@google.com> Co-authored-by: int-y1 <jason_yuen2007@hotmail.com>

Dependencies 8 + 362

363 files ported (97.8%)
148361 lines ported (97.9%)
Show graph

The unported dependencies are