Skip to content

Commit 9420f92

Browse files
author
Travis Hance
committed
prove pivotsAreCorrectAfterSplit
1 parent 11eb0ca commit 9420f92

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

immutable-btree/BtreeInv.dfy

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,20 +517,71 @@ abstract module BtreeInv {
517517
}
518518
}
519519

520+
lemma pivotsAreCorrectAfterSplit(tree: Node, newtree: Node, l: Key, u: Key, childrenToLeft: int, pos: int)
521+
requires WFTree(tree);
522+
requires SplitTransform(tree, newtree, l, u, childrenToLeft);
523+
requires pos == Keyspace.LargestLte(tree.pivots, l) + 1;
524+
requires 0 <= pos < |tree.children|;
525+
requires tree.children[pos].lb == l;
526+
requires tree.children[pos].ub == u;
527+
ensures Keyspace.IsStrictlySorted(newtree.pivots);
528+
{
529+
var child := tree.children[pos];
530+
assert |newtree.children| == |tree.children| + 1;
531+
var left_child := newtree.children[pos];
532+
var right_child := newtree.children[pos+1];
533+
assert WFTree(child);
534+
if (pos < |tree.pivots|) {
535+
if (child.Leaf?) {
536+
assert newtree.pivots[pos]
537+
== right_child.keys[0]
538+
== child.keys[childrenToLeft];
539+
assert Keyspace.lt(child.keys[childrenToLeft], child.ub);
540+
} else {
541+
assert newtree.pivots[pos] == child.pivots[childrenToLeft-1];
542+
assert Keyspace.lt(child.pivots[childrenToLeft-1], child.ub);
543+
}
544+
assert child.ub == tree.pivots[pos];
545+
assert Keyspace.lt(newtree.pivots[pos], tree.pivots[pos]);
546+
}
547+
if (pos > 0) {
548+
if (child.Leaf?) {
549+
assert Keyspace.lte(child.lb, child.keys[0]);
550+
Keyspace.reveal_IsStrictlySorted();
551+
assert Keyspace.lt(child.keys[0], child.keys[childrenToLeft]);
552+
assert Keyspace.lt(child.lb, child.keys[childrenToLeft]);
553+
} else {
554+
assert Keyspace.lt(child.lb, child.pivots[childrenToLeft-1]);
555+
}
556+
assert child.lb == tree.pivots[pos-1];
557+
assert Keyspace.lt(tree.pivots[pos-1], newtree.pivots[pos]);
558+
}
559+
Keyspace.strictlySortedInsert2(tree.pivots, newtree.pivots[pos], pos);
560+
}
561+
520562
lemma SplitIsCorrect<Value>(tree: Node, newtree: Node, l: Key, u: Key, childrenToLeft: int)
521563
requires WFTree(tree);
522564
requires CantEquivocate(tree);
523565
requires SplitTransform(tree, newtree, l, u, childrenToLeft);
566+
ensures WFTree(newtree);
524567
ensures PreservesLookups(tree, newtree);
525568
ensures PreservesLookups(newtree, tree);
526-
ensures WFTree(newtree)
527-
ensures CantEquivocate(newtree)
528-
decreases tree
569+
ensures CantEquivocate(newtree);
570+
decreases tree;
529571
{
530572
var pos := Keyspace.LargestLte(tree.pivots, l) + 1;
531573
var child := tree.children[pos];
532574
if (child.lb == l && child.ub == u) {
575+
var left_child := newtree.children[pos];
576+
var right_child := newtree.children[pos+1];
577+
pivotsAreCorrectAfterSplit(tree, newtree, l, u, childrenToLeft, pos);
578+
assert WFTree(newtree);
579+
assume false;
580+
assert PreservesLookups(tree, newtree);
581+
assert PreservesLookups(newtree, tree);
582+
assert CantEquivocate(newtree);
533583
} else {
584+
assume false;
534585
// Before we can call Define recursively, we must prove that the child CantEquivocate.
535586
forall key', valueA, valueB, lookup, lookup'
536587
|

immutable-btree/BtreeSpec.dfy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ abstract module BtreeSpec {
2727
&& CSMap.Keyspace.IsStrictlySorted(tree.keys)
2828
&& |tree.keys| == |tree.values|
2929
&& (forall i :: 0 <= i < |tree.keys| ==>
30-
&& CSMap.Keyspace.lte(tree.lb, tree.keys[i])
31-
&& CSMap.Keyspace.lt(tree.keys[i], tree.ub)
32-
)
30+
&& CSMap.Keyspace.lte(tree.lb, tree.keys[i]))
31+
&& (forall i :: 0 <= i < |tree.keys| ==>
32+
&& CSMap.Keyspace.lt(tree.keys[i], tree.ub))
3333
else
3434
&& |tree.pivots| > 0
3535
&& CSMap.Keyspace.IsStrictlySorted(tree.pivots)
@@ -193,7 +193,7 @@ abstract module BtreeSpec {
193193
{
194194
&& node.lb == left_node.lb
195195
&& left_node.ub == pivot
196-
&& pivot == right_node.ub
196+
&& pivot == right_node.lb
197197
&& right_node.ub == node.ub
198198
&& (if node.Leaf? then (
199199
&& left_node.Leaf?

lib/total_order.dfy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ abstract module Total_Order {
243243
{
244244
}
245245
}
246+
247+
lemma strictlySortedInsert2(l: seq<Element>, k: Element, pos: int)
248+
requires 0 <= pos <= |l|;
249+
requires 0 < pos ==> lt(l[pos-1], k);
250+
requires pos < |l| ==> lt(k, l[pos]);
251+
ensures IsStrictlySorted(Seq.insert(l, k, pos));
252+
{
253+
Seq.reveal_insert();
254+
reveal_IsStrictlySorted();
255+
}
246256
}
247257

248258
abstract module Bounded_Total_Order refines Total_Order {

0 commit comments

Comments
 (0)