Bill Allombert on Wed, 20 Sep 2006 00:29:59 +0200


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

Defining variable priority [technology preview]


Hello PARI-dev,

This is an experimental patch that allow to define new variables with
specified priority under GP.

This patch replace the varncmp() macro by a function that look up
assigned priorities.

It adds a GP function newvar which allow to create a new variable with
a specified priority (priority of x is 0).

Here an example of session:

? newvar(y,-1)
? x+y
%1 = y + x
? K=nfinit(x^2+1);
? nffactor(K,y^4+1)
%3 =
[y^2 + Mod(-x, x^2 + 1) 1]

[y^2 + Mod(x, x^2 + 1) 1]

The issues:
1) actually newvar allow to change priority of variable, but if you mix
object, yo can get strange results:
? newvar(y,1);
? x+y
%1 = x + y
? newvar(y,-1);
? x+y
%2 = y + x
? %1-%2
%3 = -y + y

2) newvar do not check if there is another variable with the same
priority, and you can get strange results:
? newvar(y,0);
? x-y
%1 = -y + x
? y-x
%2 = -x + y
? %1+%2
%3 = -x + x

Of course these are trivial issue, but they illustrate some of the
limitation of the whole concept.
In principle it is quite possible to change the priorities of variables
provides yu do not change the underlyng order.

So what should be the interface ? We should probably specify priority
relatively to another variable, either just above or just below.
Maybe we could have a default that block the creation of new variables
unless with newvar(), but then it should not consider that "z=2" create
a variable 'z.

Cheers,
Bill.

Index: src/headers/paricom.h
===================================================================
RCS file: /home/cvs/pari/src/headers/paricom.h,v
retrieving revision 1.99
diff -u -r1.99 paricom.h
--- src/headers/paricom.h	9 Sep 2006 17:42:34 -0000	1.99
+++ src/headers/paricom.h	19 Sep 2006 19:12:30 -0000
@@ -97,6 +97,7 @@
 /* Common global variables: */
 extern ulong DEBUGFILES, DEBUGLEVEL, DEBUGMEM, precdl;
 extern long  *ordvar;
+extern long  *cmpvar;
 extern THREAD GEN  bernzone,gpi,geuler;
 extern GEN   polvar,*pol_1,*pol_x,primetab;
 extern GEN   gen_m1,gen_1,gen_2,ghalf,gi,gen_0,gnil;
Index: src/headers/paridecl.h
===================================================================
RCS file: /home/cvs/pari/src/headers/paridecl.h,v
retrieving revision 1.594
diff -u -r1.594 paridecl.h
--- src/headers/paridecl.h	18 Sep 2006 14:05:16 -0000	1.594
+++ src/headers/paridecl.h	19 Sep 2006 20:11:04 -0000
@@ -261,9 +261,10 @@
 entree* install(void *f, char *name, char *code);
 entree* is_entry(char *s);
 void    kill0(entree *ep);
-GEN     readseq(char *t);
 long    manage_var(long n, entree *ep);
 void    name_var(long n, char *s);
+void    newvar(char *s, long p);
+GEN     readseq(char *t);
 GEN     strtoGENstr(const char *s);
 GEN     strtoi(char *s);
 GEN     strtor(char *s, long prec);
@@ -1259,6 +1260,7 @@
 long    timer(void);
 long    timer2(void);
 void    traverseheap( void(*f)(GEN, void *), void *data );
+long    varncmp(long x, long y);
 
 /* intnum.c */
 
Index: src/headers/parigen.h
===================================================================
RCS file: /home/cvs/pari/src/headers/parigen.h,v
retrieving revision 1.28
diff -u -r1.28 parigen.h
--- src/headers/parigen.h	16 Sep 2006 19:44:01 -0000	1.28
+++ src/headers/parigen.h	19 Sep 2006 21:57:13 -0000
@@ -130,5 +130,4 @@
 #define setvarn(x,s)  (((ulong*)(x))[1]=\
 		       (((ulong*)(x))[1]&(~VARNBITS)) | (ulong)evalvarn(s))
 
-#define varncmp(x,y)  ((x)-(y))
 
Index: src/language/anal.c
===================================================================
RCS file: /home/cvs/pari/src/language/anal.c,v
retrieving revision 1.252
diff -u -r1.252 anal.c
--- src/language/anal.c	18 Sep 2006 21:53:40 -0000	1.252
+++ src/language/anal.c	19 Sep 2006 21:12:58 -0000
@@ -2643,7 +2643,6 @@
     p = (GEN) gpmalloc(SIZEOF_VAR_POLS);
     var=max_avail--;
   }
-
   /* create pol_x[var] */
   p[0] = evaltyp(t_POL) | evallg(4);
   p[1] = evalsigne(1) | evalvarn(var);
@@ -2695,6 +2694,20 @@
 }
 
 void
+newvar(char *s, long p)
+{
+  long v = varn( initial_value(fetch_named_var(s)) );
+  cmpvar[v]=p;
+}
+
+long varncmp(long x, long y)
+{
+   if(x<0 || y<0)
+     pari_err(bugparier,"varncmp");
+   return (x<=MAXVARN?cmpvar[x]:x)-(y<=MAXVARN?cmpvar[y]:y);
+}
+
+void
 delete_named_var(entree *ep)
 {
   (void)manage_var(manage_var_pop, (entree*)varn(initial_value(ep)));
Index: src/language/init.c
===================================================================
RCS file: /home/cvs/pari/src/language/init.c,v
retrieving revision 1.313
diff -u -r1.313 init.c
--- src/language/init.c	19 Sep 2006 11:36:22 -0000	1.313
+++ src/language/init.c	19 Sep 2006 20:35:41 -0000
@@ -41,7 +41,7 @@
 gp_data *GP_DATA;
 
 entree  **varentries;
-long    *ordvar;
+long    *ordvar,*cmpvar;
 GEN     polvar, *pol_1, *pol_x;
 
 THREAD pari_sp bot, top, avma;
@@ -609,11 +609,14 @@
 
   varentries = (entree**) gpmalloc((MAXVARN+1)*sizeof(entree*));
   ordvar = (GEN) gpmalloc((MAXVARN+1)*sizeof(long));
+  cmpvar = (GEN) gpmalloc((MAXVARN+1)*sizeof(long));
   polvar = (GEN) gpmalloc((MAXVARN+1)*sizeof(long));
   pol_x = (GEN*) gpmalloc((MAXVARN+1)*sizeof(GEN));
   pol_1 = (GEN*) gpmalloc((MAXVARN+1)*sizeof(GEN));
   polvar[0] = evaltyp(t_VEC) | evallg(1);
   for (u=0; u <= MAXVARN; u++) { ordvar[u] = u; varentries[u] = NULL; }
+  for (u=0; u <= MAXVARN; u++) cmpvar[u] = u;
+
   pari_init_floats();
 
   (void)fetch_var(); /* create pol_x/pol_1[MAXVARN] */
@@ -696,6 +699,7 @@
   }
   free((void*)varentries);
   free((void*)ordvar);
+  free((void*)cmpvar);
   free((void*)polvar);
   free((void*)pol_x[MAXVARN]);
   free((void*)pol_x);