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