basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/routine.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : routine.cpp
00004 * DESCRIPTION: Abstract routines on 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 #include <basix/routine.hpp>
00014 #include <basix/string.hpp>
00015 #include <basix/tuple.hpp>
00016 #include <basix/alias.hpp>
00017 namespace mmx {
00018 
00019 /******************************************************************************
00020 * Routines for debugging
00021 ******************************************************************************/
00022 
00023 vector<generic>
00024 type_name (const vector<nat>& ids) {
00025   nat i, n= N(ids);
00026   vector<generic> ret= fill<generic> (n);
00027   for (i=0; i<n; i++)
00028     ret[i]= type_name (ids[i]);
00029   return ret;
00030 }
00031 
00032 /******************************************************************************
00033 * Generic routines
00034 ******************************************************************************/
00035 
00036 generic
00037 routine_rep::apply () const {
00038   return apply (vec<generic> ());
00039 }
00040 
00041 generic
00042 routine_rep::apply (const generic& g1) const {
00043   return apply (vec<generic> (g1));
00044 }
00045 
00046 generic
00047 routine_rep::apply (const generic& g1, const generic& g2) const {
00048   return apply (vec<generic> (g1, g2));
00049 }
00050 
00051 generic
00052 routine_rep::apply (const vector<generic>& v) const {
00053   mmerr << "name= " << name << "\n";
00054   mmerr << "args= " << v << "\n";
00055   ERROR ("not implemented (apply)");
00056   return generic ();
00057 }
00058 
00059 vector<nat>
00060 routine_rep::signature () const {
00061   ERROR ("not implemented (signature)");
00062   return vec<nat> ();
00063 }
00064 
00065 void
00066 routine_rep::overload (const routine& fun) const {
00067   ERROR ("not implemented (overload)");
00068 }
00069 
00070 bool
00071 routine_rep::is_overloaded () const {
00072   return false;
00073 }
00074 
00075 vector<routine>
00076 routine_rep::meanings () const {
00077   ERROR ("not implemented (meanings)");
00078 }
00079 
00080 generic
00081 routine_rep::function_body () const {
00082   return "native";
00083 }
00084 
00085 generic
00086 routine_rep::function_type () const {
00087   return gen (GEN_FUNCTION_TYPE, type_name (signature ()));
00088 }
00089 
00090 routine
00091 routine_rep::clone () const {
00092   ERROR ("not implemented (clone)");
00093   return routine (this, true);
00094 }
00095 
00096 /******************************************************************************
00097 * Identity routines
00098 ******************************************************************************/
00099 
00100 class identity_routine_rep: public routine_rep {
00101   vector<nat> sig;
00102 public:
00103   identity_routine_rep (const vector<nat>& sig2):
00104     routine_rep (GEN_IDENTITY), sig (sig2) {}
00105   generic apply (const generic& x) const { return x; }
00106   generic apply (const vector<generic>& v) const {
00107     ASSERT (N(v) == 1, "one argument expected"); return apply (v[0]); }
00108   vector<nat> signature () const { return sig; }
00109 };
00110 
00111 routine
00112 identity_routine (const vector<nat>& sig) {
00113   // WARNING: we do allow for "fake identity functions" with sig[0] != sig[1]
00114   // This is useful for fast conversions to generic
00115   ASSERT (N(sig) == 2, "identity routine should take one argument");
00116   return new identity_routine_rep (sig);
00117 }
00118 
00119 /******************************************************************************
00120 * Composition of routines
00121 ******************************************************************************/
00122 
00123 class composed_routine_rep: public routine_rep {
00124   routine fun;
00125   const vector<routine> args;
00126   vector<nat> sig;
00127 public:
00128   composed_routine_rep (const routine& fun2, const vector<routine>& args2):
00129     routine_rep (gen (GEN_COMPOSE, fun2->name, as_generic (flatten (args2)))),
00130     fun (fun2), args (args2)
00131   {
00132     sig= copy (fun->signature ());
00133     if (N(sig) != 0) {
00134       ASSERT (N(sig) == N(args)+1,
00135               "numbers of arguments don't match (composed_routine_rep)");
00136       for (nat i=0; i<N(args); i++) {
00137         const vector<nat> sub_sig= args[i]->signature ();
00138         ASSERT (N(sub_sig) == 2,
00139                 "routine with one argument expected (composed_routine_rep)");
00140         ASSERT (read (sig, i+1) == sub_sig[0] || read (sig, i+1) == 0,
00141                 "type mismatch (composed_routine_rep)");
00142         sig[i+1]= sub_sig[1];
00143       }
00144     }
00145   }
00146   generic apply (const generic& x) const {
00147     ASSERT (N(args) == 1, "arity one expected");
00148     return fun->apply (args[0]->apply (x));
00149   }
00150   generic apply (const generic& x, const generic& y) const {
00151     ASSERT (N(args) == 2, "arity two expected");
00152     return fun->apply (args[0]->apply (x), args[1]->apply (y));
00153   }
00154   generic apply (const vector<generic>& v) const {
00155     nat i, n= N(v);
00156     ASSERT (N(args) == n, "arity " * as_string (n) * " expected");
00157     vector<generic> w= fill<generic> (n);
00158     for (i=0; i<n; i++)
00159       w[i]= args[i]->apply (v[i]);
00160     return fun->apply (w);
00161   }
00162   vector<nat> signature () const { return sig; }
00163 };
00164 
00165 routine
00166 compose (const routine& fun, const vector<routine>& args) {
00167   // WARNING: the signature of the result is not necessarily correct
00168   // when simplifying with "fake identity functions", but that does not
00169   // matter for the application to overloading
00170   if (exact_eq (fun->name, GEN_IDENTITY) && N(args) == 1)
00171     return args [0];
00172   for (nat i=0; i<N(args); i++) {
00173     if (exact_neq (args[i]->name, GEN_IDENTITY))
00174       return new composed_routine_rep (fun, args);
00175   }
00176   return fun;
00177 }
00178 
00179 /******************************************************************************
00180 * Changing the signature of a routine
00181 ******************************************************************************/
00182 
00183 class change_signature_routine_rep: public routine_rep {
00184   routine     r;
00185   vector<nat> sig;
00186 public:
00187   change_signature_routine_rep (const routine& r2, const vector<nat>& sig2):
00188     routine_rep (r2->name), r (r2), sig (sig2) {}
00189   generic apply () const {
00190     return r->apply (); }
00191   generic apply (const generic& x1) const {
00192     return r->apply (x1); }
00193   generic apply (const generic& x1, const generic& x2) const {
00194     return r->apply (x1, x2); }
00195   generic apply (const vector<generic>& v) const {
00196     return r->apply (v); }
00197   vector<nat> signature () const { return sig; }
00198 };
00199 
00200 routine
00201 change_signature (const routine& r, const vector<nat>& sig) {
00202   return new change_signature_routine_rep (r, sig);
00203 }
00204 
00205 /******************************************************************************
00206 * Default routine
00207 ******************************************************************************/
00208 
00209 class default_routine_rep: public routine_rep {
00210 public:
00211   default_routine_rep (const generic& name): routine_rep (name) {}
00212   generic apply (const vector<generic>& v) const {
00213     return current_ev->apply (GEN_APPLY, cons (name, v)); }
00214   vector<nat> signature () const { return vec<nat> (); }
00215 };
00216 
00217 routine
00218 default_routine (const generic& name) {
00219   if (is<routine> (name))
00220     return as<routine> (name);
00221   if (is<alias<routine> > (name))
00222     return get_alias (as<alias<routine> > (name));
00223   return new default_routine_rep (name);
00224 }
00225 
00226 /******************************************************************************
00227 * Integrate routine (for dynamical systems)
00228 ******************************************************************************/
00229 
00230 class integrate_routine_rep: public routine_rep {
00231   routine fun;
00232 public:
00233   integrate_routine_rep (const routine& fun2):
00234     routine_rep (gen (GEN_INTEGRATE, fun2->name)), fun (fun2) {}
00235   generic apply () const {
00236     return integrate (fun->apply ()); }
00237   generic apply (const generic& x1) const {
00238     return integrate (fun->apply (x1)); }
00239   generic apply (const generic& x1, const generic& x2) const {
00240     return integrate (fun->apply (x1, x2)); }
00241   generic apply (const vector<generic>& v) const {
00242     return integrate (fun->apply (v)); }
00243   vector<nat> signature () const {
00244     return fun->signature (); }
00245 };
00246 
00247 routine
00248 integrate (const routine& r) {
00249   return new integrate_routine_rep (r);
00250 }
00251 
00252 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines