Theorem: List.subperm_append_diff_self_of_count_le
File: .lake/packages/batteries/Batteries/Data/List/Perm.lean

tactic: induction l₁ generalizing l₂ with
| nil => simp
| cons hd tl IH =>
  have : hd ∈ l₂ := by
    rw [← count_pos_iff_mem]
    exact Nat.lt_of_lt_of_le (count_pos_iff_mem.mpr (.head _)) (h hd (.head _))
  have := perm_cons_erase this
  refine Perm.trans ?_ this.symm
  rw [cons_append, diff_cons, perm_cons]
  refine IH fun x hx => ?_
  specialize h x (.tail _ hx)
  rw [perm_iff_count.mp this] at h
  if hx : x = hd then subst hd; simpa [Nat.succ_le_succ_iff] using h
  else simpa [hx] using h
state_before: α : Type u_1
inst✝ : DecidableEq α
l₁ l₂ : List α
h : ∀ (x : α), x ∈ l₁ → count x l₁ ≤ count x l₂
⊢ l₁ ++ l₂.diff l₁ ~ l₂
state_after: no goals

tactic: simp
state_before: case nil
α : Type u_1
inst✝ : DecidableEq α
l₂ : List α
h : ∀ (x : α), x ∈ [] → count x [] ≤ count x l₂
⊢ [] ++ l₂.diff [] ~ l₂
state_after: no goals

tactic: have : hd ∈ l₂ := by
  rw [← count_pos_iff_mem]
  exact Nat.lt_of_lt_of_le (count_pos_iff_mem.mpr (.head _)) (h hd (.head _))
state_before: case cons
α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ hd :: tl ++ l₂.diff (hd :: tl) ~ l₂
state_after: case cons
α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : hd ∈ l₂
⊢ hd :: tl ++ l₂.diff (hd :: tl) ~ l₂

tactic: have := perm_cons_erase this
state_before: case cons
α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this : hd ∈ l₂
⊢ hd :: tl ++ l₂.diff (hd :: tl) ~ l₂
state_after: case cons
α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
this✝ : hd ∈ l₂
this : l₂ ~ hd :: l₂.erase hd
⊢ hd :: tl ++ l₂.diff (hd :: tl) ~ l₂

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

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

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

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

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

tactic: if hx : x = hd then subst hd; simpa [Nat.succ_le_succ_iff] using h
else simpa [hx] using h
state_before: case cons
α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
this✝ : hd ∈ l₂
this : l₂ ~ hd :: l₂.erase hd
x : α
hx : x ∈ tl
h : count x (hd :: tl) ≤ count x (hd :: l₂.erase hd)
⊢ count x tl ≤ count x (l₂.erase hd)
state_after: no goals

tactic: rw [← count_pos_iff_mem]
state_before: α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ hd ∈ l₂
state_after: α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ 0 < count hd l₂

tactic: exact Nat.lt_of_lt_of_le (count_pos_iff_mem.mpr (.head _)) (h hd (.head _))
state_before: α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
h : ∀ (x : α), x ∈ hd :: tl → count x (hd :: tl) ≤ count x l₂
⊢ 0 < count hd l₂
state_after: no goals

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

tactic: simpa [Nat.succ_le_succ_iff] using h
state_before: α : Type u_1
inst✝ : DecidableEq α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
x : α
hx : x ∈ tl
this✝ : x ∈ l₂
this : l₂ ~ x :: l₂.erase x
h : count x (x :: tl) ≤ count x (x :: l₂.erase x)
⊢ count x tl ≤ count x (l₂.erase x)
state_after: no goals

tactic: simpa [hx] using h
state_before: α : Type u_1
inst✝ : DecidableEq α
hd : α
tl : List α
IH : ∀ {l₂ : List α}, (∀ (x : α), x ∈ tl → count x tl ≤ count x l₂) → tl ++ l₂.diff tl ~ l₂
l₂ : List α
this✝ : hd ∈ l₂
this : l₂ ~ hd :: l₂.erase hd
x : α
hx✝ : x ∈ tl
h : count x (hd :: tl) ≤ count x (hd :: l₂.erase hd)
hx : ¬x = hd
⊢ count x tl ≤ count x (l₂.erase hd)
state_after: no goals