basic.h
Go to the documentation of this file.
1 
11 #ifndef SYMENGINE_BASIC_H
12 #define SYMENGINE_BASIC_H
13 
14 // Include all C++ headers here
15 #include <sstream>
16 #include <typeinfo>
17 #include <map>
18 #include <vector>
19 #include <set>
20 #include <unordered_map>
21 #include <unordered_set>
22 #include <cassert>
23 #include <cmath>
24 #include <complex>
25 #include <vector>
26 #include <type_traits>
27 #include <functional>
28 #include <algorithm>
29 
30 #include <symengine/symengine_config.h>
31 #include <symengine/symengine_exception.h>
32 
33 #ifdef WITH_SYMENGINE_THREAD_SAFE
34 #include <atomic>
35 #endif
36 
37 #include <symengine/dict.h>
38 
40 namespace SymEngine
41 {
42 
43 enum TypeID {
44 #define SYMENGINE_INCLUDE_ALL
45 #define SYMENGINE_ENUM(type, Class) type,
46 #include "symengine/type_codes.inc"
47 #undef SYMENGINE_ENUM
48 #undef SYMENGINE_INCLUDE_ALL
53 };
54 
55 #include "basic-methods.inc"
56 
57 class Visitor;
58 class Symbol;
59 
94 class Basic : public EnableRCPFromThis<Basic>
95 {
96 private:
98 // The hash_ is defined as mutable, because its value is initialized to 0
99 // in the constructor and then it can be changed in Basic::hash() to the
100 // current hash (which is always the same for the given instance). The
101 // state of the instance does not change, so we define hash_ as mutable.
102 #if defined(WITH_SYMENGINE_THREAD_SAFE)
103  mutable std::atomic<hash_t> hash_; // This holds the hash value
104 #else
105  mutable hash_t hash_; // This holds the hash value
106 #endif // WITH_SYMENGINE_THREAD_SAFE
107 public:
108 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
109  virtual TypeID get_type_code() const = 0;
110 #else
111  TypeID type_code_;
112  inline TypeID get_type_code() const
113  {
114  return type_code_;
115  };
116 #endif
118  Basic() : hash_{0} {}
119  // Destructor must be explicitly defined as virtual here to avoid problems
120  // with undefined behavior while deallocating derived classes.
121  virtual ~Basic() {}
122 
124  Basic(const Basic &) = delete;
126  Basic &operator=(const Basic &) = delete;
127 
129  Basic(Basic &&) = delete;
131  Basic &operator=(Basic &&) = delete;
132 
138  virtual hash_t __hash__() const = 0;
139 
151  hash_t hash() const;
152 
163  virtual bool __eq__(const Basic &o) const = 0;
164 
166  bool __neq__(const Basic &o) const;
167 
169  int __cmp__(const Basic &o) const;
170 
176  virtual int compare(const Basic &o) const = 0;
177 
180  std::string __str__() const;
181 
183  RCP<const Basic> subs(const map_basic_basic &subs_dict) const;
184 
185  RCP<const Basic> xreplace(const map_basic_basic &subs_dict) const;
186 
188  virtual RCP<const Basic> expand_as_exp() const
189  {
190  throw NotImplementedError("Not Implemented");
191  }
192 
194  virtual vec_basic get_args() const = 0;
195 
196  SYMENGINE_INCLUDE_METHODS(= 0;)
197 
198  RCP<const Basic> diff(const RCP<const Symbol> &x, bool cache = true) const;
199 };
200 
202 struct RCPBasicHash {
204  size_t operator()(const RCP<const Basic> &k) const
205  {
206  return static_cast<size_t>(k->hash());
207  }
208 };
209 
213  bool operator()(const RCP<const Basic> &x, const RCP<const Basic> &y) const
214  {
215  return eq(*x, *y);
216  }
217 };
218 
222  bool operator()(const RCP<const Basic> &x, const RCP<const Basic> &y) const
223  {
224  hash_t xh = x->hash(), yh = y->hash();
225  if (xh != yh)
226  return xh < yh;
227  if (eq(*x, *y))
228  return false;
229  return x->__cmp__(*y) == -1;
230  }
231 };
232 
233 enum tribool { indeterminate = -1, trifalse = 0, tritrue = 1 };
234 
235 inline bool is_true(tribool x);
236 inline bool is_false(tribool x);
237 inline bool is_indeterminate(tribool x);
238 inline tribool and_tribool(tribool a, tribool b);
239 inline tribool not_tribool(tribool a);
240 inline tribool andwk_tribool(tribool a, tribool b);
241 
242 // Convenience functions
244 bool eq(const Basic &a, const Basic &b);
245 
247 bool neq(const Basic &a, const Basic &b);
248 
252 template <class T>
253 bool is_a(const Basic &b);
254 
256 bool is_a_Atom(const Basic &b);
257 
264 template <class T>
265 bool is_a_sub(const Basic &b);
266 
268 bool is_same_type(const Basic &a, const Basic &b);
269 
271 RCP<const Basic> expand(const RCP<const Basic> &self, bool deep = true);
272 void as_numer_denom(const RCP<const Basic> &x,
273  const Ptr<RCP<const Basic>> &numer,
274  const Ptr<RCP<const Basic>> &denom);
275 
276 void as_real_imag(const RCP<const Basic> &x, const Ptr<RCP<const Basic>> &real,
277  const Ptr<RCP<const Basic>> &imag);
278 
279 RCP<const Basic> rewrite_as_exp(const RCP<const Basic> &x);
280 RCP<const Basic> rewrite_as_sin(const RCP<const Basic> &x);
281 RCP<const Basic> rewrite_as_cos(const RCP<const Basic> &x);
282 
283 // Common subexpression elimination of symbolic expressions
284 // Return a vector of replacement pairs and a vector of reduced exprs
285 void cse(vec_pair &replacements, vec_basic &reduced_exprs,
286  const vec_basic &exprs);
287 
295 
311 template <class T>
312 void hash_combine(hash_t &seed, const T &v);
313 
314 const char *get_version();
315 
316 } // namespace SymEngine
317 
318 namespace std
319 {
321 template <>
322 struct hash<SymEngine::Basic>;
323 } // namespace std
324 
326 #include "basic-inl.h"
327 
328 // Macro to define the type_code_id variable and its getter method
329 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
330 #define IMPLEMENT_TYPEID(SYMENGINE_ID) \
331  \
332  const static TypeID type_code_id = SYMENGINE_ID; \
333  \
334  virtual TypeID get_type_code() const \
335  { \
336  return type_code_id; \
337  }; \
338  SYMENGINE_INCLUDE_METHODS(;)
339 #else
340 #define IMPLEMENT_TYPEID(SYMENGINE_ID) \
341  \
342  const static TypeID type_code_id = SYMENGINE_ID; \
343  SYMENGINE_INCLUDE_METHODS(;)
344 #endif
345 
346 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
347 #define SYMENGINE_ASSIGN_TYPEID()
348 #else
349 #define SYMENGINE_ASSIGN_TYPEID() this->type_code_ = type_code_id;
350 #endif
351 
352 #endif
The lowest unit of symbolic representation.
Definition: basic.h:95
bool __neq__(const Basic &o) const
true if this is not equal to o.
Definition: basic-inl.h:15
Basic(Basic &&)=delete
Delete the move constructor and assignment.
Basic()
Constructor.
Definition: basic.h:118
virtual RCP< const Basic > expand_as_exp() const
expands the special function in terms of exp function
Definition: basic.h:188
virtual vec_basic get_args() const =0
Returns the list of arguments.
RCP< const Basic > subs(const map_basic_basic &subs_dict) const
Substitutes 'subs_dict' into 'self'.
Definition: basic.cpp:27
Basic & operator=(const Basic &)=delete
Assignment operator in continuation with above.
std::string __str__() const
Definition: basic.cpp:22
Basic(const Basic &)=delete
Delete the copy constructor and assignment.
virtual bool __eq__(const Basic &o) const =0
Test equality.
virtual hash_t __hash__() const =0
hash_t hash_
Private variables.
Definition: basic.h:105
int __cmp__(const Basic &o) const
Comparison operator.
Definition: basic.cpp:7
virtual int compare(const Basic &o) const =0
Basic & operator=(Basic &&)=delete
Assignment operator in continuation with above.
hash_t hash() const
Definition: basic-inl.h:7
Main namespace for SymEngine package.
Definition: add.cpp:19
bool is_a_sub(const Basic &b)
Definition: basic-inl.h:42
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
void hash_combine(hash_t &seed, const T &v)
Definition: basic-inl.h:137
bool is_a(const Basic &b)
Templatised version to check is_a type.
Definition: basic-inl.h:36
TypeID
Definition: basic.h:43
@ TypeID_Count
Definition: basic.h:52
bool is_a_Atom(const Basic &b)
Returns true if b is an atom. i.e. b.get_args returns an empty vector.
Definition: basic.cpp:42
bool is_same_type(const Basic &a, const Basic &b)
Returns true if a and b are exactly the same type T.
Definition: basic-inl.h:47
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
Definition: basic-inl.h:29
RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self
Definition: expand.cpp:369
std::ostream & operator<<(std::ostream &out, const SymEngine::Basic &p)
<< Operator
Definition: basic-inl.h:95
STL namespace.
size_t operator()(const RCP< const Basic > &k) const
Returns the hashed value.
Definition: basic.h:204
Our comparison (==)
Definition: basic.h:211
bool operator()(const RCP< const Basic > &x, const RCP< const Basic > &y) const
Comparison Operator ==
Definition: basic.h:213
Our less operator (<):
Definition: basic.h:220
bool operator()(const RCP< const Basic > &x, const RCP< const Basic > &y) const
true if x < y, false otherwise
Definition: basic.h:222