Back to index

texmacs  1.0.7.15
math_tree.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : math_tree.cpp
00004 * DESCRIPTION: trees as mathematical expressions
00005 * COPYRIGHT  : (C) 2006  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "math_tree.hpp"
00013 
00014 /******************************************************************************
00015 * Mathematical functions on trees
00016 ******************************************************************************/
00017 
00018 tree
00019 neg (tree t) {
00020   if (is_double (t)) return as_tree (-as_double (t));
00021   return tree (MINUS, t);
00022 }
00023 
00024 tree
00025 add (tree t1, tree t2) {
00026   if (is_double (t1) && is_double (t2))
00027     return as_tree (as_double (t1) + as_double (t2));
00028   if (t1 == "0") return t2;
00029   if (t2 == "0") return t1;
00030   return tree (PLUS, t1, t2);
00031 }
00032 
00033 tree
00034 sub (tree t1, tree t2) {
00035   if (is_double (t1) && is_double (t2))
00036     return as_tree (as_double (t1) - as_double (t2));
00037   if (t1 == "0") return tree (MINUS, t2);
00038   if (t2 == "0") return t1;
00039   return tree (MINUS, t1, t2);
00040 }
00041 
00042 tree
00043 mul (tree t1, tree t2) {
00044   if (is_double (t1) && is_double (t2))
00045     return as_tree (as_double (t1) * as_double (t2));
00046   if (t1 == "0" || t2 == "0") return "0";
00047   if (t1 == "1") return t2;
00048   if (t2 == "1") return t1;
00049   return tree (TIMES, t1, t2);
00050 }
00051 
00052 tree
00053 div (tree t1, tree t2) {
00054   if (is_double (t1) && is_double (t2))
00055     return as_tree (as_double (t1) / as_double (t2));
00056   if (t1 == "0") return "0";
00057   if (t2 == "1") return t1;
00058   return tree (OVER, t1, t2);
00059 }
00060 
00061 tree
00062 sqrt (tree t) {
00063   if (is_double (t)) return as_tree (sqrt (as_double (t)));
00064   return tree (MATH_SQRT, t);
00065 }
00066 
00067 tree
00068 exp (tree t) {
00069   if (is_double (t)) return as_tree (exp (as_double (t)));
00070   return tree (EXP, t);
00071 }
00072 
00073 tree
00074 log (tree t) {
00075   if (is_double (t)) return as_tree (log (as_double (t)));
00076   return tree (LOG, t);
00077 }
00078 
00079 tree
00080 pow (tree t1, tree t2) {
00081   if (is_double (t1) && is_double (t2))
00082     return as_tree (pow (as_double (t1), as_double (t2)));
00083   if (t1 == "0" || t1 == "1") return t1;
00084   if (t2 == "0") return "1";
00085   if (t2 == "1") return t1;
00086   return tree (POW, t1, t2);
00087 }
00088 
00089 tree
00090 cos (tree t) {
00091   if (is_double (t)) return as_tree (cos (as_double (t)));
00092   return tree (COS, t);
00093 }
00094 
00095 tree
00096 sin (tree t) {
00097   if (is_double (t)) return as_tree (sin (as_double (t)));
00098   return tree (SIN, t);
00099 }
00100 
00101 tree
00102 tan (tree t) {
00103   if (is_double (t)) return as_tree (tan (as_double (t)));
00104   return tree (TAN, t);
00105 }
00106 
00107 /******************************************************************************
00108 * Pretty printing
00109 ******************************************************************************/
00110 
00111 static void
00112 math_print (string& s, tree t, int level) {
00113   if (level <= 0 && is_func (t, PLUS, 2)) {
00114     math_print (s, t[0], 0);
00115     s << " + ";
00116     math_print (s, t[1], 0);
00117   }
00118   else if (level <= 0 && is_func (t, MINUS, 2)) {
00119     math_print (s, t[0], 0);
00120     s << " - ";
00121     math_print (s, t[1], 1);
00122   }
00123   else if (level <= 1 && is_func (t, TIMES, 2)) {
00124     math_print (s, t[0], 1);
00125     s << " * ";
00126     math_print (s, t[1], 1);
00127   }
00128   else if (level <= 1 && is_func (t, OVER, 2)) {
00129     math_print (s, t[0], 1);
00130     s << " / ";
00131     math_print (s, t[1], 2);
00132   }
00133   else if (level <= 2 && is_func (t, POW, 2)) {
00134     math_print (s, t[0], 3);
00135     s << "^";
00136     math_print (s, t[1], 2);
00137   }
00138   else if (level <= 3 && is_func (t, MINUS, 1)) {
00139     s << "-";
00140     math_print (s, t[0], 3);
00141   }
00142   else if (level <= 4 && is_func (t, RSUB, 2)) {
00143     math_print (s, t[0], 4);
00144     s << "[";
00145     math_print (s, t[1], 0);
00146     s << "]";
00147   }
00148   else if (is_func (t, PLUS, 2) || is_func (t, MINUS, 2) ||
00149           is_func (t, TIMES, 2) || is_func (t, OVER, 2) ||
00150           is_func (t, POW, 2) || is_func (t, MINUS, 1) ||
00151           is_func (t, RSUB, 2))
00152     {
00153       s << "(";
00154       math_print (s, t, 0);
00155       s << ")";
00156     }
00157   else if (is_atomic (t)) s << t->label;
00158   else if (is_tuple (t)) {
00159     int i, n= N(t);
00160     s << "[ ";
00161     for (i=0; i<n; i++) {
00162       if (i != 0) s << ", ";
00163       math_print (s, t[i], 0);
00164     }
00165     if (n != 0) s << " ";
00166     s << "]";
00167   }
00168   else {
00169     int i, n= N(t);
00170     if (L(t) == MATH_SQRT) s << "sqrt (";
00171     else s << as_string (L(t)) << " (";
00172     for (i=0; i<n; i++) {
00173       if (i != 0) s << ", ";
00174       math_print (s, t[i], 0);
00175     }
00176     s << ")";
00177   }
00178 }
00179 
00180 string
00181 as_math_string (tree t) {
00182   string r;
00183   math_print (r, t, 0);
00184   return r;
00185 }