1
1
/-
2
2
Copyright (c) 2017 Johannes Hölzl. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
- Authors: Johannes Hölzl, Floris van Doorn, Sébastien Gouëzel
4
+ Authors: Johannes Hölzl, Floris van Doorn, Sébastien Gouëzel, Alex J. Best
5
5
-/
6
6
import data.list.basic
7
7
@@ -41,10 +41,24 @@ by rw [concat_eq_append, prod_append, prod_singleton]
41
41
@[simp, to_additive]
42
42
lemma prod_join {l : list (list M)} : l.join.prod = (l.map list.prod).prod :=
43
43
by induction l; [refl, simp only [*, list.join, map, prod_append, prod_cons]]
44
+
44
45
@[to_additive]
45
46
lemma prod_eq_foldr : l.prod = foldr (*) 1 l :=
46
47
list.rec_on l rfl $ λ a l ihl, by rw [prod_cons, foldr_cons, ihl]
47
48
49
+ @[simp, priority 500 , to_additive]
50
+ theorem prod_repeat (a : M) (n : ℕ) : (repeat a n).prod = a ^ n :=
51
+ begin
52
+ induction n with n ih,
53
+ { rw pow_zero, refl },
54
+ { rw [list.repeat_succ, list.prod_cons, ih, pow_succ] }
55
+ end
56
+
57
+ @[to_additive sum_eq_card_nsmul]
58
+ lemma prod_eq_pow_card (l : list M) (m : M) (h : ∀ (x ∈ l), x = m) :
59
+ l.prod = m ^ l.length :=
60
+ by rw [← prod_repeat, ← list.eq_repeat.mpr ⟨rfl, h⟩]
61
+
48
62
@[to_additive]
49
63
lemma prod_hom_rel (l : list ι) {r : M → N → Prop } {f : ι → M} {g : ι → N} (h₁ : r 1 1 )
50
64
(h₂ : ∀ ⦃i a b⦄, r a b → r (f i * a) (g i * b)) :
@@ -102,7 +116,7 @@ lemma prod_take_succ :
102
116
| (h :: t) (n+1 ) _ := by { dsimp, rw [prod_cons, prod_cons, prod_take_succ, mul_assoc] }
103
117
104
118
/-- A list with product not one must have positive length. -/
105
- @[to_additive]
119
+ @[to_additive " A list with sum not zero must have positive length. " ]
106
120
lemma length_pos_of_prod_ne_one (L : list M) (h : L.prod ≠ 1 ) : 0 < L.length :=
107
121
by { cases L, { simp at h, cases h }, { simp } }
108
122
@@ -120,17 +134,100 @@ open mul_opposite
120
134
inhabited instance to return a garbage value on the empty list, this is not possible.
121
135
Instead, we write the statement in terms of `(L.nth 0).get_or_else 1`.
122
136
-/
123
- @[to_additive]
137
+ @[to_additive " We'd like to state this as `L.head + L.tail.sum = L.sum`, but because `L.head`
138
+ relies on an inhabited instance to return a garbage value on the empty list, this is not possible.
139
+ Instead, we write the statement in terms of `(L.nth 0).get_or_else 0`." ]
124
140
lemma nth_zero_mul_tail_prod (l : list M) : (l.nth 0 ).get_or_else 1 * l.tail.prod = l.prod :=
125
141
by cases l; simp
126
142
127
143
/-- Same as `nth_zero_mul_tail_prod`, but avoiding the `list.head` garbage complication by requiring
128
144
the list to be nonempty. -/
129
- @[to_additive]
145
+ @[to_additive " Same as `nth_zero_add_tail_sum`, but avoiding the `list.head` garbage complication
146
+ by requiring the list to be nonempty." ]
130
147
lemma head_mul_tail_prod_of_ne_nil [inhabited M] (l : list M) (h : l ≠ []) :
131
148
l.head * l.tail.prod = l.prod :=
132
149
by cases l; [contradiction, simp]
133
150
151
+ @[to_additive]
152
+ lemma prod_commute (l : list M) (y : M) (h : ∀ (x ∈ l), commute y x) : commute y l.prod :=
153
+ begin
154
+ induction l with z l IH,
155
+ { simp },
156
+ { rw list.ball_cons at h,
157
+ rw list.prod_cons,
158
+ exact commute.mul_right h.1 (IH h.2 ), }
159
+ end
160
+
161
+ @[to_additive sum_le_sum] lemma prod_le_prod' [preorder M]
162
+ [covariant_class M M (function.swap (*)) (≤)] [covariant_class M M (*) (≤)]
163
+ {l : list ι} {f g : ι → M} (h : ∀ i ∈ l, f i ≤ g i) :
164
+ (l.map f).prod ≤ (l.map g).prod :=
165
+ begin
166
+ induction l with i l ihl, { refl },
167
+ rw forall_mem_cons at h,
168
+ simpa using mul_le_mul' h.1 (ihl h.2 )
169
+ end
170
+
171
+ @[to_additive sum_lt_sum] lemma prod_lt_prod'
172
+ [preorder M] [covariant_class M M (*) (<)] [covariant_class M M (*) (≤)]
173
+ [covariant_class M M (function.swap (*)) (<)] [covariant_class M M (function.swap (*)) (≤)]
174
+ {l : list ι} (f g : ι → M) (h₁ : ∀ i ∈ l, f i ≤ g i) (h₂ : ∃ i ∈ l, f i < g i) :
175
+ (l.map f).prod < (l.map g).prod :=
176
+ begin
177
+ induction l with i l ihl, { rcases h₂ with ⟨_, ⟨⟩, _⟩ },
178
+ simp only [ball_cons, bex_cons, map_cons, prod_cons] at h₁ h₂ ⊢,
179
+ cases h₂,
180
+ exacts [mul_lt_mul_of_lt_of_le h₂ (prod_le_prod' h₁.2 ),
181
+ mul_lt_mul_of_le_of_lt h₁.1 $ ihl h₁.2 h₂]
182
+ end
183
+
184
+ @[to_additive] lemma prod_lt_prod_of_ne_nil
185
+ [preorder M] [covariant_class M M (*) (<)] [covariant_class M M (*) (≤)]
186
+ [covariant_class M M (function.swap (*)) (<)] [covariant_class M M (function.swap (*)) (≤)]
187
+ {l : list ι} (hl : l ≠ []) (f g : ι → M) (hlt : ∀ i ∈ l, f i < g i) :
188
+ (l.map f).prod < (l.map g).prod :=
189
+ prod_lt_prod' f g (λ i hi, (hlt i hi).le) $ (exists_mem_of_ne_nil l hl).imp $ λ i hi, ⟨hi, hlt i hi⟩
190
+
191
+ @[to_additive sum_le_card_nsmul]
192
+ lemma prod_le_pow_card [preorder M]
193
+ [covariant_class M M (function.swap (*)) (≤)] [covariant_class M M (*) (≤)]
194
+ (l : list M) (n : M) (h : ∀ (x ∈ l), x ≤ n) :
195
+ l.prod ≤ n ^ l.length :=
196
+ by simpa only [map_id'', map_const, prod_repeat] using prod_le_prod' h
197
+
198
+ @[to_additive card_nsmul_le_sum]
199
+ lemma pow_card_le_prod [preorder M]
200
+ [covariant_class M M (function.swap (*)) (≤)] [covariant_class M M (*) (≤)]
201
+ (l : list M) (n : M) (h : ∀ (x ∈ l), n ≤ x) :
202
+ n ^ l.length ≤ l.prod :=
203
+ @prod_le_pow_card (order_dual M) _ _ _ _ l n h
204
+
205
+ @[to_additive exists_lt_of_sum_lt] lemma exists_lt_of_prod_lt' [linear_order M]
206
+ [covariant_class M M (function.swap (*)) (≤)] [covariant_class M M (*) (≤)] {l : list ι}
207
+ (f g : ι → M) (h : (l.map f).prod < (l.map g).prod) :
208
+ ∃ i ∈ l, f i < g i :=
209
+ by { contrapose! h, exact prod_le_prod' h }
210
+
211
+ @[to_additive exists_le_of_sum_le]
212
+ lemma exists_le_of_prod_le' [linear_order M] [covariant_class M M (*) (<)]
213
+ [covariant_class M M (*) (≤)] [covariant_class M M (function.swap (*)) (<)]
214
+ [covariant_class M M (function.swap (*)) (≤)] {l : list ι} (hl : l ≠ [])
215
+ (f g : ι → M) (h : (l.map f).prod ≤ (l.map g).prod) :
216
+ ∃ x ∈ l, f x ≤ g x :=
217
+ by { contrapose! h, exact prod_lt_prod_of_ne_nil hl _ _ h }
218
+
219
+ @[to_additive sum_nonneg]
220
+ lemma one_le_prod_of_one_le [preorder M] [covariant_class M M (*) (≤)] {l : list M}
221
+ (hl₁ : ∀ x ∈ l, (1 : M) ≤ x) :
222
+ 1 ≤ l.prod :=
223
+ begin
224
+ -- We don't use `pow_card_le_prod` to avoid assumption
225
+ -- [covariant_class M M (function.swap (*)) (≤)]
226
+ induction l with hd tl ih, { refl },
227
+ rw prod_cons,
228
+ exact one_le_mul (hl₁ hd (mem_cons_self hd tl)) (ih (λ x h, hl₁ x (mem_cons_of_mem hd h)))
229
+ end
230
+
134
231
end monoid
135
232
136
233
section monoid_with_zero
@@ -214,34 +311,25 @@ end
214
311
215
312
end comm_group
216
313
217
- lemma eq_of_sum_take_eq [add_left_cancel_monoid M] {L L' : list M} (h : L.length = L'.length)
218
- (h' : ∀ i ≤ L.length, (L.take i).sum = (L'.take i).sum) : L = L' :=
314
+ @[to_additive]
315
+ lemma eq_of_prod_take_eq [left_cancel_monoid M] {L L' : list M} (h : L.length = L'.length)
316
+ (h' : ∀ i ≤ L.length, (L.take i).prod = (L'.take i).prod) : L = L' :=
219
317
begin
220
318
apply ext_le h (λ i h₁ h₂, _),
221
- have : (L.take (i + 1 )).sum = (L'.take (i + 1 )).sum := h' _ (nat.succ_le_of_lt h₁),
222
- rw [sum_take_succ L i h₁, sum_take_succ L' i h₂, h' i (le_of_lt h₁)] at this ,
223
- exact add_left_cancel this
319
+ have : (L.take (i + 1 )).prod = (L'.take (i + 1 )).prod := h' _ (nat.succ_le_of_lt h₁),
320
+ rw [prod_take_succ L i h₁, prod_take_succ L' i h₂, h' i (le_of_lt h₁)] at this ,
321
+ convert mul_left_cancel this
224
322
end
225
323
226
- lemma monotone_sum_take [canonically_ordered_add_monoid M] (L : list M) :
227
- monotone (λ i, (L.take i).sum) :=
324
+ @[to_additive]
325
+ lemma monotone_prod_take [canonically_ordered_monoid M] (L : list M) :
326
+ monotone (λ i, (L.take i).prod) :=
228
327
begin
229
328
apply monotone_nat_of_le_succ (λ n, _),
230
- by_cases h : n < L.length,
231
- { rw sum_take_succ _ _ h,
232
- exact le_self_add },
233
- { push_neg at h,
234
- simp [take_all_of_le h, take_all_of_le (le_trans h (nat.le_succ _))] }
235
- end
236
-
237
- @[to_additive sum_nonneg]
238
- lemma one_le_prod_of_one_le [ordered_comm_monoid M] {l : list M} (hl₁ : ∀ x ∈ l, (1 : M) ≤ x) :
239
- 1 ≤ l.prod :=
240
- begin
241
- induction l with hd tl ih,
242
- { simp },
243
- rw prod_cons,
244
- exact one_le_mul (hl₁ hd (mem_cons_self hd tl)) (ih (λ x h, hl₁ x (mem_cons_of_mem hd h))),
329
+ cases lt_or_le n L.length with h h,
330
+ { rw prod_take_succ _ _ h,
331
+ exact le_self_mul },
332
+ { simp [take_all_of_le h, take_all_of_le (le_trans h (nat.le_succ _))] }
245
333
end
246
334
247
335
@[to_additive sum_pos]
@@ -275,8 +363,7 @@ lemma all_one_of_le_one_le_of_prod_eq_one [ordered_comm_monoid M]
275
363
x = 1 :=
276
364
le_antisymm (hl₂ ▸ single_le_prod hl₁ _ hx) (hl₁ x hx)
277
365
278
- @[to_additive]
279
- lemma prod_eq_one_iff [canonically_ordered_monoid M] (l : list M) :
366
+ @[to_additive] lemma prod_eq_one_iff [canonically_ordered_monoid M] (l : list M) :
280
367
l.prod = 1 ↔ ∀ x ∈ l, x = (1 : M) :=
281
368
⟨all_one_of_le_one_le_of_prod_eq_one (λ _ _, one_le _),
282
369
begin
@@ -310,14 +397,8 @@ lemma sum_le_foldr_max [add_monoid M] [add_monoid N] [linear_order N] (f : M →
310
397
begin
311
398
induction l with hd tl IH,
312
399
{ simpa using h0 },
313
- simp only [list.sum_cons, list.foldr_map, le_max_iff, list.foldr] at IH ⊢,
314
- cases le_or_lt (f tl.sum) (f hd),
315
- { left,
316
- refine (hadd _ _).trans _,
317
- simpa using h },
318
- { right,
319
- refine (hadd _ _).trans _,
320
- simp only [IH, max_le_iff, and_true, h.le.trans IH] }
400
+ simp only [list.sum_cons, list.foldr_map, list.foldr] at IH ⊢,
401
+ exact (hadd _ _).trans (max_le_max le_rfl IH)
321
402
end
322
403
323
404
@[simp, to_additive]
@@ -345,32 +426,6 @@ begin
345
426
exact dvd_add (h _ (mem_cons_self _ _)) (ih (λ x hx, h x (mem_cons_of_mem _ hx))) }
346
427
end
347
428
348
- lemma exists_lt_of_sum_lt [linear_ordered_cancel_add_comm_monoid M] {l : list ι} (f g : ι → M)
349
- (h : (l.map f).sum < (l.map g).sum) :
350
- ∃ x ∈ l, f x < g x :=
351
- begin
352
- induction l with x l,
353
- { exact (lt_irrefl _ h).elim },
354
- obtain h' | h' := lt_or_le (f x) (g x),
355
- { exact ⟨x, mem_cons_self _ _, h'⟩ },
356
- simp at h,
357
- obtain ⟨y, h1y, h2y⟩ := l_ih (lt_of_add_lt_add_left (h.trans_le $ add_le_add_right h' _)),
358
- exact ⟨y, mem_cons_of_mem x h1y, h2y⟩,
359
- end
360
-
361
- lemma exists_le_of_sum_le [linear_ordered_cancel_add_comm_monoid M] {l : list ι} (hl : l ≠ [])
362
- (f g : ι → M) (h : (l.map f).sum ≤ (l.map g).sum) :
363
- ∃ x ∈ l, f x ≤ g x :=
364
- begin
365
- cases l with x l,
366
- { contradiction },
367
- obtain h' | h' := le_or_lt (f x) (g x),
368
- { exact ⟨x, mem_cons_self _ _, h'⟩ },
369
- obtain ⟨y, h1y, h2y⟩ := exists_lt_of_sum_lt f g _,
370
- exact ⟨y, mem_cons_of_mem x h1y, le_of_lt h2y⟩, simp at h,
371
- exact lt_of_add_lt_add_left (h.trans_lt $ add_lt_add_right h' _),
372
- end
373
-
374
429
/-- The product of a list of positive natural numbers is positive,
375
430
and likewise for any nontrivial ordered semiring. -/
376
431
lemma prod_pos [ordered_semiring R] [nontrivial R] (l : list R) (h : ∀ a ∈ l, (0 : R) < a) :
@@ -416,11 +471,11 @@ by rw [sub_eq_add_neg, alternating_sum]
416
471
417
472
end alternating
418
473
419
- lemma sum_map_mul_left [semiring R] (L : list ι) (f : ι → R) (r : R) :
474
+ lemma sum_map_mul_left [non_unital_non_assoc_semiring R] (L : list ι) (f : ι → R) (r : R) :
420
475
(L.map (λ b, r * f b)).sum = r * (L.map f).sum :=
421
476
sum_map_hom L f $ add_monoid_hom.mul_left r
422
477
423
- lemma sum_map_mul_right [semiring R] (L : list ι) (f : ι → R) (r : R) :
478
+ lemma sum_map_mul_right [non_unital_non_assoc_semiring R] (L : list ι) (f : ι → R) (r : R) :
424
479
(L.map (λ b, f b * r)).sum = (L.map f).sum * r :=
425
480
sum_map_hom L f $ add_monoid_hom.mul_right r
426
481
0 commit comments