Getting Started with Rule-based Programming



On 12/7/09, Conrad Schiff <gravmath at yahoo.com> wrote:

> I'm curious with learning rule-based programming in Maxima and I was looking
> for some help.  First let me say that I don't know much about rule-based
> programming.  I've checked the Maxima manual and the forums and while I find
> clues, I don't see a way to get started. My ultimate goal is to implement
> abstract rules for vectors, tensors, differential forms, and geometric
> algebra but I would settle initially for implementing the rules for
> quaternions.  Is this a feasible thing to do in Maxima?  If so, how does one
> start and what sources can one use to learn?

Well, in Maxima at least, it's conceptually simple.

The Maxima simplifier attempts to detect expressions which match
a pattern, and if there is a match, the expression is replaced with
some other stuff. The pattern and its replacement are specified by
tellsimp and friends (tellsimpafter, defrule, defmatch).
What constitutes a successful match is governed by matchdeclare.

There are various complications. e.g. "+" and "*" are handled
differently because they are commutative, n-ary operators, but
only by tellsimpafter (not by tellsimp), and other commutative
or n-ary operators are not handled the same.

By rules for quaternions, I guess you mean the following.

tellsimpafter (i . j . k, -1);
tellsimp (i . i, -1);
tellsimp (i . j, k);
tellsimp (i . k, -j);
tellsimp (j . i, -k);
tellsimp (j . j, -1);
tellsimp (j . k, i);
tellsimp (k . i, j);
tellsimp (k . j, -i);
tellsimp (k . k, -1);

Since only literal symbols are involved (i, j, and k)
there is no need for matchdeclare here.

Now we get stuff like this:

expand ((i + j + k)^^2);
 => -3
expand ((i - 2*j - k) . (-5*i + j + k));
 => -9*k+4*j-i+8
expand ((a*i - b*j) . (j - c*k));
 => (b*j) . (c*k)-(b*j) . j-(a*i) . (c*k)+(a*i) . j

Hmm. We need to convince Maxima to move a, b, c
outside the "." operator. The following is a little obscure,
sorry about that.

declare ([a, b, c], scalar);
dotscrules : true;

expand ((a*i - b*j) . (j - c*k));
 => a*k+a*c*j+b*c*i+b

Disclaimer: I didn't check these results.

If you can make some kind of statement like
"replace foo(a, b, c) where a, b, and c satisfy some
predicates by bar(a, b, c)" then we can probably smash
it into Maxima's pattern matching machinery somehow.

I think the reference manual entries for matchdeclare and
tellsimpafter have some examples.

HTH

Robert Dodier