[Top][All Lists]
[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/
Re: [Axiom-math] if-expression and variables, William Sit, 2011/05/02
Re: [Axiom-math] if-expression and variables, Ralf Hemmecke, 2011/05/03