00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _CSP_KERNEL_Variable_H
00031 #define _CSP_KERNEL_Variable_H
00032
00033
00034 CSP_NAMESPACE_BEGIN(csp);
00035
00036
00037 class CSP_API Problem;
00038 class CSP_API Constraint;
00039
00040
00044 class CSP_API Variable
00045 {
00046 public:
00048 typedef FastVector<Constraint*>::const_iterator constraint_iterator;
00049
00056 Variable(const Problem& problem);
00057
00059 virtual ~Variable();
00060
00062 id_t id() const { return m_id; }
00063
00071 virtual wstring name() const;
00072
00079 virtual wstring color() const { return L"gray"; }
00080
00087 virtual wstring textColor() const { return L"black"; }
00088
00095 virtual wstring shape() const { return L"ellipse"; }
00096
00098 void setId(id_t id) { m_id = id; }
00099
00110 virtual void setBackdoorStatus(bool ) {}
00111
00122 virtual void setBackdoorKeyStatus(bool ) {}
00123
00134 virtual void setBranchingStatus(bool ) {}
00135
00137 const Problem& problem() const { return m_problem; }
00138
00140 constraint_iterator add(Constraint& constraint)
00141 {
00142 return m_activeConstraints.insert(&constraint);
00143 }
00144
00146 void remove(Constraint& constraint, bool recursive = false);
00147
00149 size_t values() const { return m_domain.size(); }
00150
00155 Value& value() const
00156 {
00157 assert(size_eq(m_domain, 1));
00158 return *m_domain.front();
00159 }
00160
00167 Value& value(id_t id) const;
00168
00170 Domain::iterator beginValues() { return m_domain.begin(); }
00171
00173 Domain::iterator endValues() { return m_domain.end(); }
00174
00176 Domain::const_iterator beginValues() const { return m_domain.begin(); }
00177
00179 Domain::const_iterator endValues() const { return m_domain.end(); }
00180
00182 constraint_iterator beginConstraints() const
00183 {
00184 return m_activeConstraints.begin();
00185 }
00186
00188 constraint_iterator endConstraints() const
00189 {
00190 return m_activeConstraints.end();
00191 }
00192
00194 constraint_iterator beginInactiveConstraints() const
00195 {
00196 return m_inactiveConstraints.begin();
00197 }
00198
00200 constraint_iterator endInactiveConstraints() const
00201 {
00202 return m_inactiveConstraints.end();
00203 }
00204
00206 Domain& domain() { return m_domain; }
00207
00209 const Domain& domain() const { return m_domain; }
00210
00212 size_t constraints() const { return m_activeConstraints.size(); }
00213
00215 size_t inactiveConstraints() const { return m_inactiveConstraints.size(); }
00216
00218 size_t hiddenConstraints() const;
00219
00225 size_t degree() const { return constraints(); }
00226
00234 ulonglong weightedDegree() const;
00235
00237 void incrementDomainWipeouts() { m_domainWipeouts++; }
00238
00240 ulonglong domainWipeouts() const { return m_domainWipeouts; }
00241
00243 bool isPast() const { return m_past; }
00244
00246 bool isCurrent() const { return m_current; }
00247
00249 bool isFuture() const { return m_future; }
00250
00252 bool isInstantiated() const { return m_iDepth != -1; }
00253
00255 int instantiationDepth() const { return m_iDepth; }
00256
00259 const vector<Domain*>& diffs() const { return m_savedDiffs; }
00260
00299 void saveDiffs() { m_depth++; }
00300
00305 void restoreDiffs();
00306
00314 void postponeDiffs();
00315
00330 void addDiffs(Domain& diffs);
00331
00346 Value* findSupport(
00347 Value& value,
00348 const Constraint& constraint,
00349 Variable& pair);
00350
00364 size_t prune(
00365 const Constraint& constraint,
00366 Domain& diffs,
00367 bool consistent = false);
00368
00373 void sortDomain() { m_domain.sort(id_less<const Value*>()); }
00374
00376 virtual wostream& print(wostream& wos) const;
00377
00379 friend CSP_API wostream& operator<<(
00380 wostream& wos, const Variable& variable)
00381 {
00382 return variable.print(wos);
00383 }
00384
00385 protected:
00387 void add(Value& v)
00388 {
00389 if (v.id() == NoId)
00390 v.setId(m_nextValueId++);
00391
00392 m_domain.push_back(&v);
00393 }
00394
00396 void remove(Value& v)
00397 {
00398 Domain::iterator i = find(m_domain.begin(), m_domain.end(), &v);
00399 assert(i != m_domain.end());
00400 assert(*i == &v);
00401 v.setId(NoId);
00402 m_domain.erase(i);
00403 m_nextValueId--;
00404 }
00405
00406 private:
00408 Variable(const Variable&);
00409
00411 Variable& operator=(const Variable&);
00412
00414 void activateConstraint(const Constraint& constraint);
00415
00417 void deactivateConstraint(const Constraint& constraint);
00418
00420 void hideConstraint(const Constraint& constraint);
00421
00423 void unhideConstraint(const Constraint& constraint);
00424
00426
00428
00429 friend class Decomposition;
00430
00432 void setPastFlag(bool past) { m_past = past; }
00433
00435 void setCurrentFlag(bool current) { m_current = current; }
00436
00438 void setFutureFlag(bool future) { m_future = future; }
00439
00441 void instantiate();
00442
00444 void deinstantiate();
00445
00451 void hideConstraints();
00452
00459 void unhideConstraints(int depth);
00460
00467 void getReachableVariables(vhash_type& reachableVariables) const;
00468
00475 void createHidingDepth();
00476
00482 int hidingDepth() const { return m_hiddenConstraints.size() - 1; }
00483
00485
00487
00489 friend class Problem;
00490
00497 virtual void init()
00498 {
00499 m_past = false;
00500 m_current = false;
00501 m_future = true;
00502 m_domainWipeouts = 0;
00503 }
00504
00506 virtual void done() {}
00507
00515 bool isInternallyConsistent();
00516
00518 id_t m_id;
00519
00521 const Problem& m_problem;
00522
00524 FastVector<Constraint*> m_activeConstraints;
00525
00527 FastVector<Constraint*> m_inactiveConstraints;
00528
00530 Domain m_domain;
00531
00533 int m_depth;
00534
00536 int m_iDepth;
00537
00539 vector<int> m_savedDepths;
00540
00542 vector<Domain*> m_savedDiffs;
00543
00545 id_t m_nextValueId;
00546
00548 bool m_past;
00549
00551 bool m_current;
00552
00554 bool m_future;
00555
00575 vector<vector<Constraint*>*> m_hiddenConstraints;
00576
00577
00578
00579
00580
00585 ulonglong m_domainWipeouts;
00586 };
00587
00588
00589 CSP_NAMESPACE_END(csp);
00590
00591
00592 #endif // _CSP_KERNEL_Variable_H
00593
00594
00595
00596