A set of benchmarks to compare a new prototype MiniZinc implementation
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12#ifndef __MINIZINC_SOLVER_HH__ 13#define __MINIZINC_SOLVER_HH__ 14 15#include <minizinc/exception.hh> 16#include <minizinc/flattener.hh> 17#include <minizinc/solver_config.hh> 18#include <minizinc/solver_instance_base.hh> 19 20#include <iostream> 21#include <memory> 22#include <string> 23#include <vector> 24 25namespace MiniZinc { 26 27class SolverInitialiser { 28public: 29 SolverInitialiser(void); 30}; 31 32class SolverFactory; 33 34/// SolverRegistry is a storage for all SolverFactories in linked modules 35class SolverRegistry { 36public: 37 void addSolverFactory(SolverFactory*); 38 void removeSolverFactory(SolverFactory*); 39 typedef std::vector<SolverFactory*> SFStorage; 40 const SFStorage& getSolverFactories() const { return sfstorage; } 41 42private: 43 SFStorage sfstorage; 44}; // SolverRegistry 45 46/// this function returns the global SolverRegistry object 47SolverRegistry* getGlobalSolverRegistry(); 48 49/// Representation of flags that can be passed to solvers 50class MZNFZNSolverFlag { 51public: 52 /// The type of the solver flag 53 enum FlagType { FT_ARG, FT_NOARG } t; 54 /// The name of the solver flag 55 std::string n; 56 57protected: 58 MZNFZNSolverFlag(const FlagType& t0, const std::string& n0) : t(t0), n(n0) {} 59 60public: 61 /// Create flag that has an argument 62 static MZNFZNSolverFlag arg(const std::string& n) { return MZNFZNSolverFlag(FT_ARG, n); } 63 /// Create flag that has no argument 64 static MZNFZNSolverFlag noarg(const std::string& n) { return MZNFZNSolverFlag(FT_NOARG, n); } 65 /// Create solver flag from standard flag 66 static MZNFZNSolverFlag std(const std::string& n); 67 /// Create solver flag from extra flag with name \a n and type \a t 68 static MZNFZNSolverFlag extra(const std::string& n, const std::string& t); 69}; 70 71/// SolverFactory's descendants create, store and destroy SolverInstances 72/// A SolverFactory stores all Instances itself and upon module exit, 73/// destroys them and de-registers itself from the global SolverRegistry 74/// An instance of SolverFactory's descendant can be created directly 75/// or by one of the specialized createF_...() functions 76class SolverFactory { 77protected: 78 /// doCreateSI should be implemented to actually allocate a SolverInstance using new() 79 virtual SolverInstanceBase* doCreateSI(std::ostream&, SolverInstanceBase::Options* opt) = 0; 80 typedef std::vector<std::unique_ptr<SolverInstanceBase>> SIStorage; 81 SIStorage sistorage; 82 83protected: 84 SolverFactory() { getGlobalSolverRegistry()->addSolverFactory(this); } 85 86public: 87 virtual ~SolverFactory() { getGlobalSolverRegistry()->removeSolverFactory(this); } 88 89public: 90 /// Create solver-specific options object 91 virtual SolverInstanceBase::Options* createOptions(void) = 0; 92 /// Function createSI also adds each SI to the local storage 93 SolverInstanceBase* createSI(std::ostream& log, SolverInstanceBase::Options* opt); 94 /// also providing a manual destroy function. 95 /// there is no need to call it upon overall finish - that is taken care of 96 void destroySI(SolverInstanceBase* pSI); 97 98public: 99 /// Process an item in the command line. 100 /// Leaving this now like this because this seems simpler. 101 /// We can also pass options internally between modules in this way 102 /// and it only needs 1 format 103 virtual bool processOption(SolverInstanceBase::Options* opt, int& i, 104 std::vector<std::string>& argv) { 105 return false; 106 } 107 108 virtual std::string getDescription(SolverInstanceBase::Options* opt = NULL) = 0; 109 virtual std::string getVersion(SolverInstanceBase::Options* opt = NULL) = 0; 110 virtual std::string getId(void) = 0; 111 virtual void printHelp(std::ostream&) {} 112}; // SolverFactory 113 114// Class MznSolver coordinates flattening and solving. 115class MznSolver { 116private: 117 SolverInitialiser _solver_init; 118 enum OptionStatus { OPTION_OK, OPTION_ERROR, OPTION_FINISH }; 119 /// Solver configurations 120 SolverConfigs solver_configs; 121 Constraint* output = nullptr; 122 std::vector<BytecodeProc> bs; 123 std::vector<std::string> data_files; 124 Env in_out_defs; 125 SolverInstanceBase* si = 0; 126 SolverInstanceBase::Options* si_opt = 0; 127 SolverFactory* sf = 0; 128 bool is_mzn2fzn = 0; 129 130 std::string executable_name; 131 std::string file; 132 std::string solver_str; 133 std::ostream& os; 134 std::ostream& log; 135 SolverInstance::Status interpreter_status = SolverInstance::UNKNOWN; 136 // Incremental interface 137 std::vector<std::pair<Variable*, size_t>> def_stack = {{nullptr, 0}}; 138 double flatten_time = 0; 139 140public: 141 bool output_dict = false; 142 Interpreter* interpreter = nullptr; 143 Solns2Out s2out; 144 // name -> <code, nargs> 145 std::unordered_map<std::string, std::pair<int, int>> resolve_call; 146 147 /// global options 148 bool flag_verbose = false; 149 bool flag_statistics = false; 150 bool flag_compiler_verbose = false; 151 bool flag_compiler_statistics = false; 152 bool flag_is_solns2out = false; 153 int flag_overall_time_limit = 0; 154 155public: 156 MznSolver(std::vector<std::string> args = {}); 157 ~MznSolver(); 158 159 std::pair<SolverInstance::Status, std::string> run(); 160 OptionStatus processOptions(std::vector<std::string>& argv); 161 SolverFactory* getSF() { 162 assert(sf); 163 return sf; 164 } 165 SolverInstanceBase::Options* getSI_OPT() { 166 assert(si_opt); 167 return si_opt; 168 } 169 bool get_flag_verbose() { return flag_verbose; /*getFlt()->get_flag_verbose();*/ } 170 void printUsage(); 171 std::string printSolution(SolverInstance::Status); 172 173 void pushToSolver(); 174 void popFromSolver(); 175 std::pair<SolverInstance::Status, std::string> solve(); 176 177private: 178 void addDefinitions(); 179 Val eval_val(EnvI& env, Expression* e); 180 void printHelp(const std::string& selectedSolver = std::string()); 181 /// Flatten model 182 void flatten(const std::string& filename = std::string(), 183 const std::string& modelName = std::string("stdin")); 184 size_t getNSolvers() { return getGlobalSolverRegistry()->getSolverFactories().size(); } 185 /// If building a flattening exe only. 186 bool ifMzn2Fzn(); 187 bool ifSolns2out(); 188 void addSolverInterface(); 189 void addSolverInterface(SolverFactory* sf); 190 void printStatistics(); 191 192 SolverInstance::Status getFltStatus() { return interpreter_status; } 193 SolverInstanceBase* getSI() { 194 assert(si); 195 return si; 196 } 197 bool get_flag_statistics() { return flag_statistics; } 198}; 199 200} // namespace MiniZinc 201 202#endif