this repo has no description
at develop 2.5 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/flat_exp.hh> 13 14namespace MiniZinc { 15 16EE flatten_vardecl(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b) { 17 CallStackItem _csi(env, e); 18 EE ret; 19 GCLock lock; 20 if (ctx.b != C_ROOT) { 21 throw FlatteningError(env, e->loc(), "not in root context"); 22 } 23 auto* v = e->cast<VarDecl>(); 24 VarDecl* it = v->flat(); 25 if (it == nullptr) { 26 TypeInst* ti = eval_typeinst(env, ctx, v); 27 if ((ti->domain() != nullptr) && ti->domain()->isa<SetLit>()) { 28 if (ti->type().bt() == Type::BT_INT && ti->type().st() == Type::ST_PLAIN) { 29 if (eval_intset(env, ti->domain())->size() == 0) { 30 env.fail("domain is empty"); 31 } 32 } else if (ti->type().bt() == Type::BT_FLOAT) { 33 if (eval_floatset(env, ti->domain())->size() == 0) { 34 env.fail("domain is empty"); 35 } 36 } 37 } 38 bool reuseVarId = 39 v->type().isAnn() || (v->toplevel() && v->id()->idn() == -1 && 40 v->id()->v().c_str()[0] != '\'' && v->id()->v().c_str()[0] != '_'); 41 VarDecl* vd = new_vardecl(env, ctx, ti, reuseVarId ? v->id() : nullptr, v, nullptr); 42 v->flat(vd); 43 Ctx nctx; 44 if ((v->e() != nullptr) && v->e()->type().bt() == Type::BT_BOOL) { 45 nctx.b = C_MIX; 46 } 47 if (v->e() != nullptr) { 48 (void)flat_exp(env, nctx, v->e(), vd, constants().varTrue); 49 if (v->e()->type().dim() > 0) { 50 Expression* ee = follow_id_to_decl(vd->e()); 51 if (ee->isa<VarDecl>()) { 52 ee = ee->cast<VarDecl>()->e(); 53 } 54 assert(ee && ee->isa<ArrayLit>()); 55 auto* al = ee->cast<ArrayLit>(); 56 if (vd->ti()->domain() != nullptr) { 57 for (unsigned int i = 0; i < al->size(); i++) { 58 if (Id* ali_id = (*al)[i]->dynamicCast<Id>()) { 59 if (ali_id != constants().absent && ali_id->decl()->ti()->domain() == nullptr) { 60 ali_id->decl()->ti()->domain(vd->ti()->domain()); 61 } 62 } 63 } 64 } 65 } 66 } 67 68 ret.r = bind(env, Ctx(), r, vd->id()); 69 } else { 70 ret.r = bind(env, Ctx(), r, it); 71 } 72 ret.b = bind(env, Ctx(), b, constants().literalTrue); 73 return ret; 74} 75} // namespace MiniZinc