void Egraph::gatherInterfaceTerms( Enode * e ) { assert( config.sat_lazy_dtc != 0 ); assert( config.logic == QF_UFIDL || config.logic == QF_UFLRA ); assert( e ); if ( config.verbosity > 2 ) cerr << "# Egraph::Gathering interface terms" << endl; vector< Enode * > unprocessed_enodes; initDup1( ); unprocessed_enodes.push_back( e ); // // Visit the DAG of the term from the leaves to the root // while( !unprocessed_enodes.empty( ) ) { Enode * enode = unprocessed_enodes.back( ); // // Skip if the node has already been processed before // if ( isDup1( enode ) ) { unprocessed_enodes.pop_back( ); continue; } bool unprocessed_children = false; Enode * arg_list; for ( arg_list = enode->getCdr( ) ; arg_list != enil ; arg_list = arg_list->getCdr( ) ) { Enode * arg = arg_list->getCar( ); assert( arg->isTerm( ) ); // // Push only if it is unprocessed // if ( !isDup1( arg ) ) { unprocessed_enodes.push_back( arg ); unprocessed_children = true; } } // // SKip if unprocessed_children // if ( unprocessed_children ) continue; unprocessed_enodes.pop_back( ); // // At this point, every child has been processed // if ( enode->isUFOp( ) ) { // Retrieve arguments for ( Enode * arg_list = enode->getCdr( ) ; !arg_list->isEnil( ) ; arg_list = arg_list->getCdr( ) ) { Enode * arg = arg_list->getCar( ); // This is for sure an interface term if ( ( arg->isArithmeticOp( ) || arg->isConstant( ) ) && interface_terms_cache.insert( arg ).second ) { interface_terms.push_back( arg ); if ( config.verbosity > 2 ) cerr << "# Egraph::Added interface term: " << arg << endl; } // We add this variable to the potential // interface terms or to interface terms if // already seen in LA else if ( arg->isVar( ) || arg->isConstant( ) ) { if ( it_la.find( arg ) == it_la.end( ) ) it_uf.insert( arg ); else if ( interface_terms_cache.insert( arg ).second ) { interface_terms.push_back( arg ); if ( config.verbosity > 2 ) cerr << "# Egraph::Added interface term: " << arg << endl; } } } } if ( enode->isArithmeticOp( ) && !isRootUF( enode ) ) { // Retrieve arguments for ( Enode * arg_list = enode->getCdr( ) ; !arg_list->isEnil( ) ; arg_list = arg_list->getCdr( ) ) { Enode * arg = arg_list->getCar( ); // This is for sure an interface term if ( arg->isUFOp( ) && interface_terms_cache.insert( arg ).second ) { interface_terms.push_back( arg ); if ( config.verbosity > 2 ) cerr << "# Egraph::Added interface term: " << arg << endl; } // We add this variable to the potential // interface terms or to interface terms if // already seen in UF else if ( arg->isVar( ) || arg->isConstant( ) ) { if ( it_uf.find( arg ) == it_uf.end( ) ) it_la.insert( arg ); else if ( interface_terms_cache.insert( arg ).second ) { interface_terms.push_back( arg ); if ( config.verbosity > 2 ) cerr << "# Egraph::Added interface term: " << arg << endl; } } } } assert( !isDup1( enode ) ); storeDup1( enode ); } doneDup1( ); }
// // Check if the subformula is purely // bool Egraph::isPureLA( Enode * e ) { assert( config.sat_lazy_dtc != 0 ); assert( config.logic == QF_UFIDL || config.logic == QF_UFLRA ); assert( e ); vector< Enode * > unprocessed_enodes; initDup1( ); unprocessed_enodes.push_back( e ); // // Visit the DAG of the term from the leaves to the root // while( !unprocessed_enodes.empty( ) ) { Enode * enode = unprocessed_enodes.back( ); // // Skip if the node has already been processed before // if ( isDup1( enode ) ) { unprocessed_enodes.pop_back( ); continue; } bool unprocessed_children = false; Enode * arg_list; for ( arg_list = enode->getCdr( ) ; arg_list != enil ; arg_list = arg_list->getCdr( ) ) { Enode * arg = arg_list->getCar( ); assert( arg->isTerm( ) ); // // Push only if it is unprocessed // if ( !isDup1( arg ) ) { unprocessed_enodes.push_back( arg ); unprocessed_children = true; } } // // SKip if unprocessed_children // if ( unprocessed_children ) continue; unprocessed_enodes.pop_back( ); cerr << "Considering enode: " << enode << endl; // // At this point, every child has been processed // if ( enode->isUFOp( ) ) { doneDup1( ); return false; } assert( !isDup1( enode ) ); storeDup1( enode ); } doneDup1( ); return true; }