cb_enumerator.cpp
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2006-2011, 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/cb_enumerator.h>
00021 #include <clasp/solver.h>
00022 #include <clasp/clause.h>
00023 #include <clasp/util/mutex.h>
00024 #include <stdio.h> // sprintf
00025 #ifdef _MSC_VER
00026 #pragma warning (disable : 4996) // sprintf may be unfase
00027 #endif
00028 namespace Clasp {
00029 
00031 // CBConsequences::SharedConstraint
00033 class CBConsequences::SharedConstraint {
00034 public:
00035         SharedConstraint() : current(0) {}
00036         SharedLiterals* fetch_if_neq(SharedLiterals* last) const {
00037                 Clasp::lock_guard<Clasp::spin_mutex> lock(mutex);
00038                 return last != current ? current->share() : 0;
00039         }
00040         void release(SharedLiterals* newLits) {
00041                 SharedLiterals* old = current;
00042                 { Clasp::lock_guard<Clasp::spin_mutex> lock(mutex); current = newLits; }
00043                 if (old) { old->release(); }
00044         }
00045         SharedLiterals*           current;
00046         mutable Clasp::spin_mutex mutex;
00047 };
00049 // CBConsequences::CBFinder
00051 class CBConsequences::CBFinder : public EnumerationConstraint {
00052 public:
00053         typedef CBConsequences::SharedConstraint  SharedCon;
00054         typedef Solver::ConstraintDB              ConstraintDB;
00055         typedef SharedLiterals                    SharedLits;
00056         CBFinder(Solver& s, MinimizeConstraint* min, SharedCon* sh) 
00057                 : EnumerationConstraint(s, min), shared(sh), last(0) {}
00058         
00059         Constraint* cloneAttach(Solver& s) { return new CBFinder(s, cloneMinimizer(s), shared); } 
00060         void doCommitModel(Enumerator& ctx, Solver& s) { static_cast<CBConsequences&>(ctx).addCurrent(s, current, s.model); }
00061         void destroy(Solver* s, bool detach);
00062         bool doUpdate(Solver& s);
00063         void pushLocked(Solver& s, ClauseHead* h);
00064         LitVec       current;
00065         SharedCon*   shared;
00066         SharedLits*  last;
00067         ConstraintDB locked;
00068 };
00070 // CBConsequences
00072 CBConsequences::CBConsequences(Consequences_t type) 
00073         : Enumerator()
00074         , shared_(0)
00075         , type_(type) {}
00076 
00077 Enumerator* EnumOptions::createConsEnumerator(const EnumOptions& opts) {
00078         return new CBConsequences(opts.type == enum_brave ? CBConsequences::brave_consequences : CBConsequences::cautious_consequences);
00079 }
00080 CBConsequences::~CBConsequences() {
00081         delete shared_;
00082 }
00083 EnumerationConstraint* CBConsequences::doInit(SharedContext& ctx, MinimizeConstraint* min, int) {
00084         cons_.clear();
00085         const SymbolTable& index = ctx.symbolTable();
00086         if (index.type() == SymbolTable::map_direct) {
00087                 for (Var v = 1, end = index.size(); v < end; ++v) { 
00088                         if (!ctx.marked(posLit(v))) {
00089                                 cons_.push_back(posLit(v));
00090                                 ctx.mark(cons_.back());
00091                         }
00092                 }
00093         }
00094         else {
00095                 for (SymbolTable::const_iterator it = index.begin(); it != index.end(); ++it) {
00096                         if (!it->second.name.empty() && !ctx.marked(it->second.lit)) { 
00097                                 cons_.push_back(it->second.lit);
00098                                 ctx.mark(cons_.back());
00099                         }
00100                 }
00101         }       
00102         uint32 m = (type_ == cautious_consequences);
00103         for (LitVec::iterator it = cons_.begin(), end = cons_.end(); it != end; ++it) {
00104                 ctx.setFrozen(it->var(), true);
00105                 ctx.unmark(it->var());
00106                 it->asUint() |= m;
00107         }
00108         delete shared_;
00109         shared_ = ctx.concurrency() > 1 ? new SharedConstraint() : 0;
00110         setIgnoreSymmetric(true);
00111         return new CBFinder(*ctx.master(), min, shared_);
00112 }
00113 void CBConsequences::addCurrent(Solver& s, LitVec& con, ValueVec& m) {
00114         con.clear();
00115         con.push_back(~s.sharedContext()->stepLiteral());
00116         for (LitVec::iterator it = cons_.begin(), end = cons_.end(); it != end; ++it) {
00117                 m[it->var()] = 0;
00118         }
00119         if (type_ == brave_consequences) {
00120                 for (LitVec::iterator it = cons_.begin(), end = cons_.end(); it != end; ++it) {
00121                         Literal& p = *it;
00122                         if (s.isTrue(p) || p.watched())  { 
00123                                 m[p.var()] |= trueValue(p); 
00124                                 p.watch();
00125                         }
00126                         else if (s.level(p.var())) {
00127                                 con.push_back(p);
00128                         }
00129                 }
00130         }
00131         else if (type_ == cautious_consequences) {
00132                 for (LitVec::iterator it = cons_.begin(), end = cons_.end(); it != end; ++it) {
00133                         Literal& p = *it;
00134                         if (!s.isTrue(p) || !p.watched()) {
00135                                 m[p.var()] &= ~trueValue(p);
00136                                 p.clearWatch();
00137                         }
00138                         else {
00139                                 if (s.level(p.var())) { con.push_back(~p); }
00140                                 m[p.var()] |= trueValue(p);
00141                         }
00142                 }
00143         }
00144         if (con.empty()) { con.push_back(negLit(0)); }
00145         if (shared_) {
00146                 shared_->release(SharedLiterals::newShareable(con, Constraint_t::learnt_other, 1));
00147         }
00148 }
00150 // CBConsequences::CBFinder implementation
00152 void CBConsequences::CBFinder::destroy(Solver* s, bool detach) {
00153         while (!locked.empty()) {
00154                 static_cast<ClauseHead*>(locked.back())->destroy(s, detach);
00155                 locked.pop_back();
00156         }
00157         EnumerationConstraint::destroy(s, detach);
00158 }
00159 void CBConsequences::CBFinder::pushLocked(Solver& s, ClauseHead* c) {
00160         for (ClauseHead* h; !locked.empty() && !(h = static_cast<ClauseHead*>(locked.back()))->locked(s);) {
00161                 h->destroy(&s, true);
00162                 locked.pop_back();
00163         }
00164         locked.push_back(c);
00165 }
00166 bool CBConsequences::CBFinder::doUpdate(Solver& s) {
00167         ClauseCreator::Result ret;
00168         uint32 flags = ClauseCreator::clause_explicit|ClauseCreator::clause_no_add;
00169         if (!shared) {
00170                 ret  = !current.empty() ? ClauseCreator::create(s, current, flags, ClauseInfo(Constraint_t::learnt_other)) : ClauseCreator::Result();
00171         }
00172         else if (SharedLiterals* x = shared->fetch_if_neq(last)) {
00173                 last = x;
00174                 ret  = ClauseCreator::integrate(s, x, flags);
00175         }
00176         if (ret.local) { pushLocked(s, ret.local); }
00177         current.clear();
00178         return ret.ok();
00179 }
00180 }


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