예제 #1
0
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;
}
예제 #2
0
파일: Debug.C 프로젝트: dpsanders/dreal3-1
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;
}
예제 #3
0
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;
}
예제 #4
0
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( );
}
예제 #5
0
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( );
}