enumerator.cpp
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2006-2012, 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/enumerator.h>
00021 #include <clasp/solver.h>
00022 namespace Clasp { 
00023 
00025 // EnumerationConstraint
00027 EnumerationConstraint::EnumerationConstraint(Solver&, MinimizeConstraint* min) : mini_(min), flags_(0), root_(0) {
00028         setDisjoint(false);
00029 }
00030 MinimizeConstraint* EnumerationConstraint::cloneMinimizer(Solver& s) const {
00031         return mini_ ? static_cast<MinimizeConstraint*>(mini_->cloneAttach(s)) : 0;
00032 }
00033 EnumerationConstraint::~EnumerationConstraint()             { }
00034 void EnumerationConstraint::destroy(Solver* s, bool x)      { if (mini_) { mini_->destroy(s, x); mini_ = 0; } Constraint::destroy(s, x); }
00035 bool EnumerationConstraint::simplify(Solver& s, bool reinit){ if (mini_) { mini_->simplify(s, reinit); } return false; }
00036 bool EnumerationConstraint::valid(Solver& s)                { return !optimize() || mini_->valid(s); }
00037 bool EnumerationConstraint::integrateBound(Solver& s) const { return !mini_ || mini_->integrate(s); }
00038 bool EnumerationConstraint::optimize() const                { return mini_ && mini_->shared()->optimize(); }
00039 void EnumerationConstraint::setDisjoint(bool x) {
00040         if (x) { flags_ |=  uint32(flag_path_disjoint); }
00041         else   { flags_ &= ~uint32(flag_path_disjoint); }
00042 }
00043 void EnumerationConstraint::end(Solver& s) {
00044         if (mini_) { mini_->relax(s, disjointPath()); }
00045         flags_ = 0;
00046         next_.clear();
00047         if (s.rootLevel() > root_) { s.popRootLevel(s.rootLevel() - root_); }
00048 }
00049 bool EnumerationConstraint::start(Solver& s, const LitVec& path, bool disjoint) {
00050         flags_ = 0;
00051         root_  = s.rootLevel();
00052         setDisjoint(disjoint);
00053         if (s.pushRoot(path)) {
00054                 integrateBound(s);
00055                 return true;
00056         }
00057         return false;
00058 }
00059 bool EnumerationConstraint::update(Solver& s) {
00060         ValueRep st = state();
00061         if (st == value_true) {
00062                 if (s.strategy.restartOnModel) { s.undoUntil(0); }
00063                 if (optimize())                { s.strengthenConditional(); }
00064         }
00065         else if (st == value_false && !s.pushRoot(next_)) {
00066                 if (!s.hasConflict()) { s.setStopConflict(); }
00067                 return false;
00068         }
00069         flags_ &= uint32(clear_state_mask);
00070         next_.clear();
00071         do {
00072                 if (!s.hasConflict() && doUpdate(s) && integrateBound(s)) {
00073                         if (st == value_true && optimize()) { mini_->shared()->heuristic(s, (s.strategy.optHeu & SolverStrategies::opt_model) != 0); }
00074                         return true;
00075                 }
00076         } while (st != value_free && s.hasConflict() && s.resolveConflict());
00077         return false;
00078 }
00079 
00080 bool EnumerationConstraint::commitModel(Enumerator& ctx, Solver& s) {
00081         if (state() == value_true)          { return !next_.empty() && (s.satPrepro()->extendModel(s.model, next_), true); }
00082         if (mini_ && !mini_->handleModel(s)){ return false; }
00083         if (!ctx.tentative())               { doCommitModel(ctx, s); }
00084         next_ = s.symmetric();
00085         flags_|= value_true;
00086         return true;
00087 }
00088 bool EnumerationConstraint::commitUnsat(Enumerator&, Solver& s) {
00089         next_.clear();
00090         flags_ |= value_false;
00091         return mini_ && mini_->handleUnsat(s, !disjointPath(), next_);
00092 }
00094 // Enumerator
00096 Enumerator::Enumerator() : mini_(0) {}
00097 Enumerator::~Enumerator()                            { if (mini_) mini_->release(); }
00098 void Enumerator::setDisjoint(Solver& s, bool b)const { constraint(s)->setDisjoint(b);    }
00099 void Enumerator::setIgnoreSymmetric(bool b)          { model_.sym = static_cast<uint32>(b == false); }
00100 void Enumerator::end(Solver& s)                const { constraint(s)->end(s); }
00101 void Enumerator::doReset()                           {}
00102 void Enumerator::reset() {
00103         if (mini_) { mini_->release(); mini_ = 0; }
00104         model_.values= 0;
00105         model_.costs = 0;
00106         model_.num   = 0;
00107         model_.opt   = 0;
00108         model_.sym   = 1;
00109         model_.type  = uint32(modelType());
00110         model_.sId   = 0;
00111         doReset();
00112 }
00113 int  Enumerator::init(SharedContext& ctx, SharedMinimizeData* min, int limit)  { 
00114         typedef MinimizeConstraint* MinPtr;
00115         ctx.master()->setEnumerationConstraint(0);
00116         reset();
00117         if (min && min->mode() == MinimizeMode_t::ignore){ min->release(); min = 0; }
00118         model_.costs = (mini_ = min);
00119         MinPtr mc    = mini_ ? mini_->attach(*ctx.master()) : 0;
00120         limit        = limit >= 0 ? limit : 1 - int(exhaustive());
00121         if (limit   != 1) { ctx.setPreserveModels(true); }
00122         ConPtr c     = doInit(ctx, mc, limit);
00123         bool optEnum = tentative();
00124         bool cons    = model_.consequences();
00125         if (limit) {
00126                 if (optimize() && !optEnum){ ctx.report(warning(Event::subsystem_prepare, "#models not 0: optimality of last model not guaranteed.")); }
00127                 if (cons)                  { ctx.report(warning(Event::subsystem_prepare, "#models not 0: last model may not cover consequences."));   }
00128         }
00129         if      (optEnum)            { model_.type = Model::model_sat; }
00130         else if (cons && optimize()) { ctx.report(warning(Event::subsystem_prepare, "Optimization: Consequences may depend on enumeration order.")); }
00131         ctx.master()->setEnumerationConstraint(c);
00132         return limit;
00133 }
00134 Enumerator::ConPtr Enumerator::constraint(const Solver& s) const {
00135         return static_cast<ConPtr>(s.enumerationConstraint());
00136 }
00137 bool Enumerator::start(Solver& s, const LitVec& path, bool disjointPath) const {
00138         return constraint(s)->start(s, path, disjointPath);
00139 }
00140 ValueRep Enumerator::commit(Solver& s) {
00141         if      (s.hasConflict() && s.decisionLevel() == s.rootLevel())         { return commitUnsat(s) ? value_free : value_false; }
00142         else if (s.numFreeVars() == 0 && s.queueSize() == 0 && !s.hasConflict()){ return commitModel(s) ? value_true : value_free;  }
00143         return value_free;
00144 }
00145 bool Enumerator::commitModel(Solver& s) {
00146         assert(s.numFreeVars() == 0 && !s.hasConflict() && s.queueSize() == 0 && constraint(s));
00147         if (constraint(s)->commitModel(*this, s)) {
00148                 s.stats.addModel(s.decisionLevel());
00149                 ++model_.num;
00150                 model_.values = &s.model;
00151                 model_.sId    = s.id();
00152                 return true;
00153         }
00154         return false;
00155 }
00156 bool Enumerator::commitSymmetric(Solver& s){ return model_.sym && !optimize() && commitModel(s); }
00157 bool Enumerator::commitUnsat(Solver& s)    { return constraint(s)->commitUnsat(*this, s); }
00158 bool Enumerator::commitComplete() {
00159         if (enumerated()) {
00160                 if (tentative()) {
00161                         mini_->markOptimal();
00162                         model_.opt = 1;
00163                         model_.num = 0;
00164                         model_.type= uint32(modelType());
00165                         return false;
00166                 }
00167                 else if (model_.consequences() || (!model_.opt && optimize())) {
00168                         model_.opt = uint32(optimize());
00169                         model_.num = 1;
00170                 }
00171         }
00172         return true;
00173 }
00174 
00175 bool Enumerator::update(Solver& s) const {
00176         return constraint(s)->update(s);
00177 }
00179 // EnumOptions
00181 Enumerator* EnumOptions::createEnumerator() const {
00182         if      (consequences())      { return createConsEnumerator(*this);  }
00183         else if (type <= enum_record) { return createModelEnumerator(*this); }
00184         else                          { return 0; }
00185 }
00186 Enumerator* EnumOptions::nullEnumerator() {
00187         struct NullEnum : Enumerator {
00188                 ConPtr doInit(SharedContext& ctx, MinimizeConstraint* m, int) {
00189                         struct Constraint : public EnumerationConstraint {
00190                                 Constraint(Solver& s, MinimizeConstraint* min) : EnumerationConstraint(s, min) {}
00191                                 bool        doUpdate(Solver& s)   { s.setStopConflict(); return false; }
00192                                 Constraint* cloneAttach(Solver& s){ return new Constraint(s, cloneMinimizer(s)); }
00193                         };
00194                         return new Constraint(*ctx.master(), m);
00195                 }
00196         };
00197         return new NullEnum;
00198 }
00199 }


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