data.list.dedup
⟷
Mathlib.Data.List.Dedup
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.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
@@ -57,8 +57,45 @@ theorem subset_dedup (l : list α) : l ⊆ dedup l :=
theorem nodup_dedup : ∀ l : list α, nodup (dedup l) := pairwise_pw_filter
+theorem head_dedup [inhabited α] (l : list α) :
+ l.dedup.head = if l.head ∈ l.tail then l.tail.dedup.head else l.head :=
+match l with
+| [] := rfl
+| (a :: l) := by { by_cases ha : a ∈ l; simp [ha, list.dedup_cons_of_mem] }
+end
+
+theorem tail_dedup [inhabited α] (l : list α) :
+ l.dedup.tail = if l.head ∈ l.tail then l.tail.dedup.tail else l.tail.dedup :=
+match l with
+| [] := rfl
+| (a :: l) := by { by_cases ha : a ∈ l; simp [ha, list.dedup_cons_of_mem] }
+end
+
theorem dedup_eq_self {l : list α} : dedup l = l ↔ nodup l := pw_filter_eq_self
+theorem dedup_eq_cons (l : list α) (a : α) (l' : list α) :
+ l.dedup = a :: l' ↔ a ∈ l ∧ a ∉ l' ∧ l.dedup.tail = l' :=
+begin
+ refine ⟨λ h, _, λ h, _⟩,
+ { refine ⟨mem_dedup.1 (h.symm ▸ mem_cons_self _ _), λ ha, _, by rw [h, tail_cons]⟩,
+ have : count a l.dedup ≤ 1 := nodup_iff_count_le_one.1 (nodup_dedup l) a,
+ rw [h, count_cons_self, add_le_iff_nonpos_left] at this,
+ exact (not_le_of_lt (count_pos.2 ha) this) },
+ { have := @cons_head_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1)),
+ have hal : a ∈ l.dedup := mem_dedup.2 h.1,
+ rw [← this, mem_cons_iff, or_iff_not_imp_right] at hal,
+ exact this ▸ h.2.2.symm ▸ (cons_eq_cons.2 ⟨(hal (h.2.2.symm ▸ h.2.1)).symm, rfl⟩) }
+end
+
+@[simp] theorem dedup_eq_nil (l : list α) : l.dedup = [] ↔ l = [] :=
+begin
+ induction l with a l hl,
+ { exact iff.rfl },
+ { by_cases h : a ∈ l,
+ { simp only [list.dedup_cons_of_mem h, hl, list.ne_nil_of_mem h] },
+ { simp only [list.dedup_cons_of_not_mem h, list.cons_ne_nil] } }
+end
+
protected lemma nodup.dedup {l : list α} (h : l.nodup) : l.dedup = l :=
list.dedup_eq_self.2 h
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(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
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.
@@ -74,11 +74,11 @@ begin
rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]]
end
-lemma repeat_dedup {x : α} : ∀ {k}, k ≠ 0 → (repeat x k).dedup = [x]
+lemma replicate_dedup {x : α} : ∀ {k}, k ≠ 0 → (replicate k x).dedup = [x]
| 0 h := (h rfl).elim
| 1 _ := rfl
-| (n+2) _ := by rw [repeat_succ, dedup_cons_of_mem (mem_repeat.2 ⟨n.succ_ne_zero, rfl⟩),
- repeat_dedup n.succ_ne_zero]
+| (n+2) _ := by rw [replicate_succ, dedup_cons_of_mem (mem_replicate.2 ⟨n.succ_ne_zero, rfl⟩),
+ replicate_dedup n.succ_ne_zero]
lemma count_dedup (l : list α) (a : α) :
l.dedup.count a = if a ∈ l then 1 else 0 :=
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
@@ -35,7 +35,7 @@ pw_filter_cons_of_pos $ by simpa only [forall_mem_ne] using h
@[simp] theorem mem_dedup {a : α} {l : list α} : a ∈ dedup l ↔ a ∈ l :=
by simpa only [dedup, forall_mem_ne, not_not] using not_congr (@forall_mem_pw_filter α (≠) _
- (λ x y z xz, not_and_distrib.1 $ mt (and.rec eq.trans) xz) a l)
+ (λ x y z xz, not_and_distrib.1 $ mt (λ h, eq.trans h.1 h.2) xz) a l)
@[simp] theorem dedup_cons_of_mem {a : α} {l : list α} (h : a ∈ l) :
dedup (a :: l) = dedup l :=
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(first ported)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -127,11 +127,11 @@ theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
refine' ⟨fun h => _, fun h => _⟩
· refine' ⟨mem_dedup.1 (h.symm ▸ mem_cons_self _ _), fun ha => _, by rw [h, tail_cons]⟩
have : count a l.dedup ≤ 1 := nodup_iff_count_le_one.1 (nodup_dedup l) a
- rw [h, count_cons_self, add_le_iff_nonpos_left] at this
+ rw [h, count_cons_self, add_le_iff_nonpos_left] at this
exact not_le_of_lt (count_pos.2 ha) this
· have := @cons_head_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1))
have hal : a ∈ l.dedup := mem_dedup.2 h.1
- rw [← this, mem_cons_iff, Classical.or_iff_not_imp_right] at hal
+ rw [← this, mem_cons_iff, Classical.or_iff_not_imp_right] at hal
exact this ▸ h.2.2.symm ▸ cons_eq_cons.2 ⟨(hal (h.2.2.symm ▸ h.2.1)).symm, rfl⟩
#align list.dedup_eq_cons List.dedup_eq_cons
-/
@@ -206,7 +206,7 @@ theorem sum_map_count_dedup_filter_eq_countP (p : α → Prop) [DecidablePred p]
simp [hp, count_dedup]
· refine' trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
obtain ⟨a', ha'⟩ := List.mem_map.1 hn
- simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
+ simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
exact ha'.2.symm
#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countP
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -131,7 +131,7 @@ theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
exact not_le_of_lt (count_pos.2 ha) this
· have := @cons_head_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1))
have hal : a ∈ l.dedup := mem_dedup.2 h.1
- rw [← this, mem_cons_iff, or_iff_not_imp_right] at hal
+ rw [← this, mem_cons_iff, Classical.or_iff_not_imp_right] at hal
exact this ▸ h.2.2.symm ▸ cons_eq_cons.2 ⟨(hal (h.2.2.symm ▸ h.2.1)).symm, rfl⟩
#align list.dedup_eq_cons List.dedup_eq_cons
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,7 +3,7 @@ Copyright (c) 2018 Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
-/
-import Mathbin.Data.List.Nodup
+import Data.List.Nodup
#align_import data.list.dedup from "leanprover-community/mathlib"@"d9e96a3e3e0894e93e10aff5244f4c96655bac1c"
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -154,11 +154,11 @@ protected theorem Nodup.dedup {l : List α} (h : l.Nodup) : l.dedup = l :=
#align list.nodup.dedup List.Nodup.dedup
-/
-#print List.dedup_idempotent /-
+#print List.dedup_idem /-
@[simp]
-theorem dedup_idempotent {l : List α} : dedup (dedup l) = dedup l :=
- pwFilter_idempotent
-#align list.dedup_idempotent List.dedup_idempotent
+theorem dedup_idem {l : List α} : dedup (dedup l) = dedup l :=
+ pwFilter_idem
+#align list.dedup_idempotent List.dedup_idem
-/
#print List.dedup_append /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -187,14 +187,14 @@ theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1
#align list.count_dedup List.count_dedup
-/
-#print List.sum_map_count_dedup_filter_eq_countp /-
+#print List.sum_map_count_dedup_filter_eq_countP /-
/-- Summing the count of `x` over a list filtered by some `p` is just `countp` applied to `p` -/
-theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p] (l : List α) :
- ((l.dedup.filterₓ p).map fun x => l.count x).Sum = l.countp p :=
+theorem sum_map_count_dedup_filter_eq_countP (p : α → Prop) [DecidablePred p] (l : List α) :
+ ((l.dedup.filterₓ p).map fun x => l.count x).Sum = l.countP p :=
by
induction' l with a as h
· simp
- · simp_rw [List.countp_cons, List.count_cons', List.sum_map_add]
+ · simp_rw [List.countP_cons, List.count_cons', List.sum_map_add]
congr 1
· refine' trans _ h
by_cases ha : a ∈ as
@@ -208,7 +208,7 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p]
obtain ⟨a', ha'⟩ := List.mem_map.1 hn
simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
exact ha'.2.symm
-#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countp
+#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countP
-/
#print List.sum_map_count_dedup_eq_length /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,14 +2,11 @@
Copyright (c) 2018 Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
-
-! This file was ported from Lean 3 source module data.list.dedup
-! leanprover-community/mathlib commit d9e96a3e3e0894e93e10aff5244f4c96655bac1c
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Data.List.Nodup
+#align_import data.list.dedup from "leanprover-community/mathlib"@"d9e96a3e3e0894e93e10aff5244f4c96655bac1c"
+
/-!
# Erasure of duplicates in a list
mathlib commit https://github.com/leanprover-community/mathlib/commit/bf2428c9486c407ca38b5b3fb10b87dad0bc99fa
@@ -99,19 +99,23 @@ theorem nodup_dedup : ∀ l : List α, Nodup (dedup l) :=
#align list.nodup_dedup List.nodup_dedup
-/
+#print List.headI_dedup /-
theorem headI_dedup [Inhabited α] (l : List α) :
l.dedup.headI = if l.headI ∈ l.tail then l.tail.dedup.headI else l.headI :=
match l with
| [] => rfl
| a :: l => by by_cases ha : a ∈ l <;> simp [ha, List.dedup_cons_of_mem]
#align list.head_dedup List.headI_dedup
+-/
+#print List.tail_dedup /-
theorem tail_dedup [Inhabited α] (l : List α) :
l.dedup.tail = if l.headI ∈ l.tail then l.tail.dedup.tail else l.tail.dedup :=
match l with
| [] => rfl
| a :: l => by by_cases ha : a ∈ l <;> simp [ha, List.dedup_cons_of_mem]
#align list.tail_dedup List.tail_dedup
+-/
#print List.dedup_eq_self /-
theorem dedup_eq_self {l : List α} : dedup l = l ↔ Nodup l :=
@@ -119,6 +123,7 @@ theorem dedup_eq_self {l : List α} : dedup l = l ↔ Nodup l :=
#align list.dedup_eq_self List.dedup_eq_self
-/
+#print List.dedup_eq_cons /-
theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
l.dedup = a :: l' ↔ a ∈ l ∧ a ∉ l' ∧ l.dedup.tail = l' :=
by
@@ -132,7 +137,9 @@ theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
rw [← this, mem_cons_iff, or_iff_not_imp_right] at hal
exact this ▸ h.2.2.symm ▸ cons_eq_cons.2 ⟨(hal (h.2.2.symm ▸ h.2.1)).symm, rfl⟩
#align list.dedup_eq_cons List.dedup_eq_cons
+-/
+#print List.dedup_eq_nil /-
@[simp]
theorem dedup_eq_nil (l : List α) : l.dedup = [] ↔ l = [] :=
by
@@ -142,6 +149,7 @@ theorem dedup_eq_nil (l : List α) : l.dedup = [] ↔ l = [] :=
· simp only [List.dedup_cons_of_mem h, hl, List.ne_nil_of_mem h]
· simp only [List.dedup_cons_of_not_mem h, List.cons_ne_nil]
#align list.dedup_eq_nil List.dedup_eq_nil
+-/
#print List.Nodup.dedup /-
protected theorem Nodup.dedup {l : List α} (h : l.Nodup) : l.dedup = l :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/b01d6eb9d0a308807af54319b264d0994b91774b
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
! This file was ported from Lean 3 source module data.list.dedup
-! leanprover-community/mathlib commit f694c7dead66f5d4c80f446c796a5aad14707f0e
+! leanprover-community/mathlib commit d9e96a3e3e0894e93e10aff5244f4c96655bac1c
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -99,12 +99,50 @@ theorem nodup_dedup : ∀ l : List α, Nodup (dedup l) :=
#align list.nodup_dedup List.nodup_dedup
-/
+theorem headI_dedup [Inhabited α] (l : List α) :
+ l.dedup.headI = if l.headI ∈ l.tail then l.tail.dedup.headI else l.headI :=
+ match l with
+ | [] => rfl
+ | a :: l => by by_cases ha : a ∈ l <;> simp [ha, List.dedup_cons_of_mem]
+#align list.head_dedup List.headI_dedup
+
+theorem tail_dedup [Inhabited α] (l : List α) :
+ l.dedup.tail = if l.headI ∈ l.tail then l.tail.dedup.tail else l.tail.dedup :=
+ match l with
+ | [] => rfl
+ | a :: l => by by_cases ha : a ∈ l <;> simp [ha, List.dedup_cons_of_mem]
+#align list.tail_dedup List.tail_dedup
+
#print List.dedup_eq_self /-
theorem dedup_eq_self {l : List α} : dedup l = l ↔ Nodup l :=
pwFilter_eq_self
#align list.dedup_eq_self List.dedup_eq_self
-/
+theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
+ l.dedup = a :: l' ↔ a ∈ l ∧ a ∉ l' ∧ l.dedup.tail = l' :=
+ by
+ refine' ⟨fun h => _, fun h => _⟩
+ · refine' ⟨mem_dedup.1 (h.symm ▸ mem_cons_self _ _), fun ha => _, by rw [h, tail_cons]⟩
+ have : count a l.dedup ≤ 1 := nodup_iff_count_le_one.1 (nodup_dedup l) a
+ rw [h, count_cons_self, add_le_iff_nonpos_left] at this
+ exact not_le_of_lt (count_pos.2 ha) this
+ · have := @cons_head_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1))
+ have hal : a ∈ l.dedup := mem_dedup.2 h.1
+ rw [← this, mem_cons_iff, or_iff_not_imp_right] at hal
+ exact this ▸ h.2.2.symm ▸ cons_eq_cons.2 ⟨(hal (h.2.2.symm ▸ h.2.1)).symm, rfl⟩
+#align list.dedup_eq_cons List.dedup_eq_cons
+
+@[simp]
+theorem dedup_eq_nil (l : List α) : l.dedup = [] ↔ l = [] :=
+ by
+ induction' l with a l hl
+ · exact Iff.rfl
+ · by_cases h : a ∈ l
+ · simp only [List.dedup_cons_of_mem h, hl, List.ne_nil_of_mem h]
+ · simp only [List.dedup_cons_of_not_mem h, List.cons_ne_nil]
+#align list.dedup_eq_nil List.dedup_eq_nil
+
#print List.Nodup.dedup /-
protected theorem Nodup.dedup {l : List α} (h : l.Nodup) : l.dedup = l :=
List.dedup_eq_self.2 h
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -144,6 +144,7 @@ theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1
#align list.count_dedup List.count_dedup
-/
+#print List.sum_map_count_dedup_filter_eq_countp /-
/-- Summing the count of `x` over a list filtered by some `p` is just `countp` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p] (l : List α) :
((l.dedup.filterₓ p).map fun x => l.count x).Sum = l.countp p :=
@@ -165,6 +166,7 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p]
simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
exact ha'.2.symm
#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countp
+-/
#print List.sum_map_count_dedup_eq_length /-
theorem sum_map_count_dedup_eq_length (l : List α) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -123,8 +123,8 @@ theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ ded
by
induction' l₁ with a l₁ IH; · rfl; rw [cons_union, ← IH]
show dedup (a :: (l₁ ++ l₂)) = insert a (dedup (l₁ ++ l₂))
- by_cases a ∈ dedup (l₁ ++ l₂) <;>
- [rw [dedup_cons_of_mem' h, insert_of_mem h];rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]]
+ by_cases a ∈ dedup (l₁ ++ l₂) <;> [rw [dedup_cons_of_mem' h, insert_of_mem h];
+ rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]]
#align list.dedup_append List.dedup_append
-/
@@ -162,7 +162,7 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p]
simp [hp, count_dedup]
· refine' trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
obtain ⟨a', ha'⟩ := List.mem_map.1 hn
- simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
+ simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
exact ha'.2.symm
#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countp
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -144,12 +144,6 @@ theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1
#align list.count_dedup List.count_dedup
-/
-/- warning: list.sum_map_count_dedup_filter_eq_countp -> List.sum_map_count_dedup_filter_eq_countp is a dubious translation:
-lean 3 declaration is
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (p : α -> Prop) [_inst_2 : DecidablePred.{succ u1} α p] (l : List.{u1} α), Eq.{1} Nat (List.sum.{0} Nat Nat.hasAdd Nat.hasZero (List.map.{u1, 0} α Nat (fun (x : α) => List.count.{u1} α (fun (a : α) (b : α) => _inst_1 a b) x l) (List.filterₓ.{u1} α p (fun (a : α) => _inst_2 a) (List.dedup.{u1} α (fun (a : α) (b : α) => _inst_1 a b) l)))) (List.countp.{u1} α p (fun (a : α) => _inst_2 a) l)
-but is expected to have type
- forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (p : α -> Bool) (_inst_2 : List.{u1} α), Eq.{1} Nat (List.sum.{0} Nat instAddNat (LinearOrderedCommMonoidWithZero.toZero.{0} Nat Nat.linearOrderedCommMonoidWithZero) (List.map.{u1, 0} α Nat (fun (x : α) => List.count.{u1} α (instBEq.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) x _inst_2) (List.filter.{u1} α p (List.dedup.{u1} α (fun (a : α) (b : α) => _inst_1 a b) _inst_2)))) (List.countp.{u1} α p _inst_2)
-Case conversion may be inaccurate. Consider using '#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countpₓ'. -/
/-- Summing the count of `x` over a list filtered by some `p` is just `countp` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p] (l : List α) :
((l.dedup.filterₓ p).map fun x => l.count x).Sum = l.countp p :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/8d33f09cd7089ecf074b4791907588245aec5d1b
@@ -123,8 +123,8 @@ theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ ded
by
induction' l₁ with a l₁ IH; · rfl; rw [cons_union, ← IH]
show dedup (a :: (l₁ ++ l₂)) = insert a (dedup (l₁ ++ l₂))
- by_cases a ∈ dedup (l₁ ++ l₂) <;> [rw [dedup_cons_of_mem' h, insert_of_mem h],
- rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]]
+ by_cases a ∈ dedup (l₁ ++ l₂) <;>
+ [rw [dedup_cons_of_mem' h, insert_of_mem h];rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]]
#align list.dedup_append List.dedup_append
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce86f4e05e9a9b8da5e316b22c76ce76440c56a1
@@ -167,7 +167,7 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Prop) [DecidablePred p]
· refine' trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
simp [hp, count_dedup]
· refine' trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
- obtain ⟨a', ha'⟩ := List.mem_map'.1 hn
+ obtain ⟨a', ha'⟩ := List.mem_map.1 hn
simp only [(fun h => hp (h ▸ (List.mem_filter.1 ha'.1).2) : a' ≠ a), if_false] at ha'
exact ha'.2.symm
#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countp
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -43,9 +43,9 @@ theorem dedup_cons_of_not_mem' {a : α} {l : List α} (h : a ∉ dedup l) :
@[simp]
theorem mem_dedup {a : α} {l : List α} : a ∈ dedup l ↔ a ∈ l := by
have := not_congr (@forall_mem_pwFilter α (· ≠ ·) _ ?_ a l)
- simpa only [dedup, forall_mem_ne, not_not] using this
- intros x y z xz
- exact not_and_or.1 <| mt (fun h ↦ h.1.trans h.2) xz
+ · simpa only [dedup, forall_mem_ne, not_not] using this
+ · intros x y z xz
+ exact not_and_or.1 <| mt (fun h ↦ h.1.trans h.2) xz
#align list.mem_dedup List.mem_dedup
@[simp]
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
.@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
-/
import Mathlib.Data.List.Nodup
-import Mathlib.Data.List.Count
#align_import data.list.dedup from "leanprover-community/mathlib"@"d9e96a3e3e0894e93e10aff5244f4c96655bac1c"
@@ -96,9 +95,10 @@ theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
l.dedup = a :: l' ↔ a ∈ l ∧ a ∉ l' ∧ l.dedup.tail = l' := by
refine' ⟨fun h => _, fun h => _⟩
· refine' ⟨mem_dedup.1 (h.symm ▸ mem_cons_self _ _), fun ha => _, by rw [h, tail_cons]⟩
+ have := count_pos_iff_mem.2 ha
have : count a l.dedup ≤ 1 := nodup_iff_count_le_one.1 (nodup_dedup l) a
- rw [h, count_cons_self, add_le_iff_nonpos_left] at this
- exact not_le_of_lt (count_pos_iff_mem.2 ha) this
+ rw [h, count_cons_self] at this
+ omega
· have := @List.cons_head!_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1))
have hal : a ∈ l.dedup := mem_dedup.2 h.1
rw [← this, mem_cons, or_iff_not_imp_right] at hal
@@ -144,34 +144,4 @@ theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1
simp_rw [count_eq_of_nodup <| nodup_dedup l, mem_dedup]
#align list.count_dedup List.count_dedup
-/-- Summing the count of `x` over a list filtered by some `p` is just `countP` applied to `p` -/
-theorem sum_map_count_dedup_filter_eq_countP (p : α → Bool) (l : List α) :
- ((l.dedup.filter p).map fun x => l.count x).sum = l.countP p := by
- induction' l with a as h
- · simp
- · simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
- congr 1
- · refine' _root_.trans _ h
- by_cases ha : a ∈ as
- · simp [dedup_cons_of_mem ha]
- · simp only [dedup_cons_of_not_mem ha, List.filter]
- match p a with
- | true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
- | false => simp only
- · by_cases hp : p a
- · refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
- simp [hp, count_dedup]
- · refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
- obtain ⟨a', ha'⟩ := List.mem_map.1 hn
- split_ifs at ha' with ha
- · simp only [ha, mem_filter, mem_dedup, find?, mem_cons, true_or, hp,
- and_false, false_and] at ha'
- · exact ha'.2.symm
-#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countP
-
-theorem sum_map_count_dedup_eq_length (l : List α) :
- (l.dedup.map fun x => l.count x).sum = l.length := by
- simpa using sum_map_count_dedup_filter_eq_countP (fun _ => True) l
-#align list.sum_map_count_dedup_eq_length List.sum_map_count_dedup_eq_length
-
end List
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
-/
import Mathlib.Data.List.Nodup
+import Mathlib.Data.List.Count
#align_import data.list.dedup from "leanprover-community/mathlib"@"d9e96a3e3e0894e93e10aff5244f4c96655bac1c"
Std bump patch for https://github.com/leanprover/std4/pull/100
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -118,9 +118,9 @@ protected theorem Nodup.dedup {l : List α} (h : l.Nodup) : l.dedup = l :=
#align list.nodup.dedup List.Nodup.dedup
@[simp]
-theorem dedup_idempotent {l : List α} : dedup (dedup l) = dedup l :=
- pwFilter_idempotent
-#align list.dedup_idempotent List.dedup_idempotent
+theorem dedup_idem {l : List α} : dedup (dedup l) = dedup l :=
+ pwFilter_idem
+#align list.dedup_idempotent List.dedup_idem
theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ dedup l₂ := by
induction' l₁ with a l₁ IH; · rfl
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>
@@ -97,7 +97,7 @@ theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
· refine' ⟨mem_dedup.1 (h.symm ▸ mem_cons_self _ _), fun ha => _, by rw [h, tail_cons]⟩
have : count a l.dedup ≤ 1 := nodup_iff_count_le_one.1 (nodup_dedup l) a
rw [h, count_cons_self, add_le_iff_nonpos_left] at this
- exact not_le_of_lt (count_pos.2 ha) this
+ exact not_le_of_lt (count_pos_iff_mem.2 ha) this
· have := @List.cons_head!_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1))
have hal : a ∈ l.dedup := mem_dedup.2 h.1
rw [← this, mem_cons, or_iff_not_imp_right] at hal
@@ -143,12 +143,12 @@ theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1
simp_rw [count_eq_of_nodup <| nodup_dedup l, mem_dedup]
#align list.count_dedup List.count_dedup
-/-- Summing the count of `x` over a list filtered by some `p` is just `countp` applied to `p` -/
-theorem sum_map_count_dedup_filter_eq_countp (p : α → Bool) (l : List α) :
- ((l.dedup.filter p).map fun x => l.count x).sum = l.countp p := by
+/-- Summing the count of `x` over a list filtered by some `p` is just `countP` applied to `p` -/
+theorem sum_map_count_dedup_filter_eq_countP (p : α → Bool) (l : List α) :
+ ((l.dedup.filter p).map fun x => l.count x).sum = l.countP p := by
induction' l with a as h
· simp
- · simp_rw [List.countp_cons, List.count_cons', List.sum_map_add]
+ · simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
congr 1
· refine' _root_.trans _ h
by_cases ha : a ∈ as
@@ -166,11 +166,11 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Bool) (l : List α) :
· simp only [ha, mem_filter, mem_dedup, find?, mem_cons, true_or, hp,
and_false, false_and] at ha'
· exact ha'.2.symm
-#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countp
+#align list.sum_map_count_dedup_filter_eq_countp List.sum_map_count_dedup_filter_eq_countP
theorem sum_map_count_dedup_eq_length (l : List α) :
(l.dedup.map fun x => l.count x).sum = l.length := by
- simpa using sum_map_count_dedup_filter_eq_countp (fun _ => True) l
+ simpa using sum_map_count_dedup_filter_eq_countP (fun _ => True) l
#align list.sum_map_count_dedup_eq_length List.sum_map_count_dedup_eq_length
end List
Per https://github.com/leanprover/lean4/issues/2343, we are going to need to change the automatic generation of instance names, as they become too long.
This PR ensures that everywhere in Mathlib that refers to an instance by name, that name is given explicitly, rather than being automatically generated.
There are four exceptions, which are now commented, with links to https://github.com/leanprover/lean4/issues/2343.
This was implemented by running Mathlib against a modified Lean that appended _ᾰ
to all automatically generated names, and fixing everything.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -124,7 +124,7 @@ theorem dedup_idempotent {l : List α} : dedup (dedup l) = dedup l :=
theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ dedup l₂ := by
induction' l₁ with a l₁ IH; · rfl
- simp only [instUnionList, cons_union] at *
+ simp only [cons_union] at *
rw [← IH, cons_append]
by_cases h : a ∈ dedup (l₁ ++ l₂)
· rw [dedup_cons_of_mem' h, insert_of_mem h]
@@ -2,14 +2,11 @@
Copyright (c) 2018 Mario Carneiro. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
-
-! This file was ported from Lean 3 source module data.list.dedup
-! leanprover-community/mathlib commit d9e96a3e3e0894e93e10aff5244f4c96655bac1c
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Data.List.Nodup
+#align_import data.list.dedup from "leanprover-community/mathlib"@"d9e96a3e3e0894e93e10aff5244f4c96655bac1c"
+
/-!
# Erasure of duplicates in a list
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
! This file was ported from Lean 3 source module data.list.dedup
-! leanprover-community/mathlib commit f694c7dead66f5d4c80f446c796a5aad14707f0e
+! leanprover-community/mathlib commit d9e96a3e3e0894e93e10aff5244f4c96655bac1c
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -76,10 +76,46 @@ theorem nodup_dedup : ∀ l : List α, Nodup (dedup l) :=
pairwise_pwFilter
#align list.nodup_dedup List.nodup_dedup
+theorem headI_dedup [Inhabited α] (l : List α) :
+ l.dedup.headI = if l.headI ∈ l.tail then l.tail.dedup.headI else l.headI :=
+ match l with
+ | [] => rfl
+ | a :: l => by by_cases ha : a ∈ l <;> simp [ha, List.dedup_cons_of_mem]
+#align list.head_dedup List.headI_dedup
+
+theorem tail_dedup [Inhabited α] (l : List α) :
+ l.dedup.tail = if l.headI ∈ l.tail then l.tail.dedup.tail else l.tail.dedup :=
+ match l with
+ | [] => rfl
+ | a :: l => by by_cases ha : a ∈ l <;> simp [ha, List.dedup_cons_of_mem]
+#align list.tail_dedup List.tail_dedup
+
theorem dedup_eq_self {l : List α} : dedup l = l ↔ Nodup l :=
pwFilter_eq_self
#align list.dedup_eq_self List.dedup_eq_self
+theorem dedup_eq_cons (l : List α) (a : α) (l' : List α) :
+ l.dedup = a :: l' ↔ a ∈ l ∧ a ∉ l' ∧ l.dedup.tail = l' := by
+ refine' ⟨fun h => _, fun h => _⟩
+ · refine' ⟨mem_dedup.1 (h.symm ▸ mem_cons_self _ _), fun ha => _, by rw [h, tail_cons]⟩
+ have : count a l.dedup ≤ 1 := nodup_iff_count_le_one.1 (nodup_dedup l) a
+ rw [h, count_cons_self, add_le_iff_nonpos_left] at this
+ exact not_le_of_lt (count_pos.2 ha) this
+ · have := @List.cons_head!_tail α ⟨a⟩ _ (ne_nil_of_mem (mem_dedup.2 h.1))
+ have hal : a ∈ l.dedup := mem_dedup.2 h.1
+ rw [← this, mem_cons, or_iff_not_imp_right] at hal
+ exact this ▸ h.2.2.symm ▸ cons_eq_cons.2 ⟨(hal (h.2.2.symm ▸ h.2.1)).symm, rfl⟩
+#align list.dedup_eq_cons List.dedup_eq_cons
+
+@[simp]
+theorem dedup_eq_nil (l : List α) : l.dedup = [] ↔ l = [] := by
+ induction' l with a l hl
+ · exact Iff.rfl
+ · by_cases h : a ∈ l
+ · simp only [List.dedup_cons_of_mem h, hl, List.ne_nil_of_mem h]
+ · simp only [List.dedup_cons_of_not_mem h, List.cons_ne_nil]
+#align list.dedup_eq_nil List.dedup_eq_nil
+
protected theorem Nodup.dedup {l : List α} (h : l.Nodup) : l.dedup = l :=
List.dedup_eq_self.2 h
#align list.nodup.dedup List.Nodup.dedup
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.)@@ -49,7 +49,6 @@ theorem mem_dedup {a : α} {l : List α} : a ∈ dedup l ↔ a ∈ l := by
simpa only [dedup, forall_mem_ne, not_not] using this
intros x y z xz
exact not_and_or.1 <| mt (fun h ↦ h.1.trans h.2) xz
-
#align list.mem_dedup List.mem_dedup
@[simp]
Notably incorporates https://github.com/leanprover/std4/pull/98 and https://github.com/leanprover/std4/pull/109.
https://github.com/leanprover/std4/pull/98 moves a number of lemmas from Mathlib to Std, so the bump requires deleting them in Mathlib. I did check on each lemma whether its attributes were kept in the move (and gave attribute markings in Mathlib if they were not present in Std), but a reviewer may wish to re-check.
List.mem_map
changed statement from b ∈ l.map f ↔ ∃ a, a ∈ l ∧ b = f a
to b ∈ l.map f ↔ ∃ a, a ∈ l ∧ f a = b
. Similarly for List.exists_of_mem_map
. This was a deliberate change, so I have simply adjusted proofs (many become simpler, which supports the change). I also deleted List.mem_map'
, List.exists_of_mem_map'
, which were temporary versions in Mathlib while waiting for this change (replacing their uses with the unprimed versions).
Also, the lemma sublist_nil_iff_eq_nil
seems to have been renamed to sublist_nil
during the move, so I added an alias for the old name.
(another issue fixed during review by @digama0) List.Sublist.filter
had an argument change from explicit to implicit. This appears to have been an oversight (cc @JamesGallicchio). I have temporarily introduced List.Sublist.filter'
with the argument explicit, and replaced Mathlib uses of Sublist.filter
with Sublist.filter'
. Later we can fix the argument in Std, and then delete List.Sublist.filter'
.
@@ -129,7 +129,7 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Bool) (l : List α) :
· refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
simp [hp, count_dedup]
· refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
- obtain ⟨a', ha'⟩ := List.mem_map'.1 hn
+ obtain ⟨a', ha'⟩ := List.mem_map.1 hn
split_ifs at ha' with ha
· simp only [ha, mem_filter, mem_dedup, find?, mem_cons, true_or, hp,
and_false, false_and] at ha'
@@ -93,10 +93,10 @@ theorem dedup_idempotent {l : List α} : dedup (dedup l) = dedup l :=
theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ dedup l₂ := by
induction' l₁ with a l₁ IH; · rfl
simp only [instUnionList, cons_union] at *
- rw [← IH]
- show dedup (a :: (l₁ ++ l₂)) = List.insert a (dedup (l₁ ++ l₂))
- by_cases a ∈ dedup (l₁ ++ l₂) <;> [rw [dedup_cons_of_mem' h, insert_of_mem h],
- rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]]
+ rw [← IH, cons_append]
+ by_cases h : a ∈ dedup (l₁ ++ l₂)
+ · rw [dedup_cons_of_mem' h, insert_of_mem h]
+ · rw [dedup_cons_of_not_mem' h, insert_of_not_mem h]
#align list.dedup_append List.dedup_append
theorem replicate_dedup {x : α} : ∀ {k}, k ≠ 0 → (replicate k x).dedup = [x]
Part of the List.repeat
-> List.replicate
refactor. On Mathlib 4 side, I removed mentions of List.repeat
in #1475 and #1579
algebra.big_operators.basic
@9003f28797c0664a49e4179487267c494477d853
..47adfab39a11a072db552f47594bf8ed2cf8a722
algebra.big_operators.multiset.basic
@9003f28797c0664a49e4179487267c494477d853
..47adfab39a11a072db552f47594bf8ed2cf8a722
algebra.gcd_monoid.multiset
@9003f28797c0664a49e4179487267c494477d853
..f694c7dead66f5d4c80f446c796a5aad14707f0e
algebra.hom.freiman
@9003f28797c0664a49e4179487267c494477d853
..f694c7dead66f5d4c80f446c796a5aad14707f0e
data.list.big_operators.basic
@26f081a2fb920140ed5bc5cc5344e84bcc7cb2b2
..47adfab39a11a072db552f47594bf8ed2cf8a722
data.list.dedup
@6133ae2da6ae6693248bb5451de703f1ef154cc8
..f694c7dead66f5d4c80f446c796a5aad14707f0e
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
! This file was ported from Lean 3 source module data.list.dedup
-! leanprover-community/mathlib commit 6133ae2da6ae6693248bb5451de703f1ef154cc8
+! leanprover-community/mathlib commit f694c7dead66f5d4c80f446c796a5aad14707f0e
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
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>
@@ -126,7 +126,7 @@ theorem sum_map_count_dedup_filter_eq_countp (p : α → Bool) (l : List α) :
| true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
| false => simp only
· by_cases hp : p a
- · refine' _root_.trans (sum_map_eq_smul_single a _ fun _ h _ => by simp [h]) _
+ · refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
simp [hp, count_dedup]
· refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
obtain ⟨a', ha'⟩ := List.mem_map'.1 hn
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>
@@ -90,8 +90,7 @@ theorem dedup_idempotent {l : List α} : dedup (dedup l) = dedup l :=
pwFilter_idempotent
#align list.dedup_idempotent List.dedup_idempotent
-theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ dedup l₂ :=
- by
+theorem dedup_append (l₁ l₂ : List α) : dedup (l₁ ++ l₂) = l₁ ∪ dedup l₂ := by
induction' l₁ with a l₁ IH; · rfl
simp only [instUnionList, cons_union] at *
rw [← IH]
@@ -114,8 +113,7 @@ theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1
/-- Summing the count of `x` over a list filtered by some `p` is just `countp` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countp (p : α → Bool) (l : List α) :
- ((l.dedup.filter p).map fun x => l.count x).sum = l.countp p :=
- by
+ ((l.dedup.filter p).map fun x => l.count x).sum = l.countp p := by
induction' l with a as h
· simp
· simp_rw [List.countp_cons, List.count_cons', List.sum_map_add]
List.repeat
(#1579)
Mathlib 3 migrated to list.replicate
in leanprover-community/mathlib#18127 (merged) and leanprover-community/mathlib#18181 (awaiting review).
@@ -106,12 +106,7 @@ theorem replicate_dedup {x : α} : ∀ {k}, k ≠ 0 → (replicate k x).dedup =
| n + 2, _ => by
rw [replicate_succ, dedup_cons_of_mem (mem_replicate.2 ⟨n.succ_ne_zero, rfl⟩),
replicate_dedup n.succ_ne_zero]
-
-set_option linter.deprecated false in
-@[deprecated replicate_dedup]
-theorem repeat_dedup {x : α} : ∀ {k}, k ≠ 0 → (List.repeat x k).dedup = [x] :=
- replicate_dedup
-#align list.repeat_dedup List.repeat_dedup
+#align list.replicate_dedup List.replicate_dedup
theorem count_dedup (l : List α) (a : α) : l.dedup.count a = if a ∈ l then 1 else 0 := by
simp_rw [count_eq_of_nodup <| nodup_dedup l, mem_dedup]
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
! This file was ported from Lean 3 source module data.list.dedup
-! leanprover-community/mathlib commit 7b78d1776212a91ecc94cf601f83bdcc46b04213
+! leanprover-community/mathlib commit 6133ae2da6ae6693248bb5451de703f1ef154cc8
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
The unported dependencies are