this repo has no description
at develop 3.7 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_par(EnvI& env, const Ctx& ctx, Expression* e, VarDecl* r, VarDecl* b) { 17 EE ret; 18 if (e->type().cv()) { 19 Ctx nctx; 20 nctx.b = ctx.b == C_ROOT ? C_ROOT : C_MIX; 21 22 try { 23 KeepAlive ka = flat_cv_exp(env, nctx, e); 24 ret.r = bind(env, ctx, r, ka()); 25 ret.b = bind(env, Ctx(), b, constants().literalTrue); 26 } catch (ResultUndefinedError&) { 27 if (e->type().isbool()) { 28 ret.r = bind(env, ctx, r, constants().literalFalse); 29 ret.b = bind(env, Ctx(), b, constants().literalTrue); 30 } else { 31 ret.r = create_dummy_value(env, e->type()); 32 ret.b = bind(env, Ctx(), b, constants().literalFalse); 33 } 34 } 35 return ret; 36 } 37 if (e->type().dim() > 0) { 38 EnvI::CSEMap::iterator it; 39 Id* id = e->dynamicCast<Id>(); 40 if ((id != nullptr) && (id->decl()->flat() == nullptr || id->decl()->toplevel())) { 41 VarDecl* vd = id->decl()->flat(); 42 if (vd == nullptr) { 43 vd = flat_exp(env, Ctx(), id->decl(), nullptr, constants().varTrue).r()->cast<Id>()->decl(); 44 id->decl()->flat(vd); 45 auto* al = follow_id(vd->id())->cast<ArrayLit>(); 46 if (al->size() == 0) { 47 if (r == nullptr) { 48 ret.r = al; 49 } else { 50 ret.r = bind(env, ctx, r, al); 51 } 52 ret.b = bind(env, Ctx(), b, constants().literalTrue); 53 return ret; 54 } 55 } 56 ret.r = bind(env, ctx, r, e->cast<Id>()->decl()->flat()->id()); 57 ret.b = bind(env, Ctx(), b, constants().literalTrue); 58 return ret; 59 } 60 if ((it = env.cseMapFind(e)) != env.cseMapEnd()) { 61 ret.r = bind(env, ctx, r, it->second.r()->cast<VarDecl>()->id()); 62 ret.b = bind(env, Ctx(), b, constants().literalTrue); 63 return ret; 64 } 65 GCLock lock; 66 auto* al = follow_id(eval_par(env, e))->cast<ArrayLit>(); 67 if (al->size() == 0 || ((r != nullptr) && r->e() == nullptr)) { 68 if (r == nullptr) { 69 ret.r = al; 70 } else { 71 ret.r = bind(env, ctx, r, al); 72 } 73 ret.b = bind(env, Ctx(), b, constants().literalTrue); 74 return ret; 75 } 76 if ((it = env.cseMapFind(al)) != env.cseMapEnd()) { 77 ret.r = bind(env, ctx, r, it->second.r()->cast<VarDecl>()->id()); 78 ret.b = bind(env, Ctx(), b, constants().literalTrue); 79 return ret; 80 } 81 std::vector<TypeInst*> ranges(al->dims()); 82 for (unsigned int i = 0; i < ranges.size(); i++) { 83 ranges[i] = 84 new TypeInst(e->loc(), Type(), 85 new SetLit(Location().introduce(), IntSetVal::a(al->min(i), al->max(i)))); 86 } 87 ASTExprVec<TypeInst> ranges_v(ranges); 88 assert(!al->type().isbot()); 89 auto* ti = new TypeInst(e->loc(), al->type(), ranges_v, nullptr); 90 VarDecl* vd = new_vardecl(env, ctx, ti, nullptr, nullptr, al); 91 EE ee(vd, nullptr); 92 env.cseMapInsert(al, ee); 93 env.cseMapInsert(vd->e(), ee); 94 95 ret.r = bind(env, ctx, r, vd->id()); 96 ret.b = bind(env, Ctx(), b, constants().literalTrue); 97 return ret; 98 } 99 GCLock lock; 100 try { 101 ret.r = bind(env, ctx, r, eval_par(env, e)); 102 ret.b = bind(env, Ctx(), b, constants().literalTrue); 103 } catch (ResultUndefinedError&) { 104 ret.r = create_dummy_value(env, e->type()); 105 ret.b = bind(env, Ctx(), b, constants().literalFalse); 106 } 107 return ret; 108} 109 110} // namespace MiniZinc