70f84ea83ef731336f16807973c3cd19f1315d07
[ginac.git] / ginac / basic.cpp
1 /** @file basic.cpp
2  *
3  *  Implementation of GiNaC's ABC. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <iostream>
24 #include <stdexcept>
25 #ifdef DO_GINAC_ASSERT
26 #  include <typeinfo>
27 #endif
28
29 #include "basic.h"
30 #include "ex.h"
31 #include "numeric.h"
32 #include "power.h"
33 #include "symbol.h"
34 #include "lst.h"
35 #include "ncmul.h"
36 #include "relational.h"
37 #include "print.h"
38 #include "archive.h"
39 #include "utils.h"
40 #include "debugmsg.h"
41
42 namespace GiNaC {
43
44 GINAC_IMPLEMENT_REGISTERED_CLASS_NO_CTORS(basic, void)
45
46 //////////
47 // default ctor, dtor, copy ctor assignment operator and helpers
48 //////////
49
50 // public
51
52 basic::basic(const basic & other) : tinfo_key(TINFO_basic), flags(0), refcount(0)
53 {
54         debugmsg("basic copy ctor", LOGLEVEL_CONSTRUCT);
55         copy(other);
56 }
57
58 const basic & basic::operator=(const basic & other)
59 {
60         debugmsg("basic operator=", LOGLEVEL_ASSIGNMENT);
61         if (this != &other) {
62                 destroy(true);
63                 copy(other);
64         }
65         return *this;
66 }
67
68 // protected
69
70 // none (all conditionally inlined)
71
72 //////////
73 // other ctors
74 //////////
75
76 // none (all conditionally inlined)
77
78 //////////
79 // archiving
80 //////////
81
82 /** Construct object from archive_node. */
83 basic::basic(const archive_node &n, const lst &sym_lst) : flags(0), refcount(0)
84 {
85         debugmsg("basic ctor from archive_node", LOGLEVEL_CONSTRUCT);
86
87         // Reconstruct tinfo_key from class name
88         std::string class_name;
89         if (n.find_string("class", class_name))
90                 tinfo_key = find_tinfo_key(class_name);
91         else
92                 throw (std::runtime_error("archive node contains no class name"));
93 }
94
95 /** Unarchive the object. */
96 DEFAULT_UNARCHIVE(basic)
97
98 /** Archive the object. */
99 void basic::archive(archive_node &n) const
100 {
101         n.add_string("class", class_name());
102 }
103
104 //////////
105 // functions overriding virtual functions from bases classes
106 //////////
107
108 // none
109
110 //////////
111 // new virtual functions which can be overridden by derived classes
112 //////////
113
114 // public
115
116 /** Output to stream.
117  *  @param c print context object that describes the output formatting
118  *  @param level value that is used to identify the precedence or indentation
119  *               level for placing parentheses and formatting */
120 void basic::print(const print_context & c, unsigned level) const
121 {
122         debugmsg("basic print", LOGLEVEL_PRINT);
123
124         if (is_of_type(c, print_tree)) {
125
126                 c.s << std::string(level, ' ') << class_name()
127                     << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
128                     << ", nops=" << nops()
129                     << std::endl;
130                 for (unsigned i=0; i<nops(); ++i)
131                         op(i).print(c, level + static_cast<const print_tree &>(c).delta_indent);
132
133         } else
134                 c.s << "[" << class_name() << " object]";
135 }
136
137 /** Little wrapper around print to be called within a debugger.
138  *  This is needed because you cannot call foo.print(cout) from within the
139  *  debugger because it might not know what cout is.  This method can be
140  *  invoked with no argument and it will simply print to stdout.
141  *
142  *  @see basic::print */
143 void basic::dbgprint(void) const
144 {
145         this->print(std::cerr);
146         std::cerr << std::endl;
147 }
148
149 /** Little wrapper around printtree to be called within a debugger.
150  *
151  *  @see basic::dbgprint
152  *  @see basic::printtree */
153 void basic::dbgprinttree(void) const
154 {
155         this->print(print_tree(std::cerr));
156 }
157
158 /** Return relative operator precedence (for parenthizing output). */
159 unsigned basic::precedence(void) const
160 {
161         return 70;
162 }
163
164 /** Create a new copy of this on the heap.  One can think of this as simulating
165  *  a virtual copy constructor which is needed for instance by the refcounted
166  *  construction of an ex from a basic. */
167 basic * basic::duplicate() const
168 {
169         debugmsg("basic duplicate",LOGLEVEL_DUPLICATE);
170         return new basic(*this);
171 }
172
173 /** Information about the object.
174  *
175  *  @see class info_flags */
176 bool basic::info(unsigned inf) const
177 {
178         // all possible properties are false for basic objects
179         return false;
180 }
181
182 /** Number of operands/members. */
183 unsigned basic::nops() const
184 {
185         // iterating from 0 to nops() on atomic objects should be an empty loop,
186         // and accessing their elements is a range error.  Container objects should
187         // override this.
188         return 0;
189 }
190
191 /** Return operand/member at position i. */
192 ex basic::op(int i) const
193 {
194         return (const_cast<basic *>(this))->let_op(i);
195 }
196
197 /** Return modifyable operand/member at position i. */
198 ex & basic::let_op(int i)
199 {
200         throw(std::out_of_range("op() out of range"));
201 }
202
203 ex basic::operator[](const ex & index) const
204 {
205         if (is_exactly_of_type(*index.bp,numeric))
206                 return op(static_cast<const numeric &>(*index.bp).to_int());
207         
208         throw(std::invalid_argument("non-numeric indices not supported by this type"));
209 }
210
211 ex basic::operator[](int i) const
212 {
213         return op(i);
214 }
215
216 /** Search ocurrences.  An object 'has' an expression if it is the expression
217  *  itself or one of the children 'has' it.  As a consequence (according to
218  *  the definition of children) given e=x+y+z, e.has(x) is true but e.has(x+y)
219  *  is false.  The expression can also contain wildcards. */
220 bool basic::has(const ex & other) const
221 {
222         GINAC_ASSERT(other.bp!=0);
223         lst repl_lst;
224         if (match(*other.bp, repl_lst))
225                 return true;
226         for (unsigned i=0; i<nops(); i++)
227                 if (op(i).has(other))
228                         return true;
229         
230         return false;
231 }
232
233 /** Construct new expression by applying the specified function to all
234  *  sub-expressions (one level only, not recursively). */
235 ex basic::map(map_function & f) const
236 {
237         unsigned num = nops();
238         if (num == 0)
239                 return *this;
240
241         basic *copy = duplicate();
242         copy->setflag(status_flags::dynallocated);
243         copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
244         ex e(*copy);
245         for (unsigned i=0; i<num; i++)
246                 e.let_op(i) = f(e.op(i));
247         return e.eval();
248 }
249
250 /** Return degree of highest power in object s. */
251 int basic::degree(const ex & s) const
252 {
253         return 0;
254 }
255
256 /** Return degree of lowest power in object s. */
257 int basic::ldegree(const ex & s) const
258 {
259         return 0;
260 }
261
262 /** Return coefficient of degree n in object s. */
263 ex basic::coeff(const ex & s, int n) const
264 {
265         return n==0 ? *this : _ex0();
266 }
267
268 /** Sort expanded expression in terms of powers of some object(s).
269  *  @param s object(s) to sort in
270  *  @param distributed recursive or distributed form (only used when s is a list) */
271 ex basic::collect(const ex & s, bool distributed) const
272 {
273         ex x;
274         if (is_ex_of_type(s, lst)) {
275
276                 // List of objects specified
277                 if (s.nops() == 1)
278                         return collect(s.op(0));
279
280                 else if (distributed) {
281
282                         // Get lower/upper degree of all symbols in list
283                         int num = s.nops();
284                         struct sym_info {
285                                 ex sym;
286                                 int ldeg, deg;
287                                 int cnt;  // current degree, 'counter'
288                                 ex coeff; // coefficient for degree 'cnt'
289                         };
290                         sym_info *si = new sym_info[num];
291                         ex c = *this;
292                         for (int i=0; i<num; i++) {
293                                 si[i].sym = s.op(i);
294                                 si[i].ldeg = si[i].cnt = this->ldegree(si[i].sym);
295                                 si[i].deg = this->degree(si[i].sym);
296                                 c = si[i].coeff = c.coeff(si[i].sym, si[i].cnt);
297                         }
298
299                         while (true) {
300
301                                 // Calculate coeff*x1^c1*...*xn^cn
302                                 ex y = _ex1();
303                                 for (int i=0; i<num; i++) {
304                                         int cnt = si[i].cnt;
305                                         y *= power(si[i].sym, cnt);
306                                 }
307                                 x += y * si[num - 1].coeff;
308
309                                 // Increment counters
310                                 int n = num - 1;
311                                 while (true) {
312                                         si[n].cnt++;
313                                         if (si[n].cnt <= si[n].deg) {
314                                                 // Update coefficients
315                                                 ex c;
316                                                 if (n == 0)
317                                                         c = *this;
318                                                 else
319                                                         c = si[n - 1].coeff;
320                                                 for (int i=n; i<num; i++)
321                                                         c = si[i].coeff = c.coeff(si[i].sym, si[i].cnt);
322                                                 break;
323                                         }
324                                         if (n == 0)
325                                                 goto done;
326                                         si[n].cnt = si[n].ldeg;
327                                         n--;
328                                 }
329                         }
330
331 done:           delete[] si;
332
333                 } else {
334
335                         // Recursive form
336                         x = *this;
337                         for (int n=s.nops()-1; n>=0; n--)
338                                 x = x.collect(s[n]);
339                 }
340
341         } else {
342
343                 // Only one object specified
344                 for (int n=this->ldegree(s); n<=this->degree(s); ++n)
345                         x += this->coeff(s,n)*power(s,n);
346         }
347         
348         // correct for lost fractional arguments and return
349         return x + (*this - x).expand();
350 }
351
352 /** Perform automatic non-interruptive symbolic evaluation on expression. */
353 ex basic::eval(int level) const
354 {
355         // There is nothing to do for basic objects:
356         return this->hold();
357 }
358
359 /** Function object to be applied by basic::evalf(). */
360 struct evalf_map_function : public map_function {
361         int level;
362         evalf_map_function(int l) : level(l) {}
363         ex operator()(const ex & e) { return evalf(e, level); }
364 };
365
366 /** Evaluate object numerically. */
367 ex basic::evalf(int level) const
368 {
369         if (nops() == 0)
370                 return *this;
371         else {
372                 if (level == 1)
373                         return *this;
374                 else if (level == -max_recursion_level)
375                         throw(std::runtime_error("max recursion level reached"));
376                 else {
377                         evalf_map_function map_evalf(level - 1);
378                         return map(map_evalf);
379                 }
380         }
381 }
382
383 /** Function object to be applied by basic::evalm(). */
384 struct evalm_map_function : public map_function {
385         ex operator()(const ex & e) { return evalm(e); }
386 } map_evalm;
387
388 /** Evaluate sums, products and integer powers of matrices. */
389 ex basic::evalm(void) const
390 {
391         if (nops() == 0)
392                 return *this;
393         else
394                 return map(map_evalm);
395 }
396
397 /** Perform automatic symbolic evaluations on indexed expression that
398  *  contains this object as the base expression. */
399 ex basic::eval_indexed(const basic & i) const
400  // this function can't take a "const ex & i" because that would result
401  // in an infinite eval() loop
402 {
403         // There is nothing to do for basic objects
404         return i.hold();
405 }
406
407 /** Add two indexed expressions. They are guaranteed to be of class indexed
408  *  (or a subclass) and their indices are compatible. This function is used
409  *  internally by simplify_indexed().
410  *
411  *  @param self First indexed expression; it's base object is *this
412  *  @param other Second indexed expression
413  *  @return sum of self and other 
414  *  @see ex::simplify_indexed() */
415 ex basic::add_indexed(const ex & self, const ex & other) const
416 {
417         return self + other;
418 }
419
420 /** Multiply an indexed expression with a scalar. This function is used
421  *  internally by simplify_indexed().
422  *
423  *  @param self Indexed expression; it's base object is *this
424  *  @param other Numeric value
425  *  @return product of self and other
426  *  @see ex::simplify_indexed() */
427 ex basic::scalar_mul_indexed(const ex & self, const numeric & other) const
428 {
429         return self * other;
430 }
431
432 /** Try to contract two indexed expressions that appear in the same product. 
433  *  If a contraction exists, the function overwrites one or both of the
434  *  expressions and returns true. Otherwise it returns false. It is
435  *  guaranteed that both expressions are of class indexed (or a subclass)
436  *  and that at least one dummy index has been found. This functions is
437  *  used internally by simplify_indexed().
438  *
439  *  @param self Pointer to first indexed expression; it's base object is *this
440  *  @param other Pointer to second indexed expression
441  *  @param v The complete vector of factors
442  *  @return true if the contraction was successful, false otherwise
443  *  @see ex::simplify_indexed() */
444 bool basic::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
445 {
446         // Do nothing
447         return false;
448 }
449
450 /** Check whether the expression matches a given pattern. For every wildcard
451  *  object in the pattern, an expression of the form "wildcard == matching_expression"
452  *  is added to repl_lst. */
453 bool basic::match(const ex & pattern, lst & repl_lst) const
454 {
455 /*
456         Sweet sweet shapes, sweet sweet shapes,
457         That's the key thing, right right.
458         Feed feed face, feed feed shapes,
459         But who is the king tonight?
460         Who is the king tonight?
461         Pattern is the thing, the key thing-a-ling,
462         But who is the king of pattern?
463         But who is the king, the king thing-a-ling,
464         Who is the king of Pattern?
465         Bog is the king, the king thing-a-ling,
466         Bog is the king of Pattern.
467         Ba bu-bu-bu-bu bu-bu-bu-bu-bu-bu bu-bu
468         Bog is the king of Pattern.
469 */
470
471         if (is_ex_exactly_of_type(pattern, wildcard)) {
472
473                 // Wildcard matches anything, but check whether we already have found
474                 // a match for that wildcard first (if so, it the earlier match must
475                 // be the same expression)
476                 for (unsigned i=0; i<repl_lst.nops(); i++) {
477                         if (repl_lst.op(i).op(0).is_equal(pattern))
478                                 return is_equal(*repl_lst.op(i).op(1).bp);
479                 }
480                 repl_lst.append(pattern == *this);
481                 return true;
482
483         } else {
484
485                 // Expression must be of the same type as the pattern
486                 if (tinfo() != pattern.bp->tinfo())
487                         return false;
488
489                 // Number of subexpressions must match
490                 if (nops() != pattern.nops())
491                         return false;
492
493                 // No subexpressions? Then just compare the objects (there can't be
494                 // wildcards in the pattern)
495                 if (nops() == 0)
496                         return is_equal(*pattern.bp);
497
498                 // Otherwise the subexpressions must match one-to-one
499                 for (unsigned i=0; i<nops(); i++)
500                         if (!op(i).match(pattern.op(i), repl_lst))
501                                 return false;
502
503                 // Looks similar enough, match found
504                 return true;
505         }
506 }
507
508 /** Substitute a set of objects by arbitrary expressions. The ex returned
509  *  will already be evaluated. */
510 ex basic::subs(const lst & ls, const lst & lr, bool no_pattern) const
511 {
512         GINAC_ASSERT(ls.nops() == lr.nops());
513
514         if (no_pattern) {
515                 for (unsigned i=0; i<ls.nops(); i++) {
516                         if (is_equal(*ls.op(i).bp))
517                                 return lr.op(i);
518                 }
519         } else {
520                 for (unsigned i=0; i<ls.nops(); i++) {
521                         lst repl_lst;
522                         if (match(*ls.op(i).bp, repl_lst))
523                                 return lr.op(i).bp->subs(repl_lst, true); // avoid infinite recursion when re-substituting the wildcards
524                 }
525         }
526
527         return *this;
528 }
529
530 /** Default interface of nth derivative ex::diff(s, n).  It should be called
531  *  instead of ::derivative(s) for first derivatives and for nth derivatives it
532  *  just recurses down.
533  *
534  *  @param s symbol to differentiate in
535  *  @param nth order of differentiation
536  *  @see ex::diff */
537 ex basic::diff(const symbol & s, unsigned nth) const
538 {
539         // trivial: zeroth derivative
540         if (nth==0)
541                 return ex(*this);
542         
543         // evaluate unevaluated *this before differentiating
544         if (!(flags & status_flags::evaluated))
545                 return ex(*this).diff(s, nth);
546         
547         ex ndiff = this->derivative(s);
548         while (!ndiff.is_zero() &&    // stop differentiating zeros
549                nth>1) {
550                 ndiff = ndiff.diff(s);
551                 --nth;
552         }
553         return ndiff;
554 }
555
556 /** Return a vector containing the free indices of an expression. */
557 exvector basic::get_free_indices(void) const
558 {
559         return exvector(); // return an empty exvector
560 }
561
562 ex basic::simplify_ncmul(const exvector & v) const
563 {
564         return simplified_ncmul(v);
565 }
566
567 // protected
568
569 /** Function object to be applied by basic::derivative(). */
570 struct derivative_map_function : public map_function {
571         const symbol &s;
572         derivative_map_function(const symbol &sym) : s(sym) {}
573         ex operator()(const ex & e) { return diff(e, s); }
574 };
575
576 /** Default implementation of ex::diff(). It maps the operation on the
577  *  operands (or returns 0 when the object has no operands).
578  *
579  *  @see ex::diff */
580 ex basic::derivative(const symbol & s) const
581 {
582         if (nops() == 0)
583                 return _ex0();
584         else {
585                 derivative_map_function map_derivative(s);
586                 return map(map_derivative);
587         }
588 }
589
590 /** Returns order relation between two objects of same type.  This needs to be
591  *  implemented by each class. It may never return anything else than 0,
592  *  signalling equality, or +1 and -1 signalling inequality and determining
593  *  the canonical ordering.  (Perl hackers will wonder why C++ doesn't feature
594  *  the spaceship operator <=> for denoting just this.) */
595 int basic::compare_same_type(const basic & other) const
596 {
597         return compare_pointers(this, &other);
598 }
599
600 /** Returns true if two objects of same type are equal.  Normally needs
601  *  not be reimplemented as long as it wasn't overwritten by some parent
602  *  class, since it just calls compare_same_type().  The reason why this
603  *  function exists is that sometimes it is easier to determine equality
604  *  than an order relation and then it can be overridden. */
605 bool basic::is_equal_same_type(const basic & other) const
606 {
607         return this->compare_same_type(other)==0;
608 }
609
610 unsigned basic::return_type(void) const
611 {
612         return return_types::commutative;
613 }
614
615 unsigned basic::return_type_tinfo(void) const
616 {
617         return tinfo();
618 }
619
620 /** Compute the hash value of an object and if it makes sense to store it in
621  *  the objects status_flags, do so.  The method inherited from class basic
622  *  computes a hash value based on the type and hash values of possible
623  *  members.  For this reason it is well suited for container classes but
624  *  atomic classes should override this implementation because otherwise they
625  *  would all end up with the same hashvalue. */
626 unsigned basic::calchash(void) const
627 {
628         unsigned v = golden_ratio_hash(tinfo());
629         for (unsigned i=0; i<nops(); i++) {
630                 v = rotate_left_31(v);
631                 v ^= (const_cast<basic *>(this))->op(i).gethash();
632         }
633         
634         // mask out numeric hashes:
635         v &= 0x7FFFFFFFU;
636         
637         // store calculated hash value only if object is already evaluated
638         if (flags & status_flags::evaluated) {
639                 setflag(status_flags::hash_calculated);
640                 hashvalue = v;
641         }
642
643         return v;
644 }
645
646 /** Function object to be applied by basic::expand(). */
647 struct expand_map_function : public map_function {
648         unsigned options;
649         expand_map_function(unsigned o) : options(o) {}
650         ex operator()(const ex & e) { return expand(e, options); }
651 };
652
653 /** Expand expression, i.e. multiply it out and return the result as a new
654  *  expression. */
655 ex basic::expand(unsigned options) const
656 {
657         if (nops() == 0)
658                 return this->setflag(status_flags::expanded);
659         else {
660                 expand_map_function map_expand(options);
661                 return map(map_expand).bp->setflag(status_flags::expanded);
662         }
663 }
664
665
666 //////////
667 // non-virtual functions in this class
668 //////////
669
670 // public
671
672 /** Substitute objects in an expression (syntactic substitution) and return
673  *  the result as a new expression.  There are two valid types of
674  *  replacement arguments: 1) a relational like object==ex and 2) a list of
675  *  relationals lst(object1==ex1,object2==ex2,...), which is converted to
676  *  subs(lst(object1,object2,...),lst(ex1,ex2,...)). */
677 ex basic::subs(const ex & e, bool no_pattern) const
678 {
679         if (e.info(info_flags::relation_equal)) {
680                 return subs(lst(e), no_pattern);
681         }
682         if (!e.info(info_flags::list)) {
683                 throw(std::invalid_argument("basic::subs(ex): argument must be a list"));
684         }
685         lst ls;
686         lst lr;
687         for (unsigned i=0; i<e.nops(); i++) {
688                 ex r = e.op(i);
689                 if (!r.info(info_flags::relation_equal)) {
690                         throw(std::invalid_argument("basic::subs(ex): argument must be a list of equations"));
691                 }
692                 ls.append(r.op(0));
693                 lr.append(r.op(1));
694         }
695         return subs(ls, lr, no_pattern);
696 }
697
698 /** Compare objects to establish canonical ordering.
699  *  All compare functions return: -1 for *this less than other, 0 equal,
700  *  1 greater. */
701 int basic::compare(const basic & other) const
702 {
703         unsigned hash_this = gethash();
704         unsigned hash_other = other.gethash();
705         
706         if (hash_this<hash_other) return -1;
707         if (hash_this>hash_other) return 1;
708         
709         unsigned typeid_this = tinfo();
710         unsigned typeid_other = other.tinfo();
711         
712         if (typeid_this<typeid_other) {
713 //              std::cout << "hash collision, different types: " 
714 //                        << *this << " and " << other << std::endl;
715 //              this->print(print_tree(std::cout));
716 //              std::cout << " and ";
717 //              other.print(print_tree(std::cout));
718 //              std::cout << std::endl;
719                 return -1;
720         }
721         if (typeid_this>typeid_other) {
722 //              std::cout << "hash collision, different types: " 
723 //                        << *this << " and " << other << std::endl;
724 //              this->print(print_tree(std::cout));
725 //              std::cout << " and ";
726 //              other.print(print_tree(std::cout));
727 //              std::cout << std::endl;
728                 return 1;
729         }
730         
731         GINAC_ASSERT(typeid(*this)==typeid(other));
732         
733 //      int cmpval = compare_same_type(other);
734 //      if ((cmpval!=0) && (hash_this<0x80000000U)) {
735 //              std::cout << "hash collision, same type: " 
736 //                        << *this << " and " << other << std::endl;
737 //              this->print(print_tree(std::cout));
738 //              std::cout << " and ";
739 //              other.print(print_tree(std::cout));
740 //              std::cout << std::endl;
741 //      }
742 //      return cmpval;
743         
744         return compare_same_type(other);
745 }
746
747 /** Test for equality.
748  *  This is only a quick test, meaning objects should be in the same domain.
749  *  You might have to .expand(), .normal() objects first, depending on the
750  *  domain of your computation, to get a more reliable answer.
751  *
752  *  @see is_equal_same_type */
753 bool basic::is_equal(const basic & other) const
754 {
755         if (this->gethash()!=other.gethash())
756                 return false;
757         if (this->tinfo()!=other.tinfo())
758                 return false;
759         
760         GINAC_ASSERT(typeid(*this)==typeid(other));
761         
762         return this->is_equal_same_type(other);
763 }
764
765 // protected
766
767 /** Stop further evaluation.
768  *
769  *  @see basic::eval */
770 const basic & basic::hold(void) const
771 {
772         return this->setflag(status_flags::evaluated);
773 }
774
775 /** Ensure the object may be modified without hurting others, throws if this
776  *  is not the case. */
777 void basic::ensure_if_modifiable(void) const
778 {
779         if (this->refcount>1)
780                 throw(std::runtime_error("cannot modify multiply referenced object"));
781         clearflag(status_flags::hash_calculated);
782 }
783
784 //////////
785 // global variables
786 //////////
787
788 int max_recursion_level = 1024;
789
790 } // namespace GiNaC