| # buf = LEB_SIZE, # apebs = # wlar, apebs[vtblpnum2] = mkpeb(aehdr0, avhdr0, buf1, m2, false), apebs[vtblpnum1] = mkpeb(aehdr, empty, mkempbuf(LEB_SIZE), 0, false), wlar[vtblpnum2] = wl-entry(m1, used), wlar[vtblpnum1] = wl-entry(m0, free), vtblpnum4 ≠ vtblpnum1, aehdr.valid?, vtblpnum2 < # wlar, vtblpnum1 < # wlar, bflipset-cons(bflipset, wlar), bflipset-cons(bflipset0, wlar), ubi-io-inv(apebs), ubi-io-peb-inv(mkpeb(aehdr0, avhdr0, buf1, m2, false)), unique-sqns(apebs), valid-ebatbl(apebs, wlar, vols, vtblpnum4), valid-eraseq(q), valid-eraseq(wlar, q), valid-eraseq(apebs, q), valid-global-sqn(apebs, sqnum), valid-peb(mkpeb(aehdr0, avhdr0, buf1, m2, false)), valid-vtbl(apebs, vols, wlar, vtblpnum4), valid-wl(apebs, wlar), ⌊err0⌋ , ¬ vtblpnum2 ∈ q, ¬ vtblpnum4 ∈ q, ¬ VTBL_VOLID ∈ vols, bflipset = ∅ → m1 + WL_THRESHOLD ≤ m0 ⊦ ⟪q0 := q; apebs0 := apebs; if err0 = ESUCCESS then {ubi_erase_worker_helper#(vtblpnum2; wlar, apebs; err0); if err0 = ESUCCESS then q := q.butlast}⟫ ( # apebs = # wlar ∧ unique-sqns(apebs) ∧ valid-global-sqn(apebs, sqnum) ∧ valid-wl(apebs, wlar) ∧ valid-eraseq(q) ∧ valid-eraseq(wlar, q) ∧ valid-eraseq(apebs, q) ∧ bflipset-cons(bflipset0, wlar) ∧ valid-ebatbl(apebs, wlar, vols, vtblpnum4) ∧ valid-vtbl(apebs, vols, wlar, vtblpnum4) ∧ ubi-io-inv(apebs) ∧ ( id(apebs, apebs0, mapped-pebs(vols)) ∧ q.lebrefs ⊆ q0.lebrefs ++ (VTBL_VOLID × VTBL_LNUM) ∨ (∃ v, m, n. v ∈ vols ∧ m < # vols[v] ∧ vols[v][m] ≠ unmapped ∧ vols = vols[v, vols[v][m, ⌜n⌝ ]] ∧ id(apebs, apebs0, mapped-pebs(vols) -- vols[v][m].pnum) ∧ apebs[n].data = apebs0[vols[v][m].pnum].data ∧ apebs[n].fill ≤ apebs0[vols[v][m].pnum].fill ∧ q.lebrefs ⊆ q0.lebrefs ++ (v × m)))) |
# apebs = # wlar, # buf = LEB_SIZE, wlar[vtblpnum1] = wl-entry(m0, free), wlar[vtblpnum2] = wl-entry(m1, used), apebs[vtblpnum1] = mkpeb(aehdr, empty, mkempbuf(LEB_SIZE), 0, false), apebs[vtblpnum2] = mkpeb(aehdr0, avhdr0, buf1, m2, false), q0 = q, aehdr.valid?, vtblpnum1 < # wlar, vtblpnum2 < # wlar, bflipset-cons(bflipset0, wlar), bflipset-cons(bflipset, wlar), ubi-io-inv(apebs), ubi-io-peb-inv(mkpeb(aehdr0, avhdr0, buf1, m2, false)), unique-sqns(apebs), valid-ebatbl(apebs, wlar, vols, vtblpnum4), valid-eraseq(apebs, q), valid-eraseq(wlar, q), valid-eraseq(q), valid-global-sqn(apebs, sqnum), valid-peb(mkpeb(aehdr0, avhdr0, buf1, m2, false)), valid-vtbl(apebs, vols, wlar, vtblpnum4), valid-wl(apebs, wlar), ⌊err0⌋ , bflipset = ∅ → m1 + WL_THRESHOLD ≤ m0 ⊦ ⟪apebs0 := apebs; if err0 = ESUCCESS then {ubi_erase_worker_helper#(vtblpnum2; wlar, apebs; err0); if err0 = ESUCCESS then q := q.butlast}⟫ ( # apebs = # wlar ∧ unique-sqns(apebs) ∧ valid-global-sqn(apebs, sqnum) ∧ valid-wl(apebs, wlar) ∧ valid-eraseq(q) ∧ valid-eraseq(wlar, q) ∧ valid-eraseq(apebs, q) ∧ bflipset-cons(bflipset0, wlar) ∧ valid-ebatbl(apebs, wlar, vols, vtblpnum4) ∧ valid-vtbl(apebs, vols, wlar, vtblpnum4) ∧ ubi-io-inv(apebs) ∧ ( id(apebs, apebs0, mapped-pebs(vols)) ∧ q.lebrefs ⊆ q0.lebrefs ++ (VTBL_VOLID × VTBL_LNUM) ∨ (∃ v, m, n. v ∈ vols ∧ m < # vols[v] ∧ vols[v][m] ≠ unmapped ∧ vols = vols[v, vols[v][m, ⌜n⌝ ]] ∧ id(apebs, apebs0, mapped-pebs(vols) -- vols[v][m].pnum) ∧ apebs[n].data = apebs0[vols[v][m].pnum].data ∧ apebs[n].fill ≤ apebs0[vols[v][m].pnum].fill ∧ q.lebrefs ⊆ q0.lebrefs ++ (v × m)))), vtblpnum4 = vtblpnum1, vtblpnum2 ∈ q, vtblpnum4 ∈ q, VTBL_VOLID ∈ vols