this repo has no description
at develop 96 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/ast.hh> 13#include <minizinc/astexception.hh> 14#include <minizinc/astiterator.hh> 15#include <minizinc/builtins.hh> 16#include <minizinc/config.hh> 17#include <minizinc/eval_par.hh> 18#include <minizinc/file_utils.hh> 19#include <minizinc/flatten_internal.hh> 20#include <minizinc/output.hh> 21#include <minizinc/prettyprinter.hh> 22#include <minizinc/support/regex.hh> 23 24#include <climits> 25#include <cmath> 26#include <iomanip> 27#include <random> 28 29namespace MiniZinc { 30 31void rb(EnvI& env, Model* m, const ASTString& id, const std::vector<Type>& t, 32 FunctionI::builtin_e b, bool fromGlobals = false) { 33 FunctionI* fi = m->matchFn(env, id, t, false); 34 if (fi) { 35 fi->_builtins.e = b; 36 } else if (!fromGlobals) { 37 throw InternalError("no definition found for builtin " + id.str()); 38 } 39} 40void rb(EnvI& env, Model* m, const ASTString& id, const std::vector<Type>& t, 41 FunctionI::builtin_f b, bool fromGlobals = false) { 42 FunctionI* fi = m->matchFn(env, id, t, false); 43 if (fi) { 44 fi->_builtins.f = b; 45 } else if (!fromGlobals) { 46 throw InternalError("no definition found for builtin " + id.str()); 47 } 48} 49void rb(EnvI& env, Model* m, const ASTString& id, const std::vector<Type>& t, 50 FunctionI::builtin_i b, bool fromGlobals = false) { 51 FunctionI* fi = m->matchFn(env, id, t, false); 52 if (fi) { 53 fi->_builtins.i = b; 54 } else if (!fromGlobals) { 55 throw InternalError("no definition found for builtin " + id.str()); 56 } 57} 58void rb(EnvI& env, Model* m, const ASTString& id, const std::vector<Type>& t, 59 FunctionI::builtin_b b, bool fromGlobals = false) { 60 FunctionI* fi = m->matchFn(env, id, t, false); 61 if (fi) { 62 fi->_builtins.b = b; 63 } else if (!fromGlobals) { 64 throw InternalError("no definition found for builtin " + id.str()); 65 } 66} 67void rb(EnvI& env, Model* m, const ASTString& id, const std::vector<Type>& t, 68 FunctionI::builtin_s b, bool fromGlobals = false) { 69 FunctionI* fi = m->matchFn(env, id, t, false); 70 if (fi) { 71 fi->_builtins.s = b; 72 } else if (!fromGlobals) { 73 throw InternalError("no definition found for builtin " + id.str()); 74 } 75} 76void rb(EnvI& env, Model* m, const ASTString& id, const std::vector<Type>& t, 77 FunctionI::builtin_str b, bool fromGlobals = false) { 78 FunctionI* fi = m->matchFn(env, id, t, false); 79 if (fi) { 80 fi->_builtins.str = b; 81 } else if (!fromGlobals) { 82 throw InternalError("no definition found for builtin " + id.str()); 83 } 84} 85 86IntVal b_int_min(EnvI& env, Call* call) { 87 switch (call->n_args()) { 88 case 1: 89 if (call->arg(0)->type().is_set()) { 90 throw EvalError(env, call->arg(0)->loc(), "sets not supported"); 91 } else { 92 GCLock lock; 93 ArrayLit* al = eval_array_lit(env, call->arg(0)); 94 if (al->size() == 0) 95 throw ResultUndefinedError(env, al->loc(), "minimum of empty array is undefined"); 96 IntVal m = eval_int(env, (*al)[0]); 97 for (unsigned int i = 1; i < al->size(); i++) m = std::min(m, eval_int(env, (*al)[i])); 98 return m; 99 } 100 case 2: { 101 return std::min(eval_int(env, call->arg(0)), eval_int(env, call->arg(1))); 102 } 103 default: 104 throw EvalError(env, Location(), "dynamic type error"); 105 } 106} 107 108IntVal b_int_max(EnvI& env, Call* call) { 109 switch (call->n_args()) { 110 case 1: 111 if (call->arg(0)->type().is_set()) { 112 throw EvalError(env, call->arg(0)->loc(), "sets not supported"); 113 } else { 114 GCLock lock; 115 ArrayLit* al = eval_array_lit(env, call->arg(0)); 116 if (al->size() == 0) 117 throw ResultUndefinedError(env, al->loc(), "maximum of empty array is undefined"); 118 IntVal m = eval_int(env, (*al)[0]); 119 for (unsigned int i = 1; i < al->size(); i++) m = std::max(m, eval_int(env, (*al)[i])); 120 return m; 121 } 122 case 2: { 123 return std::max(eval_int(env, call->arg(0)), eval_int(env, call->arg(1))); 124 } 125 default: 126 throw EvalError(env, Location(), "dynamic type error"); 127 } 128} 129 130IntVal b_arg_min_int(EnvI& env, Call* call) { 131 GCLock lock; 132 ArrayLit* al = eval_array_lit(env, call->arg(0)); 133 if (al->size() == 0) 134 throw ResultUndefinedError(env, al->loc(), "argmin of empty array is undefined"); 135 IntVal m = eval_int(env, (*al)[0]); 136 int m_idx = 0; 137 for (unsigned int i = 1; i < al->size(); i++) { 138 IntVal mi = eval_int(env, (*al)[i]); 139 if (mi < m) { 140 m = mi; 141 m_idx = i; 142 } 143 } 144 return m_idx + 1; 145} 146IntVal b_arg_max_int(EnvI& env, Call* call) { 147 GCLock lock; 148 ArrayLit* al = eval_array_lit(env, call->arg(0)); 149 if (al->size() == 0) 150 throw ResultUndefinedError(env, al->loc(), "argmax of empty array is undefined"); 151 IntVal m = eval_int(env, (*al)[0]); 152 int m_idx = 0; 153 for (unsigned int i = 1; i < al->size(); i++) { 154 IntVal mi = eval_int(env, (*al)[i]); 155 if (mi > m) { 156 m = mi; 157 m_idx = i; 158 } 159 } 160 return m_idx + 1; 161} 162IntVal b_arg_min_float(EnvI& env, Call* call) { 163 GCLock lock; 164 ArrayLit* al = eval_array_lit(env, call->arg(0)); 165 if (al->size() == 0) 166 throw ResultUndefinedError(env, al->loc(), "argmin of empty array is undefined"); 167 FloatVal m = eval_float(env, (*al)[0]); 168 int m_idx = 0; 169 for (unsigned int i = 1; i < al->size(); i++) { 170 FloatVal mi = eval_float(env, (*al)[i]); 171 if (mi < m) { 172 m = mi; 173 m_idx = i; 174 } 175 } 176 return m_idx + 1; 177} 178IntVal b_arg_max_float(EnvI& env, Call* call) { 179 GCLock lock; 180 ArrayLit* al = eval_array_lit(env, call->arg(0)); 181 if (al->size() == 0) 182 throw ResultUndefinedError(env, al->loc(), "argmax of empty array is undefined"); 183 FloatVal m = eval_float(env, (*al)[0]); 184 int m_idx = 0; 185 for (unsigned int i = 1; i < al->size(); i++) { 186 FloatVal mi = eval_float(env, (*al)[i]); 187 if (mi > m) { 188 m = mi; 189 m_idx = i; 190 } 191 } 192 return m_idx + 1; 193} 194 195IntVal b_abs_int(EnvI& env, Call* call) { 196 assert(call->n_args() == 1); 197 return std::abs(eval_int(env, call->arg(0))); 198} 199 200FloatVal b_abs_float(EnvI& env, Call* call) { 201 assert(call->n_args() == 1); 202 return std::abs(eval_float(env, call->arg(0))); 203} 204 205bool b_has_bounds_int(EnvI& env, Call* call) { 206 if (call->n_args() != 1) throw EvalError(env, Location(), "dynamic type error"); 207 IntBounds ib = compute_int_bounds(env, call->arg(0)); 208 return ib.valid && ib.l.isFinite() && ib.u.isFinite(); 209} 210bool b_has_bounds_float(EnvI& env, Call* call) { 211 if (call->n_args() != 1) throw EvalError(env, Location(), "dynamic type error"); 212 FloatBounds fb = compute_float_bounds(env, call->arg(0)); 213 return fb.valid; 214} 215 216IntVal lb_varoptint(EnvI& env, Expression* e) { 217 IntBounds b = compute_int_bounds(env, e); 218 if (b.valid) 219 return b.l; 220 else 221 return -IntVal::infinity(); 222} 223IntVal b_lb_varoptint(EnvI& env, Call* call) { 224 if (call->n_args() != 1) throw EvalError(env, Location(), "dynamic type error"); 225 return lb_varoptint(env, call->arg(0)); 226} 227 228bool b_occurs(EnvI& env, Call* call) { 229 GCLock lock; 230 return eval_par(env, call->arg(0)) != constants().absent; 231} 232 233IntVal b_deopt_int(EnvI& env, Call* call) { 234 GCLock lock; 235 Expression* e = eval_par(env, call->arg(0)); 236 if (e == constants().absent) 237 throw EvalError(env, e->loc(), "cannot evaluate deopt on absent value"); 238 return eval_int(env, e); 239} 240 241bool b_deopt_bool(EnvI& env, Call* call) { 242 GCLock lock; 243 Expression* e = eval_par(env, call->arg(0)); 244 if (e == constants().absent) 245 throw EvalError(env, e->loc(), "cannot evaluate deopt on absent value"); 246 return eval_bool(env, e); 247} 248 249FloatVal b_deopt_float(EnvI& env, Call* call) { 250 GCLock lock; 251 Expression* e = eval_par(env, call->arg(0)); 252 if (e == constants().absent) 253 throw EvalError(env, e->loc(), "cannot evaluate deopt on absent value"); 254 return eval_float(env, e); 255} 256 257IntSetVal* b_deopt_intset(EnvI& env, Call* call) { 258 GCLock lock; 259 Expression* e = eval_par(env, call->arg(0)); 260 if (e == constants().absent) 261 throw EvalError(env, e->loc(), "cannot evaluate deopt on absent value"); 262 return eval_intset(env, e); 263} 264 265std::string b_deopt_string(EnvI& env, Call* call) { 266 GCLock lock; 267 Expression* e = eval_par(env, call->arg(0)); 268 if (e == constants().absent) 269 throw EvalError(env, e->loc(), "cannot evaluate deopt on absent value"); 270 return eval_string(env, e); 271} 272 273Expression* b_deopt_expr(EnvI& env, Call* call) { 274 GCLock lock; 275 Expression* e = eval_par(env, call->arg(0)); 276 if (e == constants().absent) 277 throw EvalError(env, e->loc(), "cannot evaluate deopt on absent value"); 278 return e; 279}; 280 281IntVal b_array_lb_int(EnvI& env, Call* call) { 282 assert(call->n_args() == 1); 283 Expression* e = follow_id_to_decl(call->arg(0)); 284 285 bool foundMin = false; 286 IntVal array_lb = -IntVal::infinity(); 287 288 if (VarDecl* vd = e->dyn_cast<VarDecl>()) { 289 if (vd->ti()->domain()) { 290 GCLock lock; 291 IntSetVal* isv = eval_intset(env, vd->ti()->domain()); 292 if (isv->size() != 0) { 293 array_lb = isv->min(); 294 foundMin = true; 295 } 296 } 297 e = vd->e(); 298 } 299 300 if (e != NULL) { 301 GCLock lock; 302 ArrayLit* al = eval_array_lit(env, e); 303 if (al->size() == 0) throw EvalError(env, Location(), "lower bound of empty array undefined"); 304 IntVal min = IntVal::infinity(); 305 for (unsigned int i = 0; i < al->size(); i++) { 306 IntBounds ib = compute_int_bounds(env, (*al)[i]); 307 if (!ib.valid) goto b_array_lb_int_done; 308 min = std::min(min, ib.l); 309 } 310 if (foundMin) 311 array_lb = std::max(array_lb, min); 312 else 313 array_lb = min; 314 foundMin = true; 315 } 316b_array_lb_int_done: 317 if (foundMin) { 318 return array_lb; 319 } else { 320 return -IntVal::infinity(); 321 } 322} 323 324IntVal ub_varoptint(EnvI& env, Expression* e) { 325 IntBounds b = compute_int_bounds(env, e); 326 if (b.valid) 327 return b.u; 328 else 329 return IntVal::infinity(); 330} 331IntVal b_ub_varoptint(EnvI& env, Call* call) { 332 if (call->n_args() != 1) throw EvalError(env, Location(), "dynamic type error"); 333 return ub_varoptint(env, call->arg(0)); 334} 335 336IntVal b_array_ub_int(EnvI& env, Call* call) { 337 assert(call->n_args() == 1); 338 Expression* e = follow_id_to_decl(call->arg(0)); 339 340 bool foundMax = false; 341 IntVal array_ub = IntVal::infinity(); 342 343 if (VarDecl* vd = e->dyn_cast<VarDecl>()) { 344 if (vd->ti()->domain()) { 345 GCLock lock; 346 IntSetVal* isv = eval_intset(env, vd->ti()->domain()); 347 if (isv->size() != 0) { 348 array_ub = isv->max(); 349 foundMax = true; 350 } 351 } 352 e = vd->e(); 353 } 354 355 if (e != NULL) { 356 GCLock lock; 357 ArrayLit* al = eval_array_lit(env, e); 358 if (al->size() == 0) throw EvalError(env, Location(), "upper bound of empty array undefined"); 359 IntVal max = -IntVal::infinity(); 360 for (unsigned int i = 0; i < al->size(); i++) { 361 IntBounds ib = compute_int_bounds(env, (*al)[i]); 362 if (!ib.valid) goto b_array_ub_int_done; 363 max = std::max(max, ib.u); 364 } 365 if (foundMax) 366 array_ub = std::min(array_ub, max); 367 else 368 array_ub = max; 369 foundMax = true; 370 } 371b_array_ub_int_done: 372 if (foundMax) { 373 return array_ub; 374 } else { 375 return IntVal::infinity(); 376 } 377} 378 379IntVal b_sum_int(EnvI& env, Call* call) { 380 assert(call->n_args() == 1); 381 GCLock lock; 382 ArrayLit* al = eval_array_lit(env, call->arg(0)); 383 if (al->size() == 0) return 0; 384 IntVal m = 0; 385 for (unsigned int i = 0; i < al->size(); i++) m += eval_int(env, (*al)[i]); 386 return m; 387} 388 389IntVal b_product_int(EnvI& env, Call* call) { 390 assert(call->n_args() == 1); 391 GCLock lock; 392 ArrayLit* al = eval_array_lit(env, call->arg(0)); 393 if (al->size() == 0) return 1; 394 IntVal m = 1; 395 for (unsigned int i = 0; i < al->size(); i++) m *= eval_int(env, (*al)[i]); 396 return m; 397} 398 399FloatVal b_product_float(EnvI& env, Call* call) { 400 assert(call->n_args() == 1); 401 GCLock lock; 402 ArrayLit* al = eval_array_lit(env, call->arg(0)); 403 if (al->size() == 0) return 1; 404 FloatVal m = 1.0; 405 for (unsigned int i = 0; i < al->size(); i++) m *= eval_float(env, (*al)[i]); 406 return m; 407} 408 409FloatVal lb_varoptfloat(EnvI& env, Expression* e) { 410 FloatBounds b = compute_float_bounds(env, e); 411 if (b.valid) 412 return b.l; 413 else 414 throw EvalError(env, e->loc(), "cannot determine bounds"); 415} 416FloatVal ub_varoptfloat(EnvI& env, Expression* e) { 417 FloatBounds b = compute_float_bounds(env, e); 418 if (b.valid) 419 return b.u; 420 else 421 throw EvalError(env, e->loc(), "cannot determine bounds"); 422} 423 424FloatVal b_lb_varoptfloat(EnvI& env, Call* call) { 425 if (call->n_args() != 1) throw EvalError(env, Location(), "dynamic type error"); 426 return lb_varoptfloat(env, call->arg(0)); 427} 428FloatVal b_ub_varoptfloat(EnvI& env, Call* call) { 429 if (call->n_args() != 1) throw EvalError(env, Location(), "dynamic type error"); 430 return ub_varoptfloat(env, call->arg(0)); 431} 432 433FloatVal b_array_lb_float(EnvI& env, Call* call) { 434 assert(call->n_args() == 1); 435 Expression* e = follow_id_to_decl(call->arg(0)); 436 437 bool foundMin = false; 438 FloatVal array_lb = 0.0; 439 440 if (VarDecl* vd = e->dyn_cast<VarDecl>()) { 441 if (vd->ti()->domain()) { 442 FloatSetVal* fsv = eval_floatset(env, vd->ti()->domain()); 443 array_lb = fsv->min(); 444 foundMin = true; 445 } 446 e = vd->e(); 447 } 448 449 if (e != NULL) { 450 GCLock lock; 451 ArrayLit* al = eval_array_lit(env, e); 452 if (al->size() == 0) throw EvalError(env, Location(), "lower bound of empty array undefined"); 453 bool min_valid = false; 454 FloatVal min = 0.0; 455 for (unsigned int i = 0; i < al->size(); i++) { 456 FloatBounds fb = compute_float_bounds(env, (*al)[i]); 457 if (!fb.valid) goto b_array_lb_float_done; 458 if (min_valid) { 459 min = std::min(min, fb.l); 460 } else { 461 min_valid = true; 462 min = fb.l; 463 } 464 } 465 assert(min_valid); 466 if (foundMin) 467 array_lb = std::max(array_lb, min); 468 else 469 array_lb = min; 470 foundMin = true; 471 } 472b_array_lb_float_done: 473 if (foundMin) { 474 return array_lb; 475 } else { 476 throw EvalError(env, e->loc(), "cannot determine lower bound"); 477 } 478} 479 480FloatVal b_array_ub_float(EnvI& env, Call* call) { 481 assert(call->n_args() == 1); 482 Expression* e = follow_id_to_decl(call->arg(0)); 483 484 bool foundMax = false; 485 FloatVal array_ub = 0.0; 486 487 if (VarDecl* vd = e->dyn_cast<VarDecl>()) { 488 if (vd->ti()->domain()) { 489 FloatSetVal* fsv = eval_floatset(env, vd->ti()->domain()); 490 array_ub = fsv->max(); 491 foundMax = true; 492 } 493 e = vd->e(); 494 } 495 496 if (e != NULL) { 497 GCLock lock; 498 ArrayLit* al = eval_array_lit(env, e); 499 if (al->size() == 0) throw EvalError(env, Location(), "upper bound of empty array undefined"); 500 bool max_valid = false; 501 FloatVal max = 0.0; 502 for (unsigned int i = 0; i < al->size(); i++) { 503 FloatBounds fb = compute_float_bounds(env, (*al)[i]); 504 if (!fb.valid) goto b_array_ub_float_done; 505 if (max_valid) { 506 max = std::max(max, fb.u); 507 } else { 508 max_valid = true; 509 max = fb.u; 510 } 511 } 512 assert(max_valid); 513 if (foundMax) 514 array_ub = std::min(array_ub, max); 515 else 516 array_ub = max; 517 foundMax = true; 518 } 519b_array_ub_float_done: 520 if (foundMax) { 521 return array_ub; 522 } else { 523 throw EvalError(env, e->loc(), "cannot determine upper bound"); 524 } 525} 526 527FloatVal b_sum_float(EnvI& env, Call* call) { 528 assert(call->n_args() == 1); 529 GCLock lock; 530 ArrayLit* al = eval_array_lit(env, call->arg(0)); 531 if (al->size() == 0) return 0; 532 FloatVal m = 0; 533 for (unsigned int i = 0; i < al->size(); i++) m += eval_float(env, (*al)[i]); 534 return m; 535} 536 537FloatVal b_float_min(EnvI& env, Call* call) { 538 switch (call->n_args()) { 539 case 1: 540 if (call->arg(0)->type().is_set()) { 541 throw EvalError(env, call->arg(0)->loc(), "sets not supported"); 542 } else { 543 GCLock lock; 544 ArrayLit* al = eval_array_lit(env, call->arg(0)); 545 if (al->size() == 0) throw EvalError(env, al->loc(), "min on empty array undefined"); 546 FloatVal m = eval_float(env, (*al)[0]); 547 for (unsigned int i = 1; i < al->size(); i++) m = std::min(m, eval_float(env, (*al)[i])); 548 return m; 549 } 550 case 2: { 551 return std::min(eval_float(env, call->arg(0)), eval_float(env, call->arg(1))); 552 } 553 default: 554 throw EvalError(env, Location(), "dynamic type error"); 555 } 556} 557 558FloatVal b_float_max(EnvI& env, Call* call) { 559 switch (call->n_args()) { 560 case 1: 561 if (call->arg(0)->type().is_set()) { 562 throw EvalError(env, call->arg(0)->loc(), "sets not supported"); 563 } else { 564 GCLock lock; 565 ArrayLit* al = eval_array_lit(env, call->arg(0)); 566 if (al->size() == 0) throw EvalError(env, al->loc(), "max on empty array undefined"); 567 FloatVal m = eval_float(env, (*al)[0]); 568 for (unsigned int i = 1; i < al->size(); i++) m = std::max(m, eval_float(env, (*al)[i])); 569 return m; 570 } 571 case 2: { 572 return std::max(eval_float(env, call->arg(0)), eval_float(env, call->arg(1))); 573 } 574 default: 575 throw EvalError(env, Location(), "dynamic type error"); 576 } 577} 578 579IntSetVal* b_index_set(EnvI& env, Expression* e, int i) { 580 if (e->eid() != Expression::E_ID) { 581 GCLock lock; 582 ArrayLit* al = eval_array_lit(env, e); 583 if (al->dims() < i) throw EvalError(env, e->loc(), "index_set: wrong dimension"); 584 return IntSetVal::a(al->min(i - 1), al->max(i - 1)); 585 } 586 Id* id = e->cast<Id>(); 587 if (id->decl() == NULL) throw EvalError(env, id->loc(), "undefined identifier"); 588 if ((id->decl()->ti()->ranges().size() == 1 && id->decl()->ti()->ranges()[0]->domain() != NULL && 589 id->decl()->ti()->ranges()[0]->domain()->isa<TIId>()) || 590 (static_cast<int>(id->decl()->ti()->ranges().size()) >= i && 591 (id->decl()->ti()->ranges()[i - 1]->domain() == NULL || 592 id->decl()->ti()->ranges()[i - 1]->domain()->isa<TIId>()))) { 593 GCLock lock; 594 ArrayLit* al = eval_array_lit(env, id); 595 if (al->dims() < i) throw EvalError(env, id->loc(), "index_set: wrong dimension"); 596 return IntSetVal::a(al->min(i - 1), al->max(i - 1)); 597 } 598 if (static_cast<int>(id->decl()->ti()->ranges().size()) < i) 599 throw EvalError(env, id->loc(), "index_set: wrong dimension"); 600 return eval_intset(env, id->decl()->ti()->ranges()[i - 1]->domain()); 601} 602bool b_index_sets_agree(EnvI& env, Call* call) { 603 if (call->n_args() != 2) 604 throw EvalError(env, Location(), "index_sets_agree needs exactly two arguments"); 605 GCLock lock; 606 ArrayLit* al0 = eval_array_lit(env, call->arg(0)); 607 ArrayLit* al1 = eval_array_lit(env, call->arg(1)); 608 if (al0->type().dim() != al1->type().dim()) return false; 609 for (int i = 1; i <= al0->type().dim(); i++) { 610 IntSetVal* index0 = b_index_set(env, al0, i); 611 IntSetVal* index1 = b_index_set(env, al1, i); 612 if (!index0->equal(index1)) return false; 613 } 614 return true; 615} 616IntSetVal* b_index_set1(EnvI& env, Call* call) { 617 if (call->n_args() != 1) throw EvalError(env, Location(), "index_set needs exactly one argument"); 618 return b_index_set(env, call->arg(0), 1); 619} 620IntSetVal* b_index_set2(EnvI& env, Call* call) { 621 if (call->n_args() != 1) throw EvalError(env, Location(), "index_set needs exactly one argument"); 622 return b_index_set(env, call->arg(0), 2); 623} 624IntSetVal* b_index_set3(EnvI& env, Call* call) { 625 if (call->n_args() != 1) throw EvalError(env, Location(), "index_set needs exactly one argument"); 626 return b_index_set(env, call->arg(0), 3); 627} 628IntSetVal* b_index_set4(EnvI& env, Call* call) { 629 if (call->n_args() != 1) throw EvalError(env, Location(), "index_set needs exactly one argument"); 630 return b_index_set(env, call->arg(0), 4); 631} 632IntSetVal* b_index_set5(EnvI& env, Call* call) { 633 if (call->n_args() != 1) throw EvalError(env, Location(), "index_set needs exactly one argument"); 634 return b_index_set(env, call->arg(0), 5); 635} 636IntSetVal* b_index_set6(EnvI& env, Call* call) { 637 if (call->n_args() != 1) throw EvalError(env, Location(), "index_set needs exactly one argument"); 638 return b_index_set(env, call->arg(0), 6); 639} 640 641IntVal b_min_parsetint(EnvI& env, Call* call) { 642 assert(call->n_args() == 1); 643 IntSetVal* isv = eval_intset(env, call->arg(0)); 644 return isv->min(); 645} 646IntVal b_max_parsetint(EnvI& env, Call* call) { 647 assert(call->n_args() == 1); 648 IntSetVal* isv = eval_intset(env, call->arg(0)); 649 return isv->max(); 650} 651IntSetVal* b_lb_set(EnvI& env, Call* e) { 652 Expression* ee = eval_par(env, e->arg(0)); 653 if (ee->type().ispar()) { 654 return eval_intset(env, ee); 655 } 656 return IntSetVal::a(); 657} 658IntSetVal* b_ub_set(EnvI& env, Expression* e) { 659 IntSetVal* isv = compute_intset_bounds(env, e); 660 if (isv) return isv; 661 throw EvalError(env, e->loc(), "cannot determine bounds of set expression"); 662} 663IntSetVal* b_ub_set(EnvI& env, Call* call) { 664 assert(call->n_args() == 1); 665 return b_ub_set(env, call->arg(0)); 666} 667bool b_has_ub_set(EnvI& env, Call* call) { 668 Expression* e = call->arg(0); 669 for (;;) { 670 switch (e->eid()) { 671 case Expression::E_SETLIT: 672 return true; 673 case Expression::E_ID: { 674 Id* id = e->cast<Id>(); 675 if (id->decl() == NULL) throw EvalError(env, id->loc(), "undefined identifier"); 676 if (id->decl()->e() == NULL) 677 return id->decl()->ti()->domain() != NULL; 678 else 679 e = id->decl()->e(); 680 } break; 681 default: 682 throw EvalError(env, e->loc(), "invalid argument to has_ub_set"); 683 } 684 } 685} 686 687IntSetVal* b_array_ub_set(EnvI& env, Call* call) { 688 assert(call->n_args() == 1); 689 GCLock lock; 690 ArrayLit* al = eval_array_lit(env, call->arg(0)); 691 if (al->size() == 0) throw EvalError(env, Location(), "upper bound of empty array undefined"); 692 IntSetVal* ub = b_ub_set(env, (*al)[0]); 693 for (unsigned int i = 1; i < al->size(); i++) { 694 IntSetRanges isr(ub); 695 IntSetRanges r(b_ub_set(env, (*al)[i])); 696 Ranges::Union<IntVal, IntSetRanges, IntSetRanges> u(isr, r); 697 ub = IntSetVal::ai(u); 698 } 699 return ub; 700} 701 702IntSetVal* b_dom_varint(EnvI& env, Expression* e) { 703 Id* lastid = NULL; 704 Expression* cur = e; 705 for (;;) { 706 if (cur == NULL) { 707 if (lastid == NULL || lastid->decl()->ti()->domain() == NULL) { 708 IntBounds b = compute_int_bounds(env, e); 709 if (b.valid) 710 return IntSetVal::a(b.l, b.u); 711 else 712 return IntSetVal::a(-IntVal::infinity(), IntVal::infinity()); 713 } else { 714 return eval_intset(env, lastid->decl()->ti()->domain()); 715 } 716 } 717 switch (cur->eid()) { 718 case Expression::E_INTLIT: { 719 IntVal v = cur->cast<IntLit>()->v(); 720 return IntSetVal::a(v, v); 721 } 722 case Expression::E_ID: { 723 lastid = cur->cast<Id>(); 724 if (lastid->decl() == NULL) throw EvalError(env, lastid->loc(), "undefined identifier"); 725 cur = lastid->decl()->e(); 726 } break; 727 case Expression::E_ARRAYACCESS: { 728 bool success; 729 cur = eval_arrayaccess(env, cur->cast<ArrayAccess>(), success); 730 if (!success) { 731 cur = NULL; 732 } 733 } break; 734 default: 735 cur = NULL; 736 break; 737 } 738 } 739} 740IntSetVal* b_dom_varint(EnvI& env, Call* call) { 741 assert(call->n_args() == 1); 742 return b_dom_varint(env, call->arg(0)); 743} 744 745IntSetVal* b_dom_bounds_array(EnvI& env, Call* call) { 746 assert(call->n_args() == 1); 747 Expression* arg_e = call->arg(0); 748 Expression* e = follow_id_to_decl(arg_e); 749 750 bool foundBounds = false; 751 IntVal array_lb = -IntVal::infinity(); 752 IntVal array_ub = IntVal::infinity(); 753 754 if (VarDecl* vd = e->dyn_cast<VarDecl>()) { 755 if (vd->ti()->domain()) { 756 GCLock lock; 757 IntSetVal* isv = eval_intset(env, vd->ti()->domain()); 758 if (isv->size() != 0) { 759 array_lb = isv->min(); 760 array_ub = isv->max(); 761 foundBounds = true; 762 } 763 } 764 e = vd->e(); 765 if (e == NULL) e = vd->flat()->e(); 766 } 767 768 if (foundBounds) { 769 return IntSetVal::a(array_lb, array_ub); 770 } 771 772 if (e != NULL) { 773 GCLock lock; 774 ArrayLit* al = eval_array_lit(env, e); 775 if (al->size() == 0) throw EvalError(env, Location(), "lower bound of empty array undefined"); 776 IntVal min = IntVal::infinity(); 777 IntVal max = -IntVal::infinity(); 778 for (unsigned int i = 0; i < al->size(); i++) { 779 IntBounds ib = compute_int_bounds(env, (*al)[i]); 780 if (!ib.valid) goto b_array_lb_int_done; 781 min = std::min(min, ib.l); 782 max = std::max(max, ib.u); 783 } 784 array_lb = std::max(array_lb, min); 785 array_ub = std::min(array_ub, max); 786 foundBounds = true; 787 } 788b_array_lb_int_done: 789 if (foundBounds) { 790 return IntSetVal::a(array_lb, array_ub); 791 } else { 792 throw EvalError(env, e->loc(), "cannot determine lower bound"); 793 } 794} 795 796IntSetVal* b_dom_array(EnvI& env, Call* call) { 797 assert(call->n_args() == 1); 798 Expression* ae = call->arg(0); 799 ArrayLit* al = NULL; 800 while (al == NULL) { 801 switch (ae->eid()) { 802 case Expression::E_ARRAYLIT: 803 al = ae->cast<ArrayLit>(); 804 break; 805 case Expression::E_ID: { 806 Id* id = ae->cast<Id>(); 807 if (id->decl() == NULL) throw EvalError(env, id->loc(), "undefined identifier"); 808 if (id->decl()->e() == NULL) { 809 if (id->decl()->flat() == NULL) { 810 throw EvalError(env, id->loc(), "array without initialiser"); 811 } else { 812 if (id->decl()->flat()->e() == NULL) { 813 throw EvalError(env, id->loc(), "array without initialiser"); 814 } 815 ae = id->decl()->flat()->e(); 816 } 817 } else { 818 ae = id->decl()->e(); 819 } 820 } break; 821 default: 822 throw EvalError(env, ae->loc(), "invalid argument to dom"); 823 } 824 } 825 if (al->size() == 0) return IntSetVal::a(); 826 IntSetVal* isv = b_dom_varint(env, (*al)[0]); 827 for (unsigned int i = 1; i < al->size(); i++) { 828 IntSetRanges isr(isv); 829 IntSetRanges r(b_dom_varint(env, (*al)[i])); 830 Ranges::Union<IntVal, IntSetRanges, IntSetRanges> u(isr, r); 831 isv = IntSetVal::ai(u); 832 } 833 return isv; 834} 835IntSetVal* b_compute_div_bounds(EnvI& env, Call* call) { 836 assert(call->n_args() == 2); 837 IntBounds bx = compute_int_bounds(env, call->arg(0)); 838 if (!bx.valid) throw EvalError(env, call->arg(0)->loc(), "cannot determine bounds"); 839 /// TODO: better bounds if only some input bounds are infinite 840 if (!bx.l.isFinite() || !bx.u.isFinite()) return constants().infinity->isv(); 841 IntBounds by = compute_int_bounds(env, call->arg(1)); 842 if (!by.valid) throw EvalError(env, call->arg(1)->loc(), "cannot determine bounds"); 843 if (!by.l.isFinite() || !by.u.isFinite()) return constants().infinity->isv(); 844 Ranges::Const<IntVal> byr(by.l, by.u); 845 Ranges::Const<IntVal> by0(0, 0); 846 Ranges::Diff<IntVal, Ranges::Const<IntVal>, Ranges::Const<IntVal>> byr0(byr, by0); 847 848 IntVal min = IntVal::maxint(); 849 IntVal max = IntVal::minint(); 850 if (byr0()) { 851 min = std::min(min, bx.l / byr0.min()); 852 min = std::min(min, bx.l / byr0.max()); 853 min = std::min(min, bx.u / byr0.min()); 854 min = std::min(min, bx.u / byr0.max()); 855 max = std::max(max, bx.l / byr0.min()); 856 max = std::max(max, bx.l / byr0.max()); 857 max = std::max(max, bx.u / byr0.min()); 858 max = std::max(max, bx.u / byr0.max()); 859 ++byr0; 860 if (byr0()) { 861 min = std::min(min, bx.l / byr0.min()); 862 min = std::min(min, bx.l / byr0.max()); 863 min = std::min(min, bx.u / byr0.min()); 864 min = std::min(min, bx.u / byr0.max()); 865 max = std::max(max, bx.l / byr0.min()); 866 max = std::max(max, bx.l / byr0.max()); 867 max = std::max(max, bx.u / byr0.min()); 868 max = std::max(max, bx.u / byr0.max()); 869 } 870 } 871 return IntSetVal::a(min, max); 872} 873 874ArrayLit* b_arrayXd(EnvI& env, Call* call, int d) { 875 GCLock lock; 876 ArrayLit* al = eval_array_lit(env, call->arg(d)); 877 std::vector<std::pair<int, int>> dims(d); 878 unsigned int dim1d = 1; 879 for (int i = 0; i < d; i++) { 880 IntSetVal* di = eval_intset(env, call->arg(i)); 881 if (di->size() == 0) { 882 dims[i] = std::pair<int, int>(1, 0); 883 dim1d = 0; 884 } else if (di->size() != 1) { 885 throw EvalError(env, call->arg(i)->loc(), "arrayXd only defined for ranges"); 886 } else { 887 dims[i] = std::pair<int, int>(static_cast<int>(di->min(0).toInt()), 888 static_cast<int>(di->max(0).toInt())); 889 dim1d *= dims[i].second - dims[i].first + 1; 890 } 891 } 892 if (dim1d != al->size()) throw EvalError(env, al->loc(), "mismatch in array dimensions"); 893 ArrayLit* ret = new ArrayLit(al->loc(), *al, dims); 894 Type t = al->type(); 895 t.dim(d); 896 ret->type(t); 897 ret->flat(al->flat()); 898 return ret; 899} 900Expression* b_array1d_list(EnvI& env, Call* call) { 901 GCLock lock; 902 ArrayLit* al = eval_array_lit(env, call->arg(0)); 903 if (al->dims() == 1 && al->min(0) == 1) { 904 return call->arg(0)->isa<Id>() ? call->arg(0) : al; 905 } 906 ArrayLit* ret = new ArrayLit(al->loc(), *al); 907 Type t = al->type(); 908 t.dim(1); 909 ret->type(t); 910 ret->flat(al->flat()); 911 return ret; 912} 913Expression* b_array1d(EnvI& env, Call* call) { return b_arrayXd(env, call, 1); } 914Expression* b_array2d(EnvI& env, Call* call) { return b_arrayXd(env, call, 2); } 915Expression* b_array3d(EnvI& env, Call* call) { return b_arrayXd(env, call, 3); } 916Expression* b_array4d(EnvI& env, Call* call) { return b_arrayXd(env, call, 4); } 917Expression* b_array5d(EnvI& env, Call* call) { return b_arrayXd(env, call, 5); } 918Expression* b_array6d(EnvI& env, Call* call) { return b_arrayXd(env, call, 6); } 919 920Expression* b_arrayXd(EnvI& env, Call* call) { 921 GCLock lock; 922 ArrayLit* al0 = eval_array_lit(env, call->arg(0)); 923 ArrayLit* al1 = eval_array_lit(env, call->arg(1)); 924 if (al0->dims() == al1->dims()) { 925 bool sameDims = true; 926 for (unsigned int i = al0->dims(); i--;) { 927 if (al0->min(i) != al1->min(i) || al0->max(i) != al1->max(i)) { 928 sameDims = false; 929 break; 930 } 931 } 932 if (sameDims) return call->arg(1)->isa<Id>() ? call->arg(1) : al1; 933 } 934 std::vector<std::pair<int, int>> dims(al0->dims()); 935 for (unsigned int i = al0->dims(); i--;) { 936 dims[i] = std::make_pair(al0->min(i), al0->max(i)); 937 } 938 ArrayLit* ret = new ArrayLit(al1->loc(), *al1, dims); 939 Type t = al1->type(); 940 t.dim(static_cast<int>(dims.size())); 941 ret->type(t); 942 ret->flat(al1->flat()); 943 return ret; 944} 945 946IntVal b_length(EnvI& env, Call* call) { 947 GCLock lock; 948 ArrayLit* al = eval_array_lit(env, call->arg(0)); 949 return al->size(); 950} 951 952IntVal b_bool2int(EnvI& env, Call* call) { return eval_bool(env, call->arg(0)) ? 1 : 0; } 953 954bool b_forall_par(EnvI& env, Call* call) { 955 if (call->n_args() != 1) throw EvalError(env, Location(), "forall needs exactly one argument"); 956 GCLock lock; 957 ArrayLit* al = eval_array_lit(env, call->arg(0)); 958 for (unsigned int i = al->size(); i--;) 959 if (!eval_bool(env, (*al)[i])) return false; 960 return true; 961} 962bool b_exists_par(EnvI& env, Call* call) { 963 if (call->n_args() != 1) throw EvalError(env, Location(), "exists needs exactly one argument"); 964 GCLock lock; 965 ArrayLit* al = eval_array_lit(env, call->arg(0)); 966 for (unsigned int i = al->size(); i--;) 967 if (eval_bool(env, (*al)[i])) return true; 968 return false; 969} 970bool b_clause_par(EnvI& env, Call* call) { 971 if (call->n_args() != 2) throw EvalError(env, Location(), "clause needs exactly two arguments"); 972 GCLock lock; 973 ArrayLit* al = eval_array_lit(env, call->arg(0)); 974 for (unsigned int i = al->size(); i--;) 975 if (eval_bool(env, (*al)[i])) return true; 976 al = eval_array_lit(env, call->arg(1)); 977 for (unsigned int i = al->size(); i--;) 978 if (!eval_bool(env, (*al)[i])) return true; 979 return false; 980} 981bool b_xorall_par(EnvI& env, Call* call) { 982 if (call->n_args() != 1) throw EvalError(env, Location(), "xorall needs exactly one argument"); 983 GCLock lock; 984 int count = 0; 985 ArrayLit* al = eval_array_lit(env, call->arg(0)); 986 for (unsigned int i = al->size(); i--;) count += eval_bool(env, (*al)[i]); 987 return count % 2 == 1; 988} 989bool b_iffall_par(EnvI& env, Call* call) { 990 if (call->n_args() != 1) throw EvalError(env, Location(), "xorall needs exactly one argument"); 991 GCLock lock; 992 int count = 0; 993 ArrayLit* al = eval_array_lit(env, call->arg(0)); 994 for (unsigned int i = al->size(); i--;) count += eval_bool(env, (*al)[i]); 995 return count % 2 == 0; 996} 997 998IntVal b_card(EnvI& env, Call* call) { 999 if (call->n_args() != 1) throw EvalError(env, Location(), "card needs exactly one argument"); 1000 IntSetVal* isv = eval_intset(env, call->arg(0)); 1001 IntSetRanges isr(isv); 1002 return Ranges::cardinality(isr); 1003} 1004 1005Expression* exp_is_fixed(EnvI& env, Expression* e) { 1006 GCLock lock; 1007 Expression* cur = eval_par(env, e); 1008 for (;;) { 1009 if (cur == NULL) return NULL; 1010 if (cur->type().ispar()) return cur; 1011 switch (cur->eid()) { 1012 case Expression::E_ID: 1013 cur = cur->cast<Id>()->decl(); 1014 break; 1015 case Expression::E_VARDECL: 1016 if (cur->type().st() != Type::ST_SET) { 1017 Expression* dom = cur->cast<VarDecl>()->ti()->domain(); 1018 if (dom && (dom->isa<IntLit>() || dom->isa<BoolLit>() || dom->isa<FloatLit>())) 1019 return dom; 1020 } 1021 cur = cur->cast<VarDecl>()->e(); 1022 break; 1023 default: 1024 return NULL; 1025 } 1026 } 1027} 1028 1029bool b_is_fixed(EnvI& env, Call* call) { 1030 assert(call->n_args() == 1); 1031 return exp_is_fixed(env, call->arg(0)) != NULL; 1032} 1033 1034bool b_is_fixed_array(EnvI& env, Call* call) { 1035 assert(call->n_args() == 1); 1036 GCLock lock; 1037 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1038 if (al->size() == 0) return true; 1039 for (unsigned int i = 0; i < al->size(); i++) { 1040 if (exp_is_fixed(env, (*al)[i]) == NULL) return false; 1041 } 1042 return true; 1043} 1044 1045Expression* b_fix(EnvI& env, Call* call) { 1046 assert(call->n_args() == 1); 1047 Expression* ret = exp_is_fixed(env, call->arg(0)); 1048 if (ret == NULL) throw EvalError(env, call->arg(0)->loc(), "expression is not fixed"); 1049 return ret; 1050} 1051 1052IntVal b_fix_int(EnvI& env, Call* call) { return eval_int(env, b_fix(env, call)); } 1053bool b_fix_bool(EnvI& env, Call* call) { return eval_bool(env, b_fix(env, call)); } 1054FloatVal b_fix_float(EnvI& env, Call* call) { return eval_float(env, b_fix(env, call)); } 1055IntSetVal* b_fix_set(EnvI& env, Call* call) { return eval_intset(env, b_fix(env, call)); } 1056 1057Expression* b_fix_array(EnvI& env, Call* call) { 1058 assert(call->n_args() == 1); 1059 GCLock lock; 1060 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1061 std::vector<Expression*> fixed(al->size()); 1062 for (unsigned int i = 0; i < fixed.size(); i++) { 1063 fixed[i] = exp_is_fixed(env, (*al)[i]); 1064 if (fixed[i] == NULL) throw EvalError(env, (*al)[i]->loc(), "expression is not fixed"); 1065 } 1066 ArrayLit* ret = new ArrayLit(Location(), fixed); 1067 Type tt = al->type(); 1068 tt.ti(Type::TI_PAR); 1069 ret->type(tt); 1070 return ret; 1071} 1072 1073FloatVal b_int2float(EnvI& env, Call* call) { return eval_int(env, call->arg(0)); } 1074IntVal b_ceil(EnvI& env, Call* call) { 1075 return static_cast<IntVal>(std::ceil(eval_float(env, call->arg(0)))); 1076} 1077IntVal b_floor(EnvI& env, Call* call) { 1078 return static_cast<IntVal>(std::floor(eval_float(env, call->arg(0)))); 1079} 1080IntVal b_round(EnvI& env, Call* call) { 1081 FloatVal v(eval_float(env, call->arg(0))); 1082 return v < 0 ? static_cast<IntVal>(v - 0.5) : static_cast<IntVal>(v + 0.5); 1083 // return static_cast<IntVal>(eval_float(env,call->arg(0))+0.5); 1084} 1085FloatVal b_log10(EnvI& env, Call* call) { 1086 return std::log10(eval_float(env, call->arg(0)).toDouble()); 1087} 1088FloatVal b_log2(EnvI& env, Call* call) { 1089 return std::log(eval_float(env, call->arg(0)).toDouble()) / std::log(2.0); 1090} 1091FloatVal b_ln(EnvI& env, Call* call) { return std::log(eval_float(env, call->arg(0)).toDouble()); } 1092FloatVal b_log(EnvI& env, Call* call) { 1093 return std::log(eval_float(env, call->arg(1)).toDouble()) / 1094 std::log(eval_float(env, call->arg(0)).toDouble()); 1095} 1096FloatVal b_exp(EnvI& env, Call* call) { return std::exp(eval_float(env, call->arg(0)).toDouble()); } 1097FloatVal b_pow(EnvI& env, Call* call) { 1098 return std::pow(eval_float(env, call->arg(0)).toDouble(), 1099 eval_float(env, call->arg(1)).toDouble()); 1100} 1101IntVal b_pow_int(EnvI& env, Call* call) { 1102 IntVal p = eval_int(env, call->arg(0)); 1103 IntVal r = 1; 1104 long long int e = eval_int(env, call->arg(1)).toInt(); 1105 if (e < 0) throw EvalError(env, call->arg(1)->loc(), "Cannot raise integer to a negative power"); 1106 for (long long int i = e; i--;) r = r * p; 1107 return r; 1108} 1109FloatVal b_sqrt(EnvI& env, Call* call) { 1110 return std::sqrt(eval_float(env, call->arg(0)).toDouble()); 1111} 1112 1113bool b_assert_bool(EnvI& env, Call* call) { 1114 assert(call->n_args() == 2); 1115 GCLock lock; 1116 if (eval_bool(env, call->arg(0))) return true; 1117 StringLit* err = eval_par(env, call->arg(1))->cast<StringLit>(); 1118 throw EvalError(env, call->arg(0)->loc(), "Assertion failed: " + err->v().str()); 1119} 1120 1121Expression* b_assert(EnvI& env, Call* call) { 1122 assert(call->n_args() == 3); 1123 GCLock lock; 1124 if (eval_bool(env, call->arg(0))) return call->arg(2); 1125 StringLit* err = eval_par(env, call->arg(1))->cast<StringLit>(); 1126 throw EvalError(env, call->arg(0)->loc(), "Assertion failed: " + err->v().str()); 1127} 1128 1129bool b_abort(EnvI& env, Call* call) { 1130 GCLock lock; 1131 StringLit* err = eval_par(env, call->arg(0))->cast<StringLit>(); 1132 throw EvalError(env, call->arg(0)->loc(), "Abort: " + err->v().str()); 1133} 1134 1135Expression* b_trace(EnvI& env, Call* call) { 1136 GCLock lock; 1137 StringLit* msg = eval_par(env, call->arg(0))->cast<StringLit>(); 1138 env.errstream << msg->v(); 1139 return call->n_args() == 1 ? constants().lit_true : call->arg(1); 1140} 1141 1142Expression* b_trace_stdout(EnvI& env, Call* call) { 1143 GCLock lock; 1144 StringLit* msg = eval_par(env, call->arg(0))->cast<StringLit>(); 1145 env.outstream << msg->v(); 1146 return call->n_args() == 1 ? constants().lit_true : call->arg(1); 1147} 1148 1149bool b_in_redundant_constraint(EnvI& env, Call*) { return env.in_redundant_constraint > 0; } 1150 1151Expression* b_set2array(EnvI& env, Call* call) { 1152 assert(call->n_args() == 1); 1153 GCLock lock; 1154 IntSetVal* isv = eval_intset(env, call->arg(0)); 1155 std::vector<Expression*> elems; 1156 IntSetRanges isr(isv); 1157 for (Ranges::ToValues<IntSetRanges> isr_v(isr); isr_v(); ++isr_v) 1158 elems.push_back(IntLit::a(isr_v.val())); 1159 ArrayLit* al = new ArrayLit(call->arg(0)->loc(), elems); 1160 al->type(Type::parint(1)); 1161 return al; 1162} 1163 1164IntVal b_string_length(EnvI& env, Call* call) { 1165 GCLock lock; 1166 std::string s = eval_string(env, call->arg(0)); 1167 return s.size(); 1168} 1169 1170std::string show(EnvI& env, Expression* exp) { 1171 std::ostringstream oss; 1172 GCLock lock; 1173 Printer p(oss, 0, false); 1174 Expression* e = eval_par(env, exp); 1175 if (e->type().isvar()) { 1176 p.print(e); 1177 } else { 1178 e = eval_par(env, e); 1179 if (ArrayLit* al = e->dyn_cast<ArrayLit>()) { 1180 oss << "["; 1181 for (unsigned int i = 0; i < al->size(); i++) { 1182 p.print((*al)[i]); 1183 if (i < al->size() - 1) oss << ", "; 1184 } 1185 oss << "]"; 1186 } else { 1187 p.print(e); 1188 } 1189 } 1190 return oss.str(); 1191} 1192std::string b_show(EnvI& env, Call* call) { return show(env, call->arg(0)); } 1193std::string b_showDznId(EnvI& env, Call* call) { 1194 GCLock lock; 1195 std::string s = eval_string(env, call->arg(0)); 1196 size_t nonIdChar = 1197 s.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"); 1198 size_t nonIdBegin = s.find_first_of("0123456789_"); 1199 if (nonIdChar != std::string::npos || nonIdBegin == 0) { 1200 s = "'" + s + "'"; 1201 } 1202 return s; 1203} 1204 1205std::string b_show_json_basic(EnvI& env, Expression* e) { 1206 std::ostringstream oss; 1207 Printer p(oss, 0, false); 1208 if (SetLit* sl = e->dyn_cast<SetLit>()) { 1209 oss << "{ \"set\" : ["; 1210 if (IntSetVal* isv = sl->isv()) { 1211 bool first = true; 1212 for (IntSetRanges isr(isv); isr(); ++isr) { 1213 if (first) { 1214 first = false; 1215 } else { 1216 oss << ","; 1217 } 1218 if (isr.min() == isr.max()) { 1219 oss << isr.min(); 1220 } else { 1221 oss << "[" << isr.min() << "," << isr.max() << "]"; 1222 } 1223 } 1224 } else if (FloatSetVal* fsv = sl->fsv()) { 1225 bool first = true; 1226 for (FloatSetRanges fsr(fsv); fsr(); ++fsr) { 1227 if (first) { 1228 first = false; 1229 } else { 1230 oss << ","; 1231 } 1232 if (fsr.min() == fsr.max()) { 1233 ppFloatVal(oss, fsr.min()); 1234 } else { 1235 oss << "["; 1236 ppFloatVal(oss, fsr.min()); 1237 oss << ","; 1238 ppFloatVal(oss, fsr.max()); 1239 oss << "]"; 1240 } 1241 } 1242 } else { 1243 for (unsigned int i = 0; i < sl->v().size(); i++) { 1244 p.print(sl->v()[i]); 1245 if (i < sl->v().size() - 1) oss << ","; 1246 } 1247 } 1248 oss << "]}"; 1249 } else if (e == constants().absent) { 1250 oss << "null"; 1251 } else { 1252 p.print(e); 1253 } 1254 return oss.str(); 1255} 1256 1257std::string b_show_json(EnvI& env, Call* call) { 1258 Expression* exp = call->arg(0); 1259 GCLock lock; 1260 Expression* e = eval_par(env, exp); 1261 if (e->type().isvar()) { 1262 std::ostringstream oss; 1263 Printer p(oss, 0, false); 1264 p.print(e); 1265 return oss.str(); 1266 } else { 1267 if (ArrayLit* al = e->dyn_cast<ArrayLit>()) { 1268 std::vector<unsigned int> dims(al->dims() - 1); 1269 if (dims.size() != 0) { 1270 dims[0] = al->max(al->dims() - 1) - al->min(al->dims() - 1) + 1; 1271 } 1272 1273 for (int i = 1; i < al->dims() - 1; i++) { 1274 dims[i] = dims[i - 1] * (al->max(al->dims() - 1 - i) - al->min(al->dims() - 1 - i) + 1); 1275 } 1276 1277 std::ostringstream oss; 1278 oss << "["; 1279 for (unsigned int i = 0; i < al->size(); i++) { 1280 for (unsigned int j = 0; j < dims.size(); j++) { 1281 if (i % dims[j] == 0) { 1282 oss << "["; 1283 } 1284 } 1285 oss << b_show_json_basic(env, (*al)[i]); 1286 for (unsigned int j = 0; j < dims.size(); j++) { 1287 if (i % dims[j] == dims[j] - 1) { 1288 oss << "]"; 1289 } 1290 } 1291 1292 if (i < al->size() - 1) oss << ", "; 1293 } 1294 oss << "]"; 1295 1296 return oss.str(); 1297 } else { 1298 return b_show_json_basic(env, e); 1299 } 1300 } 1301} 1302 1303Expression* b_outputJSON(EnvI& env, Call* call) { return createJSONOutput(env, false, false); } 1304Expression* b_outputJSONParameters(EnvI& env, Call* call) { 1305 std::vector<Expression*> outputVars; 1306 outputVars.push_back(new StringLit(Location().introduce(), "{\n")); 1307 1308 class JSONParVisitor : public ItemVisitor { 1309 protected: 1310 EnvI& e; 1311 std::vector<Expression*>& outputVars; 1312 bool first_var; 1313 1314 public: 1315 JSONParVisitor(EnvI& e0, std::vector<Expression*>& outputVars0) 1316 : e(e0), outputVars(outputVars0), first_var(true) {} 1317 void vVarDeclI(VarDeclI* vdi) { 1318 VarDecl* vd = vdi->e(); 1319 if (vd->ann().contains(constants().ann.rhs_from_assignment)) { 1320 std::ostringstream s; 1321 if (first_var) { 1322 first_var = false; 1323 } else { 1324 s << ",\n"; 1325 } 1326 s << " \"" << vd->id()->str().str() << "\"" 1327 << " : "; 1328 StringLit* sl = new StringLit(Location().introduce(), s.str()); 1329 outputVars.push_back(sl); 1330 1331 std::vector<Expression*> showArgs(1); 1332 showArgs[0] = vd->id(); 1333 Call* show = new Call(Location().introduce(), "showJSON", showArgs); 1334 show->type(Type::parstring()); 1335 FunctionI* fi = e.model->matchFn(e, show, false); 1336 assert(fi); 1337 show->decl(fi); 1338 outputVars.push_back(show); 1339 } 1340 } 1341 } jsonov(env, outputVars); 1342 1343 iterItems(jsonov, env.model); 1344 outputVars.push_back(new StringLit(Location().introduce(), "\n}\n")); 1345 return new ArrayLit(Location().introduce(), outputVars); 1346} 1347 1348std::string b_format(EnvI& env, Call* call) { 1349 int width = 0; 1350 int prec = -1; 1351 GCLock lock; 1352 Expression* e; 1353 if (call->n_args() > 1) { 1354 width = static_cast<int>(eval_int(env, call->arg(0)).toInt()); 1355 if (call->n_args() == 2) { 1356 e = eval_par(env, call->arg(1)); 1357 } else { 1358 assert(call->n_args() == 3); 1359 prec = static_cast<int>(eval_int(env, call->arg(1)).toInt()); 1360 if (prec < 0) 1361 throw EvalError(env, call->arg(1)->loc(), "output precision cannot be negative"); 1362 e = eval_par(env, call->arg(2)); 1363 } 1364 } else { 1365 e = eval_par(env, call->arg(0)); 1366 } 1367 if (e->type() == Type::parint()) { 1368 long long int i = eval_int(env, e).toInt(); 1369 std::ostringstream formatted; 1370 if (width > 0) { 1371 formatted.width(width); 1372 } else if (width < 0) { 1373 formatted.width(-width); 1374 formatted.flags(std::ios::left); 1375 } 1376 if (prec != -1) formatted.precision(prec); 1377 formatted << i; 1378 return formatted.str(); 1379 } else if (e->type() == Type::parfloat()) { 1380 FloatVal i = eval_float(env, e); 1381 std::ostringstream formatted; 1382 if (width > 0) { 1383 formatted.width(width); 1384 } else if (width < 0) { 1385 formatted.width(-width); 1386 formatted.flags(std::ios::left); 1387 } 1388 formatted.setf(std::ios::fixed); 1389 formatted.precision(std::numeric_limits<double>::digits10 + 2); 1390 if (prec != -1) formatted.precision(prec); 1391 formatted << i; 1392 return formatted.str(); 1393 } else { 1394 std::string s = show(env, e); 1395 if (prec >= 0 && prec < s.size()) s = s.substr(0, prec); 1396 std::ostringstream oss; 1397 if (s.size() < std::abs(width)) { 1398 int addLeft = width < 0 ? 0 : (width - static_cast<int>(s.size())); 1399 if (addLeft < 0) addLeft = 0; 1400 int addRight = width < 0 ? (-width - static_cast<int>(s.size())) : 0; 1401 if (addRight < 0) addRight = 0; 1402 for (int i = addLeft; i--;) oss << " "; 1403 oss << s; 1404 for (int i = addRight; i--;) oss << " "; 1405 return oss.str(); 1406 } else { 1407 return s; 1408 } 1409 } 1410} 1411 1412std::string b_format_justify_string(EnvI& env, Call* call) { 1413 int width = 0; 1414 GCLock lock; 1415 Expression* e; 1416 width = static_cast<int>(eval_int(env, call->arg(0)).toInt()); 1417 e = eval_par(env, call->arg(1)); 1418 std::string s = eval_string(env, e); 1419 std::ostringstream oss; 1420 if (s.size() < std::abs(width)) { 1421 int addLeft = width < 0 ? 0 : (width - static_cast<int>(s.size())); 1422 if (addLeft < 0) addLeft = 0; 1423 int addRight = width < 0 ? (-width - static_cast<int>(s.size())) : 0; 1424 if (addRight < 0) addRight = 0; 1425 for (int i = addLeft; i--;) oss << " "; 1426 oss << s; 1427 for (int i = addRight; i--;) oss << " "; 1428 return oss.str(); 1429 } else { 1430 return s; 1431 } 1432} 1433 1434std::string b_show_int(EnvI& env, Call* call) { 1435 assert(call->n_args() == 2); 1436 GCLock lock; 1437 Expression* e = eval_par(env, call->arg(1)); 1438 std::ostringstream oss; 1439 if (IntLit* iv = e->dyn_cast<IntLit>()) { 1440 int justify = static_cast<int>(eval_int(env, call->arg(0)).toInt()); 1441 std::ostringstream oss_length; 1442 oss_length << iv->v(); 1443 int iv_length = static_cast<int>(oss_length.str().size()); 1444 int addLeft = justify < 0 ? 0 : (justify - iv_length); 1445 if (addLeft < 0) addLeft = 0; 1446 int addRight = justify < 0 ? (-justify - iv_length) : 0; 1447 if (addRight < 0) addRight = 0; 1448 for (int i = addLeft; i--;) oss << " "; 1449 oss << iv->v(); 1450 for (int i = addRight; i--;) oss << " "; 1451 } else { 1452 Printer p(oss, 0, false); 1453 p.print(e); 1454 } 1455 return oss.str(); 1456} 1457 1458std::string b_show_float(EnvI& env, Call* call) { 1459 assert(call->n_args() == 3); 1460 GCLock lock; 1461 Expression* e = eval_par(env, call->arg(2)); 1462 std::ostringstream oss; 1463 if (FloatLit* fv = e->dyn_cast<FloatLit>()) { 1464 int justify = static_cast<int>(eval_int(env, call->arg(0)).toInt()); 1465 int prec = static_cast<int>(eval_int(env, call->arg(1)).toInt()); 1466 if (prec < 0) 1467 throw EvalError(env, call->arg(1)->loc(), 1468 "number of digits in show_float cannot be negative"); 1469 std::ostringstream oss_length; 1470 oss_length << std::setprecision(prec) << std::fixed << fv->v(); 1471 int fv_length = static_cast<int>(oss_length.str().size()); 1472 int addLeft = justify < 0 ? 0 : (justify - fv_length); 1473 if (addLeft < 0) addLeft = 0; 1474 int addRight = justify < 0 ? (-justify - fv_length) : 0; 1475 if (addRight < 0) addRight = 0; 1476 for (int i = addLeft; i--;) oss << " "; 1477 oss << std::setprecision(prec) << std::fixed << fv->v(); 1478 for (int i = addRight; i--;) oss << " "; 1479 } else { 1480 Printer p(oss, 0, false); 1481 p.print(e); 1482 } 1483 return oss.str(); 1484} 1485 1486std::string b_file_path(EnvI&, Call* call) { 1487 return FileUtils::file_path(call->loc().filename().str()); 1488} 1489 1490std::string b_concat(EnvI& env, Call* call) { 1491 assert(call->n_args() == 1); 1492 GCLock lock; 1493 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1494 std::ostringstream oss; 1495 for (unsigned int i = 0; i < al->size(); i++) { 1496 oss << eval_string(env, (*al)[i]); 1497 } 1498 return oss.str(); 1499} 1500 1501std::string b_join(EnvI& env, Call* call) { 1502 assert(call->n_args() == 2); 1503 std::string sep = eval_string(env, call->arg(0)); 1504 GCLock lock; 1505 ArrayLit* al = eval_array_lit(env, call->arg(1)); 1506 std::ostringstream oss; 1507 for (unsigned int i = 0; i < al->size(); i++) { 1508 oss << eval_string(env, (*al)[i]); 1509 if (i < al->size() - 1) oss << sep; 1510 } 1511 return oss.str(); 1512} 1513 1514IntSetVal* b_array_union(EnvI& env, Call* call) { 1515 assert(call->n_args() == 1); 1516 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1517 if (al->size() == 0) return IntSetVal::a(); 1518 IntSetVal* isv = eval_intset(env, (*al)[0]); 1519 for (unsigned int i = 0; i < al->size(); i++) { 1520 IntSetRanges i0(isv); 1521 IntSetRanges i1(eval_intset(env, (*al)[i])); 1522 Ranges::Union<IntVal, IntSetRanges, IntSetRanges> u(i0, i1); 1523 isv = IntSetVal::ai(u); 1524 } 1525 return isv; 1526} 1527 1528IntSetVal* b_array_intersect(EnvI& env, Call* call) { 1529 assert(call->n_args() == 1); 1530 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1531 std::vector<IntSetVal::Range> ranges; 1532 if (al->size() > 0) { 1533 IntSetVal* i0 = eval_intset(env, (*al)[0]); 1534 if (i0->size() > 0) { 1535 IntSetRanges i0r(i0); 1536 IntVal min = i0r.min(); 1537 while (i0r()) { 1538 // Initialize with last interval 1539 IntVal max = i0r.max(); 1540 // Intersect with all other intervals 1541 restart: 1542 for (int j = al->size(); j--;) { 1543 IntSetRanges ij(eval_intset(env, (*al)[j])); 1544 // Skip intervals that are too small 1545 while (ij() && (ij.max() < min)) ++ij; 1546 if (!ij()) goto done; 1547 if (ij.min() > max) { 1548 min = ij.min(); 1549 max = ij.max(); 1550 goto restart; 1551 } 1552 // Now the intervals overlap 1553 if (min < ij.min()) min = ij.min(); 1554 if (max > ij.max()) max = ij.max(); 1555 } 1556 ranges.push_back(IntSetVal::Range(min, max)); 1557 // The next interval must be at least two elements away 1558 min = max + 2; 1559 } 1560 done: 1561 return IntSetVal::a(ranges); 1562 } else { 1563 return IntSetVal::a(); 1564 } 1565 } else { 1566 return IntSetVal::a(); 1567 } 1568} 1569 1570Expression* b_sort_by_int(EnvI& env, Call* call) { 1571 assert(call->n_args() == 2); 1572 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1573 ArrayLit* order_e = eval_array_lit(env, call->arg(1)); 1574 std::vector<IntVal> order(order_e->size()); 1575 std::vector<int> a(order_e->size()); 1576 for (unsigned int i = 0; i < order.size(); i++) { 1577 a[i] = i; 1578 order[i] = eval_int(env, (*order_e)[i]); 1579 } 1580 struct Ord { 1581 std::vector<IntVal>& order; 1582 Ord(std::vector<IntVal>& order0) : order(order0) {} 1583 bool operator()(int i, int j) { return order[i] < order[j]; } 1584 } _ord(order); 1585 std::stable_sort(a.begin(), a.end(), _ord); 1586 std::vector<Expression*> sorted(a.size()); 1587 for (unsigned int i = static_cast<unsigned int>(sorted.size()); i--;) sorted[i] = (*al)[a[i]]; 1588 ArrayLit* al_sorted = new ArrayLit(al->loc(), sorted); 1589 al_sorted->type(al->type()); 1590 return al_sorted; 1591} 1592 1593Expression* b_sort_by_float(EnvI& env, Call* call) { 1594 assert(call->n_args() == 2); 1595 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1596 ArrayLit* order_e = eval_array_lit(env, call->arg(1)); 1597 std::vector<FloatVal> order(order_e->size()); 1598 std::vector<int> a(order_e->size()); 1599 for (unsigned int i = 0; i < order.size(); i++) { 1600 a[i] = i; 1601 order[i] = eval_float(env, (*order_e)[i]); 1602 } 1603 struct Ord { 1604 std::vector<FloatVal>& order; 1605 Ord(std::vector<FloatVal>& order0) : order(order0) {} 1606 bool operator()(int i, int j) { return order[i] < order[j]; } 1607 } _ord(order); 1608 std::stable_sort(a.begin(), a.end(), _ord); 1609 std::vector<Expression*> sorted(a.size()); 1610 for (unsigned int i = static_cast<unsigned int>(sorted.size()); i--;) sorted[i] = (*al)[a[i]]; 1611 ArrayLit* al_sorted = new ArrayLit(al->loc(), sorted); 1612 al_sorted->type(al->type()); 1613 return al_sorted; 1614} 1615 1616Expression* b_sort(EnvI& env, Call* call) { 1617 assert(call->n_args() == 1); 1618 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1619 std::vector<Expression*> sorted(al->size()); 1620 for (unsigned int i = static_cast<unsigned int>(sorted.size()); i--;) sorted[i] = (*al)[i]; 1621 struct Ord { 1622 EnvI& env; 1623 Ord(EnvI& env0) : env(env0) {} 1624 bool operator()(Expression* e0, Expression* e1) { 1625 switch (e0->type().bt()) { 1626 case Type::BT_INT: 1627 return eval_int(env, e0) < eval_int(env, e1); 1628 case Type::BT_BOOL: 1629 return eval_bool(env, e0) < eval_bool(env, e1); 1630 case Type::BT_FLOAT: 1631 return eval_float(env, e0) < eval_float(env, e1); 1632 default: 1633 throw EvalError(env, e0->loc(), "unsupported type for sorting"); 1634 } 1635 } 1636 } _ord(env); 1637 std::sort(sorted.begin(), sorted.end(), _ord); 1638 ArrayLit* al_sorted = new ArrayLit(al->loc(), sorted); 1639 al_sorted->type(al->type()); 1640 return al_sorted; 1641} 1642 1643std::default_random_engine& rnd_generator(void) { 1644 // TODO: initiate with seed if given as annotation/in command line 1645 static std::default_random_engine g; 1646 return g; 1647} 1648 1649FloatVal b_normal_float_float(EnvI& env, Call* call) { 1650 assert(call->n_args() == 2); 1651 const double mean = eval_float(env, call->arg(0)).toDouble(); 1652 const double stdv = eval_float(env, call->arg(1)).toDouble(); 1653 std::normal_distribution<double> distribution(mean, stdv); 1654 // return a sample from the distribution 1655 return distribution(rnd_generator()); 1656} 1657 1658FloatVal b_normal_int_float(EnvI& env, Call* call) { 1659 assert(call->n_args() == 2); 1660 const double mean = double(eval_int(env, call->arg(0)).toInt()); 1661 const double stdv = eval_float(env, call->arg(1)).toDouble(); 1662 std::normal_distribution<double> distribution(mean, stdv); 1663 // return a sample from the distribution 1664 return distribution(rnd_generator()); 1665} 1666 1667FloatVal b_uniform_float(EnvI& env, Call* call) { 1668 assert(call->n_args() == 2); 1669 const double lb = eval_float(env, call->arg(0)).toDouble(); 1670 const double ub = eval_float(env, call->arg(1)).toDouble(); 1671 if (lb > ub) { 1672 std::stringstream ssm; 1673 ssm << "lowerbound of uniform distribution \"" << lb 1674 << "\" is higher than its upperbound: " << ub; 1675 throw EvalError(env, call->arg(0)->loc(), ssm.str()); 1676 } 1677 std::uniform_real_distribution<double> distribution(lb, ub); 1678 // return a sample from the distribution 1679 return distribution(rnd_generator()); 1680} 1681 1682IntVal b_uniform_int(EnvI& env, Call* call) { 1683 assert(call->n_args() == 2); 1684 const long long int lb = eval_int(env, call->arg(0)).toInt(); 1685 const long long int ub = eval_int(env, call->arg(1)).toInt(); 1686 if (lb > ub) { 1687 std::stringstream ssm; 1688 ssm << "lowerbound of uniform distribution \"" << lb 1689 << "\" is higher than its upperbound: " << ub; 1690 throw EvalError(env, call->arg(0)->loc(), ssm.str()); 1691 } 1692 std::uniform_int_distribution<long long int> distribution(lb, ub); 1693 // return a sample from the distribution 1694 return IntVal(distribution(rnd_generator())); 1695} 1696 1697IntVal b_poisson_int(EnvI& env, Call* call) { 1698 assert(call->n_args() == 1); 1699 long long int mean = eval_int(env, call->arg(0)).toInt(); 1700 std::poisson_distribution<long long int> distribution(mean); 1701 // return a sample from the distribution 1702 return IntVal(distribution(rnd_generator())); 1703} 1704 1705IntVal b_poisson_float(EnvI& env, Call* call) { 1706 assert(call->n_args() == 1); 1707 double mean = eval_float(env, call->arg(0)).toDouble(); 1708 std::poisson_distribution<long long int> distribution(mean); 1709 // return a sample from the distribution 1710 return IntVal(distribution(rnd_generator())); 1711} 1712 1713FloatVal b_gamma_float_float(EnvI& env, Call* call) { 1714 assert(call->n_args() == 2); 1715 const double alpha = eval_float(env, call->arg(0)).toDouble(); 1716 const double beta = eval_float(env, call->arg(1)).toDouble(); 1717 std::gamma_distribution<double> distribution(alpha, beta); 1718 // return a sample from the distribution 1719 return distribution(rnd_generator()); 1720} 1721 1722FloatVal b_gamma_int_float(EnvI& env, Call* call) { 1723 assert(call->n_args() == 2); 1724 const double alpha = eval_float(env, call->arg(0)).toDouble(); 1725 const double beta = eval_float(env, call->arg(1)).toDouble(); 1726 std::gamma_distribution<double> distribution(alpha, beta); 1727 // return a sample from the distribution 1728 return distribution(rnd_generator()); 1729} 1730 1731FloatVal b_weibull_int_float(EnvI& env, Call* call) { 1732 assert(call->n_args() == 2); 1733 const double shape = double(eval_int(env, call->arg(0)).toInt()); 1734 if (shape < 0) { 1735 std::stringstream ssm; 1736 ssm << "The shape factor for the weibull distribution \"" << shape 1737 << "\" has to be greater than zero."; 1738 throw EvalError(env, call->arg(0)->loc(), ssm.str()); 1739 } 1740 const double scale = eval_float(env, call->arg(1)).toDouble(); 1741 if (scale < 0) { 1742 std::stringstream ssm; 1743 ssm << "The scale factor for the weibull distribution \"" << scale 1744 << "\" has to be greater than zero."; 1745 throw EvalError(env, call->arg(1)->loc(), ssm.str()); 1746 } 1747 std::weibull_distribution<double> distribution(shape, scale); 1748 // return a sample from the distribution 1749 return distribution(rnd_generator()); 1750} 1751 1752FloatVal b_weibull_float_float(EnvI& env, Call* call) { 1753 assert(call->n_args() == 2); 1754 const double shape = eval_float(env, call->arg(0)).toDouble(); 1755 if (shape < 0) { 1756 std::stringstream ssm; 1757 ssm << "The shape factor for the weibull distribution \"" << shape 1758 << "\" has to be greater than zero."; 1759 throw EvalError(env, call->arg(0)->loc(), ssm.str()); 1760 } 1761 const double scale = eval_float(env, call->arg(1)).toDouble(); 1762 if (scale < 0) { 1763 std::stringstream ssm; 1764 ssm << "The scale factor for the weibull distribution \"" << scale 1765 << "\" has to be greater than zero."; 1766 throw EvalError(env, call->arg(1)->loc(), ssm.str()); 1767 } 1768 std::weibull_distribution<double> distribution(shape, scale); 1769 // return a sample from the distribution 1770 return distribution(rnd_generator()); 1771} 1772 1773FloatVal b_exponential_float(EnvI& env, Call* call) { 1774 assert(call->n_args() == 1); 1775 const double lambda = eval_float(env, call->arg(0)).toDouble(); 1776 if (lambda < 0) { 1777 std::stringstream ssm; 1778 ssm << "The lambda-parameter for the exponential distribution function \"" << lambda 1779 << "\" has to be greater than zero."; 1780 throw EvalError(env, call->arg(0)->loc(), ssm.str()); 1781 } 1782 std::exponential_distribution<double> distribution(lambda); 1783 // return a sample from the distribution 1784 return distribution(rnd_generator()); 1785} 1786 1787FloatVal b_exponential_int(EnvI& env, Call* call) { 1788 assert(call->n_args() == 1); 1789 const double lambda = double(eval_int(env, call->arg(0)).toInt()); 1790 if (lambda < 0) { 1791 std::stringstream ssm; 1792 ssm << "The lambda-parameter for the exponential distribution function \"" << lambda 1793 << "\" has to be greater than zero."; 1794 throw EvalError(env, call->arg(0)->loc(), ssm.str()); 1795 } 1796 std::exponential_distribution<double> distribution(lambda); 1797 // return a sample from the distribution 1798 return distribution(rnd_generator()); 1799} 1800 1801FloatVal b_lognormal_float_float(EnvI& env, Call* call) { 1802 assert(call->n_args() == 2); 1803 const double mean = eval_float(env, call->arg(0)).toDouble(); 1804 const double stdv = eval_float(env, call->arg(1)).toDouble(); 1805 std::lognormal_distribution<double> distribution(mean, stdv); 1806 // return a sample from the distribution 1807 return distribution(rnd_generator()); 1808} 1809 1810FloatVal b_lognormal_int_float(EnvI& env, Call* call) { 1811 assert(call->n_args() == 2); 1812 const double mean = double(eval_int(env, call->arg(0)).toInt()); 1813 const double stdv = eval_float(env, call->arg(1)).toDouble(); 1814 std::lognormal_distribution<double> distribution(mean, stdv); 1815 // return a sample from the distribution 1816 return distribution(rnd_generator()); 1817} 1818 1819FloatVal b_chisquared_float(EnvI& env, Call* call) { 1820 assert(call->n_args() == 1); 1821 const double lambda = eval_float(env, call->arg(0)).toDouble(); 1822 std::exponential_distribution<double> distribution(lambda); 1823 // return a sample from the distribution 1824 return distribution(rnd_generator()); 1825} 1826 1827FloatVal b_chisquared_int(EnvI& env, Call* call) { 1828 assert(call->n_args() == 1); 1829 const double lambda = double(eval_int(env, call->arg(0)).toInt()); 1830 std::exponential_distribution<double> distribution(lambda); 1831 // return a sample from the distribution 1832 return distribution(rnd_generator()); 1833} 1834 1835FloatVal b_cauchy_float_float(EnvI& env, Call* call) { 1836 assert(call->n_args() == 2); 1837 const double mean = eval_float(env, call->arg(0)).toDouble(); 1838 const double scale = eval_float(env, call->arg(1)).toDouble(); 1839 std::cauchy_distribution<double> distribution(mean, scale); 1840 // return a sample from the distribution 1841 return distribution(rnd_generator()); 1842} 1843 1844FloatVal b_cauchy_int_float(EnvI& env, Call* call) { 1845 assert(call->n_args() == 2); 1846 const double mean = double(eval_int(env, call->arg(0)).toInt()); 1847 const double scale = eval_float(env, call->arg(1)).toDouble(); 1848 std::cauchy_distribution<double> distribution(mean, scale); 1849 // return a sample from the distribution 1850 return distribution(rnd_generator()); 1851} 1852 1853FloatVal b_fdistribution_float_float(EnvI& env, Call* call) { 1854 assert(call->n_args() == 2); 1855 const double d1 = eval_float(env, call->arg(0)).toDouble(); 1856 const double d2 = eval_float(env, call->arg(1)).toDouble(); 1857 std::fisher_f_distribution<double> distribution(d1, d2); 1858 // return a sample from the distribution 1859 return distribution(rnd_generator()); 1860} 1861 1862FloatVal b_fdistribution_int_int(EnvI& env, Call* call) { 1863 assert(call->n_args() == 2); 1864 const double d1 = double(eval_int(env, call->arg(0)).toInt()); 1865 const double d2 = double(eval_int(env, call->arg(1)).toInt()); 1866 std::fisher_f_distribution<double> distribution(d1, d2); 1867 // return a sample from the distribution 1868 return distribution(rnd_generator()); 1869} 1870 1871FloatVal b_tdistribution_float(EnvI& env, Call* call) { 1872 assert(call->n_args() == 1); 1873 const double sampleSize = eval_float(env, call->arg(0)).toDouble(); 1874 std::student_t_distribution<double> distribution(sampleSize); 1875 // return a sample from the distribution 1876 return distribution(rnd_generator()); 1877} 1878 1879FloatVal b_tdistribution_int(EnvI& env, Call* call) { 1880 assert(call->n_args() == 1); 1881 const double sampleSize = double(eval_int(env, call->arg(0)).toInt()); 1882 std::student_t_distribution<double> distribution(sampleSize); 1883 // return a sample from the distribution 1884 return distribution(rnd_generator()); 1885} 1886 1887IntVal b_discrete_distribution(EnvI& env, Call* call) { 1888 assert(call->n_args() == 1); 1889 GCLock lock; 1890 ArrayLit* al = eval_array_lit(env, call->arg(0)); 1891 if (al->dims() != 1) { 1892 std::stringstream ssm; 1893 ssm << "expecting 1-dimensional array of weights for discrete distribution instead of: " << *al 1894 << std::endl; 1895 throw EvalError(env, al->loc(), ssm.str()); 1896 } 1897 std::vector<long long int> weights(al->size()); 1898 for (unsigned int i = 0; i < al->size(); i++) { 1899 weights[i] = eval_int(env, (*al)[i]).toInt(); 1900 } 1901#ifdef _MSC_VER 1902 std::size_t i(0); 1903 std::discrete_distribution<long long int> distribution( 1904 weights.size(), 0.0, 1.0, [&weights, &i](double) { return weights[i++]; }); 1905#else 1906 std::discrete_distribution<long long int> distribution(weights.begin(), weights.end()); 1907#endif 1908 // return a sample from the distribution 1909 IntVal iv = IntVal(distribution(rnd_generator())); 1910 return iv; 1911} 1912 1913bool b_bernoulli(EnvI& env, Call* call) { 1914 assert(call->n_args() == 1); 1915 const double p = eval_float(env, call->arg(0)).toDouble(); 1916 std::bernoulli_distribution distribution(p); 1917 // return a sample from the distribution 1918 return distribution(rnd_generator()); 1919} 1920 1921IntVal b_binomial(EnvI& env, Call* call) { 1922 assert(call->n_args() == 2); 1923 double t = double(eval_int(env, call->arg(0)).toInt()); 1924 double p = eval_float(env, call->arg(1)).toDouble(); 1925 std::binomial_distribution<long long int> distribution(t, p); 1926 // return a sample from the distribution 1927 return IntVal(distribution(rnd_generator())); 1928} 1929 1930FloatVal b_atan(EnvI& env, Call* call) { 1931 assert(call->n_args() == 1); 1932 GCLock lock; 1933 FloatVal f = eval_float(env, call->arg(0)); 1934 return std::atan(f.toDouble()); 1935} 1936 1937FloatVal b_cos(EnvI& env, Call* call) { 1938 assert(call->n_args() == 1); 1939 GCLock lock; 1940 FloatVal f = eval_float(env, call->arg(0)); 1941 return std::cos(f.toDouble()); 1942} 1943 1944FloatVal b_sin(EnvI& env, Call* call) { 1945 assert(call->n_args() == 1); 1946 GCLock lock; 1947 FloatVal f = eval_float(env, call->arg(0)); 1948 return std::sin(f.toDouble()); 1949} 1950 1951FloatVal b_asin(EnvI& env, Call* call) { 1952 assert(call->n_args() == 1); 1953 GCLock lock; 1954 FloatVal f = eval_float(env, call->arg(0)); 1955 return std::asin(f.toDouble()); 1956} 1957 1958FloatVal b_acos(EnvI& env, Call* call) { 1959 assert(call->n_args() == 1); 1960 GCLock lock; 1961 FloatVal f = eval_float(env, call->arg(0)); 1962 return std::acos(f.toDouble()); 1963} 1964 1965FloatVal b_tan(EnvI& env, Call* call) { 1966 assert(call->n_args() == 1); 1967 GCLock lock; 1968 FloatVal f = eval_float(env, call->arg(0)); 1969 return std::tan(f.toDouble()); 1970} 1971 1972IntVal b_to_enum(EnvI& env, Call* call) { 1973 assert(call->n_args() == 2); 1974 IntSetVal* isv = eval_intset(env, call->arg(0)); 1975 IntVal v = eval_int(env, call->arg(1)); 1976 if (!isv->contains(v)) 1977 throw ResultUndefinedError(env, call->loc(), "value outside of enum range"); 1978 return v; 1979} 1980 1981IntVal b_enum_next(EnvI& env, Call* call) { 1982 IntSetVal* isv = eval_intset(env, call->arg(0)); 1983 IntVal v = eval_int(env, call->arg(1)); 1984 if (!isv->contains(v + 1)) 1985 throw ResultUndefinedError(env, call->loc(), "value outside of enum range"); 1986 return v + 1; 1987} 1988 1989IntVal b_enum_prev(EnvI& env, Call* call) { 1990 IntSetVal* isv = eval_intset(env, call->arg(0)); 1991 IntVal v = eval_int(env, call->arg(1)); 1992 if (!isv->contains(v - 1)) 1993 throw ResultUndefinedError(env, call->loc(), "value outside of enum range"); 1994 return v - 1; 1995} 1996 1997IntVal b_mzn_compiler_version(EnvI&, Call*) { 1998 return atoi(MZN_VERSION_MAJOR) * 10000 + atoi(MZN_VERSION_MINOR) * 1000 + atoi(MZN_VERSION_PATCH); 1999} 2000 2001Expression* b_slice(EnvI& env, Call* call) { 2002 ArrayLit* al = eval_array_lit(env, call->arg(0)); 2003 2004 ArrayLit* slice = eval_array_lit(env, call->arg(1)); 2005 std::vector<std::pair<int, int>> newSlice(slice->size()); 2006 for (unsigned int i = 0; i < slice->size(); i++) { 2007 IntSetVal* isv = eval_intset(env, (*slice)[i]); 2008 if (isv->size() == 0) { 2009 newSlice[i] = std::pair<int, int>(1, 0); 2010 } else { 2011 if (isv->size() > 1) 2012 throw ResultUndefinedError(env, call->loc(), "array slice must be contiguous"); 2013 int sl_min = isv->min().isFinite() ? static_cast<int>(isv->min().toInt()) : al->min(i); 2014 int sl_max = isv->max().isFinite() ? static_cast<int>(isv->max().toInt()) : al->max(i); 2015 if (sl_min < al->min(i) || sl_max > al->max(i)) 2016 throw ResultUndefinedError(env, call->loc(), "array slice out of bounds"); 2017 newSlice[i] = std::pair<int, int>(sl_min, sl_max); 2018 } 2019 } 2020 2021 std::vector<std::pair<int, int>> newDims(call->n_args() - 2); 2022 for (unsigned int i = 0; i < newDims.size(); i++) { 2023 IntSetVal* isv = eval_intset(env, call->arg(2 + i)); 2024 if (isv->size() == 0) { 2025 newDims[i] = std::pair<int, int>(1, 0); 2026 } else { 2027 newDims[i] = std::pair<int, int>(static_cast<int>(isv->min().toInt()), 2028 static_cast<int>(isv->max().toInt())); 2029 } 2030 } 2031 ArrayLit* ret = new ArrayLit(al->loc(), al, newDims, newSlice); 2032 ret->type(call->type()); 2033 return ret; 2034} 2035 2036Expression* b_regular_from_string(EnvI& env, Call* call) { 2037#ifdef HAS_GECODE 2038 using namespace Gecode; 2039 ArrayLit* vars = eval_array_lit(env, call->arg(0)); 2040 std::string expr = eval_string(env, call->arg(1)); 2041 2042 IntSetVal* dom; 2043 if (vars->size() == 0) { 2044 dom = IntSetVal::a(); 2045 } else { 2046 dom = b_dom_varint(env, (*vars)[0]); 2047 for (unsigned int i = 1; i < vars->size(); i++) { 2048 IntSetRanges isr(dom); 2049 IntSetRanges r(b_dom_varint(env, (*vars)[i])); 2050 Ranges::Union<IntVal, IntSetRanges, IntSetRanges> u(isr, r); 2051 dom = IntSetVal::ai(u); 2052 } 2053 } 2054 int card = dom->max().toInt() - dom->min().toInt() + 1; 2055 int offset = 1 - dom->min().toInt(); 2056 2057 std::unique_ptr<REG> regex; 2058 try { 2059 regex = regex_from_string(expr, *dom, env.reverseEnum); 2060 } catch (const std::exception& e) { 2061 throw SyntaxError(call->arg(1)->loc(), e.what()); 2062 } 2063 DFA dfa = DFA(*regex); 2064 2065 std::vector<std::vector<Expression*>> reg_trans( 2066 dfa.n_states(), std::vector<Expression*>(card, IntLit::a(IntVal(0)))); 2067 2068 DFA::Transitions trans(dfa); 2069 while (trans()) { 2070 // std::cerr << trans.i_state() + 1 << " -- " << trans.symbol() << " --> " << 2071 // trans.o_state() + 1 << "\n"; 2072 if (trans.symbol() >= dom->min().toInt() && trans.symbol() <= dom->max().toInt()) { 2073 reg_trans[trans.i_state()][trans.symbol() + offset - 1] = 2074 IntLit::a(IntVal(trans.o_state() + 1)); 2075 } 2076 ++trans; 2077 } 2078 2079 std::vector<Expression*> args(6); 2080 if (offset == 0) { 2081 args[0] = vars; // x 2082 } else { 2083 std::vector<Expression*> nvars(vars->size()); 2084 IntLit* loffset = IntLit::a(IntVal(offset)); 2085 for (int i = 0; i < nvars.size(); ++i) { 2086 nvars[i] = new BinOp(call->loc().introduce(), (*vars)[i], BOT_PLUS, loffset); 2087 nvars[i]->type(Type::varint()); 2088 } 2089 args[0] = new ArrayLit(call->loc().introduce(), nvars); // x 2090 args[0]->type(Type::varint(1)); 2091 } 2092 args[1] = IntLit::a(IntVal(dfa.n_states())); // Q 2093 args[1]->type(Type::parint()); 2094 args[2] = IntLit::a(IntVal(card)); // S 2095 args[2]->type(Type::parint()); 2096 args[3] = new ArrayLit(call->loc().introduce(), reg_trans); // d 2097 args[3]->type(Type::parint(2)); 2098 args[4] = IntLit::a(IntVal(1)); // q0 2099 args[4]->type(Type::parint()); 2100 args[5] = new SetLit(call->loc().introduce(), 2101 IntSetVal::a(IntVal(dfa.final_fst() + 1), IntVal(dfa.final_lst()))); // F 2102 args[5]->type(Type::parsetint()); 2103 2104 auto nc = new Call(call->loc().introduce(), "regular", args); 2105 nc->type(Type::varbool()); 2106 2107 return nc; 2108#else 2109 throw FlatteningError( 2110 env, call->loc(), 2111 "MiniZinc was compiled without built-in Gecode, cannot parse regular expression"); 2112#endif 2113} 2114 2115void registerBuiltins(Env& e) { 2116 EnvI& env = e.envi(); 2117 Model* m = env.model; 2118 2119 std::vector<Type> t_intint(2); 2120 t_intint[0] = Type::parint(); 2121 t_intint[1] = Type::parint(); 2122 2123 std::vector<Type> t_intarray(1); 2124 t_intarray[0] = Type::parint(-1); 2125 2126 GCLock lock; 2127 2128 rb(env, m, ASTString("min"), t_intint, b_int_min); 2129 rb(env, m, ASTString("min"), t_intarray, b_int_min); 2130 rb(env, m, ASTString("max"), t_intint, b_int_max); 2131 rb(env, m, ASTString("max"), t_intarray, b_int_max); 2132 rb(env, m, constants().ids.sum, t_intarray, b_sum_int); 2133 rb(env, m, ASTString("product"), t_intarray, b_product_int); 2134 rb(env, m, ASTString("pow"), t_intint, b_pow_int); 2135 2136 { 2137 std::vector<Type> t(2); 2138 t[0] = Type::top(-1); 2139 t[1] = Type::top(-1); 2140 rb(env, m, ASTString("index_sets_agree"), t, b_index_sets_agree); 2141 } 2142 { 2143 std::vector<Type> t_anyarray1(1); 2144 t_anyarray1[0] = Type::optvartop(1); 2145 rb(env, m, ASTString("index_set"), t_anyarray1, b_index_set1); 2146 } 2147 { 2148 std::vector<Type> t_anyarray2(1); 2149 t_anyarray2[0] = Type::optvartop(2); 2150 rb(env, m, ASTString("index_set_1of2"), t_anyarray2, b_index_set1); 2151 rb(env, m, ASTString("index_set_2of2"), t_anyarray2, b_index_set2); 2152 } 2153 { 2154 std::vector<Type> t_anyarray3(1); 2155 t_anyarray3[0] = Type::optvartop(3); 2156 rb(env, m, ASTString("index_set_1of3"), t_anyarray3, b_index_set1); 2157 rb(env, m, ASTString("index_set_2of3"), t_anyarray3, b_index_set2); 2158 rb(env, m, ASTString("index_set_3of3"), t_anyarray3, b_index_set3); 2159 } 2160 { 2161 std::vector<Type> t_anyarray4(1); 2162 t_anyarray4[0] = Type::optvartop(4); 2163 rb(env, m, ASTString("index_set_1of4"), t_anyarray4, b_index_set1); 2164 rb(env, m, ASTString("index_set_2of4"), t_anyarray4, b_index_set2); 2165 rb(env, m, ASTString("index_set_3of4"), t_anyarray4, b_index_set3); 2166 rb(env, m, ASTString("index_set_4of4"), t_anyarray4, b_index_set4); 2167 } 2168 { 2169 std::vector<Type> t_anyarray5(1); 2170 t_anyarray5[0] = Type::optvartop(5); 2171 rb(env, m, ASTString("index_set_1of5"), t_anyarray5, b_index_set1); 2172 rb(env, m, ASTString("index_set_2of5"), t_anyarray5, b_index_set2); 2173 rb(env, m, ASTString("index_set_3of5"), t_anyarray5, b_index_set3); 2174 rb(env, m, ASTString("index_set_4of5"), t_anyarray5, b_index_set4); 2175 rb(env, m, ASTString("index_set_5of5"), t_anyarray5, b_index_set5); 2176 } 2177 { 2178 std::vector<Type> t_anyarray6(1); 2179 t_anyarray6[0] = Type::optvartop(6); 2180 rb(env, m, ASTString("index_set_1of6"), t_anyarray6, b_index_set1); 2181 rb(env, m, ASTString("index_set_2of6"), t_anyarray6, b_index_set2); 2182 rb(env, m, ASTString("index_set_3of6"), t_anyarray6, b_index_set3); 2183 rb(env, m, ASTString("index_set_4of6"), t_anyarray6, b_index_set4); 2184 rb(env, m, ASTString("index_set_5of6"), t_anyarray6, b_index_set5); 2185 rb(env, m, ASTString("index_set_6of6"), t_anyarray6, b_index_set6); 2186 } 2187 { 2188 std::vector<Type> t_arrayXd(1); 2189 t_arrayXd[0] = Type::top(-1); 2190 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d_list); 2191 t_arrayXd[0].ot(Type::OT_OPTIONAL); 2192 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d_list); 2193 t_arrayXd[0] = Type::vartop(-1); 2194 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d_list); 2195 t_arrayXd[0] = Type::optvartop(-1); 2196 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d_list); 2197 } 2198 { 2199 std::vector<Type> t_arrayXd(2); 2200 t_arrayXd[0] = Type::parsetint(); 2201 t_arrayXd[1] = Type::top(-1); 2202 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d); 2203 t_arrayXd[1].ot(Type::OT_OPTIONAL); 2204 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d); 2205 t_arrayXd[1] = Type::vartop(-1); 2206 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d); 2207 t_arrayXd[1] = Type::optvartop(-1); 2208 rb(env, m, ASTString("array1d"), t_arrayXd, b_array1d); 2209 } 2210 { 2211 std::vector<Type> t_arrayXd(2); 2212 t_arrayXd[0] = Type::optvartop(-1); 2213 t_arrayXd[1] = Type::top(-1); 2214 rb(env, m, ASTString("arrayXd"), t_arrayXd, b_arrayXd); 2215 t_arrayXd[1].ot(Type::OT_OPTIONAL); 2216 rb(env, m, ASTString("arrayXd"), t_arrayXd, b_arrayXd); 2217 t_arrayXd[1] = Type::vartop(-1); 2218 rb(env, m, ASTString("arrayXd"), t_arrayXd, b_arrayXd); 2219 t_arrayXd[1] = Type::optvartop(-1); 2220 rb(env, m, ASTString("arrayXd"), t_arrayXd, b_arrayXd); 2221 } 2222 { 2223 std::vector<Type> t_arrayXd(3); 2224 t_arrayXd[0] = Type::parsetint(); 2225 t_arrayXd[1] = Type::parsetint(); 2226 t_arrayXd[2] = Type::top(-1); 2227 rb(env, m, ASTString("array2d"), t_arrayXd, b_array2d); 2228 t_arrayXd[2].ot(Type::OT_OPTIONAL); 2229 rb(env, m, ASTString("array2d"), t_arrayXd, b_array2d); 2230 t_arrayXd[2] = Type::vartop(-1); 2231 rb(env, m, ASTString("array2d"), t_arrayXd, b_array2d); 2232 t_arrayXd[2] = Type::optvartop(-1); 2233 rb(env, m, ASTString("array2d"), t_arrayXd, b_array2d); 2234 } 2235 { 2236 std::vector<Type> t_arrayXd(4); 2237 t_arrayXd[0] = Type::parsetint(); 2238 t_arrayXd[1] = Type::parsetint(); 2239 t_arrayXd[2] = Type::parsetint(); 2240 t_arrayXd[3] = Type::top(-1); 2241 rb(env, m, ASTString("array3d"), t_arrayXd, b_array3d); 2242 t_arrayXd[3].ot(Type::OT_OPTIONAL); 2243 rb(env, m, ASTString("array3d"), t_arrayXd, b_array3d); 2244 t_arrayXd[3] = Type::vartop(-1); 2245 rb(env, m, ASTString("array3d"), t_arrayXd, b_array3d); 2246 t_arrayXd[3] = Type::optvartop(-1); 2247 rb(env, m, ASTString("array3d"), t_arrayXd, b_array3d); 2248 } 2249 { 2250 std::vector<Type> t_arrayXd(5); 2251 t_arrayXd[0] = Type::parsetint(); 2252 t_arrayXd[1] = Type::parsetint(); 2253 t_arrayXd[2] = Type::parsetint(); 2254 t_arrayXd[3] = Type::parsetint(); 2255 t_arrayXd[4] = Type::top(-1); 2256 rb(env, m, ASTString("array4d"), t_arrayXd, b_array4d); 2257 t_arrayXd[4].ot(Type::OT_OPTIONAL); 2258 rb(env, m, ASTString("array4d"), t_arrayXd, b_array4d); 2259 t_arrayXd[4] = Type::vartop(-1); 2260 rb(env, m, ASTString("array4d"), t_arrayXd, b_array4d); 2261 t_arrayXd[4] = Type::optvartop(-1); 2262 rb(env, m, ASTString("array4d"), t_arrayXd, b_array4d); 2263 } 2264 { 2265 std::vector<Type> t_arrayXd(6); 2266 t_arrayXd[0] = Type::parsetint(); 2267 t_arrayXd[1] = Type::parsetint(); 2268 t_arrayXd[2] = Type::parsetint(); 2269 t_arrayXd[3] = Type::parsetint(); 2270 t_arrayXd[4] = Type::parsetint(); 2271 t_arrayXd[5] = Type::top(-1); 2272 rb(env, m, ASTString("array5d"), t_arrayXd, b_array5d); 2273 t_arrayXd[5].ot(Type::OT_OPTIONAL); 2274 rb(env, m, ASTString("array5d"), t_arrayXd, b_array5d); 2275 t_arrayXd[5] = Type::vartop(-1); 2276 rb(env, m, ASTString("array5d"), t_arrayXd, b_array5d); 2277 t_arrayXd[5] = Type::optvartop(-1); 2278 rb(env, m, ASTString("array5d"), t_arrayXd, b_array5d); 2279 } 2280 { 2281 std::vector<Type> t_arrayXd(7); 2282 t_arrayXd[0] = Type::parsetint(); 2283 t_arrayXd[1] = Type::parsetint(); 2284 t_arrayXd[2] = Type::parsetint(); 2285 t_arrayXd[3] = Type::parsetint(); 2286 t_arrayXd[4] = Type::parsetint(); 2287 t_arrayXd[5] = Type::parsetint(); 2288 t_arrayXd[6] = Type::top(-1); 2289 rb(env, m, ASTString("array6d"), t_arrayXd, b_array6d); 2290 t_arrayXd[6].ot(Type::OT_OPTIONAL); 2291 rb(env, m, ASTString("array6d"), t_arrayXd, b_array6d); 2292 t_arrayXd[6] = Type::vartop(-1); 2293 rb(env, m, ASTString("array6d"), t_arrayXd, b_array6d); 2294 t_arrayXd[6] = Type::optvartop(-1); 2295 rb(env, m, ASTString("array6d"), t_arrayXd, b_array6d); 2296 } 2297 { 2298 std::vector<Type> stv(3); 2299 stv[0] = Type::partop(-1); 2300 stv[1] = Type::parsetint(1); 2301 stv[2] = Type::parsetint(); 2302 rb(env, m, ASTString("slice_1d"), stv, b_slice); 2303 stv[0] = Type::vartop(-1); 2304 rb(env, m, ASTString("slice_1d"), stv, b_slice); 2305 stv[0] = Type::optvartop(-1); 2306 rb(env, m, ASTString("slice_1d"), stv, b_slice); 2307 stv[0] = Type::optpartop(-1); 2308 rb(env, m, ASTString("slice_1d"), stv, b_slice); 2309 2310 stv.push_back(Type::parsetint()); 2311 stv[0] = Type::partop(-1); 2312 rb(env, m, ASTString("slice_2d"), stv, b_slice); 2313 stv[0] = Type::vartop(-1); 2314 rb(env, m, ASTString("slice_2d"), stv, b_slice); 2315 stv[0] = Type::optvartop(-1); 2316 rb(env, m, ASTString("slice_2d"), stv, b_slice); 2317 stv[0] = Type::optpartop(-1); 2318 rb(env, m, ASTString("slice_2d"), stv, b_slice); 2319 2320 stv.push_back(Type::parsetint()); 2321 stv[0] = Type::partop(-1); 2322 rb(env, m, ASTString("slice_3d"), stv, b_slice); 2323 stv[0] = Type::vartop(-1); 2324 rb(env, m, ASTString("slice_3d"), stv, b_slice); 2325 stv[0] = Type::optvartop(-1); 2326 rb(env, m, ASTString("slice_3d"), stv, b_slice); 2327 stv[0] = Type::optpartop(-1); 2328 rb(env, m, ASTString("slice_3d"), stv, b_slice); 2329 2330 stv.push_back(Type::parsetint()); 2331 stv[0] = Type::partop(-1); 2332 rb(env, m, ASTString("slice_4d"), stv, b_slice); 2333 stv[0] = Type::vartop(-1); 2334 rb(env, m, ASTString("slice_4d"), stv, b_slice); 2335 stv[0] = Type::optvartop(-1); 2336 rb(env, m, ASTString("slice_4d"), stv, b_slice); 2337 stv[0] = Type::optpartop(-1); 2338 rb(env, m, ASTString("slice_4d"), stv, b_slice); 2339 2340 stv.push_back(Type::parsetint()); 2341 stv[0] = Type::partop(-1); 2342 rb(env, m, ASTString("slice_5d"), stv, b_slice); 2343 stv[0] = Type::vartop(-1); 2344 rb(env, m, ASTString("slice_5d"), stv, b_slice); 2345 stv[0] = Type::optvartop(-1); 2346 rb(env, m, ASTString("slice_5d"), stv, b_slice); 2347 stv[0] = Type::optpartop(-1); 2348 rb(env, m, ASTString("slice_5d"), stv, b_slice); 2349 2350 stv.push_back(Type::parsetint()); 2351 stv[0] = Type::partop(-1); 2352 rb(env, m, ASTString("slice_6d"), stv, b_slice); 2353 stv[0] = Type::vartop(-1); 2354 rb(env, m, ASTString("slice_6d"), stv, b_slice); 2355 stv[0] = Type::optvartop(-1); 2356 rb(env, m, ASTString("slice_6d"), stv, b_slice); 2357 stv[0] = Type::optpartop(-1); 2358 rb(env, m, ASTString("slice_6d"), stv, b_slice); 2359 } 2360 { 2361 std::vector<Type> t(2); 2362 t[0] = Type::parbool(); 2363 t[1] = Type::parstring(); 2364 rb(env, m, constants().ids.assert, t, b_assert_bool); 2365 } 2366 { 2367 std::vector<Type> t(3); 2368 t[0] = Type::parbool(); 2369 t[1] = Type::parstring(); 2370 t[2] = Type::top(); 2371 rb(env, m, constants().ids.assert, t, b_assert); 2372 t[2] = Type::vartop(); 2373 rb(env, m, constants().ids.assert, t, b_assert); 2374 t[2] = Type::optvartop(); 2375 rb(env, m, constants().ids.assert, t, b_assert); 2376 t[2] = Type::top(-1); 2377 rb(env, m, constants().ids.assert, t, b_assert); 2378 t[2] = Type::vartop(-1); 2379 rb(env, m, constants().ids.assert, t, b_assert); 2380 t[2] = Type::optvartop(-1); 2381 rb(env, m, constants().ids.assert, t, b_assert); 2382 } 2383 { 2384 std::vector<Type> t(1); 2385 t[0] = Type::parstring(); 2386 rb(env, m, ASTString("abort"), t, b_abort); 2387 rb(env, m, constants().ids.trace, t, b_trace); 2388 rb(env, m, ASTString("trace_stdout"), t, b_trace_stdout); 2389 } 2390 { 2391 std::vector<Type> t(2); 2392 t[0] = Type::parstring(); 2393 t[1] = Type::top(); 2394 rb(env, m, constants().ids.trace, t, b_trace); 2395 rb(env, m, ASTString("trace_stdout"), t, b_trace_stdout); 2396 t[1] = Type::vartop(); 2397 rb(env, m, constants().ids.trace, t, b_trace); 2398 rb(env, m, ASTString("trace_stdout"), t, b_trace_stdout); 2399 t[1] = Type::optvartop(); 2400 rb(env, m, constants().ids.trace, t, b_trace); 2401 rb(env, m, ASTString("trace_stdout"), t, b_trace_stdout); 2402 } 2403 { 2404 rb(env, m, ASTString("mzn_in_redundant_constraint"), std::vector<Type>(), 2405 b_in_redundant_constraint); 2406 } 2407 { 2408 std::vector<Type> t_length(1); 2409 t_length[0] = Type::optvartop(-1); 2410 rb(env, m, ASTString("length"), t_length, b_length); 2411 } 2412 { 2413 std::vector<Type> t(1); 2414 t[0] = Type::parbool(); 2415 rb(env, m, constants().ids.bool2int, t, b_bool2int); 2416 } 2417 { 2418 std::vector<Type> t(1); 2419 t[0] = Type::parbool(-1); 2420 rb(env, m, constants().ids.forall, t, b_forall_par); 2421 rb(env, m, constants().ids.exists, t, b_exists_par); 2422 rb(env, m, ASTString("xorall"), t, b_xorall_par); 2423 rb(env, m, ASTString("iffall"), t, b_iffall_par); 2424 } 2425 { 2426 std::vector<Type> t(2); 2427 t[0] = Type::parbool(-1); 2428 t[1] = Type::parbool(-1); 2429 rb(env, m, constants().ids.clause, t, b_clause_par); 2430 } 2431 { 2432 std::vector<Type> t(1); 2433 t[0] = Type::varsetint(); 2434 rb(env, m, ASTString("ub"), t, b_ub_set); 2435 rb(env, m, ASTString("lb"), t, b_lb_set); 2436 } 2437 { 2438 std::vector<Type> t(1); 2439 t[0] = Type::varsetint(1); 2440 rb(env, m, ASTString("ub_array"), t, b_array_ub_set); 2441 } 2442 { 2443 std::vector<Type> t(1); 2444 t[0] = Type::varint(); 2445 rb(env, m, ASTString("dom"), t, b_dom_varint); 2446 } 2447 { 2448 std::vector<Type> t(1); 2449 t[0] = Type::varint(-1); 2450 rb(env, m, ASTString("dom_array"), t, b_dom_array); 2451 rb(env, m, ASTString("dom_bounds_array"), t, b_dom_bounds_array); 2452 } 2453 { 2454 std::vector<Type> t(1); 2455 t[0] = Type::parsetint(); 2456 rb(env, m, ASTString("min"), t, b_min_parsetint); 2457 } 2458 { 2459 std::vector<Type> t(1); 2460 t[0] = Type::parsetint(); 2461 rb(env, m, ASTString("max"), t, b_max_parsetint); 2462 } 2463 { 2464 std::vector<Type> t(1); 2465 t[0] = Type::varint(); 2466 t[0].ot(Type::OT_OPTIONAL); 2467 rb(env, m, ASTString("lb"), t, b_lb_varoptint); 2468 } 2469 { 2470 std::vector<Type> t(1); 2471 t[0] = Type::varint(); 2472 t[0].ot(Type::OT_OPTIONAL); 2473 rb(env, m, ASTString("ub"), t, b_ub_varoptint); 2474 } 2475 { 2476 std::vector<Type> t(1); 2477 t[0] = Type::varint(); 2478 rb(env, m, ASTString("lb"), t, b_lb_varoptint); 2479 } 2480 { 2481 std::vector<Type> t(1); 2482 t[0] = Type::varint(); 2483 rb(env, m, ASTString("ub"), t, b_ub_varoptint); 2484 } 2485 { 2486 std::vector<Type> t(1); 2487 t[0] = Type::varint(-1); 2488 t[0].ot(Type::OT_OPTIONAL); 2489 rb(env, m, ASTString("lb_array"), t, b_array_lb_int); 2490 } 2491 { 2492 std::vector<Type> t(1); 2493 t[0] = Type::varint(-1); 2494 t[0].ot(Type::OT_OPTIONAL); 2495 rb(env, m, ASTString("ub_array"), t, b_array_ub_int); 2496 } 2497 { 2498 std::vector<Type> t(1); 2499 t[0] = Type::varfloat(); 2500 rb(env, m, ASTString("lb"), t, b_lb_varoptfloat); 2501 } 2502 { 2503 std::vector<Type> t(1); 2504 t[0] = Type::varfloat(); 2505 rb(env, m, ASTString("ub"), t, b_ub_varoptfloat); 2506 } 2507 { 2508 std::vector<Type> t(1); 2509 t[0] = Type::varfloat(-1); 2510 rb(env, m, ASTString("lb_array"), t, b_array_lb_float); 2511 } 2512 { 2513 std::vector<Type> t(1); 2514 t[0] = Type::varfloat(-1); 2515 rb(env, m, ASTString("ub_array"), t, b_array_ub_float); 2516 } 2517 { 2518 std::vector<Type> t(1); 2519 t[0] = Type::parsetint(); 2520 rb(env, m, ASTString("card"), t, b_card); 2521 } 2522 { 2523 std::vector<Type> t(1); 2524 t[0] = Type::parint(); 2525 rb(env, m, ASTString("abs"), t, b_abs_int); 2526 t[0] = Type::parfloat(); 2527 rb(env, m, ASTString("abs"), t, b_abs_float); 2528 } 2529 { 2530 std::vector<Type> t(1); 2531 t[0] = Type::varint(); 2532 rb(env, m, ASTString("has_bounds"), t, b_has_bounds_int); 2533 } 2534 { 2535 std::vector<Type> t(1); 2536 t[0] = Type::varfloat(); 2537 rb(env, m, ASTString("has_bounds"), t, b_has_bounds_float); 2538 } 2539 { 2540 std::vector<Type> t(1); 2541 t[0] = Type::varsetint(); 2542 rb(env, m, ASTString("has_ub_set"), t, b_has_ub_set); 2543 } 2544 { 2545 std::vector<Type> t(1); 2546 t[0] = Type::optvartop(); 2547 rb(env, m, ASTString("is_fixed"), t, b_is_fixed); 2548 } 2549 { 2550 std::vector<Type> t(1); 2551 t[0] = Type::optvartop(-1); 2552 rb(env, m, ASTString("is_fixed"), t, b_is_fixed_array); 2553 } 2554 { 2555 std::vector<Type> t(1); 2556 t[0] = Type::optvartop(); 2557 rb(env, m, ASTString("fix"), t, b_fix_bool); 2558 rb(env, m, ASTString("fix"), t, b_fix_int); 2559 rb(env, m, ASTString("fix"), t, b_fix_set); 2560 rb(env, m, ASTString("fix"), t, b_fix_float); 2561 } 2562 { 2563 std::vector<Type> t(1); 2564 t[0] = Type::optvartop(1); 2565 rb(env, m, ASTString("fix"), t, b_fix_array); 2566 } 2567 { 2568 std::vector<Type> t(1); 2569 t[0] = Type::parint(); 2570 rb(env, m, ASTString("int2float"), t, b_int2float); 2571 } 2572 { 2573 std::vector<Type> t(1); 2574 t[0] = Type::parfloat(); 2575 rb(env, m, ASTString("ceil"), t, b_ceil); 2576 rb(env, m, ASTString("floor"), t, b_floor); 2577 rb(env, m, ASTString("round"), t, b_round); 2578 rb(env, m, ASTString("log10"), t, b_log10); 2579 rb(env, m, ASTString("log2"), t, b_log2); 2580 rb(env, m, ASTString("ln"), t, b_ln); 2581 rb(env, m, ASTString("exp"), t, b_exp); 2582 rb(env, m, ASTString("sqrt"), t, b_sqrt); 2583 t.push_back(Type::parfloat()); 2584 rb(env, m, ASTString("log"), t, b_log); 2585 rb(env, m, ASTString("pow"), t, b_pow); 2586 } 2587 { 2588 std::vector<Type> t(1); 2589 t[0] = Type::parfloat(1); 2590 rb(env, m, constants().ids.sum, t, b_sum_float); 2591 rb(env, m, ASTString("product"), t, b_product_float); 2592 } 2593 { 2594 std::vector<Type> t(1); 2595 t[0] = Type::parfloat(1); 2596 rb(env, m, ASTString("min"), t, b_float_min); 2597 rb(env, m, ASTString("max"), t, b_float_max); 2598 2599 t[0] = Type::parfloat(); 2600 t.push_back(Type::parfloat()); 2601 rb(env, m, ASTString("min"), t, b_float_min); 2602 rb(env, m, ASTString("max"), t, b_float_max); 2603 } 2604 { 2605 std::vector<Type> t(1); 2606 t[0] = Type::parsetint(); 2607 rb(env, m, ASTString("set2array"), t, b_set2array); 2608 } 2609 { 2610 std::vector<Type> t(1); 2611 t[0] = Type::parstring(); 2612 rb(env, m, ASTString("string_length"), t, b_string_length); 2613 } 2614 { rb(env, m, ASTString("file_path"), std::vector<Type>(), b_file_path); } 2615 { 2616 std::vector<Type> t(1); 2617 t[0] = Type::vartop(); 2618 rb(env, m, ASTString("show"), t, b_show); 2619 rb(env, m, ASTString("showJSON"), t, b_show_json); 2620 t[0] = Type::vartop(); 2621 t[0].st(Type::ST_SET); 2622 t[0].ot(Type::OT_OPTIONAL); 2623 rb(env, m, ASTString("show"), t, b_show); 2624 rb(env, m, ASTString("showJSON"), t, b_show_json); 2625 t[0] = Type::vartop(-1); 2626 rb(env, m, ASTString("show"), t, b_show); 2627 rb(env, m, ASTString("showJSON"), t, b_show_json); 2628 } 2629 { 2630 std::vector<Type> t(1); 2631 t[0] = Type::parstring(); 2632 rb(env, m, ASTString("showDznId"), t, b_showDznId); 2633 } 2634 { 2635 std::vector<Type> t(3); 2636 t[0] = t[1] = Type::parint(); 2637 t[2] = Type::vartop(); 2638 rb(env, m, ASTString("format"), t, b_format); 2639 t[2] = Type::vartop(); 2640 t[2].st(Type::ST_SET); 2641 t[2].ot(Type::OT_OPTIONAL); 2642 rb(env, m, ASTString("format"), t, b_format); 2643 t[2] = Type::vartop(-1); 2644 rb(env, m, ASTString("format"), t, b_format); 2645 } 2646 { 2647 std::vector<Type> t(2); 2648 t[0] = Type::parint(); 2649 t[1] = Type::vartop(); 2650 rb(env, m, ASTString("format"), t, b_format); 2651 t[1] = Type::vartop(); 2652 t[1].st(Type::ST_SET); 2653 t[1].ot(Type::OT_OPTIONAL); 2654 rb(env, m, ASTString("format"), t, b_format); 2655 t[1] = Type::vartop(-1); 2656 rb(env, m, ASTString("format"), t, b_format); 2657 t[1] = Type::parstring(); 2658 rb(env, m, ASTString("format_justify_string"), t, b_format_justify_string); 2659 } 2660 { 2661 std::vector<Type> t; 2662 rb(env, m, ASTString("outputJSON"), t, b_outputJSON); 2663 rb(env, m, ASTString("outputJSONParameters"), t, b_outputJSONParameters); 2664 } 2665 { 2666 std::vector<Type> t(2); 2667 t[0] = Type::parint(); 2668 t[1] = Type::varint(); 2669 rb(env, m, ASTString("show_int"), t, b_show_int); 2670 } 2671 { 2672 std::vector<Type> t(3); 2673 t[0] = Type::parint(); 2674 t[1] = Type::parint(); 2675 t[2] = Type::varfloat(); 2676 rb(env, m, ASTString("show_float"), t, b_show_float); 2677 } 2678 { 2679 std::vector<Type> t(1); 2680 t[0] = Type::parstring(1); 2681 rb(env, m, ASTString("concat"), t, b_concat); 2682 } 2683 { 2684 std::vector<Type> t(2); 2685 t[0] = Type::parstring(); 2686 t[1] = Type::parstring(1); 2687 rb(env, m, ASTString("join"), t, b_join); 2688 } 2689 { 2690 std::vector<Type> t(2); 2691 t[0] = Type::varint(); 2692 t[1] = Type::varint(); 2693 rb(env, m, ASTString("compute_div_bounds"), t, b_compute_div_bounds); 2694 } 2695 { 2696 std::vector<Type> t(1); 2697 t[0] = Type::parsetint(1); 2698 rb(env, m, ASTString("array_intersect"), t, b_array_intersect); 2699 rb(env, m, ASTString("array_union"), t, b_array_union); 2700 } 2701 { 2702 std::vector<Type> t(1); 2703 t[0] = Type::parint(); 2704 t[0].ot(Type::OT_OPTIONAL); 2705 t[0].bt(Type::BT_TOP); 2706 rb(env, m, ASTString("occurs"), t, b_occurs); 2707 rb(env, m, ASTString("deopt"), t, b_deopt_expr); 2708 t[0].bt(Type::BT_INT); 2709 rb(env, m, ASTString("deopt"), t, b_deopt_int); 2710 t[0].bt(Type::BT_BOOL); 2711 rb(env, m, ASTString("deopt"), t, b_deopt_bool); 2712 t[0].bt(Type::BT_FLOAT); 2713 rb(env, m, ASTString("deopt"), t, b_deopt_float); 2714 t[0].bt(Type::BT_STRING); 2715 rb(env, m, ASTString("deopt"), t, b_deopt_string); 2716 t[0].bt(Type::BT_INT); 2717 t[0].st(Type::ST_SET); 2718 rb(env, m, ASTString("deopt"), t, b_deopt_intset); 2719 } 2720 { 2721 std::vector<Type> t(2); 2722 t[0] = Type::varbot(1); 2723 t[1] = Type::parint(1); 2724 rb(env, m, ASTString("sort_by"), t, b_sort_by_int); 2725 t[0] = Type::bot(1); 2726 rb(env, m, ASTString("sort_by"), t, b_sort_by_int); 2727 t[0].ot(Type::OT_OPTIONAL); 2728 rb(env, m, ASTString("sort_by"), t, b_sort_by_int); 2729 } 2730 { 2731 std::vector<Type> t(2); 2732 t[0] = Type::varbot(1); 2733 t[1] = Type::parfloat(1); 2734 rb(env, m, ASTString("sort_by"), t, b_sort_by_float); 2735 t[0] = Type::bot(1); 2736 rb(env, m, ASTString("sort_by"), t, b_sort_by_float); 2737 t[0].ot(Type::OT_OPTIONAL); 2738 rb(env, m, ASTString("sort_by"), t, b_sort_by_float); 2739 } 2740 { 2741 std::vector<Type> t(1); 2742 t[0] = Type::parint(1); 2743 rb(env, m, ASTString("sort"), t, b_sort); 2744 rb(env, m, ASTString("arg_min"), t, b_arg_min_int); 2745 rb(env, m, ASTString("arg_max"), t, b_arg_max_int); 2746 t[0] = Type::parbool(1); 2747 rb(env, m, ASTString("sort"), t, b_sort); 2748 t[0] = Type::parfloat(1); 2749 rb(env, m, ASTString("sort"), t, b_sort); 2750 rb(env, m, ASTString("arg_min"), t, b_arg_min_float); 2751 rb(env, m, ASTString("arg_max"), t, b_arg_max_float); 2752 } 2753 { 2754 std::vector<Type> t(1); 2755 t[0] = Type::parfloat(); 2756 rb(env, m, ASTString("atan"), t, b_atan); 2757 } 2758 { 2759 std::vector<Type> t(1); 2760 t[0] = Type::parfloat(); 2761 rb(env, m, ASTString("cos"), t, b_cos); 2762 } 2763 { 2764 std::vector<Type> t(1); 2765 t[0] = Type::parfloat(); 2766 rb(env, m, ASTString("sin"), t, b_sin); 2767 } 2768 { 2769 std::vector<Type> t(1); 2770 t[0] = Type::parfloat(); 2771 rb(env, m, ASTString("asin"), t, b_asin); 2772 } 2773 { 2774 std::vector<Type> t(1); 2775 t[0] = Type::parfloat(); 2776 rb(env, m, ASTString("acos"), t, b_acos); 2777 } 2778 { 2779 std::vector<Type> t(1); 2780 t[0] = Type::parfloat(); 2781 rb(env, m, ASTString("tan"), t, b_tan); 2782 } 2783 { 2784 std::vector<Type> t(2); 2785 t[0] = Type::parfloat(); 2786 t[1] = Type::parfloat(); 2787 rb(env, m, ASTString("normal"), t, b_normal_float_float); 2788 t[0] = Type::parint(); 2789 rb(env, m, ASTString("normal"), t, b_normal_int_float); 2790 } 2791 { 2792 std::vector<Type> t(2); 2793 t[0] = Type::parfloat(); 2794 t[1] = Type::parfloat(); 2795 rb(env, m, ASTString("uniform"), t, b_uniform_float); 2796 t[0] = Type::parint(); 2797 t[1] = Type::parint(); 2798 rb(env, m, ASTString("uniform"), t, b_uniform_int); 2799 } 2800 { 2801 std::vector<Type> t(1); 2802 t[0] = Type::parfloat(); 2803 rb(env, m, ASTString("poisson"), t, b_poisson_float); 2804 t[0] = Type::parint(); 2805 rb(env, m, ASTString("poisson"), t, b_poisson_int); 2806 } 2807 { 2808 std::vector<Type> t(2); 2809 t[0] = Type::parfloat(); 2810 t[1] = Type::parfloat(); 2811 rb(env, m, ASTString("gamma"), t, b_gamma_float_float); 2812 t[0] = Type::parint(); 2813 rb(env, m, ASTString("gamma"), t, b_gamma_int_float); 2814 } 2815 { 2816 std::vector<Type> t(2); 2817 t[0] = Type::parfloat(); 2818 t[1] = Type::parfloat(); 2819 rb(env, m, ASTString("weibull"), t, b_weibull_float_float); 2820 t[0] = Type::parint(); 2821 rb(env, m, ASTString("weibull"), t, b_weibull_int_float); 2822 } 2823 { 2824 std::vector<Type> t(1); 2825 t[0] = Type::parfloat(); 2826 rb(env, m, ASTString("exponential"), t, b_exponential_float); 2827 t[0] = Type::parint(); 2828 rb(env, m, ASTString("exponential"), t, b_exponential_int); 2829 } 2830 { 2831 std::vector<Type> t(2); 2832 t[0] = Type::parfloat(); 2833 t[1] = Type::parfloat(); 2834 rb(env, m, ASTString("lognormal"), t, b_lognormal_float_float); 2835 t[0] = Type::parint(); 2836 rb(env, m, ASTString("lognormal"), t, b_lognormal_int_float); 2837 } 2838 { 2839 std::vector<Type> t(1); 2840 t[0] = Type::parfloat(); 2841 rb(env, m, ASTString("chisquared"), t, b_chisquared_float); 2842 t[0] = Type::parint(); 2843 rb(env, m, ASTString("chisquared"), t, b_chisquared_int); 2844 } 2845 { 2846 std::vector<Type> t(2); 2847 t[0] = Type::parfloat(); 2848 t[1] = Type::parfloat(); 2849 rb(env, m, ASTString("cauchy"), t, b_cauchy_float_float); 2850 t[0] = Type::parint(); 2851 rb(env, m, ASTString("cauchy"), t, b_cauchy_int_float); 2852 } 2853 { 2854 std::vector<Type> t(2); 2855 t[0] = Type::parfloat(); 2856 t[1] = Type::parfloat(); 2857 rb(env, m, ASTString("fdistribution"), t, b_fdistribution_float_float); 2858 t[0] = Type::parint(); 2859 t[1] = Type::parint(); 2860 rb(env, m, ASTString("fdistribution"), t, b_fdistribution_int_int); 2861 } 2862 { 2863 std::vector<Type> t(1); 2864 t[0] = Type::parfloat(); 2865 rb(env, m, ASTString("tdistribution"), t, b_tdistribution_float); 2866 t[0] = Type::parint(); 2867 rb(env, m, ASTString("tdistribution"), t, b_tdistribution_int); 2868 } 2869 { 2870 std::vector<Type> t(1); 2871 t[0] = Type::parint(1); 2872 rb(env, m, ASTString("discrete_distribution"), t, b_discrete_distribution); 2873 } 2874 { 2875 std::vector<Type> t(1); 2876 t[0] = Type::parint(); 2877 rb(env, m, ASTString("bernoulli"), t, b_bernoulli); 2878 } 2879 { 2880 std::vector<Type> t(2); 2881 t[0] = Type::parint(); 2882 t[1] = Type::parfloat(); 2883 rb(env, m, ASTString("binomial"), t, b_binomial); 2884 } 2885 { 2886 std::vector<Type> t(2); 2887 t[0] = Type::parsetint(); 2888 t[1] = Type::parint(); 2889 rb(env, m, ASTString("to_enum"), t, b_to_enum); 2890 rb(env, m, ASTString("enum_next"), t, b_enum_next); 2891 rb(env, m, ASTString("enum_prev"), t, b_enum_prev); 2892 } 2893 { rb(env, m, ASTString("mzn_compiler_version"), std::vector<Type>(), b_mzn_compiler_version); } 2894 { 2895 std::vector<Type> t(2); 2896 t[0] = Type::varint(1); 2897 t[1] = Type::parstring(); 2898 rb(env, m, ASTString("fzn_regular"), t, b_regular_from_string, true); 2899 } 2900} 2901 2902} // namespace MiniZinc