00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef __GENERIC_HPP
00014 #define __GENERIC_HPP
00015 #include <typeinfo>
00016 #include <basix/defaults.hpp>
00017 
00019 
00020 namespace mmx {
00021 #define TMPL template<typename C>
00022 #define Acc accelerator<C>
00023 class generic;
00024 class syntactic;
00025 class port;
00026 class string;
00027 class routine;
00028 class routine_rep;
00029 struct exact_eq_table;
00030 template<typename T,typename F> struct as_helper;
00031 template<typename T,typename F> inline T as (const F& x);
00032 template<typename C> struct vector_as_helper;
00033 TMPL struct inspector;
00034 TMPL struct binary_helper;
00035 generic gen_vec ();
00036 generic gen_vec (const generic& g1);
00037 generic gen_vec (const generic& g1, const generic& g2);
00038 generic gen_vec (const generic& g1, const generic& g2, const generic& g3);
00039 generic vector_access (const generic& g, nat i);
00040 TMPL generic binary_disassemble (const C& x);
00041 TMPL void binary_write (const port& out, const C& x);
00042 TMPL inline port operator << (const port& out, const C& x);
00043 void write (const port& p, const char* s, nat n);
00044 void write (const port& p, const string& s);
00045 extern port mmout;
00046 extern port mmerr;
00047 extern bool booting_done;
00048 extern generic GEN_CONVERT;
00049 
00050 
00051 
00052 
00053 
00054 #define ACC_NEGATE          0
00055 #define ACC_SQUARE          1
00056 #define ACC_INVERT          2
00057 #define ACC_ADD             3
00058 #define ACC_SUB             4
00059 #define ACC_MUL             5
00060 #define ACC_DIV             6
00061 #define ACC_SQRT            8
00062 #define ACC_EXP             9
00063 #define ACC_LOG            10
00064 #define ACC_COS            11
00065 #define ACC_SIN            12
00066 #define ACC_TAN            13
00067 #define ACC_ACOS           14
00068 #define ACC_ASIN           15
00069 #define ACC_ATAN           16
00070 #define ACC_COSH           17
00071 #define ACC_SINH           18
00072 #define ACC_TANH           19
00073 #define ACC_ACOSH          20
00074 #define ACC_ASINH          21
00075 #define ACC_ATANH          22
00076 #define ACC_HYPOT          23
00077 #define ACC_ATAN2          24
00078 #define ACC_POW            25
00079 #define ACC_LESS           26
00080 #define ACC_LESSEQ         27
00081 #define ACC_GTR            28
00082 #define ACC_GTREQ          29
00083 #define ACC_DERIVE         30
00084 #define ACC_DERIVE_WRT     31
00085 #define ACC_INTEGRATE      32
00086 #define ACC_INTEGRATE_WRT  33
00087 
00088 
00089 
00090 
00091 
00092 class generic_rep: public rep_struct {
00093 public:
00094   virtual nat get_type () const = 0;
00095   virtual bool same_type (const generic& g) const = 0;
00096   virtual nat get_symbolic_type () const = 0;
00097   virtual nat get_species_type () const = 0;
00098   virtual nat get_length () const = 0;
00099   virtual generic get_child (nat i) const = 0;
00100   virtual nat get_hard_hash_value () const = 0;
00101   virtual nat get_exact_hash_value () const = 0;
00102   virtual nat get_hash_value () const = 0;
00103   virtual bool is_hard_eq (const generic& rep) const = 0;
00104   virtual bool is_exact_eq (const generic& rep) const = 0;
00105   virtual bool is_equal (const generic& rep) const = 0;
00106   virtual generic duplicate_me () const = 0;
00107   virtual syntactic expression () const = 0;
00108   virtual generic binary_type () const = 0;
00109   virtual generic binary_disassemble () const = 0;
00110   virtual void binary_write (const port& p) const = 0;
00111   virtual generic make_abstract_vector () const = 0;
00112   virtual generic make_concrete_vector (const generic& v) const = 0;
00113 
00114   virtual nat      acc_id () const;
00115   virtual routine* acc_construct (nat id) const;
00116   virtual routine* acc_apply (nat code) const;
00117 
00118 public:
00119   inline generic_rep () {}
00120   inline virtual ~generic_rep () {}
00121   inline generic me () const;
00122 
00123   friend class generic;
00124 };
00125   
00126 class generic {
00127 INDIRECT_PROTO (generic, generic_rep)
00128 public:
00129   generic ();
00130   generic (const char* s);
00131   generic (const string& s);
00132   generic (int i);
00133   generic (nat i);
00134   generic operator () () const;
00135   generic operator () (const generic& g1) const;
00136   generic operator () (const generic& g1, const generic& g2) const;
00137   generic operator () (const generic& g1, const generic& g2,
00138                        const generic& g3) const;
00139 
00140   inline generic operator [] (nat i) const { return rep->get_child (i); }
00141   inline friend generic_rep* inspect (const generic& g) { return g.rep; };
00142   friend syntactic flatten (const generic& g);
00143 
00144   friend class generic_rep;
00145 };
00146 INDIRECT_IMPL (generic, generic_rep)
00147 
00148 inline generic generic_rep::me () const {
00149   return generic (this, true); }
00150 inline nat type (const generic& g) {
00151   return g->get_type (); }
00152 inline nat symbolic_type (const generic& g) {
00153   return g->get_symbolic_type (); }
00154 inline nat species_type (const generic& g) {
00155   return g->get_species_type (); }
00156 inline nat N (const generic& g) {
00157   return g->get_length (); }
00158 inline nat gen_hash (const generic& g) {
00159   return g->get_hard_hash_value (); }
00160 inline nat exact_hash (const generic& g) {
00161   return g->get_exact_hash_value (); }
00162 inline nat hash (const generic& g) {
00163   return g->get_hash_value (); }
00164 inline bool gen_eq (const generic& g1, const generic& g2) {
00165   return g1->is_hard_eq (g2); }
00166 inline bool gen_neq (const generic& g1, const generic& g2) {
00167   return !g1->is_hard_eq (g2); }
00168 
00169 
00170 
00171 
00172 
00173 nat new_type_id ();
00174 nat new_type_id (const char*);
00175 
00176 template<typename T>
00177 inline nat global_type_id () { return new_type_id (typeid (T ()).name()); }  
00178 inline nat binary_id (nat id1, nat id2) { return id1 ^ (0x10115 * id2); }
00179 template<typename T> struct type_information { static nat id; };
00180 template<typename T> nat type_information<T>::id= global_type_id<T> ();
00181 STMPL struct type_information<generic> { static nat id; };
00182 TMPL inline bool is (const generic& x) {
00183   return type (x) == type_information<C>::id; }
00184 inline bool same_type (const generic& x1, const generic& x2) {
00185   return x1->same_type (x2); }
00186 vector<generic> all_type_names ();
00187 void define_type_sub (const generic& name, nat id);
00188 nat type_id (const generic& name);
00189 generic type_name (nat id);
00190 generic type_name (const generic& g);
00191 template<typename C> inline nat type_id () {
00192   return type_information<C>::id; }
00193 template<typename C> inline generic type_name () {
00194   return type_name (type_id<C> ()); }
00195 
00196 #define SYMBOLIC_UNSPECIFIED  0
00197 #define SYMBOLIC_INTEGER      1
00198 #define SYMBOLIC_RATIONAL     2
00199 #define SYMBOLIC_FLOATING     3
00200 #define SYMBOLIC_BALL         4
00201 #define SYMBOLIC_REAL         5
00202 #define SYMBOLIC_LITERAL      6
00203 #define SYMBOLIC_COMPOUND     7
00204 #define SYMBOLIC_SUM          8
00205 #define SYMBOLIC_PRODUCT      9
00206 #define SYMBOLIC_DERIVATIVE  10
00207 #define SYMBOLIC_FUNCTION    11
00208 
00209 template<typename T> struct symbolic_type_information {
00210   static const nat id= SYMBOLIC_UNSPECIFIED; };
00211 
00212 #define SPECIES_DEFAULT   0
00213 #define SPECIES_VECTOR    1
00214 #define SPECIES_LIST      2
00215 #define SPECIES_TABLE     3
00216 
00217 template<typename T> struct species_type_information {
00218   static const nat id= SPECIES_DEFAULT; };
00219 inline bool is_vector (const generic& x) {
00220   return species_type (x) == SPECIES_VECTOR; }
00221 inline bool is_list (const generic& x) {
00222   return species_type (x) == SPECIES_LIST; }
00223 inline bool is_table (const generic& x) {
00224   return species_type (x) == SPECIES_TABLE; }
00225 
00226 inline bool generic_is_boolean (const generic& g) {
00227   return is<bool> (g); }
00228 inline bool generic_is_int (const generic& g) {
00229   return is<int> (g); }
00230 inline bool generic_is_double (const generic& g) {
00231   return is<double> (g); }
00232 inline bool generic_is_string (const generic& g) {
00233   return is<string> (g); }
00234 
00235 
00236 
00237 
00238 
00239 generic lit (const char* s);
00240 generic lit (const string& s);
00241 
00242 generic gen (const generic& x1, const vector<generic>& v);
00243 generic gen ();
00244 generic gen (const generic& x1);
00245 generic gen (const generic& x1, const string& x2);
00246 generic gen (const generic& x1, const generic& x2);
00247 generic gen (const generic& x1, const generic& x2, const generic& x3);
00248 generic gen (const generic& x1, const generic& x2,
00249              const generic& x3, const generic& x4);
00250 generic gen (const generic& x1, const generic& x2,
00251              const generic& x3, const generic& x4, const generic& x5);
00252 generic gen (const generic& x1, const generic& x2,
00253              const generic& x3, const generic& x4,
00254              const generic& x5, const generic& x6);
00255 
00256 generic void_value ();
00257 generic comma ();
00258 generic comma (const generic& x1, const generic& x2);
00259 generic xgen (const generic& f, const generic& args);
00260 generic xaccess (const generic& f, const generic& args);
00261 generic xtuple (const generic& args);
00262 generic xsqtuple (const generic& args);
00263 generic xrow (const generic& args);
00264 generic access (const generic& f, const generic& x);
00265 generic access (const generic& f, const generic& x, const generic& y);
00266 generic access (const generic& f, const vector<generic>& x);
00267 
00268 generic as_object (const generic& v, nat tp_id);
00269 generic as_object (const generic& v, const generic& tp);
00270 generic as_generic (const generic& obj, nat tp_id);
00271 generic as_generic (const generic& obj, const generic& tp);
00272 
00273 generic range (const generic& g, nat start, nat end);
00274 generic append (const generic& g1, const generic& g2);
00275 generic cons (const generic& g1, const generic& g2);
00276 generic cons (const generic& g1, const generic& g2, const generic& g3);
00277 generic car (const generic& g);
00278 generic cdr (const generic& g);
00279 
00280 bool is_func (const generic& g, const char* f);
00281 bool is_func (const generic& g, const char* f, nat n);
00282 bool is_func (const generic& g, const generic& f);
00283 bool is_func (const generic& g, const generic& f, nat n);
00284 nat size (const generic& g);
00285 int big_small_compare (const generic& g1, const generic& g2);
00286 int small_big_compare (const generic& g1, const generic& g2);
00287 
00288 
00289 
00290 
00291 
00292 generic convert (const generic& from, const generic& to);
00293 
00294 void set_default (generic& x);
00295 void set_smallest (generic& x);
00296 void set_largest (generic& x);
00297 void set_accuracy (generic& x);
00298 void set_pi (generic& x);
00299 void set_log2 (generic& x);
00300 void set_euler (generic& x);
00301 void set_catalan (generic& x);
00302 void set_imaginary (generic& x);
00303 void set_nan (generic& x);
00304 void set_fuzz (generic& x);
00305 void set_infinity (generic& x);
00306 void set_maximal (generic& x);
00307 void set_minimal (generic& x);
00308 
00309 generic operator - (const generic& x1);
00310 generic square (const generic &x1);
00311 generic invert (const generic &x1);
00312 generic operator + (const generic& x1, const generic& x2);
00313 generic operator - (const generic& x1, const generic& x2);
00314 generic operator * (const generic& x1, const generic& x2);
00315 generic operator / (const generic& x1, const generic& x2);
00316 generic operator + (const generic& x1, const int& x2);
00317 generic operator - (const generic& x1, const int& x2);
00318 generic operator * (const generic& x1, const int& x2);
00319 generic operator / (const generic& x1, const int& x2);
00320 generic operator + (const int& x1, const generic& x2);
00321 generic operator - (const int& x1, const generic& x2);
00322 generic operator * (const int& x1, const generic& x2);
00323 generic operator / (const int& x1, const generic& x2);
00324 
00325 generic sqrt (const generic& x1);
00326 generic exp (const generic& x1);
00327 generic log (const generic& x1);
00328 generic cos (const generic& x1);
00329 generic sin (const generic& x1);
00330 generic tan (const generic& x1);
00331 generic acos (const generic& x1);
00332 generic asin (const generic& x1);
00333 generic atan (const generic& x1);
00334 generic cosh (const generic& x1);
00335 generic sinh (const generic& x1);
00336 generic tanh (const generic& x1);
00337 generic acosh (const generic& x1);
00338 generic asinh (const generic& x1);
00339 generic atanh (const generic& x1);
00340 generic hypot (const generic& x1, const generic& x2);
00341 generic atan2 (const generic& x1, const generic& x2);
00342 generic pow (const generic& x1, const generic& x2);
00343 generic pow (const generic& x1, const int& x2);
00344 generic pow (const int& x1, const generic& x2);
00345 
00346 bool operator == (const generic& x1, const generic& x2);
00347 bool operator != (const generic& x1, const generic& x2);
00348 bool operator == (const generic& x1, const int& x2);
00349 bool operator != (const generic& x1, const int& x2);
00350 bool operator == (const int& x1, const generic& x2);
00351 bool operator != (const int& x1, const generic& x2);
00352 bool exact_eq  (const generic& x1, const generic& x2);
00353 bool exact_neq (const generic& x1, const generic& x2);
00354 bool exact_eq  (const generic& x1, const int& x2);
00355 bool exact_neq (const generic& x1, const int& x2);
00356 bool exact_eq  (const int& x1, const generic& x2);
00357 bool exact_neq (const int& x1, const generic& x2);
00358 inline bool is_exact_zero (const generic& g1) { return exact_eq (g1, 0); }
00359 
00360 bool operator < (const generic& x1, const generic& x2);
00361 bool operator <= (const generic& x1, const generic& x2);
00362 bool operator > (const generic& x1, const generic& x2);
00363 bool operator >= (const generic& x1, const generic& x2);
00364 bool operator < (const generic& x1, const int& x2);
00365 bool operator <= (const generic& x1, const int& x2);
00366 bool operator > (const generic& x1, const int& x2);
00367 bool operator >= (const generic& x1, const int& x2);
00368 bool operator < (const int& x1, const generic& x2);
00369 bool operator <= (const int& x1, const generic& x2);
00370 bool operator > (const int& x1, const generic& x2);
00371 bool operator >= (const int& x1, const generic& x2);
00372 
00373 generic derive (const generic& x1);
00374 generic integrate (const generic& x1);
00375 generic derive (const generic& x1, const generic& x2);
00376 generic integrate (const generic& x1, const generic& x2);
00377 
00378 
00379 
00380 
00381 
00382 generic construct (const int& i);
00383 generic construct (const nat& i);
00384 generic construct (const double& x);
00385 generic construct (const float& x);
00386 generic construct (const generic& x);
00387 generic eval (const generic& x);
00388 
00389 generic apply (const generic& f, const generic& x);
00390 generic apply (const generic& f, const generic& x, const generic& y);
00391 generic apply (const generic& f, const generic& x,
00392                const generic& y, const generic& z);
00393 generic apply (const generic& f, const vector<generic>& x);
00394 
00395 generic quo (const generic& x1, const generic& x2);
00396 generic rem (const generic& x1, const generic& x2);
00397 generic numerator (const generic& x);
00398 generic denominator (const generic& x);
00399 generic gcd (const generic& x1, const generic& x2);
00400 generic lcm (const generic& x1, const generic& x2);
00401 TMPL struct xgcd_matrix;
00402 xgcd_matrix<generic> xgcd (const generic& x1, const generic& x2);
00403 
00404 generic pow (const generic& x1, const nat& x2);
00405 generic pow (const nat& x1, const generic& x2);
00406 generic trig (const generic& x1);
00407 
00408 generic min (const generic& x1, const generic& x2);
00409 generic max (const generic& x1, const generic& x2);
00410 generic abs (const generic& x1);
00411 generic arg (const generic& x1);
00412 generic Re (const generic& x1);
00413 generic Im (const generic& x1);
00414 generic conj (const generic& x1);
00415 generic gaussian (const generic& x1, const generic& x2);
00416 generic polar (const generic& x1, const generic& x2);
00417 
00418 generic floor (const generic& x);
00419 generic trunc (const generic& x);
00420 generic ceil (const generic& x);
00421 generic round (const generic& x);
00422 
00423 generic prime (const generic& x1);
00424 generic substitute (const generic& x1, const generic& x2);
00425 generic compose (const generic& x1, const generic& x2);
00426 generic dilate (const generic& x1, const generic& x2);
00427 generic solve (const generic& x1, const generic& x2);
00428 
00429 generic sqrt_init (const generic& x, const generic& c);
00430 generic log_init (const generic& x, const generic& c);
00431 generic acos_init (const generic& x, const generic& c);
00432 generic asin_init (const generic& x, const generic& c);
00433 generic atan_init (const generic& x, const generic& c);
00434 generic integrate_init (const generic& x, const generic& c);
00435 generic solve_lde_init (const generic& x, const generic& c);
00436 
00437 generic change_precision (const generic& x, xnat p);
00438 xnat    precision (const generic& x);
00439 generic next_above (const generic& x);
00440 generic next_below (const generic& x);
00441 generic rounding_error (const generic& x);
00442 generic additive_error (const generic& x);
00443 generic multiplicative_error (const generic& x);
00444 generic elementary_error (const generic& x);
00445 xint    exponent (const generic& x);
00446 double  magnitude (const generic& x);
00447 generic incexp2 (const generic& x1, const xint& x2);
00448 generic decexp2 (const generic& x1, const xint& x2);
00449 generic operator << (const generic& x1, const generic& x2);
00450 generic operator >> (const generic& x1, const generic& x2);
00451 
00452 generic lshiftz (const generic& x1, const generic& x2);
00453 generic rshiftz (const generic& x1, const generic& x2);
00454 generic operator | (const generic& x1, const generic& x2);
00455 generic operator & (const generic& x1, const generic& x2);
00456 generic lres (const generic& x1, const generic& x2);
00457 generic rres (const generic& x1, const generic& x2);
00458 generic uniform (const generic& x1, const generic& x2);
00459 generic specialize (const generic& x1, const generic& x2);
00460 
00461 generic center (const generic& x1);
00462 generic radius (const generic& x1);
00463 generic sharpen (const generic& x1);
00464 generic blur (const generic& x1, const generic& x2);
00465 
00466 
00467 
00468 
00469 
00470 TMPL
00471 struct accelerator {
00472   static nat id;
00473   static routine *construct;
00474   static nat nr_construct;
00475   static routine *apply;
00476   static nat nr_apply;
00477   static void set_construct (nat id, const routine& r);
00478   static void set_apply (nat code, const routine& r);
00479 };
00480 
00481 TMPL nat Acc::id= (nat) -1;
00482 TMPL routine *Acc::construct= NULL;
00483 TMPL nat Acc::nr_construct= (nat) 0;
00484 TMPL routine *Acc::apply= NULL;
00485 TMPL nat Acc::nr_apply= (nat) 0;
00486 
00487 typedef routine* vec_routine;
00488 void fill_out (vec_routine& v, nat& n, nat i, const routine& r);
00489 
00490 
00491 
00492 
00493 
00494 TMPL
00495 class generic_concrete_rep: public generic_rep {
00496 public:
00497   C rep;
00498 
00499 protected:
00500   nat get_type () const { return type_information<C>::id; }
00501   bool same_type (const generic& g) const { return is<C> (g); }
00502   nat get_symbolic_type () const { return symbolic_type_information<C>::id; }
00503   nat get_species_type () const { return species_type_information<C>::id; }
00504   nat get_length () const { return inspector<C>::length (rep); }
00505   generic get_child (nat i) const { return inspector<C>::access (rep, i); }
00506   nat get_hard_hash_value () const { return hard_hash (rep); }
00507   nat get_exact_hash_value () const { return exact_hash (rep); }
00508   nat get_hash_value () const { return hash (rep); }
00509   bool is_hard_eq (const generic& g) const {
00510     if (type (g) != type_information<C>::id) return false;
00511     return hard_eq (rep, ((generic_concrete_rep<C>*) inspect (g)) -> rep); }
00512   bool is_exact_eq (const generic& g) const {
00513     if (type (g) != type_information<C>::id) return false;
00514     return exact_eq (rep, ((generic_concrete_rep<C>*) inspect (g)) -> rep); }
00515   bool is_equal (const generic& g) const {
00516     if (type (g) != type_information<C>::id) return false;
00517     return rep == ((generic_concrete_rep<C>*) inspect (g)) -> rep; }
00518   generic duplicate_me () const { return as<generic> (duplicate (rep)); }
00519   syntactic expression () const; 
00520   generic binary_type () const {
00521     return binary_helper<C>::full_type_name (); }
00522   generic binary_disassemble () const {
00523     return mmx::binary_disassemble (rep); }
00524   void binary_write (const port& out) const {
00525     mmx::write (out, binary_helper<C>::short_type_name ());
00526     mmx::write (out, ":", 1);
00527     mmx::binary_write (out, rep); }
00528   generic make_abstract_vector () const {
00529     return vector_as_helper<C>::abstract (rep); }
00530   generic make_concrete_vector (const generic& v) const {
00531     return as<generic> (vector_as_helper<C>::concrete (v)); }
00532 
00533   inline nat acc_id () const {
00534     return Acc::id; }
00535   inline routine* acc_construct (nat id) const {
00536     if (id < Acc::nr_construct)
00537       return (routine*) (void*)
00538         (((routine_rep**) (void*) Acc::construct) + id);
00539     else return NULL; }
00540   inline routine* acc_apply (nat code) const {
00541     if (code < Acc::nr_apply)
00542       return (routine*) (void*)
00543         (((routine_rep**) (void*) Acc::apply) + code);
00544     else return NULL; }
00545 
00546 public:
00547   generic_concrete_rep (const C& rep2): rep (rep2) {}
00548 };
00549 
00550 TMPL
00551 struct as_helper<generic,C> {
00552   static inline generic cv (const C& x) {
00553     return new generic_concrete_rep<C> (x); }
00554 };
00555 
00556 TMPL
00557 struct as_helper<C,generic> {
00558   static inline C cv (const generic& x) {
00559     return ((generic_concrete_rep<C>*) inspect(x)) -> rep; }
00560 };
00561 
00562 STMPL
00563 struct as_helper<generic,generic> {
00564   static inline generic cv (const generic& x) { return x; }
00565 };
00566 
00567 TMPL generic
00568 as_generic (const C& c) {
00569   return construct (new generic_concrete_rep<C> (c));
00570 }
00571 
00572 TMPL inline void
00573 set_as (generic& r, const C& x) {
00574   r= new generic_concrete_rep<C> (x);
00575 }
00576 
00577 TMPL inline void
00578 set_as (C& r, const generic& x) {
00579   r= ((generic_concrete_rep<C>*) inspect(x)) -> rep;
00580 }
00581 
00582 inline void
00583 set_as (generic& r, const generic& x) {
00584  r= x;
00585 }
00586 
00587 #undef TMPL
00588 #undef Acc
00589 } 
00590 #endif // __GENERIC_HPP