// // Undoes the effect of expStoreExplanation // void Egraph::expRemoveExplanation( ) { assert( exp_undo_stack.size( ) >= 2 ); Enode * x = exp_undo_stack.back( ); exp_undo_stack.pop_back( ); Enode * y = exp_undo_stack.back( ); exp_undo_stack.pop_back( ); assert( x ); assert( y ); assert( !x->isEnil( ) ); assert( !y->isEnil( ) ); // We observe that we don't need to undo the rerooting // of the explanation trees, because it doesn't affect // correctness. We just have to reroot y on itself assert( x->getExpParent( ) == y || y->getExpParent( ) == x ); if ( x->getExpParent( ) == y ) { x->setExpParent( NULL ); x->setExpReason( NULL ); } else { y->setExpParent( NULL ); y->setExpReason( NULL ); } }
// // Subroutine of explainStoreExplanation // Re-root the tree containing x, in such a way that // the new root is x itself // void Egraph::expReRootOn ( Enode * x ) { Enode * p = x; Enode * parent = p->getExpParent( ); Enode * reason = p->getExpReason( ); x->setExpParent( NULL ); x->setExpReason( NULL ); while( parent != NULL ) { // Save grandparent Enode * grandparent = parent->getExpParent( ); // Save reason Enode * saved_reason = reason; reason = parent->getExpReason( ); // Reverse edge & reason parent->setExpParent( p ); parent->setExpReason( saved_reason ); #ifdef PEDANTIC_DEBUG assert( checkExpTree( parent ) ); #endif // Move the two pointers p = parent; parent = grandparent; } }