Theorem: Std.HashMap.Imp.expand_WF.foldl
File: Std/Data/HashMap/WF.lean

tactic: induction l generalizing target with
| nil => exact ⟨ht₁, fun _ h₁ _ h₂ => (ht₂ _ h₁ _ h₂).1⟩
| cons _ _ ih =>
  simp at hl₁ hl₂ ht₂
  refine ih hl₁.2 hl₂.2
    (reinsertAux_WF ht₁ fun _ h => (ht₂ _ (Array.getElem_mem_data ..) _ h).2.1)
    (fun _ h => ?_)
  simp [reinsertAux, Bucket.update] at h
  match List.mem_or_eq_of_mem_set h with
  | .inl h =>
    intro _ hf
    have ⟨h₁, h₂⟩ := ht₂ _ h _ hf
    exact ⟨h₁, h₂.2⟩
  | .inr h => subst h; intro
    | _, .head .. =>
      exact ⟨hl₂.1 ▸ Nat.le_refl _, fun _ h h' => hl₁.1 _ h (PartialEquivBEq.symm h')⟩
    | _, .tail _ h =>
      have ⟨h₁, h₂⟩ := ht₂ _ (Array.getElem_mem_data ..) _ h
      exact ⟨h₁, h₂.2⟩
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
l : List (α × β)
i : Nat
hl₁ : ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) l
hl₂ : ∀ (x : α × β), x ∈ l → rank x.fst = i
target : Bucket α β
ht₁ : Bucket.WF target
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧ ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ l → ¬(x.fst == k) = true)
        bucket
⊢ Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target l) ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target l).val.data →
        AssocList.All (fun k x => rank k ≤ i) bucket

tactic: exact ⟨ht₁, fun _ h₁ _ h₂ => (ht₂ _ h₁ _ h₂).1⟩
state_before: case nil
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
hl₁ : ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) []
hl₂ : ∀ (x : α × β), x ∈ [] → rank x.fst = i
target : Bucket α β
ht₁ : Bucket.WF target
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ [] → ¬(x.fst == k) = true)
        bucket
⊢ Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target []) ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target []).val.data →
        AssocList.All (fun k x => rank k ≤ i) bucket

tactic: simp at hl₁ hl₂ ht₂
state_before: case cons
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) (head✝ :: tail✝)
hl₂ : ∀ (x : α × β), x ∈ head✝ :: tail✝ → rank x.fst = i
target : Bucket α β
ht₁ : Bucket.WF target
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
              x ∈ head✝ :: tail✝ → ¬(x.fst == k) = true)
        bucket
⊢ Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target (head✝ :: tail✝)) ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target (head✝ :: tail✝)).val.data →
        AssocList.All (fun k x => rank k ≤ i) bucket

tactic: refine ih hl₁.2 hl₂.2
  (reinsertAux_WF ht₁ fun _ h => (ht₂ _ (Array.getElem_mem_data ..) _ h).2.1)
  (fun _ h => ?_)
state_before: case cons
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
⊢ Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target (head✝ :: tail✝)) ∧
    ∀ (bucket : AssocList α β),
      bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target (head✝ :: tail✝)).val.data →
        AssocList.All (fun k x => rank k ≤ i) bucket

tactic: simp [reinsertAux, Bucket.update] at h
state_before: case cons
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
x✝ : AssocList α β
h : x✝ ∈ ((fun d x => reinsertAux d x.fst x.snd) target head✝).val.data
⊢ AssocList.All
    (fun k x =>
      rank k ≤ i ∧ ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == k) = true)
    x✝

tactic: match List.mem_or_eq_of_mem_set h with
| .inl h =>
  intro _ hf
  have ⟨h₁, h₂⟩ := ht₂ _ h _ hf
  exact ⟨h₁, h₂.2⟩
| .inr h => subst h; intro
  | _, .head .. =>
    exact ⟨hl₂.1 ▸ Nat.le_refl _, fun _ h h' => hl₁.1 _ h (PartialEquivBEq.symm h')⟩
  | _, .tail _ h =>
    have ⟨h₁, h₂⟩ := ht₂ _ (Array.getElem_mem_data ..) _ h
    exact ⟨h₁, h₂.2⟩
state_before: case cons
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
x✝ : AssocList α β
h :
  x✝ ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
⊢ AssocList.All
    (fun k x =>
      rank k ≤ i ∧ ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == k) = true)
    x✝

tactic: intro _ hf
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
x✝ : AssocList α β
h✝ :
  x✝ ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
h : x✝ ∈ target.val.data
⊢ AssocList.All
    (fun k x =>
      rank k ≤ i ∧ ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == k) = true)
    x✝

tactic: have ⟨h₁, h₂⟩ := ht₂ _ h _ hf
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
x✝ : AssocList α β
h✝ :
  x✝ ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
h : x✝ ∈ target.val.data
a✝ : α × β
hf : a✝ ∈ AssocList.toList x✝
⊢ rank a✝.fst ≤ i ∧
    ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == a✝.fst) = true

tactic: exact ⟨h₁, h₂.2⟩
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
x✝ : AssocList α β
h✝ :
  x✝ ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
h : x✝ ∈ target.val.data
a✝ : α × β
hf : a✝ ∈ AssocList.toList x✝
h₁ : rank a✝.fst ≤ i
h₂ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    ¬(head✝.fst == a✝.fst) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == a✝.fst) = true
⊢ rank a✝.fst ≤ i ∧
    ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == a✝.fst) = true

tactic: subst h
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
x✝ : AssocList α β
h✝ :
  x✝ ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
h :
  x✝ =
    AssocList.cons head✝.fst head✝.snd
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val]
⊢ AssocList.All
    (fun k x =>
      rank k ≤ i ∧ ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == k) = true)
    x✝

tactic: intro
| _, .head .. =>
exact ⟨hl₂.1 ▸ Nat.le_refl _, fun _ h h' => hl₁.1 _ h (PartialEquivBEq.symm h')⟩
| _, .tail _ h =>
have ⟨h₁, h₂⟩ := ht₂ _ (Array.getElem_mem_data ..) _ h
exact ⟨h₁, h₂.2⟩
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
h :
  AssocList.cons head✝.fst head✝.snd
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val] ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
⊢ AssocList.All
    (fun k x =>
      rank k ≤ i ∧ ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == k) = true)
    (AssocList.cons head✝.fst head✝.snd
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])

tactic: exact ⟨hl₂.1 ▸ Nat.le_refl _, fun _ h h' => hl₁.1 _ h (PartialEquivBEq.symm h')⟩
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
h :
  AssocList.cons head✝.fst head✝.snd
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val] ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
x✝¹ : α × β
x✝ :
  x✝¹ ∈
    AssocList.toList
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
⊢ rank (head✝.fst, head✝.snd).fst ≤ i ∧
    ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
      x ∈ tail✝ → ¬(x.fst == (head✝.fst, head✝.snd).fst) = true

tactic: have ⟨h₁, h₂⟩ := ht₂ _ (Array.getElem_mem_data ..) _ h
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
h✝ :
  AssocList.cons head✝.fst head✝.snd
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val] ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
x✝¹ : α × β
x✝ :
  x✝¹ ∈
    AssocList.toList
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
a✝ : α × β
h :
  List.Mem a✝
    (AssocList.toList
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
⊢ rank a✝.fst ≤ i ∧
    ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == a✝.fst) = true

tactic: exact ⟨h₁, h₂.2⟩
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
rank : α → Nat
i : Nat
head✝ : α × β
tail✝ : List (α × β)
ih :
  (∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α], List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝) →
    (∀ (x : α × β), x ∈ tail✝ → rank x.fst = i) →
      ∀ {target : Bucket α β},
        Bucket.WF target →
          (∀ (bucket : AssocList α β),
              bucket ∈ target.val.data →
                AssocList.All
                  (fun k x =>
                    rank k ≤ i ∧
                      ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β),
                        x ∈ tail✝ → ¬(x.fst == k) = true)
                  bucket) →
            Bucket.WF (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝) ∧
              ∀ (bucket : AssocList α β),
                bucket ∈ (List.foldl (fun d x => reinsertAux d x.fst x.snd) target tail✝).val.data →
                  AssocList.All (fun k x => rank k ≤ i) bucket
target : Bucket α β
ht₁ : Bucket.WF target
hl₁ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    (∀ (a' : α × β), a' ∈ tail✝ → ¬(head✝.fst == a'.fst) = true) ∧
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) tail✝
hl₂ : rank head✝.fst = i ∧ ∀ (a : α × β), a ∈ tail✝ → rank a.fst = i
ht₂ :
  ∀ (bucket : AssocList α β),
    bucket ∈ target.val.data →
      AssocList.All
        (fun k x =>
          rank k ≤ i ∧
            ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
              ¬(head✝.fst == k) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == k) = true)
        bucket
h✝ :
  AssocList.cons head✝.fst head✝.snd
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val] ∈
    List.set target.val.data (USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val)
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
x✝¹ : α × β
x✝ :
  x✝¹ ∈
    AssocList.toList
      (AssocList.cons head✝.fst head✝.snd
        target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
a✝ : α × β
h :
  List.Mem a✝
    (AssocList.toList
      target.val[USize.toNat (mkIdx (_ : 0 < Array.size target.val) (UInt64.toUSize (hash head✝.fst))).val])
h₁ : rank a✝.fst ≤ i
h₂ :
  ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α],
    ¬(head✝.fst == a✝.fst) = true ∧ ∀ (a : α × β), a ∈ tail✝ → ¬(a.fst == a✝.fst) = true
⊢ rank a✝.fst ≤ i ∧
    ∀ [inst : PartialEquivBEq α] [inst : LawfulHashable α] (x : α × β), x ∈ tail✝ → ¬(x.fst == a✝.fst) = true