carl  24.04
Computer ARithmetic Library
ExpressionParser.h
Go to the documentation of this file.
1 /**
2  * @file PolynomialParser.h
3  * @author Gereon Kremer <gereon.kremer@cs.rwth-aachen.de>
4  */
5 
6 #pragma once
7 
8 #include "Common.h"
10 
11 #if BOOST_VERSION >= 105900
12 #ifdef USE_CLN_NUMBERS
13 namespace boost { namespace spirit { namespace traits {
14  template<> inline bool scale(int exp, cln::cl_RA& r, cln::cl_RA acc) {
15  if (exp >= 0)
16  r = acc * carl::pow(cln::cl_RA(10), (unsigned)exp);
17  else
18  r = acc / carl::pow(cln::cl_RA(10), (unsigned)(-exp));
19  return true;
20  }
21 #if BOOST_VERSION < 107000
22  template<> inline bool is_equal_to_one(const cln::cl_RA& value) {
23  return value == 1;
24  }
25 #endif
26 }}}
27 #endif
28 namespace boost { namespace spirit { namespace traits {
29  template<> inline bool scale(int exp, mpq_class& r, mpq_class acc) {
30  if (exp >= 0)
31  r = acc * carl::pow(mpq_class(10), (unsigned)exp);
32  else
33  r = acc / carl::pow(mpq_class(10), (unsigned)(-exp));
34  return true;
35  }
36 #if BOOST_VERSION < 107000
37  template<> inline bool is_equal_to_one(const mpq_class& value) {
38  return value == 1;
39  }
40 #endif
41  template<> inline mpq_class negate(bool neg, const mpq_class& n) {
42  return neg ? mpq_class(-n) : n;
43  }
44 }}}
45 #else
46 #ifdef USE_CLN_NUMBERS
47 namespace boost { namespace spirit { namespace traits {
48  template<> inline void scale(int exp, cln::cl_RA& r) {
49  if (exp >= 0)
50  r *= carl::pow(cln::cl_RA(10), (unsigned)exp);
51  else
52  r /= carl::pow(cln::cl_RA(10), (unsigned)(-exp));
53  }
54 #if BOOST_VERSION < 107000
55  template<> inline bool is_equal_to_one(const cln::cl_RA& value) {
56  return value == 1;
57  }
58 #endif
59 }}}
60 #endif
61 namespace boost { namespace spirit { namespace traits {
62  template<> inline void scale(int exp, mpq_class& r) {
63  if (exp >= 0)
64  r *= carl::pow(mpq_class(10), (unsigned)exp);
65  else
66  r /= carl::pow(mpq_class(10), (unsigned)(-exp));
67  }
68 #if BOOST_VERSION < 107000
69  template<> inline bool is_equal_to_one(const mpq_class& value) {
70  return value == 1;
71  }
72 #endif
73  template<> inline mpq_class negate(bool neg, const mpq_class& n) {
74  return neg ? mpq_class(-n) : n;
75  }
76 }}}
77 #endif
78 
79 namespace carl::io {
80 namespace parser {
81 
82 template<typename Pol>
83 struct ExpressionParser: public qi::grammar<Iterator, ExpressionType<Pol>(), Skipper> {
84  typedef typename Pol::CoeffType CoeffType;
86 
87  class perform_addition: public boost::static_visitor<expr_type> {
88  public:
89  template<typename T, typename U>
90  expr_type operator()(const T& lhs, const U& rhs) const {
91  return Pol(lhs) + Pol(rhs);
92  }
93 
94  expr_type operator()(const CoeffType& lhs, const CoeffType& rhs) const {
95  return (lhs) + (rhs);
96  }
97 
98  expr_type operator()(const RatFun<Pol>& lhs, const Monomial::Arg& rhs) const {
99  return (lhs) + Pol(rhs);
100  }
101 
102  expr_type operator()(const RatFun<Pol>& lhs, const Term<CoeffType>& rhs) const {
103  return (lhs) + Pol(rhs);
104  }
105 
106  template<typename T>
107  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
108  operator()(const RatFun<Pol>& lhs, const T& rhs) const {
109  return (lhs) + (rhs);
110  }
111 
112  template<typename T>
113  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
114  operator()(const T& lhs, const RatFun<Pol>& rhs) const {
115  return (rhs) + Pol(lhs);
116  }
117 
118  expr_type operator()(const RatFun<Pol>& lhs, const RatFun<Pol>& rhs) const {
119  return (lhs) + (rhs);
120  }
121 
122  template<typename T>
123  expr_type operator()(const Formula<Pol>& lhs, const T& rhs) const {
124  throw std::runtime_error("No addition for formula");
125  }
126 
127  template<typename T>
128  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
129  operator()(const T& lhs, const Formula<Pol>& rhs) const {
130  throw std::runtime_error("No addition for formula");
131  }
132  };
133 
134  class perform_subtraction: public boost::static_visitor<expr_type> {
135  public:
136  template<typename T, typename U>
137  expr_type operator()(const T& lhs, const U& rhs) const {
138  return Pol(lhs) - Pol(rhs);
139  }
140 
141  expr_type operator()(const CoeffType& lhs, const CoeffType& rhs) const {
142  return (lhs) - (rhs);
143  }
144 
145  expr_type operator()(const RatFun<Pol>& lhs, const Monomial::Arg& rhs) const {
146  return (lhs) - Pol(rhs);
147  }
148 
149  expr_type operator()(const RatFun<Pol>& lhs, const Term<CoeffType>& rhs) const {
150  return (lhs) - Pol(rhs);
151  }
152 
153  template<typename T>
154  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
155  operator()(const RatFun<Pol>& lhs, const T& rhs) const {
156  return (lhs) - (rhs);
157  }
158 
159  template<typename T>
160  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
161  operator()(const T& lhs, const RatFun<Pol>& rhs) const {
162  return (rhs) - Pol(lhs);
163  }
164 
165  expr_type operator()(const RatFun<Pol>& lhs, const RatFun<Pol>& rhs) const {
166  return (lhs) - (rhs);
167  }
168 
169  template<typename T>
170  expr_type operator()(const Formula<Pol>& lhs, const T& rhs) const {
171  throw std::runtime_error("No subtraction for formula");
172  }
173 
174  template<typename T>
175  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
176  operator()(const T& lhs, const Formula<Pol>& rhs) const {
177  throw std::runtime_error("No subtraction for formula");
178  }
179  };
180 
181  class perform_multiplication: public boost::static_visitor<expr_type> {
182  public:
183  template<typename T, typename U>
184  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
185  operator()(const T& lhs, const U& rhs) const {
186  return lhs * rhs;
187  }
188 
189  template<typename T>
190  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
191  operator()(const T& lhs, const RatFun<Pol>& rhs) const {
192  return rhs * lhs;
193  }
194 
195  expr_type operator()(const RatFun<Pol>& lhs, const Monomial::Arg& rhs) const {
196  return (lhs) * Pol(rhs);
197  }
198 
199  expr_type operator()(const RatFun<Pol>& lhs, const Term<CoeffType>& rhs) const {
200  return (lhs) * Pol(rhs);
201  }
202 
203  expr_type operator()(const Monomial::Arg& lhs, const RatFun<Pol>& rhs) const {
204  return (rhs) * Pol(lhs);
205  }
206 
207  expr_type operator()(const Term<CoeffType>& lhs, const RatFun<Pol>& rhs) const {
208  return (rhs) * Pol(lhs);
209  }
210 
211  template<typename T>
212  expr_type operator()(const Formula<Pol>& lhs, const T& rhs) const {
213  throw std::runtime_error("No multiplication for formula");
214  }
215 
216  template<typename T>
217  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
218  operator()(const T& lhs, const Formula<Pol>& rhs) const {
219  throw std::runtime_error("No multiplication for formula");
220  }
221  };
222 
223  class perform_division: public boost::static_visitor<expr_type> {
224  public:
225  expr_type operator()(const RatFun<Pol>& lhs, const CoeffType& rhs) const {
226  return lhs / rhs;
227  }
228 
229  template<typename T>
230  typename std::enable_if<!std::is_base_of<Formula<Pol>, T>::value, expr_type>::type
231  operator()(const RatFun<Pol>& lhs, const T& rhs) const {
232  return lhs / rhs;
233  }
234 
235  expr_type operator()(const RatFun<Pol>& lhs, const Monomial::Arg& rhs) const {
236  return lhs / Pol(rhs);
237  }
238 
239  expr_type operator()(const RatFun<Pol>& lhs, const Term<CoeffType>& rhs) const {
240  return lhs / Pol(rhs);
241  }
242 
243  expr_type operator()(const RatFun<Pol>& lhs, const RatFun<Pol>& rhs) const {
244  return lhs / rhs;
245  }
246 
247  template<typename T>
248  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
249  operator()(const T& lhs, const CoeffType& coeff) const {
250  return lhs * reciprocal(coeff);
251  }
252 
253  template<typename T>
254  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
255  operator()(const T& lhs, const RatFun<Pol>& rhs) const {
256  // TODO: Not extremely efficient probably
257  return RatFun<Pol>(rhs.denominator(), rhs.nominator()) * Pol(lhs);
258  }
259 
260  template<typename T, typename U>
261  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
262  operator()(const T& lhs, const U& rhs) const {
263  return RatFun<Pol>(Pol(lhs), Pol(rhs));
264  }
265 
266  template<typename T>
267  expr_type operator()(const Formula<Pol>& lhs, const T& rhs) const {
268  throw std::runtime_error("No division for formula");
269  }
270 
271  template<typename T>
272  typename std::enable_if<!std::is_same<Formula<Pol>, T>::value, expr_type>::type
273  operator()(const T& lhs, const Formula<Pol>& rhs) const {
274  throw std::runtime_error("No division for formula");
275  }
276  };
277 
278  class perform_power: public boost::static_visitor<expr_type> {
279  public:
281 
283 
284  template<typename T>
285  expr_type operator()(const T& lhs) const {
286  return lhs.pow(expVal);
287  }
288 
289  expr_type operator()(const RatFun<Pol>& lhs) const {
290  return RatFun<Pol>(lhs.nominator().pow(expVal), lhs.denominator().pow(expVal));
291  }
292 
293  expr_type operator()(const CoeffType& lhs) const {
294  return carl::pow(lhs, expVal);
295  }
296 
297  expr_type operator()(const Variable& lhs) const {
298  return createMonomial(lhs, expVal);
299  }
300 
301  expr_type operator()(const Monomial::Arg& lhs) const {
302  return lhs->pow(expVal);
303  }
304 
305  expr_type operator()(const Formula<Pol>& lhs) const {
306  throw std::runtime_error("No power for fomula");
307  }
308  };
309 
310  class perform_negate: public boost::static_visitor<expr_type> {
311  public:
312  template<typename T>
313  expr_type operator()(const T& lhs) const {
314  return lhs * CoeffType(-1);
315  }
316 
317  expr_type operator()(const Formula<Pol>& lhs) const {
318  throw std::runtime_error("No negate for fomula");
319  }
320  };
321 
322  class print_expr_type: public boost::static_visitor<> {
323  public:
324  void operator()(const RatFun<Pol>& expr) const {
325  std::cout << "Rational function " << expr << std::endl;
326  }
327 
328  void operator()(const Pol& expr) const {
329  std::cout << "Polynomial " << expr << std::endl;
330  }
331 
332  void operator()(const Term<CoeffType>& expr) const {
333  std::cout << "Term " << expr << std::endl;
334  }
335 
336  void operator()(const Monomial::Arg& expr) const {
337  std::cout << "Monomial " << expr << std::endl;
338  }
339 
340  void operator()(const CoeffType& expr) const {
341  std::cout << "Coefficient " << expr << std::endl;
342  }
343 
344  void operator()(const Variable& expr) const {
345  std::cout << "Variable " << expr << std::endl;
346  }
347 
348  void operator()(const Formula<Pol>& expr) const {
349  std::cout << "Formula " << expr << std::endl;
350  }
351  };
352 
353  ExpressionParser(): ExpressionParser<Pol>::base_type(main, "polynomial") {
354  /** Tokens */
355  operationShift.add("+", ADD)("-", SUB);
356  operationScale.add("*", MUL)("/", DIV);
357  operationPow.add("^", POW)("**", POW);
358  operationSign.add("-", NEG);
359 
364 
365  varname = qi::lexeme[ (qi::alpha | qi::char_("_")) >> *(qi::alnum | qi::char_("_"))];
366  variable = varname[qi::_val = px::bind(&ExpressionParser<Pol>::newVariable, px::ref(*this), qi::_1)];
367 
368  /** Rules */
369  // operationScaleLA is a look-ahead hack to prevent the * operator from consuming ** (power)
370  operationScaleLA = qi::lexeme[ operationScale >> !qi::lit("*") ][qi::_val = qi::_1];
371  monomial = variable[qi::_val = qi::_1];
372  boolean = (qi::true_[qi::_val = px::bind(&ExpressionParser<Pol>::makeBool, px::ref(*this), true)] | qi::false_[qi::_val = px::bind(&ExpressionParser<Pol>::makeBool, px::ref(*this), false)]);
373  atom = (boolean[qi::_val = qi::_1] | monomial[qi::_val = qi::_1] | coeff[qi::_val = qi::_1]);
374  expr = ("(" > expr_sum > ")")[qi::_val = qi::_1] | atom[qi::_val = qi::_1];
375  expr_power = (expr >> *(operationPow > exponentVal))[qi::_val = px::bind(&ExpressionParser<Pol>::powExpr, px::ref(*this), qi::_1, qi::_2)];
376  expr_sign = (*operationSign > expr_power)[qi::_val = px::bind(&ExpressionParser<Pol>::signExpr, px::ref(*this), qi::_1, qi::_2)];
377  expr_product = (expr_sign >> *(operationScaleLA > expr_power))[qi::_val = px::bind(&ExpressionParser<Pol>::arithmeticExpr, px::ref(*this), qi::_1, qi::_2)];
378  expr_sum = (expr_product >> *(operationShift > expr_product))[qi::_val = px::bind(&ExpressionParser<Pol>::arithmeticExpr, px::ref(*this), qi::_1, qi::_2)];
379  main = expr_sum;
380 
381  varname.name("varname");
382  variable.name("variable");
383  monomial.name("monomial");
384  atom.name("atom");
385  expr.name("expr");
386  expr_sign.name("expr_sign");
387  expr_power.name("expr_power");
388  expr_product.name("expr_product");
389  expr_sum.name("expr_sum");
390  main.name("main");
391  }
392 
394  auto s = VariablePool::getInstance().get_name(v);
395  varmap.add(s, v);
396  }
397 
398 private:
399  enum Operation { ADD, SUB, MUL, DIV, POW, NEG };
400 
401  Variable newVariable(const std::string& s) {
402  Variable* vptr = nullptr;
403  if ((vptr = varmap.find(s)) != nullptr) {
404  return *vptr;
405  }
407  if (v != Variable::NO_VARIABLE) {
408  varmap.add(s, v);
409  return v;
410  }
411 
412  v = fresh_real_variable(s);
413  varmap.add(s, v);
414  return v;
415  }
416 
417  expr_type makeBool(bool value) {
418  if (value) {
420  } else {
422  }
423  }
424 
425  expr_type booleanBinaryExpr(const expr_type& first, const std::vector<boost::fusion::vector2<carl::FormulaType,expr_type>>& ops) {
426  expr_type res = first;
427  for (const auto& op: ops) {
428  switch (boost::fusion::at_c<0>(op)) {
429  case carl::FormulaType::AND: {
430  res = boost::apply_visitor( perform_addition(), res, boost::fusion::at_c<1>(op) );
431  break;
432  }
433  case carl::FormulaType::OR: {
434  res = boost::apply_visitor( perform_subtraction(), res, boost::fusion::at_c<1>(op) );
435  break;
436  }
438  res = boost::apply_visitor( perform_subtraction(), res, boost::fusion::at_c<1>(op) );
439  break;
440  }
441  case carl::FormulaType::IFF: {
442  res = boost::apply_visitor( perform_subtraction(), res, boost::fusion::at_c<1>(op) );
443  break;
444  }
445  }
446  }
447  return res;
448  }
449 
450  expr_type booleanUnaryExpr(const std::vector<carl::FormulaType>& ops, const expr_type& first) {
451  expr_type res = first;
452  for (const auto& op: ops) {
453  switch (op) {
454  case carl::FormulaType::NOT: {
455  res = boost::apply_visitor( perform_negate(), res );
456  break;
457  }
458  }
459  }
460  return res;
461  }
462 
463  expr_type arithmeticExpr(const expr_type& first, const std::vector<boost::fusion::vector2<Operation,expr_type>>& ops) {
464  expr_type res = first;
465  for (const auto& op: ops) {
466  switch (boost::fusion::at_c<0>(op)) {
467  case ADD: {
468  res = boost::apply_visitor( perform_addition(), res, boost::fusion::at_c<1>(op) );
469  break;
470  }
471  case SUB: {
472  res = boost::apply_visitor( perform_subtraction(), res, boost::fusion::at_c<1>(op) );
473  break;
474  }
475  case MUL: {
476  res = boost::apply_visitor( perform_multiplication(), res, boost::fusion::at_c<1>(op) );
477  break;
478  }
479  case DIV: {
480  res = boost::apply_visitor( perform_division(), res, boost::fusion::at_c<1>(op) );
481  break;
482  }
483  }
484  }
485  return res;
486  }
487 
488  expr_type powExpr(const expr_type& first, const std::vector<boost::fusion::vector2<Operation,exponent>>& ops) {
489  expr_type res = first;
490  for (const auto& op: ops) {
491  switch (boost::fusion::at_c<0>(op)) {
492  case POW: {
493  res = boost::apply_visitor( perform_power(boost::fusion::at_c<1>(op)), res );
494  break;
495  }
496  }
497  }
498  return res;
499  }
500 
501  expr_type signExpr(const std::vector<Operation>& ops, const expr_type& first) {
502  expr_type res = first;
503  for(auto op : ops) {
504  switch (op) {
505  case NEG: {
506  res = boost::apply_visitor( perform_negate(), res );
507  break;
508  }
509  default:
510  throw std::runtime_error("Unknown unary operator");
511  }
512  }
513  return res;
514  }
515 
516  qi::symbols<char, carl::FormulaType> operationNot;
517  qi::symbols<char, carl::FormulaType> operationImp;
518  qi::symbols<char, carl::FormulaType> operationIff;
519  qi::symbols<char, carl::FormulaType> operationAnd;
520  qi::symbols<char, Operation> operationShift;
521  qi::symbols<char, Operation> operationScale;
522  qi::symbols<char, Operation> operationPow;
523  qi::symbols<char, Operation> operationSign;
524  qi::symbols<char, Variable> varmap;
525 
526  qi::rule<Iterator, std::string(), Skipper> varname;
527  qi::uint_parser<exponent,10,1,-1> exponentVal;
528  qi::real_parser<CoeffType,RationalPolicies<CoeffType>> coeff;
530 
532 
536 
543 };
544 
545 }
546 }
MultivariatePolynomial< Rational > Pol
Definition: HornerTest.cpp:17
Monomial::Arg createMonomial(T &&... t)
Definition: MonomialPool.h:168
std::size_t exponent
Type of an exponent.
Definition: Monomial.h:29
cln::cl_RA reciprocal(const cln::cl_RA &a)
Definition: operations.h:546
Interval< Number > exp(const Interval< Number > &i)
Definition: Exponential.h:10
Variable fresh_real_variable() noexcept
Definition: VariablePool.h:198
Interval< Number > pow(const Interval< Number > &i, Integer exp)
Definition: Power.h:11
boost::spirit::qi::space_type Skipper
Definition: Common.h:34
std::string::const_iterator Iterator
Definition: Common.h:33
boost::variant< typename Pol::CoeffType, carl::Variable, carl::Monomial::Arg, carl::Term< typename Pol::CoeffType >, Pol, RationalFunction< Pol >, carl::Formula< Pol > > ExpressionType
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
static const Variable NO_VARIABLE
Instance of an invalid variable.
Definition: Variable.h:203
std::string get_name(Variable v, bool variableName=true) const
Get a human-readable name for the given variable.
Variable find_variable_with_name(const std::string &name) const noexcept
Searches in the friendly names list for a variable with the given name.
std::shared_ptr< const Monomial > Arg
Definition: Monomial.h:62
Represents a single term, that is a numeric coefficient and a monomial.
Definition: Term.h:23
static VariablePool & getInstance()
Returns the single instance of this class by reference.
Definition: Singleton.h:45
Represent an SMT formula, which can be an atom for some background theory or a boolean combination of...
Definition: Formula.h:47
qi::symbols< char, Operation > operationShift
qi::symbols< char, carl::FormulaType > operationImp
qi::rule< Iterator, expr_type(), Skipper > expr_power
qi::rule< Iterator, Operation(), Skipper > operationScaleLA
expr_type booleanUnaryExpr(const std::vector< carl::FormulaType > &ops, const expr_type &first)
qi::symbols< char, Variable > varmap
expr_type signExpr(const std::vector< Operation > &ops, const expr_type &first)
qi::rule< Iterator, expr_type(), Skipper > atom
qi::rule< Iterator, expr_type(), Skipper > monomial
Variable newVariable(const std::string &s)
qi::real_parser< CoeffType, RationalPolicies< CoeffType > > coeff
qi::symbols< char, Operation > operationSign
expr_type arithmeticExpr(const expr_type &first, const std::vector< boost::fusion::vector2< Operation, expr_type >> &ops)
qi::rule< Iterator, expr_type(), Skipper > boolean
expr_type booleanBinaryExpr(const expr_type &first, const std::vector< boost::fusion::vector2< carl::FormulaType, expr_type >> &ops)
qi::symbols< char, carl::FormulaType > operationNot
qi::rule< Iterator, expr_type(), Skipper > expr
qi::rule< Iterator, expr_type(), Skipper > expr_sum
qi::rule< Iterator, expr_type(), Skipper > main
expr_type powExpr(const expr_type &first, const std::vector< boost::fusion::vector2< Operation, exponent >> &ops)
qi::symbols< char, carl::FormulaType > operationIff
qi::symbols< char, Operation > operationPow
qi::uint_parser< exponent, 10, 1,-1 > exponentVal
qi::rule< Iterator, expr_type(), Skipper > expr_product
qi::rule< Iterator, std::string(), Skipper > varname
qi::symbols< char, carl::FormulaType > operationAnd
qi::rule< Iterator, Variable(), Skipper > variable
qi::symbols< char, Operation > operationScale
qi::rule< Iterator, expr_type(), Skipper > expr_sign
expr_type operator()(const RatFun< Pol > &lhs, const Monomial::Arg &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const RatFun< Pol > &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const RatFun< Pol > &rhs) const
expr_type operator()(const T &lhs, const U &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const Formula< Pol > &rhs) const
expr_type operator()(const CoeffType &lhs, const CoeffType &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const Term< CoeffType > &rhs) const
expr_type operator()(const Formula< Pol > &lhs, const T &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const RatFun< Pol > &lhs, const T &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const Formula< Pol > &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const Monomial::Arg &rhs) const
expr_type operator()(const T &lhs, const U &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const RatFun< Pol > &rhs) const
expr_type operator()(const Formula< Pol > &lhs, const T &rhs) const
expr_type operator()(const CoeffType &lhs, const CoeffType &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const RatFun< Pol > &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const RatFun< Pol > &lhs, const T &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const Term< CoeffType > &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const U &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const Monomial::Arg &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const RatFun< Pol > &rhs) const
expr_type operator()(const Formula< Pol > &lhs, const T &rhs) const
expr_type operator()(const Term< CoeffType > &lhs, const RatFun< Pol > &rhs) const
expr_type operator()(const Monomial::Arg &lhs, const RatFun< Pol > &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const Formula< Pol > &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const Term< CoeffType > &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const RatFun< Pol > &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const CoeffType &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const RatFun< Pol > &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const U &rhs) const
expr_type operator()(const Formula< Pol > &lhs, const T &rhs) const
expr_type operator()(const RatFun< Pol > &lhs, const Term< CoeffType > &rhs) const
std::enable_if<!std::is_base_of< Formula< Pol >, T >::value, expr_type >::type operator()(const RatFun< Pol > &lhs, const T &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const CoeffType &coeff) const
expr_type operator()(const RatFun< Pol > &lhs, const Monomial::Arg &rhs) const
std::enable_if<!std::is_same< Formula< Pol >, T >::value, expr_type >::type operator()(const T &lhs, const Formula< Pol > &rhs) const
expr_type operator()(const Formula< Pol > &lhs) const
expr_type operator()(const Monomial::Arg &lhs) const
expr_type operator()(const RatFun< Pol > &lhs) const
expr_type operator()(const Variable &lhs) const
expr_type operator()(const CoeffType &lhs) const
expr_type operator()(const Formula< Pol > &lhs) const
void operator()(const Monomial::Arg &expr) const
void operator()(const Formula< Pol > &expr) const
void operator()(const Term< CoeffType > &expr) const
void operator()(const RatFun< Pol > &expr) const