this repo has no description
at develop 22 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/builtins.hh> 21#include <minizinc/eval_par.hh> 22#include <minizinc/parser.hh> 23#include <minizinc/pathfileprinter.hh> 24#include <minizinc/prettyprinter.hh> 25#include <minizinc/process.hh> 26#include <minizinc/solvers/fzn_solverinstance.hh> 27#include <minizinc/timer.hh> 28#include <minizinc/typecheck.hh> 29 30#include <cstdio> 31#include <fstream> 32 33#ifdef _WIN32 34#undef ERROR 35#endif 36 37using namespace std; 38 39namespace MiniZinc { 40 41FZN_SolverFactory::FZN_SolverFactory(void) { 42 SolverConfig sc("org.minizinc.mzn-fzn", 43 MZN_VERSION_MAJOR "." MZN_VERSION_MINOR "." MZN_VERSION_PATCH); 44 sc.name("Generic FlatZinc driver"); 45 sc.mznlibVersion(1); 46 sc.description("MiniZinc generic FlatZinc solver plugin"); 47 sc.requiredFlags({"--fzn-cmd"}); 48 sc.stdFlags({"-a", "-n", "-f", "-p", "-s", "-r", "-v"}); 49 sc.tags({"__internal__"}); 50 SolverConfigs::registerBuiltinSolver(sc); 51} 52 53string FZN_SolverFactory::getDescription(SolverInstanceBase::Options*) { 54 string v = "FZN solver plugin, compiled " __DATE__ " " __TIME__; 55 return v; 56} 57 58string FZN_SolverFactory::getVersion(SolverInstanceBase::Options*) { return MZN_VERSION_MAJOR; } 59 60string FZN_SolverFactory::getId() { return "org.minizinc.mzn-fzn"; } 61 62void FZN_SolverFactory::printHelp(ostream& os) { 63 os << "MZN-FZN plugin options:" << std::endl 64 << " --fzn-cmd , --flatzinc-cmd <exe>\n the backend solver filename.\n" 65 << " -b, --backend, --solver-backend <be>\n the backend codename. Currently passed to " 66 "the solver.\n" 67 << " --fzn-flags <options>, --flatzinc-flags <options>\n Specify option to be passed to " 68 "the FlatZinc interpreter.\n" 69 << " --fzn-flag <option>, --flatzinc-flag <option>\n As above, but for a single option " 70 "string that need to be quoted in a shell.\n" 71 << " -n <n>, --num-solutions <n>\n An upper bound on the number of solutions to output. " 72 "The default should be 1.\n" 73 << " -t <ms>, --solver-time-limit <ms>, --fzn-time-limit <ms>\n Set time limit (in " 74 "milliseconds) for solving.\n" 75 << " --fzn-sigint\n Send SIGINT instead of SIGTERM.\n" 76 << " -a, --all, --all-solns, --all-solutions\n Print all solutions.\n" 77 << " -p <n>, --parallel <n>\n Use <n> threads during search. The default is " 78 "solver-dependent.\n" 79 << " -k, --keep-files\n For compatibility only: to produce .ozn and .fzn, use mzn2fzn\n" 80 " or <this_exe> --fzn ..., --ozn ...\n" 81 << " -r <n>, --seed <n>, --random-seed <n>\n For compatibility only: use solver flags " 82 "instead.\n"; 83} 84 85SolverInstanceBase::Options* FZN_SolverFactory::createOptions(void) { return new FZNSolverOptions; } 86 87SolverInstanceBase* FZN_SolverFactory::doCreateSI(std::ostream& log, 88 SolverInstanceBase::Options* opt) { 89 return new FZNSolverInstance(log, opt); 90} 91 92bool FZN_SolverFactory::processOption(SolverInstanceBase::Options* opt, int& i, 93 std::vector<std::string>& argv) { 94 FZNSolverOptions& _opt = static_cast<FZNSolverOptions&>(*opt); 95 CLOParser cop(i, argv); 96 string buffer; 97 int nn = -1; 98 99 if (cop.getOption("--fzn-cmd --flatzinc-cmd", &buffer)) { 100 _opt.fzn_solver = buffer; 101 } else if (cop.getOption("-b --backend --solver-backend", &buffer)) { 102 _opt.backend = buffer; 103 } else if (cop.getOption("--fzn-flags --flatzinc-flags", &buffer)) { 104 std::vector<std::string> cmdLine = FileUtils::parseCmdLine(buffer); 105 for (auto& s : cmdLine) { 106 _opt.fzn_flags.push_back(s); 107 } 108 } else if (cop.getOption("-t --solver-time-limit --fzn-time-limit", &nn)) { 109 _opt.fzn_time_limit_ms = nn; 110 if (_opt.supports_t) { 111 _opt.solver_time_limit_ms = nn; 112 _opt.fzn_time_limit_ms += 1000; // kill 1 second after solver should have stopped 113 } 114 } else if (cop.getOption("--fzn-sigint")) { 115 _opt.fzn_sigint = true; 116 } else if (cop.getOption("--fzn-needs-paths")) { 117 _opt.fzn_needs_paths = true; 118 } else if (cop.getOption("--fzn-output-passthrough")) { 119 _opt.fzn_output_passthrough = true; 120 } else if (cop.getOption("--fzn-flag --flatzinc-flag", &buffer)) { 121 _opt.fzn_flags.push_back(buffer); 122 } else if (_opt.supports_n && cop.getOption("-n --num-solutions", &nn)) { 123 _opt.numSols = nn; 124 } else if (_opt.supports_a && cop.getOption("-a --all --all-solns --all-solutions")) { 125 _opt.allSols = true; 126 } else if (cop.getOption("-p --parallel", &nn)) { 127 if (_opt.supports_p) _opt.parallel = to_string(nn); 128 } else if (cop.getOption("-k --keep-files")) { 129 } else if (cop.getOption("-r --seed --random-seed", &buffer)) { 130 if (_opt.supports_r) { 131 _opt.fzn_flags.push_back("-r"); 132 _opt.fzn_flags.push_back(buffer); 133 } 134 } else if (cop.getOption("-s --solver-statistics")) { 135 if (_opt.supports_s) { 136 _opt.printStatistics = true; 137 } 138 } else if (cop.getOption("-v --verbose-solving")) { 139 _opt.verbose = true; 140 } else if (cop.getOption("-f --free-search")) { 141 if (_opt.supports_f) _opt.fzn_flags.push_back("-f"); 142 } else { 143 for (auto& fznf : _opt.fzn_solver_flags) { 144 if (fznf.t == MZNFZNSolverFlag::FT_ARG && cop.getOption(fznf.n.c_str(), &buffer)) { 145 _opt.fzn_flags.push_back(fznf.n); 146 _opt.fzn_flags.push_back(buffer); 147 return true; 148 } else if (fznf.t == MZNFZNSolverFlag::FT_NOARG && cop.getOption(fznf.n.c_str())) { 149 _opt.fzn_flags.push_back(fznf.n); 150 return true; 151 } 152 } 153 154 return false; 155 } 156 return true; 157} 158 159void FZN_SolverFactory::setAcceptedFlags(SolverInstanceBase::Options* opt, 160 const std::vector<MZNFZNSolverFlag>& flags) { 161 FZNSolverOptions& _opt = static_cast<FZNSolverOptions&>(*opt); 162 _opt.fzn_solver_flags.clear(); 163 for (auto& f : flags) { 164 if (f.n == "-a") { 165 _opt.supports_a = true; 166 } else if (f.n == "-n") { 167 _opt.supports_n = true; 168 } else if (f.n == "-f") { 169 _opt.supports_f = true; 170 } else if (f.n == "-p") { 171 _opt.supports_p = true; 172 } else if (f.n == "-s") { 173 _opt.supports_s = true; 174 } else if (f.n == "-r") { 175 _opt.supports_r = true; 176 } else if (f.n == "-v") { 177 _opt.supports_v = true; 178 } else if (f.n == "-t") { 179 _opt.supports_t = true; 180 } else { 181 _opt.fzn_solver_flags.push_back(f); 182 } 183 } 184} 185 186FZNSolverInstance::FZNSolverInstance(std::ostream& log, SolverInstanceBase::Options* options) 187 : SolverInstanceBase(log, options), _model(new Model()), env(_model) {} 188 189FZNSolverInstance::~FZNSolverInstance(void) {} 190 191void FZNSolverInstance::addFunction(FunctionI* fi) { 192 _model->addItem(fi); 193 _model->registerFn(env.envi(), fi); 194} 195 196VarDecl* FZNSolverInstance::add_var_to_model(int ident, TypeInst* ti, bool view, bool isOutput) { 197 VarDecl* vd; 198 if (!view) { 199 vd = new VarDecl(Location().introduce(), ti, ident); 200 201 if (isOutput) { 202 vd->addAnnotation(constants().ann.output_var); 203 bool is_bool = ti->type().isbool(); 204 auto output_ti = 205 new TypeInst(Location().introduce(), is_bool ? Type::parbool() : Type::parint(), nullptr); 206 auto output_vd = new VarDecl(Location().introduce(), output_ti, ident); 207 env.output()->addItem(new VarDeclI(Location().introduce(), output_vd)); 208 } 209 } else { 210 vd = new VarDecl(Location().introduce(), ti, "view_" + std::to_string(ident)); 211 } 212 auto vdi = new VarDeclI(Location().introduce(), vd); 213 _model->addItem(vdi); 214 return vd; 215} 216 217Expression* FZNSolverInstance::val_to_expr(Type ty, Val v) { 218 v = Val::follow_alias(v); 219 if (v.isInt()) { 220 if (ty.isbool()) { 221 return v == 0 ? constants().lit_false : constants().lit_true; 222 } 223 return IntLit::a(v.toIntVal()); 224 } else if (v.isVar()) { 225 auto it = vdmap.find(v.timestamp()); 226 assert(it != vdmap.end()); 227 VarStore& vs = it->second; 228 if (ty.isbool()) { 229 if (vs.used_bool) { 230 return vs.bool_var()->cast<VarDecl>()->id(); 231 } 232 vs.used_bool = true; 233 234 auto ti = new TypeInst(Location().introduce(), Type::varbool()); 235 VarDecl* vd = add_var_to_model(v.timestamp(), ti, vs.used_int); 236 vs.bool_var = KeepAlive(vd); 237 238 if (vs.used_int) { 239 _model->addItem(new ConstraintI( 240 Location().introduce(), 241 new Call(Location().introduce(), constants().ids.bool2int, 242 {vs.bool_var()->cast<VarDecl>()->id(), vs.int_var()->cast<VarDecl>()->id()}))); 243 } else { 244 uninitialised_vars.erase(v.timestamp()); 245 } 246 return vs.bool_var()->cast<VarDecl>()->id(); 247 } 248 if (vs.used_int) { 249 return vs.int_var()->cast<VarDecl>()->id(); 250 } 251 vs.used_int = true; 252 253 SetLit* dom_set = new SetLit(Location().introduce(), IntSetVal::a(0, 1)); 254 auto ti = new TypeInst(Location().introduce(), Type::varint(), dom_set); 255 VarDecl* vd = add_var_to_model(v.timestamp(), ti, vs.used_bool); 256 vs.int_var = KeepAlive(vd); 257 258 if (vs.used_bool) { 259 _model->addItem(new ConstraintI( 260 Location().introduce(), 261 new Call(Location().introduce(), constants().ids.bool2int, 262 {vs.bool_var()->cast<VarDecl>()->id(), vs.int_var()->cast<VarDecl>()->id()}))); 263 } else { 264 uninitialised_vars.erase(v.timestamp()); 265 } 266 267 return vs.int_var()->cast<VarDecl>()->id(); 268 } else { 269 assert(v.isVec()); 270 if (ty.is_set()) { 271 std::vector<IntSetVal::Range> ranges; 272 Vec* vec = v.toVec(); 273 for (int i = 0; i < vec->size(); i += 2) { 274 ranges.push_back(IntSetVal::Range((*vec)[i].toIntVal(), (*vec)[i + 1].toIntVal())); 275 } 276 auto sl = new SetLit(Location().introduce(), IntSetVal::a(ranges)); 277 return sl; 278 } else { 279 // this is an array 280 Val vec = v.toVec()->raw_data(); 281 std::vector<Expression*> evec(vec.size()); 282 bool par = true; 283 for (int i = 0; i < vec.size(); ++i) { 284 assert(!vec[i].isVec()); 285 Type nty = ty; 286 nty.dim(0); 287 evec[i] = val_to_expr(nty, vec[i]); 288 par = par && evec[i]->type().ispar(); 289 } 290 auto al = new ArrayLit(Location().introduce(), evec); 291 al->type(par ? Type::parint(1) : Type::varint(1)); 292 return al; 293 } 294 } 295} 296 297void FZNSolverInstance::addConstraint(const std::vector<BytecodeProc>& bs, Constraint* c) { 298 GCLock lock; 299 const BytecodeProc& proc = bs[c->pred()]; 300 const std::string& name = proc.name; 301 if (name == "solve_this") { 302 IntVal solve_mode = c->arg(0).toIntVal(); 303 Val obj = c->arg(1); 304 SolveI* si; 305 if (solve_mode == 0) { 306 si = SolveI::sat(Location().introduce()); 307 } else if (solve_mode == 1) { 308 si = SolveI::min(Location().introduce(), val_to_expr(Type::varint(), obj)); 309 } else { 310 assert(solve_mode == 2); 311 si = SolveI::max(Location().introduce(), val_to_expr(Type::varint(), obj)); 312 } 313 if (c->size() == 5) { 314 Val search_a = c->arg(2); 315 IntVal var_sel = c->arg(3).toIntVal(); 316 IntVal val_sel = c->arg(4).toIntVal(); 317 if (search_a.isVec() && search_a.size() > 0 && var_sel > 0 && val_sel > 0) { 318 Expression* search_vars = val_to_expr(Type::varint(1), search_a); 319 ASTString var_sel_s(var_sel == 1 ? "input_order" : "first_fail"); 320 ASTString val_sel_s(val_sel == 1 ? "indomain_min" : "indomain_max"); 321 Id* var_sel_id = new Id(Location().introduce(), var_sel_s, nullptr); 322 Id* val_sel_id = new Id(Location().introduce(), val_sel_s, nullptr); 323 Id* complete_id = new Id(Location().introduce(), "complete", nullptr); 324 si->ann().add(new Call(Location().introduce(), ASTString("int_search"), 325 {search_vars, var_sel_id, val_sel_id, complete_id})); 326 } 327 } 328 _model->addItem(si); 329 return; 330 } 331 auto fnit = _model->fnmap.find(ASTString(name)); 332 assert(fnit != _model->fnmap.end()); 333 assert(fnit->second.size() == 1); 334 std::vector<Type>& tys = fnit->second[0].t; 335 assert(tys.size() == c->size()); 336 std::vector<Expression*> args(proc.nargs); 337 for (int i = 0; i < proc.nargs; ++i) { 338 args[i] = val_to_expr(tys[i], c->arg(i)); 339 } 340 auto call = new Call(Location().introduce(), name, args); 341 auto ci = new ConstraintI(Location().introduce(), call); 342 _model->addItem(ci); 343}; 344 345void FZNSolverInstance::addVariable(Variable* var, bool isOutput) { 346 GCLock lock; 347 Vec* dom = var->domain(); 348 assert(dom->size() >= 2 && dom->size() % 2 == 0); 349 350 if (!isOutput && dom->size() == 2 && (*dom)[0] == 0 && (*dom)[1] == 1) { 351 vdmap.emplace(std::piecewise_construct, std::forward_as_tuple(var->timestamp()), 352 std::forward_as_tuple(nullptr, nullptr, false, false)); 353 uninitialised_vars.insert(var->timestamp()); 354 return; 355 } 356 357 std::vector<IntSetVal::Range> ranges; 358 for (int i = 0; i < dom->size(); i += 2) { 359 ranges.emplace_back((*dom)[i].toIntVal(), (*dom)[i + 1].toIntVal()); 360 } 361 SetLit* dom_set = new SetLit(Location().introduce(), IntSetVal::a(ranges)); 362 auto ti = new TypeInst(Location().introduce(), Type::varint(), dom_set); 363 VarDecl* vd = add_var_to_model(var->timestamp(), ti, false, isOutput); 364 vdmap.emplace(std::piecewise_construct, std::forward_as_tuple(var->timestamp()), 365 std::forward_as_tuple(vd, nullptr, true, false)); 366} 367 368Val FZNSolverInstance::getSolutionValue(Variable* var) { 369 GCLock lock; 370 Id ident(Location().introduce(), var->timestamp(), nullptr); 371 auto de = getSolns2Out()->findOutputVar(ident.str()); 372 assert(de.first->e()); // A solution must have been assigned 373 return Val::fromIntVal(eval_int(env.envi(), de.first->e())); 374}; 375 376void FZNSolverInstance::pushState() { stack.emplace_back(_model->size()); } 377 378void FZNSolverInstance::popState() { 379 for (auto i = stack.back(); i < _model->size(); ++i) { 380 Item* it = (*_model)[i]; 381 if (!it->isa<FunctionI>()) { 382 it->remove(); 383 } 384 } 385 _model->compact(); 386 stack.pop_back(); 387} 388 389void FZNSolverInstance::printStatistics(bool fLegend) { 390 FlatModelStatistics stats = statistics(_model); 391 auto& out = getSolns2Out()->getOutput(); 392 393 if (stats.n_bool_vars) { 394 out << "%%%mzn-stat: flatBoolVars=" << stats.n_bool_vars << endl; 395 } 396 if (stats.n_int_vars) { 397 out << "%%%mzn-stat: flatIntVars=" << stats.n_int_vars << endl; 398 } 399 if (stats.n_float_vars) { 400 out << "%%%mzn-stat: flatFloatVars=" << stats.n_float_vars << endl; 401 } 402 if (stats.n_set_vars) { 403 out << "%%%mzn-stat: flatSetVars=" << stats.n_set_vars << endl; 404 } 405 406 if (stats.n_bool_ct) { 407 out << "%%%mzn-stat: flatBoolConstraints=" << stats.n_bool_ct << endl; 408 } 409 if (stats.n_int_ct) { 410 out << "%%%mzn-stat: flatIntConstraints=" << stats.n_int_ct << endl; 411 } 412 if (stats.n_float_ct) { 413 out << "%%%mzn-stat: flatFloatConstraints=" << stats.n_float_ct << endl; 414 } 415 if (stats.n_set_ct) { 416 out << "%%%mzn-stat: flatSetConstraints=" << stats.n_set_ct << endl; 417 } 418 419 if (stats.n_reif_ct) { 420 out << "%%%mzn-stat: evaluatedReifiedConstraints=" << stats.n_reif_ct << endl; 421 } 422 if (stats.n_imp_ct) { 423 out << "%%%mzn-stat: evaluatedHalfReifiedConstraints=" << stats.n_imp_ct << endl; 424 } 425 426 if (stats.n_imp_del) { 427 out << "%%%mzn-stat: eliminatedImplications=" << stats.n_imp_del << endl; 428 } 429 if (stats.n_lin_del) { 430 out << "%%%mzn-stat: eliminatedLinearConstraints=" << stats.n_lin_del << endl; 431 } 432 433 /// Objective / SAT. These messages are used by mzn-test.py. 434 SolveI* solveItem = _model->solveItem(); 435 if (solveItem && solveItem->st() != SolveI::SolveType::ST_SAT) { 436 if (solveItem->st() == SolveI::SolveType::ST_MAX) { 437 out << "%%%mzn-stat: method=\"maximize\"" << endl; 438 } else { 439 out << "%%%mzn-stat: method=\"minimize\"" << endl; 440 } 441 } else { 442 out << "%%%mzn-stat: method=\"satisfy\"" << endl; 443 } 444 out << "%%%mzn-stat-end" << endl << endl; 445} 446void FZNSolverInstance::printFlatZincToFile(std::string filename) { 447 std::ofstream os(filename); 448 Printer p(os, 0, true); 449 for (FunctionIterator it = _model->begin_functions(); it != _model->end_functions(); ++it) { 450 if (!it->removed()) { 451 Item& item = *it; 452 p.print(&item); 453 } 454 } 455 for (VarDeclIterator it = _model->begin_vardecls(); it != _model->end_vardecls(); ++it) { 456 if (!it->removed()) { 457 Item& item = *it; 458 p.print(&item); 459 } 460 } 461 for (ConstraintIterator it = _model->begin_constraints(); it != _model->end_constraints(); ++it) { 462 if (!it->removed()) { 463 Item& item = *it; 464 p.print(&item); 465 } 466 } 467 if (_model->solveItem()) { 468 p.print(_model->solveItem()); 469 } else { 470 GCLock lock; 471 auto si = SolveI::sat(Location().introduce()); 472 p.print(si); 473 } 474} 475void FZNSolverInstance::printOutputToFile(std::string filename) { 476 Model* output = env.output(); 477 std::ofstream os(filename); 478 Printer p(os, 0, true); 479 p.print(output); 480} 481void FZNSolverInstance::outputArray(Vec* arr) { 482 GCLock lock; 483 std::vector<Expression*> content; 484 for (int i = 0; i < arr->size(); ++i) { 485 Val real = Val::follow_alias((*arr)[i]); 486 content.push_back(val_to_expr(Type::parint(), real)); 487 } 488 auto* al = new ArrayLit(Location().introduce(), content); 489 std::vector<Expression*> sarg = {new Call(Location().introduce(), constants().ids.show, {al})}; 490 auto* sal = new ArrayLit(Location().introduce(), sarg); 491 env.output()->addItem(new OutputI(Location().introduce(), sal)); 492} 493void FZNSolverInstance::outputDict(Variable* start) { 494 GCLock lock; 495 std::vector<Expression*> content; 496 auto* open = new StringLit(Location().introduce(), "{"); 497 auto* close = new StringLit(Location().introduce(), "}"); 498 auto* comma = new StringLit(Location().introduce(), ","); 499 auto* quote = new StringLit(Location().introduce(), "\""); 500 auto* quote_colon = new StringLit(Location().introduce(), "\":"); 501 auto* var_start = new StringLit(Location().introduce(), "X_INTRODUCED_"); 502 503 content.push_back(open); 504 Variable* v = start->next(); // Skip root node 505 bool first = true; 506 while (v != start) { 507 if (!first) { 508 content.push_back(comma); 509 } 510 Val real = Val::follow_alias(Val(v)); 511 content.push_back(quote); 512 content.push_back(var_start); 513 content.push_back(new StringLit(Location().introduce(), std::to_string(v->timestamp()))); 514 content.push_back(quote_colon); 515 content.push_back(new Call(Location().introduce(), constants().ids.show, 516 {val_to_expr(Type::parint(), real)})); 517 v = v->next(); 518 first = false; 519 }; 520 content.push_back(close); 521 auto* al = new ArrayLit(Location().introduce(), content); 522 env.output()->addItem(new OutputI(Location().introduce(), al)); 523} 524 525SolverInstance::Status FZNSolverInstance::solve(void) { 526 { 527 // Add all remaining variables to the model 528 GCLock lock; 529 auto ti = new TypeInst(Location().introduce(), Type::varbool()); 530 for (int var : uninitialised_vars) { 531 add_var_to_model(var, ti); 532 } 533 } 534 535 FZNSolverOptions& opt = static_cast<FZNSolverOptions&>(*_options); 536 if (opt.fzn_solver.empty()) { 537 throw InternalError("No FlatZinc solver specified"); 538 } 539 /// Passing options to solver 540 vector<string> cmd_line; 541 cmd_line.push_back(opt.fzn_solver); 542 string sBE = opt.backend; 543 if (sBE.size()) { 544 cmd_line.push_back("-b"); 545 cmd_line.push_back(sBE); 546 } 547 for (auto& f : opt.fzn_flags) { 548 cmd_line.push_back(f); 549 } 550 if (opt.numSols != 1) { 551 cmd_line.push_back("-n"); 552 ostringstream oss; 553 oss << opt.numSols; 554 cmd_line.push_back(oss.str()); 555 } 556 if (opt.allSols) { 557 cmd_line.push_back("-a"); 558 } 559 if (opt.parallel.size()) { 560 cmd_line.push_back("-p"); 561 ostringstream oss; 562 oss << opt.parallel; 563 cmd_line.push_back(oss.str()); 564 } 565 if (opt.printStatistics) { 566 cmd_line.push_back("-s"); 567 } 568 if (opt.solver_time_limit_ms != 0) { 569 cmd_line.push_back("-t"); 570 std::ostringstream oss; 571 oss << opt.solver_time_limit_ms; 572 cmd_line.push_back(oss.str()); 573 } 574 if (opt.verbose) { 575 if (opt.supports_v) cmd_line.push_back("-v"); 576 std::cerr << "Using FZN solver " << cmd_line[0] << " for solving, parameters: "; 577 for (int i = 1; i < cmd_line.size(); ++i) cerr << "" << cmd_line[i] << " "; 578 cerr << std::endl; 579 } 580 int timelimit = opt.fzn_time_limit_ms; 581 bool sigint = opt.fzn_sigint; 582 583 FileUtils::TmpFile fznFile(".fzn"); 584 printFlatZincToFile(fznFile.name()); 585 cmd_line.push_back(fznFile.name()); 586 587 FileUtils::TmpFile* pathsFile = NULL; 588 // if(opt.fzn_needs_paths) { 589 // pathsFile = new FileUtils::TmpFile(".paths"); 590 // std::ofstream ofs(pathsFile->name()); 591 // PathFilePrinter pfp(ofs, _env.envi()); 592 // pfp.print(_fzn); 593 594 // cmd_line.push_back("--paths"); 595 // cmd_line.push_back(pathsFile->name()); 596 // } 597 getSolns2Out()->initFromEnv(&env); 598 599 if (!opt.fzn_output_passthrough) { 600 Process<Solns2Out> proc(cmd_line, getSolns2Out(), timelimit, sigint); 601 int exitStatus = proc.run(); 602 delete pathsFile; 603 return exitStatus == 0 ? getSolns2Out()->status : SolverInstance::ERROR; 604 } else { 605 Solns2Log s2l(getSolns2Out()->getOutput(), _log); 606 Process<Solns2Log> proc(cmd_line, &s2l, timelimit, sigint); 607 int exitStatus = proc.run(); 608 delete pathsFile; 609 return exitStatus == 0 ? SolverInstance::NONE : SolverInstance::ERROR; 610 } 611} 612 613void FZNSolverInstance::processFlatZinc(void) {} 614 615void FZNSolverInstance::resetSolver(void) {} 616 617Expression* FZNSolverInstance::getSolutionValue(Id* id) { 618 assert(false); 619 return NULL; 620} 621} // namespace MiniZinc