mathml.cpp
1 #include <limits>
2 #include <symengine/printers/mathml.h>
4 #include <symengine/printers.h>
5 
6 namespace SymEngine
7 {
8 
9 std::vector<std::string> init_mathml_printer_names()
10 {
11  std::vector<std::string> names = init_str_printer_names();
12  names[SYMENGINE_ASIN] = "arcsin";
13  names[SYMENGINE_ACOS] = "arccos";
14  names[SYMENGINE_ASEC] = "arcsec";
15  names[SYMENGINE_ACSC] = "arccsc";
16  names[SYMENGINE_ATAN] = "arctan";
17  names[SYMENGINE_ACOT] = "arccot";
18  names[SYMENGINE_ASINH] = "arcsinh";
19  names[SYMENGINE_ACSCH] = "arccsch";
20  names[SYMENGINE_ACOSH] = "arccosh";
21  names[SYMENGINE_ATANH] = "arctanh";
22  names[SYMENGINE_ACOTH] = "arccoth";
23  names[SYMENGINE_ASECH] = "arcsech";
24  return names;
25 }
26 
27 void MathMLPrinter::bvisit(const Basic &x)
28 {
29  throw SymEngineException("Error: not supported");
30 }
31 
32 void MathMLPrinter::bvisit(const Symbol &x)
33 {
34  s << "<ci>" << x.get_name() << "</ci>";
35 }
36 
37 void MathMLPrinter::bvisit(const Integer &x)
38 {
39  s << "<cn type=\"integer\">" << x.as_integer_class() << "</cn>";
40 }
41 
42 void MathMLPrinter::bvisit(const Rational &x)
43 {
44  const auto &rational = x.as_rational_class();
45  s << "<cn type=\"rational\">" << get_num(rational) << "<sep/>"
46  << get_den(rational) << "</cn>";
47 }
48 
49 void MathMLPrinter::bvisit(const RealDouble &x)
50 {
51  s << "<cn type=\"real\">" << x << "</cn>";
52 }
53 
54 #ifdef HAVE_SYMENGINE_MPFR
55 void MathMLPrinter::bvisit(const RealMPFR &x)
56 {
57  // TODO: Use bigfloat here
58  s << "<cn type=\"real\">" << x << "</cn>";
59 }
60 #endif
61 
62 void MathMLPrinter::bvisit(const ComplexBase &x)
63 {
64  s << "<apply><csymbol cd=\"nums1\">complex_cartesian</csymbol>";
65  x.real_part()->accept(*this);
66  x.imaginary_part()->accept(*this);
67  s << "</apply>";
68 }
69 
70 void MathMLPrinter::bvisit(const Interval &x)
71 {
72  s << "<interval closure=";
73  if (x.get_left_open()) {
74  if (x.get_right_open()) {
75  s << "\"open\">";
76  } else {
77  s << "\"open-closed\">";
78  }
79  } else {
80  if (x.get_right_open()) {
81  s << "\"closed-open\">";
82  } else {
83  s << "\"closed\">";
84  }
85  }
86  x.get_start()->accept(*this);
87  x.get_end()->accept(*this);
88  s << "</interval>";
89 }
90 
91 void MathMLPrinter::bvisit(const Piecewise &x)
92 {
93  s << "<piecewise>";
94  const auto &equations = x.get_vec();
95  for (const auto &equation : equations) {
96  s << "<piece>";
97  equation.first->accept(*this);
98  equation.second->accept(*this);
99  s << "</piece>";
100  }
101  s << "</piecewise>";
102 }
103 
104 void MathMLPrinter::bvisit(const EmptySet &x)
105 {
106  s << "<emptyset/>";
107 }
108 
109 void MathMLPrinter::bvisit(const Complexes &x)
110 {
111  s << "<complexes/>";
112 }
113 
114 void MathMLPrinter::bvisit(const Reals &x)
115 {
116  s << "<reals/>";
117 }
118 
119 void MathMLPrinter::bvisit(const Rationals &x)
120 {
121  s << "<rationals/>";
122 }
123 
124 void MathMLPrinter::bvisit(const Integers &x)
125 {
126  s << "<integers/>";
127 }
128 
129 void MathMLPrinter::bvisit(const FiniteSet &x)
130 {
131  s << "<set>";
132  const auto &args = x.get_args();
133  for (const auto &arg : args) {
134  arg->accept(*this);
135  }
136  s << "</set>";
137 }
138 
139 void MathMLPrinter::bvisit(const ConditionSet &x)
140 {
141  s << "<set><bvar>";
142  x.get_symbol()->accept(*this);
143  s << "</bvar><condition>";
144  x.get_condition()->accept(*this);
145  s << "</condition>";
146  x.get_symbol()->accept(*this);
147  s << "</set>";
148 }
149 
150 void MathMLPrinter::bvisit(const Contains &x)
151 {
152  s << "<apply><in/>";
153  x.get_expr()->accept(*this);
154  x.get_set()->accept(*this);
155  s << "</apply>";
156 }
157 
158 void MathMLPrinter::bvisit(const BooleanAtom &x)
159 {
160  if (x.get_val()) {
161  s << "<true/>";
162  } else {
163  s << "<false/>";
164  }
165 }
166 
167 void MathMLPrinter::bvisit(const And &x)
168 {
169  s << "<apply><and/>";
170  const auto &conditions = x.get_args();
171  for (const auto &condition : conditions) {
172  condition->accept(*this);
173  }
174  s << "</apply>";
175 }
176 
177 void MathMLPrinter::bvisit(const Or &x)
178 {
179  s << "<apply><or/>";
180  const auto &conditions = x.get_args();
181  for (const auto &condition : conditions) {
182  condition->accept(*this);
183  }
184  s << "</apply>";
185 }
186 
187 void MathMLPrinter::bvisit(const Xor &x)
188 {
189  s << "<apply><xor/>";
190  const auto &conditions = x.get_args();
191  for (const auto &condition : conditions) {
192  condition->accept(*this);
193  }
194  s << "</apply>";
195 }
196 
197 void MathMLPrinter::bvisit(const Not &x)
198 {
199  s << "<apply><not/>";
200  x.get_arg()->accept(*this);
201  s << "</apply>";
202 }
203 
204 void MathMLPrinter::bvisit(const Union &x)
205 {
206  s << "<apply><union/>";
207  const auto &sets = x.get_args();
208  for (const auto &set : sets) {
209  set->accept(*this);
210  }
211  s << "</apply>";
212 }
213 
214 void MathMLPrinter::bvisit(const Complement &x)
215 {
216  s << "<apply><setdiff/>";
217  x.get_universe()->accept(*this);
218  x.get_container()->accept(*this);
219  s << "</apply>";
220 }
221 
222 void MathMLPrinter::bvisit(const ImageSet &x)
223 {
224  s << "<set><bvar>";
225  x.get_expr()->accept(*this);
226  s << "</bvar><condition><apply><in/>";
227  x.get_symbol()->accept(*this);
228  x.get_baseset()->accept(*this);
229  s << "</apply></condition>";
230  x.get_symbol()->accept(*this);
231  s << "</set>";
232 }
233 
234 void MathMLPrinter::bvisit(const Add &x)
235 {
236  s << "<apply><plus/>";
237  auto args = x.get_args();
238  for (auto arg : args) {
239  arg->accept(*this);
240  }
241  s << "</apply>";
242 }
243 
244 void MathMLPrinter::bvisit(const Mul &x)
245 {
246  s << "<apply><times/>";
247  auto args = x.get_args();
248  for (auto arg : args) {
249  arg->accept(*this);
250  }
251  s << "</apply>";
252 }
253 
254 void MathMLPrinter::bvisit(const Pow &x)
255 {
256  s << "<apply><power/>";
257  x.get_base()->accept(*this);
258  x.get_exp()->accept(*this);
259  s << "</apply>";
260 }
261 
262 void MathMLPrinter::bvisit(const Constant &x)
263 {
264  s << "<";
265  if (eq(x, *pi)) {
266  s << "pi/";
267  } else if (eq(x, *E)) {
268  s << "exponentiale/";
269  } else if (eq(x, *EulerGamma)) {
270  s << "eulergamma/";
271  } else {
272  s << "cn type=\"real\">" << eval_double(x) << "</cn";
273  }
274  s << ">";
275 }
276 
277 void MathMLPrinter::bvisit(const Function &x)
278 {
279  static const std::vector<std::string> names_ = init_mathml_printer_names();
280  s << "<apply>";
281  s << "<" << names_[x.get_type_code()] << "/>";
282  const auto &args = x.get_args();
283  for (const auto &arg : args) {
284  arg->accept(*this);
285  }
286  s << "</apply>";
287 }
288 
289 void MathMLPrinter::bvisit(const UnevaluatedExpr &x)
290 {
291  apply(*x.get_arg());
292 }
293 
294 void MathMLPrinter::bvisit(const FunctionSymbol &x)
295 {
296  s << "<apply><ci>" << x.get_name() << "</ci>";
297  const auto &args = x.get_args();
298  for (const auto &arg : args) {
299  arg->accept(*this);
300  }
301  s << "</apply>";
302 }
303 
304 void MathMLPrinter::bvisit(const Equality &x)
305 {
306  s << "<apply><eq/>";
307  x.get_arg1()->accept(*this);
308  x.get_arg2()->accept(*this);
309  s << "</apply>";
310 }
311 
312 void MathMLPrinter::bvisit(const Unequality &x)
313 {
314  s << "<apply><neq/>";
315  x.get_arg1()->accept(*this);
316  x.get_arg2()->accept(*this);
317  s << "</apply>";
318 }
319 
320 void MathMLPrinter::bvisit(const LessThan &x)
321 {
322  s << "<apply><leq/>";
323  x.get_arg1()->accept(*this);
324  x.get_arg2()->accept(*this);
325  s << "</apply>";
326 }
327 
328 void MathMLPrinter::bvisit(const StrictLessThan &x)
329 {
330  s << "<apply><lt/>";
331  x.get_arg1()->accept(*this);
332  x.get_arg2()->accept(*this);
333  s << "</apply>";
334 }
335 
336 void MathMLPrinter::bvisit(const Derivative &x)
337 {
338  s << "<apply><partialdiff/><bvar>";
339  for (const auto &elem : x.get_symbols()) {
340  elem->accept(*this);
341  }
342  s << "</bvar>";
343  x.get_arg()->accept(*this);
344  s << "</apply>";
345 }
346 
347 std::string MathMLPrinter::apply(const Basic &b)
348 {
349  b.accept(*this);
350  return s.str();
351 }
352 
353 std::string mathml(const Basic &x)
354 {
355  MathMLPrinter m;
356  return m.apply(x);
357 }
358 } // namespace SymEngine
Main namespace for SymEngine package.
Definition: add.cpp:19
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
RCP< const Number > rational(long n, long d)
convenience creator from two longs
Definition: rational.h:328
T str(T... args)