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