Karim Belabas on Fri, 28 Nov 2014 14:54:45 +0100

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

Re: new GP functions varhigher / varlower

* Andreas Enge [2014-11-28 11:51]:
> On Wed, Nov 26, 2014 at 07:11:46PM +0100, Karim Belabas wrote:
> >   varhigher(name, {v}): return a variable 'name' whose priority is higher than
> >   the priority of v (of all existing variables if v is omitted).
> > 
> > 1) [WONTFIX] variables created via varhigher / varlower can not be accessed by
> > typing their name (or the quote operator 'foo). This is by design: the same
> > (display) string can be associated to many variables. A given symbol can be
> > associated to only one of them.
> I understand that this applies to the programmer's responsability, but is
> their a potential use for this confusing behaviour?

Yes: writing and distributing portable GP code. Without it

- Either you introduce an indirection level, call your variables v1, v2,
  ... and require users to always pass on variable names, which is
  cumbersome. (This is the main reason we now define 'x' and 'y': have a
  sensible default for variables in modular polynomials.)

- Or you fix your own names which are 99% guaranteed to be no longer
  available with the proper priority if your package is not the first
  one loaded into gp.


A better theoretical solution (orthogonal to PARI philosophy) would be
to define formally and explicitly a polynomial ring before any
polynomial could be created, as in Magma or Sage. Then a polynomial
contains a pointer to its parent domain and arbitrary collections
of variables could have a *local* meaning: any specific collection 
of object would belong to a specific polynomial ring with a fixed
variable ordering, independently of the rest of GP.

Having different variables printed in the same way emulates part
of this without the hassle of requiring explicit prior definitions.

E.g. if you want a tower of fields 
  K = Q[x]/(T) \subset L = K[y]/(U) \subset M = L[z]/(V)
you start with

  y = varhigher("y", x);
  z = varhigher("z", y);

and you're done. If the next package author wants his polynomials in
((Q[z])[y])[x], fine, he can have them.

  y = varlower("y", x);
  z = varlower("z", y);

and both packages can coexist. Of course both package must use their
own x, y, z and never rely on 'x, 'y, 'z (which will in general refer to
different variables)

> Local variables?

No, local variables ( actually, variables lexically scoped via my() )
are "inlined": their name is no longer a concern.

> But as I understand it, these symbols are global anyway?

Yes. That's the main problem.

> How about checking unicity of the string?

As explained above, this would defeat the purpose of those functions.

> Or dropping the first argument?

This is consistent, useful (would create fewer variables) and easy to
implement: return *any* variable whose priority satisfy the
requirements, without caring about how it is displayed.

I can add this without problem.

Unfortunately, since the current interpreter creates far too many
polynomial variables [ e.g. one for each user function ], you will end
up with really polynomials if you ever need to display them, e.g. to
debug your program. 
> This would only work in assignments, however: t=varhigher() could
> create a variable with string "t".

This doesn't work: varhigher() is not implemented in the parser and
doesn't know about assignments; also you can certainly create variables
without assigning them to any symbol, or associate them to lexically
scoped symbols (which don't really have names), etc.

Thanks for the feedback !


Karim Belabas, IMB (UMR 5251)  Tel: (+33) (0)5 40 00 26 17
Universite de Bordeaux         Fax: (+33) (0)5 40 00 69 50
351, cours de la Liberation    http://www.math.u-bordeaux1.fr/~kbelabas/
F-33405 Talence (France)       http://pari.math.u-bordeaux1.fr/  [PARI/GP]