/** * Remove all children of the SafraTreeNode <i>id</i>. */ public void removeAllChildren(int id) { Debug.Assert(id < MAX_NODES); SafraTreeNode n = _nodes[id]; SafraTreeNode child; while ((child = n.getOldestChild()) != null) { removeAllChildren(child.getID()); remove(child.getID()); } }
/** * Compare two subtrees to see if they match (taking into account the renameableNames * and the restrictedNames). */ public bool matches(SafraTreeNode this_node, SafraTreeNode other_node) { Debug.Assert(this_node != null && other_node != null); if (this_node == null || other_node == null) { return(false); } if (!renameableNames().get(this_node.getID())) { // this is not a new node, so we require a perfect match.. if (other_node.getID() != this_node.getID()) { return(false); } } else { // we are flexible with the id, as long as the id wasn't removed // in the tree if (restrictedNames().get(other_node.getID())) { return(false); } } Debug.Assert(this_node.getLabeling() == other_node.getLabeling()); Debug.Assert(this_node.hasFinalFlag() == other_node.hasFinalFlag()); // this node looks good, now the children SafraTreeNode this_child = this_node.getOldestChild(); SafraTreeNode other_child = other_node.getOldestChild(); while (this_child != null && other_child != null) { if (!matches(this_child, other_child)) { return(false); } this_child = this_child.getYoungerBrother(); other_child = other_child.getYoungerBrother(); } Debug.Assert(this_child == null && other_child == null); return(true); }
/** Node visitor */ public void visit(SafraTree tree, SafraTreeNode node) { if (node.getChildCount() <= 1) { return; } int i = 0; //for (SafraTreeNode::child_iterator it= node->children_begin(); it!=node->children_end();++it) SafraTreeNode it = node.children_begin(); while (it != node.children_end()) { BitSet reachable_this = _node_reachability[it.getID()]; reachable_this.clear(); _node_order[it.getID()] = i++; BitSet label_this = it.getLabeling(); //for (BitSetIterator label_it(label_this); label_it != BitSetIterator::end(label_this); ++label_it) for (int label_it = 0; label_it < label_this.Count; label_it++) { reachable_this.Union(_nba_reachability[label_it]); } // std::cerr << "reachability_this: "<<reachable_this << std::endl; it = it.increment(); } // reorder... // std::cerr << "Sorting!" << std::endl; // Bubble sort, ough! bool finished = false; while (!finished) { finished = true; for (SafraTreeNode a = node.getOldestChild(); a != null && a.getYoungerBrother() != null; a = a.getYoungerBrother()) { SafraTreeNode b = a.getYoungerBrother(); BitSet reach_a = _node_reachability[a.getID()]; BitSet reach_b = _node_reachability[b.getID()]; if (reach_a.intersects(reach_b)) { // a and b are not independant... // --> keep relative order... System.Diagnostics.Debug.Assert(_node_order[a.getID()] < _node_order[b.getID()]); } else { // a and b are independant... if (!(a.getLabeling() < b.getLabeling())) { // swap node.swapChildren(a, b); a = b; finished = false; } } } } }