X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fbasic.cpp;h=90b9c1452baa6828788f51764275e161db2fbcd3;hp=a92dd9ede24b8e7f2ae37657aa3e082b031c7115;hb=1067e394af3446a2fc9be1eee3a54fe422247907;hpb=1568d5f7d33270931371be997f90ea7ab2fe0ef0 diff --git a/ginac/basic.cpp b/ginac/basic.cpp index a92dd9ed..90b9c145 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -33,6 +33,7 @@ #include "symbol.h" #include "lst.h" #include "ncmul.h" +#include "relational.h" #include "print.h" #include "archive.h" #include "utils.h" @@ -154,6 +155,12 @@ void basic::dbgprinttree(void) const this->print(print_tree(std::cerr)); } +/** Return relative operator precedence (for parenthizing output). */ +unsigned basic::precedence(void) const +{ + return 70; +} + /** Create a new copy of this on the heap. One can think of this as simulating * a virtual copy constructor which is needed for instance by the refcounted * construction of an ex from a basic. */ @@ -206,14 +213,15 @@ ex basic::operator[](int i) const return op(i); } -/** Search ocurrences. An object 'has' an expression if it is the expression +/** Search ocurrences. An object 'has' an expression if it is the expression * itself or one of the children 'has' it. As a consequence (according to * the definition of children) given e=x+y+z, e.has(x) is true but e.has(x+y) - * is false. */ + * is false. The expression can also contain wildcards. */ bool basic::has(const ex & other) const { GINAC_ASSERT(other.bp!=0); - if (is_equal(*other.bp)) return true; + lst repl_lst; + if (match(*other.bp, repl_lst)) return true; if (nops()>0) { for (unsigned i=0; itinfo()) + return false; + + // Number of subexpressions must match + if (nops() != pattern.nops()) + return false; + + // No subexpressions? Then just compare the objects (there can't be + // wildcards in the pattern) + if (nops() == 0) + return is_equal(*pattern.bp); + + // Otherwise the subexpressions must match one-to-one + for (unsigned i=0; isubs(repl_lst, true); // avoid infinite recursion when re-substituting the wildcards + } } return *this; @@ -529,10 +603,10 @@ ex basic::expand(unsigned options) const * replacement arguments: 1) a relational like object==ex and 2) a list of * relationals lst(object1==ex1,object2==ex2,...), which is converted to * subs(lst(object1,object2,...),lst(ex1,ex2,...)). */ -ex basic::subs(const ex & e) const +ex basic::subs(const ex & e, bool no_pattern) const { if (e.info(info_flags::relation_equal)) { - return subs(lst(e)); + return subs(lst(e), no_pattern); } if (!e.info(info_flags::list)) { throw(std::invalid_argument("basic::subs(ex): argument must be a list")); @@ -542,12 +616,12 @@ ex basic::subs(const ex & e) const for (unsigned i=0; i