]> www.ginac.de Git - ginac.git/blobdiff - ginac/ex.cpp
- minor shortcut.
[ginac.git] / ginac / ex.cpp
index 646053b8001a89b2619841cd038b36d760e3a8a8..b6b968595e05e662aa89e2b89c0aefd4a274fbef 100644 (file)
@@ -29,8 +29,8 @@
 #include "ncmul.h"
 #include "numeric.h"
 #include "power.h"
+#include "lst.h"
 #include "relational.h"
-#include "indexed.h"
 #include "input_lexer.h"
 #include "debugmsg.h"
 #include "utils.h"
@@ -43,18 +43,6 @@ namespace GiNaC {
 
 // none (all inlined)
 
-//////////
-// functions overriding virtual functions from bases classes
-//////////
-
-// none
-
-//////////
-// new virtual functions which can be overridden by derived classes
-//////////
-
-// none
-
 //////////
 // non-virtual functions in this class
 //////////
@@ -112,68 +100,15 @@ void ex::dbgprinttree(void) const
        bp->dbgprinttree();
 }
 
-bool ex::info(unsigned inf) const
-{
-       return bp->info(inf);
-}
-
-unsigned ex::nops() const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->nops();
-}
-
 ex ex::expand(unsigned options) const
 {
        GINAC_ASSERT(bp!=0);
-       if (bp->flags & status_flags::expanded)
+       if (options == 0 && (bp->flags & status_flags::expanded)) // The "expanded" flag only covers the standard options; someone might want to re-expand with different options
                return *bp;
        else
                return bp->expand(options);
 }
 
-bool ex::has(const ex & other) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->has(other);
-}
-
-int ex::degree(const ex & s) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->degree(s);
-}
-
-int ex::ldegree(const ex & s) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->ldegree(s);
-}
-
-ex ex::coeff(const ex & s, int n) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->coeff(s,n);
-}
-
-ex ex::collect(const ex & s, bool distributed) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->collect(s, distributed);
-}
-
-ex ex::eval(int level) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->eval(level);
-}
-
-ex ex::evalf(int level) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->evalf(level);
-}
-
 /** Compute partial derivative of an expression.
  *
  *  @param s  symbol by which the expression is derived
@@ -189,51 +124,30 @@ ex ex::diff(const symbol & s, unsigned nth) const
                return bp->diff(s, nth);
 }
 
-ex ex::subs(const lst & ls, const lst & lr) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->subs(ls,lr);
-}
-
-ex ex::subs(const ex & e) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->subs(e);
-}
-
-/** Return a vector containing the free indices of the object. */
-exvector ex::get_free_indices(void) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->get_free_indices();
-}
-
-/** Simplify/canonicalize expression containing indexed objects. This
- *  performs contraction of dummy indices where possible and checks whether
- *  the free indices in sums are consistent.
- *
- *  @return simplified expression */
-ex ex::simplify_indexed(void) const
+/** Check whether expression matches a specified pattern. */
+bool ex::match(const ex & pattern) const
 {
-       return GiNaC::simplify_indexed(*this);
+       lst repl_lst;
+       return bp->match(pattern, repl_lst);
 }
 
-/** Simplify/canonicalize expression containing indexed objects. This
- *  performs contraction of dummy indices where possible, checks whether
- *  the free indices in sums are consistent, and automatically replaces
- *  scalar products by known values if desired.
- *
- *  @param sp Scalar products to be replaced automatically
- *  @return simplified expression */
-ex ex::simplify_indexed(const scalar_products & sp) const
+/** Find all occurrences of a pattern. The found matches are appended to
+ *  the "found" list. If the expression itself matches the pattern, the
+ *  children are not further examined. This function returns true when any
+ *  matches were found. */
+bool ex::find(const ex & pattern, lst & found) const
 {
-       return GiNaC::simplify_indexed(*this, sp);
-}
-
-ex ex::simplify_ncmul(const exvector & v) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->simplify_ncmul(v);
+       if (match(pattern)) {
+               found.append(*this);
+               found.sort();
+               found.unique();
+               return true;
+       }
+       bool any_found = false;
+       for (unsigned i=0; i<nops(); i++)
+               if (op(i).find(pattern, found))
+                       any_found = true;
+       return any_found;
 }
 
 ex ex::operator[](const ex & index) const
@@ -250,14 +164,6 @@ ex ex::operator[](int i) const
        return (*bp)[i];
 }
 
-/** Return operand/member at position i. */
-ex ex::op(int i) const
-{
-       debugmsg("ex op()",LOGLEVEL_MEMBER_FUNCTION);
-       GINAC_ASSERT(bp!=0);
-       return bp->op(i);
-}
-
 /** Return modifyable operand/member at position i. */
 ex & ex::let_op(int i)
 {
@@ -271,7 +177,8 @@ ex & ex::let_op(int i)
 ex ex::lhs(void) const
 {
        debugmsg("ex lhs()",LOGLEVEL_MEMBER_FUNCTION);
-       GINAC_ASSERT(is_ex_of_type(*this,relational));
+       if (!is_ex_of_type(*this,relational))
+               throw std::runtime_error("ex::lhs(): not a relation");
        return (*static_cast<relational *>(bp)).lhs();
 }
 
@@ -279,47 +186,11 @@ ex ex::lhs(void) const
 ex ex::rhs(void) const
 {
        debugmsg("ex rhs()",LOGLEVEL_MEMBER_FUNCTION);
-       GINAC_ASSERT(is_ex_of_type(*this,relational));
+       if (!is_ex_of_type(*this,relational))
+               throw std::runtime_error("ex::rhs(): not a relation");
        return (*static_cast<relational *>(bp)).rhs();
 }
 
-unsigned ex::return_type(void) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->return_type();
-}
-
-unsigned ex::return_type_tinfo(void) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->return_type_tinfo();
-}
-
-unsigned ex::gethash(void) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->gethash();
-}
-
-/** Used internally by operator+() to add two ex objects together. */
-ex ex::exadd(const ex & rh) const
-{
-       return (new add(*this,rh))->setflag(status_flags::dynallocated);
-}
-
-/** Used internally by operator*() to multiply two ex objects together. */
-ex ex::exmul(const ex & rh) const
-{
-       // Check if we are constructing a mul object or a ncmul object.  Due to
-       // ncmul::eval()'s rule to pull out commutative elements we need to check
-       // only one of the elements.
-       if (rh.bp->return_type()==return_types::commutative ||
-           bp->return_type()==return_types::commutative)
-               return (new mul(*this,rh))->setflag(status_flags::dynallocated);
-       else
-               return (new ncmul(*this,rh))->setflag(status_flags::dynallocated);
-}
-
 // private
 
 /** Make this ex writable (if more than one ex handle the same basic) by 
@@ -343,14 +214,12 @@ void ex::makewriteable()
  *  @see ex::ex(const basic &) */
 void ex::construct_from_basic(const basic & other)
 {
-       if ((other.flags & status_flags::evaluated)==0) {
-               // cf. copy ctor
-               const ex & tmpex = other.eval(1); // evaluate only one (top) level
+       if (!(other.flags & status_flags::evaluated)) {
+               const ex & tmpex(other.eval(1)); // evaluate only one (top) level
                bp = tmpex.bp;
-               GINAC_ASSERT(bp!=0);
                GINAC_ASSERT(bp->flags & status_flags::dynallocated);
                ++bp->refcount;
-               if ((other.flags & status_flags::dynallocated)&&(other.refcount==0))
+               if ((other.refcount==0) && (other.flags & status_flags::dynallocated))
                        delete &const_cast<basic &>(other);
        } else {
                if (other.flags & status_flags::dynallocated) {