| # lpt4 = # avol1, lpt[n].ref-size = 0, isbuf ↔ boolvar, avol0 = avol1, bleb = nobuffer, log = log1, log0 = nx, lpt = replay-lpt(lpt4, log0, n), lpt = lpt3, lpt0 = lpt1, lpt2 = lpt4, m = m1, m0 = LEB_SIZE, n = n0, n1 = 0, n < # lpt[n, lpt[n].flags:= LP_FREE], n < # lpt, avol-replay-lpt-unchanged(avol1, avol, lpt4, log0), awbuf-inv(avol1, nobuffer), awbuf-inv(avol, bleb), synced(avol1), synced(avol), n ≤ # lpt4 ⊦ ⟪awbuf_unmap#(n, adr, m, log, lpt0, ns, bleb, isbuf; avol); n1 := n + 1⟫ ( ( n1 ≤ # lpt4 ∧ awbuf-inv(avol, bleb) ∧ bleb = nobuffer ∧ lpt[n, lpt[n].flags:= LP_FREE][n, lpt[n, lpt[n].flags:= LP_FREE][n].size:= 0] = replay-lpt(lpt4, log0, n1) ∧ # lpt4 = # avol1 ∧ avol-replay-lpt-unchanged(avol1, avol, lpt4, log0) ∧ synced(avol)) ∧ # lpt[n, lpt[n].flags:= LP_FREE][n, lpt[n, lpt[n].flags:= LP_FREE][n].size:= 0] - n1 < # lpt3 - n0), lpt[n].flags = LP_FREE, lpt[n].flags = LP_INDEX_NODES, n ∈ log0 |
# lpt4 = # avol1, # avol = # avol1, lpt4[n0].ref-size = 0, lpt4[n0].flags ≠ LP_INDEX_NODES, lpt4[n0].flags ≠ LP_FREE, n0 < # avol1, avol-replay-lpt-unchanged(avol1, avol, lpt4, log0), awbuf-inv(avol, nobuffer), awbuf-inv(avol1, nobuffer), synced(avol), synced(avol1), ¬ n0 ∈ log0 ⊦ ⟪awbuf_unmap#(n0, adr, m, log, lpt0, ns, nobuffer, isbuf; avol); n1 := n0 + 1⟫ ( n1 ≤ # avol1 ∧ awbuf-inv(avol, nobuffer) ∧ replay-lpt(lpt4, log0, n0)[n0, mklp(lpt4[n0].ref-size, 0, LP_FREE, lpt4[n0].gcheapidx)] = replay-lpt(lpt4, log0, n1) ∧ avol-replay-lpt-unchanged(avol1, avol, lpt4, log0) ∧ # avol1 < (# avol1 - n0) + n1)
Used simplifier rules: elim-lp-upd-size: ⊦ lp.size:= n = mklp(lp.ref-size, n, lp.flags, lp.gcheapidx);%n0 ≤ n ⊦ n - n0 < m ↔ n < m + n0; (s)%fle: ⊦ m < n ∧ n ≤ n0 → m < n0; (forward) from specification nat% ⊦ awbuf-inv(avol, nobuffer) → (synced(avol) ↔ true); (ss)%m < # lpt ⊦ lpt[m, lp][m, lp0] = lpt[m, lp0]; (s)% ⊦ (lp.flags:= lpf).gcheapidx = lp.gcheapidx; (s)% ⊦ (lp.flags:= lpf).flags = lpf; (s)% ⊦ (lp.flags:= lpf).ref-size = lp.ref-size; (s)%m < # lpt ⊦ lpt[m, lp][m] = lp; (s)% ⊦ m < n → (n ≤ m ↔ false); (s)% ⊦ m +1 = m + 1; (s)% ⊦ m < n → ¬ n < m; (s)%transitivity: ⊦ n < n0 ∧ n0 < n1 → n < n1; (forward) from specification oelem[nat-set]%lf-02: ⊦ m < n ∧ m = n0 → n0 < n; (forward) from specification nat-basic%lf: ⊦ m < n ∧ n < n0 → m +1 < n0; (forward) from specification nat-basic% ⊦ m ≤ n ↔ ¬ n < m; (ss)%n ≤ m, m < # lpt ⊦ replay-lpt(lpt, nx, n)[m] = lpt[m]; (s)% ⊦ m ≤ n → (n < m ↔ false); (s)% ⊦ m < n → n ≠ 0; (s)%avol-replay-lpt-unchanged-size: ⊦ avol-replay-lpt-unchanged(avol0, avol1, lpt, nx) → # avol1 = # avol0; (forward) from specification persistence-base%lf-01: ⊦ m < n ∧ n = n0 → m < n0; (forward) from specification nat-basic%f: ⊦ m < n → n ≠ 0; (forward) from specification nat-basic%fle-01: ⊦ m ≤ n ∧ n < n0 → m < n0; (forward) from specification nat% ⊦ m < n ↔ ¬ n ≤ m; (ss)% ⊦ m < n → m ≤ n; (s)% ⊦ # lpt[n, lp] = # lpt; (s)%n ≤ # lpt ⊦ # replay-lpt(lpt, nx, n) = # lpt; (s)% ⊦ m ≤ m; (s)