Clause* Component::inferFalsityOfUnfoundedAtoms() { Var variable; do { variable = unfoundedSet.back(); setFounded( variable ); if( solver.isTrue( variable ) ) { conflict = variable; return handleConflict(); } unfoundedSet.pop_back(); getGUSData( variable ).removeFromUnfoundedSet(); if( solver.isFalse( variable ) ) continue; Clause* loopFormulaPointer = new Clause(); Clause& loopFormula = *loopFormulaPointer; loopFormula.copyLiterals( *clauseToPropagate ); if( solver.glucoseHeuristic() ) loopFormula.setLbd( clauseToPropagate->lbd() ); loopFormula.addLiteral( Literal( variable, NEGATIVE ) ); unsigned int size = loopFormula.size(); if( size >= 2 ) { loopFormula.swapLiterals( 0, size - 1 ); loopFormula.swapLiterals( 1, size - 1 ); } trace_msg( unfoundedset, 2, "Adding loop formula: " << loopFormula ); loopFormula.setLearned(); solver.onLearningALoopFormulaFromGus(); return loopFormulaPointer; } while( !unfoundedSet.empty() ); return NULL; }
/*_________________________________________________________________________________________________ | | 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* Solver::propagate() { Clause* confl = NULL; int num_props = 0; while (qhead < trail.size()){ const Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. vec<Watched>& ws = watches[toInt(p)]; Watched *i, *j, *end; num_props++; #ifdef RESTORE printf("Propagating lit "); printLit(p); printf(" number: %d\n", toInt(p)); #endif const vec<Binaire> & wbin = watchesBin[toInt(p)]; bogoProps += wbin.size(); for(int k = 0;k<wbin.size();k++) { Lit imp = wbin[k].implied; if(value(imp) == l_False) { if (handleConflict(*wbin[k].clause, num_props)) return wbin[k].clause; } if(value(imp) == l_Undef) { uncheckedEnqueue(imp,wbin[k].clause); } } if (backup.running && watchBackup.flags[toInt(p)] == false ) { watchBackup.ws[toInt(p)] = watches[toInt(p)]; watchBackup.flags[toInt(p)] = true; watchBackup.changed.push(toInt(p)); } bogoProps += ws.size(); for (i = j = (Watched*)ws, end = i + ws.size(); i != end;){ if(value(i->blocked)==l_True) { // Clause is sat *j++ = *i++; continue; } Lit bl = i->blocked; Clause& c = *(i->wcl); i++; bogoProps += 5; if (backup.running && backup.touchedClauses.find(&c) == backup.touchedClauses.end() ) { backup.touchedClauses.insert(&c); c.saveLiterals(); } // 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->wcl = &c; j->blocked = first; j++; }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; const int wsNum = toInt(~c[1]); //Save ws before changing it if (backup.running && watchBackup.flags[wsNum] == false ) { watchBackup.ws[wsNum] = watches[wsNum]; watchBackup.flags[wsNum] = true; watchBackup.changed.push(wsNum); } watches[wsNum].push(); watches[wsNum].last().wcl = &c; watches[wsNum].last().blocked = c[0]; goto FoundWatch; } // Did not find watch -- clause is unit under assignment: j->wcl = &c; j->blocked = bl; j++; if (value(first) == l_False){ if (handleConflict(c, num_props)) { confl = &c; qhead = trail.size(); // Copy the remaining watches: while (i < end) *j++ = *i++; } else { goto FoundWatch; } } else { uncheckedEnqueue(first, &c); #ifdef DYNAMICNBLEVEL if(backup.stage == 0 && c.learnt() && c.activity()>2 ) { MYFLAG++; int nblevels =0; for(int i=0;i<c.size();i++) { int l = level[var(c[i])]; if (permDiff[l] != MYFLAG) { permDiff[l] = MYFLAG; nblevels++; } } if(nblevels+1<c.activity()) { c.setActivity(nblevels); } } #endif } } FoundWatch:; } ws.shrink(i - j); } propagations+=num_props; simpDB_props-=num_props; return confl; }
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; }