Merge branch 'maint'
[platform/upstream/isl.git] / isl_tab.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2013      Ecole Normale Superieure
4  *
5  * Use of this software is governed by the MIT license
6  *
7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9  * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
10  */
11
12 #include <isl_ctx_private.h>
13 #include <isl_mat_private.h>
14 #include "isl_map_private.h"
15 #include "isl_tab.h"
16 #include <isl/seq.h>
17 #include <isl_config.h>
18
19 /*
20  * The implementation of tableaus in this file was inspired by Section 8
21  * of David Detlefs, Greg Nelson and James B. Saxe, "Simplify: a theorem
22  * prover for program checking".
23  */
24
25 struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx,
26         unsigned n_row, unsigned n_var, unsigned M)
27 {
28         int i;
29         struct isl_tab *tab;
30         unsigned off = 2 + M;
31
32         tab = isl_calloc_type(ctx, struct isl_tab);
33         if (!tab)
34                 return NULL;
35         tab->mat = isl_mat_alloc(ctx, n_row, off + n_var);
36         if (!tab->mat)
37                 goto error;
38         tab->var = isl_alloc_array(ctx, struct isl_tab_var, n_var);
39         if (!tab->var)
40                 goto error;
41         tab->con = isl_alloc_array(ctx, struct isl_tab_var, n_row);
42         if (!tab->con)
43                 goto error;
44         tab->col_var = isl_alloc_array(ctx, int, n_var);
45         if (!tab->col_var)
46                 goto error;
47         tab->row_var = isl_alloc_array(ctx, int, n_row);
48         if (!tab->row_var)
49                 goto error;
50         for (i = 0; i < n_var; ++i) {
51                 tab->var[i].index = i;
52                 tab->var[i].is_row = 0;
53                 tab->var[i].is_nonneg = 0;
54                 tab->var[i].is_zero = 0;
55                 tab->var[i].is_redundant = 0;
56                 tab->var[i].frozen = 0;
57                 tab->var[i].negated = 0;
58                 tab->col_var[i] = i;
59         }
60         tab->n_row = 0;
61         tab->n_con = 0;
62         tab->n_eq = 0;
63         tab->max_con = n_row;
64         tab->n_col = n_var;
65         tab->n_var = n_var;
66         tab->max_var = n_var;
67         tab->n_param = 0;
68         tab->n_div = 0;
69         tab->n_dead = 0;
70         tab->n_redundant = 0;
71         tab->strict_redundant = 0;
72         tab->need_undo = 0;
73         tab->rational = 0;
74         tab->empty = 0;
75         tab->in_undo = 0;
76         tab->M = M;
77         tab->cone = 0;
78         tab->bottom.type = isl_tab_undo_bottom;
79         tab->bottom.next = NULL;
80         tab->top = &tab->bottom;
81
82         tab->n_zero = 0;
83         tab->n_unbounded = 0;
84         tab->basis = NULL;
85
86         return tab;
87 error:
88         isl_tab_free(tab);
89         return NULL;
90 }
91
92 isl_ctx *isl_tab_get_ctx(struct isl_tab *tab)
93 {
94         return tab ? isl_mat_get_ctx(tab->mat) : NULL;
95 }
96
97 int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new)
98 {
99         unsigned off;
100
101         if (!tab)
102                 return -1;
103
104         off = 2 + tab->M;
105
106         if (tab->max_con < tab->n_con + n_new) {
107                 struct isl_tab_var *con;
108
109                 con = isl_realloc_array(tab->mat->ctx, tab->con,
110                                     struct isl_tab_var, tab->max_con + n_new);
111                 if (!con)
112                         return -1;
113                 tab->con = con;
114                 tab->max_con += n_new;
115         }
116         if (tab->mat->n_row < tab->n_row + n_new) {
117                 int *row_var;
118
119                 tab->mat = isl_mat_extend(tab->mat,
120                                         tab->n_row + n_new, off + tab->n_col);
121                 if (!tab->mat)
122                         return -1;
123                 row_var = isl_realloc_array(tab->mat->ctx, tab->row_var,
124                                             int, tab->mat->n_row);
125                 if (!row_var)
126                         return -1;
127                 tab->row_var = row_var;
128                 if (tab->row_sign) {
129                         enum isl_tab_row_sign *s;
130                         s = isl_realloc_array(tab->mat->ctx, tab->row_sign,
131                                         enum isl_tab_row_sign, tab->mat->n_row);
132                         if (!s)
133                                 return -1;
134                         tab->row_sign = s;
135                 }
136         }
137         return 0;
138 }
139
140 /* Make room for at least n_new extra variables.
141  * Return -1 if anything went wrong.
142  */
143 int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new)
144 {
145         struct isl_tab_var *var;
146         unsigned off = 2 + tab->M;
147
148         if (tab->max_var < tab->n_var + n_new) {
149                 var = isl_realloc_array(tab->mat->ctx, tab->var,
150                                     struct isl_tab_var, tab->n_var + n_new);
151                 if (!var)
152                         return -1;
153                 tab->var = var;
154                 tab->max_var += n_new;
155         }
156
157         if (tab->mat->n_col < off + tab->n_col + n_new) {
158                 int *p;
159
160                 tab->mat = isl_mat_extend(tab->mat,
161                                     tab->mat->n_row, off + tab->n_col + n_new);
162                 if (!tab->mat)
163                         return -1;
164                 p = isl_realloc_array(tab->mat->ctx, tab->col_var,
165                                             int, tab->n_col + n_new);
166                 if (!p)
167                         return -1;
168                 tab->col_var = p;
169         }
170
171         return 0;
172 }
173
174 struct isl_tab *isl_tab_extend(struct isl_tab *tab, unsigned n_new)
175 {
176         if (isl_tab_extend_cons(tab, n_new) >= 0)
177                 return tab;
178
179         isl_tab_free(tab);
180         return NULL;
181 }
182
183 static void free_undo_record(struct isl_tab_undo *undo)
184 {
185         switch (undo->type) {
186         case isl_tab_undo_saved_basis:
187                 free(undo->u.col_var);
188                 break;
189         default:;
190         }
191         free(undo);
192 }
193
194 static void free_undo(struct isl_tab *tab)
195 {
196         struct isl_tab_undo *undo, *next;
197
198         for (undo = tab->top; undo && undo != &tab->bottom; undo = next) {
199                 next = undo->next;
200                 free_undo_record(undo);
201         }
202         tab->top = undo;
203 }
204
205 void isl_tab_free(struct isl_tab *tab)
206 {
207         if (!tab)
208                 return;
209         free_undo(tab);
210         isl_mat_free(tab->mat);
211         isl_vec_free(tab->dual);
212         isl_basic_map_free(tab->bmap);
213         free(tab->var);
214         free(tab->con);
215         free(tab->row_var);
216         free(tab->col_var);
217         free(tab->row_sign);
218         isl_mat_free(tab->samples);
219         free(tab->sample_index);
220         isl_mat_free(tab->basis);
221         free(tab);
222 }
223
224 struct isl_tab *isl_tab_dup(struct isl_tab *tab)
225 {
226         int i;
227         struct isl_tab *dup;
228         unsigned off;
229
230         if (!tab)
231                 return NULL;
232
233         off = 2 + tab->M;
234         dup = isl_calloc_type(tab->mat->ctx, struct isl_tab);
235         if (!dup)
236                 return NULL;
237         dup->mat = isl_mat_dup(tab->mat);
238         if (!dup->mat)
239                 goto error;
240         dup->var = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_var);
241         if (!dup->var)
242                 goto error;
243         for (i = 0; i < tab->n_var; ++i)
244                 dup->var[i] = tab->var[i];
245         dup->con = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_con);
246         if (!dup->con)
247                 goto error;
248         for (i = 0; i < tab->n_con; ++i)
249                 dup->con[i] = tab->con[i];
250         dup->col_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_col - off);
251         if (!dup->col_var)
252                 goto error;
253         for (i = 0; i < tab->n_col; ++i)
254                 dup->col_var[i] = tab->col_var[i];
255         dup->row_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_row);
256         if (!dup->row_var)
257                 goto error;
258         for (i = 0; i < tab->n_row; ++i)
259                 dup->row_var[i] = tab->row_var[i];
260         if (tab->row_sign) {
261                 dup->row_sign = isl_alloc_array(tab->mat->ctx, enum isl_tab_row_sign,
262                                                 tab->mat->n_row);
263                 if (!dup->row_sign)
264                         goto error;
265                 for (i = 0; i < tab->n_row; ++i)
266                         dup->row_sign[i] = tab->row_sign[i];
267         }
268         if (tab->samples) {
269                 dup->samples = isl_mat_dup(tab->samples);
270                 if (!dup->samples)
271                         goto error;
272                 dup->sample_index = isl_alloc_array(tab->mat->ctx, int,
273                                                         tab->samples->n_row);
274                 if (!dup->sample_index)
275                         goto error;
276                 dup->n_sample = tab->n_sample;
277                 dup->n_outside = tab->n_outside;
278         }
279         dup->n_row = tab->n_row;
280         dup->n_con = tab->n_con;
281         dup->n_eq = tab->n_eq;
282         dup->max_con = tab->max_con;
283         dup->n_col = tab->n_col;
284         dup->n_var = tab->n_var;
285         dup->max_var = tab->max_var;
286         dup->n_param = tab->n_param;
287         dup->n_div = tab->n_div;
288         dup->n_dead = tab->n_dead;
289         dup->n_redundant = tab->n_redundant;
290         dup->rational = tab->rational;
291         dup->empty = tab->empty;
292         dup->strict_redundant = 0;
293         dup->need_undo = 0;
294         dup->in_undo = 0;
295         dup->M = tab->M;
296         tab->cone = tab->cone;
297         dup->bottom.type = isl_tab_undo_bottom;
298         dup->bottom.next = NULL;
299         dup->top = &dup->bottom;
300
301         dup->n_zero = tab->n_zero;
302         dup->n_unbounded = tab->n_unbounded;
303         dup->basis = isl_mat_dup(tab->basis);
304
305         return dup;
306 error:
307         isl_tab_free(dup);
308         return NULL;
309 }
310
311 /* Construct the coefficient matrix of the product tableau
312  * of two tableaus.
313  * mat{1,2} is the coefficient matrix of tableau {1,2}
314  * row{1,2} is the number of rows in tableau {1,2}
315  * col{1,2} is the number of columns in tableau {1,2}
316  * off is the offset to the coefficient column (skipping the
317  *      denominator, the constant term and the big parameter if any)
318  * r{1,2} is the number of redundant rows in tableau {1,2}
319  * d{1,2} is the number of dead columns in tableau {1,2}
320  *
321  * The order of the rows and columns in the result is as explained
322  * in isl_tab_product.
323  */
324 static struct isl_mat *tab_mat_product(struct isl_mat *mat1,
325         struct isl_mat *mat2, unsigned row1, unsigned row2,
326         unsigned col1, unsigned col2,
327         unsigned off, unsigned r1, unsigned r2, unsigned d1, unsigned d2)
328 {
329         int i;
330         struct isl_mat *prod;
331         unsigned n;
332
333         prod = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row,
334                                         off + col1 + col2);
335         if (!prod)
336                 return NULL;
337
338         n = 0;
339         for (i = 0; i < r1; ++i) {
340                 isl_seq_cpy(prod->row[n + i], mat1->row[i], off + d1);
341                 isl_seq_clr(prod->row[n + i] + off + d1, d2);
342                 isl_seq_cpy(prod->row[n + i] + off + d1 + d2,
343                                 mat1->row[i] + off + d1, col1 - d1);
344                 isl_seq_clr(prod->row[n + i] + off + col1 + d1, col2 - d2);
345         }
346
347         n += r1;
348         for (i = 0; i < r2; ++i) {
349                 isl_seq_cpy(prod->row[n + i], mat2->row[i], off);
350                 isl_seq_clr(prod->row[n + i] + off, d1);
351                 isl_seq_cpy(prod->row[n + i] + off + d1,
352                             mat2->row[i] + off, d2);
353                 isl_seq_clr(prod->row[n + i] + off + d1 + d2, col1 - d1);
354                 isl_seq_cpy(prod->row[n + i] + off + col1 + d1,
355                             mat2->row[i] + off + d2, col2 - d2);
356         }
357
358         n += r2;
359         for (i = 0; i < row1 - r1; ++i) {
360                 isl_seq_cpy(prod->row[n + i], mat1->row[r1 + i], off + d1);
361                 isl_seq_clr(prod->row[n + i] + off + d1, d2);
362                 isl_seq_cpy(prod->row[n + i] + off + d1 + d2,
363                                 mat1->row[r1 + i] + off + d1, col1 - d1);
364                 isl_seq_clr(prod->row[n + i] + off + col1 + d1, col2 - d2);
365         }
366
367         n += row1 - r1;
368         for (i = 0; i < row2 - r2; ++i) {
369                 isl_seq_cpy(prod->row[n + i], mat2->row[r2 + i], off);
370                 isl_seq_clr(prod->row[n + i] + off, d1);
371                 isl_seq_cpy(prod->row[n + i] + off + d1,
372                             mat2->row[r2 + i] + off, d2);
373                 isl_seq_clr(prod->row[n + i] + off + d1 + d2, col1 - d1);
374                 isl_seq_cpy(prod->row[n + i] + off + col1 + d1,
375                             mat2->row[r2 + i] + off + d2, col2 - d2);
376         }
377
378         return prod;
379 }
380
381 /* Update the row or column index of a variable that corresponds
382  * to a variable in the first input tableau.
383  */
384 static void update_index1(struct isl_tab_var *var,
385         unsigned r1, unsigned r2, unsigned d1, unsigned d2)
386 {
387         if (var->index == -1)
388                 return;
389         if (var->is_row && var->index >= r1)
390                 var->index += r2;
391         if (!var->is_row && var->index >= d1)
392                 var->index += d2;
393 }
394
395 /* Update the row or column index of a variable that corresponds
396  * to a variable in the second input tableau.
397  */
398 static void update_index2(struct isl_tab_var *var,
399         unsigned row1, unsigned col1,
400         unsigned r1, unsigned r2, unsigned d1, unsigned d2)
401 {
402         if (var->index == -1)
403                 return;
404         if (var->is_row) {
405                 if (var->index < r2)
406                         var->index += r1;
407                 else
408                         var->index += row1;
409         } else {
410                 if (var->index < d2)
411                         var->index += d1;
412                 else
413                         var->index += col1;
414         }
415 }
416
417 /* Create a tableau that represents the Cartesian product of the sets
418  * represented by tableaus tab1 and tab2.
419  * The order of the rows in the product is
420  *      - redundant rows of tab1
421  *      - redundant rows of tab2
422  *      - non-redundant rows of tab1
423  *      - non-redundant rows of tab2
424  * The order of the columns is
425  *      - denominator
426  *      - constant term
427  *      - coefficient of big parameter, if any
428  *      - dead columns of tab1
429  *      - dead columns of tab2
430  *      - live columns of tab1
431  *      - live columns of tab2
432  * The order of the variables and the constraints is a concatenation
433  * of order in the two input tableaus.
434  */
435 struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2)
436 {
437         int i;
438         struct isl_tab *prod;
439         unsigned off;
440         unsigned r1, r2, d1, d2;
441
442         if (!tab1 || !tab2)
443                 return NULL;
444
445         isl_assert(tab1->mat->ctx, tab1->M == tab2->M, return NULL);
446         isl_assert(tab1->mat->ctx, tab1->rational == tab2->rational, return NULL);
447         isl_assert(tab1->mat->ctx, tab1->cone == tab2->cone, return NULL);
448         isl_assert(tab1->mat->ctx, !tab1->row_sign, return NULL);
449         isl_assert(tab1->mat->ctx, !tab2->row_sign, return NULL);
450         isl_assert(tab1->mat->ctx, tab1->n_param == 0, return NULL);
451         isl_assert(tab1->mat->ctx, tab2->n_param == 0, return NULL);
452         isl_assert(tab1->mat->ctx, tab1->n_div == 0, return NULL);
453         isl_assert(tab1->mat->ctx, tab2->n_div == 0, return NULL);
454
455         off = 2 + tab1->M;
456         r1 = tab1->n_redundant;
457         r2 = tab2->n_redundant;
458         d1 = tab1->n_dead;
459         d2 = tab2->n_dead;
460         prod = isl_calloc_type(tab1->mat->ctx, struct isl_tab);
461         if (!prod)
462                 return NULL;
463         prod->mat = tab_mat_product(tab1->mat, tab2->mat,
464                                 tab1->n_row, tab2->n_row,
465                                 tab1->n_col, tab2->n_col, off, r1, r2, d1, d2);
466         if (!prod->mat)
467                 goto error;
468         prod->var = isl_alloc_array(tab1->mat->ctx, struct isl_tab_var,
469                                         tab1->max_var + tab2->max_var);
470         if (!prod->var)
471                 goto error;
472         for (i = 0; i < tab1->n_var; ++i) {
473                 prod->var[i] = tab1->var[i];
474                 update_index1(&prod->var[i], r1, r2, d1, d2);
475         }
476         for (i = 0; i < tab2->n_var; ++i) {
477                 prod->var[tab1->n_var + i] = tab2->var[i];
478                 update_index2(&prod->var[tab1->n_var + i],
479                                 tab1->n_row, tab1->n_col,
480                                 r1, r2, d1, d2);
481         }
482         prod->con = isl_alloc_array(tab1->mat->ctx, struct isl_tab_var,
483                                         tab1->max_con +  tab2->max_con);
484         if (!prod->con)
485                 goto error;
486         for (i = 0; i < tab1->n_con; ++i) {
487                 prod->con[i] = tab1->con[i];
488                 update_index1(&prod->con[i], r1, r2, d1, d2);
489         }
490         for (i = 0; i < tab2->n_con; ++i) {
491                 prod->con[tab1->n_con + i] = tab2->con[i];
492                 update_index2(&prod->con[tab1->n_con + i],
493                                 tab1->n_row, tab1->n_col,
494                                 r1, r2, d1, d2);
495         }
496         prod->col_var = isl_alloc_array(tab1->mat->ctx, int,
497                                         tab1->n_col + tab2->n_col);
498         if (!prod->col_var)
499                 goto error;
500         for (i = 0; i < tab1->n_col; ++i) {
501                 int pos = i < d1 ? i : i + d2;
502                 prod->col_var[pos] = tab1->col_var[i];
503         }
504         for (i = 0; i < tab2->n_col; ++i) {
505                 int pos = i < d2 ? d1 + i : tab1->n_col + i;
506                 int t = tab2->col_var[i];
507                 if (t >= 0)
508                         t += tab1->n_var;
509                 else
510                         t -= tab1->n_con;
511                 prod->col_var[pos] = t;
512         }
513         prod->row_var = isl_alloc_array(tab1->mat->ctx, int,
514                                         tab1->mat->n_row + tab2->mat->n_row);
515         if (!prod->row_var)
516                 goto error;
517         for (i = 0; i < tab1->n_row; ++i) {
518                 int pos = i < r1 ? i : i + r2;
519                 prod->row_var[pos] = tab1->row_var[i];
520         }
521         for (i = 0; i < tab2->n_row; ++i) {
522                 int pos = i < r2 ? r1 + i : tab1->n_row + i;
523                 int t = tab2->row_var[i];
524                 if (t >= 0)
525                         t += tab1->n_var;
526                 else
527                         t -= tab1->n_con;
528                 prod->row_var[pos] = t;
529         }
530         prod->samples = NULL;
531         prod->sample_index = NULL;
532         prod->n_row = tab1->n_row + tab2->n_row;
533         prod->n_con = tab1->n_con + tab2->n_con;
534         prod->n_eq = 0;
535         prod->max_con = tab1->max_con + tab2->max_con;
536         prod->n_col = tab1->n_col + tab2->n_col;
537         prod->n_var = tab1->n_var + tab2->n_var;
538         prod->max_var = tab1->max_var + tab2->max_var;
539         prod->n_param = 0;
540         prod->n_div = 0;
541         prod->n_dead = tab1->n_dead + tab2->n_dead;
542         prod->n_redundant = tab1->n_redundant + tab2->n_redundant;
543         prod->rational = tab1->rational;
544         prod->empty = tab1->empty || tab2->empty;
545         prod->strict_redundant = tab1->strict_redundant || tab2->strict_redundant;
546         prod->need_undo = 0;
547         prod->in_undo = 0;
548         prod->M = tab1->M;
549         prod->cone = tab1->cone;
550         prod->bottom.type = isl_tab_undo_bottom;
551         prod->bottom.next = NULL;
552         prod->top = &prod->bottom;
553
554         prod->n_zero = 0;
555         prod->n_unbounded = 0;
556         prod->basis = NULL;
557
558         return prod;
559 error:
560         isl_tab_free(prod);
561         return NULL;
562 }
563
564 static struct isl_tab_var *var_from_index(struct isl_tab *tab, int i)
565 {
566         if (i >= 0)
567                 return &tab->var[i];
568         else
569                 return &tab->con[~i];
570 }
571
572 struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i)
573 {
574         return var_from_index(tab, tab->row_var[i]);
575 }
576
577 static struct isl_tab_var *var_from_col(struct isl_tab *tab, int i)
578 {
579         return var_from_index(tab, tab->col_var[i]);
580 }
581
582 /* Check if there are any upper bounds on column variable "var",
583  * i.e., non-negative rows where var appears with a negative coefficient.
584  * Return 1 if there are no such bounds.
585  */
586 static int max_is_manifestly_unbounded(struct isl_tab *tab,
587         struct isl_tab_var *var)
588 {
589         int i;
590         unsigned off = 2 + tab->M;
591
592         if (var->is_row)
593                 return 0;
594         for (i = tab->n_redundant; i < tab->n_row; ++i) {
595                 if (!isl_int_is_neg(tab->mat->row[i][off + var->index]))
596                         continue;
597                 if (isl_tab_var_from_row(tab, i)->is_nonneg)
598                         return 0;
599         }
600         return 1;
601 }
602
603 /* Check if there are any lower bounds on column variable "var",
604  * i.e., non-negative rows where var appears with a positive coefficient.
605  * Return 1 if there are no such bounds.
606  */
607 static int min_is_manifestly_unbounded(struct isl_tab *tab,
608         struct isl_tab_var *var)
609 {
610         int i;
611         unsigned off = 2 + tab->M;
612
613         if (var->is_row)
614                 return 0;
615         for (i = tab->n_redundant; i < tab->n_row; ++i) {
616                 if (!isl_int_is_pos(tab->mat->row[i][off + var->index]))
617                         continue;
618                 if (isl_tab_var_from_row(tab, i)->is_nonneg)
619                         return 0;
620         }
621         return 1;
622 }
623
624 static int row_cmp(struct isl_tab *tab, int r1, int r2, int c, isl_int t)
625 {
626         unsigned off = 2 + tab->M;
627
628         if (tab->M) {
629                 int s;
630                 isl_int_mul(t, tab->mat->row[r1][2], tab->mat->row[r2][off+c]);
631                 isl_int_submul(t, tab->mat->row[r2][2], tab->mat->row[r1][off+c]);
632                 s = isl_int_sgn(t);
633                 if (s)
634                         return s;
635         }
636         isl_int_mul(t, tab->mat->row[r1][1], tab->mat->row[r2][off + c]);
637         isl_int_submul(t, tab->mat->row[r2][1], tab->mat->row[r1][off + c]);
638         return isl_int_sgn(t);
639 }
640
641 /* Given the index of a column "c", return the index of a row
642  * that can be used to pivot the column in, with either an increase
643  * (sgn > 0) or a decrease (sgn < 0) of the corresponding variable.
644  * If "var" is not NULL, then the row returned will be different from
645  * the one associated with "var".
646  *
647  * Each row in the tableau is of the form
648  *
649  *      x_r = a_r0 + \sum_i a_ri x_i
650  *
651  * Only rows with x_r >= 0 and with the sign of a_ri opposite to "sgn"
652  * impose any limit on the increase or decrease in the value of x_c
653  * and this bound is equal to a_r0 / |a_rc|.  We are therefore looking
654  * for the row with the smallest (most stringent) such bound.
655  * Note that the common denominator of each row drops out of the fraction.
656  * To check if row j has a smaller bound than row r, i.e.,
657  * a_j0 / |a_jc| < a_r0 / |a_rc| or a_j0 |a_rc| < a_r0 |a_jc|,
658  * we check if -sign(a_jc) (a_j0 a_rc - a_r0 a_jc) < 0,
659  * where -sign(a_jc) is equal to "sgn".
660  */
661 static int pivot_row(struct isl_tab *tab,
662         struct isl_tab_var *var, int sgn, int c)
663 {
664         int j, r, tsgn;
665         isl_int t;
666         unsigned off = 2 + tab->M;
667
668         isl_int_init(t);
669         r = -1;
670         for (j = tab->n_redundant; j < tab->n_row; ++j) {
671                 if (var && j == var->index)
672                         continue;
673                 if (!isl_tab_var_from_row(tab, j)->is_nonneg)
674                         continue;
675                 if (sgn * isl_int_sgn(tab->mat->row[j][off + c]) >= 0)
676                         continue;
677                 if (r < 0) {
678                         r = j;
679                         continue;
680                 }
681                 tsgn = sgn * row_cmp(tab, r, j, c, t);
682                 if (tsgn < 0 || (tsgn == 0 &&
683                                             tab->row_var[j] < tab->row_var[r]))
684                         r = j;
685         }
686         isl_int_clear(t);
687         return r;
688 }
689
690 /* Find a pivot (row and col) that will increase (sgn > 0) or decrease
691  * (sgn < 0) the value of row variable var.
692  * If not NULL, then skip_var is a row variable that should be ignored
693  * while looking for a pivot row.  It is usually equal to var.
694  *
695  * As the given row in the tableau is of the form
696  *
697  *      x_r = a_r0 + \sum_i a_ri x_i
698  *
699  * we need to find a column such that the sign of a_ri is equal to "sgn"
700  * (such that an increase in x_i will have the desired effect) or a
701  * column with a variable that may attain negative values.
702  * If a_ri is positive, then we need to move x_i in the same direction
703  * to obtain the desired effect.  Otherwise, x_i has to move in the
704  * opposite direction.
705  */
706 static void find_pivot(struct isl_tab *tab,
707         struct isl_tab_var *var, struct isl_tab_var *skip_var,
708         int sgn, int *row, int *col)
709 {
710         int j, r, c;
711         isl_int *tr;
712
713         *row = *col = -1;
714
715         isl_assert(tab->mat->ctx, var->is_row, return);
716         tr = tab->mat->row[var->index] + 2 + tab->M;
717
718         c = -1;
719         for (j = tab->n_dead; j < tab->n_col; ++j) {
720                 if (isl_int_is_zero(tr[j]))
721                         continue;
722                 if (isl_int_sgn(tr[j]) != sgn &&
723                     var_from_col(tab, j)->is_nonneg)
724                         continue;
725                 if (c < 0 || tab->col_var[j] < tab->col_var[c])
726                         c = j;
727         }
728         if (c < 0)
729                 return;
730
731         sgn *= isl_int_sgn(tr[c]);
732         r = pivot_row(tab, skip_var, sgn, c);
733         *row = r < 0 ? var->index : r;
734         *col = c;
735 }
736
737 /* Return 1 if row "row" represents an obviously redundant inequality.
738  * This means
739  *      - it represents an inequality or a variable
740  *      - that is the sum of a non-negative sample value and a positive
741  *        combination of zero or more non-negative constraints.
742  */
743 int isl_tab_row_is_redundant(struct isl_tab *tab, int row)
744 {
745         int i;
746         unsigned off = 2 + tab->M;
747
748         if (tab->row_var[row] < 0 && !isl_tab_var_from_row(tab, row)->is_nonneg)
749                 return 0;
750
751         if (isl_int_is_neg(tab->mat->row[row][1]))
752                 return 0;
753         if (tab->strict_redundant && isl_int_is_zero(tab->mat->row[row][1]))
754                 return 0;
755         if (tab->M && isl_int_is_neg(tab->mat->row[row][2]))
756                 return 0;
757
758         for (i = tab->n_dead; i < tab->n_col; ++i) {
759                 if (isl_int_is_zero(tab->mat->row[row][off + i]))
760                         continue;
761                 if (tab->col_var[i] >= 0)
762                         return 0;
763                 if (isl_int_is_neg(tab->mat->row[row][off + i]))
764                         return 0;
765                 if (!var_from_col(tab, i)->is_nonneg)
766                         return 0;
767         }
768         return 1;
769 }
770
771 static void swap_rows(struct isl_tab *tab, int row1, int row2)
772 {
773         int t;
774         enum isl_tab_row_sign s;
775
776         t = tab->row_var[row1];
777         tab->row_var[row1] = tab->row_var[row2];
778         tab->row_var[row2] = t;
779         isl_tab_var_from_row(tab, row1)->index = row1;
780         isl_tab_var_from_row(tab, row2)->index = row2;
781         tab->mat = isl_mat_swap_rows(tab->mat, row1, row2);
782
783         if (!tab->row_sign)
784                 return;
785         s = tab->row_sign[row1];
786         tab->row_sign[row1] = tab->row_sign[row2];
787         tab->row_sign[row2] = s;
788 }
789
790 static int push_union(struct isl_tab *tab,
791         enum isl_tab_undo_type type, union isl_tab_undo_val u) WARN_UNUSED;
792 static int push_union(struct isl_tab *tab,
793         enum isl_tab_undo_type type, union isl_tab_undo_val u)
794 {
795         struct isl_tab_undo *undo;
796
797         if (!tab)
798                 return -1;
799         if (!tab->need_undo)
800                 return 0;
801
802         undo = isl_alloc_type(tab->mat->ctx, struct isl_tab_undo);
803         if (!undo)
804                 return -1;
805         undo->type = type;
806         undo->u = u;
807         undo->next = tab->top;
808         tab->top = undo;
809
810         return 0;
811 }
812
813 int isl_tab_push_var(struct isl_tab *tab,
814         enum isl_tab_undo_type type, struct isl_tab_var *var)
815 {
816         union isl_tab_undo_val u;
817         if (var->is_row)
818                 u.var_index = tab->row_var[var->index];
819         else
820                 u.var_index = tab->col_var[var->index];
821         return push_union(tab, type, u);
822 }
823
824 int isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type)
825 {
826         union isl_tab_undo_val u = { 0 };
827         return push_union(tab, type, u);
828 }
829
830 /* Push a record on the undo stack describing the current basic
831  * variables, so that the this state can be restored during rollback.
832  */
833 int isl_tab_push_basis(struct isl_tab *tab)
834 {
835         int i;
836         union isl_tab_undo_val u;
837
838         u.col_var = isl_alloc_array(tab->mat->ctx, int, tab->n_col);
839         if (!u.col_var)
840                 return -1;
841         for (i = 0; i < tab->n_col; ++i)
842                 u.col_var[i] = tab->col_var[i];
843         return push_union(tab, isl_tab_undo_saved_basis, u);
844 }
845
846 int isl_tab_push_callback(struct isl_tab *tab, struct isl_tab_callback *callback)
847 {
848         union isl_tab_undo_val u;
849         u.callback = callback;
850         return push_union(tab, isl_tab_undo_callback, u);
851 }
852
853 struct isl_tab *isl_tab_init_samples(struct isl_tab *tab)
854 {
855         if (!tab)
856                 return NULL;
857
858         tab->n_sample = 0;
859         tab->n_outside = 0;
860         tab->samples = isl_mat_alloc(tab->mat->ctx, 1, 1 + tab->n_var);
861         if (!tab->samples)
862                 goto error;
863         tab->sample_index = isl_alloc_array(tab->mat->ctx, int, 1);
864         if (!tab->sample_index)
865                 goto error;
866         return tab;
867 error:
868         isl_tab_free(tab);
869         return NULL;
870 }
871
872 struct isl_tab *isl_tab_add_sample(struct isl_tab *tab,
873         __isl_take isl_vec *sample)
874 {
875         if (!tab || !sample)
876                 goto error;
877
878         if (tab->n_sample + 1 > tab->samples->n_row) {
879                 int *t = isl_realloc_array(tab->mat->ctx,
880                             tab->sample_index, int, tab->n_sample + 1);
881                 if (!t)
882                         goto error;
883                 tab->sample_index = t;
884         }
885
886         tab->samples = isl_mat_extend(tab->samples,
887                                 tab->n_sample + 1, tab->samples->n_col);
888         if (!tab->samples)
889                 goto error;
890
891         isl_seq_cpy(tab->samples->row[tab->n_sample], sample->el, sample->size);
892         isl_vec_free(sample);
893         tab->sample_index[tab->n_sample] = tab->n_sample;
894         tab->n_sample++;
895
896         return tab;
897 error:
898         isl_vec_free(sample);
899         isl_tab_free(tab);
900         return NULL;
901 }
902
903 struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s)
904 {
905         if (s != tab->n_outside) {
906                 int t = tab->sample_index[tab->n_outside];
907                 tab->sample_index[tab->n_outside] = tab->sample_index[s];
908                 tab->sample_index[s] = t;
909                 isl_mat_swap_rows(tab->samples, tab->n_outside, s);
910         }
911         tab->n_outside++;
912         if (isl_tab_push(tab, isl_tab_undo_drop_sample) < 0) {
913                 isl_tab_free(tab);
914                 return NULL;
915         }
916
917         return tab;
918 }
919
920 /* Record the current number of samples so that we can remove newer
921  * samples during a rollback.
922  */
923 int isl_tab_save_samples(struct isl_tab *tab)
924 {
925         union isl_tab_undo_val u;
926
927         if (!tab)
928                 return -1;
929
930         u.n = tab->n_sample;
931         return push_union(tab, isl_tab_undo_saved_samples, u);
932 }
933
934 /* Mark row with index "row" as being redundant.
935  * If we may need to undo the operation or if the row represents
936  * a variable of the original problem, the row is kept,
937  * but no longer considered when looking for a pivot row.
938  * Otherwise, the row is simply removed.
939  *
940  * The row may be interchanged with some other row.  If it
941  * is interchanged with a later row, return 1.  Otherwise return 0.
942  * If the rows are checked in order in the calling function,
943  * then a return value of 1 means that the row with the given
944  * row number may now contain a different row that hasn't been checked yet.
945  */
946 int isl_tab_mark_redundant(struct isl_tab *tab, int row)
947 {
948         struct isl_tab_var *var = isl_tab_var_from_row(tab, row);
949         var->is_redundant = 1;
950         isl_assert(tab->mat->ctx, row >= tab->n_redundant, return -1);
951         if (tab->preserve || tab->need_undo || tab->row_var[row] >= 0) {
952                 if (tab->row_var[row] >= 0 && !var->is_nonneg) {
953                         var->is_nonneg = 1;
954                         if (isl_tab_push_var(tab, isl_tab_undo_nonneg, var) < 0)
955                                 return -1;
956                 }
957                 if (row != tab->n_redundant)
958                         swap_rows(tab, row, tab->n_redundant);
959                 tab->n_redundant++;
960                 return isl_tab_push_var(tab, isl_tab_undo_redundant, var);
961         } else {
962                 if (row != tab->n_row - 1)
963                         swap_rows(tab, row, tab->n_row - 1);
964                 isl_tab_var_from_row(tab, tab->n_row - 1)->index = -1;
965                 tab->n_row--;
966                 return 1;
967         }
968 }
969
970 int isl_tab_mark_empty(struct isl_tab *tab)
971 {
972         if (!tab)
973                 return -1;
974         if (!tab->empty && tab->need_undo)
975                 if (isl_tab_push(tab, isl_tab_undo_empty) < 0)
976                         return -1;
977         tab->empty = 1;
978         return 0;
979 }
980
981 int isl_tab_freeze_constraint(struct isl_tab *tab, int con)
982 {
983         struct isl_tab_var *var;
984
985         if (!tab)
986                 return -1;
987
988         var = &tab->con[con];
989         if (var->frozen)
990                 return 0;
991         if (var->index < 0)
992                 return 0;
993         var->frozen = 1;
994
995         if (tab->need_undo)
996                 return isl_tab_push_var(tab, isl_tab_undo_freeze, var);
997
998         return 0;
999 }
1000
1001 /* Update the rows signs after a pivot of "row" and "col", with "row_sgn"
1002  * the original sign of the pivot element.
1003  * We only keep track of row signs during PILP solving and in this case
1004  * we only pivot a row with negative sign (meaning the value is always
1005  * non-positive) using a positive pivot element.
1006  *
1007  * For each row j, the new value of the parametric constant is equal to
1008  *
1009  *      a_j0 - a_jc a_r0/a_rc
1010  *
1011  * where a_j0 is the original parametric constant, a_rc is the pivot element,
1012  * a_r0 is the parametric constant of the pivot row and a_jc is the
1013  * pivot column entry of the row j.
1014  * Since a_r0 is non-positive and a_rc is positive, the sign of row j
1015  * remains the same if a_jc has the same sign as the row j or if
1016  * a_jc is zero.  In all other cases, we reset the sign to "unknown".
1017  */
1018 static void update_row_sign(struct isl_tab *tab, int row, int col, int row_sgn)
1019 {
1020         int i;
1021         struct isl_mat *mat = tab->mat;
1022         unsigned off = 2 + tab->M;
1023
1024         if (!tab->row_sign)
1025                 return;
1026
1027         if (tab->row_sign[row] == 0)
1028                 return;
1029         isl_assert(mat->ctx, row_sgn > 0, return);
1030         isl_assert(mat->ctx, tab->row_sign[row] == isl_tab_row_neg, return);
1031         tab->row_sign[row] = isl_tab_row_pos;
1032         for (i = 0; i < tab->n_row; ++i) {
1033                 int s;
1034                 if (i == row)
1035                         continue;
1036                 s = isl_int_sgn(mat->row[i][off + col]);
1037                 if (!s)
1038                         continue;
1039                 if (!tab->row_sign[i])
1040                         continue;
1041                 if (s < 0 && tab->row_sign[i] == isl_tab_row_neg)
1042                         continue;
1043                 if (s > 0 && tab->row_sign[i] == isl_tab_row_pos)
1044                         continue;
1045                 tab->row_sign[i] = isl_tab_row_unknown;
1046         }
1047 }
1048
1049 /* Given a row number "row" and a column number "col", pivot the tableau
1050  * such that the associated variables are interchanged.
1051  * The given row in the tableau expresses
1052  *
1053  *      x_r = a_r0 + \sum_i a_ri x_i
1054  *
1055  * or
1056  *
1057  *      x_c = 1/a_rc x_r - a_r0/a_rc + sum_{i \ne r} -a_ri/a_rc
1058  *
1059  * Substituting this equality into the other rows
1060  *
1061  *      x_j = a_j0 + \sum_i a_ji x_i
1062  *
1063  * with a_jc \ne 0, we obtain
1064  *
1065  *      x_j = a_jc/a_rc x_r + a_j0 - a_jc a_r0/a_rc + sum a_ji - a_jc a_ri/a_rc 
1066  *
1067  * The tableau
1068  *
1069  *      n_rc/d_r                n_ri/d_r
1070  *      n_jc/d_j                n_ji/d_j
1071  *
1072  * where i is any other column and j is any other row,
1073  * is therefore transformed into
1074  *
1075  * s(n_rc)d_r/|n_rc|            -s(n_rc)n_ri/|n_rc|
1076  * s(n_rc)d_r n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j)
1077  *
1078  * The transformation is performed along the following steps
1079  *
1080  *      d_r/n_rc                n_ri/n_rc
1081  *      n_jc/d_j                n_ji/d_j
1082  *
1083  *      s(n_rc)d_r/|n_rc|       -s(n_rc)n_ri/|n_rc|
1084  *      n_jc/d_j                n_ji/d_j
1085  *
1086  *      s(n_rc)d_r/|n_rc|       -s(n_rc)n_ri/|n_rc|
1087  *      n_jc/(|n_rc| d_j)       n_ji/(|n_rc| d_j)
1088  *
1089  *      s(n_rc)d_r/|n_rc|       -s(n_rc)n_ri/|n_rc|
1090  *      n_jc/(|n_rc| d_j)       (n_ji |n_rc|)/(|n_rc| d_j)
1091  *
1092  *      s(n_rc)d_r/|n_rc|       -s(n_rc)n_ri/|n_rc|
1093  *      n_jc/(|n_rc| d_j)       (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j)
1094  *
1095  * s(n_rc)d_r/|n_rc|            -s(n_rc)n_ri/|n_rc|
1096  * s(n_rc)d_r n_jc/(|n_rc| d_j) (n_ji |n_rc| - s(n_rc)n_jc n_ri)/(|n_rc| d_j)
1097  *
1098  */
1099 int isl_tab_pivot(struct isl_tab *tab, int row, int col)
1100 {
1101         int i, j;
1102         int sgn;
1103         int t;
1104         struct isl_mat *mat = tab->mat;
1105         struct isl_tab_var *var;
1106         unsigned off = 2 + tab->M;
1107
1108         if (tab->mat->ctx->abort) {
1109                 isl_ctx_set_error(tab->mat->ctx, isl_error_abort);
1110                 return -1;
1111         }
1112
1113         isl_int_swap(mat->row[row][0], mat->row[row][off + col]);
1114         sgn = isl_int_sgn(mat->row[row][0]);
1115         if (sgn < 0) {
1116                 isl_int_neg(mat->row[row][0], mat->row[row][0]);
1117                 isl_int_neg(mat->row[row][off + col], mat->row[row][off + col]);
1118         } else
1119                 for (j = 0; j < off - 1 + tab->n_col; ++j) {
1120                         if (j == off - 1 + col)
1121                                 continue;
1122                         isl_int_neg(mat->row[row][1 + j], mat->row[row][1 + j]);
1123                 }
1124         if (!isl_int_is_one(mat->row[row][0]))
1125                 isl_seq_normalize(mat->ctx, mat->row[row], off + tab->n_col);
1126         for (i = 0; i < tab->n_row; ++i) {
1127                 if (i == row)
1128                         continue;
1129                 if (isl_int_is_zero(mat->row[i][off + col]))
1130                         continue;
1131                 isl_int_mul(mat->row[i][0], mat->row[i][0], mat->row[row][0]);
1132                 for (j = 0; j < off - 1 + tab->n_col; ++j) {
1133                         if (j == off - 1 + col)
1134                                 continue;
1135                         isl_int_mul(mat->row[i][1 + j],
1136                                     mat->row[i][1 + j], mat->row[row][0]);
1137                         isl_int_addmul(mat->row[i][1 + j],
1138                                     mat->row[i][off + col], mat->row[row][1 + j]);
1139                 }
1140                 isl_int_mul(mat->row[i][off + col],
1141                             mat->row[i][off + col], mat->row[row][off + col]);
1142                 if (!isl_int_is_one(mat->row[i][0]))
1143                         isl_seq_normalize(mat->ctx, mat->row[i], off + tab->n_col);
1144         }
1145         t = tab->row_var[row];
1146         tab->row_var[row] = tab->col_var[col];
1147         tab->col_var[col] = t;
1148         var = isl_tab_var_from_row(tab, row);
1149         var->is_row = 1;
1150         var->index = row;
1151         var = var_from_col(tab, col);
1152         var->is_row = 0;
1153         var->index = col;
1154         update_row_sign(tab, row, col, sgn);
1155         if (tab->in_undo)
1156                 return 0;
1157         for (i = tab->n_redundant; i < tab->n_row; ++i) {
1158                 if (isl_int_is_zero(mat->row[i][off + col]))
1159                         continue;
1160                 if (!isl_tab_var_from_row(tab, i)->frozen &&
1161                     isl_tab_row_is_redundant(tab, i)) {
1162                         int redo = isl_tab_mark_redundant(tab, i);
1163                         if (redo < 0)
1164                                 return -1;
1165                         if (redo)
1166                                 --i;
1167                 }
1168         }
1169         return 0;
1170 }
1171
1172 /* If "var" represents a column variable, then pivot is up (sgn > 0)
1173  * or down (sgn < 0) to a row.  The variable is assumed not to be
1174  * unbounded in the specified direction.
1175  * If sgn = 0, then the variable is unbounded in both directions,
1176  * and we pivot with any row we can find.
1177  */
1178 static int to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign) WARN_UNUSED;
1179 static int to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign)
1180 {
1181         int r;
1182         unsigned off = 2 + tab->M;
1183
1184         if (var->is_row)
1185                 return 0;
1186
1187         if (sign == 0) {
1188                 for (r = tab->n_redundant; r < tab->n_row; ++r)
1189                         if (!isl_int_is_zero(tab->mat->row[r][off+var->index]))
1190                                 break;
1191                 isl_assert(tab->mat->ctx, r < tab->n_row, return -1);
1192         } else {
1193                 r = pivot_row(tab, NULL, sign, var->index);
1194                 isl_assert(tab->mat->ctx, r >= 0, return -1);
1195         }
1196
1197         return isl_tab_pivot(tab, r, var->index);
1198 }
1199
1200 /* Check whether all variables that are marked as non-negative
1201  * also have a non-negative sample value.  This function is not
1202  * called from the current code but is useful during debugging.
1203  */
1204 static void check_table(struct isl_tab *tab) __attribute__ ((unused));
1205 static void check_table(struct isl_tab *tab)
1206 {
1207         int i;
1208
1209         if (tab->empty)
1210                 return;
1211         for (i = tab->n_redundant; i < tab->n_row; ++i) {
1212                 struct isl_tab_var *var;
1213                 var = isl_tab_var_from_row(tab, i);
1214                 if (!var->is_nonneg)
1215                         continue;
1216                 if (tab->M) {
1217                         isl_assert(tab->mat->ctx,
1218                                 !isl_int_is_neg(tab->mat->row[i][2]), abort());
1219                         if (isl_int_is_pos(tab->mat->row[i][2]))
1220                                 continue;
1221                 }
1222                 isl_assert(tab->mat->ctx, !isl_int_is_neg(tab->mat->row[i][1]),
1223                                 abort());
1224         }
1225 }
1226
1227 /* Return the sign of the maximal value of "var".
1228  * If the sign is not negative, then on return from this function,
1229  * the sample value will also be non-negative.
1230  *
1231  * If "var" is manifestly unbounded wrt positive values, we are done.
1232  * Otherwise, we pivot the variable up to a row if needed
1233  * Then we continue pivoting down until either
1234  *      - no more down pivots can be performed
1235  *      - the sample value is positive
1236  *      - the variable is pivoted into a manifestly unbounded column
1237  */
1238 static int sign_of_max(struct isl_tab *tab, struct isl_tab_var *var)
1239 {
1240         int row, col;
1241
1242         if (max_is_manifestly_unbounded(tab, var))
1243                 return 1;
1244         if (to_row(tab, var, 1) < 0)
1245                 return -2;
1246         while (!isl_int_is_pos(tab->mat->row[var->index][1])) {
1247                 find_pivot(tab, var, var, 1, &row, &col);
1248                 if (row == -1)
1249                         return isl_int_sgn(tab->mat->row[var->index][1]);
1250                 if (isl_tab_pivot(tab, row, col) < 0)
1251                         return -2;
1252                 if (!var->is_row) /* manifestly unbounded */
1253                         return 1;
1254         }
1255         return 1;
1256 }
1257
1258 int isl_tab_sign_of_max(struct isl_tab *tab, int con)
1259 {
1260         struct isl_tab_var *var;
1261
1262         if (!tab)
1263                 return -2;
1264
1265         var = &tab->con[con];
1266         isl_assert(tab->mat->ctx, !var->is_redundant, return -2);
1267         isl_assert(tab->mat->ctx, !var->is_zero, return -2);
1268
1269         return sign_of_max(tab, var);
1270 }
1271
1272 static int row_is_neg(struct isl_tab *tab, int row)
1273 {
1274         if (!tab->M)
1275                 return isl_int_is_neg(tab->mat->row[row][1]);
1276         if (isl_int_is_pos(tab->mat->row[row][2]))
1277                 return 0;
1278         if (isl_int_is_neg(tab->mat->row[row][2]))
1279                 return 1;
1280         return isl_int_is_neg(tab->mat->row[row][1]);
1281 }
1282
1283 static int row_sgn(struct isl_tab *tab, int row)
1284 {
1285         if (!tab->M)
1286                 return isl_int_sgn(tab->mat->row[row][1]);
1287         if (!isl_int_is_zero(tab->mat->row[row][2]))
1288                 return isl_int_sgn(tab->mat->row[row][2]);
1289         else
1290                 return isl_int_sgn(tab->mat->row[row][1]);
1291 }
1292
1293 /* Perform pivots until the row variable "var" has a non-negative
1294  * sample value or until no more upward pivots can be performed.
1295  * Return the sign of the sample value after the pivots have been
1296  * performed.
1297  */
1298 static int restore_row(struct isl_tab *tab, struct isl_tab_var *var)
1299 {
1300         int row, col;
1301
1302         while (row_is_neg(tab, var->index)) {
1303                 find_pivot(tab, var, var, 1, &row, &col);
1304                 if (row == -1)
1305                         break;
1306                 if (isl_tab_pivot(tab, row, col) < 0)
1307                         return -2;
1308                 if (!var->is_row) /* manifestly unbounded */
1309                         return 1;
1310         }
1311         return row_sgn(tab, var->index);
1312 }
1313
1314 /* Perform pivots until we are sure that the row variable "var"
1315  * can attain non-negative values.  After return from this
1316  * function, "var" is still a row variable, but its sample
1317  * value may not be non-negative, even if the function returns 1.
1318  */
1319 static int at_least_zero(struct isl_tab *tab, struct isl_tab_var *var)
1320 {
1321         int row, col;
1322
1323         while (isl_int_is_neg(tab->mat->row[var->index][1])) {
1324                 find_pivot(tab, var, var, 1, &row, &col);
1325                 if (row == -1)
1326                         break;
1327                 if (row == var->index) /* manifestly unbounded */
1328                         return 1;
1329                 if (isl_tab_pivot(tab, row, col) < 0)
1330                         return -1;
1331         }
1332         return !isl_int_is_neg(tab->mat->row[var->index][1]);
1333 }
1334
1335 /* Return a negative value if "var" can attain negative values.
1336  * Return a non-negative value otherwise.
1337  *
1338  * If "var" is manifestly unbounded wrt negative values, we are done.
1339  * Otherwise, if var is in a column, we can pivot it down to a row.
1340  * Then we continue pivoting down until either
1341  *      - the pivot would result in a manifestly unbounded column
1342  *        => we don't perform the pivot, but simply return -1
1343  *      - no more down pivots can be performed
1344  *      - the sample value is negative
1345  * If the sample value becomes negative and the variable is supposed
1346  * to be nonnegative, then we undo the last pivot.
1347  * However, if the last pivot has made the pivoting variable
1348  * obviously redundant, then it may have moved to another row.
1349  * In that case we look for upward pivots until we reach a non-negative
1350  * value again.
1351  */
1352 static int sign_of_min(struct isl_tab *tab, struct isl_tab_var *var)
1353 {
1354         int row, col;
1355         struct isl_tab_var *pivot_var = NULL;
1356
1357         if (min_is_manifestly_unbounded(tab, var))
1358                 return -1;
1359         if (!var->is_row) {
1360                 col = var->index;
1361                 row = pivot_row(tab, NULL, -1, col);
1362                 pivot_var = var_from_col(tab, col);
1363                 if (isl_tab_pivot(tab, row, col) < 0)
1364                         return -2;
1365                 if (var->is_redundant)
1366                         return 0;
1367                 if (isl_int_is_neg(tab->mat->row[var->index][1])) {
1368                         if (var->is_nonneg) {
1369                                 if (!pivot_var->is_redundant &&
1370                                     pivot_var->index == row) {
1371                                         if (isl_tab_pivot(tab, row, col) < 0)
1372                                                 return -2;
1373                                 } else
1374                                         if (restore_row(tab, var) < -1)
1375                                                 return -2;
1376                         }
1377                         return -1;
1378                 }
1379         }
1380         if (var->is_redundant)
1381                 return 0;
1382         while (!isl_int_is_neg(tab->mat->row[var->index][1])) {
1383                 find_pivot(tab, var, var, -1, &row, &col);
1384                 if (row == var->index)
1385                         return -1;
1386                 if (row == -1)
1387                         return isl_int_sgn(tab->mat->row[var->index][1]);
1388                 pivot_var = var_from_col(tab, col);
1389                 if (isl_tab_pivot(tab, row, col) < 0)
1390                         return -2;
1391                 if (var->is_redundant)
1392                         return 0;
1393         }
1394         if (pivot_var && var->is_nonneg) {
1395                 /* pivot back to non-negative value */
1396                 if (!pivot_var->is_redundant && pivot_var->index == row) {
1397                         if (isl_tab_pivot(tab, row, col) < 0)
1398                                 return -2;
1399                 } else
1400                         if (restore_row(tab, var) < -1)
1401                                 return -2;
1402         }
1403         return -1;
1404 }
1405
1406 static int row_at_most_neg_one(struct isl_tab *tab, int row)
1407 {
1408         if (tab->M) {
1409                 if (isl_int_is_pos(tab->mat->row[row][2]))
1410                         return 0;
1411                 if (isl_int_is_neg(tab->mat->row[row][2]))
1412                         return 1;
1413         }
1414         return isl_int_is_neg(tab->mat->row[row][1]) &&
1415                isl_int_abs_ge(tab->mat->row[row][1],
1416                               tab->mat->row[row][0]);
1417 }
1418
1419 /* Return 1 if "var" can attain values <= -1.
1420  * Return 0 otherwise.
1421  *
1422  * The sample value of "var" is assumed to be non-negative when the
1423  * the function is called.  If 1 is returned then the constraint
1424  * is not redundant and the sample value is made non-negative again before
1425  * the function returns.
1426  */
1427 int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var)
1428 {
1429         int row, col;
1430         struct isl_tab_var *pivot_var;
1431
1432         if (min_is_manifestly_unbounded(tab, var))
1433                 return 1;
1434         if (!var->is_row) {
1435                 col = var->index;
1436                 row = pivot_row(tab, NULL, -1, col);
1437                 pivot_var = var_from_col(tab, col);
1438                 if (isl_tab_pivot(tab, row, col) < 0)
1439                         return -1;
1440                 if (var->is_redundant)
1441                         return 0;
1442                 if (row_at_most_neg_one(tab, var->index)) {
1443                         if (var->is_nonneg) {
1444                                 if (!pivot_var->is_redundant &&
1445                                     pivot_var->index == row) {
1446                                         if (isl_tab_pivot(tab, row, col) < 0)
1447                                                 return -1;
1448                                 } else
1449                                         if (restore_row(tab, var) < -1)
1450                                                 return -1;
1451                         }
1452                         return 1;
1453                 }
1454         }
1455         if (var->is_redundant)
1456                 return 0;
1457         do {
1458                 find_pivot(tab, var, var, -1, &row, &col);
1459                 if (row == var->index) {
1460                         if (restore_row(tab, var) < -1)
1461                                 return -1;
1462                         return 1;
1463                 }
1464                 if (row == -1)
1465                         return 0;
1466                 pivot_var = var_from_col(tab, col);
1467                 if (isl_tab_pivot(tab, row, col) < 0)
1468                         return -1;
1469                 if (var->is_redundant)
1470                         return 0;
1471         } while (!row_at_most_neg_one(tab, var->index));
1472         if (var->is_nonneg) {
1473                 /* pivot back to non-negative value */
1474                 if (!pivot_var->is_redundant && pivot_var->index == row)
1475                         if (isl_tab_pivot(tab, row, col) < 0)
1476                                 return -1;
1477                 if (restore_row(tab, var) < -1)
1478                         return -1;
1479         }
1480         return 1;
1481 }
1482
1483 /* Return 1 if "var" can attain values >= 1.
1484  * Return 0 otherwise.
1485  */
1486 static int at_least_one(struct isl_tab *tab, struct isl_tab_var *var)
1487 {
1488         int row, col;
1489         isl_int *r;
1490
1491         if (max_is_manifestly_unbounded(tab, var))
1492                 return 1;
1493         if (to_row(tab, var, 1) < 0)
1494                 return -1;
1495         r = tab->mat->row[var->index];
1496         while (isl_int_lt(r[1], r[0])) {
1497                 find_pivot(tab, var, var, 1, &row, &col);
1498                 if (row == -1)
1499                         return isl_int_ge(r[1], r[0]);
1500                 if (row == var->index) /* manifestly unbounded */
1501                         return 1;
1502                 if (isl_tab_pivot(tab, row, col) < 0)
1503                         return -1;
1504         }
1505         return 1;
1506 }
1507
1508 static void swap_cols(struct isl_tab *tab, int col1, int col2)
1509 {
1510         int t;
1511         unsigned off = 2 + tab->M;
1512         t = tab->col_var[col1];
1513         tab->col_var[col1] = tab->col_var[col2];
1514         tab->col_var[col2] = t;
1515         var_from_col(tab, col1)->index = col1;
1516         var_from_col(tab, col2)->index = col2;
1517         tab->mat = isl_mat_swap_cols(tab->mat, off + col1, off + col2);
1518 }
1519
1520 /* Mark column with index "col" as representing a zero variable.
1521  * If we may need to undo the operation the column is kept,
1522  * but no longer considered.
1523  * Otherwise, the column is simply removed.
1524  *
1525  * The column may be interchanged with some other column.  If it
1526  * is interchanged with a later column, return 1.  Otherwise return 0.
1527  * If the columns are checked in order in the calling function,
1528  * then a return value of 1 means that the column with the given
1529  * column number may now contain a different column that
1530  * hasn't been checked yet.
1531  */
1532 int isl_tab_kill_col(struct isl_tab *tab, int col)
1533 {
1534         var_from_col(tab, col)->is_zero = 1;
1535         if (tab->need_undo) {
1536                 if (isl_tab_push_var(tab, isl_tab_undo_zero,
1537                                             var_from_col(tab, col)) < 0)
1538                         return -1;
1539                 if (col != tab->n_dead)
1540                         swap_cols(tab, col, tab->n_dead);
1541                 tab->n_dead++;
1542                 return 0;
1543         } else {
1544                 if (col != tab->n_col - 1)
1545                         swap_cols(tab, col, tab->n_col - 1);
1546                 var_from_col(tab, tab->n_col - 1)->index = -1;
1547                 tab->n_col--;
1548                 return 1;
1549         }
1550 }
1551
1552 static int row_is_manifestly_non_integral(struct isl_tab *tab, int row)
1553 {
1554         unsigned off = 2 + tab->M;
1555
1556         if (tab->M && !isl_int_eq(tab->mat->row[row][2],
1557                                   tab->mat->row[row][0]))
1558                 return 0;
1559         if (isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
1560                                     tab->n_col - tab->n_dead) != -1)
1561                 return 0;
1562
1563         return !isl_int_is_divisible_by(tab->mat->row[row][1],
1564                                         tab->mat->row[row][0]);
1565 }
1566
1567 /* For integer tableaus, check if any of the coordinates are stuck
1568  * at a non-integral value.
1569  */
1570 static int tab_is_manifestly_empty(struct isl_tab *tab)
1571 {
1572         int i;
1573
1574         if (tab->empty)
1575                 return 1;
1576         if (tab->rational)
1577                 return 0;
1578
1579         for (i = 0; i < tab->n_var; ++i) {
1580                 if (!tab->var[i].is_row)
1581                         continue;
1582                 if (row_is_manifestly_non_integral(tab, tab->var[i].index))
1583                         return 1;
1584         }
1585
1586         return 0;
1587 }
1588
1589 /* Row variable "var" is non-negative and cannot attain any values
1590  * larger than zero.  This means that the coefficients of the unrestricted
1591  * column variables are zero and that the coefficients of the non-negative
1592  * column variables are zero or negative.
1593  * Each of the non-negative variables with a negative coefficient can
1594  * then also be written as the negative sum of non-negative variables
1595  * and must therefore also be zero.
1596  */
1597 static int close_row(struct isl_tab *tab, struct isl_tab_var *var) WARN_UNUSED;
1598 static int close_row(struct isl_tab *tab, struct isl_tab_var *var)
1599 {
1600         int j;
1601         struct isl_mat *mat = tab->mat;
1602         unsigned off = 2 + tab->M;
1603
1604         isl_assert(tab->mat->ctx, var->is_nonneg, return -1);
1605         var->is_zero = 1;
1606         if (tab->need_undo)
1607                 if (isl_tab_push_var(tab, isl_tab_undo_zero, var) < 0)
1608                         return -1;
1609         for (j = tab->n_dead; j < tab->n_col; ++j) {
1610                 int recheck;
1611                 if (isl_int_is_zero(mat->row[var->index][off + j]))
1612                         continue;
1613                 isl_assert(tab->mat->ctx,
1614                     isl_int_is_neg(mat->row[var->index][off + j]), return -1);
1615                 recheck = isl_tab_kill_col(tab, j);
1616                 if (recheck < 0)
1617                         return -1;
1618                 if (recheck)
1619                         --j;
1620         }
1621         if (isl_tab_mark_redundant(tab, var->index) < 0)
1622                 return -1;
1623         if (tab_is_manifestly_empty(tab) && isl_tab_mark_empty(tab) < 0)
1624                 return -1;
1625         return 0;
1626 }
1627
1628 /* Add a constraint to the tableau and allocate a row for it.
1629  * Return the index into the constraint array "con".
1630  */
1631 int isl_tab_allocate_con(struct isl_tab *tab)
1632 {
1633         int r;
1634
1635         isl_assert(tab->mat->ctx, tab->n_row < tab->mat->n_row, return -1);
1636         isl_assert(tab->mat->ctx, tab->n_con < tab->max_con, return -1);
1637
1638         r = tab->n_con;
1639         tab->con[r].index = tab->n_row;
1640         tab->con[r].is_row = 1;
1641         tab->con[r].is_nonneg = 0;
1642         tab->con[r].is_zero = 0;
1643         tab->con[r].is_redundant = 0;
1644         tab->con[r].frozen = 0;
1645         tab->con[r].negated = 0;
1646         tab->row_var[tab->n_row] = ~r;
1647
1648         tab->n_row++;
1649         tab->n_con++;
1650         if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->con[r]) < 0)
1651                 return -1;
1652
1653         return r;
1654 }
1655
1656 /* Add a variable to the tableau and allocate a column for it.
1657  * Return the index into the variable array "var".
1658  */
1659 int isl_tab_allocate_var(struct isl_tab *tab)
1660 {
1661         int r;
1662         int i;
1663         unsigned off = 2 + tab->M;
1664
1665         isl_assert(tab->mat->ctx, tab->n_col < tab->mat->n_col, return -1);
1666         isl_assert(tab->mat->ctx, tab->n_var < tab->max_var, return -1);
1667
1668         r = tab->n_var;
1669         tab->var[r].index = tab->n_col;
1670         tab->var[r].is_row = 0;
1671         tab->var[r].is_nonneg = 0;
1672         tab->var[r].is_zero = 0;
1673         tab->var[r].is_redundant = 0;
1674         tab->var[r].frozen = 0;
1675         tab->var[r].negated = 0;
1676         tab->col_var[tab->n_col] = r;
1677
1678         for (i = 0; i < tab->n_row; ++i)
1679                 isl_int_set_si(tab->mat->row[i][off + tab->n_col], 0);
1680
1681         tab->n_var++;
1682         tab->n_col++;
1683         if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->var[r]) < 0)
1684                 return -1;
1685
1686         return r;
1687 }
1688
1689 /* Add a row to the tableau.  The row is given as an affine combination
1690  * of the original variables and needs to be expressed in terms of the
1691  * column variables.
1692  *
1693  * We add each term in turn.
1694  * If r = n/d_r is the current sum and we need to add k x, then
1695  *      if x is a column variable, we increase the numerator of
1696  *              this column by k d_r
1697  *      if x = f/d_x is a row variable, then the new representation of r is
1698  *
1699  *               n    k f   d_x/g n + d_r/g k f   m/d_r n + m/d_g k f
1700  *              --- + --- = ------------------- = -------------------
1701  *              d_r   d_r        d_r d_x/g                m
1702  *
1703  *      with g the gcd of d_r and d_x and m the lcm of d_r and d_x.
1704  *
1705  * If tab->M is set, then, internally, each variable x is represented
1706  * as x' - M.  We then also need no subtract k d_r from the coefficient of M.
1707  */
1708 int isl_tab_add_row(struct isl_tab *tab, isl_int *line)
1709 {
1710         int i;
1711         int r;
1712         isl_int *row;
1713         isl_int a, b;
1714         unsigned off = 2 + tab->M;
1715
1716         r = isl_tab_allocate_con(tab);
1717         if (r < 0)
1718                 return -1;
1719
1720         isl_int_init(a);
1721         isl_int_init(b);
1722         row = tab->mat->row[tab->con[r].index];
1723         isl_int_set_si(row[0], 1);
1724         isl_int_set(row[1], line[0]);
1725         isl_seq_clr(row + 2, tab->M + tab->n_col);
1726         for (i = 0; i < tab->n_var; ++i) {
1727                 if (tab->var[i].is_zero)
1728                         continue;
1729                 if (tab->var[i].is_row) {
1730                         isl_int_lcm(a,
1731                                 row[0], tab->mat->row[tab->var[i].index][0]);
1732                         isl_int_swap(a, row[0]);
1733                         isl_int_divexact(a, row[0], a);
1734                         isl_int_divexact(b,
1735                                 row[0], tab->mat->row[tab->var[i].index][0]);
1736                         isl_int_mul(b, b, line[1 + i]);
1737                         isl_seq_combine(row + 1, a, row + 1,
1738                             b, tab->mat->row[tab->var[i].index] + 1,
1739                             1 + tab->M + tab->n_col);
1740                 } else
1741                         isl_int_addmul(row[off + tab->var[i].index],
1742                                                         line[1 + i], row[0]);
1743                 if (tab->M && i >= tab->n_param && i < tab->n_var - tab->n_div)
1744                         isl_int_submul(row[2], line[1 + i], row[0]);
1745         }
1746         isl_seq_normalize(tab->mat->ctx, row, off + tab->n_col);
1747         isl_int_clear(a);
1748         isl_int_clear(b);
1749
1750         if (tab->row_sign)
1751                 tab->row_sign[tab->con[r].index] = isl_tab_row_unknown;
1752
1753         return r;
1754 }
1755
1756 static int drop_row(struct isl_tab *tab, int row)
1757 {
1758         isl_assert(tab->mat->ctx, ~tab->row_var[row] == tab->n_con - 1, return -1);
1759         if (row != tab->n_row - 1)
1760                 swap_rows(tab, row, tab->n_row - 1);
1761         tab->n_row--;
1762         tab->n_con--;
1763         return 0;
1764 }
1765
1766 static int drop_col(struct isl_tab *tab, int col)
1767 {
1768         isl_assert(tab->mat->ctx, tab->col_var[col] == tab->n_var - 1, return -1);
1769         if (col != tab->n_col - 1)
1770                 swap_cols(tab, col, tab->n_col - 1);
1771         tab->n_col--;
1772         tab->n_var--;
1773         return 0;
1774 }
1775
1776 /* Add inequality "ineq" and check if it conflicts with the
1777  * previously added constraints or if it is obviously redundant.
1778  */
1779 int isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq)
1780 {
1781         int r;
1782         int sgn;
1783         isl_int cst;
1784
1785         if (!tab)
1786                 return -1;
1787         if (tab->bmap) {
1788                 struct isl_basic_map *bmap = tab->bmap;
1789
1790                 isl_assert(tab->mat->ctx, tab->n_eq == bmap->n_eq, return -1);
1791                 isl_assert(tab->mat->ctx,
1792                             tab->n_con == bmap->n_eq + bmap->n_ineq, return -1);
1793                 tab->bmap = isl_basic_map_add_ineq(tab->bmap, ineq);
1794                 if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
1795                         return -1;
1796                 if (!tab->bmap)
1797                         return -1;
1798         }
1799         if (tab->cone) {
1800                 isl_int_init(cst);
1801                 isl_int_swap(ineq[0], cst);
1802         }
1803         r = isl_tab_add_row(tab, ineq);
1804         if (tab->cone) {
1805                 isl_int_swap(ineq[0], cst);
1806                 isl_int_clear(cst);
1807         }
1808         if (r < 0)
1809                 return -1;
1810         tab->con[r].is_nonneg = 1;
1811         if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
1812                 return -1;
1813         if (isl_tab_row_is_redundant(tab, tab->con[r].index)) {
1814                 if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
1815                         return -1;
1816                 return 0;
1817         }
1818
1819         sgn = restore_row(tab, &tab->con[r]);
1820         if (sgn < -1)
1821                 return -1;
1822         if (sgn < 0)
1823                 return isl_tab_mark_empty(tab);
1824         if (tab->con[r].is_row && isl_tab_row_is_redundant(tab, tab->con[r].index))
1825                 if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
1826                         return -1;
1827         return 0;
1828 }
1829
1830 /* Pivot a non-negative variable down until it reaches the value zero
1831  * and then pivot the variable into a column position.
1832  */
1833 static int to_col(struct isl_tab *tab, struct isl_tab_var *var) WARN_UNUSED;
1834 static int to_col(struct isl_tab *tab, struct isl_tab_var *var)
1835 {
1836         int i;
1837         int row, col;
1838         unsigned off = 2 + tab->M;
1839
1840         if (!var->is_row)
1841                 return 0;
1842
1843         while (isl_int_is_pos(tab->mat->row[var->index][1])) {
1844                 find_pivot(tab, var, NULL, -1, &row, &col);
1845                 isl_assert(tab->mat->ctx, row != -1, return -1);
1846                 if (isl_tab_pivot(tab, row, col) < 0)
1847                         return -1;
1848                 if (!var->is_row)
1849                         return 0;
1850         }
1851
1852         for (i = tab->n_dead; i < tab->n_col; ++i)
1853                 if (!isl_int_is_zero(tab->mat->row[var->index][off + i]))
1854                         break;
1855
1856         isl_assert(tab->mat->ctx, i < tab->n_col, return -1);
1857         if (isl_tab_pivot(tab, var->index, i) < 0)
1858                 return -1;
1859
1860         return 0;
1861 }
1862
1863 /* We assume Gaussian elimination has been performed on the equalities.
1864  * The equalities can therefore never conflict.
1865  * Adding the equalities is currently only really useful for a later call
1866  * to isl_tab_ineq_type.
1867  */
1868 static struct isl_tab *add_eq(struct isl_tab *tab, isl_int *eq)
1869 {
1870         int i;
1871         int r;
1872
1873         if (!tab)
1874                 return NULL;
1875         r = isl_tab_add_row(tab, eq);
1876         if (r < 0)
1877                 goto error;
1878
1879         r = tab->con[r].index;
1880         i = isl_seq_first_non_zero(tab->mat->row[r] + 2 + tab->M + tab->n_dead,
1881                                         tab->n_col - tab->n_dead);
1882         isl_assert(tab->mat->ctx, i >= 0, goto error);
1883         i += tab->n_dead;
1884         if (isl_tab_pivot(tab, r, i) < 0)
1885                 goto error;
1886         if (isl_tab_kill_col(tab, i) < 0)
1887                 goto error;
1888         tab->n_eq++;
1889
1890         return tab;
1891 error:
1892         isl_tab_free(tab);
1893         return NULL;
1894 }
1895
1896 static int row_is_manifestly_zero(struct isl_tab *tab, int row)
1897 {
1898         unsigned off = 2 + tab->M;
1899
1900         if (!isl_int_is_zero(tab->mat->row[row][1]))
1901                 return 0;
1902         if (tab->M && !isl_int_is_zero(tab->mat->row[row][2]))
1903                 return 0;
1904         return isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
1905                                         tab->n_col - tab->n_dead) == -1;
1906 }
1907
1908 /* Add an equality that is known to be valid for the given tableau.
1909  */
1910 int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq)
1911 {
1912         struct isl_tab_var *var;
1913         int r;
1914
1915         if (!tab)
1916                 return -1;
1917         r = isl_tab_add_row(tab, eq);
1918         if (r < 0)
1919                 return -1;
1920
1921         var = &tab->con[r];
1922         r = var->index;
1923         if (row_is_manifestly_zero(tab, r)) {
1924                 var->is_zero = 1;
1925                 if (isl_tab_mark_redundant(tab, r) < 0)
1926                         return -1;
1927                 return 0;
1928         }
1929
1930         if (isl_int_is_neg(tab->mat->row[r][1])) {
1931                 isl_seq_neg(tab->mat->row[r] + 1, tab->mat->row[r] + 1,
1932                             1 + tab->n_col);
1933                 var->negated = 1;
1934         }
1935         var->is_nonneg = 1;
1936         if (to_col(tab, var) < 0)
1937                 return -1;
1938         var->is_nonneg = 0;
1939         if (isl_tab_kill_col(tab, var->index) < 0)
1940                 return -1;
1941
1942         return 0;
1943 }
1944
1945 static int add_zero_row(struct isl_tab *tab)
1946 {
1947         int r;
1948         isl_int *row;
1949
1950         r = isl_tab_allocate_con(tab);
1951         if (r < 0)
1952                 return -1;
1953
1954         row = tab->mat->row[tab->con[r].index];
1955         isl_seq_clr(row + 1, 1 + tab->M + tab->n_col);
1956         isl_int_set_si(row[0], 1);
1957
1958         return r;
1959 }
1960
1961 /* Add equality "eq" and check if it conflicts with the
1962  * previously added constraints or if it is obviously redundant.
1963  */
1964 int isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
1965 {
1966         struct isl_tab_undo *snap = NULL;
1967         struct isl_tab_var *var;
1968         int r;
1969         int row;
1970         int sgn;
1971         isl_int cst;
1972
1973         if (!tab)
1974                 return -1;
1975         isl_assert(tab->mat->ctx, !tab->M, return -1);
1976
1977         if (tab->need_undo)
1978                 snap = isl_tab_snap(tab);
1979
1980         if (tab->cone) {
1981                 isl_int_init(cst);
1982                 isl_int_swap(eq[0], cst);
1983         }
1984         r = isl_tab_add_row(tab, eq);
1985         if (tab->cone) {
1986                 isl_int_swap(eq[0], cst);
1987                 isl_int_clear(cst);
1988         }
1989         if (r < 0)
1990                 return -1;
1991
1992         var = &tab->con[r];
1993         row = var->index;
1994         if (row_is_manifestly_zero(tab, row)) {
1995                 if (snap) {
1996                         if (isl_tab_rollback(tab, snap) < 0)
1997                                 return -1;
1998                 } else
1999                         drop_row(tab, row);
2000                 return 0;
2001         }
2002
2003         if (tab->bmap) {
2004                 tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
2005                 if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
2006                         return -1;
2007                 isl_seq_neg(eq, eq, 1 + tab->n_var);
2008                 tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
2009                 isl_seq_neg(eq, eq, 1 + tab->n_var);
2010                 if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
2011                         return -1;
2012                 if (!tab->bmap)
2013                         return -1;
2014                 if (add_zero_row(tab) < 0)
2015                         return -1;
2016         }
2017
2018         sgn = isl_int_sgn(tab->mat->row[row][1]);
2019
2020         if (sgn > 0) {
2021                 isl_seq_neg(tab->mat->row[row] + 1, tab->mat->row[row] + 1,
2022                             1 + tab->n_col);
2023                 var->negated = 1;
2024                 sgn = -1;
2025         }
2026
2027         if (sgn < 0) {
2028                 sgn = sign_of_max(tab, var);
2029                 if (sgn < -1)
2030                         return -1;
2031                 if (sgn < 0) {
2032                         if (isl_tab_mark_empty(tab) < 0)
2033                                 return -1;
2034                         return 0;
2035                 }
2036         }
2037
2038         var->is_nonneg = 1;
2039         if (to_col(tab, var) < 0)
2040                 return -1;
2041         var->is_nonneg = 0;
2042         if (isl_tab_kill_col(tab, var->index) < 0)
2043                 return -1;
2044
2045         return 0;
2046 }
2047
2048 /* Construct and return an inequality that expresses an upper bound
2049  * on the given div.
2050  * In particular, if the div is given by
2051  *
2052  *      d = floor(e/m)
2053  *
2054  * then the inequality expresses
2055  *
2056  *      m d <= e
2057  */
2058 static struct isl_vec *ineq_for_div(struct isl_basic_map *bmap, unsigned div)
2059 {
2060         unsigned total;
2061         unsigned div_pos;
2062         struct isl_vec *ineq;
2063
2064         if (!bmap)
2065                 return NULL;
2066
2067         total = isl_basic_map_total_dim(bmap);
2068         div_pos = 1 + total - bmap->n_div + div;
2069
2070         ineq = isl_vec_alloc(bmap->ctx, 1 + total);
2071         if (!ineq)
2072                 return NULL;
2073
2074         isl_seq_cpy(ineq->el, bmap->div[div] + 1, 1 + total);
2075         isl_int_neg(ineq->el[div_pos], bmap->div[div][0]);
2076         return ineq;
2077 }
2078
2079 /* For a div d = floor(f/m), add the constraints
2080  *
2081  *              f - m d >= 0
2082  *              -(f-(m-1)) + m d >= 0
2083  *
2084  * Note that the second constraint is the negation of
2085  *
2086  *              f - m d >= m
2087  *
2088  * If add_ineq is not NULL, then this function is used
2089  * instead of isl_tab_add_ineq to effectively add the inequalities.
2090  */
2091 static int add_div_constraints(struct isl_tab *tab, unsigned div,
2092         int (*add_ineq)(void *user, isl_int *), void *user)
2093 {
2094         unsigned total;
2095         unsigned div_pos;
2096         struct isl_vec *ineq;
2097
2098         total = isl_basic_map_total_dim(tab->bmap);
2099         div_pos = 1 + total - tab->bmap->n_div + div;
2100
2101         ineq = ineq_for_div(tab->bmap, div);
2102         if (!ineq)
2103                 goto error;
2104
2105         if (add_ineq) {
2106                 if (add_ineq(user, ineq->el) < 0)
2107                         goto error;
2108         } else {
2109                 if (isl_tab_add_ineq(tab, ineq->el) < 0)
2110                         goto error;
2111         }
2112
2113         isl_seq_neg(ineq->el, tab->bmap->div[div] + 1, 1 + total);
2114         isl_int_set(ineq->el[div_pos], tab->bmap->div[div][0]);
2115         isl_int_add(ineq->el[0], ineq->el[0], ineq->el[div_pos]);
2116         isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
2117
2118         if (add_ineq) {
2119                 if (add_ineq(user, ineq->el) < 0)
2120                         goto error;
2121         } else {
2122                 if (isl_tab_add_ineq(tab, ineq->el) < 0)
2123                         goto error;
2124         }
2125
2126         isl_vec_free(ineq);
2127
2128         return 0;
2129 error:
2130         isl_vec_free(ineq);
2131         return -1;
2132 }
2133
2134 /* Check whether the div described by "div" is obviously non-negative.
2135  * If we are using a big parameter, then we will encode the div
2136  * as div' = M + div, which is always non-negative.
2137  * Otherwise, we check whether div is a non-negative affine combination
2138  * of non-negative variables.
2139  */
2140 static int div_is_nonneg(struct isl_tab *tab, __isl_keep isl_vec *div)
2141 {
2142         int i;
2143
2144         if (tab->M)
2145                 return 1;
2146
2147         if (isl_int_is_neg(div->el[1]))
2148                 return 0;
2149
2150         for (i = 0; i < tab->n_var; ++i) {
2151                 if (isl_int_is_neg(div->el[2 + i]))
2152                         return 0;
2153                 if (isl_int_is_zero(div->el[2 + i]))
2154                         continue;
2155                 if (!tab->var[i].is_nonneg)
2156                         return 0;
2157         }
2158
2159         return 1;
2160 }
2161
2162 /* Add an extra div, prescribed by "div" to the tableau and
2163  * the associated bmap (which is assumed to be non-NULL).
2164  *
2165  * If add_ineq is not NULL, then this function is used instead
2166  * of isl_tab_add_ineq to add the div constraints.
2167  * This complication is needed because the code in isl_tab_pip
2168  * wants to perform some extra processing when an inequality
2169  * is added to the tableau.
2170  */
2171 int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div,
2172         int (*add_ineq)(void *user, isl_int *), void *user)
2173 {
2174         int r;
2175         int k;
2176         int nonneg;
2177
2178         if (!tab || !div)
2179                 return -1;
2180
2181         isl_assert(tab->mat->ctx, tab->bmap, return -1);
2182
2183         nonneg = div_is_nonneg(tab, div);
2184
2185         if (isl_tab_extend_cons(tab, 3) < 0)
2186                 return -1;
2187         if (isl_tab_extend_vars(tab, 1) < 0)
2188                 return -1;
2189         r = isl_tab_allocate_var(tab);
2190         if (r < 0)
2191                 return -1;
2192
2193         if (nonneg)
2194                 tab->var[r].is_nonneg = 1;
2195
2196         tab->bmap = isl_basic_map_extend_space(tab->bmap,
2197                 isl_basic_map_get_space(tab->bmap), 1, 0, 2);
2198         k = isl_basic_map_alloc_div(tab->bmap);
2199         if (k < 0)
2200                 return -1;
2201         isl_seq_cpy(tab->bmap->div[k], div->el, div->size);
2202         if (isl_tab_push(tab, isl_tab_undo_bmap_div) < 0)
2203                 return -1;
2204
2205         if (add_div_constraints(tab, k, add_ineq, user) < 0)
2206                 return -1;
2207
2208         return r;
2209 }
2210
2211 /* If "track" is set, then we want to keep track of all constraints in tab
2212  * in its bmap field.  This field is initialized from a copy of "bmap",
2213  * so we need to make sure that all constraints in "bmap" also appear
2214  * in the constructed tab.
2215  */
2216 __isl_give struct isl_tab *isl_tab_from_basic_map(
2217         __isl_keep isl_basic_map *bmap, int track)
2218 {
2219         int i;
2220         struct isl_tab *tab;
2221
2222         if (!bmap)
2223                 return NULL;
2224         tab = isl_tab_alloc(bmap->ctx,
2225                             isl_basic_map_total_dim(bmap) + bmap->n_ineq + 1,
2226                             isl_basic_map_total_dim(bmap), 0);
2227         if (!tab)
2228                 return NULL;
2229         tab->preserve = track;
2230         tab->rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
2231         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY)) {
2232                 if (isl_tab_mark_empty(tab) < 0)
2233                         goto error;
2234                 goto done;
2235         }
2236         for (i = 0; i < bmap->n_eq; ++i) {
2237                 tab = add_eq(tab, bmap->eq[i]);
2238                 if (!tab)
2239                         return tab;
2240         }
2241         for (i = 0; i < bmap->n_ineq; ++i) {
2242                 if (isl_tab_add_ineq(tab, bmap->ineq[i]) < 0)
2243                         goto error;
2244                 if (tab->empty)
2245                         goto done;
2246         }
2247 done:
2248         if (track && isl_tab_track_bmap(tab, isl_basic_map_copy(bmap)) < 0)
2249                 goto error;
2250         return tab;
2251 error:
2252         isl_tab_free(tab);
2253         return NULL;
2254 }
2255
2256 __isl_give struct isl_tab *isl_tab_from_basic_set(
2257         __isl_keep isl_basic_set *bset, int track)
2258 {
2259         return isl_tab_from_basic_map(bset, track);
2260 }
2261
2262 /* Construct a tableau corresponding to the recession cone of "bset".
2263  */
2264 struct isl_tab *isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset,
2265         int parametric)
2266 {
2267         isl_int cst;
2268         int i;
2269         struct isl_tab *tab;
2270         unsigned offset = 0;
2271
2272         if (!bset)
2273                 return NULL;
2274         if (parametric)
2275                 offset = isl_basic_set_dim(bset, isl_dim_param);
2276         tab = isl_tab_alloc(bset->ctx, bset->n_eq + bset->n_ineq,
2277                                 isl_basic_set_total_dim(bset) - offset, 0);
2278         if (!tab)
2279                 return NULL;
2280         tab->rational = ISL_F_ISSET(bset, ISL_BASIC_SET_RATIONAL);
2281         tab->cone = 1;
2282
2283         isl_int_init(cst);
2284         for (i = 0; i < bset->n_eq; ++i) {
2285                 isl_int_swap(bset->eq[i][offset], cst);
2286                 if (offset > 0) {
2287                         if (isl_tab_add_eq(tab, bset->eq[i] + offset) < 0)
2288                                 goto error;
2289                 } else
2290                         tab = add_eq(tab, bset->eq[i]);
2291                 isl_int_swap(bset->eq[i][offset], cst);
2292                 if (!tab)
2293                         goto done;
2294         }
2295         for (i = 0; i < bset->n_ineq; ++i) {
2296                 int r;
2297                 isl_int_swap(bset->ineq[i][offset], cst);
2298                 r = isl_tab_add_row(tab, bset->ineq[i] + offset);
2299                 isl_int_swap(bset->ineq[i][offset], cst);
2300                 if (r < 0)
2301                         goto error;
2302                 tab->con[r].is_nonneg = 1;
2303                 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
2304                         goto error;
2305         }
2306 done:
2307         isl_int_clear(cst);
2308         return tab;
2309 error:
2310         isl_int_clear(cst);
2311         isl_tab_free(tab);
2312         return NULL;
2313 }
2314
2315 /* Assuming "tab" is the tableau of a cone, check if the cone is
2316  * bounded, i.e., if it is empty or only contains the origin.
2317  */
2318 int isl_tab_cone_is_bounded(struct isl_tab *tab)
2319 {
2320         int i;
2321
2322         if (!tab)
2323                 return -1;
2324         if (tab->empty)
2325                 return 1;
2326         if (tab->n_dead == tab->n_col)
2327                 return 1;
2328
2329         for (;;) {
2330                 for (i = tab->n_redundant; i < tab->n_row; ++i) {
2331                         struct isl_tab_var *var;
2332                         int sgn;
2333                         var = isl_tab_var_from_row(tab, i);
2334                         if (!var->is_nonneg)
2335                                 continue;
2336                         sgn = sign_of_max(tab, var);
2337                         if (sgn < -1)
2338                                 return -1;
2339                         if (sgn != 0)
2340                                 return 0;
2341                         if (close_row(tab, var) < 0)
2342                                 return -1;
2343                         break;
2344                 }
2345                 if (tab->n_dead == tab->n_col)
2346                         return 1;
2347                 if (i == tab->n_row)
2348                         return 0;
2349         }
2350 }
2351
2352 int isl_tab_sample_is_integer(struct isl_tab *tab)
2353 {
2354         int i;
2355
2356         if (!tab)
2357                 return -1;
2358
2359         for (i = 0; i < tab->n_var; ++i) {
2360                 int row;
2361                 if (!tab->var[i].is_row)
2362                         continue;
2363                 row = tab->var[i].index;
2364                 if (!isl_int_is_divisible_by(tab->mat->row[row][1],
2365                                                 tab->mat->row[row][0]))
2366                         return 0;
2367         }
2368         return 1;
2369 }
2370
2371 static struct isl_vec *extract_integer_sample(struct isl_tab *tab)
2372 {
2373         int i;
2374         struct isl_vec *vec;
2375
2376         vec = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var);
2377         if (!vec)
2378                 return NULL;
2379
2380         isl_int_set_si(vec->block.data[0], 1);
2381         for (i = 0; i < tab->n_var; ++i) {
2382                 if (!tab->var[i].is_row)
2383                         isl_int_set_si(vec->block.data[1 + i], 0);
2384                 else {
2385                         int row = tab->var[i].index;
2386                         isl_int_divexact(vec->block.data[1 + i],
2387                                 tab->mat->row[row][1], tab->mat->row[row][0]);
2388                 }
2389         }
2390
2391         return vec;
2392 }
2393
2394 struct isl_vec *isl_tab_get_sample_value(struct isl_tab *tab)
2395 {
2396         int i;
2397         struct isl_vec *vec;
2398         isl_int m;
2399
2400         if (!tab)
2401                 return NULL;
2402
2403         vec = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var);
2404         if (!vec)
2405                 return NULL;
2406
2407         isl_int_init(m);
2408
2409         isl_int_set_si(vec->block.data[0], 1);
2410         for (i = 0; i < tab->n_var; ++i) {
2411                 int row;
2412                 if (!tab->var[i].is_row) {
2413                         isl_int_set_si(vec->block.data[1 + i], 0);
2414                         continue;
2415                 }
2416                 row = tab->var[i].index;
2417                 isl_int_gcd(m, vec->block.data[0], tab->mat->row[row][0]);
2418                 isl_int_divexact(m, tab->mat->row[row][0], m);
2419                 isl_seq_scale(vec->block.data, vec->block.data, m, 1 + i);
2420                 isl_int_divexact(m, vec->block.data[0], tab->mat->row[row][0]);
2421                 isl_int_mul(vec->block.data[1 + i], m, tab->mat->row[row][1]);
2422         }
2423         vec = isl_vec_normalize(vec);
2424
2425         isl_int_clear(m);
2426         return vec;
2427 }
2428
2429 /* Update "bmap" based on the results of the tableau "tab".
2430  * In particular, implicit equalities are made explicit, redundant constraints
2431  * are removed and if the sample value happens to be integer, it is stored
2432  * in "bmap" (unless "bmap" already had an integer sample).
2433  *
2434  * The tableau is assumed to have been created from "bmap" using
2435  * isl_tab_from_basic_map.
2436  */
2437 struct isl_basic_map *isl_basic_map_update_from_tab(struct isl_basic_map *bmap,
2438         struct isl_tab *tab)
2439 {
2440         int i;
2441         unsigned n_eq;
2442
2443         if (!bmap)
2444                 return NULL;
2445         if (!tab)
2446                 return bmap;
2447
2448         n_eq = tab->n_eq;
2449         if (tab->empty)
2450                 bmap = isl_basic_map_set_to_empty(bmap);
2451         else
2452                 for (i = bmap->n_ineq - 1; i >= 0; --i) {
2453                         if (isl_tab_is_equality(tab, n_eq + i))
2454                                 isl_basic_map_inequality_to_equality(bmap, i);
2455                         else if (isl_tab_is_redundant(tab, n_eq + i))
2456                                 isl_basic_map_drop_inequality(bmap, i);
2457                 }
2458         if (bmap->n_eq != n_eq)
2459                 isl_basic_map_gauss(bmap, NULL);
2460         if (!tab->rational &&
2461             !bmap->sample && isl_tab_sample_is_integer(tab))
2462                 bmap->sample = extract_integer_sample(tab);
2463         return bmap;
2464 }
2465
2466 struct isl_basic_set *isl_basic_set_update_from_tab(struct isl_basic_set *bset,
2467         struct isl_tab *tab)
2468 {
2469         return (struct isl_basic_set *)isl_basic_map_update_from_tab(
2470                 (struct isl_basic_map *)bset, tab);
2471 }
2472
2473 /* Given a non-negative variable "var", add a new non-negative variable
2474  * that is the opposite of "var", ensuring that var can only attain the
2475  * value zero.
2476  * If var = n/d is a row variable, then the new variable = -n/d.
2477  * If var is a column variables, then the new variable = -var.
2478  * If the new variable cannot attain non-negative values, then
2479  * the resulting tableau is empty.
2480  * Otherwise, we know the value will be zero and we close the row.
2481  */
2482 static int cut_to_hyperplane(struct isl_tab *tab, struct isl_tab_var *var)
2483 {
2484         unsigned r;
2485         isl_int *row;
2486         int sgn;
2487         unsigned off = 2 + tab->M;
2488
2489         if (var->is_zero)
2490                 return 0;
2491         isl_assert(tab->mat->ctx, !var->is_redundant, return -1);
2492         isl_assert(tab->mat->ctx, var->is_nonneg, return -1);
2493
2494         if (isl_tab_extend_cons(tab, 1) < 0)
2495                 return -1;
2496
2497         r = tab->n_con;
2498         tab->con[r].index = tab->n_row;
2499         tab->con[r].is_row = 1;
2500         tab->con[r].is_nonneg = 0;
2501         tab->con[r].is_zero = 0;
2502         tab->con[r].is_redundant = 0;
2503         tab->con[r].frozen = 0;
2504         tab->con[r].negated = 0;
2505         tab->row_var[tab->n_row] = ~r;
2506         row = tab->mat->row[tab->n_row];
2507
2508         if (var->is_row) {
2509                 isl_int_set(row[0], tab->mat->row[var->index][0]);
2510                 isl_seq_neg(row + 1,
2511                             tab->mat->row[var->index] + 1, 1 + tab->n_col);
2512         } else {
2513                 isl_int_set_si(row[0], 1);
2514                 isl_seq_clr(row + 1, 1 + tab->n_col);
2515                 isl_int_set_si(row[off + var->index], -1);
2516         }
2517
2518         tab->n_row++;
2519         tab->n_con++;
2520         if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->con[r]) < 0)
2521                 return -1;
2522
2523         sgn = sign_of_max(tab, &tab->con[r]);
2524         if (sgn < -1)
2525                 return -1;
2526         if (sgn < 0) {
2527                 if (isl_tab_mark_empty(tab) < 0)
2528                         return -1;
2529                 return 0;
2530         }
2531         tab->con[r].is_nonneg = 1;
2532         if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
2533                 return -1;
2534         /* sgn == 0 */
2535         if (close_row(tab, &tab->con[r]) < 0)
2536                 return -1;
2537
2538         return 0;
2539 }
2540
2541 /* Given a tableau "tab" and an inequality constraint "con" of the tableau,
2542  * relax the inequality by one.  That is, the inequality r >= 0 is replaced
2543  * by r' = r + 1 >= 0.
2544  * If r is a row variable, we simply increase the constant term by one
2545  * (taking into account the denominator).
2546  * If r is a column variable, then we need to modify each row that
2547  * refers to r = r' - 1 by substituting this equality, effectively
2548  * subtracting the coefficient of the column from the constant.
2549  * We should only do this if the minimum is manifestly unbounded,
2550  * however.  Otherwise, we may end up with negative sample values
2551  * for non-negative variables.
2552  * So, if r is a column variable with a minimum that is not
2553  * manifestly unbounded, then we need to move it to a row.
2554  * However, the sample value of this row may be negative,
2555  * even after the relaxation, so we need to restore it.
2556  * We therefore prefer to pivot a column up to a row, if possible.
2557  */
2558 struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con)
2559 {
2560         struct isl_tab_var *var;
2561         unsigned off = 2 + tab->M;
2562
2563         if (!tab)
2564                 return NULL;
2565
2566         var = &tab->con[con];
2567
2568         if (var->is_row && (var->index < 0 || var->index < tab->n_redundant))
2569                 isl_die(tab->mat->ctx, isl_error_invalid,
2570                         "cannot relax redundant constraint", goto error);
2571         if (!var->is_row && (var->index < 0 || var->index < tab->n_dead))
2572                 isl_die(tab->mat->ctx, isl_error_invalid,
2573                         "cannot relax dead constraint", goto error);
2574
2575         if (!var->is_row && !max_is_manifestly_unbounded(tab, var))
2576                 if (to_row(tab, var, 1) < 0)
2577                         goto error;
2578         if (!var->is_row && !min_is_manifestly_unbounded(tab, var))
2579                 if (to_row(tab, var, -1) < 0)
2580                         goto error;
2581
2582         if (var->is_row) {
2583                 isl_int_add(tab->mat->row[var->index][1],
2584                     tab->mat->row[var->index][1], tab->mat->row[var->index][0]);
2585                 if (restore_row(tab, var) < 0)
2586                         goto error;
2587         } else {
2588                 int i;
2589
2590                 for (i = 0; i < tab->n_row; ++i) {
2591                         if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
2592                                 continue;
2593                         isl_int_sub(tab->mat->row[i][1], tab->mat->row[i][1],
2594                             tab->mat->row[i][off + var->index]);
2595                 }
2596
2597         }
2598
2599         if (isl_tab_push_var(tab, isl_tab_undo_relax, var) < 0)
2600                 goto error;
2601
2602         return tab;
2603 error:
2604         isl_tab_free(tab);
2605         return NULL;
2606 }
2607
2608 /* Remove the sign constraint from constraint "con".
2609  *
2610  * If the constraint variable was originally marked non-negative,
2611  * then we make sure we mark it non-negative again during rollback.
2612  */
2613 int isl_tab_unrestrict(struct isl_tab *tab, int con)
2614 {
2615         struct isl_tab_var *var;
2616
2617         if (!tab)
2618                 return -1;
2619
2620         var = &tab->con[con];
2621         if (!var->is_nonneg)
2622                 return 0;
2623
2624         var->is_nonneg = 0;
2625         if (isl_tab_push_var(tab, isl_tab_undo_unrestrict, var) < 0)
2626                 return -1;
2627
2628         return 0;
2629 }
2630
2631 int isl_tab_select_facet(struct isl_tab *tab, int con)
2632 {
2633         if (!tab)
2634                 return -1;
2635
2636         return cut_to_hyperplane(tab, &tab->con[con]);
2637 }
2638
2639 static int may_be_equality(struct isl_tab *tab, int row)
2640 {
2641         return tab->rational ? isl_int_is_zero(tab->mat->row[row][1])
2642                              : isl_int_lt(tab->mat->row[row][1],
2643                                             tab->mat->row[row][0]);
2644 }
2645
2646 /* Check for (near) equalities among the constraints.
2647  * A constraint is an equality if it is non-negative and if
2648  * its maximal value is either
2649  *      - zero (in case of rational tableaus), or
2650  *      - strictly less than 1 (in case of integer tableaus)
2651  *
2652  * We first mark all non-redundant and non-dead variables that
2653  * are not frozen and not obviously not an equality.
2654  * Then we iterate over all marked variables if they can attain
2655  * any values larger than zero or at least one.
2656  * If the maximal value is zero, we mark any column variables
2657  * that appear in the row as being zero and mark the row as being redundant.
2658  * Otherwise, if the maximal value is strictly less than one (and the
2659  * tableau is integer), then we restrict the value to being zero
2660  * by adding an opposite non-negative variable.
2661  */
2662 int isl_tab_detect_implicit_equalities(struct isl_tab *tab)
2663 {
2664         int i;
2665         unsigned n_marked;
2666
2667         if (!tab)
2668                 return -1;
2669         if (tab->empty)
2670                 return 0;
2671         if (tab->n_dead == tab->n_col)
2672                 return 0;
2673
2674         n_marked = 0;
2675         for (i = tab->n_redundant; i < tab->n_row; ++i) {
2676                 struct isl_tab_var *var = isl_tab_var_from_row(tab, i);
2677                 var->marked = !var->frozen && var->is_nonneg &&
2678                         may_be_equality(tab, i);
2679                 if (var->marked)
2680                         n_marked++;
2681         }
2682         for (i = tab->n_dead; i < tab->n_col; ++i) {
2683                 struct isl_tab_var *var = var_from_col(tab, i);
2684                 var->marked = !var->frozen && var->is_nonneg;
2685                 if (var->marked)
2686                         n_marked++;
2687         }
2688         while (n_marked) {
2689                 struct isl_tab_var *var;
2690                 int sgn;
2691                 for (i = tab->n_redundant; i < tab->n_row; ++i) {
2692                         var = isl_tab_var_from_row(tab, i);
2693                         if (var->marked)
2694                                 break;
2695                 }
2696                 if (i == tab->n_row) {
2697                         for (i = tab->n_dead; i < tab->n_col; ++i) {
2698                                 var = var_from_col(tab, i);
2699                                 if (var->marked)
2700                                         break;
2701                         }
2702                         if (i == tab->n_col)
2703                                 break;
2704                 }
2705                 var->marked = 0;
2706                 n_marked--;
2707                 sgn = sign_of_max(tab, var);
2708                 if (sgn < 0)
2709                         return -1;
2710                 if (sgn == 0) {
2711                         if (close_row(tab, var) < 0)
2712                                 return -1;
2713                 } else if (!tab->rational && !at_least_one(tab, var)) {
2714                         if (cut_to_hyperplane(tab, var) < 0)
2715                                 return -1;
2716                         return isl_tab_detect_implicit_equalities(tab);
2717                 }
2718                 for (i = tab->n_redundant; i < tab->n_row; ++i) {
2719                         var = isl_tab_var_from_row(tab, i);
2720                         if (!var->marked)
2721                                 continue;
2722                         if (may_be_equality(tab, i))
2723                                 continue;
2724                         var->marked = 0;
2725                         n_marked--;
2726                 }
2727         }
2728
2729         return 0;
2730 }
2731
2732 /* Update the element of row_var or col_var that corresponds to
2733  * constraint tab->con[i] to a move from position "old" to position "i".
2734  */
2735 static int update_con_after_move(struct isl_tab *tab, int i, int old)
2736 {
2737         int *p;
2738         int index;
2739
2740         index = tab->con[i].index;
2741         if (index == -1)
2742                 return 0;
2743         p = tab->con[i].is_row ? tab->row_var : tab->col_var;
2744         if (p[index] != ~old)
2745                 isl_die(tab->mat->ctx, isl_error_internal,
2746                         "broken internal state", return -1);
2747         p[index] = ~i;
2748
2749         return 0;
2750 }
2751
2752 /* Rotate the "n" constraints starting at "first" to the right,
2753  * putting the last constraint in the position of the first constraint.
2754  */
2755 static int rotate_constraints(struct isl_tab *tab, int first, int n)
2756 {
2757         int i, last;
2758         struct isl_tab_var var;
2759
2760         if (n <= 1)
2761                 return 0;
2762
2763         last = first + n - 1;
2764         var = tab->con[last];
2765         for (i = last; i > first; --i) {
2766                 tab->con[i] = tab->con[i - 1];
2767                 if (update_con_after_move(tab, i, i - 1) < 0)
2768                         return -1;
2769         }
2770         tab->con[first] = var;
2771         if (update_con_after_move(tab, first, last) < 0)
2772                 return -1;
2773
2774         return 0;
2775 }
2776
2777 /* Make the equalities that are implicit in "bmap" but that have been
2778  * detected in the corresponding "tab" explicit in "bmap" and update
2779  * "tab" to reflect the new order of the constraints.
2780  *
2781  * In particular, if inequality i is an implicit equality then
2782  * isl_basic_map_inequality_to_equality will move the inequality
2783  * in front of the other equality and it will move the last inequality
2784  * in the position of inequality i.
2785  * In the tableau, the inequalities of "bmap" are stored after the equalities
2786  * and so the original order
2787  *
2788  *              E E E E E A A A I B B B B L
2789  *
2790  * is changed into
2791  *
2792  *              I E E E E E A A A L B B B B
2793  *
2794  * where I is the implicit equality, the E are equalities,
2795  * the A inequalities before I, the B inequalities after I and
2796  * L the last inequality.
2797  * We therefore need to rotate to the right two sets of constraints,
2798  * those up to and including I and those after I.
2799  *
2800  * If "tab" contains any constraints that are not in "bmap" then they
2801  * appear after those in "bmap" and they should be left untouched.
2802  *
2803  * Note that this function leaves "bmap" in a temporary state
2804  * as it does not call isl_basic_map_gauss.  Calling this function
2805  * is the responsibility of the caller.
2806  */
2807 __isl_give isl_basic_map *isl_tab_make_equalities_explicit(struct isl_tab *tab,
2808         __isl_take isl_basic_map *bmap)
2809 {
2810         int i;
2811
2812         if (!tab || !bmap)
2813                 return isl_basic_map_free(bmap);
2814         if (tab->empty)
2815                 return bmap;
2816
2817         for (i = bmap->n_ineq - 1; i >= 0; --i) {
2818                 if (!isl_tab_is_equality(tab, bmap->n_eq + i))
2819                         continue;
2820                 isl_basic_map_inequality_to_equality(bmap, i);
2821                 if (rotate_constraints(tab, 0, tab->n_eq + i + 1) < 0)
2822                         return isl_basic_map_free(bmap);
2823                 if (rotate_constraints(tab, tab->n_eq + i + 1,
2824                                         bmap->n_ineq - i) < 0)
2825                         return isl_basic_map_free(bmap);
2826                 tab->n_eq++;
2827         }
2828
2829         return bmap;
2830 }
2831
2832 static int con_is_redundant(struct isl_tab *tab, struct isl_tab_var *var)
2833 {
2834         if (!tab)
2835                 return -1;
2836         if (tab->rational) {
2837                 int sgn = sign_of_min(tab, var);
2838                 if (sgn < -1)
2839                         return -1;
2840                 return sgn >= 0;
2841         } else {
2842                 int irred = isl_tab_min_at_most_neg_one(tab, var);
2843                 if (irred < 0)
2844                         return -1;
2845                 return !irred;
2846         }
2847 }
2848
2849 /* Check for (near) redundant constraints.
2850  * A constraint is redundant if it is non-negative and if
2851  * its minimal value (temporarily ignoring the non-negativity) is either
2852  *      - zero (in case of rational tableaus), or
2853  *      - strictly larger than -1 (in case of integer tableaus)
2854  *
2855  * We first mark all non-redundant and non-dead variables that
2856  * are not frozen and not obviously negatively unbounded.
2857  * Then we iterate over all marked variables if they can attain
2858  * any values smaller than zero or at most negative one.
2859  * If not, we mark the row as being redundant (assuming it hasn't
2860  * been detected as being obviously redundant in the mean time).
2861  */
2862 int isl_tab_detect_redundant(struct isl_tab *tab)
2863 {
2864         int i;
2865         unsigned n_marked;
2866
2867         if (!tab)
2868                 return -1;
2869         if (tab->empty)
2870                 return 0;
2871         if (tab->n_redundant == tab->n_row)
2872                 return 0;
2873
2874         n_marked = 0;
2875         for (i = tab->n_redundant; i < tab->n_row; ++i) {
2876                 struct isl_tab_var *var = isl_tab_var_from_row(tab, i);
2877                 var->marked = !var->frozen && var->is_nonneg;
2878                 if (var->marked)
2879                         n_marked++;
2880         }
2881         for (i = tab->n_dead; i < tab->n_col; ++i) {
2882                 struct isl_tab_var *var = var_from_col(tab, i);
2883                 var->marked = !var->frozen && var->is_nonneg &&
2884                         !min_is_manifestly_unbounded(tab, var);
2885                 if (var->marked)
2886                         n_marked++;
2887         }
2888         while (n_marked) {
2889                 struct isl_tab_var *var;
2890                 int red;
2891                 for (i = tab->n_redundant; i < tab->n_row; ++i) {
2892                         var = isl_tab_var_from_row(tab, i);
2893                         if (var->marked)
2894                                 break;
2895                 }
2896                 if (i == tab->n_row) {
2897                         for (i = tab->n_dead; i < tab->n_col; ++i) {
2898                                 var = var_from_col(tab, i);
2899                                 if (var->marked)
2900                                         break;
2901                         }
2902                         if (i == tab->n_col)
2903                                 break;
2904                 }
2905                 var->marked = 0;
2906                 n_marked--;
2907                 red = con_is_redundant(tab, var);
2908                 if (red < 0)
2909                         return -1;
2910                 if (red && !var->is_redundant)
2911                         if (isl_tab_mark_redundant(tab, var->index) < 0)
2912                                 return -1;
2913                 for (i = tab->n_dead; i < tab->n_col; ++i) {
2914                         var = var_from_col(tab, i);
2915                         if (!var->marked)
2916                                 continue;
2917                         if (!min_is_manifestly_unbounded(tab, var))
2918                                 continue;
2919                         var->marked = 0;
2920                         n_marked--;
2921                 }
2922         }
2923
2924         return 0;
2925 }
2926
2927 int isl_tab_is_equality(struct isl_tab *tab, int con)
2928 {
2929         int row;
2930         unsigned off;
2931
2932         if (!tab)
2933                 return -1;
2934         if (tab->con[con].is_zero)
2935                 return 1;
2936         if (tab->con[con].is_redundant)
2937                 return 0;
2938         if (!tab->con[con].is_row)
2939                 return tab->con[con].index < tab->n_dead;
2940
2941         row = tab->con[con].index;
2942
2943         off = 2 + tab->M;
2944         return isl_int_is_zero(tab->mat->row[row][1]) &&
2945                 (!tab->M || isl_int_is_zero(tab->mat->row[row][2])) &&
2946                 isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
2947                                         tab->n_col - tab->n_dead) == -1;
2948 }
2949
2950 /* Return the minimal value of the affine expression "f" with denominator
2951  * "denom" in *opt, *opt_denom, assuming the tableau is not empty and
2952  * the expression cannot attain arbitrarily small values.
2953  * If opt_denom is NULL, then *opt is rounded up to the nearest integer.
2954  * The return value reflects the nature of the result (empty, unbounded,
2955  * minimal value returned in *opt).
2956  */
2957 enum isl_lp_result isl_tab_min(struct isl_tab *tab,
2958         isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom,
2959         unsigned flags)
2960 {
2961         int r;
2962         enum isl_lp_result res = isl_lp_ok;
2963         struct isl_tab_var *var;
2964         struct isl_tab_undo *snap;
2965
2966         if (!tab)
2967                 return isl_lp_error;
2968
2969         if (tab->empty)
2970                 return isl_lp_empty;
2971
2972         snap = isl_tab_snap(tab);
2973         r = isl_tab_add_row(tab, f);
2974         if (r < 0)
2975                 return isl_lp_error;
2976         var = &tab->con[r];
2977         for (;;) {
2978                 int row, col;
2979                 find_pivot(tab, var, var, -1, &row, &col);
2980                 if (row == var->index) {
2981                         res = isl_lp_unbounded;
2982                         break;
2983                 }
2984                 if (row == -1)
2985                         break;
2986                 if (isl_tab_pivot(tab, row, col) < 0)
2987                         return isl_lp_error;
2988         }
2989         isl_int_mul(tab->mat->row[var->index][0],
2990                     tab->mat->row[var->index][0], denom);
2991         if (ISL_FL_ISSET(flags, ISL_TAB_SAVE_DUAL)) {
2992                 int i;
2993
2994                 isl_vec_free(tab->dual);
2995                 tab->dual = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_con);
2996                 if (!tab->dual)
2997                         return isl_lp_error;
2998                 isl_int_set(tab->dual->el[0], tab->mat->row[var->index][0]);
2999                 for (i = 0; i < tab->n_con; ++i) {
3000                         int pos;
3001                         if (tab->con[i].is_row) {
3002                                 isl_int_set_si(tab->dual->el[1 + i], 0);
3003                                 continue;
3004                         }
3005                         pos = 2 + tab->M + tab->con[i].index;
3006                         if (tab->con[i].negated)
3007                                 isl_int_neg(tab->dual->el[1 + i],
3008                                             tab->mat->row[var->index][pos]);
3009                         else
3010                                 isl_int_set(tab->dual->el[1 + i],
3011                                             tab->mat->row[var->index][pos]);
3012                 }
3013         }
3014         if (opt && res == isl_lp_ok) {
3015                 if (opt_denom) {
3016                         isl_int_set(*opt, tab->mat->row[var->index][1]);
3017                         isl_int_set(*opt_denom, tab->mat->row[var->index][0]);
3018                 } else
3019                         isl_int_cdiv_q(*opt, tab->mat->row[var->index][1],
3020                                              tab->mat->row[var->index][0]);
3021         }
3022         if (isl_tab_rollback(tab, snap) < 0)
3023                 return isl_lp_error;
3024         return res;
3025 }
3026
3027 int isl_tab_is_redundant(struct isl_tab *tab, int con)
3028 {
3029         if (!tab)
3030                 return -1;
3031         if (tab->con[con].is_zero)
3032                 return 0;
3033         if (tab->con[con].is_redundant)
3034                 return 1;
3035         return tab->con[con].is_row && tab->con[con].index < tab->n_redundant;
3036 }
3037
3038 /* Take a snapshot of the tableau that can be restored by s call to
3039  * isl_tab_rollback.
3040  */
3041 struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab)
3042 {
3043         if (!tab)
3044                 return NULL;
3045         tab->need_undo = 1;
3046         return tab->top;
3047 }
3048
3049 /* Undo the operation performed by isl_tab_relax.
3050  */
3051 static int unrelax(struct isl_tab *tab, struct isl_tab_var *var) WARN_UNUSED;
3052 static int unrelax(struct isl_tab *tab, struct isl_tab_var *var)
3053 {
3054         unsigned off = 2 + tab->M;
3055
3056         if (!var->is_row && !max_is_manifestly_unbounded(tab, var))
3057                 if (to_row(tab, var, 1) < 0)
3058                         return -1;
3059
3060         if (var->is_row) {
3061                 isl_int_sub(tab->mat->row[var->index][1],
3062                     tab->mat->row[var->index][1], tab->mat->row[var->index][0]);
3063                 if (var->is_nonneg) {
3064                         int sgn = restore_row(tab, var);
3065                         isl_assert(tab->mat->ctx, sgn >= 0, return -1);
3066                 }
3067         } else {
3068                 int i;
3069
3070                 for (i = 0; i < tab->n_row; ++i) {
3071                         if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
3072                                 continue;
3073                         isl_int_add(tab->mat->row[i][1], tab->mat->row[i][1],
3074                             tab->mat->row[i][off + var->index]);
3075                 }
3076
3077         }
3078
3079         return 0;
3080 }
3081
3082 /* Undo the operation performed by isl_tab_unrestrict.
3083  *
3084  * In particular, mark the variable as being non-negative and make
3085  * sure the sample value respects this constraint.
3086  */
3087 static int ununrestrict(struct isl_tab *tab, struct isl_tab_var *var)
3088 {
3089         var->is_nonneg = 1;
3090
3091         if (var->is_row && restore_row(tab, var) < -1)
3092                 return -1;
3093
3094         return 0;
3095 }
3096
3097 static int perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo) WARN_UNUSED;
3098 static int perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo)
3099 {
3100         struct isl_tab_var *var = var_from_index(tab, undo->u.var_index);
3101         switch (undo->type) {
3102         case isl_tab_undo_nonneg:
3103                 var->is_nonneg = 0;
3104                 break;
3105         case isl_tab_undo_redundant:
3106                 var->is_redundant = 0;
3107                 tab->n_redundant--;
3108                 restore_row(tab, isl_tab_var_from_row(tab, tab->n_redundant));
3109                 break;
3110         case isl_tab_undo_freeze:
3111                 var->frozen = 0;
3112                 break;
3113         case isl_tab_undo_zero:
3114                 var->is_zero = 0;
3115                 if (!var->is_row)
3116                         tab->n_dead--;
3117                 break;
3118         case isl_tab_undo_allocate:
3119                 if (undo->u.var_index >= 0) {
3120                         isl_assert(tab->mat->ctx, !var->is_row, return -1);
3121                         drop_col(tab, var->index);
3122                         break;
3123                 }
3124                 if (!var->is_row) {
3125                         if (!max_is_manifestly_unbounded(tab, var)) {
3126                                 if (to_row(tab, var, 1) < 0)
3127                                         return -1;
3128                         } else if (!min_is_manifestly_unbounded(tab, var)) {
3129                                 if (to_row(tab, var, -1) < 0)
3130                                         return -1;
3131                         } else
3132                                 if (to_row(tab, var, 0) < 0)
3133                                         return -1;
3134                 }
3135                 drop_row(tab, var->index);
3136                 break;
3137         case isl_tab_undo_relax:
3138                 return unrelax(tab, var);
3139         case isl_tab_undo_unrestrict:
3140                 return ununrestrict(tab, var);
3141         default:
3142                 isl_die(tab->mat->ctx, isl_error_internal,
3143                         "perform_undo_var called on invalid undo record",
3144                         return -1);
3145         }
3146
3147         return 0;
3148 }
3149
3150 /* Restore the tableau to the state where the basic variables
3151  * are those in "col_var".
3152  * We first construct a list of variables that are currently in
3153  * the basis, but shouldn't.  Then we iterate over all variables
3154  * that should be in the basis and for each one that is currently
3155  * not in the basis, we exchange it with one of the elements of the
3156  * list constructed before.
3157  * We can always find an appropriate variable to pivot with because
3158  * the current basis is mapped to the old basis by a non-singular
3159  * matrix and so we can never end up with a zero row.
3160  */
3161 static int restore_basis(struct isl_tab *tab, int *col_var)
3162 {
3163         int i, j;
3164         int n_extra = 0;
3165         int *extra = NULL;      /* current columns that contain bad stuff */
3166         unsigned off = 2 + tab->M;
3167
3168         extra = isl_alloc_array(tab->mat->ctx, int, tab->n_col);
3169         if (!extra)
3170                 goto error;
3171         for (i = 0; i < tab->n_col; ++i) {
3172                 for (j = 0; j < tab->n_col; ++j)
3173                         if (tab->col_var[i] == col_var[j])
3174                                 break;
3175                 if (j < tab->n_col)
3176                         continue;
3177                 extra[n_extra++] = i;
3178         }
3179         for (i = 0; i < tab->n_col && n_extra > 0; ++i) {
3180                 struct isl_tab_var *var;
3181                 int row;
3182
3183                 for (j = 0; j < tab->n_col; ++j)
3184                         if (col_var[i] == tab->col_var[j])
3185                                 break;
3186                 if (j < tab->n_col)
3187                         continue;
3188                 var = var_from_index(tab, col_var[i]);
3189                 row = var->index;
3190                 for (j = 0; j < n_extra; ++j)
3191                         if (!isl_int_is_zero(tab->mat->row[row][off+extra[j]]))
3192                                 break;
3193                 isl_assert(tab->mat->ctx, j < n_extra, goto error);
3194                 if (isl_tab_pivot(tab, row, extra[j]) < 0)
3195                         goto error;
3196                 extra[j] = extra[--n_extra];
3197         }
3198
3199         free(extra);
3200         return 0;
3201 error:
3202         free(extra);
3203         return -1;
3204 }
3205
3206 /* Remove all samples with index n or greater, i.e., those samples
3207  * that were added since we saved this number of samples in
3208  * isl_tab_save_samples.
3209  */
3210 static void drop_samples_since(struct isl_tab *tab, int n)
3211 {
3212         int i;
3213
3214         for (i = tab->n_sample - 1; i >= 0 && tab->n_sample > n; --i) {
3215                 if (tab->sample_index[i] < n)
3216                         continue;
3217
3218                 if (i != tab->n_sample - 1) {
3219                         int t = tab->sample_index[tab->n_sample-1];
3220                         tab->sample_index[tab->n_sample-1] = tab->sample_index[i];
3221                         tab->sample_index[i] = t;
3222                         isl_mat_swap_rows(tab->samples, tab->n_sample-1, i);
3223                 }
3224                 tab->n_sample--;
3225         }
3226 }
3227
3228 static int perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo) WARN_UNUSED;
3229 static int perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo)
3230 {
3231         switch (undo->type) {
3232         case isl_tab_undo_empty:
3233                 tab->empty = 0;
3234                 break;
3235         case isl_tab_undo_nonneg:
3236         case isl_tab_undo_redundant:
3237         case isl_tab_undo_freeze:
3238         case isl_tab_undo_zero:
3239         case isl_tab_undo_allocate:
3240         case isl_tab_undo_relax:
3241         case isl_tab_undo_unrestrict:
3242                 return perform_undo_var(tab, undo);
3243         case isl_tab_undo_bmap_eq:
3244                 return isl_basic_map_free_equality(tab->bmap, 1);
3245         case isl_tab_undo_bmap_ineq:
3246                 return isl_basic_map_free_inequality(tab->bmap, 1);
3247         case isl_tab_undo_bmap_div:
3248                 if (isl_basic_map_free_div(tab->bmap, 1) < 0)
3249                         return -1;
3250                 if (tab->samples)
3251                         tab->samples->n_col--;
3252                 break;
3253         case isl_tab_undo_saved_basis:
3254                 if (restore_basis(tab, undo->u.col_var) < 0)
3255                         return -1;
3256                 break;
3257         case isl_tab_undo_drop_sample:
3258                 tab->n_outside--;
3259                 break;
3260         case isl_tab_undo_saved_samples:
3261                 drop_samples_since(tab, undo->u.n);
3262                 break;
3263         case isl_tab_undo_callback:
3264                 return undo->u.callback->run(undo->u.callback);
3265         default:
3266                 isl_assert(tab->mat->ctx, 0, return -1);
3267         }
3268         return 0;
3269 }
3270
3271 /* Return the tableau to the state it was in when the snapshot "snap"
3272  * was taken.
3273  */
3274 int isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap)
3275 {
3276         struct isl_tab_undo *undo, *next;
3277
3278         if (!tab)
3279                 return -1;
3280
3281         tab->in_undo = 1;
3282         for (undo = tab->top; undo && undo != &tab->bottom; undo = next) {
3283                 next = undo->next;
3284                 if (undo == snap)
3285                         break;
3286                 if (perform_undo(tab, undo) < 0) {
3287                         tab->top = undo;
3288                         free_undo(tab);
3289                         tab->in_undo = 0;
3290                         return -1;
3291                 }
3292                 free_undo_record(undo);
3293         }
3294         tab->in_undo = 0;
3295         tab->top = undo;
3296         if (!undo)
3297                 return -1;
3298         return 0;
3299 }
3300
3301 /* The given row "row" represents an inequality violated by all
3302  * points in the tableau.  Check for some special cases of such
3303  * separating constraints.
3304  * In particular, if the row has been reduced to the constant -1,
3305  * then we know the inequality is adjacent (but opposite) to
3306  * an equality in the tableau.
3307  * If the row has been reduced to r = c*(-1 -r'), with r' an inequality
3308  * of the tableau and c a positive constant, then the inequality
3309  * is adjacent (but opposite) to the inequality r'.
3310  */
3311 static enum isl_ineq_type separation_type(struct isl_tab *tab, unsigned row)
3312 {
3313         int pos;
3314         unsigned off = 2 + tab->M;
3315
3316         if (tab->rational)
3317                 return isl_ineq_separate;
3318
3319         if (!isl_int_is_one(tab->mat->row[row][0]))
3320                 return isl_ineq_separate;
3321
3322         pos = isl_seq_first_non_zero(tab->mat->row[row] + off + tab->n_dead,
3323                                         tab->n_col - tab->n_dead);
3324         if (pos == -1) {
3325                 if (isl_int_is_negone(tab->mat->row[row][1]))
3326                         return isl_ineq_adj_eq;
3327                 else
3328                         return isl_ineq_separate;
3329         }
3330
3331         if (!isl_int_eq(tab->mat->row[row][1],
3332                         tab->mat->row[row][off + tab->n_dead + pos]))
3333                 return isl_ineq_separate;
3334
3335         pos = isl_seq_first_non_zero(
3336                         tab->mat->row[row] + off + tab->n_dead + pos + 1,
3337                         tab->n_col - tab->n_dead - pos - 1);
3338
3339         return pos == -1 ? isl_ineq_adj_ineq : isl_ineq_separate;
3340 }
3341
3342 /* Check the effect of inequality "ineq" on the tableau "tab".
3343  * The result may be
3344  *      isl_ineq_redundant:     satisfied by all points in the tableau
3345  *      isl_ineq_separate:      satisfied by no point in the tableau
3346  *      isl_ineq_cut:           satisfied by some by not all points
3347  *      isl_ineq_adj_eq:        adjacent to an equality
3348  *      isl_ineq_adj_ineq:      adjacent to an inequality.
3349  */
3350 enum isl_ineq_type isl_tab_ineq_type(struct isl_tab *tab, isl_int *ineq)
3351 {
3352         enum isl_ineq_type type = isl_ineq_error;
3353         struct isl_tab_undo *snap = NULL;
3354         int con;
3355         int row;
3356
3357         if (!tab)
3358                 return isl_ineq_error;
3359
3360         if (isl_tab_extend_cons(tab, 1) < 0)
3361                 return isl_ineq_error;
3362
3363         snap = isl_tab_snap(tab);
3364
3365         con = isl_tab_add_row(tab, ineq);
3366         if (con < 0)
3367                 goto error;
3368
3369         row = tab->con[con].index;
3370         if (isl_tab_row_is_redundant(tab, row))
3371                 type = isl_ineq_redundant;
3372         else if (isl_int_is_neg(tab->mat->row[row][1]) &&
3373                  (tab->rational ||
3374                     isl_int_abs_ge(tab->mat->row[row][1],
3375                                    tab->mat->row[row][0]))) {
3376                 int nonneg = at_least_zero(tab, &tab->con[con]);
3377                 if (nonneg < 0)
3378                         goto error;
3379                 if (nonneg)
3380                         type = isl_ineq_cut;
3381                 else
3382                         type = separation_type(tab, row);
3383         } else {
3384                 int red = con_is_redundant(tab, &tab->con[con]);
3385                 if (red < 0)
3386                         goto error;
3387                 if (!red)
3388                         type = isl_ineq_cut;
3389                 else
3390                         type = isl_ineq_redundant;
3391         }
3392
3393         if (isl_tab_rollback(tab, snap))
3394                 return isl_ineq_error;
3395         return type;
3396 error:
3397         return isl_ineq_error;
3398 }
3399
3400 int isl_tab_track_bmap(struct isl_tab *tab, __isl_take isl_basic_map *bmap)
3401 {
3402         bmap = isl_basic_map_cow(bmap);
3403         if (!tab || !bmap)
3404                 goto error;
3405
3406         if (tab->empty) {
3407                 bmap = isl_basic_map_set_to_empty(bmap);
3408                 if (!bmap)
3409                         goto error;
3410                 tab->bmap = bmap;
3411                 return 0;
3412         }
3413
3414         isl_assert(tab->mat->ctx, tab->n_eq == bmap->n_eq, goto error);
3415         isl_assert(tab->mat->ctx,
3416                     tab->n_con == bmap->n_eq + bmap->n_ineq, goto error);
3417
3418         tab->bmap = bmap;
3419
3420         return 0;
3421 error:
3422         isl_basic_map_free(bmap);
3423         return -1;
3424 }
3425
3426 int isl_tab_track_bset(struct isl_tab *tab, __isl_take isl_basic_set *bset)
3427 {
3428         return isl_tab_track_bmap(tab, (isl_basic_map *)bset);
3429 }
3430
3431 __isl_keep isl_basic_set *isl_tab_peek_bset(struct isl_tab *tab)
3432 {
3433         if (!tab)
3434                 return NULL;
3435
3436         return (isl_basic_set *)tab->bmap;
3437 }
3438
3439 static void isl_tab_print_internal(__isl_keep struct isl_tab *tab,
3440         FILE *out, int indent)
3441 {
3442         unsigned r, c;
3443         int i;
3444
3445         if (!tab) {
3446                 fprintf(out, "%*snull tab\n", indent, "");
3447                 return;
3448         }
3449         fprintf(out, "%*sn_redundant: %d, n_dead: %d", indent, "",
3450                 tab->n_redundant, tab->n_dead);
3451         if (tab->rational)
3452                 fprintf(out, ", rational");
3453         if (tab->empty)
3454                 fprintf(out, ", empty");
3455         fprintf(out, "\n");
3456         fprintf(out, "%*s[", indent, "");
3457         for (i = 0; i < tab->n_var; ++i) {
3458                 if (i)
3459                         fprintf(out, (i == tab->n_param ||
3460                                       i == tab->n_var - tab->n_div) ? "; "
3461                                                                     : ", ");
3462                 fprintf(out, "%c%d%s", tab->var[i].is_row ? 'r' : 'c',
3463                                         tab->var[i].index,
3464                                         tab->var[i].is_zero ? " [=0]" :
3465                                         tab->var[i].is_redundant ? " [R]" : "");
3466         }
3467         fprintf(out, "]\n");
3468         fprintf(out, "%*s[", indent, "");
3469         for (i = 0; i < tab->n_con; ++i) {
3470                 if (i)
3471                         fprintf(out, ", ");
3472                 fprintf(out, "%c%d%s", tab->con[i].is_row ? 'r' : 'c',
3473                                         tab->con[i].index,
3474                                         tab->con[i].is_zero ? " [=0]" :
3475                                         tab->con[i].is_redundant ? " [R]" : "");
3476         }
3477         fprintf(out, "]\n");
3478         fprintf(out, "%*s[", indent, "");
3479         for (i = 0; i < tab->n_row; ++i) {
3480                 const char *sign = "";
3481                 if (i)
3482                         fprintf(out, ", ");
3483                 if (tab->row_sign) {
3484                         if (tab->row_sign[i] == isl_tab_row_unknown)
3485                                 sign = "?";
3486                         else if (tab->row_sign[i] == isl_tab_row_neg)
3487                                 sign = "-";
3488                         else if (tab->row_sign[i] == isl_tab_row_pos)
3489                                 sign = "+";
3490                         else
3491                                 sign = "+-";
3492                 }
3493                 fprintf(out, "r%d: %d%s%s", i, tab->row_var[i],
3494                     isl_tab_var_from_row(tab, i)->is_nonneg ? " [>=0]" : "", sign);
3495         }
3496         fprintf(out, "]\n");
3497         fprintf(out, "%*s[", indent, "");
3498         for (i = 0; i < tab->n_col; ++i) {
3499                 if (i)
3500                         fprintf(out, ", ");
3501                 fprintf(out, "c%d: %d%s", i, tab->col_var[i],
3502                     var_from_col(tab, i)->is_nonneg ? " [>=0]" : "");
3503         }
3504         fprintf(out, "]\n");
3505         r = tab->mat->n_row;
3506         tab->mat->n_row = tab->n_row;
3507         c = tab->mat->n_col;
3508         tab->mat->n_col = 2 + tab->M + tab->n_col;
3509         isl_mat_print_internal(tab->mat, out, indent);
3510         tab->mat->n_row = r;
3511         tab->mat->n_col = c;
3512         if (tab->bmap)
3513                 isl_basic_map_print_internal(tab->bmap, out, indent);
3514 }
3515
3516 void isl_tab_dump(__isl_keep struct isl_tab *tab)
3517 {
3518         isl_tab_print_internal(tab, stderr, 0);
3519 }