6 #ifndef SYMENGINE_VISITOR_H
7 #define SYMENGINE_VISITOR_H
11 #include <symengine/polys/uexprpoly.h>
12 #include <symengine/polys/msymenginepoly.h>
14 #include <symengine/complex_mpc.h>
16 #include <symengine/series_piranha.h>
17 #include <symengine/series_flint.h>
19 #include <symengine/series_piranha.h>
25 #include <symengine/matrix.h>
26 #include <symengine/ntheory_funcs.h>
27 #include <symengine/symengine_casts.h>
28 #include <symengine/tuple.h>
29 #include <symengine/matrix_expressions.h>
38 #define SYMENGINE_ENUM(TypeID, Class) virtual void visit(const Class &) = 0;
39 #include "symengine/type_codes.inc"
46 template <
class Derived,
class Base = Visitor>
51 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8 \
52 || defined(__SUNPRO_CC))
56 template <
typename... Args,
58 = enable_if_t<std::is_constructible<Base, Args...>::value>>
59 BaseVisitor(Args &&...args) : Base(std::forward<Args>(args)...)
68 #define SYMENGINE_ENUM(TypeID, Class) \
69 virtual void visit(const Class &x) \
71 down_cast<Derived *>(this)->bvisit(x); \
73 #include "symengine/type_codes.inc"
96 Ptr<const Basic> looking_for_;
101 bool apply(
const Basic &b)
105 preorder_traversal_stop(b, *
this);
108 void bvisit(
const Basic &arg)
110 if (
eq(*looking_for_, arg)) {
126 void bvisit(
const Symbol &x)
142 void bvisit(
const Basic &x) {}
144 bool apply(
const Basic &b)
148 preorder_traversal_stop(b, *
this);
153 bool has_basic(
const Basic &b,
const Basic &x);
154 bool has_symbol(
const Basic &b,
const Basic &x);
161 RCP<const Basic> coeff_;
164 CoeffVisitor(Ptr<const Basic> x, Ptr<const Basic> n) : x_(x), n_(n) {}
166 void bvisit(
const Add &x)
169 RCP<const Number> coef = zero;
170 for (
auto &p : x.get_dict()) {
171 p.first->accept(*
this);
172 if (
neq(*coeff_, *zero)) {
176 if (
eq(*zero, *n_)) {
177 iaddnum(outArg(coef), x.
get_coef());
182 void bvisit(
const Mul &x)
184 for (
auto &p : x.get_dict()) {
185 if (
eq(*p.first, *x_) and
eq(*p.second, *n_)) {
186 map_basic_basic dict = x.get_dict();
192 if (
eq(*zero, *n_) and not has_symbol(x, *x_)) {
199 void bvisit(
const Pow &x)
210 void bvisit(
const Symbol &x)
212 if (
eq(x, *x_) and
eq(*one, *n_)) {
214 }
else if (
neq(x, *x_) and
eq(*zero, *n_)) {
223 if (
eq(x, *x_) and
eq(*one, *n_)) {
225 }
else if (
neq(x, *x_) and
eq(*zero, *n_)) {
232 void bvisit(
const Basic &x)
234 if (
neq(*zero, *n_)) {
238 if (has_symbol(x, *x_)) {
245 RCP<const Basic> apply(
const Basic &b)
253 RCP<const Basic> coeff(
const Basic &b,
const Basic &x,
const Basic &n);
255 set_basic free_symbols(
const Basic &b);
259 set_basic function_symbols(
const Basic &b);
264 RCP<const Basic> result_;
269 virtual RCP<const Basic> apply(
const RCP<const Basic> &x);
271 void bvisit(
const Basic &x);
272 void bvisit(
const Add &x);
273 void bvisit(
const Mul &x);
274 void bvisit(
const Pow &x);
281 auto newarg1 = apply(farg1), newarg2 = apply(farg2);
282 if (farg1 != newarg1 or farg2 != newarg2) {
283 result_ = x.
create(newarg1, newarg2);
285 result_ = x.rcp_from_this();
293 template <
typename Derived,
typename First,
typename... Rest>
295 static const bool value = std::is_base_of<First, Derived>::value
299 template <
typename Derived,
typename First>
301 static const bool value = std::is_base_of<First, Derived>::value;
304 template <
typename... Args>
311 template <
typename T,
313 void bvisit(
const T &x)
315 s.insert(x.rcp_from_this());
316 visited.insert(x.rcp_from_this());
317 bvisit((
const Basic &)x);
320 void bvisit(
const Basic &x)
322 for (
const auto &p : x.
get_args()) {
323 auto iter = visited.insert(p->rcp_from_this());
330 set_basic apply(
const Basic &b)
337 template <
typename... Args>
338 inline set_basic atoms(
const Basic &b)
341 return visitor.apply(b);
352 void apply(
const Basic &b);
353 void bvisit(
const Mul &x);
354 void bvisit(
const Add &x);
355 void bvisit(
const Pow &x);
356 void bvisit(
const Number &x);
358 void bvisit(
const Symbol &x);
360 void bvisit(
const Basic &x);
363 unsigned count_ops(
const vec_basic &a);
The base class for representing addition in symbolic expressions.
static RCP< const Basic > from_dict(const RCP< const Number > &coef, umap_basic_num &&d)
Create an appropriate instance from dictionary quickly.
static void coef_dict_add_term(const Ptr< RCP< const Number >> &coef, umap_basic_num &d, const RCP< const Number > &c, const RCP< const Basic > &term)
Updates the numerical coefficient and the dictionary.
const RCP< const Number > & get_coef() const
The lowest unit of symbolic representation.
virtual vec_basic get_args() const =0
Returns the list of arguments.
ComplexBase Class for deriving all complex classes.
RCP< T > rcp_from_this()
Get RCP<T> pointer to self (it will cast the pointer to T)
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
RCP< const Basic > get_exp() const
RCP< const Basic > get_base() const
virtual RCP< const Basic > create(const RCP< const Basic > &a, const RCP< const Basic > &b) const =0
Method to construct classes with canonicalization.
RCP< const Basic > get_arg1() const
RCP< const Basic > get_arg2() const
Main namespace for SymEngine package.
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b