// // 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 }
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( ); }
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; }
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; }
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 }
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( ); }
/*_________________________________________________________________________________________________ | | 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; }