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 /* Check for "obvious" signs of the parametric constant terms
109 * of the inequalities. As soon as a negative sign is found
110 * we return from this function and handle this constraint
111 * in the calling function. The signs of the other constraints
112 * are then mostly irrelevant.
113 * If any of the negative signs is due to the "big parameter",
114 * then we want to use this constraint first.
115 * We therefore check for signs determined by the coefficient
116 * of the big parameter first.
118 int exam_coef(Tableau
*tp
, int nvar
, int ncol
, int bigparm
)
121 #if defined(LINEAR_VALUE_IS_MP)
129 for (i
= 0; i
<tp
->height
; i
++) {
130 if (Flag(tp
, i
) != Unknown
)
132 x
= entier_sgn(Index(tp
,i
, bigparm
));
140 for(i
= 0; i
<tp
->height
; i
++)
145 p
= &(tp
->row
[i
].objet
.val
[nvar
+1]);
146 for(j
= nvar
+1; j
<ncol
; j
++) {
147 #if defined(LINEAR_VALUE_IS_MP)
148 x
= mpz_sgn(*p
); p
++ ;
153 else if (x
>0) fff
= Plus
;
155 if(fff
!= Zero
&& fff
!= ff
)
156 if(ff
== Zero
) ff
= fff
;
161 /* bug de'tecte' par [paf], 16/2/93 !
162 Si tous les coefficients des parame`tres sont ne'gatifs
163 et si le terme constant est nul, le signe est inconnu!!
164 On traite donc spe'cialement le terme constant. */
165 #if defined(LINEAR_VALUE_IS_MP)
166 x
= mpz_sgn(Index(tp
, i
, nvar
));
168 x
= Index(tp
, i
, nvar
);
171 else if(x
>0) fff
= Plus
;
173 /* ici on a le signe du terme constant */
175 /* le signe est inconnu si les coefficients sont positifs et
176 le terme constant ne'gatif */
177 case Plus
: if(fff
== Minus
) ff
= Unknown
; break;
178 /* si les coefficients sont tous nuls, le signe est celui
180 case Zero
: ff
= fff
; break;
181 /* le signe est inconnu si les coefficients sont ne'gatifs,
182 sauf si le terme constant est egalement negatif. */
183 case Minus
: if(fff
!= Minus
) ff
= Unknown
; break;
184 /* enfin, il n'y a rien a` dire si le signe des coefficients est inconnu */
187 if(ff
== Minus
) return(i
);
193 void compa_test(Tableau
*tp
, Tableau
*context
,
194 int ni
, int nvar
, int nparm
, int nc
)
196 Entier discr
[MAXPARM
];
199 int cPlus
, cMinus
, isCritic
;
201 Tableau
*tPlus
, *tMinus
;
203 struct high_water_mark q
;
205 if(nparm
== 0) return;
206 if(nparm
>= MAXPARM
) {
207 fprintf(stderr
, "Too much parameters : %d\n", nparm
);
211 #if defined(LINEAR_VALUE_IS_MP)
212 for(i
=0; i
<=nparm
; i
++)
216 for(i
= 0; i
<ni
+ nvar
; i
++)
218 if(ff
& (Critic
| Unknown
))
219 {isCritic
= Pip_True
;
220 for(j
= 0; j
<nvar
; j
++)
221 #if defined(LINEAR_VALUE_IS_MP)
222 if(mpz_sgn(Index(tp
, i
, j
)) > 0)
224 if(Index(tp
, i
, j
) > 0)
226 {isCritic
= Pip_False
;
230 for(j
= 0; j
< nparm
; j
++)
231 #if defined(LINEAR_VALUE_IS_MP)
232 mpz_set(discr
[j
], Index(tp
, i
, j
+nvar
+1)); /* loop body. */
233 mpz_set(discr
[nparm
], Index(tp
, i
, nvar
));
234 mpz_sub_ui(discr
[nparm
], discr
[nparm
], (isCritic
? 0 : 1));
236 discr
[j
] = Index(tp
, i
, j
+nvar
+1); /* loop body. */
237 discr
[nparm
] = Index(tp
, i
, nvar
)- (isCritic
? 0 : 1);
239 tPlus
= expanser(context
, nparm
, nc
, nparm
+1, nparm
, 1, 0);
240 Flag(tPlus
, nparm
+nc
) = Unknown
;
241 for(j
= 0; j
<=nparm
; j
++)
242 #if defined(LINEAR_VALUE_IS_MP)
243 mpz_set(Index(tPlus
, nparm
+nc
, j
),discr
[j
]); /* loop body. */
244 mpz_set(Denom(tPlus
, nparm
+nc
), UN
);
246 Index(tPlus
, nparm
+nc
, j
) = discr
[j
]; /* loop body. */
247 Denom(tPlus
, nparm
+nc
) = UN
;
251 traiter(tPlus
, NULL
, nparm
, 0, nc
+1, 0, -1, TRAITER_INT
);
252 cPlus
= is_not_Nil(p
);
254 fprintf(dump
, "\nThe positive case has been found ");
255 fprintf(dump
, cPlus
? "possible\n": "impossible\n");
260 for(j
= 0; j
<nparm
+1; j
++)
261 #if defined(LINEAR_VALUE_IS_MP)
262 mpz_neg(discr
[j
], discr
[j
]); /* loop body. */
263 mpz_sub_ui(discr
[nparm
], discr
[nparm
], (isCritic
? 1 : 2));
265 discr
[j
] = -discr
[j
]; /* loop body. */
266 discr
[nparm
] = discr
[nparm
] - (isCritic
? 1 : 2);
268 tMinus
= expanser(context
, nparm
, nc
, nparm
+1, nparm
, 1, 0);
269 Flag(tMinus
, nparm
+nc
) = Unknown
;
270 for(j
= 0; j
<= nparm
; j
++)
271 #if defined(LINEAR_VALUE_IS_MP)
272 mpz_set(Index(tMinus
, nparm
+nc
, j
),discr
[j
]);/* loop body. */
273 mpz_set(Denom(tMinus
, nparm
+nc
), UN
);
275 Index(tMinus
, nparm
+nc
, j
) = discr
[j
]; /* loop body. */
276 Denom(tMinus
, nparm
+nc
) = UN
;
278 traiter(tMinus
, NULL
, nparm
, 0, nc
+1, 0, -1, TRAITER_INT
);
279 cMinus
= is_not_Nil(p
);
281 fprintf(dump
, "\nThe negative case has been found ");
282 fprintf(dump
, cMinus
? "possible\n": "impossible\n");
287 if (cPlus
&& cMinus
) {
288 Flag(tp
,i
) = isCritic
? Critic
: Unknown
;
295 Flag(tp
,i
) = cPlus
? Plus
: Zero
;
301 #if defined(LINEAR_VALUE_IS_MP)
302 for(i
=0; i
<=nparm
; i
++)
309 Entier
*valeur(Tableau
*tp
, int i
, int j
)
311 if(Flag(tp
, i
) & Unit
)
312 return(tp
->row
[i
].objet
.unit
== j
? &Denom(tp
,i
) : &ZERO
);
313 else return(&Index(tp
, i
, j
));
316 void solution(Tableau
*tp
, int nvar
, int nparm
)
318 int ncol
= nvar
+ nparm
+ 1;
321 for(i
= 0; i
<nvar
; i
++)
323 for(j
= nvar
+1; j
<ncol
; j
++)
324 sol_val(*valeur(tp
, i
, j
), Denom(tp
,i
));
325 sol_val(*valeur(tp
, i
, nvar
), Denom(tp
,i
));
329 static void solution_dual(Tableau
*tp
, int nvar
, int nparm
, int *pos
)
333 sol_list(tp
->height
- nvar
);
334 for (i
= 0; i
< tp
->height
- nvar
; ++i
) {
336 if (Flag(tp
, pos
[i
]) & Unit
)
337 sol_val(*valeur(tp
, 0, tp
->row
[pos
[i
]].objet
.unit
), Denom(tp
, 0));
343 int choisir_piv(Tableau
*tp
, int pivi
, int nvar
, int nligne
)
346 Entier pivot
, foo
, x
, y
;
347 int sgn_x
, pivj
= -1;
349 #if defined(LINEAR_VALUE_IS_MP)
350 mpz_init(pivot
); mpz_init(foo
); mpz_init(x
); mpz_init(y
);
353 for(j
= 0; j
<nvar
; j
++) {
354 #if defined(LINEAR_VALUE_IS_MP)
355 mpz_set(foo
, Index(tp
, pivi
, j
));
356 if(mpz_sgn(foo
) <= 0) continue;
362 for(k
= 0; k
<nligne
; k
++)
363 {mpz_mul(x
, pivot
, *valeur(tp
, k
, j
));
364 mpz_mul(y
, *valeur(tp
, k
, pivj
), foo
);
375 if((foo
= Index(tp
, pivi
, j
)) <= 0) continue;
381 for(k
= 0; k
<nligne
; k
++)
382 {x
= pivot
* (*valeur(tp
, k
, j
)) - (*valeur(tp
, k
, pivj
)) * foo
;
393 #if defined(LINEAR_VALUE_IS_MP)
394 mpz_clear(pivot
); mpz_clear(foo
); mpz_clear(x
); mpz_clear(y
);
401 int pivoter(Tableau
*tp
, int pivi
, int nvar
, int nparm
, int ni
)
404 int ncol
= nvar
+ nparm
+ 1;
405 int nligne
= nvar
+ ni
;
407 Entier x
, y
, d
, gcd
, u
, dpiv
;
409 Entier pivot
, foo
, z
;
410 Entier ppivot
, dppiv
;
411 Entier
new[MAXCOL
], *p
, *q
;
414 #if !defined(LINEAR_VALUE_IS_MP)
415 char format_format
[32];
417 sprintf(format_format
, "\nPivot %s/%s\n", FORMAT
, FORMAT
);
421 fprintf(stdout
, "Too much variables\n");
424 if(0 > pivi
|| pivi
>= nligne
|| Flag(tp
, pivi
) == Unit
) {
425 fprintf(stdout
, "Syserr : pivoter : wrong pivot row\n");
429 pivj
= choisir_piv(tp
, pivi
, nvar
, nligne
);
430 if(pivj
< 0) return(-1);
432 fprintf(stdout
, "Syserr : pivoter : wrong pivot\n");
436 #if defined(LINEAR_VALUE_IS_MP)
437 mpz_init(x
); mpz_init(y
); mpz_init(d
);
438 mpz_init(gcd
); mpz_init(u
); mpz_init(dpiv
);
439 mpz_init(lpiv
); mpz_init(pivot
); mpz_init(foo
);
440 mpz_init(z
); mpz_init(ppivot
); mpz_init(dppiv
);
442 for(i
=0; i
<ncol
; i
++)
445 mpz_set(pivot
, Index(tp
, pivi
, pivj
));
446 mpz_set(dpiv
, Denom(tp
, pivi
));
447 mpz_gcd(d
, pivot
, dpiv
);
448 mpz_divexact(ppivot
, pivot
, d
);
449 mpz_divexact(dppiv
, dpiv
, d
);
451 pivot
= Index(tp
, pivi
, pivj
);
452 dpiv
= Denom(tp
, pivi
);
453 d
= pgcd(pivot
, dpiv
);
459 #if defined(LINEAR_VALUE_IS_MP)
460 fprintf(dump
, "Pivot ");
461 mpz_out_str(dump
, 10, ppivot
);
463 mpz_out_str(dump
, 10, dppiv
);
466 fprintf(dump
, format_format
, ppivot
, dppiv
);
468 fprintf(dump
, "%d x %d\n", pivi
, pivj
);
471 #if defined(LINEAR_VALUE_IS_MP)
472 mpz_fdiv_qr(x
, y
, tp
->determinant
, dppiv
);
474 for(i
=0; i
< tp
->l_determinant
; i
++){
475 d
=pgcd(tp
->determinant
[i
], dppiv
);
476 tp
->determinant
[i
] /= d
;
481 #if defined(LINEAR_VALUE_IS_MP)
486 fprintf(stderr
, "Integer overflow\n");
487 if(verbose
>0) fflush(dump
);
491 #if defined(LINEAR_VALUE_IS_MP)
492 mpz_mul(tp
->determinant
, x
, ppivot
);
494 for(i
=0; i
<tp
->l_determinant
; i
++)
495 if(llog(tp
->determinant
[i
]) + llog(ppivot
) < 8*sizeof(Entier
)){
496 tp
->determinant
[i
] *= ppivot
;
499 if(i
>= tp
->l_determinant
){
501 if(tp
->l_determinant
>= MAX_DETERMINANT
){
502 fprintf(stderr
, "Integer overflow : %d\n", tp
->l_determinant
);
505 tp
->determinant
[i
] = ppivot
;
510 fprintf(dump
, "determinant ");
511 #if defined(LINEAR_VALUE_IS_MP)
512 mpz_out_str(dump
, 10, tp
->determinant
);
514 for(i
=0; i
<tp
->l_determinant
; i
++)
515 fprintf(dump
, FORMAT
, tp
->determinant
[i
]);
521 for(j
= 0; j
<ncol
; j
++)
522 #if defined(LINEAR_VALUE_IS_MP)
524 mpz_set(new[j
], dpiv
);
526 mpz_neg(new[j
], Index(tp
, pivi
, j
));
528 new[j
] = (j
== pivj
? dpiv
: -Index(tp
, pivi
, j
));
531 for(k
= 0; k
<nligne
; k
++){
532 if(Flag(tp
,k
) & Unit
)continue;
533 if(k
== pivi
)continue;
534 #if defined(LINEAR_VALUE_IS_MP)
535 mpz_set(foo
, Index(tp
, k
, pivj
));
536 mpz_gcd(d
, pivot
, foo
);
537 mpz_divexact(lpiv
, pivot
, d
);
538 mpz_divexact(foo
, foo
, d
);
539 mpz_set(d
, Denom(tp
,k
));
540 mpz_mul(gcd
, lpiv
, d
);
541 mpz_set(Denom(tp
, k
), gcd
);
543 foo
= Index(tp
, k
, pivj
);
544 d
= pgcd(pivot
, foo
);
551 p
= tp
->row
[k
].objet
.val
;
552 q
= tp
->row
[pivi
].objet
.val
;
553 for(j
= 0; j
<ncol
; j
++){
555 #if defined(LINEAR_VALUE_IS_MP)
556 mpz_mul(z
, dpiv
, foo
);
561 #if defined(LINEAR_VALUE_IS_MP)
562 mpz_mul(z
, *p
, lpiv
);
566 z
= (*p
) * lpiv
- (*q
) * foo
;
571 #if defined(LINEAR_VALUE_IS_MP)
574 if(mpz_cmp_ui(gcd
, 1) != 0)
575 mpz_gcd(gcd
, gcd
, z
);
582 #if defined(LINEAR_VALUE_IS_MP)
583 if(mpz_cmp_ui(gcd
, 1) != 0){
584 p
= tp
->row
[k
].objet
.val
;
585 for(j
= 0; j
<ncol
; j
++){
586 mpz_divexact(*p
, *p
, gcd
);
590 mpz_divexact(Denom(tp
,k
), Denom(tp
,k
), gcd
);
593 p
= tp
->row
[k
].objet
.val
;
594 for(j
= 0; j
<ncol
; j
++)
596 Denom(tp
,k
) = Denom(tp
,k
)/gcd
;
600 p
= tp
->row
[pivi
].objet
.val
;
601 for(k
= 0; k
<nligne
; k
++)
602 if((Flag(tp
, k
) & Unit
) && tp
->row
[k
].objet
.unit
== pivj
) break;
604 tp
->row
[k
].objet
.val
= p
;
605 for(j
= 0; j
<ncol
; j
++)
606 #if defined(LINEAR_VALUE_IS_MP)
607 mpz_set(*p
++, new[j
]);
612 #if defined(LINEAR_VALUE_IS_MP)
613 mpz_set(Denom(tp
, k
), pivot
);
614 Flag(tp
, pivi
) = Unit
| Zero
;
615 mpz_set(Denom(tp
, pivi
), UN
);
617 Denom(tp
, k
) = pivot
;
618 Flag(tp
, pivi
) = Unit
| Zero
;
619 Denom(tp
, pivi
) = UN
;
621 tp
->row
[pivi
].objet
.unit
= pivj
;
623 for(k
= 0; k
<nligne
; k
++){
625 if(ff
& Unit
) continue;
626 #if defined(LINEAR_VALUE_IS_MP)
627 sgn_x
= mpz_sgn(Index(tp
, k
, pivj
));
629 sgn_x
= Index(tp
, k
, pivj
);
631 if(sgn_x
< 0) fff
= Minus
;
632 else if(sgn_x
== 0) fff
= Zero
;
634 if(fff
!= Zero
&& fff
!= ff
)
635 if(ff
== Zero
) ff
= (fff
== Minus
? Unknown
: fff
);
641 fprintf(dump
, "just pivoted\n");
642 tab_display(tp
, dump
);
645 #if defined(LINEAR_VALUE_IS_MP)
646 mpz_clear(x
); mpz_clear(y
); mpz_clear(d
); mpz_clear(gcd
);
647 mpz_clear(u
); mpz_clear(dpiv
); mpz_clear(lpiv
);
648 mpz_clear(pivot
); mpz_clear(foo
); mpz_clear(z
);
649 mpz_clear(ppivot
); mpz_clear(dppiv
);
651 for(i
=0; i
<ncol
; i
++)
659 * Sort the rows in increasing order of the largest coefficient
660 * and (if TRAITER_DUAL is set) return the new position of the
661 * original constraints.
663 static int *tab_sort_rows(Tableau
*tp
, int nvar
, int nligne
, int flags
)
667 double s
, t
, d
, smax
= 0;
669 int *pos
= NULL
, *ineq
= NULL
;
671 if (flags
& TRAITER_DUAL
) {
672 ineq
= malloc(tp
->height
* sizeof(int));
673 pos
= malloc((tp
->height
-nvar
) * sizeof(int));
675 fprintf(stderr
, "Memory Overflow.\n") ;
680 for (i
= nvar
; i
< nligne
; i
++) {
681 if (Flag(tp
,i
) & Unit
)
684 d
= ENTIER_TO_DOUBLE(Denom(tp
, i
));
685 for (j
= 0; j
< nvar
; j
++) {
686 t
= ENTIER_TO_DOUBLE(Index(tp
,i
,j
))/d
;
691 if (flags
& TRAITER_DUAL
)
695 for (i
= nvar
; i
< nligne
; i
++) {
696 if (Flag(tp
,i
) & Unit
)
700 for (j
= i
; j
< nligne
; j
++) {
701 if (Flag(tp
,j
) & Unit
)
703 if (tp
->row
[j
].size
< s
) {
709 temp
= tp
->row
[pivi
];
710 tp
->row
[pivi
] = tp
->row
[i
];
712 if (flags
& TRAITER_DUAL
) {
714 ineq
[i
] = ineq
[pivi
];
720 if (flags
& TRAITER_DUAL
) {
721 for (i
= nvar
; i
< nligne
; i
++)
729 /* dans cette version, "traiter" modifie ineq; par contre
730 le contexte est immediatement recopie' */
732 void traiter(Tableau
*tp
, Tableau
*ctxt
, int nvar
, int nparm
, int ni
, int nc
,
733 int bigparm
, int flags
)
736 int pivi
, nligne
, ncol
;
737 struct high_water_mark x
;
741 Entier discr
[MAXPARM
];
744 #if !defined(LINEAR_VALUE_IS_MP)
748 #if defined(LINEAR_VALUE_IS_MP)
749 for(i
=0; i
<MAXPARM
; i
++)
751 dcw
= mpz_sizeinbase(tp
->determinant
, 2);
754 for(i
=0; i
<tp
->l_determinant
; i
++)
755 dcw
+= llog(tp
->determinant
[i
]);
761 context
= expanser(ctxt
, 0, nc
, nparm
+1, 0, dch
, dcw
);
763 pos
= tab_sort_rows(tp
, nvar
, nligne
, flags
);
767 fprintf(dump
, "debut for\n");
768 tab_display(tp
, dump
);
771 nligne
= nvar
+ni
; ncol
= nvar
+nparm
+1;
772 if(nligne
> tp
->height
|| ncol
> tp
->width
) {
773 fprintf(stdout
, "Syserr : traiter : tableau too small\n");
776 pivi
= chercher(tp
, Minus
, nligne
);
777 if(pivi
< nligne
) goto pirouette
; /* There is a negative row */
779 pivi
= exam_coef(tp
, nvar
, ncol
, bigparm
);
782 fprintf(dump
, "coefs examined\n");
783 tab_display(tp
, dump
);
787 if(pivi
< nligne
) goto pirouette
;
788 /* There is a row whose coefficients are negative */
789 compa_test(tp
, context
, ni
, nvar
, nparm
, nc
);
791 fprintf(dump
, "compatibility tested\n");
792 tab_display(tp
, dump
);
796 pivi
= chercher(tp
, Minus
, nligne
);
797 if(pivi
< nligne
) goto pirouette
;
798 /* The compatibility test has found a negative row */
799 pivi
= chercher(tp
, Critic
, nligne
);
800 if(pivi
>= nligne
)pivi
= chercher(tp
, Unknown
, nligne
);
801 /* Here, the problem tree splits */
805 struct high_water_mark q
;
806 if(nc
>= context
->height
) {
807 #if defined(LINEAR_VALUE_IS_MP)
808 dcw
= mpz_sizeinbase(context
->determinant
,2);
811 for(i
=0; i
<tp
->l_determinant
; i
++)
812 dcw
+= llog(tp
->determinant
[i
]);
815 context
= expanser(context
, 0, nc
, nparm
+1, 0, dch
, dcw
);
817 if(nparm
>= MAXPARM
) {
818 fprintf(stdout
, "Too much parameters : %d\n", nparm
);
823 fprintf(stdout
,"profondeur %d %lx\n", profondeur
, q
.top
);
824 ntp
= expanser(tp
, nvar
, ni
, ncol
, 0, 0, 0);
828 entier_init_zero(com_dem
);
829 for (j
= 0; j
< nparm
; j
++)
830 entier_gcd(com_dem
, com_dem
, Index(tp
, pivi
, j
+ nvar
+1));
831 if (!(flags
& TRAITER_INT
))
832 entier_gcd(com_dem
, com_dem
, Index(tp
, pivi
, nvar
));
833 for (j
= 0; j
< nparm
; j
++) {
834 entier_divexact(Index(context
, nc
, j
), Index(tp
, pivi
, j
+ nvar
+ 1), com_dem
);
835 sol_val(Index(context
, nc
, j
), UN
);
837 if (!(flags
& TRAITER_INT
))
838 entier_divexact(Index(context
, nc
, nparm
), Index(tp
, pivi
, nvar
), com_dem
);
840 entier_pdivision(Index(context
, nc
, nparm
), Index(tp
, pivi
, nvar
), com_dem
);
841 sol_val(Index(context
, nc
, nparm
), UN
);
842 entier_clear(com_dem
);
843 Flag(context
, nc
) = Unknown
;
844 entier_set_si(Denom(context
, nc
), 1);
845 Flag(ntp
, pivi
) = Plus
;
848 if(verbose
> 0) fflush(dump
);
849 #if defined(LINEAR_VALUE_IS_MP)
850 traiter(ntp
, context
, nvar
, nparm
, ni
, nc
+1, bigparm
, flags
);
854 fprintf(stdout
, "descente %d %lx\n", profondeur
, tab_hwm().top
);
855 for(j
= 0; j
<nparm
; j
++)
856 mpz_neg(Index(context
, nc
, j
), Index(context
, nc
, j
));
857 mpz_add_ui(Index(context
, nc
, nparm
), Index(context
, nc
, nparm
), 1);
858 mpz_neg(Index(context
, nc
, nparm
), Index(context
, nc
, nparm
));
859 Flag(tp
, pivi
) = Minus
;
860 mpz_set(Denom(context
, nc
), UN
);
862 traiter(ntp
, context
, nvar
, nparm
, ni
, nc
+1, bigparm
, flags
);
866 fprintf(stderr
, "descente %d %lx\n", profondeur
, tab_hwm().top
);
867 for(j
= 0; j
<nparm
; j
++)
868 Index(context
, nc
, j
) = - Index(context
, nc
, j
);
869 Index(context
, nc
, nparm
) = - Index(context
, nc
, nparm
) -1;
870 Flag(tp
, pivi
) = Minus
;
871 Denom(context
, nc
) = UN
;
876 /* Here, all rows are positive. Do we need an integral solution? */
877 if (!(flags
& TRAITER_INT
)) {
878 solution(tp
, nvar
, nparm
);
879 if (flags
& TRAITER_DUAL
)
880 solution_dual(tp
, nvar
, nparm
, pos
);
884 pivi
= integrer(&tp
, &context
, &nvar
, &nparm
, &ni
, &nc
, bigparm
);
885 if(pivi
> 0) goto pirouette
;
886 /* A cut has been inserted and is always negative */
887 /* Here, either there is an integral solution, */
888 if(pivi
== 0) solution(tp
, nvar
, nparm
);
889 /* or no solution exists */
893 /* Here, a negative row has been found. The call to <<pivoter>> executes
897 if (pivoter(tp
, pivi
, nvar
, nparm
, ni
) < 0) {
902 /* Danger : a premature return would induce memory leaks */
904 #if defined(LINEAR_VALUE_IS_MP)
905 for(i
=0; i
<MAXPARM
; i
++)