Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef CLASP_CONSTRAINT_H_INCLUDED
00021 #define CLASP_CONSTRAINT_H_INCLUDED
00022
00023 #ifdef _MSC_VER
00024 #pragma once
00025 #endif
00026
00027 #include <clasp/literal.h>
00028 #include <utility>
00029 #include <cassert>
00030
00036 namespace Clasp {
00037
00038 class SharedContext;
00039 class Solver;
00040 class ClauseHead;
00041 struct CCMinRecursive;
00042
00047
00049 struct Constraint_t {
00050 enum Type {
00051 static_constraint = 0,
00052 learnt_conflict = 1,
00053 learnt_loop = 2,
00054 learnt_other = 3,
00055 max_value = learnt_other
00056 };
00057 struct Set {
00058 Set() : m(0) {}
00059 bool inSet(Type t) const { return (m & (uint32(1)<<t)) != 0; }
00060 void addSet(Type t) { m |= (uint32(1)<<t); }
00061 uint32 m;
00062 };
00063 };
00064 typedef Constraint_t::Type ConstraintType;
00065 typedef Constraint_t::Set TypeSet;
00067 struct Activity {
00068 enum { LBD_SHIFT = 7, MAX_LBD = (1 << LBD_SHIFT)-1, MAX_ACT = (1 << (32-LBD_SHIFT))-1 };
00069 Activity(uint32 act, uint32 lbd) : rep( (act << LBD_SHIFT) | lbd ) {}
00070 uint32 activity() const { return rep >> LBD_SHIFT; }
00071 uint32 lbd() const { return rep & uint32(MAX_LBD); }
00072 void bumpAct() { if (rep < uint32(MAX_ACT<<LBD_SHIFT)) rep += (1<<LBD_SHIFT); }
00073 void setLbd(uint32 x) { rep &= ~uint32(MAX_LBD); rep |= x; }
00074 uint32 rep;
00075 };
00076
00078
00085 class Constraint {
00086 public:
00088 struct PropResult {
00089 explicit PropResult(bool a_ok = true, bool a_keepWatch = true) : ok(a_ok), keepWatch(a_keepWatch) {}
00090 bool ok;
00091 bool keepWatch;
00092 };
00093 Constraint();
00095
00101 virtual Constraint* cloneAttach(Solver& other) = 0;
00102
00104 virtual void destroy(Solver* s = 0, bool detach = false);
00105
00107
00110 virtual ConstraintType type() const;
00111
00120 virtual PropResult propagate(Solver& s, Literal p, uint32& data) = 0;
00121
00126 virtual void reason(Solver& s, Literal p, LitVec& lits) = 0;
00127
00141 virtual bool minimize(Solver& s, Literal p, CCMinRecursive* rec);
00142
00144
00147 virtual void undoLevel(Solver& s);
00148
00161 virtual bool simplify(Solver& s, bool reinit = false);
00162
00164 virtual uint32 estimateComplexity(const Solver& s) const;
00165
00167
00170 virtual ClauseHead* clause();
00171
00173
00179 virtual bool valid(Solver& s);
00180 protected:
00181 virtual ~Constraint();
00182 private:
00183 Constraint(const Constraint&);
00184 Constraint& operator=(const Constraint&);
00185 };
00186
00188
00202 class LearntConstraint : public Constraint {
00203 public:
00204 LearntConstraint();
00206
00209 ConstraintType type() const;
00210
00215 virtual bool locked(const Solver& s) const = 0;
00216
00218
00224 virtual Activity activity() const;
00225
00227 virtual void decreaseActivity();
00229 virtual void resetActivity(Activity hint);
00230
00232
00236 virtual uint32 isOpen(const Solver& s, const TypeSet& t, LitVec& freeLits) = 0;
00237 protected:
00238 ~LearntConstraint();
00239 };
00240
00242
00264 class PostPropagator : public Constraint {
00265 public:
00266 PostPropagator();
00267 virtual ~PostPropagator();
00268 using Constraint::propagate;
00269
00270 PostPropagator* next;
00272 enum Priority {
00273 priority_class_simple = 0,
00274 priority_reserved_msg = 0,
00275 priority_reserved_ufs = 10,
00276 priority_reserved_look = 1023,
00277 priority_class_general = 1024,
00278 };
00279
00281
00286 virtual uint32 priority() const = 0;
00287
00289
00293 virtual bool init(Solver& s);
00294
00296
00324 virtual bool propagateFixpoint(Solver& s, PostPropagator* ctx) = 0;
00325
00327
00335 virtual void reset();
00336
00338
00347 virtual bool isModel(Solver& s);
00348 protected:
00350 Constraint* cloneAttach(Solver&) { return 0; }
00351
00352 PropResult propagate(Solver&, Literal, uint32&);
00353 void reason(Solver&, Literal, LitVec& );
00354 private:
00355 PostPropagator(const PostPropagator&);
00356 PostPropagator& operator=(const PostPropagator&);
00357 };
00358
00359 class MessageHandler : public PostPropagator {
00360 public:
00361 MessageHandler();
00362 virtual bool handleMessages() = 0;
00363 virtual uint32 priority()const { return PostPropagator::priority_reserved_msg; }
00364 virtual bool propagateFixpoint(Solver&, PostPropagator*) { return handleMessages(); }
00365 };
00366
00368
00370
00399 class Antecedent {
00400 public:
00401 enum Type { generic_constraint = 0, ternary_constraint = 1, binary_constraint = 2};
00403
00406 Antecedent() : data_(0) {}
00407
00409
00412 Antecedent(const Literal& p) {
00413
00414 data_ = (((uint64)p.index()) << 33) + binary_constraint;
00415 assert(type() == binary_constraint && firstLiteral() == p);
00416 }
00417
00419
00422 Antecedent(const Literal& p, const Literal& q) {
00423
00424
00425 data_ = (((uint64)p.index()) << 33) + (((uint64)q.index()) << 2) + ternary_constraint;
00426 assert(type() == ternary_constraint && firstLiteral() == p && secondLiteral() == q);
00427 }
00428
00430
00433 Antecedent(Constraint* con) : data_((uintp)con) {
00434 assert(type() == generic_constraint && constraint() == con);
00435 }
00436
00438 bool isNull() const {
00439 return data_ == 0;
00440 }
00441
00443 Type type() const {
00444 return Type( data_ & 3 );
00445 }
00446
00448 bool learnt() const { return data_ && (data_ & 3u) == 0 && constraint()->type() != Constraint_t::static_constraint; }
00449
00451
00454 Constraint* constraint() const {
00455 assert(type() == generic_constraint);
00456 return (Constraint*)(uintp)data_;
00457 }
00458
00460
00463 Literal firstLiteral() const {
00464 assert(type() != generic_constraint);
00465 return Literal::fromIndex(static_cast<uint32>(data_ >> 33));
00466 }
00467
00469
00472 Literal secondLiteral() const {
00473 assert(type() == ternary_constraint);
00474 return Literal::fromIndex( static_cast<uint32>(data_>>1) >> 1 );
00475 }
00476
00478
00481 void reason(Solver& s, Literal p, LitVec& lits) const {
00482 assert(!isNull());
00483 Type t = type();
00484 if (t == generic_constraint) {
00485 constraint()->reason(s, p, lits);
00486 }
00487 else {
00488 lits.push_back(firstLiteral());
00489 if (t == ternary_constraint) {
00490 lits.push_back(secondLiteral());
00491 }
00492 }
00493 }
00494 template <class S>
00495 bool minimize(S& s, Literal p, CCMinRecursive* rec) const {
00496 assert(!isNull());
00497 Type t = type();
00498 if (t == generic_constraint) {
00499 return constraint()->minimize(s, p, rec);
00500 }
00501 else {
00502 return s.ccMinimize(firstLiteral(), rec)
00503 && (t != ternary_constraint || s.ccMinimize(secondLiteral(), rec));
00504 }
00505 }
00506
00508 bool operator==(const Constraint* con) const {
00509 return static_cast<uintp>(data_) == reinterpret_cast<uintp>(con);
00510 }
00511
00513
00516 static bool checkPlatformAssumptions();
00517
00518 uint64 asUint() const { return data_; }
00519 uint64& asUint() { return data_; }
00520 private:
00521 uint64 data_;
00522 };
00523
00524
00525 class PlatformError : public ClaspError {
00526 public:
00527 explicit PlatformError(const char* msg);
00528 };
00529
00530 }
00531 #endif