Beispiel #1
0
lbool SimpSMTSolver::solve( const vec< Enode * > & assumps
    , const unsigned conflicts
    , bool do_simp
    , bool turn_off_simp )
{
  vec<Lit> lits;
  for ( int i=0; i<assumps.size(); ++i )
  {
    Enode * e = assumps[ i ];
    if ( e->isFalse( ) )
    {
      return l_False;
    }
    if ( e->isTrue( ) )
    {
      continue;
    }

    Lit l = theory_handler->enodeToLit( e );


    lits.push( l );
  }
  return solve( lits, conflicts, do_simp, turn_off_simp );
}
Beispiel #2
0
//
// Check if a formula is a clause
//
bool Cnfizer::checkClause( Enode * e, set< enodeid_t > & check_cache )
{
  assert( e );

  if ( e->isLit( ) )
  {
    check_cache.insert( e->getId( ) );                           // Don't check again
    return true;
  }

  if ( !e->isOr( ) )
    return false;

  if ( check_cache.find( e->getId( ) ) != check_cache.end( ) )   // Already visited term
    return true;

  bool is_clause = true;
  for ( Enode * list = e->getCdr( ) ;
        list != egraph.enil && is_clause ;
        list = list->getCdr( ) )
    is_clause = checkClause( list->getCar( ), check_cache );

  if ( !is_clause )
    return false;

  check_cache.insert( e->getId( ) );                             // Don't check again

  return true;
}
Beispiel #3
0
vector<shared_ptr<nonlinear_constraint>> make_nlctrs(Enode * const e,
                                                     unordered_set<Enode *> const & var_set,
                                                     lbool const p) {
    vector<shared_ptr<nonlinear_constraint>> ret;
    if (e->isTrue()) {
        return ret;
    }
    if (e->isFalse()) {
        DREAL_LOG_FATAL << "false is not a valid invariant (forall_t constraint)";
        throw logic_error("false is not a valid invariant (forall_t constraint)");
    }
    if (e->isNot()) {
        return make_nlctrs(e->get1st(), var_set, !p);
    }
    if (e->isAnd()) {
        Enode * tmp = e->getCdr();
        while (!tmp->isEnil()) {
            auto const nlctrs = make_nlctrs(e->get1st(), var_set, p);
            ret.insert(ret.end(), nlctrs.begin(), nlctrs.end());
            tmp = tmp->getCdr();
        }
        return ret;
    }
    if (e->isOr()) {
        DREAL_LOG_FATAL << "or is not a valid invariant for now, (forall_t constraint)";
        throw logic_error("false is not a valid invariant for now, (forall_t constraint)");
    }
    ret.push_back(make_shared<nonlinear_constraint>(e, var_set, p));
    return ret;
}
Beispiel #4
0
//
// Check if its a pure conjunction of literals
//
bool Cnfizer::checkPureConj( Enode * e, set< enodeid_t > & check_cache )
{
  if ( check_cache.find( e->getId( ) ) != check_cache.end( ) )
    return true;

  if ( e->isLit( ) )
  {
    check_cache.insert( e->getId( ) );
    return true;
  }

  if ( !e->isAnd( ) )
    return false;

  bool is_pure_conj = true;
  for ( Enode * list = e->getCdr( ) ;
        list != egraph.enil && is_pure_conj ;
        list = list->getCdr( ) )
    is_pure_conj = checkPureConj( list->getCar( ), check_cache );

  if ( !is_pure_conj )
   return false;

  check_cache.insert( e->getId( ) );

  return true;
}
Beispiel #5
0
ostream& display(ostream& out, box const & b, bool const exact, bool const old_style) {
    std::streamsize ss = out.precision();
    out.precision(16);
    if (old_style) {
        out << "delta-sat with the following box:" << endl;
        unsigned const s = b.size();
        for (unsigned i = 0; i < s; i++) {
            Enode * e = b.m_vars[i];
            string const & name = e->getCar()->getName();
            ibex::Interval const & v = b.m_values[i];
            out << "\t" << name << " : " << v;
            if (i != (s - 1)) {
                out << ";";
            }
            out << endl;
        }
    } else {
        unsigned const s = b.size();
        for (unsigned i = 0; i < s; i++) {
            Enode * e = b.m_vars[i];
            ibex::Interval const & v = b.m_values[i];
            ibex::Interval const & d = b.m_domains[i];
            out << e->getCar()->getName()
                << " : ";
            display(out, d, exact);
            out << " = ";
            display(out, v, exact);
            out << endl;
        }
    }
    out.precision(ss);
    return out;
}
Beispiel #6
0
ibex::SystemFactory * contractor_ibex_polytope::build_system_factory(
    vector<Enode *> const & vars, vector<shared_ptr<nonlinear_constraint>> const & ctrs) {
    DREAL_LOG_DEBUG << "build_system_factory:";
    ibex::SystemFactory * sf = new ibex::SystemFactory();
    map<string, ibex::ExprSymbol const *> var_map;  // Needed for translateEnodeToExprCtr

    // Construct System: add Variables
    for (Enode * e : vars) {
        string const & name = e->getCar()->getNameFull();
        DREAL_LOG_INFO << "build_system_factory: Add Variable " << name;
        auto var_it = m_var_cache.find(e);
        ibex::ExprSymbol const * var = nullptr;
        if (var_it == m_var_cache.end()) {
            // Not found
            var = &ibex::ExprSymbol::new_(name.c_str(), ibex::Dim::scalar());
            DREAL_LOG_INFO << "Added: var " << var << endl;
            m_var_cache.emplace(e, var);
        } else {
            // Found
            var = var_it->second;
        }
        var_map.emplace(name, var);
        sf->add_var(*var);
    }
    DREAL_LOG_DEBUG << "build_system_factory: Add Variable: DONE";

    // Construct System: add constraints
    for (shared_ptr<nonlinear_constraint> const ctr : ctrs) {
        if (ctr->is_neq()) {
            continue;
        }
        DREAL_LOG_INFO << "build_system_factory: Add Constraint: " << *ctr;
        Enode * e = ctr->get_enode();
        auto p = e->getPolarity();
        assert(p == l_True || p == l_False);
        auto & m_exprctr_cache = (p == l_True) ? m_exprctr_cache_pos : m_exprctr_cache_neg;
        auto exprctr_it = m_exprctr_cache.find(e);
        ibex::ExprCtr const * exprctr = nullptr;
        if (exprctr_it == m_exprctr_cache.end()) {
            // Not found
            exprctr = translate_enode_to_exprctr(var_map, e);
            m_exprctr_cache.emplace(e, exprctr);
            DREAL_LOG_INFO << "Added: exprctr " << p << " " << *exprctr << endl;
        } else {
            // Found
            exprctr = exprctr_it->second;
        }
        if (exprctr) {
            DREAL_LOG_INFO << "build_system_factory: Add Constraint: expr: " << *exprctr;
            sf->add_ctr(*exprctr);
        }
    }
    DREAL_LOG_DEBUG << "build_system_factory: Add Constraint: "
                    << "DONE";
    DREAL_LOG_DEBUG << "build_system_factory: DONE";
    return sf;
}
Beispiel #7
0
void THandler::clearVar( Var v )
{
  assert( var_to_enode[ v ] != NULL );
  Enode * e = var_to_enode[ v ];
  assert( e->getId( ) < static_cast< int >( enode_id_to_var.size( ) ) );
  assert( enode_id_to_var[ e->getId( ) ] == v );
  var_to_enode[ v ] = NULL;
  enode_id_to_var[ e->getId( ) ] = var_Undef;
}
Beispiel #8
0
double dreal_get_domain_ub(dreal_context c, dreal_expr v) {
  assert(c);
  assert(v);
  OpenSMTContext * c_ = static_cast<OpenSMTContext *>(c);
  OpenSMTContext & context = *c_;
  assert(context.getStatus() == l_True);
  Enode * var = static_cast<Enode *>(v);
  return var->getDomainUpperBound();
}
Beispiel #9
0
void dreal_set_domain_ub(dreal_context c, dreal_expr v, double n) {
  assert(c);
  assert(v);
  OpenSMTContext * c_ = static_cast<OpenSMTContext *>(c);
  OpenSMTContext & context = *c_;
  assert(context.getStatus() == l_True);
  Enode * var = static_cast<Enode *>(v);
  var->setDomainUpperBound(n);
}
Beispiel #10
0
ostream & ode_constraint::display(ostream & out) const {
    out << "ode_constraint(" << m_int << ")" << endl;
    for (shared_ptr<forallt_constraint> const & inv : m_invs) {
        Enode * e = inv->get_enodes()[0];
        if (e->hasPolarity() && e->getPolarity() == l_True) {
            out << *inv << endl;
        }
    }
    return out;
}
Beispiel #11
0
double opensmt_get_domain_lb( opensmt_context c, opensmt_expr v )
{
  assert( c );
  assert( v );
  OpenSMTContext * c_ = static_cast< OpenSMTContext * >( c );
  OpenSMTContext & context = *c_;
  assert( context.getStatus( ) == l_True );
  Enode * var = static_cast< Enode * >( v );
  return var->getDomainLowerBound();
}
Beispiel #12
0
//
// Retrieve the formulae at the top-level
//
void Cnfizer::retrieveTopLevelFormulae( Enode * f, vector< Enode * > & top_level_formulae )
{
  if ( f->isAnd( ) )
    for ( Enode * list = f->getCdr( ) ;
          list != egraph.enil ;
          list = list->getCdr( ) )
      retrieveTopLevelFormulae( list->getCar( ), top_level_formulae );
  else
    top_level_formulae.push_back( f );
}
Beispiel #13
0
void opensmt_set_domain_lb( opensmt_context c, opensmt_expr v, double n )
{
  assert( c );
  assert( v );
  OpenSMTContext * c_ = static_cast< OpenSMTContext * >( c );
  OpenSMTContext & context = *c_;
  assert( context.getStatus( ) == l_True );
  Enode * var = static_cast< Enode * >( v );
  var->setDomainLowerBound(n);
}
Beispiel #14
0
//
// Inform Theory-Solvers of Theory-Atoms
//
void THandler::inform( )
{
  for ( ; tatoms_given < tatoms_list.size( ) ; tatoms_given ++ )
  {
    if ( !tatoms_give[ tatoms_given ] ) continue;
    Enode * atm = tatoms_list[ tatoms_given ];
    assert( atm );
    assert( atm->isTAtom( ) );
    core_solver.inform( atm );
  }
}
Beispiel #15
0
Lit THandler::getSuggestion( )
{
  Enode * e = core_solver.getSuggestion( );

  if ( e == NULL )
    return lit_Undef;

  bool negate = e->getDecPolarity( ) == l_False;
  Var v = enodeToVar( e );
  return Lit( v, negate );
}
Beispiel #16
0
void CoreSMTSolver::printExtModel( ostream & out )
{
  for (Var v = 2; v < model.size(); v++)
  {
    Enode * e = theory_handler->varToEnode( v );
    int tmp1, tmp2;
    if( sscanf( (e->getCar( )->getName( )).c_str( ), CNF_STR, &tmp1, &tmp2 ) != 1 )
      if ( model[ v ] != l_Undef )
        out << ( model[ v ] == l_True ? "" : "(not " ) << e << ( model[ v ] == l_True ? "" : ")" ) << endl;
  }
}
Beispiel #17
0
dreal_expr dreal_get_value(dreal_context c, dreal_expr v) {
  assert(c);
  assert(v);
  OpenSMTContext * c_ = static_cast<OpenSMTContext *>(c);
  OpenSMTContext & context = *c_;
  assert(context.getStatus() == l_True);
  Enode * var = static_cast<Enode *>(v);
  const Real & value = var->getValue();
  Enode * res = context.mkNum(value);
  return static_cast<void *>(res);
}
Beispiel #18
0
void Egraph::expCleanup ( )
{
    // Destroy the eq classes of the explanation
    while ( !exp_cleanup.empty( ) )
    {
        Enode * x = exp_cleanup.back( );
        x->setExpRoot( x );
        x->setExpHighestNode( x );
        exp_cleanup.pop_back( );
    }
}
Beispiel #19
0
void opensmt_define_ode( opensmt_context c, const char * flowname, opensmt_expr * vars, opensmt_expr * rhses, unsigned n)
{
  assert( c );
  OpenSMTContext * c_ = static_cast< OpenSMTContext * >( c );
  OpenSMTContext & context = *c_;
  vector<pair<string, Enode *> *> odes;
  for (unsigned i = 0; i < n; i++) {
      Enode * var = static_cast<Enode *>(vars[i]);
      Enode * rhs = static_cast<Enode *>(rhses[i]);
      odes.push_back(new pair<string, Enode*>(var->getCar()->getName(), rhs));
  }
  context.DefineODE(flowname, &odes);
}
Beispiel #20
0
void THandler::verifyDeductionWithExternalTool( Enode * imp )
{
  assert( imp->isDeduced( ) );

  // First stage: print declarations
  const char * name = "/tmp/verifydeduction.smt2";
  std::ofstream dump_out( name );

  core_solver.dumpHeaderToFile( dump_out );

  dump_out << "(assert" << endl;
  dump_out << "(and" << endl;
  for ( int j = 0 ; j < trail.size( ) ; j ++ )
  {
    Var v = var( trail[ j ] );

    if ( v == var_True || v == var_False )
      continue;

    Enode * e = varToEnode( v );
    assert( e );

    if ( !e->isTAtom( ) )
      continue;

    bool negated = sign( trail[ j ] );
    if ( negated )
      dump_out << "(not ";
    e->print( dump_out );
    if ( negated )
      dump_out << ")";

    dump_out << endl;
  }

  if ( imp->getDeduced( ) == l_True )
    dump_out << "(not " << imp << ")" << endl;
  else
    dump_out << imp << endl;

  dump_out << "))" << endl;
  dump_out << "(check-sat)" << endl;
  dump_out << "(exit)" << endl;
  dump_out.close( );

  // Second stage, check the formula
  const bool tool_res = callCertifyingSolver( name );

  if ( tool_res )
    opensmt_error2( config.certifying_solver, " says this is not a valid deduction" );
}
Beispiel #21
0
ostream & print_infix_op(ostream & out, Enode * const e, string const & op,
                         std::function<ostream &(ostream &, Enode * const)> const & f) {
    assert(e->getArity() >= 2);
    out << "(";
    f(out, e->get1st());
    Enode * tmp = e->getCdr()->getCdr();
    while (!tmp->isEnil()) {
        out << " " << op << " ";
        f(out, tmp->getCar());
        tmp = tmp->getCdr();
    }
    out << ")";
    return out;
}
Beispiel #22
0
//
// Return the conflict generated by a theory solver
//
void THandler::getConflict ( vec< Lit > & conflict, int & max_decision_level )
{
  // First of all, the explanation in a tsolver is
  // stored as conjunction of enodes e1,...,en
  // with associated polarities p1,...,pn. Since the sat-solver
  // wants a clause we store it in the form ( l1 | ... | ln )
  // where li is the literal corresponding with ei with polarity !pi
  vector< Enode * > & explanation = core_solver.getConflict( );
  assert( !explanation.empty( ) );

  if ( config.certification_level > 0 )
    verifyExplanationWithExternalTool( explanation );

#ifdef PRODUCE_PROOF
  max_decision_level = -1;
  for ( vector< Enode * >::iterator it = explanation.begin( )
      ; it != explanation.end( )
      ; ++ it )
  {
    Enode * ei  = *it;
    assert( ei->hasPolarity( ) );
    assert( ei->getPolarity( ) == l_True
         || ei->getPolarity( ) == l_False );
    bool negate = ei->getPolarity( ) == l_False;

    Var v = enodeToVar( ei );
#if PEDANTIC_DEBUG
    assert( isOnTrail( Lit( v, negate ) ) );
#endif
    Lit l = Lit( v, !negate );
    conflict.push( l );

    if ( max_decision_level < level[ v ] )
      max_decision_level = level[ v ];
  }
  if ( config.produce_inter == 0 )
    explanation.clear( );
#else
  max_decision_level = -1;
  while ( !explanation.empty( ) )
  {
    Enode * ei  = explanation.back( );
    explanation.pop_back( );
    assert( ei->hasPolarity( ) );
    assert( ei->getPolarity( ) == l_True
         || ei->getPolarity( ) == l_False );
    bool negate = ei->getPolarity( ) == l_False;

    Var v = enodeToVar( ei );
#if PEDANTIC_DEBUG
    assert( isOnTrail( Lit( v, negate ) ) );
#endif
    Lit l = Lit( v, !negate );
    conflict.push( l );

    if ( max_decision_level < level[ v ] )
      max_decision_level = level[ v ];
  }
#endif
}
Beispiel #23
0
void Egraph::expEnqueueArguments( Enode * x, Enode * y )
{
    assert( x->isTerm( ) );
    assert( y->isTerm( ) );
    assert( x->getArity( ) == y->getArity( ) );
    // No explanation needed if they are the same
    if ( x == y )
        return;

    // Simple explanation if they are arity 0 terms
    if ( x->getArity( ) == 0 )
    {
        exp_pending.push_back( x );
        exp_pending.push_back( y );
        return;
    }
    // Otherwise they are the same function symbol
    // Recursively enqueue the explanations for the args
    assert( x->getCar( ) == y->getCar( ) );
    Enode * xptr = x->getCdr( );
    Enode * yptr = y->getCdr( );
    while ( !xptr->isEnil( ) )
    {
        exp_pending.push_back( xptr->getCar( ) );
        exp_pending.push_back( yptr->getCar( ) );
        xptr = xptr->getCdr( );
        yptr = yptr->getCdr( );
    }
    // Check both lists have the same length
    assert( yptr->isEnil( ) );
}
Beispiel #24
0
dreal_expr dreal_mk_real_var(dreal_context c, char const * s , double lb, double ub) {
  assert(c);
  assert(s);
  OpenSMTContext * c_ = static_cast<OpenSMTContext *>(c);
  OpenSMTContext & context = *c_;
  Snode * sort = context.mkSortReal();
  context.DeclareFun(s, sort);
  Enode * res = context.mkVar(s, true);
  res->setDomainLowerBound(lb);
  res->setDomainUpperBound(ub);
  res->setValueLowerBound(lb);
  res->setValueUpperBound(ub);
  return static_cast<void *>(res);
}
Beispiel #25
0
//
// 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;
    }
}
Beispiel #26
0
opensmt_expr opensmt_mk_int_var( opensmt_context c, char const * s , long lb, long ub)
{
  assert( c );
  assert( s );
  OpenSMTContext * c_ = static_cast< OpenSMTContext * >( c );
  OpenSMTContext & context = *c_;
  Snode * sort = context.mkSortInt( );
  context.DeclareFun( s, sort );
  Enode * res = context.mkVar( s, true );
  res->setDomainLowerBound(lb);
  res->setDomainUpperBound(ub);
  res->setValueLowerBound(lb);
  res->setValueUpperBound(ub);
  return static_cast< void * >( res );
}
Beispiel #27
0
//
// Give the formula to the solver
//
bool Cnfizer::giveToSolver( Enode * f )
{
  vector< Enode * > clause;
  //
  // A unit clause
  //
  if ( f->isLit( ) )
  {
    clause.push_back( f );
#ifdef PRODUCE_PROOF
    if ( config.produce_inter > 0 )
      return solver.addSMTClause( clause, current_partitions );
#endif
    return solver.addSMTClause( clause );
  }
  //
  // A clause
  //
  if ( f->isOr( ) )
  {
    vector< Enode * > lits;
    retrieveClause( f, lits );
    for ( unsigned i = 0 ; i < lits.size( ) ; i ++ )
    {
      Enode * arg = lits[ i ];
      assert( arg->isLit( ) );
      clause.push_back( arg );
    }
#ifdef PRODUCE_PROOF
    if ( config.produce_inter > 0 )
      return solver.addSMTClause( clause, current_partitions );
    return solver.addSMTClause( clause );
#else
    return solver.addSMTClause( clause );
#endif
  }
  //
  // Conjunction
  //
  assert( f->isAnd( ) );
  vector< Enode * > conj;
  retrieveTopLevelFormulae( f, conj );
  bool result = true;
  for ( unsigned i = 0 ; i < conj.size( ) && result ; i ++ )
    result = giveToSolver( conj[ i ] );

  return result;
}
Beispiel #28
0
//
// Retrieve a clause
//
void Cnfizer::retrieveClause( Enode * f, vector< Enode * > & clause )
{
  assert( f->isLit( ) || f->isOr( ) );

  if ( f->isLit( ) )
  {
    clause.push_back( f );
  }
  else if ( f->isOr( ) )
  {
    for ( Enode * list = f->getCdr( ) ;
          list != egraph.enil ;
          list = list->getCdr( ) )
      retrieveClause( list->getCar( ), clause );
  }
}
Beispiel #29
0
//
// Retrieve conjuncts
//
void Cnfizer::retrieveConjuncts( Enode * f, vector< Enode * > & conjuncts )
{
  assert( f->isLit( ) || f->isAnd( ) );

  if ( f->isLit( ) )
  {
    conjuncts.push_back( f );
  }
  else if ( f->isAnd( ) )
  {
    for ( Enode * list = f->getCdr( ) ;
          list != egraph.enil ;
          list = list->getCdr( ) )
      retrieveConjuncts( list->getCar( ), conjuncts );
  }
}
Beispiel #30
0
dreal_expr dreal_mk_forall(dreal_context c, dreal_expr * varlist, unsigned n, dreal_expr body) {
  assert(c);
  OpenSMTContext * c_ = static_cast<OpenSMTContext *>(c);
  OpenSMTContext & context = *c_;
  vector<pair<string, Snode *>> sorted_var_list;
  for (unsigned i = 0; i <n; ++i) {
      dreal_expr var = varlist[i];
      Enode * e = static_cast<Enode*>(var);
      Snode * sort = e->getSort();
      string name = e->getCar()->getNameFull();
      sorted_var_list.push_back(make_pair(name, sort));
  }
  Enode * e_body = static_cast<Enode*>(body);
  Enode * res = context.mkForall(sorted_var_list, e_body);
  return static_cast<void *>(res);
}