00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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;
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
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 void Implicative::makeStructure() {
00228
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
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
00321
00322
00323
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
00352
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
00362
00363 if (!goalDefined)
00364 return 0;
00365 if (goal->status(propsteps) == SS_FAILED)
00366 return 0;
00368
00369
00370
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
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
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 }