Skip to content

Commit dcfb782

Browse files
committed
feat: Adding/removing an element from a product of finsets (#7898)
Lemmas about the interaction of `Fintype.piFinset` with `Fin.consEquiv`, `Fin.snocEquiv`, `Fin.insertNthEquiv`.
1 parent dfcf58d commit dcfb782

File tree

1 file changed

+70
-17
lines changed

1 file changed

+70
-17
lines changed

Mathlib/Data/Fin/Tuple/Finset.lean

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,87 @@ Copyright (c) 2023 Bolton Bailey. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Bolton Bailey
55
-/
6-
import Mathlib.Data.Fin.Tuple.Basic
6+
import Mathlib.Data.Finset.Prod
77
import Mathlib.Data.Fintype.Pi
8+
import Mathlib.Logic.Equiv.Fin
89

910
/-!
1011
# Fin-indexed tuples of finsets
1112
-/
1213

13-
open Fintype
14+
open Fin Fintype
1415

1516
namespace Fin
16-
variable {n : ℕ} {α : Fin (n + 1) → Type*}
17+
variable {n : ℕ} {α : Fin (n + 1) → Type*} {f : ∀ i, α i} {s : ∀ i, Finset (α i)} {p : Fin (n + 1)}
18+
19+
open Fintype
20+
21+
lemma mem_piFinset_iff_zero_tail :
22+
f ∈ Fintype.piFinset s ↔ f 0 ∈ s 0 ∧ tail f ∈ piFinset (tail s) := by
23+
simp only [Fintype.mem_piFinset, forall_fin_succ, tail]
1724

18-
lemma mem_piFinset_succ {x : ∀ i, α i} {s : ∀ i, Finset (α i)} :
19-
x ∈ piFinset s ↔ x 0 ∈ s 0 ∧ tail x ∈ piFinset (tail s) := by
20-
simp only [mem_piFinset, forall_iff_succ, tail]
25+
lemma mem_piFinset_iff_last_init :
26+
f ∈ piFinset s ↔ f (last n) ∈ s (last n) ∧ init f ∈ piFinset (init s) := by
27+
simp only [Fintype.mem_piFinset, forall_fin_succ', init, and_comm]
2128

22-
lemma mem_piFinset_succ' {x : ∀ i, α i} {s : ∀ i, Finset (α i)} :
23-
x ∈ piFinset s ↔ x (last n) ∈ s (last n) ∧ init x ∈ piFinset (init s) := by
24-
simp only [mem_piFinset, forall_iff_castSucc, init]
29+
lemma mem_piFinset_iff_pivot_removeNth (p : Fin (n + 1)) :
30+
f ∈ piFinset s ↔ f p ∈ s p ∧ removeNth p f ∈ piFinset (removeNth p s) := by
31+
simp only [Fintype.mem_piFinset, forall_iff_succAbove p, removeNth]
2532

26-
lemma cons_mem_piFinset_cons {x₀ : α 0} {x : ∀ i : Fin n, α i.succ}
27-
{s₀ : Finset (α 0)} {s : ∀ i : Fin n, Finset (α i.succ)} :
28-
cons x₀ x ∈ piFinset (cons s₀ s) ↔ x₀ ∈ s₀ ∧ x ∈ piFinset s := by
29-
simp_rw [mem_piFinset_succ, cons_zero, tail_cons]
33+
@[deprecated (since := "2024-09-20")] alias mem_piFinset_succ := mem_piFinset_iff_zero_tail
34+
@[deprecated (since := "2024-09-20")] alias mem_piFinset_succ' := mem_piFinset_iff_last_init
3035

31-
lemma snoc_mem_piFinset_snoc {x : ∀ i : Fin n, α i.castSucc} {xₙ : α (.last n)}
32-
{s : ∀ i : Fin n, Finset (α i.castSucc)} {sₙ : Finset (α <| .last n)} :
33-
snoc x xₙ ∈ piFinset (snoc s sₙ) ↔ xₙ ∈ sₙ ∧ x ∈ piFinset s := by
34-
simp_rw [mem_piFinset_succ', init_snoc, snoc_last]
36+
lemma cons_mem_piFinset_cons {x_zero : α 0} {x_tail : (i : Fin n) → α i.succ}
37+
{s_zero : Finset (α 0)} {s_tail : (i : Fin n) → Finset (α i.succ)} :
38+
cons x_zero x_tail ∈ piFinset (cons s_zero s_tail) ↔
39+
x_zero ∈ s_zero ∧ x_tail ∈ piFinset s_tail := by
40+
simp_rw [mem_piFinset_iff_zero_tail, cons_zero, tail_cons]
41+
42+
lemma snoc_mem_piFinset_snoc {x_last : α (last n)} {x_init : (i : Fin n) → α i.castSucc}
43+
{s_last : Finset (α (last n))} {s_init : (i : Fin n) → Finset (α i.castSucc)} :
44+
snoc x_init x_last ∈ piFinset (snoc s_init s_last) ↔
45+
x_last ∈ s_last ∧ x_init ∈ piFinset s_init := by
46+
simp_rw [mem_piFinset_iff_last_init, init_snoc, snoc_last]
47+
48+
lemma insertNth_mem_piFinset_insertNth {x_pivot : α p} {x_remove : ∀ i, α (succAbove p i)}
49+
{s_pivot : Finset (α p)} {s_remove : ∀ i, Finset (α (succAbove p i))} :
50+
insertNth p x_pivot x_remove ∈ piFinset (insertNth p s_pivot s_remove) ↔
51+
x_pivot ∈ s_pivot ∧ x_remove ∈ piFinset s_remove := by
52+
simp [mem_piFinset_iff_pivot_removeNth p]
3553

3654
end Fin
55+
56+
namespace Finset
57+
variable {n : ℕ} {α : Fin (n + 1) → Type*} {p : Fin (n + 1)} (S : ∀ i, Finset (α i))
58+
59+
lemma map_consEquiv_filter_piFinset (P : (∀ i, α (succ i)) → Prop) [DecidablePred P] :
60+
((piFinset S).filter fun r ↦ P <| tail r).map (consEquiv α).symm.toEmbedding =
61+
S 0 ×ˢ (piFinset fun x ↦ S <| succ x).filter P := by
62+
unfold tail; ext; simp [Fin.forall_iff_succ, and_assoc]
63+
64+
lemma map_snocEquiv_filter_piFinset (P : (∀ i, α (castSucc i)) → Prop) [DecidablePred P] :
65+
((piFinset S).filter fun r ↦ P <| init r).map (snocEquiv α).symm.toEmbedding =
66+
S (last _) ×ˢ (piFinset <| init S).filter P := by
67+
unfold init; ext; simp [Fin.forall_iff_castSucc, and_assoc]
68+
69+
lemma map_insertNthEquiv_filter_piFinset (P : (∀ i, α (p.succAbove i)) → Prop) [DecidablePred P] :
70+
((piFinset S).filter fun r ↦ P <| p.removeNth r).map (p.insertNthEquiv α).symm.toEmbedding =
71+
S p ×ˢ (piFinset <| p.removeNth S).filter P := by
72+
unfold removeNth; ext; simp [Fin.forall_iff_succAbove p, and_assoc]
73+
74+
lemma card_consEquiv_filter_piFinset (P : (∀ i, α (succ i)) → Prop) [DecidablePred P] :
75+
((piFinset S).filter fun r ↦ P <| tail r).card =
76+
(S 0).card * ((piFinset fun x ↦ S <| succ x).filter P).card := by
77+
rw [← card_product, ← map_consEquiv_filter_piFinset, card_map]
78+
79+
lemma card_snocEquiv_filter_piFinset (P : (∀ i, α (castSucc i)) → Prop) [DecidablePred P] :
80+
((piFinset S).filter fun r ↦ P <| init r).card =
81+
(S (last _)).card * ((piFinset <| init S).filter P).card := by
82+
rw [← card_product, ← map_snocEquiv_filter_piFinset, card_map]
83+
84+
lemma card_insertNthEquiv_filter_piFinset (P : (∀ i, α (p.succAbove i)) → Prop) [DecidablePred P] :
85+
((piFinset S).filter fun r ↦ P <| p.removeNth r).card =
86+
(S p).card * ((piFinset <| p.removeNth S).filter P).card := by
87+
rw [← card_product, ← map_insertNthEquiv_filter_piFinset, card_map]
88+
89+
end Finset

0 commit comments

Comments
 (0)