Theorem: List.subperm_append_diff_self_of_count_le
File: Mathlib/Data/List/Perm.lean

tactic: induction' l₁ with hd tl IH generalizing l₂
state_before: α : Type uu
β : Type vv
l₁✝ l₂✝ : List α
inst✝ : DecidableEq α
l₁ l₂ : List α
h : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂
⊢ l₁ ++ List.diff l₂ l₁ ~ l₂

tactic: simp
state_before: case nil
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
l₂ : List α
h : ∀ (x : α), x ∈ [] → count x [] ≤ count x l₂
⊢ [] ++ List.diff l₂ [] ~ l₂

tactic: have : hd ∈ l₂ := by
  rw [← count_pos]
  exact lt_of_lt_of_le (count_pos.mpr (mem_cons_self _ _)) (h hd (mem_cons_self _ _))
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ hd :: tl ++ List.diff l₂ (hd :: tl) ~ l₂

tactic: replace := perm_cons_erase this
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : hd ∈ l₂
⊢ hd :: tl ++ List.diff l₂ (hd :: tl) ~ l₂

tactic: refine' Perm.trans _ this.symm
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : l₂ ~ hd :: List.erase l₂ hd
⊢ hd :: tl ++ List.diff l₂ (hd :: tl) ~ l₂

tactic: rw [cons_append, diff_cons, perm_cons]
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : l₂ ~ hd :: List.erase l₂ hd
⊢ hd :: tl ++ List.diff l₂ (hd :: tl) ~ hd :: List.erase l₂ hd

tactic: refine' IH fun x hx => _
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : l₂ ~ hd :: List.erase l₂ hd
⊢ tl ++ List.diff (List.erase l₂ hd) tl ~ List.erase l₂ hd

tactic: specialize h x (mem_cons_of_mem _ hx)
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : l₂ ~ hd :: List.erase l₂ hd
x : α
hx : x ∈ tl
⊢ count x tl ≤ count x (List.erase l₂ hd)

tactic: rw [perm_iff_count.mp this] at h
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
this : l₂ ~ hd :: List.erase l₂ hd
x : α
hx : x ∈ tl
h : count x (hd :: tl) ≤ count x l₂
⊢ count x tl ≤ count x (List.erase l₂ hd)

tactic: by_cases hx : x = hd
state_before: case cons
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
this : l₂ ~ hd :: List.erase l₂ hd
x : α
hx : x ∈ tl
h : count x (hd :: tl) ≤ count x (hd :: List.erase l₂ hd)
⊢ count x tl ≤ count x (List.erase l₂ hd)

tactic: rw [← count_pos]
state_before: α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ hd ∈ l₂

tactic: exact lt_of_lt_of_le (count_pos.mpr (mem_cons_self _ _)) (h hd (mem_cons_self _ _))
state_before: α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ 0 < count hd l₂

tactic: subst hd
state_before: case pos
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
this : l₂ ~ hd :: List.erase l₂ hd
x : α
hx✝ : x ∈ tl
h : count x (hd :: tl) ≤ count x (hd :: List.erase l₂ hd)
hx : x = hd
⊢ count x tl ≤ count x (List.erase l₂ hd)

tactic: simpa [Nat.succ_le_succ_iff] using h
state_before: case pos
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
x : α
hx : x ∈ tl
this : l₂ ~ x :: List.erase l₂ x
h : count x (x :: tl) ≤ count x (x :: List.erase l₂ x)
⊢ count x tl ≤ count x (List.erase l₂ x)

tactic: simpa [hx] using h
state_before: case neg
α : Type uu
β : Type vv
l₁✝ l₂✝¹ : List α
inst✝ : DecidableEq α
l₁ l₂✝ : List α
h✝ : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂✝
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ List.diff l₂ tl ~ l₂
l₂ : List α
this : l₂ ~ hd :: List.erase l₂ hd
x : α
hx✝ : x ∈ tl
h : count x (hd :: tl) ≤ count x (hd :: List.erase l₂ hd)
hx : ¬x = hd
⊢ count x tl ≤ count x (List.erase l₂ hd)