this repo has no description
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