Generated on Tue Apr 18 10:21:32 2017 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  *  Last modified:
00014  *     $Date: 2016-08-26 02:45:29 +0200 (Fri, 26 Aug 2016) $ by $Author: tack $
00015  *     $Revision: 15155 $
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 #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  * Support for DLLs under Windows
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 // Configure auto-linking
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:
00114     std::vector<std::string> iv_names;
00116     std::vector<std::string> bv_names;
00117 #ifdef GECODE_HAS_FLOAT_VARS
00118 
00119     std::vector<std::string> fv_names;
00120 #endif
00121 #ifdef GECODE_HAS_SET_VARS
00122 
00123     std::vector<std::string> sv_names;
00124 #endif
00125     AST::Array* _output;
00126     void printElem(std::ostream& out,
00127                    AST::Node* ai,
00128                    const Gecode::IntVarArray& iv,
00129                    const Gecode::BoolVarArray& bv
00130 #ifdef GECODE_HAS_SET_VARS
00131                    ,
00132                    const Gecode::SetVarArray& sv
00133 #endif
00134 #ifdef GECODE_HAS_FLOAT_VARS
00135                   ,
00136                   const Gecode::FloatVarArray& fv
00137 #endif
00138                    ) const;
00139     void printElemDiff(std::ostream& out,
00140                        AST::Node* ai,
00141                        const Gecode::IntVarArray& iv1,
00142                        const Gecode::IntVarArray& iv2,
00143                        const Gecode::BoolVarArray& bv1,
00144                        const Gecode::BoolVarArray& bv2
00145 #ifdef GECODE_HAS_SET_VARS
00146                        ,
00147                        const Gecode::SetVarArray& sv1,
00148                        const Gecode::SetVarArray& sv2
00149 #endif
00150 #ifdef GECODE_HAS_FLOAT_VARS
00151                        ,
00152                        const Gecode::FloatVarArray& fv1,
00153                        const Gecode::FloatVarArray& fv2
00154 #endif
00155                        ) const;
00156   public:
00157     Printer(void) : _output(NULL) {}
00158     void init(AST::Array* output);
00159 
00160     void print(std::ostream& out,
00161                const Gecode::IntVarArray& iv,
00162                const Gecode::BoolVarArray& bv
00163 #ifdef GECODE_HAS_SET_VARS
00164                ,
00165                const Gecode::SetVarArray& sv
00166 #endif
00167 #ifdef GECODE_HAS_FLOAT_VARS
00168                ,
00169                const Gecode::FloatVarArray& fv
00170 #endif
00171                ) const;
00172 
00173     void printDiff(std::ostream& out,
00174                const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2,
00175                const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2
00176 #ifdef GECODE_HAS_SET_VARS
00177                ,
00178                const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2
00179 #endif
00180 #ifdef GECODE_HAS_FLOAT_VARS
00181                ,
00182                const Gecode::FloatVarArray& fv1,
00183                const Gecode::FloatVarArray& fv2
00184 #endif
00185                ) const;
00186 
00187 
00188     ~Printer(void);
00189 
00190     void addIntVarName(const std::string& n);
00191     const std::string& intVarName(int i) const { return iv_names[i]; }
00192     void addBoolVarName(const std::string& n);
00193     const std::string& boolVarName(int i) const { return bv_names[i]; }
00194 #ifdef GECODE_HAS_FLOAT_VARS
00195     void addFloatVarName(const std::string& n);
00196     const std::string& floatVarName(int i) const { return fv_names[i]; }
00197 #endif
00198 #ifdef GECODE_HAS_SET_VARS
00199     void addSetVarName(const std::string& n);
00200     const std::string& setVarName(int i) const { return sv_names[i]; }
00201 #endif
00202 
00203     void shrinkElement(AST::Node* node,
00204                        std::map<int,int>& iv, std::map<int,int>& bv,
00205                        std::map<int,int>& sv, std::map<int,int>& fv);
00206 
00207     void shrinkArrays(Space& home,
00208                       int& optVar, bool optVarIsInt,
00209                       Gecode::IntVarArray& iv,
00210                       Gecode::BoolVarArray& bv
00211 #ifdef GECODE_HAS_SET_VARS
00212                       ,
00213                       Gecode::SetVarArray& sv
00214 #endif
00215 #ifdef GECODE_HAS_FLOAT_VARS
00216                       ,
00217                       Gecode::FloatVarArray& fv
00218 #endif
00219                      );
00220 
00221   private:
00222     Printer(const Printer&);
00223     Printer& operator=(const Printer&);
00224   };
00225 
00230   class FlatZincOptions : public Gecode::BaseOptions {
00231   protected:
00233 
00234       Gecode::Driver::IntOption         _solutions; 
00235       Gecode::Driver::BoolOption        _allSolutions; 
00236       Gecode::Driver::DoubleOption      _threads;   
00237       Gecode::Driver::BoolOption        _free; 
00238       Gecode::Driver::DoubleOption      _decay;       
00239       Gecode::Driver::UnsignedIntOption _c_d;       
00240       Gecode::Driver::UnsignedIntOption _a_d;       
00241       Gecode::Driver::UnsignedIntOption _node;      
00242       Gecode::Driver::UnsignedIntOption _fail;      
00243       Gecode::Driver::UnsignedIntOption _time;      
00244       Gecode::Driver::IntOption         _seed;      
00245       Gecode::Driver::StringOption      _restart;   
00246       Gecode::Driver::DoubleOption      _r_base;    
00247       Gecode::Driver::UnsignedIntOption _r_scale;   
00248       Gecode::Driver::BoolOption        _nogoods;   
00249       Gecode::Driver::UnsignedIntOption _nogoods_limit; 
00250       Gecode::Driver::BoolOption        _interrupt; 
00251       Gecode::Driver::DoubleOption      _step;        
00252 
00253 
00255 
00256       Gecode::Driver::StringOption      _mode;       
00257       Gecode::Driver::BoolOption        _stat;       
00258       Gecode::Driver::StringValueOption _output;     
00259 
00260   public:
00262     FlatZincOptions(const char* s)
00263     : Gecode::BaseOptions(s),
00264       _solutions("-n","number of solutions (0 = all, -1 = one/best)",-1),
00265       _allSolutions("-a", "return all solutions (equal to -n 0)"),
00266       _threads("-p","number of threads (0 = #processing units)",
00267                Gecode::Search::Config::threads),
00268       _free("-f", "free search, no need to follow search-specification"),
00269       _decay("-decay","decay factor",0.99),
00270       _c_d("-c-d","recomputation commit distance",Gecode::Search::Config::c_d),
00271       _a_d("-a-d","recomputation adaption distance",Gecode::Search::Config::a_d),
00272       _node("-node","node cutoff (0 = none, solution mode)"),
00273       _fail("-fail","failure cutoff (0 = none, solution mode)"),
00274       _time("-time","time (in ms) cutoff (0 = none, solution mode)"),
00275       _seed("-r","random seed",0),
00276       _restart("-restart","restart sequence type",RM_NONE),
00277       _r_base("-restart-base","base for geometric restart sequence",1.5),
00278       _r_scale("-restart-scale","scale factor for restart sequence",250),
00279       _nogoods("-nogoods","whether to use no-goods from restarts",false),
00280       _nogoods_limit("-nogoods-limit","depth limit for no-good extraction",
00281                      Search::Config::nogoods_limit),
00282       _interrupt("-interrupt","whether to catch Ctrl-C (true) or not (false)",
00283                  true),
00284       _step("-step","step distance for float optimization",0.0),
00285       _mode("-mode","how to execute script",Gecode::SM_SOLUTION),
00286       _stat("-s","emit statistics"),
00287       _output("-o","file to send output to") {
00288 
00289       _mode.add(Gecode::SM_SOLUTION, "solution");
00290       _mode.add(Gecode::SM_STAT, "stat");
00291       _mode.add(Gecode::SM_GIST, "gist");
00292       _restart.add(RM_NONE,"none");
00293       _restart.add(RM_CONSTANT,"constant");
00294       _restart.add(RM_LINEAR,"linear");
00295       _restart.add(RM_LUBY,"luby");
00296       _restart.add(RM_GEOMETRIC,"geometric");
00297 
00298       add(_solutions); add(_threads); add(_c_d); add(_a_d);
00299       add(_allSolutions);
00300       add(_free);
00301       add(_decay);
00302       add(_node); add(_fail); add(_time); add(_interrupt);
00303       add(_seed);
00304       add(_step);
00305       add(_restart); add(_r_base); add(_r_scale);
00306       add(_nogoods); add(_nogoods_limit);
00307       add(_mode); add(_stat);
00308       add(_output);
00309     }
00310 
00311     void parse(int& argc, char* argv[]) {
00312       Gecode::BaseOptions::parse(argc,argv);
00313       if (_allSolutions.value() && _solutions.value()==-1) {
00314         _solutions.value(0);
00315       }
00316       if (_stat.value())
00317         _mode.value(Gecode::SM_STAT);
00318     }
00319 
00320     virtual void help(void) {
00321       std::cerr << "Gecode FlatZinc interpreter" << std::endl
00322                 << " - Supported FlatZinc version: " << GECODE_FLATZINC_VERSION
00323                 << std::endl << std::endl;
00324       Gecode::BaseOptions::help();
00325     }
00326 
00327     int solutions(void) const { return _solutions.value(); }
00328     bool allSolutions(void) const { return _allSolutions.value(); }
00329     double threads(void) const { return _threads.value(); }
00330     bool free(void) const { return _free.value(); }
00331     unsigned int c_d(void) const { return _c_d.value(); }
00332     unsigned int a_d(void) const { return _a_d.value(); }
00333     unsigned int node(void) const { return _node.value(); }
00334     unsigned int fail(void) const { return _fail.value(); }
00335     unsigned int time(void) const { return _time.value(); }
00336     int seed(void) const { return _seed.value(); }
00337     double step(void) const { return _step.value(); }
00338     const char* output(void) const { return _output.value(); }
00339     Gecode::ScriptMode mode(void) const {
00340       return static_cast<Gecode::ScriptMode>(_mode.value());
00341     }
00342 
00343     double decay(void) const { return _decay.value(); }
00344     RestartMode restart(void) const {
00345       return static_cast<RestartMode>(_restart.value());
00346     }
00347     double restart_base(void) const { return _r_base.value(); }
00348     unsigned int restart_scale(void) const { return _r_scale.value(); }
00349     bool nogoods(void) const { return _nogoods.value(); }
00350     unsigned int nogoods_limit(void) const { return _nogoods_limit.value(); }
00351     bool interrupt(void) const { return _interrupt.value(); }
00352 
00353     void allSolutions(bool b) { _allSolutions.value(b); }
00354   };
00355 
00356   class BranchInformation : public SharedHandle {
00357   public:
00359     BranchInformation(void);
00361     BranchInformation(const BranchInformation& bi);
00363     void init(void);
00365     void add(BrancherGroup bg,
00366              const std::string& rel0,
00367              const std::string& rel1,
00368              const std::vector<std::string>& n);
00370     void print(const Brancher& b,
00371                unsigned int a, int i, int n, std::ostream& o) const;
00372 #ifdef GECODE_HAS_FLOAT_VARS
00373 
00374     void print(const Brancher& b,
00375                unsigned int a, int i, const FloatNumBranch& nl,
00376                std::ostream& o) const;
00377 #endif
00378   };
00379 
00384  class GECODE_FLATZINC_EXPORT FznRnd {
00385  protected:
00387    Gecode::Support::RandomGenerator random;
00389    Gecode::Support::Mutex mutex;
00390  public:
00392    FznRnd(unsigned int s=1);
00394    unsigned int operator ()(unsigned int n);
00395  };
00396 
00401   class GECODE_FLATZINC_EXPORT FlatZincSpace : public Space {
00402   public:
00403     enum Meth {
00404       SAT, //< Solve as satisfaction problem
00405       MIN, //< Solve as minimization problem
00406       MAX  //< Solve as maximization problem
00407     };
00408   protected:
00410     int intVarCount;
00412     int boolVarCount;
00414     int floatVarCount;
00416     int setVarCount;
00417 
00419     int _optVar;
00421     bool _optVarIsInt;
00422 
00424     Meth _method;
00425 
00427     unsigned int _lns;
00428 
00430     IntSharedArray _lnsInitialSolution;
00431 
00433     FznRnd* _random;
00434 
00436     AST::Array* _solveAnnotations;
00437 
00439     FlatZincSpace(bool share, FlatZincSpace&);
00440   private:
00442     template<template<class> class Engine>
00443     void
00444     runEngine(std::ostream& out, const Printer& p,
00445               const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00447     template<template<class> class Engine,
00448              template<class, template<class> class> class Meta>
00449     void
00450     runMeta(std::ostream& out, const Printer& p,
00451             const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00452     void
00453     branchWithPlugin(AST::Node* ann);
00454   public:
00456     Gecode::IntVarArray iv;
00458     Gecode::IntVarArray iv_aux;
00459 
00461     Gecode::IntVarArray iv_lns;
00462 
00464     std::vector<bool> iv_introduced;
00466     int* iv_boolalias;
00468     Gecode::BoolVarArray bv;
00470     Gecode::BoolVarArray bv_aux;
00472     std::vector<bool> bv_introduced;
00473 #ifdef GECODE_HAS_SET_VARS
00474 
00475     Gecode::SetVarArray sv;
00477     Gecode::SetVarArray sv_aux;
00479     std::vector<bool> sv_introduced;
00480 #endif
00481 #ifdef GECODE_HAS_FLOAT_VARS
00482 
00483     Gecode::FloatVarArray fv;
00485     Gecode::FloatVarArray fv_aux;
00487     std::vector<bool> fv_introduced;
00489     Gecode::FloatNum step;
00490 #endif
00491 
00492     bool needAuxVars;
00494     FlatZincSpace(FznRnd* random = NULL);
00495 
00497     ~FlatZincSpace(void);
00498 
00500     void init(int intVars, int boolVars, int setVars, int floatVars);
00501 
00503     void newIntVar(IntVarSpec* vs);
00505     void aliasBool2Int(int iv, int bv);
00507     int aliasBool2Int(int iv);
00509     void newBoolVar(BoolVarSpec* vs);
00511     void newSetVar(SetVarSpec* vs);
00513     void newFloatVar(FloatVarSpec* vs);
00514 
00516     void postConstraints(std::vector<ConExpr*>& ces);
00517 
00519     void solve(AST::Array* annotation);
00521     void minimize(int var, bool isInt, AST::Array* annotation);
00523     void maximize(int var, bool isInt, AST::Array* annotation);
00524 
00526     void run(std::ostream& out, const Printer& p,
00527              const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00528 
00530     void print(std::ostream& out, const Printer& p) const;
00531 
00534     void compare(const Space& s, std::ostream& out) const;
00537     void compare(const FlatZincSpace& s, std::ostream& out,
00538                  const Printer& p) const;
00539 
00548     void shrinkArrays(Printer& p);
00549 
00551     Meth method(void) const;
00552 
00554     int optVar(void) const;
00556     bool optVarIsInt(void) const;
00557 
00567     void createBranchers(Printer& p, AST::Node* ann,
00568                          int seed, double decay,
00569                          bool ignoreUnknown,
00570                          std::ostream& err = std::cerr);
00571 
00573     AST::Array* solveAnnotations(void) const;
00574 
00576     BranchInformation branchInfo;
00577 
00579     virtual void constrain(const Space& s);
00581     virtual Gecode::Space* copy(bool share);
00583     virtual bool slave(const MetaInfo& mi);
00584 
00586 
00587 
00588     IntArgs arg2intargs(AST::Node* arg, int offset = 0);
00590     IntArgs arg2boolargs(AST::Node* arg, int offset = 0);
00592     IntSet arg2intset(AST::Node* n);
00594     IntSetArgs arg2intsetargs(AST::Node* arg, int offset = 0);
00596     IntVarArgs arg2intvarargs(AST::Node* arg, int offset = 0);
00598     BoolVarArgs arg2boolvarargs(AST::Node* arg, int offset = 0, int siv=-1);
00600     BoolVar arg2BoolVar(AST::Node* n);
00602     IntVar arg2IntVar(AST::Node* n);
00604     bool isBoolArray(AST::Node* b, int& singleInt);
00605 #ifdef GECODE_HAS_SET_VARS
00606 
00607     SetVar arg2SetVar(AST::Node* n);
00609     SetVarArgs arg2setvarargs(AST::Node* arg, int offset = 0, int doffset = 0,
00610                               const IntSet& od=IntSet::empty);
00611 #endif
00612 #ifdef GECODE_HAS_FLOAT_VARS
00613 
00614     FloatValArgs arg2floatargs(AST::Node* arg, int offset = 0);
00616     FloatVar arg2FloatVar(AST::Node* n);
00618     FloatVarArgs arg2floatvarargs(AST::Node* arg, int offset = 0);
00619 #endif
00620 
00621     IntPropLevel ann2ipl(AST::Node* ann);
00623   };
00624 
00626   class GECODE_VTABLE_EXPORT Error {
00627   private:
00628     const std::string msg;
00629   public:
00630     Error(const std::string& where, const std::string& what)
00631     : msg(where+": "+what) {}
00632     const std::string& toString(void) const { return msg; }
00633   };
00634 
00640   GECODE_FLATZINC_EXPORT
00641   FlatZincSpace* parse(const std::string& fileName,
00642                        Printer& p, std::ostream& err = std::cerr,
00643                        FlatZincSpace* fzs=NULL, FznRnd* rnd=NULL);
00644 
00650   GECODE_FLATZINC_EXPORT
00651   FlatZincSpace* parse(std::istream& is,
00652                        Printer& p, std::ostream& err = std::cerr,
00653                        FlatZincSpace* fzs=NULL, FznRnd* rnd=NULL);
00654 
00655 }}
00656 
00657 #endif
00658 
00659 // STATISTICS: flatzinc-any