00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "gecode/set/projectors-compiler.hh"
00039 #include <iostream>
00040 #include <sstream>
00041 #include <string>
00042 #include <vector>
00043
00044 namespace Gecode {
00045
00046 ProjectorCompiler::Indent::Indent(void) : i(0) {}
00047
00048 void
00049 ProjectorCompiler::Indent::operator++(void) { i+=2; }
00050 void
00051 ProjectorCompiler::Indent::operator--(void) { i-=2; }
00052
00053 std::ostream&
00054 operator<<(std::ostream& os, const ProjectorCompiler::Indent& indent) {
00055 for (int i=0; i<indent.i; i++)
00056 os << " ";
00057 return os;
00058 }
00059
00060 bool
00061 ProjectorCompiler::nary(void) {
00062 return spec._arity <= 0 || spec._arity >= 4;
00063 }
00064
00065 std::string
00066 ProjectorCompiler::propcost(void) {
00067 switch (spec._arity) {
00068 case 1: return "PC_UNARY_HI";
00069 case 2: return "PC_BINARY_HI";
00070 case 3: return "PC_TERNARY_HI";
00071 default: return "PC_LINEAR_HI";
00072 }
00073 }
00074
00075 void
00076 ProjectorCompiler::header(std::ostream& os) {
00077 os
00078 << "// This file was generated from projector specifications."
00079 << std::endl << std::endl;
00080
00081 if (spec._namespace != "") {
00082 os << indent << spec._namespace << std::endl;
00083 ++indent;
00084 }
00085 }
00086
00087 void
00088 ProjectorCompiler::footer(std::ostream& os) {
00089 if (spec._namespace != "") {
00090 --indent;
00091 os << indent << "}";
00092 }
00093 os << std::endl;
00094 }
00095
00096 void
00097 ProjectorCompiler::viewsarglist(std::ostream& os) {
00098 if (nary()) {
00099 os << "ViewArray<View>& x";
00100 } else {
00101 for (int i=0; i<spec._arity; i++) {
00102 if (views==SINGLE_VIEW)
00103 os << "View";
00104 else
00105 os << "View" << i;
00106 os << " x" << i;
00107 if (i<spec._arity-1)
00108 os << ", ";
00109 }
00110 }
00111 if (spec._reified)
00112 os << ", Gecode::Int::BoolView b";
00113 }
00114
00115 void
00116 ProjectorCompiler::initarglist(std::ostream& os) {
00117 if (nary()) {
00118 os << "_x(x)";
00119 } else {
00120 for (int i=0; i<spec._arity; i++) {
00121 os << "_x"<< i << "("
00122 << "x" << i << ")";
00123 if (i<spec._arity-1)
00124 os <<", ";
00125 }
00126 }
00127 if (spec._reified)
00128 os << ", _b(b)";
00129 }
00130
00131 void ProjectorCompiler::templateparams(void) {
00132 iccos << "<";
00133 if (nary() || views==SINGLE_VIEW)
00134 iccos << "View";
00135 else
00136 for (int i=0; i<spec._arity; i++) {
00137 iccos << "View" << i;
00138 if (i!=spec._arity-1)
00139 hhos << ", ";
00140 }
00141 iccos << ">";
00142 }
00143
00144 void ProjectorCompiler::templatehead(std::ostream& os) {
00145 if (nary() || views==SINGLE_VIEW)
00146 os << indent << "template <class View>" << std::endl;
00147 else {
00148 os << indent << "template <";
00149 for (int i=0; i<spec._arity; i++) {
00150 os << "class View" << i;
00151 if (i!=spec._arity-1)
00152 os << ", ";
00153 }
00154 os << ">" << std::endl;
00155 }
00156 }
00157
00158 void
00159 ProjectorCompiler::classdef(void) {
00160 using namespace std;
00161 templatehead(hhos);
00162 hhos << indent
00163 << "class " << spec._name << " : public Propagator { " << endl
00164 << indent << "protected:" << endl;
00165
00166 if (nary())
00167 hhos << indent
00168 << " ViewArray<View> _x; ///< The view array" << endl;
00169 else
00170 for (int i=0; i<spec._arity; i++) {
00171 hhos << indent << " ";
00172 if (views==SINGLE_VIEW)
00173 hhos << "View";
00174 else
00175 hhos << "View" << i;
00176 hhos << " _x" << i << "; ///< View #" << i << endl;
00177 }
00178
00179 if (spec._reified)
00180 hhos << indent
00181 << " Gecode::Int::BoolView _b; ///< Boolean view for reification"
00182 << endl;
00183
00184 hhos << indent
00185 << " /// Constructor for cloning" << endl << indent
00186 << " " << spec._name << "(Space* home,bool,"
00187 << spec._name << "&);" << endl;
00188
00189 hhos << indent
00190 << " /// Constructor for creation" << endl << indent
00191 << " " << spec._name << "(Space* home, ";
00192 viewsarglist(hhos);
00193 hhos
00194 << ");" << endl;
00195
00196 hhos << endl;
00197 hhos << indent << " /// Propagate non-negated version" << endl;
00198 hhos << indent << " ExecStatus propagatePositive(Space* home);"
00199 << endl;
00200
00201 if (spec._reified || spec._negated) {
00202 hhos << indent << " /// Check if the constraint holds" << endl;
00203 hhos << indent << " ExecStatus check(Space* home);" << endl;
00204 hhos << indent << " /// Propagate negated version" << endl;
00205 hhos << indent << " ExecStatus propagateNegative(Space* home);"
00206 << endl << endl;
00207 }
00208
00209 hhos << indent
00210 << "public:" << endl;
00211
00212 hhos << indent
00213 << " /// Cost function (defined as " << propcost() << ")"
00214 << endl << indent
00215 << " virtual PropCost cost(ModEventDelta med) const;" << endl;
00216
00217 hhos << indent
00218 << " /// Delete propagator and return its size"
00219 << endl << indent
00220 << " virtual size_t dispose(Space* home);" << endl;
00221
00222 hhos << indent
00223 << " /// Copy propagator during cloning" << endl << indent
00224 << " virtual Actor* copy(Space* home,bool);" << endl
00225 << endl << indent
00226 << " /// Perform propagation" << endl << indent
00227 << " virtual ExecStatus propagate(Space* home, ModEventDelta med);" << endl
00228 << endl << indent
00229 << " /// Post projection propagator" << endl << indent
00230 << " static ExecStatus post(Space* home, ";
00231 viewsarglist(hhos);
00232 hhos
00233 << ");" << endl;
00234
00235 hhos << indent << "};" << endl;
00236
00237 }
00238
00239 std::string
00240 ProjectorCompiler::propcond(PropCond pc) {
00241 if (spec._reified || spec._negated) {
00242 switch (pc) {
00243 case Gecode::Set::PC_SET_VAL : return "Gecode::Set::PC_SET_VAL";
00244 case Gecode::Set::PC_SET_CARD : return "Gecode::Set::PC_SET_CARD";
00245 case Gecode::Set::PC_SET_CGLB :
00246 case Gecode::Set::PC_SET_CLUB :
00247 case Gecode::Set::PC_SET_ANY : return "Gecode::Set::PC_SET_ANY";
00248 default: GECODE_NEVER;
00249 }
00250 }
00251
00252 switch (pc) {
00253 case Gecode::Set::PC_SET_VAL : return "Gecode::Set::PC_SET_VAL";
00254 case Gecode::Set::PC_SET_CARD : return "Gecode::Set::PC_SET_CARD";
00255 case Gecode::Set::PC_SET_CGLB : return "Gecode::Set::PC_SET_CGLB";
00256 case Gecode::Set::PC_SET_CLUB : return "Gecode::Set::PC_SET_CLUB";
00257 case Gecode::Set::PC_SET_ANY : return "Gecode::Set::PC_SET_ANY";
00258 default:
00260 std::cerr << "Unknown PropCond" << std::endl;
00261 exit(2);
00262 }
00263 }
00264
00265 void
00266 ProjectorCompiler::standardMemberFunctions(void) {
00267 using namespace std;
00269
00270 templatehead(iccos);
00271 iccos << indent << spec._name;
00272 templateparams();
00273 iccos << "::" << spec._name << endl << indent
00274 << "(Space* home, ";
00275 viewsarglist(iccos);
00276 iccos << ")" << endl;
00277
00278 ++indent;
00279
00280 iccos << indent
00281 << ": Propagator(home), ";
00282 initarglist(iccos);
00283 iccos << " {" << endl;
00284
00285 int projArity = spec._ps.arity();
00286 Support::DynamicArray<int> scope;
00287 spec._ps.scope(scope, projArity);
00288 bool isNary = nary();
00289
00290 for (int i=0; i<=projArity; i++) {
00291 iccos << indent << "_x";
00292 if (isNary) iccos << "[";
00293 iccos << i;
00294 if (isNary) iccos << "]";
00295 iccos << ".subscribe(home, this, " << propcond(scope[i])
00296 << ");" << endl;
00297 }
00298
00299 if (spec._reified)
00300 iccos << indent << "_b.subscribe(home, this, Gecode::Int::PC_INT_VAL);"
00301 << endl;
00302
00303 --indent;
00304 iccos << indent << "}" << endl;
00306
00307 iccos << endl;
00308
00310
00311 templatehead(iccos);
00312 iccos << indent
00313 << spec._name;
00314 templateparams();
00315 iccos << "::" << spec._name << endl << indent
00316 << "(Space* home, bool share, " << spec._name << "& p)" << endl;
00317
00318 ++indent;
00319
00320 iccos << indent
00321 << ": Propagator(home, share, p) {" << endl;
00322
00323 if (isNary) {
00324 iccos << indent << "_x.update(home, share, p._x);" << endl;
00325 } else {
00326 for (int i=0; i<spec._arity; i++)
00327 iccos << indent
00328 << "_x" << i << ".update(home, share, p._x" << i << ");" << endl;
00329 }
00330
00331 if (spec._reified)
00332 iccos << indent << "_b.update(home, share, p._b);" << endl;
00333
00334 --indent;
00335 iccos << indent << "}" << endl;
00337
00338
00340
00341 iccos << endl;
00342 templatehead(iccos);
00343 iccos << indent << "size_t" << endl;
00344 iccos << indent << spec._name;
00345 templateparams();
00346 iccos << "::dispose(Space* home) {" << endl;
00347 ++indent;
00348 iccos << indent << "if (!home->failed()) {" << endl;
00349 ++indent;
00350
00351 for (int i=0; i<=projArity; i++) {
00352 iccos << indent << "_x";
00353 if (isNary) iccos << "[";
00354 iccos << i;
00355 if (isNary) iccos << "]";
00356 iccos << ".cancel(home, this, " << propcond(scope[i])
00357 << ");" << endl;
00358 }
00359
00360 if (spec._reified)
00361 iccos << indent << "_b.cancel(home, this, Gecode::Int::PC_INT_VAL);"
00362 << endl;
00363
00364 --indent;
00365 iccos << indent << "}" << endl;
00366
00367 iccos << indent << "(void) Propagator::dispose(home);" << endl
00368 << indent << "return sizeof(*this);" << endl;
00369
00370 --indent;
00371 iccos << indent << "}" << endl << endl;
00373
00374
00376
00377 templatehead(iccos);
00378 iccos << indent
00379 << "Actor*" << endl << indent
00380 << spec._name;
00381 templateparams();
00382 iccos << "::copy(Space* home, bool share) {"
00383 << endl << indent
00384 << " return new (home) " << spec._name << "(home,share,*this);"
00385 << endl << indent << "}" << endl << endl;
00387
00389
00390 templatehead(iccos);
00391 iccos << indent
00392 << "ExecStatus" << endl << indent
00393 << spec._name;
00394 templateparams();
00395 iccos << "::post(Space* home, ";
00396 viewsarglist(iccos);
00397 iccos << ") {" << endl << indent
00398 << " (void) new (home) " << spec._name << "(home, ";
00399 if (isNary) {
00400 iccos << "x";
00401 } else {
00402 for (int i=0; i<spec._arity; i++) {
00403 iccos << "x" << i;
00404 if (i<spec._arity-1)
00405 iccos << ", ";
00406 }
00407 }
00408 if (spec._reified)
00409 iccos << ", b";
00410 iccos << ");" << endl
00411 << indent << " return ES_OK;" << endl
00412 << indent << "}" << endl;
00414
00415
00417
00418 iccos << endl;
00419 templatehead(iccos);
00420 iccos << indent
00421 << "PropCost" << endl << indent
00422 << spec._name;
00423 templateparams();
00424 iccos << "::cost(ModEventDelta) const {" << endl << indent
00425 << " return " << propcost() << ";" << endl << indent
00426 << "}" << endl;
00428
00429 }
00430
00431 int
00432 ProjectorCompiler::iterator(const SetExprCode& instrs,
00433 bool countSize, bool invert) {
00434 using namespace std;
00435 vector<string> typestack;
00436 vector<int> argstack;
00437
00438 int arg = 0;
00439
00440 for (int i=0; i<instrs.size(); i++) {
00441 switch (instrs[i]) {
00442 case SetExprCode::COMPLEMENT:
00443 {
00444 string t = typestack.back(); typestack.pop_back();
00445 int a = argstack.back(); argstack.pop_back();
00446 iccos << indent
00447 << "RangesCompl<" << t << " > i" << (++arg)
00448 << "(i" << a << ");" << endl;
00449 typestack.push_back("RangesCompl<"+t+" >");
00450 argstack.push_back(arg);
00451 }
00452 break;
00453 case SetExprCode::INTER:
00454 {
00455 string t2 = typestack.back(); typestack.pop_back();
00456 string t1 = typestack.back(); typestack.pop_back();
00457 int a2 = argstack.back(); argstack.pop_back();
00458 int a1 = argstack.back(); argstack.pop_back();
00459 iccos << indent
00460 << "Iter::Ranges::Inter<" << t1 << ", " << t2 << " > i"
00461 << (++arg)
00462 << "(i" << a1 << ", i" << a2 << ");" << endl;
00463 typestack.push_back("Iter::Ranges::Inter<"+t1+", "+t2+" >");
00464 argstack.push_back(arg);
00465 }
00466 break;
00467 case SetExprCode::UNION:
00468 {
00469 string t2 = typestack.back(); typestack.pop_back();
00470 string t1 = typestack.back(); typestack.pop_back();
00471 int a2 = argstack.back(); argstack.pop_back();
00472 int a1 = argstack.back(); argstack.pop_back();
00473 iccos << indent
00474 << "Iter::Ranges::Union<" << t1 << ", " << t2 << " > i"
00475 << (++arg)
00476 << "(i" << a1 << ", i" << a2 << ");" << endl;
00477 typestack.push_back("Iter::Ranges::Union<"+t1+", "+t2+" >");
00478 argstack.push_back(arg);
00479 }
00480 break;
00481 case SetExprCode::GLB:
00482 case SetExprCode::LUB:
00483 {
00484 string bound;
00485 if (invert) {
00486 if (instrs[i] == SetExprCode::GLB)
00487 bound = "Lub";
00488 else
00489 bound = "Glb";
00490 } else {
00491 if (instrs[i] == SetExprCode::GLB)
00492 bound = "Glb";
00493 else
00494 bound = "Lub";
00495 }
00496
00497 int a = argstack.back(); argstack.pop_back();
00498 iccos << indent;
00499 if (nary() || views==SINGLE_VIEW) {
00500 iccos << bound << "Ranges<View> i";
00501 string ty = bound + "Ranges<View>";
00502 typestack.push_back(ty);
00503 } else {
00504 iccos << bound << "Ranges<View" << a << "> i";
00505 stringstream s;
00506 s << a;
00507 string ty = bound + "Ranges<View";
00508 ty += s.str();
00509 ty += ">";
00510 typestack.push_back(ty);
00511 }
00512 iccos << (++arg);
00513 if (nary())
00514 iccos << "(_x[" << a << "]);" << endl;
00515 else
00516 iccos << "(_x" << a << ");" << endl;
00517 argstack.push_back(arg);
00518 }
00519 break;
00520 case SetExprCode::EMPTY : iccos << " e "; break;
00521 case SetExprCode::UNIVERSE : iccos << " u "; break;
00522 default:
00523 {
00524 argstack.push_back((instrs[i])-SetExprCode::LAST);
00525 }
00526 break;
00527 }
00528 }
00529
00530 if (countSize) {
00531 ++arg;
00532 iccos << indent << "Iter::Ranges::Size<" << typestack.back()
00533 << " > i" << arg << "(i" << (arg-1) << ");" << endl;
00534 }
00535
00536 return arg;
00537 }
00538
00539 void
00540 ProjectorCompiler::allAssigned(std::ostream& os) {
00541 using namespace std;
00542 os << indent << "bool assigned=true;" << endl;
00543 if (nary()) {
00544 os << indent << "for (int i=_x.size(); i--;)" << endl;
00545 os << indent << " assigned = assigned && _x[i].assigned();" << endl;
00546 } else {
00547 for (int i=0; i<spec._arity; i++)
00548 os << indent << "assigned = assigned && _x" << i << ".assigned();"
00549 << endl;
00550 }
00551 }
00552
00553 void
00554 ProjectorCompiler::propagation(void) {
00555 using namespace std;
00556 if (!spec._negated || spec._reified) {
00557 templatehead(iccos);
00558 iccos << indent << "ExecStatus" << endl << indent << spec._name;
00559 templateparams();
00560 iccos << "::propagatePositive(Space* home) {" << endl;
00561 ++indent;
00562
00563 string me_check;
00564 switch (fixpoint) {
00565 case NO_FIX:
00566 {
00567 me_check="GECODE_ME_CHECK(";
00568 allAssigned(iccos);
00569 }
00570 break;
00571 case ITER_FIX:
00572 {
00573 iccos << indent << "bool modified=true;" << endl;
00574 iccos << indent << "while (modified) {" << endl;
00575 ++indent;
00576 iccos << indent << "modified = false;" << endl;
00577 me_check = "GECODE_ME_CHECK_MODIFIED(modified, ";
00578 }
00579 break;
00580 default: GECODE_NEVER;
00581 }
00582
00583 for (int i=spec._ps.size(); i--; ) {
00584 SetExprCode glb = spec._ps[i].getGlb();
00585 if (glb.size() > 0 && glb[0] != SetExprCode::EMPTY) {
00586 iccos << indent << "{" << endl;
00587 ++indent;
00588 int arg = iterator(glb, false, true);
00589 iccos << indent << me_check;
00590 if (nary())
00591 iccos << "_x[" << spec._ps[i].getIdx() << "]";
00592 else
00593 iccos << "_x" << spec._ps[i].getIdx();
00594 iccos << ".includeI(home, i" << arg << "));" << endl;
00595 --indent;
00596 iccos << indent << "}" << endl;
00597 }
00598 SetExprCode lub = spec._ps[i].getLub();
00599 if (lub.size() > 0 && lub[0] != SetExprCode::UNIVERSE) {
00600 iccos << indent << "{" << endl;
00601 ++indent;
00602 int arg = iterator(lub);
00603 iccos << indent << me_check;
00604 if (nary())
00605 iccos << "_x[" << spec._ps[i].getIdx() << "]";
00606 else
00607 iccos << "_x" << spec._ps[i].getIdx();
00608 iccos << ".intersectI(home, i" << arg << "));" << endl;
00609 --indent;
00610 iccos << indent << "}" << endl;
00611 }
00612 }
00613
00614 switch (fixpoint) {
00615 case NO_FIX:
00616 iccos << indent << "return assigned ? ES_SUBSUMED(this,home) : ES_NOFIX;"
00617 << endl;
00618 break;
00619 case ITER_FIX:
00620 {
00621 --indent;
00622 iccos << indent << "}" << endl;
00623 allAssigned(iccos);
00624 iccos << indent << "return assigned ? ES_SUBSUMED(this,home) : ES_FIX;"
00625 << endl;
00626 }
00627 break;
00628 default: GECODE_NEVER;
00629 }
00630
00631 --indent;
00632 iccos << indent << "}" << endl << endl;
00633 }
00634
00635 if (spec._negated || spec._reified) {
00636 templatehead(iccos);
00637 iccos << indent << "ExecStatus" << endl << indent << spec._name;
00638 templateparams();
00639 iccos << "::check(Space* home) {" << endl;
00640 ++indent;
00641 iccos << indent << "ExecStatus es = ES_SUBSUMED(this,home);" << endl;
00642 for (int i=spec._ps.size(); i--; ) {
00643 SetExprCode glb = spec._ps[i].getGlb();
00644 if (glb.size() > 0 && glb[0] != SetExprCode::EMPTY) {
00645 iccos << indent << "{" << endl;
00646 ++indent;
00647 int arg = iterator(glb,true,true);
00648
00649 iccos << indent;
00650 if (nary())
00651 iccos << "LubRanges<View> j(_x[" << spec._ps[i].getIdx() << "]);";
00652 else if (views==SINGLE_VIEW)
00653 iccos << "LubRanges<View> j(_x" << spec._ps[i].getIdx() << ");";
00654 else
00655 iccos << "LubRanges<View" << spec._ps[i].getIdx() << "> j(x"
00656 << spec._ps[i].getIdx() << ");";
00657 iccos << endl;
00658 iccos << indent
00659 << "if (!Iter::Ranges::subset(i" << arg
00660 << ",j)) return ES_FAILED;"
00661 << endl;
00662 iccos << indent << "while (i" << arg << "()) ++i" << arg << ";"
00663 << endl;
00664 if (nary())
00665 iccos << indent << "if (i" << arg << ".size() > _x[" << i << "].cardMax())";
00666 else
00667 iccos << indent << "if (i" << arg << ".size() > _x" << i << ".cardMax())";
00668 iccos << endl;
00669 iccos << indent << " return ES_FAILED;" << endl;
00670 --indent;
00671 iccos << indent << "}" << endl;
00672 }
00673 SetExprCode lub = spec._ps[i].getLub();
00674 if (lub.size() > 0 && lub[0] != SetExprCode::UNIVERSE) {
00675 iccos << indent << "{" << endl;
00676 ++indent;
00677 int arg = iterator(lub,true);
00678
00679 iccos << indent;
00680 if (nary())
00681 iccos << "GlbRanges<View> j(_x[" << spec._ps[i].getIdx() << "]);";
00682 else if (views==SINGLE_VIEW)
00683 iccos << "GlbRanges<View> j(_x" << spec._ps[i].getIdx() << ");";
00684 else
00685 iccos << "GlbRanges<View" << spec._ps[i].getIdx() << "> j(x"
00686 << spec._ps[i].getIdx() << ");";
00687 iccos << endl;
00688 iccos << indent
00689 << "if (!Iter::Ranges::subset(j,i" << arg
00690 << ")) return ES_FAILED;"
00691 << endl;
00692 iccos << indent << "while (i" << arg << "()) ++i" << arg << ";"
00693 << endl;
00694 if (nary())
00695 iccos << indent << "if (i" << arg << ".size() < _x[" << i << "].cardMin())";
00696 else
00697 iccos << indent << "if (i" << arg << ".size() < _x" << i << ".cardMin())";
00698 iccos << endl;
00699
00700 iccos << indent << " return ES_FAILED;" << endl;
00701 --indent;
00702 iccos << indent << "}" << endl;
00703 }
00704 if (glb.size() > 0 && glb[0] != SetExprCode::EMPTY) {
00705 iccos << indent << "{" << endl;
00706 ++indent;
00707 int arg = iterator(glb,false,false);
00708
00709 iccos << indent;
00710 if (nary())
00711 iccos << "GlbRanges<View> j(_x[" << spec._ps[i].getIdx() << "]);";
00712 else if (views==SINGLE_VIEW)
00713 iccos << "GlbRanges<View> j(_x" << spec._ps[i].getIdx() << ");";
00714 else
00715 iccos << "GlbRanges<View" << spec._ps[i].getIdx() << "> j(_x"
00716 << spec._ps[i].getIdx() << ");";
00717 iccos << endl;
00718 iccos << indent
00719 << "if (!Iter::Ranges::subset(i" << arg
00720 << ",j)) es = ES_FIX;"
00721 << endl;
00722 --indent;
00723 iccos << indent << "}" << endl;
00724 }
00725 if (lub.size() > 0 && lub[0] != SetExprCode::UNIVERSE) {
00726 iccos << indent << "{" << endl;
00727 ++indent;
00728 int arg = iterator(lub,false,true);
00729
00730 iccos << indent;
00731 if (nary())
00732 iccos << "LubRanges<View> j(_x[" << spec._ps[i].getIdx() << "]);";
00733 else if (views==SINGLE_VIEW)
00734 iccos << "LubRanges<View> j(_x" << spec._ps[i].getIdx() << ");";
00735 else
00736 iccos << "LubRanges<View" << spec._ps[i].getIdx() << "> j(_x"
00737 << spec._ps[i].getIdx() << ");";
00738 iccos << endl;
00739 iccos << indent
00740 << "if (!Iter::Ranges::subset(j,i" << arg
00741 << ")) es = ES_FIX;"
00742 << endl;
00743 --indent;
00744 iccos << indent << "}" << endl;
00745 }
00746 }
00747 iccos << indent << "return es;" << endl;
00748 --indent;
00749 iccos << indent << "}" << endl << endl;
00750
00751 templatehead(iccos);
00752 iccos << indent << "ExecStatus" << endl << indent << spec._name;
00753 templateparams();
00754 iccos << "::propagateNegative(Space* home) {" << endl;
00755 ++indent;
00756 iccos << indent << "switch (ExecStatus es=check(home)) {" << endl;
00757 iccos << indent << "case ES_FAILED: return ES_SUBSUMED(this,home);" << endl;
00758 iccos << indent << "case ES_SUBSUMED(this,home): return ES_FAILED;" << endl;
00759 iccos << indent << "default: return es;" << endl;
00760 iccos << indent << "}" << endl;
00761 --indent;
00762 iccos << indent << "}" << endl << endl;
00763 }
00764
00765 templatehead(iccos);
00766 iccos << indent << "ExecStatus" << endl << indent << spec._name;
00767 templateparams();
00768 iccos << "::propagate(Space* home, ModEventDelta) {" << endl;
00769 ++indent;
00770
00771 if (spec._negated && ! spec._reified) {
00772 iccos << indent << "return propagateNegative(home);" << endl;
00773 --indent;
00774 iccos << indent << "}" << endl;
00775 return;
00776 }
00777
00778 if (spec._reified) {
00779 if (spec._negated) {
00780 iccos << indent << "if (_b.zero()) return propagatePositive(home);"
00781 << endl;
00782 iccos << indent << "if (_b.one()) return propagateNegative(home);"
00783 << endl;
00784 iccos << indent << "switch (check(home)) {" << endl;
00785 iccos << indent << "case ES_SUBSUMED(this,home):" << endl;
00786 iccos << indent << " GECODE_ME_CHECK(_b.zero_none(home));" << endl;
00787 iccos << indent << " return ES_SUBSUMED(this,home);" << endl;
00788 iccos << indent << "case ES_FAILED:" << endl;
00789 iccos << indent << " GECODE_ME_CHECK(_b.one_none(home));" << endl;
00790 iccos << indent << " return ES_SUBSUMED(this,home);" << endl;
00791 iccos << indent << "default:" << endl;
00792 iccos << indent << " return ES_FIX;" << endl;
00793 iccos << indent << "}" << endl;
00794 --indent;
00795 iccos << indent << "}" << endl;
00796 } else {
00797 iccos << indent << "if (_b.one()) return propagatePositive(home);"
00798 << endl;
00799 iccos << indent << "if (_b.zero()) return propagateNegative(home);"
00800 << endl;
00801 iccos << indent << "switch (check(home)) {" << endl;
00802 iccos << indent << "case ES_SUBSUMED(this,home):" << endl;
00803 iccos << indent << " GECODE_ME_CHECK(_b.one_none(home));" << endl;
00804 iccos << indent << " return ES_SUBSUMED(this,home);" << endl;
00805 iccos << indent << "case ES_FAILED:" << endl;
00806 iccos << indent << " GECODE_ME_CHECK(_b.zero_none(home));" << endl;
00807 iccos << indent << " return ES_SUBSUMED(this,home);" << endl;
00808 iccos << indent << "default:" << endl;
00809 iccos << indent << " return ES_FIX;" << endl;
00810 iccos << indent << "}" << endl;
00811 --indent;
00812 iccos << indent << "}" << endl;
00813 }
00814 return;
00815 }
00816
00817 iccos << indent << "return propagatePositive(home);" << endl;
00818 --indent;
00819 iccos << indent << "}" << endl;
00820 return;
00821
00822 }
00823
00824 ProjectorCompiler::ProjectorCompiler(std::ostream& _hhos,
00825 std::ostream& _iccos,
00826 const ProjectorPropagatorSpec& _spec)
00827 : hhos(_hhos), iccos(_iccos), spec(_spec),
00828 compiletest(false),
00829 fixpoint(NO_FIX),
00830 views(SINGLE_VIEW)
00831 {}
00832
00833 void
00834 ProjectorCompiler::compile(void) {
00835 using namespace std;
00836 if (spec._arity < spec._ps.arity()) {
00838 std::cerr << "Arity mismatch\n";
00839 exit(2);
00840 }
00841
00842 header(hhos);
00843 classdef();
00844 footer(iccos);
00845
00846 hhos << endl;
00847
00848 header(iccos);
00849 standardMemberFunctions();
00850 iccos << endl;
00851 propagation();
00852 footer(iccos);
00853
00854
00855 }
00856
00857 }
00858
00859