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