satelite.cpp
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2006-2010, Benjamin Kaufmann
00003 // 
00004 // This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/ 
00005 // 
00006 // Clasp is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // Clasp is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with Clasp; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 //
00020 #include <clasp/satelite.h>
00021 #include <clasp/clause.h>
00022 
00023 #ifdef _MSC_VER
00024 #pragma warning (disable : 4200) // nonstandard extension used : zero-sized array
00025 #endif
00026 namespace Clasp { namespace SatElite {
00028 // SatElite preprocessing
00029 //
00031 SatElite::SatElite() 
00032         : occurs_(0)
00033         , elimHeap_(LessOccCost(occurs_))
00034         , qFront_(0)
00035         , facts_(0) {
00036 }
00037 
00038 SatElite::~SatElite() {
00039         SatElite::doCleanUp();
00040 }
00041 
00042 void SatElite::reportProgress(Progress::EventOp id, uint32 curr, uint32 max) {
00043         ctx_->report(Progress(this, id, curr, max));
00044 }
00045 
00046 Clasp::SatPreprocessor* SatElite::clone() {
00047         SatElite* cp = new SatElite();
00048         return cp;
00049 }
00050 
00051 void SatElite::doCleanUp() {
00052         delete [] occurs_;  occurs_ = 0; 
00053         ClauseList().swap(resCands_);
00054         VarVec().swap(posT_);
00055         VarVec().swap(negT_);
00056         LitVec().swap(resolvent_);
00057         VarVec().swap(queue_);
00058         elimHeap_.clear();
00059         qFront_ = facts_ = 0;
00060 }
00061 
00062 SatPreprocessor::Clause* SatElite::popSubQueue() {
00063         if (Clause* c = clause( queue_[qFront_++] )) {
00064                 c->setInQ(false);
00065                 return c;
00066         }
00067         return 0;
00068 }
00069 
00070 void SatElite::addToSubQueue(uint32 clauseId) {
00071         assert(clause(clauseId) != 0);
00072         if (!clause(clauseId)->inQ()) {
00073                 queue_.push_back(clauseId);
00074                 clause(clauseId)->setInQ(true);
00075         }
00076 }
00077 
00078 void SatElite::attach(uint32 clauseId, bool initialClause) {
00079         Clause& c = *clause(clauseId);
00080         c.abstraction() = 0;
00081         for (uint32 i = 0; i != c.size(); ++i) {
00082                 Var v = c[i].var();
00083                 occurs_[v].add(clauseId, c[i].sign());
00084                 occurs_[v].unmark();
00085                 c.abstraction() |= Clause::abstractLit(c[i]);
00086                 if (elimHeap_.is_in_queue(v)) {
00087                         elimHeap_.decrease(v);
00088                 }
00089                 else if (initialClause) {
00090                         updateHeap(v);
00091                 }
00092         }
00093         occurs_[c[0].var()].addWatch(clauseId);
00094         addToSubQueue(clauseId);
00095         stats.clAdded += !initialClause;
00096 }
00097 
00098 void SatElite::detach(uint32 id) {
00099         Clause& c  = *clause(id);
00100         occurs_[c[0].var()].removeWatch(id);
00101         for (uint32 i = 0; i != c.size(); ++i) {
00102                 Var v = c[i].var();
00103                 occurs_[v].remove(id, c[i].sign(), false);
00104                 updateHeap(v);
00105         }
00106         destroyClause(id);
00107 }
00108 
00109 void SatElite::bceVeRemove(uint32 id, bool freeId, Var ev, bool blocked) {
00110         Clause& c  = *clause(id);
00111         occurs_[c[0].var()].removeWatch(id);
00112         uint32 pos = 0;
00113         for (uint32 i = 0; i != c.size(); ++i) {
00114                 Var v = c[i].var();
00115                 if (v != ev) {
00116                         occurs_[v].remove(id, c[i].sign(), freeId);
00117                         updateHeap(v);
00118                 }
00119                 else {
00120                         occurs_[ev].remove(id, c[i].sign(), false);
00121                         pos = i;
00122                 }
00123         }
00124         std::swap(c[0], c[pos]);
00125         c.setMarked(blocked);
00126         eliminateClause(id);
00127 }
00128 
00129 bool SatElite::initPreprocess(Options& opts) {
00130         reportProgress(Progress::event_algorithm, 0,100);
00131         opts_     = &opts;
00132         occurs_   = new OccurList[ctx_->numVars()+1];
00133         qFront_   = 0;
00134         occurs_[0].bce = (opts.type == Options::sat_pre_full);
00135         return true;
00136 }
00137 bool SatElite::doPreprocess() {
00138         // 1. add clauses to occur lists
00139         for (uint32 i  = 0, end = numClauses(); i != end; ++i) {
00140                 attach(i, true);
00141         }
00142         // 2. remove subsumed clauses, eliminate vars by clause distribution
00143         timeout_ = opts_->limTime ? time(0) + opts_->limTime : std::numeric_limits<std::time_t>::max();
00144         for (uint32 i = 0, end = opts_->limIters ? opts_->limIters : UINT32_MAX; queue_.size()+elimHeap_.size() > 0; ++i) {
00145                 if (!backwardSubsume())   { return false; }
00146                 if (timeout() || i == end){ break;        }
00147                 if (!eliminateVars())     { return false; }
00148         }
00149         reportProgress(Progress::event_algorithm, 100,100);
00150         return true;
00151 }
00152 
00153 // (Destructive) unit propagation on clauses.
00154 // Removes satisfied clauses and shortens clauses w.r.t. false literals.
00155 // Pre:   Assignment is propagated w.r.t other non-clause constraints
00156 // Post:  Assignment is fully propagated and no clause contains an assigned literal
00157 bool SatElite::propagateFacts() {
00158         Solver* s = ctx_->master();
00159         assert(s->queueSize() == 0);
00160         while (facts_ != s->numAssignedVars()) {
00161                 Literal l     = s->trail()[facts_++];
00162                 OccurList& ov = occurs_[l.var()];
00163                 ClRange cls   = occurs_[l.var()].clauseRange();
00164                 for (ClIter x = cls.first; x != cls.second; ++x) {
00165                         if      (clause(x->var()) == 0)          { continue; }
00166                         else if (x->sign() == l.sign())          { detach(x->var()); }
00167                         else if (!strengthenClause(x->var(), ~l)){ return false; }
00168                 }
00169                 ov.clear();
00170                 ov.mark(!l.sign());
00171         }
00172         assert(s->queueSize() == 0);
00173         return true;
00174 }
00175 
00176 // Backward subsumption and self-subsumption resolution until fixpoint
00177 bool SatElite::backwardSubsume() {
00178         if (!propagateFacts()) return false;
00179         while (qFront_ != queue_.size()) {
00180                 if ((qFront_ & 8191) == 0) {
00181                         if (timeout()) break;
00182                         if (queue_.size() > 1000) reportProgress(Progress::event_subsumption, qFront_, queue_.size());
00183                 }
00184                 if (peekSubQueue() == 0) { ++qFront_; continue; }
00185                 Clause& c = *popSubQueue();
00186                 // Try to minimize effort by testing against the var in c that occurs least often;
00187                 Literal best  = c[0];
00188                 for (uint32 i = 1; i < c.size(); ++i) {
00189                         if (occurs_[c[i].var()].numOcc() < occurs_[best.var()].numOcc()) {
00190                                 best  = c[i];
00191                         }
00192                 }
00193                 // Test against all clauses containing best
00194                 ClWList& cls  = occurs_[best.var()].refs;
00195                 Literal res   = negLit(0);
00196                 uint32  j     = 0;
00197                 // must use index access because cls might change!
00198                 for (uint32 i = 0, end = cls.left_size(); i != end; ++i) {
00199                         Literal cl      = cls.left(i);
00200                         uint32 otherId  = cl.var();
00201                         Clause* other   = clause(otherId);
00202                         if (other && other!= &c && (res = subsumes(c, *other, best.sign()==cl.sign()?posLit(0):best)) != negLit(0)) {
00203                                 if (res == posLit(0)) {
00204                                         // other is subsumed - remove it
00205                                         detach(otherId);
00206                                         other = 0;
00207                                 }
00208                                 else {
00209                                         // self-subsumption resolution; other is subsumed by c\{res} U {~res}
00210                                         // remove ~res from other, add it to subQ so that we can check if it now subsumes c
00211                                         res = ~res;
00212                                         occurs_[res.var()].remove(otherId, res.sign(), res.var() != best.var());
00213                                         updateHeap(res.var());
00214                                         if (!strengthenClause(otherId, res))              { return false; }
00215                                         if (res.var() == best.var() || !clause(otherId))  { other = 0; }
00216                                 }
00217                         }
00218                         if (other && j++ != i)  { cls.left(j-1) = cl; }
00219                 }
00220                 cls.shrink_left(cls.left_begin()+j);
00221                 occurs_[best.var()].dirty = 0;
00222                 assert(occurs_[best.var()].numOcc() == (uint32)cls.left_size());
00223                 if (!propagateFacts()) return false;
00224         }   
00225         queue_.clear();
00226         qFront_ = 0;
00227         return true;
00228 }
00229 
00230 // checks if 'c' subsumes 'other', and at the same time, if it can be used to 
00231 // simplify 'other' by subsumption resolution.
00232 // Return:
00233 //  - negLit(0) - No subsumption or simplification
00234 //  - posLit(0) - 'c' subsumes 'other'
00235 //  - l         - The literal l can be deleted from 'other'
00236 Literal SatElite::subsumes(const Clause& c, const Clause& other, Literal res) const {
00237         if (other.size() < c.size() || (c.abstraction() & ~other.abstraction()) != 0) {
00238                 return negLit(0);
00239         }
00240         if (c.size() < 10 || other.size() < 10) {
00241                 for (uint32 i = 0; i != c.size(); ++i) {
00242                         for (uint32 j = 0; j != other.size(); ++j) {
00243                                 if (c[i].var() == other[j].var()) {
00244                                         if (c[i].sign() == other[j].sign())     { goto found; }
00245                                         else if (res != posLit(0) && res!=c[i]) { return negLit(0); }
00246                                         res = c[i];
00247                                         goto found;
00248                                 }
00249                         }
00250                         return negLit(0); 
00251                 found:;
00252                 }
00253         }
00254         else {
00255                 markAll(&other[0], other.size());
00256                 for (uint32 i = 0; i != c.size(); ++i) {
00257                         if (occurs_[c[i].var()].litMark == 0) { res = negLit(0); break; }
00258                         if (occurs_[c[i].var()].marked(!c[i].sign())) {
00259                                 if (res != posLit(0)&&res!=c[i]) { res = negLit(0); break; }
00260                                 res = c[i];
00261                         }
00262                 }
00263                 unmarkAll(&other[0], other.size());
00264         }
00265         return res;
00266 }
00267 
00268 uint32 SatElite::findUnmarkedLit(const Clause& c, uint32 x) const {
00269         for (; x != c.size() && occurs_[c[x].var()].marked(c[x].sign()); ++x)
00270                 ;
00271         return x;
00272 }
00273 
00274 // checks if 'cl' is subsumed by one of the existing clauses and at the same time
00275 // strengthens 'cl' if possible.
00276 // Return:
00277 //  - true  - 'cl' is subsumed
00278 //  - false - 'cl' is not subsumed but may itself subsume other clauses
00279 // Pre: All literals of l are marked, i.e. 
00280 // for each literal l in cl, occurs_[l.var()].marked(l.sign()) == true
00281 bool SatElite::subsumed(LitVec& cl) {
00282         Literal l;
00283         uint32 x = 0;
00284         uint32 str = 0;
00285         LitVec::size_type j = 0;
00286         for (LitVec::size_type i = 0; i != cl.size(); ++i) {
00287                 l = cl[i];
00288                 if (occurs_[l.var()].litMark == 0) { --str; continue; }
00289                 ClWList& cls   = occurs_[l.var()].refs; // right: all clauses watching either l or ~l
00290                 WIter wj       = cls.right_begin();
00291                 for (WIter w = wj, end = cls.right_end(); w != end; ++w) {
00292                         Clause& c = *clause(*w);
00293                         if (c[0] == l)  {
00294                                 if ( (x = findUnmarkedLit(c, 1)) == c.size() ) {
00295                                         while (w != end) { *wj++ = *w++; }
00296                                         cls.shrink_right( wj );
00297                                         return true;
00298                                 }
00299                                 c[0] = c[x];
00300                                 c[x] = l;
00301                                 occurs_[c[0].var()].addWatch(*w);
00302                                 if (occurs_[c[0].var()].litMark != 0 && findUnmarkedLit(c, x+1) == c.size()) {
00303                                         occurs_[c[0].var()].unmark();  // no longer part of cl
00304                                         ++str;
00305                                 }
00306                         }
00307                         else if ( findUnmarkedLit(c, 1) == c.size() ) {
00308                                 occurs_[l.var()].unmark(); // no longer part of cl
00309                                 while (w != end) { *wj++ = *w++; }
00310                                 cls.shrink_right( wj );
00311                                 goto removeLit;
00312                         }
00313                         else { *wj++ = *w; }  
00314                 }
00315                 cls.shrink_right(wj);
00316                 if (j++ != i) { cl[j-1] = cl[i]; }
00317 removeLit:;
00318         }
00319         cl.erase(cl.begin()+j, cl.end());
00320         if (str > 0) {
00321                 for (LitVec::size_type i = 0; i != cl.size();) {
00322                         if (occurs_[cl[i].var()].litMark == 0) {
00323                                 cl[i] = cl.back();
00324                                 cl.pop_back();
00325                                 if (--str == 0) break;
00326                         }
00327                         else { ++i; }
00328                 }
00329         }
00330         return false;
00331 }
00332 
00333 // Pre: c contains l
00334 // Pre: c was already removed from l's occur-list
00335 bool SatElite::strengthenClause(uint32 clauseId, Literal l) {
00336         Clause& c = *clause(clauseId);
00337         if (c[0] == l) {
00338                 occurs_[c[0].var()].removeWatch(clauseId);
00339                 // Note: Clause::strengthen shifts literals after l to the left. Thus
00340                 // c[1] will be c[0] after strengthen
00341                 occurs_[c[1].var()].addWatch(clauseId);
00342         }
00343         ++stats.litsRemoved;
00344         c.strengthen(l);
00345         if (c.size() == 1) {
00346                 Literal unit = c[0];
00347                 detach(clauseId);
00348                 return ctx_->master()->force(unit, 0) && ctx_->master()->propagate();
00349         }
00350         addToSubQueue(clauseId);
00351         return true;
00352 }
00353 
00354 // Split occurrences of v into pos and neg and 
00355 // mark all clauses containing v
00356 SatElite::ClRange SatElite::splitOcc(Var v, bool mark) {
00357         ClRange cls      = occurs_[v].clauseRange();
00358         occurs_[v].dirty = 0;
00359         posT_.clear(); negT_.clear();
00360         ClIter j = cls.first;
00361         for (ClIter x = j; x != cls.second; ++x) {
00362                 if (Clause* c = clause(x->var())) {
00363                         assert(c->marked() == false);
00364                         c->setMarked(mark);
00365                         (x->sign() ? negT_ : posT_).push_back(x->var());
00366                         if (j != x) *j = *x;
00367                         ++j;
00368                 }
00369         }
00370         occurs_[v].refs.shrink_left(j);
00371         return occurs_[v].clauseRange();
00372 }
00373 
00374 void SatElite::markAll(const Literal* lits, uint32 size) const {
00375         for (uint32 i = 0; i != size; ++i) {
00376                 occurs_[lits[i].var()].mark(lits[i].sign());
00377         }
00378 }
00379 void SatElite::unmarkAll(const Literal* lits, uint32 size) const {
00380         for (uint32 i = 0; i != size; ++i) {
00381                 occurs_[lits[i].var()].unmark();
00382         }
00383 }
00384 
00385 // Run variable and/or blocked clause elimination on var v.
00386 // If the number of non-trivial resolvents is <= maxCnt, 
00387 // v is eliminated by clause distribution. If bce is enabled,
00388 // clauses blocked on a literal of v are removed.
00389 bool SatElite::bceVe(Var v, uint32 maxCnt) {
00390         Solver* s = ctx_->master();
00391         if (s->value(v) != value_free) return true;
00392         assert(!ctx_->varInfo(v).frozen() && !ctx_->eliminated(v));
00393         resCands_.clear();
00394         // distribute clauses on v 
00395         // check if number of clauses decreases if we'd eliminate v
00396         uint32 bce     = opts_->bce();
00397         ClRange cls    = splitOcc(v, bce > 1);
00398         uint32 cnt     = 0;
00399         uint32 markMax = ((uint32)negT_.size() * (bce>1));
00400         uint32 blocked = 0;
00401         bool stop      = false;
00402         Clause* lhs, *rhs;
00403         for (VarVec::const_iterator i = posT_.begin(); i != posT_.end() && !stop; ++i) {
00404                 lhs         = clause(*i);
00405                 markAll(&(*lhs)[0], lhs->size());
00406                 lhs->setMarked(bce != 0);
00407                 for (VarVec::const_iterator j = negT_.begin(); j != negT_.end(); ++j) {
00408                         if (!trivialResolvent(*(rhs = clause(*j)), v)) {
00409                                 markMax -= rhs->marked();
00410                                 rhs->setMarked(false); // not blocked on v
00411                                 lhs->setMarked(false); // not blocked on v
00412                                 if (++cnt <= maxCnt) {
00413                                         resCands_.push_back(lhs);
00414                                         resCands_.push_back(rhs);
00415                                 }
00416                                 else if (!markMax) {
00417                                         stop = (bce == 0);
00418                                         break;
00419                                 }
00420                         }
00421                 }
00422                 unmarkAll(&(*lhs)[0], lhs->size());
00423                 if (lhs->marked()) {
00424                         posT_[blocked++] = *i;
00425                 }
00426         }
00427         if (cnt <= maxCnt) {
00428                 // eliminate v by clause distribution
00429                 ctx_->eliminate(v);  // mark var as eliminated
00430                 // remove old clauses, store them in the elimination table so that
00431                 // (partial) models can be extended.
00432                 for (ClIter it = cls.first; it != cls.second; ++it) {
00433                         // reuse first cnt ids for resolvents
00434                         if (clause(it->var())) {
00435                                 bool freeId = (cnt && cnt--);
00436                                 bceVeRemove(it->var(), freeId, v, false);
00437                         }
00438                 }
00439                 // add non trivial resolvents
00440                 assert( resCands_.size() % 2 == 0 );
00441                 ClIter it = cls.first;
00442                 for (VarVec::size_type i = 0; i != resCands_.size(); i+=2, ++it) {
00443                         if (!addResolvent(it->var(), *resCands_[i], *resCands_[i+1])) {
00444                                 return false;
00445                         }
00446                 }
00447                 assert(occurs_[v].numOcc() == 0);
00448                 // release memory
00449                 occurs_[v].clear();
00450         }
00451         else if ( (blocked + markMax) > 0 ) {
00452                 // remove blocked clauses
00453                 for (uint32 i = 0; i != blocked; ++i) {
00454                         bceVeRemove(posT_[i], false, v, true);
00455                 }
00456                 for (VarVec::const_iterator it = negT_.begin(); markMax; ++it) {
00457                         if ( (rhs = clause(*it))->marked() ) {
00458                                 bceVeRemove(*it, false, v, true);
00459                                 --markMax;
00460                         }
00461                 }
00462         }
00463         return opts_->limIters != 0 || backwardSubsume();
00464 }
00465 
00466 bool SatElite::bce() {
00467         uint32 ops = 0;
00468         for (ClWList& bce= occurs_[0].refs; bce.right_size() != 0; ++ops) {
00469                 Var v          = *(bce.right_end()-1);
00470                 bce.pop_right();
00471                 occurs_[v].bce=0; 
00472                 if ((ops & 1023) == 0)   {
00473                         if (timeout())         { bce.clear(); return true; }
00474                         if ((ops & 8191) == 0) { reportProgress(Progress::event_bce, ops, 1+bce.size()); }
00475                 }
00476                 if (!cutoff(v) && !bceVe(v, 0)) { return false; }
00477         }
00478         return true;
00479 }
00480 
00481 bool SatElite::eliminateVars() {
00482         Var     v          = 0;
00483         uint32  occ        = 0;
00484         if (!bce()) return false;
00485         for (uint32 ops = 0; !elimHeap_.empty(); ++ops) {
00486                 v   = elimHeap_.top();  elimHeap_.pop();
00487                 occ = occurs_[v].numOcc();
00488                 if ((ops & 1023) == 0)   {
00489                         if (timeout())         { elimHeap_.clear(); return true; }
00490                         if ((ops & 8191) == 0) { reportProgress(Progress::event_var_elim, ops, 1+elimHeap_.size()); }
00491                 }
00492                 if (!cutoff(v) && !bceVe(v, occ)) {
00493                         return false;
00494                 }
00495         }
00496         return opts_->limIters != 0 || bce();
00497 }
00498 
00499 // returns true if the result of resolving c1 (implicitly given) and c2 on v yields a tautologous clause
00500 bool SatElite::trivialResolvent(const Clause& c2, Var v) const {
00501         for (uint32 i = 0, end = c2.size(); i != end; ++i) {
00502                 Literal x = c2[i];
00503                 if (occurs_[x.var()].marked(!x.sign()) && x.var() != v) {
00504                         return true;
00505                 }               
00506         }
00507         return false;
00508 }
00509 
00510 // Pre: lhs and rhs can be resolved on lhs[0].var()
00511 // Pre: trivialResolvent(lhs, rhs, lhs[0].var()) == false
00512 bool SatElite::addResolvent(uint32 id, const Clause& lhs, const Clause& rhs) {
00513         resolvent_.clear();
00514         Solver* s = ctx_->master();
00515         assert(lhs[0] == ~rhs[0]);
00516         uint32 i, end;
00517         Literal l;
00518         for (i = 1, end = lhs.size(); i != end; ++i) {
00519                 l = lhs[i];
00520                 if (!s->isFalse(l)) {
00521                         if (s->isTrue(l)) goto unmark;
00522                         occurs_[l.var()].mark(l.sign());
00523                         resolvent_.push_back(l);
00524                 }
00525         }
00526         for (i = 1, end = rhs.size(); i != end; ++i) {
00527                 l = rhs[i];
00528                 if (!s->isFalse(l) && !occurs_[l.var()].marked(l.sign())) {
00529                         if (s->isTrue(l)) goto unmark;
00530                         occurs_[l.var()].mark(l.sign());
00531                         resolvent_.push_back(l);
00532                 }
00533         }
00534         if (!subsumed(resolvent_))  {
00535                 if (resolvent_.empty())   { return false; }
00536                 if (resolvent_.size()==1) { 
00537                         occurs_[resolvent_[0].var()].unmark();
00538                         return s->force(resolvent_[0], 0) && s->propagate() && propagateFacts();
00539                 }
00540                 setClause(id, resolvent_);
00541                 attach(id, false);
00542                 return true;
00543         }
00544 unmark:
00545         if (!resolvent_.empty()) { 
00546                 unmarkAll(&resolvent_[0], resolvent_.size()); 
00547         }
00548         return true;
00549 }
00550 
00551 // extends the model given in assign by the vars that were eliminated
00552 void SatElite::doExtendModel(ValueVec& m, LitVec& unconstr) {
00553         const ValueRep value_eliminated = 4u;
00554         if (!elimTop_) return;
00555         // compute values of eliminated vars / blocked literals by "unit propagating"
00556         // eliminated/blocked clauses in reverse order
00557         uint32 uv   = 0;
00558         uint32 us   = unconstr.size();
00559         Clause* r   = elimTop_;
00560         do {
00561                 Literal x  = (*r)[0];
00562                 Var last   = x.var();
00563                 bool check = true;
00564                 if (!r->marked()) {
00565                         // eliminated var - compute the implied value
00566                         m[last]  = value_eliminated;
00567                 }
00568                 if (uv != us && unconstr[uv].var() == last) {
00569                         // last is unconstraint w.r.t the current model -
00570                         // set remembered value
00571                         check    = false;
00572                         m[last]  = trueValue(unconstr[uv]);
00573                         ++uv;
00574                 }
00575                 do {
00576                         Clause& c = *r;
00577                         if (m[x.var()] != trueValue(x) && check) {
00578                                 for (uint32 i = 1, end = c.size(); i != end; ++i) {
00579                                         ValueRep vi = m[c[i].var()] & 3u;
00580                                         if (vi != falseValue(c[i])) {
00581                                                 x = c[i];
00582                                                 break;
00583                                         }
00584                                 }
00585                                 if (x == c[0]) {
00586                                         // all lits != x are false
00587                                         // clause is unit or conflicting
00588                                         assert(c.marked() || m[x.var()] != falseValue(x));
00589                                         m[x.var()] = trueValue(x);
00590                                         check      = false;
00591                                 }
00592                         }
00593                         r = r->next();
00594                 } while (r && (x = (*r)[0]).var() == last);
00595                 if (m[last] == value_eliminated) {
00596                         // last seems unconstraint w.r.t the model
00597                         m[last] |= value_true;
00598                         unconstr.push_back(posLit(last));       
00599                 }
00600         } while (r);
00601         // check whether newly added unconstraint vars are really unconstraint w.r.t the model
00602         // or if they are implied by some blocked clause.
00603         LitVec::iterator j = unconstr.begin()+us;
00604         for (LitVec::iterator it = j, end = unconstr.end(); it != end; ++it) {
00605                 if ((m[it->var()] & value_eliminated) != 0) {
00606                         // var is unconstraint - assign to true and remember it
00607                         // so that we can later enumerate the model containing ~var
00608                         m[it->var()] = value_true;
00609                         *j++ = *it;
00610                 }
00611         }
00612         unconstr.erase(j, unconstr.end());
00613 }
00614 }
00615 SatPreprocessor* SatPreParams::create(const SatPreParams& opts) {
00616         if (opts.type != 0) { return new SatElite::SatElite(); }
00617         return 0;
00618 }
00619 }


clasp
Author(s): Benjamin Kaufmann
autogenerated on Thu Aug 27 2015 12:41:39