Skip to content

Commit

Permalink
feat(data/list/basic): Alias for length_le_of_sublist (#16841)
Browse files Browse the repository at this point in the history
Make an alias `list.sublist.length_le` of `list.length_le_of_sublist` and use it. Rename `list.eq_of_sublist_of_length_eq` and `list.eq_of_sublist_of_length_le` to use dot notation.
  • Loading branch information
YaelDillies committed Oct 10, 2022
1 parent 103252a commit 11156f5
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 40 deletions.
32 changes: 15 additions & 17 deletions src/data/list/basic.lean
Expand Up @@ -13,7 +13,7 @@ open function nat (hiding one_pos)

namespace list
universes u v w x
variables {ι : Type*} {α : Type u} {β : Type v} {γ : Type w} {δ : Type x}
variables {ι : Type*} {α : Type u} {β : Type v} {γ : Type w} {δ : Type x} {l₁ l₂ : list α}

attribute [inline] list.head

Expand Down Expand Up @@ -277,6 +277,8 @@ lemma length_eq_two {l : list α} : l.length = 2 ↔ ∃ a b, l = [a, b] :=
lemma length_eq_three {l : list α} : l.length = 3 ↔ ∃ a b c, l = [a, b, c] :=
match l with [a, b, c], _ := ⟨a, b, c, rfl⟩ end, λ ⟨a, b, c, e⟩, e.symm ▸ rfl⟩

alias length_le_of_sublist ← sublist.length_le

/-! ### set-theoretic notation of lists -/

lemma empty_eq : (∅ : list α) = [] := by refl
Expand Down Expand Up @@ -1090,22 +1092,19 @@ eq_nil_of_subset_nil $ s.subset
⟨eq_nil_of_sublist_nil, λ H, H ▸ sublist.refl _⟩

@[simp] theorem repeat_sublist_repeat (a : α) {m n} : repeat a m <+ repeat a n ↔ m ≤ n :=
⟨λ h, by simpa only [length_repeat] using length_le_of_sublist h,
⟨λ h, by simpa only [length_repeat] using h.length_le,
λ h, by induction h; [refl, simp only [*, repeat_succ, sublist.cons]] ⟩

theorem eq_of_sublist_of_length_eq : ∀ {l₁ l₂ : list α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
theorem sublist.eq_of_length : ∀ {l₁ l₂ : list α}, l₁ <+ l₂ → length l₁ = length l₂ → l₁ = l₂
| ._ ._ sublist.slnil h := rfl
| ._ ._ (sublist.cons l₁ l₂ a s) h :=
absurd (length_le_of_sublist s) $ not_le_of_gt $ by rw h; apply lt_succ_self
| ._ ._ (sublist.cons l₁ l₂ a s) h := by cases s.length_le.not_lt (by rw h; apply lt_succ_self)
| ._ ._ (sublist.cons2 l₁ l₂ a s) h :=
by rw [length, length] at h; injection h with h; rw eq_of_sublist_of_length_eq s h
by rw [length, length] at h; injection h with h; rw s.eq_of_length h

theorem eq_of_sublist_of_length_le {l₁ l₂ : list α} (s : l₁ <+ l₂) (h : length l₂ ≤ length l₁) :
l₁ = l₂ :=
eq_of_sublist_of_length_eq s (le_antisymm (length_le_of_sublist s) h)
theorem sublist.eq_of_length_le (s : l₁ <+ l₂) (h : length l₂ ≤ length l₁) : l₁ = l₂ :=
s.eq_of_length $ s.length_le.antisymm h

theorem sublist.antisymm {l₁ l₂ : list α} (s₁ : l₁ <+ l₂) (s₂ : l₂ <+ l₁) : l₁ = l₂ :=
eq_of_sublist_of_length_le s₁ (length_le_of_sublist s₂)
lemma sublist.antisymm (s₁ : l₁ <+ l₂) (s₂ : l₂ <+ l₁) : l₁ = l₂ := s₁.eq_of_length_le s₂.length_le

instance decidable_sublist [decidable_eq α] : ∀ (l₁ l₂ : list α), decidable (l₁ <+ l₂)
| [] l₂ := is_true $ nil_sublist _
Expand Down Expand Up @@ -3003,7 +3002,7 @@ by simp only [map_filter_map, H, filter_map_some]

theorem length_filter_le (p : α → Prop) [decidable_pred p] (l : list α) :
(l.filter p).length ≤ l.length :=
list.length_le_of_sublist (list.filter_sublist _)
(list.filter_sublist _).length_le

theorem length_filter_map_le (f : α → option β) (l : list α) :
(list.filter_map f l).length ≤ l.length :=
Expand Down Expand Up @@ -3169,14 +3168,13 @@ begin
{ exact iff_of_true rfl (forall_mem_nil _) },
rw forall_mem_cons, by_cases p a,
{ rw [filter_cons_of_pos _ h, cons_inj, ih, and_iff_right h] },
{ rw [filter_cons_of_neg _ h],
refine iff_of_false _ (mt and.left h), intro e,
have := filter_sublist l, rw e at this,
exact not_lt_of_ge (length_le_of_sublist this) (lt_succ_self _) }
{ refine iff_of_false (λ hl, h $ of_mem_filter (_ : a ∈ filter p (a :: l))) (mt and.left h),
rw hl,
exact mem_cons_self _ _ }
end

theorem filter_length_eq_length {l} : (filter p l).length = l.length ↔ ∀ a ∈ l, p a :=
iff.trans ⟨eq_of_sublist_of_length_eq l.filter_sublist, congr_arg list.length⟩ filter_eq_self
iff.trans ⟨l.filter_sublist.eq_of_length, congr_arg list.length⟩ filter_eq_self

theorem filter_eq_nil {l} : filter p l = [] ↔ ∀ a ∈ l, ¬p a :=
by simp only [eq_nil_iff_forall_not_mem, mem_filter, not_and]
Expand Down
5 changes: 2 additions & 3 deletions src/data/list/count.lean
Expand Up @@ -45,7 +45,7 @@ by induction l with x l ih; [refl, by_cases (p x)];
simp only [countp_cons_of_neg _ _ h, ih, filter_cons_of_neg _ h]]; refl

lemma countp_le_length : countp p l ≤ l.length :=
by simpa only [countp_eq_length_filter] using length_le_of_sublist (filter_sublist _)
by simpa only [countp_eq_length_filter] using length_filter_le _ _

@[simp] lemma 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]
Expand Down Expand Up @@ -175,8 +175,7 @@ lemma le_count_iff_repeat_sublist {a : α} {l : list α} {n : ℕ} :

lemma repeat_count_eq_of_count_eq_length {a : α} {l : list α} (h : count a l = length l) :
repeat a (count a l) = l :=
eq_of_sublist_of_length_eq (le_count_iff_repeat_sublist.mp (le_refl (count a l)))
(eq.trans (length_repeat a (count a l)) h)
(le_count_iff_repeat_sublist.mp le_rfl).eq_of_length $ (length_repeat a (count a l)).trans h

@[simp] lemma count_filter {p} [decidable_pred p]
{a} {l : list α} (h : p a) : count a (filter p l) = count a l :=
Expand Down
14 changes: 7 additions & 7 deletions src/data/list/infix.lean
Expand Up @@ -113,9 +113,9 @@ alias reverse_prefix ↔ _ is_suffix.reverse
alias reverse_suffix ↔ _ is_prefix.reverse
alias reverse_infix ↔ _ is_infix.reverse

lemma is_infix.length_le (h : l₁ <:+: l₂) : l₁.length ≤ l₂.length := length_le_of_sublist h.sublist
lemma is_prefix.length_le (h : l₁ <+: l₂) : l₁.length ≤ l₂.length := length_le_of_sublist h.sublist
lemma is_suffix.length_le (h : l₁ <:+ l₂) : l₁.length ≤ l₂.length := length_le_of_sublist h.sublist
lemma is_infix.length_le (h : l₁ <:+: l₂) : l₁.length ≤ l₂.length := h.sublist.length_le
lemma is_prefix.length_le (h : l₁ <+: l₂) : l₁.length ≤ l₂.length := h.sublist.length_le
lemma is_suffix.length_le (h : l₁ <:+ l₂) : l₁.length ≤ l₂.length := h.sublist.length_le

lemma eq_nil_of_infix_nil (h : l <:+: []) : l = [] := eq_nil_of_sublist_nil h.sublist

Expand All @@ -138,13 +138,13 @@ lemma infix_iff_prefix_suffix (l₁ l₂ : list α) : l₁ <:+: l₂ ↔ ∃ t,
λ ⟨._, ⟨t, rfl⟩, s, e⟩, ⟨s, t, by rw append_assoc; exact e⟩⟩

lemma eq_of_infix_of_length_eq (h : l₁ <:+: l₂) : l₁.length = l₂.length → l₁ = l₂ :=
eq_of_sublist_of_length_eq h.sublist
h.sublist.eq_of_length

lemma eq_of_prefix_of_length_eq (h : l₁ <+: l₂) : l₁.length = l₂.length → l₁ = l₂ :=
eq_of_sublist_of_length_eq h.sublist
h.sublist.eq_of_length

lemma eq_of_suffix_of_length_eq (h : l₁ <:+ l₂) : l₁.length = l₂.length → l₁ = l₂ :=
eq_of_sublist_of_length_eq h.sublist
h.sublist.eq_of_length

lemma prefix_of_prefix_length_le : ∀ {l₁ l₂ l₃ : list α},
l₁ <+: l₃ → l₂ <+: l₃ → length l₁ ≤ length l₂ → l₁ <+: l₂
Expand Down Expand Up @@ -259,7 +259,7 @@ instance decidable_prefix [decidable_eq α] : ∀ (l₁ l₂ : list α), decidab
-- Alternatively, use mem_tails
instance decidable_suffix [decidable_eq α] : ∀ (l₁ l₂ : list α), decidable (l₁ <:+ l₂)
| [] l₂ := is_true ⟨l₂, append_nil _⟩
| (a :: l₁) [] := is_false $ mt (length_le_of_sublist ∘ is_suffix.sublist) dec_trivial
| (a :: l₁) [] := is_false $ mt (sublist.length_le ∘ is_suffix.sublist) dec_trivial
| l₁ (b :: l₂) := decidable_of_decidable_of_iff (@or.decidable _ _
_ (l₁.decidable_suffix l₂)) suffix_cons_iff.symm

Expand Down
8 changes: 3 additions & 5 deletions src/data/list/perm.lean
Expand Up @@ -352,12 +352,10 @@ theorem perm.subperm {l₁ l₂ : list α} (p : l₁ ~ l₂) : l₁ <+~ l₂ :=
let ⟨l₁', p₁, s₁⟩ := p₂.subperm_left.2 s in ⟨l₁', p₁, s₁.trans s₂⟩

theorem subperm.length_le {l₁ l₂ : list α} : l₁ <+~ l₂ → length l₁ ≤ length l₂
| ⟨l, p, s⟩ := p.length_eq ▸ length_le_of_sublist s
| ⟨l, p, s⟩ := p.length_eq ▸ s.length_le

theorem subperm.perm_of_length_le {l₁ l₂ : list α} : l₁ <+~ l₂ → length l₂ ≤ length l₁ → l₁ ~ l₂
| ⟨l, p, s⟩ h :=
suffices l = l₂, from this ▸ p.symm,
eq_of_sublist_of_length_le s $ p.symm.length_eq ▸ h
| ⟨l, p, s⟩ h := (s.eq_of_length_le $ p.symm.length_eq ▸ h) ▸ p.symm

theorem subperm.antisymm {l₁ l₂ : list α} (h₁ : l₁ <+~ l₂) (h₂ : l₂ <+~ l₁) : l₁ ~ l₂ :=
h₁.perm_of_length_le h₂.length_le
Expand Down Expand Up @@ -591,7 +589,7 @@ theorem subperm.exists_of_length_lt {l₁ l₂ : list α} :
{ cases h },
{ cases lt_or_eq_of_le (nat.le_of_lt_succ h : length l₁ ≤ length l₂) with h h,
{ exact (IH h).imp (λ a s, s.trans (sublist_cons _ _).subperm) },
{ exact ⟨a, eq_of_sublist_of_length_eq s h ▸ subperm.refl _⟩ } },
{ exact ⟨a, s.eq_of_length h ▸ subperm.refl _⟩ } },
{ exact (IH $ nat.lt_of_succ_lt_succ h).imp
(λ a s, (swap _ _ _).subperm_right.1 $ (subperm_cons _).2 s) }
end
Expand Down
2 changes: 1 addition & 1 deletion src/data/list/range.lean
Expand Up @@ -77,7 +77,7 @@ theorem nodup_range' (s n : ℕ) : nodup (range' s n) :=
by rw [add_right_comm, range'_append]

theorem range'_sublist_right {s m n : ℕ} : range' s m <+ range' s n ↔ m ≤ n :=
⟨λ h, by simpa only [length_range'] using length_le_of_sublist h,
⟨λ h, by simpa only [length_range'] using h.length_le,
λ h, by rw [← tsub_add_cancel_of_le h, ← range'_append]; apply sublist_append_left⟩

theorem range'_subset_right {s m n : ℕ} : range' s m ⊆ range' s n ↔ m ≤ n :=
Expand Down
2 changes: 1 addition & 1 deletion src/data/list/sublists.lean
Expand Up @@ -284,7 +284,7 @@ end

lemma sublists_len_of_length_lt {n} {l : list α} (h : l.length < n) : sublists_len n l = [] :=
eq_nil_iff_forall_not_mem.mpr $ λ x, mem_sublists_len.not.mpr $ λ ⟨hs, hl⟩,
(h.trans_eq hl.symm).not_le (length_le_of_sublist hs)
(h.trans_eq hl.symm).not_le (sublist.length_le hs)

@[simp] lemma sublists_len_length : ∀ (l : list α), sublists_len l.length l = [l]
| [] := rfl
Expand Down
6 changes: 3 additions & 3 deletions src/data/multiset/basic.lean
Expand Up @@ -517,12 +517,12 @@ theorem card_eq_one {s : multiset α} : card s = 1 ↔ ∃ a, s = {a} :=
λ ⟨a, e⟩, e.symm ▸ rfl⟩

theorem card_le_of_le {s t : multiset α} (h : s ≤ t) : card s ≤ card t :=
le_induction_on h $ λ l₁ l₂, length_le_of_sublist
le_induction_on h $ λ l₁ l₂, sublist.length_le

@[mono] theorem card_mono : monotone (@card α) := λ a b, card_le_of_le

theorem eq_of_le_of_card_le {s t : multiset α} (h : s ≤ t) : card t ≤ card s → s = t :=
le_induction_on h $ λ l₁ l₂ s h₂, congr_arg coe $ eq_of_sublist_of_length_le s h₂
le_induction_on h $ λ l₁ l₂ s h₂, congr_arg coe $ s.eq_of_length_le h₂

theorem card_lt_of_lt {s t : multiset α} (h : s < t) : card s < card t :=
lt_of_not_ge $ λ h₂, ne_of_lt h $ eq_of_le_of_card_le (le_of_lt h) h₂
Expand Down Expand Up @@ -1413,7 +1413,7 @@ mem_filter.2 ⟨m, h⟩

theorem filter_eq_self {s} : filter p s = s ↔ ∀ a ∈ s, p a :=
quot.induction_on s $ λ l, iff.trans ⟨λ h,
eq_of_sublist_of_length_eq (filter_sublist _) (@congr_arg _ _ _ _ card h),
(filter_sublist _).eq_of_length (@congr_arg _ _ _ _ card h),
congr_arg coe⟩ filter_eq_self

theorem filter_eq_nil {s} : filter p s = 0 ↔ ∀ a ∈ s, ¬p a :=
Expand Down
3 changes: 1 addition & 2 deletions src/group_theory/free_group.lean
Expand Up @@ -275,8 +275,7 @@ protected theorem sublist : red L₁ L₂ → L₂ <+ L₁ :=
refl_trans_gen_of_transitive_reflexive
(λl, list.sublist.refl l) (λa b c hab hbc, list.sublist.trans hbc hab) (λa b, red.step.sublist)

theorem length_le (h : red L₁ L₂) : L₂.length ≤ L₁.length :=
list.length_le_of_sublist h.sublist
theorem length_le (h : red L₁ L₂) : L₂.length ≤ L₁.length := h.sublist.length_le

theorem sizeof_of_step : ∀ {L₁ L₂ : list (α × bool)}, step L₁ L₂ → L₂.sizeof < L₁.sizeof
| _ _ (@step.bnot _ L1 L2 x b) :=
Expand Down
2 changes: 1 addition & 1 deletion src/number_theory/arithmetic_function.lean
Expand Up @@ -797,7 +797,7 @@ lemma card_distinct_factors_eq_card_factors_iff_squarefree {n : ℕ} (h0 : n ≠
begin
rw [squarefree_iff_nodup_factors h0, card_distinct_factors_apply],
split; intro h,
{ rw ← list.eq_of_sublist_of_length_eq n.factors.dedup_sublist h,
{ rw ←n.factors.dedup_sublist.eq_of_length h,
apply list.nodup_dedup },
{ rw h.dedup,
refl }
Expand Down

0 comments on commit 11156f5

Please sign in to comment.