this repo has no description
at develop 6.4 kB view raw
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#ifdef _MSC_VER 13#define _CRT_SECURE_NO_WARNINGS 14#endif 15 16#ifdef _WIN32 17#define NOMINMAX // Need this before all (implicit) include's of Windows.h 18#endif 19 20#include <minizinc/process.hh> 21#include <minizinc/solvers/mzn_solverinstance.hh> 22#include <minizinc/timer.hh> 23 24#include <cstdio> 25#include <fstream> 26 27#ifdef _WIN32 28#undef ERROR 29#endif 30 31using namespace std; 32 33namespace MiniZinc { 34 35MZN_SolverFactory::MZN_SolverFactory(void) { 36 SolverConfig sc("org.minizinc.mzn-mzn", 37 MZN_VERSION_MAJOR "." MZN_VERSION_MINOR "." MZN_VERSION_PATCH); 38 sc.name("Generic MiniZinc driver"); 39 sc.mznlibVersion(1); 40 sc.description("MiniZinc generic MiniZinc solver plugin"); 41 sc.requiredFlags({"-m"}); 42 sc.tags({"__internal__"}); 43 sc.supportsFzn(false); 44 sc.supportsMzn(true); 45 sc.needsSolns2Out(false); 46 SolverConfigs::registerBuiltinSolver(sc); 47} 48 49string MZN_SolverFactory::getDescription(SolverInstanceBase::Options*) { 50 string v = "MZN solver plugin, compiled " __DATE__ " " __TIME__; 51 return v; 52} 53 54string MZN_SolverFactory::getVersion(SolverInstanceBase::Options*) { return MZN_VERSION_MAJOR; } 55 56string MZN_SolverFactory::getId() { return "org.minizinc.mzn-mzn"; } 57 58void MZN_SolverFactory::printHelp(ostream& os) { 59 os << "MZN-MZN plugin options:" << std::endl 60 << " -m, --minizinc-cmd <exe>\n the backend solver filename.\n" 61 << " --mzn-flags <options>, --minizinc-flags <options>\n Specify option to be passed to " 62 "the MiniZinc interpreter.\n" 63 << " --mzn-flag <option>, --minizinc-flag <option>\n As above, but for a single option " 64 "string that need to be quoted in a shell.\n" 65 << " -t <ms>, --solver-time-limit <ms>, --mzn-time-limit <ms>\n Set time limit for " 66 "solving.\n" 67 << " --mzn-sigint\n Send SIGINT instead of SIGTERM.\n"; 68} 69 70SolverInstanceBase::Options* MZN_SolverFactory::createOptions(void) { return new MZNSolverOptions; } 71 72SolverInstanceBase* MZN_SolverFactory::doCreateSI(std::ostream& log, 73 SolverInstanceBase::Options* opt) { 74 return new MZNSolverInstance(log, opt); 75} 76 77void MZN_SolverFactory::setAcceptedFlags(SolverInstanceBase::Options* opt, 78 const std::vector<MZNFZNSolverFlag>& flags) { 79 MZNSolverOptions& _opt = static_cast<MZNSolverOptions&>(*opt); 80 _opt.mzn_solver_flags.clear(); 81 for (auto& f : flags) { 82 if (f.n == "-t") { 83 _opt.supports_t = true; 84 } else { 85 _opt.mzn_solver_flags.push_back(f); 86 } 87 } 88} 89 90bool MZN_SolverFactory::processOption(SolverInstanceBase::Options* opt, int& i, 91 std::vector<std::string>& argv) { 92 MZNSolverOptions& _opt = static_cast<MZNSolverOptions&>(*opt); 93 CLOParser cop(i, argv); 94 string buffer; 95 int nn = -1; 96 97 if (cop.getOption("-m --minizinc-cmd", &buffer)) { 98 _opt.mzn_solver = buffer; 99 } else if (cop.getOption("--mzn-flags --minizinc-flags", &buffer)) { 100 std::vector<std::string> cmdLine = FileUtils::parseCmdLine(buffer); 101 for (auto& s : cmdLine) { 102 _opt.mzn_flags.push_back(s); 103 } 104 } else if (cop.getOption("-t --solver-time-limit --mzn-time-limit", &nn)) { 105 _opt.mzn_time_limit_ms = nn; 106 if (_opt.supports_t) { 107 _opt.solver_time_limit_ms = nn; 108 _opt.mzn_time_limit_ms += 1000; // kill 1 second after solver should have stopped 109 } 110 } else if (cop.getOption("--mzn-sigint")) { 111 _opt.mzn_sigint = true; 112 } else if (cop.getOption("--mzn-flag --minizinc-flag", &buffer)) { 113 _opt.mzn_flags.push_back(buffer); 114 } else if (cop.getOption("--solver-statistics")) { 115 _opt.printStatistics = true; 116 } else if (cop.getOption("--verbose-solving")) { 117 _opt.verbose = true; 118 } else { 119 for (auto& mznf : _opt.mzn_solver_flags) { 120 if (mznf.t == MZNFZNSolverFlag::FT_ARG && cop.getOption(mznf.n.c_str(), &buffer)) { 121 _opt.mzn_flags.push_back(mznf.n); 122 _opt.mzn_flags.push_back(buffer); 123 return true; 124 } else if (mznf.t == MZNFZNSolverFlag::FT_NOARG && cop.getOption(mznf.n.c_str())) { 125 _opt.mzn_flags.push_back(mznf.n); 126 return true; 127 } 128 } 129 std::string input_file(argv[i]); 130 if (input_file.length() <= 4) { 131 return false; 132 } 133 size_t last_dot = input_file.find_last_of('.'); 134 if (last_dot == string::npos) { 135 return false; 136 } 137 std::string extension = input_file.substr(last_dot, string::npos); 138 if (extension == ".mzn" || extension == ".mzc" || extension == ".fzn" || extension == ".dzn" || 139 extension == ".json") { 140 _opt.mzn_flags.push_back(input_file); 141 } else { 142 return false; 143 } 144 } 145 return true; 146} 147 148MZNSolverInstance::MZNSolverInstance(std::ostream& log, SolverInstanceBase::Options* options) 149 : SolverInstanceBase(log, options) {} 150 151MZNSolverInstance::~MZNSolverInstance(void) {} 152 153SolverInstance::Status MZNSolverInstance::solve(void) { 154 MZNSolverOptions& opt = static_cast<MZNSolverOptions&>(*_options); 155 if (opt.mzn_solver.empty()) { 156 throw InternalError("No MiniZinc solver specified"); 157 } 158 /// Passing options to solver 159 vector<string> cmd_line; 160 cmd_line.push_back(opt.mzn_solver); 161 for (auto& f : opt.mzn_flags) cmd_line.push_back(f); 162 if (opt.printStatistics) { 163 cmd_line.push_back("-s"); 164 } 165 if (opt.verbose) { 166 cmd_line.push_back("-v"); 167 _log << "Using MZN solver " << cmd_line[0] << " for solving, parameters: "; 168 for (int i = 1; i < cmd_line.size(); ++i) _log << "" << cmd_line[i] << " "; 169 _log << std::endl; 170 } 171 if (opt.solver_time_limit_ms != 0) { 172 cmd_line.push_back("-t"); 173 std::ostringstream oss; 174 oss << opt.solver_time_limit_ms; 175 cmd_line.push_back(oss.str()); 176 } 177 int timelimit = opt.mzn_time_limit_ms; 178 bool sigint = opt.mzn_sigint; 179 Solns2Log s2l(getSolns2Out()->getOutput(), _log); 180 Process<Solns2Log> proc(cmd_line, &s2l, timelimit, sigint); 181 int exitCode = proc.run(); 182 183 return exitCode == 0 ? SolverInstance::UNKNOWN : SolverInstance::ERROR; 184} 185 186void MZNSolverInstance::processFlatZinc(void) {} 187 188void MZNSolverInstance::resetSolver(void) {} 189 190} // namespace MiniZinc