Theorem: Batteries.HashMap.Imp.erase_WF
File: .lake/packages/batteries/Batteries/Data/HashMap/WF.lean

tactic: dsimp [erase, cond]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
⊢ (m.erase k).buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
⊢ (match AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] with
      | true =>
        { size := m.size - 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.erase k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      | false => { size := m.size, buckets := m.buckets }).buckets.WF

tactic: split
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
⊢ (match AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] with
      | true =>
        { size := m.size - 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.erase k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      | false => { size := m.size, buckets := m.buckets }).buckets.WF
state_after: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
⊢ { size := m.size - 1,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.erase k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF

case h_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = false
⊢ { size := m.size, buckets := m.buckets }.buckets.WF

tactic: refine h.update (fun H => ?_) (fun H a h => ?_) <;> simp only [AssocList.toList_erase] at h ⊢
state_before: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
⊢ { size := m.size - 1,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.erase k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF
state_after: case h_1.refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
H : List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList
⊢ List.Pairwise (fun a b => ¬(a.fst == b.fst) = true)
    (List.eraseP (fun x => x.fst == k) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList)

case h_1.refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h✝ : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : a ∈ List.eraseP (fun x => x.fst == k) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat

tactic: exact H.sublist (List.eraseP_sublist _)
state_before: case h_1.refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
H : List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList
⊢ List.Pairwise (fun a b => ¬(a.fst == b.fst) = true)
    (List.eraseP (fun x => x.fst == k) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList)
state_after: no goals

tactic: exact H _ (List.mem_of_mem_eraseP h)
state_before: case h_1.refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h✝ : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : a ∈ List.eraseP (fun x => x.fst == k) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
state_after: no goals

tactic: exact h
state_before: case h_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = false
⊢ { size := m.size, buckets := m.buckets }.buckets.WF
state_after: no goals