1 /******************************************************************************
2 * PIP : Parametric Integer Programming *
3 ******************************************************************************
5 ******************************************************************************
7 * Copyright Paul Feautrier, 1988-2005 *
9 * This is free software; you can redistribute it and/or modify it under the *
10 * terms of the GNU General Public License as published by the Free Software *
11 * Foundation; either version 2 of the License, or (at your option) any later *
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 General Public License along *
20 * with software; if not, write to the Free Software Foundation, Inc., *
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
++];
80 #if defined(LINEAR_VALUE_IS_MP)
81 int dscanf(FILE *foo
, Entier val
)
83 int dscanf(FILE *foo
, Entier
*val
)
89 for(;inptr
< proviso
; inptr
++)
90 if(inbuff
[inptr
] != ' ' && inbuff
[inptr
] != '\n' && inbuff
[inptr
] != '\t')
92 while(inptr
>= proviso
)
93 {p
= fgets(inbuff
, 256, foo
);
94 if(p
== NULL
) return EOF
;
95 proviso
= strlen(inbuff
);
97 fprintf(dump
, ".. %s", inbuff
);
100 for(inptr
= 0; inptr
< proviso
; inptr
++)
101 if(inbuff
[inptr
] != ' '
102 && inbuff
[inptr
] != '\n'
103 && inbuff
[inptr
] != '\t') break;
105 #if defined(LINEAR_VALUE_IS_MP)
106 if(gmp_sscanf(inbuff
+inptr
, GMP_INPUT_FORMAT
, val
) != 1)
108 if(sscanf(inbuff
+inptr
, FORMAT
, val
) != 1)
112 for(; inptr
< proviso
; inptr
++)
113 if((c
= inbuff
[inptr
]) != '-' && !isdigit(c
)) break;
118 /******************************************************************************
119 * Fonctions d'affichage des structures *
120 ******************************************************************************/
123 /* Fonction pip_matrix_print :
124 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
125 * que contient la structure de type PipMatrix qu'elle recoit en parametre.
126 * Premiere version : Ced. 29 juillet 2001.
128 void pip_matrix_print(FILE * foo
, PipMatrix
* Mat
)
131 unsigned NbRows
, NbColumns
;
133 fprintf(foo
,"%d %d\n", NbRows
=Mat
->NbRows
, NbColumns
=Mat
->NbColumns
) ;
134 for (i
=0;i
<NbRows
;i
++)
136 for (j
=0;j
<NbColumns
;j
++)
137 #if defined(LINEAR_VALUE_IS_MP)
139 mpz_out_str(foo
,10,*p
++) ;
142 fprintf(foo
," "FORMAT
, *p
++) ;
149 /* Fonction pip_vector_print :
150 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
151 * que contient la structure de type PipVector qu'elle recoit en parametre.
152 * Premiere version : Ced. 20 juillet 2001.
154 void pip_vector_print(FILE * foo
, PipVector
* vector
)
158 { fprintf(foo
,"#[") ;
159 for (i
=0;i
<vector
->nb_elements
;i
++)
161 #if defined(LINEAR_VALUE_IS_MP)
162 mpz_out_str(foo
,10,vector
->the_vector
[i
]) ;
163 if (mpz_cmp(vector
->the_deno
[i
],UN
) != 0)
165 fprintf(foo
,FORMAT
,vector
->the_vector
[i
]) ;
166 if (vector
->the_deno
[i
] != UN
)
169 #if defined(LINEAR_VALUE_IS_MP)
170 mpz_out_str(foo
,10,vector
->the_deno
[i
]) ;
172 fprintf(foo
,FORMAT
,vector
->the_deno
[i
]) ;
181 /* Fonction pip_newparm_print :
182 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
183 * que contient la structure de type PipNewparm qu'elle recoit en parametre.
184 * Le parametre indent est le nombre d'espaces blancs en debut de chaque
185 * ligne avant indentation. Une valeur negative de indent signifie qu'on ne
186 * desire pas d'indentation.
187 * Premiere version : Ced. 18 octobre 2001.
189 void pip_newparm_print(FILE * foo
, PipNewparm
* newparm
, int indent
)
194 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
195 fprintf(foo
,"(newparm ") ;
196 fprintf(foo
,"%d",newparm
->rank
) ;
197 fprintf(foo
," (div ") ;
198 pip_vector_print(foo
,newparm
->vector
) ;
200 #if defined(LINEAR_VALUE_IS_MP)
201 mpz_out_str(foo
,10,newparm
->deno
) ;
203 fprintf(foo
,FORMAT
,newparm
->deno
) ;
205 fprintf(foo
,"))\n") ;
207 while ((newparm
= newparm
->next
) != NULL
) ;
212 /* Fonction pip_list_print :
213 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
214 * que contient la structure de type PipList qu'elle recoit en parametre.
215 * Le parametre indent est le nombre d'espaces blancs en debut de chaque
216 * ligne avant indentation. Une valeur negative de indent signifie qu'on ne
217 * desire pas d'indentation.
218 * Premiere version : Ced. 18 octobre 2001.
219 * 16 novembre 2005 : Ced. Prise en compte du cas list->vector == NULL,
220 * jusque là impossible.
222 void pip_list_print(FILE * foo
, PipList
* list
, int indent
)
226 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
227 fprintf(foo
,"()\n") ;
230 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
231 fprintf(foo
,"(list\n") ;
233 { if (list
->vector
!= NULL
)
234 { for (i
=0;i
<indent
+1;i
++) fprintf(foo
," ") ; /* Indent. */
235 pip_vector_print(foo
,list
->vector
) ;
239 while ((list
= list
->next
) != NULL
) ;
240 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
246 /* Fonction pip_quast_print :
247 * Cette fonction se charge d'imprimer sur le flux 'foo' les informations
248 * que contient la structure de type PipQuast qu'elle recoit en parametre.
249 * Le parametre indent est le nombre d'espaces blancs en debut de chaque
250 * ligne avant indentation. Une valeur negative de indent signifie qu'on ne
251 * desire pas d'indentation.
252 * 20 juillet 2001 : Premiere version, Ced.
253 * 18 octobre 2001 : eclatement.
255 void pip_quast_print(FILE * foo
, PipQuast
* solution
, int indent
)
258 int new_indent
= indent
>= 0 ? indent
+1 : indent
;
260 if (solution
!= NULL
)
261 { pip_newparm_print(foo
,solution
->newparm
,indent
) ;
262 if (solution
->condition
== NULL
) {
263 pip_list_print(foo
, solution
->list
, indent
);
264 /* Possible dual solution */
265 if (solution
->next_then
)
266 pip_quast_print(foo
, solution
->next_then
, new_indent
);
268 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
269 fprintf(foo
,"(if ") ;
270 pip_vector_print(foo
,solution
->condition
) ;
272 pip_quast_print(foo
, solution
->next_then
, new_indent
);
273 pip_quast_print(foo
, solution
->next_else
, new_indent
);
274 for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
279 { for (i
=0;i
<indent
;i
++) fprintf(foo
," ") ; /* Indent. */
280 fprintf(foo
,"void\n") ;
285 /* Function pip_options_print:
286 * This function prints the content of a PipOptions structure (options)
287 * into a file (foo, possibly stdout).
288 * March 17th 2003: first version.
290 void * pip_options_print(FILE * foo
, PipOptions
* options
)
291 { fprintf(foo
,"Option setting is:\n") ;
292 fprintf(foo
,"Nq =%d\n",options
->Nq
) ;
293 fprintf(foo
,"Verbose =%d\n",options
->Verbose
) ;
294 fprintf(foo
,"Simplify =%d\n",options
->Simplify
) ;
295 fprintf(foo
,"Deepest_cut =%d\n",options
->Deepest_cut
) ;
296 fprintf(foo
,"Maximize =%d\n",options
->Maximize
) ;
297 fprintf(foo
,"Urs_parms =%d\n",options
->Urs_parms
);
298 fprintf(foo
,"Urs_unknowns=%d\n",options
->Urs_unknowns
);
303 /******************************************************************************
304 * Fonctions de liberation memoire *
305 ******************************************************************************/
308 /* Fonction pip_matrix_free :
309 * Cette fonction libere la memoire reservee a la structure de type PipMatrix
310 * que pointe son parametre.
311 * Premiere version : Ced. 29 juillet 2001.
313 void pip_matrix_free(PipMatrix
* matrix
)
315 #if defined(LINEAR_VALUE_IS_MP)
320 for (i
=0;i
<matrix
->p_Init_size
;i
++)
325 { free(matrix
->p_Init
) ;
332 /* Fonction pip_vector_free :
333 * Cette fonction libere la memoire reservee a la structure de type PipVector
334 * que pointe son parametre.
335 * 20 juillet 2001 : Premiere version, Ced.
336 * 18 octobre 2001 : simplification suite a l'eclatement de PipVector.
337 * 16 novembre 2005 : Ced. Prise en compte du cas NULL.
339 void pip_vector_free(PipVector
* vector
)
344 #if defined(LINEAR_VALUE_IS_MP)
345 for (i
=0;i
<vector
->nb_elements
;i
++)
346 { mpz_clear(vector
->the_vector
[i
]);
347 mpz_clear(vector
->the_deno
[i
]);
351 free(vector
->the_vector
) ;
352 free(vector
->the_deno
) ;
358 /* Fonction pip_newparm_free :
359 * Cette fonction libere la memoire reservee a la structure de type PipNewparm
360 * que pointe son parametre. Sont liberes aussi tous les elements de la
361 * liste chainee dont il pouvait etre le depart.
362 * Premiere version : Ced. 18 octobre 2001.
364 void pip_newparm_free(PipNewparm
* newparm
)
365 { PipNewparm
* next
;
367 while (newparm
!= NULL
)
368 { next
= newparm
->next
;
369 #if defined(LINEAR_VALUE_IS_MP)
370 mpz_clear(newparm
->deno
);
372 pip_vector_free(newparm
->vector
) ;
379 /* Fonction pip_list_free :
380 * Cette fonction libere la memoire reservee a la structure de type PipList
381 * que pointe son parametre. Sont liberes aussi tous les elements de la
382 * liste chainee dont il pouvait etre le depart.
383 * Premiere version : Ced. 18 octobre 2001.
385 void pip_list_free(PipList
* list
)
389 { next
= list
->next
;
390 pip_vector_free(list
->vector
) ;
397 /* Fonction pip_quast_free :
398 * Cette fonction libere la memoire reservee a la structure de type
399 * PipSolution que pointe son parametre. Sont liberees aussi toutes les
400 * differentes listes chainees qui pouvaient en partir.
401 * 20 juillet 2001 : Premiere version, Ced.
402 * 18 octobre 2001 : simplification suite a l'eclatement de PipVector.
404 void pip_quast_free(PipQuast
* solution
)
408 pip_newparm_free(solution
->newparm
) ;
410 pip_list_free(solution
->list
) ;
412 pip_vector_free(solution
->condition
);
413 pip_quast_free(solution
->next_then
);
414 pip_quast_free(solution
->next_else
);
419 /* Funtion pip_options_free:
420 * This function frees the allocated memory for a PipOptions structure.
421 * March 15th 2003: first version.
423 void pip_options_free(PipOptions
* options
)
428 /******************************************************************************
429 * Fonction d'initialisation des options *
430 ******************************************************************************/
433 /* Funtion pip_options_init:
434 * This function allocates the memory for a PipOptions structure and fill the
435 * options with the default values.
437 * Nq est un booleen renseignant si on cherche
438 * une solution entiere (vrai=1) ou non (faux=0). Verbose est un booleen
439 * permettant de rendre Pip bavard (Verbose a vrai=1), il imprimera
440 * alors la plupart de ses traitements dans le fichier dont le nom est
441 * dans la variable d'environnement DEBUG, ou si DEBUG
442 * n'est pas placee, dans un nouveau fichier de nom genere par mkstemp, si
443 * Verbose est a faux=0, Pip restera muet. Simplify est un booleen permettant
444 * de demander a Pip de simplifier sa solution (en eliminant les formes de type
445 * 'if #[...] () ()') quand il est a vrai=1, ou non quand il est a faux=0. Max
446 * n'est pas encore utilise et doit etre mis a 0.
448 * March 15th 2003: first version.
450 PipOptions
* pip_options_init(void)
451 { PipOptions
* options
;
453 options
= (PipOptions
*)malloc(sizeof(PipOptions
)) ;
454 /* Default values of the options. */
455 options
->Nq
= 1 ; /* Integer solution. */
456 options
->Verbose
= 0 ; /* No comments. */
457 options
->Simplify
= 0 ; /* Do not simplify solutions. */
458 options
->Deepest_cut
= 0 ; /* Do not use deepest cut algorithm. */
459 options
->Maximize
= 0 ; /* Do not compute maximum. */
460 options
->Urs_parms
= 0 ; /* All parameters are non-negative. */
461 options
->Urs_unknowns
= 0 ; /* All unknows are non-negative. */
462 options
->Compute_dual
= 0; /* Don't compute dual variables. */
468 /******************************************************************************
469 * Fonctions d'acquisition de matrices *
470 ******************************************************************************/
473 /* Fonction pip_matrix_alloc :
474 * Fonction (tres) modifiee de Matrix_Alloc de la polylib. Elle alloue l'espace
475 * memoire necessaire pour recevoir le contenu d'une matrice de NbRows lignes
476 * et de NbColumns colonnes, et initialise les valeurs a 0. Elle retourne un
477 * pointeur sur l'espace memoire alloue.
478 * Premiere version : Ced. 18 octobre 2001.
480 PipMatrix
* pip_matrix_alloc(unsigned NbRows
, unsigned NbColumns
)
481 { PipMatrix
* matrix
;
485 matrix
= (PipMatrix
*)malloc(sizeof(PipMatrix
)) ;
487 { fprintf(stderr
, "Memory Overflow.\n") ;
490 matrix
->NbRows
= NbRows
;
491 matrix
->NbColumns
= NbColumns
;
492 matrix
->p_Init_size
= NbRows
* NbColumns
;
495 matrix
->p_Init
= NULL
;
498 { if (NbColumns
== 0)
500 matrix
->p_Init
= NULL
;
503 { p
= (Entier
**)malloc(NbRows
*sizeof(Entier
*)) ;
505 { fprintf(stderr
, "Memory Overflow.\n") ;
508 q
= (Entier
*)malloc(NbRows
* NbColumns
* sizeof(Entier
)) ;
510 { fprintf(stderr
, "Memory Overflow.\n") ;
515 for (i
=0;i
<NbRows
;i
++)
517 for (j
=0;j
<NbColumns
;j
++)
518 #if defined(LINEAR_VALUE_IS_MP)
519 mpz_init_set_si(*(q
+j
),0) ;
531 /* Fonction pip_matrix_read :
532 * Adaptation de Matrix_Read de la polylib. Cette fonction lit les donnees
533 * d'une matrice dans un fichier 'foo' et retourne un pointeur vers une
534 * structure ou elle a copie les informations de cette matrice. Les donnees
535 * doivent se presenter tq :
536 * - des lignes de commentaires commencant par # (optionnelles),
537 * - le nombre de lignes suivit du nombre de colonnes de la matrice, puis
538 * eventuellement d'un commentaire sur une meme ligne,
539 * - des lignes de la matrice, chaque ligne devant etre sur sa propre ligne de
540 * texte et eventuellement suivies d'un commentaire.
541 * Premiere version : Ced. 18 octobre 2001.
542 * 24 octobre 2002 : premiere version MP, attention, uniquement capable de
543 * lire des long long pour l'instant. On utilise pas
544 * mpz_inp_str car on lit depuis des char * et non des FILE.
546 PipMatrix
* pip_matrix_read(FILE * foo
)
547 { unsigned NbRows
, NbColumns
;
549 #if defined(LINEAR_VALUE_IS_MP)
552 char *c
, s
[1024], str
[1024] ;
556 while (fgets(s
,1024,foo
) == 0) ;
557 while ((*s
=='#' || *s
=='\n') || (sscanf(s
," %u %u",&NbRows
,&NbColumns
)<2))
558 fgets(s
, 1024, foo
) ;
560 matrix
= pip_matrix_alloc(NbRows
,NbColumns
) ;
563 for (i
=0;i
<matrix
->NbRows
;i
++)
565 { c
= fgets(s
,1024,foo
) ;
566 while (isspace(*c
) && (*c
!= '\n'))
569 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
572 { fprintf(stderr
, "Not enough rows.\n") ;
575 for (j
=0;j
<matrix
->NbColumns
;j
++)
576 { if (c
== NULL
|| *c
== '#' || *c
== '\n')
577 { fprintf(stderr
, "Not enough columns.\n") ;
580 /* NdCed : Dans le n ca met strlen(str). */
581 if (sscanf(c
,"%s%n",str
,&n
) == 0)
582 { fprintf(stderr
, "Not enough rows.\n") ;
585 #if defined(LINEAR_VALUE_IS_MP)
586 sscanf(str
,"%lld",&val
) ;
587 mpz_set_si(*p
++,val
) ;
589 sscanf(str
,FORMAT
,p
++) ;
598 /* initialization of pip */
599 static int pip_initialized
= 0;
602 /* Avoid initializing (and leaking) several times */
603 if (!pip_initialized
) {
604 #if defined(LINEAR_VALUE_IS_MP)
605 mpz_init_set_si(UN
, 1);
606 mpz_init_set_si(ZERO
, 0);
620 # if defined(LINEAR_VALUE_IS_MP)
628 * Compute dual variables of equalities from dual variables of
629 * the corresponding pair of inequalities.
631 * In practice, this means we need to remove one of the two
632 * dual variables that corrsponding to the inequalities
633 * and negate the value if it corresponds to the negative
636 static void pip_quast_equalities_dual(PipQuast
*solution
, PipMatrix
*inequnk
)
638 PipList
**list_p
, *list
;
643 if (solution
->condition
) {
644 pip_quast_equalities_dual(solution
->next_then
, inequnk
);
645 pip_quast_equalities_dual(solution
->next_else
, inequnk
);
649 if (!solution
->next_then
)
651 if (!solution
->next_then
->list
)
653 list_p
= &solution
->next_then
->list
;
654 for (i
= 0; i
< inequnk
->NbRows
; ++i
) {
655 if (entier_zero_p(inequnk
->p
[i
][0])) {
656 if (entier_notzero_p((*list_p
)->vector
->the_vector
[0])) {
657 list_p
= &(*list_p
)->next
;
659 *list_p
= list
->next
;
664 *list_p
= list
->next
;
667 entier_oppose((*list_p
)->vector
->the_vector
[0],
668 (*list_p
)->vector
->the_vector
[0]);
669 list_p
= &(*list_p
)->next
;
672 list_p
= &(*list_p
)->next
;
677 /******************************************************************************
678 * Fonction de resolution *
679 ******************************************************************************/
682 /* Fonction pip_solve :
683 * Cette fonction fait un appel a Pip pour la resolution d'un probleme. Le
684 * probleme est fourni dans les arguments. Deux matrices de la forme de celles
685 * utilisees dans la Polylib forment les systemes d'equations/inequations :
686 * un pour les inconnues, l'autre pour les parametres. Bg est le 'bignum'.
687 * Le dernier argument contient les options guidant le comportement de PIP.
688 * Cette fonction retourne la solution sous la forme d'un arbre de structures
690 * 30 juillet 2001 : Premiere version, Ced.
691 * 18 octobre 2001 : suppression de l'argument Np, le nombre de parametres. Il
692 * est a present deduit de ineqpar. Si ineqpar vaut NULL,
693 * c'est que Np vaut 0. S'il y a des parametres mais pas de
694 * contraintes dessus, ineqpar sera une matrice de 0 lignes
695 * mais du bon nombre de colonnes (Np + 2).
696 * 27 février 2003 : Verbose est maintenant gradué.
697 * -1 -> silence absolu
698 * 0 -> silence relatif
699 * 1 -> information sur les coupures dans le cas ou on
700 * cherche une solution entière.
701 * 2 -> information sur les pivots et les déterminants
702 * 3 -> information sur les tableaux.
703 * Chaque option inclut les précédentes. [paf]
704 * 15 mars 2003 : passage a une structure d'options.
706 PipQuast
* pip_solve(inequnk
, ineqpar
, Bg
, options
)
707 PipMatrix
* inequnk
, * ineqpar
;
709 PipOptions
* options
;
710 { Tableau
* ineq
, * context
, * ctxt
;
711 int i
, Np
, Nn
, Nl
, Nm
, p
, q
, xq
, non_vide
, Shift
= 0, Urs_parms
= 0;
713 struct high_water_mark hq
;
715 PipQuast
* solution
;
720 /* initialisations diverses :
721 * - la valeur de Verbose et Deepest_cut sont placees dans leurs variables
722 * globales. Dans le cas ou on doit etre en mode verbose, on ouvre le
723 * fichier dans lequel ecrire les tracages. Si la variable d'environnement
724 * DEBUG est placee, on ecrira dans le nom de fichier correspondant, sinon,
725 * dans un nouveau fichier de nom genere par mkstemp,
726 * - limit est mis au 0 long int (sa valeur par defaut dans Pip original),
727 * - on lance les initialisations pour tab et sol (autres mises en place
728 * de variables globales).
730 verbose
= options
->Verbose
;
731 deepest_cut
= options
->Deepest_cut
;
733 { g
= getenv("DEBUG") ;
735 { dump
= fopen(g
, "w") ;
737 { fprintf(stderr
,"%s unaccessible\n",g
) ;
742 { mkstemp(dump_name
) ;
743 dump
= fopen(dump_name
, "w") ;
746 #if defined(LINEAR_VALUE_IS_MP)
752 /* Si inequnk est NULL, la solution est automatiquement void (NULL). */
754 { /* Np vaut 0 si ineqpar vaut NULL, ineqpar->NbColumns - 2 sinon (on a -1
755 * pour la constante et -1 pour le marqueur d'egalite/inegalite = -2).
757 Np
= (ineqpar
== NULL
) ? 0 : ineqpar
->NbColumns
- 2 ;
758 /* Calcul du nombre d'inconnues du probleme. Comme les matrices d'entree
759 * sont sous la forme de la polylib.
761 Nn
= inequnk
->NbColumns
- Np
- 2 ;
762 /* Calcul du nombre d'inequations du probleme. Le format de matrice de la
763 * polylib permet les egalites, on doit donc les compter double quand il
766 Nl
= inequnk
->NbRows
;
767 for (i
=0;i
<inequnk
->NbRows
;i
++)
768 #if defined(LINEAR_VALUE_IS_MP)
769 if (mpz_sgn(**(inequnk
->p
+ i
)) == 0)
771 if (**(inequnk
->p
+ i
) == 0)
775 /* On prend les 'marques' de debut de traitement. */
780 if (options
->Maximize
) {
781 sol_flags
|= SOL_MAX
;
783 } else if (options
->Urs_unknowns
) {
784 sol_flags
|= SOL_SHIFT
;
788 if (options
->Urs_parms
) {
789 Urs_parms
= Np
- (Bg
>= 0);
793 /* Si un maximum est demande, mais sans bignum, on crée le bignum. */
794 if (options
->Maximize
|| options
->Urs_unknowns
) {
796 Bg
= inequnk
->NbColumns
- 1 ; /* On choisit sa place. */
797 Np
++ ; /* On le compte comme parametre. */
798 sol_flags
|= SOL_REMOVE
; /* On le supprime apres. */
802 /* On s'assure d'abord que le systeme pour le contexte n'est pas vide
803 * avant de commencer le traitement. Si c'est le cas, la solution est
807 { /* Calcul du nombre d'inequations sur les parametres. Le format de
808 * matrice de la polylib permet les egalites, on doit donc les compter
809 * double quand il y en a.
811 Nm
= ineqpar
->NbRows
;
812 for (i
=0;i
<ineqpar
->NbRows
;i
++)
813 #if defined(LINEAR_VALUE_IS_MP)
814 if (mpz_sgn(**(ineqpar
->p
+ i
)) == 0)
816 if (**(ineqpar
->p
+ i
) == 0)
820 context
= tab_Matrix2Tableau(ineqpar
,Nm
,Np
,0, Shift
,Bg
-Nn
, Urs_parms
);
822 tab_simplify(context
, Np
);
825 { /* Traduction du format de matrice de la polylib vers celui de
826 * traitement de Pip. Puis traitement proprement dit.
828 ctxt
= expanser(context
, Np
, Nm
, Np
+1, Np
, 0, 0) ;
829 traiter(ctxt
, NULL
, Np
, 0, Nm
, 0, -1, TRAITER_INT
);
830 non_vide
= is_not_Nil(p
) ;
834 non_vide
= Pip_True
;
838 ineqpar
= pip_matrix_alloc(0, 2);
839 context
= tab_Matrix2Tableau(ineqpar
, Nm
, Np
, 0, Shift
, Bg
-Nn
, Urs_parms
);
840 pip_matrix_free(ineqpar
);
841 non_vide
= Pip_True
;
845 fprintf(dump
, "%d %d %d %d %d %d\n",Nn
,Np
,Nl
,Nm
,Bg
,options
->Nq
) ;
847 /* S'il est possible de trouver une solution, on passe au traitement. */
850 ineq
= tab_Matrix2Tableau(inequnk
,Nl
,Nn
,Nn
, Shift
,Bg
, Urs_parms
);
852 tab_simplify(ineq
, Nn
);
856 flags
|= TRAITER_INT
;
857 else if (options
->Compute_dual
) {
858 flags
|= TRAITER_DUAL
;
859 sol_flags
|= SOL_DUAL
;
861 traiter(ineq
, context
, Nn
, Np
, Nl
, Nm
, Bg
, flags
);
863 if (options
->Simplify
)
866 /* On traduit la solution du format de solution de Pip vers un arbre
867 * de structures de type PipQuast.
869 solution
= sol_quast_edit(&xq
, NULL
, Bg
-Nn
-1, Urs_parms
, sol_flags
);
870 if ((sol_flags
& SOL_DUAL
) && Nl
> inequnk
->NbRows
)
871 pip_quast_equalities_dual(solution
, inequnk
);