Generated on Wed Mar 19 07:30:01 2008 for Gecode by doxygen 1.5.5

reflection.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2007
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-03-04 10:14:14 +0100 (Tue, 04 Mar 2008) $ by $Author: tack $
00011  *     $Revision: 6403 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "gecode/kernel.hh"
00039 
00040 namespace Gecode { namespace Reflection {
00041 
00042   // Registry
00043 
00045   class Registry::RegistryObject {
00046   public:
00048     Support::SymbolMap<poster> posters;
00050     Support::SymbolMap<varCreator> varCreators;
00052     Support::SymbolMap<varConstrainer> varConstrainers;
00054     Support::SymbolMap<varUpdater> varUpdaters;
00056     Support::SymbolMap<varPrinter> varPrinters;
00058     Support::SymbolMap<varSpec> varSpecs;
00059   };
00060   
00061   Registry::Registry(void) : ro(new RegistryObject()) {}
00062 
00063   Registry::~Registry(void) { delete ro; }
00064 
00065   Registry& registry(void) {
00066     static Registry r;
00067     return r;
00068   };
00069   
00070   VarImpBase*
00071   Registry::createVar(Space* home, VarSpec& spec) const {
00072     varCreator vc = NULL;
00073     if (!ro->varCreators.get(spec.vti(),vc)) {
00074       throw Reflection::ReflectionException("VTI not found");
00075     }
00076     return vc(home, spec);
00077   }
00078 
00079   void
00080   Registry::constrainVar(Space* home, VarImpBase* v, VarSpec& spec) const {
00081     varConstrainer vc = NULL;
00082     if (!ro->varConstrainers.get(spec.vti(),vc)) {
00083       throw Reflection::ReflectionException("VTI not found");
00084     }
00085     vc(home, v, spec);
00086   }
00087 
00088   VarImpBase*
00089   Registry::updateVariable(Space* home, bool share, VarImpBase* v,
00090                            const Support::Symbol& vti) const {
00091     varUpdater vu = NULL;
00092     if (!ro->varUpdaters.get(vti,vu)) {
00093       throw Reflection::ReflectionException("VTI not found");
00094     }
00095     return vu(home, share, v);
00096   }
00097 
00098   std::ostream&
00099   Registry::printVariable(std::ostream& os, VarImpBase* v,
00100                           const Support::Symbol& vti) const {
00101     varPrinter vp = NULL;
00102     if (!ro->varPrinters.get(vti,vp)) {
00103       throw Reflection::ReflectionException("VTI not found");
00104     }
00105     return vp(os, v);
00106   }
00107 
00108   Arg*
00109   Registry::spec(const Space* home, VarMap& vm,
00110                  VarImpBase* v, const Support::Symbol& vti) const {
00111     varSpec vs = NULL;
00112     if (!ro->varSpecs.get(vti,vs)) {
00113       throw Reflection::ReflectionException("VTI not found");      
00114     }
00115     return vs(home, vm, v);
00116   }
00117 
00118   void
00119   Registry::post(Space* home, VarMap& vm, const ActorSpec& spec) const {
00120     poster p = NULL;
00121     if (!ro->posters.get(spec.ati(),p)) {
00122       throw Reflection::ReflectionException("Constraint not found");
00123     }
00124     p(home, vm, spec);
00125   }
00126 
00127   void
00128   Registry::add(Support::Symbol vti, varCreator vc) {
00129     ro->varCreators.put(vti, vc);
00130   }
00131 
00132   void
00133   Registry::add(Support::Symbol vti, varConstrainer vc) {
00134     ro->varConstrainers.put(vti, vc);
00135   }
00136 
00137   void
00138   Registry::add(Support::Symbol vti, varUpdater vu) {
00139     ro->varUpdaters.put(vti, vu);
00140   }
00141 
00142   void
00143   Registry::add(Support::Symbol vti, varPrinter vp) {
00144     ro->varPrinters.put(vti, vp);
00145   }
00146 
00147   void
00148   Registry::add(Support::Symbol vti, varSpec vs) {
00149     ro->varSpecs.put(vti, vs);
00150   }
00151 
00152   void
00153   Registry::add(const Support::Symbol& id, poster p) {
00154     ro->posters.put(id, p);
00155   }
00156 
00157   void
00158   Registry::print(std::ostream&) {
00159   }
00160 
00161   /*
00162    * Arguments
00163    *
00164    */
00165 
00166   Arg::Arg(argtype t0) : t(t0) {}
00167   
00168   bool
00169   Arg::isInt(void) const {
00170     return t == INT_ARG;
00171   }
00172   int
00173   Arg::toInt(void) const {
00174     if (!isInt())
00175       throw ReflectionException("not an IntArg");
00176     return arg1.i;
00177   }
00178   Arg*
00179   Arg::newInt(int i) {
00180     Arg* ret = new Arg(INT_ARG);
00181     ret->arg1.i = i;
00182     return ret;
00183   }
00184   void
00185   Arg::initInt(int i) {
00186     t = INT_ARG;
00187     arg1.i = i;
00188   }
00189 
00190   bool
00191   Arg::isVar(void) const {
00192     return (t == VAR_ARG);
00193   }
00194   int
00195   Arg::toVar(void) const {
00196     if (!isVar())
00197       throw ReflectionException("not a VarArg");
00198     return arg1.i;
00199   }
00200   Arg*
00201   Arg::newVar(int i) {
00202     Arg* ret = new Arg(VAR_ARG);
00203     ret->arg1.i = i;
00204     return ret;
00205   }
00206   void
00207   Arg::initVar(int i) {
00208     t = VAR_ARG;
00209     arg1.i = i;
00210   }
00211 
00212   bool
00213   Arg::isArray(void) const {
00214     return (t == ARRAY_ARG);
00215   }
00216   ArrayArg*
00217   Arg::toArray(void) {
00218     if (!isArray())
00219       throw ReflectionException("not an ArrayArg");
00220     return static_cast<ArrayArg*>(this);
00221   }
00222   const ArrayArg*
00223   Arg::toArray(void) const {
00224     if (!isArray())
00225       throw ReflectionException("not an ArrayArg");
00226     return static_cast<const ArrayArg*>(this);
00227   }
00228   ArrayArg*
00229   Arg::newArray(int n) {
00230     Arg* ret = new Arg(ARRAY_ARG);
00231     ret->arg1.i = n;
00232     if (n > 0)
00233       ret->arg2.aa = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*n));
00234     else
00235       ret->arg2.aa = NULL;
00236     return static_cast<ArrayArg*>(ret);
00237   }
00238   void
00239   Arg::initArray(int n) {
00240     t = ARRAY_ARG;
00241     arg1.i = n;
00242     arg2.aa = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*n));
00243   }
00244 
00245   bool
00246   Arg::isIntArray(void) const {
00247     return (t == INT_ARRAY_ARG);
00248   }
00249   IntArrayArg*
00250   Arg::toIntArray(void) {
00251     if (!isIntArray())
00252       throw ReflectionException("not an IntArrayArg");
00253     return static_cast<IntArrayArg*>(this);
00254   }
00255   const IntArrayArg*
00256   Arg::toIntArray(void) const {
00257     if (!isIntArray())
00258       throw ReflectionException("not an IntArrayArg");
00259     return static_cast<const IntArrayArg*>(this);
00260   }
00261   IntArrayArg*
00262   Arg::newIntArray(int n) {
00263     Arg* ret = new Arg(INT_ARRAY_ARG);
00264     ret->arg1.i = n;
00265     if (n > 0)
00266       ret->arg2.ia = static_cast<int*>(Memory::malloc(sizeof(int)*n));
00267     else
00268       ret->arg2.ia = NULL;
00269     return static_cast<IntArrayArg*>(ret);
00270   }
00271   void
00272   Arg::initIntArray(int n) {
00273     t = INT_ARRAY_ARG;
00274     arg1.i = n;
00275     arg2.ia = static_cast<int*>(Memory::malloc(sizeof(int)*n));
00276   }
00277 
00278   bool
00279   Arg::isString(void) const {
00280     return (t == STRING_ARG);
00281   }
00282   const char*
00283   Arg::toString(void) const {
00284     if (!isString())
00285       throw ReflectionException("not a StringArg");
00286     return arg1.s;
00287   }
00288 
00289 #if defined(_MSC_VER)
00290 #define strdup _strdup
00291 #endif
00292 
00293   Arg*
00294   Arg::newString(const char* s) {
00295     Arg* ret = new Arg(STRING_ARG);
00296     ret->arg1.s = strdup(s);
00297     return ret;    
00298   }
00299   void
00300   Arg::initString(const char* s) {
00301     t = STRING_ARG;
00302     arg1.s = strdup(s);
00303   }
00304 
00305 #if defined(_MSC_VER)
00306 #undef strdup
00307 #endif
00308 
00309   bool
00310   Arg::isPair(void) const {
00311     return (t == PAIR_ARG);
00312   }
00313   Arg*
00314   Arg::first(void) {
00315     if (!isPair())
00316       throw ReflectionException("not a PairArg");
00317     return arg1.first;
00318   }
00319   const Arg*
00320   Arg::first(void) const {
00321     if (!isPair())
00322       throw ReflectionException("not a PairArg");
00323     return arg1.first;
00324   }
00325   Arg*
00326   Arg::second(void) {
00327     if (!isPair())
00328       throw ReflectionException("not a PairArg");
00329     return arg2.second;
00330   }
00331   const Arg*
00332   Arg::second(void) const {
00333     if (!isPair())
00334       throw ReflectionException("not a PairArg");
00335     return arg2.second;
00336   }
00337   Arg*
00338   Arg::newPair(Arg* a, Arg* b) {
00339     Arg* ret = new Arg(PAIR_ARG);
00340     ret->arg1.first = a;
00341     ret->arg2.second = b;
00342     return ret;
00343   }
00344   void
00345   Arg::initPair(Arg* a, Arg* b) {
00346     t = PAIR_ARG;
00347     arg1.first = a;
00348     arg2.second = b;
00349   }
00350 
00351   bool
00352   Arg::isSharedObject(void) const {
00353     return (t == SHARED_OBJECT_ARG);
00354   }
00355   Arg*
00356   Arg::toSharedObject(void) {
00357     if (!isSharedObject())
00358       throw ReflectionException("not a SharedObjectArg");
00359     return arg1.first;
00360   }
00361   const Arg*
00362   Arg::toSharedObject(void) const {
00363     if (!isSharedObject())
00364       throw ReflectionException("not a SharedObjectArg");
00365     return arg1.first;
00366   }
00367   Arg*
00368   Arg::newSharedObject(Arg* a) {
00369     Arg* ret = new Arg(SHARED_OBJECT_ARG);
00370     ret->arg1.first = a;
00371     return ret;
00372   }
00373   void
00374   Arg::initSharedObject(Arg* a) {
00375     t = SHARED_OBJECT_ARG;
00376     arg1.first = a;
00377   }
00378   
00379   bool
00380   Arg::isSharedReference(void) const {
00381     return (t == SHARED_REF_ARG);
00382   }
00383   int
00384   Arg::toSharedReference(void) const {
00385     if (!isSharedReference())
00386       throw ReflectionException("not a SharedReferenceArg");
00387     return arg1.i;
00388   }
00389   Arg*
00390   Arg::newSharedReference(int ref) {
00391     Arg* ret = new Arg(SHARED_REF_ARG);
00392     ret->arg1.i = ref;
00393     return ret;
00394   }
00395   void
00396   Arg::initSharedReference(int ref) {
00397     t = SHARED_REF_ARG;
00398     arg1.i = ref;
00399   }
00400 
00401   Arg::~Arg(void) {
00402     switch (t) {
00403     case ARRAY_ARG:
00404       for (int i=arg1.i; i--;)
00405         delete arg2.aa[i];
00406       if (arg2.aa != NULL)
00407         Memory::free(arg2.aa);
00408       break;
00409     case INT_ARRAY_ARG:
00410       if (arg2.ia != NULL)
00411         Memory::free(arg2.ia);
00412       break;
00413     case PAIR_ARG:
00414       delete arg1.first;
00415       delete arg2.second;
00416       break;
00417     case STRING_ARG:
00418       ::free(arg1.s);
00419       break;
00420     case SHARED_OBJECT_ARG:
00421       delete arg1.first;
00422       break;
00423     default:
00424       break;
00425     }
00426   }
00427 
00428   const Arg*
00429   ArrayArg::operator[](int i) const {
00430     if (i >= arg1.i)
00431       throw ReflectionException("Array index out of range");
00432     return arg2.aa[i];
00433   }
00434   Arg*&
00435   ArrayArg::operator[](int i) {
00436     if (i >= arg1.i)
00437       throw ReflectionException("Array index out of range");
00438     return arg2.aa[i];
00439   }
00440   int
00441   ArrayArg::size(void) const {
00442     return arg1.i;
00443   }
00444 
00445   const int&
00446   IntArrayArg::operator[](int i) const {
00447     if (i >= arg1.i)
00448       throw ReflectionException("Array index out of range");
00449     return arg2.ia[i];
00450   }
00451   int&
00452   IntArrayArg::operator[](int i) {
00453     if (i >= arg1.i)
00454       throw ReflectionException("Array index out of range");
00455     return arg2.ia[i];
00456   }
00457   int
00458   IntArrayArg::size(void) const {
00459     return arg1.i;
00460   }
00461 
00462   IntArrayArgRanges::IntArrayArgRanges(Reflection::IntArrayArg* a0) 
00463     : a(a0), n(0) {}
00464 
00465   bool
00466   IntArrayArgRanges::operator()(void) { return n < a->size(); }
00467 
00468   void
00469   IntArrayArgRanges::operator++(void) { n += 2; }
00470 
00471   int
00472   IntArrayArgRanges::min(void) const { return (*a)[n]; }
00473 
00474   int
00475   IntArrayArgRanges::max(void) const { return (*a)[n+1]; }
00476 
00477   unsigned int
00478   IntArrayArgRanges::width(void) const { 
00479     return static_cast<unsigned int>(max() - min()) + 1; 
00480   }
00481 
00482   //
00483   // VarSpec
00484   //
00485 
00487   class VarSpec::Domain {
00488   public:
00490     Support::Symbol _vti;
00492     Support::Symbol _n;
00494     Arg* _dom;
00496     int r;
00498     Domain(Support::Symbol vti, Arg* domain);
00500     ~Domain(void);
00501   };
00502 
00503   /*
00504    * Variable specifications
00505    *
00506    */
00507 
00508   inline
00509   VarSpec::Domain::Domain(Support::Symbol vti, Arg* domain)
00510   : _vti(vti), _dom(domain), r(1) {}
00511 
00512   inline
00513   VarSpec::Domain::~Domain(void) {
00514     delete _dom;
00515   }
00516 
00517   VarSpec::VarSpec(void) : _dom(NULL) {}
00518   
00519   VarSpec::VarSpec(Support::Symbol vti, Arg* dom) 
00520   : _dom(new Domain(vti,dom)) {}
00521 
00522   VarSpec::VarSpec(const VarSpec& s) : _dom(s._dom) {
00523     if (_dom)
00524       _dom->r++;
00525   }
00526   
00527   const VarSpec&
00528   VarSpec::operator=(const VarSpec& s) {
00529     if (this != &s) {
00530       if (_dom && --_dom->r == 0)
00531         delete _dom;
00532       _dom = s._dom;
00533       if (_dom)
00534         _dom->r++;
00535     }
00536     return *this;
00537   }
00538   
00539   VarSpec::~VarSpec(void) {
00540     if (_dom && --_dom->r == 0)
00541       delete _dom;
00542   }
00543 
00544   void
00545   VarSpec::name(const Support::Symbol& n) {
00546     if (_dom == NULL)
00547       throw ReflectionException("Empty VarSpec");
00548     _dom->_n = n;
00549   }
00550   
00551   Support::Symbol
00552   VarSpec::name(void) const {
00553     if (_dom == NULL)
00554       throw ReflectionException("Empty VarSpec");
00555     return _dom->_n;
00556   }
00557 
00558   bool
00559   VarSpec::hasName(void) const {
00560     if (_dom == NULL)
00561       throw ReflectionException("Empty VarSpec");
00562     return !_dom->_n.empty();
00563   }
00564 
00565   Support::Symbol
00566   VarSpec::vti(void) const {
00567     if (_dom == NULL)
00568       throw ReflectionException("Empty VarSpec");
00569     return _dom->_vti;
00570   }
00571 
00572   Arg*
00573   VarSpec::dom(void) const {
00574     if (_dom == NULL)
00575       throw ReflectionException("Empty VarSpec");
00576     return _dom->_dom;
00577   }
00578 
00579   //
00580   // ActorSpec
00581   //
00582 
00584   class ActorSpec::Arguments {
00585   public:
00587     Support::Symbol _ati;
00589     int   size;
00591     int   n;
00593     Arg** a;
00595     int queue;
00597     int r;
00599     Arguments(const Support::Symbol&);
00601     ~Arguments(void);
00602   };
00603 
00604   /*
00605    * Actor specifications
00606    *
00607    */
00608 
00609   inline
00610   ActorSpec::Arguments::Arguments(const Support::Symbol& ati)
00611    :  _ati(ati), size(4), n(0), r(1) {
00612      a = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*size));
00613   }
00614 
00615   inline
00616   ActorSpec::Arguments::~Arguments(void) {
00617     for (int i=n; i--;)
00618       delete a[i];
00619     Memory::free(a);
00620   }
00621 
00622   void
00623   ActorSpec::resize(void) {
00624     assert(_args != NULL);
00625     _args->size = _args->size * 3 / 2;
00626     Arg** newargs =
00627       static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*_args->size));
00628     for (int i=_args->n; i--;)
00629       newargs[i] = _args->a[i];
00630     Memory::free(_args->a);
00631     _args->a = newargs;
00632   }
00633 
00634   ActorSpec::ActorSpec(void) : _args(NULL) {}
00635 
00636   ActorSpec::ActorSpec(const Support::Symbol& ati) {
00637     _args = new Arguments(ati);
00638   }
00639 
00640   ActorSpec::ActorSpec(const ActorSpec& s) : _args(s._args) {
00641     if (_args != NULL)
00642       _args->r++;
00643   }
00644   
00645   const ActorSpec&
00646   ActorSpec::operator=(const ActorSpec& s) {
00647     if (this != &s) {
00648       if (_args && --_args->r == 0)
00649         delete _args;
00650       _args = s._args;
00651       if (_args)
00652         _args->r++;
00653     }
00654     return *this;
00655   }
00656 
00657   Arg*
00658   ActorSpec::operator[](int i) const {
00659     if (_args == NULL || i < 0 || i >= _args->n)
00660       throw ReflectionException("Array index out of range");
00661     return _args->a[i];
00662   }
00663 
00664   int
00665   ActorSpec::noOfArgs(void) const {
00666     return _args == NULL ? 0 : _args->n;
00667   }
00668 
00669   void
00670   ActorSpec::checkArity(int n) const {
00671     if (_args == NULL || _args->n != n) {
00672       throw ReflectionException("Illegal arity in ActorSpec");
00673     }
00674   }
00675 
00676   Support::Symbol
00677   ActorSpec::ati(void) const {
00678     if (_args == NULL)
00679       throw ReflectionException("Empty ActorSpec");
00680     return _args->_ati;
00681   }
00682 
00683   bool
00684   ActorSpec::isBranching(void) const {
00685     if (_args == NULL)
00686       throw ReflectionException("Empty ActorSpec");
00687     return _args->queue < 0;
00688   }
00689 
00690   int
00691   ActorSpec::queue(void) const {
00692     if (_args == NULL)
00693       throw ReflectionException("Empty ActorSpec");
00694     return _args->queue-1;
00695   }
00696 
00697   unsigned int
00698   ActorSpec::branchingId(void) const {
00699     if (_args == NULL)
00700       throw ReflectionException("Empty ActorSpec");
00701     assert(isBranching());
00702     return static_cast<unsigned int>(-_args->queue-1);
00703   }
00704 
00705   ActorSpec::~ActorSpec(void) {
00706     if (_args && --_args->r == 0)
00707       delete _args;
00708   }
00709 
00710   void
00711   ActorSpec::add(Arg* arg) {
00712     if (_args == NULL)
00713       throw ReflectionException("Empty ActorSpec");
00714     if (_args->n == _args->size)
00715       resize();
00716     _args->a[_args->n] = arg;
00717     _args->n++;
00718   }
00719 
00720   void
00721   ActorSpec::queue(int q) {
00722     if (_args == NULL)
00723       throw ReflectionException("Empty ActorSpec");
00724     _args->queue = q;
00725   }
00726 
00727   /*
00728    * Branch specification
00729    *
00730    */
00731    
00733   class BranchingSpec::Arguments {
00734   public:
00736     unsigned int   n;
00738     Arg** a;
00740     unsigned int id;
00742     int r;
00744     Arguments(unsigned int id, unsigned int a);
00746     ~Arguments(void);
00747   };
00748 
00749   inline
00750   BranchingSpec::Arguments::Arguments(unsigned int id0, unsigned int n0)
00751    : n(n0), id(id0), r(1) {
00752      a = static_cast<Arg**>(Memory::malloc(sizeof(Arg*)*n));
00753      for (unsigned int i=n; i--;)
00754        a[i] = NULL;
00755   }
00756 
00757   inline
00758   BranchingSpec::Arguments::~Arguments(void) {
00759     for (unsigned int i=n; i--;)
00760       delete a[i];
00761     Memory::free(a);
00762   }
00763   
00764   BranchingSpec::BranchingSpec(void) : _args(NULL) {}
00765   
00766   BranchingSpec::BranchingSpec(const BranchingDesc* d) {
00767     _args = new Arguments(d->id(), d->alternatives());
00768   }
00769 
00770   BranchingSpec::BranchingSpec(const BranchingSpec& s) : _args(s._args) {
00771     if (_args)
00772       _args->r++;
00773   }
00774   
00775   const BranchingSpec&
00776   BranchingSpec::operator=(const BranchingSpec& s) {
00777     if (this != &s) {
00778       if (_args && --_args->r == 0)
00779         delete _args;
00780       _args = s._args;
00781       if (_args)
00782         _args->r++;
00783     }
00784     return *this;
00785   }
00786 
00787   Arg*
00788   BranchingSpec::operator[](int i) const {
00789     if (_args == NULL || i < 0 || static_cast<unsigned int>(i) >= _args->n)
00790       throw ReflectionException("Array index out of range");
00791     return _args->a[i];
00792   }
00793 
00794   Arg*&
00795   BranchingSpec::operator[](int i) {
00796     if (_args == NULL || i < 0 || static_cast<unsigned int>(i) >= _args->n)
00797       throw ReflectionException("Array index out of range");
00798     return _args->a[i];
00799   }
00800 
00801   BranchingSpec::~BranchingSpec(void) {
00802     if (_args && --_args->r == 0)
00803       delete _args;
00804   }
00805   
00806   bool
00807   BranchingSpec::createdBy(const ActorSpec& b) const {
00808     if (!b.isBranching())
00809       throw ReflectionException("ActorSpec does not belong to a Branching");
00810     return _args != NULL && _args->id == b.branchingId();
00811   }
00812 
00813   unsigned int
00814   BranchingSpec::alternatives(void) const {
00815     return _args == NULL ? 0 : _args->n;
00816   }
00817   
00818 
00819   /*
00820    * Specification iterator
00821    *
00822    */
00823    
00824   bool
00825   ActorSpecIter::operator()(void) const {
00826     return cur != &s->a_actors;
00827   }
00828 
00829   void
00830   ActorSpecIter::operator++(void) {
00831     cur = cur->next();
00832     while (active > &s->pc.p.queue[0] && (cur == active)) {
00833       active--;
00834       cur = active;
00835       cur = cur->next();
00836     }
00837     if (active == &s->pc.p.queue[0] && cur == active) {
00838       active--;
00839       cur = s->a_actors.next();
00840     }
00841     if (cur == s->b_commit)
00842       isBranching = true;
00843   }
00844 
00845   ActorSpecIter::ActorSpecIter(const Space* s0, VarMap& m0)
00846   : m(&m0), s(s0),
00847     active(s0->pc.p.active == NULL ?
00848            &s->pc.p.queue[PC_MAX] : s0->pc.p.active),
00849     cur(active),
00850     isBranching(false) {
00851     if (s->stable() && !s->failed())
00852       cur = &s->a_actors;
00853     ++(*this);
00854   }
00855 
00856   ActorSpec
00857   ActorSpecIter::actor(void) const {
00858     ActorSpec spec = static_cast<const Actor*>(cur)->spec(s,*m);
00859     if (isBranching)
00860       spec.queue(-1-static_cast<const Branching*>(cur)->id);
00861     else
00862       spec.queue( (active - &s->pc.p.queue[0]) + 1);
00863     return spec;
00864   }
00865 
00866   Unreflector::Unreflector(Space* home0, Reflection::VarMap& m0)
00867     : home(home0), m(m0) {}
00868 
00869   Unreflector::~Unreflector(void) {}
00870     
00871   Reflection::VarMap&
00872   Unreflector::varMap(void) const {
00873     return m;
00874   }
00875 
00876   void
00877   Unreflector::var(Reflection::VarSpec& spec) {
00878     VarImpBase* vb = NULL;
00879     if (!spec.name().empty() &&
00880         (vb = m.varImpBase(spec.name())) != NULL) {
00881       // TODO: assert that spec and original var are compatible,
00882       // constrain domain of var to spec
00883       Reflection::registry().constrainVar(home, vb, spec);
00884     } else {
00885       vb = Reflection::registry().createVar(home, spec);
00886     }
00887     (void) m.put(vb, new Reflection::VarSpec(spec));
00888   }
00889 
00890   void
00891   Unreflector::post(Reflection::ActorSpec& spec) {
00892     Reflection::registry().post(home, m, spec);
00893   }
00894 
00895   /* Generic variable */
00896   
00897   void
00898   Var::update(Space* home, bool share, Var& v) {
00899     new (&_vti) Support::Symbol(v._vti);
00900     _var = registry().updateVariable(home, share, v._var, v._vti);
00901   }
00902 
00903   std::ostream&
00904   Var::print(std::ostream& os) const {
00905     return registry().printVariable(os, _var, _vti);
00906   }
00907   
00908   Arg*
00909   Var::spec(const Space* home, VarMap& vm) const {
00910     return registry().spec(home, vm, _var, _vti);
00911   }
00912 
00913 }}
00914 
00915 std::ostream&
00916 operator<<(std::ostream& os, const Gecode::Reflection::Var& v) {
00917   return v.print(os);
00918 }
00919 
00920 
00921 // STATISTICS: kernel-other