Generated on Mon Aug 25 11:35:43 2008 for Gecode by doxygen 1.5.6

compiler.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-01-13 15:02:42 +0100 (Sun, 13 Jan 2008) $ by $Author: schulte $
00011  *     $Revision: 5862 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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     // Constructor
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     // Copy constructor
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     // Dispose function
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     // Copy function
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     // Post member function
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     // Cost member function
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 // STATISTICS: set-prop