1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 /* 3 * Main authors: 4 * Vincent Barichard <Vincent.Barichard@univ-angers.fr> 5 * 6 * Copyright: 7 * Vincent Barichard, 2013 8 * 9 * Last modified: 10 * $Date$ by $Author$ 11 * $Revision$ 12 * 13 * This file is part of Quacode: 14 * http://quacode.barichard.com 15 * 16 * Permission is hereby granted, free of charge, to any person obtaining 17 * a copy of this software and associated documentation files (the 18 * "Software"), to deal in the Software without restriction, including 19 * without limitation the rights to use, copy, modify, merge, publish, 20 * distribute, sublicense, and/or sell copies of the Software, and to 21 * permit persons to whom the Software is furnished to do so, subject to 22 * the following conditions: 23 * 24 * The above copyright notice and this permission notice shall be 25 * included in all copies or substantial portions of the Software. 26 * 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 31 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 32 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 33 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 * 35 */ 36 #ifndef GECODE_QSPACEINFO_HH 37 #define GECODE_QSPACEINFO_HH 38 39 #include <iomanip> 40 #include <quacode/qcsp.hh> 41 #include <vector> 42 43 namespace Gecode { 44 // Forward declaration 45 class QSpaceInfo; 46 47 struct StrategyMethodValues { 48 /// Method used to build strategy during search 49 static const unsigned int BUILD = 1; ///< We build strategy 50 static const unsigned int DYNAMIC = 2; ///< Select strategy to dynamic instead of static, if not possible the strategy will be not built 51 static const unsigned int FAILTHROUGH = 4; ///< If static (not dynamic) strategy is selected but not possible, we go to dynamic strategy, but it may crashes because of lack of memory 52 static const unsigned int EXPAND = 8; ///< Expand all choices of solver (takes more computing time) 53 }; 54 /// The value of the methode used to build the winning strategy 55 typedef unsigned int StrategyMethod; 56 57 namespace Int { 58 /** 59 * \brief Watch propagator for a FORALL variable 60 * \ingroup FuncIntProp 61 */ 62 template<class View> 63 class Watch : public BinaryPropagator<View,PC_INT_DOM> { 64 protected: 65 using BinaryPropagator<View,PC_INT_DOM>::x0; 66 using BinaryPropagator<View,PC_INT_DOM>::x1; 67 68 /// Initial size of x0 69 unsigned int x0Size; 70 /// Constructor for cloning \a p 71 Watch(Space& home, bool share, Watch& p); 72 /// Constructor for posting 73 Watch(Home home, View x0, View x1, unsigned int _x0Size); 74 public: 75 76 /// Copy propagator during cloning 77 virtual Actor* copy(Space& home, bool share); 78 /// Cost function, very low 79 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 80 /// Perform propagation 81 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 82 /// Post watch constraint for x0 83 static ExecStatus post(Home home, View x0, View x1, unsigned int _x0Size); 84 }; 85 } 86 87 class DynamicStrategy; 88 class DynamicExpandStrategy; 89 class StrategyExplore; 90 91 // A strategy corresponds to a way to store values of variable with order. 92 // For example, a binder VxEyFz with x in {0,1,2} y in {-1,1} and z in {3,4} will 93 // result in a data structure of size : 1 + #{0,1,2} * (1 + ((1+1) + (1 + #{3,4}))) = 19 boxes 94 // Only one value per existential variable and all values for universal variables plus 95 // the id of the variable. 96 // The general formula is: Qx_i...Qx_n, Q in {V,E} 97 // we get: size(Qx_n) = if (Q == E) 2 else 1+#x_n 98 // size(Qx_i) = if (Q == E) 2 + size(Qx_{i+1}) else 1 + #x_i * (1 + size(Qx_{i+1})) 99 // The storage of strategy is not obvious, for previous example, it will be: 100 // |id(x)|v1(x)|id(y)|v(y)|id(z)|v1(z)|v2(z)|v2(x)|id(y)|v(y)|id(z)|v1(z)|v2(z)|v3(x)|id(y)|v(y)|id(z)|v1(z)|v2(z)| 101 // Forward declaration 102 class Strategy { 103 friend class DynamicStrategy; 104 friend class DynamicExpandStrategy; 105 friend class StrategyExplore; 106 public: 107 /// Values for current strategy state 108 static const unsigned int NONE = 0; 109 static const unsigned int CHOICE = 1; 110 static const unsigned int SUCCESS = 2; 111 static const unsigned int FAILURE = 3; 112 113 protected: 114 union Box { // A box of an array is either a variable id, either a variable idx 115 struct { 116 int id; // Id of variable 117 unsigned int nbAlt; // Number of explored boxes of the variable 118 bool needNewBlock; // Flag to know if the variable will be stored in a new linked block 119 // Useful only for dynamic strategy 120 } var; 121 struct { 122 int inf; // The inf value of a variable 123 int sup; // The sup value of a variable 124 bool leaf; // Flag to know if box is a leaf or not 125 } val; 126 struct { 127 Box* ptr; // Ptr to next linked block of strategy 128 // Useful only for dynamic strategy 129 unsigned int size; // Size of next block 130 } nextBlock; 131 }; 132 133 // Element of the current branch tree 134 struct BPtr { 135 int id; // Id of variable 136 int vInf; // The inf value for this variable 137 int vSup; // The sup value for this variable 138 Box* ptrId; // Pointer to the box which stores data about the current opened variable 139 Box* ptrCur; // Pointer to the current box for variable id (is moved according to the search) 140 unsigned int curRemainingStrategySize; // Current remaining size below this choice 141 142 // The following element is only meaningful for dynamic strategy 143 std::vector<Box*> blocks; // List of block to free if this node will be deleted 144 unsigned int curRemainingBlockSize; // Current remaining size of the current linked block below this choice 145 BPtrGecode::Strategy::BPtr146 BPtr() : id(-1), vInf(0), vSup(0), ptrId(NULL), ptrCur(NULL), curRemainingStrategySize(0), curRemainingBlockSize(0) {} BPtrGecode::Strategy::BPtr147 BPtr(int i, Box* pId, unsigned int crss) : id(i), vInf(0), vSup(0), ptrId(pId), ptrCur(NULL), curRemainingStrategySize(crss), curRemainingBlockSize(0) {} BPtrGecode::Strategy::BPtr148 BPtr(int i, Box* pId, unsigned int crss, Box* pNewBlock, unsigned int crbs) : id(i), vInf(0), vSup(0), ptrId(pId), ptrCur(NULL), curRemainingStrategySize(crss), curRemainingBlockSize(crbs) { if (pNewBlock != NULL) blocks.push_back(pNewBlock); } 149 }; 150 151 Box* bx; /// Array of boxes of the strategy 152 std::vector<unsigned int> domSize; // Size of domain of each variable 153 std::vector<int> idxInCurBranch; // Index of variable in current branch tree 154 unsigned int strategyTotalSize; // Size of all the strategy 155 Box* cur; /// Current pointed box of the strategy 156 157 std::vector<BPtr> curBranch; // Current branch of the search tree (contains id of variables) 158 int curDepth; // Current depth of the search tree (last chosen variable corresponds do curDepth - 1) 159 unsigned int lastEvent; // Last event recorded during search 160 161 // Print current strategy 162 void print(std::ostream& os, Box* p, unsigned int curRemainingStrategySize, int depth) const; 163 164 // Backtrack the strategy from a failure to the node of \a vId 165 // We assume that \a vId corresponds to an existential variable 166 void backtrackFromFailure(int vId); 167 // Backtrack the strategy from a failure to the node of \a vId 168 // We assume that \a vId corresponds to a universal variable 169 void backtrackFromSuccess(int vId); 170 171 // Add a new variable (new node) to the strategy 172 void addVariable(int vId); 173 // Add a new value to the current strategy 174 void addValue(int vId, int vInf, int vSup); 175 176 // Make the last value added to be a leaf 177 void makeLeaf(void); 178 179 // Copy constructor 180 Strategy(const Strategy& s); 181 public: 182 // Constructors 183 Strategy(); 184 // Destructor 185 virtual ~Strategy(); 186 187 // Copy current dynamic strategy copy(void) const188 virtual Strategy* copy(void) const { return new Strategy(*this); } 189 190 // Add new variable to the strategy 191 void add(unsigned int id, unsigned int size); 192 // Build vector of boxes, assumes that modeling is ended 193 QUACODE_EXPORT virtual bool strategyInit(); 194 /// Clear all data of the current strategy (used when search algorithm resets as well) 195 QUACODE_EXPORT virtual void strategyReset(); 196 197 // Return current depth of strategy depth(void) const198 int depth(void) const { return curDepth; } 199 // Return true if strategy has ever been allocated allocated(void) const200 bool allocated(void) const { return (bx != NULL); } 201 // Return depth of variable in the search tree, only usefull for debugging purpose varDepth(int vId) const202 int varDepth(int vId) const { return idxInCurBranch[vId]; } 203 204 /// Called when a failed scenario was found 205 virtual void scenarioFailed(); 206 /// Called when a successful scenario was found 207 virtual void scenarioSuccess(const QSpaceInfo&); 208 /// Record a new choice in the scenario, for variable \a vId 209 /// with value [ \a vInf , \a vSup ] 210 virtual void scenarioChoice(int vId, int vInf, int vSup); 211 212 // Print current strategy 213 QUACODE_EXPORT virtual void print(std::ostream& os) const; 214 }; 215 216 // This is an expanded strategy. It is based on a static strategy where all choices 217 // are expanded. 218 // For static expanded strategy, some data structures of Strategy are unused. For example 219 // curBranch is not needed as we don't need to know about the backtrack 220 class StaticExpandStrategy : public Strategy { 221 // Copy constructor 222 StaticExpandStrategy(const StaticExpandStrategy& s); 223 224 // Add a new value to the current strategy 225 // Return true if the value is new and has been add 226 void addValue(int vId, int vInf, int vSup, unsigned int sizeBelow, bool& bForce); 227 228 public: 229 // Constructors 230 StaticExpandStrategy(); 231 // Destructor 232 virtual ~StaticExpandStrategy(); 233 234 // Copy current dynamic strategy copy(void) const235 virtual StaticExpandStrategy* copy(void) const { return new StaticExpandStrategy(*this); } 236 237 // Build vector of boxes, assumes that modeling is ended 238 QUACODE_EXPORT virtual bool strategyInit(); 239 240 /// Called when a failed scenario was found 241 virtual void scenarioFailed(); 242 /// Called when a successful scenario was found 243 virtual void scenarioSuccess(const QSpaceInfo& qsi); 244 /// Record a new choice in the scenario, for variable \a vId 245 /// with value [ \a vInf , \a vSup ] 246 virtual void scenarioChoice(int vId, int vInf, int vSup); 247 }; 248 249 250 // A dynamic strategy is a dynamic data structure to record winning strategy. 251 // Contrary to instance of class Strategy, operations are not in constant time. 252 // So it may increases computing time. But it does not require to allocate the 253 // full strategy in memory, so it may be uses to store strategies which cannot be 254 // stored with full tree, but are smaller because sub-trees are cut during the search. 255 class DynamicStrategy : public Strategy { 256 // Print current strategy 257 void print(std::ostream& os, Box* p, unsigned int curRemainingBlockSize, int depth) const; 258 259 protected: 260 // Size of the first block (the one pointed by the bx member) 261 unsigned int bxBlockSize; 262 263 // Convert constructor 264 DynamicStrategy(const Strategy& s); 265 // Copy constructor 266 DynamicStrategy(const DynamicStrategy& s); 267 // Backtrack the strategy from a failure to the node of \a vId 268 // We assume that \a vId corresponds to an existential variable 269 void backtrackFromFailure(int vId); 270 // Backtrack the strategy from a failure to the node of \a vId 271 // We assume that \a vId corresponds to a universal variable 272 void backtrackFromSuccess(int vId); 273 274 // Add a new variable (new node) to the strategy 275 void addVariable(int vId); 276 277 public: 278 // Hint to bound the maximum allocated memory space for one block 279 static const unsigned int sMaxBlockMemory = 2 * 1024; 280 // Constructors 281 DynamicStrategy(); 282 // Destructor 283 virtual ~DynamicStrategy(); 284 285 // Copy current dynamic strategy copy(void) const286 virtual DynamicStrategy* copy(void) const { return new DynamicStrategy(*this); } 287 288 // Build vector of boxes, assumes that modeling is ended 289 QUACODE_EXPORT virtual bool strategyInit(); 290 /// Clear all data of the current strategy (used when search algorithm resets as well) 291 QUACODE_EXPORT virtual void strategyReset(); 292 293 /// Called when a failed scenario was found 294 virtual void scenarioFailed(); 295 /// Called when a successful scenario was found 296 virtual void scenarioSuccess(const QSpaceInfo&); 297 /// Record a new choice in the scenario, for variable \a vId 298 /// with value [ \a vInf , \a vSup ] 299 virtual void scenarioChoice(int vId, int vInf, int vSup); 300 301 // Print current strategy 302 QUACODE_EXPORT virtual void print(std::ostream& os) const; 303 304 // Static function to convert strategy object 305 static DynamicStrategy* fromStaticStrategy(const Strategy& ds); 306 }; 307 308 // This is an expanded strategy. It is based on a dynamic strategy where all choices 309 // are expanded. 310 // For dynamic expanded strategy, we use the curBranch data structure to store the blocks 311 // allowed. These blocks will be freed when backtrack because of failure 312 class DynamicExpandStrategy : public DynamicStrategy { 313 // Copy constructor 314 DynamicExpandStrategy(const DynamicExpandStrategy& s); 315 // Convert constructor 316 DynamicExpandStrategy(const Strategy& s); 317 318 // Add a new value to the current strategy 319 // Return true if the value is new and has been add 320 void addValue(int vId, int vInf, int vSup, unsigned int& sizeBelow, unsigned int& allocatedBlockSizeBelow, bool& bForce); 321 322 public: 323 // Constructors 324 DynamicExpandStrategy(); 325 // Destructor 326 virtual ~DynamicExpandStrategy(); 327 328 // Copy current dynamic strategy copy(void) const329 virtual DynamicExpandStrategy* copy(void) const { return new DynamicExpandStrategy(*this); } 330 331 // Build vector of boxes, assumes that modeling is ended 332 QUACODE_EXPORT virtual bool strategyInit(); 333 334 /// Called when a failed scenario was found 335 virtual void scenarioFailed(); 336 /// Called when a successful scenario was found 337 virtual void scenarioSuccess(const QSpaceInfo& qsi); 338 /// Record a new choice in the scenario, for variable \a vId 339 /// with value [ \a vInf , \a vSup ] 340 virtual void scenarioChoice(int vId, int vInf, int vSup); 341 342 // Static function to convert strategy object 343 static DynamicExpandStrategy* fromStaticStrategy(const Strategy& ds); 344 }; 345 346 /** 347 * \brief Class to iterate over a strategy 348 */ 349 class StrategyExplore { 350 private: 351 /// current strategy 352 const Strategy& s; 353 /// Stack of nodes to keep trace of parent 354 std::vector<Strategy::Box*> backStack; 355 public: 356 /// Initialize 357 StrategyExplore(const Strategy& s); 358 /// Test whether there nodes left (not on a leaf) 359 bool operator ()(void) const; 360 /// Move iterator to next node below (take the value of the edge) 361 void operator ++(int vEdge); 362 /// Move iterator to node upside (the parent) 363 void operator --(void); 364 /// Return node number (corresponding to the id of the variable of this node) 365 unsigned int variableId(void) const; 366 /// Return the number of values below the current node (i.e. the number of edges) 367 unsigned int nbValues(void) const; 368 /// Return the value of i^th edge of current node 369 int value(unsigned int ith) const; 370 }; 371 372 373 class QSpaceInfo { 374 friend class StaticExpandStrategy; 375 friend class DynamicExpandStrategy; 376 template<class View> friend class ::Gecode::Int::Watch; 377 /// Data structure to store link between id of variable in the binder 378 /// and the Gecode object (index of IntVar or BoolVar in the array of variables) 379 struct LkBinderVarObj { 380 static const unsigned int BOOL = 0; 381 static const unsigned int INT = 1; 382 int id; 383 int type; LkBinderVarObjGecode::QSpaceInfo::LkBinderVarObj384 LkBinderVarObj(int _i, int _t) : id(_i), type(_t) {} 385 }; 386 387 protected: 388 class QSpaceSharedInfoO : public SharedHandle::Object { 389 private: 390 // Data structure to gather information about brancher shared among all spaces 391 struct QBI { 392 TQuantifier quantifier; // Brancher quantifier 393 unsigned int offset; // Brancher offset (number of variables before it) 394 unsigned int size; // Brancher size (number of variables in brancher) QBIGecode::QSpaceInfo::QSpaceSharedInfoO::QBI395 QBI(void) : quantifier(EXISTS), offset(0), size(0) {} QBIGecode::QSpaceInfo::QSpaceSharedInfoO::QBI396 QBI(TQuantifier _q, unsigned int _o, unsigned int _s) 397 : quantifier(_q), offset(_o), size(_s) {} 398 }; 399 400 std::vector<LkBinderVarObj> _linkIdVars; // Link between id variable in strategy and Gecode object 401 std::vector<QBI> v; // Vector of data information about branchers 402 Strategy* s; // Current strategy 403 404 // Copy constructor 405 QSpaceSharedInfoO(const QSpaceSharedInfoO&); 406 public: 407 QSpaceSharedInfoO(StrategyMethod sm); 408 virtual ~QSpaceSharedInfoO(void); copy(void) const409 virtual SharedHandle::Object* copy(void) const { return new QSpaceSharedInfoO(*this); } 410 411 /// Add new quantified brancher information 412 void add(const QSpaceInfo& qsi, const BrancherHandle& bh, TQuantifier _q, const BoolVarArgs& x); 413 /// Add new quantified brancher information 414 void add(const QSpaceInfo& qsi, const BrancherHandle& bh, TQuantifier _q, const IntVarArgs& x); 415 /// Return the quantifier used for the brancher \a bh brancherQuantifier(unsigned int id) const416 forceinline TQuantifier brancherQuantifier(unsigned int id) const { return v[id-1].quantifier; } 417 /// Return the offset computed when the brancher \a bh was added brancherOffset(const unsigned int id) const418 forceinline unsigned int brancherOffset(const unsigned int id) const { return v[id-1].offset; } 419 // Return the last id of brancher stored in Shared Info. 420 // Return 0 if no brancher recorded. getLastBrancherId(void) const421 forceinline int getLastBrancherId(void) const { return v.size(); } 422 423 /// Initialize data structures of strategy, may return another method if strategy can't be allocated with given method 424 StrategyMethod strategyInit(StrategyMethod sm); 425 /// Clear all data of the current strategy (used when search algorithm resets as well) 426 void strategyReset(void); 427 /// Print the current strategy 428 void strategyPrint(std::ostream& os) const; 429 /// Called when a failed scenario was found 430 void scenarioFailed(void); 431 /// Called when a successful scenario was found 432 void scenarioSuccess(const QSpaceInfo& qsi); 433 /// Record a new choice event in the scenario, for brancher id \a id, 434 /// variable position \a pos and value [ \a vInf , \a vSup ] 435 void scenarioChoice(unsigned int id, int pos, int vInf, int vSup); 436 437 // Return the vector of link between the id of variable in the binder and the 438 // id of the same variable in its specific data structure 439 const std::vector<LkBinderVarObj>& linkIdVars(void) const; 440 }; 441 442 class QSpaceSharedInfo : public SharedHandle { 443 public: 444 /// Constructor 445 QSpaceSharedInfo(void); 446 /// Copy constructor 447 QSpaceSharedInfo(const QSpaceSharedInfo& bi); 448 /// Initialise for use 449 void init(StrategyMethod sm); 450 /// Add new brancher information 451 void add(const QSpaceInfo& qsi, const BrancherHandle& bh, TQuantifier _q, const IntVarArgs& x); 452 void add(const QSpaceInfo& qsi, const BrancherHandle& bh, TQuantifier _q, const BoolVarArgs& x); 453 454 /// SharedInfo access 455 /// Return the quantifier used for the brancher \a id 456 TQuantifier brancherQuantifier(unsigned int id) const; 457 /// Return the offset computed when the brancher \a id was added 458 unsigned int brancherOffset(unsigned int id) const; 459 /// Initialize data structures of strategy, may return another method if strategy can't be allocated with given method 460 StrategyMethod strategyInit(StrategyMethod sm); 461 /// Clear all data of the current strategy (used when search algorithm resets as well) 462 void strategyReset(void); 463 /// Print the current strategy 464 void strategyPrint(std::ostream& os) const; 465 /// Called when a failed scenario was found 466 void scenarioFailed(void); 467 /// Called when no strategy has been found (failed problem) 468 void scenarioSuccess(const QSpaceInfo& qsi); 469 /// Called when a successful scenario was found 470 // Record a new choice event in the strategy, for brancher id \a id, 471 // variable position \a pos and value [ \a vInf , \a vSup ] 472 void scenarioChoice(unsigned int id, int pos, int vInf, int vSup); 473 474 // Return the last id of brancher stored in Shared Info. 475 // Return -1 if not brancher recorded. 476 int getLastBrancherId(void) const; 477 // Return the vector of link between the id of variable in the binder and the 478 // id of the same variable in its specific data structure 479 const std::vector<LkBinderVarObj>& linkIdVars(void) const; 480 }; 481 482 /// Wrapper function to record choice in scenario 483 static void scenarioChoice(const Space &home, const BrancherHandle& bh, unsigned int a, BoolVar x, int i, const int& n, std::ostream& ); 484 static void scenarioChoice(const Space &home, const BrancherHandle& bh, unsigned int a, IntVar x, int i, const int& n, std::ostream& ); 485 486 /// The following arrays are not maintained during cloning !!! 487 /// Only meaningful during modeling 488 IntVarArgs _watchedIntVariables; 489 IntVarArgs _unWatchedIntVariables; 490 BoolVarArgs _watchedBoolVariables; 491 BoolVarArgs _unWatchedBoolVariables; 492 /// Return the corresponding unWatched variable if founded, NULL otherwise. 493 /// If Null is returned, it means that the variable isn't universally quantified. 494 BoolVar* unWatched(BoolVar x); 495 /// Return the corresponding unWatched variable if founded, NULL otherwise. 496 /// If Null is returned, it means that the variable isn't universally quantified. 497 IntVar* unWatched(IntVar x); 498 499 /// Shared information among all spaces 500 QSpaceSharedInfo sharedInfo; 501 502 /// Boolean flag to know if we have to record the winning strategy 503 bool bRecordStrategy; 504 /// The current strategy method to use during search 505 StrategyMethod curStrategyMethod; 506 507 // Number of WatchConstraint in space 508 unsigned int nbWatchConstraint; 509 /// Record a new watch constraint in space 510 void addWatchConstraint(void); 511 /// Remove a watch constraint of space 512 void delWatchConstraint(void); 513 514 /// Array of all boolean variables to branch with 515 BoolVarArray _boolVars; 516 /// Array of all integer variables to branch with 517 IntVarArray _intVars; 518 519 /// Update QSpace with data from brancher handle \a bh which contains variables \a x quantified with 520 /// quantifier \a _q. It will also update data shared by all clones. 521 QUACODE_EXPORT void updateQSpaceInfo(const BrancherHandle& bh, TQuantifier _q, const IntVarArgs& x); 522 QUACODE_EXPORT void updateQSpaceInfo(const BrancherHandle& bh, TQuantifier _q, const BoolVarArgs& x); 523 private: 524 /// Copy Constructor (disabled) 525 QSpaceInfo(const QSpaceInfo& qs); 526 public: 527 /// Default constructor 528 QUACODE_EXPORT QSpaceInfo(void); 529 /// Default destructor 530 QUACODE_EXPORT ~QSpaceInfo(void); 531 /// Copy Constructor 532 QUACODE_EXPORT QSpaceInfo(Space& home, bool share, QSpaceInfo& qs); 533 534 /// Return the quantifier used for the brancher \a id 535 TQuantifier brancherQuantifier(unsigned int id) const; 536 /// Return the offset computed when the brancher \a id was added 537 unsigned int brancherOffset(unsigned int id) const; 538 /// Return the number of recorded watch constraints in space 539 unsigned int watchConstraints(void) const; 540 541 /// Return the quantifier of the given integer variable quantifier(IntVar x)542 TQuantifier quantifier(IntVar x) { return (unWatched(x)?FORALL:EXISTS); }; 543 /// Return the quantifier of the given boolean variable quantifier(BoolVar x)544 TQuantifier quantifier(BoolVar x) { return (unWatched(x)?FORALL:EXISTS); }; 545 546 /// Return the current method used to build strategy 547 StrategyMethod strategyMethod(void) const; 548 /// Set the current method used to build strategy 549 void strategyMethod(StrategyMethod sm); 550 /// Initialize data structures of strategy. If the current strategy method can't 551 /// be used, it will update the strategy method value and returns it. 552 StrategyMethod strategyInit(); 553 /// Clear all data of the current strategy (used when search algorithm resets as well) 554 void strategyReset(); 555 /// Print the current strategy 556 void strategyPrint(std::ostream& os) const; 557 /// Called when no strategy has been found (failed problem) 558 void strategyFailed(); 559 /// Called when a strategy has been found (satisfiable problem) 560 void strategySuccess(); 561 /// Called when a failed scenario was found 562 void scenarioFailed(); 563 /// Called when a successful scenario was found 564 void scenarioSuccess(); 565 566 /// Return the unwatched variable corresponding to the watched one 567 IntVar getUnWatched(IntVar x); 568 /// Return the unwatched variable corresponding to the watched one 569 BoolVar getUnWatched(BoolVar x); 570 571 /// Set the given boolean variable \a x to be universal (It posts the according watching constraint) 572 void setForAll(Home home, BoolVar x); 573 /// Set the given array of boolean variables \a x to be universal (It posts the according watching constraint) 574 void setForAll(Home home, const BoolVarArgs& x); 575 /// Set the given integer variable \a x to be universal (It posts the according watching constraint) 576 void setForAll(Home home, IntVar x); 577 /// Set the given array of integer variables \a x to be universal (It posts the according watching constraint) 578 void setForAll(Home home, const IntVarArgs& x); 579 580 /// Function call when a new instance is found in QDFS algorithm 581 virtual void eventNewInstance(void) const; 582 583 /// Wrapper function to print data during branching 584 static BoolVarValPrint customBoolVVP; 585 static IntVarValPrint customIntVVP; 586 template <class VarType> static void runCustomChoice(const Space &home, const BrancherHandle& bh, unsigned int alt, VarType x, int pos, const int& val, std::ostream& os); 587 template <class VarType> static void doubleChoice(const Space &home, const BrancherHandle& bh, unsigned int alt, VarType x, int pos, const int& val, std::ostream& os); 588 template <class VarType> static void tripleChoice(const Space &home, const BrancherHandle& bh, unsigned int alt, VarType x, int pos, const int& val, std::ostream& os); 589 590 /// Branch over boolean variable \a x, quantified variable selection \a vars and value selection \a vals 591 template <class BranchType> QUACODE_EXPORT std::vector<BrancherHandle> branch(Home home, const BoolVar& x, BranchType vars, IntValBranch vals, BoolBranchFilter bf=NULL, BoolVarValPrint vvp=NULL); 592 /// Branch over boolean variables \a x, quantified variable selection \a vars and value selection \a vals 593 template <class BranchType> QUACODE_EXPORT std::vector<BrancherHandle> branch(Home home, const BoolVarArgs& x, BranchType vars, IntValBranch vals, BoolBranchFilter bf=NULL, BoolVarValPrint vvp=NULL); 594 /// Branch over integer variable \a x, quantified variable selection \a vars and value selection \a vals 595 template <class BranchType> QUACODE_EXPORT std::vector<BrancherHandle> branch(Home home, const IntVar& x, BranchType vars, IntValBranch vals, IntBranchFilter bf=NULL, IntVarValPrint vvp=NULL); 596 /// Branch over integer variables \a x, quantified variable selection \a vars and value selection \a vals 597 template <class BranchType> QUACODE_EXPORT std::vector<BrancherHandle> branch(Home home, const IntVarArgs& x, BranchType vars, IntValBranch vals, IntBranchFilter bf=NULL, IntVarValPrint vvp=NULL); 598 599 }; 600 } 601 602 #include <quacode/qspaceinfo.hpp> 603 #include <quacode/qint/watch.hpp> 604 605 #endif 606