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

reflection.icc

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-05 09:20:52 +0100 (Wed, 05 Mar 2008) $ by $Author: tack $
00011  *     $Revision: 6414 $
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 <iostream>
00039 #include <cstring>
00040 
00046 namespace Gecode { namespace Reflection {
00047   
00052 
00053   class GECODE_VTABLE_EXPORT ReflectionException : public Exception {
00054   public:
00056     ReflectionException(const char* what) : Exception("Reflection", what) {}
00057   };
00058 
00060   class GECODE_VTABLE_EXPORT NoReflectionDefinedException
00061   : public ReflectionException {
00062   public:
00063     NoReflectionDefinedException(void)
00064     : ReflectionException("No reflection defined") {}
00065   };
00066 
00068   
00069   class ArrayArg;
00070   class IntArrayArg;
00071   
00084   class GECODE_KERNEL_EXPORT Arg {
00085   protected:
00087     enum argtype {
00088       INT_ARG,           
00089       VAR_ARG,           
00090       ARRAY_ARG,         
00091       INT_ARRAY_ARG,     
00092       STRING_ARG,        
00093       PAIR_ARG,          
00094       SHARED_OBJECT_ARG, 
00095       SHARED_REF_ARG     
00096     };
00097 
00099     argtype t;
00100     
00101     union {
00103       int i;
00105       char* s;
00107       Arg* first;
00108     } arg1;
00109 
00110     union {
00112       Arg* second;
00114       Arg** aa;
00116       int* ia;
00117     } arg2;
00119     Arg(argtype t);
00120     
00121   public:
00123     bool         isInt(void) const;
00125     int          toInt(void) const;
00127     static Arg*  newInt(int i);
00129     void         initInt(int i);
00130     
00132     bool         isVar(void) const;
00134     int          toVar(void) const;
00136     static Arg*  newVar(int i);
00138     void         initVar(int i);
00139     
00141     bool             isArray(void) const;
00143     ArrayArg*        toArray(void);
00145     const ArrayArg*  toArray(void) const;
00147     static ArrayArg* newArray(int n);
00149     void         initArray(int n);
00150     
00152     bool                isIntArray(void) const;
00154     IntArrayArg*        toIntArray(void);
00156     const IntArrayArg*  toIntArray(void) const;
00158     static IntArrayArg* newIntArray(int n);
00160     template <class A>
00161     static IntArrayArg* newIntArray(const A& a);
00163     void         initIntArray(int n);
00164 
00166     bool         isString(void) const;
00168     const char*  toString(void) const;
00170     static Arg*  newString(const char* s);
00172     void         initString(const char* s);
00173     
00175     bool         isPair(void) const;
00177     Arg*         first(void);
00179     const Arg*   first(void) const;
00181     Arg*         second(void);
00183     const Arg*   second(void) const;
00185     static Arg*  newPair(Arg* a, Arg* b);
00187     void         initPair(Arg* a, Arg* b);
00188     
00190     bool         isSharedObject(void) const;
00192     Arg*         toSharedObject(void);
00194     const Arg*   toSharedObject(void) const;
00196     static Arg*  newSharedObject(Arg* a);
00198     void         initSharedObject(Arg* a);
00199     
00201     bool         isSharedReference(void) const;
00203     int          toSharedReference(void) const;
00205     static Arg*  newSharedReference(int ref);
00207     void         initSharedReference(int ref);
00208     
00210     GECODE_MSC_VIRTUAL ~Arg(void);
00211   };
00212   
00213 
00222   class GECODE_KERNEL_EXPORT ArrayArg : public Arg {
00223   private:
00225     ArrayArg(void);
00226   public:
00228     const Arg* operator[](int i) const;
00230     Arg*& operator[](int i);
00232     int size(void) const;
00233   };
00234 
00243   class GECODE_KERNEL_EXPORT IntArrayArg : public Arg {
00244   private:
00246     IntArrayArg(void);
00247   public:
00249     const int& operator[](int i) const;
00251     int& operator[](int i);
00253     int size(void) const;
00254   };
00255 
00262   class GECODE_KERNEL_EXPORT IntArrayArgRanges {
00263   private:
00265     Reflection::IntArrayArg* a;
00267     int n;
00268   public:
00270     IntArrayArgRanges(Reflection::IntArrayArg* a0);
00272     bool operator()(void);
00274     void operator++(void);
00276     int min(void) const;
00278     int max(void) const;
00280     unsigned int width(void) const;
00281   };
00282   
00299   class GECODE_KERNEL_EXPORT VarSpec {
00300   private:
00301     class Domain;
00303     Domain* _dom;
00304   public:
00306     VarSpec(void);
00308     VarSpec(Support::Symbol vti, Arg* domain);
00310     VarSpec(const VarSpec& s);
00312     const VarSpec& operator=(const VarSpec& s);
00314     GECODE_MSC_VIRTUAL ~VarSpec(void);
00316     void name(const Support::Symbol& n0);
00318     Support::Symbol name(void) const;
00320     bool hasName(void) const;
00322     Arg* dom(void) const;
00323     // Get the variable type identifier for this variable
00324     Support::Symbol vti(void) const;
00325   };
00326   
00348   class GECODE_KERNEL_EXPORT ActorSpec {
00349     friend class BranchingSpec;
00350   private:
00351     class Arguments;
00353     Arguments* _args;
00355     void resize(void);
00356     friend class ActorSpecIter;
00358     void queue(int q);
00362     unsigned int branchingId(void) const;
00363   public:
00365     ActorSpec(void);
00367     ActorSpec(const Support::Symbol& name);
00369     ActorSpec(const ActorSpec& s);
00371     const ActorSpec& operator=(const ActorSpec& s);
00373     GECODE_MSC_VIRTUAL ~ActorSpec(void);
00374     
00376 
00377 
00378     Support::Symbol ati(void) const;
00380     int noOfArgs(void) const;
00382     void checkArity(int n) const;
00384     Arg* operator[](int i) const;
00385 
00387     bool isBranching(void) const;
00391     int queue(void) const;
00393     
00395 
00396 
00397     void add(Arg* arg);
00399   };
00400 
00401 }}
00402 
00406 Gecode::Reflection::ActorSpec
00407 operator<<(Gecode::Reflection::ActorSpec s, Gecode::Reflection::Arg* arg);
00408 
00409 
00413 Gecode::Reflection::ActorSpec
00414 operator<<(Gecode::Reflection::ActorSpec s, int i);
00415 
00419 Gecode::Reflection::ActorSpec
00420 operator<<(Gecode::Reflection::ActorSpec s, unsigned int i);
00421 
00425 Gecode::Reflection::ActorSpec
00426 operator<<(Gecode::Reflection::ActorSpec s, double i);
00427 
00428 /* Implementation of ActorSpec operators */
00429 
00430 forceinline Gecode::Reflection::ActorSpec
00431 operator<<(Gecode::Reflection::ActorSpec s, Gecode::Reflection::Arg* arg) {
00432   s.add(arg);
00433   return s;
00434 }
00435 forceinline Gecode::Reflection::ActorSpec
00436 operator<<(Gecode::Reflection::ActorSpec s, int i) {
00437   return s << Gecode::Reflection::Arg::newInt(i);
00438 }
00439 forceinline Gecode::Reflection::ActorSpec
00440 operator<<(Gecode::Reflection::ActorSpec s, unsigned int i) {
00441   return s << Gecode::Reflection::Arg::newInt(static_cast<int>(i));
00442 }
00443 forceinline Gecode::Reflection::ActorSpec
00444 operator<<(Gecode::Reflection::ActorSpec s, double i) {
00445   return s << Gecode::Reflection::Arg::newInt(static_cast<int>(i));
00446 }
00447 
00448 namespace Gecode { namespace Reflection {
00449 
00464   class GECODE_KERNEL_EXPORT BranchingSpec {
00465   private:
00466     class Arguments;
00468     Arguments* _args;
00469   public:
00471     BranchingSpec(void);
00479     BranchingSpec(const BranchingDesc* d);
00481     BranchingSpec(const BranchingSpec& s);
00483     const BranchingSpec& operator=(const BranchingSpec& s);
00485     GECODE_MSC_VIRTUAL ~BranchingSpec(void);
00486     
00488 
00489 
00490     bool createdBy(const ActorSpec& b) const;
00492     unsigned int alternatives(void) const;
00494     Arg* operator[](int i) const;
00495     
00497     Arg*& operator[](int i);
00499   };
00500   
00501   class VarMap;
00502 
00512   class GECODE_KERNEL_EXPORT ActorSpecIter {
00513   private:
00515     VarMap*      m;
00517     const Space* s;
00519     const ActorLink *active;
00521     const ActorLink *cur;
00523     bool       isBranching;
00524   public:
00526     ActorSpecIter(const Space*, VarMap&);
00528     bool operator()(void) const;
00530     void operator++(void);
00532     ActorSpec actor(void) const;
00533   };
00534 
00539   class Registry {
00540   private:
00541     class RegistryObject;
00542     RegistryObject* ro;
00543   public:
00545     typedef void (*poster) (Space*, VarMap&, const ActorSpec&);
00547     typedef VarImpBase* (*varCreator) (Space*, VarSpec&);
00549     typedef void (*varConstrainer) (Space*, VarImpBase*, VarSpec&);
00551     typedef VarImpBase* (*varUpdater) (Space*, bool, VarImpBase*);
00553     typedef std::ostream& (*varPrinter) (std::ostream&, VarImpBase*);
00555     typedef Arg* (*varSpec) (const Space* home, VarMap& m, VarImpBase*);
00556 
00558     GECODE_KERNEL_EXPORT Registry(void);
00560     GECODE_KERNEL_EXPORT GECODE_MSC_VIRTUAL ~Registry(void);
00561 
00563     GECODE_KERNEL_EXPORT VarImpBase*
00564     createVar(Space* home, VarSpec& spec) const;
00565 
00567     GECODE_KERNEL_EXPORT void
00568     constrainVar(Space* home, VarImpBase* v, VarSpec& spec) const;
00569 
00571     GECODE_KERNEL_EXPORT VarImpBase*
00572     updateVariable(Space* home, bool share, VarImpBase* v,
00573                    const Support::Symbol& vti) const;
00574 
00576     GECODE_KERNEL_EXPORT std::ostream&
00577     printVariable(std::ostream& os, VarImpBase* v,
00578                   const Support::Symbol& vti) const;
00579 
00581     GECODE_KERNEL_EXPORT Arg*
00582     spec(const Space* home, VarMap& vm,
00583          VarImpBase* v, const Support::Symbol& vti) const;
00584 
00586     GECODE_KERNEL_EXPORT void
00587     post(Space* home, VarMap& vm, const ActorSpec& spec) const;
00588 
00590     GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varCreator vc);
00592     GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varConstrainer vc);
00594     GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varUpdater vu);
00596     GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varPrinter vp);
00598     GECODE_KERNEL_EXPORT void add(Support::Symbol vti, varSpec vp);
00600     GECODE_KERNEL_EXPORT void add(const Support::Symbol& ati, poster p);
00602     GECODE_KERNEL_EXPORT void print(std::ostream& out);
00603   private:
00605     Registry(const Registry&);
00607     Registry& operator=(const Registry&);
00608   };
00609   
00611   GECODE_KERNEL_EXPORT Registry& registry(void);
00612 
00621   template <class P>
00622   class ActorRegistrar {
00623   public:
00625     ActorRegistrar(void);
00626   };
00627 
00628   template <class P>
00629   ActorRegistrar<P>::ActorRegistrar(void) {
00630     registry().add(P::ati(), &P::post);
00631   }
00632 
00642   template <class V>
00643   class VarImpRegistrar {
00644   private:
00645     static VarImpBase* updateVar(Space* home, bool share, VarImpBase* v);
00646     static std::ostream& printVar(std::ostream& os, VarImpBase* v);
00647     static Reflection::Arg* spec(const Space* home, Reflection::VarMap& m,
00648                                  VarImpBase* v);
00649   public:
00651     VarImpRegistrar(void);
00652   };
00653 
00654   template <class V>
00655   VarImpBase*
00656   VarImpRegistrar<V>::updateVar(Space* home, bool share, VarImpBase* v) {
00657     typedef typename VarImpVarTraits<V>::Var Var;
00658     typedef typename VarViewTraits<Var>::View View;
00659     View view(static_cast<V*>(v));
00660     Var var(view);
00661     Var varCopy;
00662     varCopy.update(home, share, var);
00663     View viewCopy(varCopy);
00664     return viewCopy.var();
00665   }
00666 
00667   template <class V>
00668   std::ostream&
00669   VarImpRegistrar<V>::printVar(std::ostream& os, VarImpBase* v) {
00670     typedef typename VarImpVarTraits<V>::Var Var;
00671     typedef typename VarViewTraits<Var>::View View;
00672     View view(static_cast<V*>(v));
00673     Var var(view);
00674     return os << var;
00675   }
00676 
00677   template <class V>
00678   Reflection::Arg*
00679   VarImpRegistrar<V>::spec(const Space* home, Reflection::VarMap& m,
00680                            VarImpBase* v) {
00681     typedef typename VarImpVarTraits<V>::Var Var;
00682     typedef typename VarViewTraits<Var>::View View;
00683     View view(static_cast<V*>(v));
00684     return view.spec(home, m);
00685   }
00686 
00687   template <class V>
00688   VarImpRegistrar<V>::VarImpRegistrar(void) {
00689     registry().add(V::vti, &V::create);
00690     registry().add(V::vti, &V::constrain);
00691     registry().add(V::vti, &VarImpRegistrar<V>::updateVar);
00692     registry().add(V::vti, &VarImpRegistrar<V>::printVar);
00693     registry().add(V::vti, &VarImpRegistrar<V>::spec);
00694   }
00695 
00705   class Var {
00706   private:
00708     VarImpBase* _var;
00710     Support::Symbol _vti;
00711   public:
00713     Var(void);
00715     template <class V> explicit Var(const V& v);
00717     Var(VarImpBase* var, const Support::Symbol& vti);
00719     GECODE_KERNEL_EXPORT void update(Space* home, bool share, Var& v);
00721     GECODE_KERNEL_EXPORT std::ostream& print(std::ostream& os) const;
00723     GECODE_KERNEL_EXPORT Arg* spec(const Space* home, VarMap& vm) const;
00725     template <class VarImp>
00726     VarImp* var(void) const;
00727   };
00728 
00737   class GECODE_KERNEL_EXPORT Unreflector {
00738   private:
00740     Space* home;
00742     Reflection::VarMap& m;
00743     
00744   public:
00746     Unreflector(Space* home0, Reflection::VarMap& m0);
00747 
00749     GECODE_MSC_VIRTUAL ~Unreflector(void);
00750     
00752     Reflection::VarMap& varMap(void) const;
00753     
00755     void var(Reflection::VarSpec& spec);
00756 
00758     void post(Reflection::ActorSpec& spec);
00759   };
00760 
00761   forceinline
00762   Var::Var(void) {}
00763     
00764   template <class V>
00765   Var::Var(const V& v) {
00766     typedef typename VarViewTraits<V>::View View;
00767     View view(v);
00768     _var = view.var();
00769     _vti = view.var()->vti;
00770   }
00771 
00772   template <>
00773   inline
00774   Var::Var(const Var& v) : _var(v._var), _vti(v._vti) {}
00775   
00776   inline
00777   Var::Var(VarImpBase* var, const Support::Symbol& vti)
00778     : _var(var), _vti(vti) {}
00779 
00780   template <>
00781   inline VarImpBase*
00782   Var::var(void) const {
00783     return static_cast<VarImpBase*>(_var);
00784   }
00785   
00786   template <class VarImp>
00787   VarImp*
00788   Var::var(void) const {
00789     if (! (VarImp::vti == _vti))
00790       throw ReflectionException("VTI mismatch");
00791     return static_cast<VarImp*>(_var);
00792   }
00793 
00798 
00799 #define GECODE_REGISTER1(P) \
00800   ::Gecode::Reflection::ActorRegistrar< P > GECODE_FRESH(r);
00802 #define GECODE_REGISTER2(P1,P2) \
00803   ::Gecode::Reflection::ActorRegistrar< P1,P2 > GECODE_FRESH(r);
00805 #define GECODE_REGISTER3(P1,P2,P3) \
00806   ::Gecode::Reflection::ActorRegistrar< P1,P2,P3 > GECODE_FRESH(r);
00808 #define GECODE_REGISTER4(P1,P2,P3,P4) \
00809   ::Gecode::Reflection::ActorRegistrar< P1,P2,P3,P4 > GECODE_FRESH(r);
00811 #define GECODE_REGISTER5(P1,P2,P3,P4,P5) \
00812   ::Gecode::Reflection::ActorRegistrar< P1,P2,P3,P4,P5 > GECODE_FRESH(r);
00814 #define GECODE_REGISTER6(P1,P2,P3,P4,P5,P6) \
00815   ::Gecode::Reflection::ActorRegistrar< P1,P2,P3,P4,P5,P6 > GECODE_FRESH(r);
00816 
00818 
00819   /**************************************
00820    * Implementations
00821    **************************************/
00822 
00823   template <class A>
00824   IntArrayArg*
00825   Arg::newIntArray(const A& a) {
00826     IntArrayArg* ret = Arg::newIntArray(a.size());
00827     for (int i=a.size(); i--;)
00828       (*ret)[i] = a[i];
00829     return ret;
00830   }
00831   
00838   template <class View>
00839   class TypeOf {
00840   public:
00842     static Support::Symbol t(void) { return View::type(); }
00843   };
00844   
00847   template <>
00848   class TypeOf<bool> {
00849   public:
00851     static Support::Symbol t(void) { return Support::Symbol("bool"); }
00852   };
00853 
00856   template <>
00857   class TypeOf<int> {
00858   public:
00860     static Support::Symbol t(void) { return Support::Symbol("int"); }
00861   };
00862 
00865   template <>
00866   class TypeOf<double> {
00867   public:
00869     static Support::Symbol t(void) { return Support::Symbol("double"); }
00870   };
00871 
00873 
00874 }
00875   class IntSet;
00876 namespace Reflection {
00877 
00884   template <>
00885   class TypeOf<const IntSet> {
00886   public:
00888     static Support::Symbol t(void) { return Support::Symbol("IntSet"); }    
00889   };
00890 
00892   template <class View0>
00893   Support::Symbol
00894   mangle(const Support::Symbol& ati) {
00895     Support::Symbol mangled = ati.copy();
00896     mangled += "<";
00897     mangled += TypeOf<View0>::t();
00898     mangled += ">";
00899     return mangled;
00900   }
00902   template <class View0, bool b>
00903   Support::Symbol
00904   mangle(const Support::Symbol& ati) {
00905     Support::Symbol mangled = ati.copy();
00906     mangled += "<";
00907     mangled += TypeOf<View0>::t();
00908     mangled += ",";
00909     mangled += (b ? "true" : "false");
00910     mangled += ">";
00911     return mangled;
00912   }
00914   template <class View0, class View1>
00915   Support::Symbol
00916   mangle(const Support::Symbol& ati) {
00917     Support::Symbol mangled = ati.copy();
00918     mangled += "<";
00919     mangled += TypeOf<View0>::t();
00920     mangled += ",";
00921     mangled += TypeOf<View1>::t();
00922     mangled += ">";
00923     return mangled;
00924   }
00926   template <class View0, class View1, bool b>
00927   Support::Symbol
00928   mangle(const Support::Symbol& ati) {
00929     Support::Symbol mangled = ati.copy();
00930     mangled += "<";
00931     mangled += TypeOf<View0>::t();
00932     mangled += ",";
00933     mangled += TypeOf<View1>::t();
00934     mangled += ",";
00935     mangled += (b ? "true" : "false");
00936     mangled += ">";
00937     return mangled;
00938   }
00940   template <class View0, class View1, class View2>
00941   Support::Symbol
00942   mangle(const Support::Symbol& ati) {
00943     Support::Symbol mangled = ati.copy();
00944     mangled += "<";
00945     mangled += TypeOf<View0>::t();
00946     mangled += ",";
00947     mangled += TypeOf<View1>::t();
00948     mangled += ",";
00949     mangled += TypeOf<View2>::t();
00950     mangled += ">";
00951     return mangled;
00952   }
00954   template <class View0, class View1, class View2, bool b>
00955   Support::Symbol
00956   mangle(const Support::Symbol& ati) {
00957     Support::Symbol mangled = ati.copy();
00958     mangled += "<";
00959     mangled += TypeOf<View0>::t();
00960     mangled += ",";
00961     mangled += TypeOf<View1>::t();
00962     mangled += ",";
00963     mangled += TypeOf<View2>::t();
00964     mangled += ",";
00965     mangled += (b ? "true" : "false");
00966     mangled += ">";
00967     return mangled;
00968   }
00970   template <class View0, class View1, class View2, class View3>
00971   Support::Symbol
00972   mangle(const Support::Symbol& ati) {
00973     Support::Symbol mangled = ati.copy();
00974     mangled += "<";
00975     mangled += TypeOf<View0>::t();
00976     mangled += ",";
00977     mangled += TypeOf<View1>::t();
00978     mangled += ",";
00979     mangled += TypeOf<View2>::t();
00980     mangled += ",";
00981     mangled += TypeOf<View3>::t();
00982     mangled += ">";
00983     return mangled;
00984   }
00986   template <class View0, class View1, class View2, class View3, bool b>
00987   Support::Symbol
00988   mangle(const Support::Symbol& ati) {
00989     Support::Symbol mangled = ati.copy();
00990     mangled += "<";
00991     mangled += TypeOf<View0>::t();
00992     mangled += ",";
00993     mangled += TypeOf<View1>::t();
00994     mangled += ",";
00995     mangled += TypeOf<View2>::t();
00996     mangled += ",";
00997     mangled += TypeOf<View3>::t();
00998     mangled += ",";
00999     mangled += (b ? "true" : "false");
01000     mangled += ">";
01001     return mangled;
01002   }
01003   
01005 
01006 }}
01007 
01009 GECODE_KERNEL_EXPORT std::ostream&
01010 operator<<(std::ostream& os, const Gecode::Reflection::Var& v);
01011 
01012 // STATISTICS: kernel-other