Module docstring
{"# List Permutations and list lattice operations.
This file develops theory about the List.Perm relation and the lattice structure on lists.
"}
{"# List Permutations and list lattice operations.
This file develops theory about the List.Perm relation and the lattice structure on lists.
"}
List.Perm.bagInter_right
theorem
{l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) : l₁.bagInter t ~ l₂.bagInter t
theorem Perm.bagInter_right {l₁ l₂ : List α} (t : List α) (h : l₁ ~ l₂) :
l₁.bagInter t ~ l₂.bagInter t := by
induction h generalizing t with
| nil => simp
| cons x => by_cases x ∈ t <;> simp [*, Perm.cons]
| swap x y =>
by_cases h : x = y
· simp [h]
by_cases xt : x ∈ t <;> by_cases yt : y ∈ t
· simp [xt, yt, mem_erase_of_ne h, mem_erase_of_ne (Ne.symm h), erase_comm, swap]
· simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
· simp [xt, yt, mt mem_of_mem_erase, Perm.cons]
· simp [xt, yt]
| trans _ _ ih_1 ih_2 => exact (ih_1 _).trans (ih_2 _)
List.Perm.bagInter_left
theorem
(l : List α) {t₁ t₂ : List α} (p : t₁ ~ t₂) : l.bagInter t₁ = l.bagInter t₂
List.Perm.bagInter
theorem
{l₁ l₂ t₁ t₂ : List α} (hl : l₁ ~ l₂) (ht : t₁ ~ t₂) : l₁.bagInter t₁ ~ l₂.bagInter t₂
theorem Perm.bagInter {l₁ l₂ t₁ t₂ : List α} (hl : l₁ ~ l₂) (ht : t₁ ~ t₂) :
l₁.bagInter t₁ ~ l₂.bagInter t₂ :=
ht.bagInter_left l₂ ▸ hl.bagInter_right _
List.Perm.inter_append
theorem
{l t₁ t₂ : List α} (h : Disjoint t₁ t₂) : l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂
theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) :
l ∩ (t₁ ++ t₂)l ∩ (t₁ ++ t₂) ~ l ∩ t₁ ++ l ∩ t₂ := by
induction l with
| nil => simp
| cons x xs l_ih =>
by_cases h₁ : x ∈ t₁
· have h₂ : x ∉ t₂ := h h₁
simp [*]
by_cases h₂ : x ∈ t₂
· simp only [*, inter_cons_of_not_mem, false_or, mem_append, inter_cons_of_mem,
not_false_iff]
refine Perm.trans (Perm.cons _ l_ih) ?_
change [x][x] ++ xs ∩ t₁ ++ xs ∩ t₂ ~ xs ∩ t₁ ++ ([x] ++ xs ∩ t₂)
rw [← List.append_assoc]
solve_by_elim [Perm.append_right, perm_append_comm]
· simp [*]
List.Perm.take_inter
theorem
{xs ys : List α} (n : ℕ) (h : xs ~ ys) (h' : ys.Nodup) : xs.take n ~ ys.inter (xs.take n)
theorem Perm.take_inter {xs ys : List α} (n : ℕ) (h : xs ~ ys)
(h' : ys.Nodup) : xs.take n ~ ys.inter (xs.take n) := by
simp only [List.inter]
exact Perm.trans (show xs.take n ~ xs.filter (xs.take n).elem by
conv_lhs => rw [Nodup.take_eq_filter_mem ((Perm.nodup_iff h).2 h')])
(Perm.filter _ h)
List.Perm.drop_inter
theorem
{xs ys : List α} (n : ℕ) (h : xs ~ ys) (h' : ys.Nodup) : xs.drop n ~ ys.inter (xs.drop n)
theorem Perm.drop_inter {xs ys : List α} (n : ℕ) (h : xs ~ ys) (h' : ys.Nodup) :
xs.drop n ~ ys.inter (xs.drop n) := by
by_cases h'' : n ≤ xs.length
· let n' := xs.length - n
have h₀ : n = xs.length - n' := by rwa [Nat.sub_sub_self]
have h₁ : xs.drop n = (xs.reverse.take n').reverse := by
rw [take_reverse, h₀, reverse_reverse]
rw [h₁]
apply (reverse_perm _).trans
rw [inter_reverse]
apply Perm.take_inter _ _ h'
apply (reverse_perm _).trans; assumption
· have : xs.drop n = [] := by
apply eq_nil_of_length_eq_zero
rw [length_drop, Nat.sub_eq_zero_iff_le]
apply le_of_not_ge h''
simp [this, List.inter]
List.Perm.dropSlice_inter
theorem
{xs ys : List α} (n m : ℕ) (h : xs ~ ys) (h' : ys.Nodup) : List.dropSlice n m xs ~ ys ∩ List.dropSlice n m xs
theorem Perm.dropSlice_inter {xs ys : List α} (n m : ℕ) (h : xs ~ ys)
(h' : ys.Nodup) : List.dropSliceList.dropSlice n m xs ~ ys ∩ List.dropSlice n m xs := by
simp only [dropSlice_eq]
have : n ≤ n + m := Nat.le_add_right _ _
have h₂ := h.nodup_iff.2 h'
apply Perm.trans _ (Perm.inter_append _).symm
· exact Perm.append (Perm.take_inter _ h h') (Perm.drop_inter _ h h')
· exact disjoint_take_drop h₂ this