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