piplib 1.2
[piplib.git] / source / sol.c
blob10779c8455d212624723ddef2f66831a08146102
1 /******************************************************************************
2 * PIP : Parametric Integer Programming *
3 ******************************************************************************
4 * sol.h *
5 ******************************************************************************
6 * *
7 * Copyright Paul Feautrier, 1988, 1993, 1994, 1996, 2002 *
8 * *
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 *
12 * version. *
13 * *
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 *
17 * for more details. *
18 * *
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 *
22 * *
23 * Written by Paul Feautrier and Cedric Bastoul *
24 * *
25 ******************************************************************************/
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
31 #include <piplib/piplib.h>
33 extern long int cross_product, limit;
34 extern int verbose;
35 extern FILE *dump;
37 struct S
38 {int flags;
39 Entier param1, param2;
42 #define Free 0
43 #define Nil 1
44 #define If 2
45 #define List 3
46 #define Form 4
47 #define New 5
48 #define Div 6
49 #define Val 7
50 #define Error 8
52 struct S sol_space[SOL_SIZE];
53 static int sol_free;
55 #if !defined(LINEAR_VALUE_IS_MP)
56 Entier mod(Entier, Entier);
58 Entier pgcd(Entier x, Entier y)
59 {Entier r;
60 while(y)
61 {r = mod(x, y);
62 x = y;
63 y = r;
65 return(x>= 0? x : -x);
67 #endif
69 void sol_init(void)
71 sol_free = 0;
74 int sol_hwm()
76 return(sol_free);
79 void sol_reset(p)
80 int p;
81 {int i;
82 if(p<0 || p>=SOL_SIZE)
83 {fprintf(stderr, "Syserr : sol_reset : Memory allocation error\n");
84 exit(40);
86 #if defined(LINEAR_VALUE_IS_MP)
87 for(i=p; i<sol_free; i++){
88 mpz_clear(sol_space[i].param1);
89 mpz_clear(sol_space[i].param2);
91 #endif
92 sol_free = p;
95 struct S *sol_alloc(void)
96 {struct S *r;
97 r = sol_space + sol_free;
98 r->flags = Free;
99 #if defined(LINEAR_VALUE_IS_MP)
100 mpz_init_set_si(r->param1,0);
101 mpz_init_set_si(r->param2,0);
102 #else
103 r->param1 = r->param2 = 0;
104 #endif
105 sol_free++;
106 if(sol_free >= SOL_SIZE)
107 {fprintf(stderr, "The solution is too complex! : sol\n");
108 exit(26);
110 return(r);
113 void sol_nil(void)
115 struct S * r;
116 r = sol_alloc();
117 r -> flags = Nil;
118 if(verbose > 0)
119 {fprintf(dump, "\nNil");
120 fflush(dump);
124 void sol_error(int c)
126 struct S *r;
127 r = sol_alloc();
128 r->flags = Nil;
129 #if defined(LINEAR_VALUE_IS_MP)
130 mpz_set_si(r->param1, c);
131 #else
132 r->param1 = c;
133 #endif
134 if(verbose > 0) {
135 fprintf(dump, "Erreur %d\n", c);
136 fflush(dump);
140 int is_not_Nil(p)
141 int p;
143 return(sol_space[p].flags != Nil);
146 void sol_if(void)
148 struct S *r;
149 r = sol_alloc();
150 r -> flags = If;
151 if(verbose > 0) {
152 fprintf(dump, "\nIf ");
153 fflush(dump);
157 void sol_list(n)
158 int n;
159 {struct S * r;
160 r = sol_alloc();
161 r->flags = List;
162 #if defined(LINEAR_VALUE_IS_MP)
163 mpz_set_si(r->param1, n);
164 #else
165 r->param1 = n;
166 #endif
167 if(verbose > 0) {
168 fprintf(dump, "\nList %d ", n);
169 fflush(dump);
173 void sol_forme(l)
174 int l;
176 struct S *r;
177 r = sol_alloc();
178 r -> flags = Form;
179 #if defined(LINEAR_VALUE_IS_MP)
180 mpz_set_ui(r -> param1, l);
181 #else
182 r -> param1 = l;
183 #endif
184 if(verbose > 0) {
185 fprintf(dump, "\nForme %d ", l);
186 fflush(dump);
190 void sol_new(k)
191 int k;
193 struct S *r;
194 r = sol_alloc();
195 r -> flags = New;
196 #if defined(LINEAR_VALUE_IS_MP)
197 mpz_set_ui(r -> param1, k);
198 #else
199 r -> param1 = k;
200 #endif
201 if(verbose > 0) {
202 fprintf(dump, "New %d ", k);
203 fflush(dump);
207 void sol_div()
209 struct S *r;
210 r = sol_alloc();
211 r -> flags = Div;
212 if(verbose > 0) {
213 fprintf(dump, "Div ");
214 fflush(dump);
218 void sol_val(n, d)
219 Entier n, d;
221 struct S *r;
222 r = sol_alloc();
223 r -> flags = Val;
224 #if defined(LINEAR_VALUE_IS_MP)
225 mpz_set(r -> param1, n);
226 mpz_set(r -> param2, d);
227 #else
228 r -> param1 = n;
229 r -> param2 = d;
230 #endif
231 if(verbose > 0) {
232 fprintf(dump, "val(");
233 #if defined(LINEAR_VALUE_IS_MP)
234 mpz_out_str(dump, 10, n);
235 fprintf(dump, "/");
236 mpz_out_str(dump, 10, d);
237 #else
238 fprintf(dump, FORMAT, n);
239 fprintf(dump, "/");
240 fprintf(dump, FORMAT, d);
241 #endif
242 fprintf(dump, ") ");
243 fflush(dump);
247 int skip(int);
249 /* a` partir d'un point de la solution, sauter un objet
250 bien forme' ainsi qu'un e'ventuel New et pointer sur l'objet
251 suivant */
253 int skip_New (int i)
255 if(sol_space[i].flags != New) return i;
256 i = skip(i+1); /* sauter le Div */
257 return i;
259 /* au lancement, i indexe une cellule qui est la te^te d'un objet.
260 la valeur retourne'e est la te^te de l'objet qui suit. Les
261 objets de type New sont e'limine's */
263 int skip (int i)
264 {int n, f;
265 while((f = sol_space[i].flags) == Free || f == Error) i++;
266 switch (sol_space[i].flags) {
267 case Nil : case Val : i++; break;
268 case New : i = skip_New(i); break;
269 case If : i = skip(i+1); /* sauter le pre'dicat */
270 i = skip(i); /* sauter le vrai */
271 i = skip(i); break; /* sauter le faux */
272 case List : case Form :
273 #if defined(LINEAR_VALUE_IS_MP)
274 n = mpz_get_si(sol_space[i].param1);
275 #else
276 n = sol_space[i].param1;
277 #endif
278 i++;
279 while(n--) i = skip(i);
280 break;
281 case Div : i = skip(i+1); /* sauter la forme */
282 i = skip(i); /* sauter le diviseur */
283 break;
284 default : fprintf(stderr,
285 "Syserr : skip : unknown %d\n", sol_space[i].flags);
287 return skip_New(i);
289 /* simplification de la solution : e'limination des constructions
290 (if p () ()). N'est en service qu'en pre'sence de l'option -z */
292 void sol_simplify(int i)
293 {int j, k, l;
294 if(sol_space[i].flags == If) {
295 j = skip(i+1); /* j : debut de la partie vraie */
296 k = skip(j); /* k : debut de la partie fausse */
297 sol_simplify(k);
298 sol_simplify(j);
299 if(sol_space[j].flags == Nil && sol_space[k].flags == Nil) {
300 sol_space[i].flags = Nil;
301 if(k >= sol_free - 1) sol_free = i+1;
302 else for(l = i+1; l<=k; l++) sol_space[l].flags = Free;
307 /* e'dition de la solution */
309 int sol_edit(FILE *foo, int i)
310 {int j, n;
311 struct S *p;
312 Entier N, D, d;
313 #if defined(LINEAR_VALUE_IS_MP)
314 mpz_init(N);
315 mpz_init(D);
316 mpz_init(d);
317 #endif
319 p = sol_space + i;
320 for(;;) {
321 if(p->flags == Free) {
322 p++;
323 i++;
324 continue;
326 if(p->flags == New) {
327 #if defined(LINEAR_VALUE_IS_MP)
328 n = mpz_get_si(p->param1);
329 #else
330 n = p->param1;
331 #endif
332 fprintf(foo, "(newparm %d ", n);
333 if(verbose>0)fprintf(dump, "(newparm %d ", n);
334 i = sol_edit(foo, ++i);
335 p = sol_space +i;
336 fprintf(foo, ")\n");
337 if(verbose>0)fprintf(dump, ")\n");
338 continue;
340 break;
342 switch(p->flags){
343 case Nil : fprintf(foo, "()\n");
344 if(verbose>0)fprintf(dump, "()\n");
345 i++; break;
346 case Error :
347 #if defined(LINEAR_VALUE_IS_MP)
348 fprintf(foo, "Error %d\n", mpz_get_si(p->param1));
349 if(verbose>0)
350 fprintf(dump, "Error %d\n", mpz_get_si(p->param1));
351 #else
352 fprintf(foo, "Error %d\n", p->param1);
353 if(verbose>0)
354 fprintf(dump, "Error %d\n", p->param1);
355 #endif
356 i++; break;
357 case If : fprintf(foo, "(if ");
358 if(verbose>0)fprintf(dump, "(if ");
359 i = sol_edit(foo, ++i);
360 i = sol_edit(foo, i);
361 i = sol_edit(foo, i);
362 fprintf(foo, ")\n");
363 if(verbose>0)fprintf(dump, ")\n");
364 break;
365 case List: fprintf(foo, "(list ");
366 if(verbose>0)fprintf(dump, "(list ");
367 #if defined(LINEAR_VALUE_IS_MP)
368 n = mpz_get_si(p->param1);
369 #else
370 n = p->param1;
371 #endif
372 i++;
373 while(n--) i = sol_edit(foo, i);
374 fprintf(foo, ")\n");
375 if(verbose>0)fprintf(dump, ")\n");
376 break;
377 case Form: fprintf(foo, "#[");
378 if(verbose>0)fprintf(dump, "#[");
379 #if defined(LINEAR_VALUE_IS_MP)
380 n = mpz_get_si(p->param1);
381 #else
382 n = p->param1;
383 #endif
384 for(j = 0; j<n; j++){
385 i++; p++;
386 #if defined(LINEAR_VALUE_IS_MP)
387 mpz_set(N, p->param1); mpz_set(D, p->param2);
388 mpz_gcd(d, N, D);
389 if(mpz_cmp(d, D) == 0){
390 putc(' ', foo);
391 mpz_divexact(N, N, d);
392 mpz_out_str(foo, 10, N);
393 if(verbose>0){
394 putc(' ', dump);
395 mpz_out_str(dump, 10, N);
398 else{
399 mpz_divexact(N, N, d);
400 mpz_divexact(D, D, d);
401 putc(' ', foo);
402 mpz_out_str(foo, 10, N);
403 putc('/', foo);
404 mpz_out_str(foo, 10, D);
405 if(verbose>0){
406 putc(' ', dump);
407 mpz_out_str(dump, 10, N);
408 putc('/', dump);
409 mpz_out_str(dump, 10, D);
412 #else
413 N = p->param1; D = p->param2;
414 d = pgcd(N, D);
415 if(d == D){
416 putc(' ', foo);
417 fprintf(foo, FORMAT, N/d);
418 if(verbose>0){
419 putc(' ', dump);
420 fprintf(dump, FORMAT, N/d);
423 else{
424 putc(' ', foo);
425 fprintf(foo,FORMAT,N/d);
426 fprintf(foo,"/");
427 fprintf(foo,FORMAT, D/d);
428 if(verbose>0){
429 putc(' ', dump);
430 fprintf(dump,FORMAT,N/d);
431 fprintf(dump,"/");
432 fprintf(dump,FORMAT, D/d);
435 #endif
437 fprintf(foo, "]\n");
438 if(verbose>0)fprintf(dump, "]\n");
439 i++;
440 break;
441 case Div : fprintf(foo, "(div ");
442 if(verbose>0)fprintf(dump, "(div ");
443 i = sol_edit(foo, ++i);
444 i = sol_edit(foo, i);
445 fprintf(foo, ")\n");
446 if(verbose>0)fprintf(dump, ")\n");
447 break;
448 case Val :
449 #if defined(LINEAR_VALUE_IS_MP)
450 mpz_set(N, p->param1); mpz_set(D, p->param2);
451 mpz_gcd(d, N, D);
452 if(mpz_cmp(d, D) == 0){
453 mpz_divexact(N, N, d);
454 putc(' ', foo);
455 mpz_out_str(foo, 10, N);
456 if(verbose>0){
457 putc(' ', dump);
458 mpz_out_str(dump, 10, N);
461 else{
462 mpz_divexact(N, N, d);
463 mpz_divexact(D, D, d);
464 putc(' ', foo);
465 mpz_out_str(foo, 10, N);
466 fprintf(foo, "/");
467 mpz_out_str(foo, 10, D);
468 if(verbose>0){
469 putc(' ', dump);
470 mpz_out_str(dump, 10, N);
471 fprintf(dump, "/");
472 mpz_out_str(dump, 10, D);
475 #else
476 N = p->param1; D = p->param2;
477 d = pgcd(N, D);
478 if(d == D){putc(' ', foo);
479 fprintf(foo, FORMAT, N/d);
480 if(verbose>0)
481 {putc(' ', dump);
482 fprintf(dump, FORMAT, N/d);
485 else{putc(' ', foo);
486 fprintf(foo, FORMAT, N/d);
487 fprintf(foo, "/");
488 fprintf(foo, FORMAT, D/d);
489 if(verbose>0)
490 {putc(' ', dump);
491 fprintf(dump, FORMAT, N/d);
492 fprintf(dump, "/");
493 fprintf(dump, FORMAT, D/d);
496 #endif
497 i++;
498 break;
499 default : fprintf(foo, "Inconnu : sol\n");
500 if(verbose>0)fprintf(dump, "Inconnu : sol\n");
502 #if defined(LINEAR_VALUE_IS_MP)
503 mpz_clear(d);
504 mpz_clear(D);
505 mpz_clear(N);
506 #endif
507 return(i);
511 /* Fonction sol_vector_edit :
512 * Cette fonction a pour but de placer les informations correspondant
513 * a un Vector dans la grammaire dans une structure de type PipVector. Elle
514 * prend en parametre un pointeur vers une case memoire contenant le
515 * numero de cellule du tableau sol_space a partir de laquelle on doit
516 * commencer la lecture des informations. Elle retourne un pointeur vers
517 * une structure de type PipVector contenant les informations de ce Vector.
518 * Premiere version : Ced. 20 juillet 2001.
520 PipVector * sol_vector_edit(int * i)
521 { int j, n ;
522 struct S *p ;
523 Entier N, D, d ;
524 PipVector * vector ;
526 #if defined(LINEAR_VALUE_IS_MP)
527 mpz_init(N) ;
528 mpz_init(D) ;
529 mpz_init(d) ;
530 #endif
532 vector = (PipVector *)malloc(sizeof(PipVector)) ;
533 if (vector == NULL)
534 { fprintf(stderr, "Memory Overflow.\n") ;
535 exit(1) ;
537 p = sol_space + (*i) ;
538 #if defined(LINEAR_VALUE_IS_MP)
539 n = mpz_get_si(p->param1) ;
540 #else
541 n = p->param1 ;
542 #endif
543 vector->nb_elements = n ;
544 vector->the_vector = (Entier *)malloc(sizeof(Entier)*n) ;
545 if (vector->the_vector == NULL)
546 { fprintf(stderr, "Memory Overflow.\n") ;
547 exit(1) ;
549 vector->the_deno = (Entier *)malloc(sizeof(Entier)*n) ;
550 if (vector->the_deno == NULL)
551 { fprintf(stderr, "Memory Overflow.\n") ;
552 exit(1) ;
555 for (j=0;j<n;j++)
556 { (*i)++ ;
557 p++ ;
558 #if defined(LINEAR_VALUE_IS_MP)
559 mpz_set(N,p->param1) ;
560 mpz_set(D,p->param2) ;
561 mpz_gcd(d, N, D);
562 mpz_init(vector->the_vector[j]) ;
563 mpz_divexact(vector->the_vector[j],N,d) ;
564 mpz_init(vector->the_deno[j]) ;
565 if (mpz_cmp(d, D) == 0)
566 mpz_set(vector->the_deno[j],UN) ;
567 else
568 mpz_divexact(vector->the_deno[j],D,d) ;
569 #else
570 N = p->param1 ;
571 D = p->param2 ;
572 d = pgcd(N, D) ;
573 vector->the_vector[j] = N/d ;
574 if (d == D)
575 vector->the_deno[j] = UN ;
576 else
577 vector->the_deno[j] = D/d ;
578 #endif
580 (*i)++ ;
582 #if defined(LINEAR_VALUE_IS_MP)
583 mpz_clear(d);
584 mpz_clear(D);
585 mpz_clear(N);
586 #endif
588 return(vector) ;
592 /* Fonction sol_newparm_edit :
593 * Cette fonction a pour but de placer les informations correspondant
594 * a un Newparm dans la grammaire dans une structure de type PipNewparm. Elle
595 * prend en parametre un pointeur vers une case memoire contenant le
596 * numero de cellule du tableau sol_space a partir de laquelle on doit
597 * commencer la lecture des informations. Elle retourne un pointeur vers
598 * une structure de type PipNewparm contenant les informations de ce Newparm.
599 * Premiere version : Ced. 18 octobre 2001.
601 PipNewparm * sol_newparm_edit(int * i)
602 { struct S * p ;
603 PipNewparm * newparm, * newparm_new, * newparm_now ;
605 /* On place p au lieu de lecture. */
606 p = sol_space + (*i) ;
607 /* On passe le New et le Div pour aller a Form et lire le VECTOR. */
608 (*i) += 2 ;
610 newparm = (PipNewparm *)malloc(sizeof(PipNewparm)) ;
611 if (newparm == NULL)
612 { fprintf(stderr, "Memory Overflow.\n") ;
613 exit(1) ;
615 newparm->vector = sol_vector_edit(i) ;
616 #if defined(LINEAR_VALUE_IS_MP)
617 newparm->rank = mpz_get_si(p->param1) ;
618 /* On met p a jour pour lire le denominateur (un Val de param2 UN). */
619 p = sol_space + (*i) ;
620 mpz_init_set(newparm->deno,p->param1) ;
621 #else
622 newparm->rank = p->param1 ;
623 p = sol_space + (*i) ;
624 newparm->deno = p->param1 ;
625 #endif
626 newparm->next = NULL ;
628 newparm_now = newparm ;
629 if (verbose)
630 { fprintf(dump,"\n(newparm ") ;
631 fprintf(dump,FORMAT,newparm->rank) ;
632 fprintf(dump," (div ") ;
633 pip_vector_print(dump,newparm->vector) ;
634 fprintf(dump," ") ;
635 #if defined(LINEAR_VALUE_IS_MP)
636 mpz_out_str(dump,10,newparm->deno) ;
637 #else
638 fprintf(dump,FORMAT,newparm->deno) ;
639 #endif
640 fprintf(dump,"))") ;
643 /* On passe aux elements suivants. */
644 (*i) ++ ;
645 p = sol_space + (*i) ;
646 while (p->flags == New)
647 { (*i) += 2 ;
648 newparm_new = (PipNewparm *)malloc(sizeof(PipNewparm)) ;
649 if (newparm_new == NULL)
650 { fprintf(stderr, "Memory Overflow.\n") ;
651 exit(1) ;
653 newparm_new->vector = sol_vector_edit(i) ;
654 #if defined(LINEAR_VALUE_IS_MP)
655 newparm_new->rank = mpz_get_si(p->param1) ;
656 p = sol_space + (*i) ;
657 mpz_init_set(newparm_new->deno,p->param1) ;
658 #else
659 newparm_new->rank = p->param1 ;
660 p = sol_space + (*i) ;
661 newparm_new->deno = p->param1 ;
662 #endif
663 newparm_new->next = NULL ;
665 newparm_now->next = newparm_new ;
666 newparm_now = newparm_now->next ;
667 if (verbose)
668 { fprintf(dump,"\n(newparm ") ;
669 fprintf(dump,FORMAT,newparm_new->rank) ;
670 fprintf(dump," (div ") ;
671 pip_vector_print(dump,newparm_new->vector) ;
672 fprintf(dump," ") ;
673 #if defined(LINEAR_VALUE_IS_MP)
674 mpz_out_str(dump,10,newparm_new->deno) ;
675 #else
676 fprintf(dump,FORMAT,newparm_new->deno) ;
677 #endif
678 fprintf(dump,"))") ;
680 (*i) ++ ;
681 p = sol_space + (*i) ;
683 return(newparm) ;
687 /* Fonction sol_list_edit :
688 * Cette fonction a pour but de placer les informations correspondant
689 * a une List dans la grammaire dans une structure de type PipList. Elle
690 * prend en parametre un pointeur vers une case memoire contenant le
691 * numero de cellule du tableau sol_space a partir de laquelle on doit
692 * commencer la lecture des informations. Elle retourne un pointeur vers
693 * une structure de type PipList contenant les informations de cette List.
694 * Premiere version : Ced. 18 octobre 2001.
696 PipList * sol_list_edit(int * i, int nb_elements)
697 { PipList * list, * list_new, * list_now ;
699 /* Pour le premier element. */
700 list = (PipList *)malloc(sizeof(PipList)) ;
701 if (list == NULL)
702 { fprintf(stderr, "Memory Overflow.\n") ;
703 exit(1) ;
705 list->vector = sol_vector_edit(i) ;
706 list->next = NULL ;
708 list_now = list ;
709 if (verbose)
710 { fprintf(dump,"\n(list ") ;
711 pip_vector_print(dump,list->vector) ;
713 nb_elements-- ;
715 /* Pour les elements suivants. */
716 while (nb_elements--)
717 { list_new = (PipList *)malloc(sizeof(PipList)) ;
718 if (list_new == NULL)
719 { fprintf(stderr, "Memory Overflow.\n") ;
720 exit(1) ;
722 list_new->vector = sol_vector_edit(i) ;
723 list_new->next = NULL ;
725 if (verbose)
726 { fprintf(dump,"\n") ;
727 pip_vector_print(dump,list_new->vector) ;
729 list_now->next = list_new ;
730 list_now = list_now->next ;
732 if (verbose)
733 fprintf(dump,"\n)") ;
735 return(list) ;
739 /* Fonction sol_quast_edit :
740 * Cette fonction a pour but de placer les informations de la solution
741 * (qui sont contenues dans le tableau sol_space) dans une structure de
742 * type PipQuast en vue d'une utilisation directe de la solution par une
743 * application exterieure. Elle prend en parametre un pointeur vers une
744 * case memoire contenant le numero de cellule du tableau sol_space
745 * a partir de laquelle on doit commencer la lecture des informations. Elle
746 * recoit aussi l'adresse du PipQuast qui l'a appelle (pour le champ father).
747 * Elle retourne un pointeur vers une structure de type PipQuast qui
748 * contient toutes les informations sur la solution (sous forme d'arbre).
749 * Remarques : cette fonction lit les informations comme elles doivent
750 * se presenter a la fin du traitement. Elle respecte scrupuleusement
751 * la grammaire attendue et n'accepte de passer des cellules a Free
752 * qu'entre une des trois grandes formes (if, list ou suite de newparm).
753 * 20 juillet 2001 : Premiere version, Ced.
754 * 31 juillet 2001 : Ajout du traitement de l'option verbose = code*2 :0(
755 * 18 octobre 2001 : Grands changements dus a l'eclatement de la structure
756 * PipVector en PipVector, PipNewparm et PipList, et
757 * eclatement de la fonction avec sol_newparm_edit et
758 * sol_list_edit.
760 PipQuast * sol_quast_edit(int * i, PipQuast * father)
761 { int nb_elements ;
762 struct S * p ;
763 PipQuast * solution ;
764 PipList * list_new, * list_now ;
765 PipNewparm * newparm_new, * newparm_now ;
767 /* On place p au lieu de lecture. */
768 p = sol_space + (*i) ;
769 /* En cas d'utilisation de l'option de simplification, une plage de
770 * structures S peut avoir les flags a Free. On doit alors les passer.
772 while (p->flags == Free)
773 { p ++ ;
774 (*i) ++ ;
777 solution = (PipQuast *)malloc(sizeof(PipQuast)) ;
778 if (solution == NULL)
779 { fprintf(stderr, "Memory Overflow.\n") ;
780 exit(1) ;
782 solution->newparm = NULL ;
783 solution->list = NULL ;
784 solution->condition = NULL ;
785 solution->next_then = NULL ;
786 solution->next_else = NULL ;
787 solution->father = father ;
789 /* On peut commencer par une chaine de nouveaux parametres... */
790 if (p->flags == New)
791 { solution->newparm = sol_newparm_edit(i) ;
792 p = sol_space + (*i) ;
795 /* ...ensuite soit par une liste (vide ou non) soit par un if. */
796 (*i)++ ; /* Factorise de List, Nil et If. */
797 switch (p->flags)
798 { case List :
799 #if defined(LINEAR_VALUE_IS_MP)
800 if ((nb_elements = mpz_get_si(p->param1)) != 0)
801 #else
802 if ((nb_elements = p->param1) != 0)
803 #endif
804 solution->list = sol_list_edit(i,nb_elements) ;
805 break ;
806 case Nil : if (verbose)
807 fprintf(dump,"\n()") ;
808 break ;
809 case If : solution->condition = sol_vector_edit(i) ;
810 if (verbose)
811 { fprintf(dump,"\n(if ") ;
812 pip_vector_print(dump,solution->condition) ;
814 solution->next_then = sol_quast_edit(i,solution) ;
815 solution->next_else = sol_quast_edit(i,solution) ;
816 if (verbose)
817 fprintf(dump,"\n)") ;
818 break ;
819 default : fprintf(stderr,"\nAie !!! Flag %d inattendu.\n",p->flags) ;
820 if (verbose)
821 fprintf(dump,"\nAie !!! Flag %d inattendu.\n",p->flags) ;
822 exit(1) ;
825 return(solution) ;