/* Create a conforming refinement where node is refined. Algorithm A.5 */ void partition_refine_node( workspace *w, tree *node) { assert( w->is_conform); assert( tree_is_leaf( node)); tri *t = w->tris[node->i]; tree *neighbour = edge_get( w->edges, t->p[2], t->p[1]); if( neighbour == NULL) { //no neighbouring triangle; we are on the edge tree_subdivide( w, node); } else { tri *neighbour_tri = w->tris[neighbour->i]; if( neighbour_tri->p[2] == t->p[1] && neighbour_tri->p[1] == t->p[2]) { //same refinement edge tree_subdivide( w, node); tree_subdivide( w, neighbour); } else { partition_refine_node( w, neighbour); tree *left = neighbour->left; tree *right = neighbour->right; tree *children[2] = {left, right}; int i; for( i = 0; i < 2; i++) { if( w->tris[children[i]->i]->p[1] == t->p[2] && w->tris[children[i]->i]->p[2] == t->p[1]) { //we found the right child tree_subdivide( w, children[i]); tree_subdivide( w, node); } } } } assert( !tree_is_leaf( node)); w->is_conform = 1; }
/* Find inner nodes of the total partition. */ void partition_inner_nodes( workspace *w, tree ***inners, int *ninners) { tree **queue = malloc( w->nleaves * sizeof( tree *)); *inners = malloc( w->nleaves * sizeof( tree *)); *ninners = 0; int nqueue = w->nroots; int i; for( i = 0; i < w->nroots; i++) { queue[i] = w->roots[i]; } int j; while( nqueue > 0) { tree *node = queue[0]; for( j = 0; j < nqueue - 1; j++) { queue[j] = queue[j+1]; } nqueue--; if( !tree_is_leaf( node)) { for( j = *ninners; j >= 1; j--) { (*inners)[j] = (*inners)[j-1]; } (*inners)[0] = node; (*ninners)++; queue[nqueue++] = node->left; queue[nqueue++] = node->right; } } free( queue); }
char *check_tree(struct tree *t, char *spec) //@ requires tree(t, ?v) &*& [_]string(spec, ?cs); /*@ ensures switch (check_tree_pure(v, cs)) { case check_fail: return result == 0; case check_success(cs0): return result != 0 &*& [_]string(result, cs0); }; @*/ { bool b = tree_is_leaf(t); //@ string_limits(spec); //@ open string(spec, _); if (*spec == 'L') { tree_dispose(t); if (!b) return 0; return spec + 1; } else if (*spec == 'N') { struct tree *l; struct tree *r; if (b) { tree_dispose(t); return 0; } tree_destruct_node(t, &l, &r); spec = check_tree(l, spec + 1); if (spec == 0) { tree_dispose(r); return 0; } return check_tree(r, spec); } else { tree_dispose(t); return 0; } }
/* if the expression consists of a single * root node pointing to a string it is a word */ int expr_is_word(Expr *expr) { /* we need this here because an empty list is * also a tree, so we check if it points to a word */ if (expr_get_word(expr) != NULL) return tree_is_leaf(expr); return 0; }
/* Create a conforming refinement where nodes[n] are refined. Algorithm A.13 */ void partition_refine( workspace *w, tree **nodes, int n) { assert( w->is_conform); int i; for( i = 0; i < n; i++) { if( tree_is_leaf( nodes[i])) { partition_refine_node( w, nodes[i]); } } }
void extract_fextract(bit_file_t *compressed, bit_file_t *extracted, tree_node* root, unsigned int bytecount) { unsigned int bytesread = 0; tree_node *current = root; while (bytesread < bytecount) { current = BitFileGetBit(compressed) ? current->right : current->left; if (tree_is_leaf(current)) { BitFilePutChar(current->content, extracted); current = root; bytesread++; } } }