axiom-developer
[Top][All Lists]
Advanced

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

Re: [Axiom-developer] Unit package proposals and questions


From: C Y
Subject: Re: [Axiom-developer] Unit package proposals and questions
Date: Thu, 8 Sep 2005 09:19:45 -0400
User-agent: KMail/1.8.2

On Thursday 08 September 2005 01:39 am, William Sit wrote:
> > C Y wrote:
> >
> > OK, but don't we want to take it one step further and have Axiom assume
> > that after a setDim("Dimension",s) command is issued when we type s on
> > the input line we are referring to the new object with outputform "s [m]"
> > when s is any type of  Variable?  If s is a number this doesn't make
> > sense, but intuitively when I do setDim("Length",x) I expect that from
> > that point on, unless I do unsetDim("x") to explicitly undo the setDim
> > command, when I say "x" I'm referring to the object that has both the
> > variable x and the information about Dimension.
>
> As I show in my earlier reply, we can do setDim("dim",s) but we still need
> to assign it to s when s is a Symbol. There is a catch: since there are
> many domains that include symbols, it won't be clear where s belongs. 

I'm not following - are you thinking that we won't know what type "s" is  
inside the object containing both dimension and the nondimensional quantity?  
Well, what about if we had just typed "s" on the input line without saying 
anything about where it belongs? In my copy of Axiom this gives:

   (2)  s
                                                             Type: Variable s

I'm thinking we can assume whatever the "default" assumption would have been 
on the command line - just remember that, bump s temporarily to a symbol, and 
then return it to being a Variable (in this case.)  Or do you mean that s 
will need to wind up in a UnitSystem?  This isn't obvious to me - Dimension 
is more general than any one UnitSystem.  Maybe we need a domain for 
dimension-without-specific-unit objects?

> In other words, since there are many setDim functions, one for each domain 
> in the UnitSystem Category, and each PARAMETER S for UnitSystem, you have to
> do a package call to explicitly say which S should contain the symbol. For
> example, you may want:
>
>    s:=setDim("Length",('s)::S)
>
> or
>
>    s:=setDim("Length",'s)$SIUnitSystem(S)
>
> In such cases, there is no point in retracting s to S (which will give a
> symbol s). In order to make s behave more like it were without units, let's
> see what the following scenario will require (assume FPS system)
>
> (1) ->  s:=setDim("Length",4)
>               4 [ft]
> (2) ->  s:= 7
>
> In order that (2) gives the answer "7 [ft]", the package will have to
> include a coercion function that is quite smart: 

Wait - why do we want s:=7 to work in that case?  I would expect that to fail 
- 7 is a dimensionless number.  For this to work, wouldn't we want either:

s:=setDim("Length",7)    or   w:=setDim("Length",7)
                                             s:=w

> it will need to first 
> coerce 7 to FPSUnitSystem(PositiveInteger) WITHOUT knowing its dimension,
> then coerce that to FPSUnitSystem(S), without knowing the dimension ---
> which requires S to have PositiveInteger as a subdomain, then assign
> whatever property s has (its dimension and unit at the time) to 7, and
> finally assigning the fully formed object (Rep for 7 [ft]) to the
> identifier s of type FPSUnitSystem(S). Now of course, the more direct and
> intuitive way is simply to change the value field in the Rep for s to 7.
> But HOW is the Interpreter to know that via a simple, universally coded
> assignment?

I may have misstated the problem.  For the case of numbers, I do not expect 
the above "magical" intuition about a number.  I was referring to the case of 
variables specifically.  Here's the scenario:

I have the equation x(t) := x0+v0*t+1/2*a*t^2 which I want to define with 
dimensional information.  To do this, I need to assign dimensions to each of 
the components in this equation.  What I would LIKE to do is something 
similar to the following:

(1) -> setDim("Length",x0)
(2) -> setDim("Velocity",v0)
(3) -> setDim("Time",t)
(4) -> setDim("Acceleration",a)

Then, if I want to assign 7 meters to x0, I would do the following:

(5) -> x0 := setDimUnit("Length","m",7)

This would do the following:

1.  Create a temporary dimensional object using 7, m, and Length
2.  Verify that m and Length are a legal paring in the temporary object
3.  Check if x0 is associated with a dimension.   If not, proceed to assign it 
the full contents of the temporary dimensional object.  If it does, as in 
this case, check that the dimension of x0 matches the dimension of the 
temporary object.  If it does not, return an error.  If it does, assign the 
x0 dimensional object the specific unit and amount (7).  

Generating plots of dimensional quantities will be interesting, but that's a 
bit down the road at the moment.  Does the above make sense?

> So to help the Interpreter, or indeed, to avoid having to modify the
> interpreter to make it smarter -- such modification will add so much
> inefficiency to ordinary assignment that it is not advisable in any
> case---we can design functions to do the more intuitive thing:
>
> (2') ->   setValue(s, 7)
>
> but of course this is not as intuitive for the user as (2)! However, it is
> actually quite uniform and similar to setDim or setUnit.
>
> The same means that a statement like:
>
> (3) ->  s:= s + 7
>
> would involve the same type of coercions as for (2). If instead,
>
> (3') -> setValue(s, s+7)
>
> then the function setValue *may* be taught to first retract the s in s+7 to
> S, add 7 to it in the domain S, then put this in the value-field of Rep of
> s. I say *may*, because the general situation would require a parser!

I don't think we want the "value" part of a dimension+nondim object to be 
workable as an individual object at all.  Adding 7 to it shouldn't be legal.

> So there is still a big design problem to think about: how to make
> subsequent computations intuitive without writing a parser for the package!
> The following way perhaps works (effectively asking the user to do the
> parsing):
>
>     setValue(s, retract(s)+7)
>
> (any implementation, in Axiom, will require conditional implementation,
> testing that S can do arithmetic with PositiveInteger or Integer), and if s
> is not just a symbol, a retractIfCan(s) may be more appropriate.

I vote for just avoiding the whole situation by not dealing in anything but 
unit/dimensional quantities when dimensions are in play.  It's a bit sad to 
lose the convenience of being able to say s:=7*m but you finally convinced 
me.

> > That's implicit in issuing the setDim command in the first
> > place.  In a software design sense I would think that doing otherwise
> > would violate the Principle of Least Surprise.
>
> You should know that Axiom is full of surprises because it is not easy to
> understand the implications of a strongly typed language.

Oh, I know :-).  But we've got to try to meet our users at least part way or 
we won't have many users!  We need to stay correct, but what I'm trying to do 
is make things as convenient as possible while remaining correct.

> > I would rather use some command
> > like stripDim("x") to get at the object "x" that doesn't have a dimension
> > associated with it if for some reason I want it, because once I so setDim
> > command it's assumed (at least by me) that I don't WANT to have x work as
> > an object without dimension anymore.  Obviously this doesn't work for
> > setDim("Length",4), since 4 is not a variable, but in the case of x it
> > should (at least IMHO) work.
>
> The problem is with subsequent arithmetic (not to mention the grander
> vector calculus) that involves quantities whose dimensions or units have
> not been defined, whether they be numbers or expressions.

I don't think we want to combine dimension/unit quantities with quantities 
whose dimensions or units have not been defined - are there scenarios where 
this is needed?

> In some sense, 
> this is again forcing the user to know what he is doing, to think of
> dimensions and units in every step of the computation. But users used to
> the sloppy way will find this very frustrating.  In the simple example
> above, s+7, the dimension and unit of 7 are not given. Is it good idea to
> "help" the user and "guess" that 7 should have the same dimension and unit
> as s? If so, wouldn't that allow a sloppy user to add s [ft] to 7 [in] and
> get (s+7) [ft]?

No, we shouldn't do that.  That wasn't what I was advocating - sorry if I gave 
that impression.

> I think we should not provide such automation: two reasons: simplifies
> implementation, and forces the user to be specific on dimensions and units.
> So a user MUST declare, using setDimUnit, EVERY quantity he wants to
> compute using a unit system. If all inputs to an expression are declared
> ahead of time, the arithmetic will take place in the unit system domain and
> parsing done by the Interpreter, without the use of setValue.

Right.

> It would be desirable to allow:
>
>     s:= setDimUnit("Length","in",'s)
>     t:= s + 7 [ft]
>
> to give a value of s+84 [in] for t. But this involves modifying the
> interpreter and the language! ([ft] may be a list containing a variable
> ft). Here is an argument for using variables for units, because there would
> have been created conversion (rewrite) rule ft == 12 in, which would be
> applied automatically.

I figured this scenario wouldn't work as I began coming to grips with your 
design - I don't think the above is possible, sadly.  It would have to be 
done as follows, given the best setDimUnit definition I can see as being 
workable:

     s:= setDimUnit("Length","in",s)
     t:= s + setDimUnit("Length","ft",7)

This would be legal, but the units of t, unless previously set, would be 
determined in this case by what the global default is.  (Probably meters ;-)

> > Maybe we can flag this behavior so that if a hard core
> > Axiom user prefers the behavior which is a consequence of strict
> > interaction with a strong type system and doesn't want to special case
> > variable behavior Axiom won't do the extra voodoo?
>
> In general, I don't like (personal bias) a program to provide automatic
> help (such as checking grammar or spelling or indentations in MS Word!). It
> is far better to have fewer options and the system behaves consistently.

Well, I guess I'm in the middle - I like spell checking, but I don't like 
grammer checking (particularly since grammer checking can't be defined 
programatically, IIRC!).

> > What if we internally use
> > some symbol other than the one given in setDim("Length",a) and have a
> > rule for displaying a variable with dimension that it shouldn't show the
> > internal symbol but a instead.  Something like:
> >
> > setDim("Length",a) -> creates some object containing [nondim_a,Length]
> > and assigns this to the name a, just like a := <object> would.  Then we
> > create some kind of display rule that rather that variables of the form
> > nondim_* be displayed as * in output?  This would preserve the Axiom type
> > behavior while hiding the messy details and avoiding violating user
> > expection of variable interaction.  This could probably be turned off as
> > well if a hardcore Axiom user wants normal behavior.
>
> I suppose the above is obsolete now?

I think you addressed that problem in the previous email, but we'll see when 
we get to coding :-).

Cheers,
CY




reply via email to

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