Dafny twostate lemmas and iteration - heap-memory

Trying to verify the following code. I got stuck trying to ensure that all entries to the stack are members of the the tree root repr set. Then it became clear that it wasn't clear that the root remained valid after inverting some elements within it. It's unclear to me if my twostate lemma correctly demonstrates that a root node remains valid after a change to an element within it.
/**
* https://leetcode.com/problems/invert-binary-tree/description/
*/
function invertTree(root: TreeNode | null): TreeNode | null {
if(root == null) return null;
let queue = [root];
while(queue.length != 0) {
let current = queue.pop();
if(current != null) {
queue.push(current.left);
queue.push(current.right);
//The following in js syntax sugar to swap to variables without a temp variable
[current.left, current.right] = [current.right, current.left];
}
}
return root;
};
class TreeNode {
var val: int;
var left: TreeNode?;
var right: TreeNode?;
ghost var repr: set<TreeNode>;
constructor(val: int, left: TreeNode?, right: TreeNode?)
requires left != null ==> left.Valid()
requires right != null ==> right.Valid()
requires left != null && right != null ==> left.repr !! right.repr
ensures this.val == val
ensures this.left == left
ensures this.right == right
ensures left != null ==> this !in left.repr
ensures right != null ==> this !in right.repr
ensures Valid()
{
this.val := val;
this.left := left;
this.right := right;
var leftRepr := if left != null then {left}+left.repr else {};
var rightRepr := if right != null then {right}+right.repr else {};
this.repr := {this} + leftRepr + rightRepr;
}
predicate Valid()
reads this, repr
decreases repr
{
this in repr &&
(this.left != null ==>
(this.left in repr
&& this !in this.left.repr
&& this.left.repr < repr
&& this.left.Valid()
))
&& (this.right != null ==>
(this.right in repr
&& this !in this.right.repr
&& this.right.repr < repr
&& this.right.Valid())) &&
(this.left != null && this.right != null ==> this.left.repr !! this.right.repr && this.repr == {this} + this.left.repr + this.right.repr)
&& (this.left != null && this.right == null ==> this.repr == {this} + this.left.repr)
&& (this.right != null && this.left == null ==> this.repr == {this} + this.right.repr)
&& (this.right == null && this.left == null ==> this.repr == {this})
}
}
method {:verify } invertBinaryTreeIterative(root: TreeNode?) returns (newRoot: TreeNode?)
modifies if root != null then root.repr else {}
requires root != null ==> root.Valid()
ensures root == null ==> newRoot == null
// ensures root != null ==> newRoot != null && newRoot.repr == old(root.repr) && newRoot.Valid()
// ensures root != null ==> newRoot == root && newRoot.right == old(root.left) && root.left == old(root.right)
// ensures root != null ==> forall node :: node in newRoot.repr ==> node.right == old(node.left) && node.left == old(node.right)
{
if root == null {
return null;
}
assert root != null;
assert root.Valid();
var stack: seq<TreeNode> := [root];
ghost var visited: set<TreeNode> := {};
ghost var unvisited: set<TreeNode> := root.repr;
assert TreeUnion(stack) == unvisited;
assert TreeUnion(stack) == root.repr - visited;
assert root in root.repr;
assert root.repr <= root.repr;
assert root in stack;
while |stack| > 0
modifies root.repr
invariant root.Valid()
invariant forall x :: x in stack ==> x in root.repr;
invariant forall x :: x in stack ==> x.Valid() && x.repr <= root.repr;
invariant visited + unvisited == root.repr;
// invariant visited == visited + {stack[0]}
invariant TreeUnion(stack) == root.repr - visited
// invariant forall node :: node in visited ==> node.right == old(node.left) && node.left == old(node.right) && node.Valid()
decreases unvisited
{
var current: TreeNode := stack[0];
assert current in stack;
ChildNodesAreValid(root, current);
if current.left != null {
assert current.left.repr <= root.repr;
assert current.left in root.repr;
ChildNodesAreValid(root, current.left);
stack := stack + [current.left];
}
if current.right != null {
assert current.right.repr <= root.repr;
assert current.right in root.repr;
ChildNodesAreValid(root, current.right);
stack := stack + [current.right];
}
var temp := current.left;
current.left := current.right;
current.right := temp;
assert temp == old(current.left);
assert current.left == old(current.right) && current.right == old(current.left);
ValidSwappingStillValid(root, current);
visited := visited + {current};
unvisited := unvisited - {current};
stack := stack[1..];
}
return root;
}
lemma ChildNodesAreInRoot(root: TreeNode, child: TreeNode)
requires root.Valid()
requires (root.left != null && child == root.left) || (root.right != null && root.right == child)
ensures child in root.repr;
{
}
lemma ChildChildrenNodesAreInRoot(root: TreeNode, child: TreeNode)
requires root.Valid()
requires (root.left != null && (child == root.left.left || child == root.left.right)) || (root.right != null && (root.right.left == child || root.right.right == child))
ensures child in root.repr;
{
}
lemma ChildNodesAreValid(root: TreeNode, child: TreeNode)
requires root.Valid()
requires child in root.repr;
decreases root.repr
ensures child.repr <= root.repr;
ensures child.Valid()
{
if child == root {
}else if child == root.left {
}else if child == root.right {
}else if root.left != null && root.right != null {
assert root.repr == {root} + root.left.repr + root.right.repr;
if child in root.left.repr {
ChildNodesAreValid(root.left, child);
}else if child in root.right.repr {
ChildNodesAreValid(root.right, child);
}else{
assert false;
}
}else if root.right != null {
}else if root.left != null {
}else{
assert false;
}
}
twostate lemma ValidSwappingStillValid(root: TreeNode, child: TreeNode)
requires root.Valid()
requires child in root.repr;
requires child.left == old(child.right) && child.right == old(child.left)
ensures root.Valid()
{
ChildNodesAreValid(root,child);
assert child.Valid();
}
function TreeUnion(nodes: seq<TreeNode>): set<TreeNode>
reads set x | 0 <= x < |nodes| :: nodes[x]
{
if |nodes| > 0 then nodes[0].repr + TreeUnion(nodes[1..]) else {}
}
Version 2
function method PreorderTraversal(root: TreeNode): seq<TreeNode>
reads root.repr
requires root.Valid()
ensures forall x :: x in PreorderTraversal(root) ==> x in root.repr && x.Valid()
ensures forall x :: x in root.repr ==> x in PreorderTraversal(root)
ensures forall k :: 0 <= k < |PreorderTraversal(root)| ==> PreorderTraversal(root)[k] in root.repr
{
if root.left != null && root.right != null then [root]+PreorderTraversal(root.left)+PreorderTraversal(root.right) else if root.left != null then [root]+PreorderTraversal(root.left) else if root.right != null then [root]+PreorderTraversal(root.right) else [root]
}
method {:verify true} invertBinaryTreeIterative2(root: TreeNode?) returns (newRoot: TreeNode?)
modifies if root != null then root.repr else {}
requires root != null ==> root.Valid()
ensures root == null ==> newRoot == null
// ensures root != null ==> newRoot != null && newRoot.repr == old(root.repr) && newRoot.Valid()
ensures root != null ==> newRoot == root && newRoot.right == old(root.left) && root.left == old(root.right)
ensures root != null ==> forall node :: node in newRoot.repr ==> node.right == old(node.left) && node.left == old(node.right)
{
if root == null {
return null;
}
var nodes := PreorderTraversal(root);
assert forall k :: 0 <= k < |nodes| ==> nodes[k] in root.repr;
var i := 0;
while i < |nodes|
modifies root.repr
invariant 0 <= i <= |nodes|
invariant root.repr == old(root.repr)
//invariant root.Valid()
invariant forall k :: 0<= k < i ==> nodes[k].right == old(nodes[k].left) && nodes[k].left == old(nodes[k].right)
{
assert nodes[i] in nodes;
assert nodes[i] in root.repr;
var temp := nodes[i].left;
nodes[i].left := nodes[i].right;
nodes[i].right := temp;
ValidSwappingStillValid(root, nodes[i]);
i := i + 1;
}
return root;
}
Now in version two it seems to be nearly working but I'm getting one error for the last method invariant about the old(node.left) that receiver might not be allocated in the state in which its fields are accessed. What does this mean?

Related

EXC BAD ACCESS TREAD in c

it gives me EXC_BAD_ACCESS (code=1, address=0xc) at the strcmp in the while (strcmp(parola, temp->next->parola) picture of the xcode debugging session
if (temp->next != NULL){
if (strcmp(temp->next->parola, "\0") != 0 && strcmp(parola, "\0") != 0){
while (strcmp(parola, temp->next->parola) != 0){
if(temp->next != NULL){
if (strcmp(temp->next->parola, "\0") != 0 && strcmp(parola, "\0") != 0){
temp = temp->next;
} else {break;}
} else {break;}
}
}
}
if (temp->next != NULL){
if (strcmp(temp->next->parola, "\0") != 0 && strcmp(parola, "\0") != 0){
while (strcmp(parola, temp->next->parola) != 0){
if (strcmp(temp->next->parola, "\0") != 0 && strcmp(parola, "\0") != 0){
temp = temp->next;
if(temp->next != NULL){
} else {break;}
} else {break;}
}
}
}

NULL assignment to a structure pointer is not working through function. What to do?

I am trying to implement BST deletion. According to algorithm, we can delete a leaf directly. Now I'm assigning NULL to leaf directly and still this node remains as it is.
In the test case I gave tried to delete leaf and it is not working.
Please help!
struct node * delet(long data, struct node* root)
{
int i=1;
struct node *temp = root,*t;
while(temp != 0)
{
if(data < temp->data)
{
i=2*i;
temp = temp->l;
}
else if(data > temp->data)
{
i = (2*i)+1;
temp = temp->r ;
}
else
{
printf("%d\n",i);
break;
}
}
if(temp->l == 0 && temp->r == 0)
{
temp = 0;
return root;
}
else if(temp->l == 0)
{
temp->data = temp->l->data;
temp->l = 0;
}
else if(temp->r == 0)
{
temp->data = temp->r->data;
temp->r = 0;
}
else
{
t = temp;
t = t->r;
while(t->l != 0)
{
t = t->l;
}
temp->data = t->data;
if(t->r != 0)
{
t->data = t->r->data;
t->r = 0;
return root;
}
else
{
t = 0;
return root;
}
}
}
temp = 0; doesn't delete the leaf from the tree, just nulls a local variable.
You want to null some node's l or r in order to remove a node from the tree.
Try keeping the parent as well and once temp points to the leaf, nullify temp's parent r or l.
Same goes for t = 0; later on.
Note David's comment about first releasing this memory..
For example (assuming not deleting the root):
...
if(data < temp->data)
{
i=2*i;
parent = temp;
temp = temp->l;
}
else if(data > temp->data)
{
i = (2*i)+1;
parent = temp;
temp = temp->r ;
}
else
{
printf("%d\n",i);
break;
}
...
if(temp->l == 0 && temp->r == 0)
{
if (parent->l == temp)
parent->l = 0;
else
parent->r = 0;
// Free temp if needed
return root;
}
...
Also note that you have:
else if(temp->l == 0)
{
temp->data = temp->l->data;
Which is a dereference of a null pointer (temp->l is NULL), and the same thing for temp->r == 0 case.
Then you have
temp->l = 0;
but you're already in a temp->l == 0 case, so I don't think this is what you meant.

Anybody know a more efficient way to do this?

I know this is simple. But that's what is bothering me. Is there a better way to do this?
The arrays are generally unimportant just the function of what this code's goal is what I'm trying to condense.
for(int p=0; p<28;p++){
if(p == 0){
Pile1[0] = deck[p];
}
if(p == 1 || p == 7){
if(p == 1){
Pile2[0] = deck[p];
}
if(p == 7){
Pile2[1] = deck[p];
}
}
if(p == 2 || p == 8 || p == 13){
if(p == 2){
Pile3[0] = deck[p];
}
if(p == 8){
Pile3[1] = deck[p];
}
if(p == 13){
Pile3[2] = deck[p];
}
}
if(p == 3 || p == 9 || p == 14 || p == 18){
if(p == 3){
Pile4[0] = deck[p];
}
if(p == 9){
Pile4[1] = deck[p];
}
if(p == 14){
Pile4[2] = deck[p];
}
if(p == 18){
Pile4[3] = deck[p];
}
}
if(p == 4 || p == 10 || p == 15 || p == 19 || p == 22){
if(p == 4){
Pile5[0] = deck[p];
}
if(p == 10){
Pile5[1] = deck[p];
}
if(p == 15){
Pile5[2] = deck[p];
}
if(p == 19){
Pile5[3] = deck[p];
}
if(p == 22){
Pile5[4] = deck[p];
}
}
if(p == 5 || p == 11 || p == 16 || p == 20 || p == 23 || p == 25){
if(p == 5){
Pile6[0] = deck[p];
}
if(p == 11){
Pile6[1] = deck[p];
}
if(p == 16){
Pile6[2] = deck[p];
}
if(p == 20){
Pile6[3] = deck[p];
}
if(p == 23){
Pile6[4] = deck[p];
}
if(p == 25){
Pile6[5] = deck[p];
}
}
if(p == 6 || p == 12 || p == 17 || p == 21 || p == 24 || p == 26 || p == 27){
if(p == 6){
Pile7[0] = deck[p];
}
if(p == 12){
Pile7[1] = deck[p];
}
if(p == 17){
Pile7[2] = deck[p];
}
if(p == 21){
Pile7[3] = deck[p];
}
if(p == 24){
Pile7[4] = deck[p];
}
if(p == 26){
Pile7[5] = deck[p];
}
if(p == 27){
Pile7[6] = deck[p];
}
}
}
For of all, you can get rid of the loop. The following code is equivalent.
Pile1[0] = deck[0];
Pile2[0] = deck[1];
Pile2[1] = deck[7];
Pile3[0] = deck[2];
Pile3[1] = deck[8];
Pile3[2] = deck[13];
Pile4[0] = deck[3];
Pile4[1] = deck[9];
Pile4[2] = deck[14];
Pile4[3] = deck[18];
Pile5[0] = deck[4];
Pile5[1] = deck[10];
Pile5[2] = deck[15];
Pile5[3] = deck[19];
Pile5[4] = deck[22];
Pile6[0] = deck[5];
Pile6[1] = deck[11];
Pile6[2] = deck[16];
Pile6[3] = deck[20];
Pile6[4] = deck[23];
Pile6[5] = deck[25];
Pile7[0] = deck[6];
Pile7[1] = deck[12];
Pile7[2] = deck[17];
Pile7[3] = deck[21];
Pile7[4] = deck[24];
Pile7[5] = deck[26];
Pile7[6] = deck[27];
Next, instead of using Pile1...Pile7, a 2D array would be better. So, just figure out the math and patterns.
int Pile[7][7];
for (int p=1; p<=6; p++) {
for (int i=0, j=p-1; i<p; i++, j+=(7-i)) {
Pile[p][i] = deck[j];
}
}
Generates the same result, where Pile[X] is used instead of PileX.

my binary search tree program stopped working (C)

For some reason the insertion part of the code is not working as intended. When I run the program it just gives an error "bst.exe has stopped working" and it happens in this function. The whole idea of this portion of the code is to ITERATIVELY insert a new node and update the root.
static NODE *insert_i(NODE *r, int x)
{
NODE *leaf;
if(r == NULL)
{
leaf = malloc(sizeof(NODE));
leaf->left = NULL;
leaf->right = NULL;
leaf->val = x;
count++;
return leaf;
}
while(r)
{
if(r->val == x)
return r;
if(x < r->val && r->left != NULL)
r = r->left;
else if(x > r->val && r->right != NULL)
r = r->right;
}
leaf = malloc(sizeof(NODE));
leaf->left = NULL;
leaf->right = NULL;
leaf->val = x;
count++;
if(x < r->val)
r->left = leaf;
else
r->right = leaf;
return r;
}
void bst_insert(BST_PTR t, int x)
{
t->root = insert_i(t->root, x);
}
At this point, outside the loop
if(x < r->val)
r->left = leaf;
else
r->right = leaf;
r is NULL. So, if you access r->val, it will crash.
Try to keep track of the parent as shown below.
NODE *leaf;
NODE * par
while(r)
{
if(r->val == x)
return r;
par = r;
if(x < r->val && r->left != NULL)
r = r->left;
else if(x > r->val && r->right != NULL)
r = r->right;
}
leaf = malloc(sizeof(NODE));
leaf->left = NULL;
leaf->right = NULL;
leaf->val = x;
count++;
if(x < par->val)
par->left = leaf;
else
par->right = leaf;
return r;

modified depth first traversal of tree

I got this question in an interview with amazon.
I was asked to perform a depth first traversal of a tree, without using recursion or stack. I could use a parent pointer for each node, as a part of the structure, but nothing else other than that.(for ex, a "visited" variable" or anything).
Please suggest me an algorithm.
The parent pointer is actually all you need. The trick is to consume the tree as you traverse it.
Ugly pseudocode:
cur = treeroot;
while (1) { // Get to bottom of tree
if (cur.hasLeft) {
cur = left;
} else if (cur.hasRight) {
cur = right;
} else {
break;
}
// cur is now the bottom node
while (1) {
doStuff(cur); // output cur, perform op on it, whatever
if (!cur.hasParent) { // Done with traversal
break;
}
prev = cur; // So we can tell which way we came up to the parent.
cur = cur.parent;
if (cur.hasLeft && cur.left == prev) { // Delete left child; it's done
cur.hasLeft = false;
} else if (cur.hasRight && cur.right == prev) { // Delete right child; it's done
// Note: "else" not desirable if a node should not be able to have the same child in two spots
cur.hasRight = false;
}
if (cur.hasLeft) { // Go all the way to the bottom of the left child
cur = cur.left;
while (1) {
if (cur.hasLeft) {
cur = cur.left;
} else if (cur.hasRight) {
cur = cur.right;
} else {
break;
}
}
} else if (cur.hasRight) { // Go all the way to the bottom of the right child
cur = cur.right;
while (1) {
if (cur.hasLeft) {
cur = cur.left;
} else if (cur.hasRight) {
cur = cur.right;
} else {
break;
}
}
}
}
For a 'hacky' solution you can use the fact that pointers are usually 4 byte aligned (i.e, last two bits are 0) and use those two bits as your visited flag.
Here is my proposition for a binary tree. The language is C#. It's a private method of a binarTree class that holds ints
private Node DFS(int value)
{
Node current = this.root;
if(current.data == value) return current;
while(true)
{
//go down-left as far as possible
while(current.leftChild != null)
{
current = current.leftChild;
if(current.data == value) return current;
}
//leftChild is null, but maybe I can go right from here
while(current.leftChild == null && current.rightChild != null)
{
current = current.rightChild;
if(current.data == value) return current;
}
if(current.leftChild == null && current.rightChild == null)
{
// Ok, I got to a leaf. Now I have to get back to the last "crossroads"
// I went down-left from, but there was also down-right option
while(current.parent != null &&
(current == current.parent.rightChild ||
current.parent.rightChild == null))
{
current = current.parent;
}
if(current.parent == null) return null;
// Ok If I'm here, that means I found the crossroads mentioned before
// I'll go down-right once and then I should try down-left again
current = current.parent.rightChild;
if(current.data == value) return current;
}
}
}
If it's not a binary tree, then things get more complicated of course, but the logic is similar. Go down to the leaf taking the first possible child at each level. Once you reach a leaf you go up. Every time you look up at a parent you check if the child you are supposed to come from was the last in parent's list. If not, you take next child and go down again. If yes, you go up and check the following parent. If you get back to the root you searched the whole tree.
EDIT
Ok search and traversals are distinct things, my bad. Here is some modified code for traversals
preorder:
public void preorderTraversal()
{
Node current = this.root;
Console.WriteLine(" item: {0} ", current.data);
while(true)
{
while(current.leftChild != null)
{
current = current.leftChild;
Console.WriteLine(" item: {0} ", current.data);
}
while(current.leftChild == null && current.rightChild != null)
{
current = current.rightChild;
Console.WriteLine(" item: {0} ", current.data);
}
if(current.leftChild == null && current.rightChild == null)
{
while(current.parent != null &&
(current == current.parent.rightChild ||
current.parent.rightChild == null))
{
current = current.parent;
}
if(current.parent == null)
{
return;
}
else
{
current = current.parent.rightChild;
Console.WriteLine(" item: {0} ", current.data);
}
}
}
}
inorder:
public void inorderTraversal()
{
Node current = this.root;
while(true)
{
while(current.leftChild != null)
{
current = current.leftChild;
}
Console.WriteLine(" item: {0} ", current.data);
while(current.leftChild == null && current.rightChild != null)
{
current = current.rightChild;
Console.WriteLine(" item: {0} ", current.data);
}
if(current.leftChild == null && current.rightChild == null)
{
while(current.parent != null &&
(current == current.parent.rightChild ||
current.parent.rightChild == null))
{
current = current.parent;
if(current.rightChild == null)
{
Console.WriteLine(" item: {0} ", current.data);
}
}
if(current.parent == null)
{
return;
}
else
{
Console.WriteLine(" item: {0} ", current.parent.data);
current = current.parent.rightChild;
}
}
}
}
postorder:
public void postorderTraversal()
{
Node current = this.root;
while(true)
{
while(true)
{
if(current.leftChild != null)
{
current = current.leftChild;
}
else if(current.rightChild != null)
{
current = current.rightChild;
}
else
{
break;
}
}
while(current.parent != null &&
(current == current.parent.rightChild ||
current.parent.rightChild == null))
{
Console.WriteLine(" item: {0} ", current.data);
current = current.parent;
}
Console.WriteLine(" item: {0} ", current.data);
if(current.parent == null)
{
return;
}
else
{
current = current.parent.rightChild;
}
}
}
If you have a parent pointer, then you can unwind up the tree without a stack. The only other problem during unwind is "do I need to visit the other child(ren)?" This can be answered simply by comparing pointer values to work out if you've just returned from the left child or the right child (or generalise to N children).
EDIT
Pseudocode (untested):
p_last = NULL;
p = p_head;
descend = true;
while (NULL != p)
{
p_tmp = p;
if (descend)
{
// ... Node processing here...
if (0 == p->num_children)
{
// No children, so unwind
p = p_parent;
descend = false;
}
else
{
// Visit first child
p = p->child[0];
}
}
else
{
// Find the child we just visited
for (i = 0; i < p->num_children; i++)
{
if (p_last == p->child[i])
{
break;
}
}
if (i == num_children-1)
{
// Processed last child, so unwind
p = p_parent;
}
else
{
// Visit next child
p = p->p_child[i+1];
descend = true;
}
}
p_last = p_tmp;
}
This shows how I'd do it in C. It demonstrates both pre-order and post-order traversal, and is generalised for 0..N children of each node.
struct node {
struct node *parent;
struct node *child[NCHILD];
};
void dfs(struct node *head, void (*visit_preorder)(struct node *n), void (*visit_postorder)(struct node *n))
{
struct node *current = head;
struct node *prev = head;
while (current)
{
int i;
/* preorder traversal */
if (prev == current->parent)
visit_preorder(current);
/* Find first child to visit */
for (i = NCHILD; i > 0; i--)
{
if (prev == current->child[i - 1])
break;
}
while (i < NCHILD && current->child[i] == NULL)
i++;
prev = current;
if (i < NCHILD)
{
/* Descend to current->child[i] */
current = current->child[i];
}
else
{
/* Postorder traversal */
visit_postorder(current);
/* Ascend back to parent */
current = current->parent;
}
}
}

Resources