| # avol0 = # lpt, # lpt0 = # lpt, n < # lpt ∧ lpf0 = LP_INDEX_NODES ↔ n ∈ istore, istore0[n] = indexblock(indx1, lax2, m8), istore[n] = indexblock(indx0, lax0, m3), remove-refsize0(crash(istore, istore0))[n] = indexblock(indx, lax, m), replay-lpt(lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx)), nx, # lpt)[n] = mklp(m0, m1, lpf, m2), lpt[n] = mklp(m4, m5, lpf0, m6), gstore0[n] = groupblock(gndx, lax1, m7), lpt0[n] = mklp(m9, m10, lpf1, m11), dom istore ∩ elems nx = ∅, synced(avol0), avol1 ↓ avol0, istore0 ⊑ istore, n < # lpt → (n ∈ istore0 ↔ lpf1 = LP_INDEX_NODES ∧ m9 ≠ 0) ∧ (n ∈ gstore0 ↔ lpf1 = LP_GROUP_NODES ∧ m9 ≠ 0) ∧ (n ∈ istore0 → m9 = m8) ∧ (n ∈ gstore0 → m9 = m7) ∧ (lpf1 = LP_FREE → m9 = 0), n ∈ istore → abs-leb(avol0[n], indexblock(indx0, lax0, m3), mklp(m3, m5, lpf0, m6)) ∧ m4 = m3, ∀ n. n < # lpt ∧ lpt0[n].flags = LP_FREE → lpt0[n].ref-size = 0 ⊦ (n < # lpt ∧ lpf = LP_INDEX_NODES ↔ n ∈ remove-refsize0(crash(istore, istore0))) ∧ (n ∈ remove-refsize0(crash(istore, istore0)) → abs-leb(avol1[n], indexblock(indx, lax, m), mklp(m, m1, lpf, m2)) ∧ m0 = m) |
m < n, n ≤ # lpt ⊦ replay-lpt(lpt, nx, n)[m] = (lpt[m].flags = LP_FREE ∨ m ∈ nx ⊃ lpt[m] ;(lpt[m].flags = LP_INDEX_NODES ∧ lpt[m].ref-size ≠ 0 ⊃ lpt[m].size:= LEB_SIZE ;(lpt[m].ref-size = 0 ⊃ mklp(0, 0, LP_FREE, lpt[m].gcheapidx);lpt[m]) ) )
# lpt0 = # lpt, # avol0 = # lpt, (lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n].flags = LP_FREE ∨ n ∈ nx ⊃ lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n] ;( lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n].flags = LP_INDEX_NODES ∧ lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n].ref-size ≠ 0 ⊃ lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n].size:= LEB_SIZE ;(lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n].ref-size = 0 ⊃ mklp(0, 0, LP_FREE, lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n].gcheapidx) ;lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx))[n] ) ) ) = mklp(m0, m1, lpf, m2), n < # lpt ∧ lpf0 = LP_INDEX_NODES ↔ n ∈ istore, lpt0[n] = mklp(m9, m10, lpf1, m11), gstore0[n] = groupblock(gndx, lax1, m7), lpt[n] = mklp(m4, m5, lpf0, m6), remove-refsize0(crash(istore, istore0))[n] = indexblock(indx, lax, m), istore[n] = indexblock(indx0, lax0, m3), istore0[n] = indexblock(indx1, lax2, m8), dom istore ∩ elems nx = ∅, n < # lpt, synced(avol0), avol1 ↓ avol0, # lpt ≤ # lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx)), istore0 ⊑ istore, n ∈ istore → abs-leb(avol0[n], indexblock(indx0, lax0, m3), mklp(m3, m5, lpf0, m6)) ∧ m4 = m3, n < # lpt → (n ∈ istore0 ↔ lpf1 = LP_INDEX_NODES ∧ m9 ≠ 0) ∧ (n ∈ gstore0 ↔ lpf1 = LP_GROUP_NODES ∧ m9 ≠ 0) ∧ (n ∈ istore0 → m9 = m8) ∧ (n ∈ gstore0 → m9 = m7) ∧ (lpf1 = LP_FREE → m9 = 0), ∀ n. n < # lpt ∧ lpt0[n].flags = LP_FREE → lpt0[n].ref-size = 0 ⊦ (n < # lpt ∧ lpf = LP_INDEX_NODES ↔ n ∈ remove-refsize0(crash(istore, istore0))) ∧ (n ∈ remove-refsize0(crash(istore, istore0)) → abs-leb(avol1[n], indexblock(indx, lax, m), mklp(m, m1, lpf, m2)) ∧ m0 = m)
Used simplifier rules: replay-lpt-at-above: n ≤ m, m < # lpt ⊦ replay-lpt(lpt, nx, n)[m] = lpt[m];% ⊦ # lpt.mapIndices(ns, lptfun) = # lpt; (s)% ⊦ m ≤ m; (s)% ⊦ ¬ n ∈ istore → istore[n] = (∅)[n]; (s)% ⊦ m < n ↔ ¬ n ≤ m; (ss)% ⊦ m ≤ n → (n < m ↔ false); (s)% ⊦ n ∈ remove-refsize0(istore) ↔ n ∈ istore ∧ istore[n].ref-size ≠ 0; (ws)% ⊦ n ∈ crash(istore, istore0) ↔ n ∈ istore0; (s)%prefix-fwd-in: ⊦ istore ⊑ istore0 ∧ n ∈ istore → n ∈ istore0; (forward) from specification ablock-store-inv[index-store] Used terms: n, # lpt, nx, lpt0 .mapIndices (elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx) )