RE : subst("+","-", - x);



["laurent couraud" , Tue, 26 Apr 2005 23:21:21 +0200]:
> If I call your natoms() function on "2*a+5*b" I take 4 but what I want is 2.

Because there are four parts where atomp() returns true: 2, a, 5, and b.

> And when I have a power I want that natoms give me the value of the power.
> To define more precisely the result that I want :
> 
> For simplicity and generality suppose that m, n, p, are numeric integer.
> And x1, x2, ...... xi are formal parameters or varies.
> 
> Natoms(0) => 0
> Natoms(n) => 1
> Natoms(x1) => 1
> Natoms(x1+x2) => 2
> Natoms(n*x1+m*x2) => 2
> Natoms(x1-x2) => 2
> Natoms(n*x1-m*x2) => 2
> Natoms(x1^n) => n
> Natoms(n*x1-m*x2*x3^p) => p+2

Consider this definition:

,----
| natoms(expr) :=
|   if expr = 0
|   then 0
|   else if atom(expr)
|        then
|          if symbolp(expr)
|          then 1
|          else 0
|        else
|          if nounify(inpart(expr, 0)) = nounify("^")
|          then inpart(expr, 2)
|          else apply("+", maplist(natoms, args(expr))) $
| 
| natoms(0); ==> 0 //
| natoms(1); ==> 0 //
                 ^
-----------------'
| natoms(a); ==> 1 //
| natoms(a+b); ==> 2 //
| natoms(2*a+3*b); ==> 2 //
| natoms(a-b); ==> 2 //
| natoms(2*a-3*b); ==> 2 //
| natoms(a^3); ==> 3 //
| natoms(2*a-3*b*c^4); ==> 6 //
`----

The case natoms(n) = 1 is the only one not handled correctly.  If you
really want that, you can easily implement that rule with something
like

  Natoms(expr) := if numberp(expr) then ... else natoms(expr);

or some variation on this.

> In fact with your function I have discover the function args().
> Then when I did a bad call on it I saw that it call fullmap.
> I think that fullmap is more appropriate for what I want because mapatom
> give a Boolean.

The above definition doesn't work properly for subscripts:

    natoms(x[1]); ==> 0 //
    natoms(z[a]); ==> 1 //
    natoms(z[a,b]); ==> 2 //

which is probably not what you want.  The reason is that one would
have to test for subvarp() explicitly.  (Another case illustrating my
belief that subscripts are a misfeature.)  Or use mapatom instead of
atom:

    atom(x[1]); ==> FALSE //
    mapatom(x[1]); ==> TRUE //

Regards,

Albert.