Example #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 );
}
Example #2
0
bool SimpSMTSolver::addSMTClause( vector< Enode * > & smt_clause
#ifdef PRODUCE_PROOF
                                , const ipartitions_t in 
#endif
				)
{
  assert( config.sat_preprocess_theory == 0 );
  vec< Lit > sat_clause;

#ifdef PRODUCE_PROOF
  assert( config.produce_inter == 0 || in != 0 );
#endif

  for ( vector< Enode * >::iterator it = smt_clause.begin( ) ;
      it != smt_clause.end( ) ;
      it ++ )
  {
    Enode * e = *it;
    // Do not add false literals
    if ( e->isFalse( ) ) continue;
    // If a literal is true, the clause is true
    if ( e->isTrue( ) )
      return true;

    // Keep track of atoms seen, as they may
    // be interface equalities to skip later
    if ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
      atoms_seen.insert( e );

    Lit l = theory_handler->enodeToLit( e );
    sat_clause.push( l );
  }

#ifdef PRODUCE_PROOF
  return addClause( sat_clause, in );
#else
  return addClause( sat_clause );
#endif
}
Example #3
0
void OpenSMTContext::staticCheckSAT( )
{
  if ( config.verbosity > 1 )
    cerr << "# OpenSMTContext::Statically Checking" << endl;

  // Retrieve the formula
  Enode * formula = egraph.getUncheckedAssertions( );

  if ( config.dump_formula != 0 )
    egraph.dumpToFile( "original.smt2", formula );

  if ( formula == NULL )
    opensmt_error( "formula undefined" );

  if ( config.logic == UNDEF )
    opensmt_error( "unable to determine logic" );

  // Removes ITEs if there is any
  if ( egraph.hasItes( ) )
  {
#ifdef PRODUCE_PROOF
    if ( config.produce_inter > 0 )
      opensmt_error( "Interpolation not supported for ite construct" );
#endif
    ExpandITEs expander( egraph, config );
    formula = expander.doit( formula );

    if ( config.dump_formula != 0 )
      egraph.dumpToFile( "ite_expanded.smt2", formula );
  }

  // Gather interface terms for DTC
  if ( ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
    // Don't use with DTC of course
    && config.sat_lazy_dtc == 1
    // Don't use when dumping interpolants
    && config.sat_dump_rnd_inter == 0 )
  {
    Purify purifier( egraph, config );
    formula = purifier.doit( formula );

    if ( config.dump_formula != 0 )
      egraph.dumpToFile( "purified.smt2", formula );
  }

  // Ackermanize away functional symbols
  if ( ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
    // Don't use with DTC of course
    && config.sat_lazy_dtc == 0
    // Don't use when dumping interpolants
    && config.sat_dump_rnd_inter == 0 )
  {
    Ackermanize ackermanizer( egraph, config );
    formula = ackermanizer.doit( formula );

    if ( config.dump_formula != 0 )
      egraph.dumpToFile( "ackermanized.smt2", formula );
  }

  // Artificially create a boolean
  // abstraction, if necessary
  if ( config.logic == QF_BV )
  {
    BVBooleanize booleanizer( egraph, config );
    formula = booleanizer.doit( formula );
  }

  // Top-Level Propagator. It also canonize atoms
  TopLevelProp propagator( egraph, config );
  formula = propagator.doit( formula );

  // Applies array axioms where possible
  if( config.logic == QF_AX )
  {
    ArraySimplify simplifier( egraph, config );
    formula = simplifier.doit( formula );
  }

  // Convert RDL into IDL, also compute if GMP is needed
  if ( config.logic == QF_RDL )
  {
    DLRescale rescaler( egraph, config );
    rescaler.doit( formula );
  }

  // For static checking, make sure that if DTC is used
  // then incrementality is enabled
  if ( ( config.logic == QF_UFIDL
      || config.logic == QF_UFLRA )
      && config.sat_lazy_dtc != 0 )
  {
    config.incremental = 1;
  }

  if ( config.dump_formula != 0 )
    egraph.dumpToFile( "presolve.smt2", formula );

  // Solve only if not simplified already
  if ( formula->isTrue( ) )
  {
    state = l_True;
  }
  else if ( formula->isFalse( ) )
  {
    state = l_False;
  }
  else
  {
    // Initialize theory solvers
    egraph.initializeTheorySolvers( &solver );

    // Compute polarities
    egraph.computePolarities( formula );

    // CNFize the input formula and feed clauses to the solver
    state = cnfizer.cnfizeAndGiveToSolver( formula );

    // Solve
    if ( state == l_Undef )
    {
      state = solver.smtSolve( config.sat_preprocess_booleans != 0
                            || config.sat_preprocess_theory   != 0 );
    }

    // If computation has been stopped, return undef
    if ( opensmt::stop ) state = l_Undef;
  }
}
Example #4
0
Var CoreSMTSolver::generateNextEij( )
{
  if ( egraph.getInterfaceTermsNumber( ) == 0 )
    return var_Undef;

  assert( config.sat_lazy_dtc != 0 );
  Var v = var_Undef;
  lbool pol = l_Undef;
  while ( v == var_Undef )
  {
    // Already returned all the possible eij
    if ( next_it_i == egraph.getInterfaceTermsNumber( ) - 1
      && next_it_j == egraph.getInterfaceTermsNumber( ) )
      return var_Undef;

    // Get terms
    // Enode * i = interface_terms[ next_it_i ];
    // Enode * j = interface_terms[ next_it_j ];
    Enode * i = egraph.getInterfaceTerm( next_it_i );
    Enode * j = egraph.getInterfaceTerm( next_it_j );
    // Increase counters
    next_it_j ++;
    if ( next_it_j == next_it_i ) next_it_j ++;
    // if ( next_it_j == static_cast< int >( interface_terms.size( ) ) )
    if ( next_it_j == egraph.getInterfaceTermsNumber( ) )
    {
      next_it_i ++;
      next_it_j = next_it_i + 1;
    }
    // No need to create eij if both numbers,
    // it's either trivially true or false
    if ( i->isConstant( )
      && j->isConstant( ) )
      continue;

    if ( config.logic == QF_UFLRA
      || config.logic == QF_UFIDL )
    {
      //
      // Since arithmetic solvers do not
      // understand equalities, produce
      // the splitted versions of equalities
      // and add linking clauses
      //
      Enode * eij = egraph.mkEq( egraph.cons( i, egraph.cons( j ) ) );

      if ( config.verbosity > 2 )
        cerr << "# CoreSMTSolver::Adding eij: " << eij << endl;

      if ( eij->isTrue( ) || eij->isFalse( ) ) continue;
      // Canonize
      LAExpression la( eij );
      Enode * eij_can = la.toEnode( egraph );
      // Continue if already generated equality
      // if ( !interface_equalities.insert( eij_can ).second ) continue;
      if ( eij_can->isTrue( ) || eij_can->isFalse( ) ) continue;
      v = theory_handler->enodeToVar( eij );
      // Created one equality that is already assigned
      // Skip it
      if ( value( v ) != l_Undef )
      {
        v = var_Undef;
        continue;
      }
      // Get lhs and rhs
      Enode * lhs = eij_can->get1st( );
      Enode * rhs = eij_can->get2nd( );
      Enode * leq = egraph.mkLeq( egraph.cons( lhs, egraph.cons( rhs ) ) );
      // Canonize lhs
      LAExpression b( leq );
      leq = b.toEnode( egraph );
      // Canonize rhs
      Enode * geq = egraph.mkGeq( egraph.cons( lhs, egraph.cons( rhs ) ) );
      LAExpression c( geq );
      geq = c.toEnode( egraph );
      // Add clause ( !x=y v x<=y )
      vector< Enode * > clause;
      clause.push_back( egraph.mkNot( egraph.cons( eij ) ) );
      clause.push_back( leq );
      addSMTAxiomClause( clause );
      // Add clause ( !x=y v x>=y )
      clause.pop_back( );
      clause.push_back( geq );
      addSMTAxiomClause( clause );
      // Add clause ( x=y v !x>=y v !x<=y )
      clause.clear( );
      clause.push_back( eij );
      clause.push_back( egraph.mkNot( egraph.cons( leq ) ) );
      clause.push_back( egraph.mkNot( egraph.cons( geq ) ) );
      addSMTAxiomClause( clause );

      pol = theory_handler->evaluate( eij );
      if ( pol == l_Undef ) pol = theory_handler->evaluate( leq );
      if ( pol == l_Undef ) pol = theory_handler->evaluate( geq );
    }
    else
    {
      Enode * eij = egraph.mkEq( egraph.cons( i, egraph.cons( j ) ) );
      // Continue if already generated equality
      if ( !interface_equalities.insert( eij ).second ) continue;
      if ( eij->isTrue( ) || eij->isFalse( ) ) continue;
      // Add new atom and get variable
      v = theory_handler->enodeToVar( eij );
      // Initialize congruence data structure
      egraph.initializeCong( eij );
    }
  }
#ifdef STATISTICS
  ie_generated ++;
#endif
  assert( v != var_Undef );
  assert( polarity.size( ) > v );
  // Assign to false first. We merge the least possible
  // Alternatively we can merge the most, or
  polarity[ v ] = ( pol == l_True
                    ? false
                    : ( pol == l_False
                        ? true
                        : true ) );

  return v;
}