data.sym.card
⟷
Mathlib.Data.Sym.Card
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)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(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
@@ -158,7 +158,7 @@ theorem card_image_diag (s : Finset α) : (s.diag.image Quotient.mk').card = s.c
rintro ⟨x₀, x₁⟩ hx _ _ h
cases Quotient.eq'.1 h
· rfl
- · simp only [mem_coe, mem_diag] at hx
+ · simp only [mem_coe, mem_diag] at hx
rw [hx.2]
#align sym2.card_image_diag Sym2.card_image_diag
-/
@@ -172,7 +172,7 @@ theorem two_mul_card_image_offDiag (s : Finset α) :
∀ x ∈ s.off_diag, Quotient.mk' x ∈ s.off_diag.image Quotient.mk'),
sum_const_nat (Quotient.ind _), mul_comm]
rintro ⟨x, y⟩ hxy
- simp_rw [mem_image, exists_prop, mem_off_diag, Quotient.eq'] at hxy
+ simp_rw [mem_image, exists_prop, mem_off_diag, Quotient.eq'] at hxy
obtain ⟨a, ⟨ha₁, ha₂, ha⟩, h⟩ := hxy
obtain ⟨hx, hy, hxy⟩ : x ∈ s ∧ y ∈ s ∧ x ≠ y := by
cases h <;> have := ha.symm <;> exact ⟨‹_›, ‹_›, ‹_›⟩
@@ -234,7 +234,7 @@ theorem Finset.card_sym2 (s : Finset α) : s.Sym2.card = s.card * (s.card + 1) /
Nat.add_one_sub_one, mul_comm]
rw [disjoint_left]
rintro m ha hb
- rw [mem_image] at ha hb
+ rw [mem_image] at ha hb
obtain ⟨⟨a, ha, rfl⟩, ⟨b, hb, hab⟩⟩ := ha, hb
refine' not_is_diag_mk_of_mem_off_diag hb _
rw [hab]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -95,7 +95,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
simp only [map_map, comp_app]
nth_rw_rhs 1 [← map_id' s]
refine' Sym.map_congr fun v hv => _
- simp [Fin.predAbove_zero (ne_of_mem_of_not_mem hv hs)]
+ simp [Fin.predAbove_zero_of_ne_zero (ne_of_mem_of_not_mem hv hs)]
right_inv s := by
simp only [Fin.zero_succAbove, map_map, comp_app]
nth_rw_rhs 1 [← map_id' s]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -230,8 +230,8 @@ theorem card_subtype_not_diag [Fintype α] : card { a : Sym2 α // ¬a.IsDiag }
theorem Finset.card_sym2 (s : Finset α) : s.Sym2.card = s.card * (s.card + 1) / 2 :=
by
rw [← image_diag_union_image_off_diag, card_union_eq, Sym2.card_image_diag,
- Sym2.card_image_offDiag, Nat.choose_two_right, add_comm, ← Nat.triangle_succ, Nat.succ_sub_one,
- mul_comm]
+ Sym2.card_image_offDiag, Nat.choose_two_right, add_comm, ← Nat.triangle_succ,
+ Nat.add_one_sub_one, mul_comm]
rw [disjoint_left]
rintro m ha hb
rw [mem_image] at ha hb
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,9 +3,9 @@ Copyright (c) 2021 Yaël Dillies, Bhavik Mehta. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies, Bhavik Mehta, Huỳnh Trần Khanh, Stuart Presnell
-/
-import Mathbin.Algebra.BigOperators.Basic
-import Mathbin.Data.Finset.Sym
-import Mathbin.Data.Fintype.Sum
+import Algebra.BigOperators.Basic
+import Data.Finset.Sym
+import Data.Fintype.Sum
#align_import data.sym.card from "leanprover-community/mathlib"@"7d34004e19699895c13c86b78ae62bbaea0bc893"
mathlib commit https://github.com/leanprover-community/mathlib/commit/63721b2c3eba6c325ecf8ae8cca27155a4f6306f
@@ -100,7 +100,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
simp only [Fin.zero_succAbove, map_map, comp_app]
nth_rw_rhs 1 [← map_id' s]
refine' Sym.map_congr fun v hv => _
- rw [← Fin.zero_succAbove v, ← @Fin.castSucc_zero n.succ, Fin.predAbove_succAbove 0 v]
+ rw [← Fin.zero_succAbove v, ← @Fin.castSucc_zero' n.succ, Fin.predAbove_succAbove 0 v]
#align sym.E2 Sym.e2
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,16 +2,13 @@
Copyright (c) 2021 Yaël Dillies, Bhavik Mehta. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies, Bhavik Mehta, Huỳnh Trần Khanh, Stuart Presnell
-
-! This file was ported from Lean 3 source module data.sym.card
-! leanprover-community/mathlib commit 7d34004e19699895c13c86b78ae62bbaea0bc893
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Algebra.BigOperators.Basic
import Mathbin.Data.Finset.Sym
import Mathbin.Data.Fintype.Sum
+#align_import data.sym.card from "leanprover-community/mathlib"@"7d34004e19699895c13c86b78ae62bbaea0bc893"
+
/-!
# Stars and bars
mathlib commit https://github.com/leanprover-community/mathlib/commit/2fe465deb81bcd7ccafa065bb686888a82f15372
@@ -91,7 +91,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
where
toFun s := map (Fin.predAbove 0) s.1
invFun s :=
- ⟨map (Fin.succAbove 0) s,
+ ⟨map (Fin.succAboveEmb 0) s,
(mt mem_map.1) (not_exists.2 fun t => not_and.2 fun _ => Fin.succAbove_ne _ t)⟩
left_inv s := by
obtain ⟨s, hs⟩ := s
@@ -103,7 +103,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
simp only [Fin.zero_succAbove, map_map, comp_app]
nth_rw_rhs 1 [← map_id' s]
refine' Sym.map_congr fun v hv => _
- rw [← Fin.zero_succAbove v, ← @Fin.castSuccEmb_zero n.succ, Fin.predAbove_succAbove 0 v]
+ rw [← Fin.zero_succAbove v, ← @Fin.castSucc_zero n.succ, Fin.predAbove_succAbove 0 v]
#align sym.E2 Sym.e2
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/5dc6092d09e5e489106865241986f7f2ad28d4c8
@@ -103,7 +103,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
simp only [Fin.zero_succAbove, map_map, comp_app]
nth_rw_rhs 1 [← map_id' s]
refine' Sym.map_congr fun v hv => _
- rw [← Fin.zero_succAbove v, ← @Fin.castSucc_zero n.succ, Fin.predAbove_succAbove 0 v]
+ rw [← Fin.zero_succAbove v, ← @Fin.castSuccEmb_zero n.succ, Fin.predAbove_succAbove 0 v]
#align sym.E2 Sym.e2
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -69,6 +69,7 @@ section Sym
variable (α) (n : ℕ)
+#print Sym.e1 /-
/-- Over `fin n+1`, the multisets of size `k+1` containing `0` are equivalent to those of size `k`,
as demonstrated by respectively erasing or appending `0`.
-/
@@ -79,7 +80,9 @@ protected def e1 {n k : ℕ} : { s : Sym (Fin n.succ) k.succ // ↑0 ∈ s } ≃
left_inv s := by simp
right_inv s := by simp
#align sym.E1 Sym.e1
+-/
+#print Sym.e2 /-
/-- The multisets of size `k` over `fin n+2` not containing `0`
are equivalent to those of size `k` over `fin n+1`,
as demonstrated by respectively decrementing or incrementing every element of the multiset.
@@ -102,6 +105,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
refine' Sym.map_congr fun v hv => _
rw [← Fin.zero_succAbove v, ← @Fin.castSucc_zero n.succ, Fin.predAbove_succAbove 0 v]
#align sym.E2 Sym.e2
+-/
#print Sym.card_sym_fin_eq_multichoose /-
theorem card_sym_fin_eq_multichoose (n k : ℕ) : card (Sym (Fin n) k) = multichoose n k :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -157,7 +157,7 @@ theorem card_image_diag (s : Finset α) : (s.diag.image Quotient.mk').card = s.c
rintro ⟨x₀, x₁⟩ hx _ _ h
cases Quotient.eq'.1 h
· rfl
- · simp only [mem_coe, mem_diag] at hx
+ · simp only [mem_coe, mem_diag] at hx
rw [hx.2]
#align sym2.card_image_diag Sym2.card_image_diag
-/
@@ -171,7 +171,7 @@ theorem two_mul_card_image_offDiag (s : Finset α) :
∀ x ∈ s.off_diag, Quotient.mk' x ∈ s.off_diag.image Quotient.mk'),
sum_const_nat (Quotient.ind _), mul_comm]
rintro ⟨x, y⟩ hxy
- simp_rw [mem_image, exists_prop, mem_off_diag, Quotient.eq'] at hxy
+ simp_rw [mem_image, exists_prop, mem_off_diag, Quotient.eq'] at hxy
obtain ⟨a, ⟨ha₁, ha₂, ha⟩, h⟩ := hxy
obtain ⟨hx, hy, hxy⟩ : x ∈ s ∧ y ∈ s ∧ x ≠ y := by
cases h <;> have := ha.symm <;> exact ⟨‹_›, ‹_›, ‹_›⟩
@@ -233,7 +233,7 @@ theorem Finset.card_sym2 (s : Finset α) : s.Sym2.card = s.card * (s.card + 1) /
mul_comm]
rw [disjoint_left]
rintro m ha hb
- rw [mem_image] at ha hb
+ rw [mem_image] at ha hb
obtain ⟨⟨a, ha, rfl⟩, ⟨b, hb, hab⟩⟩ := ha, hb
refine' not_is_diag_mk_of_mem_off_diag hb _
rw [hab]
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -69,12 +69,6 @@ section Sym
variable (α) (n : ℕ)
-/- warning: sym.E1 -> Sym.e1 is a dubious translation:
-lean 3 declaration is
- forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (Nat.succ n)) (Nat.succ k)) (fun (s : Sym.{0} (Fin (Nat.succ n)) (Nat.succ k)) => Membership.Mem.{0, 0} (Fin (Nat.succ n)) (Sym.{0} (Fin (Nat.succ n)) (Nat.succ k)) (Sym.hasMem.{0} (Fin (Nat.succ n)) (Nat.succ k)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat (Fin (Nat.succ n)) (HasLiftT.mk.{1, 1} Nat (Fin (Nat.succ n)) (CoeTCₓ.coe.{1, 1} Nat (Fin (Nat.succ n)) (Nat.castCoe.{0} (Fin (Nat.succ n)) (AddMonoidWithOne.toNatCast.{0} (Fin (Nat.succ n)) (Fin.addMonoidWithOne (Nat.succ n) (NeZero.succ n)))))) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) s)) (Sym.{0} (Fin (Nat.succ n)) k)
-but is expected to have type
- forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (s : Sym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) => Membership.mem.{0, 0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (Sym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (Sym.instMembershipSym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (OfNat.ofNat.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) 0 (Fin.instOfNatFin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) 0 (NeZero.succ n))) s)) (Sym.{0} (Fin (Nat.succ n)) k)
-Case conversion may be inaccurate. Consider using '#align sym.E1 Sym.e1ₓ'. -/
/-- Over `fin n+1`, the multisets of size `k+1` containing `0` are equivalent to those of size `k`,
as demonstrated by respectively erasing or appending `0`.
-/
@@ -86,12 +80,6 @@ protected def e1 {n k : ℕ} : { s : Sym (Fin n.succ) k.succ // ↑0 ∈ s } ≃
right_inv s := by simp
#align sym.E1 Sym.e1
-/- warning: sym.E2 -> Sym.e2 is a dubious translation:
-lean 3 declaration is
- forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (fun (s : Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) => Not (Membership.Mem.{0, 0} (Fin (Nat.succ (Nat.succ n))) (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (Sym.hasMem.{0} (Fin (Nat.succ (Nat.succ n))) k) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat (Fin (Nat.succ (Nat.succ n))) (HasLiftT.mk.{1, 1} Nat (Fin (Nat.succ (Nat.succ n))) (CoeTCₓ.coe.{1, 1} Nat (Fin (Nat.succ (Nat.succ n))) (Nat.castCoe.{0} (Fin (Nat.succ (Nat.succ n))) (AddMonoidWithOne.toNatCast.{0} (Fin (Nat.succ (Nat.succ n))) (Fin.addMonoidWithOne (Nat.succ (Nat.succ n)) (Sym.e2._proof_1 n)))))) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) s))) (Sym.{0} (Fin (Nat.succ n)) k)
-but is expected to have type
- forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (fun (s : Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) => Not (Membership.mem.{0, 0} (Fin (Nat.succ (Nat.succ n))) (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (Sym.instMembershipSym.{0} (Fin (Nat.succ (Nat.succ n))) k) (OfNat.ofNat.{0} (Fin (Nat.succ (Nat.succ n))) 0 (Fin.instOfNatFin (Nat.succ (Nat.succ n)) 0 (NeZero.succ (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))) s))) (Sym.{0} (Fin (Nat.succ n)) k)
-Case conversion may be inaccurate. Consider using '#align sym.E2 Sym.e2ₓ'. -/
/-- The multisets of size `k` over `fin n+2` not containing `0`
are equivalent to those of size `k` over `fin n+1`,
as demonstrated by respectively decrementing or incrementing every element of the multiset.
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -121,8 +121,7 @@ theorem card_sym_fin_eq_multichoose (n k : ℕ) : card (Sym (Fin n) k) = multich
apply @pincer_recursion fun n k => card (Sym (Fin n) k) = multichoose n k
· simp
· intro b
- induction' b with b IHb
- · simp
+ induction' b with b IHb; · simp
rw [multichoose_zero_succ, card_eq_zero_iff]
infer_instance
· intro x y h1 h2
@@ -140,9 +139,7 @@ theorem card_sym_fin_eq_multichoose (n k : ℕ) : card (Sym (Fin n) k) = multich
#print Sym.card_sym_eq_multichoose /-
/-- For any fintype `α` of cardinality `n`, `card (sym α k) = multichoose (card α) k` -/
theorem card_sym_eq_multichoose (α : Type _) (k : ℕ) [Fintype α] [Fintype (Sym α k)] :
- card (Sym α k) = multichoose (card α) k :=
- by
- rw [← card_sym_fin_eq_multichoose]
+ card (Sym α k) = multichoose (card α) k := by rw [← card_sym_fin_eq_multichoose];
exact card_congr (equiv_congr (equiv_fin α))
#align sym.card_sym_eq_multichoose Sym.card_sym_eq_multichoose
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/cc5dd6244981976cc9da7afc4eee5682b037a013
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies, Bhavik Mehta, Huỳnh Trần Khanh, Stuart Presnell
! This file was ported from Lean 3 source module data.sym.card
-! leanprover-community/mathlib commit 0bd2ea37bcba5769e14866170f251c9bc64e35d7
+! leanprover-community/mathlib commit 7d34004e19699895c13c86b78ae62bbaea0bc893
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -15,6 +15,9 @@ import Mathbin.Data.Fintype.Sum
/-!
# Stars and bars
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
In this file, we prove (in `sym.card_sym_eq_multichoose`) that the function `multichoose n k`
defined in `data/nat/choose/basic` counts the number of multisets of cardinality `k` over an
alphabet of cardinality `n`. In conjunction with `nat.multichoose_eq` proved in
mathlib commit https://github.com/leanprover-community/mathlib/commit/08e1d8d4d989df3a6df86f385e9053ec8a372cc1
@@ -66,6 +66,12 @@ section Sym
variable (α) (n : ℕ)
+/- warning: sym.E1 -> Sym.e1 is a dubious translation:
+lean 3 declaration is
+ forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (Nat.succ n)) (Nat.succ k)) (fun (s : Sym.{0} (Fin (Nat.succ n)) (Nat.succ k)) => Membership.Mem.{0, 0} (Fin (Nat.succ n)) (Sym.{0} (Fin (Nat.succ n)) (Nat.succ k)) (Sym.hasMem.{0} (Fin (Nat.succ n)) (Nat.succ k)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat (Fin (Nat.succ n)) (HasLiftT.mk.{1, 1} Nat (Fin (Nat.succ n)) (CoeTCₓ.coe.{1, 1} Nat (Fin (Nat.succ n)) (Nat.castCoe.{0} (Fin (Nat.succ n)) (AddMonoidWithOne.toNatCast.{0} (Fin (Nat.succ n)) (Fin.addMonoidWithOne (Nat.succ n) (NeZero.succ n)))))) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) s)) (Sym.{0} (Fin (Nat.succ n)) k)
+but is expected to have type
+ forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (s : Sym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) => Membership.mem.{0, 0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (Sym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (Sym.instMembershipSym.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) k (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (OfNat.ofNat.{0} (Fin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) 0 (Fin.instOfNatFin (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) 0 (NeZero.succ n))) s)) (Sym.{0} (Fin (Nat.succ n)) k)
+Case conversion may be inaccurate. Consider using '#align sym.E1 Sym.e1ₓ'. -/
/-- Over `fin n+1`, the multisets of size `k+1` containing `0` are equivalent to those of size `k`,
as demonstrated by respectively erasing or appending `0`.
-/
@@ -77,6 +83,12 @@ protected def e1 {n k : ℕ} : { s : Sym (Fin n.succ) k.succ // ↑0 ∈ s } ≃
right_inv s := by simp
#align sym.E1 Sym.e1
+/- warning: sym.E2 -> Sym.e2 is a dubious translation:
+lean 3 declaration is
+ forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (fun (s : Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) => Not (Membership.Mem.{0, 0} (Fin (Nat.succ (Nat.succ n))) (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (Sym.hasMem.{0} (Fin (Nat.succ (Nat.succ n))) k) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat (Fin (Nat.succ (Nat.succ n))) (HasLiftT.mk.{1, 1} Nat (Fin (Nat.succ (Nat.succ n))) (CoeTCₓ.coe.{1, 1} Nat (Fin (Nat.succ (Nat.succ n))) (Nat.castCoe.{0} (Fin (Nat.succ (Nat.succ n))) (AddMonoidWithOne.toNatCast.{0} (Fin (Nat.succ (Nat.succ n))) (Fin.addMonoidWithOne (Nat.succ (Nat.succ n)) (Sym.e2._proof_1 n)))))) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) s))) (Sym.{0} (Fin (Nat.succ n)) k)
+but is expected to have type
+ forall {n : Nat} {k : Nat}, Equiv.{1, 1} (Subtype.{1} (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (fun (s : Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) => Not (Membership.mem.{0, 0} (Fin (Nat.succ (Nat.succ n))) (Sym.{0} (Fin (Nat.succ (Nat.succ n))) k) (Sym.instMembershipSym.{0} (Fin (Nat.succ (Nat.succ n))) k) (OfNat.ofNat.{0} (Fin (Nat.succ (Nat.succ n))) 0 (Fin.instOfNatFin (Nat.succ (Nat.succ n)) 0 (NeZero.succ (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) n (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))) s))) (Sym.{0} (Fin (Nat.succ n)) k)
+Case conversion may be inaccurate. Consider using '#align sym.E2 Sym.e2ₓ'. -/
/-- The multisets of size `k` over `fin n+2` not containing `0`
are equivalent to those of size `k` over `fin n+1`,
as demonstrated by respectively decrementing or incrementing every element of the multiset.
@@ -100,6 +112,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
rw [← Fin.zero_succAbove v, ← @Fin.castSucc_zero n.succ, Fin.predAbove_succAbove 0 v]
#align sym.E2 Sym.e2
+#print Sym.card_sym_fin_eq_multichoose /-
theorem card_sym_fin_eq_multichoose (n k : ℕ) : card (Sym (Fin n) k) = multichoose n k :=
by
apply @pincer_recursion fun n k => card (Sym (Fin n) k) = multichoose n k
@@ -119,7 +132,9 @@ theorem card_sym_fin_eq_multichoose (n k : ℕ) : card (Sym (Fin n) k) = multich
apply (Equiv.sumCongr sym.E1.symm sym.E2.symm).trans
apply Equiv.sumCompl
#align sym.card_sym_fin_eq_multichoose Sym.card_sym_fin_eq_multichoose
+-/
+#print Sym.card_sym_eq_multichoose /-
/-- For any fintype `α` of cardinality `n`, `card (sym α k) = multichoose (card α) k` -/
theorem card_sym_eq_multichoose (α : Type _) (k : ℕ) [Fintype α] [Fintype (Sym α k)] :
card (Sym α k) = multichoose (card α) k :=
@@ -127,13 +142,16 @@ theorem card_sym_eq_multichoose (α : Type _) (k : ℕ) [Fintype α] [Fintype (S
rw [← card_sym_fin_eq_multichoose]
exact card_congr (equiv_congr (equiv_fin α))
#align sym.card_sym_eq_multichoose Sym.card_sym_eq_multichoose
+-/
+#print Sym.card_sym_eq_choose /-
/-- The *stars and bars* lemma: the cardinality of `sym α k` is equal to
`nat.choose (card α + k - 1) k`. -/
theorem card_sym_eq_choose {α : Type _} [Fintype α] (k : ℕ) [Fintype (Sym α k)] :
card (Sym α k) = (card α + k - 1).choose k := by
rw [card_sym_eq_multichoose, Nat.multichoose_eq]
#align sym.card_sym_eq_choose Sym.card_sym_eq_choose
+-/
end Sym
@@ -143,6 +161,7 @@ namespace Sym2
variable [DecidableEq α]
+#print Sym2.card_image_diag /-
/-- The `diag` of `s : finset α` is sent on a finset of `sym2 α` of card `s.card`. -/
theorem card_image_diag (s : Finset α) : (s.diag.image Quotient.mk').card = s.card :=
by
@@ -153,7 +172,9 @@ theorem card_image_diag (s : Finset α) : (s.diag.image Quotient.mk').card = s.c
· simp only [mem_coe, mem_diag] at hx
rw [hx.2]
#align sym2.card_image_diag Sym2.card_image_diag
+-/
+#print Sym2.two_mul_card_image_offDiag /-
theorem two_mul_card_image_offDiag (s : Finset α) :
2 * (s.offDiag.image Quotient.mk').card = s.offDiag.card :=
by
@@ -178,7 +199,9 @@ theorem two_mul_card_image_offDiag (s : Finset α) :
simp only [not_and, Prod.mk.inj_iff, mem_singleton]
exact fun _ => hxy'
#align sym2.two_mul_card_image_off_diag Sym2.two_mul_card_image_offDiag
+-/
+#print Sym2.card_image_offDiag /-
/-- The `off_diag` of `s : finset α` is sent on a finset of `sym2 α` of card `s.off_diag.card / 2`.
This is because every element `⟦(x, y)⟧` of `sym2 α` not on the diagonal comes from exactly two
pairs: `(x, y)` and `(y, x)`. -/
@@ -187,7 +210,9 @@ theorem card_image_offDiag (s : Finset α) : (s.offDiag.image Quotient.mk').card
rw [Nat.choose_two_right, mul_tsub, mul_one, ← off_diag_card,
Nat.div_eq_of_eq_mul_right zero_lt_two (two_mul_card_image_off_diag s).symm]
#align sym2.card_image_off_diag Sym2.card_image_offDiag
+-/
+#print Sym2.card_subtype_diag /-
theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card α :=
by
convert card_image_diag (univ : Finset α)
@@ -197,7 +222,9 @@ theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card
obtain ⟨a, ha⟩ := Quotient.exists_rep x
exact and_iff_right ⟨a, mem_univ _, ha⟩
#align sym2.card_subtype_diag Sym2.card_subtype_diag
+-/
+#print Sym2.card_subtype_not_diag /-
theorem card_subtype_not_diag [Fintype α] : card { a : Sym2 α // ¬a.IsDiag } = (card α).choose 2 :=
by
convert card_image_off_diag (univ : Finset α)
@@ -207,7 +234,9 @@ theorem card_subtype_not_diag [Fintype α] : card { a : Sym2 α // ¬a.IsDiag }
obtain ⟨a, ha⟩ := Quotient.exists_rep x
exact and_iff_right ⟨a, mem_univ _, ha⟩
#align sym2.card_subtype_not_diag Sym2.card_subtype_not_diag
+-/
+#print Finset.card_sym2 /-
/-- Finset **stars and bars** for the case `n = 2`. -/
theorem Finset.card_sym2 (s : Finset α) : s.Sym2.card = s.card * (s.card + 1) / 2 :=
by
@@ -222,11 +251,14 @@ theorem Finset.card_sym2 (s : Finset α) : s.Sym2.card = s.card * (s.card + 1) /
rw [hab]
exact is_diag_mk_of_mem_diag ha
#align finset.card_sym2 Finset.card_sym2
+-/
+#print Sym2.card /-
/-- Type **stars and bars** for the case `n = 2`. -/
protected theorem card [Fintype α] : card (Sym2 α) = card α * (card α + 1) / 2 :=
Finset.card_sym2 _
#align sym2.card Sym2.card
+-/
end Sym2
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
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>
@@ -104,7 +104,6 @@ theorem card_sym_fin_eq_multichoose : ∀ n k : ℕ, card (Sym (Fin n) k) = mult
refine Fintype.card_congr (Equiv.symm ?_)
apply (Sym.e1.symm.sumCongr Sym.e2.symm).trans
apply Equiv.sumCompl
- termination_by n k => n + k
#align sym.card_sym_fin_eq_multichoose Sym.card_sym_fin_eq_multichoose
/-- For any fintype `α` of cardinality `n`, `card (Sym α k) = multichoose (card α) k`. -/
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -93,7 +93,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
set_option linter.uppercaseLean3 false in
#align sym.E2 Sym.e2
--- porting note: use eqn compiler instead of `pincerRecursion` to make cases more readable
+-- Porting note: use eqn compiler instead of `pincerRecursion` to make cases more readable
theorem card_sym_fin_eq_multichoose : ∀ n k : ℕ, card (Sym (Fin n) k) = multichoose n k
| n, 0 => by simp
| 0, k + 1 => by rw [multichoose_zero_succ]; exact card_eq_zero
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>
@@ -104,7 +104,7 @@ theorem card_sym_fin_eq_multichoose : ∀ n k : ℕ, card (Sym (Fin n) k) = mult
refine Fintype.card_congr (Equiv.symm ?_)
apply (Sym.e1.symm.sumCongr Sym.e2.symm).trans
apply Equiv.sumCompl
- termination_by card_sym_fin_eq_multichoose n k => n + k
+ termination_by n k => n + k
#align sym.card_sym_fin_eq_multichoose Sym.card_sym_fin_eq_multichoose
/-- For any fintype `α` of cardinality `n`, `card (Sym α k) = multichoose (card α) k`. -/
@@ -6,6 +6,7 @@ Authors: Yaël Dillies, Bhavik Mehta, Huỳnh Trần Khanh, Stuart Presnell
import Mathlib.Algebra.BigOperators.Basic
import Mathlib.Data.Finset.Sym
import Mathlib.Data.Fintype.Sum
+import Mathlib.Data.Fintype.Prod
#align_import data.sym.card from "leanprover-community/mathlib"@"0bd2ea37bcba5769e14866170f251c9bc64e35d7"
Sym2
's global Prod
setoid instance, use s(x, y)
notation for unordered pairs (#8729)
The Sym2
type used a global setoid instance on α × α
so that ⟦(x, y)⟧
could stand for an unordered pair using standard Quotient
syntax. This commit refactors Sym2
to not use Quotient
and instead use its own s(x, y)
notation. One benefit to this is that this notation produces a term with type Sym2
rather than Quotient
.
The Fintype
instance for Sym2
is in Mathlib.Data.Finset.Sym
. We switch from using the one for Quotient
because it does not require DecidableEq
.
@@ -129,68 +129,61 @@ namespace Sym2
variable [DecidableEq α]
/-- The `diag` of `s : Finset α` is sent on a finset of `Sym2 α` of card `s.card`. -/
-theorem card_image_diag (s : Finset α) : (s.diag.image (Quotient.mk _)).card = s.card := by
+theorem card_image_diag (s : Finset α) : (s.diag.image Sym2.mk).card = s.card := by
rw [card_image_of_injOn, diag_card]
rintro ⟨x₀, x₁⟩ hx _ _ h
- cases Quotient.eq'.1 h
+ cases Sym2.eq.1 h
· rfl
· simp only [mem_coe, mem_diag] at hx
rw [hx.2]
#align sym2.card_image_diag Sym2.card_image_diag
theorem two_mul_card_image_offDiag (s : Finset α) :
- 2 * (s.offDiag.image (Quotient.mk _)).card = s.offDiag.card := by
- rw [card_eq_sum_card_image (Quotient.mk _ : α × α → _), sum_const_nat (Quotient.ind' _), mul_comm]
- rintro ⟨x, y⟩ hxy
+ 2 * (s.offDiag.image Sym2.mk).card = s.offDiag.card := by
+ rw [card_eq_sum_card_image (Sym2.mk : α × α → _), sum_const_nat (Sym2.ind _), mul_comm]
+ rintro x y hxy
simp_rw [mem_image, mem_offDiag] at hxy
obtain ⟨a, ⟨ha₁, ha₂, ha⟩, h⟩ := hxy
- replace h := Quotient.eq.1 h
+ replace h := Sym2.eq.1 h
obtain ⟨hx, hy, hxy⟩ : x ∈ s ∧ y ∈ s ∧ x ≠ y := by
cases h <;> refine' ⟨‹_›, ‹_›, _⟩ <;> [exact ha; exact ha.symm]
have hxy' : y ≠ x := hxy.symm
- have : (s.offDiag.filter fun z => ⟦z⟧ = ⟦(x, y)⟧) = ({(x, y), (y, x)} : Finset _) := by
+ have : (s.offDiag.filter fun z => Sym2.mk z = s(x, y)) = ({(x, y), (y, x)} : Finset _) := by
ext ⟨x₁, y₁⟩
rw [mem_filter, mem_insert, mem_singleton, Sym2.eq_iff, Prod.mk.inj_iff, Prod.mk.inj_iff,
and_iff_right_iff_imp]
-- `hxy'` is used in `exact`
rintro (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩) <;> rw [mem_offDiag] <;> exact ⟨‹_›, ‹_›, ‹_›⟩
- dsimp only [Quotient.mk''_eq_mk] -- Porting note: Added `dsimp`
rw [this, card_insert_of_not_mem, card_singleton]
simp only [not_and, Prod.mk.inj_iff, mem_singleton]
exact fun _ => hxy'
#align sym2.two_mul_card_image_off_diag Sym2.two_mul_card_image_offDiag
/-- The `offDiag` of `s : Finset α` is sent on a finset of `Sym2 α` of card `s.offDiag.card / 2`.
-This is because every element `⟦(x, y)⟧` of `Sym2 α` not on the diagonal comes from exactly two
+This is because every element `s(x, y)` of `Sym2 α` not on the diagonal comes from exactly two
pairs: `(x, y)` and `(y, x)`. -/
theorem card_image_offDiag (s : Finset α) :
- (s.offDiag.image (Quotient.mk _)).card = s.card.choose 2 := by
+ (s.offDiag.image Sym2.mk).card = s.card.choose 2 := by
rw [Nat.choose_two_right, mul_tsub, mul_one, ← offDiag_card,
Nat.div_eq_of_eq_mul_right zero_lt_two (two_mul_card_image_offDiag s).symm]
#align sym2.card_image_off_diag Sym2.card_image_offDiag
theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card α := by
convert card_image_diag (univ : Finset α)
- -- Porting note (kmill): Quotient.mk and Quotient.mk'' are syntactically different.
- -- `filter_image_quotient_mk''_isDiag` was part of rw
- refine Eq.trans ?_ congr(Finset.card $(filter_image_quotient_mk''_isDiag univ))
- rw [Fintype.card_of_subtype]
+ rw [← filter_image_mk_isDiag, Fintype.card_of_subtype]
rintro x
rw [mem_filter, univ_product_univ, mem_image]
- obtain ⟨a, ha⟩ := Quotient.exists_rep x
+ obtain ⟨a, ha⟩ := Quot.exists_rep x
exact and_iff_right ⟨a, mem_univ _, ha⟩
#align sym2.card_subtype_diag Sym2.card_subtype_diag
theorem card_subtype_not_diag [Fintype α] :
card { a : Sym2 α // ¬a.IsDiag } = (card α).choose 2 := by
convert card_image_offDiag (univ : Finset α)
- -- Porting note (kmill): Quotient.mk and Quotient.mk'' are syntactically different.
- -- `filter_image_quotient_mk''_not_isDiag` was part of rw
- refine Eq.trans ?_ congr(Finset.card $(filter_image_quotient_mk''_not_isDiag univ))
- rw [Fintype.card_of_subtype]
+ rw [← filter_image_mk_not_isDiag, Fintype.card_of_subtype]
rintro x
rw [mem_filter, univ_product_univ, mem_image]
- obtain ⟨a, ha⟩ := Quotient.exists_rep x
+ obtain ⟨a, ha⟩ := Quot.exists_rep x
exact and_iff_right ⟨a, mem_univ _, ha⟩
#align sym2.card_subtype_not_diag Sym2.card_subtype_not_diag
@@ -129,7 +129,7 @@ namespace Sym2
variable [DecidableEq α]
/-- The `diag` of `s : Finset α` is sent on a finset of `Sym2 α` of card `s.card`. -/
-theorem card_image_diag (s : Finset α) : (s.diag.image Quotient.mk').card = s.card := by
+theorem card_image_diag (s : Finset α) : (s.diag.image (Quotient.mk _)).card = s.card := by
rw [card_image_of_injOn, diag_card]
rintro ⟨x₀, x₁⟩ hx _ _ h
cases Quotient.eq'.1 h
@@ -139,8 +139,8 @@ theorem card_image_diag (s : Finset α) : (s.diag.image Quotient.mk').card = s.c
#align sym2.card_image_diag Sym2.card_image_diag
theorem two_mul_card_image_offDiag (s : Finset α) :
- 2 * (s.offDiag.image Quotient.mk').card = s.offDiag.card := by
- rw [card_eq_sum_card_image (Quotient.mk' : α × α → _), sum_const_nat (Quotient.ind' _), mul_comm]
+ 2 * (s.offDiag.image (Quotient.mk _)).card = s.offDiag.card := by
+ rw [card_eq_sum_card_image (Quotient.mk _ : α × α → _), sum_const_nat (Quotient.ind' _), mul_comm]
rintro ⟨x, y⟩ hxy
simp_rw [mem_image, mem_offDiag] at hxy
obtain ⟨a, ⟨ha₁, ha₂, ha⟩, h⟩ := hxy
@@ -154,7 +154,7 @@ theorem two_mul_card_image_offDiag (s : Finset α) :
and_iff_right_iff_imp]
-- `hxy'` is used in `exact`
rintro (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩) <;> rw [mem_offDiag] <;> exact ⟨‹_›, ‹_›, ‹_›⟩
- dsimp [Quotient.mk', Quotient.mk''_eq_mk] -- Porting note: Added `dsimp`
+ dsimp only [Quotient.mk''_eq_mk] -- Porting note: Added `dsimp`
rw [this, card_insert_of_not_mem, card_singleton]
simp only [not_and, Prod.mk.inj_iff, mem_singleton]
exact fun _ => hxy'
@@ -164,15 +164,17 @@ theorem two_mul_card_image_offDiag (s : Finset α) :
This is because every element `⟦(x, y)⟧` of `Sym2 α` not on the diagonal comes from exactly two
pairs: `(x, y)` and `(y, x)`. -/
theorem card_image_offDiag (s : Finset α) :
- (s.offDiag.image Quotient.mk').card = s.card.choose 2 := by
+ (s.offDiag.image (Quotient.mk _)).card = s.card.choose 2 := by
rw [Nat.choose_two_right, mul_tsub, mul_one, ← offDiag_card,
Nat.div_eq_of_eq_mul_right zero_lt_two (two_mul_card_image_offDiag s).symm]
#align sym2.card_image_off_diag Sym2.card_image_offDiag
theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card α := by
convert card_image_diag (univ : Finset α)
- simp_rw [Quotient.mk'_eq_mk, ← Quotient.mk''_eq_mk]
- rw [Fintype.card_of_subtype, ← filter_image_quotient_mk''_isDiag]
+ -- Porting note (kmill): Quotient.mk and Quotient.mk'' are syntactically different.
+ -- `filter_image_quotient_mk''_isDiag` was part of rw
+ refine Eq.trans ?_ congr(Finset.card $(filter_image_quotient_mk''_isDiag univ))
+ rw [Fintype.card_of_subtype]
rintro x
rw [mem_filter, univ_product_univ, mem_image]
obtain ⟨a, ha⟩ := Quotient.exists_rep x
@@ -182,31 +184,18 @@ theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card
theorem card_subtype_not_diag [Fintype α] :
card { a : Sym2 α // ¬a.IsDiag } = (card α).choose 2 := by
convert card_image_offDiag (univ : Finset α)
- simp_rw [Quotient.mk'_eq_mk, ← Quotient.mk''_eq_mk] -- Porting note: Added `simp_rw`
- rw [Fintype.card_of_subtype, ← filter_image_quotient_mk''_not_isDiag]
+ -- Porting note (kmill): Quotient.mk and Quotient.mk'' are syntactically different.
+ -- `filter_image_quotient_mk''_not_isDiag` was part of rw
+ refine Eq.trans ?_ congr(Finset.card $(filter_image_quotient_mk''_not_isDiag univ))
+ rw [Fintype.card_of_subtype]
rintro x
rw [mem_filter, univ_product_univ, mem_image]
obtain ⟨a, ha⟩ := Quotient.exists_rep x
exact and_iff_right ⟨a, mem_univ _, ha⟩
#align sym2.card_subtype_not_diag Sym2.card_subtype_not_diag
-/-- Finset **stars and bars** for the case `n = 2`. -/
-theorem _root_.Finset.card_sym2 (s : Finset α) : s.sym2.card = s.card * (s.card + 1) / 2 := by
- rw [← image_diag_union_image_offDiag, card_union_eq, Sym2.card_image_diag,
- Sym2.card_image_offDiag, Nat.choose_two_right, add_comm, ← Nat.triangle_succ, Nat.succ_sub_one,
- mul_comm]
- rw [disjoint_left]
- rintro m ha hb
- rw [mem_image] at ha hb
- obtain ⟨⟨a, ha, rfl⟩, ⟨b, hb, hab⟩⟩ := ha, hb
- refine' not_isDiag_mk'_of_mem_offDiag hb _
- dsimp [Quotient.mk'] at hab -- Porting note: Added `dsimp`
- rw [hab]
- exact isDiag_mk'_of_mem_diag ha
-#align finset.card_sym2 Finset.card_sym2
-
/-- Type **stars and bars** for the case `n = 2`. -/
-protected theorem card [Fintype α] : card (Sym2 α) = card α * (card α + 1) / 2 :=
+protected theorem card [Fintype α] : card (Sym2 α) = Nat.choose (card α + 1) 2 :=
Finset.card_sym2 _
#align sym2.card Sym2.card
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>
@@ -171,7 +171,7 @@ theorem card_image_offDiag (s : Finset α) :
theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card α := by
convert card_image_diag (univ : Finset α)
- simp_rw [Quotient.mk', ← Quotient.mk''_eq_mk] -- Porting note: Added `simp_rw`
+ simp_rw [Quotient.mk'_eq_mk, ← Quotient.mk''_eq_mk]
rw [Fintype.card_of_subtype, ← filter_image_quotient_mk''_isDiag]
rintro x
rw [mem_filter, univ_product_univ, mem_image]
@@ -182,7 +182,7 @@ theorem card_subtype_diag [Fintype α] : card { a : Sym2 α // a.IsDiag } = card
theorem card_subtype_not_diag [Fintype α] :
card { a : Sym2 α // ¬a.IsDiag } = (card α).choose 2 := by
convert card_image_offDiag (univ : Finset α)
- simp_rw [Quotient.mk', ← Quotient.mk''_eq_mk] -- Porting note: Added `simp_rw`
+ simp_rw [Quotient.mk'_eq_mk, ← Quotient.mk''_eq_mk] -- Porting note: Added `simp_rw`
rw [Fintype.card_of_subtype, ← filter_image_quotient_mk''_not_isDiag]
rintro x
rw [mem_filter, univ_product_univ, mem_image]
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -55,7 +55,7 @@ stars and bars, multichoose
open Finset Fintype Function Sum Nat
-variable {α β : Type _}
+variable {α β : Type*}
namespace Sym
@@ -107,7 +107,7 @@ theorem card_sym_fin_eq_multichoose : ∀ n k : ℕ, card (Sym (Fin n) k) = mult
#align sym.card_sym_fin_eq_multichoose Sym.card_sym_fin_eq_multichoose
/-- For any fintype `α` of cardinality `n`, `card (Sym α k) = multichoose (card α) k`. -/
-theorem card_sym_eq_multichoose (α : Type _) (k : ℕ) [Fintype α] [Fintype (Sym α k)] :
+theorem card_sym_eq_multichoose (α : Type*) (k : ℕ) [Fintype α] [Fintype (Sym α k)] :
card (Sym α k) = multichoose (card α) k := by
rw [← card_sym_fin_eq_multichoose]
exact card_congr (equivCongr (equivFin α))
@@ -115,7 +115,7 @@ theorem card_sym_eq_multichoose (α : Type _) (k : ℕ) [Fintype α] [Fintype (S
/-- The *stars and bars* lemma: the cardinality of `Sym α k` is equal to
`Nat.choose (card α + k - 1) k`. -/
-theorem card_sym_eq_choose {α : Type _} [Fintype α] (k : ℕ) [Fintype (Sym α k)] :
+theorem card_sym_eq_choose {α : Type*} [Fintype α] (k : ℕ) [Fintype (Sym α k)] :
card (Sym α k) = (card α + k - 1).choose k := by
rw [card_sym_eq_multichoose, Nat.multichoose_eq]
#align sym.card_sym_eq_choose Sym.card_sym_eq_choose
@@ -2,16 +2,13 @@
Copyright (c) 2021 Yaël Dillies, Bhavik Mehta. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies, Bhavik Mehta, Huỳnh Trần Khanh, Stuart Presnell
-
-! This file was ported from Lean 3 source module data.sym.card
-! leanprover-community/mathlib commit 0bd2ea37bcba5769e14866170f251c9bc64e35d7
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Algebra.BigOperators.Basic
import Mathlib.Data.Finset.Sym
import Mathlib.Data.Fintype.Sum
+#align_import data.sym.card from "leanprover-community/mathlib"@"0bd2ea37bcba5769e14866170f251c9bc64e35d7"
+
/-!
# Stars and bars
Co-authored-by: Komyyy <pol_tta@outlook.jp> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>
@@ -91,7 +91,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
refine (Sym.map_congr fun v hv ↦ ?_).trans (map_id' _)
exact Fin.succAbove_predAbove (ne_of_mem_of_not_mem hv s.2)
right_inv s := by
- simp only [map_map, comp_apply, ← Fin.castSuccEmb_zero, Fin.predAbove_succAbove, map_id']
+ simp only [map_map, comp_apply, ← Fin.castSucc_zero, Fin.predAbove_succAbove, map_id']
set_option linter.uppercaseLean3 false in
#align sym.E2 Sym.e2
@@ -91,7 +91,7 @@ protected def e2 {n k : ℕ} : { s : Sym (Fin n.succ.succ) k // ↑0 ∉ s } ≃
refine (Sym.map_congr fun v hv ↦ ?_).trans (map_id' _)
exact Fin.succAbove_predAbove (ne_of_mem_of_not_mem hv s.2)
right_inv s := by
- simp only [map_map, comp_apply, ← Fin.castSucc_zero, Fin.predAbove_succAbove, map_id']
+ simp only [map_map, comp_apply, ← Fin.castSuccEmb_zero, Fin.predAbove_succAbove, map_id']
set_option linter.uppercaseLean3 false in
#align sym.E2 Sym.e2
The main breaking change is that tac <;> [t1, t2]
is now written tac <;> [t1; t2]
, to avoid clashing with tactics like cases
and use
that take comma-separated lists.
@@ -149,7 +149,7 @@ theorem two_mul_card_image_offDiag (s : Finset α) :
obtain ⟨a, ⟨ha₁, ha₂, ha⟩, h⟩ := hxy
replace h := Quotient.eq.1 h
obtain ⟨hx, hy, hxy⟩ : x ∈ s ∧ y ∈ s ∧ x ≠ y := by
- cases h <;> refine' ⟨‹_›, ‹_›, _⟩ <;> [exact ha, exact ha.symm]
+ cases h <;> refine' ⟨‹_›, ‹_›, _⟩ <;> [exact ha; exact ha.symm]
have hxy' : y ≠ x := hxy.symm
have : (s.offDiag.filter fun z => ⟦z⟧ = ⟦(x, y)⟧) = ({(x, y), (y, x)} : Finset _) := by
ext ⟨x₁, y₁⟩
The unported dependencies are