// // 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; } }
// // Subroutine of explain // A step of explanation for x and y // void Egraph::expExplainAlongPath ( Enode * x, Enode * y ) { Enode * v = expHighestNode( x ); Enode * to = expHighestNode( y ); while ( v != to ) { Enode * p = v->getExpParent( ); assert( p != NULL ); Enode * r = v->getExpReason( ); // If it is not a congruence edge if ( r != NULL ) { if ( !isDup1( r ) ) { assert( r->isTerm( ) ); explanation.push_back( r ); storeDup1( r ); } } // Otherwise it is a congruence edge // This means that the edge is linking nodes // like (v)f(a1,...,an) (p)f(b1,...,bn), and that // a1,...,an = b1,...bn. For each pair ai,bi // we have therefore to compute the reasons else { assert( v->getCar( ) == p->getCar( ) ); assert( v->getArity( ) == p->getArity( ) ); expEnqueueArguments( v, p ); } #ifdef PRODUCE_PROOF if ( config.produce_inter > 0 && config.logic != QF_AX ) { cgraph.addCNode( v ); cgraph.addCNode( p ); cgraph.addCEdge( v, p, r ); } #endif expUnion( v, p ); v = expHighestNode( p ); } }