this repo has no description
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