strprinter.h
1 #ifndef SYMENGINE_STR_PRINTER_H
2 #define SYMENGINE_STR_PRINTER_H
3 
4 #include <symengine/visitor.h>
5 #include <symengine/printers.h>
6 
7 namespace SymEngine
8 {
9 
10 std::string print_double(double d);
11 std::vector<std::string> init_str_printer_names();
12 
13 enum class PrecedenceEnum { Relational, Add, Mul, Pow, Atom };
14 
15 class Precedence : public BaseVisitor<Precedence>
16 {
17 private:
18  PrecedenceEnum precedence;
19 
20 public:
21  void bvisit(const Add &x);
22  void bvisit(const Mul &x);
23  void bvisit(const Relational &x);
24  void bvisit(const Pow &x);
25  template <typename Poly>
26  void bvisit_upoly(const Poly &x)
27  {
28  if (x.end() == ++x.begin()) {
29  auto it = x.begin();
30  precedence = PrecedenceEnum::Atom;
31  if (it->second == 1) {
32  if (it->first == 0 or it->first == 1) {
33  precedence = PrecedenceEnum::Atom;
34  } else {
35  precedence = PrecedenceEnum::Pow;
36  }
37  } else {
38  if (it->first == 0) {
39  Expression(it->second).get_basic()->accept(*this);
40  } else {
41  precedence = PrecedenceEnum::Mul;
42  }
43  }
44  } else if (x.begin() == x.end()) {
45  precedence = PrecedenceEnum::Atom;
46  } else {
47  precedence = PrecedenceEnum::Add;
48  }
49  }
50 
51  template <typename Container, typename Poly>
52  void bvisit(const UPolyBase<Container, Poly> &x)
53  {
54  bvisit_upoly(down_cast<const Poly &>(x));
55  }
56 
57  void bvisit(const GaloisField &x);
58 
59  template <typename Container, typename Poly>
60  void bvisit(const MSymEnginePoly<Container, Poly> &x)
61  {
62  if (0 == x.get_poly().dict_.size()) {
63  precedence = PrecedenceEnum::Atom;
64  } else if (1 == x.get_poly().dict_.size()) {
65  auto iter = x.get_poly().dict_.begin();
66  precedence = PrecedenceEnum::Atom;
67  bool first = true; // true if there are no nonzero exponents, false
68  // otherwise
69  for (unsigned int exp : iter->first) {
70  if (exp > 0) {
71  if (first && exp > 1)
72  precedence = PrecedenceEnum::Pow;
73  if (!first)
74  precedence = PrecedenceEnum::Mul;
75  first = false;
76  }
77  }
78  if (!first) {
79  if (iter->second != 1)
80  precedence = PrecedenceEnum::Mul;
81  }
82  } else {
83  precedence = PrecedenceEnum::Add;
84  }
85  }
86 
87  void bvisit(const Rational &x);
88  void bvisit(const Complex &x);
89  void bvisit(const Integer &x);
90  void bvisit(const RealDouble &x);
91 #ifdef HAVE_SYMENGINE_PIRANHA
92  void bvisit(const URatPSeriesPiranha &x);
93  void bvisit(const UPSeriesPiranha &x);
94 #endif
95  void bvisit(const ComplexDouble &x);
96 #ifdef HAVE_SYMENGINE_MPFR
97  void bvisit(const RealMPFR &x);
98 #endif
99 #ifdef HAVE_SYMENGINE_MPC
100  void bvisit(const ComplexMPC &x);
101 #endif
102  void bvisit(const Basic &x);
103  PrecedenceEnum getPrecedence(const RCP<const Basic> &x);
104 };
105 
106 class StrPrinter : public BaseVisitor<StrPrinter>
107 {
108 private:
109  static const std::vector<std::string> names_;
110 
111 protected:
112  std::string str_;
113  virtual std::string print_mul();
114  virtual bool split_mul_coef();
115  virtual void _print_pow(std::ostringstream &o, const RCP<const Basic> &a,
116  const RCP<const Basic> &b);
117  virtual std::string print_div(const std::string &num,
118  const std::string &den, bool paren);
119  virtual std::string get_imag_symbol();
120  virtual std::string parenthesize(const std::string &expr);
121  std::string parenthesizeLT(const RCP<const Basic> &x,
122  PrecedenceEnum precedenceEnum);
123  std::string parenthesizeLE(const RCP<const Basic> &x,
124  PrecedenceEnum precedenceEnum);
125 
126 public:
127  void bvisit(const Basic &x);
128  void bvisit(const Symbol &x);
129  void bvisit(const Integer &x);
130  void bvisit(const Rational &x);
131  void bvisit(const Complex &x);
132  void bvisit(const Interval &x);
133  void bvisit(const Complexes &x);
134  void bvisit(const Reals &x);
135  void bvisit(const Rationals &x);
136  void bvisit(const Integers &x);
137  void bvisit(const Naturals &x);
138  void bvisit(const Naturals0 &x);
139  void bvisit(const Piecewise &x);
140  void bvisit(const EmptySet &x);
141  void bvisit(const FiniteSet &x);
142  void bvisit(const UniversalSet &x);
143  void bvisit(const ConditionSet &x);
144  void bvisit(const Contains &x);
145  void bvisit(const BooleanAtom &x);
146  void bvisit(const And &x);
147  void bvisit(const Or &x);
148  void bvisit(const Xor &x);
149  void bvisit(const Not &x);
150  void bvisit(const Union &x);
151  void bvisit(const Intersection &x);
152  void bvisit(const Complement &x);
153  void bvisit(const ImageSet &x);
154  void bvisit(const Add &x);
155  void bvisit(const Mul &x);
156  void bvisit(const Pow &x);
157  void bvisit(const UIntPoly &x);
158  void bvisit(const MIntPoly &x);
159  void bvisit(const URatPoly &x);
160 #ifdef HAVE_SYMENGINE_FLINT
161  void bvisit(const UIntPolyFlint &x);
162  void bvisit(const URatPolyFlint &x);
163 #endif
164  void bvisit(const UExprPoly &x);
165  void bvisit(const MExprPoly &x);
166  void bvisit(const GaloisField &x);
167  void bvisit(const Infty &x);
168  void bvisit(const NaN &x);
169  void bvisit(const UnivariateSeries &x);
170 #ifdef HAVE_SYMENGINE_PIRANHA
171  void bvisit(const URatPSeriesPiranha &x);
172  void bvisit(const UPSeriesPiranha &x);
173  void bvisit(const UIntPolyPiranha &x);
174  void bvisit(const URatPolyPiranha &x);
175 #endif
176  void bvisit(const Constant &x);
177  void bvisit(const Function &x);
178  void bvisit(const FunctionSymbol &x);
179  void bvisit(const Derivative &x);
180  void bvisit(const Subs &x);
181  void bvisit(const RealDouble &x);
182  void bvisit(const ComplexDouble &x);
183  void bvisit(const Equality &x);
184  void bvisit(const Unequality &x);
185  void bvisit(const LessThan &x);
186  void bvisit(const StrictLessThan &x);
187 #ifdef HAVE_SYMENGINE_MPFR
188  void bvisit(const RealMPFR &x);
189 #endif
190 #ifdef HAVE_SYMENGINE_MPC
191  void bvisit(const ComplexMPC &x);
192 #endif
193  void bvisit(const NumberWrapper &x);
194  void bvisit(const Tuple &x);
195  void bvisit(const IdentityMatrix &x);
196  void bvisit(const ZeroMatrix &x);
197 
198  std::string apply(const RCP<const Basic> &b);
199  std::string apply(const vec_basic &v);
200  std::string apply(const Basic &b);
201 };
202 
203 class JuliaStrPrinter : public BaseVisitor<JuliaStrPrinter, StrPrinter>
204 {
205 public:
206  using StrPrinter::bvisit;
207  void _print_pow(std::ostringstream &o, const RCP<const Basic> &a,
208  const RCP<const Basic> &b) override;
209  std::string get_imag_symbol() override;
210  void bvisit(const Constant &x);
211  void bvisit(const NaN &x);
212  void bvisit(const Infty &x);
213 };
214 } // namespace SymEngine
215 
216 #endif // SYMENGINE_STR_PRINTER_H
The base class for representing addition in symbolic expressions.
Definition: add.h:27
The lowest unit of symbolic representation.
Definition: basic.h:97
Complex Double Class to hold std::complex<double> values.
Complex Class.
Definition: complex.h:33
const RCP< const Basic > & get_basic() const
Method to get Basic from Expression.
Definition: expression.h:259
Integer Class.
Definition: integer.h:19
Rational Class.
Definition: rational.h:16
RealDouble Class to hold double values.
Definition: real_double.h:20
UnivariateSeries Class.
Main namespace for SymEngine package.
Definition: add.cpp:19
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
Definition: pow.cpp:271