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

Proof steps:
state_before: α : Type u_1
β : Type u_2
sz : Nat
inst✝¹ : BEq α
inst✝ : Hashable α
buckets : Buckets α β
H : buckets.WF
x✝³ : AssocList α β
x✝² : x✝³ ∈ (Buckets.mk (buckets.val.size * 2) ⋯).val.data
x✝¹ : α × β
x✝ : x✝¹ ∈ x✝³.toList
⊢ (fun k x => ((hash k).toUSize % buckets.val.size).toNat < 0) x✝¹.fst x✝¹.snd
state_after: no goals
tactic: simp_all [Buckets.mk, List.mem_replicate]
state_before: α : Type u_1
β : Type u_2
sz : Nat
inst✝¹ : BEq α
inst✝ : Hashable α
buckets : Buckets α β
H : buckets.WF
i : Nat
source : Array (AssocList α β)
hs₁ :
  ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α β),
    bucket ∈ source.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList
hs₂ : ∀ (j : Nat) (h : j < source.size), AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat = j) source[j]
target : Buckets α β
ht :
  target.WF ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ target.val.data → AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat < i) bucket
⊢ (expand.go i source target).WF
state_after: α : Type u_1
β : Type u_2
sz : Nat
inst✝¹ : BEq α
inst✝ : Hashable α
buckets : Buckets α β
H : buckets.WF
i : Nat
source : Array (AssocList α β)
hs₁ :
  ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α β),
    bucket ∈ source.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList
hs₂ : ∀ (j : Nat) (h : j < source.size), AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat = j) source[j]
target : Buckets α β
ht :
  target.WF ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ target.val.data → AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat < i) bucket
⊢ (if h : i < source.size then
      let idx := ⟨i, h⟩;
      let es := source.get idx;
      let source := source.set idx AssocList.nil;
      let target := AssocList.foldl reinsertAux target es;
      expand.go (i + 1) source target
    else target).WF
tactic: unfold expand.go
state_before: α : Type u_1
β : Type u_2
sz : Nat
inst✝¹ : BEq α
inst✝ : Hashable α
buckets : Buckets α β
H : buckets.WF
i : Nat
source : Array (AssocList α β)
hs₁ :
  ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α β),
    bucket ∈ source.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList
hs₂ : ∀ (j : Nat) (h : j < source.size), AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat = j) source[j]
target : Buckets α β
ht :
  target.WF ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ target.val.data → AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat < i) bucket
⊢ (if h : i < source.size then
      let idx := ⟨i, h⟩;
      let es := source.get idx;
      let source := source.set idx AssocList.nil;
      let target := AssocList.foldl reinsertAux target es;
      expand.go (i + 1) source target
    else target).WF
state_after: case isTrue
α : Type u_1
β : Type u_2
sz : Nat
inst✝¹ : BEq α
inst✝ : Hashable α
buckets : Buckets α β
H : buckets.WF
i : Nat
source : Array (AssocList α β)
hs₁ :
  ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α β),
    bucket ∈ source.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList
hs₂ : ∀ (j : Nat) (h : j < source.size), AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat = j) source[j]
target : Buckets α β
ht :
  target.WF ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ target.val.data → AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat < i) bucket
h✝ : i < source.size
⊢ (let idx := ⟨i, h✝⟩;
    let es := source.get idx;
    let source := source.set idx AssocList.nil;
    let target := AssocList.foldl reinsertAux target es;
    expand.go (i + 1) source target).WF

case isFalse
α : Type u_1
β : Type u_2
sz : Nat
inst✝¹ : BEq α
inst✝ : Hashable α
buckets : Buckets α β
H : buckets.WF
i : Nat
source : Array (AssocList α β)
hs₁ :
  ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α β),
    bucket ∈ source.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList
hs₂ : ∀ (j : Nat) (h : j < source.size), AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat = j) source[j]
target : Buckets α β
ht :
  target.WF ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ target.val.data → AssocList.All (fun k x => ((hash k).toUSize % source.size).toNat < i) bucket
h✝ : ¬i < source.size
⊢ target.WF
tactic: split