Soft boxes ... or: how to parenthesize for fun and profit



Users often want to parenthesize expressions in ways that aren't simplified
according to Maxima's general simplifier, e.g.

       1 + (x?2 - 1)

so that they can then do map(factor,...) -- or simply to show a
step-by-step derivation.

Here's a simple way of doing this using my contrib package 'simplifying':

*load(simplifying)$*

*softbox_op : verbify("(")$      *
*     /* reuse the existing paren operator */*
*simplifying(softbox_op,lambda([[expr]],*
*        if ?substp then softbox(resimplify(last(expr))) else last(expr)))$
*
*     /* suppress **(x) => x within substpart, using special variable **?substp
*/*
*     /* '(a,b,c) formerly simplified to (a,b,c);*
*        it now simplifies to c -- which is correct if a and b are
side-effect-free */*
*softbox(expr):= simpfuncall(softbox_op,expr)$*
*     /* construct (x) with a simp flag already on it */*
*resimplify(expr) := expand(expr,0,0)$*
*     /* resimplifies everything, removing softboxes among other things */*
*remsoftbox(expr) := subst(lambda([[ex]],last(ex)),softbox_op,expr)$*

*/* removes softboxes without other resimplifications (could be more
efficient...) */*


Examples:

*     softbox(x) => (x)  ;   resimplify(%) => x*
*     softbox(x+1)-x => (x+1)-x  ;  resimplify(%) => 1*
*
*
*     ex: a*b + b*c + c*d$  => c*d + b*c + a*b*
*     factor(ex) == factorsum(ex) => unchanged*
*     ex1: substpart(softbox(piece),ex,[1,2]) => (c*d+b*c) + a*b*
*     map(factor,ex1) => c*(d+b) + a*b*
*
*
*     remsoftbox(softbox(factor(4))) => 2^2*
*     remsoftbox(softbox(5)-softbox(4)) => 1    ... doesn't suppress
simplification of outer operations*
*     resimplify(softbox(factor(4))) => 4*

Not all parentheses are soft boxes:

*box_softbox(expr) := subst('box,softbox_op,expr)$*
*     /* convert soft to hard boxes */*


Example:


*     box_softbox( (x-1)*a - softbox(x-1)*a ) => a*(x-1) - a*box(x-1)*

Now, softbox(x)-softbox(x) still simplifies to 0, and softbox(x)*softbox(x)
still simplifies to softbox(x)?2 -- just as with 'hard' boxes.  If we want to
avoid this, we can define softbox_unique, which includes a unique number in
each softbox:

*if not(numberp(softbox_counter)) then softbox_counter : 0$*
*     /* initialize only if not defined */*
*softbox_unique(expr):=simpfuncall(paren_op,softbox_counter :
softbox_counter + 1,expr)$*

This could be made less ugly by using a distinct softbox_op and hacking *
nformat* if really necessary.  Of course, with q: softbox_unique(ex)$, you
still have q-q => 0.

There are places in Maxima that resimplify unexpectedly (to me at least),
and therefore don't preserve softboxes.  For example, factor(softbox(4)) =>
2^2, not (x) or (2^2), though factor(g(4)) => g(4).

I look forward to your feedback.

              -s