/* * This function recursively visits the subtree, which root node is node. */ void dfs(struct node *node) /*@ requires unvisited_node_p(node, ?node_children_count, ?node_children, ?node_subtree, _, _); @*/ /*@ ensures visited_node_p(node, node_children_count, node_children, node_subtree, 0, 0); @*/ { /*@ open unvisited_node_p(node, node_children_count, node_children, node_subtree, _, _); @*/ node->parent = 0; node->distance = 0; /*@ close visiting_node_p(node, node_children_count, node_children, node_subtree, 0, 0); @*/ dfs_worker(node, 0); }
void Graph::dfs_worker(int v, void(*process_vertex_early)(int v), void(*process_vertex_late)(int v), void(*process_edge)(int v,EdgeNode *p)) { EdgeNode *p; int y; if(finished) return; discovered[v] = TRUE; entry_time[v] = ++time; process_vertex_early(v); p = this->edges[v]; while(p){ y = p->y; if(!discovered[y]){ parent[y] = v; process_edge(v,p); dfs_worker(y,process_vertex_early, process_vertex_late, process_edge); } else if( (!processed[y] && parent[v] != y) || (this->directed)){ process_edge(v,p); } if(finished) return; p = p->next; } process_vertex_late(v); exit_time[v] = ++time; processed[v] = TRUE; }
void Graph::dfs(int start){ prepare_search(); dfs_worker(start, &(do_nothing), &(print_vertex), &(do_nothing)); }
/* * This function recursively visits the subtree, which root node is node. * * It sets the node->parent pointer to point to the parent of the node and * sets node->distance = node->parent->distance + 1. */ void dfs_worker(struct node *node, int depth) /*@ requires depth >= 0 &*& visiting_node_p(node, ?node_children_count, ?node_children, ?node_subtree, ?parent, depth); @*/ /*@ ensures visited_node_p(node, node_children_count, node_children, node_subtree, parent, depth); @*/ { /*@ open visiting_node_p(node, node_children_count, node_children, node_subtree, parent, depth); @*/ int children_count = node->children_count; struct node *children = node->children; // Opening just to get the value of the subtree_children. /*@ open unvisited_children_p(children, node_children_count, ?subtree_children); @*/ /*@ close unvisited_children_p(children, node_children_count, subtree_children); @*/ int i = 0; /*@ close visited_children_p( children, 0, subtree_children_nil, node, depth + 1); @*/ for (; i != children_count; i++) /*@ invariant unvisited_children_p( children + i, children_count - i, ?children_nodes1) &*& visited_children_p( children, i, ?children_nodes2, node, depth + 1) &*& (children_merge(children_nodes2, children_nodes1) == subtree_children) &*& i >= 0; @*/ { /*@ open unvisited_children_p(children + i, children_count - i, children_nodes1); @*/ /*@ open unvisited_children_p(children + i + 1, children_count - i - 1, ?children_nodes1_left); @*/ /*@ close unvisited_children_p(children + i + 1, children_count - i - 1, children_nodes1_left); @*/ struct node *child = children + i; //@ open unvisited_child_p(child, ?child_subtree); //@ open unvisited_node_p(child, _, _, child_subtree, _, _); child->parent = node; child->distance = depth + 1; //@ close visiting_node_p(child, _, _, _, node, depth + 1); dfs_worker(child, depth + 1); //@ close visited_child_p(child, node, depth + 1, child_subtree); //@ visited_children_append(children, i); /*@ children_merge_associative( children_nodes2, subtree_children_cons(child_subtree, subtree_children_nil), children_nodes1_left); @*/ } /*@ open visited_children_p( children, i, ?children_nodes2, node, depth + 1); @*/ /*@ close visited_children_p( children, i, children_nodes2, node, depth + 1); @*/ /*@ open unvisited_children_p(children + i, children_count - i, ?children_nodes1); @*/ //@ children_merge_nil(children_nodes2); //@ assert(children_nodes2 == subtree_children); assert(children_count - i == 0); //@ close visited_node_p(node, _, _, node_subtree, _, depth); }