/Users/jamian/Desktop/gecode-2.0.1/contribs/qecode/implicative.cc

Go to the documentation of this file.
00001 /*************************************************************[implicative.cc]
00002 Copyright (c) 2007, Universite d'Orleans - Jeremie Vautard, Marco Benedetti,
00003 Arnaud Lallouet.
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 *****************************************************************************/
00023 #include "implicative.hh"
00024 #include "myDom.cc"
00025 
00026 Implicative::Implicative(int ns,bool firstQ,int* nv) : QSpace() {
00027     n=0;
00028     for (int i=0;i<ns;i++) {
00029         n += nv[i];
00030     }
00031     nbSpaces=ns;
00032     v=new void*[n];
00033     type_of_v = new VarType[n];
00034     q=new bool[n];
00035     whichSpaceOwns=new int[n];
00036     nbVarBySpace=new int[nbSpaces];
00037     rules=new MySpace*[ns];
00038     ruleDefined=new bool[n];
00039     nbVarBySpace[0]=nv[0];
00040     rules[0]=new MySpace(nbVarBySpace[0]);
00041     ruleDefined[0] = true;
00042     for (int i=1;i<nbSpaces;i++) {
00043         nbVarBySpace[i]=nbVarBySpace[i-1]+nv[i];
00044         rules[i]=new MySpace(nbVarBySpace[i]);
00045         ruleDefined[i]=true;
00046     }
00047     goal=new MySpace(n);
00048     goalDefined=true;
00049     for(unsigned int i=0;i<n;i++) {
00050         int lespace=0;
00051         while (nbVarBySpace[lespace]<=i) lespace++;
00052         whichSpaceOwns[i]=lespace;
00053         q[i] = ((lespace%2 == 0) ? firstQ : !firstQ);
00054     }
00055     
00056     varInitialised=new bool[n];
00057     for (unsigned int i=0;i<n;i++) varInitialised[i]=false;
00058     currentDeclareSpace=0;
00059     prop_power=2;
00060 }
00061 
00062 
00063 Implicative::Implicative(Implicative& qc) : QSpace(qc) {
00064     
00065     unsigned long int rien;
00066     q=qc.q;
00067     nbSpaces=qc.nbSpaces;             // | Shared among every descendants of Implicatives
00068     nbVarBySpace=qc.nbVarBySpace;     // |
00069     whichSpaceOwns=qc.whichSpaceOwns; // |
00070     varInitialised=qc.varInitialised; // |
00071     rules = new MySpace*[n];
00072     ruleDefined=new bool[n];
00073     w=qc.w;
00074     w->update(this);
00075     prop_power=qc.prop_power;
00076     
00077     for (int i=0;i<nbSpaces;i++) {
00078         if (!qc.ruleDefined[i]) {
00079             ruleDefined[i]=false;
00080         }
00081         else if (qc.rules[i]->status(rien) == SS_FAILED) {
00082             ruleDefined[i]=false;
00083         }
00084         else {
00085             rules[i]=static_cast<MySpace*>(qc.rules[i]->clone());
00086             ruleDefined[i]=true;
00087         }
00088     }
00089     if (!qc.goalDefined) {
00090         goalDefined=false;
00091     }
00092     else if (qc.goal->status(rien) == SS_FAILED) {
00093         goalDefined=false;
00094     }
00095     else {
00096         goal=static_cast<MySpace*>(qc.goal->clone());
00097         goalDefined=true;
00098     }
00099     
00100     for (unsigned int i=0;i<n;i++) {
00101         if (ruleDefined[whichSpaceOwns[i]]) {
00102             v[i] = (rules[whichSpaceOwns[i]]->v[i]);
00103         }
00104     }
00105     
00106     
00107 }
00108 
00109 
00110 Implicative::~Implicative() {
00111     for (int i=0;i<nbSpaces;i++) {
00112         if (ruleDefined[i])
00113             delete rules[i];
00114     }    
00115     
00116     if (goalDefined) 
00117         delete goal;
00118     delete [] rules;
00119     delete [] ruleDefined;
00120 }
00121 
00122 
00123 int Implicative::spaces() {
00124     return nbSpaces;
00125 }
00126 
00127 
00128 void Implicative::QIntVar(int var,int min,int max) {
00129     if (varInitialised[var]) {
00130         cout<<"Variable "<<var<<"  Already created !!"<<endl;
00131         abort();
00132     }
00133     
00134     for (int i=whichSpaceOwns[var];i<nbSpaces;i++) {
00135         rules[i]->v[var] = new IntVar(rules[i],min,max);
00136         rules[i]->type_of_v[var] = VTYPE_INT;
00137     }
00138     goal->v[var] = new IntVar(goal,min,max);
00139     goal->type_of_v[var] = VTYPE_INT;
00140     varInitialised[var]=true;
00141     type_of_v[var]=VTYPE_INT;
00142 }
00143 
00144 
00145 void Implicative::QBoolVar(int var,int min,int max) {
00146     if (varInitialised[var]) {
00147         cout<<"Variable "<<var<<" Already created !!"<<endl;
00148         abort();
00149     }
00150     
00151     for (int i=whichSpaceOwns[var];i<nbSpaces;i++) {
00152         rules[i]->v[var] = new BoolVar(rules[i],min,max);
00153         rules[i]->type_of_v[var]=VTYPE_BOOL;
00154     }
00155     goal->v[var] = new BoolVar(goal,min,max);
00156     goal->type_of_v[var]=VTYPE_BOOL;
00157     varInitialised[var]=true;
00158     type_of_v[var]=VTYPE_BOOL;
00159 }
00160 
00161 
00162 void Implicative::QIntVar(int var,IntSet dom) {
00163     if (varInitialised[var]) {
00164         cout<<"Variable "<<var<<" Already created !!"<<endl;
00165         abort();
00166     }
00167     
00168     for (int i=whichSpaceOwns[var];i<nbSpaces;i++) {
00169         rules[i]->v[var] = new IntVar(rules[i],dom);
00170         rules[i]->type_of_v[var] = VTYPE_INT;
00171     }
00172     goal->v[var] = new IntVar(goal,dom);
00173     goal->type_of_v[var] = VTYPE_INT;
00174     varInitialised[var]=true;
00175     type_of_v[var]=VTYPE_INT;
00176 }
00177 
00178 
00179 MySpace* Implicative::space() {
00180     if (currentDeclareSpace<nbSpaces)
00181         return rules[currentDeclareSpace];
00182     if (currentDeclareSpace==nbSpaces)
00183         return goal;
00184     return NULL;
00185 }
00186 
00187 
00188 IntVar Implicative::var(int n) {
00189     return *(static_cast<IntVar*>(space()->v[n]));
00190 }
00191 
00192 
00193 BoolVar Implicative::bvar(int n) {
00194     return *(static_cast<BoolVar*>(space()->v[n]));
00195 }
00196 
00197 
00198 int Implicative::nextScope() {
00199     if (currentDeclareSpace == -1) return -1;
00200     currentDeclareSpace++;
00201     if (currentDeclareSpace>nbSpaces) return -1;
00202     return currentDeclareSpace;
00203 }
00204 
00205 /*
00206 MySpace* Implicative::getRuleSpace(int sp) {
00207     bool var=true;
00208     for(int i=0;i<n;i++) {
00209         var = var && varInitialised[i];
00210     }
00211     if (!var) return NULL;
00212     if ( sp >= nbSpaces ) return NULL;
00213     return rules[sp];
00214 }
00215 
00216 
00217 MySpace* Implicative::getGoalSpace() {
00218     bool var=true;
00219     for(int i=0;i<n;i++) {
00220         var = var && varInitialised[i];
00221     }
00222     if (!var) return NULL;
00223     return goal;
00224 }
00225 */
00226 
00227 void Implicative::makeStructure() {
00228 //    bool varInit=true;
00229     for (unsigned int i=0;i<n;i++) {
00230         if (varInitialised[i] == false) {
00231             cout<<"Can't make structure : variable "<<i<<" not initialised"<<endl;
00232             abort();
00233         }
00234     }
00235     
00236     for (unsigned int i=0;i<n;i++) {
00237         v[i] = rules[whichSpaceOwns[i]]->v[i];
00238     }
00239     w=new Warner(this);
00240     for(unsigned int i=0;i<n;i++) {
00241         switch (type_of_v[i]) {
00242             case VTYPE_INT:
00243                 IntWarningProp::IntWarning(rules[whichSpaceOwns[i]],i,*(static_cast<IntVar*>(rules[whichSpaceOwns[i]]->v[i])),w);
00244                 break;
00245             case VTYPE_BOOL:
00246                 BoolWarningProp::BoolWarning(rules[whichSpaceOwns[i]],i,*(static_cast<BoolVar*>(rules[whichSpaceOwns[i]]->v[i])),w);
00247                 break;
00248             default:
00249                 abort();
00250         }
00251     } 
00252 }
00253 
00254 
00255 bool Implicative::quantification(int v) {
00256     return q[v];
00257 }
00258 
00259 // Returns the number of the first failed space (number of rule space, nbSpaces if goal, nbSpaces+1 if there is no failed space)
00260 int Implicative::cascade(int firstSpace, unsigned long int& propsteps) {
00261     int curSpace = firstSpace;
00262     
00263     while(curSpace < nbSpaces) {
00264         MySpace* nextSpace = (curSpace==nbSpaces-1)?goal:rules[curSpace+1];
00265         bool* nextDefined  = (curSpace==nbSpaces-1)?&goalDefined:&(ruleDefined[curSpace+1]);
00266         
00267         if (!ruleDefined[curSpace]) {
00268             return curSpace;
00269         }
00270         if (rules[curSpace]->status(propsteps) == SS_FAILED) {
00271             return curSpace;
00272         }
00273         if (*nextDefined) {
00274             if (nextSpace->status(propsteps) != SS_FAILED) {
00275                 for (int i=0;i<nbVarBySpace[curSpace];i++) {
00276                     switch (type_of_v[i]) {
00277                         case VTYPE_INT :
00278                         {
00279                             IntView dest(*(static_cast<IntVar*>(nextSpace->v[i])));
00280                             IntView src(*(static_cast<IntVar*>(rules[curSpace]->v[i])));
00281                             ViewRanges<IntView> rg(src);
00282                             if (dest.inter_r(nextSpace,rg) == ME_GEN_FAILED) {
00283                                 nextSpace->fail();
00284                             };
00285                         }
00286                             break;
00287                         case VTYPE_BOOL :
00288                         {
00289                             BoolView bdest(*(static_cast<BoolVar*>(nextSpace->v[i])));
00290                             BoolView bsrc(*(static_cast<BoolVar*>(rules[curSpace]->v[i])));
00291                             ViewRanges<BoolView> brg(bsrc);
00292                             if (bdest.inter_r(nextSpace,brg) == ME_GEN_FAILED) {
00293                                 nextSpace->fail();
00294                             };
00295                         }
00296                             break;
00297                     }
00298                 }
00299             }
00300         }
00301         curSpace++;
00302     }
00303     
00304     if (!goalDefined) {
00305         return nbSpaces;
00306     }
00307     if (goal->status(propsteps) == SS_FAILED) {
00308         return nbSpaces;
00309     }
00310     
00311     return nbSpaces+1;
00312 }
00313 
00314 
00315 int Implicative::status(int var, unsigned long int& propsteps) {
00316     int currentSpace=whichSpaceOwns[var];
00317     currentSpace--;
00318     if (currentSpace<0) currentSpace=0;
00319     
00320     // First case : Strong propagation : ///////////////////////////////////////////
00321     // First, call cascade propagation. ////////////////////////////////////////////
00322     // We fail the spaces after the first failed one (so they are not //////////////
00323     // copied anymore)//////////////////////////////////////////////////////////////
00324     if (prop_power == 2) {                                                        //
00325         int firstFailed=cascade(currentSpace,propsteps);                          //
00326         for (int i=firstFailed;i<nbSpaces;i++) {                                  //
00327             if (ruleDefined[i]) rules[i]->fail();                                 //
00328         }                                                                         //
00329         if (firstFailed <= nbSpaces) {                                            //
00330             if (goalDefined)                                                      //
00331                 goal->fail();                                                     //
00332         }                                                                         //
00333                                                                                   //
00334         if (firstFailed==currentSpace) {                                          //
00335             return (quantification(var)?1:0);                                     //
00336         }                                                                         //
00337                                                                                   //
00338         return -1;                                                                //
00339     }                                                                             //
00341     
00342     else {
00343         cout<<"Propagation "<<prop_power<<" is not supported in this version of Qecode."<<endl;
00344         abort();
00345     }
00346 }
00347 
00348 
00349 int Implicative::finalStatus(unsigned long int& propsteps) {
00350     
00351     // Step 1 : we check every rule space in the order. If one of them is failed, //
00352     // we can answer. //////////////////////////////////////////////////////////////
00353     for (int i=0;i<nbSpaces;i++) {                                                //
00354         if (!ruleDefined[i])                                                      //
00355             return q[ nbVarBySpace[i]-1 ] ? 1 : 0;                                //
00356         if (rules[i]->status(propsteps) == SS_FAILED)                             //
00357             return q[ nbVarBySpace[i]-1 ] ? 1 : 0;                                //
00358     }                                                                             //
00360     
00361     // Step 2 : if we are here, then the rules were not violated. So, we check /////
00362     // the goal. ///////////////////////////////////////////////////////////////////
00363     if (!goalDefined)                                                             //
00364         return 0;                                                                 //
00365     if (goal->status(propsteps) == SS_FAILED)                                     //
00366         return 0;                                                                 //
00368     
00369     // Step 3 : if we are here, then the rules were respected, and the goal ////////
00370     // is also true. So, the whole problem is true. ////////////////////////////////
00371     return 1;                                                                     //
00373 }
00374 
00375 bool Implicative::subsumed(int var) {
00376     
00377     int varSpace=whichSpaceOwns[var];
00378     if (!ruleDefined[varSpace])
00379         return true;
00380     
00381     switch (type_of_v[var]) {
00382         case VTYPE_INT : 
00383         {
00384             IntVar* zeVar = static_cast<IntVar*>(rules[varSpace]->v[var]);
00385             unsigned int varSize=zeVar->size();
00386             
00387             if (zeVar->size() < 2) {
00388                 return true;
00389             }
00390 
00391             if (zeVar->degree() > 1) {
00392                 return false;
00393             }        
00394                 
00395             for (int i=varSpace+1;i<nbSpaces;i++) {
00396                 if (!ruleDefined[i])
00397                     return true;
00398                 if (static_cast<IntVar*>(rules[i]->v[var])->degree() > 0)
00399                     return false;
00400                 if (static_cast<IntVar*>(rules[i]->v[var])->size() < varSize)
00401                     return false;
00402             }
00403                 
00404             if (!goalDefined) {
00405                 return true;
00406             }
00407             if (static_cast<IntVar*>(goal->v[var])->degree() >0) {
00408                 return false;
00409             }
00410             if (static_cast<IntVar*>(goal->v[var])->size() < varSize) {
00411                 return false;
00412             }
00413             //else
00414             return true;
00415         }
00416             break;
00417         case VTYPE_BOOL :
00418         {
00419             BoolVar* zeBVar = static_cast<BoolVar*>(rules[varSpace]->v[var]);
00420             unsigned int varBSize=zeBVar->size();
00421             
00422             if (zeBVar->size() < 2) {
00423                 return true;
00424             }
00425                 
00426             if (zeBVar->degree() > 1) {
00427                 return false;
00428             }        
00429             
00430             for (int i=varSpace+1;i<nbSpaces;i++) {
00431                 if (!ruleDefined[i])
00432                     return true;
00433                 if (static_cast<BoolVar*>(rules[i]->v[var])->degree() > 0)
00434                     return false;
00435                 if (static_cast<BoolVar*>(rules[i]->v[var])->size() < varBSize)
00436                     return false;
00437             }
00438                 
00439             if (!goalDefined) {
00440                 return true;
00441             }
00442             if (static_cast<BoolVar*>(goal->v[var])->degree() >0) {
00443                 return false;
00444             }
00445             if (static_cast<BoolVar*>(goal->v[var])->size() < varBSize) {
00446                 return false;
00447             }
00448             //else
00449             return true;
00450         }
00451             break;
00452         default :
00453             return false;
00454     }
00455 }
00456 
00457 
00458 Implicative* Implicative::clone() {
00459     Implicative* resultat=new Implicative(*this);
00460     return resultat;
00461 }
00462 
00463 
00464 void Implicative::assign_int(int var,int** vals,int nbVals) {
00465     if (type_of_v[var] != VTYPE_INT) {
00466         cout<<"Wrong variable type for assigning"<<endl;
00467         abort();
00468     }
00469     int varspace = whichSpaceOwns[var];
00470     for (int i=varspace;i<nbSpaces;i++) {
00471         if (ruleDefined[i]) {
00472             MySpace* s = rules[i];
00473             post(s,*(static_cast<IntVar*>(s->v[var])) >= vals[0][0]);
00474             for (int j=1;j<nbVals;j++) {
00475                 IntSet rg(vals[1][j-1]+1,vals[0][j]-1);
00476                 myAntidom_int(s,*(static_cast<IntVar*>(s->v[var])),rg,ICL_DOM);
00477             }
00478             post(s,*(static_cast<IntVar*>(s->v[var])) <= vals[1][nbVals-1]);
00479         }
00480     }
00481 }
00482 
00483 
00484 void Implicative::remove_int(int var,int** vals,int nbVals) {
00485     if (type_of_v[var] != VTYPE_INT) {
00486         cout<<"Wrong variable type for assigning"<<endl;
00487         abort();
00488     }
00489     int varspace = whichSpaceOwns[var];
00490     for (int i=varspace;i<nbSpaces;i++) {
00491         if (ruleDefined[i]) {
00492             MySpace* s = rules[i];
00493             for (int j=0;j<nbVals;j++) {
00494                 IntSet rg(vals[0][j],vals[1][j]);
00495                 myAntidom_int(s,*(static_cast<IntVar*>(s->v[var])),rg,ICL_DOM);
00496             }
00497         }
00498     }
00499 }
00500 
00501 void Implicative::assign_bool(int var,int** vals,int nbVals) {
00502     if (type_of_v[var] != VTYPE_BOOL) {
00503         cout<<"Wrong variable type for assigning"<<endl;
00504         abort();
00505     }
00506     int varspace = whichSpaceOwns[var];
00507     for (int i=varspace;i<nbSpaces;i++) {
00508         if (ruleDefined[i]) {
00509             MySpace* s = rules[i];
00510             post(s,*(static_cast<BoolVar*>(s->v[var])) >= vals[0][0]);
00511             for (int j=1;j<nbVals;j++) {
00512                 IntSet rg(vals[1][j-1]+1,vals[0][j]-1);
00513                 myAntidom_bool(s,*(static_cast<BoolVar*>(s->v[var])),rg,ICL_DOM);
00514             }
00515             post(s,*(static_cast<BoolVar*>(s->v[var])) <= vals[1][nbVals-1]);
00516         }
00517     }
00518 }
00519 
00520 
00521 void Implicative::remove_bool(int var,int** vals,int nbVals) {
00522     if (type_of_v[var] != VTYPE_BOOL) {
00523         cout<<"Wrong variable type for assigning"<<endl;
00524         abort();
00525     }
00526     int varspace = whichSpaceOwns[var];
00527     for (int i=varspace;i<nbSpaces;i++) {
00528         if (ruleDefined[i]) {
00529             MySpace* s = rules[i];
00530             for (int j=0;j<nbVals;j++) {
00531                 IntSet rg(vals[0][j],vals[1][j]);
00532                 myAntidom_bool(s,*(static_cast<BoolVar*>(s->v[var])),rg,ICL_DOM);
00533             }
00534         }
00535     }
00536 }
00537 
00538 void Implicative::assign_bool(int var,int b) {
00539     if (type_of_v[var] != VTYPE_INT) {
00540         cout<<"Wrong variable type for assigning"<<endl;
00541         abort();
00542     }
00543     int varspace = whichSpaceOwns[var];
00544     for (int i=varspace;i<nbSpaces;i++) {
00545         if (ruleDefined[i]) {
00546             MySpace* s = rules[i];
00547             rel(s,*(static_cast<BoolVar*>(s->v[var])),IRT_EQ,b);
00548         }
00549     }
00550 }
00551 
00552 void Implicative::remove_bool(int var,int b) {
00553     if (type_of_v[var] != VTYPE_INT) {
00554         cout<<"Wrong variable type for assigning"<<endl;
00555         abort();
00556     }
00557     int varspace = whichSpaceOwns[var];
00558     for (int i=varspace;i<nbSpaces;i++) {
00559         if (ruleDefined[i]) {
00560             MySpace* s = rules[i];
00561             rel(s,*(static_cast<BoolVar*>(s->v[var])),IRT_NQ,b);
00562         }
00563     }
00564 }
00565 
00566 
00567 void Implicative::backtrack() {
00568     w->update(this);
00569 }
00570 
00571 
00572 void Implicative::indicateBranchingHeuristic(BranchingHeuristic* bh) {
00573     w->setBH(bh);
00574 }
00575 
00576 void Implicative::print() {
00577     for (int i=0;i<nv();i++)
00578         cout<<(q[i]?"A":"E");
00579     cout<<endl;
00580     for (int i=0;i<nbSpaces;i++) {
00581         if (ruleDefined[i]) {
00582             for (int j=0;j<nbVarBySpace[i];j++)
00583                 cout<<rules[i]->v[j]<<" ";
00584             cout<<endl;
00585         }
00586         else cout<<"Undefined"<<endl;
00587     }
00588     if (goalDefined) {
00589         for (int j=0;j<nv();j++)
00590             cout<<goal->v[j]<<" ";
00591         cout<<endl;
00592     }
00593     else cout<<"Undefined"<<endl;
00594     cout<<endl<<endl;
00595 }

Generated on Thu Feb 7 14:33:45 2008 for qecode by  doxygen 1.5.2