# if-expression and variables

20 messages
Open this post in threaded view
|

## if-expression and variables

 Dear all, I'm new to axiom and have a problem with piecewise functions. test1 (x | x < 10) == 2*x test1 (x | x < 10) == 5*x^2 test1 ->    test1 (x | x < 10) == 2x    test1 (x | ^ x < 10) == 5x                                                    Type: FunctionCalled test1 y ->      2    5y 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 => or explicit if-then-else does not help. -- Kind regards, Stefan _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 What you want is probably better called a "piecewise expression" - not a function in Axiom's sense. Unfortunately as far as I know piecewise expressions like "(if y < 10 then 2*y else 5*y**2)" are not implemented in any version of Axiom so they can not be returned as the result of a function application like "test1(y)". To explain the results that you get, it is important to know that in older versions of Axiom (in particular in the original Axiom open source project), the expression   y<10 is evaluated as a comparison of polynomials in lexicographical order. As such "y<10" is "false". In other versions of Axiom to avoid such confusion lexicographical ordering is no longer expressed by the "<" function so the expression "y<10" is not evaluated at all. In FriCAS you would write: "smaller?(x,10)", in OpenAxiom it is written: "before?(10,x)". But like in the original Axiom, both of these functions are always fully evaluated as a boolean value, true or false.  They cannot be used like "unevaluated functions" or expressions. I hope that helps. Regards, Bill Page. On Sat, Apr 30, 2011 at 2:40 PM, Stefan Karrmann <[hidden email]> wrote: > Dear all, > > I'm new to axiom and have a problem with piecewise functions. > > test1 (x | x < 10) == 2*x > test1 (x | x < 10) == 5*x^2 > test1 > -> >   test1 (x | x < 10) == 2x >   test1 (x | ^ x < 10) == 5x >                                                   Type: FunctionCalled > test1 y > -> >     2 >   5y > > 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 => or explicit if-then-else does not help. > > -- > Kind regards, > Stefan > > > _______________________________________________ > Axiom-math mailing list > [hidden email] > https://lists.nongnu.org/mailman/listinfo/axiom-math> _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by Stefan Karrmann-2 Dear Stefan: When you input "x < 10" into a symbolic computation program, the meaning is at first ambiguous. In the context of a function such as test1, a meaning can be obtained by assuming x is of the same type as 10 (or at least numeric) and the usual ordering of numbers is used for the "<" operation. However, if the input x is not numeric, such as the symbol y you use, then it does not make sense to compare a symbol y with a number, except in the context of polynomials (y and 10 both treated as polynomials in y). There, the usual ordering is an extension of a term-ordering and y > 10, as polynomials, and that is why you get 5y^2.  (BTW, you have a typo in your definition of test1.) To implement what you expect for "test1 y" would require a whole new setup, treating "y < 10" as an unevaluated expression (hold the evaluation until more information is known about y). But even if that is the setup, "test1 y" could only return "test1 y", unless there is an instruction from the user to "expand" the definition of test1. 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. At a higher level of symbolic computation, it is possible to simplify a boolean expression of inequalities (in Axiom, as far as I know, there is no such domain yet; Mathematica has a function called "Reduce" that does simplifications involving inequalities and equations). However, that would not be in the simple context of a piecewise function. Tim Daly has done some experiments with a proviso domain in Axiom. He may be able to tell you more. William On Sat, 30 Apr 2011 20:40:28 +0200   Stefan Karrmann <[hidden email]> wrote: > Dear all, > > I'm new to axiom and have a problem with piecewise >functions. > > test1 (x | x < 10) == 2*x > test1 (x | x < 10) == 5*x^2 > test1 > -> >   test1 (x | x < 10) == 2x >   test1 (x | ^ x < 10) == 5x >                                                   Type: >FunctionCalled > test1 y > -> >     2 >   5y > > 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 => or explicit if-then-else does >not help. > > -- > Kind regards, > Stefan > > > _______________________________________________ > Axiom-math mailing list > [hidden email] > https://lists.nongnu.org/mailman/listinfo/axiom-mathWilliam 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/_______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by Stefan Karrmann-2 PS: I just like to add that if a system provides automatically an expansion of the definition of test1 in "evaluating" "test1 y", then it is easy to see the system can easily get "clogged" with unintelligible output, for example, even in as simple an expression as "test1 test1 y" and no system can handle expansion of things like "test1^n y" (iterating test1 n times, where n is also a variable). (Mathematica provides a "notation" to hold the expression, for example, Nest[test1,y,n]), in effect, creating a new function through composition.) The problem in Axiom is, however, still due to the dual (and automatically selected) meanings of "y < 10". If we qualify the "<" operation by "<(\$Integer)", then Axiom will refuse to evaluate "y <(\$Integer) 10" because y is not known to be of type Integer. Axiom announces an error, while Mathematica returns the input. William On Sat, 30 Apr 2011 20:40:28 +0200   Stefan Karrmann <[hidden email]> wrote: > Dear all, > > I'm new to axiom and have a problem with piecewise >functions. > > test1 (x | x < 10) == 2*x > test1 (x | x < 10) == 5*x^2 > test1 > -> >   test1 (x | x < 10) == 2x >   test1 (x | ^ x < 10) == 5x >                                                   Type: >FunctionCalled > test1 y > -> >     2 >   5y > > 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 => or explicit if-then-else does >not help. > > -- > Kind regards, > Stefan > > > _______________________________________________ > Axiom-math mailing list > [hidden email] > https://lists.nongnu.org/mailman/listinfo/axiom-mathWilliam 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/_______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by William Sit-2 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 == ( _            atom? f => (symbol? f => (symbol f = x => 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) ==      if atom?(f)        then          if symbol?(f)            then              if symbol(f)= 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 := 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)==sub(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 >  Stefan Karrmann <[hidden email]> wrote: >> >> Dear all, >> >> I'm new to axiom and have a problem with piecewise functions. >> >> test1 (x | x < 10) == 2*x >> test1 (x | x < 10) == 5*x^2 >> test1 >> ->   test1 (x | x < 10) == 2x >>  test1 (x | ^ x < 10) == 5x >>                                                  Type: FunctionCalled >> test1 y >> -> >>    2 >>  5y >> >> 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 => or explicit if-then-else does not help. >> >> -- >> Kind regards, >> Stefan >> _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 Oops, I forgot that 'parse' was never implemented in the InputForm domain in the original Axiom.  In this case use:  parse(s:String):InputForm == ncParseFromString(s)\$Lisp Regards, Bill Page. On Mon, May 2, 2011 at 11:57 PM, Bill Page <[hidden email]> wrote: > > Now the function that Stefan has in mind can be written in a fairly > transparent manner. > > (3) -> ex:InputForm := 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.) > _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by Bill Page-7 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 <[hidden email]> 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 >== ( _ >           atom? f => (symbol? f => (symbol f = x => >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) == >     if atom?(f) >       then >         if symbol?(f) >           then >             if symbol(f)= 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 := 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)==sub(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 >>  Stefan Karrmann <[hidden email]> wrote: >>> >>> Dear all, >>> >>> I'm new to axiom and have a problem with piecewise >>>functions. >>> >>> test1 (x | x < 10) == 2*x >>> test1 (x | x < 10) == 5*x^2 >>> test1 >>> ->   test1 (x | x < 10) == 2x >>>  test1 (x | ^ x < 10) == 5x >>>                                                  Type: >>>FunctionCalled >>> test1 y >>> -> >>>    2 >>>  5y >>> >>> 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 => 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/_______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by Stefan Karrmann-2 Dear Stefan, as others already have pointed out, for Axiom, your question is not really well posed. In Axiom    if x<10 then 2*x else 5*x^2 is *not* an expression (as you might know it from other untyped CAS like Mathematica or Maple), but rather a programming language construct. In other words, if Axiom sees this, it is evaluated. So the result is either 2*x or 5*x^2 depending on the (boolean) outcome of the evaluation of x<10. I think, Bill suggested to use something like InputForm. There it would be possible to represent an if-expression unevaluated. But you should rather say what you actually want (it's not the same what you expect). In order for us to suggest you a proper way to handle your use case, you should tell us why you want a piecewise function and (more important) what you later want to do with that function. Until we have that information, everything would be just digging in the dark. Ralf On 04/30/2011 08:40 PM, Stefan Karrmann wrote: > Dear all, > > I'm new to axiom and have a problem with piecewise functions. > > test1 (x | x<  10) == 2*x > test1 (x | x<  10) == 5*x^2 > test1 > -> >     test1 (x | x<  10) == 2x >     test1 (x | ^ x<  10) == 5x >                                                     Type: FunctionCalled > test1 y > -> >       2 >     5y > > 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 =>  or explicit if-then-else does not help. > _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 On 05/03/2011 04:21 AM, Ralf Hemmecke wrote: > Dear Stefan, > > as others already have pointed out, for Axiom, your question is not > really well posed. > > In Axiom > >   if x<10 then 2*x else 5*x^2 > > is *not* an expression (as you might know it from other untyped CAS > like Mathematica or Maple), but rather a programming language > construct. In other words, if Axiom sees this, it is evaluated. So the > result is either 2*x or 5*x^2 depending on the (boolean) outcome of > the evaluation of x<10. > > I think, Bill suggested to use something like InputForm. There it > would be possible to represent an if-expression unevaluated. > > But you should rather say what you actually want (it's not the same > what you expect). > > In order for us to suggest you a proper way to handle your use case, > you should tell us why you want a piecewise function and (more > important) what you later want to do with that function. > > Until we have that information, everything would be just digging in > the dark. > > Ralf Ralf But the question is not intrinsically a "programing construct".  With some (bulky) symbolic logic constructs one can express it in a mathematical sense. That is: set membership and "exclusive or".  I wouldn't have the slightest idea how to implement it in Axiom; nonetheless questions like this have non programmatic expressions.  For instance Prolog has an explicit resolution syntax that is reasonably obvious and supports embedding logic conditions on and on.   As I recall you can even extend it to second order logic. _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 > But the question is not intrinsically a "programing construct". What does that mean? > With some (bulky) symbolic logic constructs one can express it in a > mathematical sense. That is: set membership and "exclusive or". You want to rewrite the if-statement into set membership and exclusive or? > I wouldn't have the slightest idea how to implement it in Axiom; > nonetheless questions like this have non programmatic expressions. I must admit I don't quite understand what exactly you want to do. Can you give a more explicit use case. Maybe something written in another CAS which you want to turn into an AXIOM equivalent. > For instance Prolog has an explicit resolution syntax that is > reasonably obvious and supports embedding logic conditions on and > on. As I recall you can even extend it to second order logic. Good for Prolog, but Axiom is not Prolog. ;-) To give a few hints. As Bill already said, Axiom is more an algebraic system rather than a symbolic one. Of course, since Axiom has a proper programming language underneath, one can do everything, but the question is, how much is already implemented. The first questions, when one programs with Axiom usually are: What is my "domain of computation"? (That is basically like with universal algebra. What is the carrier set and what are the operations?) How are the elements of the carrier set represented in terms of already existing (library) types? Now answer that questions for the "if-expression". It's a rather general thing and can certainly be represented by something like a LISP S-expression. But that's too general to fall into a reasonable algebra, except (maybe) a boolean algebra. As William stated, "x<10" makes no sense in general. Or rather is is just a sequence of symbols. It only makes sense if you can say what "<", "x" and "10" actually are in this context. Or maybe it stands as an abbreviation for "(lambda x).x<10". In fact, usually Axiom wants typed expressions. Remember, everything in Axiom has a type. (It's only the interpreter that makes your life as a user easier by accepting things without explicit type information. --- I actually think, it makes it harder to understand Axiom.) Again. What is your use case? Ralf _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by William Sit-2 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. _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 > 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. Well, if one uses Axiom (which was designed to be *typed*) in order to implement such an evaluate function, then one basically implements an untyped CAS inside a typed CAS. Possible, but why would I want that? There might be some use cases for this, but personally, I am so happy that Axiom is typed, that I find this making-Axiom-untyped  (or one-typed, i.e. just InputForm) a bit counter-productive. Ralf _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by Ralf Hemmecke On 05/03/2011 11:01 AM, Ralf Hemmecke wrote: >> But the question is not intrinsically a "programing construct". > > What does that mean? More or less I mean a tree structure where the nodes have evaluation contents; say Boolean evaluations or calculations.  Then nodes may have left/right (true/false) subbranches or terminate.   In the case of "case" the subbranches could be most anything.  When the tree terminates, reaches an end node,  then return  the terminating evaluation/value (for debuging the option of returning the path might be nice).  If a mid-level evaluation doesn't match a subsequent branch then return failure; of course the lack of a subbranch would be taken as matching anything. This isn't what I meant by "symbolic logic" but is equivalent and seems perfectly clear without any evocation of "horn clauses" and such. > >> With some (bulky) symbolic logic constructs one can express it in a >> mathematical sense. That is: set membership and "exclusive or". > > You want to rewrite the if-statement into set membership and exclusive > or? Yes I did; but upon reflection I am reluctant to go there. > > To give a few hints. As Bill already said, Axiom is more an algebraic > system rather than a symbolic one. Of course, since Axiom has a proper > programming language underneath, one can do everything, but the > question is, how much is already implemented. > > The first questions, when one programs with Axiom usually are: > What is my "domain of computation"? > (That is basically like with universal algebra. What is the carrier > set and what are the operations?) > How are the elements of the carrier set represented in terms of > already existing (library) types? Yes, I think it boils down to second-order logic; in this case a category of unevaluated expressions.   As above; stored in the tree and then brought front and center and evaluated in the tree accessing environment. Going back to the original question.  It seems the questioner expects to fabricate a template and later to create instances of it with varying variables.  I would think that keeping the old (hopefully private) variables and then assigning incoming variables to the private variables might eliminate having multiple copies laying around and perhaps the need of a template at all. Probably doesn't cover all cases though. Sorry if I have taken the discussion drifting; I merely wanted to point out the if/else can be a static data structure rather than in-line code. Ray _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 >> The first questions, when one programs with Axiom usually are: >> What is my "domain of computation"? >> (That is basically like with universal algebra. What is the carrier >> set and what are the operations?) >> How are the elements of the carrier set represented in terms of >> already existing (library) types? > Yes, I think it boils down to second-order logic; in this case a > category of unevaluated expressions. As above; stored in the tree and > then brought front and center and evaluated in the tree accessing > environment. As I said, it's no problem to implement that in Axiom. Actually, InputForm is basically such a domain. > Going back to the original question. It seems the questioner expects to > fabricate a template and later to create instances of it with varying > variables. Although possible, that is a mindset that belongs to traditional (typeless) CAS. I would rather ask the questioner to state the actual problem instead of already giving a direction, i.e. using expression trees. > Sorry if I have taken the discussion drifting; I merely wanted to point > out the if/else can be a static data structure rather than in-line code. Well, of course, that's possible. In fact, expression trees is something that almost all computer algebra systems rely upon. But Axiom is different. Take for example 1+1. What is this evaluated? Three out of infinitely many results. 1) 2 2) 0 3) 1+1 In Axiom (at least in SPAD) there would only be one possible result, since the compiler checks types. If it is clear what 1 and + means, it's also deterministic what the result is. Ralf _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

 In reply to this post by Ralf Hemmecke Dear all, thanks for your answers. They clears a lot. I actually want to integrate test1 and solve an differential equation with it. E.g. test2 x == rho * test1 x y = operator 'y odeq := D(y x) = test2 x solve(odeq, y, x) Obviously, the solution is "formally" y_sol x == integrate(test2 x,x) Kind regards, Stefan Am Dienstag, den 03.05.2011, 11:21 +0200 schrieb Ralf Hemmecke: > Dear Stefan, > > as others already have pointed out, for Axiom, your question is not > really well posed. > > In Axiom > >    if x<10 then 2*x else 5*x^2 > > is *not* an expression (as you might know it from other untyped CAS like > Mathematica or Maple), but rather a programming language construct. In > other words, if Axiom sees this, it is evaluated. So the result is > either 2*x or 5*x^2 depending on the (boolean) outcome of the evaluation > of x<10. > > I think, Bill suggested to use something like InputForm. There it would > be possible to represent an if-expression unevaluated. > > But you should rather say what you actually want (it's not the same what > you expect). > > In order for us to suggest you a proper way to handle your use case, you > should tell us why you want a piecewise function and (more important) > what you later want to do with that function. > > Until we have that information, everything would be just digging in the > dark. > > Ralf > > On 04/30/2011 08:40 PM, Stefan Karrmann wrote: > > Dear all, > > > > I'm new to axiom and have a problem with piecewise functions. > > > > test1 (x | x<  10) == 2*x > > test1 (x | x >= 10) == 5*x^2 > > [was typo: test1 (x | x<  10) == 5*x^2] > > test1 > > -> > >     test1 (x | x<  10) == 2x > >     test1 (x | ^ x<  10) == 5x > >                                                     Type: FunctionCalled > > test1 y > > -> > >       2 > >     5y > > > > 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 =>  or explicit if-then-else does not help. _______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math
Open this post in threaded view
|

## Re: if-expression and variables

Open this post in threaded view
|

## Re: if-expression and variables

Open this post in threaded view
|

## Re: if-expression and variables

 Dear all, we can help ourselves in some cases by: sign x == (abs x)/x H x == (1 + sign x)/2 step (a,b,x) == (H(x-a)) * (H(b-x)) The drawback is that we get a 'Division by zero'. Kind regards, Stefan Am Donnerstag, den 05.05.2011, 00:23 -0400 schrieb William Sit: > Dear Stefan: > > You posed a legitimate problem: how should symbolic > computation handle piecewise defined functions, and in > particular, how to integrate such a function. > > Maple and Mathematica both can handle piecewise functions. > Look up "piecewise" from Maple Help. You can easily define > a piecewise function, and differentiate or integrate it. > Indeed, Maple says: > > The piecewise function can be differentiated, integrated, > simplified, plotted, and used in the following types of > differential equations: constant coefficients and > discontinuous perturbation function, general first-order > linear, Riccati, and some other classes which are handled > by integration or variation of parameter. See > dsolve[piecewise] for more details. series, limit, abs, > and signum can handle the piecewise function. > > As example, the desired solution the problem of > integrating f(x) from 0 to t, where f(x) is 2x if x < 10 > and 5x^2 otherwise, should be the function g(t), defined > as t^2 if t < 10 and -4000/3 +(5 t^3)/3 otherwise. Maple > does exactly that. In fact, I even tried to integrate > f(f(x)) and f(f(x+1)) and Maple does it with no problems > with all the cases covered. > > Mathematica has a similar function called Piecewise to > construct piecewise functions, and like Maple, Piecewise > can be used in such functions as Integrate, Minimize, > Reduce, DSolve and Simplify, as well as their numeric > analogs. > > This may be an uncovered domain in Axiom. A search for > "piecewise" shows no hits. I think piecewise functions > have to be separately handled, particularly in case > analysis (possibly involving semi-algebraic sets and CAD) > if there is any indefiniteness in the answer (like an > indefinite integral). There is some evidence that if the > user does not use the built-in "piecewise" or "Piecewise" > function, but uses an if-then-else construction, neither > Maple nor Mathematica can handle subsequent mathematical > calculations. For example, the system would not do the > case analysis, much less the "simplification" > automatically, but would present the result as the > integral of If[x < 10, 2 x, 5 x^2] (in Mathematica; I did > not try Maple). Even when the case analysis is done, it > would still not simplify or evaluate the integrals: > > h[x_] := If[x < 10, Integrate[2 y, {y, 0, x}], >    Integrate[2 y, {y, 0, 10}] + Integrate[5 y^2, {y, 10, > x}]] > > when h[x] is called. It will evaluate on numerical inputs. > > In our earlier discussions, we were "lured" into using > "if-the-else" constructions and thus got the feeling that > this is difficult to handle. The confusion is that we > interpret "x < 10" as an binary relation, whereas it > should be handled as a semi-algebraic set (in one > dimension, this is just an interval)! > > However, the algorithms seem to be there, and someone > should implement them in Axiom if it is not already done > but hidden in some obscure packages. > > William > > On Wed, 04 May 2011 22:37:48 +0200 >   Stefan Karrmann <[hidden email]> wrote: > > Dear all, > > > > thanks for your answers. They clears a lot. > > > > I actually want to integrate test1 and solve an > >differential equation > > with it. > > > > E.g. > > test2 x == rho * test1 x > > y = operator 'y > > odeq := D(y x) = test2 x > > solve(odeq, y, x) > > > > Obviously, the solution is "formally" > > > > y_sol x == integrate(test2 x,x) > > > > Kind regards, > > Stefan > > > > Am Dienstag, den 03.05.2011, 11:21 +0200 schrieb Ralf > >Hemmecke: > >> Dear Stefan, > >> > >> as others already have pointed out, for Axiom, your > >>question is not > >> really well posed. > >> > >> In Axiom > >> > >>    if x<10 then 2*x else 5*x^2 > >> > >> is *not* an expression (as you might know it from other > >>untyped CAS like > >> Mathematica or Maple), but rather a programming language > >>construct. In > >> other words, if Axiom sees this, it is evaluated. So the > >>result is > >> either 2*x or 5*x^2 depending on the (boolean) outcome > >>of the evaluation > >> of x<10. > >> > >> I think, Bill suggested to use something like InputForm. > >>There it would > >> be possible to represent an if-expression unevaluated. > >> > >> But you should rather say what you actually want (it's > >>not the same what > >> you expect). > >> > >> In order for us to suggest you a proper way to handle > >>your use case, you > >> should tell us why you want a piecewise function and > >>(more important) > >> what you later want to do with that function. > >> > >> Until we have that information, everything would be just > >>digging in the > >> dark. > >> > >> Ralf > >> > >> On 04/30/2011 08:40 PM, Stefan Karrmann wrote: > >> > Dear all, > >> > > >> > I'm new to axiom and have a problem with piecewise > >>functions. > >> > > >> > test1 (x | x<  10) == 2*x > >> > test1 (x | x >= 10) == 5*x^2 > >> > [was typo: test1 (x | x<  10) == 5*x^2] > >> > test1 > >> > -> > >> >     test1 (x | x<  10) == 2x > >> >     test1 (x | ^ x<  10) == 5x > >> > > >>                                                    Type: > >>FunctionCalled > >> > test1 y > >> > -> > >> >       2 > >> >     5y > >> > > >> > 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 =>  or explicit if-then-else > >>does not help. > > > > > > _______________________________________________ > > Axiom-math mailing list > > [hidden email] > > https://lists.nongnu.org/mailman/listinfo/axiom-math> > 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/_______________________________________________ Axiom-math mailing list [hidden email] https://lists.nongnu.org/mailman/listinfo/axiom-math