1 /******************************************************************************
2 * PIP : Parametric Integer Programming *
3 ******************************************************************************
5 ******************************************************************************
7 * Copyright Paul Feautrier, 1988-2005 *
9 * This library is free software; you can redistribute it and/or modify it *
10 * under the terms of the GNU Lesser General Public License as published by *
11 * the Free Software Foundation; either version 2.1 of the License, or (at *
12 * your option) any later version. *
14 * This software is distributed in the hope that it will be useful, but *
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
19 * You should have received a copy of the GNU Lesser General Public License *
20 * along with this library; if not, write to the Free Software Foundation, *
21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
23 * Written by Paul Feautrier *
25 *****************************************************************************/
32 #define max(x,y) ((x) > (y)? (x) : (y))
34 extern long int cross_product
, limit
;
37 extern int profondeur
;
38 extern int compa_count
;
40 #if !defined(LINEAR_VALUE_IS_MP)
43 /* x must be positive, you dummy */
45 while(x
) x
>>= 1, n
++;
50 int chercher(Tableau
*p
, int masque
, int n
)
53 if(p
->row
[i
].flags
& masque
) break;
57 /* il est convenu que traiter ne doit modifier ni le tableau, ni le contexte;
58 le tableau peut grandir en cas de coupure (+1 en hauteur et +1 en largeur
59 si nparm != 0) et en cas de partage (+1 en hauteur)(seulement si nparm != 0).
60 le contexte peut grandir en cas de coupure (+2 en hauteur et +1 en largeur)
61 (seulement si nparm !=0) et en cas de partage (+1 en hauteur)(nparm !=0).
62 On estime le nombre de coupures a llog(D) et le nombre de partages a
66 Tableau
*expanser(Tableau
*tp
, int virt
, int reel
, int ncol
,
67 int off
, int dh
, int dw
)
73 if(tp
== NULL
) return(NULL
);
74 rp
= tab_alloc(reel
+dh
, ncol
+dw
, virt
);
76 #if defined(LINEAR_VALUE_IS_MP)
77 mpz_set(rp
->determinant
, tp
->determinant
);
79 rp
->l_determinant
= tp
->l_determinant
;
80 for(i
=0; i
<tp
->l_determinant
; i
++)
81 rp
->determinant
[i
] = tp
->determinant
[i
];
83 pq
= (Entier
*) & (rp
->row
[virt
+reel
+dh
]);
84 for(i
= off
; i
<virt
+ reel
; i
++)
85 {ff
= Flag(rp
, i
) = Flag(tp
, i
-off
);
86 #if defined(LINEAR_VALUE_IS_MP)
87 mpz_set(Denom(rp
, i
), Denom(tp
, i
-off
));
89 Denom(rp
, i
) = Denom(tp
, i
-off
);
91 if(ff
& Unit
) rp
->row
[i
].objet
.unit
= tp
->row
[i
-off
].objet
.unit
;
93 rp
->row
[i
].objet
.val
= pq
;
95 pp
= tp
->row
[i
-off
].objet
.val
;
96 qq
= rp
->row
[i
].objet
.val
;
97 for(j
= 0; j
<ncol
; j
++)
98 #if defined(LINEAR_VALUE_IS_MP)
99 mpz_set(*qq
++, *pp
++);
108 int exam_coef(Tableau
*tp
, int nvar
, int ncol
, int bigparm
)
111 #if defined(LINEAR_VALUE_IS_MP)
118 for(i
= 0; i
<tp
->height
; i
++)
122 #if defined(LINEAR_VALUE_IS_MP)
124 x
= mpz_sgn(Index(tp
,i
, bigparm
));
126 if(bigparm
>= 0 && (x
= Index(tp
,i
, bigparm
))) {
133 #if defined(LINEAR_VALUE_IS_MP)
140 p
= &(tp
->row
[i
].objet
.val
[nvar
+1]);
141 for(j
= nvar
+1; j
<ncol
; j
++) {
142 #if defined(LINEAR_VALUE_IS_MP)
143 x
= mpz_sgn(*p
); p
++ ;
148 else if (x
>0) fff
= Plus
;
150 if(fff
!= Zero
&& fff
!= ff
)
151 if(ff
== Zero
) ff
= fff
;
156 /* bug de'tecte' par [paf], 16/2/93 !
157 Si tous les coefficients des parame`tres sont ne'gatifs
158 et si le terme constant est nul, le signe est inconnu!!
159 On traite donc spe'cialement le terme constant. */
160 #if defined(LINEAR_VALUE_IS_MP)
161 x
= mpz_sgn(Index(tp
, i
, nvar
));
163 x
= Index(tp
, i
, nvar
);
166 else if(x
>0) fff
= Plus
;
168 /* ici on a le signe du terme constant */
170 /* le signe est inconnu si les coefficients sont positifs et
171 le terme constant ne'gatif */
172 case Plus
: if(fff
== Minus
) ff
= Unknown
; break;
173 /* si les coefficients sont tous nuls, le signe est celui
175 case Zero
: ff
= fff
; break;
176 /* le signe est inconnu si les coefficients sont ne'gatifs,
177 sauf si le terme constant est egalement negatif. */
178 case Minus
: if(fff
!= Minus
) ff
= Unknown
; break;
179 /* enfin, il n'y a rien a` dire si le signe des coefficients est inconnu */
182 if(ff
== Minus
) return(i
);
188 void compa_test(Tableau
*tp
, Tableau
*context
,
189 int ni
, int nvar
, int nparm
, int nc
)
191 Entier discr
[MAXPARM
];
194 int cPlus
, cMinus
, isCritic
;
196 Tableau
*tPlus
, *tMinus
;
198 struct high_water_mark q
;
200 if(nparm
== 0) return;
201 if(nparm
>= MAXPARM
) {
202 fprintf(stderr
, "Too much parameters : %d\n", nparm
);
206 #if defined(LINEAR_VALUE_IS_MP)
207 for(i
=0; i
<=nparm
; i
++)
211 for(i
= 0; i
<ni
+ nvar
; i
++)
213 if(ff
& (Critic
| Unknown
))
214 {isCritic
= Pip_True
;
215 for(j
= 0; j
<nvar
; j
++)
216 #if defined(LINEAR_VALUE_IS_MP)
217 if(mpz_sgn(Index(tp
, i
, j
)) > 0)
219 if(Index(tp
, i
, j
) > 0)
221 {isCritic
= Pip_False
;
225 for(j
= 0; j
< nparm
; j
++)
226 #if defined(LINEAR_VALUE_IS_MP)
227 mpz_set(discr
[j
], Index(tp
, i
, j
+nvar
+1)); /* loop body. */
228 mpz_set(discr
[nparm
], Index(tp
, i
, nvar
));
229 mpz_sub_ui(discr
[nparm
], discr
[nparm
], (isCritic
? 0 : 1));
231 discr
[j
] = Index(tp
, i
, j
+nvar
+1); /* loop body. */
232 discr
[nparm
] = Index(tp
, i
, nvar
)- (isCritic
? 0 : 1);
234 tPlus
= expanser(context
, nparm
, nc
, nparm
+1, nparm
, 1, 0);
235 Flag(tPlus
, nparm
+nc
) = Unknown
;
236 for(j
= 0; j
<=nparm
; j
++)
237 #if defined(LINEAR_VALUE_IS_MP)
238 mpz_set(Index(tPlus
, nparm
+nc
, j
),discr
[j
]); /* loop body. */
239 mpz_set(Denom(tPlus
, nparm
+nc
), UN
);
241 Index(tPlus
, nparm
+nc
, j
) = discr
[j
]; /* loop body. */
242 Denom(tPlus
, nparm
+nc
) = UN
;
246 traiter(tPlus
, NULL
, nparm
, 0, nc
+1, 0, -1, TRAITER_INT
);
247 cPlus
= is_not_Nil(p
);
249 fprintf(dump
, "\nThe positive case has been found ");
250 fprintf(dump
, cPlus
? "possible\n": "impossible\n");
255 for(j
= 0; j
<nparm
+1; j
++)
256 #if defined(LINEAR_VALUE_IS_MP)
257 mpz_neg(discr
[j
], discr
[j
]); /* loop body. */
258 mpz_sub_ui(discr
[nparm
], discr
[nparm
], (isCritic
? 1 : 2));
260 discr
[j
] = -discr
[j
]; /* loop body. */
261 discr
[nparm
] = discr
[nparm
] - (isCritic
? 1 : 2);
263 tMinus
= expanser(context
, nparm
, nc
, nparm
+1, nparm
, 1, 0);
264 Flag(tMinus
, nparm
+nc
) = Unknown
;
265 for(j
= 0; j
<= nparm
; j
++)
266 #if defined(LINEAR_VALUE_IS_MP)
267 mpz_set(Index(tMinus
, nparm
+nc
, j
),discr
[j
]);/* loop body. */
268 mpz_set(Denom(tMinus
, nparm
+nc
), UN
);
270 Index(tMinus
, nparm
+nc
, j
) = discr
[j
]; /* loop body. */
271 Denom(tMinus
, nparm
+nc
) = UN
;
273 traiter(tMinus
, NULL
, nparm
, 0, nc
+1, 0, -1, TRAITER_INT
);
274 cMinus
= is_not_Nil(p
);
276 fprintf(dump
, "\nThe negative case has been found ");
277 fprintf(dump
, cMinus
? "possible\n": "impossible\n");
282 if (cPlus
&& cMinus
) {
283 Flag(tp
,i
) = isCritic
? Critic
: Unknown
;
290 Flag(tp
,i
) = cPlus
? Plus
: Zero
;
296 #if defined(LINEAR_VALUE_IS_MP)
297 for(i
=0; i
<=nparm
; i
++)
304 Entier
*valeur(Tableau
*tp
, int i
, int j
)
306 if(Flag(tp
, i
) & Unit
)
307 return(tp
->row
[i
].objet
.unit
== j
? &Denom(tp
,i
) : &ZERO
);
308 else return(&Index(tp
, i
, j
));
311 void solution(Tableau
*tp
, int nvar
, int nparm
)
313 int ncol
= nvar
+ nparm
+ 1;
316 for(i
= 0; i
<nvar
; i
++)
318 for(j
= nvar
+1; j
<ncol
; j
++)
319 sol_val(*valeur(tp
, i
, j
), Denom(tp
,i
));
320 sol_val(*valeur(tp
, i
, nvar
), Denom(tp
,i
));
324 static void solution_dual(Tableau
*tp
, int nvar
, int nparm
, int *pos
)
328 sol_list(tp
->height
- nvar
);
329 for (i
= 0; i
< tp
->height
- nvar
; ++i
) {
331 if (Flag(tp
, pos
[i
]) & Unit
)
332 sol_val(*valeur(tp
, 0, tp
->row
[pos
[i
]].objet
.unit
), Denom(tp
, 0));
338 int choisir_piv(Tableau
*tp
, int pivi
, int nvar
, int nligne
)
341 Entier pivot
, foo
, x
, y
;
342 int sgn_x
, pivj
= -1;
344 #if defined(LINEAR_VALUE_IS_MP)
345 mpz_init(pivot
); mpz_init(foo
); mpz_init(x
); mpz_init(y
);
348 for(j
= 0; j
<nvar
; j
++) {
349 #if defined(LINEAR_VALUE_IS_MP)
350 mpz_set(foo
, Index(tp
, pivi
, j
));
351 if(mpz_sgn(foo
) <= 0) continue;
357 for(k
= 0; k
<nligne
; k
++)
358 {mpz_mul(x
, pivot
, *valeur(tp
, k
, j
));
359 mpz_mul(y
, *valeur(tp
, k
, pivj
), foo
);
370 if((foo
= Index(tp
, pivi
, j
)) <= 0) continue;
376 for(k
= 0; k
<nligne
; k
++)
377 {x
= pivot
* (*valeur(tp
, k
, j
)) - (*valeur(tp
, k
, pivj
)) * foo
;
388 #if defined(LINEAR_VALUE_IS_MP)
389 mpz_clear(pivot
); mpz_clear(foo
); mpz_clear(x
); mpz_clear(y
);
396 int pivoter(Tableau
*tp
, int pivi
, int nvar
, int nparm
, int ni
)
399 int ncol
= nvar
+ nparm
+ 1;
400 int nligne
= nvar
+ ni
;
402 Entier x
, y
, d
, gcd
, u
, dpiv
;
404 Entier pivot
, foo
, z
;
405 Entier ppivot
, dppiv
;
406 Entier
new[MAXCOL
], *p
, *q
;
409 #if !defined(LINEAR_VALUE_IS_MP)
410 char format_format
[32];
412 sprintf(format_format
, "\nPivot %s/%s\n", FORMAT
, FORMAT
);
416 fprintf(stdout
, "Too much variables\n");
419 if(0 > pivi
|| pivi
>= nligne
|| Flag(tp
, pivi
) == Unit
) {
420 fprintf(stdout
, "Syserr : pivoter : wrong pivot row\n");
424 pivj
= choisir_piv(tp
, pivi
, nvar
, nligne
);
425 if(pivj
< 0) return(-1);
427 fprintf(stdout
, "Syserr : pivoter : wrong pivot\n");
431 #if defined(LINEAR_VALUE_IS_MP)
432 mpz_init(x
); mpz_init(y
); mpz_init(d
);
433 mpz_init(gcd
); mpz_init(u
); mpz_init(dpiv
);
434 mpz_init(lpiv
); mpz_init(pivot
); mpz_init(foo
);
435 mpz_init(z
); mpz_init(ppivot
); mpz_init(dppiv
);
437 for(i
=0; i
<ncol
; i
++)
440 mpz_set(pivot
, Index(tp
, pivi
, pivj
));
441 mpz_set(dpiv
, Denom(tp
, pivi
));
442 mpz_gcd(d
, pivot
, dpiv
);
443 mpz_divexact(ppivot
, pivot
, d
);
444 mpz_divexact(dppiv
, dpiv
, d
);
446 pivot
= Index(tp
, pivi
, pivj
);
447 dpiv
= Denom(tp
, pivi
);
448 d
= pgcd(pivot
, dpiv
);
454 #if defined(LINEAR_VALUE_IS_MP)
455 fprintf(dump
, "Pivot ");
456 mpz_out_str(dump
, 10, ppivot
);
458 mpz_out_str(dump
, 10, dppiv
);
461 fprintf(dump
, format_format
, ppivot
, dppiv
);
463 fprintf(dump
, "%d x %d\n", pivi
, pivj
);
466 #if defined(LINEAR_VALUE_IS_MP)
467 mpz_fdiv_qr(x
, y
, tp
->determinant
, dppiv
);
469 for(i
=0; i
< tp
->l_determinant
; i
++){
470 d
=pgcd(tp
->determinant
[i
], dppiv
);
471 tp
->determinant
[i
] /= d
;
476 #if defined(LINEAR_VALUE_IS_MP)
481 fprintf(stderr
, "Integer overflow\n");
482 if(verbose
>0) fflush(dump
);
486 #if defined(LINEAR_VALUE_IS_MP)
487 mpz_mul(tp
->determinant
, x
, ppivot
);
489 for(i
=0; i
<tp
->l_determinant
; i
++)
490 if(llog(tp
->determinant
[i
]) + llog(ppivot
) < 8*sizeof(Entier
)){
491 tp
->determinant
[i
] *= ppivot
;
494 if(i
>= tp
->l_determinant
){
496 if(tp
->l_determinant
>= MAX_DETERMINANT
){
497 fprintf(stderr
, "Integer overflow : %d\n", tp
->l_determinant
);
500 tp
->determinant
[i
] = ppivot
;
505 fprintf(dump
, "determinant ");
506 #if defined(LINEAR_VALUE_IS_MP)
507 mpz_out_str(dump
, 10, tp
->determinant
);
509 for(i
=0; i
<tp
->l_determinant
; i
++)
510 fprintf(dump
, FORMAT
, tp
->determinant
[i
]);
516 for(j
= 0; j
<ncol
; j
++)
517 #if defined(LINEAR_VALUE_IS_MP)
519 mpz_set(new[j
], dpiv
);
521 mpz_neg(new[j
], Index(tp
, pivi
, j
));
523 new[j
] = (j
== pivj
? dpiv
: -Index(tp
, pivi
, j
));
526 for(k
= 0; k
<nligne
; k
++){
527 if(Flag(tp
,k
) & Unit
)continue;
528 if(k
== pivi
)continue;
529 #if defined(LINEAR_VALUE_IS_MP)
530 mpz_set(foo
, Index(tp
, k
, pivj
));
531 mpz_gcd(d
, pivot
, foo
);
532 mpz_divexact(lpiv
, pivot
, d
);
533 mpz_divexact(foo
, foo
, d
);
534 mpz_set(d
, Denom(tp
,k
));
535 mpz_mul(gcd
, lpiv
, d
);
536 mpz_set(Denom(tp
, k
), gcd
);
538 foo
= Index(tp
, k
, pivj
);
539 d
= pgcd(pivot
, foo
);
546 p
= tp
->row
[k
].objet
.val
;
547 q
= tp
->row
[pivi
].objet
.val
;
548 for(j
= 0; j
<ncol
; j
++){
550 #if defined(LINEAR_VALUE_IS_MP)
551 mpz_mul(z
, dpiv
, foo
);
556 #if defined(LINEAR_VALUE_IS_MP)
557 mpz_mul(z
, *p
, lpiv
);
561 z
= (*p
) * lpiv
- (*q
) * foo
;
566 #if defined(LINEAR_VALUE_IS_MP)
569 if(mpz_cmp_ui(gcd
, 1) != 0)
570 mpz_gcd(gcd
, gcd
, z
);
577 #if defined(LINEAR_VALUE_IS_MP)
578 if(mpz_cmp_ui(gcd
, 1) != 0){
579 p
= tp
->row
[k
].objet
.val
;
580 for(j
= 0; j
<ncol
; j
++){
581 mpz_divexact(*p
, *p
, gcd
);
585 mpz_divexact(Denom(tp
,k
), Denom(tp
,k
), gcd
);
588 p
= tp
->row
[k
].objet
.val
;
589 for(j
= 0; j
<ncol
; j
++)
591 Denom(tp
,k
) = Denom(tp
,k
)/gcd
;
595 p
= tp
->row
[pivi
].objet
.val
;
596 for(k
= 0; k
<nligne
; k
++)
597 if((Flag(tp
, k
) & Unit
) && tp
->row
[k
].objet
.unit
== pivj
) break;
599 tp
->row
[k
].objet
.val
= p
;
600 for(j
= 0; j
<ncol
; j
++)
601 #if defined(LINEAR_VALUE_IS_MP)
602 mpz_set(*p
++, new[j
]);
607 #if defined(LINEAR_VALUE_IS_MP)
608 mpz_set(Denom(tp
, k
), pivot
);
609 Flag(tp
, pivi
) = Unit
| Zero
;
610 mpz_set(Denom(tp
, pivi
), UN
);
612 Denom(tp
, k
) = pivot
;
613 Flag(tp
, pivi
) = Unit
| Zero
;
614 Denom(tp
, pivi
) = UN
;
616 tp
->row
[pivi
].objet
.unit
= pivj
;
618 for(k
= 0; k
<nligne
; k
++){
620 if(ff
& Unit
) continue;
621 #if defined(LINEAR_VALUE_IS_MP)
622 sgn_x
= mpz_sgn(Index(tp
, k
, pivj
));
624 sgn_x
= Index(tp
, k
, pivj
);
626 if(sgn_x
< 0) fff
= Minus
;
627 else if(sgn_x
== 0) fff
= Zero
;
629 if(fff
!= Zero
&& fff
!= ff
)
630 if(ff
== Zero
) ff
= (fff
== Minus
? Unknown
: fff
);
636 fprintf(dump
, "just pivoted\n");
637 tab_display(tp
, dump
);
640 #if defined(LINEAR_VALUE_IS_MP)
641 mpz_clear(x
); mpz_clear(y
); mpz_clear(d
); mpz_clear(gcd
);
642 mpz_clear(u
); mpz_clear(dpiv
); mpz_clear(lpiv
);
643 mpz_clear(pivot
); mpz_clear(foo
); mpz_clear(z
);
644 mpz_clear(ppivot
); mpz_clear(dppiv
);
646 for(i
=0; i
<ncol
; i
++)
654 * Sort the rows in increasing order of the largest coefficient
655 * and (if TRAITER_DUAL is set) return the new position of the
656 * original constraints.
658 static int *tab_sort_rows(Tableau
*tp
, int nvar
, int nligne
, int flags
)
662 double s
, t
, d
, smax
= 0;
664 int *pos
= NULL
, *ineq
= NULL
;
666 if (flags
& TRAITER_DUAL
) {
667 ineq
= malloc(tp
->height
* sizeof(int));
668 pos
= malloc((tp
->height
-nvar
) * sizeof(int));
670 fprintf(stderr
, "Memory Overflow.\n") ;
675 for (i
= nvar
; i
< nligne
; i
++) {
676 if (Flag(tp
,i
) & Unit
)
679 d
= ENTIER_TO_DOUBLE(Denom(tp
, i
));
680 for (j
= 0; j
< nvar
; j
++) {
681 t
= ENTIER_TO_DOUBLE(Index(tp
,i
,j
))/d
;
686 if (flags
& TRAITER_DUAL
)
690 for (i
= nvar
; i
< nligne
; i
++) {
691 if (Flag(tp
,i
) & Unit
)
695 for (j
= i
; j
< nligne
; j
++) {
696 if (Flag(tp
,j
) & Unit
)
698 if (tp
->row
[j
].size
< s
) {
704 temp
= tp
->row
[pivi
];
705 tp
->row
[pivi
] = tp
->row
[i
];
707 if (flags
& TRAITER_DUAL
) {
709 ineq
[i
] = ineq
[pivi
];
715 if (flags
& TRAITER_DUAL
) {
716 for (i
= nvar
; i
< nligne
; i
++)
724 /* dans cette version, "traiter" modifie ineq; par contre
725 le contexte est immediatement recopie' */
727 void traiter(Tableau
*tp
, Tableau
*ctxt
, int nvar
, int nparm
, int ni
, int nc
,
728 int bigparm
, int flags
)
731 int pivi
, nligne
, ncol
;
732 struct high_water_mark x
;
736 Entier discr
[MAXPARM
];
739 #if !defined(LINEAR_VALUE_IS_MP)
743 #if defined(LINEAR_VALUE_IS_MP)
744 for(i
=0; i
<MAXPARM
; i
++)
746 dcw
= mpz_sizeinbase(tp
->determinant
, 2);
749 for(i
=0; i
<tp
->l_determinant
; i
++)
750 dcw
+= llog(tp
->determinant
[i
]);
756 context
= expanser(ctxt
, 0, nc
, nparm
+1, 0, dch
, dcw
);
758 pos
= tab_sort_rows(tp
, nvar
, nligne
, flags
);
762 fprintf(dump
, "debut for\n");
763 tab_display(tp
, dump
);
766 nligne
= nvar
+ni
; ncol
= nvar
+nparm
+1;
767 if(nligne
> tp
->height
|| ncol
> tp
->width
) {
768 fprintf(stdout
, "Syserr : traiter : tableau too small\n");
771 pivi
= chercher(tp
, Minus
, nligne
);
772 if(pivi
< nligne
) goto pirouette
; /* There is a negative row */
774 pivi
= exam_coef(tp
, nvar
, ncol
, bigparm
);
777 fprintf(dump
, "coefs examined\n");
778 tab_display(tp
, dump
);
782 if(pivi
< nligne
) goto pirouette
;
783 /* There is a row whose coefficients are negative */
784 compa_test(tp
, context
, ni
, nvar
, nparm
, nc
);
786 fprintf(dump
, "compatibility tested\n");
787 tab_display(tp
, dump
);
791 pivi
= chercher(tp
, Minus
, nligne
);
792 if(pivi
< nligne
) goto pirouette
;
793 /* The compatibility test has found a negative row */
794 pivi
= chercher(tp
, Critic
, nligne
);
795 if(pivi
>= nligne
)pivi
= chercher(tp
, Unknown
, nligne
);
796 /* Here, the problem tree splits */
800 struct high_water_mark q
;
801 if(nc
>= context
->height
) {
802 #if defined(LINEAR_VALUE_IS_MP)
803 dcw
= mpz_sizeinbase(context
->determinant
,2);
806 for(i
=0; i
<tp
->l_determinant
; i
++)
807 dcw
+= llog(tp
->determinant
[i
]);
810 context
= expanser(context
, 0, nc
, nparm
+1, 0, dch
, dcw
);
812 if(nparm
>= MAXPARM
) {
813 fprintf(stdout
, "Too much parameters : %d\n", nparm
);
818 fprintf(stdout
,"profondeur %d %lx\n", profondeur
, q
.top
);
819 ntp
= expanser(tp
, nvar
, ni
, ncol
, 0, 0, 0);
823 entier_init_zero(com_dem
);
824 for (j
= 0; j
< nparm
; j
++)
825 entier_gcd(com_dem
, com_dem
, Index(tp
, pivi
, j
+ nvar
+1));
826 if (!(flags
& TRAITER_INT
))
827 entier_gcd(com_dem
, com_dem
, Index(tp
, pivi
, nvar
));
828 for (j
= 0; j
< nparm
; j
++) {
829 entier_divexact(Index(context
, nc
, j
), Index(tp
, pivi
, j
+ nvar
+ 1), com_dem
);
830 sol_val(Index(context
, nc
, j
), UN
);
832 if (!(flags
& TRAITER_INT
))
833 entier_divexact(Index(context
, nc
, nparm
), Index(tp
, pivi
, nvar
), com_dem
);
835 entier_pdivision(Index(context
, nc
, nparm
), Index(tp
, pivi
, nvar
), com_dem
);
836 sol_val(Index(context
, nc
, nparm
), UN
);
837 entier_clear(com_dem
);
838 Flag(context
, nc
) = Unknown
;
839 entier_set_si(Denom(context
, nc
), 1);
840 Flag(ntp
, pivi
) = Plus
;
843 if(verbose
> 0) fflush(dump
);
844 #if defined(LINEAR_VALUE_IS_MP)
845 traiter(ntp
, context
, nvar
, nparm
, ni
, nc
+1, bigparm
, flags
);
849 fprintf(stdout
, "descente %d %lx\n", profondeur
, tab_hwm().top
);
850 for(j
= 0; j
<nparm
; j
++)
851 mpz_neg(Index(context
, nc
, j
), Index(context
, nc
, j
));
852 mpz_add_ui(Index(context
, nc
, nparm
), Index(context
, nc
, nparm
), 1);
853 mpz_neg(Index(context
, nc
, nparm
), Index(context
, nc
, nparm
));
854 Flag(tp
, pivi
) = Minus
;
855 mpz_set(Denom(context
, nc
), UN
);
857 traiter(ntp
, context
, nvar
, nparm
, ni
, nc
+1, bigparm
, flags
);
861 fprintf(stderr
, "descente %d %lx\n", profondeur
, tab_hwm().top
);
862 for(j
= 0; j
<nparm
; j
++)
863 Index(context
, nc
, j
) = - Index(context
, nc
, j
);
864 Index(context
, nc
, nparm
) = - Index(context
, nc
, nparm
) -1;
865 Flag(tp
, pivi
) = Minus
;
866 Denom(context
, nc
) = UN
;
871 /* Here, all rows are positive. Do we need an integral solution? */
872 if (!(flags
& TRAITER_INT
)) {
873 solution(tp
, nvar
, nparm
);
874 if (flags
& TRAITER_DUAL
)
875 solution_dual(tp
, nvar
, nparm
, pos
);
879 pivi
= integrer(&tp
, &context
, &nvar
, &nparm
, &ni
, &nc
, bigparm
);
880 if(pivi
> 0) goto pirouette
;
881 /* A cut has been inserted and is always negative */
882 /* Here, either there is an integral solution, */
883 if(pivi
== 0) solution(tp
, nvar
, nparm
);
884 /* or no solution exists */
888 /* Here, a negative row has been found. The call to <<pivoter>> executes
892 if (pivoter(tp
, pivi
, nvar
, nparm
, ni
) < 0) {
897 /* Danger : a premature return would induce memory leaks */
899 #if defined(LINEAR_VALUE_IS_MP)
900 for(i
=0; i
<MAXPARM
; i
++)