| # lpt0 = # lpt, # avol0 = # lpt, n = # lpt0, dom istore ∩ elems nx = ∅, dom gstore0 ∪ elems nx = dom gstore ∪ ginval, ginval < # lpt, abs-gstore(avol0, lpt, gstore, ginval), abs-istore(avol0, lpt, istore), awbuf-inv(avol0, bleb), bufs-log-only(bleb, nx, lpt), flash-lpt-cons(lpt0, istore0, gstore0), lpt-ram-flash(lpt, lpt0, nx), synced(avol0), avol1 ↓ avol0, istore0 ⊑ istore ⊦ abs-gstore(avol1, replay-lpt(replay-log(lpt0, nx), nx, n), crash(gstore, gstore0, ginval, nx), ginval) |
# avol0 = # lpt, # lpt0 = # lpt, dom istore ∩ elems nx = ∅, dom gstore0 ∪ elems nx = dom gstore ∪ ginval, ginval < # lpt, awbuf-inv(avol0, bleb), flash-lpt-cons(lpt0, istore0, gstore0), synced(avol0), avol1 ↓ avol0, istore0 ⊑ istore, ∀ n. n < # lpt ∧ lpt0[n].flags = LP_GROUP_NODES ∧ lpt[n].flags = LP_GROUP_NODES ∧ ¬ n ∈ nx → lpt[n].size = lpt0[n].size, ∀ n. (n < # lpt ∧ lpt[n].flags = LP_INDEX_NODES ↔ n ∈ istore) ∧ (n ∈ istore → abs-leb(avol0[n], istore[n], lpt[n]) ∧ lpt[n].ref-size = istore[n].ref-size), ∀ n. (n < # lpt ∧ lpt[n].flags = LP_GROUP_NODES ↔ n ∈ gstore) ∧ (n ∈ gstore ∧ ¬ n ∈ ginval → abs-leb(avol0[n], gstore[n], lpt[n])) ∧ (n ∈ gstore → lpt[n].ref-size = gstore[n].ref-size), bleb = nobuffer ∨ bleb.leb < # lpt ∧ (nx ≠ [] ∧ bleb.leb = nx.last ∧ lpt[bleb.leb].flags = LP_GROUP_NODES ∨ lpt[bleb.leb].flags = LP_INDEX_NODES) ⊦ ( n < # lpt ∧ replay-lpt(lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx)), nx, # lpt)[n].flags = LP_GROUP_NODES ↔ n ∈ crash(gstore, gstore0, ginval, nx)) ∧ ( n ∈ gstore ∧ ¬ n ∈ ginval → abs-leb (avol1[n], crash(gstore, gstore0, ginval, nx)[n], replay-lpt(lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx)), nx, # lpt)[n])) ∧ ( n ∈ crash(gstore, gstore0, ginval, nx) → replay-lpt(lpt0.mapIndices(elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx)), nx, # lpt)[n].ref-size = (n ∈ nx ∨ ¬ n ∈ ginval ⊃ groupblock(gstore[n].gndlist, gstore[n].ladrlist, (n ∈ gstore0 ⊃ gstore0[n].ref-size;0));gstore0[n]).ref-size)
Used simplifier rules: lpt-ram-flash: ⊦ lpt-ram-flash(lpt1, lpt0, nx) ↔ # lpt0 = # lpt1 ∧ (∀ n. n < # lpt1 ∧ lpt0[n].flags = LP_GROUP_NODES ∧ lpt1[n].flags = LP_GROUP_NODES ∧ ¬ n ∈ nx → lpt1[n].size = lpt0[n].size);%bufs-log-only: ⊦ bufs-log-only(bleb, nx, lpt) ↔ bleb = nobuffer ∨ bleb.leb < # lpt ∧ ( nx ≠ [] ∧ bleb.leb = nx.last ∧ lpt[bleb.leb].flags = LP_GROUP_NODES ∨ lpt[bleb.leb].flags = LP_INDEX_NODES);%abs-istore-def: ⊦ abs-istore(avol, lpt, istore) ↔ (∀ n. (n < # lpt ∧ lpt[n].flags = LP_INDEX_NODES ↔ n ∈ istore) ∧ ( n ∈ istore → abs-leb(avol[n], istore[n], lpt[n]) ∧ lpt[n].ref-size = istore[n].ref-size));%abs-gstore-def: ⊦ abs-gstore(avol, lpt, gstore, ginval) ↔ (∀ n. (n < # lpt ∧ lpt[n].flags = LP_GROUP_NODES ↔ n ∈ gstore) ∧ ( n ∈ gstore ∧ ¬ n ∈ ginval → abs-leb(avol[n], gstore[n], lpt[n])) ∧ (n ∈ gstore → lpt[n].ref-size = gstore[n].ref-size));%replay-log: ⊦ replay-log(lpt, nx) = lpt .mapIndices (elems nx, λ lp. mklp(lp.ref-size, LEB_SIZE, LP_GROUP_NODES, lp.gcheapidx) );%replay-lpt-size: n ≤ # lpt ⊦ # replay-lpt(lpt, nx, n) = # lpt;%⊦ n ∈ crash(gstore, gstore0, ginval, nx) → crash(gstore, gstore0, ginval, nx)[n] = (n ∈ nx ∨ ¬ n ∈ ginval ⊃ groupblock (gstore[n].gndlist, gstore[n].ladrlist, (n ∈ gstore0 ⊃ gstore0[n].ref-size;0)) ;gstore0[n] ); (s)% ⊦ n ∈ crash(gstore, gstore0, ginval, nx) ↔ n ∈ gstore ∨ n ∈ ginval; (ws)% ⊦ ¬ n < n; (s)% ⊦ m < n → n ≠ 0; (s)%lf-01: ⊦ m < n ∧ n = n0 → m < n0; (forward) from specification nat-basic%lf-02: ⊦ m < n ∧ m = n0 → n0 < n; (forward) from specification nat-basic%f: ⊦ m < n → n ≠ 0; (forward) from specification nat-basic% ⊦ m ≤ n ↔ ¬ n < m; (ss)% ⊦ # lpt.mapIndices(ns, lptfun) = # lpt; (s)