PIPS
chernikova.h
Go to the documentation of this file.
1 /*
2  $Id: chernikova.h 1641 2016-03-02 08:20:19Z coelho $
3 
4  Copyright 1989-2016 MINES ParisTech
5 
6  This file is part of Linear/C3 Library.
7 
8  Linear/C3 Library is free software: you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  any later version.
12 
13  Linear/C3 Library is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE.
16 
17  See the GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #ifndef LINEAR_CHERNIKOVA_H
24 #define LINEAR_CHERNIKOVA_H
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <limits.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 
34 #include "assert.h"
35 #include "boolean.h"
36 #include "vecteur.h"
37 #include "contrainte.h"
38 #include "sc.h"
39 #include "sommet.h"
40 #include "ray_dte.h"
41 #include "sg.h"
42 #include "polyedre.h"
43 #include "polynome.h"
44 
45 // Debugging
46 // ---------
47 
48 #define FPRINT_NBDIGITS 6
49 
50 #define _STRINGOF(str) #str
51 #define STRINGOF(str) _STRINGOF(str)
52 
53 // Memory management
54 // -----------------
55 
56 static void* NOWUNUSED safe_malloc(size_t size) {
57  void* ptr = malloc(size);
58  if (ptr == NULL) {
59  fprintf(stderr, "[" __FILE__ "] out of memory space\n");
60  abort();
61  }
62  return ptr;
63 }
64 
65 static void* NOWUNUSED safe_realloc(void* ptr, size_t size) {
66  ptr = realloc(ptr, size);
67  if (ptr == NULL) {
68  fprintf(stderr, "[" __FILE__ "] out of memory space\n");
69  abort();
70  }
71  return ptr;
72 }
73 
74 static void NOWUNUSED safe_free(void* ptr) {
75  if (ptr != NULL) {
76  free(ptr);
77  }
78 }
79 
80 #define BSWAP(a, b, l) { \
81  char* t = (char*) safe_malloc(l * sizeof(char)); \
82  memcpy((t), (char*) (a), (int) (l)); \
83  memcpy((char*) (a), (char*) (b), (int) (l)); \
84  memcpy((char*) (b), (t), (int) (l)); \
85  free(t); \
86 }
87 
88 #define SWAP(a, b, t) { \
89  (t) = (a); \
90  (a) = (b); \
91  (b) = (t); \
92 }
93 
94 // Alarms
95 // ------
96 
97 // set timeout with signal and alarm
98 // based on environment variable LINEAR_CONVEX_HULL_TIMEOUT
99 #include <signal.h>
100 
101 // name of environment variable to trigger local timeout
102 #define TIMEOUT_ENV "LINEAR_CONVEX_HULL_TIMEOUT"
103 
104 static bool sc_convex_hull_timeout = false;
105 
107  static int linear_convex_hull_timeout = -1;
108  // initialize once from environment
109  if (linear_convex_hull_timeout == -1) {
110  char* env = getenv(TIMEOUT_ENV);
111  if (env) {
112  // fprintf(stderr, "setting convex hull timeout from: %s\n", env);
113  linear_convex_hull_timeout = atoi(env);
114  }
115  // set to 0 in case of
116  if (linear_convex_hull_timeout < 0) {
117  linear_convex_hull_timeout = 0;
118  }
119  }
120  return linear_convex_hull_timeout;
121 }
122 
123 static void catch_alarm_sc_convex_hull(int sig NOWUNUSED) {
124  fprintf(stderr, "CATCH alarm sc_convex_hull !!!\n");
125  //put inside CATCH(any_exception_error) alarm(0); //clear the alarm
126  sc_convex_hull_timeout = true;
128 }
129 
130 // Real vectors
131 // ------------
132 
133 static zval_t* zvec_alloc(unsigned nbvals) {
134  zval_t* zvec = safe_malloc(nbvals * sizeof(zval_t));
135  int i;
136  for (i = 0; i < (int) nbvals; i++) {
137  zval_init(zvec[i]);
138  }
139  return zvec;
140 }
141 
142 static void zvec_free(zval_t* zvec, unsigned nbvals) {
143  int i;
144  for (i = 0; i < (int) nbvals; i++) {
145  zval_clear(zvec[i]);
146  }
147  free(zvec);
148 }
149 
150 static void NOWUNUSED zvec_safe_free(zval_t* zvec, unsigned nbvals) {
151  if (zvec != NULL) {
152  zvec_free(zvec, nbvals);
153  }
154 }
155 
156 static void zvec_swap(zval_t* zvec1, zval_t* zvec2, unsigned nbvals) {
157  zval_t tmp;
158  zval_init(tmp);
159  unsigned i;
160  for (i = 0; i < nbvals; i++) {
161  zval_set(tmp, zvec1[i]);
162  zval_set(zvec1[i], zvec2[i]);
163  zval_set(zvec2[i], tmp);
164  }
165  zval_clear(tmp);
166 }
167 
168 static void zvec_set_i(zval_t* zvec, long val, unsigned nbvals) {
169  unsigned i;
170  for (i = 0; i < nbvals; i++) {
171  zval_set_i(zvec[i], val);
172  }
173 }
174 
175 static void zvec_copy(zval_t* zvec1, zval_t* zvec2, unsigned nbvals) {
176  zval_t* cv1, * cv2;
177  cv1 = zvec1;
178  cv2 = zvec2;
179  unsigned i;
180  for (i = 0; i < nbvals; i++) {
181  zval_set(*cv2++,*cv1++);
182  }
183 }
184 
185 // set zvec3 to lambda * zvec1 + mu * zvec2
186 static void zvec_combine(zval_t* zvec1, zval_t* zvec2, zval_t* zvec3,
187  zval_t lambda, zval_t mu, unsigned nbvals) {
188  zval_t tmp;
189  zval_init(tmp);
190  unsigned i;
191  for (i = 0; i < nbvals; i++) {
192  zval_mul(tmp, lambda, zvec1[i]);
193  zval_addmul(tmp, mu, zvec2[i]);
194  zval_set(zvec3[i], tmp);
195  }
196  zval_clear(tmp);
197 }
198 
199 // set zvec2 to 1/lambda * zvec1
200 static void zvec_antiscale(zval_t* zvec1, zval_t* zvec2,
201  zval_t lambda, unsigned nbvals) {
202  unsigned i;
203  for (i = 0; i < nbvals; i++) {
204  zval_div(zvec2[i], zvec1[i], lambda);
205  }
206 }
207 
208 static void zvec_neg(zval_t* zvec1, zval_t* zvec2, unsigned nbvals) {
209  unsigned i;
210  for (i = 0; i < nbvals; i++) {
211  zval_neg(zvec2[i], zvec1[i]);
212  }
213 }
214 
215 static int zvec_index_first_notzero(zval_t* zvec, unsigned nbvals) {
216  zval_t *cv;
217  cv = zvec;
218  int i;
219  for (i = 0; i < (int) nbvals; i++) {
220  if (!zval_equal_i(*cv, 0)) {
221  break;
222  }
223  cv++;
224  }
225  return i == (int) nbvals ? -1 : i;
226 }
227 
228 // find the position and the index of the smallest (in absolute value) element
229 // different from 0
230 static void zvec_min_notzero(zval_t* zvec, unsigned nbvals,
231  int* pindex, zval_t* pmin) {
232  zval_t aux;
233  int i = zvec_index_first_notzero(zvec, nbvals);
234  if (i == -1) {
235  zval_set_i(*pmin, 1);
236  return;
237  }
238  *pindex = i;
239  zval_abs(*pmin, zvec[i]);
240  zval_init(aux);
241  for (i = i + 1; i < (int) nbvals; i++) {
242  if (zval_equal_i(zvec[i], 0)) {
243  continue;
244  }
245  zval_abs(aux, zvec[i]);
246  if (zval_cmp(aux, *pmin) < 0) {
247  zval_set(*pmin, aux);
248  *pindex = i;
249  }
250  }
251  zval_clear(aux);
252 }
253 
254 // compute the gcd of the values in zvec
255 static void zvec_gcd(zval_t* zvec, unsigned nbvals, zval_t *pgcd) {
256  zval_t* vals = safe_malloc(nbvals * sizeof(zval_t));
257  zval_t* cw, * cv;
258  int i, index = 0;
259  bool notzero;
260  for (i = 0; i < (int) nbvals; i++) {
261  zval_init(vals[i]);
262  }
263  cv = zvec;
264  for (cw = vals, i = 0; i < (int) nbvals; i++) {
265  zval_abs(*cw, *cv);
266  cw++;
267  cv++;
268  }
269  do {
270  zvec_min_notzero(vals, nbvals, &index, pgcd);
271  if (!zval_equal_i(*pgcd, 1)) {
272  cw = vals;
273  notzero = false;
274  for (i = 0; i < (int) nbvals; i++, cw++) {
275  if (i != index) {
276  zval_mod(*cw, *cw, *pgcd);
277  notzero |= !zval_equal_i(*cw, 0);
278  }
279  }
280  }
281  else {
282  break;
283  }
284  }
285  while (notzero);
286  for (i = 0; i < (int) nbvals; i++) {
287  zval_clear(vals[i]);
288  }
289  free(vals);
290 }
291 
292 // divide values in zvec s.t. the gcd is 1
293 static void zvec_normalize(zval_t* zvec, unsigned nbvals) {
294  zval_t gcd;
295  zval_init(gcd);
296  zvec_gcd(zvec, nbvals, &gcd);
297  if (!zval_equal_i(gcd, 1)) {
298  zvec_antiscale(zvec, zvec, gcd, nbvals);
299  }
300  zval_clear(gcd);
301 }
302 
303 static int NOWUNUSED zvec_fprint(FILE* stream, zval_t* zvec, unsigned nbvals) {
304  int c = fprintf(stream, "[");
305  if (nbvals != 0) {
306  c += zval_fprint(stream, zvec[0]);
307  }
308  unsigned i;
309  for (i = 1; i < nbvals; i++) {
310  c += fprintf(stream, ", ");
311  c += zval_fprint(stream, zvec[i]);
312  }
313  c += fprintf(stream, "]");
314  return c;
315 }
316 
317 // Real matrices
318 // -------------
319 
320 typedef struct {
321  unsigned nbrows;
322  unsigned nbcols;
325  unsigned nbvals;
327 
328 typedef zmat_s zmat_t[1];
329 
330 static zmat_p zmat_alloc(unsigned nbrows, unsigned nbcols) {
331  zmat_p zmat = safe_malloc(sizeof(zmat_s));
332  zmat->nbrows = nbrows;
333  zmat->nbcols = nbcols;
334  if (nbrows == 0 || nbcols == 0) {
335  zmat->vals = (zval_t**) 0;
336  zmat->rawvals = (zval_t*) 0;
337  zmat->nbvals = 0;
338  }
339  else {
340  zmat->nbvals = nbrows * nbcols;
341  zval_t* rawvals = zvec_alloc(zmat->nbvals);
342  zval_t** vals = safe_malloc(nbrows * sizeof(zval_t*));
343  zmat->rawvals = rawvals;
344  zmat->vals = vals;
345  int i;
346  for (i = 0; i < (int) nbrows; i++) {
347  *vals++ = rawvals;
348  rawvals += nbcols;
349  }
350  }
351  return zmat;
352 }
353 
354 static void zmat_free(zmat_p zmat) {
355  if (zmat->rawvals) {
356  zvec_free(zmat->rawvals, zmat->nbvals);
357  }
358  if (zmat->vals) {
359  free(zmat->vals);
360  }
361  free(zmat);
362 }
363 
364 static void NOWUNUSED zmat_safe_free(zmat_p zmat) {
365  if (zmat != NULL) {
366  zmat_free(zmat);
367  }
368 }
369 
370 // add rows to the matrix
371 static void zmat_extend(zmat_p zmat, unsigned nbrows) {
372  zmat->vals = safe_realloc(zmat->vals, nbrows * sizeof(zval_t*));
373  int i;
374  if (zmat->nbvals < nbrows * zmat->nbcols) {
375  zmat->rawvals = safe_realloc(zmat->rawvals, nbrows * zmat->nbcols * sizeof(zval_t));
376  zvec_set_i(zmat->rawvals + zmat->nbrows * zmat->nbcols, 0,
377  zmat->nbvals - zmat->nbrows * zmat->nbcols);
378  for (i = (int) zmat->nbvals; i < (int) (zmat->nbcols * nbrows); i++) {
379  zval_init(zmat->rawvals[i]);
380  }
381  zmat->nbvals = zmat->nbcols*nbrows;
382  }
383  else {
384  zvec_set_i(zmat->rawvals + zmat->nbrows * zmat->nbcols, 0,
385  (nbrows - zmat->nbrows) * zmat->nbcols);
386  }
387  for (i = 0; i < (int) nbrows; i++) {
388  zmat->vals[i] = zmat->rawvals + (i * zmat->nbcols);
389  }
390  zmat->nbrows = nbrows;
391 }
392 
393 static void NOWUNUSED zmat_fprint(FILE* stream, zmat_p zmat) {
394  fprintf(stream, "%d %d\n", zmat->nbrows, zmat->nbcols);
395  if (zmat->nbcols == 0) {
396  fprintf(stream, "\n");
397  return;
398  }
399  int i, j;
400  for (i = 0; i < (int) zmat->nbrows; i++) {
401  zval_t* vals = *(zmat->vals+i);
402  for (j = 0; j < (int) zmat->nbcols; j++) {
403  fprintf(stream, "%" STRINGOF(FPRINT_NBDIGITS) "li", zval_get_i(*vals++));
404  }
405  fprintf(stream, "\n");
406  }
407 }
408 
409 // Boolean misc
410 // ------------
411 
412 #define WSIZE (8 * sizeof(int))
413 
414 #define MSB ((unsigned) (((unsigned) 1) << (WSIZE - 1)))
415 
416 #define NEXT(j ,b) { \
417  if (!((b) >>= 1)) { \
418  (b) = MSB; \
419  (j)++; \
420  } \
421 }
422 
423 // Boolean vectors
424 // ---------------
425 
426 // store the logical `or' the bvec1 and bvec2 into bvec3
427 static void bvec_lor(int* bvec1, int* bvec2, int* bvec3, unsigned nbvals) {
428  int* cp1, * cp2, * cp3;
429  cp1 = bvec1;
430  cp2 = bvec2;
431  cp3 = bvec3;
432  int i;
433  for (i = 0; i < (int) nbvals; i++) {
434  *cp3 = *cp1 | *cp2;
435  cp3++;
436  cp1++;
437  cp2++;
438  }
439 }
440 
441 #define bvec_copy(bvec1, bvec2, nbvals) \
442  (memcpy((char*) (bvec2), (char*) (bvec1), (int) ((nbvals) * sizeof(int))))
443 
444 #define bvec_init(bvec, nbvals) \
445  (memset((char*) (bvec), 0, (int) ((nbvals) * sizeof(int))))
446 
447 // Boolean matrices (used as saturation matrices)
448 // ----------------
449 
450 typedef struct {
451  unsigned nbrows;
452  unsigned nbcols;
453  int **vals;
454  int *rawvals;
456 
457 typedef bmat_s bmat_t[1];
458 
459 static bmat_p bmat_alloc(int nbrows, int nbcols) {
460  int** vals;
461  int* rawvals;
462  bmat_p bmat = safe_malloc(sizeof(bmat_s));
463  bmat->nbrows = nbrows;
464  bmat->nbcols = nbcols;
465  if (nbrows == 0 || nbcols == 0) {
466  bmat->vals = NULL;
467  return bmat;
468  }
469  bmat->vals = vals = safe_malloc(nbrows * sizeof(int*));
470  bmat->rawvals = rawvals = safe_malloc(nbrows * nbcols * sizeof(int));
471  int i;
472  for (i = 0; i < nbrows; i++) {
473  *vals++ = rawvals;
474  rawvals += nbcols;
475  }
476  return bmat;
477 }
478 
479 static void bmat_free(bmat_p bmat) {
480  if (bmat->vals) {
481  free(bmat->rawvals);
482  free(bmat->vals);
483  }
484  free(bmat);
485 }
486 
487 static void NOWUNUSED bmat_safe_free(bmat_p bmat) {
488  if (bmat != NULL) {
489  bmat_free(bmat);
490  }
491 }
492 
493 static void bmat_extend(bmat_p bmat, zmat_p zmat, unsigned nbrows) {
494  unsigned nbcols = (zmat->nbrows - 1) / WSIZE + 1;
495  bmat->vals = safe_realloc(bmat->vals, nbrows * sizeof(int*));
496  bmat->rawvals = safe_realloc(bmat->rawvals, nbrows * nbcols * sizeof(int));
497  int i;
498  for (i = 0; i < (int) nbrows; i++) {
499  bmat->vals[i] = bmat->rawvals + (i * nbcols);
500  }
501  bmat->nbrows = nbrows;
502 }
503 
504 static void NOWUNUSED bmat_fprint(FILE* stream, bmat_p bmat) {
505  int *vals;
506  fprintf(stream, "%d %d\n", bmat->nbrows, bmat->nbcols);
507  int i, j;
508  for (i = 0; i < (int) bmat->nbrows; i++) {
509  vals = *(bmat->vals + i);
510  for (j = 0; j < (int) bmat->nbcols; j++) {
511  fprintf(stream, " %10X ", *vals++);
512  }
513  fprintf(stream, "\n");
514  }
515 }
516 
517 // Chernikova's algorithm
518 // ----------------------
519 
520 // Chernikova's algorithm allows to switch between constraint and ray
521 // representations of a polyhedron. Both are stored into matrices. A (boolean)
522 // saturation matrix is also used to speed up computations.
523 //
524 // Constraints are represented by lines in the matrix `constrs', as follows:
525 // ----------------------------
526 // | ... | ... | ... |
527 // | e | a1 a2 ... an | b |
528 // | ... | ... | ... |
529 // ----------------------------
530 // | 1 | 0 0 ... 0 | 1 | <- l
531 // ----------------------------
532 // where
533 // * e is the type of constraint: 0 for an equation ax = b,
534 // 1 for an inequation ax >= b;
535 // * a1, ..., an are the coefficients in a;
536 // * b is the constant term.
537 // Equations are stored first, followed by inequations.
538 // An additional last line l is also present.
539 //
540 // Rays, lines and vertices are represented by lines in the matrix `rays':
541 // ----------------------------
542 // | ... | ... | ... |
543 // | r | a1 a2 ... an | d |
544 // | ... | ... | ... |
545 // ----------------------------
546 // where
547 // * r and d allow to determine the data type: line (r = d = 0),
548 // ray (r = 1, d = 0) or vertex (r = 1, d != 0);
549 // * a1, ..., an are the coefficients;
550 // * only for vertices, d is the denominator.
551 // Lines are stored first, then rays and finally vertices.
552 
553 static void combine(zval_t* zvec1, zval_t* zvec2, zval_t* zvec3,
554  int pos, unsigned nbvals) {
555  zval_t a1, a2, gcd;
556  zval_t abs_a1, abs_a2, neg_a1;
557  zval_init(a1); zval_init(a2); zval_init(gcd);
558  zval_init(abs_a1); zval_init(abs_a2); zval_init(neg_a1);
559  zval_set(a1, zvec1[pos]);
560  zval_set(a2, zvec2[pos]);
561  zval_abs(abs_a1, a1);
562  zval_abs(abs_a2, a2);
563  zval_gcd(gcd, abs_a1, abs_a2);
564  zval_div(a1, a1, gcd);
565  zval_div(a2, a2, gcd);
566  zval_neg(neg_a1, a1);
567  zvec_combine(zvec1 + 1, zvec2 + 1, zvec3 + 1, a2, neg_a1, nbvals);
568  zvec_normalize(zvec3 + 1, nbvals);
569  zval_clear(a1); zval_clear(a2); zval_clear(gcd);
570  zval_clear(abs_a1); zval_clear(abs_a2); zval_clear(neg_a1);
571 }
572 
573 static void sort_rays(zmat_p rays, bmat_p sat, int nbbrays, int nbrays,
574  int *equal_bound, int *sup_bound, unsigned nbcols1,
575  unsigned nbcols2, unsigned bx, unsigned jx) {
576  int inf_bound;
577  zval_t** uni_eq, ** uni_sup, ** uni_inf;
578  int ** inc_eq, ** inc_sup, ** inc_inf;
579  *sup_bound = *equal_bound = nbbrays;
580  uni_sup = uni_eq = rays->vals + nbbrays;
581  inc_sup = inc_eq = sat->vals + nbbrays;
582  inf_bound = nbrays;
583  uni_inf = rays->vals + nbrays;
584  inc_inf = sat->vals + nbrays;
585  while (inf_bound > *sup_bound) {
586  if (zval_equal_i(**uni_sup, 0)) {
587  if (inc_eq != inc_sup) {
588  zvec_swap(*uni_eq, *uni_sup, nbcols1);
589  BSWAP(*inc_eq, *inc_sup, nbcols2);
590  }
591  (*equal_bound)++;
592  uni_eq++;
593  inc_eq++;
594  (*sup_bound)++;
595  uni_sup++;
596  inc_sup++;
597  }
598  else {
599  *((*inc_sup) + jx) |= bx;
600  if (zval_cmp_i(**uni_sup, 0) < 0) {
601  inf_bound--;
602  uni_inf--;
603  inc_inf--;
604  if (inc_inf != inc_sup) {
605  zvec_swap(*uni_inf, *uni_sup, nbcols1);
606  BSWAP(*inc_inf, *inc_sup, nbcols2);
607  }
608  }
609  else {
610  (*sup_bound)++;
611  uni_sup++;
612  inc_sup++;
613  }
614  }
615  }
616 }
617 
618 static int chernikova(
619  zmat_p constrs, zmat_p rays, bmat_p sat,
620  volatile unsigned nbbrays,
621  volatile unsigned nbmaxrays,
622  bool dual)
623 {
624  unsigned nbconstrs = constrs->nbrows;
625  volatile unsigned nbrays = rays->nbrows;
626  unsigned nbdims = constrs->nbcols - 1;
627  unsigned sat_nbcols = sat->nbcols;
628  unsigned nbcols1 = nbdims + 1;
629  unsigned nbcols2 = sat_nbcols * sizeof(int);
630  int sup_bound, equal_bound, bound;
631  int i, j, k, l;
632  unsigned bx, m, jx;
633  bool redundant, rayonly;
634  int aux, nbcommonconstrs, index;
635  zval_t* vals1, * vals2, * vals3;
636  int* iv1, * iv2;
637  int* tmp = safe_malloc(nbcols2);
639  free(tmp);
640  RETHROW();
641  }
642  TRY {
643  jx = 0;
644  bx = MSB;
645  for (k = 0; k < (int) nbconstrs; k++) {
646  index = nbrays;
647  for (i = 0; i < (int) nbrays; i++) {
648  vals1 = rays->vals[i] + 1;
649  vals2 = constrs->vals[k] + 1;
650  vals3 = rays->vals[i];
651  zval_mul(*vals3, *vals1, *vals2);
652  vals1++;
653  vals2++;
654  for (j = 1; j < (int) nbdims; j++) {
655  zval_addmul(*vals3, *vals1, *vals2);
656  vals1++;
657  vals2++;
658  }
659  if (!zval_equal_i(*vals3, 0) && i < index) {
660  index = i;
661  }
662  }
663  if (index < (int) nbbrays) {
664  nbbrays--;
665  if ((int) nbbrays != index) {
666  zvec_swap(rays->vals[index], rays->vals[nbbrays], nbcols1);
667  }
668  for (i = 0; i < (int) nbbrays; i++) {
669  if (!zval_equal_i(rays->vals[i][0], 0)) {
670  combine(rays->vals[i], rays->vals[nbbrays], rays->vals[i],
671  0, nbdims);
672  }
673  }
674  if (zval_cmp_i(rays->vals[nbbrays][0], 0) < 0) {
675  vals1 = rays->vals[nbbrays];
676  for (j = 0; j < (int) nbdims + 1; j++) {
677  zval_neg(*vals1, *vals1);
678  vals1++;
679  }
680  }
681  for (i = (int) nbbrays + 1; i < (int) nbrays; i++) {
682  if (!zval_equal_i(rays->vals[i][0], 0)) {
683  combine(rays->vals[i], rays->vals[nbbrays], rays->vals[i],
684  0, nbdims);
685  }
686  }
687  if (!zval_equal_i(constrs->vals[k][0], 0)) {
688  for (j = 0; j < (int) sat_nbcols; j++) {
689  sat->vals[nbbrays][j] = 0;
690  }
691  sat->vals[nbbrays][jx] |= bx;
692  }
693  else {
694  if (--nbrays != nbbrays) {
695  zvec_copy(rays->vals[nbrays], rays->vals[nbbrays], nbdims + 1);
696  bvec_copy(sat->vals[nbrays], sat->vals[nbbrays], sat_nbcols);
697  }
698  }
699  }
700  else {
701  sort_rays(rays, sat, nbbrays, nbrays, &equal_bound, &sup_bound,
702  nbcols1, nbcols2, bx, jx);
703  bound = nbrays;
704  for (i = equal_bound; i < sup_bound; i++) {
705  for (j = sup_bound; j < bound; j++) {
706  nbcommonconstrs = 0;
707  for (l = 0; l < (int) jx; l++) {
708  aux = tmp[l] = sat->vals[i][l] | sat->vals[j][l];
709  for (m = MSB; m != 0; m >>= 1) {
710  if(!(aux & m)) {
711  nbcommonconstrs++;
712  }
713  }
714  }
715  aux = tmp[jx] = sat->vals[i][jx] | sat->vals[j][jx];
716  for (m = MSB; m != bx; m >>= 1) {
717  if (!(aux & m)) {
718  nbcommonconstrs++;
719  }
720  }
721  rayonly = zval_equal_i(rays->vals[i][nbdims], 0) &&
722  zval_equal_i(rays->vals[j][nbdims], 0) &&
723  dual == false;
724  if (rayonly) {
725  nbcommonconstrs++;
726  }
727  if (nbcommonconstrs + nbbrays >= nbdims - 2) {
728  redundant = false;
729  for (m = nbbrays; (int) m < bound; m++) {
730  if (((int) m != i) && ((int) m != j)) {
731  if (rayonly && !zval_equal_i(rays->vals[m][nbdims], 0)) {
732  continue;
733  }
734  iv1 = tmp;
735  iv2 = sat->vals[m];
736  for (l = 0; l <= (int) jx; l++, iv2++, iv1++) {
737  if (*iv2 & ~*iv1) {
738  break;
739  }
740  }
741  if (l > (int) jx) {
742  redundant = true;
743  break;
744  }
745  }
746  }
747  if (!redundant) {
748  if (nbrays == nbmaxrays) {
749  nbmaxrays *= 2;
750  rays->nbrows = nbrays;
751  zmat_extend(rays, nbmaxrays);
752  bmat_extend(sat, constrs, nbmaxrays);
753  }
754  combine(rays->vals[j], rays->vals[i], rays->vals[nbrays],
755  0, nbdims);
756  bvec_lor(sat->vals[j], sat->vals[i], sat->vals[nbrays],
757  sat_nbcols);
758  sat->vals[nbrays][jx] &= ~bx;
759  nbrays++;
760  }
761  }
762  }
763  }
764  j = !zval_equal_i(constrs->vals[k][0], 0) ? sup_bound : equal_bound;
765  i = nbrays;
766  while (j < bound && i > bound) {
767  i--;
768  zvec_copy(rays->vals[i], rays->vals[j], nbdims + 1);
769  bvec_copy(sat->vals[i], sat->vals[j], sat_nbcols);
770  j++;
771  }
772  if (j == bound) {
773  nbrays = i;
774  }
775  else {
776  nbrays = j;
777  }
778  }
779  NEXT(jx, bx);
780  }
781  rays->nbrows = nbrays;
782  sat->nbrows = nbrays;
783  }
785  free(tmp);
786  return 0;
787 }
788 
789 static int gauss(zmat_p zmat, int nbeqs, int nbdims) {
790  zval_t** vals = zmat->vals;
791  int nbrows = zmat->nbrows;
792  int i, j, k, pivot, rank;
793  int* indexes = safe_malloc(nbdims * sizeof(int));
794  zval_t gcd;
795  zval_init (gcd);
796  rank = 0;
798  safe_free(indexes);
799  zval_clear(gcd);
800  RETHROW();
801  }
802  TRY {
803  for (j = 1; j <= nbdims; j++) {
804  for (i = rank; i < nbeqs; i++) {
805  if (!zval_equal_i(vals[i][j], 0)) {
806  break;
807  }
808  }
809  if (i != nbeqs) {
810  if (i != rank) {
811  zvec_swap(vals[rank] + 1, vals[i] + 1, nbdims);
812  }
813  zvec_gcd(vals[rank] + 1, nbdims, &gcd);
814  if (zval_cmp_i(gcd, 2) >= 0) {
815  zvec_antiscale(vals[rank] + 1, vals[rank] + 1, gcd, nbdims);
816  }
817  if (zval_cmp_i(vals[rank][j], 0) < 0) {
818  zvec_neg(vals[rank] + 1, vals[rank] + 1, nbdims);
819  }
820  pivot = i;
821  for (i = pivot + 1; i < nbeqs; i++) {
822  if (!zval_equal_i(vals[i][j], 0)) {
823  combine(vals[i], vals[rank], vals[i], j, nbdims);
824  }
825  }
826  indexes[rank] = j;
827  rank++;
828  }
829  }
830  for (k = rank - 1; k >= 0; k--) {
831  j = indexes[k];
832  for (i = 0; i < k; i++) {
833  if (!zval_equal_i(vals[i][j], 0)) {
834  combine(vals[i], vals[k], vals[i], j, nbdims);
835  }
836  }
837  for (i = nbeqs; i < nbrows; i++) {
838  if (!zval_equal_i(vals[i][j], 0)) {
839  combine (vals[i], vals[k], vals[i], j, nbdims);
840  }
841  }
842  }
843  }
845  free(indexes);
846  zval_clear(gcd);
847  return rank;
848 }
849 
850 static void remove_redundants(zmat_p* pconstrs, zmat_p* prays, bmat_p sat)
851 {
852  zmat_p constrs = *pconstrs, rays = *prays;
853  zmat_p constrs2 = NULL, rays2 = NULL;
854  unsigned nbbrays, nburays, nbeqs, nbineqs;
855  unsigned nbbrays2 = -1, nburays2 = -1, nbeqs2 = -1, nbineqs2 = -1;
856  unsigned nbdims = constrs->nbcols - 1;
857  unsigned nbrays = rays->nbrows;
858  unsigned sat_nbcols = sat->nbcols;
859  volatile unsigned nbconstrs = constrs->nbrows;
860  unsigned nbcols2 = sat_nbcols * sizeof(int);
861  int i, j, k;
862  int aux;
863  bool redundant;
864  unsigned status;
865  unsigned* trace = NULL, * bx = NULL, * jx = NULL, dimrayspace, b;
866  zval_t* tmp = zvec_alloc(nbdims + 1);;
867  zval_t one/*, mone*/;
868  zval_init(one);/* zval_init(mone);*/
869  zval_set_i(one, 1);/* zval_set_i(mone, -1);*/
870  bx = safe_malloc(nbconstrs * sizeof(unsigned));
871  jx = safe_malloc(nbconstrs * sizeof(unsigned));
873  zvec_free(tmp, nbdims + 1);
874  zval_clear(one); //zval_clear(mone);
875  safe_free(bx);
876  safe_free(jx);
877  safe_free(trace);
878  zmat_safe_free(constrs2);
879  zmat_safe_free(rays2);
880  RETHROW();
881  }
882  TRY {
883  i = 0;
884  b = MSB;
885  for (j = 0; j < (int) nbconstrs; j++) {
886  jx[j] = i;
887  bx[j] = b;
888  NEXT(i, b);
889  }
890  aux = 0;
891  for (i = 0; i < (int) nbrays; i++) {
892  zval_set_i(rays->vals[i][0], 0);
893  if (!zval_equal_i(rays->vals[i][nbdims], 0)) {
894  aux++;
895  }
896  }
897  if (!aux) {
898  goto empty;
899  }
900  nbeqs = 0;
901  for (j = 0; j < (int) nbconstrs; j++) {
902  zval_set_i(constrs->vals[j][0], 0);
903  i = zvec_index_first_notzero(constrs->vals[j] + 1, nbdims - 1);
904  if (i == -1) {
905  for (i = 0; i < (int) nbrays; i++) {
906  if (!(sat->vals[i][jx[j]] & bx[j])) {
907  zval_add(constrs->vals[j][0], constrs->vals[j][0], one);
908  }
909  }
910  if (zval_cmp_i(constrs->vals[j][0], nbrays) == 0 &&
911  !zval_equal_i(constrs->vals[j][nbdims], 0)) {
912  goto empty;
913  }
914  nbconstrs--;
915  if (j == (int) nbconstrs) {
916  continue;
917  }
918  zvec_swap(constrs->vals[j], constrs->vals[nbconstrs], nbdims + 1);
919  SWAP(jx[j], jx[nbconstrs], aux);
920  SWAP(bx[j], bx[nbconstrs], aux);
921  j--;
922  continue;
923  }
924  for (i = 0; i < (int) nbrays; i++) {
925  if (!(sat->vals[i][jx[j]] & bx[j])) {
926  zval_add(constrs->vals[j][0], constrs->vals[j][0], one);
927  zval_add(rays->vals[i][0], rays->vals[i][0], one);
928  }
929  }
930  if (zval_cmp_i(constrs->vals[j][0], nbrays) == 0) {
931  nbeqs++;
932  }
933  }
934  constrs->nbrows = nbconstrs;
935  nbbrays = 0;
936  for (i = 0; i < (int) nbrays; i++) {
937  if (zval_equal_i(rays->vals[i][nbdims], 0)) {
938  zval_add(rays->vals[i][0], rays->vals[i][0], one);
939  }
940  if (zval_cmp_i(rays->vals[i][0], nbconstrs + 1) == 0) {
941  nbbrays++;
942  }
943  }
944  for (i = 0; i < (int) nbeqs; i++) {
945  if (zval_cmp_i(constrs->vals[i][0], nbrays) != 0) {
946  for (k = i + 1; zval_cmp_i(constrs->vals[k][0], nbrays) != 0 &&
947  k < (int) nbconstrs; k++);
948  if (k == (int) nbconstrs) {
949  break;
950  }
951  zvec_copy(constrs->vals[k], tmp, nbdims + 1);
952  aux = jx[k];
953  j = bx[k];
954  for (; k > i; k--) {
955  zvec_copy(constrs->vals[k - 1], constrs->vals[k], nbdims + 1);
956  jx[k] = jx[k - 1];
957  bx[k] = bx[k - 1];
958  }
959  zvec_copy(tmp, constrs->vals[i], nbdims + 1);
960  jx[i] = aux;
961  bx[i] = j;
962  }
963  }
964  nbeqs2 = gauss(constrs, nbeqs, nbdims);
965  if (nbeqs2 >= nbdims) {
966  goto empty;
967  }
968  for (i = 0, k = nbrays; i < (int) nbbrays && k > i; i++) {
969  if (zval_cmp_i(rays->vals[i][0], nbconstrs + 1) != 0) {
970  while (--k > i && zval_cmp_i(rays->vals[k][0], nbconstrs + 1) != 0);
971  zvec_swap(rays->vals[i], rays->vals[k], nbdims + 1);
972  BSWAP(sat->vals[i], sat->vals[k], nbcols2);
973  }
974  }
975  nbbrays2 = gauss(rays, nbbrays, nbdims);
976  if (nbbrays2 >= nbdims) {
977  goto empty;
978  }
979  dimrayspace = nbdims - 1 - nbeqs2 - nbbrays2;
980  nbineqs = 0;
981  for (j = 0; j < (int) nbconstrs; j++) {
982  i = zvec_index_first_notzero(constrs->vals[j] + 1, nbdims - 1);
983  if (i == -1) {
984  if (zval_cmp_i(constrs->vals[j][0], nbrays) == 0 &&
985  !zval_equal_i(constrs->vals[j][nbdims], 0)) {
986  goto empty;
987  }
988  zval_set_i(constrs->vals[j][0], 2);
989  continue;
990  }
991  status = zval_get_i(constrs->vals[j][0]);
992  if (status == 0) {
993  zval_set_i(constrs->vals[j][0], 2);
994  }
995  else if (status < dimrayspace) {
996  zval_set_i(constrs->vals[j][0], 2);
997  }
998  else if (status == nbrays) {
999  zval_set_i(constrs->vals[j][0], 0);
1000  }
1001  else {
1002  nbineqs++;
1003  zval_set_i(constrs->vals[j][0], 1);
1004  }
1005  }
1006  nburays = 0;
1007  for (j = 0; j < (int) nbrays; j++) {
1008  status = zval_get_i(rays->vals[j][0]);
1009  if (status < dimrayspace) {
1010  zval_set_i(rays->vals[j][0], 2);
1011  }
1012  else if (status == nbconstrs + 1) {
1013  zval_set_i(rays->vals[j][0], 0);
1014  }
1015  else {
1016  nburays++;
1017  zval_set_i(rays->vals[j][0], 1);
1018  }
1019  }
1020  constrs2 = zmat_alloc(nbineqs + nbeqs2 + 1, nbdims + 1);
1021  rays2 = zmat_alloc(nburays + nbbrays2, nbdims + 1);
1022  if (nbbrays2) {
1023  zvec_copy(rays->vals[0], rays2->vals[0], (nbdims + 1) * nbbrays2);
1024  }
1025  if (nbeqs2) {
1026  zvec_copy(constrs->vals[0], constrs2->vals[0], (nbdims + 1) * nbeqs2);
1027  }
1028  trace = safe_malloc(sat_nbcols * sizeof(unsigned));
1029  nbineqs2 = 0;
1030  for (j = nbeqs; j < (int) nbconstrs; j++) {
1031  if (zval_equal_i(constrs->vals[j][0], 1)) {
1032  for (k = 0; k < (int) sat_nbcols; k++) {
1033  trace[k] = 0;
1034  }
1035  for (i = nbbrays; i < (int) nbrays; i++) {
1036  if (zval_equal_i(rays->vals[i][0], 1)) {
1037  if (!(sat->vals[i][jx[j]] & bx[j])) {
1038  for (k = 0; k < (int) sat_nbcols; k++) {
1039  trace[k] |= sat->vals[i][k];
1040  }
1041  }
1042  }
1043  }
1044  redundant = false;
1045  for (i = nbeqs; i < (int) nbconstrs; i++) {
1046  if (zval_equal_i(constrs->vals[i][0], 1) && (i != j) &&
1047  !(trace[jx[i]] & bx[i])) {
1048  redundant = true;
1049  break;
1050  }
1051  }
1052  if (redundant) {
1053  zval_set_i(constrs->vals[j][0], 2);
1054  }
1055  else {
1056  zvec_copy(constrs->vals[j], constrs2->vals[nbeqs2 + nbineqs2],
1057  nbdims + 1);
1058  nbineqs2++;
1059  }
1060  }
1061  }
1062  free(trace);
1063  trace = safe_malloc(nbrays * sizeof(unsigned));
1064  nburays2 = 0;
1065  aux = 0;
1066  for (i = nbbrays; i < (int) nbrays; i++) {
1067  if (zval_equal_i(rays->vals[i][0], 1)) {
1068  if (!zval_equal_i(rays->vals[i][nbdims], 0)) {
1069  for (k = nbbrays; k < (int) nbrays; k++) {
1070  trace[k] = 0;
1071  }
1072  }
1073  else {
1074  for (k = nbbrays; k < (int) nbrays; k++) {
1075  trace[k] = !zval_equal_i(rays->vals[k][nbdims], 0);
1076  }
1077  }
1078  for (j = nbeqs; j < (int) nbconstrs; j++) {
1079  if (zval_equal_i(constrs->vals[j][0], 1)) {
1080  if (!(sat->vals[i][jx[j]] & bx[j])) {
1081  for (k = nbbrays; k < (int) nbrays; k++) {
1082  trace[k] |= sat->vals[k][jx[j]] & bx[j];
1083  }
1084  }
1085  }
1086  }
1087  redundant = false;
1088  for (j = nbbrays; j < (int) nbrays; j++) {
1089  if (zval_equal_i(rays->vals[j][0], 1) && (i != j) && !trace[j]) {
1090  redundant = true;
1091  break;
1092  }
1093  }
1094  if (redundant) {
1095  zval_set_i(rays->vals[i][0], 2);
1096  }
1097  else {
1098  zvec_copy(rays->vals[i], rays2->vals[nbbrays2 + nburays2],
1099  nbdims + 1);
1100  nburays2++;
1101  if (zval_equal_i(rays->vals[i][nbdims], 0)) {
1102  aux++;
1103  }
1104  }
1105  }
1106  }
1107  if (aux >= (int) dimrayspace) {
1108  zvec_set_i(constrs2->vals[nbeqs2 + nbineqs2], 0, nbdims + 1);
1109  zval_set_i(constrs2->vals[nbeqs2 + nbineqs2][0], 1);
1110  zval_set_i(constrs2->vals[nbeqs2 + nbineqs2][nbdims], 1);
1111  nbineqs2++;
1112  }
1113  }
1115  free(trace);
1116  free(bx);
1117  free(jx);
1118  constrs2->nbrows = nbeqs2 +nbineqs2;
1119  rays2->nbrows = nbbrays2 + nburays2;
1120  zvec_free(tmp, nbdims + 1);
1121  zval_clear(one); //zval_clear(mone);
1122  zmat_free(constrs);
1123  zmat_free(rays);
1124  *pconstrs = constrs2;
1125  *prays = rays2;
1126  return;
1127 empty:
1128  zvec_free(tmp, nbdims + 1);
1129  zval_clear(one); //zval_clear(mone);
1130  safe_free(bx);
1131  safe_free (jx);
1133  constrs2 = zmat_alloc(nbdims, nbdims + 1);
1134  rays2 = zmat_alloc(0, nbdims + 1);
1135  for (i = 0; i < (int) nbdims; i++) {
1136  zval_set_i(constrs2->vals[i][i + 1], 1);
1137  }
1138  zmat_free(constrs);
1139  zmat_free(rays);
1140  *pconstrs = constrs2;
1141  *prays = rays2;
1142  return;
1143 }
1144 
1145 static bmat_p transpose_sat(zmat_p constrs, zmat_p rays, bmat_p sat) {
1146  int sat_nbcols;
1147  if (constrs->nbrows != 0) {
1148  sat_nbcols = (constrs->nbrows - 1) / WSIZE + 1;
1149  }
1150  else {
1151  sat_nbcols = 0;
1152  }
1153  bmat_p tsat = bmat_alloc(rays->nbrows, sat_nbcols);
1154  bvec_init(tsat->rawvals, rays->nbrows * sat_nbcols);
1155  unsigned i, j;
1156  unsigned jx1, jx2, bx1, bx2;
1157  for (i = 0, jx1 = 0, bx1 = MSB; i < rays->nbrows; i++) {
1158  for (j = 0, jx2 = 0, bx2 = MSB; j < constrs->nbrows; j++) {
1159  if (sat->vals[j][jx1] & bx1) {
1160  tsat->vals[i][jx2] |= bx2;
1161  }
1162  NEXT(jx2, bx2);
1163  }
1164  NEXT(jx1, bx1);
1165  }
1166  return tsat;
1167 }
1168 
1169 // convert from constrs to rays
1170 static zmat_p rays_of_constrs(zmat_p* pconstrs, unsigned nbmaxrays) {
1171  zmat_p constrs = *pconstrs;
1172  unsigned nbdims = constrs->nbcols - 1;
1173  nbmaxrays = nbmaxrays < nbdims ? nbdims : nbmaxrays;
1174  zmat_p rays = zmat_alloc(nbmaxrays, nbdims + 1);
1175  unsigned i;
1176  for (i = 0; i < nbmaxrays * (nbdims + 1); i++) {
1177  zval_set_i(rays->rawvals[i], 0);
1178  }
1179  for (i = 0; i < nbdims; i++) {
1180  zval_set_i(rays->vals[i][i + 1], 1);
1181  }
1182  zval_set_i(rays->vals[nbdims - 1][0], 1);
1183  rays->nbrows = nbdims;
1184  int nbcols = (constrs->nbrows - 1) / WSIZE + 1;
1185  bmat_p sat = bmat_alloc(nbmaxrays, nbcols);
1186  bvec_init(sat->rawvals, nbdims * nbcols);
1187  sat->nbrows = nbdims;
1188  chernikova(constrs, rays, sat, nbdims - 1, nbmaxrays, false);
1189  remove_redundants(pconstrs, &rays, sat);
1190  bmat_free(sat);
1191  return rays;
1192 }
1193 
1194 // convert from rays to constrs
1195 static zmat_p constrs_of_rays(zmat_p* prays, unsigned nbmaxconstrs) {
1196  zmat_p rays = *prays;
1197  unsigned nbdims = rays->nbcols - 1;
1198  nbmaxconstrs = nbmaxconstrs < nbdims ? nbdims : nbmaxconstrs;
1199  zmat_p constrs = zmat_alloc(nbmaxconstrs, nbdims + 1);
1200  unsigned i;
1201  for (i = 0; i < nbmaxconstrs * (nbdims + 1); i++) {
1202  zval_set_i(constrs->rawvals[i], 0);
1203  }
1204  for (i = 0; i < nbdims; i++) {
1205  zval_set_i(constrs->vals[i][i + 1], 1);
1206  }
1207  constrs->nbrows = nbdims;
1208  int nbcols = (rays->nbrows - 1) / WSIZE + 1;
1209  bmat_p tsat = bmat_alloc(nbmaxconstrs, nbcols);
1210  bvec_init(tsat->rawvals, nbdims * nbcols);
1211  tsat->nbrows = nbdims;
1212  chernikova(rays, constrs, tsat, nbdims, nbmaxconstrs, true);
1213  bmat_p sat = transpose_sat(constrs, rays, tsat);
1214  bmat_free(tsat);
1215  remove_redundants(&constrs, prays, sat);
1216  bmat_free(sat);
1217  return constrs;
1218 }
1219 
1220 // Data conversion
1221 // ---------------
1222 
1223 static void zmat_set_row(zmat_p zmat, unsigned i,
1224  int first, Pvecteur pv, int last, Pbase base) {
1225  Pvecteur coord = base;
1226  zval_set_i(zmat->vals[i][0], first);
1227  int j = 1;
1228  for (; coord != NULL; coord = coord->succ, j++) {
1229  zval_set_i(zmat->vals[i][j], vect_coeff(vecteur_var(coord), pv));
1230  }
1231  zval_set_i(zmat->vals[i][j], last);
1232 }
1233 
1235  int i;
1236  Pvecteur pv = NULL, coord;
1237  for (i = 0, coord = base; coord != NULL; i++, coord = coord->succ) {
1238  if (!zval_equal_i(zvec[i], 0)) {
1239  if (pv == NULL) {
1240  pv = vect_new(vecteur_var(coord), zval_get_i(zvec[i]));
1241  }
1242  else {
1243  vect_add_elem(&pv, vecteur_var(coord), zval_get_i(zvec[i]));
1244  }
1245  }
1246  }
1247  return pv;
1248 }
1249 
1250 // build a constraint matrix from a constraint system
1252  unsigned nbrows = sc->nb_eq + sc->nb_ineq + 1; // extra constraint
1253  unsigned nbcols = sc->dimension + 2; // constraint type + extra var
1254  zmat_p constrs = zmat_alloc(nbrows, nbcols);
1255  unsigned i, j;
1256  i = 0;
1257  for (; (int) i < sc->nb_eq; i++) {
1258  zval_set_i(constrs->vals[i][0], 0);
1259  }
1260  for (; i < nbrows; i++) {
1261  zval_set_i(constrs->vals[i][0], 1);
1262  }
1263  i = 0;
1264  Pcontrainte pc;
1265  Pvecteur coord;
1266  for (pc = sc->egalites; pc != NULL; pc = pc->succ, i++) {
1267  for (j = 1, coord = sc->base; coord != NULL; coord = coord->succ, j++) {
1268  zval_set_i(constrs->vals[i][j], -vect_coeff(vecteur_var(coord), pc->vecteur));
1269  }
1270  zval_set_i(constrs->vals[i][j], -vect_coeff(TCST, pc->vecteur));
1271  }
1272  for (pc = sc->inegalites; pc != NULL; pc = pc->succ, i++) {
1273  for (j = 1, coord = sc->base; coord != NULL; coord = coord->succ, j++) {
1274  zval_set_i(constrs->vals[i][j], -vect_coeff(vecteur_var(coord), pc->vecteur));
1275  }
1276  zval_set_i(constrs->vals[i][j], -vect_coeff(TCST, pc->vecteur));
1277  }
1278  for (j = 1; j < nbcols - 1; j++) {
1279  zval_set_i(constrs->vals[nbrows - 1][j], 0);
1280  }
1281  zval_set_i(constrs->vals[nbrows - 1][nbcols - 1], 1);
1282  return constrs;
1283 }
1284 
1285 // build a constraint system from a constraint matrix
1287  Psysteme sc = sc_new();
1288  sc->base = base_copy(base);
1289  sc->dimension = base_dimension(base);
1290  sc->nb_eq = 0;
1291  sc->egalites = NULL;
1292  sc->nb_ineq = 0;
1293  sc->inegalites = NULL;
1294  Pcontrainte pce = NULL, pci = NULL;
1295  unsigned i;
1296  for (i = 0; i < constrs->nbrows; i++) {
1297  Pvecteur pv = vecteur_of_zvec(constrs->vals[i] + 1, base);
1298  Value cst = zval_get_i(constrs->vals[i][constrs->nbcols - 1]);
1299  vect_add_elem(&pv, TCST, cst);
1300  vect_chg_sgn(pv);
1301  if (zval_equal_i(constrs->vals[i][0], 0)) {
1302  sc->nb_eq++;
1303  if (!pce) {
1304  sc->egalites = pce = contrainte_make(pv);
1305  }
1306  else {
1307  pce->succ = contrainte_make(pv);
1308  pce = pce->succ;
1309  }
1310  }
1311  else if (zval_equal_i(constrs->vals[i][0], 1)) {
1312  sc->nb_ineq++;
1313  if (!pci) {
1314  sc->inegalites = pci = contrainte_make(pv);
1315  }
1316  else {
1317  pci->succ = contrainte_make(pv);
1318  pci = pci->succ;
1319  }
1320  }
1321  else {
1322  assert(false);
1323  }
1324  }
1325  sc_normalize(sc);
1326  return sc;
1327 }
1328 
1329 // build a ray matrix from a generator system
1331  unsigned nbrows = sg_nbre_sommets(sg) + sg_nbre_rayons(sg) +
1333  unsigned nbcols = base_dimension(sg->base) + 2;
1334  zmat_p rays = zmat_alloc(nbrows, nbcols);
1335  Psommet ps; Pray_dte pr;
1336  int i = 0;
1337  for (pr = sg->dtes_sg.vsg; pr != NULL; pr = pr->succ, i++) {
1338  zmat_set_row(rays, i, 0, pr->vecteur, 0, sg->base);
1339  }
1340  for (pr = sg->rays_sg.vsg; pr != NULL; pr = pr->succ, i++) {
1341  zmat_set_row(rays, i, 1, pr->vecteur, 0, sg->base);
1342  }
1343  for (ps = sg->soms_sg.ssg; ps != NULL; ps = ps->succ, i++) {
1344  zmat_set_row(rays, i, 1, ps->vecteur, ps->denominateur, sg->base);
1345  }
1346  return rays;
1347 }
1348 
1349 // build a generator system from a ray matrix
1351  Ptsg sg = sg_new();
1352  sg->base = base_copy(base);
1353  sg->soms_sg.nb_s = 0;
1354  sg->soms_sg.ssg = NULL;
1355  sg->rays_sg.nb_v = 0;
1356  sg->rays_sg.vsg = NULL;
1357  sg->dtes_sg.nb_v = 0;
1358  sg->dtes_sg.vsg = NULL;
1359  Psommet verts = NULL; Pray_dte urays = NULL, brays = NULL;
1360  Pvecteur pv;
1361  unsigned i;
1362  for (i = 0; i < rays->nbrows; i++) {
1363  pv = vecteur_of_zvec(rays->vals[i] + 1, base);
1364  if (zval_equal_i(rays->vals[i][0], 0)) {
1365  sg->dtes_sg.nb_v++;
1366  if (!brays) {
1367  sg->dtes_sg.vsg = brays = ray_dte_make(pv);
1368  }
1369  else {
1370  brays->succ = ray_dte_make(pv);
1371  brays = brays->succ;
1372  }
1373  }
1374  else if (zval_equal_i(rays->vals[i][0], 1)) {
1375  if (zval_equal_i(rays->vals[i][rays->nbcols - 1], 0)) {
1376  sg->rays_sg.nb_v++;
1377  if (!urays) {
1378  sg->rays_sg.vsg = urays = ray_dte_make(pv);
1379  }
1380  else {
1381  urays->succ = ray_dte_make(pv);
1382  urays = urays->succ;
1383  }
1384  }
1385  else {
1386  sg->soms_sg.nb_s++;
1387  long ratio = zval_get_i(rays->vals[i][rays->nbcols - 1]);
1388  if (!verts) {
1389  sg->soms_sg.ssg = verts = sommet_make(ratio, pv);
1390  }
1391  else {
1392  verts->succ = sommet_make(ratio, pv);
1393  verts = verts->succ;
1394  }
1395  }
1396  }
1397  else {
1398  assert(false);
1399  }
1400  }
1401  return sg;
1402 }
1403 
1404 static zmat_p NOWUNUSED rays_of_sc(Psysteme sc, unsigned nbmaxrays) {
1405  zmat_p constrs = constrs_of_sc(sc);
1406  zmat_p rays = rays_of_constrs(&constrs, nbmaxrays);
1407  zmat_free(constrs);
1408  return rays;
1409 }
1410 
1411 static Psysteme NOWUNUSED sc_of_rays(zmat_p* prays, Pbase base, unsigned nbmaxconstrs) {
1412  zmat_p constrs = constrs_of_rays(prays, nbmaxconstrs);
1413  Psysteme sc = sc_of_constrs(constrs, base);
1414  zmat_free(constrs);
1415  return sc;
1416 }
1417 
1418 static zmat_p NOWUNUSED constrs_of_sg(Ptsg sg, unsigned nbmaxconstrs) {
1419  zmat_p rays = rays_of_sg(sg);
1420  zmat_p constrs = constrs_of_rays(&rays, nbmaxconstrs);
1421  zmat_free(rays);
1422  return constrs;
1423 }
1424 
1425 static Ptsg NOWUNUSED sg_of_constrs(zmat_p* pconstrs, Pbase base, unsigned nbmaxrays) {
1426  zmat_p rays = rays_of_constrs(pconstrs, nbmaxrays);
1427  Ptsg sg = sg_of_rays(rays, base);
1428  zmat_free(rays);
1429  return sg;
1430 }
1431 
1432 // Main functions
1433 // --------------
1434 
1435 #define NBMAXRAYS (20000)
1436 #define NBMAXCONSTRS (20000)
1437 
1438 static inline Ptsg sg_of_sc(Psysteme sc) {
1439  zmat_p rays = NULL;
1440  Ptsg sg = NULL;
1442  zmat_safe_free(rays);
1443  if (sg != NULL) {
1444  sg_rm(sg);
1445  }
1446  RETHROW();
1447  }
1448  TRY {
1449  rays = rays_of_sc(sc, NBMAXRAYS);
1450  sg = sg_of_rays(rays, sc->base);
1451  zmat_free(rays);
1452  }
1454  return sg;
1455 }
1456 
1457 static inline Psysteme sc_of_sg(Ptsg sg) {
1458  zmat_p constrs = NULL;
1459  Psysteme sc = NULL;
1461  zmat_safe_free(constrs);
1462  if (sc != NULL) {
1463  sc_rm(sc);
1464  }
1465  RETHROW();
1466  }
1467  TRY {
1468  constrs = constrs_of_sg(sg, NBMAXCONSTRS);
1469  sc = sc_of_constrs(constrs, sg->base);
1470  zmat_free(constrs);
1471  }
1473  return sc;
1474 }
1475 
1476 static inline Psysteme sc_union(Psysteme sc1, Psysteme sc2) {
1477  assert(bases_strictly_equal_p(sc1->base, sc2->base));
1478  zmat_p rays1 = NULL, rays2 = NULL, rays = NULL;
1479  Psysteme sc = NULL;
1481  zmat_safe_free(rays1);
1482  zmat_safe_free(rays2);
1483  zmat_safe_free(rays);
1484  if (sc != NULL) {
1485  sc_rm(sc);
1486  }
1487  // clear the alarm if necessary
1489  alarm(0);
1490  }
1491  if (sc_convex_hull_timeout) {
1492  sc_convex_hull_timeout = false;
1493  }
1494  RETHROW();
1495  }
1496  TRY {
1497  // start the alarm
1499  signal(SIGALRM, catch_alarm_sc_convex_hull);
1501  }
1502  rays1 = rays_of_sc(sc1, NBMAXRAYS);
1503  rays2 = rays_of_sc(sc2, NBMAXRAYS);
1504  unsigned nbrows1 = rays1->nbrows;
1505  unsigned nbrows2 = rays2->nbrows;
1506  unsigned nbrows = nbrows1 + nbrows2;
1507  unsigned nbcols = rays1->nbcols;
1508  rays = zmat_alloc(nbrows, nbcols);
1509  // merge rays1 and rays2, preserving ray order
1510  unsigned i = 0, i1 = 0, i2 = 0, j;
1511  while (i1 < nbrows1 && zval_equal_i(rays1->vals[i1][0], 0) &&
1512  zval_equal_i(rays1->vals[i1][nbcols - 1], 0)) {
1513  for (j = 0; j < nbcols; j++) {
1514  zval_set(rays->vals[i][j], rays1->vals[i1][j]);
1515  }
1516  i++, i1++;
1517  }
1518  while (i2 < nbrows2 && zval_equal_i(rays2->vals[i2][0], 0) &&
1519  zval_equal_i(rays2->vals[i2][nbcols - 1], 0)) {
1520  for (j = 0; j < nbcols; j++) {
1521  zval_set(rays->vals[i][j], rays2->vals[i2][j]);
1522  }
1523  i++, i2++;
1524  }
1525  while (i1 < nbrows1 && zval_equal_i(rays1->vals[i1][0], 1) &&
1526  zval_equal_i(rays1->vals[i1][nbcols - 1], 0)) {
1527  for (j = 0; j < nbcols; j++) {
1528  zval_set(rays->vals[i][j], rays1->vals[i1][j]);
1529  }
1530  i++, i1++;
1531  }
1532  while (i2 < nbrows2 && zval_equal_i(rays2->vals[i2][0], 1) &&
1533  zval_equal_i(rays2->vals[i2][nbcols - 1], 0)) {
1534  for (j = 0; j < nbcols; j++) {
1535  zval_set(rays->vals[i][j], rays2->vals[i2][j]);
1536  }
1537  i++, i2++;
1538  }
1539  while (i1 < nbrows1 && zval_equal_i(rays1->vals[i1][0], 1) &&
1540  !zval_equal_i(rays1->vals[i1][nbcols - 1], 0)) {
1541  for (j = 0; j < nbcols; j++) {
1542  zval_set(rays->vals[i][j], rays1->vals[i1][j]);
1543  }
1544  i++, i1++;
1545  }
1546  while (i2 < nbrows2 && zval_equal_i(rays2->vals[i2][0], 1) &&
1547  !zval_equal_i(rays2->vals[i2][nbcols - 1], 0)) {
1548  for (j = 0; j < nbcols; j++) {
1549  zval_set(rays->vals[i][j], rays2->vals[i2][j]);
1550  }
1551  i++, i2++;
1552  }
1553  assert(i == nbrows);
1554  zmat_free(rays1); rays1 = NULL;
1555  zmat_free(rays2); rays2 = NULL;
1556  sc = sc_of_rays(&rays, sc1->base, NBMAXCONSTRS);
1557  zmat_free(rays);
1558  }
1559  // Clear the alarm if necessary
1561  alarm(0);
1562  }
1564  return sc;
1565 }
1566 
1567 #endif // LINEAR_CHERNIKOVA_H
1568 
#define zval_mul(z1, z2, z3)
Set z1 to z2 times z3.
#define zval_abs(z1, z2)
Set z1 to the absolute value of z2.
#define NOWUNUSED
Definition: arith_fixprec.h:48
#define zval_mod(z1, z2, z3)
Set z1 to z2 mod z3.
#define zval_clear(z)
Free the space occupied by z.
Definition: arith_fixprec.h:71
#define zval_div(z1, z2, z3)
Set z1 to z2/z3.
#define zval_cmp(z1, z2)
Compare z1 and z2.
#define zval_set_i(z, n)
Set the value of z from the signed long n.
Definition: arith_fixprec.h:81
#define zval_fprint(stream, z)
Output z on stdio stream stream.
long int zval_t
Type of integer numbers.
Definition: arith_fixprec.h:61
#define zval_set(z1, z2)
Set the value of z1 from z2.
Definition: arith_fixprec.h:76
#define zval_add(z1, z2, z3)
Set z1 to z2 + z3.
#define zval_equal_i(z, n)
Return non-zero if z and the unsigned long n are equal, zero if they are non-equal.
#define zval_gcd(z1, z2, z3)
Set z1 to the greatest common divisor of z2 and z3.
#define zval_init(z)
Initialize z and set its value to 0.
Definition: arith_fixprec.h:66
#define zval_cmp_i(z, n)
Compare z with a signed long n.
#define zval_addmul(z1, z2, z3)
Set z1 to z1 + z2 times z3.
#define zval_neg(z1, z2)
Set z1 to -z2.
#define zval_get_i(z)
Return the value of z as a signed long.
Definition: arith_fixprec.h:96
#define CATCH(what)
@ timeout_error
@ any_exception_error
catch all
#define THROW(what)
#define UNCATCH(what)
#define RETHROW()
#define TRY
#define pgcd(a, b)
Pour la recherche de performance, selection d'une implementation particuliere des fonctions.
void const char const char const int
int Value
bool bases_strictly_equal_p(Pbase b1, Pbase b2)
Make sure that each dimension of b1 is the same dimension in b2.
Definition: base.c:660
bdt base
Current expression.
Definition: bdt_read_paf.c:100
static int chernikova(zmat_p constrs, zmat_p rays, bmat_p sat, volatile unsigned nbbrays, volatile unsigned nbmaxrays, bool dual)
Definition: chernikova.h:618
static Psysteme NOWUNUSED sc_of_rays(zmat_p *prays, Pbase base, unsigned nbmaxconstrs)
Definition: chernikova.h:1411
static void NOWUNUSED zmat_safe_free(zmat_p zmat)
Definition: chernikova.h:364
#define MSB
Definition: chernikova.h:414
static Ptsg sg_of_rays(zmat_p rays, Pbase base)
Definition: chernikova.h:1350
static void zvec_copy(zval_t *zvec1, zval_t *zvec2, unsigned nbvals)
Definition: chernikova.h:175
static void zmat_free(zmat_p zmat)
Definition: chernikova.h:354
static int zvec_index_first_notzero(zval_t *zvec, unsigned nbvals)
Definition: chernikova.h:215
static void sort_rays(zmat_p rays, bmat_p sat, int nbbrays, int nbrays, int *equal_bound, int *sup_bound, unsigned nbcols1, unsigned nbcols2, unsigned bx, unsigned jx)
Definition: chernikova.h:573
static void NOWUNUSED safe_free(void *ptr)
Definition: chernikova.h:74
static int gauss(zmat_p zmat, int nbeqs, int nbdims)
Definition: chernikova.h:789
#define TIMEOUT_ENV
Definition: chernikova.h:102
static void NOWUNUSED bmat_safe_free(bmat_p bmat)
Definition: chernikova.h:487
static int get_linear_convex_hull_timeout()
Definition: chernikova.h:106
static zmat_p NOWUNUSED constrs_of_sg(Ptsg sg, unsigned nbmaxconstrs)
Definition: chernikova.h:1418
static void NOWUNUSED bmat_fprint(FILE *stream, bmat_p bmat)
Definition: chernikova.h:504
static Ptsg NOWUNUSED sg_of_constrs(zmat_p *pconstrs, Pbase base, unsigned nbmaxrays)
Definition: chernikova.h:1425
static void zvec_swap(zval_t *zvec1, zval_t *zvec2, unsigned nbvals)
Definition: chernikova.h:156
static Psysteme sc_union(Psysteme sc1, Psysteme sc2)
Definition: chernikova.h:1476
static void bmat_extend(bmat_p bmat, zmat_p zmat, unsigned nbrows)
Definition: chernikova.h:493
static void remove_redundants(zmat_p *pconstrs, zmat_p *prays, bmat_p sat)
Definition: chernikova.h:850
static zmat_p rays_of_sg(Ptsg sg)
Definition: chernikova.h:1330
static bmat_p transpose_sat(zmat_p constrs, zmat_p rays, bmat_p sat)
Definition: chernikova.h:1145
#define STRINGOF(str)
Definition: chernikova.h:51
static Psysteme sc_of_constrs(zmat_p constrs, Pbase base)
Definition: chernikova.h:1286
static zval_t * zvec_alloc(unsigned nbvals)
Definition: chernikova.h:133
#define NBMAXRAYS
Definition: chernikova.h:1435
#define bvec_init(bvec, nbvals)
Definition: chernikova.h:444
static zmat_p zmat_alloc(unsigned nbrows, unsigned nbcols)
Definition: chernikova.h:330
static Psysteme sc_of_sg(Ptsg sg)
Definition: chernikova.h:1457
static bool sc_convex_hull_timeout
Definition: chernikova.h:104
#define WSIZE
Definition: chernikova.h:412
static zmat_p constrs_of_rays(zmat_p *prays, unsigned nbmaxconstrs)
Definition: chernikova.h:1195
static void zvec_antiscale(zval_t *zvec1, zval_t *zvec2, zval_t lambda, unsigned nbvals)
Definition: chernikova.h:200
#define BSWAP(a, b, l)
Definition: chernikova.h:80
static void zmat_set_row(zmat_p zmat, unsigned i, int first, Pvecteur pv, int last, Pbase base)
Definition: chernikova.h:1223
static zmat_p NOWUNUSED rays_of_sc(Psysteme sc, unsigned nbmaxrays)
Definition: chernikova.h:1404
static void zvec_normalize(zval_t *zvec, unsigned nbvals)
Definition: chernikova.h:293
static void zvec_neg(zval_t *zvec1, zval_t *zvec2, unsigned nbvals)
Definition: chernikova.h:208
static void bvec_lor(int *bvec1, int *bvec2, int *bvec3, unsigned nbvals)
Definition: chernikova.h:427
#define FPRINT_NBDIGITS
Definition: chernikova.h:48
static void NOWUNUSED zvec_safe_free(zval_t *zvec, unsigned nbvals)
Definition: chernikova.h:150
static int NOWUNUSED zvec_fprint(FILE *stream, zval_t *zvec, unsigned nbvals)
Definition: chernikova.h:303
static void zvec_free(zval_t *zvec, unsigned nbvals)
Definition: chernikova.h:142
static Ptsg sg_of_sc(Psysteme sc)
Definition: chernikova.h:1438
static void bmat_free(bmat_p bmat)
Definition: chernikova.h:479
static zmat_p rays_of_constrs(zmat_p *pconstrs, unsigned nbmaxrays)
Definition: chernikova.h:1170
static void zvec_gcd(zval_t *zvec, unsigned nbvals, zval_t *pgcd)
Definition: chernikova.h:255
static void *NOWUNUSED safe_realloc(void *ptr, size_t size)
Definition: chernikova.h:65
static zmat_p constrs_of_sc(Psysteme sc)
Definition: chernikova.h:1251
bmat_s bmat_t[1]
Definition: chernikova.h:457
struct zmat_s * zmat_p
#define NBMAXCONSTRS
Definition: chernikova.h:1436
zmat_s zmat_t[1]
Definition: chernikova.h:328
static void zvec_combine(zval_t *zvec1, zval_t *zvec2, zval_t *zvec3, zval_t lambda, zval_t mu, unsigned nbvals)
Definition: chernikova.h:186
static void zvec_set_i(zval_t *zvec, long val, unsigned nbvals)
Definition: chernikova.h:168
static Pvecteur vecteur_of_zvec(zval_t *zvec, Pbase base)
Definition: chernikova.h:1234
#define NEXT(j,b)
Definition: chernikova.h:416
#define SWAP(a, b, t)
Definition: chernikova.h:88
static void zvec_min_notzero(zval_t *zvec, unsigned nbvals, int *pindex, zval_t *pmin)
Definition: chernikova.h:230
static void catch_alarm_sc_convex_hull(int sig NOWUNUSED)
Definition: chernikova.h:123
static void *NOWUNUSED safe_malloc(size_t size)
Definition: chernikova.h:56
#define bvec_copy(bvec1, bvec2, nbvals)
Definition: chernikova.h:441
static void combine(zval_t *zvec1, zval_t *zvec2, zval_t *zvec3, int pos, unsigned nbvals)
Definition: chernikova.h:553
static bmat_p bmat_alloc(int nbrows, int nbcols)
Definition: chernikova.h:459
static void zmat_extend(zmat_p zmat, unsigned nbrows)
Definition: chernikova.h:371
static void NOWUNUSED zmat_fprint(FILE *stream, zmat_p zmat)
Definition: chernikova.h:393
struct bmat_s * bmat_p
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
struct _newgen_struct_status_ * status
Definition: database.h:31
static jmp_buf env
Definition: genClib.c:2473
void * malloc(YYSIZE_T)
void free(void *)
Ptsg sg
static int redundant(Pproblem XX, int i1, int i2)
Definition: isolve.c:720
#define abort()
Definition: misc-local.h:53
static entity rank
#define assert(ex)
Definition: newgen_assert.h:41
Psysteme dual(Psysteme sys, Psommet fonct)
Psysteme dual(Psysteme ps, Psommet fonct): Algorithme dual du simplexe avec initialisation des parame...
Definition: pldual.c:351
Pray_dte ray_dte_make(Pvecteur v)
Pray_dte ray_dte_make(Pvecteur v): allocation et initialisation d'une structure ray_dte;.
Definition: ray_dte.c:108
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
void pivot(frac *X, frac A, frac B, frac C, frac D, bool ofl_ctrl)
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
#define sg_nbre_sommets(sg)
nombre de sommets: int sg_nbre_sommets(Ptsg)
Definition: sg-local.h:96
#define sg_nbre_droites(sg)
nombre de droites: int sg_nbre_droites(Ptsg)
Definition: sg-local.h:102
#define sg_nbre_rayons(sg)
nombre de rayons: int sg_nbre_rayons(Ptsg)
Definition: sg-local.h:99
Ptsg sg_new()
Ptsg sg_new(): allocation d'un systeme generateur et initialisation a la valeur ensemble vide.
Definition: sg.c:55
void sg_rm(Ptsg sg)
void sg_rm(Ptsg sg): liberation de l'espace memoire occupe par un systeme generateur
Definition: sg.c:249
int aux
Definition: solpip.c:104
Psommet sommet_make(Value d, Pvecteur v)
Psommet sommet_make(int d, Pvecteur v): allocation et initialisation d'un sommet de denominateur d et...
Definition: sommet.c:67
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
int nb_ineq
Definition: sc-local.h:73
int nb_eq
Definition: sc-local.h:72
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
int ** vals
Definition: chernikova.h:453
unsigned nbcols
Definition: chernikova.h:452
unsigned nbrows
Definition: chernikova.h:451
int * rawvals
Definition: chernikova.h:454
struct rdte * succ
Definition: ray_dte-local.h:46
struct Svecteur * vecteur
Definition: ray_dte-local.h:45
struct typ_som * ssg
Definition: sg-local.h:43
int nb_s
Definition: sg-local.h:42
Pray_dte vsg
Definition: sg-local.h:49
int nb_v
Definition: sg-local.h:48
structure de donnees Sommet
Definition: sommet-local.h:64
struct typ_som * succ
Definition: sommet-local.h:68
Pvecteur vecteur
Definition: sommet-local.h:66
Value denominateur
Definition: sommet-local.h:67
Representation d'un systeme generateur par trois ensembles de sommets de rayons et de droites.
Definition: sg-local.h:66
Stsg_vects rays_sg
Definition: sg-local.h:68
Stsg_soms soms_sg
Definition: sg-local.h:67
Pbase base
Definition: sg-local.h:70
Stsg_vects dtes_sg
Definition: sg-local.h:69
zval_t ** vals
Definition: chernikova.h:323
zval_t * rawvals
Definition: chernikova.h:324
unsigned nbrows
Definition: chernikova.h:321
unsigned nbvals
Definition: chernikova.h:325
unsigned nbcols
Definition: chernikova.h:322
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define base_dimension(b)
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228