[GiNaC-devel] [PATCH] match: don't modify subexpression list if expression doesn't match the pattern.
Alexei Sheplyakov
varg at theor.jinr.ru
Tue Jul 15 19:11:23 CEST 2008
As of now the match() method modifies the list of matched subexpressions
(its second argument) even if the expression in question does not match
the pattern. Thus, this simple program
#include <iostream>
#include <ginac/ginac.h>
using namespace GiNaC;
int main(int argc, char** argv)
{
symbol x;
ex e = pow(x, 5);
ex pattern = pow(wild(), -1);
lst repl;
bool test = e.match(pattern, repl);
std::cout << "repl = " << repl << std::endl;
}
prints
repl = {x}
Such behaviour is a bit unexpected. Sometimes it confuses even GiNaC
developers, see e.g.
http://www.ginac.de/pipermail/ginac-devel/2006-April/000942.html
Hence this patch. Now the above program prints
repl = {}
as expected.
---
doc/tutorial/ginac.texi | 5 +----
ginac/basic.cpp | 8 +++++++-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi
index 555b2d6..05fdca4 100644
--- a/doc/tutorial/ginac.texi
+++ b/doc/tutorial/ginac.texi
@@ -4420,10 +4420,7 @@ This function returns @code{true} when the expression matches the pattern
and @code{false} if it doesn't. If used in the second form, the actual
subexpressions matched by the wildcards get returned in the @code{repls}
object as a list of relations of the form @samp{wildcard == expression}.
-If @code{match()} returns false, the state of @code{repls} is undefined.
-For reproducible results, the list should be empty when passed to
- at code{match()}, but it is also possible to find similarities in multiple
-expressions by passing in the result of a previous match.
+If @code{match()} returns false, @code{repls} remains unmodified.
The matching algorithm works as follows:
diff --git a/ginac/basic.cpp b/ginac/basic.cpp
index a3de04a..7a0633d 100644
--- a/ginac/basic.cpp
+++ b/ginac/basic.cpp
@@ -585,12 +585,18 @@ bool basic::match(const ex & pattern, lst & repl_lst) const
if (!match_same_type(ex_to<basic>(pattern)))
return false;
+ // Even if the expression does not match the pattern, some of
+ // its subexpressions could match it. For example, x^5*y^(-1)
+ // does not match the pattern $0^5, but its subexpression x^5
+ // does. So, save repl_lst in order to not add bogus entries.
+ lst tmp_repl = repl_lst;
// Otherwise the subexpressions must match one-to-one
for (size_t i=0; i<nops(); i++)
- if (!op(i).match(pattern.op(i), repl_lst))
+ if (!op(i).match(pattern.op(i), tmp_repl))
return false;
// Looks similar enough, match found
+ repl_lst = tmp_repl;
return true;
}
}
--
1.5.6
--
All science is either physics or stamp collecting.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
URL: <http://www.ginac.de/pipermail/ginac-devel/attachments/20080715/445e998f/attachment.sig>
More information about the GiNaC-devel
mailing list