Newbie help, predicate confusion



Hi everybody!

On Tue, Dec 10, 2002 at 10:57:16PM -0500, Stavros Macrakis wrote:
> Recursion is straightforward, just like Lisp (including Scheme) or C or
> whatever, though a bit different from Haskell or Prolog.
> 
> For your example:
> 
>   filter(f,l):=
>     if l=[]
>       then []
>     elseif f(first(l))
>       then cons(first(l),filter(f,rest(l)))
>     else filter(f,rest(l));
> 
>   filter(evenp,[1,3,4,6,7,9,10]) => [4, 6, 10]

Nice!  I'm glad I can do it that way!

> You seem to have forgotten that your filter funtion is called "cond",
> not "p".  I'm afraid Maxima is not clever enough to Do What You Mean
> here (Google: DWIM). :-)

Oy.  I'm really sorry about that, a bit insulting to ask specialists
to help find those kinds of errors.  (Thanks also to Dan Stanger for
mailing me privately about this.)

> >>>>>>>>>>     Evaluating predicates <<<<<<<<<<<<
> 
> Here there is a real issue.  Remember that Maxima is a symbolic system,
> so it must have some way of representing equalities such as x^2=4 and
> inequalities such as x^2<1.  It would not do for x^2=4 to be evaluated
> immediately as either True or False.  In fact, usually it *cannot* be
> evaluated as True or False.  Similarly for inequalities.

This is sort of what I figured, but surprisingly (to me at least),
these

  filter( lambda([x], x>0), makelist(i,i,-4,4) );
  filter( lambda([x], if x>0 then true else false), makelist(i,i,-4,4) );

behave the same.  However, the following is still causing cognitive
dissonance for me:

  (C52) lambda([x], if x>0 then true else false)(a);

  MACSYMA was unable to evaluate the predicate:

  ** error while printing ERROR message **
  MACSYMA was unable to evaluate the predicate:~%~M
  #0: LAMBDA([x],IF x > 0 THEN TRUE ELSE FALSE)(x=a)
   -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);)

as opposed to

  lambda([x], x>0)(a) => (x>0)

I guess what I don't understand is the interplay and between
evaluation and simplification.  Is there an alternate form of "if"
which would work through the simplification mechanism?  So that I
could write, say

  if( x>0, x^2, 0 )

and if x happens to be free, this expression simply remains
unsimplified as a "symbolic if clause," to be possibly simplified
later given assumptions on x.

> In this case, unless you've asserted things about the value of a, it
> will give an error, since it doesn't know.  (Isn't there some way to
> force IS to ask questions, like ASKSIGN?)

Makes sense.  It almost seems like in general you want to drive
everything through simplification, rather than evaluation.

> > Ultimately, what I'd like to get working as a first use of
> > maxima is a little routine that computes the eigenvector corresponding
> > to the maximal real eigenvalue of a matrix.  Phew, it seems pretty
> > distant at this point!
> 
> Have you looked at the built-in eigenvector/eigenvalue functions?
> 
> Note that if your matrices are symbolic, eigenV's blow up very quickly.

They're integer matrices, but I don't want numerical results; I want
to compute some simple algebraic invariants for orbits of graphs as
part of a large automated Proof (that's capital p:).  So I need it to
be exact and to detect minute changes in the vector.

  filter(f,l):=
    if l=[]
      then []
    elseif f(first(l))
      then cons(first(l),filter(f,rest(l)))
      else filter(f,rest(l));

  thread(a,b):=
    makelist([a[i],b[i]], i, min(1,length(a),length(b)), min(length(a),length(b)))$

  maxby(gt,list):=
    block([max],
      max:list[1],
      for l in rest(list) do (if gt(l,max) then max:l),
      return(max))$

(Don't worry, this isn't my usual programming style, I just don't feel
that comfortable with maxima, yet...)

  maxRealEigenvector(mat):=
    block([es],
      es:eigenvectors(mat),
      maxby( lambda([a,b],a[1]>b[1]),
	filter( lambda([x], imagpart(x[1])=0),
	  thread( es[1][1], rest(es) ) ) ) [2])$


Then, for instance,

(C7) maxRealEigenvector( matrix( [2,1], [1,1] ) );
				   SQRT(5) - 1
(D7) 			       [1, -----------]
					2

Say, do you happen to know how bad the symbolic eigenvectors will be?
I've coded everything up numerically using lapack, but feel really
uneasy about using the results in for a proof.  Do you know any
references on symbolic eigenvector techniques?  (To give you an idea
of how little I know: the only computer algebra book I have is Baader
& Nipkow's "Term rewriting and all that.")

Finally, while I have you on the phone, one more can of worms about
currying.  I can define

  lpnorm(p,v) := sum(v[i]^p,i,min(1,length(v)),length(v))^(1/p)$

no problem, but I'd really like to curry it, so that I can pass around
lpnorm(2) as a norm, without the receiver having a clue about the p
parameter.  I think the problems I have boils down to the following:

(C11) lambda([a],lambda([b],a+b))(1)(2);
(D11) 				     a + 2

Does that make sense?

It does work to define lpnorm over a tuple as above and then use:

  lambda([v],lpnorm(2,v)) ([1,2]);

but that seems a bit odd.

Also, is there a function I can apply() to a list to get the sum?
Like Plus@@List in math'a?  That way, I could define something like:

  lpnorm(p,v) := apply(plus, map( lambda([x],x^p), v))^(1/p)

I'm just suspicious about defining functions with all these index
lookups on lisp lists.

Thanks so much for all your help, everyone, and especially macrakis
(I'm sorry that's all I know of your name).  It's so great to have a
gpl'd algebra system!

Thanks again,
  Carl

PS: Suppose I wanted to set up a rewrite system for regular
    expressions.  Would that be hard to do in maxima?  I've done it by
    hand before in Haskell, but it seems like most of the
    infrastructure might already exist in maxima.  Perhaps a way to
    specify new types of objects and a way to provide a list of
    rewrite rules.  Could you give any references?  Thanks.