On 5/7/07, Daniel Lakeland <dlakelan at street-artists.org> wrote:
> matchdeclare(aa,atom,bb,atom,cc,atom);
> tellsimpafter(laplace(signum(aa-bb),aa,cc),exp(-bb*cc)/cc);
OK, here is a partial solution. A complete solution isn't possible
due to strangeness in the pattern-matching code; sorry about that.
matchdeclare ([aa, cc], symbolp, bb, lambda ([e], not symbolp(e)));
laplace (signum (aa + bb), aa, cc);
tellsimpafter (''%, exp (bb * cc) / cc);
laplace (signum (x - a), x, s);
=> laplace(signum(x - a), x, s)
''%;
=> %e^-(a*s)/s
It turns out this formulation works but there are lots of almost-
identical ones which don't.
There are various sources of strangeness here.
(1) tellsimpafter calls internal functions PART+ and PART* to
match arguments for + and * resp. (and tellsimp calls those
functions when + or * is not the top-level operator).
PART+ and PART* attempt to match multiple actual arguments
to a single formal argument; this is what I call "argument sweep-
up matching". This works pretty well if you have mutually
exclusive argument types (e.g. base-60 numbers vs everything
else). But PART+ and PART* cannot match two formal
arguments of the same type.
(2) tellsimpafter and friends are confused about nouns and verbs.
Evaluating laplace (signum (aa + bb), aa, cc) causes laplace and
signum to be replaced by nouns. The first time
laplace (signum (x - a), x, s) is entered, laplace isn't a noun and
the rule is not invoked. The rule is invoked the 2nd time around.
(3) Subtraction x - a is simplified into x + (-1) * a so (3a) the
operator isn't minus, and (3b) the 2nd argument is no longer a
symbol.
There's more but I'll give it a rest at this point.
I'm sorry this is so confusing. I still like Maxima's rule stuff
a lot. It needs some serious work though.
As you can see some problems in the pattern-matching code
stem from special cases for built-in stuff.
My experience has been that pattern-matching is more
predictable when applied to user-defined functions.
HTH
Robert