예제 #1
0
파일: THandler.C 프로젝트: clhuang/dreal3
//
// 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
}
예제 #2
0
파일: THandler.C 프로젝트: clhuang/dreal3
void THandler::backtrack( )
{
  // Undoes the state of theory atoms if needed
  while ( (int)stack.size( ) > trail.size( ) )
  {
    Enode * e = stack.back( );
    stack.pop_back( );

    // It was var_True or var_False
    if ( e == NULL )
      continue;

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

    core_solver.popBacktrackPoint( );

    assert( e->isTAtom( ) );
    assert( e->hasPolarity( ) );
    assert( e->getPolarity( ) == l_True
         || e->getPolarity( ) == l_False );
    // Reset polarity
    e->resetPolarity( );
    assert( !e->hasPolarity( ) );
  }
  checked_trail_size = stack.size( );
}
예제 #3
0
파일: THandler.C 프로젝트: clhuang/dreal3
bool THandler::assertLits( )
{
  bool res = true;

  assert( checked_trail_size == stack.size( ) );
  assert( (int)stack.size( ) <= trail.size( ) );
  DREAL_LOG_DEBUG << "THandler::assertLits()" << endl;

  for ( int i = checked_trail_size ; i < trail.size( ) && res ; i ++ )
  {
    const Lit l = trail[ i ];
    const Var v = var( l );

    Enode * e = var_to_enode[ v ];
    assert( v <= 1 || e );
    stack.push_back( e );

    if ( v == var_True || v == var_False )
    {
      assert( v != var_True  || sign( l ) == false );
      assert( v != var_False || sign( l ) == true );
      continue;
    }

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

    // Push backtrack point
    core_solver.pushBacktrackPoint( );

    assert( !e->hasPolarity( ) );
    DREAL_LOG_DEBUG << "THandler::assertLits(): asserting " << e << " with sign = " << sign(l) << endl;
    e->setPolarity( (sign( l ) ? l_False : l_True) );
    assert( e->hasPolarity( ) );
    res = core_solver.assertLit( e );

    if ( !res && config.certification_level > 2 )
      verifyCallWithExternalTool( res, i );
  }

  checked_trail_size = stack.size( );
  assert( !res || trail.size( ) == (int)stack.size( ) );

  return res;
}
예제 #4
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;
}
예제 #5
0
void CostSolver::check_status()
{
#ifndef NDEBUG
  for ( costfuns_t::iterator it = costfuns_.begin();
        it != costfuns_.end();
        ++it )
  {
    costfun & fun = **it;
    codomain slack = 0;
    for ( incurnode * n=fun.unassigned.head; n; n=n->next )
    {
      assert( !n->atom->hasPolarity() );
      if ( n->next )
      {
        assert( n != n->next );
        if ( n->cost > n->next->cost )
        {
          cout << n->cost << " > " << n->next->cost << endl;
        }
        assert( n->cost <= n->next->cost );
        assert( n->next->prev == n );
      }
      if ( n->prev )
      {
        assert( n->prev != n );
        assert( n->prev->next == n );
      }
      slack += get_incurred( n->atom );
    }
    assert( slack == fun.slack );
    {
      codomain incurred = 0;
      for ( costfun::nodes_t::iterator it = fun.assigned.begin();
            it != fun.assigned.end();
            ++it )
      {
        incurnode * node = *it;
        assert( node->atom->hasPolarity() );
        if ( node->atom->getPolarity() == l_True )
        {
          incurred += get_incurred( node->atom );
        }
      }
      if ( fun.incurred != incurred )
      {
        if ( conflict_ )
        {
          cout << "conflict = " << conflict_ << endl;
        }
        cout << "incurred = " << incurred << endl;
        print_status( cout, fun );
      }
      assert( fun.incurred == incurred );
    }
  }
  if ( conflict_ )
  {
    cout << "ct conflict " << conflict_ << endl;
    costfun & fun = *nodemap_.find( conflict_ )->second;
    codomain incurred = 0;
    Enode * upper_bound = 0;
    Enode * lower_bound = 0;
    for ( vector<Enode*>::iterator it = explanation.begin();
          it != explanation.end();
          ++it )
    {
      Enode * atom = *it;
      assert( atom->hasPolarity() );
      if ( atom->isCostIncur() )
      {
        if ( atom->getPolarity() == l_True )
        {
          incurred += get_incurred( atom );
        }
      }
      if ( atom->isCostBound() )
      {
        if ( atom->getPolarity() == l_True )
        {
          assert( !upper_bound );
          upper_bound = atom;
        }
        else
        {
          assert( !lower_bound );
          assert( atom->getPolarity() == l_False );
          lower_bound = atom;
        }
      }
    }
    if ( !fun.lowerbound.empty() && fun.upperbound.empty() )
    {
      assert( fun.incurred + fun.slack < get_bound( fun.lowerbound.top() ) );
    }
    if ( fun.lowerbound.empty() && !fun.upperbound.empty() )
    {
      assert( fun.incurred >= get_bound( fun.upperbound.top() ) );
      assert( incurred >= get_bound( upper_bound ) );
    }
  }
#endif
}
예제 #6
0
파일: THandler.C 프로젝트: clhuang/dreal3
void THandler::getReason( Lit l, vec< Lit > & reason )
{
#if LAZY_COMMUNICATION
  assert( checked_trail_size == stack.size( ) );
  assert( static_cast< int >( checked_trail_size ) == trail.size( ) );
#else
#endif

  Var v = var(l);
  Enode * e = varToEnode( v );

  // It must be a TAtom and already disabled
  assert( e->isTAtom( ) );
  assert( !e->hasPolarity( ) );
  assert( e->isDeduced( ) );
  assert( e->getDeduced( ) != l_Undef );           // Last assigned deduction
#if LAZY_COMMUNICATION
  assert( e->getPolarity( ) != l_Undef );          // Last assigned polarity
  assert( e->getPolarity( ) == e->getDeduced( ) ); // The two coincide
#else
#endif

  core_solver.pushBacktrackPoint( );

  // Assign reversed polarity temporairly
  e->setPolarity( e->getDeduced( ) == l_True ? l_False : l_True );
  // Compute reason in whatever solver
  const bool res = core_solver.assertLit( e, true ) &&
                   core_solver.check( true );
  // Result must be false
  if ( res )
  {
    cout << endl << "unknown" << endl;
    exit( 1 );
  }

  // Get Explanation
  vector< Enode * > & explanation = core_solver.getConflict( true );

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

  // Reserve room for implied lit
  reason.push( lit_Undef );
  // Copy explanation

  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 );

    // Toggle polarity for deduced literal
    if ( e == ei )
    {
      assert( e->getDeduced( ) != l_Undef );           // But still holds the deduced polarity
      // The deduced literal must have been pushed
      // with the the same polarity that has been deduced
      reason[ 0 ] = Lit( v, !negate );
    }
    else
    {
      assert( ei->hasPolarity( ) );                    // Lit in explanation is active
      // This assertion might fail if in your theory solver
      // you do not skip deduced literals during assertLit
      //
      // TODO: check ! It could be deduced: by another solver
      // For instance BV found conflict and ei was deduced by EUF solver
      //
      // assert( !ei->isDeduced( ) );                     // and not deduced
      Lit l = Lit( v, !negate );
      reason.push( l );
    }
  }

  core_solver.popBacktrackPoint( );

  // Resetting polarity
  e->resetPolarity( );
}
예제 #7
0
/*_________________________________________________________________________________________________
|
|  propagate : [void]  ->  [Clause*]
|  
|  Description:
|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
|    otherwise NULL.
|  
|    Post-conditions:
|      * the propagation queue is empty, even if there was a conflict.
|________________________________________________________________________________________________@*/
Clause* MiniSATP::propagate(const bool deduce)
{
    Clause* confl     = NULL;
    int     num_props = 0;

    while (qhead < trail.size()){
        Lit             p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
        vec<Clause*>&  ws  = watches[toInt(p)];
        Clause         **i, **j, **end;
        num_props++;

        for (i = j = (Clause**)ws, end = i + ws.size();  i != end;){
            Clause& c = **i++;

            // Make sure the false literal is data[1]:
            Lit false_lit = ~p;
            if (c[0] == false_lit)
                c[0] = c[1], c[1] = false_lit;

            assert(c[1] == false_lit);

            // If 0th watch is true, then clause is already satisfied.
            Lit first = c[0];
            if (value(first) == l_True){
                *j++ = &c;
            }else{
                // Look for new watch:
                for (int k = 2; k < c.size(); k++)
                    if (value(c[k]) != l_False){
                        c[1] = c[k]; c[k] = false_lit;
                        watches[toInt(~c[1])].push(&c);
                        goto FoundWatch; }

                // Did not find watch -- clause is unit under assignment:
                *j++ = &c;
                if (value(first) == l_False){
                    confl = &c;
                    qhead = trail.size();
                    // Copy the remaining watches:
                    while (i < end)
                        *j++ = *i++;
                }
		else
		{
		  uncheckedEnqueue(first, &c);

//=================================================================================================
// Added Code

		  assert( (int)var_to_enode.size( ) > var( first ) );
		  if ( deduce && var_to_enode[ var( first ) ] != NULL )
		  {
		    Enode * e = var_to_enode[ var( first ) ];
		    if ( !e->hasPolarity( ) && !e->isDeduced( ) )
		    {
		      e->setDeduced( sign( first ), solver_id );
		      deductions.push_back( e );
		    }
		  }

// Added Code
//=================================================================================================

		}
            }
        FoundWatch:;
        }
        ws.shrink(i - j);
    }
    propagations += num_props;
    simpDB_props -= num_props;

    return confl;
}