@@ -20,6 +20,7 @@ generally for sums going from `0` to `n`.
2020This refines files `Data.List.NatAntidiagonal` and `Data.Multiset.NatAntidiagonal`.
2121-/
2222
23+ open Function
2324
2425namespace Finset
2526
@@ -51,7 +52,7 @@ theorem antidiagonal_succ (n : ℕ) :
5152 antidiagonal (n + 1 ) =
5253 cons (0 , n + 1 )
5354 ((antidiagonal n).map
54- (Function. Embedding.prodMap ⟨Nat.succ, Nat.succ_injective⟩ (Function. Embedding.refl _)))
55+ (Embedding.prodMap ⟨Nat.succ, Nat.succ_injective⟩ (Embedding.refl _)))
5556 (by simp) := by
5657 apply eq_of_veq
5758 rw [cons_val, map_val]
@@ -62,7 +63,7 @@ theorem antidiagonal_succ' (n : ℕ) :
6263 antidiagonal (n + 1 ) =
6364 cons (n + 1 , 0 )
6465 ((antidiagonal n).map
65- (Function. Embedding.prodMap (Function. Embedding.refl _) ⟨Nat.succ, Nat.succ_injective⟩))
66+ (Embedding.prodMap (Embedding.refl _) ⟨Nat.succ, Nat.succ_injective⟩))
6667 (by simp) := by
6768 apply eq_of_veq
6869 rw [cons_val, map_val]
@@ -74,19 +75,24 @@ theorem antidiagonal_succ_succ' {n : ℕ} :
7475 cons (0 , n + 2 )
7576 (cons (n + 2 , 0 )
7677 ((antidiagonal n).map
77- (Function. Embedding.prodMap ⟨Nat.succ, Nat.succ_injective⟩
78+ (Embedding.prodMap ⟨Nat.succ, Nat.succ_injective⟩
7879 ⟨Nat.succ, Nat.succ_injective⟩)) <|
7980 by simp)
8081 (by simp) := by
8182 simp_rw [antidiagonal_succ (n + 1 ), antidiagonal_succ', Finset.map_cons, map_map]
8283 rfl
8384#align finset.nat.antidiagonal_succ_succ' Finset.Nat.antidiagonal_succ_succ'
8485
85- theorem map_swap_antidiagonal {n : ℕ} :
86+ /-- See also `Finset.map.map_prodComm_antidiagonal`. -/
87+ @[simp] theorem map_swap_antidiagonal {n : ℕ} :
8688 (antidiagonal n).map ⟨Prod.swap, Prod.swap_injective⟩ = antidiagonal n :=
8789 eq_of_veq <| by simp [antidiagonal, Multiset.Nat.map_swap_antidiagonal]
8890#align finset.nat.map_swap_antidiagonal Finset.Nat.map_swap_antidiagonal
8991
92+ @[simp] theorem map_prodComm_antidiagonal {n : ℕ} :
93+ (antidiagonal n).map (Equiv.prodComm ℕ ℕ) = antidiagonal n :=
94+ map_swap_antidiagonal
95+
9096/-- A point in the antidiagonal is determined by its first co-ordinate. -/
9197theorem antidiagonal_congr {n : ℕ} {p q : ℕ × ℕ} (hp : p ∈ antidiagonal n)
9298 (hq : q ∈ antidiagonal n) : p = q ↔ p.fst = q.fst := by
@@ -122,10 +128,61 @@ theorem filter_snd_eq_antidiagonal (n m : ℕ) :
122128 filter (fun x : ℕ × ℕ ↦ x.snd = m) (antidiagonal n) = if m ≤ n then {(n - m, m)} else ∅ := by
123129 have : (fun x : ℕ × ℕ ↦ (x.snd = m)) ∘ Prod.swap = fun x : ℕ × ℕ ↦ x.fst = m := by
124130 ext; simp
125- rw [← map_swap_antidiagonal]
126- simp [filter_map, this, filter_fst_eq_antidiagonal, apply_ite (Finset.map _)]
131+ rw [← map_swap_antidiagonal, filter_map ]
132+ simp [this, filter_fst_eq_antidiagonal, apply_ite (Finset.map _)]
127133#align finset.nat.filter_snd_eq_antidiagonal Finset.Nat.filter_snd_eq_antidiagonal
128134
135+ @[simp] lemma antidiagonal_filter_snd_le_of_le {n k : ℕ} (h : k ≤ n) :
136+ (antidiagonal n).filter (fun a ↦ a.snd ≤ k) = (antidiagonal k).map
137+ (Embedding.prodMap ⟨_, add_left_injective (n - k)⟩ (Embedding.refl ℕ)) := by
138+ ext ⟨i, j⟩
139+ suffices : i + j = n ∧ j ≤ k ↔ ∃ a, a + j = k ∧ a + (n - k) = i
140+ · simpa
141+ refine' ⟨fun hi ↦ ⟨k - j, tsub_add_cancel_of_le hi.2 , _⟩, _⟩
142+ · rw [add_comm, tsub_add_eq_add_tsub h, ← hi.1 , add_assoc, Nat.add_sub_of_le hi.2 ,
143+ add_tsub_cancel_right]
144+ · rintro ⟨l, hl, rfl⟩
145+ refine' ⟨_, hl ▸ Nat.le_add_left j l⟩
146+ rw [add_assoc, add_comm, add_assoc, add_comm j l, hl]
147+ exact Nat.sub_add_cancel h
148+
149+ @[simp] lemma antidiagonal_filter_fst_le_of_le {n k : ℕ} (h : k ≤ n) :
150+ (antidiagonal n).filter (fun a ↦ a.fst ≤ k) = (antidiagonal k).map
151+ (Embedding.prodMap (Embedding.refl ℕ) ⟨_, add_left_injective (n - k)⟩) := by
152+ have aux₁ : fun a ↦ a.fst ≤ k = (fun a ↦ a.snd ≤ k) ∘ (Equiv.prodComm ℕ ℕ).symm := rfl
153+ have aux₂ : ∀ i j, (∃ a b, a + b = k ∧ b = i ∧ a + (n - k) = j) ↔
154+ ∃ a b, a + b = k ∧ a = i ∧ b + (n - k) = j :=
155+ fun i j ↦ by rw [exists_comm]; exact exists ₂_congr (fun a b ↦ by rw [add_comm])
156+ rw [← map_prodComm_antidiagonal]
157+ simp_rw [aux₁, ← map_filter, antidiagonal_filter_snd_le_of_le h, map_map]
158+ ext ⟨i, j⟩
159+ simpa using aux₂ i j
160+
161+ @[simp] lemma antidiagonal_filter_le_fst_of_le {n k : ℕ} (h : k ≤ n) :
162+ (antidiagonal n).filter (fun a ↦ k ≤ a.fst) = (antidiagonal (n - k)).map
163+ (Embedding.prodMap ⟨_, add_left_injective k⟩ (Embedding.refl ℕ)) := by
164+ ext ⟨i, j⟩
165+ suffices : i + j = n ∧ k ≤ i ↔ ∃ a, a + j = n - k ∧ a + k = i
166+ · simpa
167+ refine' ⟨fun hi ↦ ⟨i - k, _, tsub_add_cancel_of_le hi.2 ⟩, _⟩
168+ · rw [← Nat.sub_add_comm hi.2 , hi.1 ]
169+ · rintro ⟨l, hl, rfl⟩
170+ refine' ⟨_, Nat.le_add_left k l⟩
171+ rw [add_right_comm, hl]
172+ exact tsub_add_cancel_of_le h
173+
174+ @[simp] lemma antidiagonal_filter_le_snd_of_le {n k : ℕ} (h : k ≤ n) :
175+ (antidiagonal n).filter (fun a ↦ k ≤ a.snd) = (antidiagonal (n - k)).map
176+ (Embedding.prodMap (Embedding.refl ℕ) ⟨_, add_left_injective k⟩) := by
177+ have aux₁ : fun a ↦ k ≤ a.snd = (fun a ↦ k ≤ a.fst) ∘ (Equiv.prodComm ℕ ℕ).symm := rfl
178+ have aux₂ : ∀ i j, (∃ a b, a + b = n - k ∧ b = i ∧ a + k = j) ↔
179+ ∃ a b, a + b = n - k ∧ a = i ∧ b + k = j :=
180+ fun i j ↦ by rw [exists_comm]; exact exists ₂_congr (fun a b ↦ by rw [add_comm])
181+ rw [← map_prodComm_antidiagonal]
182+ simp_rw [aux₁, ← map_filter, antidiagonal_filter_le_fst_of_le h, map_map]
183+ ext ⟨i, j⟩
184+ simpa using aux₂ i j
185+
129186section EquivProd
130187
131188/-- The disjoint union of antidiagonals `Σ (n : ℕ), antidiagonal n` is equivalent to the product
0 commit comments