Generated on Tue Jul 27 2010 21:59:09 for Gecode by doxygen 1.7.1

registry.cpp

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  *  Contributing authors:
00007  *     Mikael Lagerkvist <lagerkvist@gmail.com>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2007
00011  *     Mikael Lagerkvist, 2009
00012  *
00013  *  Last modified:
00014  *     $Date: 2010-07-21 11:42:47 +0200 (Wed, 21 Jul 2010) $ by $Author: tack $
00015  *     $Revision: 11243 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  Permission is hereby granted, free of charge, to any person obtaining
00022  *  a copy of this software and associated documentation files (the
00023  *  "Software"), to deal in the Software without restriction, including
00024  *  without limitation the rights to use, copy, modify, merge, publish,
00025  *  distribute, sublicense, and/or sell copies of the Software, and to
00026  *  permit persons to whom the Software is furnished to do so, subject to
00027  *  the following conditions:
00028  *
00029  *  The above copyright notice and this permission notice shall be
00030  *  included in all copies or substantial portions of the Software.
00031  *
00032  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00033  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00034  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00035  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00036  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00037  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00038  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00039  *
00040  */
00041 
00042 #include <gecode/flatzinc/registry.hh>
00043 #include <gecode/kernel.hh>
00044 #include <gecode/int.hh>
00045 #include <gecode/scheduling.hh>
00046 #include <gecode/graph.hh>
00047 #include <gecode/minimodel.hh>
00048 #ifdef GECODE_HAS_SET_VARS
00049 #include <gecode/set.hh>
00050 #endif
00051 #include <gecode/flatzinc.hh>
00052 
00053 namespace Gecode { namespace FlatZinc {
00054 
00055   Registry& registry(void) {
00056     static Registry r;
00057     return r;
00058   }
00059 
00060   void
00061   Registry::post(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00062     std::map<std::string,poster>::iterator i = r.find(ce.id);
00063     if (i == r.end()) {
00064       throw FlatZinc::Error("Registry",
00065         std::string("Constraint ")+ce.id+" not found");
00066     }
00067     i->second(s, ce, ann);
00068   }
00069 
00070   void
00071   Registry::add(const std::string& id, poster p) {
00072     r[id] = p;
00073   }
00074 
00075   namespace {
00076   
00077     IntConLevel ann2icl(AST::Node* ann) {
00078       if (ann) {
00079         if (ann->hasAtom("val"))
00080           return ICL_VAL;
00081         if (ann->hasAtom("domain"))
00082           return ICL_DOM;
00083         if (ann->hasAtom("bounds") ||
00084             ann->hasAtom("boundsR") ||
00085             ann->hasAtom("boundsD") ||
00086             ann->hasAtom("boundsZ"))
00087           return ICL_BND;
00088       }
00089       return ICL_DEF;
00090     }
00091   
00092     inline IntRelType
00093     swap(IntRelType irt) {
00094       switch (irt) {
00095       case IRT_LQ: return IRT_GQ;
00096       case IRT_LE: return IRT_GR;
00097       case IRT_GQ: return IRT_LQ;
00098       case IRT_GR: return IRT_LE;
00099       default:     return irt;
00100       }
00101     }
00102 
00103     inline IntRelType
00104     neg(IntRelType irt) {
00105       switch (irt) {
00106       case IRT_EQ: return IRT_NQ;
00107       case IRT_NQ: return IRT_EQ;
00108       case IRT_LQ: return IRT_GR;
00109       case IRT_LE: return IRT_GQ;
00110       case IRT_GQ: return IRT_LE;
00111       case IRT_GR:
00112       default:
00113         assert(irt == IRT_GR);
00114       }
00115       return IRT_LQ;
00116     }
00117 
00118     inline IntArgs arg2intargs(AST::Node* arg, int offset = 0) {
00119       AST::Array* a = arg->getArray();
00120       IntArgs ia(a->a.size()+offset);
00121       for (int i=offset; i--;)
00122         ia[i] = 0;
00123       for (int i=a->a.size(); i--;)
00124         ia[i+offset] = a->a[i]->getInt();
00125       return ia;
00126     }
00127 
00128     inline IntArgs arg2boolargs(AST::Node* arg, int offset = 0) {
00129       AST::Array* a = arg->getArray();
00130       IntArgs ia(a->a.size()+offset);
00131       for (int i=offset; i--;)
00132         ia[i] = 0;
00133       for (int i=a->a.size(); i--;)
00134         ia[i+offset] = a->a[i]->getBool();
00135       return ia;
00136     }
00137 
00138     inline IntSet arg2intset(FlatZincSpace& s, AST::Node* n) {
00139       AST::SetLit* sl = n->getSet();
00140       IntSet d;
00141       if (sl->interval) {
00142         d = IntSet(sl->min, sl->max);
00143       } else {
00144         Region re(s);
00145         int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
00146         for (int i=sl->s.size(); i--; )
00147           is[i] = sl->s[i];
00148         d = IntSet(is, sl->s.size());
00149       }
00150       return d;
00151     }
00152 
00153     inline IntSetArgs arg2intsetargs(FlatZincSpace& s,
00154                                      AST::Node* arg, int offset = 0) {
00155       AST::Array* a = arg->getArray();
00156       if (a->a.size() == 0) {
00157         IntSetArgs emptyIa(0);
00158         return emptyIa;
00159       }
00160       IntSetArgs ia(a->a.size()+offset);      
00161       for (int i=offset; i--;)
00162         ia[i] = IntSet::empty;
00163       for (int i=a->a.size(); i--;) {
00164         ia[i+offset] = arg2intset(s, a->a[i]);
00165       }
00166       return ia;
00167     }
00168   
00169     inline IntVarArgs arg2intvarargs(FlatZincSpace& s, AST::Node* arg,
00170                                      int offset = 0) {
00171       AST::Array* a = arg->getArray();
00172       if (a->a.size() == 0) {
00173         IntVarArgs emptyIa(0);
00174         return emptyIa;
00175       }
00176       IntVarArgs ia(a->a.size()+offset);
00177       for (int i=offset; i--;)
00178         ia[i] = IntVar(s, 0, 0);
00179       for (int i=a->a.size(); i--;) {
00180         if (a->a[i]->isIntVar()) {
00181           ia[i+offset] = s.iv[a->a[i]->getIntVar()];        
00182         } else {
00183           int value = a->a[i]->getInt();
00184           IntVar iv(s, value, value);
00185           ia[i+offset] = iv;        
00186         }
00187       }
00188       return ia;
00189     }
00190 
00191     inline BoolVarArgs arg2boolvarargs(FlatZincSpace& s, AST::Node* arg,
00192                                        int offset = 0, int siv=-1) {
00193       AST::Array* a = arg->getArray();
00194       if (a->a.size() == 0) {
00195         BoolVarArgs emptyIa(0);
00196         return emptyIa;
00197       }
00198       BoolVarArgs ia(a->a.size()+offset-(siv==-1?0:1));
00199       for (int i=offset; i--;)
00200         ia[i] = BoolVar(s, 0, 0);
00201       for (int i=0; i<static_cast<int>(a->a.size()); i++) {
00202         if (i==siv)
00203           continue;
00204         if (a->a[i]->isBool()) {
00205           bool value = a->a[i]->getBool();
00206           BoolVar iv(s, value, value);
00207           ia[offset++] = iv;
00208         } else if (a->a[i]->isIntVar() &&
00209                    s.aliasBool2Int(a->a[i]->getIntVar()) != -1) {
00210           ia[offset++] = s.bv[s.aliasBool2Int(a->a[i]->getIntVar())];
00211         } else {
00212           ia[offset++] = s.bv[a->a[i]->getBoolVar()];
00213         }
00214       }
00215       return ia;
00216     }
00217 
00218 #ifdef GECODE_HAS_SET_VARS
00219     SetVar getSetVar(FlatZincSpace& s, AST::Node* n) {
00220       SetVar x0;
00221       if (!n->isSetVar()) {
00222         IntSet d = arg2intset(s,n);
00223         x0 = SetVar(s, d, d);        
00224       } else {
00225         x0 = s.sv[n->getSetVar()];
00226       }
00227       return x0;
00228     }
00229 
00230     inline SetVarArgs arg2setvarargs(FlatZincSpace& s, AST::Node* arg,
00231                                      int offset = 0) {
00232       AST::Array* a = arg->getArray();
00233       if (a->a.size() == 0) {
00234         SetVarArgs emptyIa(0);
00235         return emptyIa;
00236       }
00237       SetVarArgs ia(a->a.size()+offset);
00238       for (int i=offset; i--;)
00239         ia[i] = SetVar(s, IntSet::empty, IntSet::empty);
00240       for (int i=a->a.size(); i--;) {
00241         ia[i+offset] = getSetVar(s, a->a[i]);
00242       }
00243       return ia;
00244     }
00245 #endif
00246 
00247     BoolVar getBoolVar(FlatZincSpace& s, AST::Node* n) {
00248       BoolVar x0;
00249       if (n->isBool()) {
00250         x0 = BoolVar(s, n->getBool(), n->getBool());
00251       }
00252       else {
00253         x0 = s.bv[n->getBoolVar()];
00254       }
00255       return x0;
00256     }
00257 
00258     IntVar getIntVar(FlatZincSpace& s, AST::Node* n) {
00259       IntVar x0;
00260       if (n->isIntVar()) {
00261         x0 = s.iv[n->getIntVar()];
00262       } else {
00263         x0 = IntVar(s, n->getInt(), n->getInt());            
00264       }
00265       return x0;
00266     }
00267 
00268     bool isBoolArray(FlatZincSpace& s, AST::Node* b, int& singleInt) {
00269       AST::Array* a = b->getArray();
00270       singleInt = -1;
00271       if (a->a.size() == 0)
00272         return true;
00273       for (int i=a->a.size(); i--;) {
00274         if (a->a[i]->isBoolVar() || a->a[i]->isBool()) {
00275         } else if (a->a[i]->isIntVar()) {
00276           if (s.aliasBool2Int(a->a[i]->getIntVar()) == -1) {
00277             if (singleInt != -1) {
00278               return false;
00279             }
00280             singleInt = i;
00281           }
00282         } else {
00283           return false;
00284         }
00285       }
00286       return true;
00287     }
00288 
00289     void p_distinct(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00290       IntVarArgs va = arg2intvarargs(s, ce[0]);
00291       distinct(s, va, ann2icl(ann));    
00292     }
00293     void p_distinctOffset(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00294       IntVarArgs va = arg2intvarargs(s, ce[1]);
00295       AST::Array* offs = ce.args->a[0]->getArray();
00296       IntArgs oa(offs->a.size());
00297       for (int i=offs->a.size(); i--; ) {
00298         oa[i] = offs->a[i]->getInt();    
00299       }
00300       distinct(s, oa, va, ann2icl(ann));
00301     }
00302 
00303     void p_all_equal(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00304       IntVarArgs va = arg2intvarargs(s, ce[0]);
00305       rel(s, va, IRT_EQ, ann2icl(ann));
00306     }
00307 
00308     void p_int_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce, 
00309                    AST::Node* ann) {
00310       if (ce[0]->isIntVar()) {
00311         if (ce[1]->isIntVar()) {
00312           rel(s, getIntVar(s, ce[0]), irt, getIntVar(s, ce[1]), 
00313               ann2icl(ann));
00314         } else {
00315           rel(s, getIntVar(s, ce[0]), irt, ce[1]->getInt(), ann2icl(ann));
00316         }
00317       } else {
00318         rel(s, getIntVar(s, ce[1]), swap(irt), ce[0]->getInt(), 
00319             ann2icl(ann));
00320       }
00321     }
00322     void p_int_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00323       p_int_CMP(s, IRT_EQ, ce, ann);
00324     }
00325     void p_int_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00326       p_int_CMP(s, IRT_NQ, ce, ann);
00327     }
00328     void p_int_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00329       p_int_CMP(s, IRT_GQ, ce, ann);
00330     }
00331     void p_int_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00332       p_int_CMP(s, IRT_GR, ce, ann);
00333     }
00334     void p_int_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00335       p_int_CMP(s, IRT_LQ, ce, ann);
00336     }
00337     void p_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00338       p_int_CMP(s, IRT_LE, ce, ann);
00339     }
00340     void p_int_CMP_reif(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00341                         AST::Node* ann) {
00342       if (ce[2]->isBool()) {
00343         if (ce[2]->getBool()) {
00344           p_int_CMP(s, irt, ce, ann);
00345         } else {
00346           p_int_CMP(s, neg(irt), ce, ann);
00347         }
00348         return;
00349       }
00350       if (ce[0]->isIntVar()) {
00351         if (ce[1]->isIntVar()) {
00352           rel(s, getIntVar(s, ce[0]), irt, getIntVar(s, ce[1]),
00353                  getBoolVar(s, ce[2]), ann2icl(ann));
00354         } else {
00355           rel(s, getIntVar(s, ce[0]), irt, ce[1]->getInt(),
00356                  getBoolVar(s, ce[2]), ann2icl(ann));
00357         }
00358       } else {
00359         rel(s, getIntVar(s, ce[1]), swap(irt), ce[0]->getInt(),
00360                getBoolVar(s, ce[2]), ann2icl(ann));
00361       }
00362     }
00363 
00364     /* Comparisons */
00365     void p_int_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00366       p_int_CMP_reif(s, IRT_EQ, ce, ann);
00367     }
00368     void p_int_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00369       p_int_CMP_reif(s, IRT_NQ, ce, ann);
00370     }
00371     void p_int_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00372       p_int_CMP_reif(s, IRT_GQ, ce, ann);
00373     }
00374     void p_int_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00375       p_int_CMP_reif(s, IRT_GR, ce, ann);
00376     }
00377     void p_int_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00378       p_int_CMP_reif(s, IRT_LQ, ce, ann);
00379     }
00380     void p_int_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00381       p_int_CMP_reif(s, IRT_LE, ce, ann);
00382     }
00383 
00384     /* linear (in-)equations */
00385     void p_int_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00386                        AST::Node* ann) {
00387       IntArgs ia = arg2intargs(ce[0]);
00388       int singleIntVar;
00389       if (isBoolArray(s,ce[1],singleIntVar)) {
00390         if (singleIntVar != -1) {
00391           if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
00392             IntVar siv = getIntVar(s, ce[1]->getArray()->a[singleIntVar]);
00393             BoolVarArgs iv = arg2boolvarargs(s, ce[1], 0, singleIntVar);
00394             IntArgs ia_tmp(ia.size()-1);
00395             int count = 0;
00396             for (int i=0; i<ia.size(); i++) {
00397               if (i != singleIntVar)
00398                 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
00399             }
00400             linear(s, ia_tmp, iv, irt, siv, ann2icl(ann));
00401           } else {
00402             IntVarArgs iv = arg2intvarargs(s, ce[1]);
00403             linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00404           }
00405         } else {
00406           BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00407           linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00408         }
00409       } else {
00410         IntVarArgs iv = arg2intvarargs(s, ce[1]);
00411         linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00412       }
00413     }
00414     void p_int_lin_CMP_reif(FlatZincSpace& s, IntRelType irt,
00415                             const ConExpr& ce, AST::Node* ann) {
00416       if (ce[2]->isBool()) {
00417         if (ce[2]->getBool()) {
00418           p_int_lin_CMP(s, irt, ce, ann);
00419         } else {
00420           p_int_lin_CMP(s, neg(irt), ce, ann);
00421         }
00422         return;
00423       }
00424       IntArgs ia = arg2intargs(ce[0]);
00425       int singleIntVar;
00426       if (isBoolArray(s,ce[1],singleIntVar)) {
00427         if (singleIntVar != -1) {
00428           if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
00429             IntVar siv = getIntVar(s, ce[1]->getArray()->a[singleIntVar]);
00430             BoolVarArgs iv = arg2boolvarargs(s, ce[1], 0, singleIntVar);
00431             IntArgs ia_tmp(ia.size()-1);
00432             int count = 0;
00433             for (int i=0; i<ia.size(); i++) {
00434               if (i != singleIntVar)
00435                 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
00436             }
00437             linear(s, ia_tmp, iv, irt, siv, getBoolVar(s, ce[3]), 
00438                    ann2icl(ann));
00439           } else {
00440             IntVarArgs iv = arg2intvarargs(s, ce[1]);
00441             linear(s, ia, iv, irt, ce[2]->getInt(),
00442                    getBoolVar(s, ce[3]), ann2icl(ann));
00443           }
00444         } else {
00445           BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00446           linear(s, ia, iv, irt, ce[2]->getInt(),
00447                  getBoolVar(s, ce[3]), ann2icl(ann));
00448         }
00449       } else {
00450         IntVarArgs iv = arg2intvarargs(s, ce[1]);
00451         linear(s, ia, iv, irt, ce[2]->getInt(), getBoolVar(s, ce[3]), 
00452                ann2icl(ann));
00453       }
00454     }
00455     void p_int_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00456       p_int_lin_CMP(s, IRT_EQ, ce, ann);
00457     }
00458     void p_int_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00459       p_int_lin_CMP_reif(s, IRT_EQ, ce, ann);    
00460     }
00461     void p_int_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00462       p_int_lin_CMP(s, IRT_NQ, ce, ann);
00463     }
00464     void p_int_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00465       p_int_lin_CMP_reif(s, IRT_NQ, ce, ann);    
00466     }
00467     void p_int_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00468       p_int_lin_CMP(s, IRT_LQ, ce, ann);
00469     }
00470     void p_int_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00471       p_int_lin_CMP_reif(s, IRT_LQ, ce, ann);    
00472     }
00473     void p_int_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00474       p_int_lin_CMP(s, IRT_LE, ce, ann);
00475     }
00476     void p_int_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00477       p_int_lin_CMP_reif(s, IRT_LE, ce, ann);    
00478     }
00479     void p_int_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00480       p_int_lin_CMP(s, IRT_GQ, ce, ann);
00481     }
00482     void p_int_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00483       p_int_lin_CMP_reif(s, IRT_GQ, ce, ann);    
00484     }
00485     void p_int_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00486       p_int_lin_CMP(s, IRT_GR, ce, ann);
00487     }
00488     void p_int_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00489       p_int_lin_CMP_reif(s, IRT_GR, ce, ann);    
00490     }
00491 
00492     void p_bool_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00493                         AST::Node* ann) {
00494       IntArgs ia = arg2intargs(ce[0]);
00495       BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00496       if (ce[2]->isIntVar())
00497         linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], ann2icl(ann));
00498       else
00499         linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00500     }
00501     void p_bool_lin_CMP_reif(FlatZincSpace& s, IntRelType irt,
00502                             const ConExpr& ce, AST::Node* ann) {
00503       if (ce[2]->isBool()) {
00504         if (ce[2]->getBool()) {
00505           p_bool_lin_CMP(s, irt, ce, ann);
00506         } else {
00507           p_bool_lin_CMP(s, neg(irt), ce, ann);
00508         }
00509         return;
00510       }
00511       IntArgs ia = arg2intargs(ce[0]);
00512       BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00513       if (ce[2]->isIntVar())
00514         linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], getBoolVar(s, ce[3]), 
00515                ann2icl(ann));
00516       else
00517         linear(s, ia, iv, irt, ce[2]->getInt(), getBoolVar(s, ce[3]), 
00518                ann2icl(ann));
00519     }
00520     void p_bool_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00521       p_bool_lin_CMP(s, IRT_EQ, ce, ann);
00522     }
00523     void p_bool_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00524     {
00525       p_bool_lin_CMP_reif(s, IRT_EQ, ce, ann);
00526     }
00527     void p_bool_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00528       p_bool_lin_CMP(s, IRT_NQ, ce, ann);
00529     }
00530     void p_bool_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00531     {
00532       p_bool_lin_CMP_reif(s, IRT_NQ, ce, ann);
00533     }
00534     void p_bool_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00535       p_bool_lin_CMP(s, IRT_LQ, ce, ann);
00536     }
00537     void p_bool_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00538     {
00539       p_bool_lin_CMP_reif(s, IRT_LQ, ce, ann);
00540     }
00541     void p_bool_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00542     {
00543       p_bool_lin_CMP(s, IRT_LE, ce, ann);
00544     }
00545     void p_bool_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00546     {
00547       p_bool_lin_CMP_reif(s, IRT_LE, ce, ann);
00548     }
00549     void p_bool_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00550       p_bool_lin_CMP(s, IRT_GQ, ce, ann);
00551     }
00552     void p_bool_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00553     {
00554       p_bool_lin_CMP_reif(s, IRT_GQ, ce, ann);
00555     }
00556     void p_bool_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00557       p_bool_lin_CMP(s, IRT_GR, ce, ann);
00558     }
00559     void p_bool_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) 
00560     {
00561       p_bool_lin_CMP_reif(s, IRT_GR, ce, ann);
00562     }
00563 
00564     /* arithmetic constraints */
00565   
00566     void p_int_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00567       if (!ce[0]->isIntVar()) {
00568         rel(s, ce[0]->getInt() + getIntVar(s, ce[1])
00569                 == getIntVar(s,ce[2]), ann2icl(ann));
00570       } else if (!ce[1]->isIntVar()) {
00571         rel(s, getIntVar(s,ce[0]) + ce[1]->getInt()
00572                 == getIntVar(s,ce[2]), ann2icl(ann));
00573       } else if (!ce[2]->isIntVar()) {
00574         rel(s, getIntVar(s,ce[0]) + getIntVar(s,ce[1]) 
00575                 == ce[2]->getInt(), ann2icl(ann));
00576       } else {
00577         rel(s, getIntVar(s,ce[0]) + getIntVar(s,ce[1]) 
00578                 == getIntVar(s,ce[2]), ann2icl(ann));
00579       }
00580     }
00581 
00582     void p_int_minus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00583       if (!ce[0]->isIntVar()) {
00584         rel(s, ce[0]->getInt() - getIntVar(s, ce[1])
00585                 == getIntVar(s,ce[2]), ann2icl(ann));
00586       } else if (!ce[1]->isIntVar()) {
00587         rel(s, getIntVar(s,ce[0]) - ce[1]->getInt()
00588                 == getIntVar(s,ce[2]), ann2icl(ann));
00589       } else if (!ce[2]->isIntVar()) {
00590         rel(s, getIntVar(s,ce[0]) - getIntVar(s,ce[1]) 
00591                 == ce[2]->getInt(), ann2icl(ann));
00592       } else {
00593         rel(s, getIntVar(s,ce[0]) - getIntVar(s,ce[1]) 
00594                 == getIntVar(s,ce[2]), ann2icl(ann));
00595       }
00596     }
00597 
00598     void p_int_times(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00599       IntVar x0 = getIntVar(s, ce[0]);
00600       IntVar x1 = getIntVar(s, ce[1]);
00601       IntVar x2 = getIntVar(s, ce[2]);
00602       mult(s, x0, x1, x2, ann2icl(ann));    
00603     }
00604     void p_int_div(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00605       IntVar x0 = getIntVar(s, ce[0]);
00606       IntVar x1 = getIntVar(s, ce[1]);
00607       IntVar x2 = getIntVar(s, ce[2]);
00608       div(s,x0,x1,x2, ann2icl(ann));
00609     }
00610     void p_int_mod(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00611       IntVar x0 = getIntVar(s, ce[0]);
00612       IntVar x1 = getIntVar(s, ce[1]);
00613       IntVar x2 = getIntVar(s, ce[2]);
00614       mod(s,x0,x1,x2, ann2icl(ann));
00615     }
00616 
00617     void p_int_min(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00618       IntVar x0 = getIntVar(s, ce[0]);
00619       IntVar x1 = getIntVar(s, ce[1]);
00620       IntVar x2 = getIntVar(s, ce[2]);
00621       min(s, x0, x1, x2, ann2icl(ann));
00622     }
00623     void p_int_max(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00624       IntVar x0 = getIntVar(s, ce[0]);
00625       IntVar x1 = getIntVar(s, ce[1]);
00626       IntVar x2 = getIntVar(s, ce[2]);
00627       max(s, x0, x1, x2, ann2icl(ann));
00628     }
00629     void p_int_negate(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00630       IntVar x0 = getIntVar(s, ce[0]);
00631       IntVar x1 = getIntVar(s, ce[1]);
00632       rel(s, x0 == -x1, ann2icl(ann));
00633     }
00634 
00635     /* Boolean constraints */
00636     void p_bool_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce, 
00637                    AST::Node* ann) {
00638       rel(s, getBoolVar(s, ce[0]), irt, getBoolVar(s, ce[1]), 
00639           ann2icl(ann));
00640     }
00641     void p_bool_CMP_reif(FlatZincSpace& s, IntRelType irt, const ConExpr& ce, 
00642                    AST::Node* ann) {
00643       rel(s, getBoolVar(s, ce[0]), irt, getBoolVar(s, ce[1]),
00644           getBoolVar(s, ce[2]), ann2icl(ann));
00645     }
00646     void p_bool_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00647       p_bool_CMP(s, IRT_EQ, ce, ann);
00648     }
00649     void p_bool_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00650       p_bool_CMP_reif(s, IRT_EQ, ce, ann);
00651     }
00652     void p_bool_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00653       p_bool_CMP(s, IRT_NQ, ce, ann);
00654     }
00655     void p_bool_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00656       p_bool_CMP_reif(s, IRT_NQ, ce, ann);
00657     }
00658     void p_bool_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00659       p_bool_CMP(s, IRT_GQ, ce, ann);
00660     }
00661     void p_bool_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00662       p_bool_CMP_reif(s, IRT_GQ, ce, ann);
00663     }
00664     void p_bool_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00665       p_bool_CMP(s, IRT_LQ, ce, ann);
00666     }
00667     void p_bool_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00668       p_bool_CMP_reif(s, IRT_LQ, ce, ann);
00669     }
00670     void p_bool_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00671       p_bool_CMP(s, IRT_GR, ce, ann);
00672     }
00673     void p_bool_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00674       p_bool_CMP_reif(s, IRT_GR, ce, ann);
00675     }
00676     void p_bool_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00677       p_bool_CMP(s, IRT_LE, ce, ann);
00678     }
00679     void p_bool_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00680       p_bool_CMP_reif(s, IRT_LE, ce, ann);
00681     }
00682 
00683 #define BOOL_OP(op) \
00684     BoolVar b0 = getBoolVar(s, ce[0]); \
00685     BoolVar b1 = getBoolVar(s, ce[1]); \
00686     if (ce[2]->isBool()) { \
00687       rel(s, b0, op, b1, ce[2]->getBool(), ann2icl(ann)); \
00688     } else { \
00689       rel(s, b0, op, b1, s.bv[ce[2]->getBoolVar()], ann2icl(ann)); \
00690     }
00691 
00692 #define BOOL_ARRAY_OP(op) \
00693     BoolVarArgs bv = arg2boolvarargs(s, ce[0]); \
00694     if (ce[1]->isBool()) { \
00695       rel(s, op, bv, ce[1]->getBool(), ann2icl(ann)); \
00696     } else { \
00697       rel(s, op, bv, s.bv[ce[1]->getBoolVar()], ann2icl(ann)); \
00698     }
00699 
00700     void p_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00701       BOOL_OP(BOT_OR);
00702     }
00703     void p_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00704       BOOL_OP(BOT_AND);
00705     }
00706     void p_array_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00707     {
00708       BOOL_ARRAY_OP(BOT_AND);
00709     }
00710     void p_array_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00711     {
00712       BOOL_ARRAY_OP(BOT_OR);
00713     }
00714     void p_array_bool_clause(FlatZincSpace& s, const ConExpr& ce,
00715                              AST::Node* ann) {
00716       BoolVarArgs bvp = arg2boolvarargs(s, ce[0]);
00717       BoolVarArgs bvn = arg2boolvarargs(s, ce[1]);
00718       clause(s, BOT_OR, bvp, bvn, 1, ann2icl(ann));
00719     }
00720     void p_array_bool_clause_reif(FlatZincSpace& s, const ConExpr& ce,
00721                              AST::Node* ann) {
00722       BoolVarArgs bvp = arg2boolvarargs(s, ce[0]);
00723       BoolVarArgs bvn = arg2boolvarargs(s, ce[1]);
00724       BoolVar b0 = getBoolVar(s, ce[2]);
00725       clause(s, BOT_OR, bvp, bvn, b0, ann2icl(ann));
00726     }
00727     void p_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00728       BOOL_OP(BOT_XOR);
00729     }
00730     void p_bool_l_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00731       BoolVar b0 = getBoolVar(s, ce[0]);
00732       BoolVar b1 = getBoolVar(s, ce[1]);
00733       if (ce[2]->isBool()) {
00734         rel(s, b1, BOT_IMP, b0, ce[2]->getBool(), ann2icl(ann));
00735       } else {
00736         rel(s, b1, BOT_IMP, b0, s.bv[ce[2]->getBoolVar()], ann2icl(ann));
00737       }
00738     }
00739     void p_bool_r_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00740       BOOL_OP(BOT_IMP);
00741     }
00742     void p_bool_not(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00743       BoolVar x0 = getBoolVar(s, ce[0]);
00744       BoolVar x1 = getBoolVar(s, ce[1]);
00745       rel(s, x0, BOT_XOR, x1, 1, ann2icl(ann));
00746     }
00747   
00748     /* element constraints */
00749     void p_array_int_element(FlatZincSpace& s, const ConExpr& ce, 
00750                                  AST::Node* ann) {
00751       bool isConstant = true;
00752       AST::Array* a = ce[1]->getArray();
00753       for (int i=a->a.size(); i--;) {
00754         if (!a->a[i]->isInt()) {
00755           isConstant = false;
00756           break;
00757         }
00758       }
00759       IntVar selector = getIntVar(s, ce[0]);
00760       rel(s, selector > 0);
00761       if (isConstant) {
00762         IntArgs ia = arg2intargs(ce[1], 1);
00763         element(s, ia, selector, getIntVar(s, ce[2]), ann2icl(ann));
00764       } else {
00765         IntVarArgs iv = arg2intvarargs(s, ce[1], 1);
00766         element(s, iv, selector, getIntVar(s, ce[2]), ann2icl(ann));
00767       }
00768     }
00769     void p_array_bool_element(FlatZincSpace& s, const ConExpr& ce, 
00770                                   AST::Node* ann) {
00771       bool isConstant = true;
00772       AST::Array* a = ce[1]->getArray();
00773       for (int i=a->a.size(); i--;) {
00774         if (!a->a[i]->isBool()) {
00775           isConstant = false;
00776           break;
00777         }
00778       }
00779       IntVar selector = getIntVar(s, ce[0]);
00780       rel(s, selector > 0);
00781       if (isConstant) {
00782         IntArgs ia = arg2boolargs(ce[1], 1);
00783         element(s, ia, selector, getBoolVar(s, ce[2]), ann2icl(ann));
00784       } else {
00785         BoolVarArgs iv = arg2boolvarargs(s, ce[1], 1);
00786         element(s, iv, selector, getBoolVar(s, ce[2]), ann2icl(ann));
00787       }
00788     }
00789   
00790     /* coercion constraints */
00791     void p_bool2int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00792       BoolVar x0 = getBoolVar(s, ce[0]);
00793       IntVar x1 = getIntVar(s, ce[1]);
00794       if (ce[0]->isBoolVar() && ce[1]->isIntVar()) {
00795         s.aliasBool2Int(ce[1]->getIntVar(), ce[0]->getBoolVar());
00796       }
00797       channel(s, x0, x1, ann2icl(ann));
00798     }
00799 
00800     void p_int_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
00801       IntSet d = arg2intset(s,ce[1]);
00802       if (ce[0]->isBoolVar()) {
00803         IntSetRanges dr(d);
00804         Iter::Ranges::Singleton sr(0,1);
00805         Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
00806         IntSet d01(i);
00807         if (d01.size() == 0) {
00808           s.fail();
00809         } else {
00810           rel(s, getBoolVar(s, ce[0]), IRT_GQ, d01.min());
00811           rel(s, getBoolVar(s, ce[0]), IRT_LQ, d01.max());
00812         }
00813       } else {
00814         dom(s, getIntVar(s, ce[0]), d);
00815       }
00816     }
00817 
00818     /* constraints from the standard library */
00819   
00820     void p_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00821       IntVar x0 = getIntVar(s, ce[0]);
00822       IntVar x1 = getIntVar(s, ce[1]);
00823       abs(s, x0, x1, ann2icl(ann));
00824     }
00825   
00826     void p_array_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00827       IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00828       IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00829       rel(s, iv0, IRT_LE, iv1, ann2icl(ann));
00830     }
00831 
00832     void p_array_int_lq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00833       IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00834       IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00835       rel(s, iv0, IRT_LQ, iv1, ann2icl(ann));
00836     }
00837   
00838     void p_count(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00839       IntVarArgs iv = arg2intvarargs(s, ce[0]);
00840       if (!ce[1]->isIntVar()) {
00841         if (!ce[2]->isIntVar()) {
00842           count(s, iv, ce[1]->getInt(), IRT_EQ, ce[2]->getInt(), 
00843                 ann2icl(ann));
00844         } else {
00845           count(s, iv, ce[1]->getInt(), IRT_EQ, getIntVar(s, ce[2]), 
00846                 ann2icl(ann));
00847         }
00848       } else if (!ce[2]->isIntVar()) {
00849         count(s, iv, getIntVar(s, ce[1]), IRT_EQ, ce[2]->getInt(), 
00850               ann2icl(ann));
00851       } else {
00852         count(s, iv, getIntVar(s, ce[1]), IRT_EQ, getIntVar(s, ce[2]), 
00853               ann2icl(ann));
00854       }
00855     }
00856 
00857     void count_rel(IntRelType irt,
00858                    FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00859       IntVarArgs iv = arg2intvarargs(s, ce[1]);
00860       count(s, iv, ce[2]->getInt(), irt, ce[0]->getInt(), ann2icl(ann));
00861     }
00862 
00863     void p_at_most(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00864       count_rel(IRT_LQ, s, ce, ann);
00865     }
00866 
00867     void p_at_least(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00868       count_rel(IRT_GQ, s, ce, ann);
00869     }
00870 
00871     void p_global_cardinality(FlatZincSpace& s, const ConExpr& ce,
00872                               AST::Node* ann) {
00873       IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00874       IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00875       int cmin = ce[2]->getInt();
00876 
00877       int smallest = cmin;
00878       int largest = iv1.size()-1;
00879       for (int i=iv0.size(); i--;) {
00880         smallest = std::min(smallest, iv0[i].min());
00881         largest = std::max(largest, iv0[i].max());
00882       }
00883       
00884 
00885       if (cmin == 0 && smallest == 0 && largest == iv1.size()-1) {
00886         count(s, iv0, iv1, ann2icl(ann));      
00887       } else {
00888         IntArgs values(largest - smallest + 1);
00889         for (int i=largest-smallest+1; i--;)
00890           values[i] = i+smallest;
00891         IntVarArgs iv1tmp(largest-smallest+1);
00892         int k = 0;
00893         for (int i=cmin-smallest; i--;) {
00894           iv1tmp[k++] = IntVar(s, 0, iv0.size());
00895         }
00896         for (int i=0; i<iv1.size(); i++)
00897           iv1tmp[k++] = iv1[i];
00898         for (int i=k; i<iv1tmp.size(); i++) {
00899           iv1tmp[i] = IntVar(s, 0, iv0.size());
00900         }
00901         count(s, iv0, iv1tmp, values, ann2icl(ann));
00902       }
00903     }
00904 
00905     void p_minimum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00906       IntVarArgs iv = arg2intvarargs(s, ce[1]);
00907       min(s, iv, getIntVar(s, ce[0]), ann2icl(ann));
00908     }
00909 
00910     void p_maximum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00911       IntVarArgs iv = arg2intvarargs(s, ce[1]);
00912       max(s, iv, getIntVar(s, ce[0]), ann2icl(ann));
00913     }
00914 
00915     void p_regular(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00916       IntVarArgs iv = arg2intvarargs(s, ce[0]);
00917       int q = ce[1]->getInt();
00918       int symbols = ce[2]->getInt();
00919       IntArgs d = arg2intargs(ce[3]);
00920       int q0 = ce[4]->getInt();
00921 
00922       int noOfTrans = 0;
00923       for (int i=1; i<=q; i++) {
00924         for (int j=1; j<=symbols; j++) {
00925           if (d[(i-1)*symbols+(j-1)] > 0)
00926             noOfTrans++;
00927         }
00928       }
00929     
00930       Region re(s);
00931       DFA::Transition* t = re.alloc<DFA::Transition>(noOfTrans+1);
00932       noOfTrans = 0;
00933       for (int i=1; i<=q; i++) {
00934         for (int j=1; j<=symbols; j++) {
00935           if (d[(i-1)*symbols+(j-1)] > 0) {
00936             t[noOfTrans].i_state = i;
00937             t[noOfTrans].symbol  = j;
00938             t[noOfTrans].o_state = d[(i-1)*symbols+(j-1)];
00939             noOfTrans++;
00940           }
00941         }
00942       }
00943       t[noOfTrans].i_state = -1;
00944     
00945       // Final states
00946       AST::SetLit* sl = ce[5]->getSet();
00947       int* f;
00948       if (sl->interval) {
00949         f = static_cast<int*>(malloc(sizeof(int)*(sl->max-sl->min+2)));
00950         for (int i=sl->min; i<=sl->max; i++)
00951           f[i-sl->min] = i;
00952         f[sl->max-sl->min+1] = -1;
00953       } else {
00954         f = static_cast<int*>(malloc(sizeof(int)*(sl->s.size()+1)));
00955         for (int j=sl->s.size(); j--; )
00956           f[j] = sl->s[j];
00957         f[sl->s.size()] = -1;
00958       }
00959         
00960       DFA dfa(q0,t,f);
00961       free(f);
00962       extensional(s, iv, dfa, ann2icl(ann));
00963     }
00964 
00965     void
00966     p_sort(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00967       IntVarArgs x = arg2intvarargs(s, ce[0]);
00968       IntVarArgs y = arg2intvarargs(s, ce[1]);
00969       IntVarArgs xy(x.size()+y.size());
00970       for (int i=x.size(); i--;)
00971         xy[i] = x[i];
00972       for (int i=y.size(); i--;)
00973         xy[i+x.size()] = y[i];
00974       unshare(s, xy);
00975       for (int i=x.size(); i--;)
00976         x[i] = xy[i];
00977       for (int i=y.size(); i--;)
00978         y[i] = xy[i+x.size()];
00979       sorted(s, x, y, ann2icl(ann));
00980     }
00981 
00982     void
00983     p_inverse_offsets(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00984       IntVarArgs x = arg2intvarargs(s, ce[0]);
00985       int xoff = ce[1]->getInt();
00986       IntVarArgs y = arg2intvarargs(s, ce[2]);
00987       int yoff = ce[3]->getInt();
00988       channel(s, x, xoff, y, yoff, ann2icl(ann));
00989     }
00990 
00991     void
00992     p_increasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00993       IntVarArgs x = arg2intvarargs(s, ce[0]);
00994       rel(s,x,IRT_LQ,ann2icl(ann));
00995     }
00996 
00997     void
00998     p_increasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00999       BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01000       rel(s,x,IRT_LQ,ann2icl(ann));
01001     }
01002 
01003     void
01004     p_decreasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01005       IntVarArgs x = arg2intvarargs(s, ce[0]);
01006       rel(s,x,IRT_GQ,ann2icl(ann));
01007     }
01008 
01009     void
01010     p_decreasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01011       BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01012       rel(s,x,IRT_GQ,ann2icl(ann));
01013     }
01014 
01015     void
01016     p_table_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01017       IntVarArgs x = arg2intvarargs(s, ce[0]);
01018       IntArgs tuples = arg2intargs(ce[1]);
01019       int noOfVars   = x.size();
01020       int noOfTuples = tuples.size()/noOfVars;
01021       TupleSet ts;
01022       for (int i=0; i<noOfTuples; i++) {
01023         IntArgs t(noOfVars);
01024         for (int j=0; j<x.size(); j++) {
01025           t[j] = tuples[i*noOfVars+j];
01026         }
01027         ts.add(t);
01028       }
01029       ts.finalize();
01030       extensional(s,x,ts,EPK_DEF,ann2icl(ann));
01031     }
01032     void
01033     p_table_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01034       BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01035       IntArgs tuples = arg2boolargs(ce[1]);
01036       int noOfVars   = x.size();
01037       int noOfTuples = tuples.size()/noOfVars;
01038       TupleSet ts;
01039       for (int i=0; i<noOfTuples; i++) {
01040         IntArgs t(noOfVars);
01041         for (int j=0; j<x.size(); j++) {
01042           t[j] = tuples[i*noOfVars+j];
01043         }
01044         ts.add(t);
01045       }
01046       ts.finalize();
01047       extensional(s,x,ts,EPK_DEF,ann2icl(ann));
01048     }
01049 
01050     void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
01051                       AST::Node* ann) {
01052       IntVarArgs start = arg2intvarargs(s, ce[0]);
01053       IntVarArgs duration = arg2intvarargs(s, ce[1]);
01054       IntVarArgs height = arg2intvarargs(s, ce[2]);
01055       int n = start.size();
01056       IntVar bound = getIntVar(s, ce[3]);
01057 
01058       int minHeight = INT_MAX; int minHeight2 = INT_MAX;
01059       for (int i=n; i--;)
01060         if (height[i].min() < minHeight)
01061           minHeight = height[i].min();
01062         else if (height[i].min() < minHeight2)
01063           minHeight2 = height[i].min();
01064       bool disjunctive =
01065        (minHeight > bound.max()/2) ||
01066        (minHeight2 > bound.max()/2 && minHeight+minHeight2>bound.max());
01067       if (disjunctive) {
01068         rel(s, bound >= max(height));
01069         // Unary
01070         if (duration.assigned()) {
01071           IntArgs durationI(n);
01072           bool allone = true;
01073           for (int i=n; i--;) {
01074             durationI[i] = duration[i].val();
01075             if (durationI[i] != 1)
01076               allone = false;
01077           }
01078           if (allone) {
01079             distinct(s,start,ann2icl(ann));
01080           } else {
01081             unary(s,start,durationI);
01082           }
01083         } else {
01084           IntVarArgs end(s,n,Int::Limits::min,Int::Limits::max);
01085           for (int i=n; i--;)
01086             rel(s,start[i]+duration[i]==end[i]);
01087           unary(s,start,duration,end);
01088         }
01089       } else if (bound.assigned()) {
01090         if (height.assigned()) {
01091           IntArgs heightI(n);
01092           for (int i=n; i--;)
01093             heightI[i] = height[i].val();
01094           if (duration.assigned()) {
01095             IntArgs durationI(n);
01096             for (int i=n; i--;)
01097               durationI[i] = duration[i].val();
01098             cumulative(s, bound.val(), start, durationI, heightI);
01099           } else {
01100             IntVarArgs end(n);
01101             for (int i = n; i--; )
01102               end[i] = expr(s, start[i]+duration[i]);
01103             cumulative(s, bound.val(), start, duration, end, heightI);
01104           }
01105         } else {
01106           IntArgs machine = IntArgs::create(n,0,0);
01107           IntArgs limit(1, bound.val());
01108           IntVarArgs end(n);
01109           for (int i = n; i--; ) end[i] = IntVar(s, 0, Int::Limits::max);
01110           cumulatives(s, machine, start, duration, end, height, limit, true,
01111                       ann2icl(ann));
01112         }        
01113       } else {
01114         int min = Gecode::Int::Limits::max;
01115         int max = Gecode::Int::Limits::min;
01116         IntVarArgs end(start.size());
01117         for (int i = start.size(); i--; ) {
01118           min = std::min(min, start[i].min());
01119           max = std::max(max, start[i].max() + duration[i].max());
01120           end[i] = expr(s, start[i] + duration[i]);
01121         }
01122         for (int time = min; time < max; ++time) {
01123           IntVarArgs x(start.size());
01124           for (int i = start.size(); i--; ) {
01125             IntVar overlaps = channel(s, expr(s, (start[i] <= time) && 
01126                                                  (time < end[i])));
01127             x[i] = expr(s, overlaps * height[i]);
01128           }
01129           linear(s, x, IRT_LQ, bound);
01130         }
01131       }
01132     }
01133 
01134     void p_among_seq_int(FlatZincSpace& s, const ConExpr& ce,
01135                          AST::Node* ann) {
01136       IntVarArgs x = arg2intvarargs(s, ce[0]);
01137       IntSet S = arg2intset(s, ce[1]);
01138       int q = ce[2]->getInt();
01139       int l = ce[3]->getInt();
01140       int u = ce[4]->getInt();
01141       sequence(s, x, S, q, l, u, ann2icl(ann));
01142     }
01143 
01144     void p_among_seq_bool(FlatZincSpace& s, const ConExpr& ce,
01145                           AST::Node* ann) {
01146       BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01147       bool val = ce[1]->getBool();
01148       int q = ce[2]->getInt();
01149       int l = ce[3]->getInt();
01150       int u = ce[4]->getInt();
01151       IntSet S(val, val);
01152       sequence(s, x, S, q, l, u, ann2icl(ann));
01153     }
01154 
01155     void p_schedule_unary(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01156       IntVarArgs x = arg2intvarargs(s, ce[0]);
01157       IntArgs p = arg2intargs(ce[1]);
01158       unary(s, x, p);
01159     }
01160 
01161     void p_schedule_unary_optional(FlatZincSpace& s, const ConExpr& ce,
01162                                    AST::Node*) {
01163       IntVarArgs x = arg2intvarargs(s, ce[0]);
01164       IntArgs p = arg2intargs(ce[1]);
01165       BoolVarArgs m = arg2boolvarargs(s, ce[2]);
01166       unary(s, x, p, m);
01167     }
01168 
01169     void p_circuit(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01170       IntVarArgs xv = arg2intvarargs(s, ce[0]);
01171       circuit(s,xv,ann2icl(ann));
01172     }
01173     void p_circuit_cost_array(FlatZincSpace& s, const ConExpr& ce,
01174                               AST::Node *ann) {
01175       IntArgs c = arg2intargs(ce[0]);
01176       IntVarArgs xv = arg2intvarargs(s, ce[1]);
01177       IntVarArgs yv = arg2intvarargs(s, ce[2]);
01178       IntVar z = getIntVar(s, ce[3]);
01179       circuit(s,c,xv,yv,z,ann2icl(ann));
01180     }
01181     void p_circuit_cost(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01182       IntArgs c = arg2intargs(ce[0]);
01183       IntVarArgs xv = arg2intvarargs(s, ce[1]);
01184       IntVar z = getIntVar(s, ce[2]);
01185       circuit(s,c,xv,z,ann2icl(ann));
01186     }
01187 
01188     class IntPoster {
01189     public:
01190       IntPoster(void) {
01191         registry().add("all_different_int", &p_distinct);
01192         registry().add("all_different_offset", &p_distinctOffset);
01193         registry().add("all_equal_int", &p_all_equal);
01194         registry().add("int_eq", &p_int_eq);
01195         registry().add("int_ne", &p_int_ne);
01196         registry().add("int_ge", &p_int_ge);
01197         registry().add("int_gt", &p_int_gt);
01198         registry().add("int_le", &p_int_le);
01199         registry().add("int_lt", &p_int_lt);
01200         registry().add("int_eq_reif", &p_int_eq_reif);
01201         registry().add("int_ne_reif", &p_int_ne_reif);
01202         registry().add("int_ge_reif", &p_int_ge_reif);
01203         registry().add("int_gt_reif", &p_int_gt_reif);
01204         registry().add("int_le_reif", &p_int_le_reif);
01205         registry().add("int_lt_reif", &p_int_lt_reif);
01206         registry().add("int_lin_eq", &p_int_lin_eq);
01207         registry().add("int_lin_eq_reif", &p_int_lin_eq_reif);
01208         registry().add("int_lin_ne", &p_int_lin_ne);
01209         registry().add("int_lin_ne_reif", &p_int_lin_ne_reif);
01210         registry().add("int_lin_le", &p_int_lin_le);
01211         registry().add("int_lin_le_reif", &p_int_lin_le_reif);
01212         registry().add("int_lin_lt", &p_int_lin_lt);
01213         registry().add("int_lin_lt_reif", &p_int_lin_lt_reif);
01214         registry().add("int_lin_ge", &p_int_lin_ge);
01215         registry().add("int_lin_ge_reif", &p_int_lin_ge_reif);
01216         registry().add("int_lin_gt", &p_int_lin_gt);
01217         registry().add("int_lin_gt_reif", &p_int_lin_gt_reif);
01218         registry().add("int_plus", &p_int_plus);
01219         registry().add("int_minus", &p_int_minus);
01220         registry().add("int_times", &p_int_times);
01221         registry().add("int_div", &p_int_div);
01222         registry().add("int_mod", &p_int_mod);
01223         registry().add("int_min", &p_int_min);
01224         registry().add("int_max", &p_int_max);
01225         registry().add("int_abs", &p_abs);
01226         registry().add("int_negate", &p_int_negate);
01227         registry().add("bool_eq", &p_bool_eq);
01228         registry().add("bool_eq_reif", &p_bool_eq_reif);
01229         registry().add("bool_ne", &p_bool_ne);
01230         registry().add("bool_ne_reif", &p_bool_ne_reif);
01231         registry().add("bool_ge", &p_bool_ge);
01232         registry().add("bool_ge_reif", &p_bool_ge_reif);
01233         registry().add("bool_le", &p_bool_le);
01234         registry().add("bool_le_reif", &p_bool_le_reif);
01235         registry().add("bool_gt", &p_bool_gt);
01236         registry().add("bool_gt_reif", &p_bool_gt_reif);
01237         registry().add("bool_lt", &p_bool_lt);
01238         registry().add("bool_lt_reif", &p_bool_lt_reif);
01239         registry().add("bool_or", &p_bool_or);
01240         registry().add("bool_and", &p_bool_and);
01241         registry().add("bool_xor", &p_bool_xor);
01242         registry().add("array_bool_and", &p_array_bool_and);
01243         registry().add("array_bool_or", &p_array_bool_or);
01244         registry().add("bool_clause", &p_array_bool_clause);
01245         registry().add("bool_clause_reif", &p_array_bool_clause_reif);
01246         registry().add("bool_left_imp", &p_bool_l_imp);
01247         registry().add("bool_right_imp", &p_bool_r_imp);
01248         registry().add("bool_not", &p_bool_not);
01249         registry().add("array_int_element", &p_array_int_element);
01250         registry().add("array_var_int_element", &p_array_int_element);
01251         registry().add("array_bool_element", &p_array_bool_element);
01252         registry().add("array_var_bool_element", &p_array_bool_element);
01253         registry().add("bool2int", &p_bool2int);
01254         registry().add("int_in", &p_int_in);
01255       
01256         registry().add("array_int_lt", &p_array_int_lt);
01257         registry().add("array_int_lq", &p_array_int_lq);
01258         registry().add("count", &p_count);
01259         registry().add("at_least_int", &p_at_least);      
01260         registry().add("at_most_int", &p_at_most);
01261         registry().add("global_cardinality_gecode", &p_global_cardinality);
01262         registry().add("minimum_int", &p_minimum);
01263         registry().add("maximum_int", &p_maximum);
01264         registry().add("regular", &p_regular);
01265         registry().add("sort", &p_sort);
01266         registry().add("inverse_offsets", &p_inverse_offsets);
01267         registry().add("increasing_int", &p_increasing_int);
01268         registry().add("increasing_bool", &p_increasing_bool);
01269         registry().add("decreasing_int", &p_decreasing_int);
01270         registry().add("decreasing_bool", &p_decreasing_bool);
01271         registry().add("table_int", &p_table_int);
01272         registry().add("table_bool", &p_table_bool);
01273         registry().add("cumulatives", &p_cumulatives);
01274         registry().add("among_seq_int", &p_among_seq_int);
01275         registry().add("among_seq_bool", &p_among_seq_bool);
01276 
01277         registry().add("bool_lin_eq", &p_bool_lin_eq);
01278         registry().add("bool_lin_ne", &p_bool_lin_ne);
01279         registry().add("bool_lin_le", &p_bool_lin_le);
01280         registry().add("bool_lin_lt", &p_bool_lin_lt);
01281         registry().add("bool_lin_ge", &p_bool_lin_ge);
01282         registry().add("bool_lin_gt", &p_bool_lin_gt);
01283 
01284         registry().add("bool_lin_eq_reif", &p_bool_lin_eq_reif);
01285         registry().add("bool_lin_ne_reif", &p_bool_lin_ne_reif);
01286         registry().add("bool_lin_le_reif", &p_bool_lin_le_reif);
01287         registry().add("bool_lin_lt_reif", &p_bool_lin_lt_reif);
01288         registry().add("bool_lin_ge_reif", &p_bool_lin_ge_reif);
01289         registry().add("bool_lin_gt_reif", &p_bool_lin_gt_reif);
01290         
01291         registry().add("schedule_unary", &p_schedule_unary);
01292         registry().add("schedule_unary_optional", &p_schedule_unary_optional);
01293 
01294         registry().add("circuit", &p_circuit);
01295         registry().add("circuit_cost_array", &p_circuit_cost_array);
01296         registry().add("circuit_cost", &p_circuit_cost);
01297       }
01298     };
01299     IntPoster __int_poster;
01300 
01301 #ifdef GECODE_HAS_SET_VARS
01302     void p_set_OP(FlatZincSpace& s, SetOpType op,
01303                   const ConExpr& ce, AST::Node *) {
01304       rel(s, getSetVar(s, ce[0]), op, getSetVar(s, ce[1]), 
01305           SRT_EQ, getSetVar(s, ce[2]));
01306     }
01307     void p_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01308       p_set_OP(s, SOT_UNION, ce, ann);
01309     }
01310     void p_set_intersect(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01311       p_set_OP(s, SOT_INTER, ce, ann);
01312     }
01313     void p_set_diff(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01314       p_set_OP(s, SOT_MINUS, ce, ann);
01315     }
01316 
01317     void p_set_symdiff(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01318       SetVar x = getSetVar(s, ce[0]);
01319       SetVar y = getSetVar(s, ce[1]);
01320 
01321       SetVarLubRanges xub(x);
01322       IntSet xubs(xub);
01323       SetVar x_y(s,IntSet::empty,xubs);
01324       rel(s, x, SOT_MINUS, y, SRT_EQ, x_y);
01325 
01326       SetVarLubRanges yub(y);
01327       IntSet yubs(yub);
01328       SetVar y_x(s,IntSet::empty,yubs);
01329       rel(s, y, SOT_MINUS, x, SRT_EQ, y_x);
01330     
01331       rel(s, x_y, SOT_UNION, y_x, SRT_EQ, getSetVar(s, ce[2]));
01332     }
01333 
01334     void p_array_set_OP(FlatZincSpace& s, SetOpType op,
01335                         const ConExpr& ce, AST::Node *) {
01336       SetVarArgs xs = arg2setvarargs(s, ce[0]);
01337       rel(s, op, xs, getSetVar(s, ce[1]));
01338     }
01339     void p_array_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01340       p_array_set_OP(s, SOT_UNION, ce, ann);
01341     }
01342     void p_array_set_partition(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01343       p_array_set_OP(s, SOT_DUNION, ce, ann);
01344     }
01345 
01346 
01347     void p_set_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01348       rel(s, getSetVar(s, ce[0]), SRT_EQ, getSetVar(s, ce[1]));
01349     }
01350     void p_set_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01351       rel(s, getSetVar(s, ce[0]), SRT_NQ, getSetVar(s, ce[1]));
01352     }
01353     void p_set_subset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01354       rel(s, getSetVar(s, ce[0]), SRT_SUB, getSetVar(s, ce[1]));
01355     }
01356     void p_set_superset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01357       rel(s, getSetVar(s, ce[0]), SRT_SUP, getSetVar(s, ce[1]));
01358     }
01359     void p_set_card(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01360       if (!ce[1]->isIntVar()) {
01361         cardinality(s, getSetVar(s, ce[0]), ce[1]->getInt(), 
01362                     ce[1]->getInt());
01363       } else {
01364         cardinality(s, getSetVar(s, ce[0]), getIntVar(s, ce[1]));
01365       }
01366     }
01367     void p_set_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01368       if (!ce[1]->isSetVar()) {
01369         IntSet d = arg2intset(s,ce[1]);
01370         if (ce[0]->isBoolVar()) {
01371           IntSetRanges dr(d);
01372           Iter::Ranges::Singleton sr(0,1);
01373           Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01374           IntSet d01(i);
01375           if (d01.size() == 0) {
01376             s.fail();
01377           } else {
01378             rel(s, getBoolVar(s, ce[0]), IRT_GQ, d01.min());
01379             rel(s, getBoolVar(s, ce[0]), IRT_LQ, d01.max());
01380           }
01381         } else {
01382           dom(s, getIntVar(s, ce[0]), d);
01383         }
01384       } else {
01385         if (!ce[0]->isIntVar()) {
01386           dom(s, getSetVar(s, ce[1]), SRT_SUP, ce[0]->getInt());
01387         } else {
01388           rel(s, getSetVar(s, ce[1]), SRT_SUP, getIntVar(s, ce[0]));
01389         }
01390       }
01391     }
01392     void p_set_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01393       rel(s, getSetVar(s, ce[0]), SRT_EQ, getSetVar(s, ce[1]),
01394           getBoolVar(s, ce[2]));
01395     }
01396     void p_set_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01397       rel(s, getSetVar(s, ce[0]), SRT_NQ, getSetVar(s, ce[1]),
01398           getBoolVar(s, ce[2]));
01399     }
01400     void p_set_subset_reif(FlatZincSpace& s, const ConExpr& ce,
01401                            AST::Node *) {
01402       rel(s, getSetVar(s, ce[0]), SRT_SUB, getSetVar(s, ce[1]),
01403           getBoolVar(s, ce[2]));
01404     }
01405     void p_set_superset_reif(FlatZincSpace& s, const ConExpr& ce,
01406                              AST::Node *) {
01407       rel(s, getSetVar(s, ce[0]), SRT_SUP, getSetVar(s, ce[1]),
01408           getBoolVar(s, ce[2]));
01409     }
01410     void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01411       if (!ce[1]->isSetVar()) {
01412         IntSet d = arg2intset(s,ce[1]);
01413         if (ce[0]->isBoolVar()) {
01414           IntSetRanges dr(d);
01415           Iter::Ranges::Singleton sr(0,1);
01416           Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01417           IntSet d01(i);
01418           if (d01.size() == 0) {
01419             rel(s, getBoolVar(s, ce[2]) == 0);
01420           } else if (d01.max() == 0) {
01421             rel(s, getBoolVar(s, ce[2]) == !getBoolVar(s, ce[0]));
01422           } else if (d01.min() == 1) {
01423             rel(s, getBoolVar(s, ce[2]) == getBoolVar(s, ce[0]));
01424           } else {
01425             rel(s, getBoolVar(s, ce[2]) == 1);
01426           }
01427         } else {
01428           dom(s, getIntVar(s, ce[0]), d, getBoolVar(s, ce[2]));
01429         }
01430       } else {
01431         if (!ce[0]->isIntVar()) {
01432           dom(s, getSetVar(s, ce[1]), SRT_SUP, ce[0]->getInt(),
01433               getBoolVar(s, ce[2]));
01434         } else {
01435           rel(s, getSetVar(s, ce[1]), SRT_SUP, getIntVar(s, ce[0]),
01436               getBoolVar(s, ce[2]));
01437         }
01438       }
01439     }
01440     void p_set_disjoint(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01441       rel(s, getSetVar(s, ce[0]), SRT_DISJ, getSetVar(s, ce[1]));
01442     }
01443 
01444     void p_array_set_element(FlatZincSpace& s, const ConExpr& ce,
01445                              AST::Node*) {
01446       bool isConstant = true;
01447       AST::Array* a = ce[1]->getArray();
01448       for (int i=a->a.size(); i--;) {
01449         if (a->a[i]->isSetVar()) {
01450           isConstant = false;
01451           break;
01452         }
01453       }
01454       IntVar selector = getIntVar(s, ce[0]);
01455       rel(s, selector > 0);
01456       if (isConstant) {
01457         IntSetArgs sv = arg2intsetargs(s,ce[1],1);
01458         element(s, sv, selector, getSetVar(s, ce[2]));
01459       } else {
01460         SetVarArgs sv = arg2setvarargs(s, ce[1], 1);
01461         element(s, sv, selector, getSetVar(s, ce[2]));
01462       }
01463     }
01464 
01465     void p_array_set_element_op(FlatZincSpace& s, const ConExpr& ce,
01466                                 AST::Node*, SetOpType op,
01467                                 const IntSet& universe = 
01468                                 IntSet(Set::Limits::min,Set::Limits::max)) {
01469       bool isConstant = true;
01470       AST::Array* a = ce[1]->getArray();
01471       for (int i=a->a.size(); i--;) {
01472         if (a->a[i]->isSetVar()) {
01473           isConstant = false;
01474           break;
01475         }
01476       }
01477       SetVar selector = getSetVar(s, ce[0]);
01478       dom(s, selector, SRT_DISJ, 0);
01479       if (isConstant) {
01480         IntSetArgs sv = arg2intsetargs(s,ce[1], 1);
01481         element(s, op, sv, selector, getSetVar(s, ce[2]), universe);
01482       } else {
01483         SetVarArgs sv = arg2setvarargs(s, ce[1], 1);
01484         element(s, op, sv, selector, getSetVar(s, ce[2]), universe);
01485       }
01486     }
01487 
01488     void p_array_set_element_union(FlatZincSpace& s, const ConExpr& ce,
01489                                        AST::Node* ann) {
01490       p_array_set_element_op(s, ce, ann, SOT_UNION);
01491     }
01492 
01493     void p_array_set_element_intersect(FlatZincSpace& s, const ConExpr& ce,
01494                                        AST::Node* ann) {
01495       p_array_set_element_op(s, ce, ann, SOT_INTER);
01496     }
01497 
01498     void p_array_set_element_intersect_in(FlatZincSpace& s,
01499                                               const ConExpr& ce,
01500                                               AST::Node* ann) {
01501       IntSet d = arg2intset(s, ce[3]);
01502       p_array_set_element_op(s, ce, ann, SOT_INTER, d);
01503     }
01504 
01505     void p_array_set_element_partition(FlatZincSpace& s, const ConExpr& ce,
01506                                            AST::Node* ann) {
01507       p_array_set_element_op(s, ce, ann, SOT_DUNION);
01508     }
01509 
01510     void p_set_convex(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01511       convex(s, getSetVar(s, ce[0]));
01512     }
01513 
01514     void p_array_set_seq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01515       SetVarArgs sv = arg2setvarargs(s, ce[0]);
01516       sequence(s, sv);
01517     }
01518 
01519     void p_array_set_seq_union(FlatZincSpace& s, const ConExpr& ce,
01520                                AST::Node *) {
01521       SetVarArgs sv = arg2setvarargs(s, ce[0]);
01522       sequence(s, sv, getSetVar(s, ce[1]));
01523     }
01524 
01525     class SetPoster {
01526     public:
01527       SetPoster(void) {
01528         registry().add("set_eq", &p_set_eq);
01529         registry().add("equal", &p_set_eq);
01530         registry().add("set_ne", &p_set_ne);
01531         registry().add("set_union", &p_set_union);
01532         registry().add("array_set_element", &p_array_set_element);
01533         registry().add("array_var_set_element", &p_array_set_element);
01534         registry().add("set_intersect", &p_set_intersect);
01535         registry().add("set_diff", &p_set_diff);
01536         registry().add("set_symdiff", &p_set_symdiff);
01537         registry().add("set_subset", &p_set_subset);
01538         registry().add("set_superset", &p_set_superset);
01539         registry().add("set_card", &p_set_card);
01540         registry().add("set_in", &p_set_in);
01541         registry().add("set_eq_reif", &p_set_eq_reif);
01542         registry().add("equal_reif", &p_set_eq_reif);
01543         registry().add("set_ne_reif", &p_set_ne_reif);
01544         registry().add("set_subset_reif", &p_set_subset_reif);
01545         registry().add("set_superset_reif", &p_set_superset_reif);
01546         registry().add("set_in_reif", &p_set_in_reif);
01547         registry().add("disjoint", &p_set_disjoint);
01548 
01549         registry().add("array_set_union", &p_array_set_union);
01550         registry().add("array_set_partition", &p_array_set_partition);
01551         registry().add("set_convex", &p_set_convex);
01552         registry().add("array_set_seq", &p_array_set_seq);
01553         registry().add("array_set_seq_union", &p_array_set_seq_union);
01554         registry().add("array_set_element_union", 
01555                        &p_array_set_element_union);
01556         registry().add("array_set_element_intersect", 
01557                        &p_array_set_element_intersect);
01558         registry().add("array_set_element_intersect_in", 
01559                        &p_array_set_element_intersect_in);
01560         registry().add("array_set_element_partition", 
01561                        &p_array_set_element_partition);
01562       }
01563     };
01564     SetPoster __set_poster;
01565 #endif
01566 
01567   }
01568 }}
01569 
01570 // STATISTICS: flatzinc-any