00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #include <basix/string.hpp>
00014 #include <basix/identifiers.hpp>
00015 #include <basix/literal.hpp>
00016 #include <basix/compound.hpp>
00017 #include <basix/vector_sort.hpp>
00018 namespace mmx {
00019 
00020 
00021 
00022 
00023 
00024 syntactic::syntactic (const int& i): rep (as_string (i)) {}
00025 bool is_atom (const syntactic& g) { return is<literal> (*g); }
00026 string as_string (const syntactic& g) { return literal_to_string (*g); }
00027 
00028 syntactic
00029 apply (const vector<syntactic>& v) {
00030   VERIFY (N(v) != 0, "non-empty vector expected");
00031   if (is<literal> (*v[0])) {
00032     string s= as_string (as<literal> (*v[0]));
00033     if (N(s) == 1) {
00034       if (s[0] == '-' && N(v) == 2) return -v[1];
00035       if (s[0] == '+' && N(v) == 3) return v[1] + v[2];
00036       if (s[0] == '-' && N(v) == 3) return v[1] - v[2];
00037       if (s[0] == '*' && N(v) == 3) return v[1] * v[2];
00038       if (s[0] == '/' && N(v) == 3) return v[1] / v[2];
00039       if (s[0] == '^' && N(v) == 3) return pow (v[1], v[2]);
00040     }
00041   }
00042   return as_syntactic (vector_to_compound (*((vector<generic>*) (void*) &v)));
00043 }
00044 
00045 syntactic apply (const syntactic& f) {
00046   return apply (vec (f)); }
00047 syntactic apply (const syntactic& f, const syntactic& a1) {
00048   return apply (vec (f, a1)); }
00049 syntactic apply (const syntactic& f, const syntactic& a1,
00050                  const syntactic& a2) {
00051   return apply (vec (f, a1, a2)); }
00052 syntactic apply (const syntactic& f, const syntactic& a1,
00053                  const syntactic& a2, const syntactic& a3) {
00054   return apply (vec (f, a1, a2, a3)); }
00055 syntactic apply (const syntactic& f,
00056                  const syntactic& a1, const syntactic& a2,
00057                  const syntactic& a3, const syntactic& a4) {
00058   return apply (vec (f, a1, a2, a3, a4)); }
00059 syntactic apply (const syntactic& f,
00060                  const syntactic& a1, const syntactic& a2,
00061                  const syntactic& a3, const syntactic& a4,
00062                  const syntactic& a5) {
00063   return apply (vec (f, a1, a2, a3, a4, a5)); }
00064 syntactic apply (const syntactic& f,
00065                  const syntactic& a1, const syntactic& a2,
00066                  const syntactic& a3, const syntactic& a4,
00067                  const syntactic& a5, const syntactic& a6) {
00068   return apply (vec (f, a1, a2, a3, a4, a5, a6)); }
00069 syntactic apply (const syntactic& f, const vector<syntactic>& a) {
00070   return apply (cons (f, a)); }
00071 
00072 bool is_func (const syntactic& g, const char* f) {
00073   return is_func (*g, f); }
00074 bool is_func (const syntactic& g, const char* f, nat n) {
00075   return is_func (*g, f, n); }
00076 bool is_func (const syntactic& g, const syntactic& f) {
00077   return is_func (*g, *f); }
00078 bool is_func (const syntactic& g, const syntactic& f, nat n) {
00079   return is_func (*g, *f, n); }
00080 bool is_func (const syntactic& g, const generic& f) {
00081   return is_func (*g, f); }
00082 bool is_func (const syntactic& g, const generic& f, nat n) {
00083   return is_func (*g, f, n); }
00084 
00085 vector<syntactic>
00086 components (const syntactic& g) {
00087   vector<syntactic> v= fill<syntactic> (N(g));
00088   for (nat i=0; i<N(g); i++) v[i]= g[i];
00089   return v;
00090 }
00091 
00092 vector<syntactic>
00093 arguments (const syntactic& g) {
00094   return cdr (components (g));
00095 }
00096 
00097 
00098 
00099 
00100 
00101 void set_default (syntactic& x) { x= syntactic ("false"); }
00102 void set_smallest (syntactic& x) { x= as_syntactic (GEN_SMALLEST); }
00103 void set_largest (syntactic& x) { x= as_syntactic (GEN_LARGEST); }
00104 void set_accuracy (syntactic& x) { x= as_syntactic (GEN_ACCURACY); }
00105 void set_pi (syntactic& x) { x= as_syntactic (GEN_PI); }
00106 void set_log2 (syntactic& x) { x= log (as_syntactic (2)); }
00107 void set_euler (syntactic& x) { x= as_syntactic (GEN_EULER); }
00108 void set_catalan (syntactic& x) { x= as_syntactic (GEN_CATALAN); }
00109 void set_imaginary (syntactic& x) { x= as_syntactic (GEN_I); }
00110 void set_nan (syntactic& x) { x= as_syntactic (GEN_NAN); }
00111 void set_fuzz (syntactic& x) { x= as_syntactic (GEN_FUZZ); }
00112 void set_infinity (syntactic& x) { x= as_syntactic (GEN_INFINITY); }
00113 void set_maximal (syntactic& x) { x= as_syntactic (GEN_INFINITY); }
00114 void set_minimal (syntactic& x) { x= -as_syntactic (GEN_INFINITY); }
00115 
00116 
00117 
00118 
00119 
00120 static void
00121 signed_decompose (const syntactic& g, syntactic& abs_g, int& sgn_g) {
00122   if (is_atom (g)) {
00123     const string s= as_string (g);
00124     if (N(s) > 1 && s[0] == '-' &&
00125         (s[1] == '.' || (s[1] >= '0' && s[1] <= '9'))) {
00126       abs_g= syntactic (s (1, N(s)));
00127       sgn_g= -1;
00128     }
00129     else {
00130       abs_g= g;
00131       sgn_g= 1;
00132     }
00133   }
00134   else if (is_func (g, GEN_MINUS, 1)) {
00135     signed_decompose (g[1], abs_g, sgn_g);
00136     sgn_g= -sgn_g;
00137   }
00138   else if (is_func (g, GEN_TIMES, 2) || is_func (g, GEN_OVER, 2)) {
00139     syntactic a1, a2;
00140     int     s1, s2;
00141     signed_decompose (g[1], a1, s1);
00142     signed_decompose (g[2], a2, s2);
00143     if (is_func (g, GEN_TIMES, 2)) abs_g= a1 * a2;
00144     else abs_g= a1 / a2;
00145     sgn_g= s1 * s2;
00146   }
00147   else {
00148     abs_g= g;
00149     sgn_g= 1;
00150   }
00151 }
00152 
00153 syntactic
00154 operator - (const syntactic& g) {
00155   if (exact_eq (g, 0)) return g;
00156   if (is_func (g, GEN_MINUS, 1))
00157     return g[1];
00158   if (is_func (g, GEN_PLUS, 2))
00159     return (-g[1]) - g[2];
00160   if (is_func (g, GEN_MINUS, 2))
00161     return (-g[1]) + g[2];
00162   syntactic abs_g; int sgn_g;
00163   signed_decompose (g, abs_g, sgn_g);
00164   if (sgn_g > 0) return syn (GEN_MINUS, abs_g);
00165   else return abs_g;
00166 }
00167 
00168 syntactic
00169 operator + (const syntactic& g1, const syntactic& g2) {
00170   if (exact_eq (g1, 0)) return g2;
00171   if (exact_eq (g2, 0)) return g1;
00172   if (is_func (g2, GEN_MINUS, 1))
00173     return g1 - g2[1];
00174   if (is_func (g2, GEN_PLUS, 2))
00175     return (g1 + g2[1]) + g2[2];
00176   if (is_func (g2, GEN_MINUS, 2))
00177     return (g1 + g2[1]) - g2[2];
00178   syntactic abs_g2; int sgn_g2;
00179   signed_decompose (g2, abs_g2, sgn_g2);
00180   if (sgn_g2 < 0) return syn (GEN_MINUS, g1, abs_g2);
00181   else return syn (GEN_PLUS, g1, abs_g2);
00182 }
00183 
00184 syntactic
00185 operator - (const syntactic& g1, const syntactic& g2) {
00186   if (exact_eq (g2, 0)) return g1;
00187   if (is_func (g2, GEN_MINUS, 1))
00188     return g1 + g2[1];
00189   if (is_func (g2, GEN_PLUS, 2))
00190     return (g1 - g2[1]) - g2[2];
00191   if (is_func (g2, GEN_MINUS, 2))
00192     return (g1 - g2[1]) + g2[2];
00193   syntactic abs_g2; int sgn_g2;
00194   signed_decompose (g2, abs_g2, sgn_g2);
00195   if (exact_eq (g1, 0)) {
00196     if (sgn_g2 > 0) return syn (GEN_MINUS, abs_g2);
00197     else return abs_g2;    
00198   }
00199   else {
00200     if (sgn_g2 > 0) return syn (GEN_MINUS, g1, abs_g2);
00201     else return syn (GEN_PLUS, g1, abs_g2);
00202   }
00203 }
00204 
00205 static syntactic
00206 migrate_sub (const syntactic& g, const syntactic& h) {
00207   if (is_func (g, GEN_MINUS, 2))
00208     return syn (GEN_MINUS, migrate_sub (g[1], h), g[2]);
00209   syntactic abs_g; int sgn_g;
00210   signed_decompose (g, abs_g, sgn_g);
00211   return syn (GEN_MINUS, h, abs_g);
00212 }
00213 
00214 static syntactic
00215 migrate_sub (const syntactic& g, nat found) {
00216   if (found == 0) return migrate_sub (g[1], g[2]);
00217   return syn (g[0], migrate_sub (g[1], found-1), g[2]);
00218 }
00219 
00220 syntactic
00221 migrate_negate (const syntactic& g, nat maximal) {
00222   int i= 0, found= -1;
00223   syntactic h= g;
00224   while (is_func (h, GEN_PLUS, 2) || is_func (h, GEN_MINUS, 2)) {
00225     if (is_func (h, GEN_PLUS, 2)) found= i;
00226     if (maximal == 0) return g;
00227     h= h[1];
00228     maximal--;
00229     i++;
00230   }
00231   if (found == -1) return g;
00232   syntactic abs_h; int sgn_h;
00233   signed_decompose (h, abs_h, sgn_h);
00234   if (sgn_h >= 0) return g;
00235   return migrate_sub (g, found);
00236 }
00237 
00238 
00239 
00240 
00241 
00242 static bool frac_flag= false;
00243 
00244 bool
00245 set_frac_flag (bool new_val) {
00246   bool ret= frac_flag;
00247   frac_flag= new_val;
00248   return ret;
00249 }
00250 
00251 syntactic
00252 operator * (const syntactic& g1, const syntactic& g2) {
00253   if (frac_flag && is_func (g1, GEN_OVER, 2)) {
00254     if (is_func (g2, GEN_OVER, 2))
00255       return syn (GEN_OVER, g1[1] * g2[1], g1[2] * g2[2]);
00256     else return syn (GEN_OVER, g1[1] * g2, g1[2]);
00257   }
00258   if (frac_flag && is_func (g2, GEN_OVER, 2))
00259     return syn (GEN_OVER, g1 * g2[1], g2[2]);
00260   if (exact_eq (g1, 0)) return 0;
00261   if (exact_eq (g2, 0)) return 0;
00262   if (exact_eq (g1, 1)) return g2;
00263   if (exact_eq (g2, 1)) return g1;
00264   if (exact_eq (g1, -1)) return -g2;
00265   if (exact_eq (g2, -1)) return -g1;
00266   return syn (GEN_TIMES, g1, g2);
00267 }
00268 
00269 syntactic
00270 operator / (const syntactic& g1, const syntactic& g2) {
00271   if (frac_flag && is_func (g2, GEN_OVER, 2))
00272     return g1 * syn (GEN_OVER, g2[2], g2[1]);
00273   if (exact_eq (g2, 1)) return g1;
00274   if (exact_eq (g2, -1)) return -g1;
00275   if (frac_flag) return g1 * syn (GEN_OVER, 1, g2);
00276   else return syn (GEN_OVER, g1, g2);
00277 }
00278 
00279 syntactic
00280 square (const syntactic& g) {
00281   return syn (GEN_POWER, g, syntactic (2));
00282 }
00283 
00284 syntactic
00285 invert (const syntactic& g) {
00286   return syntactic (1) / g;
00287 }
00288 
00289 syntactic
00290 pow (const syntactic& g1, const syntactic& g2) {
00291   if (exact_eq (g1, 0)) return 0;
00292   if (exact_eq (g1, 1)) return 1;
00293   if (exact_eq (g2, 0)) return 1;
00294   if (exact_eq (g2, 1)) return g1;
00295   if (exact_eq (g2, syn (GEN_OVER, syntactic (1), syntactic (2))))
00296     return syn (GEN_SQRT, g1);
00297   if (frac_flag) {
00298     syntactic abs; int sgn;
00299     signed_decompose (g2, abs, sgn);
00300     if (sgn < 0) return syn (GEN_OVER, 1, pow (g1, abs));
00301   }
00302   return syn (GEN_POWER, g1, g2);
00303 }
00304 
00305 syntactic
00306 pow (const syntactic& g1, const int& g2) {
00307   return pow (g1, flatten (g2));
00308 }
00309 
00310 syntactic
00311 pow (const int& g1, const syntactic& g2) {
00312   return pow (flatten (g1), g2);
00313 }
00314 
00315 
00316 
00317 
00318 
00319 bool is_numeric (const string& s);
00320 
00321 struct sum_less_op {
00322   static bool
00323   op (const syntactic& s1, const syntactic& s2) {
00324     generic g1= as_generic (s1);
00325     generic g2= as_generic (s2);
00326     if ((is_func (g1, GEN_TIMES, 2) || is_func (g1, GEN_OVER, 2)) &&
00327         is<literal> (g1[1]) && is_numeric (as_string (as<literal> (g1[1]))))
00328       g1= (is_func (g1, GEN_TIMES, 2)? g1[2]: gen (GEN_OVER, 1, g1[2]));
00329     if ((is_func (g2, GEN_TIMES, 2) || is_func (g2, GEN_OVER, 2)) &&
00330         is<literal> (g2[1]) && is_numeric (as_string (as<literal> (g2[1]))))
00331       g2= (is_func (g2, GEN_TIMES, 2)? g2[2]: gen (GEN_OVER, 1, g2[2]));
00332     return big_small_compare (g1, g2) <= 0;
00333   }
00334 };
00335 
00336 syntactic
00337 ordered_sum (const vector<syntactic>& v) {
00338   vector<syntactic> w= copy (v);
00339   sort_leq<sum_less_op> (w);
00340   syntactic r= 0;
00341   for (nat i=0; i<N(w); i++) r= r + w[i];
00342   return migrate_negate (r, 5);
00343 }
00344 
00345 struct product_less_op {
00346   static bool
00347   op (const syntactic& s1, const syntactic& s2) {
00348     generic g1= as_generic (s1);
00349     generic g2= as_generic (s2);
00350     if (is_func (g1, GEN_OVER, 2) && exact_eq (g1[1], 1)) g1= g1[2];
00351     if (is_func (g2, GEN_OVER, 2) && exact_eq (g2[1], 1)) g2= g2[2];
00352     if (is_func (g1, GEN_POWER, 2) &&
00353         is<literal> (g1[2]) && is_numeric (as_string (as<literal> (g1[2]))))
00354       g1= g1[1];
00355     if (is_func (g2, GEN_POWER, 2) &&
00356         is<literal> (g2[2]) && is_numeric (as_string (as<literal> (g2[2]))))
00357       g2= g2[1];
00358     
00359     return big_small_compare (g1, g2) <= 0;
00360   }
00361 };
00362 
00363 syntactic
00364 ordered_product (const vector<syntactic>& v) {
00365   vector<syntactic> w= copy (v);
00366   sort_leq<product_less_op> (w);
00367   bool old= set_frac_flag (true);
00368   syntactic r= 1;
00369   for (nat i=0; i<N(w); i++) r= r * w[i];
00370   (void) set_frac_flag (old);
00371   return r;
00372 }
00373 
00374 
00375 
00376 
00377 
00378 bool
00379 operator < (const syntactic& x, const syntactic& y) {
00380   return small_big_compare (as_generic (x), as_generic (y)) < 0;
00381 }
00382 
00383 bool
00384 operator <= (const syntactic& x, const syntactic& y) {
00385   return small_big_compare (as_generic (x), as_generic (y)) <= 0;
00386 }
00387 
00388 bool
00389 operator > (const syntactic& x, const syntactic& y) {
00390   return small_big_compare (as_generic (x), as_generic (y)) > 0;
00391 }
00392 
00393 bool
00394 operator >= (const syntactic& x, const syntactic& y) {
00395   return small_big_compare (as_generic (x), as_generic (y)) >= 0;
00396 }
00397 
00398 
00399 
00400 
00401 
00402 syntactic gcd (const syntactic& g1, const syntactic& g2) {
00403   if (exact_eq (g1, 0)) return g2;
00404   if (exact_eq (g2, 0)) return g1;
00405   return syn (GEN_GCD, g1, g2);
00406 }
00407 
00408 syntactic lcm (const syntactic& g1, const syntactic& g2) {
00409   if (exact_eq (g1, 0) || exact_eq (g2, 0)) return 0;
00410   return syn (GEN_LCM, g1, g2);
00411 }
00412 
00413 syntactic xgcd (const syntactic& g1, const syntactic& g2) {
00414   if (exact_eq (g1, 0))
00415     return exact_eq (g2, 0) ?
00416       syn (GEN_SQTUPLE, syn (GEN_ROW, 1, 0     ), syn (GEN_ROW, 0, 1)) :
00417       syn (GEN_SQTUPLE, syn (GEN_ROW, 0, 1 / g2), syn (GEN_ROW, 1, 0));
00418   return exact_eq (g2, 0) ?
00419     syn (GEN_SQTUPLE, syn (GEN_ROW, 1 / g1, 0), syn (GEN_ROW, 0  , 1 )) :
00420     syn (GEN_SQTUPLE, syn (GEN_ROW, 1 / g1, 0), syn (GEN_ROW, -g2, g1));
00421 }
00422 
00423 
00424 
00425 
00426 
00427 syntactic sqrt (const syntactic& g) { return syn (GEN_SQRT, g); }
00428 syntactic exp (const syntactic& g) { return syn (GEN_EXP, g); }
00429 syntactic log (const syntactic& g) { return syn (GEN_LOG, g); }
00430 syntactic cos (const syntactic& g) { return syn (GEN_COS, g); }
00431 syntactic sin (const syntactic& g) { return syn (GEN_SIN, g); }
00432 syntactic tan (const syntactic& g) { return syn (GEN_TAN, g); }
00433 syntactic acos (const syntactic& g) { return syn (GEN_ARCCOS, g); }
00434 syntactic asin (const syntactic& g) { return syn (GEN_ARCSIN, g); }
00435 syntactic atan (const syntactic& g) { return syn (GEN_ARCTAN, g); }
00436 syntactic cosh (const syntactic& g) { return syn (GEN_CH, g); }
00437 syntactic sinh (const syntactic& g) { return syn (GEN_SH, g); }
00438 syntactic tanh (const syntactic& g) { return syn (GEN_TH, g); }
00439 syntactic acosh (const syntactic& g) { return syn (GEN_ARGCH, g); }
00440 syntactic asinh (const syntactic& g) { return syn (GEN_ARGSH, g); }
00441 syntactic atanh (const syntactic& g) { return syn (GEN_ARGTH, g); }
00442 
00443 syntactic trig (const syntactic& g) {
00444   return syn (GEN_SQTUPLE, cos (g), sin (g)); }
00445 syntactic hypot (const syntactic& g1, const syntactic& g2) {
00446   return syn (GEN_HYPOT, g1, g2); }
00447 syntactic atan2 (const syntactic& g1, const syntactic& g2) {
00448   return syn (GEN_ARCTAN2, g1, g2); }
00449 
00450 syntactic Re (const syntactic& g1) { return syn (GEN_RE, g1); }
00451 syntactic Im (const syntactic& g1) { return syn (GEN_IM, g1); }
00452 syntactic abs (const syntactic& g1) { return syn (GEN_ABS, g1); }
00453 syntactic arg (const syntactic& g1) { return syn (GEN_ARG, g1); }
00454 syntactic conj (const syntactic& g1) { return syn (GEN_CONJ, g1); }
00455 syntactic gaussian (const syntactic& g1, const syntactic& g2) {
00456   return g1 + g2 * Imaginary (syntactic); }
00457 syntactic polar (const syntactic& g1, const syntactic& g2) {
00458   return g1 * exp (g2 * Imaginary (syntactic)); }
00459 
00460 syntactic center (const syntactic& g1) { return syn (GEN_CENTER, g1); }
00461 syntactic radius (const syntactic& g1) { return syn (GEN_RADIUS, g1); }
00462 syntactic numerator (const syntactic& g1) {
00463   return syn (GEN_NUMERATOR, g1); }
00464 syntactic denominator (const syntactic& g1) {
00465   return syn (GEN_DENOMINATOR, g1); }
00466 
00467 syntactic operator << (const syntactic& x1, const syntactic& x2) {
00468   return syn (GEN_LESSLESS, x1, x2); }
00469 syntactic operator >> (const syntactic& x1, const syntactic& x2) {
00470   return syn (GEN_GTRGTR, x1, x2); }
00471 syntactic lshiftz (const syntactic& g, const syntactic& sh) {
00472   return syn ("lshiftz", g, sh); }
00473 syntactic rshiftz (const syntactic& g, const syntactic& sh) {
00474   return syn ("rshiftz", g, sh); }
00475 
00476 syntactic derive (const syntactic& g) {
00477   return syn (GEN_DERIVE, g); }
00478 syntactic derive (const syntactic& g, const syntactic& v) {
00479   return syn (GEN_DERIVE, g, v); }
00480 syntactic xderive (const syntactic& g) {
00481   return syn (GEN_XDERIVE, g); }
00482 syntactic xderive (const syntactic& g, const syntactic& v) {
00483   return syn (GEN_XDERIVE, g, v); }
00484 syntactic integrate (const syntactic& g) {
00485   return syn (GEN_INTEGRATE, g); }
00486 syntactic integrate (const syntactic& g, const syntactic& v) {
00487   return syn (GEN_INTEGRATE, g, v); }
00488 
00489 syntactic sqrt_init (const syntactic& x, const syntactic& c) {
00490   return syn ("sqrt_init", x, c); }
00491 syntactic log_init (const syntactic& x, const syntactic& c) {
00492   return syn ("log_init", x, c); }
00493 syntactic acos_init (const syntactic& x, const syntactic& c) {
00494   return syn ("acos_init", x, c); }
00495 syntactic asin_init (const syntactic& x, const syntactic& c) {
00496   return syn ("asin_init", x, c); }
00497 syntactic atan_init (const syntactic& x, const syntactic& c) {
00498   return syn ("atan_init", x, c); }
00499 syntactic integrate_init (const syntactic& g, const syntactic& c) {
00500   return syn ("integrate_init", g, c); }
00501 syntactic integrate_init (const syntactic& g, const syntactic& v,
00502                           const syntactic& c) {
00503   return syn ("integrate_init", g, v, c); }
00504 syntactic solve_lde_init (const syntactic& x, const syntactic& c) {
00505   return syn ("solve_lde_init", x, c); }
00506 
00507 syntactic access (const syntactic& g, const syntactic& i) {
00508   return syn (GEN_ACCESS, g, i); }
00509 syntactic access (const syntactic& g, const syntactic& i, const syntactic& j) {
00510   return syn (GEN_ACCESS, g, i, j); }
00511 syntactic inject (const syntactic& x, const syntactic& y, const syntactic& z) {
00512   return syn ("inject", x, y, z); }
00513 syntactic project (const syntactic& x, const syntactic& y) {
00514   return syn ("project", x, y); }
00515 
00516 
00517 
00518 
00519 
00520 bool operator == (const vector<syntactic>& v, const vector<syntactic>& w) {
00521   if (is_a_scalar (v)) return is_a_scalar (w) && v.scalar () == w.scalar ();
00522   if (N(v) != N(w)) return false;
00523   for (nat i=0; i<N(v); i++)
00524     if (v[i] != w[i]) return false;
00525   return true;
00526 }
00527 
00528 bool operator != (const vector<syntactic>& v, const vector<syntactic>& w) {
00529   return !(v == w);
00530 }
00531 
00532 bool exact_eq (const vector<syntactic>& v, const vector<syntactic>& w) {
00533   if (is_a_scalar (v))
00534     return is_a_scalar (w) && exact_eq (v.scalar (), w.scalar ());
00535   if (N(v) != N(w)) return false;
00536   for (nat i=0; i<N(v); i++)
00537     if (exact_neq (v[i], w[i])) return false;
00538   return true;
00539 }
00540 
00541 bool exact_neq (const vector<syntactic>& v, const vector<syntactic>& w) {
00542   return !exact_eq (v, w);
00543 }
00544 
00545 
00546 
00547 
00548 
00549 nat      the_series_prec = 10;
00550 nat      the_series_zt   = 25;
00551 bool     the_series_expr = false;
00552 
00553 syntactic&
00554 the_series_var () {
00555   static syntactic v ("z");
00556   return v;
00557 }
00558 
00559 syntactic&
00560 the_polynomial_var () {
00561   static syntactic v ("x");
00562   return v;
00563 }
00564 
00565 syntactic flatten (const bool& b) {
00566   return b? syntactic ("true"): syntactic ("false"); }
00567 syntactic flatten (const char& i) {
00568   return syntactic (as_string (i)); }
00569 syntactic flatten (const signed char& i) {
00570   return syntactic (as_string (i)); }
00571 syntactic flatten (const unsigned char& i) {
00572   return syntactic (as_string (i)); }
00573 syntactic flatten (const short int& i) {
00574   return syntactic (as_string (i)); }
00575 syntactic flatten (const short unsigned int& i) {
00576   return syntactic (as_string (i)); }
00577 syntactic flatten (const int& i) {
00578   return syntactic (as_string (i)); }
00579 syntactic flatten (const unsigned int& i) {
00580   return syntactic (as_string (i)); }
00581 syntactic flatten (const long int& i) {
00582   return syntactic (as_string (i)); }
00583 syntactic flatten (const long unsigned int& i) {
00584   return syntactic (as_string (i)); }
00585 syntactic flatten (const long long int& i) {
00586   return syntactic (as_string (i)); }
00587 syntactic flatten (const long long unsigned int& i) {
00588   return syntactic (as_string (i)); }
00589 syntactic flatten (const float& x) {
00590   return syntactic (as_string (x)); }
00591 syntactic flatten (const double& x) {
00592   return syntactic (as_string (x)); }
00593 syntactic flatten (const long double& x) {
00594   return syntactic (as_string (x)); }
00595 syntactic flatten (const char* const & s) {
00596   return syn ("$text", syntactic (quote (s))); }
00597 syntactic flatten (const string& s) {
00598   return syn ("$text", syntactic (quote (s))); }
00599 
00600 }