basix_doc 0.1
|
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