00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef __GECODE_FLATZINC_HH__
00043 #define __GECODE_FLATZINC_HH__
00044
00045 #include <iostream>
00046
00047 #include <gecode/kernel.hh>
00048 #include <gecode/int.hh>
00049 #ifdef GECODE_HAS_SET_VARS
00050 #include <gecode/set.hh>
00051 #endif
00052 #ifdef GECODE_HAS_FLOAT_VARS
00053 #include <gecode/float.hh>
00054 #endif
00055 #include <map>
00056
00057
00058
00059
00060
00061
00062 #if !defined(GECODE_STATIC_LIBS) && \
00063 (defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER))
00064
00065 #ifdef GECODE_BUILD_FLATZINC
00066 #define GECODE_FLATZINC_EXPORT __declspec( dllexport )
00067 #else
00068 #define GECODE_FLATZINC_EXPORT __declspec( dllimport )
00069 #endif
00070
00071 #else
00072
00073 #ifdef GECODE_GCC_HAS_CLASS_VISIBILITY
00074
00075 #define GECODE_FLATZINC_EXPORT __attribute__ ((visibility("default")))
00076
00077 #else
00078
00079 #define GECODE_FLATZINC_EXPORT
00080
00081 #endif
00082 #endif
00083
00084
00085 #ifndef GECODE_BUILD_FLATZINC
00086 #define GECODE_LIBRARY_NAME "FlatZinc"
00087 #include <gecode/support/auto-link.hpp>
00088 #endif
00089
00090 #include <gecode/driver.hh>
00091
00092 #include <gecode/flatzinc/conexpr.hh>
00093 #include <gecode/flatzinc/ast.hh>
00094 #include <gecode/flatzinc/varspec.hh>
00095
00105 namespace Gecode { namespace FlatZinc {
00106
00111 class GECODE_FLATZINC_EXPORT Printer {
00112 private:
00113 AST::Array* _output;
00114 void printElem(std::ostream& out,
00115 AST::Node* ai,
00116 const Gecode::IntVarArray& iv,
00117 const Gecode::BoolVarArray& bv
00118 #ifdef GECODE_HAS_SET_VARS
00119 ,
00120 const Gecode::SetVarArray& sv
00121 #endif
00122 #ifdef GECODE_HAS_FLOAT_VARS
00123 ,
00124 const Gecode::FloatVarArray& fv
00125 #endif
00126 ) const;
00127 void printElemDiff(std::ostream& out,
00128 AST::Node* ai,
00129 const Gecode::IntVarArray& iv1,
00130 const Gecode::IntVarArray& iv2,
00131 const Gecode::BoolVarArray& bv1,
00132 const Gecode::BoolVarArray& bv2
00133 #ifdef GECODE_HAS_SET_VARS
00134 ,
00135 const Gecode::SetVarArray& sv1,
00136 const Gecode::SetVarArray& sv2
00137 #endif
00138 #ifdef GECODE_HAS_FLOAT_VARS
00139 ,
00140 const Gecode::FloatVarArray& fv1,
00141 const Gecode::FloatVarArray& fv2
00142 #endif
00143 ) const;
00144 public:
00145 Printer(void) : _output(NULL) {}
00146 void init(AST::Array* output);
00147
00148 void print(std::ostream& out,
00149 const Gecode::IntVarArray& iv,
00150 const Gecode::BoolVarArray& bv
00151 #ifdef GECODE_HAS_SET_VARS
00152 ,
00153 const Gecode::SetVarArray& sv
00154 #endif
00155 #ifdef GECODE_HAS_FLOAT_VARS
00156 ,
00157 const Gecode::FloatVarArray& fv
00158 #endif
00159 ) const;
00160
00161 void printDiff(std::ostream& out,
00162 const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2,
00163 const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2
00164 #ifdef GECODE_HAS_SET_VARS
00165 ,
00166 const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2
00167 #endif
00168 #ifdef GECODE_HAS_FLOAT_VARS
00169 ,
00170 const Gecode::FloatVarArray& fv1,
00171 const Gecode::FloatVarArray& fv2
00172 #endif
00173 ) const;
00174
00175
00176 ~Printer(void);
00177
00178 void shrinkElement(AST::Node* node,
00179 std::map<int,int>& iv, std::map<int,int>& bv,
00180 std::map<int,int>& sv, std::map<int,int>& fv);
00181
00182 void shrinkArrays(Space& home,
00183 int& optVar,
00184 Gecode::IntVarArray& iv,
00185 Gecode::BoolVarArray& bv
00186 #ifdef GECODE_HAS_SET_VARS
00187 ,
00188 Gecode::SetVarArray& sv
00189 #endif
00190 #ifdef GECODE_HAS_FLOAT_VARS
00191 ,
00192 Gecode::FloatVarArray& fv
00193 #endif
00194 );
00195
00196 private:
00197 Printer(const Printer&);
00198 Printer& operator=(const Printer&);
00199 };
00200
00205 class FlatZincOptions : public Gecode::BaseOptions {
00206 protected:
00208
00209 Gecode::Driver::UnsignedIntOption _solutions;
00210 Gecode::Driver::BoolOption _allSolutions;
00211 Gecode::Driver::DoubleOption _threads;
00212 Gecode::Driver::BoolOption _free;
00213 Gecode::Driver::DoubleOption _decay;
00214 Gecode::Driver::UnsignedIntOption _c_d;
00215 Gecode::Driver::UnsignedIntOption _a_d;
00216 Gecode::Driver::UnsignedIntOption _node;
00217 Gecode::Driver::UnsignedIntOption _fail;
00218 Gecode::Driver::UnsignedIntOption _time;
00219 Gecode::Driver::IntOption _seed;
00220 Gecode::Driver::StringOption _restart;
00221 Gecode::Driver::DoubleOption _r_base;
00222 Gecode::Driver::UnsignedIntOption _r_scale;
00223 Gecode::Driver::BoolOption _interrupt;
00224
00225
00227
00228 Gecode::Driver::StringOption _mode;
00229 Gecode::Driver::BoolOption _stat;
00230 Gecode::Driver::StringValueOption _output;
00231
00232 public:
00234 FlatZincOptions(const char* s)
00235 : Gecode::BaseOptions(s),
00236 _solutions("-n","number of solutions (0 = all)",1),
00237 _allSolutions("-a", "return all solutions (equal to -solutions 0)"),
00238 _threads("-p","number of threads (0 = #processing units)",
00239 Gecode::Search::Config::threads),
00240 _free("--free", "no need to follow search-specification"),
00241 _decay("-decay","decay factor",1.0),
00242 _c_d("-c-d","recomputation commit distance",Gecode::Search::Config::c_d),
00243 _a_d("-a-d","recomputation adaption distance",Gecode::Search::Config::a_d),
00244 _node("-node","node cutoff (0 = none, solution mode)"),
00245 _fail("-fail","failure cutoff (0 = none, solution mode)"),
00246 _time("-time","time (in ms) cutoff (0 = none, solution mode)"),
00247 _seed("-r","random seed",0),
00248 _restart("-restart","restart sequence type",RM_NONE),
00249 _r_base("-restart-base","base for geometric restart sequence",1.5),
00250 _r_scale("-restart-scale","scale factor for restart sequence",250),
00251 _interrupt("-interrupt","whether to catch Ctrl-C (true) or not (false)",
00252 true),
00253 _mode("-mode","how to execute script",Gecode::SM_SOLUTION),
00254 _stat("-s","emit statistics"),
00255 _output("-o","file to send output to") {
00256
00257 _mode.add(Gecode::SM_SOLUTION, "solution");
00258 _mode.add(Gecode::SM_STAT, "stat");
00259 _mode.add(Gecode::SM_GIST, "gist");
00260 _restart.add(RM_NONE,"none");
00261 _restart.add(RM_CONSTANT,"constant");
00262 _restart.add(RM_LINEAR,"linear");
00263 _restart.add(RM_LUBY,"luby");
00264 _restart.add(RM_GEOMETRIC,"geometric");
00265
00266 add(_solutions); add(_threads); add(_c_d); add(_a_d);
00267 add(_allSolutions);
00268 add(_free);
00269 add(_decay);
00270 add(_node); add(_fail); add(_time); add(_interrupt);
00271 add(_seed);
00272 add(_restart); add(_r_base); add(_r_scale);
00273 add(_mode); add(_stat);
00274 add(_output);
00275 }
00276
00277 void parse(int& argc, char* argv[]) {
00278 Gecode::BaseOptions::parse(argc,argv);
00279 if (_allSolutions.value()) {
00280 _solutions.value(0);
00281 }
00282 if (_stat.value())
00283 _mode.value(Gecode::SM_STAT);
00284 }
00285
00286 virtual void help(void) {
00287 std::cerr << "Gecode FlatZinc interpreter" << std::endl
00288 << " - Supported FlatZinc version: " << GECODE_FLATZINC_VERSION
00289 << std::endl << std::endl;
00290 Gecode::BaseOptions::help();
00291 }
00292
00293 unsigned int solutions(void) const { return _solutions.value(); }
00294 bool allSolutions(void) const { return _allSolutions.value(); }
00295 double threads(void) const { return _threads.value(); }
00296 bool free(void) const { return _free.value(); }
00297 unsigned int c_d(void) const { return _c_d.value(); }
00298 unsigned int a_d(void) const { return _a_d.value(); }
00299 unsigned int node(void) const { return _node.value(); }
00300 unsigned int fail(void) const { return _fail.value(); }
00301 unsigned int time(void) const { return _time.value(); }
00302 int seed(void) const { return _seed.value(); }
00303 const char* output(void) const { return _output.value(); }
00304 Gecode::ScriptMode mode(void) const {
00305 return static_cast<Gecode::ScriptMode>(_mode.value());
00306 }
00307
00308 double decay(void) const { return _decay.value(); }
00309 RestartMode restart(void) const {
00310 return static_cast<RestartMode>(_restart.value());
00311 }
00312 double restart_base(void) const { return _r_base.value(); }
00313 unsigned int restart_scale(void) const { return _r_scale.value(); }
00314 bool interrupt(void) const { return _interrupt.value(); }
00315
00316 };
00317
00322 class GECODE_FLATZINC_EXPORT FlatZincSpace : public Space {
00323 public:
00324 enum Meth {
00325 SAT,
00326 MIN,
00327 MAX
00328 };
00329 protected:
00331 int intVarCount;
00333 int boolVarCount;
00335 int floatVarCount;
00337 int setVarCount;
00338
00340 int _optVar;
00341
00343 Meth _method;
00344
00346 AST::Array* _solveAnnotations;
00347
00349 FlatZincSpace(bool share, FlatZincSpace&);
00350 private:
00352 template<template<class> class Engine>
00353 void
00354 runEngine(std::ostream& out, const Printer& p,
00355 const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00357 template<template<class> class Engine,
00358 template<template<class> class,class> class Meta>
00359 void
00360 runMeta(std::ostream& out, const Printer& p,
00361 const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00362 void
00363 branchWithPlugin(AST::Node* ann);
00364 public:
00366 Gecode::IntVarArray iv;
00368 Gecode::IntVarArray iv_aux;
00370 std::vector<bool> iv_introduced;
00372 int* iv_boolalias;
00374 Gecode::BoolVarArray bv;
00376 Gecode::BoolVarArray bv_aux;
00378 std::vector<bool> bv_introduced;
00379 #ifdef GECODE_HAS_SET_VARS
00380
00381 Gecode::SetVarArray sv;
00383 Gecode::SetVarArray sv_aux;
00385 std::vector<bool> sv_introduced;
00386 #endif
00387 #ifdef GECODE_HAS_FLOAT_VARS
00388
00389 Gecode::FloatVarArray fv;
00391 Gecode::FloatVarArray fv_aux;
00393 std::vector<bool> fv_introduced;
00394 #endif
00395
00396 bool needAuxVars;
00398 FlatZincSpace(void);
00399
00401 ~FlatZincSpace(void);
00402
00404 void init(int intVars, int boolVars, int setVars, int floatVars);
00405
00407 void newIntVar(IntVarSpec* vs);
00409 void aliasBool2Int(int iv, int bv);
00411 int aliasBool2Int(int iv);
00413 void newBoolVar(BoolVarSpec* vs);
00415 void newSetVar(SetVarSpec* vs);
00417 void newFloatVar(FloatVarSpec* vs);
00418
00420 void postConstraint(const ConExpr& ce, AST::Node* annotation);
00421
00423 void solve(AST::Array* annotation);
00425 void minimize(int var, AST::Array* annotation);
00427 void maximize(int var, AST::Array* annotation);
00428
00430 void run(std::ostream& out, const Printer& p,
00431 const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00432
00434 void print(std::ostream& out, const Printer& p) const;
00435
00438 void compare(const Space& s, std::ostream& out) const;
00441 void compare(const FlatZincSpace& s, std::ostream& out,
00442 const Printer& p) const;
00443
00452 void shrinkArrays(Printer& p);
00453
00455 Meth method(void) const;
00456
00458 int optVar(void) const;
00459
00469 void createBranchers(AST::Node* ann,
00470 int seed, double decay,
00471 bool ignoreUnknown,
00472 std::ostream& err = std::cerr);
00473
00475 AST::Array* solveAnnotations(void) const;
00476
00478 virtual void constrain(const Space& s);
00480 virtual Gecode::Space* copy(bool share);
00481
00482
00484
00485
00486 IntArgs arg2intargs(AST::Node* arg, int offset = 0);
00488 IntArgs arg2boolargs(AST::Node* arg, int offset = 0);
00490 IntSet arg2intset(AST::Node* n);
00492 IntSetArgs arg2intsetargs(AST::Node* arg, int offset = 0);
00494 IntVarArgs arg2intvarargs(AST::Node* arg, int offset = 0);
00496 BoolVarArgs arg2boolvarargs(AST::Node* arg, int offset = 0, int siv=-1);
00498 BoolVar arg2BoolVar(AST::Node* n);
00500 IntVar arg2IntVar(AST::Node* n);
00502 bool isBoolArray(AST::Node* b, int& singleInt);
00503 #ifdef GECODE_HAS_SET_VARS
00504
00505 SetVar arg2SetVar(AST::Node* n);
00507 SetVarArgs arg2setvarargs(AST::Node* arg, int offset = 0, int doffset = 0,
00508 const IntSet& od=IntSet::empty);
00509 #endif
00510 #ifdef GECODE_HAS_FLOAT_VARS
00511
00512 FloatValArgs arg2floatargs(AST::Node* arg, int offset = 0);
00514 FloatVar arg2FloatVar(AST::Node* n);
00516 FloatVarArgs arg2floatvarargs(AST::Node* arg, int offset = 0);
00517 #endif
00518
00519 IntConLevel ann2icl(AST::Node* ann);
00521 };
00522
00524 class Error {
00525 private:
00526 const std::string msg;
00527 public:
00528 Error(const std::string& where, const std::string& what)
00529 : msg(where+": "+what) {}
00530 const std::string& toString(void) const { return msg; }
00531 };
00532
00538 GECODE_FLATZINC_EXPORT
00539 FlatZincSpace* parse(const std::string& fileName,
00540 Printer& p, std::ostream& err = std::cerr,
00541 FlatZincSpace* fzs=NULL);
00542
00548 GECODE_FLATZINC_EXPORT
00549 FlatZincSpace* parse(std::istream& is,
00550 Printer& p, std::ostream& err = std::cerr,
00551 FlatZincSpace* fzs=NULL);
00552
00553 }}
00554
00555 #endif
00556
00557