this repo has no description
1#include "Model.h" 2 3using namespace MiniZinc; 4using namespace std; 5 6int MznModel::addData(const char* const name, PyObject* value) { 7 GCLock Lock; 8 if (value == NULL) { 9 PyErr_SetString(PyExc_TypeError, "MiniZinc: Model.addData: Received a NULL value"); 10 return -1; 11 } 12 for (unsigned int i = 0; i < _m->size(); i++) 13 if (VarDeclI* vdi = (*_m)[i]->dyn_cast<VarDeclI>()) { 14 if (strcmp(vdi->e()->id()->str().c_str(), name) == 0) { 15 vector<pair<int, int> > dimList; 16 Type type; 17 Expression* rhs = 18 python_to_minizinc(value, vdi->e()->ti()->ranges()); //, vdi->e()->type(), name); 19 if (rhs == NULL) return -1; 20 vdi->e()->e(rhs); 21 return 0; 22 } 23 } 24 MZN_PYERR_SET_STRING(PyExc_TypeError, "MiniZinc: Model.addData: Undefined name '%s'", name); 25 return -1; 26} 27 28int MznModel::load(PyObject* args, PyObject* keywds, bool fromFile) { 29 GCLock Lock; 30 Model* saveModel = _m; 31 stringstream errorStream; 32 vector<string> data; 33 34 PyObject* obj = Py_None; 35 char* options = NULL; 36 const char* py_string; 37 char* errorFile = "./error.txt"; 38 39 bool isDict = false; 40 41 if (fromFile) { 42 char* kwlist[] = {"file", "data", "options"}; 43 if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|Os", kwlist, &py_string, &obj, &options)) { 44 PyErr_SetString(PyExc_TypeError, "MiniZinc: load: Parsing error"); 45 return -1; 46 } 47 if (options != NULL) { 48 char* pch; 49 bool t_flag = false; 50 pch = strtok(options, " "); 51 while (pch != NULL) { 52 if (strcmp(pch, "-t") == 0) 53 t_flag = true; 54 else { 55 if (t_flag) { 56 char* ptr; 57 int t = strtol(pch, &ptr, 10); 58 if (t == 0) { 59 PyErr_SetString(PyExc_ValueError, 60 "MiniZinc: Model.load: Time value must be a valid positive number"); 61 return -1; 62 } 63 timeLimit = t; 64 t_flag = false; 65 } else { 66 PyErr_SetString(PyExc_ValueError, "MiniZinc: Model.load: Unknown option"); 67 return -1; 68 } 69 } 70 pch = strtok(NULL, " "); 71 } 72 } 73 if (obj != Py_None) { 74 if (PyUnicode_Check(obj)) { 75 data.push_back(string(PyUnicode_AsUTF8(obj))); 76 } else if (PyList_Check(obj)) { 77 Py_ssize_t n = PyList_GET_SIZE(obj); 78 for (Py_ssize_t i = 0; i != n; ++i) { 79 const char* name = PyUnicode_AsUTF8(PyList_GET_ITEM(obj, i)); 80 if (name == NULL) { 81 PyErr_SetString(PyExc_TypeError, 82 "MiniZinc: Model.load: Element in the list must be a filename"); 83 return -1; 84 } 85 data.push_back(string(name)); 86 } 87 } else if (PyDict_Check(obj)) { 88 isDict = true; 89 } else { 90 PyErr_SetString(PyExc_TypeError, 91 "MiniZinc: Model.load: The second argument must be either a filename, a " 92 "list of filenames or a dictionary of data"); 93 return -1; 94 } 95 } 96 vector<string> models{py_string}; 97 _m = parse(models, data, *includePaths, false, false, false, errorStream); 98 _e = new Env(_m); 99 } else { 100 char* kwlist[] = {"string", "error", "options"}; 101 if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|ss", kwlist, &py_string, &errorFile, 102 &options)) { 103 PyErr_SetString(PyExc_TypeError, "MiniZinc: Model.load: Keyword parsing error"); 104 return -1; 105 } 106 _m = parseFromString(string(py_string), errorFile, *includePaths, false, false, false, 107 errorStream); 108 _e = new Env(_m); 109 } 110 if (_m) { 111 delete saveModel; 112 if (isDict) { 113 stringstream assignments; 114 Py_ssize_t pos = 0; 115 PyObject* key; 116 PyObject* value; 117 GCLock lock; 118 while (PyDict_Next(obj, &pos, &key, &value)) { 119 const char* name = PyUnicode_AsUTF8(key); 120 if (addData(name, value) == -1) { 121 // addData handles the error message 122 return -1; 123 } 124 } 125 } 126 loaded = true; 127 return 0; 128 } else { 129 const std::string tmp = "MiniZinc: Model.load: " + errorStream.str(); 130 PyErr_SetString(PyExc_RuntimeError, tmp.c_str()); 131 return -1; 132 } 133} 134 135PyObject* MznModel::solve(PyObject* args, PyObject* kwds) { 136 if (!loaded) { 137 PyErr_SetString(PyExc_RuntimeError, 138 "MiniZinc: Model.solve: No data has been loaded into the model"); 139 return NULL; 140 } 141 142 PyObject* dict = NULL; 143 144 static char* kwlist[] = {"dict", "solver", "time", NULL}; 145 146 char* solverName = ""; 147 unsigned long newTimeLimit = 0; 148 149 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Osk", kwlist, &dict, &solverName, &newTimeLimit)) { 150 PyErr_SetString(PyExc_RuntimeError, "MiniZinc: Model.solve: Parsing error"); 151 return NULL; 152 } 153 154 Model* saveModel; 155 { 156 GCLock lock; 157 saveModel = copy(_e->envi(), _m); 158 Py_ssize_t pos = 0; 159 PyObject* key; 160 PyObject* value; 161 if (dict) { 162 while (PyDict_Next(dict, &pos, &key, &value)) { 163 const char* name = PyUnicode_AsUTF8(key); 164 if (addData(name, value) == -1) { 165 // addData handled the error message 166 goto SOLVE__ERROR_HANDLING; 167 } 168 } 169 } 170 if (newTimeLimit > 0) { 171 timeLimit = newTimeLimit; 172 } 173 if (strlen(solverName)) { 174 if (set_solver(solverName) == NULL) { 175 // setSolver handled the error message 176 goto SOLVE__ERROR_HANDLING; 177 } 178 } 179 goto SOLVE__NO_ERROR; 180 SOLVE__ERROR_HANDLING: 181 delete _m; 182 _m = saveModel; 183 _e = new Env(_m); 184 return NULL; 185 } 186 187SOLVE__NO_ERROR: 188 vector<TypeError> typeErrors; 189 try { 190 MiniZinc::typecheck(*_e, _m, typeErrors, false); 191 } catch (LocationException& e) { 192 MZN_PYERR_SET_STRING(PyExc_RuntimeError, "MiniZinc: Model.solve: %s: %s", e.what(), 193 e.msg().c_str()); 194 return NULL; 195 } 196 if (typeErrors.size() > 0) { 197 stringstream errorLog; 198 for (unsigned int i = 0; i < typeErrors.size(); i++) { 199 errorLog << typeErrors[i].loc() << ":" << endl; 200 errorLog << typeErrors[i].what() << ": " << typeErrors[i].msg() << "\n"; 201 } 202 const std::string& tmp = errorLog.str(); 203 const char* cstr = tmp.c_str(); 204 PyErr_SetString(PyExc_TypeError, cstr); 205 return NULL; 206 } 207 MiniZinc::registerBuiltins(*_e, _m); 208 209 Env* env = _e; 210 try { 211 FlatteningOptions fopts; 212 flatten(*env, fopts); 213 } catch (LocationException& e) { 214 stringstream errorLog; 215 errorLog << e.what() << ": " << std::endl; 216 env->dumpErrorStack(errorLog); 217 errorLog << " " << e.msg() << std::endl; 218 const std::string& tmp = errorLog.str(); 219 const char* cstr = tmp.c_str(); 220 PyErr_SetString(PyExc_RuntimeError, cstr); 221 return NULL; 222 } 223 if (env->warnings().size() != 0) { 224 stringstream warningLog; 225 warningLog << "MiniZinc: Model.solve: Warning:\n"; 226 for (unsigned int i = 0; i < env->warnings().size(); i++) { 227 warningLog << env->warnings()[i]; 228 } 229 const std::string& tmp = warningLog.str(); 230 const char* cstr = tmp.c_str(); 231 PyErr_WarnEx(PyExc_RuntimeWarning, cstr, 1); 232 } 233 optimize(*env); 234 oldflatzinc(*env); 235 GCLock lock; 236 Options options; 237 if (timeLimit != 0) options.setIntParam("time", timeLimit); 238 delete _m; 239 _m = saveModel; 240 _e = new Env(_m); 241 PyMznSolver* ret = reinterpret_cast<PyMznSolver*>(PyMznSolver_new(&PyMznSolver_Type, NULL, NULL)); 242 switch (sc) { 243 case SC_UNKNOWN: 244 delete env; 245 PyErr_SetString(PyExc_ValueError, "MiniZinc: Model.solve: Solver name is not set"); 246 return NULL; 247 248 case SC_GECODE: 249 ret->solver = new GecodeSolverInstance(*env, options); 250 break; 251 } 252 ret->solver->processFlatZinc(); 253 ret->env = env; 254 return reinterpret_cast<PyObject*>(ret); 255} 256 257/* 258 * Description: Creates a minizinc constraint 259 * Note: Need an outer GCLock for this to work 260 */ 261static PyObject* MznModel_Constraint(MznModel* self, PyObject* args) { 262 PyObject* obj; 263 if (!PyArg_ParseTuple(args, "O", &obj)) { 264 PyErr_SetString(PyExc_TypeError, 265 "MiniZinc: Model.Constraint: Requires an object of Minizinc Variable"); 266 return NULL; 267 } 268 269 GCLock Lock; 270 ConstraintI* i; 271 if (PyObject_ExactTypeCheck(obj, &MznExpression_Type)) { 272 i = new ConstraintI(Location(), (reinterpret_cast<MznExpression*>(obj)->e)); 273 } else if (PyBool_Check(obj)) { 274 bool val = PyObject_IsTrue(obj); 275 i = new ConstraintI(Location(), new BoolLit(Location(), val)); 276 } else { 277 PyErr_SetString( 278 PyExc_TypeError, 279 "MiniZinc: Model.Constraint: Object must be a MiniZinc Variable or Python Boolean value"); 280 return NULL; 281 } 282 self->_m->addItem(i); 283 Py_RETURN_NONE; 284} 285 286/* 287 * Description: Defines the type of solution of the model 288 */ 289// The responsibility to check if the parsed argument is annotation or not is of the Python 290// interface, not the C++ interface 291static PyObject* MznModel_SolveItem(MznModel* self, PyObject* args) { 292 unsigned int solveType; 293 PyObject* PyExp = NULL; 294 PyObject* PyAnn = NULL; 295 Expression* e = NULL; 296 Expression* ann = NULL; 297 298 if (!PyArg_ParseTuple(args, "I|OO", &solveType, &PyAnn, &PyExp)) { 299 PyErr_SetString(PyExc_TypeError, 300 "MiniZinc: Model.SolveItem: Requires a solver code, an annotation (can be " 301 "NULL) and an optional expression (for optimisation)"); 302 return NULL; 303 } 304 305 if (solveType > 2) { 306 PyErr_SetString( 307 PyExc_ValueError, 308 "MiniZinc: Model.SolveItem: Invalid solver code (Must be a positive less than 3 integer)"); 309 return NULL; 310 } 311 if (solveType) { 312 if (PyExp == NULL) { 313 PyErr_SetString( 314 PyExc_TypeError, 315 "MiniZinc: Model.SolveItem: Optimisation solver requires an addition constraint object"); 316 return NULL; 317 } else if (PyObject_ExactTypeCheck(PyExp, &MznExpression_Type)) { 318 e = reinterpret_cast<MznExpression*>(PyExp)->e; 319 } else { 320 PyErr_SetString(PyExc_TypeError, 321 "MiniZinc: Model.SolveItem: Expression must be a Minizinc Variable Object"); 322 return NULL; 323 } 324 } 325 326 GCLock Lock; 327 SolveI* i; 328 switch (solveType) { 329 case 0: 330 i = SolveI::sat(Location()); 331 break; 332 case 1: 333 i = SolveI::min(Location(), (e)); 334 break; 335 case 2: 336 i = SolveI::max(Location(), (e)); 337 break; 338 } 339 if (PyObject_IsTrue(PyAnn)) { 340 if (PyObject_TypeCheck(PyAnn, &MznExpression_Type)) { 341 ann = reinterpret_cast<MznExpression*>(PyAnn)->e; 342 i->ann().add(ann); 343 } else if (PyList_Check(PyAnn)) { 344 long n = PyList_GET_SIZE(PyAnn); 345 for (long idx = 0; idx != n; ++idx) { 346 PyObject* PyItem = PyList_GET_ITEM(PyAnn, idx); 347 if (!PyObject_TypeCheck(PyItem, &MznExpression_Type)) { 348 // XXX: CONSIDER REVIEW - should I delete i or it will be automatically deleted 349 delete i; 350 MZN_PYERR_SET_STRING( 351 PyExc_TypeError, 352 "MiniZinc: Model.SolveItem: Item at position %ld must be a MiniZinc Variable", idx); 353 return NULL; 354 } 355 ann = reinterpret_cast<MznExpression*>(PyItem)->e; 356 i->ann().add(ann); 357 } 358 } else if (PyTuple_Check(PyAnn)) { 359 long n = PyTuple_GET_SIZE(PyAnn); 360 for (long idx = 0; idx != n; ++idx) { 361 PyObject* PyItem = PyTuple_GET_ITEM(PyAnn, idx); 362 if (!PyObject_TypeCheck(PyItem, &MznExpression_Type)) { 363 // XXX: CONSIDER REVIEW 364 delete i; 365 MZN_PYERR_SET_STRING( 366 PyExc_TypeError, 367 "MiniZinc: Model.SolveItem: Item at position %ld must be a MiniZinc Variable", idx); 368 return NULL; 369 } 370 ann = reinterpret_cast<MznExpression*>(PyItem)->e; 371 i->ann().add(ann); 372 } 373 } else { 374 // XXX: CONSIDER REVIEW 375 delete i; 376 PyErr_SetString(PyExc_TypeError, 377 "MiniZinc: Model.SolveItem: Annotation must be a single value of or a " 378 "list/tuple of MiniZinc Variable Object"); 379 return NULL; 380 } 381 } 382 self->_m->addItem(i); 383 Py_RETURN_NONE; 384} 385 386static PyObject* MznModel_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { 387 MznModel* self = reinterpret_cast<MznModel*>(type->tp_alloc(type, 0)); 388 if (self == NULL) { 389 PyErr_SetString(PyExc_RuntimeError, "MiniZinc: Unable to create new model"); 390 return NULL; 391 } 392 self->includePaths = NULL; 393 self->_m = NULL; 394 self->_e = NULL; 395 return reinterpret_cast<PyObject*>(self); 396} 397 398static int MznModel_init(MznModel* self, PyObject* args = NULL) { 399 self->loaded = false; 400 string std_lib_dir; 401 if (char* MZNSTDLIBDIR = getenv("MZN_STDLIB_DIR")) { 402 std_lib_dir = string(MZNSTDLIBDIR); 403 } else { 404 PyErr_SetString(PyExc_EnvironmentError, 405 "MiniZinc: Model.init: No MiniZinc library directory MZN_STDLIB_DIR defined."); 406 return -1; 407 } 408 stringstream libNames; 409 libNames << "include \"globals.mzn\";"; 410 if (args != NULL) { 411 PyObject* PyLibNames = NULL; 412 if (PyUnicode_Check(args)) { 413 libNames << "\ninclude \"" << PyUnicode_AsUTF8(args) << "\";"; 414 } else if (PyTuple_Check(args)) { 415 Py_ssize_t n = PyTuple_GET_SIZE(args); 416 if (n > 1) { 417 PyErr_SetString(PyExc_TypeError, "MiniZinc: Model.init: Accept at most 1 argument"); 418 return -1; 419 } else if (n == 1) { 420 PyLibNames = PyTuple_GET_ITEM(args, 0); 421 if (PyObject_IsTrue(PyLibNames)) { 422 if (PyUnicode_Check(PyLibNames)) { 423 libNames << "\ninclude \"" << PyUnicode_AsUTF8(PyLibNames) << "\";"; 424 } else if (PyList_Check(PyLibNames)) { 425 Py_ssize_t n = PyList_GET_SIZE(PyLibNames); 426 for (Py_ssize_t i = 0; i != n; ++i) { 427 PyObject* temp = PyList_GET_ITEM(PyLibNames, i); 428 if (!PyUnicode_Check(temp)) { 429 PyErr_SetString(PyExc_TypeError, 430 "MiniZinc: Model.init: Items in parsing list must be strings"); 431 return -1; 432 } 433 libNames << "\ninclude \"" << PyUnicode_AsUTF8(temp) << "\";"; 434 } 435 } else if (PyTuple_Check(PyLibNames)) { 436 Py_ssize_t n = PyTuple_GET_SIZE(PyLibNames); 437 for (Py_ssize_t i = 0; i != n; ++i) { 438 PyObject* temp = PyTuple_GET_ITEM(PyLibNames, i); 439 if (!PyUnicode_Check(temp)) { 440 PyErr_SetString(PyExc_TypeError, 441 "MiniZinc: Model.init: Items in parsing tuples must be strings"); 442 return -1; 443 } 444 libNames << "\ninclude \"" << PyUnicode_AsUTF8(temp) << "\";"; 445 } 446 } else { 447 PyErr_SetString(PyExc_TypeError, 448 "MiniZinc: Model.init: Parsing argument must be a string or " 449 "list/tuple of strings"); 450 return -1; 451 } 452 } 453 } 454 } 455 } 456 const std::string& libNamesStr = libNames.str(); 457 self->timeLimit = 0; 458 self->includePaths = new vector<string>; 459 self->includePaths->push_back(std_lib_dir + "/gecode/"); 460 self->includePaths->push_back(std_lib_dir + "/std/"); 461 self->sc = MznModel::default_solver; 462 stringstream errorStream; 463 self->_m = parseFromString(libNamesStr, "error.txt", *(self->includePaths), false, false, false, 464 errorStream); 465 self->_e = new Env(self->_m); 466 if (!(self->_m)) { 467 const std::string& tmp = errorStream.str(); 468 const char* cstr = tmp.c_str(); 469 PyErr_SetString(PyExc_EnvironmentError, cstr); 470 return -1; 471 } 472 return 0; 473} 474 475static void MznModel_dealloc(MznModel* self) { 476 if (self->_m) delete self->_m; 477 if (self->_m) delete self->includePaths; 478 Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); 479} 480 481static PyObject* MznModel_addData(MznModel* self, PyObject* args) { 482 PyObject* obj; 483 const char* name; 484 if (!PyArg_ParseTuple(args, "sO", &name, &obj)) { 485 PyErr_SetString(PyExc_RuntimeError, "MiniZinc: Model.addData: Parsing error"); 486 return NULL; 487 } 488 if (self->addData(name, obj) == -1) { 489 // addData set error string already 490 return NULL; 491 } 492 Py_RETURN_NONE; 493} 494 495static PyObject* MznModel_copy(MznModel* self) { 496 MznModel* ret = reinterpret_cast<MznModel*>(MznModel_new(&MznModel_Type, NULL, NULL)); 497 GCLock lock; 498 ret->_m = copy(self->_e->envi(), self->_m); 499 ret->includePaths = new vector<string>(*(self->includePaths)); 500 501 ret->timeLimit = self->timeLimit; 502 ret->loaded = self->loaded; 503 return reinterpret_cast<PyObject*>(ret); 504} 505 506static PyObject* MznModel_debugprint(MznModel* self) { 507 debugprint(self->_m); 508 Py_RETURN_NONE; 509} 510 511static PyObject* MznModel_load(MznModel* self, PyObject* args, PyObject* keywds) { 512 if (self->load(args, keywds, true) < 0) return NULL; 513 Py_RETURN_NONE; 514} 515 516static PyObject* MznModel_load_from_string(MznModel* self, PyObject* args, PyObject* keywds) { 517 if (self->load(args, keywds, false) < 0) return NULL; 518 Py_RETURN_NONE; 519} 520 521static PyObject* MznModel_solve(MznModel* self, PyObject* args, PyObject* kwds) { 522 return self->solve(args, kwds); 523} 524 525static PyObject* MznModel_set_time_limit(MznModel* self, PyObject* args) { 526 unsigned long t; 527 if (!PyArg_ParseTuple(args, "k", &t)) { 528 PyErr_SetString(PyExc_TypeError, 529 "MiniZinc: Model.set_time_limit: Time limit must be an integer"); 530 return NULL; 531 } 532 self->timeLimit = t; 533 return Py_None; 534} 535 536PyObject* MznModel::set_solver(const char* s) { 537 std::string name(s); 538 // lower characters in name 539 for (std::string::iterator i = name.begin(); i != name.end(); ++i) 540 if (*i <= 'Z' && *i >= 'A') *i = *i - ('Z' - 'z'); 541 if (name == "gecode") 542 sc = SC_GECODE; 543 else { 544 MZN_PYERR_SET_STRING(PyExc_ValueError, "MiniZinc: Model.set_solver: Unexpected solver name: %s", 545 name.c_str()); 546 return NULL; 547 } 548 return Py_None; 549} 550 551static PyObject* MznModel_set_solver(MznModel* self, PyObject* args) { 552 const char* s; 553 if (!PyArg_ParseTuple(args, "s", &s)) { 554 PyErr_SetString(PyExc_TypeError, "MiniZinc: Model.set_solver: Solver name must be a string"); 555 return NULL; 556 } 557 return (self->set_solver(s)); 558} 559 560static PyObject* MznModel_Declaration(MznModel* self, PyObject* args) { 561 GCLock Lock; 562 enum TypeId { 563 PARINT, // 0 564 PARBOOL, // 1 565 PARFLOAT, // 2 566 PARSTRING, // 3 567 ANN, // 4 568 PARSETINT, // 5 569 PARSETBOOL, // 6 570 PARSETFLOAT, // 7 571 PARSETSTRING, // 8 572 VARINT, // 9 573 VARBOOL, // 10 574 VARFLOAT, // 11 575 VARSETINT, // 12 576 VARBOT, // 13 577 BOT, // 14 578 TOP, // 15 579 VARTOP, // 16 580 OPTVARTOP // 17 581 }; 582 583 char* name; 584 long tid; 585 PyObject* pydim = NULL; 586 PyObject* pylb = NULL; 587 PyObject* pyub = NULL; 588 PyObject* pyval = NULL; 589 Type type; 590 Expression* domain = NULL; 591 Expression* initValue = NULL; 592 Py_ssize_t dim; 593 594 vector<TypeInst*> ranges; 595 Type::BaseType code = Type::BT_UNKNOWN; 596 597 if (!PyArg_ParseTuple(args, "sO|OOO", &name, &pyval, &pydim, &pylb, &pyub)) { 598 MZN_PYERR_SET_STRING(PyExc_TypeError, 599 "MiniZinc: MznModel.Declaration: Variable parsing error"); 600 return NULL; 601 } 602 // if only 2 arguments, second value is the initial value 603 if (pydim == NULL) { 604 vector<pair<int, int> > dimList; 605 initValue = python_to_minizinc(pyval, type, dimList); 606 dim = dimList.size(); 607 domain = NULL; 608 } else 609 // else if > 2 arguments, create a MiniZinc Variable 610 { 611#if PY_MAJOR_VERSION < 3 612 if (PyInt_Check(pyval)) { 613 tid = PyInt_AS_LONG(pyval); 614 pyval = NULL; 615 } else 616#endif 617 if (PyLong_Check(pyval)) { 618 tid = PyLong_AsLong(pyval); 619 pyval = NULL; 620 } else { 621 PyErr_SetString(PyExc_TypeError, 622 "MiniZinc: MznModel.Declaration: Type Id must be an integer"); 623 return NULL; 624 } 625 if (tid > 17 || tid < 0) { 626 PyErr_SetString(PyExc_ValueError, "MiniZinc: MznModel.Declaration: Type Id is from 0 to 17"); 627 return NULL; 628 } 629 630 int errorOccurred; 631 ranges = pydim_to_minizinc_ranges(pydim, errorOccurred); 632 if (errorOccurred) return NULL; 633 dim = ranges.size(); 634 635 // Process different types 636 switch (static_cast<TypeId>(tid)) { 637 case VARINT: 638 type = Type::varint(dim); 639 code = Type::BT_INT; 640 if (pyub == NULL) { 641 Type tempType; 642 vector<pair<int, int> > tempDimList; 643 domain = python_to_minizinc(pylb, tempType, tempDimList); 644 if (tempType.st() != Type::ST_SET) { 645 PyErr_SetString(PyExc_TypeError, 646 "MiniZinc: MznModel.Declaration: If 5th argument does not exist, 4th " 647 "argument must be a Minizinc Set"); 648 return NULL; 649 } 650 } else 651 domain = new BinOp(Location(), one_dim_python_to_minizinc(pylb, code), BOT_DOTDOT, 652 one_dim_python_to_minizinc(pyub, code)); 653 break; 654 case VARBOOL: 655 type = Type::varbool(dim); 656 break; 657 case VARFLOAT: 658 type = Type::varfloat(dim); 659 code = Type::BT_FLOAT; 660 domain = new BinOp(Location(), one_dim_python_to_minizinc(pylb, code), BOT_DOTDOT, 661 one_dim_python_to_minizinc(pyub, code)); 662 break; 663 case VARSETINT: 664 type = Type::varsetint(dim); 665 if (pyub == NULL) { 666 Type tempType; 667 vector<pair<int, int> > tempDimList; 668 domain = python_to_minizinc(pylb, tempType, tempDimList); 669 if (tempType.st() != Type::ST_SET) { 670 PyErr_SetString(PyExc_TypeError, 671 "MiniZinc: MznModel.Declaration: If 5th argument does not exist, 4th " 672 "argument must be a Minizinc Set"); 673 return NULL; 674 } 675 } else 676 domain = new BinOp(Location(), one_dim_python_to_minizinc(pylb, code), BOT_DOTDOT, 677 one_dim_python_to_minizinc(pyub, code)); 678 break; 679 default: 680 MZN_PYERR_SET_STRING(PyExc_ValueError, 681 "MiniZinc: MznModel.Declaration: Value code %li not supported", tid); 682 return NULL; 683 } 684 } 685 686 VarDecl* vd = new VarDecl(Location(), new TypeInst(Location(), type, ranges, domain), 687 string(name), initValue); 688 self->_m->addItem(new VarDeclI(Location(), vd)); 689 self->loaded = true; 690 691 PyObject* ret = MznExpression_new(&MznExpression_Type, NULL, NULL); 692 reinterpret_cast<MznExpression*>(ret)->e = vd->id(); 693 return ret; 694}