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 Cedric Bastoul *
25 ******************************************************************************/
27 /* Premiere version du 30 juillet 2001. */
35 #define min(x,y) ((x) < (y)? (x) : (y))
40 long int cross_product
, limit
;
41 int allocation
, comptage
;
48 char dump_name
[] = "PipXXXXXX";
50 /* Larger line buffer to accomodate Frédo Vivien exemples. A version
51 handling arbitrary line length should be written ASAP.
56 char inbuff
[INLENGTH
];
61 /******************************************************************************
62 * Fonctions d'acquisition de données (ex-maind.c) *
63 ******************************************************************************/
70 {p
= fgets(inbuff
, INLENGTH
, foo
);
71 if(p
== NULL
) return EOF
;
72 proviso
= min(INLENGTH
, strlen(inbuff
));
74 if(verbose
> 2) fprintf(dump
, "-- %s", inbuff
);
76 return inbuff
[inptr
++];
79 FILE *pip_create_dump_file()
88 fprintf(stderr
, "%s unaccessible\n", g
);
91 dump
= fopen(dump_name
, "w");
97 #if defined(LINEAR_VALUE_IS_MP)
98 int dscanf(FILE *foo
, Entier val
)
100 int dscanf(FILE *foo
, Entier
*val
)
106 for(;inptr
< proviso
; inptr
++)
107 if(inbuff
[inptr
] != ' ' && inbuff
[inptr
] != '\n' && inbuff
[inptr
] != '\t')
109 while(inptr
>= proviso
)
110 {p
= fgets(inbuff
, 256, foo
);
111 if(p
== NULL
) return EOF
;
112 proviso
= strlen(inbuff
);
114 fprintf(dump
, ".. %s", inbuff
);
117 for(inptr
= 0; inptr
< proviso
; inptr
++)
118 if(inbuff
[inptr
] != ' '
119 && inbuff
[inptr
] != '\n'
120 && inbuff
[inptr
] != '\t') break;
122 #if defined(LINEAR_VALUE_IS_MP)
123 if(gmp_sscanf(inbuff
+inptr
, GMP_INPUT_FORMAT
, val
) != 1)
125 if(sscanf(inbuff
+inptr
, FORMAT
, val
) != 1)
129 for(; inptr
< proviso
; inptr
++)
130 if((c
= inbuff
[inptr
]) != '-' && !isdigit(c
)) break;
135 /******************************************************************************
136 * Fonctions d'affichage des structures *
137 ******************************************************************************/
140 /* Fonction pip_matrix_print :
141 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
142 * que contient la structure de type PipMatrix qu'elle recoit en parametre.
143 * Premiere version : Ced. 29 juillet 2001.
145 void pip_matrix_print(FILE * foo
, PipMatrix
* Mat
)
148 unsigned NbRows
, NbColumns
;
150 fprintf(foo
,"%d %d\n", NbRows
=Mat
->NbRows
, NbColumns
=Mat
->NbColumns
) ;
151 for (i
=0;i
<NbRows
;i
++)
153 for (j
=0;j
<NbColumns
;j
++)
154 #if defined(LINEAR_VALUE_IS_MP)
156 mpz_out_str(foo
,10,*p
++) ;
159 fprintf(foo
," "FORMAT
, *p
++) ;
166 /* Fonction pip_vector_print :
167 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
168 * que contient la structure de type PipVector qu'elle recoit en parametre.
169 * Premiere version : Ced. 20 juillet 2001.
171 void pip_vector_print(FILE * foo
, PipVector
* vector
)
175 { fprintf(foo
,"#[") ;
176 for (i
=0;i
<vector
->nb_elements
;i
++)
178 #if defined(LINEAR_VALUE_IS_MP)
179 mpz_out_str(foo
,10,vector
->the_vector
[i
]) ;
180 if (mpz_cmp(vector
->the_deno
[i
],UN
) != 0)
182 fprintf(foo
,FORMAT
,vector
->the_vector
[i
]) ;
183 if (vector
->the_deno
[i
] != UN
)
186 #if defined(LINEAR_VALUE_IS_MP)
187 mpz_out_str(foo
,10,vector
->the_deno
[i
]) ;
189 fprintf(foo
,FORMAT
,vector
->the_deno
[i
]) ;
198 /* Fonction pip_newparm_print :
199 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
200 * que contient la structure de type PipNewparm qu'elle recoit en parametre.
201 * Le parametre indent est le nombre d'espaces blancs en debut de chaque
202 * ligne avant indentation. Une valeur negative de indent signifie qu'on ne
203 * desire pas d'indentation.
204 * Premiere version : Ced. 18 octobre 2001.
206 void pip_newparm_print(FILE * foo
, PipNewparm
* newparm
, int indent
)
211 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
212 fprintf(foo
,"(newparm ") ;
213 fprintf(foo
,"%d",newparm
->rank
) ;
214 fprintf(foo
," (div ") ;
215 pip_vector_print(foo
,newparm
->vector
) ;
217 #if defined(LINEAR_VALUE_IS_MP)
218 mpz_out_str(foo
,10,newparm
->deno
) ;
220 fprintf(foo
,FORMAT
,newparm
->deno
) ;
222 fprintf(foo
,"))\n") ;
224 while ((newparm
= newparm
->next
) != NULL
) ;
229 /* Fonction pip_list_print :
230 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
231 * que contient la structure de type PipList qu'elle recoit en parametre.
232 * Le parametre indent est le nombre d'espaces blancs en debut de chaque
233 * ligne avant indentation. Une valeur negative de indent signifie qu'on ne
234 * desire pas d'indentation.
235 * Premiere version : Ced. 18 octobre 2001.
236 * 16 novembre 2005 : Ced. Prise en compte du cas list->vector == NULL,
237 * jusque là impossible.
239 void pip_list_print(FILE * foo
, PipList
* list
, int indent
)
243 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
244 fprintf(foo
,"()\n") ;
247 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
248 fprintf(foo
,"(list\n") ;
250 { if (list
->vector
!= NULL
)
251 { for (i
=0;i
<indent
+1;i
++) fprintf(foo
," ") ; /* Indent. */
252 pip_vector_print(foo
,list
->vector
) ;
256 while ((list
= list
->next
) != NULL
) ;
257 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
263 /* Fonction pip_quast_print :
264 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
265 * que contient la structure de type PipQuast qu'elle recoit en parametre.
266 * Le parametre indent est le nombre d'espaces blancs en debut de chaque
267 * ligne avant indentation. Une valeur negative de indent signifie qu'on ne
268 * desire pas d'indentation.
269 * 20 juillet 2001 : Premiere version, Ced.
270 * 18 octobre 2001 : eclatement.
272 void pip_quast_print(FILE * foo
, PipQuast
* solution
, int indent
)
275 int new_indent
= indent
>= 0 ? indent
+1 : indent
;
277 if (solution
!= NULL
)
278 { pip_newparm_print(foo
,solution
->newparm
,indent
) ;
279 if (solution
->condition
== NULL
) {
280 pip_list_print(foo
, solution
->list
, indent
);
281 /* Possible dual solution */
282 if (solution
->next_then
)
283 pip_quast_print(foo
, solution
->next_then
, new_indent
);
285 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
286 fprintf(foo
,"(if ") ;
287 pip_vector_print(foo
,solution
->condition
) ;
289 pip_quast_print(foo
, solution
->next_then
, new_indent
);
290 pip_quast_print(foo
, solution
->next_else
, new_indent
);
291 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
296 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
297 fprintf(foo
,"void\n") ;
302 /* Function pip_options_print:
303 * This function prints the content of a PipOptions structure (options)
304 * into a file (foo, possibly stdout).
305 * March 17th 2003: first version.
307 void * pip_options_print(FILE * foo
, PipOptions
* options
)
308 { fprintf(foo
,"Option setting is:\n") ;
309 fprintf(foo
,"Nq =%d\n",options
->Nq
) ;
310 fprintf(foo
,"Verbose =%d\n",options
->Verbose
) ;
311 fprintf(foo
,"Simplify =%d\n",options
->Simplify
) ;
312 fprintf(foo
,"Deepest_cut =%d\n",options
->Deepest_cut
) ;
313 fprintf(foo
,"Maximize =%d\n",options
->Maximize
) ;
314 fprintf(foo
,"Urs_parms =%d\n",options
->Urs_parms
);
315 fprintf(foo
,"Urs_unknowns=%d\n",options
->Urs_unknowns
);
320 /******************************************************************************
321 * Fonctions de liberation memoire *
322 ******************************************************************************/
325 /* Fonction pip_matrix_free :
326 * Cette fonction libere la memoire reservee a la structure de type PipMatrix
327 * que pointe son parametre.
328 * Premiere version : Ced. 29 juillet 2001.
330 void pip_matrix_free(PipMatrix
* matrix
)
332 #if defined(LINEAR_VALUE_IS_MP)
337 for (i
=0;i
<matrix
->p_Init_size
;i
++)
342 { free(matrix
->p_Init
) ;
349 /* Fonction pip_vector_free :
350 * Cette fonction libere la memoire reservee a la structure de type PipVector
351 * que pointe son parametre.
352 * 20 juillet 2001 : Premiere version, Ced.
353 * 18 octobre 2001 : simplification suite a l'eclatement de PipVector.
354 * 16 novembre 2005 : Ced. Prise en compte du cas NULL.
356 void pip_vector_free(PipVector
* vector
)
361 #if defined(LINEAR_VALUE_IS_MP)
362 for (i
=0;i
<vector
->nb_elements
;i
++)
363 { mpz_clear(vector
->the_vector
[i
]);
364 mpz_clear(vector
->the_deno
[i
]);
368 free(vector
->the_vector
) ;
369 free(vector
->the_deno
) ;
375 /* Fonction pip_newparm_free :
376 * Cette fonction libere la memoire reservee a la structure de type PipNewparm
377 * que pointe son parametre. Sont liberes aussi tous les elements de la
378 * liste chainee dont il pouvait etre le depart.
379 * Premiere version : Ced. 18 octobre 2001.
381 void pip_newparm_free(PipNewparm
* newparm
)
382 { PipNewparm
* next
;
384 while (newparm
!= NULL
)
385 { next
= newparm
->next
;
386 #if defined(LINEAR_VALUE_IS_MP)
387 mpz_clear(newparm
->deno
);
389 pip_vector_free(newparm
->vector
) ;
396 /* Fonction pip_list_free :
397 * Cette fonction libere la memoire reservee a la structure de type PipList
398 * que pointe son parametre. Sont liberes aussi tous les elements de la
399 * liste chainee dont il pouvait etre le depart.
400 * Premiere version : Ced. 18 octobre 2001.
402 void pip_list_free(PipList
* list
)
406 { next
= list
->next
;
407 pip_vector_free(list
->vector
) ;
414 /* Fonction pip_quast_free :
415 * Cette fonction libere la memoire reservee a la structure de type
416 * PipSolution que pointe son parametre. Sont liberees aussi toutes les
417 * differentes listes chainees qui pouvaient en partir.
418 * 20 juillet 2001 : Premiere version, Ced.
419 * 18 octobre 2001 : simplification suite a l'eclatement de PipVector.
421 void pip_quast_free(PipQuast
* solution
)
425 pip_newparm_free(solution
->newparm
) ;
427 pip_list_free(solution
->list
) ;
429 pip_vector_free(solution
->condition
);
430 pip_quast_free(solution
->next_then
);
431 pip_quast_free(solution
->next_else
);
436 /* Funtion pip_options_free:
437 * This function frees the allocated memory for a PipOptions structure.
438 * March 15th 2003: first version.
440 void pip_options_free(PipOptions
* options
)
445 /******************************************************************************
446 * Fonction d'initialisation des options *
447 ******************************************************************************/
450 /* Funtion pip_options_init:
451 * This function allocates the memory for a PipOptions structure and fill the
452 * options with the default values.
454 * Nq est un booleen renseignant si on cherche
455 * une solution entiere (vrai=1) ou non (faux=0). Verbose est un booleen
456 * permettant de rendre Pip bavard (Verbose a vrai=1), il imprimera
457 * alors la plupart de ses traitements dans le fichier dont le nom est
458 * dans la variable d'environnement DEBUG, ou si DEBUG
459 * n'est pas placee, dans un nouveau fichier de nom genere par mkstemp, si
460 * Verbose est a faux=0, Pip restera muet. Simplify est un booleen permettant
461 * de demander a Pip de simplifier sa solution (en eliminant les formes de type
462 * 'if #[...] () ()') quand il est a vrai=1, ou non quand il est a faux=0. Max
463 * n'est pas encore utilise et doit etre mis a 0.
465 * March 15th 2003: first version.
467 PipOptions
* pip_options_init(void)
468 { PipOptions
* options
;
470 options
= (PipOptions
*)malloc(sizeof(PipOptions
)) ;
471 /* Default values of the options. */
472 options
->Nq
= 1 ; /* Integer solution. */
473 options
->Verbose
= 0 ; /* No comments. */
474 options
->Simplify
= 0 ; /* Do not simplify solutions. */
475 options
->Deepest_cut
= 0 ; /* Do not use deepest cut algorithm. */
476 options
->Maximize
= 0 ; /* Do not compute maximum. */
477 options
->Urs_parms
= 0 ; /* All parameters are non-negative. */
478 options
->Urs_unknowns
= 0 ; /* All unknows are non-negative. */
479 options
->Compute_dual
= 0; /* Don't compute dual variables. */
485 /******************************************************************************
486 * Fonctions d'acquisition de matrices *
487 ******************************************************************************/
490 /* Fonction pip_matrix_alloc :
491 * Fonction (tres) modifiee de Matrix_Alloc de la polylib. Elle alloue l'espace
492 * memoire necessaire pour recevoir le contenu d'une matrice de NbRows lignes
493 * et de NbColumns colonnes, et initialise les valeurs a 0. Elle retourne un
494 * pointeur sur l'espace memoire alloue.
495 * Premiere version : Ced. 18 octobre 2001.
497 PipMatrix
* pip_matrix_alloc(unsigned NbRows
, unsigned NbColumns
)
498 { PipMatrix
* matrix
;
502 matrix
= (PipMatrix
*)malloc(sizeof(PipMatrix
)) ;
504 { fprintf(stderr
, "Memory Overflow.\n") ;
507 matrix
->NbRows
= NbRows
;
508 matrix
->NbColumns
= NbColumns
;
509 matrix
->p_Init_size
= NbRows
* NbColumns
;
512 matrix
->p_Init
= NULL
;
515 { if (NbColumns
== 0)
517 matrix
->p_Init
= NULL
;
520 { p
= (Entier
**)malloc(NbRows
*sizeof(Entier
*)) ;
522 { fprintf(stderr
, "Memory Overflow.\n") ;
525 q
= (Entier
*)malloc(NbRows
* NbColumns
* sizeof(Entier
)) ;
527 { fprintf(stderr
, "Memory Overflow.\n") ;
532 for (i
=0;i
<NbRows
;i
++)
534 for (j
=0;j
<NbColumns
;j
++)
535 #if defined(LINEAR_VALUE_IS_MP)
536 mpz_init_set_si(*(q
+j
),0) ;
548 /* Fonction pip_matrix_read :
549 * Adaptation de Matrix_Read de la polylib. Cette fonction lit les donnees
550 * d'une matrice dans un fichier 'foo' et retourne un pointeur vers une
551 * structure ou elle a copie les informations de cette matrice. Les donnees
552 * doivent se presenter tq :
553 * - des lignes de commentaires commencant par # (optionnelles),
554 * - le nombre de lignes suivit du nombre de colonnes de la matrice, puis
555 * eventuellement d'un commentaire sur une meme ligne,
556 * - des lignes de la matrice, chaque ligne devant etre sur sa propre ligne de
557 * texte et eventuellement suivies d'un commentaire.
558 * Premiere version : Ced. 18 octobre 2001.
559 * 24 octobre 2002 : premiere version MP, attention, uniquement capable de
560 * lire des long long pour l'instant. On utilise pas
561 * mpz_inp_str car on lit depuis des char * et non des FILE.
563 PipMatrix
* pip_matrix_read(FILE * foo
)
564 { unsigned NbRows
, NbColumns
;
566 #if defined(LINEAR_VALUE_IS_MP)
569 char *c
, s
[1024], str
[1024] ;
573 while (fgets(s
,1024,foo
) == 0) ;
574 while ((*s
=='#' || *s
=='\n') || (sscanf(s
," %u %u",&NbRows
,&NbColumns
)<2))
575 fgets(s
, 1024, foo
) ;
577 matrix
= pip_matrix_alloc(NbRows
,NbColumns
) ;
580 for (i
=0;i
<matrix
->NbRows
;i
++)
582 { c
= fgets(s
,1024,foo
) ;
583 while (isspace(*c
) && (*c
!= '\n'))
586 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
589 { fprintf(stderr
, "Not enough rows.\n") ;
592 for (j
=0;j
<matrix
->NbColumns
;j
++)
593 { if (c
== NULL
|| *c
== '#' || *c
== '\n')
594 { fprintf(stderr
, "Not enough columns.\n") ;
597 /* NdCed : Dans le n ca met strlen(str). */
598 if (sscanf(c
,"%s%n",str
,&n
) == 0)
599 { fprintf(stderr
, "Not enough rows.\n") ;
602 #if defined(LINEAR_VALUE_IS_MP)
603 sscanf(str
,"%lld",&val
) ;
604 mpz_set_si(*p
++,val
) ;
606 sscanf(str
,FORMAT
,p
++) ;
615 /* initialization of pip */
616 static int pip_initialized
= 0;
619 /* Avoid initializing (and leaking) several times */
620 if (!pip_initialized
) {
621 #if defined(LINEAR_VALUE_IS_MP)
622 mpz_init_set_si(UN
, 1);
623 mpz_init_set_si(ZERO
, 0);
637 # if defined(LINEAR_VALUE_IS_MP)
645 * Compute dual variables of equalities from dual variables of
646 * the corresponding pair of inequalities.
648 * In practice, this means we need to remove one of the two
649 * dual variables that corrsponding to the inequalities
650 * and negate the value if it corresponds to the negative
653 static void pip_quast_equalities_dual(PipQuast
*solution
, PipMatrix
*inequnk
)
655 PipList
**list_p
, *list
;
660 if (solution
->condition
) {
661 pip_quast_equalities_dual(solution
->next_then
, inequnk
);
662 pip_quast_equalities_dual(solution
->next_else
, inequnk
);
666 if (!solution
->next_then
)
668 if (!solution
->next_then
->list
)
670 list_p
= &solution
->next_then
->list
;
671 for (i
= 0; i
< inequnk
->NbRows
; ++i
) {
672 if (entier_zero_p(inequnk
->p
[i
][0])) {
673 if (entier_notzero_p((*list_p
)->vector
->the_vector
[0])) {
674 list_p
= &(*list_p
)->next
;
676 *list_p
= list
->next
;
681 *list_p
= list
->next
;
684 entier_oppose((*list_p
)->vector
->the_vector
[0],
685 (*list_p
)->vector
->the_vector
[0]);
686 list_p
= &(*list_p
)->next
;
689 list_p
= &(*list_p
)->next
;
694 /******************************************************************************
695 * Fonction de resolution *
696 ******************************************************************************/
699 /* Fonction pip_solve :
700 * Cette fonction fait un appel a Pip pour la resolution d'un probleme. Le
701 * probleme est fourni dans les arguments. Deux matrices de la forme de celles
702 * utilisees dans la Polylib forment les systemes d'equations/inequations :
703 * un pour les inconnues, l'autre pour les parametres. Bg est le 'bignum'.
704 * Le dernier argument contient les options guidant le comportement de PIP.
705 * Cette fonction retourne la solution sous la forme d'un arbre de structures
707 * 30 juillet 2001 : Premiere version, Ced.
708 * 18 octobre 2001 : suppression de l'argument Np, le nombre de parametres. Il
709 * est a present deduit de ineqpar. Si ineqpar vaut NULL,
710 * c'est que Np vaut 0. S'il y a des parametres mais pas de
711 * contraintes dessus, ineqpar sera une matrice de 0 lignes
712 * mais du bon nombre de colonnes (Np + 2).
713 * 27 février 2003 : Verbose est maintenant gradué.
714 * -1 -> silence absolu
715 * 0 -> silence relatif
716 * 1 -> information sur les coupures dans le cas ou on
717 * cherche une solution entière.
718 * 2 -> information sur les pivots et les déterminants
719 * 3 -> information sur les tableaux.
720 * Chaque option inclut les précédentes. [paf]
721 * 15 mars 2003 : passage a une structure d'options.
723 PipQuast
* pip_solve(inequnk
, ineqpar
, Bg
, options
)
724 PipMatrix
* inequnk
, * ineqpar
;
726 PipOptions
* options
;
727 { Tableau
* ineq
, * context
, * ctxt
;
728 int i
, Np
, Nn
, Nl
, Nm
, p
, q
, xq
, non_vide
, Shift
= 0, Urs_parms
= 0;
730 struct high_water_mark hq
;
732 PipQuast
* solution
;
737 /* initialisations diverses :
738 * - la valeur de Verbose et Deepest_cut sont placees dans leurs variables
739 * globales. Dans le cas ou on doit etre en mode verbose, on ouvre le
740 * fichier dans lequel ecrire les tracages. Si la variable d'environnement
741 * DEBUG est placee, on ecrira dans le nom de fichier correspondant, sinon,
742 * dans un nouveau fichier de nom genere par mkstemp,
743 * - limit est mis au 0 long int (sa valeur par defaut dans Pip original),
744 * - on lance les initialisations pour tab et sol (autres mises en place
745 * de variables globales).
747 verbose
= options
->Verbose
;
748 deepest_cut
= options
->Deepest_cut
;
750 dump
= pip_create_dump_file();
754 #if defined(LINEAR_VALUE_IS_MP)
760 /* Si inequnk est NULL, la solution est automatiquement void (NULL). */
762 { /* Np vaut 0 si ineqpar vaut NULL, ineqpar->NbColumns - 2 sinon (on a -1
763 * pour la constante et -1 pour le marqueur d'egalite/inegalite = -2).
765 Np
= (ineqpar
== NULL
) ? 0 : ineqpar
->NbColumns
- 2 ;
766 /* Calcul du nombre d'inconnues du probleme. Comme les matrices d'entree
767 * sont sous la forme de la polylib.
769 Nn
= inequnk
->NbColumns
- Np
- 2 ;
770 /* Calcul du nombre d'inequations du probleme. Le format de matrice de la
771 * polylib permet les egalites, on doit donc les compter double quand il
774 Nl
= inequnk
->NbRows
;
775 for (i
=0;i
<inequnk
->NbRows
;i
++)
776 #if defined(LINEAR_VALUE_IS_MP)
777 if (mpz_sgn(**(inequnk
->p
+ i
)) == 0)
779 if (**(inequnk
->p
+ i
) == 0)
783 /* On prend les 'marques' de debut de traitement. */
788 if (options
->Maximize
) {
789 sol_flags
|= SOL_MAX
;
791 } else if (options
->Urs_unknowns
) {
792 sol_flags
|= SOL_SHIFT
;
796 if (options
->Urs_parms
) {
797 Urs_parms
= Np
- (Bg
>= 0);
801 /* Si un maximum est demande, mais sans bignum, on crée le bignum. */
802 if (options
->Maximize
|| options
->Urs_unknowns
) {
804 Bg
= inequnk
->NbColumns
- 1 ; /* On choisit sa place. */
805 Np
++ ; /* On le compte comme parametre. */
806 sol_flags
|= SOL_REMOVE
; /* On le supprime apres. */
810 /* On s'assure d'abord que le systeme pour le contexte n'est pas vide
811 * avant de commencer le traitement. Si c'est le cas, la solution est
815 { /* Calcul du nombre d'inequations sur les parametres. Le format de
816 * matrice de la polylib permet les egalites, on doit donc les compter
817 * double quand il y en a.
819 Nm
= ineqpar
->NbRows
;
820 for (i
=0;i
<ineqpar
->NbRows
;i
++)
821 #if defined(LINEAR_VALUE_IS_MP)
822 if (mpz_sgn(**(ineqpar
->p
+ i
)) == 0)
824 if (**(ineqpar
->p
+ i
) == 0)
828 context
= tab_Matrix2Tableau(ineqpar
, Nm
, Np
-Urs_parms
, -1,
829 Shift
, Bg
-Nn
-1, Urs_parms
);
831 tab_simplify(context
, Np
);
834 { /* Traduction du format de matrice de la polylib vers celui de
835 * traitement de Pip. Puis traitement proprement dit.
837 ctxt
= expanser(context
, Np
, Nm
, Np
+1, Np
, 0, 0) ;
838 traiter(ctxt
, NULL
, Np
, 0, Nm
, 0, -1, TRAITER_INT
);
839 non_vide
= is_not_Nil(p
) ;
843 non_vide
= Pip_True
;
847 ineqpar
= pip_matrix_alloc(0, 2);
848 context
= tab_Matrix2Tableau(ineqpar
, Nm
, Np
-Urs_parms
, -1,
849 Shift
, Bg
-Nn
-1, Urs_parms
);
850 pip_matrix_free(ineqpar
);
851 non_vide
= Pip_True
;
855 fprintf(dump
, "%d %d %d %d %d %d\n",Nn
,Np
,Nl
,Nm
,Bg
,options
->Nq
) ;
857 /* S'il est possible de trouver une solution, on passe au traitement. */
860 ineq
= tab_Matrix2Tableau(inequnk
,Nl
,Nn
,Nn
, Shift
,Bg
, Urs_parms
);
862 tab_simplify(ineq
, Nn
);
866 flags
|= TRAITER_INT
;
867 else if (options
->Compute_dual
) {
868 flags
|= TRAITER_DUAL
;
869 sol_flags
|= SOL_DUAL
;
871 traiter(ineq
, context
, Nn
, Np
, Nl
, Nm
, Bg
, flags
);
873 if (options
->Simplify
)
876 /* On traduit la solution du format de solution de Pip vers un arbre
877 * de structures de type PipQuast.
879 solution
= sol_quast_edit(&xq
, NULL
, Bg
-Nn
-1, Urs_parms
, sol_flags
);
880 if ((sol_flags
& SOL_DUAL
) && Nl
> inequnk
->NbRows
)
881 pip_quast_equalities_dual(solution
, inequnk
);