void HCComponent::computeReasonForUnfoundedAtom( Var v, Learning& learning ) { trace_msg( modelchecker, 2, "Processing variable " << solver.getLiteral( v ) ); vector< Clause* >& definingRules = getGUSData( v ).definingRulesForNonHCFAtom; for( unsigned int i = 0; i < definingRules.size(); i++ ) { Clause* rule = definingRules[ i ]; trace_msg( modelchecker, 3, "Processing rule " << *rule ); bool skipRule = false; unsigned int min = UINT_MAX; unsigned int pos = UINT_MAX; for( unsigned int j = 0; j < rule->size(); j++ ) { Literal lit = rule->getAt( j ); if( isInUnfoundedSet( lit.getVariable() ) ) { trace_msg( modelchecker, 4, "Literal " << lit << " is in the unfounded set" ); if( lit.isHeadAtom() ) { trace_msg( modelchecker, 5, "Skip " << lit << " because it is in the head" ); continue; } else if( lit.isPositiveBodyLiteral() ) { trace_msg( modelchecker, 5, "Skip rule because of an unfounded positive body literal: " << lit ); skipRule = true; break; } } //This should be not true anymore. // assert( !isInUnfoundedSet( lit.getVariable() ) ); //If the variable is in the HCC component and it is undefined can be a reason during partial checks if( solver.isUndefined( lit ) && solver.getHCComponent( lit.getVariable() ) == this && ( lit.isNegativeBodyLiteral() || lit.isHeadAtom() ) ) { if( pos == UINT_MAX ) pos = j; continue; } if( !solver.isTrue( lit ) ) { trace_msg( modelchecker, 5, "Skip " << lit << " because it is not true" ); continue; } unsigned int dl = solver.getDecisionLevel( lit ); if( dl == 0 ) { trace_msg( modelchecker, 5, "Skip rule because of a literal of level 0: " << lit ); skipRule = true; break; } if( dl < min ) { min = dl; pos = j; } } if( !skipRule ) { assert_msg( pos < rule->size(), "Trying to access " << pos << " in " << *rule ); trace_msg( modelchecker, 4, "The reason is: " << rule->getAt( pos ) ); learning.onNavigatingLiteralForUnfoundedSetLearning( rule->getAt( pos ).getOppositeLiteral() ); } } }
Clause* Component::getClauseToPropagate( Learning& learning ) { begin:; if( unfoundedSet.empty() ) { assert( !done ); clauseToPropagate = NULL; assert( !variablesWithoutSourcePointer.empty() || checkSourcePointersStatus() ); assert( !variablesWithoutSourcePointer.empty() || checkFoundedStatus() ); if( variablesWithoutSourcePointer.empty() ) return NULL; if( first ) computeGUSFirst(); else computeGUS(); assert( !unfoundedSet.empty() || variablesWithoutSourcePointer.empty() ); assert( !unfoundedSet.empty() || checkSourcePointersStatus() ); assert( !unfoundedSet.empty() || checkFoundedStatus() ); if( unfoundedSet.empty() ) return NULL; assert( clauseToPropagate == NULL ); clauseToPropagate = learning.learnClausesFromUnfoundedSet( unfoundedSet ); clausesToDelete.push_back( clauseToPropagate ); trace_msg( unfoundedset, 2, "Reasons of unfounded sets: " << *clauseToPropagate ); goto begin; } else { assert( clauseToPropagate != NULL ); if( done ) { Var variable = updateClauseToPropagate(); if( variable == 0 ) { assert( unfoundedSet.empty() ); done = 0; clauseToPropagate = NULL; goto begin; } Clause* c = clauseToPropagate; if( solver.isTrue( variable ) ) { assert( c->getAt( 0 ) == Literal( variable, FALSE ) ); assert( solver.getDecisionLevel( variable ) == solver.getCurrentDecisionLevel() ); c = new Clause( clauseToPropagate->size() ); c->copyLiterals( *clauseToPropagate ); if( solver.glucoseHeuristic() ) c->setLbd( clauseToPropagate->lbd() ); c->setLearned(); reset(); assert( !done ); assert( clauseToPropagate == NULL ); } return c; } if( conflict != 0 ) return handleConflict(); //Keep small clauses if( clauseToPropagate->size() <= 3 || unfoundedSet.size() == 1 ) { Clause* c = inferFalsityOfUnfoundedAtoms(); if( c != NULL ) return c; goto begin; } assert( unfoundedSet.size() >= 2 ); assert( clauseToPropagate->size() > 3 ); assert( !done ); clauseToPropagate->addLiteralInLearnedClause( Literal::null ); clauseToPropagate->swapLiterals( 0, 1 ); clauseToPropagate->swapLiterals( 0, clauseToPropagate->size() - 1 ); // assert( unfoundedSet.empty() ); // clauseToPropagate = NULL; done = 1; goto begin; // return NULL; } goto begin; }