IVector ode_solver::extract_invariants() { map<Enode*, pair<double, double>> inv_map; for (auto inv : m_invs) { Enode * p = inv->getCdr()->getCdr()->getCdr()->getCdr()->getCar(); Enode * op = p->getCar(); bool pos = true; // Handle Negation if (op->getId() == ENODE_ID_NOT) { p = p->getCdr()->getCar(); op = p->getCar(); pos = false; } switch (op->getId()) { case ENODE_ID_GEQ: case ENODE_ID_GT: // Handle >= & > pos = !pos; case ENODE_ID_LEQ: case ENODE_ID_LT: { // Handle <= & < Enode * lhs = pos ? p->getCdr()->getCar() : p->getCdr()->getCdr()->getCar(); Enode * rhs = pos ? p->getCdr()->getCdr()->getCar() : p->getCdr()->getCar(); if (lhs->isVar() && rhs->isConstant()) { if (inv_map.find(lhs) != inv_map.end()) { inv_map[lhs].second = rhs->getValue(); } else { inv_map.emplace(lhs, make_pair(lhs->getLowerBound(), rhs->getValue())); } } else if (lhs->isConstant() && rhs->isVar()) { if (inv_map.find(rhs) != inv_map.end()) { inv_map[rhs].first = lhs->getValue(); } else { inv_map.emplace(rhs, make_pair(lhs->getValue(), rhs->getUpperBound())); } } else { cerr << "ode_solver::extract_invariant: error:" << p << endl; } } break; default: cerr << "ode_solver::extract_invariant: error" << p << endl; } } IVector ret (m_t_vars.size()); unsigned i = 0; for (auto const & m_t_var : m_t_vars) { if (inv_map.find(m_t_var) != inv_map.end()) { auto inv = interval(inv_map[m_t_var].first, inv_map[m_t_var].second); DREAL_LOG_INFO << "Invariant extracted from " << m_t_var << " = " << inv; ret[i++] = inv; } else { auto inv = interval(m_t_var->getLowerBound(), m_t_var->getUpperBound()); DREAL_LOG_INFO << "Default Invariant set for " << m_t_var << " = " << inv; ret[i++] = inv; } } return ret; }
map<Enode *, bool> CoreSMTSolver::getBoolModel() { map<Enode *, bool> ret; for (int i = 0; i < trail.size(); i++) { Lit const & l = trail[i]; Var const v = var(l); if (v >= 2) { Enode * e = theory_handler->varToEnode(v); bool p = value(l) == l_True; if (e->isNot()) { e = e->get1st(); p = !p; } if (e->isVar()) { if (sign(l)) { p = !p; } ret.emplace(e, p); } } } return ret; }
lbool CostSolver::inform( Enode * e ) { assert( e ); assert( belongsToT( e ) ); #if DEBUG cout << "ct inform " << e << endl; #endif if ( e->isCostIncur() ) { assert( e->getArity() == 3 ); Enode * args = e->getCdr(); Enode * var = args->getCar(); Enode * cost = args->getCdr()->getCar(); #if DEBUG cout << "ct inform var = " << var << endl; cout << "ct inform cost = " << cost << endl; #endif assert( var->isVar() ); assert( cost->isConstant() ); nodemap_t::iterator it = nodemap_.find( var ); if ( it != nodemap_.end() ) { costfun & fun = *it->second; nodemap_[ e ] = &fun; add_incur( fun, e, cost ); } else { costfun * fun = new costfun( var ); #if DEBUG cout << "ct new cost fun " << var << endl; #endif nodemap_[ var ] = fun; nodemap_[ e ] = fun; costfuns_.push_back( fun ); add_incur( *fun, e, cost ); } } if ( e->isCostBound() ) { assert( e->getArity() == 2 ); Enode * args = e->getCdr(); Enode * var = args->getCar(); nodemap_t::iterator it = nodemap_.find( var ); if ( it != nodemap_.end() ) { costfun & fun = *it->second; nodemap_[ var ] = &fun; nodemap_[ e ] = &fun; add_bound( fun, e ); } else { costfun * fun = new costfun( var ); #if DEBUG cout << "ct new cost fun " << var << endl; #endif nodemap_[ var ] = fun; nodemap_[ e ] = fun; costfuns_.push_back( fun ); add_bound( *fun, e ); } } #if DEBUG print_status( cout ); #endif return l_Undef; }
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( ); }
void Egraph::getInterfaceVars( Enode * e, set< Enode * > & iv ) { assert( config.produce_inter != 0 ); 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( ); if ( enode->isVar( ) && interface_terms_cache.find( enode ) != interface_terms_cache.end( ) ) iv.insert( enode ); assert( !isDup1( enode ) ); storeDup1( enode ); } doneDup1( ); }