Dafny modification clauses and nullable fields - heap-memory

There are a lot of gotcha's with the frame system. Trying to verify another leetcode problem, essentially that the tree left and right nodes are swapped in place. Attempting to solve it as both an object method and a standalone function.
The problem with the standalone function it complains that the recursive call might violate the context's modify clause. I added everything I could think of to the modify clause but it still doesn't work. I feel like the induction should be sufficient.
/**
* https://leetcode.com/problems/invert-binary-tree/description/
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
function invertTree(root: TreeNode | null): TreeNode | null {
if(root == null) return null;
let leftChild = invertTree(root.left);
let rightChild = invertTree(root.right);
root.right = leftChild;
root.left = rightChild;
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)
}
}
method invertBinaryTree(root: TreeNode?) returns (newRoot: TreeNode?)
modifies {root} + (if root != null && root.left != null then {root.left} else {}) + (if root != null && root.right != null then {root.right} else {})
requires root != null ==> root.Valid()
ensures root != null ==> newRoot == root && newRoot.right == old(root.left) && root.left == old(root.right)
ensures root == null ==> newRoot == null
ensures root != null ==> newRoot != null && newRoot.repr == root.repr && newRoot.Valid()
decreases if root == null then {} else root.repr
{
if root != null {
assert root in root.repr;
assert root.Valid();
var leftChild := null;
if root.left != null {
assert root.left != null;
assert root.left.repr < root.repr;
assert root.left.Valid();
leftChild := invertBinaryTree(root.left);
}
var rightChild := root.right;
if root.right != null {
assert root.right.Valid();
rightChild := invertBinaryTree(root.right);
}
root.right := leftChild;
root.left := rightChild;
return root;
}else{
return null;
}
}

Your modifies clause does not take into account that the method is recursive. So you need to say not only what you modify at the top level of the recursion, but also what all possible recursive calls will modify.
I believe something like
modifies if root != null then root.repr else {}
should work for you.

Related

is this Ternary expression redundant in splay function

https://www.geeksforgeeks.org/splay-tree-set-1-insert/
When I was learning about splay trees, I referred to this article and had a little doubt about the code in it.
this is splay function in this article
struct node *splay(struct node *root, int key)
{
// Base cases: root is NULL or key is present at root
if (root == NULL || root->key == key)
return root;
// Key lies in left subtree
if (root->key > key)
{
// Key is not in tree, we are done
if (root->left == NULL) return root;
// Zig-Zig (Left Left)
if (root->left->key > key)
{
// First recursively bring the key as root of left-left
root->left->left = splay(root->left->left, key);
// Do first rotation for root, second rotation is done after else
root = rightRotate(root);
}
else if (root->left->key < key) // Zig-Zag (Left Right)
{
// First recursively bring the key as root of left-right
root->left->right = splay(root->left->right, key);
// Do first rotation for root->left
if (root->left->right != NULL)
root->left = leftRotate(root->left);
}
// Do second rotation for root
return (root->left == NULL)? root: rightRotate(root);
}
else // Key lies in right subtree
{
// Key is not in tree, we are done
if (root->right == NULL) return root;
// Zag-Zig (Right Left)
if (root->right->key > key)
{
// Bring the key as root of right-left
root->right->left = splay(root->right->left, key);
// Do first rotation for root->right
if (root->right->left != NULL)
root->right = rightRotate(root->right);
}
else if (root->right->key < key)// Zag-Zag (Right Right)
{
// Bring the key as root of right-right and do first rotation
root->right->right = splay(root->right->right, key);
root = leftRotate(root);
}
// Do second rotation for root
return (root->right == NULL)? root: leftRotate(root);
}
}
Here is a snippet from the source code return (root->left == NULL)? root: rightRotate(root);, it appears in the last paragraph of the function.
My question is if I can write like thisreturn rightRotate(root), Because we have already judged whether this pointer is NULL above, It seems to me that after we do the rotate operation, the root->left can not be NULL. If this pointer can be null, hope to point out the situation that does not hold
is this Ternary expression redundant in splay function
No, root = rightRotate(root); and root = leftRotate(root); change root.

BST; the sum of BST elements which are greater then the sum of their direct children

So the task is to write a function which returns the sum of BST elements which are greater then the sum of their direct children. Do not count leaf nodes. I did it this way, the base case when the tree is empty return 0, and if it doesn't have sons also return 0. Then I checked if node has one or two children and the condition for the sums.
int sum(struct node* root)
{
if (root== NULL) return 0;
if (root->right == NULL && root->left==NULL) return 0;
if (root->right!= NULL && root->left != NULL)
{
if (((root->right)->key + (root->left)->key) < root->key) return root->key;
}
if (root->right != NULL && root->left==NULL)
{
if ((root->right)->key< root->key) return root->key;
}
if (root->left != NULL && root->right==NULL)
{
if ((root->left)->key < root->key) return root->key;
}
else return sum(root->right) + sum(root->left);
}
Main:
struct node* root = NULL;
add(&root,-4);
add(&root,6);
add(&root,8);
add(&root,-11);
add(&root,5);
add(&root,7);
add(&root,-20);
printf("%d",sum(root));
It should return -1 (6+8-11-4), but my function doesn't work I don't know why.
In your code, the else clause will never be executed; your previous conditions have dealt with all possibilities.
However, the expression should be executed. You either need to add + sum(root->left) + sum(root->right) as part of the three non-degenerate return statements, or you need to save the root->key in a local variable (defaulting to zero) and fall through to return return_value + sum(root->left) + sum(root->right);.
Hence (using the abbreviation rv for 'return value':
int sum(struct node* root)
{
int rv = 0;
if (root == NULL || (root->right == NULL && root->left == NULL))
return rv;
if (root->right != NULL && root->left != NULL)
{
if ((root->right->key + root->left->key) < root->key)
rv = root->key;
}
if (root->right != NULL && root->left == NULL)
{
if (root->right->key < root->key)
rv = root->key;
}
if (root->left != NULL && root->right == NULL)
{
if (root->left->key < root->key)
rv = root->key;
}
return rv + sum(root->right) + sum(root->left);
}
Warning: pristine code, unsullied by any attempt to compile it.
You could use an else if chain for the last three 'outer' if tests (with an else clause instead of the last test) to avoid repeated tests. Whether there'd be a measurable difference is debatable; an optimizer might even make the change for itself.

Memory Allocation error identified by valgrind

bool load(const char *dictionary)
{
// TODO
//create alphanumeric frequency trie from dictionary stored in temporary location
// open dictioary
FILE *dict = fopen(dictionary, "r");
if (dict == NULL)
{
return false;
}
//beggining of dictionary trie called 'root'
root = (trie*) malloc( sizeof(trie) );
if (root == NULL)
{
printf("error allocating memory to root for load");
return false;
}
//beggining of traversal node called 'current' and "attachment" to read/traverse root node
trie* current = NULL;
int a = (int)'a';
int z = (int)'z';
int cha = 0;
current = root;
//construct trie letter branches from ch (character) of single word-lines in dictionary
for ( char ch = fgetc(dict) ; EOF != ch ; ch = fgetc(dict) )
{
//set cursor letter to indexable value
if ( ch == '\'' )
{
cha = (z + 1) - a;
//printf("#%d ",cha);
}
else
{
cha = (ch - a);
//printf("%d ",cha);
}
//create or traverse existing letter branch for next letter ch in word-line
if( current->children[cha] == NULL && ) //(cha >= 0 && cha <=26) )
{
//printf("L");
current -> children[cha] = (trie*) malloc( sizeof(trie) );
current = current -> children[cha];
}
else //if ( cha >= 0 && cha <=26 )
{
current = current -> children[cha];
}
//for end of word-line in dictionary label as word and reset cursor node to root of dictionary trie (tree)
if ( ch == '\n' )
{
//printf("\n");
current->is_word = true;
wordcount++;
current = root;
//printf("%d", wordcount);
}
}
My program compiles and works exactly as specified for a problem I'm working on however i'm failing the valgrind test at the beginning of the if statement below. Valgrind Test returns "Invalid read of size 8." I'm hoping the code I provided below is enough to clarify where I'm insulting the system's memory.
if( (cha >= 0 && cha <=26) && current->children[cha] == NULL )
{
current -> children[cha] = (trie*) malloc( sizeof(trie) );
current = current -> children[cha];
}
else if ( cha >= 0 && cha <=26 )
{
current = current -> children[cha];
}
Also below is the structure of my trie node:
#define COUNT 27
typedef struct trie
{
bool is_word;
struct trie *children[COUNT];
}
trie;
//instantiation structures and variables
trie* root;
int wordcount = 0;
bool loaded;
//freetrie function prototype
void freetrie(trie* step);
Here's how I free malloc memory for the trie nodes:
void freetrie(trie* root)
{
for(int i = 0; i < 27; i++)
{
if (root -> children[i] != NULL)
{
freetrie(root -> children[i]);
}
}
free(root);
return;
}
bool unload(void)
{
// TODO
// free memory allocated by load for dictionary
trie* current = root;
freetrie(current);
return true;
}
The line if( current->children[cha] == NULL && (cha >= 0 && cha <=26) ) executes index boundary check only after accessing array, it should be rewritten to verify that index is valid before accessing array at that position. It is also a good idea to get rid of magic numbers:
#define TRIE_CHILDREN_COUNT 27
typedef struct trie
{
bool is_word;
struct trie *children[TRIE_CHILDREN_COUNT];
}
trie;
if((0 <= cha) && (cha < TRIE_CHILDREN_COUNT) && (NULL == current->children[cha]))

Binary Search Tree in C: remove node function

I'm putting together functions for a binary search tree and ran into a wall. I'm working on each situation that might be encountered when a node holding a specified value needs to be removed from the tree. I'm uncertain how to handle freeing the node if it does not have a left and right child. The function must return a node. Do I back up, examine each left and right child, and remove the value while it's in a child? But then if the value is in the root, wouldn't I have a similar problem with how to remove it? Just by way of explanation, the program uses a void pointer then casts the TYPE val in a separate function compare() which evaluates both values and returns -1 for <, 0 for ==, and 1 for >.
struct Node *_removeNode(struct Node *cur, TYPE val)
{
if (compare(cur->val, val) == 0) { //if val == cur->val
if (cur->right != NULL && cur->left != NULL) { //if cur has right and left
cur = _leftMost(cur->right);
free(_leftMost(cur->right));
}
else if (cur->right == NULL && cur->left != NULL) { //if cur has left
cur = cur->left;
free(cur->left);
}
else if (cur->right != NULL && cur->left == NULL){ //if cur has right
cur = cur->right;
free(cur->right);
}
else if (cur->right == NULL && cur->left == NULL){ //if cur has no child
//free cur if cur = val
}
}
else if (compare(cur->val, val) == -1) {
cur->right = _removeNode(cur->right, val);
}
else if (compare(cur->val, val) == 1) {
cur->left = _removeNode(cur->left, val);
}
return cur;
}
If the node has neither child then it can simply be deleted. In order to make your recursion in the other cases work, you should return NULL from _removeNode. In all cases, cur should be deleted (freed) as it is no longer needed. In each case, you need to return the replacement subtree. The complication occurs in the first case where the left most descendent of the right child is pulled up. After pulling it up, you need to remove it from the right sub-tree (note that it may be the right sub-tree).
I wrote all of the below off the top of my head so be prepared for a few errors/a bit of debugging. Also, _leftMost and _removeLeftMost can be merged with a bit of work.
The block in question should look something like:
Node *replacement;
if (cur->right != NULL && cur->left != NULL) { //if cur has right and left
replacement = _leftMost(cur->right);
replacement->right = _removeLeftMost(cur->right,replacement);
replacement->left = cur->left;
}
else if (cur->right == NULL && cur->left != NULL) { //if cur has left
replacement = cur->left;
}
else if (cur->right != NULL && cur->left == NULL){ //if cur has right
replacement = cur->right;
}
else if (cur->right == NULL && cur->left == NULL){ //if cur has no child
replacement = NULL;
}
free(cur);
cur = replacement;
The function _removeLeftMost walks down the left child pointers until it sees the node to be replaced and then replaces it with the right child of that node. Something like:
Node *_removeLeftMost(node, remove) {
if (node == remove) {
return node->right; // Note that remove->left should be null
}
else {
node->left = _removeLeftMost(node->left,remove);
return node;
}
}
Also, the main call is something like
root = _removeNode(root, val);
So that handles your concern when the node is the root.

Changing From Assert Function in C To If Statement

I have found some code online for red black trees, and am trying to implement it.
I do not want to use the assert function though which the original code has located here
I am getting a seg fault on the line n->color = child->color; just before the delete fix. After debugging I discovered that the child did not exist in this case, and so the reason for the assert statement in the original code. I decided to add what I thought was appropriate with the additional if clause around everything from where child is dealt with downward.
However, now the program does not actually delete, because if the child does not exist, it never makes it into the loop. After trial and error I still cannot find where to close the if clause in order to take the place of the assert statement properly.
Please let me know your ideas!
Here is my "translated" code without the assert, and using an if statement instead.
void delete_node(int key)
{
node* child;
node* n ;
n = searchTree(key);
if(n == NULL)return;
if(n->left != NULL && n->right != NULL)
{
node* pred = n->left;
while(pred->right != NULL)
pred = pred->right;
n->value = pred->value;
n = pred;
}
if(n->right != NULL || n->left != NULL){
child = n->right == NULL ? n->left : n->right;
if(n->color == 'b')
{
n->color = child->color;
delete_fix1(n);
}
swap_nodes(n, child);
if(n->parent == NULL && child != NULL)
child->color = 'b';
free(n);
}
}
Test data (Seg Fault occurs when attempting to delete 4):
i stand for insert (insert occurs flawlessly as far as I can tell)
d stands for delete
i 7
i 8
i 1
d 8
i 4
i 10
d 4
i 11
This:
assert(n->left == NULL || n->right == NULL)
Is nowhere near this:
if (n->right != NULL || n->left != NULL)
Recheck your translation. The assert states that one of them must be NULL. your if-expr evals true if either are not NULL. Your if-expr passes if both are non-null, where the assert would fail. Likewise, your if-expr fails if both are NULL, while the assert would pass.
Don't take shortcuts when doing this kinda of thing. First. keep the asserts regardless of your added checks. Second, until it is up and working, copy the assert clauses verbatim in your if (expr): or (!(expr)) for bailout conditions.
verbatim check:
assert(n->left == NULL || n->right == NULL)
if (n->left == NULL || n->right == NULL)...
bailout check:
assert(n->left == NULL || n->right == NULL)
if (!(n->left == NULL || n->right == NULL))
bailout loud.
EDIT Translation of linked code with integrated if-expr
void rbtree_delete(rbtree t, void* key, compare_func compare)
{
node child;
node n = lookup_node(t, key, compare);
if (n == NULL) return; /* Key not found, do nothing */
if (n->left != NULL && n->right != NULL) {
/* Copy key/value from predecessor and then delete it instead */
node pred = maximum_node(n->left);
n->key = pred->key;
n->value = pred->value;
n = pred;
}
assert(n->left == NULL || n->right == NULL);
if (n->left == NULL || n->right == NULL) // << note: SAME as above
{
child = n->right == NULL ? n->left : n->right;
if (node_color(n) == BLACK) {
n->color = node_color(child);
delete_case1(t, n);
}
replace_node(t, n, child);
if (n->parent == NULL && child != NULL)
child->color = BLACK;
free(n);
}
verify_properties(t);
}

Resources