Subject: Getting Started with Rule-based Programming
From: Robert Dodier
Date: Mon, 7 Dec 2009 23:01:07 -0700
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