@@ -20,6 +20,7 @@ generally for sums going from `0` to `n`.
20
20
This refines files `Data.List.NatAntidiagonal` and `Data.Multiset.NatAntidiagonal`.
21
21
-/
22
22
23
+ open Function
23
24
24
25
namespace Finset
25
26
@@ -51,7 +52,7 @@ theorem antidiagonal_succ (n : ℕ) :
51
52
antidiagonal (n + 1 ) =
52
53
cons (0 , n + 1 )
53
54
((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 _)))
55
56
(by simp) := by
56
57
apply eq_of_veq
57
58
rw [cons_val, map_val]
@@ -62,7 +63,7 @@ theorem antidiagonal_succ' (n : ℕ) :
62
63
antidiagonal (n + 1 ) =
63
64
cons (n + 1 , 0 )
64
65
((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⟩))
66
67
(by simp) := by
67
68
apply eq_of_veq
68
69
rw [cons_val, map_val]
@@ -74,19 +75,24 @@ theorem antidiagonal_succ_succ' {n : ℕ} :
74
75
cons (0 , n + 2 )
75
76
(cons (n + 2 , 0 )
76
77
((antidiagonal n).map
77
- (Function. Embedding.prodMap ⟨Nat.succ, Nat.succ_injective⟩
78
+ (Embedding.prodMap ⟨Nat.succ, Nat.succ_injective⟩
78
79
⟨Nat.succ, Nat.succ_injective⟩)) <|
79
80
by simp)
80
81
(by simp) := by
81
82
simp_rw [antidiagonal_succ (n + 1 ), antidiagonal_succ', Finset.map_cons, map_map]
82
83
rfl
83
84
#align finset.nat.antidiagonal_succ_succ' Finset.Nat.antidiagonal_succ_succ'
84
85
85
- theorem map_swap_antidiagonal {n : ℕ} :
86
+ /-- See also `Finset.map.map_prodComm_antidiagonal`. -/
87
+ @[simp] theorem map_swap_antidiagonal {n : ℕ} :
86
88
(antidiagonal n).map ⟨Prod.swap, Prod.swap_injective⟩ = antidiagonal n :=
87
89
eq_of_veq <| by simp [antidiagonal, Multiset.Nat.map_swap_antidiagonal]
88
90
#align finset.nat.map_swap_antidiagonal Finset.Nat.map_swap_antidiagonal
89
91
92
+ @[simp] theorem map_prodComm_antidiagonal {n : ℕ} :
93
+ (antidiagonal n).map (Equiv.prodComm ℕ ℕ) = antidiagonal n :=
94
+ map_swap_antidiagonal
95
+
90
96
/-- A point in the antidiagonal is determined by its first co-ordinate. -/
91
97
theorem antidiagonal_congr {n : ℕ} {p q : ℕ × ℕ} (hp : p ∈ antidiagonal n)
92
98
(hq : q ∈ antidiagonal n) : p = q ↔ p.fst = q.fst := by
@@ -122,10 +128,61 @@ theorem filter_snd_eq_antidiagonal (n m : ℕ) :
122
128
filter (fun x : ℕ × ℕ ↦ x.snd = m) (antidiagonal n) = if m ≤ n then {(n - m, m)} else ∅ := by
123
129
have : (fun x : ℕ × ℕ ↦ (x.snd = m)) ∘ Prod.swap = fun x : ℕ × ℕ ↦ x.fst = m := by
124
130
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 _)]
127
133
#align finset.nat.filter_snd_eq_antidiagonal Finset.Nat.filter_snd_eq_antidiagonal
128
134
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
+
129
186
section EquivProd
130
187
131
188
/-- The disjoint union of antidiagonals `Σ (n : ℕ), antidiagonal n` is equivalent to the product
0 commit comments