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