Hi, Yes, you are absolutely correct in your analysis: failing a space does not stop execution of a space's method (or with other words, does not throw a C++ exception or something like that). The reason for that is that it does not matter! The code defining the variables, constraints, and propagators is executed just once initially in order to create the space for the root node of the search tree. This is cheap. What takes time is doing constraint propagation (triggered by status()) and this is terminated immediately when failure occurs.
Maybe MPG should explain this at some point. I am not sure I understand your second point. After running status() you should always check whether a space is failed (status() returns that information). So, when testing why not run status() everytime to make sure that things are not yet failed? Christian -- Christian Schulte, www.ict.kth.se/~cschulte/ -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Milt Sent: Sunday, November 20, 2011 7:43 PM To: [email protected] Subject: Re: [gecode-users] Indexing into arrays Guido, Thanks for your quick reply! I'd certainly missed that point about status() ...got it. But I think I still must be missing something, because I'm getting behavior I don't quite understand. So I distilled my code down to the simple example below that behaves as follows. -When I run the code below, I get these results (the rel(!A[0]) fails the space): A[0]=1, B0=0, C=0 A[1]=[0..1], B1=193, C=0 -I'd have expected A[1] to be equal to 0. -But when I change the assignment of B0 from expr(*this,0) to expr(*this,192), I get what I'd expect as results (the rel(!A[0]) doesn't fail the space): A[0]=0, B0=192, C=0 A[1]=0, B1=193, C=0 Is this what's meant in MPG section 4.1.7, that after a space fails, the domain may have more content than expected? Question: If so, then when the space fails during the relation !A[0], why does Gecode keep running my code to define A[1], do the status, and the couts? (I'd have expected Gecode to recognize that the space failed, abandon the failed space ASAP, and hurry to try another branching variable or value.) Also, my approach to debugging the constraint posting within my model is to use compiler directives (#if, #else, #endif) to maintain 2 paths thru my code: 1 - one that is normal, branching and exploring as intended, for example on an IntVarArray "list", which my code uses to compose constraints to post, and 2 - one that is for debugging a single test case at a time, so it branches and updates a different variable array "list_other", which my code ignores, and defines an IntVarArgs "list", and defines its items specifically to be a test case I'm debugging. So my code, which is written to examine "list", now focuses exclusively on the test case. This lets me avoid the confusion of the entire design space, and see just how the test case is being treated. (e.g., why it isn't being filtered out by the constraint I'd expect to catch it, or failing good cases.) Question: But, if Gecode shows extra items once it fails, as in the example below, how can I tell when the space has failed, to know whether my code is faulty in not narrowing down a domain, or whether some constraint has failed for the test case and I'm getting the after-fail behavior? (and if so, is there any simple way to detect which constraint detected the failed space, i.e., the straw that broke the camel's back; or does order of constraint posting matter?) Question: Is this a reasonable debugging strategy for the constraint posting (I'm not dealing with the search issues yet), or do people typically use other better techniques? (not sure where I'd look for Gecode debugging techniques...saw your interaction w/Roberto Pinto in 2006, but I'm looking for more of a targetable data dump of the data structures than an interactive Gist like exploration of the design-space search order -- Gist is great, but not what I think I need for this purpose.) Thanks for your help, -Milt --------------- class Trim : public Space { protected: public: IntVarArray IVA; // Constructor for script Trim() : IVA(*this, 1, 0, 3) { IntVar B0 = expr(*this,0); IntVar B1 = expr(*this,193); int C = 0; BoolVarArgs A(2); //Post constraints A[0] = expr(*this,B0==C,ICL_DOM); rel(*this,!A[0],ICL_DOM); A[1] = expr(*this,B1==C,ICL_DOM); status(); cout<<"A[0]="<<A[0]<<", B0="<<B0<<", C="<<C<<endl; cout<<"A[1]="<<A[1]<<", B1="<<B1<<", C="<<C<<endl; // post branching branch(*this, IVA, INT_VAR_SIZE_MIN, INT_VAL_MIN); } // search support: Constructor for cloning Trim(bool share, Trim& s) : Space(share, s) { IVA.update(*this, share, s.IVA); } // perform copying during cloning virtual Space* copy(bool share) { return new Trim(share,*this); } }; _______________________________________________ Gecode users mailing list [email protected] https://www.gecode.org/mailman/listinfo/gecode-users _______________________________________________ Gecode users mailing list [email protected] https://www.gecode.org/mailman/listinfo/gecode-users
