| ((ls(rxs, xs) * ls(rys, ys) * del-list(to_delete, n)))(H), # xs < h0, n + # xs ≤ h0, n ≤ # xs + # ys, ys = [] ∨ # ys = h0 ⊦ ⟪tree_buffer_heap_process_queue#(; H, to_delete); xs_len := # xs; h := h0; choose r with ¬ r ∈ H ∧ r ≠ null in {H := H ++ r; H[r].val := a; H[r].nxt := rxs; if xs_len + 1 = h then {if rys ≠ null then to_delete := rys + to_delete; rys := r; xs_len := 0; rxs := null} else {rxs := r; xs_len := 1 + xs_len}}⟫ ⟨xs_len0 := # xs; caterpillar_add#(a, h0; xs, xs_len0, ys)⟩ ∃ n. ((ls(rxs, xs) * ls(rys, ys) * del-list(to_delete, n)))(H) ∧ n ≤ # xs + # ys ∧ n + # xs ≤ h0 ∧ xs_len = xs_len0 |
((del-list(to_delete, n) * P))(H) ⊦ ⟪tree_buffer_heap_process_queue#(; H, to_delete)⟫ ((n ≥ 2 → ((del-list(to_delete, n - 2) * P))(H)) ∧ (n < 2 → to_delete = [] ∧ ((del-list([], 0) * P))(H)))
P0 = ls(rys, ys) * ls(rxs, xs), n0 = n, ((ls(rxs, xs) * ls(rys, ys) * del-list(to_delete, n)))(H), ((del-list(to_delete, n) * ls(rys, ys) * ls(rxs, xs)))(H), # xs < h0, n ≤ # xs + # ys, n + # xs ≤ h0, ys = [] ∨ # ys = h0 ⊦ [tree_buffer_heap_process_queue#(; H, to_delete)] ( (n0 ≥ 2 → ((del-list(to_delete, n0 - 2) * P0))(H)) ∧ (n0 < 2 → to_delete = [] ∧ ((del-list([], 0) * P0))(H)) → ⟪xs_len := # xs; h := h0; choose r with ¬ r ∈ H ∧ r ≠ null in {H := H ++ r; H[r].val := a; H[r].nxt := rxs; if xs_len + 1 = h then {if rys ≠ null then to_delete := rys + to_delete; rys := r; xs_len := 0; rxs := null} else {rxs := r; xs_len := 1 + xs_len}}⟫ ⟨xs_len0 := # xs; caterpillar_add#(a, h0; xs, xs_len0, ys)⟩ ∃ n. ((ls(rxs, xs) * ls(rys, ys) * del-list(to_delete, n)))(H) ∧ n ≤ # xs + # ys ∧ n + # xs ≤ h0 ∧ xs_len = xs_len0)
Used simplifier rules: sep-ass: ⊦ (P0 * P1) * P2 = P0 * P1 * P2; from specification heap-sep%sep-com: ⊦ P0 * P1 = P1 * P0; from specification heap-sep