Generated on Tue May 22 09:39:40 2018 for Gecode by doxygen 1.6.3

flatzinc.hh

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  *     Gabriel Hjort Blindell <gabriel.hjort.blindell@gmail.com>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2007-2012
00011  *     Gabriel Hjort Blindell, 2012
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 #ifndef __GECODE_FLATZINC_HH__
00039 #define __GECODE_FLATZINC_HH__
00040 
00041 #include <iostream>
00042 
00043 #include <gecode/kernel.hh>
00044 #include <gecode/int.hh>
00045 #ifdef GECODE_HAS_SET_VARS
00046 #include <gecode/set.hh>
00047 #endif
00048 #ifdef GECODE_HAS_FLOAT_VARS
00049 #include <gecode/float.hh>
00050 #endif
00051 #include <map>
00052 
00053 /*
00054  * Support for DLLs under Windows
00055  *
00056  */
00057 
00058 #if !defined(GECODE_STATIC_LIBS) && \
00059     (defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER))
00060 
00061 #ifdef GECODE_BUILD_FLATZINC
00062 #define GECODE_FLATZINC_EXPORT __declspec( dllexport )
00063 #else
00064 #define GECODE_FLATZINC_EXPORT __declspec( dllimport )
00065 #endif
00066 
00067 #else
00068 
00069 #ifdef GECODE_GCC_HAS_CLASS_VISIBILITY
00070 
00071 #define GECODE_FLATZINC_EXPORT __attribute__ ((visibility("default")))
00072 
00073 #else
00074 
00075 #define GECODE_FLATZINC_EXPORT
00076 
00077 #endif
00078 #endif
00079 
00080 // Configure auto-linking
00081 #ifndef GECODE_BUILD_FLATZINC
00082 #define GECODE_LIBRARY_NAME "FlatZinc"
00083 #include <gecode/support/auto-link.hpp>
00084 #endif
00085 
00086 #include <gecode/driver.hh>
00087 
00088 #include <gecode/flatzinc/conexpr.hh>
00089 #include <gecode/flatzinc/ast.hh>
00090 #include <gecode/flatzinc/varspec.hh>
00091 
00101 namespace Gecode { namespace FlatZinc {
00102 
00107   class GECODE_FLATZINC_EXPORT Printer {
00108   private:
00110     std::vector<std::string> iv_names;
00112     std::vector<std::string> bv_names;
00113 #ifdef GECODE_HAS_FLOAT_VARS
00114 
00115     std::vector<std::string> fv_names;
00116 #endif
00117 #ifdef GECODE_HAS_SET_VARS
00118 
00119     std::vector<std::string> sv_names;
00120 #endif
00121     AST::Array* _output;
00122     void printElem(std::ostream& out,
00123                    AST::Node* ai,
00124                    const Gecode::IntVarArray& iv,
00125                    const Gecode::BoolVarArray& bv
00126 #ifdef GECODE_HAS_SET_VARS
00127                    ,
00128                    const Gecode::SetVarArray& sv
00129 #endif
00130 #ifdef GECODE_HAS_FLOAT_VARS
00131                   ,
00132                   const Gecode::FloatVarArray& fv
00133 #endif
00134                    ) const;
00135     void printElemDiff(std::ostream& out,
00136                        AST::Node* ai,
00137                        const Gecode::IntVarArray& iv1,
00138                        const Gecode::IntVarArray& iv2,
00139                        const Gecode::BoolVarArray& bv1,
00140                        const Gecode::BoolVarArray& bv2
00141 #ifdef GECODE_HAS_SET_VARS
00142                        ,
00143                        const Gecode::SetVarArray& sv1,
00144                        const Gecode::SetVarArray& sv2
00145 #endif
00146 #ifdef GECODE_HAS_FLOAT_VARS
00147                        ,
00148                        const Gecode::FloatVarArray& fv1,
00149                        const Gecode::FloatVarArray& fv2
00150 #endif
00151                        ) const;
00152   public:
00153     Printer(void) : _output(NULL) {}
00154     void init(AST::Array* output);
00155 
00156     void print(std::ostream& out,
00157                const Gecode::IntVarArray& iv,
00158                const Gecode::BoolVarArray& bv
00159 #ifdef GECODE_HAS_SET_VARS
00160                ,
00161                const Gecode::SetVarArray& sv
00162 #endif
00163 #ifdef GECODE_HAS_FLOAT_VARS
00164                ,
00165                const Gecode::FloatVarArray& fv
00166 #endif
00167                ) const;
00168 
00169     void printDiff(std::ostream& out,
00170                const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2,
00171                const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2
00172 #ifdef GECODE_HAS_SET_VARS
00173                ,
00174                const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2
00175 #endif
00176 #ifdef GECODE_HAS_FLOAT_VARS
00177                ,
00178                const Gecode::FloatVarArray& fv1,
00179                const Gecode::FloatVarArray& fv2
00180 #endif
00181                ) const;
00182 
00183 
00184     ~Printer(void);
00185 
00186     void addIntVarName(const std::string& n);
00187     const std::string& intVarName(int i) const { return iv_names[i]; }
00188     void addBoolVarName(const std::string& n);
00189     const std::string& boolVarName(int i) const { return bv_names[i]; }
00190 #ifdef GECODE_HAS_FLOAT_VARS
00191     void addFloatVarName(const std::string& n);
00192     const std::string& floatVarName(int i) const { return fv_names[i]; }
00193 #endif
00194 #ifdef GECODE_HAS_SET_VARS
00195     void addSetVarName(const std::string& n);
00196     const std::string& setVarName(int i) const { return sv_names[i]; }
00197 #endif
00198 
00199     void shrinkElement(AST::Node* node,
00200                        std::map<int,int>& iv, std::map<int,int>& bv,
00201                        std::map<int,int>& sv, std::map<int,int>& fv);
00202 
00203     void shrinkArrays(Space& home,
00204                       int& optVar, bool optVarIsInt,
00205                       Gecode::IntVarArray& iv,
00206                       Gecode::BoolVarArray& bv
00207 #ifdef GECODE_HAS_SET_VARS
00208                       ,
00209                       Gecode::SetVarArray& sv
00210 #endif
00211 #ifdef GECODE_HAS_FLOAT_VARS
00212                       ,
00213                       Gecode::FloatVarArray& fv
00214 #endif
00215                      );
00216 
00217   private:
00218     Printer(const Printer&);
00219     Printer& operator=(const Printer&);
00220   };
00221 
00226   class FlatZincOptions : public Gecode::BaseOptions {
00227   protected:
00229 
00230       Gecode::Driver::IntOption         _solutions; 
00231       Gecode::Driver::BoolOption        _allSolutions; 
00232       Gecode::Driver::DoubleOption      _threads;   
00233       Gecode::Driver::BoolOption        _free; 
00234       Gecode::Driver::DoubleOption      _decay;       
00235       Gecode::Driver::UnsignedIntOption _c_d;       
00236       Gecode::Driver::UnsignedIntOption _a_d;       
00237       Gecode::Driver::UnsignedIntOption _node;      
00238       Gecode::Driver::UnsignedIntOption _fail;      
00239       Gecode::Driver::UnsignedIntOption _time;      
00240       Gecode::Driver::IntOption         _seed;      
00241       Gecode::Driver::StringOption      _restart;   
00242       Gecode::Driver::DoubleOption      _r_base;    
00243       Gecode::Driver::UnsignedIntOption _r_scale;   
00244       Gecode::Driver::BoolOption        _nogoods;   
00245       Gecode::Driver::UnsignedIntOption _nogoods_limit; 
00246       Gecode::Driver::BoolOption        _interrupt; 
00247       Gecode::Driver::DoubleOption      _step;        
00248 
00249 
00251 
00252       Gecode::Driver::StringOption      _mode;       
00253       Gecode::Driver::BoolOption        _stat;       
00254       Gecode::Driver::StringValueOption _output;     
00255 
00256 #ifdef GECODE_HAS_CPPROFILER
00257 
00258       Gecode::Driver::IntOption         _profiler_id; 
00259       Gecode::Driver::UnsignedIntOption _profiler_port; 
00260       Gecode::Driver::BoolOption        _profiler_info; 
00261 
00262 #endif
00263 
00265   public:
00267     FlatZincOptions(const char* s)
00268     : Gecode::BaseOptions(s),
00269       _solutions("n","number of solutions (0 = all, -1 = one/best)",-1),
00270       _allSolutions("a", "return all solutions (equal to -n 0)"),
00271       _threads("p","number of threads (0 = #processing units)",
00272                Gecode::Search::Config::threads),
00273       _free("f", "free search, no need to follow search-specification"),
00274       _decay("decay","decay factor",0.99),
00275       _c_d("c-d","recomputation commit distance",Gecode::Search::Config::c_d),
00276       _a_d("a-d","recomputation adaption distance",Gecode::Search::Config::a_d),
00277       _node("node","node cutoff (0 = none, solution mode)"),
00278       _fail("fail","failure cutoff (0 = none, solution mode)"),
00279       _time("time","time (in ms) cutoff (0 = none, solution mode)"),
00280       _seed("r","random seed",0),
00281       _restart("restart","restart sequence type",RM_NONE),
00282       _r_base("restart-base","base for geometric restart sequence",1.5),
00283       _r_scale("restart-scale","scale factor for restart sequence",250),
00284       _nogoods("nogoods","whether to use no-goods from restarts",false),
00285       _nogoods_limit("nogoods-limit","depth limit for no-good extraction",
00286                      Search::Config::nogoods_limit),
00287       _interrupt("interrupt","whether to catch Ctrl-C (true) or not (false)",
00288                  true),
00289       _step("step","step distance for float optimization",0.0),
00290       _mode("mode","how to execute script",Gecode::SM_SOLUTION),
00291       _stat("s","emit statistics"),
00292       _output("o","file to send output to")
00293 
00294 #ifdef GECODE_HAS_CPPROFILER
00295       ,
00296       _profiler_id("cpprofiler-id", "use this execution id with cpprofiler", 0),
00297       _profiler_port("cpprofiler-port", "connect to cpprofiler on this port", 6565),
00298       _profiler_info("cpprofiler-info", "send solution information to cpprofiler", false)
00299 
00300 #endif
00301     {
00302       _mode.add(Gecode::SM_SOLUTION, "solution");
00303       _mode.add(Gecode::SM_STAT, "stat");
00304       _mode.add(Gecode::SM_GIST, "gist");
00305       _mode.add(Gecode::SM_CPPROFILER, "cpprofiler");
00306       _restart.add(RM_NONE,"none");
00307       _restart.add(RM_CONSTANT,"constant");
00308       _restart.add(RM_LINEAR,"linear");
00309       _restart.add(RM_LUBY,"luby");
00310       _restart.add(RM_GEOMETRIC,"geometric");
00311 
00312       add(_solutions); add(_threads); add(_c_d); add(_a_d);
00313       add(_allSolutions);
00314       add(_free);
00315       add(_decay);
00316       add(_node); add(_fail); add(_time); add(_interrupt);
00317       add(_seed);
00318       add(_step);
00319       add(_restart); add(_r_base); add(_r_scale);
00320       add(_nogoods); add(_nogoods_limit);
00321       add(_mode); add(_stat);
00322       add(_output);
00323 #ifdef GECODE_HAS_CPPROFILER
00324       add(_profiler_id);
00325       add(_profiler_port);
00326       add(_profiler_info);
00327 #endif
00328     }
00329 
00330     void parse(int& argc, char* argv[]) {
00331       Gecode::BaseOptions::parse(argc,argv);
00332       if (_allSolutions.value() && _solutions.value()==-1) {
00333         _solutions.value(0);
00334       }
00335       if (_stat.value())
00336         _mode.value(Gecode::SM_STAT);
00337     }
00338 
00339     virtual void help(void) {
00340       std::cerr << "Gecode FlatZinc interpreter" << std::endl
00341                 << " - Supported FlatZinc version: " << GECODE_FLATZINC_VERSION
00342                 << std::endl << std::endl;
00343       Gecode::BaseOptions::help();
00344     }
00345 
00346     int solutions(void) const { return _solutions.value(); }
00347     bool allSolutions(void) const { return _allSolutions.value(); }
00348     double threads(void) const { return _threads.value(); }
00349     bool free(void) const { return _free.value(); }
00350     unsigned int c_d(void) const { return _c_d.value(); }
00351     unsigned int a_d(void) const { return _a_d.value(); }
00352     unsigned int node(void) const { return _node.value(); }
00353     unsigned int fail(void) const { return _fail.value(); }
00354     unsigned int time(void) const { return _time.value(); }
00355     int seed(void) const { return _seed.value(); }
00356     double step(void) const { return _step.value(); }
00357     const char* output(void) const { return _output.value(); }
00358 
00359     Gecode::ScriptMode mode(void) const {
00360       return static_cast<Gecode::ScriptMode>(_mode.value());
00361     }
00362 
00363     double decay(void) const { return _decay.value(); }
00364     RestartMode restart(void) const {
00365       return static_cast<RestartMode>(_restart.value());
00366     }
00367     void restart(RestartMode rm) {
00368       _restart.value(rm);
00369     }
00370     double restart_base(void) const { return _r_base.value(); }
00371     void restart_base(double d) { _r_base.value(d); }
00372     unsigned int restart_scale(void) const { return _r_scale.value(); }
00373     void restart_scale(int i) { _r_scale.value(i); }
00374     bool nogoods(void) const { return _nogoods.value(); }
00375     unsigned int nogoods_limit(void) const { return _nogoods_limit.value(); }
00376     bool interrupt(void) const { return _interrupt.value(); }
00377 
00378 #ifdef GECODE_HAS_CPPROFILER
00379 
00380     int profiler_id(void) const { return _profiler_id.value(); }
00381     unsigned int profiler_port(void) const { return _profiler_port.value(); }
00382     bool profiler_info(void) const { return _profiler_info.value(); }
00383 
00384 #endif
00385 
00386     void allSolutions(bool b) { _allSolutions.value(b); }
00387   };
00388 
00389   class BranchInformation : public SharedHandle {
00390   public:
00392     BranchInformation(void);
00394     BranchInformation(const BranchInformation& bi);
00396     void init(void);
00398     void add(BrancherGroup bg,
00399              const std::string& rel0,
00400              const std::string& rel1,
00401              const std::vector<std::string>& n);
00403     void print(const Brancher& b,
00404                unsigned int a, int i, int n, std::ostream& o) const;
00405 #ifdef GECODE_HAS_FLOAT_VARS
00406 
00407     void print(const Brancher& b,
00408                unsigned int a, int i, const FloatNumBranch& nl,
00409                std::ostream& o) const;
00410 #endif
00411   };
00412 
00414   GECODE_FLATZINC_EXPORT
00415   extern Rnd defrnd;
00416 
00417   class FlatZincSpaceInitData;
00418 
00423   class GECODE_FLATZINC_EXPORT FlatZincSpace : public Space {
00424   public:
00425     enum Meth {
00426       SAT, //< Solve as satisfaction problem
00427       MIN, //< Solve as minimization problem
00428       MAX  //< Solve as maximization problem
00429     };
00430   protected:
00432     FlatZincSpaceInitData* _initData;
00434     int intVarCount;
00436     int boolVarCount;
00438     int floatVarCount;
00440     int setVarCount;
00441 
00443     int _optVar;
00445     bool _optVarIsInt;
00446 
00448     Meth _method;
00449 
00451     unsigned int _lns;
00452 
00454     IntSharedArray _lnsInitialSolution;
00455 
00457     Rnd _random;
00458 
00460     AST::Array* _solveAnnotations;
00461 
00463     FlatZincSpace(FlatZincSpace&);
00464   private:
00466     template<template<class> class Engine>
00467     void
00468     runEngine(std::ostream& out, const Printer& p,
00469               const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00471     template<template<class> class Engine,
00472              template<class, template<class> class> class Meta>
00473     void
00474     runMeta(std::ostream& out, const Printer& p,
00475             const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00476     void
00477     branchWithPlugin(AST::Node* ann);
00478   public:
00480     Gecode::IntVarArray iv;
00482     Gecode::IntVarArray iv_aux;
00483 
00485     Gecode::IntVarArray iv_lns;
00486 
00488     std::vector<bool> iv_introduced;
00490     int* iv_boolalias;
00492     Gecode::BoolVarArray bv;
00494     Gecode::BoolVarArray bv_aux;
00496     std::vector<bool> bv_introduced;
00497 #ifdef GECODE_HAS_SET_VARS
00498 
00499     Gecode::SetVarArray sv;
00501     Gecode::SetVarArray sv_aux;
00503     std::vector<bool> sv_introduced;
00504 #endif
00505 #ifdef GECODE_HAS_FLOAT_VARS
00506 
00507     Gecode::FloatVarArray fv;
00509     Gecode::FloatVarArray fv_aux;
00511     std::vector<bool> fv_introduced;
00513     Gecode::FloatNum step;
00514 #endif
00515 
00516     bool needAuxVars;
00518     FlatZincSpace(Rnd& random = defrnd);
00519 
00521     ~FlatZincSpace(void);
00522 
00524     void init(int intVars, int boolVars, int setVars, int floatVars);
00525 
00527     void newIntVar(IntVarSpec* vs);
00529     void aliasBool2Int(int iv, int bv);
00531     int aliasBool2Int(int iv);
00533     void newBoolVar(BoolVarSpec* vs);
00535     void newSetVar(SetVarSpec* vs);
00537     void newFloatVar(FloatVarSpec* vs);
00538 
00540     void postConstraints(std::vector<ConExpr*>& ces);
00541 
00543     void solve(AST::Array* annotation);
00545     void minimize(int var, bool isInt, AST::Array* annotation);
00547     void maximize(int var, bool isInt, AST::Array* annotation);
00548 
00550     void run(std::ostream& out, const Printer& p,
00551              const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00552 
00554     void print(std::ostream& out, const Printer& p) const;
00555 #ifdef GECODE_HAS_CPPROFILER
00556 
00557     std::string getDomains(const Printer& p) const;
00558 #endif
00559 
00560 
00561     void compare(const Space& s, std::ostream& out) const;
00564     void compare(const FlatZincSpace& s, std::ostream& out,
00565                  const Printer& p) const;
00566 
00575     void shrinkArrays(Printer& p);
00576 
00578     Meth method(void) const;
00579 
00581     int optVar(void) const;
00583     bool optVarIsInt(void) const;
00584 
00594     void createBranchers(Printer& p, AST::Node* ann,
00595                          FlatZincOptions& opt, bool ignoreUnknown,
00596                          std::ostream& err = std::cerr);
00597 
00599     AST::Array* solveAnnotations(void) const;
00600 
00602     BranchInformation branchInfo;
00603 
00605     virtual void constrain(const Space& s);
00607     virtual Gecode::Space* copy(void);
00609     virtual bool slave(const MetaInfo& mi);
00610 
00612 
00613 
00614     IntArgs arg2intargs(AST::Node* arg, int offset = 0);
00616     IntSharedArray arg2intsharedarray(AST::Node* arg, int offset = 0);
00618     IntArgs arg2boolargs(AST::Node* arg, int offset = 0);
00620     IntSharedArray arg2boolsharedarray(AST::Node* arg, int offset = 0);
00622     IntSet arg2intset(AST::Node* n);
00624     IntSetArgs arg2intsetargs(AST::Node* arg, int offset = 0);
00626     IntVarArgs arg2intvarargs(AST::Node* arg, int offset = 0);
00628     BoolVarArgs arg2boolvarargs(AST::Node* arg, int offset = 0, int siv=-1);
00630     BoolVar arg2BoolVar(AST::Node* n);
00632     IntVar arg2IntVar(AST::Node* n);
00634     TupleSet arg2tupleset(AST::Node* n, int noOfVars);
00636     bool isBoolArray(AST::Node* b, int& singleInt);
00637 #ifdef GECODE_HAS_SET_VARS
00638 
00639     SetVar arg2SetVar(AST::Node* n);
00641     SetVarArgs arg2setvarargs(AST::Node* arg, int offset = 0, int doffset = 0,
00642                               const IntSet& od=IntSet::empty);
00643 #endif
00644 #ifdef GECODE_HAS_FLOAT_VARS
00645 
00646     FloatValArgs arg2floatargs(AST::Node* arg, int offset = 0);
00648     FloatVar arg2FloatVar(AST::Node* n);
00650     FloatVarArgs arg2floatvarargs(AST::Node* arg, int offset = 0);
00651 #endif
00652 
00653     IntPropLevel ann2ipl(AST::Node* ann);
00655     DFA getSharedDFA(DFA& a);
00657   };
00658 
00660   class GECODE_VTABLE_EXPORT Error {
00661   private:
00662     const std::string msg;
00663   public:
00664     Error(const std::string& where, const std::string& what)
00665     : msg(where+": "+what) {}
00666     const std::string& toString(void) const { return msg; }
00667   };
00668 
00674   GECODE_FLATZINC_EXPORT
00675   FlatZincSpace* parse(const std::string& fileName,
00676                        Printer& p, std::ostream& err = std::cerr,
00677                        FlatZincSpace* fzs=NULL, Rnd& rnd=defrnd);
00678 
00684   GECODE_FLATZINC_EXPORT
00685   FlatZincSpace* parse(std::istream& is,
00686                        Printer& p, std::ostream& err = std::cerr,
00687                        FlatZincSpace* fzs=NULL, Rnd& rnd=defrnd);
00688 
00689 }}
00690 
00691 #endif
00692 
00693 // STATISTICS: flatzinc-any