Bill Allombert on Fri, 15 Jun 2012 12:01:34 +0200

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

Re: gp_read_str

On Fri, Jun 15, 2012 at 08:51:58AM +0200, Dirk Laurie wrote:
> 2012/6/14 Bill Allombert <>:
> > I am still not quite clear on what you need.
> Pari, by and large, is a system that works with anonymous values.
> The implied variable in a polynomial has a number, not a name.
> Names are the user's language, not the system's.  The same GEN
> that prints now as "a+b+c" will print as "c+a+b" if way back in
> my code, before the first "a" appears, I add a statement that
> involves "c".  Yes, deep down there is a table that says in what
> order I introduced the names, but Pari uses it only on the surface;
> you could say it speaks my language only when it needs to communicate
> with me.

Yes, there is a function fetch_user_name() which allow to assign name to polynomial
variables, which are used for displaying them.

> The Pari evaluator can be thought of as a stripped-down GP without the
> stuff mainly of interest to the human at the keyboard.

Yes, we even provide a minigp.c example which implement a stripped-down GP
(but rather complete) from the PARI library in less than 100 lines of code.

>  The way you
> get a name into Pari's table of variables is to actually use that name
> in an expression or as an lvalue.  No other way.

Well, at least there are no functions in libpari that change the value of
GP variables. That would be awkward.

But more to the point, when one write "b=10" what happen depend both on the state of the 
GP bytecode compiler when it is read and on the state of the evaluator when it
is executed. (e.g. b can be an alias to a, or a local variable).

> C is a language that works with names at compile-time.  You have to
> tell it what type of value you will be associating with which name.
> When working with the Pari library, one's program has lots of names whose
> associated value will be of type GEN.  Sometimes, the only available
> reference to some GEN is stored in a C variable; the Pari evaluator has
> no name for it.  This GEN has been computed during the current run, not
> read in as binary from a file, so the internal variables in it still have
> the same names as when first used.  No other code has touched its contents.
> But such a value is not accessible by the Pari evaluator.  One can freely
> use it in the C code, e.g. when calling routines from the Pari library,
> but one can't use that GEN in a GP expression â you can use only values
> associated with names that GP knows.  GP has three sources of names: names
> with which it was born, names that you have used in the past when calling
> the evaluator, and names that have added to it using `pari_add_function`.

Yes, pari_add_function is the standard mechanism for interfacing C with GP.
(In PARI 2.5, there is the converse mechanism,
closure_callgenall() et al. which allows to evaluate a GP function in a C

> You absolutely may not, must not, tamper in any way with GP's names
> and the GEN objects associated with them except by calling the Pari
> evaluator.

Let says one could easily confuse the evaluator.

> So the only way of using the C API to teach GP a new name requires that
> the name refers to a function, not a value.  (I most certainly did not
> have this insight during my previous post.)
> I am now in a position to understand the following suggestion. :-)
> > Maybe you could add an extra function to the GP interpretor that returns
> > the value of the Lua pointer:
> >    gp_read_str("b=fromlua(\"b\")");
> I can't do that.  Lua's C API gives you access to the value of an
> object, not to its name.  (Names in Lua are extremely context-dependent;
> Lua has the notion of `_ENV` which allows a switch from one set of names
> to another with a single assignment statment.)
> But you have given me the germ of a solution: I can shove the Lua values
> into a C location before calling `gp_read_str` and use such an extra
> function to retrieve them.
> Basically I have to mimic what the interactive GP does when making
> a reference to a GEN on the stack. (That part of GP is not available
> for library use.)  Thus:
> 1. Lua> setarg{p,q,r}
>    -- makes the C program store those GEN's in a static array PARAM.
> 2. The Pari evaluator will know a function `param(k)` that returns
>    `PARAM[k-1]` having range-checked `k` of course.
> 3. Lua> f=gen"$1*($2-$3)"
>    -- The "gen" function translates `$1` to `param(1)` etc before passing
>    -- the string to `gp_read_str`.
> I use `$`, not `%`, because `%` also means `modulo`.

Mayeb there are nicer ways to do that with PARI 2.5.
For example you do 
GEN code = gp_read_str("(a,b,c)->a*(b-c)");
and then
GEN res = closure_callgenvec(code, mkvec3(a,b,c))

> > And it was completely changed between 2.3 and 2.5.
> Some homework for me to do, then.

Yes, but it was really changed for the best.