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, 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