this repo has no description
at develop 5.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/flatten_internal.hh> 13#include <minizinc/pathfileprinter.hh> 14 15#include <sstream> 16 17namespace MiniZinc { 18 19using std::string; 20using std::vector; 21 22PathFilePrinter::PathFilePrinter(std::ostream& o, EnvI&) : os(o), constraint_index(0) {} 23 24void PathFilePrinter::addBetterName(Id* id, string name, string path, bool overwrite = false) { 25 string oname; 26 string opath; 27 28 NameMap::iterator it = betternames.find(id); 29 if (it != betternames.end()) { 30 oname = it->second.first; 31 opath = it->second.second; 32 } 33 34 if (!name.empty() && (overwrite || oname.empty())) oname = name; 35 if (!path.empty() && (overwrite || opath.empty())) opath = path; 36 37 betternames[id] = NamePair(oname, opath); 38} 39 40string path2name(string path) { 41 std::stringstream name; 42 43 size_t idpos = path.rfind("id:"); 44 if (idpos != string::npos) { 45 idpos += 3; 46 size_t semi = path.find(";", idpos); 47 if (semi != string::npos) { 48 // Variable name 49 name << path.substr(idpos, semi - idpos); 50 51 // Check for array 52 int dim = 0; 53 size_t ilpos = semi - idpos; 54 do { 55 ilpos = path.find("il:", ilpos); 56 if (ilpos != string::npos) { 57 ilpos += 3; 58 semi = path.find(";", ilpos); 59 if (semi != string::npos) { 60 if (dim == 0) 61 name << "["; 62 else 63 name << ","; 64 name << path.substr(ilpos, semi - ilpos); 65 dim++; 66 } 67 } 68 } while (ilpos != string::npos); 69 70 if (dim > 0) name << "?]"; 71 72 // Check for anon 73 if (path.find(":anon") != string::npos || path.find("=") != string::npos) { 74 name.str(""); 75 name.clear(); 76 } 77 } 78 } 79 80 return name.str(); 81} 82 83void PathFilePrinter::print(Model* m) { 84 // Build map 85 for (VarDeclIterator vdit = m->begin_vardecls(); vdit != m->end_vardecls(); ++vdit) { 86 VarDecl* e = vdit->e(); 87 for (ExpressionSetIter it = e->ann().begin(); it != e->ann().end(); ++it) { 88 if (Call* ca = (*it)->dyn_cast<Call>()) { 89 ASTString cid = ca->id(); 90 if (cid == constants().ann.output_array) { 91 if (ArrayLit* rhs = e->e()->dyn_cast<ArrayLit>()) { 92 for (unsigned int ind = 0; ind < rhs->size(); ind++) { 93 if (Id* id = (*rhs)[ind]->dyn_cast<Id>()) { 94 std::stringstream bettername; 95 bettername << *e->id() << "["; 96 97 // Array of sets 98 ArrayLit& dimsets = *ca->arg(0)->cast<ArrayLit>(); 99 vector<IntVal> dims(dimsets.size(), 1); 100 for (unsigned int i = 0; i < dimsets.size(); i++) { 101 SetLit* sl = dimsets[i]->cast<SetLit>(); 102 dims[i] = sl->isv()->card(); 103 } 104 vector<IntVal> dimspan(dims.size(), 1); 105 for (unsigned int i = 0; i < dims.size(); i++) 106 for (unsigned int j = i + 1; j < dims.size(); j++) dimspan[i] *= dims[j]; 107 108 IntVal curind = ind; 109 for (unsigned int i = 0; i < dims.size() - 1; i++) { 110 IntVal thisind = curind / dimspan[i]; 111 curind -= thisind * dimspan[i]; 112 bettername << dimsets[i]->cast<SetLit>()->isv()->min() + thisind << ","; 113 } 114 bettername << dimsets[dimsets.size() - 1]->cast<SetLit>()->isv()->min() + curind 115 << "]"; 116 117 addBetterName(id, bettername.str(), "", true); 118 } 119 } 120 } 121 } else if (ca->id() == constants().ann.mzn_path) { 122 StringLit* sl = ca->arg(0)->cast<StringLit>(); 123 addBetterName(e->id(), path2name(sl->v().str()), sl->v().str()); 124 } 125 } 126 } 127 } 128 129 // Print values 130 for (Item* item : *m) print(item); 131} 132 133void PathFilePrinter::print(Item* item) { 134 if (VarDeclI* vdi = item->dyn_cast<VarDeclI>()) { 135 Id* id = vdi->e()->id(); 136 NamePair np = betternames[id]; 137 if (!np.first.empty() || !np.second.empty()) { 138 // FlatZinc name 139 os << *id << "\t"; 140 141 // Nice name 142 if (np.first.empty()) { 143 os << *id << "\t"; 144 } else { 145 string name = np.first; 146 os << name; 147 if (name.find("?") != string::npos) os << "(" << *id << ")"; 148 os << "\t"; 149 } 150 151 // Path 152 os << np.second << std::endl; 153 } 154 } else if (ConstraintI* ci = item->dyn_cast<ConstraintI>()) { 155 StringLit* sl = nullptr; 156 Expression* e = ci->e(); 157 for (ExpressionSetIter it = e->ann().begin(); it != e->ann().end(); ++it) { 158 if (Call* ca = (*it)->dyn_cast<Call>()) { 159 ASTString cid = ca->id(); 160 if (cid == constants().ann.mzn_path) { 161 sl = ca->arg(0)->cast<StringLit>(); 162 } 163 } 164 } 165 166 os << constraint_index << "\t"; 167 os << constraint_index << "\t"; 168 if (sl) { 169 os << sl->v(); 170 } else { 171 os << ""; 172 } 173 os << std::endl; 174 constraint_index++; 175 } 176} 177} // namespace MiniZinc