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