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/flatzinc.hh>
00039 #include <gecode/flatzinc/registry.hh>
00040
00041 #include <gecode/search.hh>
00042
00043 #include <vector>
00044 #include <string>
00045 using namespace std;
00046
00047 namespace Gecode { namespace FlatZinc {
00048
00049 IntSet vs2is(IntVarSpec* vs) {
00050 if (vs->assigned) {
00051 return IntSet(vs->i,vs->i);
00052 }
00053 if (vs->domain()) {
00054 AST::SetLit* sl = vs->domain.some();
00055 if (sl->interval) {
00056 return IntSet(sl->min, sl->max);
00057 } else {
00058 int* newdom = heap.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
00059 for (int i=sl->s.size(); i--;)
00060 newdom[i] = sl->s[i];
00061 IntSet ret(newdom, sl->s.size());
00062 heap.free(newdom, static_cast<unsigned long int>(sl->s.size()));
00063 return ret;
00064 }
00065 }
00066 return IntSet(Int::Limits::min, Int::Limits::max);
00067 }
00068
00069 int vs2bsl(BoolVarSpec* bs) {
00070 if (bs->assigned) {
00071 return bs->i;
00072 }
00073 if (bs->domain()) {
00074 AST::SetLit* sl = bs->domain.some();
00075 assert(sl->interval);
00076 return std::min(1, std::max(0, sl->min));
00077 }
00078 return 0;
00079 }
00080
00081 int vs2bsh(BoolVarSpec* bs) {
00082 if (bs->assigned) {
00083 return bs->i;
00084 }
00085 if (bs->domain()) {
00086 AST::SetLit* sl = bs->domain.some();
00087 assert(sl->interval);
00088 return std::max(0, std::min(1, sl->max));
00089 }
00090 return 1;
00091 }
00092
00093 TieBreakVarBranch<IntVarBranch> ann2ivarsel(AST::Node* ann) {
00094 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
00095 if (s->id == "input_order")
00096 return TieBreakVarBranch<IntVarBranch>(INT_VAR_NONE);
00097 if (s->id == "first_fail")
00098 return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_MIN);
00099 if (s->id == "anti_first_fail")
00100 return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_MAX);
00101 if (s->id == "smallest")
00102 return TieBreakVarBranch<IntVarBranch>(INT_VAR_MIN_MIN);
00103 if (s->id == "largest")
00104 return TieBreakVarBranch<IntVarBranch>(INT_VAR_MAX_MAX);
00105 if (s->id == "occurrence")
00106 return TieBreakVarBranch<IntVarBranch>(INT_VAR_DEGREE_MAX);
00107 if (s->id == "max_regret")
00108 return TieBreakVarBranch<IntVarBranch>(INT_VAR_REGRET_MIN_MAX);
00109 if (s->id == "most_constrained")
00110 return TieBreakVarBranch<IntVarBranch>(INT_VAR_SIZE_MIN,
00111 INT_VAR_DEGREE_MAX);
00112 if (s->id == "random")
00113 return TieBreakVarBranch<IntVarBranch>(INT_VAR_RND);
00114 }
00115 std::cerr << "Warning, ignored search annotation: ";
00116 ann->print(std::cerr);
00117 std::cerr << std::endl;
00118 return TieBreakVarBranch<IntVarBranch>(INT_VAR_NONE);
00119 }
00120
00121 IntValBranch ann2ivalsel(AST::Node* ann) {
00122 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
00123 if (s->id == "indomain_min")
00124 return INT_VAL_MIN;
00125 if (s->id == "indomain_max")
00126 return INT_VAL_MAX;
00127 if (s->id == "indomain_median")
00128 return INT_VAL_MED;
00129 if (s->id == "indomain_split")
00130 return INT_VAL_SPLIT_MIN;
00131 if (s->id == "indomain_reverse_split")
00132 return INT_VAL_SPLIT_MAX;
00133 if (s->id == "indomain_random")
00134 return INT_VAL_RND;
00135 if (s->id == "indomain")
00136 return INT_VALUES_MIN;
00137 }
00138 std::cerr << "Warning, ignored search annotation: ";
00139 ann->print(std::cerr);
00140 std::cerr << std::endl;
00141 return INT_VAL_MIN;
00142 }
00143
00144 #ifdef GECODE_HAS_SET_VARS
00145 SetVarBranch ann2svarsel(AST::Node* ann) {
00146 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
00147 if (s->id == "input_order")
00148 return SET_VAR_NONE;
00149 if (s->id == "first_fail")
00150 return SET_VAR_SIZE_MIN;
00151 if (s->id == "anti_first_fail")
00152 return SET_VAR_SIZE_MAX;
00153 if (s->id == "smallest")
00154 return SET_VAR_MIN_MIN;
00155 if (s->id == "largest")
00156 return SET_VAR_MIN_MAX;
00157 }
00158 std::cerr << "Warning, ignored search annotation: ";
00159 ann->print(std::cerr);
00160 std::cerr << std::endl;
00161 return SET_VAR_NONE;
00162 }
00163
00164 SetValBranch ann2svalsel(AST::Node* ann) {
00165 if (AST::Atom* s = dynamic_cast<AST::Atom*>(ann)) {
00166 if (s->id == "indomain_min")
00167 return SET_VAL_MIN_INC;
00168 if (s->id == "indomain_max")
00169 return SET_VAL_MAX_INC;
00170 if (s->id == "outdomain_min")
00171 return SET_VAL_MIN_EXC;
00172 if (s->id == "outdomain_max")
00173 return SET_VAL_MAX_EXC;
00174 }
00175 std::cerr << "Warning, ignored search annotation: ";
00176 ann->print(std::cerr);
00177 std::cerr << std::endl;
00178 return SET_VAL_MIN_INC;
00179 }
00180 #endif
00181
00182 FlatZincSpace::FlatZincSpace(bool share, FlatZincSpace& f)
00183 : Space(share, f) {
00184 _optVar = f._optVar;
00185 _method = f._method;
00186 iv.update(*this, share, f.iv);
00187 bv.update(*this, share, f.bv);
00188 #ifdef GECODE_HAS_SET_VARS
00189 sv.update(*this, share, f.sv);
00190 #endif
00191 }
00192
00193 FlatZincSpace::FlatZincSpace(int intVars,
00194 int boolVars,
00195 #ifdef GECODE_HAS_SET_VARS
00196 int setVars)
00197 #else
00198 int)
00199 #endif
00200 : intVarCount(0), boolVarCount(0), setVarCount(0),
00201 iv(*this, intVars), iv_introduced(intVars),
00202 bv(*this, boolVars), bv_introduced(boolVars)
00203 #ifdef GECODE_HAS_SET_VARS
00204 , sv(*this, setVars),
00205 sv_introduced(setVars)
00206 #endif
00207 {}
00208
00209 void
00210 FlatZincSpace::newIntVar(IntVarSpec* vs) {
00211 if (vs->alias) {
00212 iv[intVarCount++] = iv[vs->i];
00213 } else {
00214 iv[intVarCount++] = IntVar(*this, vs2is(vs));
00215 }
00216 iv_introduced[intVarCount-1] = vs->introduced;
00217 }
00218
00219 void
00220 FlatZincSpace::newBoolVar(BoolVarSpec* vs) {
00221 if (vs->alias) {
00222 bv[boolVarCount++] = bv[vs->i];
00223 } else {
00224 bv[boolVarCount++] = BoolVar(*this, vs2bsl(vs), vs2bsh(vs));
00225 }
00226 bv_introduced[boolVarCount-1] = vs->introduced;
00227 }
00228
00229 #ifdef GECODE_HAS_SET_VARS
00230 void
00231 FlatZincSpace::newSetVar(SetVarSpec* vs) {
00232 if (vs->alias) {
00233 sv[setVarCount++] = sv[vs->i];
00234 } else if (vs->assigned) {
00235 assert(vs->upperBound());
00236 AST::SetLit* vsv = vs->upperBound.some();
00237 if (vsv->interval) {
00238 IntSet d(vsv->min, vsv->max);
00239 sv[setVarCount++] = SetVar(*this, d, d);
00240 } else {
00241 int* is = heap.alloc<int>(static_cast<unsigned long int>(vsv->s.size()));
00242 for (int i=vsv->s.size(); i--; )
00243 is[i] = vsv->s[i];
00244 IntSet d(is, vsv->s.size());
00245 heap.free(is,static_cast<unsigned long int>(vsv->s.size()));
00246 sv[setVarCount++] = SetVar(*this, d, d);
00247 }
00248 } else if (vs->upperBound()) {
00249 AST::SetLit* vsv = vs->upperBound.some();
00250 if (vsv->interval) {
00251 IntSet d(vsv->min, vsv->max);
00252 sv[setVarCount++] = SetVar(*this, IntSet::empty, d);
00253 } else {
00254 int* is = heap.alloc<int>(static_cast<unsigned long int>(vsv->s.size()));
00255 for (int i=vsv->s.size(); i--; )
00256 is[i] = vsv->s[i];
00257 IntSet d(is, vsv->s.size());
00258 heap.free(is,static_cast<unsigned long int>(vsv->s.size()));
00259 sv[setVarCount++] = SetVar(*this, IntSet::empty, d);
00260 }
00261 } else {
00262 sv[setVarCount++] = SetVar(*this, IntSet::empty,
00263 IntSet(Set::Limits::min,
00264 Set::Limits::max));
00265 }
00266 sv_introduced[setVarCount-1] = vs->introduced;
00267 }
00268 #else
00269 void
00270 FlatZincSpace::newSetVar(SetVarSpec*) {
00271 throw FlatZinc::Error("Gecode", "set variables not supported");
00272 }
00273 #endif
00274
00275 void
00276 FlatZincSpace::postConstraint(const ConExpr& ce, AST::Node* ann) {
00277 try {
00278 registry().post(*this, ce, ann);
00279 } catch (Gecode::Exception& e) {
00280 throw FlatZinc::Error("Gecode", e.what());
00281 } catch (AST::TypeError& e) {
00282 throw FlatZinc::Error("Type error", e.what());
00283 }
00284 }
00285
00286 void flattenAnnotations(AST::Array* ann, std::vector<AST::Node*>& out) {
00287 for (unsigned int i=0; i<ann->a.size(); i++) {
00288 if (ann->a[i]->isCall("seq_search")) {
00289 AST::Call* c = ann->a[i]->getCall();
00290 if (c->args->isArray())
00291 flattenAnnotations(c->args->getArray(), out);
00292 else
00293 out.push_back(c->args);
00294 } else {
00295 out.push_back(ann->a[i]);
00296 }
00297 }
00298 }
00299
00300 void
00301 FlatZincSpace::parseSolveAnn(AST::Array* ann) {
00302 bool hadSearchAnnotation = false;
00303 if (ann) {
00304 std::vector<AST::Node*> flatAnn;
00305 flattenAnnotations(ann, flatAnn);
00306
00307 for (unsigned int i=0; i<flatAnn.size(); i++) {
00308 try {
00309 AST::Call *call = flatAnn[i]->getCall("int_search");
00310 AST::Array *args = call->getArgs(4);
00311 AST::Array *vars = args->a[0]->getArray();
00312 int k=vars->a.size();
00313 for (int i=vars->a.size(); i--;)
00314 if (vars->a[i]->isInt())
00315 k--;
00316 IntVarArgs va(k);
00317 k=0;
00318 for (unsigned int i=0; i<vars->a.size(); i++) {
00319 if (vars->a[i]->isInt())
00320 continue;
00321 va[k++] = iv[vars->a[i]->getIntVar()];
00322 }
00323 branch(*this, va, ann2ivarsel(args->a[1]), ann2ivalsel(args->a[2]));
00324 hadSearchAnnotation = true;
00325 } catch (AST::TypeError& e) {
00326 (void) e;
00327 try {
00328 AST::Call *call = flatAnn[i]->getCall("bool_search");
00329 AST::Array *args = call->getArgs(4);
00330 AST::Array *vars = args->a[0]->getArray();
00331 int k=vars->a.size();
00332 for (int i=vars->a.size(); i--;)
00333 if (vars->a[i]->isBool())
00334 k--;
00335 BoolVarArgs va(k);
00336 k=0;
00337 for (unsigned int i=0; i<vars->a.size(); i++) {
00338 if (vars->a[i]->isBool())
00339 continue;
00340 va[k++] = bv[vars->a[i]->getBoolVar()];
00341 }
00342 branch(*this, va, ann2ivarsel(args->a[1]),
00343 ann2ivalsel(args->a[2]));
00344 hadSearchAnnotation = true;
00345 } catch (AST::TypeError& e) {
00346 (void) e;
00347 #ifdef GECODE_HAS_SET_VARS
00348 try {
00349 AST::Call *call = flatAnn[i]->getCall("set_search");
00350 AST::Array *args = call->getArgs(4);
00351 AST::Array *vars = args->a[0]->getArray();
00352 int k=vars->a.size();
00353 for (int i=vars->a.size(); i--;)
00354 if (vars->a[i]->isSet())
00355 k--;
00356 SetVarArgs va(k);
00357 k=0;
00358 for (unsigned int i=0; i<vars->a.size(); i++) {
00359 if (vars->a[i]->isSet())
00360 continue;
00361 va[k++] = sv[vars->a[i]->getSetVar()];
00362 }
00363 branch(*this, va, ann2svarsel(args->a[1]),
00364 ann2svalsel(args->a[2]));
00365 hadSearchAnnotation = true;
00366 } catch (AST::TypeError& e) {
00367 (void) e;
00368 std::cerr << "Warning, ignored search annotation: ";
00369 flatAnn[i]->print(std::cerr);
00370 std::cerr << std::endl;
00371 }
00372 #else
00373 std::cerr << "Warning, ignored search annotation: ";
00374 flatAnn[i]->print(std::cerr);
00375 std::cerr << std::endl;
00376 #endif
00377 }
00378 }
00379 }
00380 }
00381 if (!hadSearchAnnotation) {
00382 int countUp = 0;
00383 int countDown = iv.size()-1;
00384 IntVarArgs iva(iv.size());
00385 for (int i=0; i<iv.size(); i++)
00386 if (iv_introduced[i])
00387 iva[countDown--] = iv[i];
00388 else
00389 iva[countUp++] = iv[i];
00390 countUp = 0;
00391 countDown = bv.size()-1;
00392 BoolVarArgs bva(bv.size());
00393 for (int i=0; i<bv.size(); i++)
00394 if (bv_introduced[i])
00395 bva[countDown--] = bv[i];
00396 else
00397 bva[countUp++] = bv[i];
00398 branch(*this, iva, INT_VAR_NONE, INT_VAL_MIN);
00399 branch(*this, bva, INT_VAR_NONE, INT_VAL_MIN);
00400 #ifdef GECODE_HAS_SET_VARS
00401 countUp = 0;
00402 countDown = sv.size()-1;
00403 SetVarArgs sva(sv.size());
00404 for (int i=0; i<sv.size(); i++)
00405 if (sv_introduced[i])
00406 sva[countDown--] = sv[i];
00407 else
00408 sva[countUp++] = sv[i];
00409 branch(*this, sva, SET_VAR_NONE, SET_VAL_MIN_INC);
00410 #endif
00411 }
00412 }
00413
00414 void
00415 FlatZincSpace::solve(AST::Array* ann) {
00416 _method = SAT;
00417 parseSolveAnn(ann);
00418 }
00419
00420 void
00421 FlatZincSpace::minimize(int var, AST::Array* ann) {
00422 _method = MIN;
00423 _optVar = var;
00424 parseSolveAnn(ann);
00425
00426 IntVarArgs optVar(1);
00427 optVar[0] = iv[_optVar];
00428 branch(*this, optVar, INT_VAR_NONE, INT_VAL_MIN);
00429 }
00430
00431 void
00432 FlatZincSpace::maximize(int var, AST::Array* ann) {
00433 _method = MAX;
00434 _optVar = var;
00435 parseSolveAnn(ann);
00436
00437 IntVarArgs optVar(1);
00438 optVar[0] = iv[_optVar];
00439 branch(*this, optVar, INT_VAR_NONE, INT_VAL_MAX);
00440 }
00441
00442 #ifdef GECODE_HAS_GIST
00443
00447 template<class Engine>
00448 class GistEngine {
00449 };
00450
00452 template<typename S>
00453 class GistEngine<DFS<S> > {
00454 public:
00455 static void explore(S* root, Gist::Inspector* i) {
00456 Gecode::Gist::Options o; o.inspect.click(i);
00457 (void) Gecode::Gist::dfs(root, o);
00458 }
00459 };
00460
00462 template<typename S>
00463 class GistEngine<LDS<S> > {
00464 public:
00465 static void explore(S* root, Gist::Inspector* i) {
00466 Gecode::Gist::Options o; o.inspect.click(i);
00467 (void) Gecode::Gist::dfs(root, o);
00468 }
00469 };
00470
00472 template<typename S>
00473 class GistEngine<BAB<S> > {
00474 public:
00475 static void explore(S* root, Gist::Inspector* i) {
00476 Gecode::Gist::Options o; o.inspect.click(i);
00477 (void) Gecode::Gist::bab(root, o);
00478 }
00479 };
00480
00482 template<typename S>
00483 class GistEngine<Restart<S> > {
00484 public:
00485 static void explore(S* root, Gist::Inspector* i) {
00486 Gecode::Gist::Options o; o.inspect.click = i;
00487 (void) Gecode::Gist::bab(root, o);
00488 }
00489 };
00490
00492 template<class S>
00493 class FZPrintingInspector : public Gecode::Gist::TextInspector {
00494 private:
00495 const Printer& p;
00496 public:
00498 FZPrintingInspector(const Printer& p0);
00500 virtual void inspect(const Space& node);
00501 };
00502
00503 template<class S>
00504 FZPrintingInspector<S>::FZPrintingInspector(const Printer& p0)
00505 : TextInspector("Gecode/FlatZinc"), p(p0) {}
00506
00507 template<class S>
00508 void
00509 FZPrintingInspector<S>::inspect(const Space& node) {
00510 init();
00511 dynamic_cast<const S&>(node).print(getStream(), p);
00512 getStream() << std::endl;
00513 }
00514
00515 #endif
00516
00517 template<template<class> class Engine>
00518 void
00519 FlatZincSpace::runEngine(std::ostream& out, const Printer& p,
00520 const FlatZincOptions& opt, Support::Timer& t_total) {
00521 #ifdef GECODE_HAS_GIST
00522 if (opt.mode() == SM_GIST) {
00523 FZPrintingInspector<FlatZincSpace> pi(p);
00524 (void) GistEngine<Engine<FlatZincSpace> >::explore(this,&pi);
00525 return;
00526 }
00527 #endif
00528 StatusStatistics sstat;
00529 unsigned int n_p = 0;
00530 Support::Timer t_solve;
00531 t_solve.start();
00532 if (status(sstat) != SS_FAILED) {
00533 n_p = propagators();
00534 }
00535 Search::Options o;
00536 o.stop = Driver::Cutoff::create(opt.node(), opt.fail(), opt.time());
00537 o.c_d = opt.c_d();
00538 o.a_d = opt.a_d();
00539 o.threads = opt.threads();
00540 Engine<FlatZincSpace> se(this,o);
00541 int noOfSolutions = _method == SAT ? opt.solutions() : 0;
00542 int findSol = noOfSolutions;
00543 while (FlatZincSpace* sol = se.next()) {
00544 sol->print(out, p);
00545 out << "----------" << std::endl;
00546 delete sol;
00547 if (--findSol==0)
00548 goto stopped;
00549 }
00550 if (!se.stopped())
00551 out << "==========" << endl;
00552 stopped:
00553 if (opt.mode() == SM_STAT) {
00554 Gecode::Search::Statistics stat = se.statistics();
00555 out << endl
00556 << "%% runtime: ";
00557 Driver::stop(t_total,out);
00558 out << endl
00559 << "%% solvetime: ";
00560 Driver::stop(t_solve,out);
00561 out << endl
00562 << "%% solutions: "
00563 << std::abs(noOfSolutions - findSol) << endl
00564 << "%% variables: "
00565 << (intVarCount + boolVarCount + setVarCount) << endl
00566 << "%% propagators: " << n_p << endl
00567 << "%% propagations: " << sstat.propagate+stat.propagate << endl
00568 << "%% nodes: " << stat.node << endl
00569 << "%% failures: " << stat.fail << endl
00570 << "%% peak depth: " << stat.depth << endl
00571 << "%% peak memory: "
00572 << static_cast<int>((stat.memory+1023) / 1024) << " KB"
00573 << endl;
00574 }
00575 }
00576
00577 void
00578 FlatZincSpace::run(std::ostream& out, const Printer& p,
00579 const FlatZincOptions& opt, Support::Timer& t_total) {
00580 switch (_method) {
00581 case MIN:
00582 case MAX:
00583 runEngine<BAB>(out,p,opt,t_total);
00584 break;
00585 case SAT:
00586 runEngine<DFS>(out,p,opt,t_total);
00587 break;
00588 }
00589 }
00590
00591 void
00592 FlatZincSpace::constrain(const Space& s) {
00593 if (_method == MIN)
00594 rel(*this, iv[_optVar], IRT_LE,
00595 static_cast<const FlatZincSpace*>(&s)->iv[_optVar].val());
00596 else
00597 rel(*this, iv[_optVar], IRT_GR,
00598 static_cast<const FlatZincSpace*>(&s)->iv[_optVar].val());
00599 }
00600
00601 Space*
00602 FlatZincSpace::copy(bool share) {
00603 return new FlatZincSpace(share, *this);
00604 }
00605
00606 FlatZincSpace::Meth
00607 FlatZincSpace::method(void) {
00608 return _method;
00609 }
00610
00611 void
00612 FlatZincSpace::print(std::ostream& out, const Printer& p) const {
00613 p.print(out, iv, bv
00614 #ifdef GECODE_HAS_SET_VARS
00615 , sv
00616 #endif
00617 );
00618 }
00619
00620 void
00621 Printer::init(AST::Array* output) {
00622 _output = output;
00623 }
00624
00625 void
00626 Printer::printElem(std::ostream& out,
00627 AST::Node* ai,
00628 const Gecode::IntVarArray& iv,
00629 const Gecode::BoolVarArray& bv
00630 #ifdef GECODE_HAS_SET_VARS
00631 , const Gecode::SetVarArray& sv
00632 #endif
00633 ) const {
00634 int k;
00635 if (ai->isInt(k)) {
00636 out << k;
00637 } else if (ai->isIntVar()) {
00638 out << iv[ai->getIntVar()];
00639 } else if (ai->isBoolVar()) {
00640 if (bv[ai->getBoolVar()].min() == 1) {
00641 out << "true";
00642 } else if (bv[ai->getBoolVar()].max() == 0) {
00643 out << "false";
00644 } else {
00645 out << "false..true";
00646 }
00647 #ifdef GECODE_HAS_SET_VARS
00648 } else if (ai->isSetVar()) {
00649 if (!sv[ai->getSetVar()].assigned()) {
00650 out << sv[ai->getSetVar()];
00651 return;
00652 }
00653 SetVarGlbRanges svr(sv[ai->getSetVar()]);
00654 if (!svr()) {
00655 out << "{}";
00656 return;
00657 }
00658 int min = svr.min();
00659 int max = svr.max();
00660 ++svr;
00661 if (svr()) {
00662 SetVarGlbValues svv(sv[ai->getSetVar()]);
00663 int i = svv.val();
00664 out << "{" << i;
00665 ++svv;
00666 for (; svv(); ++svv)
00667 out << ", " << svv.val();
00668 out << "}";
00669 } else {
00670 out << min << ".." << max;
00671 }
00672 #endif
00673 } else if (ai->isBool()) {
00674 out << (ai->getBool() ? "true" : "false");
00675 } else if (ai->isSet()) {
00676 AST::SetLit* s = ai->getSet();
00677 if (s->interval) {
00678 out << s->min << ".." << s->max;
00679 } else {
00680 out << "{";
00681 for (unsigned int i=0; i<s->s.size(); i++) {
00682 out << s->s[i] << (i < s->s.size()-1 ? ", " : "}");
00683 }
00684 }
00685 } else if (ai->isString()) {
00686 std::string s = ai->getString();
00687 for (unsigned int i=0; i<s.size(); i++) {
00688 if (s[i] == '\\' && i<s.size()-1) {
00689 switch (s[i+1]) {
00690 case 'n': out << "\n"; break;
00691 case '\\': out << "\\"; break;
00692 case 't': out << "\t"; break;
00693 default: out << "\\" << s[i+1];
00694 }
00695 i++;
00696 } else {
00697 out << s[i];
00698 }
00699 }
00700 }
00701 }
00702
00703 void
00704 Printer::print(std::ostream& out,
00705 const Gecode::IntVarArray& iv,
00706 const Gecode::BoolVarArray& bv
00707 #ifdef GECODE_HAS_SET_VARS
00708 ,
00709 const Gecode::SetVarArray& sv
00710 #endif
00711 ) const {
00712 if (_output == NULL)
00713 return;
00714 for (unsigned int i=0; i< _output->a.size(); i++) {
00715 AST::Node* ai = _output->a[i];
00716 if (ai->isArray()) {
00717 AST::Array* aia = ai->getArray();
00718 int size = aia->a.size();
00719 out << "[";
00720 for (int j=0; j<size; j++) {
00721 printElem(out,aia->a[j],iv,bv
00722 #ifdef GECODE_HAS_SET_VARS
00723 ,sv
00724 #endif
00725 );
00726 if (j<size-1)
00727 out << ", ";
00728 }
00729 out << "]";
00730 } else if (ai->isCall("ifthenelse")) {
00731 AST::Array* aia = ai->getCall("ifthenelse")->getArgs(3);
00732 if (aia->a[0]->isBool()) {
00733 if (aia->a[0]->getBool())
00734 printElem(out, aia->a[1], iv,bv
00735 #ifdef GECODE_HAS_SET_VARS
00736 ,sv
00737 #endif
00738 );
00739 else
00740 printElem(out, aia->a[2], iv,bv
00741 #ifdef GECODE_HAS_SET_VARS
00742 ,sv
00743 #endif
00744 );
00745 } else if (aia->a[0]->isBoolVar()) {
00746 BoolVar b = bv[aia->a[0]->getBoolVar()];
00747 if (b.one())
00748 printElem(out, aia->a[1], iv,bv
00749 #ifdef GECODE_HAS_SET_VARS
00750 ,sv
00751 #endif
00752 );
00753 else if (b.zero())
00754 printElem(out, aia->a[2], iv,bv
00755 #ifdef GECODE_HAS_SET_VARS
00756 ,sv
00757 #endif
00758 );
00759 else
00760 std::cerr << "Error: Condition not fixed." << std::endl;
00761 } else {
00762 std::cerr << "Error: Condition not Boolean." << std::endl;
00763 }
00764 } else {
00765 printElem(out,ai,iv,bv
00766 #ifdef GECODE_HAS_SET_VARS
00767 ,sv
00768 #endif
00769 );
00770 }
00771 }
00772 }
00773
00774 Printer::~Printer(void) {
00775 delete _output;
00776 }
00777
00778 }}
00779
00780