eliminate a variable if we can (not tested)
[barvinok.git] / reduce_evalue.c
blobef4af31b238efd411f302d05bc3f67b55a467986
1 #include <polylib/polylibgmp.h>
3 /*------------------------------------------------------------*/
4 /* int eequal (e1, e2) */
5 /* e1, e2 : pointers to evalues */
6 /* returns 1 (true) if they are equal, 0 (false) if not */
7 /*------------------------------------------------------------*/
8 static int eequal(evalue *e1,evalue *e2) {
10 int i;
11 enode *p1, *p2;
13 if (value_ne(e1->d,e2->d))
14 return 0;
16 /* e1->d == e2->d */
17 if (value_notzero_p(e1->d)) {
18 if (value_ne(e1->x.n,e2->x.n))
19 return 0;
21 /* e1->d == e2->d != 0 AND e1->n == e2->n */
22 return 1;
25 /* e1->d == e2->d == 0 */
26 p1 = e1->x.p;
27 p2 = e2->x.p;
28 if (p1->type != p2->type) return 0;
29 if (p1->size != p2->size) return 0;
30 if (p1->pos != p2->pos) return 0;
31 for (i=0; i<p1->size; i++)
32 if (!eequal(&p1->arr[i], &p2->arr[i]) )
33 return 0;
34 return 1;
35 } /* eequal */
37 /*------------------------------------------------------------*/
38 /* void reduce_evalue ( e ) */
39 /* e : pointer to an evalue */
40 /*------------------------------------------------------------*/
41 void reduce_evalue (evalue *e) {
43 enode *p;
44 int i, j, k;
46 if (value_notzero_p(e->d))
47 return; /* a rational number, its already reduced */
48 if(!(p = e->x.p))
49 return; /* hum... an overflow probably occured */
51 /* First reduce the components of p */
52 for (i=0; i<p->size; i++)
53 reduce_evalue(&p->arr[i]);
55 if (p->type==periodic) {
57 /* Try to reduce the period */
58 for (i=1; i<=(p->size)/2; i++) {
59 if ((p->size % i)==0) {
61 /* Can we reduce the size to i ? */
62 for (j=0; j<i; j++)
63 for (k=j+i; k<e->x.p->size; k+=i)
64 if (!eequal(&p->arr[j], &p->arr[k])) goto you_lose;
66 /* OK, lets do it */
67 for (j=i; j<p->size; j++) free_evalue_refs(&p->arr[j]);
68 p->size = i;
69 break;
71 you_lose: /* OK, lets not do it */
72 continue;
76 /* Try to reduce its strength */
77 if (p->size == 1) {
78 value_clear(e->d);
79 memcpy(e,&p->arr[0],sizeof(evalue));
80 free(p);
83 else if (p->type==polynomial) {
85 /* Try to reduce the degree */
86 for (i=p->size-1;i>=0;i--) {
87 if (value_one_p(p->arr[i].d) && value_zero_p(p->arr[i].x.n))
89 /* Zero coefficient */
90 continue;
91 else
92 break;
94 if (i==-1) p->size = 1;
95 else if (i+1<p->size) p->size = i+1;
97 /* Try to reduce its strength */
98 if (p->size == 1) {
99 value_clear(e->d);
100 memcpy(e,&p->arr[0],sizeof(evalue));
101 free(p);
104 } /* reduce_evalue */