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, int prop) : QSpace(1) {
00027 n=0;
00028 for (int i=0;i<ns;i++) {
00029 n += nv[i];
00030 }
00031 nbSpaces=ns;
00032 v=IntVarArgs(n);
00033 q=new bool[n];
00034 whichSpaceOwns=new int[n];
00035 nbVarBySpace=new int[nbSpaces];
00036 rules=new MySpace*[ns];
00037 ruleDefined=new bool[n];
00038 nbVarBySpace[0]=nv[0];
00039 rules[0]=new MySpace(nbVarBySpace[0]);
00040 ruleDefined[0] = true;
00041 for (int i=1;i<nbSpaces;i++) {
00042 nbVarBySpace[i]=nbVarBySpace[i-1]+nv[i];
00043 rules[i]=new MySpace(nbVarBySpace[i]);
00044 ruleDefined[i]=true;
00045 }
00046 goal=new MySpace(n);
00047 goalDefined=true;
00048 for(int i=0;i<n;i++) {
00049 int lespace=0;
00050 while (nbVarBySpace[lespace]<=i) lespace++;
00051 whichSpaceOwns[i]=lespace;
00052 q[i] = ((lespace%2 == 0) ? firstQ : !firstQ);
00053 }
00054
00055 varInitialised=new bool[n];
00056 for (int i=0;i<n;i++) varInitialised[i]=false;
00057 currentDeclareSpace=0;
00058 prop_power=prop;
00059 }
00060
00061
00062 Implicative::Implicative(Implicative& qc) : QSpace(qc) {
00063
00064 unsigned long int rien;
00065 q=qc.q;
00066 nbSpaces=qc.nbSpaces;
00067 nbVarBySpace=qc.nbVarBySpace;
00068 whichSpaceOwns=qc.whichSpaceOwns;
00069 varInitialised=qc.varInitialised;
00070 rules = new MySpace*[n];
00071 ruleDefined=new bool[n];
00072 w=qc.w;
00073 w->update(this);
00074 prop_power=qc.prop_power;
00075
00076 for (int i=0;i<nbSpaces;i++) {
00077 if (!qc.ruleDefined[i]) {
00078 ruleDefined[i]=false;
00079 }
00080 else if (qc.rules[i]->status(rien) == SS_FAILED) {
00081 ruleDefined[i]=false;
00082 }
00083 else {
00084 rules[i]=static_cast<MySpace*>(qc.rules[i]->clone());
00085 ruleDefined[i]=true;
00086 }
00087 }
00088 if (!qc.goalDefined) {
00089 goalDefined=false;
00090 }
00091 else if (qc.goal->status(rien) == SS_FAILED) {
00092 goalDefined=false;
00093 }
00094 else {
00095 goal=static_cast<MySpace*>(qc.goal->clone());
00096 goalDefined=true;
00097 }
00098
00099 for (int i=0;i<n;i++) {
00100 if (ruleDefined[whichSpaceOwns[i]]) {
00101 v[i] = (rules[whichSpaceOwns[i]]->v[i]);
00102 }
00103 }
00104
00105
00106 }
00107
00108
00109 Implicative::~Implicative() {
00110 for (int i=0;i<nbSpaces;i++) {
00111 if (ruleDefined[i])
00112 delete rules[i];
00113 }
00114
00115 if (goalDefined)
00116 delete goal;
00117 delete rules;
00118 delete ruleDefined;
00119 }
00120
00121
00122 int Implicative::spaces() {
00123 return nbSpaces;
00124 }
00125
00126
00127 void Implicative::QIntVar(int var,int min,int max) {
00128 if (varInitialised[var]) {
00129 cout<<"Variable "<<var<<" Already created !!"<<endl;
00130 abort();
00131 }
00132
00133 for (int i=whichSpaceOwns[var];i<nbSpaces;i++) {
00134 rules[i]->v[var] = IntVar(rules[i],min,max);
00135 }
00136 goal->v[var] = IntVar(goal,min,max);
00137 varInitialised[var]=true;
00138 }
00139
00140
00141 void Implicative::QBoolVar(int var,int min,int max) {
00142 if (varInitialised[var]) {
00143 cout<<"Variable "<<var<<" Already created !!"<<endl;
00144 abort();
00145 }
00146
00147 for (int i=whichSpaceOwns[var];i<nbSpaces;i++) {
00148 rules[i]->v[var] = BoolVar(rules[i],min,max);
00149 }
00150 goal->v[var] = BoolVar(goal,min,max);
00151 varInitialised[var]=true;
00152 }
00153
00154
00155 void Implicative::QIntVar(int var,IntSet dom) {
00156 if (varInitialised[var]) {
00157 cout<<"Variable "<<var<<" Already created !!"<<endl;
00158 abort();
00159 }
00160
00161 for (int i=whichSpaceOwns[var];i<nbSpaces;i++) {
00162 rules[i]->v[var] = IntVar(rules[i],dom);
00163 }
00164 goal->v[var] = IntVar(goal,dom);
00165 varInitialised[var]=true;
00166 }
00167
00168
00169 MySpace* Implicative::space() {
00170 if (currentDeclareSpace<nbSpaces)
00171 return rules[currentDeclareSpace];
00172 if (currentDeclareSpace==nbSpaces)
00173 return goal;
00174 return NULL;
00175 }
00176
00177
00178 IntVar Implicative::var(int n) {
00179 return space()->v[n];
00180 }
00181
00182
00183 BoolVar Implicative::bvar(int n) {
00184 return static_cast<BoolVar>(space()->v[n]);
00185 }
00186
00187
00188 int Implicative::nextScope() {
00189 if (currentDeclareSpace == -1) return -1;
00190 currentDeclareSpace++;
00191 if (currentDeclareSpace>nbSpaces) return -1;
00192 return currentDeclareSpace;
00193 }
00194
00195
00196 MySpace* Implicative::getRuleSpace(int sp) {
00197 bool var=true;
00198 for(int i=0;i<n;i++) {
00199 var = var && varInitialised[i];
00200 }
00201 if (!var) return NULL;
00202 if ( sp >= nbSpaces ) return NULL;
00203 return rules[sp];
00204 }
00205
00206
00207 MySpace* Implicative::getGoalSpace() {
00208 bool var=true;
00209 for(int i=0;i<n;i++) {
00210 var = var && varInitialised[i];
00211 }
00212 if (!var) return NULL;
00213 return goal;
00214 }
00215
00216
00217 void Implicative::makeStructure() {
00218 bool varInit=true;
00219 for (int i=0;i<n;i++) {
00220 if (varInitialised[i] == false) {
00221 cout<<"Can't make structure : variable "<<i<<" not initialised"<<endl;
00222 abort();
00223 }
00224 }
00225
00226 for (int i=0;i<n;i++) {
00227 v[i] = rules[whichSpaceOwns[i]]->v[i];
00228 }
00229 w=new Warner(this);
00230 for(int i=0;i<n;i++) {
00231 WarningProp::warning(rules[whichSpaceOwns[i]],i,rules[whichSpaceOwns[i]]->v[i],w);
00232 }
00233 }
00234
00235
00236 bool Implicative::quantification(int v) {
00237 return q[v];
00238 }
00239
00240
00241 int Implicative::cascade(int firstSpace, unsigned long int& propsteps) {
00242 int curSpace = firstSpace;
00243
00244 while(curSpace < nbSpaces) {
00245 MySpace* nextSpace = (curSpace==nbSpaces-1)?goal:rules[curSpace+1];
00246 bool* nextDefined = (curSpace==nbSpaces-1)?&goalDefined:&(ruleDefined[curSpace+1]);
00247
00248 if (!ruleDefined[curSpace]) {
00249 return curSpace;
00250 }
00251 if (rules[curSpace]->status(propsteps) == SS_FAILED) {
00252 return curSpace;
00253 }
00254 if (*nextDefined) {
00255 if (nextSpace->status(propsteps) != SS_FAILED) {
00256 for (int i=0;i<nbVarBySpace[curSpace];i++) {
00257 IntView dest(nextSpace->v[i]);
00258 IntView src(rules[curSpace]->v[i]);
00259 ViewRanges<IntView> rg(src);
00260 if (dest.inter(nextSpace,rg) == ME_GEN_FAILED) {
00261 nextSpace->fail();
00262 }
00263 }
00264 }
00265 }
00266 curSpace++;
00267 }
00268
00269 if (!goalDefined) {
00270 return nbSpaces;
00271 }
00272 if (goal->status(propsteps) == SS_FAILED) {
00273 return nbSpaces;
00274 }
00275
00276 return nbSpaces+1;
00277 }
00278
00279
00280 int Implicative::status(int var, unsigned long int& propsteps) {
00281 int currentSpace=whichSpaceOwns[var];
00282 currentSpace--;
00283 if (currentSpace<0) currentSpace=0;
00284
00285
00286
00287
00288
00289 if (prop_power == 2) {
00290 int firstFailed=cascade(currentSpace,propsteps);
00291 for (int i=firstFailed;i<nbSpaces;i++) {
00292 if (ruleDefined[i]) rules[i]->fail();
00293 }
00294 if (firstFailed <= nbSpaces) {
00295 if (goalDefined)
00296 goal->fail();
00297 }
00298
00299 if (firstFailed==currentSpace) {
00300 return (quantification(var)?1:0);
00301 }
00302
00303 return -1;
00304 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00325
00326 else {
00327 cout<<"Propagation "<<prop_power<<" is not supported in this version of Qecode."<<endl;
00328 abort();
00329 }
00330 }
00331
00332
00333 int Implicative::finalStatus(unsigned long int& propsteps) {
00334
00335
00336
00337 for (int i=0;i<nbSpaces;i++) {
00338 if (!ruleDefined[i])
00339 return q[ nbVarBySpace[i]-1 ] ? 1 : 0;
00340 if (rules[i]->status(propsteps) == SS_FAILED)
00341 return q[ nbVarBySpace[i]-1 ] ? 1 : 0;
00342 }
00344
00345
00346
00347 if (!goalDefined)
00348 return 0;
00349 if (goal->status(propsteps) == SS_FAILED)
00350 return 0;
00352
00353
00354
00355 return 1;
00357 }
00358
00359 bool Implicative::subsumed(int var) {
00360
00361 int varSpace=whichSpaceOwns[var];
00362 if (!ruleDefined[varSpace])
00363 return true;
00364 int varSize=rules[varSpace]->v[var].size();
00365
00366 if (rules[varSpace]->v[var].size() < 2)
00367 return true;
00368
00369 if (rules[varSpace]->v[var].degree() > 1)
00370 return false;
00371
00372
00373 for (int i=varSpace+1;i<nbSpaces;i++) {
00374 if (!ruleDefined[i])
00375 return true;
00376 if (rules[i]->v[var].degree() > 0)
00377 return false;
00378 if (rules[i]->v[var].size() < varSize)
00379 return false;
00380 }
00381
00382 if (!goalDefined)
00383 return true;
00384 if (goal->v[var].degree() >0)
00385 return false;
00386 if (goal->v[var].size() < varSize)
00387 return false;
00388
00389
00390 return true;
00391 }
00392
00393
00394 Implicative* Implicative::clone() {
00395 Implicative* resultat=new Implicative(*this);
00396 return resultat;
00397 }
00398
00399
00400 void Implicative::assign(int var,int** vals,int nbVals) {
00401 int varspace = whichSpaceOwns[var];
00402 for (int i=varspace;i<nbSpaces;i++) {
00403 if (ruleDefined[i]) {
00404 MySpace* s = rules[i];
00405 post(s,s->v[var] >= vals[0][0]);
00406 for (int j=1;j<nbVals;j++) {
00407 IntSet rg(vals[1][j-1]+1,vals[0][j]-1);
00408 antidom(s,s->v[var],rg,ICL_DOM);
00409 }
00410 post(s,s->v[var] <= vals[1][nbVals-1]);
00411 }
00412 }
00413 }
00414
00415
00416 void Implicative::remove(int var,int** vals,int nbVals) {
00417 int varspace = whichSpaceOwns[var];
00418 for (int i=varspace;i<nbSpaces;i++) {
00419 if (ruleDefined[i]) {
00420 MySpace* s = rules[i];
00421 for (int j=0;j<nbVals;j++) {
00422 IntSet rg(vals[0][j],vals[1][j]);
00423 antidom(s,s->v[var],rg,ICL_DOM);
00424 }
00425 }
00426 }
00427 }
00428
00429
00430 void Implicative::backtrack() {
00431 w->update(this);
00432 }
00433
00434
00435 void Implicative::indicateBranchingHeuristic(BranchingHeuristic* bh) {
00436 w->setBH(bh);
00437 }
00438
00439 void Implicative::print() {
00440 for (int i=0;i<nv();i++)
00441 cout<<(q[i]?"A":"E");
00442 cout<<endl;
00443 for (int i=0;i<nbSpaces;i++) {
00444 if (ruleDefined[i]) {
00445 for (int j=0;j<nbVarBySpace[i];j++)
00446 cout<<rules[i]->v[j]<<" ";
00447 cout<<endl;
00448 }
00449 else cout<<"Undefined"<<endl;
00450 }
00451 if (goalDefined) {
00452 for (int j=0;j<nv();j++)
00453 cout<<goal->v[j]<<" ";
00454 cout<<endl;
00455 }
00456 else cout<<"Undefined"<<endl;
00457 cout<<endl<<endl;
00458 }