axiom-math
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Axiom-math] if-expression and variables


From: William Sit
Subject: Re: [Axiom-math] if-expression and variables
Date: Wed, 04 May 2011 22:59:42 -0400

Dear Bill:

Thanks for answer the questions. I agree that we are drifting away from the original question -- which is a constant curse on Axiom.

Here is how I would combine "interpret test1(x0)" with "expr test1(x0)". Note that for test2, the target domain is Any (which is sort of a Union, and better than InputForm). Note that the source domain varies as the input argument of test2.

(24) -> test2(x0)==(integer? x0 => interpret test1(x0); expr test1(x0))
   Compiled code for test2 has been cleared.
   1 old definition(s) deleted for function or rule test2
Type: Void
(25) -> test2(y)
   Compiling function test2 with type Variable y -> Any

   (25)
   if y < 10
     then 2y
            2
     else 5y
Type: OutputForm
(26) -> test2(3)
Loading j:/OpenAxiom/axiom014/mnt/windows/algebra/INTRET.o for
      package IntegerRetractions
Compiling function test1 with type PositiveInteger -> InputForm Compiling function test2 with type PositiveInteger -> Any

   (26)  6
Type: PositiveInteger
(27) -> test2(y+1)
Compiling function test1 with type Polynomial Integer -> InputForm Compiling function test2 with type Polynomial Integer -> Any

   (27)
   if y + 1 < 10
     then 2(y + 1)
                  2
     else 5(y + 1)

And to illustrate the possible problems with a "global substitution", I try a different definition for ex:

(13) -> ex:InputForm := ncParseFromString("if x<10 then x:=x+1 else x:=x-1")$Lisp; expr ex

   (13)
   if x < 10
     then x := x + 1
     else x := x - 1
Type: OutputForm
(14) -> destruct ex

   (14)  [IF,(< x 10),(LET x (+ x 1)),(LET x (- x 1))]
Type: List InputForm

(18) -> test1(x0)==sub(ex,x,x0)
Type: Void
(19) -> expr test1(y)
Compiling function sub with type (InputForm,Symbol,InputForm) ->
      InputForm
Compiling function test1 with type Variable y -> InputForm

   (19)
   if y < 10
     then y := y + 1
     else y := y - 1
Type: OutputForm

(20) -> interpret test1(3)
Compiling function test1 with type PositiveInteger -> InputForm

3 is not valid on the left-hand side of an assignment expression.
(20) -> expr test1(x+1)
Compiling function test1 with type Polynomial Integer -> InputForm

   (20)
   if x + 1 < 10
     then x + 1 := x + 1 + 1
     else x + 1 := x + 1 - 1
Type: OutputForm Even though the output of (20) is what you "expect", it should have been flagged just like when x0 = 3. Why does Axiom think it is okay to put x+1 on the left hand side of an assign? (If the right hand side is more complicated, I don't suppose we expect the system to actually solve for x; and even if it does, it would not know which root to take for say a quadratic.)

The problem is not because I use an assignment, but because an InputForm is supposedly free to do any computation, including a conditional increment/decrement on the input. Another problem, when dealing with the original question, as amended, is there is no "integrate" operation on InputForm.

Here's an unexpected turn out (I should have parenthesized the object of "if"): the system should have flagged an input or syntax error if it actually interpreted the ; to end the if-clause. Is NIL or the () regarded as an error indication in Lisp or InputForm?

Type: InputForm (11) -> ex:InputForm := ncParseFromString("if x<10 then x:=x+1;2*x else 5*x^2")$
Lisp; expr ex

   (11)  NIL
Type: OutputForm
(12) -> flatten ex

   (12)  ()
Type: InputForm

William



On Tue, 3 May 2011 13:32:55 -0400
 Bill Page <address@hidden> wrote:
William,

As usual this thread is drifting away from the original question but I still think it is interesting from a more general point of view. It seems to me that InputForm is an often under-appreciated and
under-used domain in Axiom.

On Tue, May 3, 2011 at 3:04 AM, you wrote:
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.

True. The question is: how much programming is required versus how much one can do "off-the-shelf". With any system that is designed to be extended like Axiom, this is always a moving target. As user requirements are identified and programming solutions found, these solutions should become candidates for inclusion in the standard
library.

However, what you did essentially defines two different piecewise function, one for numeric and one for symbolic, by using "interpret" and "expr".

There is only one definition of 'test1'

(3) -> ex:InputForm := parse("if x<10 then 2*x else 5*x^2");
(4) -> test1(x0)==sub(ex, x,x0)

In that sense there is only one "function". (I think this definition is more properly called a "mode".) This highlights a significant difference between function definitions in the Axiom interpreter versus the library compiler. Untyped modes will (usually but not necessarily) be instantiated into fully typed functions. Warning
messages like:

Compiling function test1 with type PositiveInteger -> InputForm

are intend to inform the user that this "function" resulted in one of possibly several different fully typed compiled functions.

If you use "interpret test1(y)" you would still get the wrong answer, and

Yes. It is the "wrong" answer in as much as it probably differs wildly from what a beginning user would expect. That is way other variants of Axiom choose to eliminate "<" to denote the default ordering of polynomials. In these other systems "interpret test1(y)" would not be evaluated since these is preferable over an apparently wrong result.

similarly, if you use "expr test1(3)", then you would not have the result
evaluated.

That is true. 'expr' is only a matter of "pretty printing" and unevaluated expression (InputForm). 'interpret' on the other hand applies all of Axiom's built-in and library-dependent rules for
evaluation.

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).


I suppose you are suggesting a function that in Axiom parlance might be called "interpretIfCan". It is not obvious to me how one could "test if the input is a symbolic expression". In a deep sense everything in Axiom (in fact in any computer system) is "symbolic". From the point of view of Axiom's run-time system (i.e. Lisp) some things are considered "atomic" such as symbols, integers, etc. But

(5) -> sub(ex,x,3)
Compiling function sub with type (InputForm,Symbol,InputForm) ->
     InputForm

  (5)  (IF (< 3 10) (* 2 3) (* 5 (^ 3 2)))
Type: InputForm

is not atomic in this sense, yet it can be evaluated by 'interpret' to
something which is:

(6) -> interpret(sub(ex,x,3))::InputForm

  (6)  6
Type: InputForm

It would certainly be possible in principle to implement a function such as:

  evaluate: InputForm -> InputForm

which attempts to 'interpret' its input and if possible returns the InputForm derived from the corresponding value, otherwise it would
return the input unchanged.

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 think 'sub' does exactly and only what I claimed.

(2) -> sub(f:InputForm, x:Symbol, y:InputForm):InputForm == ( _;f); _ atom? f => (symbol? f => (symbol f = x => y;f);f); _
           [sub(g,x,y) for g in destruct f]::InputForm)

It finds all occurrences of the symbol (passed as formal parameter x) in the InputForm (passed by parameter f). It inserts an InputForm (passed as parameter y) into f where x occurs in f. The result is still a value of type InputForm which may or may not be able to be evaluated by 'interpret'. Nothing is "bound" in f. Also there is no concept of "local variable" because the InputForm is not yet evaluated in any way. The declaration "f:InputForm" is just like any other similar declaration in an Axiom function. It says only that the value passed by formal parameter f must be of type InputForm. f is not a function, it just stands for some value of type InputForm.

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).

As you can see InputForm is only slightly removed from Lisp. The underlying representation of InputForm is exactly a Lisp s-expression
of a particular form.

Mathematica is able to provide that, because neither the input nor the output
is restricted by its type.

I think that is not very accurate. It might be better to say that in Mathematica everything is of only one type: symbolic. In Axiom terms this would be like making everything an InputForm. This is not as "bad" or as "stupid" as it might sound. But it is not very "algebraic"
in the sense in which I used the word earlier.

In Axiom, maybe we can do the same with a Union like
Union(Integer, InputForm).

I am not sure how Union would help in this case.

...

Regards,
Bill Page.

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/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]