data.list.count
⟷
Mathlib.Data.List.Count
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.
(last sync)
attach
and filter
lemmas (#18087)
Left commutativity and cardinality of list.filter
/multiset.filter
/finset.filter
. Interaction of count
/countp
and attach
.
@@ -84,6 +84,9 @@ by simp only [countp_eq_length_filter, filter_filter]
| [] := rfl
| (a::l) := by rw [map_cons, countp_cons, countp_cons, countp_map]
+@[simp] lemma countp_attach (l : list α) : l.attach.countp (λ a, p ↑a) = l.countp p :=
+by rw [←countp_map, attach_map_coe]
+
variables {p q}
lemma countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp q l :=
@@ -197,6 +200,9 @@ lemma count_bind {α β} [decidable_eq β] (l : list α) (f : α → list β) (x
count x (l.bind f) = sum (map (count x ∘ f) l) :=
by rw [list.bind, count_join, map_map]
+@[simp] lemma count_attach (a : {x // x ∈ l}) : l.attach.count a = l.count a :=
+eq.trans (countp_congr $ λ _ _, subtype.ext_iff) $ countp_attach _ _
+
@[simp] lemma count_map_of_injective {α β} [decidable_eq α] [decidable_eq β]
(l : list α) (f : α → β) (hf : function.injective f) (x : α) :
count (f x) (map f l) = count x l :=
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
list.replicate
with Mathlib 4 (#18181)
Sync arguments order and golfs with leanprover-community/mathlib4#1579
@@ -174,12 +174,15 @@ begin
exacts [h ▸ count_replicate_self _ _, count_eq_zero_of_not_mem $ mt eq_of_mem_replicate h]
end
+theorem filter_eq (l : list α) (a : α) : l.filter (eq a) = replicate (count a l) a :=
+by simp [eq_replicate, count, countp_eq_length_filter, @eq_comm _ _ a]
+
+theorem filter_eq' (l : list α) (a : α) : l.filter (λ x, x = a) = replicate (count a l) a :=
+by simp only [filter_eq, @eq_comm _ _ a]
+
lemma le_count_iff_replicate_sublist {a : α} {l : list α} {n : ℕ} :
n ≤ count a l ↔ replicate n a <+ l :=
-⟨λ h, ((replicate_sublist_replicate a).2 h).trans $
- have filter (eq a) l = replicate (count a l) a, from eq_replicate.2
- ⟨by simp only [count, countp_eq_length_filter], λ b m, (of_mem_filter m).symm⟩,
- by rw ← this; apply filter_sublist,
+⟨λ h, ((replicate_sublist_replicate a).2 h).trans $ filter_eq l a ▸ filter_sublist _,
λ h, by simpa only [count_replicate_self] using h.count_le a⟩
lemma replicate_count_eq_of_count_eq_length {a : α} {l : list α} (h : count a l = length l) :
(no changes)
(no changes)
list.replicate
and migrate to it (#18127)
This definition differs from list.repeat
by the order of arguments. The new order is in sync with the Lean 4 version.
@@ -164,27 +164,27 @@ lemma not_mem_of_count_eq_zero {a : α} {l : list α} (h : count a l = 0) : a
@[simp] lemma count_eq_length {a : α} {l} : count a l = l.length ↔ ∀ b ∈ l, a = b :=
countp_eq_length _
-@[simp] lemma count_repeat_self (a : α) (n : ℕ) : count a (repeat a n) = n :=
-by rw [count, countp_eq_length_filter, filter_eq_self.2, length_repeat];
- exact λ b m, (eq_of_mem_repeat m).symm
+@[simp] lemma count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n :=
+by rw [count, countp_eq_length_filter, filter_eq_self.2, length_replicate];
+ exact λ b m, (eq_of_mem_replicate m).symm
-lemma count_repeat (a b : α) (n : ℕ) : count a (repeat b n) = if a = b then n else 0 :=
+lemma count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 :=
begin
split_ifs with h,
- exacts [h ▸ count_repeat_self _ _, count_eq_zero_of_not_mem (mt eq_of_mem_repeat h)]
+ exacts [h ▸ count_replicate_self _ _, count_eq_zero_of_not_mem $ mt eq_of_mem_replicate h]
end
-lemma le_count_iff_repeat_sublist {a : α} {l : list α} {n : ℕ} :
- n ≤ count a l ↔ repeat a n <+ l :=
-⟨λ h, ((repeat_sublist_repeat a).2 h).trans $
- have filter (eq a) l = repeat a (count a l), from eq_repeat.2
+lemma le_count_iff_replicate_sublist {a : α} {l : list α} {n : ℕ} :
+ n ≤ count a l ↔ replicate n a <+ l :=
+⟨λ h, ((replicate_sublist_replicate a).2 h).trans $
+ have filter (eq a) l = replicate (count a l) a, from eq_replicate.2
⟨by simp only [count, countp_eq_length_filter], λ b m, (of_mem_filter m).symm⟩,
by rw ← this; apply filter_sublist,
- λ h, by simpa only [count_repeat_self] using h.count_le a⟩
+ λ h, by simpa only [count_replicate_self] using h.count_le a⟩
-lemma repeat_count_eq_of_count_eq_length {a : α} {l : list α} (h : count a l = length l) :
- repeat a (count a l) = l :=
-(le_count_iff_repeat_sublist.mp le_rfl).eq_of_length $ (length_repeat a (count a l)).trans h
+lemma replicate_count_eq_of_count_eq_length {a : α} {l : list α} (h : count a l = length l) :
+ replicate (count a l) a = l :=
+(le_count_iff_replicate_sublist.mp le_rfl).eq_of_length $ (length_replicate (count a l) a).trans h
@[simp] lemma count_filter {p} [decidable_pred p]
{a} {l : list α} (h : p a) : count a (filter p l) = count a l :=
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
list.count_repeat
to list.count_repeat_self
;list.count_repeat
with if .. then .. else
in the RHS.@@ -164,17 +164,23 @@ lemma not_mem_of_count_eq_zero {a : α} {l : list α} (h : count a l = 0) : a
@[simp] lemma count_eq_length {a : α} {l} : count a l = l.length ↔ ∀ b ∈ l, a = b :=
countp_eq_length _
-@[simp] lemma count_repeat (a : α) (n : ℕ) : count a (repeat a n) = n :=
+@[simp] lemma count_repeat_self (a : α) (n : ℕ) : count a (repeat a n) = n :=
by rw [count, countp_eq_length_filter, filter_eq_self.2, length_repeat];
exact λ b m, (eq_of_mem_repeat m).symm
+lemma count_repeat (a b : α) (n : ℕ) : count a (repeat b n) = if a = b then n else 0 :=
+begin
+ split_ifs with h,
+ exacts [h ▸ count_repeat_self _ _, count_eq_zero_of_not_mem (mt eq_of_mem_repeat h)]
+end
+
lemma le_count_iff_repeat_sublist {a : α} {l : list α} {n : ℕ} :
n ≤ count a l ↔ repeat a n <+ l :=
⟨λ h, ((repeat_sublist_repeat a).2 h).trans $
have filter (eq a) l = repeat a (count a l), from eq_repeat.2
⟨by simp only [count, countp_eq_length_filter], λ b m, (of_mem_filter m).symm⟩,
by rw ← this; apply filter_sublist,
- λ h, by simpa only [count_repeat] using h.count_le a⟩
+ λ h, by simpa only [count_repeat_self] using h.count_le a⟩
lemma repeat_count_eq_of_count_eq_length {a : α} {l : list α} (h : count a l = length l) :
repeat a (count a l) = l :=
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(first ported)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -3,7 +3,7 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-/
-import Data.List.BigOperators.Basic
+import Algebra.BigOperators.List.Basic
#align_import data.list.count from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
@@ -437,7 +437,7 @@ theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (l : List α) : count a (l.e
#align list.count_erase_of_ne List.count_erase_of_ne
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:642:2: warning: expanding binder collection (a' «expr ≠ » a) -/
#print List.prod_map_eq_pow_single /-
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
@@ -448,13 +448,13 @@ theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β
· specialize h a fun a' ha' hfa' => hf a' ha' (mem_cons_of_mem _ hfa')
rw [List.map_cons, List.prod_cons, count_cons, h]
split_ifs with ha'
- · rw [ha', pow_succ]
+ · rw [ha', pow_succ']
· rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul]
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:642:2: warning: expanding binder collection (a' «expr ≠ » a) -/
#print List.prod_eq_pow_single /-
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -169,7 +169,7 @@ variable {p q}
theorem countP_mono_left (h : ∀ x ∈ l, p x → q x) : countP p l ≤ countP q l :=
by
induction' l with a l ihl; · rfl
- rw [forall_mem_cons] at h ; cases' h with ha hl
+ rw [forall_mem_cons] at h; cases' h with ha hl
rw [countp_cons, countp_cons]
refine' add_le_add (ihl hl) _
split_ifs <;> try simp only [le_rfl, zero_le]
@@ -417,7 +417,7 @@ theorem count_erase (a b : α) : ∀ l : List α, count a (l.eraseₓ b) = count
· rw [if_pos hc, hc, count_cons', Nat.add_sub_cancel]
· rw [if_neg hc, count_cons', count_cons', count_erase]
by_cases ha : a = b
- · rw [← ha, eq_comm] at hc
+ · rw [← ha, eq_comm] at hc
rw [if_pos ha, if_neg hc, add_zero, add_zero]
· rw [if_neg ha, tsub_zero, tsub_zero]
#align list.count_erase List.count_erase
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -156,10 +156,12 @@ theorem countP_map (p : β → Prop) [DecidablePred p] (f : α → β) :
#align list.countp_map List.countP_map
-/
+#print List.countP_attach /-
@[simp]
theorem countP_attach (l : List α) : (l.attach.countP fun a => p ↑a) = l.countP p := by
rw [← countp_map, attach_map_coe]
#align list.countp_attach List.countP_attach
+-/
variable {p q}
@@ -382,10 +384,12 @@ theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (
#align list.count_bind List.count_bind
-/
+#print List.count_attach /-
@[simp]
theorem count_attach (a : { x // x ∈ l }) : l.attach.count a = l.count a :=
Eq.trans (countP_congr fun _ _ => Subtype.ext_iff) <| countP_attach _ _
#align list.count_attach List.count_attach
+-/
#print List.count_map_of_injective /-
@[simp]
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -5,7 +5,7 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M
-/
import Data.List.BigOperators.Basic
-#align_import data.list.count from "leanprover-community/mathlib"@"47adfab39a11a072db552f47594bf8ed2cf8a722"
+#align_import data.list.count from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
/-!
# Counting in lists
@@ -156,6 +156,11 @@ theorem countP_map (p : β → Prop) [DecidablePred p] (f : α → β) :
#align list.countp_map List.countP_map
-/
+@[simp]
+theorem countP_attach (l : List α) : (l.attach.countP fun a => p ↑a) = l.countP p := by
+ rw [← countp_map, attach_map_coe]
+#align list.countp_attach List.countP_attach
+
variable {p q}
#print List.countP_mono_left /-
@@ -377,6 +382,11 @@ theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (
#align list.count_bind List.count_bind
-/
+@[simp]
+theorem count_attach (a : { x // x ∈ l }) : l.attach.count a = l.count a :=
+ Eq.trans (countP_congr fun _ _ => Subtype.ext_iff) <| countP_attach _ _
+#align list.count_attach List.count_attach
+
#print List.count_map_of_injective /-
@[simp]
theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : List α) (f : α → β)
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,7 +3,7 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-/
-import Mathbin.Data.List.BigOperators.Basic
+import Data.List.BigOperators.Basic
#align_import data.list.count from "leanprover-community/mathlib"@"47adfab39a11a072db552f47594bf8ed2cf8a722"
@@ -423,7 +423,7 @@ theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (l : List α) : count a (l.e
#align list.count_erase_of_ne List.count_erase_of_ne
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (a' «expr ≠ » a) -/
#print List.prod_map_eq_pow_single /-
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
@@ -440,7 +440,7 @@ theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (a' «expr ≠ » a) -/
#print List.prod_eq_pow_single /-
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -29,90 +29,90 @@ section Countp
variable (p q : α → Prop) [DecidablePred p] [DecidablePred q]
-#print List.countp_nil /-
+#print List.countP_nil /-
@[simp]
-theorem countp_nil : countp p [] = 0 :=
+theorem countP_nil : countP p [] = 0 :=
rfl
-#align list.countp_nil List.countp_nil
+#align list.countp_nil List.countP_nil
-/
-#print List.countp_cons_of_pos /-
+#print List.countP_cons_of_pos /-
@[simp]
-theorem countp_cons_of_pos {a : α} (l) (pa : p a) : countp p (a :: l) = countp p l + 1 :=
+theorem countP_cons_of_pos {a : α} (l) (pa : p a) : countP p (a :: l) = countP p l + 1 :=
if_pos pa
-#align list.countp_cons_of_pos List.countp_cons_of_pos
+#align list.countp_cons_of_pos List.countP_cons_of_pos
-/
-#print List.countp_cons_of_neg /-
+#print List.countP_cons_of_neg /-
@[simp]
-theorem countp_cons_of_neg {a : α} (l) (pa : ¬p a) : countp p (a :: l) = countp p l :=
+theorem countP_cons_of_neg {a : α} (l) (pa : ¬p a) : countP p (a :: l) = countP p l :=
if_neg pa
-#align list.countp_cons_of_neg List.countp_cons_of_neg
+#align list.countp_cons_of_neg List.countP_cons_of_neg
-/
-#print List.countp_cons /-
-theorem countp_cons (a : α) (l) : countp p (a :: l) = countp p l + ite (p a) 1 0 := by
+#print List.countP_cons /-
+theorem countP_cons (a : α) (l) : countP p (a :: l) = countP p l + ite (p a) 1 0 := by
by_cases h : p a <;> simp [h]
-#align list.countp_cons List.countp_cons
+#align list.countp_cons List.countP_cons
-/
-#print List.length_eq_countp_add_countp /-
-theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
+#print List.length_eq_countP_add_countP /-
+theorem length_eq_countP_add_countP (l) : length l = countP p l + countP (fun a => ¬p a) l := by
induction' l with x h ih <;> [rfl; by_cases p x] <;>
[simp only [countp_cons_of_pos _ _ h,
countp_cons_of_neg (fun a => ¬p a) _ (Decidable.not_not.2 h), ih, length];
simp only [countp_cons_of_pos (fun a => ¬p a) _ h, countp_cons_of_neg _ _ h, ih, length]] <;>
ac_rfl
-#align list.length_eq_countp_add_countp List.length_eq_countp_add_countp
+#align list.length_eq_countp_add_countp List.length_eq_countP_add_countP
-/
-#print List.countp_eq_length_filter /-
-theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
+#print List.countP_eq_length_filter /-
+theorem countP_eq_length_filter (l) : countP p l = length (filter p l) := by
induction' l with x l ih <;> [rfl; by_cases p x] <;>
[simp only [filter_cons_of_pos _ h, countp, ih, if_pos h];
simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]] <;>
rfl
-#align list.countp_eq_length_filter List.countp_eq_length_filter
+#align list.countp_eq_length_filter List.countP_eq_length_filter
-/
-#print List.countp_le_length /-
-theorem countp_le_length : countp p l ≤ l.length := by
+#print List.countP_le_length /-
+theorem countP_le_length : countP p l ≤ l.length := by
simpa only [countp_eq_length_filter] using length_filter_le _ _
-#align list.countp_le_length List.countp_le_length
+#align list.countp_le_length List.countP_le_length
-/
-#print List.countp_append /-
+#print List.countP_append /-
@[simp]
-theorem countp_append (l₁ l₂) : countp p (l₁ ++ l₂) = countp p l₁ + countp p l₂ := by
+theorem countP_append (l₁ l₂) : countP p (l₁ ++ l₂) = countP p l₁ + countP p l₂ := by
simp only [countp_eq_length_filter, filter_append, length_append]
-#align list.countp_append List.countp_append
+#align list.countp_append List.countP_append
-/
-#print List.countp_join /-
-theorem countp_join : ∀ l : List (List α), countp p l.join = (l.map (countp p)).Sum
+#print List.countP_join /-
+theorem countP_join : ∀ l : List (List α), countP p l.join = (l.map (countP p)).Sum
| [] => rfl
| a :: l => by rw [join, countp_append, map_cons, sum_cons, countp_join]
-#align list.countp_join List.countp_join
+#align list.countp_join List.countP_join
-/
-#print List.countp_pos /-
-theorem countp_pos {l} : 0 < countp p l ↔ ∃ a ∈ l, p a := by
+#print List.countP_pos /-
+theorem countP_pos {l} : 0 < countP p l ↔ ∃ a ∈ l, p a := by
simp only [countp_eq_length_filter, length_pos_iff_exists_mem, mem_filter, exists_prop]
-#align list.countp_pos List.countp_pos
+#align list.countp_pos List.countP_pos
-/
-#print List.countp_eq_zero /-
+#print List.countP_eq_zero /-
@[simp]
-theorem countp_eq_zero {l} : countp p l = 0 ↔ ∀ a ∈ l, ¬p a := by
+theorem countP_eq_zero {l} : countP p l = 0 ↔ ∀ a ∈ l, ¬p a := by
rw [← not_iff_not, ← Ne.def, ← pos_iff_ne_zero, countp_pos]; simp
-#align list.countp_eq_zero List.countp_eq_zero
+#align list.countp_eq_zero List.countP_eq_zero
-/
-#print List.countp_eq_length /-
+#print List.countP_eq_length /-
@[simp]
-theorem countp_eq_length {l} : countp p l = l.length ↔ ∀ a ∈ l, p a := by
+theorem countP_eq_length {l} : countP p l = l.length ↔ ∀ a ∈ l, p a := by
rw [countp_eq_length_filter, filter_length_eq_length]
-#align list.countp_eq_length List.countp_eq_length
+#align list.countp_eq_length List.countP_eq_length
-/
#print List.length_filter_lt_length_iff_exists /-
@@ -122,44 +122,44 @@ theorem length_filter_lt_length_iff_exists (l) : length (filter p l) < length l
#align list.length_filter_lt_length_iff_exists List.length_filter_lt_length_iff_exists
-/
-#print List.Sublist.countp_le /-
-theorem Sublist.countp_le (s : l₁ <+ l₂) : countp p l₁ ≤ countp p l₂ := by
+#print List.Sublist.countP_le /-
+theorem Sublist.countP_le (s : l₁ <+ l₂) : countP p l₁ ≤ countP p l₂ := by
simpa only [countp_eq_length_filter] using length_le_of_sublist (s.filter p)
-#align list.sublist.countp_le List.Sublist.countp_le
+#align list.sublist.countp_le List.Sublist.countP_le
-/
-#print List.countp_filter /-
+#print List.countP_filter /-
@[simp]
-theorem countp_filter (l : List α) : countp p (filter q l) = countp (fun a => p a ∧ q a) l := by
+theorem countP_filter (l : List α) : countP p (filter q l) = countP (fun a => p a ∧ q a) l := by
simp only [countp_eq_length_filter, filter_filter]
-#align list.countp_filter List.countp_filter
+#align list.countp_filter List.countP_filter
-/
-#print List.countp_true /-
+#print List.countP_true /-
@[simp]
-theorem countp_true : (l.countp fun _ => True) = l.length := by simp
-#align list.countp_true List.countp_true
+theorem countP_true : (l.countP fun _ => True) = l.length := by simp
+#align list.countp_true List.countP_true
-/
-#print List.countp_false /-
+#print List.countP_false /-
@[simp]
-theorem countp_false : (l.countp fun _ => False) = 0 := by simp
-#align list.countp_false List.countp_false
+theorem countP_false : (l.countP fun _ => False) = 0 := by simp
+#align list.countp_false List.countP_false
-/
-#print List.countp_map /-
+#print List.countP_map /-
@[simp]
-theorem countp_map (p : β → Prop) [DecidablePred p] (f : α → β) :
- ∀ l, countp p (map f l) = countp (p ∘ f) l
+theorem countP_map (p : β → Prop) [DecidablePred p] (f : α → β) :
+ ∀ l, countP p (map f l) = countP (p ∘ f) l
| [] => rfl
| a :: l => by rw [map_cons, countp_cons, countp_cons, countp_map]
-#align list.countp_map List.countp_map
+#align list.countp_map List.countP_map
-/
variable {p q}
-#print List.countp_mono_left /-
-theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp q l :=
+#print List.countP_mono_left /-
+theorem countP_mono_left (h : ∀ x ∈ l, p x → q x) : countP p l ≤ countP q l :=
by
induction' l with a l ihl; · rfl
rw [forall_mem_cons] at h ; cases' h with ha hl
@@ -167,13 +167,13 @@ theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp
refine' add_le_add (ihl hl) _
split_ifs <;> try simp only [le_rfl, zero_le]
exact absurd (ha ‹_›) ‹_›
-#align list.countp_mono_left List.countp_mono_left
+#align list.countp_mono_left List.countP_mono_left
-/
-#print List.countp_congr /-
-theorem countp_congr (h : ∀ x ∈ l, p x ↔ q x) : countp p l = countp q l :=
- le_antisymm (countp_mono_left fun x hx => (h x hx).1) (countp_mono_left fun x hx => (h x hx).2)
-#align list.countp_congr List.countp_congr
+#print List.countP_congr /-
+theorem countP_congr (h : ∀ x ∈ l, p x ↔ q x) : countP p l = countP q l :=
+ le_antisymm (countP_mono_left fun x hx => (h x hx).1) (countP_mono_left fun x hx => (h x hx).2)
+#align list.countp_congr List.countP_congr
-/
end Countp
@@ -229,13 +229,13 @@ theorem count_tail :
#print List.count_le_length /-
theorem count_le_length (a : α) (l : List α) : count a l ≤ l.length :=
- countp_le_length _
+ countP_le_length _
#align list.count_le_length List.count_le_length
-/
#print List.Sublist.count_le /-
theorem Sublist.count_le (h : l₁ <+ l₂) (a : α) : count a l₁ ≤ count a l₂ :=
- h.countp_le _
+ h.countP_le _
#align list.sublist.count_le List.Sublist.count_le
-/
@@ -260,13 +260,13 @@ theorem count_singleton' (a b : α) : count a [b] = ite (a = b) 1 0 :=
#print List.count_append /-
@[simp]
theorem count_append (a : α) : ∀ l₁ l₂, count a (l₁ ++ l₂) = count a l₁ + count a l₂ :=
- countp_append _
+ countP_append _
#align list.count_append List.count_append
-/
#print List.count_join /-
theorem count_join (l : List (List α)) (a : α) : l.join.count a = (l.map (count a)).Sum :=
- countp_join _ _
+ countP_join _ _
#align list.count_join List.count_join
-/
@@ -276,30 +276,32 @@ theorem count_concat (a : α) (l : List α) : count a (concat l a) = succ (count
#align list.count_concat List.count_concat
-/
-#print List.count_pos /-
+#print List.count_pos_iff_mem /-
@[simp]
-theorem count_pos {a : α} {l : List α} : 0 < count a l ↔ a ∈ l := by
+theorem count_pos_iff_mem {a : α} {l : List α} : 0 < count a l ↔ a ∈ l := by
simp only [count, countp_pos, exists_prop, exists_eq_right']
-#align list.count_pos List.count_pos
+#align list.count_pos List.count_pos_iff_mem
-/
-#print List.one_le_count_iff_mem /-
+/- warning: list.one_le_count_iff_mem clashes with list.count_pos -> List.count_pos_iff_mem
+Case conversion may be inaccurate. Consider using '#align list.one_le_count_iff_mem List.count_pos_iff_memₓ'. -/
+#print List.count_pos_iff_mem /-
@[simp]
-theorem one_le_count_iff_mem {a : α} {l : List α} : 1 ≤ count a l ↔ a ∈ l :=
- count_pos
-#align list.one_le_count_iff_mem List.one_le_count_iff_mem
+theorem count_pos_iff_mem {a : α} {l : List α} : 1 ≤ count a l ↔ a ∈ l :=
+ count_pos_iff_mem
+#align list.one_le_count_iff_mem List.count_pos_iff_mem
-/
#print List.count_eq_zero_of_not_mem /-
@[simp]
theorem count_eq_zero_of_not_mem {a : α} {l : List α} (h : a ∉ l) : count a l = 0 :=
- Decidable.by_contradiction fun h' => h <| count_pos.1 (Nat.pos_of_ne_zero h')
+ Decidable.by_contradiction fun h' => h <| count_pos_iff_mem.1 (Nat.pos_of_ne_zero h')
#align list.count_eq_zero_of_not_mem List.count_eq_zero_of_not_mem
-/
#print List.not_mem_of_count_eq_zero /-
theorem not_mem_of_count_eq_zero {a : α} {l : List α} (h : count a l = 0) : a ∉ l := fun h' =>
- (count_pos.2 h').ne' h
+ (count_pos_iff_mem.2 h').ne' h
#align list.not_mem_of_count_eq_zero List.not_mem_of_count_eq_zero
-/
@@ -313,7 +315,7 @@ theorem count_eq_zero {a : α} {l} : count a l = 0 ↔ a ∉ l :=
#print List.count_eq_length /-
@[simp]
theorem count_eq_length {a : α} {l} : count a l = l.length ↔ ∀ b ∈ l, a = b :=
- countp_eq_length _
+ countP_eq_length _
#align list.count_eq_length List.count_eq_length
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,14 +2,11 @@
Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-
-! This file was ported from Lean 3 source module data.list.count
-! leanprover-community/mathlib commit 47adfab39a11a072db552f47594bf8ed2cf8a722
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Data.List.BigOperators.Basic
+#align_import data.list.count from "leanprover-community/mathlib"@"47adfab39a11a072db552f47594bf8ed2cf8a722"
+
/-!
# Counting in lists
@@ -424,7 +421,7 @@ theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (l : List α) : count a (l.e
#align list.count_erase_of_ne List.count_erase_of_ne
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
#print List.prod_map_eq_pow_single /-
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
@@ -441,7 +438,7 @@ theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
#print List.prod_eq_pow_single /-
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -32,25 +32,34 @@ section Countp
variable (p q : α → Prop) [DecidablePred p] [DecidablePred q]
+#print List.countp_nil /-
@[simp]
theorem countp_nil : countp p [] = 0 :=
rfl
#align list.countp_nil List.countp_nil
+-/
+#print List.countp_cons_of_pos /-
@[simp]
theorem countp_cons_of_pos {a : α} (l) (pa : p a) : countp p (a :: l) = countp p l + 1 :=
if_pos pa
#align list.countp_cons_of_pos List.countp_cons_of_pos
+-/
+#print List.countp_cons_of_neg /-
@[simp]
theorem countp_cons_of_neg {a : α} (l) (pa : ¬p a) : countp p (a :: l) = countp p l :=
if_neg pa
#align list.countp_cons_of_neg List.countp_cons_of_neg
+-/
+#print List.countp_cons /-
theorem countp_cons (a : α) (l) : countp p (a :: l) = countp p l + ite (p a) 1 0 := by
by_cases h : p a <;> simp [h]
#align list.countp_cons List.countp_cons
+-/
+#print List.length_eq_countp_add_countp /-
theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
induction' l with x h ih <;> [rfl; by_cases p x] <;>
[simp only [countp_cons_of_pos _ _ h,
@@ -58,55 +67,76 @@ theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a
simp only [countp_cons_of_pos (fun a => ¬p a) _ h, countp_cons_of_neg _ _ h, ih, length]] <;>
ac_rfl
#align list.length_eq_countp_add_countp List.length_eq_countp_add_countp
+-/
+#print List.countp_eq_length_filter /-
theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
induction' l with x l ih <;> [rfl; by_cases p x] <;>
[simp only [filter_cons_of_pos _ h, countp, ih, if_pos h];
simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]] <;>
rfl
#align list.countp_eq_length_filter List.countp_eq_length_filter
+-/
+#print List.countp_le_length /-
theorem countp_le_length : countp p l ≤ l.length := by
simpa only [countp_eq_length_filter] using length_filter_le _ _
#align list.countp_le_length List.countp_le_length
+-/
+#print List.countp_append /-
@[simp]
theorem countp_append (l₁ l₂) : countp p (l₁ ++ l₂) = countp p l₁ + countp p l₂ := by
simp only [countp_eq_length_filter, filter_append, length_append]
#align list.countp_append List.countp_append
+-/
+#print List.countp_join /-
theorem countp_join : ∀ l : List (List α), countp p l.join = (l.map (countp p)).Sum
| [] => rfl
| a :: l => by rw [join, countp_append, map_cons, sum_cons, countp_join]
#align list.countp_join List.countp_join
+-/
+#print List.countp_pos /-
theorem countp_pos {l} : 0 < countp p l ↔ ∃ a ∈ l, p a := by
simp only [countp_eq_length_filter, length_pos_iff_exists_mem, mem_filter, exists_prop]
#align list.countp_pos List.countp_pos
+-/
+#print List.countp_eq_zero /-
@[simp]
theorem countp_eq_zero {l} : countp p l = 0 ↔ ∀ a ∈ l, ¬p a := by
rw [← not_iff_not, ← Ne.def, ← pos_iff_ne_zero, countp_pos]; simp
#align list.countp_eq_zero List.countp_eq_zero
+-/
+#print List.countp_eq_length /-
@[simp]
theorem countp_eq_length {l} : countp p l = l.length ↔ ∀ a ∈ l, p a := by
rw [countp_eq_length_filter, filter_length_eq_length]
#align list.countp_eq_length List.countp_eq_length
+-/
+#print List.length_filter_lt_length_iff_exists /-
theorem length_filter_lt_length_iff_exists (l) : length (filter p l) < length l ↔ ∃ x ∈ l, ¬p x :=
by
rw [length_eq_countp_add_countp p l, ← countp_pos, countp_eq_length_filter, lt_add_iff_pos_right]
#align list.length_filter_lt_length_iff_exists List.length_filter_lt_length_iff_exists
+-/
+#print List.Sublist.countp_le /-
theorem Sublist.countp_le (s : l₁ <+ l₂) : countp p l₁ ≤ countp p l₂ := by
simpa only [countp_eq_length_filter] using length_le_of_sublist (s.filter p)
#align list.sublist.countp_le List.Sublist.countp_le
+-/
+#print List.countp_filter /-
@[simp]
theorem countp_filter (l : List α) : countp p (filter q l) = countp (fun a => p a ∧ q a) l := by
simp only [countp_eq_length_filter, filter_filter]
#align list.countp_filter List.countp_filter
+-/
#print List.countp_true /-
@[simp]
@@ -120,15 +150,18 @@ theorem countp_false : (l.countp fun _ => False) = 0 := by simp
#align list.countp_false List.countp_false
-/
+#print List.countp_map /-
@[simp]
theorem countp_map (p : β → Prop) [DecidablePred p] (f : α → β) :
∀ l, countp p (map f l) = countp (p ∘ f) l
| [] => rfl
| a :: l => by rw [map_cons, countp_cons, countp_cons, countp_map]
#align list.countp_map List.countp_map
+-/
variable {p q}
+#print List.countp_mono_left /-
theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp q l :=
by
induction' l with a l ihl; · rfl
@@ -138,10 +171,13 @@ theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp
split_ifs <;> try simp only [le_rfl, zero_le]
exact absurd (ha ‹_›) ‹_›
#align list.countp_mono_left List.countp_mono_left
+-/
+#print List.countp_congr /-
theorem countp_congr (h : ∀ x ∈ l, p x ↔ q x) : countp p l = countp q l :=
le_antisymm (countp_mono_left fun x hx => (h x hx).1) (countp_mono_left fun x hx => (h x hx).2)
#align list.countp_congr List.countp_congr
+-/
end Countp
@@ -200,9 +236,11 @@ theorem count_le_length (a : α) (l : List α) : count a l ≤ l.length :=
#align list.count_le_length List.count_le_length
-/
+#print List.Sublist.count_le /-
theorem Sublist.count_le (h : l₁ <+ l₂) (a : α) : count a l₁ ≤ count a l₂ :=
h.countp_le _
#align list.sublist.count_le List.Sublist.count_le
+-/
#print List.count_le_count_cons /-
theorem count_le_count_cons (a b : α) (l : List α) : count a l ≤ count a (b :: l) :=
@@ -268,15 +306,19 @@ theorem not_mem_of_count_eq_zero {a : α} {l : List α} (h : count a l = 0) : a
#align list.not_mem_of_count_eq_zero List.not_mem_of_count_eq_zero
-/
+#print List.count_eq_zero /-
@[simp]
theorem count_eq_zero {a : α} {l} : count a l = 0 ↔ a ∉ l :=
⟨not_mem_of_count_eq_zero, count_eq_zero_of_not_mem⟩
#align list.count_eq_zero List.count_eq_zero
+-/
+#print List.count_eq_length /-
@[simp]
theorem count_eq_length {a : α} {l} : count a l = l.length ↔ ∀ b ∈ l, a = b :=
countp_eq_length _
#align list.count_eq_length List.count_eq_length
+-/
#print List.count_replicate_self /-
@[simp]
@@ -294,48 +336,64 @@ theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a =
#align list.count_replicate List.count_replicate
-/
+#print List.filter_eq /-
theorem filter_eq (l : List α) (a : α) : l.filterₓ (Eq a) = replicate (count a l) a := by
simp [eq_replicate, count, countp_eq_length_filter, @eq_comm _ _ a]
#align list.filter_eq List.filter_eq
+-/
+#print List.filter_eq' /-
theorem filter_eq' (l : List α) (a : α) : (l.filterₓ fun x => x = a) = replicate (count a l) a := by
simp only [filter_eq, @eq_comm _ _ a]
#align list.filter_eq' List.filter_eq'
+-/
+#print List.le_count_iff_replicate_sublist /-
theorem le_count_iff_replicate_sublist {a : α} {l : List α} {n : ℕ} :
n ≤ count a l ↔ replicate n a <+ l :=
⟨fun h => ((replicate_sublist_replicate a).2 h).trans <| filter_eq l a ▸ filter_sublist _,
fun h => by simpa only [count_replicate_self] using h.count_le a⟩
#align list.le_count_iff_replicate_sublist List.le_count_iff_replicate_sublist
+-/
+#print List.replicate_count_eq_of_count_eq_length /-
theorem replicate_count_eq_of_count_eq_length {a : α} {l : List α} (h : count a l = length l) :
replicate (count a l) a = l :=
(le_count_iff_replicate_sublist.mp le_rfl).eq_of_length <|
(length_replicate (count a l) a).trans h
#align list.replicate_count_eq_of_count_eq_length List.replicate_count_eq_of_count_eq_length
+-/
+#print List.count_filter /-
@[simp]
theorem count_filter {p} [DecidablePred p] {a} {l : List α} (h : p a) :
count a (filter p l) = count a l := by
simp only [count, countp_filter, show (fun b => a = b ∧ p b) = Eq a by ext b; constructor <;> cc]
#align list.count_filter List.count_filter
+-/
+#print List.count_bind /-
theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (x : β) :
count x (l.bind f) = sum (map (count x ∘ f) l) := by rw [List.bind, count_join, map_map]
#align list.count_bind List.count_bind
+-/
+#print List.count_map_of_injective /-
@[simp]
theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : List α) (f : α → β)
(hf : Function.Injective f) (x : α) : count (f x) (map f l) = count x l := by
simp only [count, countp_map, (· ∘ ·), hf.eq_iff]
#align list.count_map_of_injective List.count_map_of_injective
+-/
+#print List.count_le_count_map /-
theorem count_le_count_map [DecidableEq β] (l : List α) (f : α → β) (x : α) :
count x l ≤ count (f x) (map f l) :=
by
rw [count, count, countp_map]
exact countp_mono_left fun y hyl => congr_arg f
#align list.count_le_count_map List.count_le_count_map
+-/
#print List.count_erase /-
theorem count_erase (a b : α) : ∀ l : List α, count a (l.eraseₓ b) = count a l - ite (a = b) 1 0
@@ -367,6 +425,7 @@ theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (l : List α) : count a (l.e
-/
/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+#print List.prod_map_eq_pow_single /-
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
(hf : ∀ (a') (_ : a' ≠ a), a' ∈ l → f a' = 1) : (l.map f).Prod = f a ^ l.count a :=
@@ -380,14 +439,17 @@ theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β
· rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul]
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
+-/
/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+#print List.prod_eq_pow_single /-
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
(h : ∀ (a') (_ : a' ≠ a), a' ∈ l → a' = 1) : l.Prod = a ^ l.count a :=
trans (by rw [map_id'']) (prod_map_eq_pow_single a id h)
#align list.prod_eq_pow_single List.prod_eq_pow_single
#align list.sum_eq_nsmul_single List.sum_eq_nsmul_single
+-/
end Count
mathlib commit https://github.com/leanprover-community/mathlib/commit/31c24aa72e7b3e5ed97a8412470e904f82b81004
@@ -366,7 +366,7 @@ theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (l : List α) : count a (l.e
#align list.count_erase_of_ne List.count_erase_of_ne
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (a' «expr ≠ » a) -/
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
(hf : ∀ (a') (_ : a' ≠ a), a' ∈ l → f a' = 1) : (l.map f).Prod = f a ^ l.count a :=
@@ -381,7 +381,7 @@ theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (a' «expr ≠ » a) -/
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
(h : ∀ (a') (_ : a' ≠ a), a' ∈ l → a' = 1) : l.Prod = a ^ l.count a :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -52,18 +52,17 @@ theorem countp_cons (a : α) (l) : countp p (a :: l) = countp p l + ite (p a) 1
#align list.countp_cons List.countp_cons
theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
- induction' l with x h ih <;> [rfl;by_cases p x] <;>
+ induction' l with x h ih <;> [rfl; by_cases p x] <;>
[simp only [countp_cons_of_pos _ _ h,
- countp_cons_of_neg (fun a => ¬p a) _ (Decidable.not_not.2 h), ih,
- length];simp only [countp_cons_of_pos (fun a => ¬p a) _ h, countp_cons_of_neg _ _ h, ih,
- length]] <;>
+ countp_cons_of_neg (fun a => ¬p a) _ (Decidable.not_not.2 h), ih, length];
+ simp only [countp_cons_of_pos (fun a => ¬p a) _ h, countp_cons_of_neg _ _ h, ih, length]] <;>
ac_rfl
#align list.length_eq_countp_add_countp List.length_eq_countp_add_countp
theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
- induction' l with x l ih <;> [rfl;by_cases p x] <;>
- [simp only [filter_cons_of_pos _ h, countp, ih,
- if_pos h];simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]] <;>
+ induction' l with x l ih <;> [rfl; by_cases p x] <;>
+ [simp only [filter_cons_of_pos _ h, countp, ih, if_pos h];
+ simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]] <;>
rfl
#align list.countp_eq_length_filter List.countp_eq_length_filter
@@ -133,7 +132,7 @@ variable {p q}
theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp q l :=
by
induction' l with a l ihl; · rfl
- rw [forall_mem_cons] at h; cases' h with ha hl
+ rw [forall_mem_cons] at h ; cases' h with ha hl
rw [countp_cons, countp_cons]
refine' add_le_add (ihl hl) _
split_ifs <;> try simp only [le_rfl, zero_le]
@@ -291,7 +290,7 @@ theorem count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n :=
theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 :=
by
split_ifs with h
- exacts[h ▸ count_replicate_self _ _, count_eq_zero_of_not_mem <| mt eq_of_mem_replicate h]
+ exacts [h ▸ count_replicate_self _ _, count_eq_zero_of_not_mem <| mt eq_of_mem_replicate h]
#align list.count_replicate List.count_replicate
-/
@@ -347,7 +346,7 @@ theorem count_erase (a b : α) : ∀ l : List α, count a (l.eraseₓ b) = count
· rw [if_pos hc, hc, count_cons', Nat.add_sub_cancel]
· rw [if_neg hc, count_cons', count_cons', count_erase]
by_cases ha : a = b
- · rw [← ha, eq_comm] at hc
+ · rw [← ha, eq_comm] at hc
rw [if_pos ha, if_neg hc, add_zero, add_zero]
· rw [if_neg ha, tsub_zero, tsub_zero]
#align list.count_erase List.count_erase
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -32,55 +32,25 @@ section Countp
variable (p q : α → Prop) [DecidablePred p] [DecidablePred q]
-/- warning: list.countp_nil -> List.countp_nil is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (List.nil.{u1} α)) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool), Eq.{1} Nat (List.countp.{u1} α p (List.nil.{u1} α)) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))
-Case conversion may be inaccurate. Consider using '#align list.countp_nil List.countp_nilₓ'. -/
@[simp]
theorem countp_nil : countp p [] = 0 :=
rfl
#align list.countp_nil List.countp_nil
-/- warning: list.countp_cons_of_pos -> List.countp_cons_of_pos is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] {a : α} (l : List.{u1} α), (p a) -> (Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (List.cons.{u1} α a l)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) {_inst_1 : α} (a : List.{u1} α), (Eq.{1} Bool (p _inst_1) Bool.true) -> (Eq.{1} Nat (List.countp.{u1} α p (List.cons.{u1} α _inst_1 a)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.countp.{u1} α p a) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))))
-Case conversion may be inaccurate. Consider using '#align list.countp_cons_of_pos List.countp_cons_of_posₓ'. -/
@[simp]
theorem countp_cons_of_pos {a : α} (l) (pa : p a) : countp p (a :: l) = countp p l + 1 :=
if_pos pa
#align list.countp_cons_of_pos List.countp_cons_of_pos
-/- warning: list.countp_cons_of_neg -> List.countp_cons_of_neg is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] {a : α} (l : List.{u1} α), (Not (p a)) -> (Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (List.cons.{u1} α a l)) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) {_inst_1 : α} (a : List.{u1} α), (Not (Eq.{1} Bool (p _inst_1) Bool.true)) -> (Eq.{1} Nat (List.countp.{u1} α p (List.cons.{u1} α _inst_1 a)) (List.countp.{u1} α p a))
-Case conversion may be inaccurate. Consider using '#align list.countp_cons_of_neg List.countp_cons_of_negₓ'. -/
@[simp]
theorem countp_cons_of_neg {a : α} (l) (pa : ¬p a) : countp p (a :: l) = countp p l :=
if_neg pa
#align list.countp_cons_of_neg List.countp_cons_of_neg
-/- warning: list.countp_cons -> List.countp_cons is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (a : α) (l : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (List.cons.{u1} α a l)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (ite.{1} Nat (p a) (_inst_1 a) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : α) (a : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (List.cons.{u1} α _inst_1 a)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.countp.{u1} α p a) (ite.{1} Nat (Eq.{1} Bool (p _inst_1) Bool.true) (instDecidableEqBool (p _inst_1) Bool.true) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))))
-Case conversion may be inaccurate. Consider using '#align list.countp_cons List.countp_consₓ'. -/
theorem countp_cons (a : α) (l) : countp p (a :: l) = countp p l + ite (p a) 1 0 := by
by_cases h : p a <;> simp [h]
#align list.countp_cons List.countp_cons
-/- warning: list.length_eq_countp_add_countp -> List.length_eq_countp_add_countp is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{1} Nat (List.length.{u1} α l) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (List.countp.{u1} α (fun (a : α) => Not (p a)) (fun (a : α) => Not.decidable (p a) (_inst_1 a)) l))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{1} Nat (List.length.{u1} α _inst_1) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.countp.{u1} α p _inst_1) (List.countp.{u1} α (fun (a : α) => Decidable.decide (Not (Eq.{1} Bool (p a) Bool.true)) (instDecidableNot (Eq.{1} Bool (p a) Bool.true) (instDecidableEqBool (p a) Bool.true))) _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.length_eq_countp_add_countp List.length_eq_countp_add_countpₓ'. -/
theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
induction' l with x h ih <;> [rfl;by_cases p x] <;>
[simp only [countp_cons_of_pos _ _ h,
@@ -90,12 +60,6 @@ theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a
ac_rfl
#align list.length_eq_countp_add_countp List.length_eq_countp_add_countp
-/- warning: list.countp_eq_length_filter -> List.countp_eq_length_filter is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (List.length.{u1} α (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p _inst_1) (List.length.{u1} α (List.filter.{u1} α p _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.countp_eq_length_filter List.countp_eq_length_filterₓ'. -/
theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
induction' l with x l ih <;> [rfl;by_cases p x] <;>
[simp only [filter_cons_of_pos _ h, countp, ih,
@@ -103,97 +67,43 @@ theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
rfl
#align list.countp_eq_length_filter List.countp_eq_length_filter
-/- warning: list.countp_le_length -> List.countp_le_length is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {l : List.{u1} α} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], LE.le.{0} Nat Nat.hasLe (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (List.length.{u1} α l)
-but is expected to have type
- forall {α : Type.{u1}} {l : List.{u1} α} (p : α -> Bool), LE.le.{0} Nat instLENat (List.countp.{u1} α p l) (List.length.{u1} α l)
-Case conversion may be inaccurate. Consider using '#align list.countp_le_length List.countp_le_lengthₓ'. -/
theorem countp_le_length : countp p l ≤ l.length := by
simpa only [countp_eq_length_filter] using length_filter_le _ _
#align list.countp_le_length List.countp_le_length
-/- warning: list.countp_append -> List.countp_append is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l₁ : List.{u1} α) (l₂ : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (Append.append.{u1} (List.{u1} α) (List.hasAppend.{u1} α) l₁ l₂)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l₁) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l₂))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α) (l₁ : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (HAppend.hAppend.{u1, u1, u1} (List.{u1} α) (List.{u1} α) (List.{u1} α) (instHAppend.{u1} (List.{u1} α) (List.instAppendList.{u1} α)) _inst_1 l₁)) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.countp.{u1} α p _inst_1) (List.countp.{u1} α p l₁))
-Case conversion may be inaccurate. Consider using '#align list.countp_append List.countp_appendₓ'. -/
@[simp]
theorem countp_append (l₁ l₂) : countp p (l₁ ++ l₂) = countp p l₁ + countp p l₂ := by
simp only [countp_eq_length_filter, filter_append, length_append]
#align list.countp_append List.countp_append
-/- warning: list.countp_join -> List.countp_join is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} (List.{u1} α)), Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (List.join.{u1} α l)) (List.sum.{0} Nat Nat.hasAdd Nat.hasZero (List.map.{u1, 0} (List.{u1} α) Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a)) l))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} (List.{u1} α)), Eq.{1} Nat (List.countp.{u1} α p (List.join.{u1} α _inst_1)) (List.sum.{0} Nat instAddNat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) (List.map.{u1, 0} (List.{u1} α) Nat (List.countp.{u1} α p) _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.countp_join List.countp_joinₓ'. -/
theorem countp_join : ∀ l : List (List α), countp p l.join = (l.map (countp p)).Sum
| [] => rfl
| a :: l => by rw [join, countp_append, map_cons, sum_cons, countp_join]
#align list.countp_join List.countp_join
-/- warning: list.countp_pos -> List.countp_pos is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (LT.lt.{0} Nat Nat.hasLt (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero))) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l)) (Exists.{succ u1} α (fun (a : α) => Exists.{0} (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) (fun (H : Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) => p a)))
-but is expected to have type
- forall {α : Type.{u1}} {p : List.{u1} α} (_inst_1 : α -> Bool), Iff (LT.lt.{0} Nat instLTNat (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0)) (List.countp.{u1} α _inst_1 p)) (Exists.{succ u1} α (fun (a : α) => And (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a p) (Eq.{1} Bool (_inst_1 a) Bool.true)))
-Case conversion may be inaccurate. Consider using '#align list.countp_pos List.countp_posₓ'. -/
theorem countp_pos {l} : 0 < countp p l ↔ ∃ a ∈ l, p a := by
simp only [countp_eq_length_filter, length_pos_iff_exists_mem, mem_filter, exists_prop]
#align list.countp_pos List.countp_pos
-/- warning: list.countp_eq_zero -> List.countp_eq_zero is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (Not (p a)))
-but is expected to have type
- forall {α : Type.{u1}} {p : List.{u1} α} (_inst_1 : α -> Bool), Iff (Eq.{1} Nat (List.countp.{u1} α _inst_1 p) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (forall (a : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a p) -> (Not (Eq.{1} Bool (_inst_1 a) Bool.true)))
-Case conversion may be inaccurate. Consider using '#align list.countp_eq_zero List.countp_eq_zeroₓ'. -/
@[simp]
theorem countp_eq_zero {l} : countp p l = 0 ↔ ∀ a ∈ l, ¬p a := by
rw [← not_iff_not, ← Ne.def, ← pos_iff_ne_zero, countp_pos]; simp
#align list.countp_eq_zero List.countp_eq_zero
-/- warning: list.countp_eq_length -> List.countp_eq_length is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] {l : List.{u1} α}, Iff (Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (List.length.{u1} α l)) (forall (a : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l) -> (p a))
-but is expected to have type
- forall {α : Type.{u1}} {p : List.{u1} α} (_inst_1 : α -> Bool), Iff (Eq.{1} Nat (List.countp.{u1} α _inst_1 p) (List.length.{u1} α p)) (forall (a : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a p) -> (Eq.{1} Bool (_inst_1 a) Bool.true))
-Case conversion may be inaccurate. Consider using '#align list.countp_eq_length List.countp_eq_lengthₓ'. -/
@[simp]
theorem countp_eq_length {l} : countp p l = l.length ↔ ∀ a ∈ l, p a := by
rw [countp_eq_length_filter, filter_length_eq_length]
#align list.countp_eq_length List.countp_eq_length
-/- warning: list.length_filter_lt_length_iff_exists -> List.length_filter_lt_length_iff_exists is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Iff (LT.lt.{0} Nat Nat.hasLt (List.length.{u1} α (List.filterₓ.{u1} α p (fun (a : α) => _inst_1 a) l)) (List.length.{u1} α l)) (Exists.{succ u1} α (fun (x : α) => Exists.{0} (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) (fun (H : Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) => Not (p x))))
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Iff (LT.lt.{0} Nat instLTNat (List.length.{u1} α (List.filter.{u1} α p _inst_1)) (List.length.{u1} α _inst_1)) (Exists.{succ u1} α (fun (x : α) => And (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x _inst_1) (Not (Eq.{1} Bool (p x) Bool.true))))
-Case conversion may be inaccurate. Consider using '#align list.length_filter_lt_length_iff_exists List.length_filter_lt_length_iff_existsₓ'. -/
theorem length_filter_lt_length_iff_exists (l) : length (filter p l) < length l ↔ ∃ x ∈ l, ¬p x :=
by
rw [length_eq_countp_add_countp p l, ← countp_pos, countp_eq_length_filter, lt_add_iff_pos_right]
#align list.length_filter_lt_length_iff_exists List.length_filter_lt_length_iff_exists
-/- warning: list.sublist.countp_le -> List.Sublist.countp_le is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {l₁ : List.{u1} α} {l₂ : List.{u1} α} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], (List.Sublist.{u1} α l₁ l₂) -> (LE.le.{0} Nat Nat.hasLe (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l₁) (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l₂))
-but is expected to have type
- forall {α : Type.{u1}} (l₁ : α -> Bool) {l₂ : List.{u1} α} {p : List.{u1} α}, (List.Sublist.{u1} α l₂ p) -> (LE.le.{0} Nat instLENat (List.countp.{u1} α l₁ l₂) (List.countp.{u1} α l₁ p))
-Case conversion may be inaccurate. Consider using '#align list.sublist.countp_le List.Sublist.countp_leₓ'. -/
theorem Sublist.countp_le (s : l₁ <+ l₂) : countp p l₁ ≤ countp p l₂ := by
simpa only [countp_eq_length_filter] using length_le_of_sublist (s.filter p)
#align list.sublist.countp_le List.Sublist.countp_le
-/- warning: list.countp_filter -> List.countp_filter is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} (p : α -> Prop) (q : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] [_inst_2 : DecidablePred.{succ u1} α q] (l : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) (List.filterₓ.{u1} α q (fun (a : α) => _inst_2 a) l)) (List.countp.{u1} α (fun (a : α) => And (p a) (q a)) (fun (a : α) => And.decidable (p a) (q a) (_inst_1 a) (_inst_2 a)) l)
-but is expected to have type
- forall {α : Type.{u1}} (p : α -> Bool) (q : α -> Bool) (_inst_1 : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p (List.filter.{u1} α q _inst_1)) (List.countp.{u1} α (fun (a : α) => Decidable.decide (And (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (q a) Bool.true)) (instDecidableAnd (Eq.{1} Bool (p a) Bool.true) (Eq.{1} Bool (q a) Bool.true) (instDecidableEqBool (p a) Bool.true) (instDecidableEqBool (q a) Bool.true))) _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.countp_filter List.countp_filterₓ'. -/
@[simp]
theorem countp_filter (l : List α) : countp p (filter q l) = countp (fun a => p a ∧ q a) l := by
simp only [countp_eq_length_filter, filter_filter]
@@ -211,12 +121,6 @@ theorem countp_false : (l.countp fun _ => False) = 0 := by simp
#align list.countp_false List.countp_false
-/
-/- warning: list.countp_map -> List.countp_map is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {β : Type.{u2}} (p : β -> Prop) [_inst_3 : DecidablePred.{succ u2} β p] (f : α -> β) (l : List.{u1} α), Eq.{1} Nat (List.countp.{u2} β p (fun (a : β) => _inst_3 a) (List.map.{u1, u2} α β f l)) (List.countp.{u1} α (Function.comp.{succ u1, succ u2, 1} α β Prop p f) (fun (a : α) => _inst_3 (f a)) l)
-but is expected to have type
- forall {α : Type.{u1}} {β : Type.{u2}} (p : β -> Bool) (_inst_3 : α -> β) (f : List.{u1} α), Eq.{1} Nat (List.countp.{u2} β p (List.map.{u1, u2} α β _inst_3 f)) (List.countp.{u1} α (Function.comp.{succ u1, succ u2, 1} α β Bool p _inst_3) f)
-Case conversion may be inaccurate. Consider using '#align list.countp_map List.countp_mapₓ'. -/
@[simp]
theorem countp_map (p : β → Prop) [DecidablePred p] (f : α → β) :
∀ l, countp p (map f l) = countp (p ∘ f) l
@@ -226,12 +130,6 @@ theorem countp_map (p : β → Prop) [DecidablePred p] (f : α → β) :
variable {p q}
-/- warning: list.countp_mono_left -> List.countp_mono_left is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {l : List.{u1} α} {p : α -> Prop} {q : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] [_inst_2 : DecidablePred.{succ u1} α q], (forall (x : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (p x) -> (q x)) -> (LE.le.{0} Nat Nat.hasLe (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (List.countp.{u1} α q (fun (a : α) => _inst_2 a) l))
-but is expected to have type
- forall {α : Type.{u1}} {l : List.{u1} α} {p : α -> Bool} {q : α -> Bool}, (forall (x : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x l) -> (Eq.{1} Bool (p x) Bool.true) -> (Eq.{1} Bool (q x) Bool.true)) -> (LE.le.{0} Nat instLENat (List.countp.{u1} α p l) (List.countp.{u1} α q l))
-Case conversion may be inaccurate. Consider using '#align list.countp_mono_left List.countp_mono_leftₓ'. -/
theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp q l :=
by
induction' l with a l ihl; · rfl
@@ -242,12 +140,6 @@ theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp
exact absurd (ha ‹_›) ‹_›
#align list.countp_mono_left List.countp_mono_left
-/- warning: list.countp_congr -> List.countp_congr is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {l : List.{u1} α} {p : α -> Prop} {q : α -> Prop} [_inst_1 : DecidablePred.{succ u1} α p] [_inst_2 : DecidablePred.{succ u1} α q], (forall (x : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) x l) -> (Iff (p x) (q x))) -> (Eq.{1} Nat (List.countp.{u1} α p (fun (a : α) => _inst_1 a) l) (List.countp.{u1} α q (fun (a : α) => _inst_2 a) l))
-but is expected to have type
- forall {α : Type.{u1}} {l : List.{u1} α} {p : α -> Bool} {q : α -> Bool}, (forall (x : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) x l) -> (Iff (Eq.{1} Bool (p x) Bool.true) (Eq.{1} Bool (q x) Bool.true))) -> (Eq.{1} Nat (List.countp.{u1} α p l) (List.countp.{u1} α q l))
-Case conversion may be inaccurate. Consider using '#align list.countp_congr List.countp_congrₓ'. -/
theorem countp_congr (h : ∀ x ∈ l, p x ↔ q x) : countp p l = countp q l :=
le_antisymm (countp_mono_left fun x hx => (h x hx).1) (countp_mono_left fun x hx => (h x hx).2)
#align list.countp_congr List.countp_congr
@@ -309,12 +201,6 @@ theorem count_le_length (a : α) (l : List α) : count a l ≤ l.length :=
#align list.count_le_length List.count_le_length
-/
-/- warning: list.sublist.count_le -> List.Sublist.count_le is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {l₁ : List.{u1} α} {l₂ : List.{u1} α} [_inst_1 : DecidableEq.{succ u1} α], (List.Sublist.{u1} α l₁ l₂) -> (forall (a : α), LE.le.{0} Nat Nat.hasLe (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l₁) (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l₂))
-but is expected to have type
- forall {α : Type.{u1}} [l₁ : DecidableEq.{succ u1} α] {l₂ : List.{u1} α} {_inst_1 : List.{u1} α}, (List.Sublist.{u1} α l₂ _inst_1) -> (forall (a : α), LE.le.{0} Nat instLENat (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => l₁ a b)) a l₂) (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => l₁ a b)) a _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.sublist.count_le List.Sublist.count_leₓ'. -/
theorem Sublist.count_le (h : l₁ <+ l₂) (a : α) : count a l₁ ≤ count a l₂ :=
h.countp_le _
#align list.sublist.count_le List.Sublist.count_le
@@ -383,23 +269,11 @@ theorem not_mem_of_count_eq_zero {a : α} {l : List α} (h : count a l = 0) : a
#align list.not_mem_of_count_eq_zero List.not_mem_of_count_eq_zero
-/
-/- warning: list.count_eq_zero -> List.count_eq_zero is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l : List.{u1} α}, Iff (Eq.{1} Nat (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (Not (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a l))
-but is expected to have type
- forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [a : DecidableEq.{succ u1} α] {l : α}, Iff (Eq.{1} Nat (List.count.{u1} α (instBEq.{u1} α (fun (a_1 : α) (b : α) => a a_1 b)) l _inst_1) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (Not (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) l _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.count_eq_zero List.count_eq_zeroₓ'. -/
@[simp]
theorem count_eq_zero {a : α} {l} : count a l = 0 ↔ a ∉ l :=
⟨not_mem_of_count_eq_zero, count_eq_zero_of_not_mem⟩
#align list.count_eq_zero List.count_eq_zero
-/- warning: list.count_eq_length -> List.count_eq_length is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l : List.{u1} α}, Iff (Eq.{1} Nat (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l) (List.length.{u1} α l)) (forall (b : α), (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) b l) -> (Eq.{succ u1} α a b))
-but is expected to have type
- forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [a : DecidableEq.{succ u1} α] {l : α}, Iff (Eq.{1} Nat (List.count.{u1} α (instBEq.{u1} α (fun (a_1 : α) (b : α) => a a_1 b)) l _inst_1) (List.length.{u1} α _inst_1)) (forall (b : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) b _inst_1) -> (Eq.{succ u1} α l b))
-Case conversion may be inaccurate. Consider using '#align list.count_eq_length List.count_eq_lengthₓ'. -/
@[simp]
theorem count_eq_length {a : α} {l} : count a l = l.length ↔ ∀ b ∈ l, a = b :=
countp_eq_length _
@@ -421,90 +295,42 @@ theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a =
#align list.count_replicate List.count_replicate
-/
-/- warning: list.filter_eq -> List.filter_eq is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (Eq.{succ u1} α a) (fun (a_1 : α) => _inst_1 a a_1) l) (List.replicate.{u1} α (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l) a)
-but is expected to have type
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (a_1 : α) => Decidable.decide (Eq.{succ u1} α a a_1) (_inst_1 a a_1)) l) (List.replicate.{u1} α (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a l) a)
-Case conversion may be inaccurate. Consider using '#align list.filter_eq List.filter_eqₓ'. -/
theorem filter_eq (l : List α) (a : α) : l.filterₓ (Eq a) = replicate (count a l) a := by
simp [eq_replicate, count, countp_eq_length_filter, @eq_comm _ _ a]
#align list.filter_eq List.filter_eq
-/- warning: list.filter_eq' -> List.filter_eq' is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.filterₓ.{u1} α (fun (x : α) => Eq.{succ u1} α x a) (fun (a_1 : α) => _inst_1 a_1 a) l) (List.replicate.{u1} α (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l) a)
-but is expected to have type
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (l : List.{u1} α) (a : α), Eq.{succ u1} (List.{u1} α) (List.filter.{u1} α (fun (a_1 : α) => Decidable.decide (Eq.{succ u1} α a_1 a) (_inst_1 a_1 a)) l) (List.replicate.{u1} α (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a l) a)
-Case conversion may be inaccurate. Consider using '#align list.filter_eq' List.filter_eq'ₓ'. -/
theorem filter_eq' (l : List α) (a : α) : (l.filterₓ fun x => x = a) = replicate (count a l) a := by
simp only [filter_eq, @eq_comm _ _ a]
#align list.filter_eq' List.filter_eq'
-/- warning: list.le_count_iff_replicate_sublist -> List.le_count_iff_replicate_sublist is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l : List.{u1} α} {n : Nat}, Iff (LE.le.{0} Nat Nat.hasLe n (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l)) (List.Sublist.{u1} α (List.replicate.{u1} α n a) l)
-but is expected to have type
- forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [a : DecidableEq.{succ u1} α] {l : Nat} {n : α}, Iff (LE.le.{0} Nat instLENat l (List.count.{u1} α (instBEq.{u1} α (fun (a_1 : α) (b : α) => a a_1 b)) n _inst_1)) (List.Sublist.{u1} α (List.replicate.{u1} α l n) _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.le_count_iff_replicate_sublist List.le_count_iff_replicate_sublistₓ'. -/
theorem le_count_iff_replicate_sublist {a : α} {l : List α} {n : ℕ} :
n ≤ count a l ↔ replicate n a <+ l :=
⟨fun h => ((replicate_sublist_replicate a).2 h).trans <| filter_eq l a ▸ filter_sublist _,
fun h => by simpa only [count_replicate_self] using h.count_le a⟩
#align list.le_count_iff_replicate_sublist List.le_count_iff_replicate_sublist
-/- warning: list.replicate_count_eq_of_count_eq_length -> List.replicate_count_eq_of_count_eq_length is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {a : α} {l : List.{u1} α}, (Eq.{1} Nat (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l) (List.length.{u1} α l)) -> (Eq.{succ u1} (List.{u1} α) (List.replicate.{u1} α (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l) a) l)
-but is expected to have type
- forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [a : DecidableEq.{succ u1} α] {l : α}, (Eq.{1} Nat (List.count.{u1} α (instBEq.{u1} α (fun (a_1 : α) (b : α) => a a_1 b)) l _inst_1) (List.length.{u1} α _inst_1)) -> (Eq.{succ u1} (List.{u1} α) (List.replicate.{u1} α (List.count.{u1} α (instBEq.{u1} α (fun (a_1 : α) (b : α) => a a_1 b)) l _inst_1) l) _inst_1)
-Case conversion may be inaccurate. Consider using '#align list.replicate_count_eq_of_count_eq_length List.replicate_count_eq_of_count_eq_lengthₓ'. -/
theorem replicate_count_eq_of_count_eq_length {a : α} {l : List α} (h : count a l = length l) :
replicate (count a l) a = l :=
(le_count_iff_replicate_sublist.mp le_rfl).eq_of_length <|
(length_replicate (count a l) a).trans h
#align list.replicate_count_eq_of_count_eq_length List.replicate_count_eq_of_count_eq_length
-/- warning: list.count_filter -> List.count_filter is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {p : α -> Prop} [_inst_2 : DecidablePred.{succ u1} α p] {a : α} {l : List.{u1} α}, (p a) -> (Eq.{1} Nat (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) l)) (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l))
-but is expected to have type
- forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [p : DecidableEq.{succ u1} α] {_inst_2 : α -> Bool} {a : α}, (Eq.{1} Bool (_inst_2 a) Bool.true) -> (Eq.{1} Nat (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => p a b)) a (List.filter.{u1} α _inst_2 _inst_1)) (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => p a b)) a _inst_1))
-Case conversion may be inaccurate. Consider using '#align list.count_filter List.count_filterₓ'. -/
@[simp]
theorem count_filter {p} [DecidablePred p] {a} {l : List α} (h : p a) :
count a (filter p l) = count a l := by
simp only [count, countp_filter, show (fun b => a = b ∧ p b) = Eq a by ext b; constructor <;> cc]
#align list.count_filter List.count_filter
-/- warning: list.count_bind -> List.count_bind is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {β : Type.{u2}} [_inst_2 : DecidableEq.{succ u2} β] (l : List.{u1} α) (f : α -> (List.{u2} β)) (x : β), Eq.{1} Nat (List.count.{u2} β (fun (a : β) (b : β) => _inst_2 a b) x (List.bind.{u1, u2} α β l f)) (List.sum.{0} Nat Nat.hasAdd Nat.hasZero (List.map.{u1, 0} α Nat (Function.comp.{succ u1, succ u2, 1} α (List.{u2} β) Nat (List.count.{u2} β (fun (a : β) (b : β) => _inst_2 a b) x) f) l))
-but is expected to have type
- forall {α : Type.{u2}} {β : Type.{u1}} [_inst_2 : DecidableEq.{succ u1} β] (l : List.{u2} α) (f : α -> (List.{u1} β)) (x : β), Eq.{1} Nat (List.count.{u1} β (instBEq.{u1} β (fun (a : β) (b : β) => _inst_2 a b)) x (List.bind.{u2, u1} α β l f)) (List.sum.{0} Nat instAddNat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) (List.map.{u2, 0} α Nat (Function.comp.{succ u2, succ u1, 1} α (List.{u1} β) Nat (List.count.{u1} β (instBEq.{u1} β (fun (a : β) (b : β) => _inst_2 a b)) x) f) l))
-Case conversion may be inaccurate. Consider using '#align list.count_bind List.count_bindₓ'. -/
theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (x : β) :
count x (l.bind f) = sum (map (count x ∘ f) l) := by rw [List.bind, count_join, map_map]
#align list.count_bind List.count_bind
-/- warning: list.count_map_of_injective -> List.count_map_of_injective is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {β : Type.{u2}} [_inst_2 : DecidableEq.{succ u1} α] [_inst_3 : DecidableEq.{succ u2} β] (l : List.{u1} α) (f : α -> β), (Function.Injective.{succ u1, succ u2} α β f) -> (forall (x : α), Eq.{1} Nat (List.count.{u2} β (fun (a : β) (b : β) => _inst_3 a b) (f x) (List.map.{u1, u2} α β f l)) (List.count.{u1} α (fun (a : α) (b : α) => _inst_2 a b) x l))
-but is expected to have type
- forall {α : Type.{u2}} {β : Type.{u1}} [_inst_2 : DecidableEq.{succ u2} α] [_inst_3 : DecidableEq.{succ u1} β] (l : List.{u2} α) (f : α -> β), (Function.Injective.{succ u2, succ u1} α β f) -> (forall (x : α), Eq.{1} Nat (List.count.{u1} β (instBEq.{u1} β (fun (a : β) (b : β) => _inst_3 a b)) (f x) (List.map.{u2, u1} α β f l)) (List.count.{u2} α (instBEq.{u2} α (fun (a : α) (b : α) => _inst_2 a b)) x l))
-Case conversion may be inaccurate. Consider using '#align list.count_map_of_injective List.count_map_of_injectiveₓ'. -/
@[simp]
theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : List α) (f : α → β)
(hf : Function.Injective f) (x : α) : count (f x) (map f l) = count x l := by
simp only [count, countp_map, (· ∘ ·), hf.eq_iff]
#align list.count_map_of_injective List.count_map_of_injective
-/- warning: list.count_le_count_map -> List.count_le_count_map is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (l : List.{u1} α) (f : α -> β) (x : α), LE.le.{0} Nat Nat.hasLe (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) x l) (List.count.{u2} β (fun (a : β) (b : β) => _inst_2 a b) (f x) (List.map.{u1, u2} α β f l))
-but is expected to have type
- forall {α : Type.{u1}} [β : DecidableEq.{succ u1} α] {_inst_1 : Type.{u2}} [_inst_2 : DecidableEq.{succ u2} _inst_1] (l : List.{u1} α) (f : α -> _inst_1) (x : α), LE.le.{0} Nat instLENat (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => β a b)) x l) (List.count.{u2} _inst_1 (instBEq.{u2} _inst_1 (fun (a : _inst_1) (b : _inst_1) => _inst_2 a b)) (f x) (List.map.{u1, u2} α _inst_1 f l))
-Case conversion may be inaccurate. Consider using '#align list.count_le_count_map List.count_le_count_mapₓ'. -/
theorem count_le_count_map [DecidableEq β] (l : List α) (f : α → β) (x : α) :
count x l ≤ count (f x) (map f l) :=
by
@@ -541,12 +367,6 @@ theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (l : List α) : count a (l.e
#align list.count_erase_of_ne List.count_erase_of_ne
-/
-/- warning: list.prod_map_eq_pow_single -> List.prod_map_eq_pow_single is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : Monoid.{u2} β] {l : List.{u1} α} (a : α) (f : α -> β), (forall (a' : α), (Ne.{succ u1} α a' a) -> (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a' l) -> (Eq.{succ u2} β (f a') (OfNat.ofNat.{u2} β 1 (OfNat.mk.{u2} β 1 (One.one.{u2} β (MulOneClass.toHasOne.{u2} β (Monoid.toMulOneClass.{u2} β _inst_2))))))) -> (Eq.{succ u2} β (List.prod.{u2} β (MulOneClass.toHasMul.{u2} β (Monoid.toMulOneClass.{u2} β _inst_2)) (MulOneClass.toHasOne.{u2} β (Monoid.toMulOneClass.{u2} β _inst_2)) (List.map.{u1, u2} α β f l)) (HPow.hPow.{u2, 0, u2} β Nat β (instHPow.{u2, 0} β Nat (Monoid.Pow.{u2} β _inst_2)) (f a) (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l)))
-but is expected to have type
- forall {α : Type.{u1}} {β : List.{u1} α} [_inst_1 : DecidableEq.{succ u1} α] {_inst_2 : Type.{u2}} [l : Monoid.{u2} _inst_2] (a : α) (f : α -> _inst_2), (forall (a' : α), (Ne.{succ u1} α a' a) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a' β) -> (Eq.{succ u2} _inst_2 (f a') (OfNat.ofNat.{u2} _inst_2 1 (One.toOfNat1.{u2} _inst_2 (Monoid.toOne.{u2} _inst_2 l))))) -> (Eq.{succ u2} _inst_2 (List.prod.{u2} _inst_2 (MulOneClass.toMul.{u2} _inst_2 (Monoid.toMulOneClass.{u2} _inst_2 l)) (Monoid.toOne.{u2} _inst_2 l) (List.map.{u1, u2} α _inst_2 f β)) (HPow.hPow.{u2, 0, u2} _inst_2 Nat _inst_2 (instHPow.{u2, 0} _inst_2 Nat (Monoid.Pow.{u2} _inst_2 l)) (f a) (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a β)))
-Case conversion may be inaccurate. Consider using '#align list.prod_map_eq_pow_single List.prod_map_eq_pow_singleₓ'. -/
/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
@@ -562,12 +382,6 @@ theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
-/- warning: list.prod_eq_pow_single -> List.prod_eq_pow_single is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : Monoid.{u1} α] {l : List.{u1} α} (a : α), (forall (a' : α), (Ne.{succ u1} α a' a) -> (Membership.Mem.{u1, u1} α (List.{u1} α) (List.hasMem.{u1} α) a' l) -> (Eq.{succ u1} α a' (OfNat.ofNat.{u1} α 1 (OfNat.mk.{u1} α 1 (One.one.{u1} α (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α _inst_2))))))) -> (Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α _inst_2)) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α _inst_2)) l) (HPow.hPow.{u1, 0, u1} α Nat α (instHPow.{u1, 0} α Nat (Monoid.Pow.{u1} α _inst_2)) a (List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) a l)))
-but is expected to have type
- forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [_inst_2 : DecidableEq.{succ u1} α] [l : Monoid.{u1} α] (a : α), (forall (a' : α), (Ne.{succ u1} α a' a) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a' _inst_1) -> (Eq.{succ u1} α a' (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (Monoid.toOne.{u1} α l))))) -> (Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α l)) (Monoid.toOne.{u1} α l) _inst_1) (HPow.hPow.{u1, 0, u1} α Nat α (instHPow.{u1, 0} α Nat (Monoid.Pow.{u1} α l)) a (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_2 a b)) a _inst_1)))
-Case conversion may be inaccurate. Consider using '#align list.prod_eq_pow_single List.prod_eq_pow_singleₓ'. -/
/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -152,10 +152,8 @@ but is expected to have type
forall {α : Type.{u1}} {p : List.{u1} α} (_inst_1 : α -> Bool), Iff (Eq.{1} Nat (List.countp.{u1} α _inst_1 p) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (forall (a : α), (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a p) -> (Not (Eq.{1} Bool (_inst_1 a) Bool.true)))
Case conversion may be inaccurate. Consider using '#align list.countp_eq_zero List.countp_eq_zeroₓ'. -/
@[simp]
-theorem countp_eq_zero {l} : countp p l = 0 ↔ ∀ a ∈ l, ¬p a :=
- by
- rw [← not_iff_not, ← Ne.def, ← pos_iff_ne_zero, countp_pos]
- simp
+theorem countp_eq_zero {l} : countp p l = 0 ↔ ∀ a ∈ l, ¬p a := by
+ rw [← not_iff_not, ← Ne.def, ← pos_iff_ne_zero, countp_pos]; simp
#align list.countp_eq_zero List.countp_eq_zero
/- warning: list.countp_eq_length -> List.countp_eq_length is a dubious translation:
@@ -301,9 +299,7 @@ theorem count_cons_of_ne {a b : α} (h : a ≠ b) (l : List α) : count a (b ::
theorem count_tail :
∀ (l : List α) (a : α) (h : 0 < l.length),
l.tail.count a = l.count a - ite (a = List.nthLe l 0 h) 1 0
- | _ :: _, a, h => by
- rw [count_cons]
- split_ifs <;> simp
+ | _ :: _, a, h => by rw [count_cons]; split_ifs <;> simp
#align list.count_tail List.count_tail
-/
@@ -478,10 +474,7 @@ Case conversion may be inaccurate. Consider using '#align list.count_filter List
@[simp]
theorem count_filter {p} [DecidablePred p] {a} {l : List α} (h : p a) :
count a (filter p l) = count a l := by
- simp only [count, countp_filter,
- show (fun b => a = b ∧ p b) = Eq a by
- ext b
- constructor <;> cc]
+ simp only [count, countp_filter, show (fun b => a = b ∧ p b) = Eq a by ext b; constructor <;> cc]
#align list.count_filter List.count_filter
/- warning: list.count_bind -> List.count_bind is a dubious translation:
mathlib commit https://github.com/leanprover-community/mathlib/commit/8d33f09cd7089ecf074b4791907588245aec5d1b
@@ -82,10 +82,11 @@ but is expected to have type
forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{1} Nat (List.length.{u1} α _inst_1) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (List.countp.{u1} α p _inst_1) (List.countp.{u1} α (fun (a : α) => Decidable.decide (Not (Eq.{1} Bool (p a) Bool.true)) (instDecidableNot (Eq.{1} Bool (p a) Bool.true) (instDecidableEqBool (p a) Bool.true))) _inst_1))
Case conversion may be inaccurate. Consider using '#align list.length_eq_countp_add_countp List.length_eq_countp_add_countpₓ'. -/
theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
- induction' l with x h ih <;> [rfl, by_cases p x] <;>
+ induction' l with x h ih <;> [rfl;by_cases p x] <;>
[simp only [countp_cons_of_pos _ _ h,
- countp_cons_of_neg (fun a => ¬p a) _ (Decidable.not_not.2 h), ih, length],
- simp only [countp_cons_of_pos (fun a => ¬p a) _ h, countp_cons_of_neg _ _ h, ih, length]] <;>
+ countp_cons_of_neg (fun a => ¬p a) _ (Decidable.not_not.2 h), ih,
+ length];simp only [countp_cons_of_pos (fun a => ¬p a) _ h, countp_cons_of_neg _ _ h, ih,
+ length]] <;>
ac_rfl
#align list.length_eq_countp_add_countp List.length_eq_countp_add_countp
@@ -96,9 +97,9 @@ but is expected to have type
forall {α : Type.{u1}} (p : α -> Bool) (_inst_1 : List.{u1} α), Eq.{1} Nat (List.countp.{u1} α p _inst_1) (List.length.{u1} α (List.filter.{u1} α p _inst_1))
Case conversion may be inaccurate. Consider using '#align list.countp_eq_length_filter List.countp_eq_length_filterₓ'. -/
theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
- induction' l with x l ih <;> [rfl, by_cases p x] <;>
- [simp only [filter_cons_of_pos _ h, countp, ih, if_pos h],
- simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]] <;>
+ induction' l with x l ih <;> [rfl;by_cases p x] <;>
+ [simp only [filter_cons_of_pos _ h, countp, ih,
+ if_pos h];simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]] <;>
rfl
#align list.countp_eq_length_filter List.countp_eq_length_filter
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -553,7 +553,7 @@ lean 3 declaration is
but is expected to have type
forall {α : Type.{u1}} {β : List.{u1} α} [_inst_1 : DecidableEq.{succ u1} α] {_inst_2 : Type.{u2}} [l : Monoid.{u2} _inst_2] (a : α) (f : α -> _inst_2), (forall (a' : α), (Ne.{succ u1} α a' a) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a' β) -> (Eq.{succ u2} _inst_2 (f a') (OfNat.ofNat.{u2} _inst_2 1 (One.toOfNat1.{u2} _inst_2 (Monoid.toOne.{u2} _inst_2 l))))) -> (Eq.{succ u2} _inst_2 (List.prod.{u2} _inst_2 (MulOneClass.toMul.{u2} _inst_2 (Monoid.toMulOneClass.{u2} _inst_2 l)) (Monoid.toOne.{u2} _inst_2 l) (List.map.{u1, u2} α _inst_2 f β)) (HPow.hPow.{u2, 0, u2} _inst_2 Nat _inst_2 (instHPow.{u2, 0} _inst_2 Nat (Monoid.Pow.{u2} _inst_2 l)) (f a) (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a β)))
Case conversion may be inaccurate. Consider using '#align list.prod_map_eq_pow_single List.prod_map_eq_pow_singleₓ'. -/
-/- ./././Mathport/Syntax/Translate/Basic.lean:628:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] {l : List α} (a : α) (f : α → β)
(hf : ∀ (a') (_ : a' ≠ a), a' ∈ l → f a' = 1) : (l.map f).Prod = f a ^ l.count a :=
@@ -574,7 +574,7 @@ lean 3 declaration is
but is expected to have type
forall {α : Type.{u1}} {_inst_1 : List.{u1} α} [_inst_2 : DecidableEq.{succ u1} α] [l : Monoid.{u1} α] (a : α), (forall (a' : α), (Ne.{succ u1} α a' a) -> (Membership.mem.{u1, u1} α (List.{u1} α) (List.instMembershipList.{u1} α) a' _inst_1) -> (Eq.{succ u1} α a' (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α (Monoid.toOne.{u1} α l))))) -> (Eq.{succ u1} α (List.prod.{u1} α (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α l)) (Monoid.toOne.{u1} α l) _inst_1) (HPow.hPow.{u1, 0, u1} α Nat α (instHPow.{u1, 0} α Nat (Monoid.Pow.{u1} α l)) a (List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_2 a b)) a _inst_1)))
Case conversion may be inaccurate. Consider using '#align list.prod_eq_pow_single List.prod_eq_pow_singleₓ'. -/
-/- ./././Mathport/Syntax/Translate/Basic.lean:628:2: warning: expanding binder collection (a' «expr ≠ » a) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (a' «expr ≠ » a) -/
@[to_additive]
theorem prod_eq_pow_single [Monoid α] {l : List α} (a : α)
(h : ∀ (a') (_ : a' ≠ a), a' ∈ l → a' = 1) : l.Prod = a ^ l.count a :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
Most of them go back to the port.
@@ -86,7 +86,8 @@ variable [DecidableEq α]
#align list.count_nil List.count_nil
-@[deprecated] theorem count_cons' (a b : α) (l : List α) :
+@[deprecated] -- 2023-08-23
+theorem count_cons' (a b : α) (l : List α) :
count a (b :: l) = count a l + if a = b then 1 else 0 := by
simp only [count, beq_iff_eq, countP_cons, Nat.add_right_inj]
simp only [eq_comm]
Data.List.Count
, Data.List.Dedup
, Data.List.ProdSigma
, Data.List.Range
, Data.List.Rotate
, Data.List.Zip
not depend on Data.List.BigOperators.Basic
.Data.List.BigOperators.Basic
. For the lemmas that were Nat
-specific, keep a version of them in the original file but stated using Nat.sum
.Nat.sum_eq_listSum (l : List Nat) : Nat.sum l = l.sum
.@@ -3,7 +3,7 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-/
-import Mathlib.Algebra.BigOperators.List.Basic
+import Mathlib.Data.List.Basic
#align_import data.list.count from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
@@ -15,12 +15,13 @@ elements of a list satisfying a predicate and equal to a given element respectiv
definitions can be found in `Std.Data.List.Basic`.
-/
-set_option autoImplicit true
-
+assert_not_exists Set.range
+assert_not_exists GroupWithZero
+assert_not_exists Ring
open Nat
-variable {l : List α}
+variable {α : Type*} {l : List α}
namespace List
@@ -44,11 +45,6 @@ variable (p q : α → Bool)
#align list.countp_append List.countP_append
-theorem countP_join : ∀ l : List (List α), countP p l.join = (l.map (countP p)).sum
- | [] => rfl
- | a :: l => by rw [join, countP_append, map_cons, sum_cons, countP_join l]
-#align list.countp_join List.countP_join
-
#align list.countp_pos List.countP_pos
#align list.countp_eq_zero List.countP_eq_zero
@@ -92,7 +88,7 @@ variable [DecidableEq α]
@[deprecated] theorem count_cons' (a b : α) (l : List α) :
count a (b :: l) = count a l + if a = b then 1 else 0 := by
- simp only [count, beq_iff_eq, countP_cons, add_right_inj]
+ simp only [count, beq_iff_eq, countP_cons, Nat.add_right_inj]
simp only [eq_comm]
#align list.count_cons' List.count_cons'
@@ -116,10 +112,6 @@ variable [DecidableEq α]
#align list.count_append List.count_append
-theorem count_join (l : List (List α)) (a : α) : l.join.count a = (l.map (count a)).sum :=
- countP_join _ _
-#align list.count_join List.count_join
-
#align list.count_concat List.count_concat
#align list.count_pos List.count_pos_iff_mem
@@ -148,10 +140,6 @@ theorem count_join (l : List (List α)) (a : α) : l.join.count a = (l.map (coun
#align list.count_filter List.count_filter
-theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (x : β) :
- count x (l.bind f) = sum (map (count x ∘ f) l) := by rw [List.bind, count_join, map_map]
-#align list.count_bind List.count_bind
-
@[simp]
lemma count_attach (a : {x // x ∈ l}) : l.attach.count a = l.count ↑a :=
Eq.trans (countP_congr fun _ _ => by simp [Subtype.ext_iff]) <| countP_attach _ _
@@ -171,26 +159,6 @@ theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : Li
#align list.count_erase_of_ne List.count_erase_of_ne
-@[to_additive]
-theorem prod_map_eq_pow_single [Monoid β] (a : α) (f : α → β)
- (hf : ∀ a', a' ≠ a → a' ∈ l → f a' = 1) : (l.map f).prod = f a ^ l.count a := by
- induction' l with a' as h generalizing a
- · rw [map_nil, prod_nil, count_nil, _root_.pow_zero]
- · specialize h a fun a' ha' hfa' => hf a' ha' (mem_cons_of_mem _ hfa')
- rw [List.map_cons, List.prod_cons, count_cons, h]
- split_ifs with ha'
- · rw [ha', _root_.pow_succ']
- · rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul, add_zero]
-#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
-#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
-
-@[to_additive]
-theorem prod_eq_pow_single [Monoid α] (a : α)
- (h : ∀ a', a' ≠ a → a' ∈ l → a' = 1) : l.prod = a ^ l.count a :=
- _root_.trans (by rw [map_id]) (prod_map_eq_pow_single a id h)
-#align list.prod_eq_pow_single List.prod_eq_pow_single
-#align list.sum_eq_nsmul_single List.sum_eq_nsmul_single
-
end Count
end List
Algebra.BigOperators.List
(#11729)
This is algebra and should be foldered as such.
@@ -3,7 +3,7 @@ Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-/
-import Mathlib.Data.List.BigOperators.Basic
+import Mathlib.Algebra.BigOperators.List.Basic
#align_import data.list.count from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
We change the following field in the definition of an additive commutative monoid:
nsmul_succ : ∀ (n : ℕ) (x : G),
- AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+ AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x
where the latter is more natural
We adjust the definitions of ^
in monoids, groups, etc.
Originally there was a warning comment about why this natural order was preferred
use
x * npowRec n x
and notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
is blocked, to avoid deep recursion issues.
but it seems to no longer apply.
Remarks on the PR :
pow_succ
and pow_succ'
have switched their meanings.Ideal.IsPrime.mul_mem_pow
which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul
.@@ -179,7 +179,7 @@ theorem prod_map_eq_pow_single [Monoid β] (a : α) (f : α → β)
· specialize h a fun a' ha' hfa' => hf a' ha' (mem_cons_of_mem _ hfa')
rw [List.map_cons, List.prod_cons, count_cons, h]
split_ifs with ha'
- · rw [ha', _root_.pow_succ]
+ · rw [ha', _root_.pow_succ']
· rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul, add_zero]
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -71,7 +71,7 @@ theorem length_filter_lt_length_iff_exists (l) :
#align list.countp_map List.countP_map
--- porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
+-- Porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
lemma countP_attach (l : List α) : l.attach.countP (fun a : {x // x ∈ l} ↦ p a) = l.countP p := by
simp_rw [← Function.comp_apply (g := Subtype.val), ← countP_map, attach_map_val]
#align list.countp_attach List.countP_attach
@@ -73,7 +73,7 @@ theorem length_filter_lt_length_iff_exists (l) :
-- porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
lemma countP_attach (l : List α) : l.attach.countP (fun a : {x // x ∈ l} ↦ p a) = l.countP p := by
- simp_rw [←Function.comp_apply (g := Subtype.val), ←countP_map, attach_map_val]
+ simp_rw [← Function.comp_apply (g := Subtype.val), ← countP_map, attach_map_val]
#align list.countp_attach List.countP_attach
#align list.countp_mono_left List.countP_mono_left
attach
and filter
lemmas (#1470)
Match https://github.com/leanprover-community/mathlib/pull/18087
@@ -5,7 +5,7 @@ Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, M
-/
import Mathlib.Data.List.BigOperators.Basic
-#align_import data.list.count from "leanprover-community/mathlib"@"47adfab39a11a072db552f47594bf8ed2cf8a722"
+#align_import data.list.count from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
/-!
# Counting in lists
@@ -71,6 +71,11 @@ theorem length_filter_lt_length_iff_exists (l) :
#align list.countp_map List.countP_map
+-- porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}`
+lemma countP_attach (l : List α) : l.attach.countP (fun a : {x // x ∈ l} ↦ p a) = l.countP p := by
+ simp_rw [←Function.comp_apply (g := Subtype.val), ←countP_map, attach_map_val]
+#align list.countp_attach List.countP_attach
+
#align list.countp_mono_left List.countP_mono_left
#align list.countp_congr List.countP_congr
@@ -147,6 +152,11 @@ theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (
count x (l.bind f) = sum (map (count x ∘ f) l) := by rw [List.bind, count_join, map_map]
#align list.count_bind List.count_bind
+@[simp]
+lemma count_attach (a : {x // x ∈ l}) : l.attach.count a = l.count ↑a :=
+ Eq.trans (countP_congr fun _ _ => by simp [Subtype.ext_iff]) <| countP_attach _ _
+#align list.count_attach List.count_attach
+
@[simp]
theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : List α) (f : α → β)
(hf : Function.Injective f) (x : α) : count (f x) (map f l) = count x l := by
Removes nonterminal simps on lines looking like simp [...]
@@ -86,9 +86,8 @@ variable [DecidableEq α]
#align list.count_nil List.count_nil
@[deprecated] theorem count_cons' (a b : α) (l : List α) :
- count a (b :: l) = count a l + if a = b then 1 else 0 := by conv =>
- simp [count, countP_cons]
- lhs
+ count a (b :: l) = count a l + if a = b then 1 else 0 := by
+ simp only [count, beq_iff_eq, countP_cons, add_right_inj]
simp only [eq_comm]
#align list.count_cons' List.count_cons'
This incorporates changes from https://github.com/leanprover-community/mathlib4/pull/6575
I have also renamed Multiset.countp
to Multiset.countP
for consistency.
Co-authored-by: James Gallichio <jamesgallicchio@gmail.com>
Co-authored-by: James <jamesgallicchio@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -10,7 +10,7 @@ import Mathlib.Data.List.BigOperators.Basic
/-!
# Counting in lists
-This file proves basic properties of `List.countp` and `List.count`, which count the number of
+This file proves basic properties of `List.countP` and `List.count`, which count the number of
elements of a list satisfying a predicate and equal to a given element respectively. Their
definitions can be found in `Std.Data.List.Basic`.
-/
@@ -24,144 +24,58 @@ variable {l : List α}
namespace List
-section Countp
+section CountP
variable (p q : α → Bool)
-@[simp]
-theorem countp_nil : countp p [] = 0 := rfl
-#align list.countp_nil List.countp_nil
-
--- Porting note: added to aid in the following proof.
-protected theorem countp_go_eq_add (l) : countp.go p l n = n + countp.go p l 0 := by
- induction' l with head tail ih generalizing n
- · rfl
- · unfold countp.go
- rw [ih (n := n + 1), ih (n := n), ih (n := 1)]
- by_cases h : p head
- · simp [h, add_assoc]
- · simp [h]
+#align list.countp_nil List.countP_nil
-@[simp]
-theorem countp_cons_of_pos {a : α} (l) (pa : p a) : countp p (a :: l) = countp p l + 1 := by
- have : countp.go p (a :: l) 0 = countp.go p l 1
- · change (bif _ then _ else _) = countp.go _ _ _
- rw [pa]
- rfl
- unfold countp
- rw [this, add_comm, List.countp_go_eq_add]
-#align list.countp_cons_of_pos List.countp_cons_of_pos
+#align list.countp_cons_of_pos List.countP_cons_of_pos
-@[simp]
-theorem countp_cons_of_neg {a : α} (l) (pa : ¬p a) : countp p (a :: l) = countp p l := by
- change (bif _ then _ else _) = countp.go _ _ _
- rw [Bool.of_not_eq_true pa]
- rfl
-#align list.countp_cons_of_neg List.countp_cons_of_neg
-
-theorem countp_cons (a : α) (l) : countp p (a :: l) = countp p l + if p a then 1 else 0 := by
- by_cases h : p a <;> simp [h]
-#align list.countp_cons List.countp_cons
-
-theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
- induction' l with x h ih
- · rfl
- by_cases h : p x
- · rw [countp_cons_of_pos _ _ h, countp_cons_of_neg _ _ _, length, ih]
- · ac_rfl
- · simp only [h]
- · rw [countp_cons_of_pos (fun a => ¬p a) _ _, countp_cons_of_neg _ _ h, length, ih]
- · ac_rfl
- · simp only [h]
-#align list.length_eq_countp_add_countp List.length_eq_countp_add_countp
-
-theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
- induction' l with x l ih
- · rfl
- by_cases h : p x
- · rw [countp_cons_of_pos p l h, ih, filter_cons_of_pos l h, length]
- · rw [countp_cons_of_neg p l h, ih, filter_cons_of_neg l h]
-#align list.countp_eq_length_filter List.countp_eq_length_filter
-
-theorem countp_le_length : countp p l ≤ l.length := by
- simpa only [countp_eq_length_filter] using length_filter_le _ _
-#align list.countp_le_length List.countp_le_length
+#align list.countp_cons_of_neg List.countP_cons_of_neg
-@[simp]
-theorem countp_append (l₁ l₂) : countp p (l₁ ++ l₂) = countp p l₁ + countp p l₂ := by
- simp only [countp_eq_length_filter, filter_append, length_append]
-#align list.countp_append List.countp_append
+#align list.countp_cons List.countP_cons
+
+#align list.length_eq_countp_add_countp List.length_eq_countP_add_countP
+
+#align list.countp_eq_length_filter List.countP_eq_length_filter
+
+#align list.countp_le_length List.countP_le_length
+
+#align list.countp_append List.countP_append
-theorem countp_join : ∀ l : List (List α), countp p l.join = (l.map (countp p)).sum
+theorem countP_join : ∀ l : List (List α), countP p l.join = (l.map (countP p)).sum
| [] => rfl
- | a :: l => by rw [join, countp_append, map_cons, sum_cons, countp_join l]
-#align list.countp_join List.countp_join
+ | a :: l => by rw [join, countP_append, map_cons, sum_cons, countP_join l]
+#align list.countp_join List.countP_join
-theorem countp_pos : 0 < countp p l ↔ ∃ a ∈ l, p a := by
- simp only [countp_eq_length_filter, length_pos_iff_exists_mem, mem_filter, exists_prop]
-#align list.countp_pos List.countp_pos
+#align list.countp_pos List.countP_pos
-@[simp]
-theorem countp_eq_zero : countp p l = 0 ↔ ∀ a ∈ l, ¬p a := by
- rw [← not_iff_not, ← Ne.def, ← pos_iff_ne_zero, countp_pos]
- simp
-#align list.countp_eq_zero List.countp_eq_zero
+#align list.countp_eq_zero List.countP_eq_zero
-@[simp]
-theorem countp_eq_length : countp p l = l.length ↔ ∀ a ∈ l, p a := by
- rw [countp_eq_length_filter, filter_length_eq_length]
-#align list.countp_eq_length List.countp_eq_length
+#align list.countp_eq_length List.countP_eq_length
theorem length_filter_lt_length_iff_exists (l) :
length (filter p l) < length l ↔ ∃ x ∈ l, ¬p x := by
- simpa [length_eq_countp_add_countp p l, countp_eq_length_filter] using
- countp_pos (fun x => ¬p x) (l := l)
+ simpa [length_eq_countP_add_countP p l, countP_eq_length_filter] using
+ countP_pos (fun x => ¬p x) (l := l)
#align list.length_filter_lt_length_iff_exists List.length_filter_lt_length_iff_exists
-theorem Sublist.countp_le (s : l₁ <+ l₂) : countp p l₁ ≤ countp p l₂ := by
- simpa only [countp_eq_length_filter] using length_le_of_sublist (s.filter p)
-#align list.sublist.countp_le List.Sublist.countp_le
+#align list.sublist.countp_le List.Sublist.countP_le
-@[simp]
-theorem countp_filter (l : List α) : countp p (filter q l) = countp (fun a => p a ∧ q a) l := by
- simp only [countp_eq_length_filter, filter_filter]
-#align list.countp_filter List.countp_filter
+#align list.countp_filter List.countP_filter
-@[simp]
-theorem countp_true : (l.countp fun _ => true) = l.length := by simp
-#align list.countp_true List.countp_true
+#align list.countp_true List.countP_true
-@[simp]
-theorem countp_false : (l.countp fun _ => false) = 0 := by simp
-#align list.countp_false List.countp_false
+#align list.countp_false List.countP_false
-@[simp]
-theorem countp_map (p : β → Bool) (f : α → β) :
- ∀ l, countp p (map f l) = countp (p ∘ f) l
- | [] => rfl
- | a :: l => by rw [map_cons, countp_cons, countp_cons, countp_map p f l]; rfl
-#align list.countp_map List.countp_map
-
-variable {p q}
-
-theorem countp_mono_left (h : ∀ x ∈ l, p x → q x) : countp p l ≤ countp q l := by
- induction' l with a l ihl
- · rfl
- rw [forall_mem_cons] at h
- cases' h with ha hl
- rw [countp_cons, countp_cons]
- refine' _root_.add_le_add (ihl hl) _
- split_ifs <;> simp only [le_rfl, _root_.zero_le]
- exact absurd (ha ‹_›) ‹_›
-#align list.countp_mono_left List.countp_mono_left
-
-theorem countp_congr (h : ∀ x ∈ l, p x ↔ q x) : countp p l = countp q l :=
- _root_.le_antisymm
- (countp_mono_left fun x hx => (h x hx).1)
- (countp_mono_left fun x hx => (h x hx).2)
-#align list.countp_congr List.countp_congr
-
-end Countp
+#align list.countp_map List.countP_map
+
+#align list.countp_mono_left List.countP_mono_left
+
+#align list.countp_congr List.countP_congr
+
+end CountP
/-! ### count -/
@@ -169,152 +83,65 @@ section Count
variable [DecidableEq α]
-@[simp]
-theorem count_nil (a : α) : count a [] = 0 := rfl
#align list.count_nil List.count_nil
-theorem count_cons' (a b : α) (l : List α) :
+@[deprecated] theorem count_cons' (a b : α) (l : List α) :
count a (b :: l) = count a l + if a = b then 1 else 0 := by conv =>
- simp [count, countp_cons]
+ simp [count, countP_cons]
lhs
simp only [eq_comm]
#align list.count_cons' List.count_cons'
-theorem count_cons (a b : α) (l : List α) :
- count a (b :: l) = if a = b then succ (count a l) else count a l := by
- simp [count_cons']
- split_ifs <;> rfl
#align list.count_cons List.count_cons
-@[simp]
-theorem count_cons_self (a : α) (l : List α) : count a (a :: l) = count a l + 1 := by
- simp [count_cons']
#align list.count_cons_self List.count_cons_self
-@[simp]
-theorem count_cons_of_ne (h : a ≠ b) (l : List α) : count a (b :: l) = count a l := by
- simp [count_cons']
- exact h
#align list.count_cons_of_ne List.count_cons_of_ne
-theorem count_tail :
- ∀ (l : List α) (a : α) (h : 0 < l.length),
- l.tail.count a = l.count a - if a = List.get l ⟨0, h⟩ then 1 else 0
- | head :: tail, a, h => by
- rw [count_cons']
- split_ifs <;> simp at * <;> contradiction
#align list.count_tail List.count_tail
-theorem count_le_length (a : α) (l : List α) : count a l ≤ l.length :=
- countp_le_length _
#align list.count_le_length List.count_le_length
-theorem Sublist.count_le (h : l₁ <+ l₂) (a : α) : count a l₁ ≤ count a l₂ :=
- h.countp_le _
#align list.sublist.count_le List.Sublist.count_le
-theorem count_le_count_cons (a b : α) (l : List α) : count a l ≤ count a (b :: l) :=
- (sublist_cons _ _).count_le _
#align list.count_le_count_cons List.count_le_count_cons
-theorem count_singleton (a : α) : count a [a] = 1 := by
- rw [count_cons]
- simp
#align list.count_singleton List.count_singleton
-theorem count_singleton' (a b : α) : count a [b] = if a = b then 1 else 0 := by
- rw [count_cons]
- rfl
#align list.count_singleton' List.count_singleton'
-@[simp]
-theorem count_append (a : α) : ∀ l₁ l₂, count a (l₁ ++ l₂) = count a l₁ + count a l₂ :=
- countp_append _
#align list.count_append List.count_append
theorem count_join (l : List (List α)) (a : α) : l.join.count a = (l.map (count a)).sum :=
- countp_join _ _
+ countP_join _ _
#align list.count_join List.count_join
-theorem count_concat (a : α) (l : List α) : count a (concat l a) = succ (count a l) := by simp
#align list.count_concat List.count_concat
-@[simp]
-theorem count_pos {a : α} {l : List α} : 0 < count a l ↔ a ∈ l := by
- simp only [count, countp_pos, beq_iff_eq, exists_eq_right]
-#align list.count_pos List.count_pos
+#align list.count_pos List.count_pos_iff_mem
-@[simp]
-theorem one_le_count_iff_mem {a : α} {l : List α} : 1 ≤ count a l ↔ a ∈ l := count_pos
-#align list.one_le_count_iff_mem List.one_le_count_iff_mem
+#align list.one_le_count_iff_mem List.count_pos_iff_mem
--- Porting note: lower priority to make simpNF linter happy
-@[simp 900]
-theorem count_eq_zero_of_not_mem {a : α} {l : List α} (h : a ∉ l) : count a l = 0 :=
- Decidable.by_contradiction fun h' => h <| count_pos.1 (Nat.pos_of_ne_zero h')
#align list.count_eq_zero_of_not_mem List.count_eq_zero_of_not_mem
-theorem not_mem_of_count_eq_zero {a : α} {l : List α} (h : count a l = 0) : a ∉ l :=
- fun h' => (count_pos.2 h').ne' h
#align list.not_mem_of_count_eq_zero List.not_mem_of_count_eq_zero
-@[simp]
-theorem count_eq_zero : count a l = 0 ↔ a ∉ l :=
- ⟨not_mem_of_count_eq_zero, count_eq_zero_of_not_mem⟩
#align list.count_eq_zero List.count_eq_zero
-@[simp]
-theorem count_eq_length : count a l = l.length ↔ ∀ b ∈ l, a = b := by
- simp_rw [count, countp_eq_length, beq_iff_eq, eq_comm]
#align list.count_eq_length List.count_eq_length
-@[simp]
-theorem count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n :=
- (count_eq_length.2 <| fun _ h => (eq_of_mem_replicate h).symm).trans (length_replicate _ _)
#align list.count_replicate_self List.count_replicate_self
-theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 := by
- split
- exacts [‹a = b› ▸ count_replicate_self _ _, count_eq_zero.2 <| mt eq_of_mem_replicate ‹a ≠ b›]
#align list.count_replicate List.count_replicate
--- porting note: new lemma
-theorem filter_beq' (l : List α) (a : α) : l.filter (· == a) = replicate (count a l) a := by
- simp only [count, countp_eq_length_filter, eq_replicate, mem_filter, beq_iff_eq]
- exact ⟨trivial, fun _ h => h.2⟩
-
-theorem filter_eq' (l : List α) (a : α) : l.filter (· = a) = replicate (count a l) a :=
- filter_beq' l a
#align list.filter_eq' List.filter_eq'
-theorem filter_eq (l : List α) (a : α) : l.filter (a = ·) = replicate (count a l) a := by
- simpa only [eq_comm] using filter_eq' l a
#align list.filter_eq List.filter_eq
--- porting note: new lemma
-theorem filter_beq (l : List α) (a : α) : l.filter (a == ·) = replicate (count a l) a :=
- filter_eq l a
-
-theorem le_count_iff_replicate_sublist : n ≤ count a l ↔ replicate n a <+ l :=
- ⟨fun h => ((replicate_sublist_replicate a).2 h).trans <| filter_eq l a ▸ filter_sublist _,
- fun h => by simpa only [count_replicate_self] using h.count_le a⟩
#align list.le_count_iff_replicate_sublist List.le_count_iff_replicate_sublist
-theorem replicate_count_eq_of_count_eq_length (h : count a l = length l) :
- replicate (count a l) a = l :=
- (le_count_iff_replicate_sublist.mp le_rfl).eq_of_length <|
- (length_replicate (count a l) a).trans h
#align list.replicate_count_eq_of_count_eq_length List.replicate_count_eq_of_count_eq_length
-@[simp]
-theorem count_filter (h : p a) : count a (filter p l) = count a l := by
- rw [count, countp_filter]
- congr
- funext b
- rw [Bool.beq_eq_decide_eq]
- by_cases hb : b = a
- · simp [hb, h]
- · simp [hb]
#align list.count_filter List.count_filter
theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (x : β) :
@@ -324,37 +151,15 @@ theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (
@[simp]
theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : List α) (f : α → β)
(hf : Function.Injective f) (x : α) : count (f x) (map f l) = count x l := by
- simp only [count, countp_map, (· ∘ ·), hf.beq_eq]
+ simp only [count, countP_map, (· ∘ ·), hf.beq_eq]
#align list.count_map_of_injective List.count_map_of_injective
-theorem count_le_count_map [DecidableEq β] (l : List α) (f : α → β) (x : α) :
- count x l ≤ count (f x) (map f l) := by
- rw [count, count, countp_map]
- exact countp_mono_left <| by simp (config := {contextual := true})
#align list.count_le_count_map List.count_le_count_map
-theorem count_erase (a b : α) :
- ∀ l : List α, count a (l.erase b) = count a l - if a = b then 1 else 0
- | [] => by simp
- | c :: l => by
- rw [erase_cons]
- by_cases hc : c = b
- · rw [if_pos hc, hc, count_cons', Nat.add_sub_cancel]
- · rw [if_neg hc, count_cons', count_cons', count_erase a b l]
- by_cases ha : a = b
- · rw [← ha, eq_comm] at hc
- rw [if_pos ha, if_neg hc, add_zero, add_zero]
- · rw [if_neg ha, tsub_zero, tsub_zero]
#align list.count_erase List.count_erase
-@[simp]
-theorem count_erase_self (a : α) (l : List α) : count a (List.erase l a) = count a l - 1 := by
- rw [count_erase, if_pos rfl]
#align list.count_erase_self List.count_erase_self
-@[simp]
-theorem count_erase_of_ne (ab : a ≠ b) (l : List α) : count a (l.erase b) = count a l :=
- by rw [count_erase, if_neg ab, tsub_zero]
#align list.count_erase_of_ne List.count_erase_of_ne
@[to_additive]
@@ -366,7 +171,7 @@ theorem prod_map_eq_pow_single [Monoid β] (a : α) (f : α → β)
rw [List.map_cons, List.prod_cons, count_cons, h]
split_ifs with ha'
· rw [ha', _root_.pow_succ]
- · rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul]
+ · rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul, add_zero]
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
Autoimplicits are highly controversial and also defeat the performance-improving work in #6474.
The intent of this PR is to make autoImplicit
opt-in on a per-file basis, by disabling it in the lakefile and enabling it again with set_option autoImplicit true
in the few files that rely on it.
That also keeps this PR small, as opposed to attempting to "fix" files to not need it any more.
I claim that many of the uses of autoImplicit
in these files are accidental; situations such as:
variables
are in scope, but pasting the lemma in the wrong sectionHaving set_option autoImplicit false
as the default prevents these types of mistake being made in the 90% of files where autoImplicit
s are not used at all, and causes them to be caught by CI during review.
I think there were various points during the port where we encouraged porters to delete the universes u v
lines; I think having autoparams for universe variables only would cover a lot of the cases we actually use them, while avoiding any real shortcomings.
A Zulip poll (after combining overlapping votes accordingly) was in favor of this change with 5:5:18
as the no:dontcare:yes
vote ratio.
While this PR was being reviewed, a handful of files gained some more likely-accidental autoImplicits. In these places, set_option autoImplicit true
has been placed locally within a section, rather than at the top of the file.
@@ -15,6 +15,8 @@ elements of a list satisfying a predicate and equal to a given element respectiv
definitions can be found in `Std.Data.List.Basic`.
-/
+set_option autoImplicit true
+
open Nat
@@ -2,14 +2,11 @@
Copyright (c) 2014 Parikshit Khanna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
-
-! This file was ported from Lean 3 source module data.list.count
-! leanprover-community/mathlib commit 47adfab39a11a072db552f47594bf8ed2cf8a722
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Data.List.BigOperators.Basic
+#align_import data.list.count from "leanprover-community/mathlib"@"47adfab39a11a072db552f47594bf8ed2cf8a722"
+
/-!
# Counting in lists
This PR fixes two things:
align
statements for definitions and theorems and instances that are separated by two newlines from the relevant declaration (s/\n\n#align/\n#align
). This is often seen in the mathport output after ending calc
blocks.#align
statements. (This was needed for a script I wrote for #3630.)@@ -51,7 +51,6 @@ theorem countp_cons_of_pos {a : α} (l) (pa : p a) : countp p (a :: l) = countp
rfl
unfold countp
rw [this, add_comm, List.countp_go_eq_add]
-
#align list.countp_cons_of_pos List.countp_cons_of_pos
@[simp]
@@ -327,7 +326,6 @@ theorem count_bind {α β} [DecidableEq β] (l : List α) (f : α → List β) (
theorem count_map_of_injective {α β} [DecidableEq α] [DecidableEq β] (l : List α) (f : α → β)
(hf : Function.Injective f) (x : α) : count (f x) (map f l) = count x l := by
simp only [count, countp_map, (· ∘ ·), hf.beq_eq]
-
#align list.count_map_of_injective List.count_map_of_injective
theorem count_le_count_map [DecidableEq β] (l : List α) (f : α → β) (x : α) :
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro
! This file was ported from Lean 3 source module data.list.count
-! leanprover-community/mathlib commit 6afc9b06856ad973f6a2619e3e8a0a8d537a58f2
+! leanprover-community/mathlib commit 47adfab39a11a072db552f47594bf8ed2cf8a722
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -39,7 +39,7 @@ protected theorem countp_go_eq_add (l) : countp.go p l n = n + countp.go p l 0 :
· rfl
· unfold countp.go
rw [ih (n := n + 1), ih (n := n), ih (n := 1)]
- by_cases p head
+ by_cases h : p head
· simp [h, add_assoc]
· simp [h]
@@ -68,7 +68,7 @@ theorem countp_cons (a : α) (l) : countp p (a :: l) = countp p l + if p a then
theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a => ¬p a) l := by
induction' l with x h ih
· rfl
- by_cases p x
+ by_cases h : p x
· rw [countp_cons_of_pos _ _ h, countp_cons_of_neg _ _ _, length, ih]
· ac_rfl
· simp only [h]
@@ -80,7 +80,7 @@ theorem length_eq_countp_add_countp (l) : length l = countp p l + countp (fun a
theorem countp_eq_length_filter (l) : countp p l = length (filter p l) := by
induction' l with x l ih
· rfl
- by_cases p x
+ by_cases h : p x
· rw [countp_cons_of_pos p l h, ih, filter_cons_of_pos l h, length]
· rw [countp_cons_of_neg p l h, ih, filter_cons_of_neg l h]
#align list.countp_eq_length_filter List.countp_eq_length_filter
@@ -378,6 +378,7 @@ theorem prod_eq_pow_single [Monoid α] (a : α)
(h : ∀ a', a' ≠ a → a' ∈ l → a' = 1) : l.prod = a ^ l.count a :=
_root_.trans (by rw [map_id]) (prod_map_eq_pow_single a id h)
#align list.prod_eq_pow_single List.prod_eq_pow_single
+#align list.sum_eq_nsmul_single List.sum_eq_nsmul_single
end Count
smul
in #715, but that was a bad decisionsmul
now use nsmul
. This doesn't raise an error unless they are aligned or explicitly used elsewhere.smul
to nsmul
.Co-authored-by: Reid Barton <rwbarton@gmail.com>
@@ -371,6 +371,7 @@ theorem prod_map_eq_pow_single [Monoid β] (a : α) (f : α → β)
· rw [ha', _root_.pow_succ]
· rw [hf a' (Ne.symm ha') (List.mem_cons_self a' as), one_mul]
#align list.prod_map_eq_pow_single List.prod_map_eq_pow_single
+#align list.sum_map_eq_nsmul_single List.sum_map_eq_nsmul_single
@[to_additive]
theorem prod_eq_pow_single [Monoid α] (a : α)
by
line breaks (#1523)
During porting, I usually fix the desired format we seem to want for the line breaks around by
with
awk '{do {{if (match($0, "^ by$") && length(p) < 98) {p=p " by";} else {if (NR!=1) {print p}; p=$0}}} while (getline == 1) if (getline==0) print p}' Mathlib/File/Im/Working/On.lean
I noticed there are some more files that slipped through.
This pull request is the result of running this command:
grep -lr "^ by\$" Mathlib | xargs -n 1 awk -i inplace '{do {{if (match($0, "^ by$") && length(p) < 98 && not (match(p, "^[ \t]*--"))) {p=p " by";} else {if (NR!=1) {print p}; p=$0}}} while (getline == 1) if (getline==0) print p}'
Co-authored-by: Moritz Firsching <firsching@google.com>
@@ -362,8 +362,7 @@ theorem count_erase_of_ne (ab : a ≠ b) (l : List α) : count a (l.erase b) = c
@[to_additive]
theorem prod_map_eq_pow_single [Monoid β] (a : α) (f : α → β)
- (hf : ∀ a', a' ≠ a → a' ∈ l → f a' = 1) : (l.map f).prod = f a ^ l.count a :=
- by
+ (hf : ∀ a', a' ≠ a → a' ∈ l → f a' = 1) : (l.map f).prod = f a ^ l.count a := by
induction' l with a' as h generalizing a
· rw [map_nil, prod_nil, count_nil, _root_.pow_zero]
· specialize h a fun a' ha' hfa' => hf a' ha' (mem_cons_of_mem _ hfa')
List.repeat
(#1579)
Mathlib 3 migrated to list.replicate
in leanprover-community/mathlib#18127 (merged) and leanprover-community/mathlib#18181 (awaiting review).
@@ -167,7 +167,6 @@ end Countp
/-! ### count -/
-
section Count
variable [DecidableEq α]
@@ -268,66 +267,46 @@ theorem count_eq_zero : count a l = 0 ↔ a ∉ l :=
@[simp]
theorem count_eq_length : count a l = l.length ↔ ∀ b ∈ l, a = b := by
- rw [count, countp_eq_length]
- refine ⟨fun h b hb => ?h₁, fun h b hb => ?h₂⟩
- · refine' Eq.symm _
- simpa using h b hb
- · rw [h b hb, beq_self_eq_true]
+ simp_rw [count, countp_eq_length, beq_iff_eq, eq_comm]
#align list.count_eq_length List.count_eq_length
@[simp]
theorem count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n :=
(count_eq_length.2 <| fun _ h => (eq_of_mem_replicate h).symm).trans (length_replicate _ _)
+#align list.count_replicate_self List.count_replicate_self
theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 := by
split
exacts [‹a = b› ▸ count_replicate_self _ _, count_eq_zero.2 <| mt eq_of_mem_replicate ‹a ≠ b›]
+#align list.count_replicate List.count_replicate
+
+-- porting note: new lemma
+theorem filter_beq' (l : List α) (a : α) : l.filter (· == a) = replicate (count a l) a := by
+ simp only [count, countp_eq_length_filter, eq_replicate, mem_filter, beq_iff_eq]
+ exact ⟨trivial, fun _ h => h.2⟩
+
+theorem filter_eq' (l : List α) (a : α) : l.filter (· = a) = replicate (count a l) a :=
+ filter_beq' l a
+#align list.filter_eq' List.filter_eq'
+
+theorem filter_eq (l : List α) (a : α) : l.filter (a = ·) = replicate (count a l) a := by
+ simpa only [eq_comm] using filter_eq' l a
+#align list.filter_eq List.filter_eq
+
+-- porting note: new lemma
+theorem filter_beq (l : List α) (a : α) : l.filter (a == ·) = replicate (count a l) a :=
+ filter_eq l a
theorem le_count_iff_replicate_sublist : n ≤ count a l ↔ replicate n a <+ l :=
- ⟨fun h =>
- ((replicate_sublist_replicate a).2 h).trans <| by
- have : filter (Eq a) l = replicate (count a l) a := eq_replicate.2 ⟨?h₁, ?h₂⟩
- rw [← this]
- apply filter_sublist
- · simp [count, countp_eq_length_filter, ← Bool.beq_eq_decide_eq, Bool.beq_comm]
- · intro b hb
- simpa [decide_eq_true_eq, eq_comm] using of_mem_filter hb,
+ ⟨fun h => ((replicate_sublist_replicate a).2 h).trans <| filter_eq l a ▸ filter_sublist _,
fun h => by simpa only [count_replicate_self] using h.count_le a⟩
+#align list.le_count_iff_replicate_sublist List.le_count_iff_replicate_sublist
theorem replicate_count_eq_of_count_eq_length (h : count a l = length l) :
replicate (count a l) a = l :=
(le_count_iff_replicate_sublist.mp le_rfl).eq_of_length <|
(length_replicate (count a l) a).trans h
-
-section deprecated
-
-set_option linter.deprecated false
-
---Porting note: removed `simp`, `simp` can prove it using corresponding lemma about replicate
-@[deprecated count_replicate_self]
-theorem count_repeat_self (a : α) (n : ℕ) : count a (List.repeat a n) = n :=
- count_replicate_self _ _
-#align list.count_repeat_self List.count_repeat_self
-
---Porting note: removed `simp`, `simp` can prove it using corresponding lemma about replicate
-@[deprecated count_replicate]
-theorem count_repeat (a b : α) (n : ℕ) : count a (List.repeat b n) = if a = b then n else 0 :=
- count_replicate _ _ _
-#align list.count_repeat List.count_repeat
-
-@[deprecated le_count_iff_replicate_sublist]
-theorem le_count_iff_repeat_sublist {a : α} {l : List α} {n : ℕ} :
- n ≤ count a l ↔ List.repeat a n <+ l :=
- le_count_iff_replicate_sublist
-#align list.le_count_iff_repeat_sublist List.le_count_iff_repeat_sublist
-
-@[deprecated replicate_count_eq_of_count_eq_length]
-theorem repeat_count_eq_of_count_eq_length {a : α} {l : List α} (h : count a l = length l) :
- List.repeat a (count a l) = l :=
- replicate_count_eq_of_count_eq_length h
-#align list.repeat_count_eq_of_count_eq_length List.repeat_count_eq_of_count_eq_length
-
-end deprecated
+#align list.replicate_count_eq_of_count_eq_length List.replicate_count_eq_of_count_eq_length
@[simp]
theorem count_filter (h : p a) : count a (filter p l) = count a l := by
List.count_replicate
, add a new version (#1475)
This is a forward-port of leanprover-community/mathlib#18125
@@ -276,10 +276,12 @@ theorem count_eq_length : count a l = l.length ↔ ∀ b ∈ l, a = b := by
#align list.count_eq_length List.count_eq_length
@[simp]
-theorem count_replicate (a : α) (n : ℕ) : count a (replicate n a) = n := by
- rw [count, countp_eq_length_filter, filter_eq_self.2, length_replicate]
- intro b hb
- rw [eq_of_mem_replicate hb, beq_self_eq_true]
+theorem count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n :=
+ (count_eq_length.2 <| fun _ h => (eq_of_mem_replicate h).symm).trans (length_replicate _ _)
+
+theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 := by
+ split
+ exacts [‹a = b› ▸ count_replicate_self _ _, count_eq_zero.2 <| mt eq_of_mem_replicate ‹a ≠ b›]
theorem le_count_iff_replicate_sublist : n ≤ count a l ↔ replicate n a <+ l :=
⟨fun h =>
@@ -290,7 +292,7 @@ theorem le_count_iff_replicate_sublist : n ≤ count a l ↔ replicate n a <+ l
· simp [count, countp_eq_length_filter, ← Bool.beq_eq_decide_eq, Bool.beq_comm]
· intro b hb
simpa [decide_eq_true_eq, eq_comm] using of_mem_filter hb,
- fun h => by simpa only [count_replicate] using h.count_le a⟩
+ fun h => by simpa only [count_replicate_self] using h.count_le a⟩
theorem replicate_count_eq_of_count_eq_length (h : count a l = length l) :
replicate (count a l) a = l :=
@@ -301,10 +303,16 @@ section deprecated
set_option linter.deprecated false
+--Porting note: removed `simp`, `simp` can prove it using corresponding lemma about replicate
+@[deprecated count_replicate_self]
+theorem count_repeat_self (a : α) (n : ℕ) : count a (List.repeat a n) = n :=
+ count_replicate_self _ _
+#align list.count_repeat_self List.count_repeat_self
+
--Porting note: removed `simp`, `simp` can prove it using corresponding lemma about replicate
@[deprecated count_replicate]
-theorem count_repeat (a : α) (n : ℕ) : count a (List.repeat a n) = n :=
- count_replicate _ _
+theorem count_repeat (a b : α) (n : ℕ) : count a (List.repeat b n) = if a = b then n else 0 :=
+ count_replicate _ _ _
#align list.count_repeat List.count_repeat
@[deprecated le_count_iff_replicate_sublist]
Co-authored-by: ChrisHughes24 <chrishughes24@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: thirdsgames <thirdsgames2018@gmail.com> Co-authored-by: zeramorphic <zeramorphic@proton.me> Co-authored-by: zeramorphic <50671761+zeramorphic@users.noreply.github.com>
The unported dependencies are