00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "gecode/serialization.hh"
00039 #ifdef GECODE_HAS_INT_VARS
00040 #include "gecode/int.hh"
00041 #endif
00042 #ifdef GECODE_HAS_SET_VARS
00043 #include "gecode/set.hh"
00044 #endif
00045
00046 namespace Gecode {
00047
00048 namespace {
00049 #ifdef GECODE_HAS_INT_VARS
00050 void emitIntVar(std::ostream& os, int varNo, Reflection::VarSpec& vs) {
00051 using namespace std;
00052 os << "var ";
00053 Reflection::Arg* dom = vs.dom();
00054 if (!dom->isIntArray())
00055 throw Exception("Serialization",
00056 "Internal error: invalid domain specification for IntVar.");
00057 Reflection::IntArrayArg* a = dom->toIntArray();
00058 if (a->size() == 2) {
00059 os << (*a)[0] << ".." << (*a)[1];
00060 } else {
00061 os << "{";
00062 for (int i=0; i<a->size(); i+=2) {
00063 for (int j=(*a)[i]; j<=(*a)[i+1]; j++)
00064 os << j << (i==a->size()-2 && j==(*a)[i+1] ? "" : ",");
00065 }
00066 os << "}";
00067 }
00068 if (!vs.name().empty()) {
00069 os << ": " << vs.name() << ";" << endl;
00070 }
00071 else
00072 os << ": _v" << varNo << ";" << endl;
00073 }
00074 void emitBoolVar(std::ostream& os, int varNo, Reflection::VarSpec& vs) {
00075 using namespace std;
00076 os << "var ";
00077 Reflection::Arg* dom = vs.dom();
00078 if (!dom->isInt())
00079 throw Exception("Serialization",
00080 "Internal error: invalid domain specification for BoolVar.");
00081 switch (dom->toInt()) {
00082 case 0: os << "false..true"; break;
00083 case 1: os << "false"; break;
00084 case 2: os << "true"; break;
00085 default:
00086 throw Exception("Serialization",
00087 "Internal error: invalid domain specification for BoolVar.");
00088 }
00089 if (!vs.name().empty()) {
00090 os << ": " << vs.name() << ";" << endl;
00091 }
00092 else
00093 os << ": _v" << varNo << ";" << endl;
00094 }
00095 #endif
00096 #ifdef GECODE_HAS_SET_VARS
00097 void emitSetVar(std::ostream& os, int varNo, Reflection::VarSpec& vs) {
00098 using namespace std;
00099 os << "var set of ";
00100 Reflection::Arg* dom = vs.dom();
00101 if (! (dom->isPair() &&
00102 dom->first()->isPair() && dom->second()->isPair() &&
00103 dom->first()->first()->isIntArray() &&
00104 dom->second()->first()->isIntArray() &&
00105 dom->first()->second()->isInt() &&
00106 dom->second()->second()->isInt()))
00107 throw Exception("Serialization",
00108 "Internal error: invalid domain specification for SetVar.");
00109
00110 int lbCard = 0;
00111 int ubCard = 0;
00112
00113
00114 Reflection::IntArrayArg* a = dom->second()->first()->toIntArray();
00115 if (a->size() == 2) {
00116 os << (*a)[0] << ".." << (*a)[1];
00117 ubCard = (*a)[1] - (*a)[0];
00118 } else {
00119 os << "{";
00120 for (int i=0; i<a->size(); i+=2) {
00121 for (int j=(*a)[i]; j<(*a)[i+1]; j++) {
00122 os << j << (i==a->size()-2 && j==(*a)[i+1]-1 ? "" : ",");
00123 ubCard += (*a)[i+1] - (*a)[i];
00124 }
00125 }
00126 os << "}";
00127 }
00128 if (!vs.name().empty()) {
00129 os << ": " << vs.name() << ";" << endl;
00130 }
00131 else
00132 os << ": _v" << varNo << ";" << endl;
00133
00134
00135
00136
00137 if (dom->first()->first()->toIntArray()->size() != 0) {
00138 os << "constraint subset(";
00139 a = dom->first()->first()->toIntArray();
00140 if (a->size() == 2) {
00141 os << (*a)[0] << ".." << (*a)[1];
00142 } else {
00143 os << "{";
00144 for (int i=0; i<a->size(); i+=2) {
00145 for (int j=(*a)[i]; j<(*a)[i+1]; j++)
00146 os << j << (i==a->size()-2 && j==(*a)[i+1]-1 ? "" : ",");
00147 }
00148 os << "}";
00149 }
00150 if (!vs.name().empty()) {
00151 os << "," << vs.name() << ");" << endl;
00152 }
00153 else
00154 os << ", _v" << varNo << ");" << endl;
00155 }
00156
00157 if (lbCard != dom->first()->second()->toInt() ||
00158 ubCard != dom->second()->second()->toInt()) {
00159 os << "constraint cardinality(";
00160 if (!vs.name().empty())
00161 os << vs.name() << ", ";
00162 else
00163 os << "_v" << varNo;
00164 os << ", " << lbCard << ", " << ubCard << ");" << endl;
00165
00166 }
00167
00168 }
00169 #endif
00170
00171 void emitVar(std::ostream& os, int v, Reflection::VarMap& vm) {
00172 using namespace std;
00173 Reflection::VarSpec& vs = vm.spec(v);
00174 if (vs.name().empty())
00175 os << "_v" << v;
00176 else
00177 os << vs.name();
00178 }
00179
00180 void emitVarArray(std::ostream& os, Reflection::ArrayArg* a,
00181 Reflection::VarMap& vm) {
00182 using namespace std;
00183 for (int i=0; i<a->size(); i++)
00184 emitVar(os, (*a)[i]->toVar(), vm);
00185 }
00186
00187 void emitArray(std::ostream& os, Reflection::ArrayArg* a,
00188 Reflection::VarMap& vm) {
00189 using namespace std;
00190 if ((*a)[0]->isInt()) {
00191 os << "[";
00192 for (int i=0; i<a->size(); i++) {
00193 os << (*a)[i]->toInt();
00194 if (i<a->size()-1)
00195 os << ", ";
00196 }
00197 os << "]";
00198 return;
00199 }
00200
00201 if ((*a)[0]->isVar()) {
00202 os << "[";
00203 for (int i=0; i<a->size(); i++) {
00204 emitVar(os, (*a)[i]->toVar(), vm);
00205 if (i<a->size()-1)
00206 os << ",";
00207 }
00208 os << "]";
00209 return;
00210 }
00211
00212 if ((*a)[0]->isPair()) {
00213 Reflection::ArrayArg* aa = Reflection::Arg::newArray(a->size());
00214 Reflection::ArrayArg* ab = Reflection::Arg::newArray(a->size());
00215 for (int i=0; i<a->size(); i++) {
00216 (*aa)[i] = (*a)[i]->first();
00217 (*ab)[i] = (*a)[i]->second();
00218 }
00219 emitArray(os, aa, vm);
00220 os << ", ";
00221 emitArray(os, ab, vm);
00222
00223 for (int i=0; i<a->size(); i++) {
00224 (*aa)[i] = NULL;
00225 (*ab)[i] = NULL;
00226 }
00227 delete aa;
00228 delete ab;
00229 return;
00230 }
00231
00232 throw Exception("Serialization", "Specification not understood");
00233 }
00234
00235 void emitArg(std::ostream& os, Reflection::Arg* arg,
00236 Reflection::VarMap& vm) {
00237 using namespace std;
00238 if (arg->isInt()) {
00239 os << arg->toInt();
00240 return;
00241 }
00242 if (arg->isString()) {
00243 os << "\"" << arg->toString() << "\"";
00244 return;
00245 }
00246 if (arg->isVar()) {
00247 Reflection::VarSpec& s = vm.spec(arg->toVar());
00248 if (s.name().empty())
00249 os << "_v" << arg->toVar();
00250 else
00251 os << s.name();
00252 return;
00253 }
00254 if (arg->isIntArray()) {
00255 Reflection::IntArrayArg* a = arg->toIntArray();
00256 os << "[";
00257 for (int i=0; i<a->size(); i++) {
00258 os << (*a)[i];
00259 if (i<a->size()-1)
00260 os << ", ";
00261 }
00262 os << "]";
00263 return;
00264 }
00265 if (arg->isArray()) {
00266 Reflection::ArrayArg* a = arg->toArray();
00267 if (a->size() == 0) {
00268 os << "[]";
00269 return;
00270 }
00271 emitArray(os, a, vm);
00272 return;
00273 }
00274 if (arg->isSharedReference()) {
00275 os << "_array" << arg->toSharedReference();
00276 return;
00277 }
00278 assert(!arg->isSharedObject());
00279 throw Exception("Serialization", "Specification not understood");
00280 }
00281
00282 void emitSharedObject(std::ostream& os, int soCount,
00283 Reflection::VarMap& vm,
00284 Reflection::Arg* arg0) {
00285 using namespace std;
00286 Reflection::Arg* arg = arg0->toSharedObject();
00287 if (arg->isIntArray()) {
00288 Reflection::IntArrayArg* a = arg->toIntArray();
00289 os << "array[0.."<<a->size()-1<<"] of int: _array" << soCount << " = ";
00290 os << "[";
00291 for (int i=0; i<a->size(); i++) {
00292 os << (*a)[i];
00293 if (i<a->size()-1)
00294 os << ", ";
00295 }
00296 os << "];" << std::endl;
00297 return;
00298 }
00299 if (arg->isArray()) {
00300 Reflection::ArrayArg* a = arg->toArray();
00301 os << "array[0.."<<a->size()-1<<"] of int: _array" << soCount << " = ";
00302 if (a->size() == 0) {
00303 os << "[];" << std::endl;
00304 return;
00305 }
00306 emitArray(os, a, vm);
00307 os << ";" << std::endl;
00308 return;
00309 }
00310 return;
00311 }
00312
00313 void emitVarMap(std::ostream& os, int& varCount,
00314 Reflection::VarMapIter& vmi) {
00315 for (; vmi(); ++vmi, ++varCount) {
00316 Reflection::VarSpec& vs = vmi.spec();
00317 if (false) { }
00318 #ifdef GECODE_HAS_INT_VARS
00319 else if (vs.vti() == Int::IntVarImp::vti)
00320 emitIntVar(os, varCount, vs);
00321 else if (vs.vti() == Int::BoolVarImp::vti)
00322 emitBoolVar(os, varCount, vs);
00323 #endif
00324 #ifdef GECODE_HAS_SET_VARS
00325 else if (vs.vti() == Set::SetVarImp::vti)
00326 emitSetVar(os, varCount, vs);
00327 #endif
00328 }
00329 }
00330 }
00331
00332
00333 void emitFlatzinc(Space* home, std::ostream& os) {
00334 using namespace std;
00335 Reflection::VarMap vm;
00336 home->getVars(vm, false);
00337 Reflection::VarMapIter vmi(vm);
00338 int varCount = 0;
00339 int soCount = 0;
00340 emitVarMap(os,varCount,vmi);
00341 for (Reflection::ActorSpecIter si(home, vm); si(); ++si) {
00342 Reflection::ActorSpec s = si.actor();
00343
00344 emitVarMap(os,varCount,vmi);
00345
00346 int soBase = soCount;
00347 for (int i=0; i<s.noOfArgs(); i++) {
00348 if (s[i] && s[i]->isSharedObject())
00349 emitSharedObject(os, soBase++, vm, s[i]);
00350 }
00351
00352 os << "constraint " << s.ati() << "(";
00353
00354 soBase = soCount;
00355 for (int i=0; i<s.noOfArgs(); i++) {
00356 if (s[i] == NULL)
00357 os << "[]";
00358 else if (s[i]->isSharedObject())
00359 os << "_array" << soBase++;
00360 else
00361 emitArg(os, s[i], vm);
00362 if (i<s.noOfArgs()-1)
00363 os << ", ";
00364 }
00365 os << ");" << endl;
00366 soCount = soBase;
00367 }
00368 }
00369
00370 }
00371
00372