Hello,
> I quite new to Maxima and I have a problem with the defrule function.
> I'm just testing out what's possible and what not.
That's very admirable. Keep up the good work.
> For example, I want to replace log(a*b) with log(a)*log(b) or with
> log(a)+log(b).
> I've tried it the following code:
> matchdeclare(a,true);
> matchdeclare(b,true);
>
> defrule(r1, log(a*b), log(a)*log(b)); in the first case or
> defrule(r2, log(a*b), log(a)+log(b)); in the second case.
Some notes: (1) the pattern matcher treats + and * specially:
when it sees a * something in a pattern it matches a to the product
of all arguments of * which match a. E.g. matchdeclare (a, atom);
=> a matches the product of all atoms. Likewise for a + something.
(2) the pattern matcher is greedy. In a pattern like a*b, when a and b
are declared the same, one of them will never get matched to anything
(the other will get all the matches).
Here's something that seems to work. I'm sorry that this is
probably not obvious. The main idea is to look for "any product"
and not "a product of 2 terms". The inflag stuff is to help recognize
stuff like a * b / c as the product of a, b, and 1/c.
matchdeclare (a, timesp);
timesp (e) := not atom(e) and block ([inflag : true], op(e)) = "*";
defrule (r, log (a), apply ("+", map (log, block ([inflag : true], args (a)))));
apply1 (log (x), r);
apply1 (log (x*y), r);
apply1 (log (3*x/y/z), r);
HTH
Robert Dodier