Generated on Wed Nov 1 15:04:44 2006 for Gecode by doxygen 1.4.5

compiler.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Guido Tack, 2006
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-04-11 15:58:37 +0200 (Tue, 11 Apr 2006) $ by $Author: tack $
00010  *     $Revision: 3188 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
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     // Constructor
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     // Copy constructor
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     // Dispose function
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     // Copy function
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     // Post member function
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     // Cost member function
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 // STATISTICS: set-prop