this repo has no description
at develop 6.6 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#include <minizinc/eval_par.hh> 13#include <minizinc/solver_instance_base.hh> 14 15#ifdef _MSC_VER 16#define _CRT_SECURE_NO_WARNINGS 17#undef ERROR // MICROsoft. 18#undef min 19#undef max 20#endif 21 22namespace MiniZinc { 23 24SolverInstanceBase::Status SolverInstanceBase::solve(void) { return SolverInstance__ERROR; } 25 26void SolverInstanceBase::reset(void) { assert(false); } 27 28void SolverInstanceBase::resetWithConstraints(Model::iterator begin, Model::iterator end) { 29 assert(false); 30} 31 32void SolverInstanceBase::processPermanentConstraints(Model::iterator begin, Model::iterator end) { 33 assert(false); 34} 35 36void Registry::add(const std::string& name, poster p) { _registry.insert(std::make_pair(name, p)); } 37void Registry::post(std::string name, Constraint* c) { 38 std::unordered_map<std::string, poster>::iterator it = _registry.find(name); 39 if (it == _registry.end()) { 40 GCLock lock; 41 throw InternalError("Error: solver backend cannot handle constraint: " + name + "\n"); 42 } 43 it->second(_base, c); 44} 45 46void SolverInstanceBase::printSolution() { 47 std::ostringstream oss; 48 49 if (_options->printStatistics) printStatistics(1); // Insert stats before sol separator 50 if (0 == pS2Out) { 51 getEnv()->evalOutput(std::cout); // deprecated 52 std::cout << oss.str(); 53 if (oss.str().size() && '\n' != oss.str().back()) std::cout << '\n'; 54 std::cout << "----------" << std::endl; 55 } else 56 getSolns2Out()->evalOutput(oss.str()); 57} 58 59void SolverInstanceBase2::printSolution() { 60 GCLock lock; 61 assignSolutionToOutput(); 62 SolverInstanceBase::printSolution(); 63} 64 65// void 66// SolverInstanceBase::assignSolutionToOutput(void) { 67// for (VarDeclIterator it = getEnv()->output()->begin_vardecls(); it != 68// getEnv()->output()->end_vardecls(); ++it) { 69// if (it->e()->e() == NULL) { 70// it->e()->e(getSolutionValue(it->e()->id())); 71// } 72// } 73// } 74 75void SolverInstanceBase2::assignSolutionToOutput() { 76 GCLock lock; 77 78 MZN_ASSERT_HARD_MSG( 79 0 != pS2Out, "Setup a Solns2Out object to use default solution extraction/reporting procs"); 80 81 if (_varsWithOutput.empty()) { 82 for (VarDeclIterator it = getEnv()->flat()->begin_vardecls(); 83 it != getEnv()->flat()->end_vardecls(); ++it) { 84 if (!it->removed()) { 85 VarDecl* vd = it->e(); 86 if (!vd->ann().isEmpty()) { 87 if (vd->ann().containsCall(constants().ann.output_array.aststr()) || 88 vd->ann().contains(constants().ann.output_var)) { 89 _varsWithOutput.push_back(vd); 90 } 91 } 92 } 93 } 94 } 95 96 pS2Out->declNewOutput(); // Even for empty output decl 97 98 // iterate over set of ids that have an output annotation && obtain their right hand side from the 99 // flat model 100 for (unsigned int i = 0; i < _varsWithOutput.size(); i++) { 101 VarDecl* vd = _varsWithOutput[i]; 102 // std::cout << "DEBUG: Looking at var-decl with output-annotation: " << *vd << std::endl; 103 if (Call* output_array_ann = Expression::dyn_cast<Call>( 104 getAnnotation(vd->ann(), constants().ann.output_array.aststr()))) { 105 assert(vd->e()); 106 107 if (ArrayLit* al = vd->e()->dyn_cast<ArrayLit>()) { 108 std::vector<Expression*> array_elems; 109 ArrayLit& array = *al; 110 for (unsigned int j = 0; j < array.size(); j++) { 111 if (Id* id = array[j]->dyn_cast<Id>()) { 112 // std::cout << "DEBUG: getting solution value from " << *id << " : " << id->v() << 113 // std::endl; 114 array_elems.push_back(getSolutionValue(id)); 115 } else if (FloatLit* floatLit = array[j]->dyn_cast<FloatLit>()) { 116 array_elems.push_back(floatLit); 117 } else if (IntLit* intLit = array[j]->dyn_cast<IntLit>()) { 118 array_elems.push_back(intLit); 119 } else if (BoolLit* boolLit = array[j]->dyn_cast<BoolLit>()) { 120 array_elems.push_back(boolLit); 121 } else if (SetLit* setLit = array[j]->dyn_cast<SetLit>()) { 122 array_elems.push_back(setLit); 123 } else if (StringLit* strLit = array[j]->dyn_cast<StringLit>()) { 124 array_elems.push_back(strLit); 125 } else { 126 std::ostringstream oss; 127 oss << "Error: array element " << *array[j] << " is not an id nor a literal"; 128 throw InternalError(oss.str()); 129 } 130 } 131 GCLock lock; 132 ArrayLit* dims; 133 Expression* e = output_array_ann->arg(0); 134 if (ArrayLit* al = e->dyn_cast<ArrayLit>()) { 135 dims = al; 136 } else if (Id* id = e->dyn_cast<Id>()) { 137 dims = id->decl()->e()->cast<ArrayLit>(); 138 } else { 139 throw -1; 140 } 141 std::vector<std::pair<int, int> > dims_v; 142 for (int i = 0; i < dims->length(); i++) { 143 IntSetVal* isv = eval_intset(getEnv()->envi(), (*dims)[i]); 144 if (isv->size() == 0) { 145 dims_v.push_back(std::pair<int, int>(1, 0)); 146 } else { 147 dims_v.push_back(std::pair<int, int>(static_cast<int>(isv->min().toInt()), 148 static_cast<int>(isv->max().toInt()))); 149 } 150 } 151 ArrayLit* array_solution = new ArrayLit(Location(), array_elems, dims_v); 152 KeepAlive ka(array_solution); 153 auto& de = getSolns2Out()->findOutputVar(vd->id()->str().str()); 154 de.first->e(array_solution); 155 } 156 } else if (vd->ann().contains(constants().ann.output_var)) { 157 Expression* sol = getSolutionValue(vd->id()); 158 vd->e(sol); 159 auto& de = getSolns2Out()->findOutputVar(vd->id()->str().str()); 160 de.first->e(sol); 161 } 162 } 163} 164 165void SolverInstanceBase::flattenSearchAnnotations(const Annotation& ann, 166 std::vector<Expression*>& out) { 167 for (ExpressionSetIter i = ann.begin(); i != ann.end(); ++i) { 168 Expression* e = *i; 169 if (e->isa<Call>() && (e->cast<Call>()->id().str() == "seq_search" || 170 e->cast<Call>()->id().str() == "warm_start_array")) { 171 Call* c = e->cast<Call>(); 172 auto* anns = c->arg(0)->cast<ArrayLit>(); 173 for (unsigned int i = 0; i < anns->size(); i++) { 174 Annotation subann; 175 subann.add((*anns)[i]); 176 flattenSearchAnnotations(subann, out); 177 } 178 } else { 179 out.push_back(*i); 180 } 181 } 182} 183 184} // namespace MiniZinc