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_setlit(EnvI& env, Ctx ctx, Expression* e, VarDecl* r, VarDecl* b) {
17 CallStackItem _csi(env, e);
18 EE ret;
19 SetLit* sl = e->cast<SetLit>();
20 assert(sl->isv() == NULL && sl->fsv() == NULL);
21 std::vector<EE> elems_ee(sl->v().size());
22 for (unsigned int i = sl->v().size(); i--;)
23 elems_ee[i] = flat_exp(env, ctx, sl->v()[i], NULL, NULL);
24 std::vector<Expression*> elems(elems_ee.size());
25 bool allPar = true;
26 for (unsigned int i = static_cast<unsigned int>(elems.size()); i--;) {
27 elems[i] = elems_ee[i].r();
28 allPar = allPar && elems[i]->type().ispar();
29 }
30
31 ret.b = conj(env, b, Ctx(), elems_ee);
32 if (allPar) {
33 GCLock lock;
34 Expression* ee = eval_par(env, e);
35 ret.r = bind(env, Ctx(), r, ee);
36 } else {
37 GCLock lock;
38 ArrayLit* al = new ArrayLit(sl->loc(), elems);
39 al->type(Type::varint(1));
40 std::vector<Expression*> args(1);
41 args[0] = al;
42 Call* cc = new Call(sl->loc().introduce(), "array2set", args);
43 cc->type(Type::varsetint());
44 FunctionI* fi = env.model->matchFn(env, cc->id(), args, false);
45 if (fi == NULL) {
46 throw FlatteningError(env, cc->loc(), "cannot find matching declaration");
47 }
48 assert(fi);
49 assert(env.isSubtype(fi->rtype(env, args, false), cc->type(), false));
50 cc->decl(fi);
51 EE ee = flat_exp(env, Ctx(), cc, NULL, constants().var_true);
52 ret.r = bind(env, Ctx(), r, ee.r());
53 }
54 return ret;
55}
56} // namespace MiniZinc