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