3 * Implementation of GiNaC's ABC. */
6 * GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
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.
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.
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
25 #ifdef DO_GINAC_ASSERT
36 #include "relational.h"
44 GINAC_IMPLEMENT_REGISTERED_CLASS_NO_CTORS(basic, void)
47 // default ctor, dtor, copy ctor assignment operator and helpers
52 basic::basic(const basic & other) : tinfo_key(TINFO_basic), flags(0), refcount(0)
54 debugmsg("basic copy ctor", LOGLEVEL_CONSTRUCT);
58 const basic & basic::operator=(const basic & other)
60 debugmsg("basic operator=", LOGLEVEL_ASSIGNMENT);
70 // none (all conditionally inlined)
76 // none (all conditionally inlined)
82 /** Construct object from archive_node. */
83 basic::basic(const archive_node &n, const lst &sym_lst) : flags(0), refcount(0)
85 debugmsg("basic ctor from archive_node", LOGLEVEL_CONSTRUCT);
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);
92 throw (std::runtime_error("archive node contains no class name"));
95 /** Unarchive the object. */
96 DEFAULT_UNARCHIVE(basic)
98 /** Archive the object. */
99 void basic::archive(archive_node &n) const
101 n.add_string("class", class_name());
105 // functions overriding virtual functions from bases classes
111 // new virtual functions which can be overridden by derived classes
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
122 debugmsg("basic print", LOGLEVEL_PRINT);
124 if (is_of_type(c, print_tree)) {
126 c.s << std::string(level, ' ') << class_name()
127 << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
128 << ", nops=" << nops()
130 for (unsigned i=0; i<nops(); ++i)
131 op(i).print(c, level + static_cast<const print_tree &>(c).delta_indent);
134 c.s << "[" << class_name() << " object]";
137 /** Little wrapper arount 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.
142 * @see basic::print */
143 void basic::dbgprint(void) const
145 this->print(std::cerr);
146 std::cerr << std::endl;
149 /** Little wrapper arount printtree to be called within a debugger.
151 * @see basic::dbgprint
152 * @see basic::printtree */
153 void basic::dbgprinttree(void) const
155 this->print(print_tree(std::cerr));
158 /** Return relative operator precedence (for parenthizing output). */
159 unsigned basic::precedence(void) const
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
169 debugmsg("basic duplicate",LOGLEVEL_DUPLICATE);
170 return new basic(*this);
173 /** Information about the object.
175 * @see class info_flags */
176 bool basic::info(unsigned inf) const
178 // all possible properties are false for basic objects
182 /** Number of operands/members. */
183 unsigned basic::nops() const
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
191 /** Return operand/member at position i. */
192 ex basic::op(int i) const
194 return (const_cast<basic *>(this))->let_op(i);
197 /** Return modifyable operand/member at position i. */
198 ex & basic::let_op(int i)
200 throw(std::out_of_range("op() out of range"));
203 ex basic::operator[](const ex & index) const
205 if (is_exactly_of_type(*index.bp,numeric))
206 return op(static_cast<const numeric &>(*index.bp).to_int());
208 throw(std::invalid_argument("non-numeric indices not supported by this type"));
211 ex basic::operator[](int i) const
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
222 GINAC_ASSERT(other.bp!=0);
224 if (match(*other.bp, repl_lst)) return true;
226 for (unsigned i=0; i<nops(); i++)
227 if (op(i).has(other))
234 /** Return degree of highest power in object s. */
235 int basic::degree(const ex & s) const
240 /** Return degree of lowest power in object s. */
241 int basic::ldegree(const ex & s) const
246 /** Return coefficient of degree n in object s. */
247 ex basic::coeff(const ex & s, int n) const
249 return n==0 ? *this : _ex0();
252 /** Sort expression in terms of powers of some object(s).
253 * @param s object(s) to sort in
254 * @param distributed recursive or distributed form (only used when s is a list) */
255 ex basic::collect(const ex & s, bool distributed) const
258 if (is_ex_of_type(s, lst)) {
260 // List of objects specified
262 return collect(s.op(0));
264 else if (distributed) {
266 // Get lower/upper degree of all symbols in list
271 int cnt; // current degree, 'counter'
272 ex coeff; // coefficient for degree 'cnt'
274 sym_info *si = new sym_info[num];
276 for (int i=0; i<num; i++) {
278 si[i].ldeg = si[i].cnt = this->ldegree(si[i].sym);
279 si[i].deg = this->degree(si[i].sym);
280 c = si[i].coeff = c.coeff(si[i].sym, si[i].cnt);
285 // Calculate coeff*x1^c1*...*xn^cn
287 for (int i=0; i<num; i++) {
289 y *= power(si[i].sym, cnt);
291 x += y * si[num - 1].coeff;
293 // Increment counters
297 if (si[n].cnt <= si[n].deg) {
298 // Update coefficients
304 for (int i=n; i<num; i++)
305 c = si[i].coeff = c.coeff(si[i].sym, si[i].cnt);
310 si[n].cnt = si[n].ldeg;
321 for (int n=s.nops()-1; n>=0; n--)
327 // Only one object specified
328 for (int n=this->ldegree(s); n<=this->degree(s); ++n)
329 x += this->coeff(s,n)*power(s,n);
332 // correct for lost fractional arguments and return
333 return x + (*this - x).expand();
336 /** Perform automatic non-interruptive symbolic evaluation on expression. */
337 ex basic::eval(int level) const
339 // There is nothing to do for basic objects:
343 /** Evaluate object numerically. */
344 ex basic::evalf(int level) const
346 // There is nothing to do for basic objects:
350 /** Perform automatic symbolic evaluations on indexed expression that
351 * contains this object as the base expression. */
352 ex basic::eval_indexed(const basic & i) const
353 // this function can't take a "const ex & i" because that would result
354 // in an infinite eval() loop
356 // There is nothing to do for basic objects
360 /** Add two indexed expressions. They are guaranteed to be of class indexed
361 * (or a subclass) and their indices are compatible. This function is used
362 * internally by simplify_indexed().
364 * @param self First indexed expression; it's base object is *this
365 * @param other Second indexed expression
366 * @return sum of self and other
367 * @see ex::simplify_indexed() */
368 ex basic::add_indexed(const ex & self, const ex & other) const
373 /** Multiply an indexed expression with a scalar. This function is used
374 * internally by simplify_indexed().
376 * @param self Indexed expression; it's base object is *this
377 * @param other Numeric value
378 * @return product of self and other
379 * @see ex::simplify_indexed() */
380 ex basic::scalar_mul_indexed(const ex & self, const numeric & other) const
385 /** Try to contract two indexed expressions that appear in the same product.
386 * If a contraction exists, the function overwrites one or both of the
387 * expressions and returns true. Otherwise it returns false. It is
388 * guaranteed that both expressions are of class indexed (or a subclass)
389 * and that at least one dummy index has been found. This functions is
390 * used internally by simplify_indexed().
392 * @param self Pointer to first indexed expression; it's base object is *this
393 * @param other Pointer to second indexed expression
394 * @param v The complete vector of factors
395 * @return true if the contraction was successful, false otherwise
396 * @see ex::simplify_indexed() */
397 bool basic::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
403 /** Check whether the expression matches a given pattern. For every wildcard
404 * object in the pattern, an expression of the form "wildcard == matching_expression"
405 * is added to repl_lst. */
406 bool basic::match(const ex & pattern, lst & repl_lst) const
409 Sweet sweet shapes, sweet sweet shapes,
410 Thats the key thing, right right.
411 Feed feed face, feed feed shapes,
412 But who is the king tonight?
413 Who is the king tonight?
414 Pattern is the thing, the key thing-a-ling,
415 But who is the king of pattern?
416 But who is the king, the king thing-a-ling,
417 Who is the king of Pattern?
418 Bog is the king, the king thing-a-ling,
419 Bog is the king of Pattern.
420 Ba bu-bu-bu-bu bu-bu-bu-bu-bu-bu bu-bu
421 Bog is the king of Pattern.
424 if (is_ex_exactly_of_type(pattern, wildcard)) {
426 // Wildcard matches anything, but check whether we already have found
427 // a match for that wildcard first (if so, it the earlier match must
428 // be the same expression)
429 for (unsigned i=0; i<repl_lst.nops(); i++) {
430 if (repl_lst.op(i).op(0).is_equal(pattern))
431 return is_equal(*repl_lst.op(i).op(1).bp);
433 repl_lst.append(pattern == *this);
438 // Expression must be of the same type as the pattern
439 if (tinfo() != pattern.bp->tinfo())
442 // Number of subexpressions must match
443 if (nops() != pattern.nops())
446 // No subexpressions? Then just compare the objects (there can't be
447 // wildcards in the pattern)
449 return is_equal(*pattern.bp);
451 // Otherwise the subexpressions must match one-to-one
452 for (unsigned i=0; i<nops(); i++)
453 if (!op(i).match(pattern.op(i), repl_lst))
456 // Looks similar enough, match found
461 /** Substitute a set of objects by arbitrary expressions. The ex returned
462 * will already be evaluated. */
463 ex basic::subs(const lst & ls, const lst & lr, bool no_pattern) const
465 GINAC_ASSERT(ls.nops() == lr.nops());
468 for (unsigned i=0; i<ls.nops(); i++) {
469 if (is_equal(*ls.op(i).bp))
473 for (unsigned i=0; i<ls.nops(); i++) {
475 if (match(*ls.op(i).bp, repl_lst))
476 return lr.op(i).bp->subs(repl_lst, true); // avoid infinite recursion when re-substituting the wildcards
483 /** Default interface of nth derivative ex::diff(s, n). It should be called
484 * instead of ::derivative(s) for first derivatives and for nth derivatives it
485 * just recurses down.
487 * @param s symbol to differentiate in
488 * @param nth order of differentiation
490 ex basic::diff(const symbol & s, unsigned nth) const
492 // trivial: zeroth derivative
496 // evaluate unevaluated *this before differentiating
497 if (!(flags & status_flags::evaluated))
498 return ex(*this).diff(s, nth);
500 ex ndiff = this->derivative(s);
501 while (!ndiff.is_zero() && // stop differentiating zeros
503 ndiff = ndiff.diff(s);
509 /** Return a vector containing the free indices of an expression. */
510 exvector basic::get_free_indices(void) const
512 return exvector(); // return an empty exvector
515 ex basic::simplify_ncmul(const exvector & v) const
517 return simplified_ncmul(v);
522 /** Default implementation of ex::diff(). It simply throws an error message.
524 * @exception logic_error (differentiation not supported by this type)
526 ex basic::derivative(const symbol & s) const
528 throw(std::logic_error("differentiation not supported by this type"));
531 /** Returns order relation between two objects of same type. This needs to be
532 * implemented by each class. It may never return anything else than 0,
533 * signalling equality, or +1 and -1 signalling inequality and determining
534 * the canonical ordering. (Perl hackers will wonder why C++ doesn't feature
535 * the spaceship operator <=> for denoting just this.) */
536 int basic::compare_same_type(const basic & other) const
538 return compare_pointers(this, &other);
541 /** Returns true if two objects of same type are equal. Normally needs
542 * not be reimplemented as long as it wasn't overwritten by some parent
543 * class, since it just calls compare_same_type(). The reason why this
544 * function exists is that sometimes it is easier to determine equality
545 * than an order relation and then it can be overridden. */
546 bool basic::is_equal_same_type(const basic & other) const
548 return this->compare_same_type(other)==0;
551 unsigned basic::return_type(void) const
553 return return_types::commutative;
556 unsigned basic::return_type_tinfo(void) const
561 /** Compute the hash value of an object and if it makes sense to store it in
562 * the objects status_flags, do so. The method inherited from class basic
563 * computes a hash value based on the type and hash values of possible
564 * members. For this reason it is well suited for container classes but
565 * atomic classes should override this implementation because otherwise they
566 * would all end up with the same hashvalue. */
567 unsigned basic::calchash(void) const
569 unsigned v = golden_ratio_hash(tinfo());
570 for (unsigned i=0; i<nops(); i++) {
571 v = rotate_left_31(v);
572 v ^= (const_cast<basic *>(this))->op(i).gethash();
575 // mask out numeric hashes:
578 // store calculated hash value only if object is already evaluated
579 if (flags & status_flags::evaluated) {
580 setflag(status_flags::hash_calculated);
587 /** Expand expression, i.e. multiply it out and return the result as a new
589 ex basic::expand(unsigned options) const
591 return this->setflag(status_flags::expanded);
596 // non-virtual functions in this class
601 /** Substitute objects in an expression (syntactic substitution) and return
602 * the result as a new expression. There are two valid types of
603 * replacement arguments: 1) a relational like object==ex and 2) a list of
604 * relationals lst(object1==ex1,object2==ex2,...), which is converted to
605 * subs(lst(object1,object2,...),lst(ex1,ex2,...)). */
606 ex basic::subs(const ex & e, bool no_pattern) const
608 if (e.info(info_flags::relation_equal)) {
609 return subs(lst(e), no_pattern);
611 if (!e.info(info_flags::list)) {
612 throw(std::invalid_argument("basic::subs(ex): argument must be a list"));
616 for (unsigned i=0; i<e.nops(); i++) {
618 if (!r.info(info_flags::relation_equal)) {
619 throw(std::invalid_argument("basic::subs(ex): argument must be a list of equations"));
624 return subs(ls, lr, no_pattern);
627 /** Compare objects to establish canonical ordering.
628 * All compare functions return: -1 for *this less than other, 0 equal,
630 int basic::compare(const basic & other) const
632 unsigned hash_this = gethash();
633 unsigned hash_other = other.gethash();
635 if (hash_this<hash_other) return -1;
636 if (hash_this>hash_other) return 1;
638 unsigned typeid_this = tinfo();
639 unsigned typeid_other = other.tinfo();
641 if (typeid_this<typeid_other) {
642 // std::cout << "hash collision, different types: "
643 // << *this << " and " << other << std::endl;
644 // this->print(print_tree(std::cout));
645 // std::cout << " and ";
646 // other.print(print_tree(std::cout));
647 // std::cout << std::endl;
650 if (typeid_this>typeid_other) {
651 // std::cout << "hash collision, different types: "
652 // << *this << " and " << other << std::endl;
653 // this->print(print_tree(std::cout));
654 // std::cout << " and ";
655 // other.print(print_tree(std::cout));
656 // std::cout << std::endl;
660 GINAC_ASSERT(typeid(*this)==typeid(other));
662 // int cmpval = compare_same_type(other);
663 // if ((cmpval!=0) && (hash_this<0x80000000U)) {
664 // std::cout << "hash collision, same type: "
665 // << *this << " and " << other << std::endl;
666 // this->print(print_tree(std::cout));
667 // std::cout << " and ";
668 // other.print(print_tree(std::cout));
669 // std::cout << std::endl;
673 return compare_same_type(other);
676 /** Test for equality.
677 * This is only a quick test, meaning objects should be in the same domain.
678 * You might have to .expand(), .normal() objects first, depending on the
679 * domain of your computation, to get a more reliable answer.
681 * @see is_equal_same_type */
682 bool basic::is_equal(const basic & other) const
684 if (this->gethash()!=other.gethash())
686 if (this->tinfo()!=other.tinfo())
689 GINAC_ASSERT(typeid(*this)==typeid(other));
691 return this->is_equal_same_type(other);
696 /** Stop further evaluation.
698 * @see basic::eval */
699 const basic & basic::hold(void) const
701 return this->setflag(status_flags::evaluated);
704 /** Ensure the object may be modified without hurting others, throws if this
705 * is not the case. */
706 void basic::ensure_if_modifiable(void) const
708 if (this->refcount>1)
709 throw(std::runtime_error("cannot modify multiply referenced object"));
716 int max_recursion_level = 1024;