basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/routine.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : routine.hpp
00004 * DESCRIPTION: Abstract routines for generic expressions
00005 * COPYRIGHT  : (C) 2006  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #ifndef __ROUTINE_HPP
00014 #define __ROUTINE_HPP
00015 #include <basix/evaluator.hpp>
00016 #include <basix/vector.hpp>
00017 #include <basix/wrap.hpp>
00018 #include <basix/compound.hpp>
00019 
00021 
00022 namespace mmx {
00023 class environment;
00024 
00025 /******************************************************************************
00026 * Abstraction
00027 *****************************************************************************/
00028 
00029 template<typename T>
00030 struct generic_converter {
00031   static inline T make_concrete (const generic& x) {
00032     return as<T,generic> (x); }
00033   static inline generic make_abstract (const T& x) {
00034     // NOTE: returning as<generic,T> does not seem to call the appropriate
00035     // converter in the case when T=bool. A compiler bug?
00036     return new generic_concrete_rep<T> (x); }
00037 };
00038 
00039 STMPL
00040 struct generic_converter<generic> {
00041   static inline generic make_concrete (const generic& x) {
00042     return x; }
00043   static inline generic make_abstract (const generic& x) {
00044     return x; }
00045 };
00046 
00047 template<typename T> inline T
00048 make_concrete (const generic& x) {
00049   return generic_converter<T>::make_concrete (x);
00050 }
00051 
00052 template<typename T> inline generic
00053 make_abstract (const T& x) {
00054   return generic_converter<T>::make_abstract (x);
00055 }
00056 
00057 /******************************************************************************
00058 * Abstract generic routines
00059 ******************************************************************************/
00060 
00061 class routine;
00062 class routine_rep: public rep_struct {
00063 public:
00064   generic name;
00065 public:
00066   inline routine_rep (const generic& name2): name (name2) {}
00067   virtual inline ~routine_rep () {}
00068   virtual generic apply () const;
00069   virtual generic apply (const generic& g1) const;
00070   virtual generic apply (const generic& g1, const generic& g2) const;
00071   virtual generic apply (const vector<generic>& args) const;
00072   virtual vector<nat> signature () const;
00073   virtual void overload (const routine& fun) const;
00074   virtual bool is_overloaded () const;
00075   virtual vector<routine> meanings () const;
00076   virtual generic function_body () const;
00077   virtual generic function_type () const;
00078   virtual routine clone () const;
00079 };
00080 
00081 class routine {
00082 INDIRECT_PROTO (routine, routine_rep)
00083 public:
00084   inline const routine_rep* operator * () const { return rep; }
00085   inline routine (): rep (NULL) {}
00086   inline generic operator () () {
00087     return rep->apply (); }
00088   inline generic operator () (const generic& g1) {
00089     return rep->apply (g1); }
00090   inline generic operator () (const generic& g1, const generic& g2) {
00091     return rep->apply (g1, g2); }
00092   inline generic operator () (const vector<generic>& v) {
00093     return rep->apply (v); }
00094   friend inline bool is_nil (const routine& fun);
00095 };
00096 INDIRECT_NULL_IMPL (routine, routine_rep)
00097 
00098 inline bool is_nil (const routine& fun) {
00099   return fun.rep == NULL; }
00100 inline syntactic flatten (const routine& fun) {
00101   if (is_nil (fun)) return as_syntactic (GEN_NIL);
00102   else return as_syntactic (fun->name); }
00103 
00104 WRAP_INDIRECT_IMPL(inline,routine)
00105 
00106 /******************************************************************************
00107 * Evaluation
00108 ******************************************************************************/
00109 
00110 inline generic
00111 eval (const routine& f, const vector<generic>& v) {
00112   return f->apply (v);
00113 }
00114 
00115 template<typename C> inline C
00116 eval (const routine& f, const vector<C>& v) {
00117   return as<C> (f->apply (as<vector<generic> > (v)));
00118 }
00119 
00120 template<typename C> vector<C>
00121 eval (const vector<routine>& f, const vector<C>& v) {
00122   vector<C> r= fill<C> (N(f));
00123   for (nat i=0; i<N(f); i++)
00124     r[i]= eval (f[i], v);
00125   return r;
00126 }
00127 
00128 /******************************************************************************
00129 * Concrete generic routines
00130 ******************************************************************************/
00131 
00132 template<typename D>
00133 class nullary_routine_rep: public routine_rep {
00134   typedef D (*function_type) ();
00135   function_type fun;
00136 public:
00137   nullary_routine_rep (const generic& name, function_type fun2):
00138     routine_rep (name), fun (fun2) {}
00139   generic apply () const {
00140     return make_abstract<D> (fun ());
00141   }
00142   generic apply (const vector<generic>& v) const {
00143     ASSERT (N(v) == 0, "zero arguments expected");
00144     return apply ();
00145   }
00146   vector<nat> signature () const {
00147     return vec<nat> (type_information<D>::id);
00148   }
00149 };
00150 
00151 template<>
00152 class nullary_routine_rep<void>: public routine_rep {
00153   typedef void (*function_type) ();
00154   function_type fun;
00155 public:
00156   nullary_routine_rep (const generic& name, function_type fun2):
00157     routine_rep (name), fun (fun2) {}
00158   generic apply () const {
00159     fun ();
00160     return void_value ();
00161   }
00162   generic apply (const vector<generic>& v) const {
00163     ASSERT (N(v) == 0, "zero arguments expected");
00164     return apply ();
00165   }
00166   vector<nat> signature () const {
00167     return vec<nat> ((nat) 0);
00168   }
00169 };
00170 
00171 template<typename D> routine
00172 nullary_routine (const generic& name, D (*fun) ()) {
00173   return new nullary_routine_rep<D> (name, fun);
00174 }
00175 
00176 extern generic type_name (nat id);
00177 
00178 template<typename D, typename S1>
00179 class unary_routine_rep: public routine_rep {
00180   typedef D (*function_type) (const S1&);
00181   function_type fun;
00182 public:
00183   unary_routine_rep (const generic& name, function_type fun2):
00184     routine_rep (name), fun (fun2) {}
00185   generic apply (const generic& x1) const {
00186     return make_abstract<D> (fun (make_concrete<S1> (x1)));
00187   }
00188   generic apply (const vector<generic>& v) const {
00189     ASSERT (N(v) == 1, "one argument expected");
00190     return apply (v[0]);
00191   }
00192   vector<nat> signature () const {
00193     return vec<nat> (type_information<D>::id, type_information<S1>::id);
00194   }
00195 };
00196 
00197 template<typename S1>
00198 class unary_routine_rep<void,S1>: public routine_rep {
00199   typedef void (*function_type) (const S1&);
00200   function_type fun;
00201 public:
00202   unary_routine_rep (const generic& name, function_type fun2):
00203     routine_rep (name), fun (fun2) {}
00204   generic apply (const generic& x1) const {
00205     fun (make_concrete<S1> (x1));
00206     return void_value ();
00207   }
00208   generic apply (const vector<generic>& v) const {
00209     ASSERT (N(v) == 1, "one argument expected");
00210     return apply (v[0]);
00211   }
00212   vector<nat> signature () const {
00213     return vec<nat> ((nat) 0, type_information<S1>::id);
00214   }
00215 };
00216 
00217 template<typename D, typename S1> routine
00218 unary_routine (const generic& name, D (*fun) (const S1&)) {
00219   return new unary_routine_rep<D,S1> (name, fun);
00220 }
00221 
00222 template<typename D, typename S1, typename S2>
00223 class binary_routine_rep: public routine_rep {
00224   typedef D (*function_type) (const S1&, const S2&);
00225   function_type fun;
00226 public:
00227   binary_routine_rep (const generic& name, function_type fun2):
00228     routine_rep (name), fun (fun2) {}
00229   generic apply (const generic& x1, const generic& x2) const {
00230     return make_abstract<D> (fun (make_concrete<S1> (x1),
00231                                   make_concrete<S2> (x2)));
00232   }
00233   generic apply (const vector<generic>& v) const {
00234     ASSERT (N(v) == 2, "two arguments expected");
00235     return apply (v[0], v[1]);
00236   }
00237   vector<nat> signature () const {
00238     return vec<nat> (type_information<D>::id,
00239                      type_information<S1>::id,
00240                      type_information<S2>::id);
00241   }
00242 };
00243 
00244 template<typename S1, typename S2>
00245 class binary_routine_rep<void,S1,S2>: public routine_rep {
00246   typedef void (*function_type) (const S1&, const S2&);
00247   function_type fun;
00248 public:
00249   binary_routine_rep (const generic& name, function_type fun2):
00250     routine_rep (name), fun (fun2) {}
00251   generic apply (const generic& x1, const generic& x2) const {
00252     fun (make_concrete<S1> (x1), make_concrete<S2> (x2));
00253     return void_value ();
00254   }
00255   generic apply (const vector<generic>& v) const {
00256     ASSERT (N(v) == 2, "two arguments expected");
00257     return apply (v[0], v[1]);
00258   }
00259   vector<nat> signature () const {
00260     return vec<nat> ((nat) 0,
00261                      type_information<S1>::id,
00262                      type_information<S2>::id);
00263   }
00264 };
00265 
00266 template<typename D, typename S1, typename S2> routine
00267 binary_routine (const generic& name, D (*f) (const S1&, const S2&)) {
00268   return new binary_routine_rep<D,S1,S2> (name, f);
00269 }
00270 
00271 template<typename D, typename S1, typename S2, typename S3>
00272 class ternary_routine_rep: public routine_rep {
00273   typedef D (*function_type) (const S1&, const S2&, const S3&);
00274   function_type fun;
00275 public:
00276   ternary_routine_rep (const generic& name, function_type fun2):
00277     routine_rep (name), fun (fun2) {}
00278   generic apply (const vector<generic>& v) const {
00279     ASSERT (N(v) == 3, "three arguments expected");
00280     return make_abstract<D> (fun (make_concrete<S1> (v[0]),
00281                                   make_concrete<S2> (v[1]),
00282                                   make_concrete<S3> (v[2])));
00283   }
00284   vector<nat> signature () const {
00285     return vec<nat> (type_information<D>::id,
00286                      type_information<S1>::id,
00287                      type_information<S2>::id,
00288                      type_information<S3>::id);
00289   }
00290 };
00291 
00292 template<typename S1, typename S2, typename S3>
00293 class ternary_routine_rep<void,S1,S2,S3>: public routine_rep {
00294   typedef void (*function_type) (const S1&, const S2&, const S3&);
00295   function_type fun;
00296 public:
00297   ternary_routine_rep (const generic& name, function_type fun2):
00298     routine_rep (name), fun (fun2) {}
00299   generic apply (const vector<generic>& v) const {
00300     ASSERT (N(v) == 3, "three arguments expected");
00301     fun (make_concrete<S1> (v[0]),
00302          make_concrete<S2> (v[1]),
00303          make_concrete<S3> (v[2]));
00304     return void_value ();
00305   }
00306   vector<nat> signature () const {
00307     return vec<nat> ((nat) 0,
00308                      type_information<S1>::id,
00309                      type_information<S2>::id,
00310                      type_information<S3>::id);
00311   }
00312 };
00313 
00314 template<typename D, typename S1, typename S2, typename S3> routine
00315 ternary_routine (const generic& name,
00316                  D (*f) (const S1&, const S2&, const S3&)) {
00317   return new ternary_routine_rep<D,S1,S2,S3> (name, f);
00318 }
00319 
00320 template<typename D, typename S1, typename S2, typename S3, typename S4>
00321 class quaternary_routine_rep: public routine_rep {
00322   typedef D (*function_type) (const S1&, const S2&, const S3&, const S4&);
00323   function_type fun;
00324 public:
00325   quaternary_routine_rep (const generic& name, function_type fun2):
00326     routine_rep (name), fun (fun2) {}
00327   generic apply (const vector<generic>& v) const {
00328     ASSERT (N(v) == 4, "four arguments expected");
00329     return make_abstract<D> (fun (make_concrete<S1> (v[0]),
00330                                   make_concrete<S2> (v[1]),
00331                                   make_concrete<S3> (v[2]),
00332                                   make_concrete<S4> (v[3])));
00333   }
00334   vector<nat> signature () const {
00335     return vec<nat> (type_information<D>::id,
00336                      type_information<S1>::id,
00337                      type_information<S2>::id,
00338                      type_information<S3>::id,
00339                      type_information<S4>::id);
00340   }
00341 };
00342 
00343 template<typename S1, typename S2, typename S3, typename S4>
00344 class quaternary_routine_rep<void,S1,S2,S3,S4>: public routine_rep {
00345   typedef void (*function_type) (const S1&, const S2&, const S3&, const S4&);
00346   function_type fun;
00347 public:
00348   quaternary_routine_rep (const generic& name, function_type fun2):
00349     routine_rep (name), fun (fun2) {}
00350   generic apply (const vector<generic>& v) const {
00351     ASSERT (N(v) == 4, "four arguments expected");
00352     fun (make_concrete<S1> (v[0]),
00353          make_concrete<S2> (v[1]),
00354          make_concrete<S3> (v[2]),
00355          make_concrete<S4> (v[3]));
00356     return void_value ();
00357   }
00358   vector<nat> signature () const {
00359     return vec<nat> ((nat) 0,
00360                      type_information<S1>::id,
00361                      type_information<S2>::id,
00362                      type_information<S3>::id,
00363                      type_information<S4>::id);
00364   }
00365 };
00366 
00367 template<typename D, typename S1, typename S2, typename S3, typename S4> routine
00368 quaternary_routine (const generic& name,
00369                     D (*f) (const S1&, const S2&, const S3&,const S4&)) {
00370   return new quaternary_routine_rep<D,S1,S2,S3,S4> (name, f);
00371 }
00372 
00373 template<typename D, typename S1, typename S2, typename S3,
00374          typename S4, typename S5>
00375 class quintary_routine_rep: public routine_rep {
00376   typedef D (*function_type) (const S1&, const S2&, const S3&,
00377                               const S4&, const S5&);
00378   function_type fun;
00379 public:
00380   quintary_routine_rep (const generic& name, function_type fun2):
00381     routine_rep (name), fun (fun2) {}
00382   generic apply (const vector<generic>& v) const {
00383     ASSERT (N(v) == 5, "five arguments expected");
00384     return make_abstract<D> (fun (make_concrete<S1> (v[0]),
00385                                   make_concrete<S2> (v[1]),
00386                                   make_concrete<S3> (v[2]),
00387                                   make_concrete<S4> (v[3]),
00388                                   make_concrete<S4> (v[4])));
00389   }
00390   vector<nat> signature () const {
00391     return vec<nat> (type_information<D>::id,
00392                      type_information<S1>::id,
00393                      type_information<S2>::id,
00394                      type_information<S3>::id,
00395                      type_information<S4>::id,
00396                      type_information<S5>::id);
00397   }
00398 };
00399 
00400 template<typename S1, typename S2, typename S3, typename S4, typename S5>
00401 class quintary_routine_rep<void,S1,S2,S3,S4,S5>: public routine_rep {
00402   typedef void (*function_type) (const S1&, const S2&, const S3&,
00403                                  const S4&, const S5&);
00404   function_type fun;
00405 public:
00406   quintary_routine_rep (const generic& name, function_type fun2):
00407     routine_rep (name), fun (fun2) {}
00408   generic apply (const vector<generic>& v) const {
00409     ASSERT (N(v) == 4, "four arguments expected");
00410     fun (make_concrete<S1> (v[0]),
00411          make_concrete<S2> (v[1]),
00412          make_concrete<S3> (v[2]),
00413          make_concrete<S4> (v[3]),
00414          make_concrete<S4> (v[4]));
00415     return void_value ();
00416   }
00417   vector<nat> signature () const {
00418     return vec<nat> ((nat) 0,
00419                      type_information<S1>::id,
00420                      type_information<S2>::id,
00421                      type_information<S3>::id,
00422                      type_information<S4>::id,
00423                      type_information<S5>::id);
00424   }
00425 };
00426 
00427 template<typename D, typename S1, typename S2, typename S3,
00428          typename S4, typename S5> routine
00429 quintary_routine (const generic& name,
00430                   D (*f) (const S1&, const S2&, const S3&,
00431                           const S4&, const S5&)) {
00432   return new quintary_routine_rep<D,S1,S2,S3,S4,S5> (name, f);
00433 }
00434 
00435 /******************************************************************************
00436 * Other types of routines
00437 ******************************************************************************/
00438 
00439 routine identity_routine (const vector<nat>& sig);
00440 routine compose (const routine& fun, const vector<routine>& args);
00441 inline routine compose (const routine& fun, const routine& arg) {
00442   return compose (fun, vec (arg)); }
00443 routine change_signature (const routine& r, const vector<nat>& sig);
00444 routine default_routine (const generic& name);
00445 routine integrate (const routine& fun);
00446 
00447 } // namespace mmx
00448 #endif // __ROUTINE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines