group_theory.commuting_probability
⟷
Mathlib.GroupTheory.CommutingProbability
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.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(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)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -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''
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -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"
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -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
+-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -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 :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -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 _)
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -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) :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -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))
mathlib commit https://github.com/leanprover-community/mathlib/commit/0b9eaaa7686280fad8cce467f5c3c57ee6ce77f8
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/08e1d8d4d989df3a6df86f385e9053ec8a372cc1
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce86f4e05e9a9b8da5e316b22c76ce76440c56a1
@@ -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ₓ'. -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/b19481deb571022990f1baa9cbf9172e6757a479
@@ -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]
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce7e9d53d4bbc38065db3b595cd5bd73c323bc1d
@@ -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 _)
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -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 :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/3ade05ac9447ae31a22d2ea5423435e054131240
@@ -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
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -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]
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 | |
@@ -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''
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>
@@ -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
open Classical
(#11199)
We remove all but one open Classical
s, 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.
@@ -30,7 +30,7 @@ set_option autoImplicit true
noncomputable section
-open Classical
+open scoped Classical
open BigOperators
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>
@@ -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
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 aesop
s along the way.
@@ -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 ℕ :=
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>
@@ -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)]
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>
@@ -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
@@ -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
@@ -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⟩
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.
In particular this includes adjustments for the Lean PRs
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).
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})
.
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:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[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>
@@ -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
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/).
@@ -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
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:
variables
are in scope, but pasting the lemma in the wrong sectionHaving set_option autoImplicit false
as the default prevents these types of mistake being made in the 90% of files where autoImplicit
s 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.
@@ -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
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -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]
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
.
@@ -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
This PR removes the finite assumption on a couple lemmas.
@@ -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
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
.
@@ -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,
@@ -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.
This PR fixes two things:
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.#align
statements. (This was needed for a script I wrote for #3630.)@@ -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
The unported dependencies are