Re: if-expression and variables

"William Sit" <[email protected]> Tue, 03 May 2011 03:04:34 -0400
Newsgroups gmane.comp.mathematics.axiom.general
Message-ID <[email protected]>
Dear Bill:

You are right. I should not have declare "It is not =

possible" (even with a qualifier) since one can program =

around the difficulties. However, what you did essentially =

defines two different piecewise function, one for numeric =

and one for symbolic, by using "interpret" and "expr". If =

you use "interpret test1(y)" you would still get the wrong =

answer,, and similarly, if you use "expr test1(3)", then =

you would not have the result evaluated. Of course, you =

can combine the two cases and again distinguish them by =

testing if the input is a symbolic expression or numeric =

(keeping it unevaluated in the first case, and evaluating =

in the second).

Your routine sub is, I believe, not full proof. If x were =

modified inside f, would a static substitution of all =

occurrences of x by y work? (isn't y bound and x is not?). =

Or if there were a local variable x that temporarily hides =

the scope of the outer x. By using f:InputForm, the dummy =

argument for f is no longer a dummy; as a function, f is =

independent of the literal used for its argument. Of =

course, we can identify the argument of f in the sub =

routine without passing it as an argument for sub.

I am sure that in lisp, you can do anything. (Tim: would =

you rise up to the challenge?) I believe Stefan's question =

is whether it can be done "intuitively" (even though he =

did not say so explicitly). Mathematica is able to provide =

that, because neither the input nor the output is =

restricted by its type. In Axiom, maybe we can do the same =

with a Union like Union(Integer, InputForm).

I did not test the above claims. Axiom may surprise me.

William


On Mon, 2 May 2011 23:57:34 -0400
  Bill Page <[email protected]> wrote:
> William,
> =

> On Mon, May 2, 2011 at 9:07 PM, you wrote to Stefan:
>> ...
>> So the answer to your question "How is it possible ..." =

>>is, "It is not
>> possible, in the context of piecewise functions." =

>>because no matter what
>> the system does, you gain no new information other than =

>>what you inputted,
>> until you let the system know what y is, numerically.
>>
> =

> I think we should be careful not to give the wrong =

>impression about
> the capabilities of Axiom. It is not quite accurate to =

>say that what
> Stefan wants to do is "impossible" in Axiom since Axiom =

>does contain
> some rather sophisticated ways of representing symbolic =

>expressions. I
> think it may be correct to claim that at the present =

>time the Axiom
> library is fundamentally "algebraic" in orientation and =

>not "symbolic"
> but the dividing line between these two views of =

>computer algebra is
> not so clear cut.
> =

> In particular, Axiom's InputForm domain represents =

>"algebraically"
> everything that can be evaluated in Axiom in purely =

>symbolic form.
> Normally this is only an intermediate representation =

>which is
> immediately evaluated by Axiom.  But with the help of a =

>simple symbol
> substitution routine like the following we can do a lot =

>more in a
> purely symbolic manner.
> =

> (1) -> sub(f:InputForm, x:Symbol, y:InputForm):InputForm =

>=3D=3D ( _
>           atom? f =3D> (symbol? f =3D> (symbol f =3D x =3D> =

>y;f);f); _
>             [sub(g,x,y) for g in destruct f]::InputForm)
> =

>   Function declaration sub : =

>(InputForm,Symbol,InputForm) -> InputForm
>      has been added to workspace.
>                                                           =

>        Type: Void
> =

> (2) -> sub
> =

>   (2)
>   sub (f,x,y) =3D=3D
>     if atom?(f)
>       then
>         if symbol?(f)
>           then
>             if symbol(f)=3D x
>               then y
>               else f
>           else f
>       else ([[sub(g,x,y) for g in destruct(f)]]) :: =

>InputForm
> =

>                                                    Type: =

>FunctionCalled(sub)
> =

> The function 'sub' operates on symbolic "input form" f =

>by replacing
> symbol x with input form y wherever x occurs. I think it =

>should be
> fairly obvious how this recursive routine works except =

>perhaps for
> 'destruct' which breaks a top-level input form into a =

>list of
> lower-level input forms. In this way the routine =

>traverses the entire
> tree structure representing the given input form.
> =

> Now the function that Stefan has in mind can be written =

>in a fairly
> transparent manner.
> =

> (3) -> ex:InputForm :=3D parse("if x<10 then 2*x else =

>5*x^2"); expr ex
> =

>   (3)
>   if x < 10
>     then 2x
>            2
>     else 5x
>                                                           =

>  Type: OutputForm
> =

> The function 'parse' returns an unevaluated input form =

>for the
> expression inside "...". The function 'expr' prints this =

>in a readable
> manner. (InputForm is displayed in this form by default =

>in OpenAxiom.)
> =

> (4) -> test1(x0)=3D=3Dsub(ex, x,x0)
>                                                           =

>        Type: Void
> =

> In the definition of 'test1' the function 'sub' replaces =

>the symbol x
> with the input form of x0.  The result remains =

>unevaluated.
> =

> (5) -> expr test1(y)
>   Compiling function sub with type =

>(InputForm,InputForm,InputForm) ->
>      InputForm
>   Compiling function test1 with type Variable(y) -> =

>InputForm
> =

>   (5)
>   if y < 10
>     then 2y
>            2
>     else 5y
>                                                           =

>  Type: OutputForm
> =

> But this need not always be the case.
> =

> (6) -> interpret test1(3)
>   Compiling function test1 with type PositiveInteger -> =

>InputForm
> =

>   (6)  6
>                                                        Type: =

>PositiveInteger
> (7) -> interpret test1(13)
> =

>   (7)  845
>                                                        Type: =

>PositiveInteger
> =

> The function 'interpret' evaluates an input form. This =

>is possible
> only because in the above two instances x is replaced =

>with a numeric
> value. But in general the argument to test1 need not be =

>numeric and we
> can keep the unevaluated symbolic form. For example we =

>can write:
> =

> (8) -> expr test1(x+1)
>   Compiling function test1 with type Polynomial(Integer) =

>-> InputForm
> =

>   (8)
>   if x + 1 < 10
>     then 2(x + 1)
>                  2
>     else 5(x + 1)
>                                                           =

>  Type: OutputForm
> =

> Perhaps this is not nearly as obvious as the way it =

>might be done in
> Mathematica or Maple - especially for someone just =

>beginning to use
> Axiom but I think it is equivalent to what is done in =

>these other
> systems and it is fair to say that it is in keeping with =

>the view in
> Axiom that everything is fundamentally algebraic.
> =

> Regards,
> Bill Page.
> =

>> ...
> =

>> On Sat, 30 Apr 2011 20:40:28 +0200
>> =A0Stefan Karrmann <[email protected]> wrote:
>>>
>>> Dear all,
>>>
>>> I'm new to axiom and have a problem with piecewise =

>>>functions.
>>>
>>> test1 (x | x < 10) =3D=3D 2*x
>>> test1 (x | x < 10) =3D=3D 5*x^2
>>> test1
>>> -> =A0 test1 (x | x < 10) =3D=3D 2x
>>> =A0test1 (x | ^ x < 10) =3D=3D 5x
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 =A0 =A0 =A0Type: =

>>>FunctionCalled
>>> test1 y
>>> ->
>>> =A0 =A02
>>> =A05y
>>>
>>> I expected something like (if y < 10 then 2*y else =

>>>5*y**2).
>>>
>>> How is it possible to pass a Variable to a piecewise =

>>>function respecting
>>> the pieces?
>>>
>>> PS: Using a block and =3D> or explicit if-then-else does =

>>>not help.
>>>
>>> --
>>> Kind regards,
>>> Stefan
>>>

William Sit, Professor Emeritus
Mathematics, City College of New York
Office: R6/291D Tel: 212-650-5179
Home Page: http://scisun.sci.ccny.cuny.edu/~wyscc/