4 #include "ev_operations.h"
7 #define NALLOC(p,n) p = (typeof(p))malloc((n) * sizeof(*p))
9 void evalue_set_si(evalue
*ev
, int n
, int d
) {
10 value_set_si(ev
->d
, d
);
12 value_set_si(ev
->x
.n
, n
);
15 void evalue_set(evalue
*ev
, Value n
, Value d
) {
16 value_assign(ev
->d
, d
);
18 value_assign(ev
->x
.n
, n
);
21 void aep_evalue(evalue
*e
, int *ref
) {
26 if (value_notzero_p(e
->d
))
27 return; /* a rational number, its already reduced */
29 return; /* hum... an overflow probably occured */
31 /* First check the components of p */
32 for (i
=0;i
<p
->size
;i
++)
33 aep_evalue(&p
->arr
[i
],ref
);
36 if (p
->type
!= modulo
)
37 p
->pos
= ref
[p
->pos
-1]+1;
42 void addeliminatedparams_evalue(evalue
*e
,Matrix
*CT
) {
48 if (value_notzero_p(e
->d
))
49 return; /* a rational number, its already reduced */
51 return; /* hum... an overflow probably occured */
54 ref
= (int *)malloc(sizeof(int)*(CT
->NbRows
-1));
55 for(i
=0;i
<CT
->NbRows
-1;i
++)
56 for(j
=0;j
<CT
->NbColumns
;j
++)
57 if(value_notzero_p(CT
->p
[i
][j
])) {
62 /* Transform the references in e, using ref */
66 } /* addeliminatedparams_evalue */
76 struct fixed_param
*fixed
;
81 static int relations_depth(evalue
*e
)
86 value_zero_p(e
->d
) && e
->x
.p
->type
== relation
;
87 e
= &e
->x
.p
->arr
[1], ++d
);
91 #define EVALUE_IS_ONE(ev) (value_pos_p((ev).d) && value_one_p((ev).x.n))
93 static void realloc_substitution(struct subst
*s
, int d
)
95 struct fixed_param
*n
;
98 for (i
= 0; i
< s
->n
; ++i
)
105 static void add_modulo_substitution(struct subst
*s
, evalue
*r
)
112 assert(value_zero_p(r
->d
) && r
->x
.p
->type
== relation
);
115 /* May have been reduced already */
116 if (value_notzero_p(m
->d
))
119 if (s
->n
>= s
->max
) {
120 int d
= relations_depth(r
);
121 realloc_substitution(s
, d
);
124 assert(value_zero_p(m
->d
) && m
->x
.p
->type
== modulo
);
125 assert(m
->x
.p
->size
== 3);
126 assert(EVALUE_IS_ONE(m
->x
.p
->arr
[2]));
127 assert(EVALUE_IS_ZERO(m
->x
.p
->arr
[1]));
130 assert(value_zero_p(p
->d
) && p
->x
.p
->type
== polynomial
);
131 assert(p
->x
.p
->size
== 2);
134 assert(value_one_p(f
->d
));
135 neg
= value_neg_p(f
->x
.n
);
137 s
->fixed
[s
->n
].m
= m
->x
.p
->pos
;
138 s
->fixed
[s
->n
].pos
= p
->x
.p
->pos
;
139 value_init(s
->fixed
[s
->n
].d
);
141 value_oppose(s
->fixed
[s
->n
].d
, f
->x
.n
);
143 value_assign(s
->fixed
[s
->n
].d
, f
->x
.n
);
144 value_init(s
->fixed
[s
->n
].s
.d
);
145 evalue_copy(&s
->fixed
[s
->n
].s
, &p
->x
.p
->arr
[0]);
149 evalue_set_si(&mone
, -1, 1);
150 emul(&mone
, &s
->fixed
[s
->n
].s
);
151 free_evalue_refs(&mone
);
156 int _reduce_evalue (evalue
*e
, struct subst
*s
, int m
) {
161 if (value_notzero_p(e
->d
)) {
163 assert(value_one_p(e
->d
));
164 value_set_si(e
->d
, m
);
165 mpz_fdiv_r(e
->x
.n
, e
->x
.n
, e
->d
);
166 value_set_si(e
->d
, 1);
168 return; /* a rational number, its already reduced */
172 return; /* hum... an overflow probably occured */
174 /* First reduce the components of p */
175 for (i
=0; i
<p
->size
; i
++) {
176 int add
= p
->type
== relation
&& i
== 1;
178 add_modulo_substitution(s
, e
);
180 if (i
== 0 && p
->type
==modulo
) {
182 while ((factor
= _reduce_evalue(&p
->arr
[i
], s
, p
->pos
)) != 0) {
187 evalue_set_si(&f
, factor
, 1);
188 emul(&f
, &p
->arr
[0]);
189 value_assign(f
.d
, f
.x
.n
);
190 value_set_si(f
.x
.n
, 1);
191 assert(p
->size
>= 3);
192 emul(&f
, &p
->arr
[2]);
193 for (j
= 3; j
< p
->size
; ++j
) {
194 mpz_mul_si(f
.d
, f
.d
, factor
);
195 emul(&f
, &p
->arr
[j
]);
197 free_evalue_refs(&f
);
200 _reduce_evalue(&p
->arr
[i
], s
, m
);
204 value_clear(s
->fixed
[s
->n
].d
);
205 free_evalue_refs(&s
->fixed
[s
->n
].s
);
209 if (p
->type
==periodic
) {
211 /* Try to reduce the period */
212 for (i
=1; i
<=(p
->size
)/2; i
++) {
213 if ((p
->size
% i
)==0) {
215 /* Can we reduce the size to i ? */
217 for (k
=j
+i
; k
<e
->x
.p
->size
; k
+=i
)
218 if (!eequal(&p
->arr
[j
], &p
->arr
[k
])) goto you_lose
;
221 for (j
=i
; j
<p
->size
; j
++) free_evalue_refs(&p
->arr
[j
]);
225 you_lose
: /* OK, lets not do it */
230 /* Try to reduce its strength */
233 memcpy(e
,&p
->arr
[0],sizeof(evalue
));
237 else if (p
->type
==polynomial
) {
238 for (k
= 0; s
&& k
< s
->n
; ++k
) {
239 if (s
->fixed
[k
].pos
== p
->pos
) {
240 int divide
= value_notone_p(s
->fixed
[k
].d
);
243 if (s
->fixed
[k
].m
!= 0 && s
->fixed
[k
].m
!= m
) {
244 if (!divide
&& m
!= 0 && (s
->fixed
[k
].m
% m
== 0))
245 return s
->fixed
[k
].m
/ m
;
249 if (divide
&& m
!= 0)
254 value_assign(d
.d
, s
->fixed
[k
].d
);
256 value_set_si(d
.x
.n
, 1);
259 for (i
=p
->size
-1;i
>=1;i
--) {
260 emul(&s
->fixed
[k
].s
, &p
->arr
[i
]);
262 emul(&d
, &p
->arr
[i
]);
263 eadd(&p
->arr
[i
], &p
->arr
[i
-1]);
264 free_evalue_refs(&(p
->arr
[i
]));
267 _reduce_evalue(&p
->arr
[0], s
, m
);
270 free_evalue_refs(&d
);
276 /* Try to reduce the degree */
277 for (i
=p
->size
-1;i
>=1;i
--) {
278 if (!(value_one_p(p
->arr
[i
].d
) && value_zero_p(p
->arr
[i
].x
.n
)))
280 /* Zero coefficient */
281 free_evalue_refs(&(p
->arr
[i
]));
286 /* Try to reduce its strength */
289 memcpy(e
,&p
->arr
[0],sizeof(evalue
));
293 else if (p
->type
==modulo
) {
294 if (value_notzero_p(p
->arr
[0].d
)) {
297 value_set_si(v
.d
, 1);
299 value_set_si(p
->arr
[0].d
, p
->pos
);
300 mpz_fdiv_r(v
.x
.n
, p
->arr
[0].x
.n
, p
->arr
[0].d
);
302 for (i
=p
->size
-1;i
>=2;i
--) {
303 emul(&v
, &p
->arr
[i
]);
304 eadd(&p
->arr
[i
], &p
->arr
[i
-1]);
305 free_evalue_refs(&(p
->arr
[i
]));
308 free_evalue_refs(&v
);
309 _reduce_evalue(&p
->arr
[1], s
, m
);
312 /* Try to reduce the degree */
313 for (i
=p
->size
-1;i
>=2;i
--) {
314 if (!(value_one_p(p
->arr
[i
].d
) && value_zero_p(p
->arr
[i
].x
.n
)))
316 /* Zero coefficient */
317 free_evalue_refs(&(p
->arr
[i
]));
322 /* Try to reduce its strength */
325 memcpy(e
,&p
->arr
[1],sizeof(evalue
));
326 free_evalue_refs(&(p
->arr
[0]));
330 else if (p
->type
== relation
) {
331 if (p
->size
== 3 && EVALUE_IS_ZERO(p
->arr
[2])) {
332 free_evalue_refs(&(p
->arr
[2]));
335 if (p
->size
== 2 && EVALUE_IS_ZERO(p
->arr
[1])) {
336 free_evalue_refs(&(p
->arr
[1]));
337 free_evalue_refs(&(p
->arr
[0]));
338 evalue_set_si(e
, 0, 1);
340 } else if (value_notzero_p(p
->arr
[0].d
)) {
341 if (value_zero_p(p
->arr
[0].x
.n
)) {
343 memcpy(e
,&p
->arr
[1],sizeof(evalue
));
345 free_evalue_refs(&(p
->arr
[2]));
349 memcpy(e
,&p
->arr
[2],sizeof(evalue
));
351 evalue_set_si(e
, 0, 1);
352 free_evalue_refs(&(p
->arr
[1]));
354 free_evalue_refs(&(p
->arr
[0]));
359 } /* reduce_evalue */
361 static void add_substitution(struct subst
*s
, Value
*row
, unsigned dim
)
366 for (k
= 0; k
< dim
; ++k
)
367 if (value_notzero_p(row
[k
+1]))
370 Vector_Normalize_Positive(row
+1, dim
+1, k
);
371 assert(s
->n
< s
->max
);
372 value_init(s
->fixed
[s
->n
].d
);
373 value_assign(s
->fixed
[s
->n
].d
, row
[k
+1]);
374 s
->fixed
[s
->n
].pos
= k
+1;
375 s
->fixed
[s
->n
].m
= 0;
376 r
= &s
->fixed
[s
->n
].s
;
378 for (l
= k
+1; l
< dim
; ++l
)
379 if (value_notzero_p(row
[l
+1])) {
380 value_set_si(r
->d
, 0);
381 r
->x
.p
= new_enode(polynomial
, 2, l
+ 1);
382 value_init(r
->x
.p
->arr
[1].x
.n
);
383 value_oppose(r
->x
.p
->arr
[1].x
.n
, row
[l
+1]);
384 value_set_si(r
->x
.p
->arr
[1].d
, 1);
388 value_oppose(r
->x
.n
, row
[dim
+1]);
389 value_set_si(r
->d
, 1);
393 void reduce_evalue (evalue
*e
) {
394 if (value_notzero_p(e
->d
))
395 return; /* a rational number, its already reduced */
397 if (e
->x
.p
->type
== partition
) {
398 struct subst s
= { NULL
, 0, 0 };
401 for (i
= 0; i
< e
->x
.p
->size
/2; ++i
) {
403 Polyhedron
*D
= EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]);
404 /* This shouldn't really happen;
405 * Empty domains should not be added.
411 if (!D
->next
&& D
->NbEq
) {
415 realloc_substitution(&s
, dim
);
417 int d
= relations_depth(&e
->x
.p
->arr
[2*i
+1]);
419 NALLOC(s
.fixed
, s
.max
);
422 for (j
= 0; j
< D
->NbEq
; ++j
)
423 add_substitution(&s
, D
->Constraint
[j
], dim
);
425 _reduce_evalue(&e
->x
.p
->arr
[2*i
+1], &s
, 0);
426 if (EVALUE_IS_ZERO(e
->x
.p
->arr
[2*i
+1])) {
428 free_evalue_refs(&e
->x
.p
->arr
[2*i
+1]);
429 Domain_Free(EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]));
430 value_clear(e
->x
.p
->arr
[2*i
].d
);
432 e
->x
.p
->arr
[2*i
] = e
->x
.p
->arr
[e
->x
.p
->size
];
433 e
->x
.p
->arr
[2*i
+1] = e
->x
.p
->arr
[e
->x
.p
->size
+1];
438 for (j
= 0; j
< s
.n
; ++j
) {
439 value_clear(s
.fixed
[j
].d
);
440 free_evalue_refs(&s
.fixed
[j
].s
);
447 _reduce_evalue(e
, 0, 0);
450 void print_evalue(FILE *DST
,evalue
*e
,char **pname
) {
452 if(value_notzero_p(e
->d
)) {
453 if(value_notone_p(e
->d
)) {
454 value_print(DST
,VALUE_FMT
,e
->x
.n
);
456 value_print(DST
,VALUE_FMT
,e
->d
);
459 value_print(DST
,VALUE_FMT
,e
->x
.n
);
463 print_enode(DST
,e
->x
.p
,pname
);
467 void print_enode(FILE *DST
,enode
*p
,char **pname
) {
472 fprintf(DST
, "NULL");
478 for (i
=0; i
<p
->size
; i
++) {
479 print_evalue(DST
, &p
->arr
[i
], pname
);
483 fprintf(DST
, " }\n");
487 for (i
=p
->size
-1; i
>=0; i
--) {
488 print_evalue(DST
, &p
->arr
[i
], pname
);
489 if (i
==1) fprintf(DST
, " * %s + ", pname
[p
->pos
-1]);
491 fprintf(DST
, " * %s^%d + ", pname
[p
->pos
-1], i
);
493 fprintf(DST
, " )\n");
497 for (i
=0; i
<p
->size
; i
++) {
498 print_evalue(DST
, &p
->arr
[i
], pname
);
499 if (i
!=(p
->size
-1)) fprintf(DST
, ", ");
501 fprintf(DST
," ]_%s", pname
[p
->pos
-1]);
505 for (i
=p
->size
-1; i
>=1; i
--) {
506 print_evalue(DST
, &p
->arr
[i
], pname
);
512 print_evalue(DST
, &p
->arr
[0], pname
);
513 fprintf(DST
, ") mod %d", p
->pos
);
515 fprintf(DST
, ")^%d + ", i
-1);
517 fprintf(DST
, " + ", i
-1);
520 fprintf(DST
, " )\n");
524 print_evalue(DST
, &p
->arr
[0], pname
);
525 fprintf(DST
, "= 0 ] * \n");
526 print_evalue(DST
, &p
->arr
[1], pname
);
528 fprintf(DST
, " +\n [ ");
529 print_evalue(DST
, &p
->arr
[0], pname
);
530 fprintf(DST
, "!= 0 ] * \n");
531 print_evalue(DST
, &p
->arr
[2], pname
);
535 for (i
=0; i
<p
->size
/2; i
++) {
536 Print_Domain(DST
, EVALUE_DOMAIN(p
->arr
[2*i
]), pname
);
537 print_evalue(DST
, &p
->arr
[2*i
+1], pname
);
546 static int mod_term_smaller(evalue
*e1
, evalue
*e2
)
548 if (value_notzero_p(e1
->d
)) {
549 if (value_zero_p(e2
->d
))
551 return value_lt(e1
->x
.n
, e2
->x
.n
);
553 if (value_notzero_p(e2
->d
))
555 if (e1
->x
.p
->pos
< e2
->x
.p
->pos
)
557 else if (e1
->x
.p
->pos
> e2
->x
.p
->pos
)
560 return mod_term_smaller(&e1
->x
.p
->arr
[0], &e2
->x
.p
->arr
[0]);
563 static void eadd_rev(evalue
*e1
, evalue
*res
)
567 evalue_copy(&ev
, e1
);
569 free_evalue_refs(res
);
573 static void eadd_rev_cst (evalue
*e1
, evalue
*res
)
577 evalue_copy(&ev
, e1
);
578 eadd(res
, &ev
.x
.p
->arr
[ev
.x
.p
->type
==modulo
]);
579 free_evalue_refs(res
);
583 struct section
{ Polyhedron
* D
; evalue E
; };
585 void eadd_partitions (evalue
*e1
,evalue
*res
)
590 s
= (struct section
*)
591 malloc((e1
->x
.p
->size
/2+1) * (res
->x
.p
->size
/2+1) *
592 sizeof(struct section
));
596 for (j
= 0; j
< e1
->x
.p
->size
/2; ++j
) {
597 assert(res
->x
.p
->size
>= 2);
598 fd
= DomainDifference(EVALUE_DOMAIN(e1
->x
.p
->arr
[2*j
]),
599 EVALUE_DOMAIN(res
->x
.p
->arr
[0]), 0);
601 for (i
= 1; i
< res
->x
.p
->size
/2; ++i
) {
603 fd
= DomainDifference(fd
, EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]), 0);
612 value_init(s
[n
].E
.d
);
613 evalue_copy(&s
[n
].E
, &e1
->x
.p
->arr
[2*j
+1]);
617 for (i
= 0; i
< res
->x
.p
->size
/2; ++i
) {
618 fd
= EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]);
619 for (j
= 0; j
< e1
->x
.p
->size
/2; ++j
) {
621 d
= DomainIntersection(EVALUE_DOMAIN(e1
->x
.p
->arr
[2*j
]),
622 EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]), 0);
628 fd
= DomainDifference(fd
, EVALUE_DOMAIN(e1
->x
.p
->arr
[2*j
]), 0);
629 if (t
!= EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]))
631 value_init(s
[n
].E
.d
);
632 evalue_copy(&s
[n
].E
, &res
->x
.p
->arr
[2*i
+1]);
633 eadd(&e1
->x
.p
->arr
[2*j
+1], &s
[n
].E
);
638 s
[n
].E
= res
->x
.p
->arr
[2*i
+1];
642 free_evalue_refs(&res
->x
.p
->arr
[2*i
+1]);
645 if (fd
!= EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]))
646 Domain_Free(EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]));
647 value_clear(res
->x
.p
->arr
[2*i
].d
);
651 res
->x
.p
= new_enode(partition
, 2*n
, -1);
652 for (j
= 0; j
< n
; ++j
) {
653 s
[j
].D
= DomainConstraintSimplify(s
[j
].D
, 0);
654 EVALUE_SET_DOMAIN(res
->x
.p
->arr
[2*j
], s
[j
].D
);
655 value_clear(res
->x
.p
->arr
[2*j
+1].d
);
656 res
->x
.p
->arr
[2*j
+1] = s
[j
].E
;
662 static void explicit_complement(evalue
*res
)
664 enode
*rel
= new_enode(relation
, 3, 0);
666 value_clear(rel
->arr
[0].d
);
667 rel
->arr
[0] = res
->x
.p
->arr
[0];
668 value_clear(rel
->arr
[1].d
);
669 rel
->arr
[1] = res
->x
.p
->arr
[1];
670 value_set_si(rel
->arr
[2].d
, 1);
671 value_init(rel
->arr
[2].x
.n
);
672 value_set_si(rel
->arr
[2].x
.n
, 0);
677 void eadd(evalue
*e1
,evalue
*res
) {
680 if (value_notzero_p(e1
->d
) && value_notzero_p(res
->d
)) {
681 /* Add two rational numbers */
687 value_multiply(m1
,e1
->x
.n
,res
->d
);
688 value_multiply(m2
,res
->x
.n
,e1
->d
);
689 value_addto(res
->x
.n
,m1
,m2
);
690 value_multiply(res
->d
,e1
->d
,res
->d
);
691 Gcd(res
->x
.n
,res
->d
,&g
);
692 if (value_notone_p(g
)) {
693 value_division(res
->d
,res
->d
,g
);
694 value_division(res
->x
.n
,res
->x
.n
,g
);
696 value_clear(g
); value_clear(m1
); value_clear(m2
);
699 else if (value_notzero_p(e1
->d
) && value_zero_p(res
->d
)) {
700 switch (res
->x
.p
->type
) {
702 /* Add the constant to the constant term of a polynomial*/
703 eadd(e1
, &res
->x
.p
->arr
[0]);
706 /* Add the constant to all elements of a periodic number */
707 for (i
=0; i
<res
->x
.p
->size
; i
++) {
708 eadd(e1
, &res
->x
.p
->arr
[i
]);
712 fprintf(stderr
, "eadd: cannot add const with vector\n");
715 eadd(e1
, &res
->x
.p
->arr
[1]);
718 assert(EVALUE_IS_ZERO(*e1
));
719 break; /* Do nothing */
721 /* Create (zero) complement if needed */
722 if (res
->x
.p
->size
< 3 && !EVALUE_IS_ZERO(*e1
))
723 explicit_complement(res
);
724 for (i
= 1; i
< res
->x
.p
->size
; ++i
)
725 eadd(e1
, &res
->x
.p
->arr
[i
]);
731 /* add polynomial or periodic to constant
732 * you have to exchange e1 and res, before doing addition */
734 else if (value_zero_p(e1
->d
) && value_notzero_p(res
->d
)) {
738 else { // ((e1->d==0) && (res->d==0))
739 assert(!((e1
->x
.p
->type
== partition
) ^
740 (res
->x
.p
->type
== partition
)));
741 if (e1
->x
.p
->type
== partition
) {
742 eadd_partitions(e1
, res
);
745 if (e1
->x
.p
->type
== relation
&&
746 (res
->x
.p
->type
!= relation
||
747 mod_term_smaller(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0]))) {
751 if (res
->x
.p
->type
== relation
) {
752 if (e1
->x
.p
->type
== relation
&&
753 eequal(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0])) {
754 if (res
->x
.p
->size
< 3 && e1
->x
.p
->size
== 3)
755 explicit_complement(res
);
756 if (e1
->x
.p
->size
< 3 && res
->x
.p
->size
== 3)
757 explicit_complement(e1
);
758 for (i
= 1; i
< res
->x
.p
->size
; ++i
)
759 eadd(&e1
->x
.p
->arr
[i
], &res
->x
.p
->arr
[i
]);
762 if (res
->x
.p
->size
< 3)
763 explicit_complement(res
);
764 for (i
= 1; i
< res
->x
.p
->size
; ++i
)
765 eadd(e1
, &res
->x
.p
->arr
[i
]);
768 if ((e1
->x
.p
->type
!= res
->x
.p
->type
) ) {
769 /* adding to evalues of different type. two cases are possible
770 * res is periodic and e1 is polynomial, you have to exchange
771 * e1 and res then to add e1 to the constant term of res */
772 if (e1
->x
.p
->type
== polynomial
) {
773 eadd_rev_cst(e1
, res
);
775 else if (res
->x
.p
->type
== polynomial
) {
776 /* res is polynomial and e1 is periodic,
777 add e1 to the constant term of res */
779 eadd(e1
,&res
->x
.p
->arr
[0]);
785 else if (e1
->x
.p
->pos
!= res
->x
.p
->pos
||
786 (res
->x
.p
->type
== modulo
&&
787 !eequal(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0]))) {
788 /* adding evalues of different position (i.e function of different unknowns
789 * to case are possible */
791 switch (res
->x
.p
->type
) {
793 if(mod_term_smaller(res
, e1
))
794 eadd(e1
,&res
->x
.p
->arr
[1]);
796 eadd_rev_cst(e1
, res
);
798 case polynomial
: // res and e1 are polynomials
799 // add e1 to the constant term of res
801 if(res
->x
.p
->pos
< e1
->x
.p
->pos
)
802 eadd(e1
,&res
->x
.p
->arr
[0]);
804 eadd_rev_cst(e1
, res
);
805 // value_clear(g); value_clear(m1); value_clear(m2);
807 case periodic
: // res and e1 are pointers to periodic numbers
808 //add e1 to all elements of res
810 if(res
->x
.p
->pos
< e1
->x
.p
->pos
)
811 for (i
=0;i
<res
->x
.p
->size
;i
++) {
812 eadd(e1
,&res
->x
.p
->arr
[i
]);
821 //same type , same pos and same size
822 if (e1
->x
.p
->size
== res
->x
.p
->size
) {
823 // add any element in e1 to the corresponding element in res
824 if (res
->x
.p
->type
== modulo
)
825 assert(eequal(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0]));
826 i
= res
->x
.p
->type
== modulo
? 1 : 0;
827 for (; i
<res
->x
.p
->size
; i
++) {
828 eadd(&e1
->x
.p
->arr
[i
], &res
->x
.p
->arr
[i
]);
833 /* Sizes are different */
834 switch(res
->x
.p
->type
) {
837 /* VIN100: if e1-size > res-size you have to copy e1 in a */
838 /* new enode and add res to that new node. If you do not do */
839 /* that, you lose the the upper weight part of e1 ! */
841 if(e1
->x
.p
->size
> res
->x
.p
->size
)
845 if (res
->x
.p
->type
== modulo
)
846 assert(eequal(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0]));
847 i
= res
->x
.p
->type
== modulo
? 1 : 0;
848 for (; i
<e1
->x
.p
->size
; i
++) {
849 eadd(&e1
->x
.p
->arr
[i
], &res
->x
.p
->arr
[i
]);
856 /* add two periodics of the same pos (unknown) but whith different sizes (periods) */
859 /* you have to create a new evalue 'ne' in whitch size equals to the lcm
860 of the sizes of e1 and res, then to copy res periodicaly in ne, after
861 to add periodicaly elements of e1 to elements of ne, and finaly to
866 value_init(ex
); value_init(ey
);value_init(ep
);
869 value_set_si(ex
,e1
->x
.p
->size
);
870 value_set_si(ey
,res
->x
.p
->size
);
871 value_assign (ep
,*Lcm(ex
,ey
));
872 p
=(int)mpz_get_si(ep
);
873 ne
= (evalue
*) malloc (sizeof(evalue
));
875 value_set_si( ne
->d
,0);
877 ne
->x
.p
=new_enode(res
->x
.p
->type
,p
, res
->x
.p
->pos
);
879 value_assign(ne
->x
.p
->arr
[i
].d
, res
->x
.p
->arr
[i
%y
].d
);
880 if (value_notzero_p(ne
->x
.p
->arr
[i
].d
)) {
881 value_init(ne
->x
.p
->arr
[i
].x
.n
);
882 value_assign(ne
->x
.p
->arr
[i
].x
.n
, res
->x
.p
->arr
[i
%y
].x
.n
);
885 ne
->x
.p
->arr
[i
].x
.p
=ecopy(res
->x
.p
->arr
[i
%y
].x
.p
);
889 eadd(&e1
->x
.p
->arr
[i
%x
], &ne
->x
.p
->arr
[i
]);
892 value_assign(res
->d
, ne
->d
);
898 fprintf(stderr
, "eadd: ?cannot add vectors of different length\n");
905 static void emul_rev (evalue
*e1
, evalue
*res
)
909 evalue_copy(&ev
, e1
);
911 free_evalue_refs(res
);
915 static void emul_poly (evalue
*e1
, evalue
*res
)
917 int i
, j
, o
= res
->x
.p
->type
== modulo
;
919 int size
=(e1
->x
.p
->size
+ res
->x
.p
->size
- o
- 1);
921 value_set_si(tmp
.d
,0);
922 tmp
.x
.p
=new_enode(res
->x
.p
->type
, size
, res
->x
.p
->pos
);
924 evalue_copy(&tmp
.x
.p
->arr
[0], &e1
->x
.p
->arr
[0]);
925 for (i
=o
; i
< e1
->x
.p
->size
; i
++) {
926 evalue_copy(&tmp
.x
.p
->arr
[i
], &e1
->x
.p
->arr
[i
]);
927 emul(&res
->x
.p
->arr
[o
], &tmp
.x
.p
->arr
[i
]);
930 evalue_set_si(&tmp
.x
.p
->arr
[i
], 0, 1);
931 for (i
=o
+1; i
<res
->x
.p
->size
; i
++)
932 for (j
=o
; j
<e1
->x
.p
->size
; j
++) {
935 evalue_copy(&ev
, &e1
->x
.p
->arr
[j
]);
936 emul(&res
->x
.p
->arr
[i
], &ev
);
937 eadd(&ev
, &tmp
.x
.p
->arr
[i
+j
-o
]);
938 free_evalue_refs(&ev
);
940 free_evalue_refs(res
);
944 void emul_partitions (evalue
*e1
,evalue
*res
)
949 s
= (struct section
*)
950 malloc((e1
->x
.p
->size
/2) * (res
->x
.p
->size
/2) *
951 sizeof(struct section
));
955 for (i
= 0; i
< res
->x
.p
->size
/2; ++i
) {
956 for (j
= 0; j
< e1
->x
.p
->size
/2; ++j
) {
957 d
= DomainIntersection(EVALUE_DOMAIN(e1
->x
.p
->arr
[2*j
]),
958 EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]), 0);
964 /* This code is only needed because the partitions
965 are not true partitions.
967 for (k
= 0; k
< n
; ++k
) {
968 if (DomainIncludes(s
[k
].D
, d
))
970 if (DomainIncludes(d
, s
[k
].D
)) {
972 free_evalue_refs(&s
[k
].E
);
983 value_init(s
[n
].E
.d
);
984 evalue_copy(&s
[n
].E
, &res
->x
.p
->arr
[2*i
+1]);
985 emul(&e1
->x
.p
->arr
[2*j
+1], &s
[n
].E
);
989 Domain_Free(EVALUE_DOMAIN(res
->x
.p
->arr
[2*i
]));
990 value_clear(res
->x
.p
->arr
[2*i
].d
);
991 free_evalue_refs(&res
->x
.p
->arr
[2*i
+1]);
995 res
->x
.p
= new_enode(partition
, 2*n
, -1);
996 for (j
= 0; j
< n
; ++j
) {
997 s
[j
].D
= DomainConstraintSimplify(s
[j
].D
, 0);
998 EVALUE_SET_DOMAIN(res
->x
.p
->arr
[2*j
], s
[j
].D
);
999 value_clear(res
->x
.p
->arr
[2*j
+1].d
);
1000 res
->x
.p
->arr
[2*j
+1] = s
[j
].E
;
1006 /* Computes the product of two evalues "e1" and "res" and puts the result in "res". you must
1007 * do a copy of "res" befor calling this function if you nead it after. The vector type of
1008 * evalues is not treated here */
1010 void emul (evalue
*e1
, evalue
*res
){
1013 if((value_zero_p(e1
->d
)&&e1
->x
.p
->type
==evector
)||(value_zero_p(res
->d
)&&(res
->x
.p
->type
==evector
))) {
1014 fprintf(stderr
, "emul: do not proced on evector type !\n");
1018 if (value_zero_p(e1
->d
) && e1
->x
.p
->type
== partition
) {
1019 if (value_zero_p(res
->d
) && res
->x
.p
->type
== partition
)
1020 emul_partitions(e1
, res
);
1023 } else if (value_zero_p(res
->d
) && res
->x
.p
->type
== partition
) {
1024 for (i
= 0; i
< res
->x
.p
->size
/2; ++i
)
1025 emul(e1
, &res
->x
.p
->arr
[2*i
+1]);
1027 if (value_zero_p(res
->d
) && res
->x
.p
->type
== relation
) {
1028 if (value_zero_p(e1
->d
) && e1
->x
.p
->type
== relation
&&
1029 eequal(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0])) {
1030 if (res
->x
.p
->size
< 3 && e1
->x
.p
->size
== 3)
1031 explicit_complement(res
);
1032 if (e1
->x
.p
->size
< 3 && res
->x
.p
->size
== 3)
1033 explicit_complement(e1
);
1034 for (i
= 1; i
< res
->x
.p
->size
; ++i
)
1035 emul(&e1
->x
.p
->arr
[i
], &res
->x
.p
->arr
[i
]);
1038 for (i
= 1; i
< res
->x
.p
->size
; ++i
)
1039 emul(e1
, &res
->x
.p
->arr
[i
]);
1041 if(value_zero_p(e1
->d
)&& value_zero_p(res
->d
)) {
1042 switch(e1
->x
.p
->type
) {
1044 switch(res
->x
.p
->type
) {
1046 if(e1
->x
.p
->pos
== res
->x
.p
->pos
) {
1047 /* Product of two polynomials of the same variable */
1052 /* Product of two polynomials of different variables */
1054 if(res
->x
.p
->pos
< e1
->x
.p
->pos
)
1055 for( i
=0; i
<res
->x
.p
->size
; i
++)
1056 emul(e1
, &res
->x
.p
->arr
[i
]);
1064 /* Product of a polynomial and a periodic or modulo */
1069 switch(res
->x
.p
->type
) {
1071 if(e1
->x
.p
->pos
==res
->x
.p
->pos
&& e1
->x
.p
->size
==res
->x
.p
->size
) {
1072 /* Product of two periodics of the same parameter and period */
1074 for(i
=0; i
<res
->x
.p
->size
;i
++)
1075 emul(&(e1
->x
.p
->arr
[i
]), &(res
->x
.p
->arr
[i
]));
1080 if(e1
->x
.p
->pos
==res
->x
.p
->pos
&& e1
->x
.p
->size
!=res
->x
.p
->size
) {
1081 /* Product of two periodics of the same parameter and different periods */
1085 value_init(x
); value_init(y
);value_init(z
);
1088 value_set_si(x
,e1
->x
.p
->size
);
1089 value_set_si(y
,res
->x
.p
->size
);
1090 value_assign (z
,*Lcm(x
,y
));
1091 lcm
=(int)mpz_get_si(z
);
1092 newp
= (evalue
*) malloc (sizeof(evalue
));
1093 value_init(newp
->d
);
1094 value_set_si( newp
->d
,0);
1095 newp
->x
.p
=new_enode(periodic
,lcm
, e1
->x
.p
->pos
);
1096 for(i
=0;i
<lcm
;i
++) {
1097 value_assign(newp
->x
.p
->arr
[i
].d
, res
->x
.p
->arr
[i
%iy
].d
);
1098 if (value_notzero_p(newp
->x
.p
->arr
[i
].d
)) {
1099 value_assign(newp
->x
.p
->arr
[i
].x
.n
, res
->x
.p
->arr
[i
%iy
].x
.n
);
1102 newp
->x
.p
->arr
[i
].x
.p
=ecopy(res
->x
.p
->arr
[i
%iy
].x
.p
);
1107 emul(&e1
->x
.p
->arr
[i
%ix
], &newp
->x
.p
->arr
[i
]);
1109 value_assign(res
->d
,newp
->d
);
1112 value_clear(x
); value_clear(y
);value_clear(z
);
1116 /* Product of two periodics of different parameters */
1118 for(i
=0; i
<res
->x
.p
->size
; i
++)
1119 emul(e1
, &(res
->x
.p
->arr
[i
]));
1125 /* Product of a periodic and a polynomial */
1127 for(i
=0; i
<res
->x
.p
->size
; i
++)
1128 emul(e1
, &(res
->x
.p
->arr
[i
]));
1134 switch(res
->x
.p
->type
) {
1136 for(i
=0; i
<res
->x
.p
->size
; i
++)
1137 emul(e1
, &(res
->x
.p
->arr
[i
]));
1142 if (e1
->x
.p
->pos
== res
->x
.p
->pos
&&
1143 eequal(&e1
->x
.p
->arr
[0], &res
->x
.p
->arr
[0])) {
1144 if (e1
->x
.p
->pos
!= 2)
1148 /* x mod 2 == (x mod 2)^2 */
1149 /* a0 b0 + (a0 b1 + a1 b0 + a1 b1) (x mod 2) */
1150 assert(e1
->x
.p
->size
== 3);
1151 assert(res
->x
.p
->size
== 3);
1153 evalue_copy(&tmp
, &res
->x
.p
->arr
[1]);
1154 eadd(&res
->x
.p
->arr
[2], &tmp
);
1155 emul(&e1
->x
.p
->arr
[2], &tmp
);
1156 emul(&e1
->x
.p
->arr
[1], res
);
1157 eadd(&tmp
, &res
->x
.p
->arr
[2]);
1158 free_evalue_refs(&tmp
);
1161 if(mod_term_smaller(res
, e1
))
1162 for(i
=1; i
<res
->x
.p
->size
; i
++)
1163 emul(e1
, &(res
->x
.p
->arr
[i
]));
1178 if (value_notzero_p(e1
->d
)&& value_notzero_p(res
->d
)) {
1179 /* Product of two rational numbers */
1183 value_multiply(res
->d
,e1
->d
,res
->d
);
1184 value_multiply(res
->x
.n
,e1
->x
.n
,res
->x
.n
);
1185 Gcd(res
->x
.n
, res
->d
,&g
);
1186 if (value_notone_p(g
)) {
1187 value_division(res
->d
,res
->d
,g
);
1188 value_division(res
->x
.n
,res
->x
.n
,g
);
1194 if(value_zero_p(e1
->d
)&& value_notzero_p(res
->d
)) {
1195 /* Product of an expression (polynomial or peririodic) and a rational number */
1201 /* Product of a rationel number and an expression (polynomial or peririodic) */
1203 i
= res
->x
.p
->type
== modulo
? 1 : 0;
1204 for (; i
<res
->x
.p
->size
; i
++)
1205 emul(e1
, &res
->x
.p
->arr
[i
]);
1216 void emask(evalue
*mask
, evalue
*res
) {
1222 if (EVALUE_IS_ZERO(*res
))
1225 assert(value_zero_p(mask
->d
));
1226 assert(mask
->x
.p
->type
== partition
);
1227 assert(value_zero_p(res
->d
));
1228 assert(res
->x
.p
->type
== partition
);
1230 s
= (struct section
*)
1231 malloc((mask
->x
.p
->size
/2+1) * (res
->x
.p
->size
/2) *
1232 sizeof(struct section
));
1236 evalue_set_si(&mone
, -1, 1);
1239 for (j
= 0; j
< res
->x
.p
->size
/2; ++j
) {
1240 assert(mask
->x
.p
->size
>= 2);
1241 fd
= DomainDifference(EVALUE_DOMAIN(res
->x
.p
->arr
[2*j
]),
1242 EVALUE_DOMAIN(mask
->x
.p
->arr
[0]), 0);
1244 for (i
= 1; i
< mask
->x
.p
->size
/2; ++i
) {
1246 fd
= DomainDifference(fd
, EVALUE_DOMAIN(mask
->x
.p
->arr
[2*i
]), 0);
1255 value_init(s
[n
].E
.d
);
1256 evalue_copy(&s
[n
].E
, &res
->x
.p
->arr
[2*j
+1]);
1260 for (i
= 0; i
< mask
->x
.p
->size
/2; ++i
) {
1261 if (EVALUE_IS_ONE(mask
->x
.p
->arr
[2*i
+1]))
1264 fd
= EVALUE_DOMAIN(mask
->x
.p
->arr
[2*i
]);
1265 eadd(&mone
, &mask
->x
.p
->arr
[2*i
+1]);
1266 emul(&mone
, &mask
->x
.p
->arr
[2*i
+1]);
1267 for (j
= 0; j
< res
->x
.p
->size
/2; ++j
) {
1269 d
= DomainIntersection(EVALUE_DOMAIN(res
->x
.p
->arr
[2*j
]),
1270 EVALUE_DOMAIN(mask
->x
.p
->arr
[2*i
]), 0);
1276 fd
= DomainDifference(fd
, EVALUE_DOMAIN(res
->x
.p
->arr
[2*j
]), 0);
1277 if (t
!= EVALUE_DOMAIN(mask
->x
.p
->arr
[2*i
]))
1279 value_init(s
[n
].E
.d
);
1280 evalue_copy(&s
[n
].E
, &res
->x
.p
->arr
[2*j
+1]);
1281 emul(&mask
->x
.p
->arr
[2*i
+1], &s
[n
].E
);
1287 /* Just ignore; this may have been previously masked off */
1291 free_evalue_refs(&mone
);
1292 free_evalue_refs(mask
);
1293 free_evalue_refs(res
);
1296 evalue_set_si(res
, 0, 1);
1298 res
->x
.p
= new_enode(partition
, 2*n
, -1);
1299 for (j
= 0; j
< n
; ++j
) {
1300 EVALUE_SET_DOMAIN(res
->x
.p
->arr
[2*j
], s
[j
].D
);
1301 value_clear(res
->x
.p
->arr
[2*j
+1].d
);
1302 res
->x
.p
->arr
[2*j
+1] = s
[j
].E
;
1309 void evalue_copy(evalue
*dst
, evalue
*src
)
1311 value_assign(dst
->d
, src
->d
);
1312 if(value_notzero_p(src
->d
)) {
1313 value_init(dst
->x
.n
);
1314 value_assign(dst
->x
.n
, src
->x
.n
);
1316 dst
->x
.p
= ecopy(src
->x
.p
);
1319 enode
*new_enode(enode_type type
,int size
,int pos
) {
1325 fprintf(stderr
, "Allocating enode of size 0 !\n" );
1328 res
= (enode
*) malloc(sizeof(enode
) + (size
-1)*sizeof(evalue
));
1332 for(i
=0; i
<size
; i
++) {
1333 value_init(res
->arr
[i
].d
);
1334 value_set_si(res
->arr
[i
].d
,0);
1335 res
->arr
[i
].x
.p
= 0;
1340 enode
*ecopy(enode
*e
) {
1345 res
= new_enode(e
->type
,e
->size
,e
->pos
);
1346 for(i
=0;i
<e
->size
;++i
) {
1347 value_assign(res
->arr
[i
].d
,e
->arr
[i
].d
);
1348 if(value_zero_p(res
->arr
[i
].d
))
1349 res
->arr
[i
].x
.p
= ecopy(e
->arr
[i
].x
.p
);
1350 else if (EVALUE_IS_DOMAIN(res
->arr
[i
]))
1351 EVALUE_SET_DOMAIN(res
->arr
[i
], Domain_Copy(EVALUE_DOMAIN(e
->arr
[i
])));
1353 value_init(res
->arr
[i
].x
.n
);
1354 value_assign(res
->arr
[i
].x
.n
,e
->arr
[i
].x
.n
);
1360 int eequal(evalue
*e1
,evalue
*e2
) {
1365 if (value_ne(e1
->d
,e2
->d
))
1368 /* e1->d == e2->d */
1369 if (value_notzero_p(e1
->d
)) {
1370 if (value_ne(e1
->x
.n
,e2
->x
.n
))
1373 /* e1->d == e2->d != 0 AND e1->n == e2->n */
1377 /* e1->d == e2->d == 0 */
1380 if (p1
->type
!= p2
->type
) return 0;
1381 if (p1
->size
!= p2
->size
) return 0;
1382 if (p1
->pos
!= p2
->pos
) return 0;
1383 for (i
=0; i
<p1
->size
; i
++)
1384 if (!eequal(&p1
->arr
[i
], &p2
->arr
[i
]) )
1389 void free_evalue_refs(evalue
*e
) {
1394 if (EVALUE_IS_DOMAIN(*e
)) {
1395 Domain_Free(EVALUE_DOMAIN(*e
));
1398 } else if (value_pos_p(e
->d
)) {
1400 /* 'e' stores a constant */
1402 value_clear(e
->x
.n
);
1405 assert(value_zero_p(e
->d
));
1408 if (!p
) return; /* null pointer */
1409 for (i
=0; i
<p
->size
; i
++) {
1410 free_evalue_refs(&(p
->arr
[i
]));
1414 } /* free_evalue_refs */
1416 static void mod2table_r(evalue
*e
, Vector
*periods
, Value m
, int p
,
1417 Vector
* val
, evalue
*res
)
1419 unsigned nparam
= periods
->Size
;
1422 double d
= compute_evalue(e
, val
->p
);
1427 value_set_si(res
->d
, 1);
1428 value_init(res
->x
.n
);
1429 value_set_double(res
->x
.n
, d
);
1430 mpz_fdiv_r(res
->x
.n
, res
->x
.n
, m
);
1433 if (value_one_p(periods
->p
[p
]))
1434 mod2table_r(e
, periods
, m
, p
+1, val
, res
);
1439 value_assign(tmp
, periods
->p
[p
]);
1440 value_set_si(res
->d
, 0);
1441 res
->x
.p
= new_enode(periodic
, VALUE_TO_INT(tmp
), p
+1);
1443 value_decrement(tmp
, tmp
);
1444 value_assign(val
->p
[p
], tmp
);
1445 mod2table_r(e
, periods
, m
, p
+1, val
,
1446 &res
->x
.p
->arr
[VALUE_TO_INT(tmp
)]);
1447 } while (value_pos_p(tmp
));
1453 void evalue_mod2table(evalue
*e
, int nparam
)
1458 if (EVALUE_IS_DOMAIN(*e
) || value_pos_p(e
->d
))
1461 for (i
=0; i
<p
->size
; i
++) {
1462 evalue_mod2table(&(p
->arr
[i
]), nparam
);
1464 if (p
->type
== modulo
) {
1465 Vector
*periods
= Vector_Alloc(nparam
);
1466 Vector
*val
= Vector_Alloc(nparam
);
1472 value_set_si(tmp
, p
->pos
);
1473 Vector_Set(periods
->p
, 1, nparam
);
1474 Vector_Set(val
->p
, 0, nparam
);
1475 for (ev
= &p
->arr
[0]; value_zero_p(ev
->d
); ev
= &ev
->x
.p
->arr
[0]) {
1478 assert(p
->type
== polynomial
);
1479 assert(p
->size
== 2);
1480 assert(value_one_p(p
->arr
[1].d
));
1481 Gcd(tmp
, p
->arr
[1].x
.n
, &periods
->p
[p
->pos
-1]);
1482 value_division(periods
->p
[p
->pos
-1], tmp
, periods
->p
[p
->pos
-1]);
1484 value_set_si(tmp
, p
->pos
);
1486 mod2table_r(&p
->arr
[0], periods
, tmp
, 0, val
, &EP
);
1489 evalue_set_si(&res
, 0, 1);
1490 /* Compute the polynomial using Horner's rule */
1491 for (i
=p
->size
-1;i
>1;i
--) {
1492 eadd(&p
->arr
[i
], &res
);
1495 eadd(&p
->arr
[1], &res
);
1497 free_evalue_refs(e
);
1498 free_evalue_refs(&EP
);
1503 Vector_Free(periods
);
1505 } /* evalue_mod2table */
1507 /********************************************************/
1508 /* function in domain */
1509 /* check if the parameters in list_args */
1510 /* verifies the constraints of Domain P */
1511 /********************************************************/
1512 int in_domain(Polyhedron
*P
, Value
*list_args
) {
1515 Value v
; /* value of the constraint of a row when
1516 parameters are instanciated*/
1522 /*P->Constraint constraint matrice of polyhedron P*/
1523 for(row
=0;row
<P
->NbConstraints
;row
++) {
1524 value_assign(v
,P
->Constraint
[row
][P
->Dimension
+1]); /*constant part*/
1525 for(col
=1;col
<P
->Dimension
+1;col
++) {
1526 value_multiply(tmp
,P
->Constraint
[row
][col
],list_args
[col
-1]);
1527 value_addto(v
,v
,tmp
);
1529 if (value_notzero_p(P
->Constraint
[row
][0])) {
1531 /*if v is not >=0 then this constraint is not respected */
1532 if (value_neg_p(v
)) {
1536 return P
->next
? in_domain(P
->next
, list_args
) : 0;
1541 /*if v is not = 0 then this constraint is not respected */
1542 if (value_notzero_p(v
))
1547 /*if not return before this point => all
1548 the constraints are respected */
1554 /****************************************************/
1555 /* function compute enode */
1556 /* compute the value of enode p with parameters */
1557 /* list "list_args */
1558 /* compute the polynomial or the periodic */
1559 /****************************************************/
1561 static double compute_enode(enode
*p
, Value
*list_args
) {
1573 if (p
->type
== polynomial
) {
1575 value_assign(param
,list_args
[p
->pos
-1]);
1577 /* Compute the polynomial using Horner's rule */
1578 for (i
=p
->size
-1;i
>0;i
--) {
1579 res
+=compute_evalue(&p
->arr
[i
],list_args
);
1580 res
*=VALUE_TO_DOUBLE(param
);
1582 res
+=compute_evalue(&p
->arr
[0],list_args
);
1584 else if (p
->type
== modulo
) {
1585 double d
= compute_evalue(&p
->arr
[0], list_args
);
1590 value_set_double(param
, d
);
1591 value_set_si(m
, p
->pos
);
1592 mpz_fdiv_r(param
, param
, m
);
1594 /* Compute the polynomial using Horner's rule */
1595 for (i
=p
->size
-1;i
>1;i
--) {
1596 res
+=compute_evalue(&p
->arr
[i
],list_args
);
1597 res
*=VALUE_TO_DOUBLE(param
);
1599 res
+=compute_evalue(&p
->arr
[1],list_args
);
1601 else if (p
->type
== periodic
) {
1602 value_assign(param
,list_args
[p
->pos
-1]);
1604 /* Choose the right element of the periodic */
1605 value_absolute(m
,param
);
1606 value_set_si(param
,p
->size
);
1607 value_modulus(m
,m
,param
);
1608 res
= compute_evalue(&p
->arr
[VALUE_TO_INT(m
)],list_args
);
1610 else if (p
->type
== relation
) {
1611 if (fabs(compute_evalue(&p
->arr
[0], list_args
)) < 0.5)
1612 res
= compute_evalue(&p
->arr
[1], list_args
);
1613 else if (p
->size
> 2)
1614 res
= compute_evalue(&p
->arr
[2], list_args
);
1616 else if (p
->type
== partition
) {
1617 for (i
= 0; i
< p
->size
/2; ++i
)
1618 if (in_domain(EVALUE_DOMAIN(p
->arr
[2*i
]), list_args
)) {
1619 res
= compute_evalue(&p
->arr
[2*i
+1], list_args
);
1626 } /* compute_enode */
1628 /*************************************************/
1629 /* return the value of Ehrhart Polynomial */
1630 /* It returns a double, because since it is */
1631 /* a recursive function, some intermediate value */
1632 /* might not be integral */
1633 /*************************************************/
1635 double compute_evalue(evalue
*e
,Value
*list_args
) {
1639 if (value_notzero_p(e
->d
)) {
1640 if (value_notone_p(e
->d
))
1641 res
= VALUE_TO_DOUBLE(e
->x
.n
) / VALUE_TO_DOUBLE(e
->d
);
1643 res
= VALUE_TO_DOUBLE(e
->x
.n
);
1646 res
= compute_enode(e
->x
.p
,list_args
);
1648 } /* compute_evalue */
1651 /****************************************************/
1652 /* function compute_poly : */
1653 /* Check for the good validity domain */
1654 /* return the number of point in the Polyhedron */
1655 /* in allocated memory */
1656 /* Using the Ehrhart pseudo-polynomial */
1657 /****************************************************/
1658 Value
*compute_poly(Enumeration
*en
,Value
*list_args
) {
1661 /* double d; int i; */
1663 tmp
= (Value
*) malloc (sizeof(Value
));
1664 assert(tmp
!= NULL
);
1666 value_set_si(*tmp
,0);
1669 return(tmp
); /* no ehrhart polynomial */
1670 if(en
->ValidityDomain
) {
1671 if(!en
->ValidityDomain
->Dimension
) { /* no parameters */
1672 value_set_double(*tmp
,compute_evalue(&en
->EP
,list_args
)+.25);
1677 return(tmp
); /* no Validity Domain */
1679 if(in_domain(en
->ValidityDomain
,list_args
)) {
1681 #ifdef EVAL_EHRHART_DEBUG
1682 Print_Domain(stdout
,en
->ValidityDomain
);
1683 print_evalue(stdout
,&en
->EP
);
1686 /* d = compute_evalue(&en->EP,list_args);
1688 printf("(double)%lf = %d\n", d, i ); */
1689 value_set_double(*tmp
,compute_evalue(&en
->EP
,list_args
)+.25);
1695 value_set_si(*tmp
,0);
1696 return(tmp
); /* no compatible domain with the arguments */
1697 } /* compute_poly */
1699 size_t value_size(Value v
) {
1700 return (v
[0]._mp_size
> 0 ? v
[0]._mp_size
: -v
[0]._mp_size
)
1701 * sizeof(v
[0]._mp_d
[0]);
1704 size_t domain_size(Polyhedron
*D
)
1707 size_t s
= sizeof(*D
);
1709 for (i
= 0; i
< D
->NbConstraints
; ++i
)
1710 for (j
= 0; j
< D
->Dimension
+2; ++j
)
1711 s
+= value_size(D
->Constraint
[i
][j
]);
1713 for (i
= 0; i
< D
->NbRays
; ++i
)
1714 for (j
= 0; j
< D
->Dimension
+2; ++j
)
1715 s
+= value_size(D
->Ray
[i
][j
]);
1720 size_t enode_size(enode
*p
) {
1721 size_t s
= sizeof(*p
) - sizeof(p
->arr
[0]);
1724 if (p
->type
== partition
)
1725 for (i
= 0; i
< p
->size
/2; ++i
) {
1726 s
+= domain_size(EVALUE_DOMAIN(p
->arr
[2*i
]));
1727 s
+= evalue_size(&p
->arr
[2*i
+1]);
1730 for (i
= 0; i
< p
->size
; ++i
) {
1731 s
+= evalue_size(&p
->arr
[i
]);
1736 size_t evalue_size(evalue
*e
)
1738 size_t s
= sizeof(*e
);
1739 s
+= value_size(e
->d
);
1740 if (value_notzero_p(e
->d
))
1741 s
+= value_size(e
->x
.n
);
1743 s
+= enode_size(e
->x
.p
);