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