[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: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20080715/445e998f/attachment.sig 


More information about the GiNaC-devel mailing list