Polly 23.0.0git
isl_tab_pip.c
Go to the documentation of this file.
1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
4 * Copyright 2016-2017 Sven Verdoolaege
5 * Copyright 2023 Cerebras Systems
6 *
7 * Use of this software is governed by the MIT license
8 *
9 * Written by Sven Verdoolaege, K.U.Leuven, Departement
10 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
11 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
12 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
13 * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
14 */
15
16#include <isl_ctx_private.h>
17#include "isl_map_private.h"
18#include <isl_seq.h>
19#include "isl_tab.h"
20#include "isl_sample.h"
21#include <isl_mat_private.h>
22#include <isl_vec_private.h>
23#include <isl_aff_private.h>
25#include <isl_options_private.h>
26#include <isl_config.h>
27
28#include <bset_to_bmap.c>
29
30/*
31 * The implementation of parametric integer linear programming in this file
32 * was inspired by the paper "Parametric Integer Programming" and the
33 * report "Solving systems of affine (in)equalities" by Paul Feautrier
34 * (and others).
35 *
36 * The strategy used for obtaining a feasible solution is different
37 * from the one used in isl_tab.c. In particular, in isl_tab.c,
38 * upon finding a constraint that is not yet satisfied, we pivot
39 * in a row that increases the constant term of the row holding the
40 * constraint, making sure the sample solution remains feasible
41 * for all the constraints it already satisfied.
42 * Here, we always pivot in the row holding the constraint,
43 * choosing a column that induces the lexicographically smallest
44 * increment to the sample solution.
45 *
46 * By starting out from a sample value that is lexicographically
47 * smaller than any integer point in the problem space, the first
48 * feasible integer sample point we find will also be the lexicographically
49 * smallest. If all variables can be assumed to be non-negative,
50 * then the initial sample value may be chosen equal to zero.
51 * However, we will not make this assumption. Instead, we apply
52 * the "big parameter" trick. Any variable x is then not directly
53 * used in the tableau, but instead it is represented by another
54 * variable x' = M + x, where M is an arbitrarily large (positive)
55 * value. x' is therefore always non-negative, whatever the value of x.
56 * Taking as initial sample value x' = 0 corresponds to x = -M,
57 * which is always smaller than any possible value of x.
58 *
59 * The big parameter trick is used in the main tableau and
60 * also in the context tableau if isl_context_lex is used.
61 * In this case, each tableaus has its own big parameter.
62 * Before doing any real work, we check if all the parameters
63 * happen to be non-negative. If so, we drop the column corresponding
64 * to M from the initial context tableau.
65 * If isl_context_gbr is used, then the big parameter trick is only
66 * used in the main tableau.
67 */
68
69struct isl_context;
71 /* detect nonnegative parameters in context and mark them in tab */
72 struct isl_tab *(*detect_nonnegative_parameters)(
73 struct isl_context *context, struct isl_tab *tab);
74 /* return temporary reference to basic set representation of context */
75 struct isl_basic_set *(*peek_basic_set)(struct isl_context *context);
76 /* return temporary reference to tableau representation of context */
77 struct isl_tab *(*peek_tab)(struct isl_context *context);
78 /* add equality; check is 1 if eq may not be valid;
79 * update is 1 if we may want to call ineq_sign on context later.
80 */
81 void (*add_eq)(struct isl_context *context, isl_int *eq,
82 int check, int update);
83 /* add inequality; check is 1 if ineq may not be valid;
84 * update is 1 if we may want to call ineq_sign on context later.
85 */
86 void (*add_ineq)(struct isl_context *context, isl_int *ineq,
87 int check, int update);
88 /* check sign of ineq based on previous information.
89 * strict is 1 if saturation should be treated as a positive sign.
90 */
92 isl_int *ineq, int strict);
93 /* check if inequality maintains feasibility */
94 int (*test_ineq)(struct isl_context *context, isl_int *ineq);
95 /* return index of a div that corresponds to "div" */
96 int (*get_div)(struct isl_context *context, struct isl_tab *tab,
97 struct isl_vec *div);
98 /* insert div "div" to context at "pos" and return non-negativity */
100 __isl_keep isl_vec *div);
102 struct isl_tab *tab);
103 /* return row index of "best" split */
104 int (*best_split)(struct isl_context *context, struct isl_tab *tab);
105 /* check if context has already been determined to be empty */
106 int (*is_empty)(struct isl_context *context);
107 /* check if context is still usable */
108 int (*is_ok)(struct isl_context *context);
109 /* save a copy/snapshot of context */
110 void *(*save)(struct isl_context *context);
111 /* restore saved context */
112 void (*restore)(struct isl_context *context, void *);
113 /* discard saved context */
114 void (*discard)(void *);
115 /* invalidate context */
117 /* free context */
118 __isl_null struct isl_context *(*free)(struct isl_context *context);
119};
120
121/* Shared parts of context representation.
122 *
123 * "n_unknown" is the number of final unknown integer divisions
124 * in the input domain.
125 */
129};
130
133 struct isl_tab *tab;
134};
135
136/* A stack (linked list) of solutions of subtrees of the search space.
137 *
138 * "ma" describes the solution as a function of "dom".
139 * In particular, the domain space of "ma" is equal to the space of "dom".
140 *
141 * If "ma" is NULL, then there is no solution on "dom".
142 */
150
151struct isl_sol;
156
157/* isl_sol is an interface for constructing a solution to
158 * a parametric integer linear programming problem.
159 * Every time the algorithm reaches a state where a solution
160 * can be read off from the tableau, the function "add" is called
161 * on the isl_sol passed to find_solutions_main. In a state where
162 * the tableau is empty, "add_empty" is called instead.
163 * "free" is called to free the implementation specific fields, if any.
164 *
165 * "error" is set if some error has occurred. This flag invalidates
166 * the remainder of the data structure.
167 * If "rational" is set, then a rational optimization is being performed.
168 * "level" is the current level in the tree with nodes for each
169 * split in the context.
170 * If "max" is set, then a maximization problem is being solved, rather than
171 * a minimization problem, which means that the variables in the
172 * tableau have value "M - x" rather than "M + x".
173 * "n_out" is the number of output dimensions in the input.
174 * "space" is the space in which the solution (and also the input) lives.
175 *
176 * The context tableau is owned by isl_sol and is updated incrementally.
177 *
178 * There are currently two implementations of this interface,
179 * isl_sol_map, which simply collects the solutions in an isl_map
180 * and (optionally) the parts of the context where there is no solution
181 * in an isl_set, and
182 * isl_sol_pma, which collects an isl_pw_multi_aff instead.
183 */
184struct isl_sol {
185 int error;
187 int level;
188 int max;
193 void (*add)(struct isl_sol *sol,
195 void (*add_empty)(struct isl_sol *sol, struct isl_basic_set *bset);
196 void (*free)(struct isl_sol *sol);
198};
199
200static void sol_free(struct isl_sol *sol)
201{
202 struct isl_partial_sol *partial, *next;
203 if (!sol)
204 return;
205 for (partial = sol->partial; partial; partial = next) {
206 next = partial->next;
207 isl_basic_set_free(partial->dom);
208 isl_multi_aff_free(partial->ma);
209 free(partial);
210 }
211 isl_space_free(sol->space);
212 if (sol->context)
213 sol->context->op->free(sol->context);
214 sol->free(sol);
215 free(sol);
216}
217
218/* Add equality constraint "eq" to the context of "sol".
219 * "check" is set if "eq" is not known to be a valid constraint.
220 * "update" is set if ineq_sign() may still get called on the context.
221 */
222static void sol_context_add_eq(struct isl_sol *sol, isl_int *eq, int check,
223 int update)
224{
225 if (sol->error)
226 return;
227 sol->context->op->add_eq(sol->context, eq, check, update);
228 if (!sol->context->op->is_ok(sol->context))
229 sol->error = 1;
230}
231
232/* Add inequality constraint "ineq" to the context of "sol".
233 * "check" is set if "ineq" is not known to be a valid constraint.
234 * "update" is set if ineq_sign() may still get called on the context.
235 */
236static void sol_context_add_ineq(struct isl_sol *sol, isl_int *ineq, int check,
237 int update)
238{
239 if (sol->error)
240 return;
241 sol->context->op->add_ineq(sol->context, ineq, check, update);
242 if (!sol->context->op->is_ok(sol->context))
243 sol->error = 1;
244}
245
246/* Push a partial solution represented by a domain and function "ma"
247 * onto the stack of partial solutions.
248 * If "ma" is NULL, then "dom" represents a part of the domain
249 * with no solution.
250 */
251static void sol_push_sol(struct isl_sol *sol,
253{
254 struct isl_partial_sol *partial;
255
256 if (sol->error || !dom)
257 goto error;
258
259 partial = isl_alloc_type(dom->ctx, struct isl_partial_sol);
260 if (!partial)
261 goto error;
262
263 partial->level = sol->level;
264 partial->dom = dom;
265 partial->ma = ma;
266 partial->next = sol->partial;
267
268 sol->partial = partial;
269
270 return;
271error:
273 isl_multi_aff_free(ma);
274 sol->error = 1;
275}
276
277/* Check that the final columns of "M", starting at "first", are zero.
278 */
280 unsigned first)
281{
282 int i;
283 isl_size rows, cols;
284 unsigned n;
285
286 rows = isl_mat_rows(M);
287 cols = isl_mat_cols(M);
288 if (rows < 0 || cols < 0)
289 return isl_stat_error;
290 n = cols - first;
291 for (i = 0; i < rows; ++i)
292 if (isl_seq_any_non_zero(M->row[i] + first, n))
294 "final columns should be zero",
295 return isl_stat_error);
296 return isl_stat_ok;
297}
298
299/* Set the affine expressions in "ma" according to the rows in "M", which
300 * are defined over the local space "ls".
301 * The matrix "M" may have extra (zero) columns beyond the number
302 * of variables in "ls".
303 */
307{
308 int i;
309 isl_size dim;
310 isl_aff *aff;
311
313 if (!ma || dim < 0 || !M)
314 goto error;
315
316 if (check_final_columns_are_zero(M, 1 + dim) < 0)
317 goto error;
318 for (i = 1; i < M->n_row; ++i) {
320 if (aff) {
321 isl_int_set(aff->v->el[0], M->row[0][0]);
322 isl_seq_cpy(aff->v->el + 1, M->row[i], 1 + dim);
323 }
325 ma = isl_multi_aff_set_aff(ma, i - 1, aff);
326 }
328 isl_mat_free(M);
329
330 return ma;
331error:
333 isl_mat_free(M);
334 isl_multi_aff_free(ma);
335 return NULL;
336}
337
338/* Push a partial solution represented by a domain and mapping M
339 * onto the stack of partial solutions.
340 *
341 * The affine matrix "M" maps the dimensions of the context
342 * to the output variables. Convert it into an isl_multi_aff and
343 * then call sol_push_sol.
344 *
345 * Note that the description of the initial context may have involved
346 * existentially quantified variables, in which case they also appear
347 * in "dom". These need to be removed before creating the affine
348 * expression because an affine expression cannot be defined in terms
349 * of existentially quantified variables without a known representation.
350 * Since newly added integer divisions are inserted before these
351 * existentially quantified variables, they are still in the final
352 * positions and the corresponding final columns of "M" are zero
353 * because align_context_divs adds the existentially quantified
354 * variables of the context to the main tableau without any constraints and
355 * any equality constraints that are added later on can only serve
356 * to eliminate these existentially quantified variables.
357 */
358static void sol_push_sol_mat(struct isl_sol *sol,
360{
361 isl_local_space *ls;
363 isl_size n_div;
364 int n_known;
365
367 if (n_div < 0)
368 goto error;
369 n_known = n_div - sol->context->n_unknown;
370
371 ma = isl_multi_aff_alloc(isl_space_copy(sol->space));
374 n_known, n_div - n_known);
375 ma = set_from_affine_matrix(ma, ls, M);
376
377 if (!ma)
379 sol_push_sol(sol, dom, ma);
380 return;
381error:
383 isl_mat_free(M);
384 sol_push_sol(sol, NULL, NULL);
385}
386
387/* Pop one partial solution from the partial solution stack and
388 * pass it on to sol->add or sol->add_empty.
389 */
390static void sol_pop_one(struct isl_sol *sol)
391{
392 struct isl_partial_sol *partial;
393
394 partial = sol->partial;
395 sol->partial = partial->next;
396
397 if (partial->ma)
398 sol->add(sol, partial->dom, partial->ma);
399 else
400 sol->add_empty(sol, partial->dom);
401 free(partial);
402}
403
404/* Return a fresh copy of the domain represented by the context tableau.
405 */
406static struct isl_basic_set *sol_domain(struct isl_sol *sol)
407{
408 struct isl_basic_set *bset;
409
410 if (sol->error)
411 return NULL;
412
415 sol->context->op->peek_tab(sol->context));
416
417 return bset;
418}
419
420/* Check whether two partial solutions have the same affine expressions.
421 */
423 struct isl_partial_sol *s2)
424{
425 if (!s1->ma != !s2->ma)
426 return isl_bool_false;
427 if (!s1->ma)
428 return isl_bool_true;
429
430 return isl_multi_aff_plain_is_equal(s1->ma, s2->ma);
431}
432
433/* Swap the initial two partial solutions in "sol".
434 *
435 * That is, go from
436 *
437 * sol->partial = p1; p1->next = p2; p2->next = p3
438 *
439 * to
440 *
441 * sol->partial = p2; p2->next = p1; p1->next = p3
442 */
443static void swap_initial(struct isl_sol *sol)
444{
445 struct isl_partial_sol *partial;
446
447 partial = sol->partial;
448 sol->partial = partial->next;
449 partial->next = partial->next->next;
450 sol->partial->next = partial;
451}
452
453/* Combine the initial two partial solution of "sol" into
454 * a partial solution with the current context domain of "sol" and
455 * the function description of the second partial solution in the list.
456 * The level of the new partial solution is set to the current level.
457 *
458 * That is, the first two partial solutions (D1,M1) and (D2,M2) are
459 * replaced by (D,M2), where D is the domain of "sol", which is assumed
460 * to be the union of D1 and D2, while M1 is assumed to be equal to M2
461 * (at least on D1).
462 */
464{
465 struct isl_partial_sol *partial;
466 isl_basic_set *bset;
467
468 partial = sol->partial;
469
470 bset = sol_domain(sol);
471 isl_basic_set_free(partial->next->dom);
472 partial->next->dom = bset;
473 partial->next->level = sol->level;
474
475 if (!bset)
476 return isl_stat_error;
477
478 sol->partial = partial->next;
479 isl_basic_set_free(partial->dom);
480 isl_multi_aff_free(partial->ma);
481 free(partial);
482
483 return isl_stat_ok;
484}
485
486/* Are "ma1" and "ma2" equal to each other on "dom"?
487 *
488 * Combine "ma1" and "ma2" with "dom" and check if the results are the same.
489 * "dom" may have existentially quantified variables. Eliminate them first
490 * as otherwise they would have to be eliminated twice, in a more complicated
491 * context.
492 */
495{
496 isl_set *set;
497 isl_pw_multi_aff *pma1, *pma2;
499
502 isl_multi_aff_copy(ma1));
503 pma2 = isl_pw_multi_aff_alloc(set, isl_multi_aff_copy(ma2));
504 equal = isl_pw_multi_aff_is_equal(pma1, pma2);
507
508 return equal;
509}
510
511/* The initial two partial solutions of "sol" are known to be at
512 * the same level.
513 * If they represent the same solution (on different parts of the domain),
514 * then combine them into a single solution at the current level.
515 * Otherwise, pop them both.
516 *
517 * Even if the two partial solution are not obviously the same,
518 * one may still be a simplification of the other over its own domain.
519 * Also check if the two sets of affine functions are equal when
520 * restricted to one of the domains. If so, combine the two
521 * using the set of affine functions on the other domain.
522 * That is, for two partial solutions (D1,M1) and (D2,M2),
523 * if M1 = M2 on D1, then the pair of partial solutions can
524 * be replaced by (D1+D2,M2) and similarly when M1 = M2 on D2.
525 */
527{
528 struct isl_partial_sol *partial;
529 isl_bool same;
530
531 partial = sol->partial;
532
533 same = same_solution(partial, partial->next);
534 if (same < 0)
535 return isl_stat_error;
536 if (same)
537 return combine_initial_into_second(sol);
538 if (partial->ma && partial->next->ma) {
539 same = equal_on_domain(partial->ma, partial->next->ma,
540 partial->dom);
541 if (same < 0)
542 return isl_stat_error;
543 if (same)
544 return combine_initial_into_second(sol);
545 same = equal_on_domain(partial->ma, partial->next->ma,
546 partial->next->dom);
547 if (same) {
548 swap_initial(sol);
549 return combine_initial_into_second(sol);
550 }
551 }
552
553 sol_pop_one(sol);
554 sol_pop_one(sol);
555
556 return isl_stat_ok;
557}
558
559/* Pop all solutions from the partial solution stack that were pushed onto
560 * the stack at levels that are deeper than the current level.
561 * If the two topmost elements on the stack have the same level
562 * and represent the same solution, then their domains are combined.
563 * This combined domain is the same as the current context domain
564 * as sol_pop is called each time we move back to a higher level.
565 * If the outer level (0) has been reached, then all partial solutions
566 * at the current level are also popped off.
567 */
568static void sol_pop(struct isl_sol *sol)
569{
570 struct isl_partial_sol *partial;
571
572 if (sol->error)
573 return;
574
575 partial = sol->partial;
576 if (!partial)
577 return;
578
579 if (partial->level == 0 && sol->level == 0) {
580 for (partial = sol->partial; partial; partial = sol->partial)
581 sol_pop_one(sol);
582 return;
583 }
584
585 if (partial->level <= sol->level)
586 return;
587
588 if (partial->next && partial->next->level == partial->level) {
589 if (combine_initial_if_equal(sol) < 0)
590 goto error;
591 } else
592 sol_pop_one(sol);
593
594 if (sol->level == 0) {
595 for (partial = sol->partial; partial; partial = sol->partial)
596 sol_pop_one(sol);
597 return;
598 }
599
600 if (0)
601error: sol->error = 1;
602}
603
604static void sol_dec_level(struct isl_sol *sol)
605{
606 if (sol->error)
607 return;
608
609 sol->level--;
610
611 sol_pop(sol);
612}
613
615{
616 struct isl_sol_callback *callback = (struct isl_sol_callback *)cb;
617
619
620 return callback->sol->error ? isl_stat_error : isl_stat_ok;
621}
622
623/* Move down to next level and push callback onto context tableau
624 * to decrease the level again when it gets rolled back across
625 * the current state. That is, dec_level will be called with
626 * the context tableau in the same state as it is when inc_level
627 * is called.
628 */
629static void sol_inc_level(struct isl_sol *sol)
630{
631 struct isl_tab *tab;
632
633 if (sol->error)
634 return;
635
636 sol->level++;
637 tab = sol->context->op->peek_tab(sol->context);
638 if (isl_tab_push_callback(tab, &sol->dec_level.callback) < 0)
639 sol->error = 1;
640}
641
642static void scale_rows(struct isl_mat *mat, isl_int m, int n_row)
643{
644 int i;
645
646 if (isl_int_is_one(m))
647 return;
648
649 for (i = 0; i < n_row; ++i)
650 isl_seq_scale(mat->row[i], mat->row[i], m, mat->n_col);
651}
652
653/* Add the solution identified by the tableau and the context tableau.
654 *
655 * The layout of the variables is as follows.
656 * tab->n_var is equal to the total number of variables in the input
657 * map (including divs that were copied from the context)
658 * + the number of extra divs constructed
659 * Of these, the first tab->n_param and the last tab->n_div variables
660 * correspond to the variables in the context, i.e.,
661 * tab->n_param + tab->n_div = context_tab->n_var
662 * tab->n_param is equal to the number of parameters and input
663 * dimensions in the input map
664 * tab->n_div is equal to the number of divs in the context
665 *
666 * If there is no solution, then call add_empty with a basic set
667 * that corresponds to the context tableau. (If add_empty is NULL,
668 * then do nothing).
669 *
670 * If there is a solution, then first construct a matrix that maps
671 * all dimensions of the context to the output variables, i.e.,
672 * the output dimensions in the input map.
673 * The divs in the input map (if any) that do not correspond to any
674 * div in the context do not appear in the solution.
675 * The algorithm will make sure that they have an integer value,
676 * but these values themselves are of no interest.
677 * We have to be careful not to drop or rearrange any divs in the
678 * context because that would change the meaning of the matrix.
679 *
680 * To extract the value of the output variables, it should be noted
681 * that we always use a big parameter M in the main tableau and so
682 * the variable stored in this tableau is not an output variable x itself, but
683 * x' = M + x (in case of minimization)
684 * or
685 * x' = M - x (in case of maximization)
686 * If x' appears in a column, then its optimal value is zero,
687 * which means that the optimal value of x is an unbounded number
688 * (-M for minimization and M for maximization).
689 * We currently assume that the output dimensions in the original map
690 * are bounded, so this cannot occur.
691 * Similarly, when x' appears in a row, then the coefficient of M in that
692 * row is necessarily 1.
693 * If the row in the tableau represents
694 * d x' = c + d M + e(y)
695 * then, in case of minimization, the corresponding row in the matrix
696 * will be
697 * a c + a e(y)
698 * with a d = m, the (updated) common denominator of the matrix.
699 * In case of maximization, the row will be
700 * -a c - a e(y)
701 */
702static void sol_add(struct isl_sol *sol, struct isl_tab *tab)
703{
704 struct isl_basic_set *bset = NULL;
705 struct isl_mat *mat = NULL;
706 unsigned off;
707 int row;
708 isl_int m;
709
710 if (sol->error || !tab)
711 goto error;
712
713 if (tab->empty && !sol->add_empty)
714 return;
715 if (sol->context->op->is_empty(sol->context))
716 return;
717
718 bset = sol_domain(sol);
719
720 if (tab->empty) {
721 sol_push_sol(sol, bset, NULL);
722 return;
723 }
724
725 off = 2 + tab->M;
726
727 mat = isl_mat_alloc(tab->mat->ctx, 1 + sol->n_out,
728 1 + tab->n_param + tab->n_div);
729 if (!mat)
730 goto error;
731
733
734 isl_seq_clr(mat->row[0] + 1, mat->n_col - 1);
735 isl_int_set_si(mat->row[0][0], 1);
736 for (row = 0; row < sol->n_out; ++row) {
737 int i = tab->n_param + row;
738 int r, j;
739
740 isl_seq_clr(mat->row[1 + row], mat->n_col);
741 if (!tab->var[i].is_row) {
742 if (tab->M)
744 "unbounded optimum", goto error2);
745 continue;
746 }
747
748 r = tab->var[i].index;
749 if (tab->M &&
750 isl_int_ne(tab->mat->row[r][2], tab->mat->row[r][0]))
752 "unbounded optimum", goto error2);
753 isl_int_gcd(m, mat->row[0][0], tab->mat->row[r][0]);
754 isl_int_divexact(m, tab->mat->row[r][0], m);
755 scale_rows(mat, m, 1 + row);
756 isl_int_divexact(m, mat->row[0][0], tab->mat->row[r][0]);
757 isl_int_mul(mat->row[1 + row][0], m, tab->mat->row[r][1]);
758 for (j = 0; j < tab->n_param; ++j) {
759 int col;
760 if (tab->var[j].is_row)
761 continue;
762 col = tab->var[j].index;
763 isl_int_mul(mat->row[1 + row][1 + j], m,
764 tab->mat->row[r][off + col]);
765 }
766 for (j = 0; j < tab->n_div; ++j) {
767 int col;
768 if (tab->var[tab->n_var - tab->n_div+j].is_row)
769 continue;
770 col = tab->var[tab->n_var - tab->n_div+j].index;
771 isl_int_mul(mat->row[1 + row][1 + tab->n_param + j], m,
772 tab->mat->row[r][off + col]);
773 }
774 if (sol->max)
775 isl_seq_neg(mat->row[1 + row], mat->row[1 + row],
776 mat->n_col);
777 }
778
780
781 sol_push_sol_mat(sol, bset, mat);
782 return;
783error2:
785error:
786 isl_basic_set_free(bset);
787 isl_mat_free(mat);
788 sol->error = 1;
789}
790
792 struct isl_sol sol;
793 struct isl_map *map;
794 struct isl_set *empty;
795};
796
797static void sol_map_free(struct isl_sol *sol)
798{
799 struct isl_sol_map *sol_map = (struct isl_sol_map *) sol;
800 isl_map_free(sol_map->map);
801 isl_set_free(sol_map->empty);
802}
803
804/* This function is called for parts of the context where there is
805 * no solution, with "bset" corresponding to the context tableau.
806 * Simply add the basic set to the set "empty".
807 */
809 struct isl_basic_set *bset)
810{
811 if (!bset || !sol->empty)
812 goto error;
813
814 sol->empty = isl_set_grow(sol->empty, 1);
815 bset = isl_basic_set_simplify(bset);
816 bset = isl_basic_set_finalize(bset);
817 sol->empty = isl_set_add_basic_set(sol->empty, isl_basic_set_copy(bset));
818 if (!sol->empty)
819 goto error;
820 isl_basic_set_free(bset);
821 return;
822error:
823 isl_basic_set_free(bset);
824 sol->sol.error = 1;
825}
826
828 struct isl_basic_set *bset)
829{
830 sol_map_add_empty((struct isl_sol_map *)sol, bset);
831}
832
833/* Given a basic set "dom" that represents the context and a tuple of
834 * affine expressions "ma" defined over this domain, construct a basic map
835 * that expresses this function on the domain.
836 */
837static void sol_map_add(struct isl_sol_map *sol,
839{
840 isl_basic_map *bmap;
841
842 if (sol->sol.error || !dom || !ma)
843 goto error;
844
846 bmap = isl_basic_map_intersect_domain(bmap, dom);
847 sol->map = isl_map_grow(sol->map, 1);
848 sol->map = isl_map_add_basic_map(sol->map, bmap);
849 if (!sol->map)
850 sol->sol.error = 1;
851 return;
852error:
854 isl_multi_aff_free(ma);
855 sol->sol.error = 1;
856}
857
858static void sol_map_add_wrap(struct isl_sol *sol,
860{
861 sol_map_add((struct isl_sol_map *)sol, dom, ma);
862}
863
864
865/* Store the "parametric constant" of row "row" of tableau "tab" in "line",
866 * i.e., the constant term and the coefficients of all variables that
867 * appear in the context tableau.
868 * Note that the coefficient of the big parameter M is NOT copied.
869 * The context tableau may not have a big parameter and even when it
870 * does, it is a different big parameter.
871 */
872static void get_row_parameter_line(struct isl_tab *tab, int row, isl_int *line)
873{
874 int i;
875 unsigned off = 2 + tab->M;
876
877 isl_int_set(line[0], tab->mat->row[row][1]);
878 for (i = 0; i < tab->n_param; ++i) {
879 if (tab->var[i].is_row)
880 isl_int_set_si(line[1 + i], 0);
881 else {
882 int col = tab->var[i].index;
883 isl_int_set(line[1 + i], tab->mat->row[row][off + col]);
884 }
885 }
886 for (i = 0; i < tab->n_div; ++i) {
887 if (tab->var[tab->n_var - tab->n_div + i].is_row)
888 isl_int_set_si(line[1 + tab->n_param + i], 0);
889 else {
890 int col = tab->var[tab->n_var - tab->n_div + i].index;
891 isl_int_set(line[1 + tab->n_param + i],
892 tab->mat->row[row][off + col]);
893 }
894 }
895}
896
897/* Check if rows "row1" and "row2" have identical "parametric constants",
898 * as explained above.
899 * In this case, we also insist that the coefficients of the big parameter
900 * be the same as the values of the constants will only be the same
901 * if these coefficients are also the same.
902 */
903static int identical_parameter_line(struct isl_tab *tab, int row1, int row2)
904{
905 int i;
906 unsigned off = 2 + tab->M;
907
908 if (isl_int_ne(tab->mat->row[row1][1], tab->mat->row[row2][1]))
909 return 0;
910
911 if (tab->M && isl_int_ne(tab->mat->row[row1][2],
912 tab->mat->row[row2][2]))
913 return 0;
914
915 for (i = 0; i < tab->n_param + tab->n_div; ++i) {
916 int pos = i < tab->n_param ? i :
917 tab->n_var - tab->n_div + i - tab->n_param;
918 int col;
919
920 if (tab->var[pos].is_row)
921 continue;
922 col = tab->var[pos].index;
923 if (isl_int_ne(tab->mat->row[row1][off + col],
924 tab->mat->row[row2][off + col]))
925 return 0;
926 }
927 return 1;
928}
929
930/* Return an inequality that expresses that the "parametric constant"
931 * should be non-negative.
932 * This function is only called when the coefficient of the big parameter
933 * is equal to zero.
934 */
935static struct isl_vec *get_row_parameter_ineq(struct isl_tab *tab, int row)
936{
937 struct isl_vec *ineq;
938
939 ineq = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_param + tab->n_div);
940 if (!ineq)
941 return NULL;
942
943 get_row_parameter_line(tab, row, ineq->el);
944 if (ineq)
945 ineq = isl_vec_normalize(ineq);
946
947 return ineq;
948}
949
950/* Normalize a div expression of the form
951 *
952 * [(g*f(x) + c)/(g * m)]
953 *
954 * with c the constant term and f(x) the remaining coefficients, to
955 *
956 * [(f(x) + [c/g])/m]
957 */
959{
961 int len = div->size - 2;
962
963 isl_seq_gcd(div->el + 2, len, &ctx->normalize_gcd);
965
967 return;
968
969 isl_int_divexact(div->el[0], div->el[0], ctx->normalize_gcd);
970 isl_int_fdiv_q(div->el[1], div->el[1], ctx->normalize_gcd);
971 isl_seq_scale_down(div->el + 2, div->el + 2, ctx->normalize_gcd, len);
972}
973
974/* Return an integer division for use in a parametric cut based
975 * on the given row.
976 * In particular, let the parametric constant of the row be
977 *
978 * \sum_i a_i y_i
979 *
980 * where y_0 = 1, but none of the y_i corresponds to the big parameter M.
981 * The div returned is equal to
982 *
983 * floor(\sum_i {-a_i} y_i) = floor((\sum_i (-a_i mod d) y_i)/d)
984 */
985static struct isl_vec *get_row_parameter_div(struct isl_tab *tab, int row)
986{
987 struct isl_vec *div;
988
989 div = isl_vec_alloc(tab->mat->ctx, 1 + 1 + tab->n_param + tab->n_div);
990 if (!div)
991 return NULL;
992
993 isl_int_set(div->el[0], tab->mat->row[row][0]);
994 get_row_parameter_line(tab, row, div->el + 1);
995 isl_seq_neg(div->el + 1, div->el + 1, div->size - 1);
996 normalize_div(div);
997 isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1);
998
999 return div;
1000}
1001
1002/* Return an integer division for use in transferring an integrality constraint
1003 * to the context.
1004 * In particular, let the parametric constant of the row be
1005 *
1006 * \sum_i a_i y_i
1007 *
1008 * where y_0 = 1, but none of the y_i corresponds to the big parameter M.
1009 * The the returned div is equal to
1010 *
1011 * floor(\sum_i {a_i} y_i) = floor((\sum_i (a_i mod d) y_i)/d)
1012 */
1013static struct isl_vec *get_row_split_div(struct isl_tab *tab, int row)
1014{
1015 struct isl_vec *div;
1016
1017 div = isl_vec_alloc(tab->mat->ctx, 1 + 1 + tab->n_param + tab->n_div);
1018 if (!div)
1019 return NULL;
1020
1021 isl_int_set(div->el[0], tab->mat->row[row][0]);
1022 get_row_parameter_line(tab, row, div->el + 1);
1023 normalize_div(div);
1024 isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1);
1025
1026 return div;
1027}
1028
1029/* Construct and return an inequality that expresses an upper bound
1030 * on the given div.
1031 * In particular, if the div is given by
1032 *
1033 * d = floor(e/m)
1034 *
1035 * then the inequality expresses
1036 *
1037 * m d <= e
1038 */
1040 unsigned div)
1041{
1043 unsigned div_pos;
1044 struct isl_vec *ineq;
1045
1047 if (total < 0)
1048 return NULL;
1049
1050 div_pos = 1 + total - bset->n_div + div;
1051
1052 ineq = isl_vec_alloc(bset->ctx, 1 + total);
1053 if (!ineq)
1054 return NULL;
1055
1056 isl_seq_cpy(ineq->el, bset->div[div] + 1, 1 + total);
1057 isl_int_neg(ineq->el[div_pos], bset->div[div][0]);
1058 return ineq;
1059}
1060
1061/* Given a row in the tableau and a div that was created
1062 * using get_row_split_div and that has been constrained to equality, i.e.,
1063 *
1064 * d = floor(\sum_i {a_i} y_i) = \sum_i {a_i} y_i
1065 *
1066 * replace the expression "\sum_i {a_i} y_i" in the row by d,
1067 * i.e., we subtract "\sum_i {a_i} y_i" and add 1 d.
1068 * The coefficients of the non-parameters in the tableau have been
1069 * verified to be integral. We can therefore simply replace coefficient b
1070 * by floor(b). For the coefficients of the parameters we have
1071 * floor(a_i) = a_i - {a_i}, while for the other coefficients, we have
1072 * floor(b) = b.
1073 */
1074static struct isl_tab *set_row_cst_to_div(struct isl_tab *tab, int row, int div)
1075{
1076 isl_seq_fdiv_q(tab->mat->row[row] + 1, tab->mat->row[row] + 1,
1077 tab->mat->row[row][0], 1 + tab->M + tab->n_col);
1078
1079 isl_int_set_si(tab->mat->row[row][0], 1);
1080
1081 if (tab->var[tab->n_var - tab->n_div + div].is_row) {
1082 int drow = tab->var[tab->n_var - tab->n_div + div].index;
1083
1084 isl_assert(tab->mat->ctx,
1085 isl_int_is_one(tab->mat->row[drow][0]), goto error);
1086 isl_seq_combine(tab->mat->row[row] + 1,
1087 tab->mat->ctx->one, tab->mat->row[row] + 1,
1088 tab->mat->ctx->one, tab->mat->row[drow] + 1,
1089 1 + tab->M + tab->n_col);
1090 } else {
1091 int dcol = tab->var[tab->n_var - tab->n_div + div].index;
1092
1093 isl_int_add_ui(tab->mat->row[row][2 + tab->M + dcol],
1094 tab->mat->row[row][2 + tab->M + dcol], 1);
1095 }
1096
1097 return tab;
1098error:
1099 isl_tab_free(tab);
1100 return NULL;
1101}
1102
1103/* Check if the (parametric) constant of the given row is obviously
1104 * negative, meaning that we don't need to consult the context tableau.
1105 * If there is a big parameter and its coefficient is non-zero,
1106 * then this coefficient determines the outcome.
1107 * Otherwise, we check whether the constant is negative and
1108 * all non-zero coefficients of parameters are negative and
1109 * belong to non-negative parameters.
1110 */
1111static int is_obviously_neg(struct isl_tab *tab, int row)
1112{
1113 int i;
1114 int col;
1115 unsigned off = 2 + tab->M;
1116
1117 if (tab->M) {
1118 if (isl_int_is_pos(tab->mat->row[row][2]))
1119 return 0;
1120 if (isl_int_is_neg(tab->mat->row[row][2]))
1121 return 1;
1122 }
1123
1124 if (isl_int_is_nonneg(tab->mat->row[row][1]))
1125 return 0;
1126 for (i = 0; i < tab->n_param; ++i) {
1127 /* Eliminated parameter */
1128 if (tab->var[i].is_row)
1129 continue;
1130 col = tab->var[i].index;
1131 if (isl_int_is_zero(tab->mat->row[row][off + col]))
1132 continue;
1133 if (!tab->var[i].is_nonneg)
1134 return 0;
1135 if (isl_int_is_pos(tab->mat->row[row][off + col]))
1136 return 0;
1137 }
1138 for (i = 0; i < tab->n_div; ++i) {
1139 if (tab->var[tab->n_var - tab->n_div + i].is_row)
1140 continue;
1141 col = tab->var[tab->n_var - tab->n_div + i].index;
1142 if (isl_int_is_zero(tab->mat->row[row][off + col]))
1143 continue;
1144 if (!tab->var[tab->n_var - tab->n_div + i].is_nonneg)
1145 return 0;
1146 if (isl_int_is_pos(tab->mat->row[row][off + col]))
1147 return 0;
1148 }
1149 return 1;
1150}
1151
1152/* Check if the (parametric) constant of the given row is obviously
1153 * non-negative, meaning that we don't need to consult the context tableau.
1154 * If there is a big parameter and its coefficient is non-zero,
1155 * then this coefficient determines the outcome.
1156 * Otherwise, we check whether the constant is non-negative and
1157 * all non-zero coefficients of parameters are positive and
1158 * belong to non-negative parameters.
1159 */
1160static int is_obviously_nonneg(struct isl_tab *tab, int row)
1161{
1162 int i;
1163 int col;
1164 unsigned off = 2 + tab->M;
1165
1166 if (tab->M) {
1167 if (isl_int_is_pos(tab->mat->row[row][2]))
1168 return 1;
1169 if (isl_int_is_neg(tab->mat->row[row][2]))
1170 return 0;
1171 }
1172
1173 if (isl_int_is_neg(tab->mat->row[row][1]))
1174 return 0;
1175 for (i = 0; i < tab->n_param; ++i) {
1176 /* Eliminated parameter */
1177 if (tab->var[i].is_row)
1178 continue;
1179 col = tab->var[i].index;
1180 if (isl_int_is_zero(tab->mat->row[row][off + col]))
1181 continue;
1182 if (!tab->var[i].is_nonneg)
1183 return 0;
1184 if (isl_int_is_neg(tab->mat->row[row][off + col]))
1185 return 0;
1186 }
1187 for (i = 0; i < tab->n_div; ++i) {
1188 if (tab->var[tab->n_var - tab->n_div + i].is_row)
1189 continue;
1190 col = tab->var[tab->n_var - tab->n_div + i].index;
1191 if (isl_int_is_zero(tab->mat->row[row][off + col]))
1192 continue;
1193 if (!tab->var[tab->n_var - tab->n_div + i].is_nonneg)
1194 return 0;
1195 if (isl_int_is_neg(tab->mat->row[row][off + col]))
1196 return 0;
1197 }
1198 return 1;
1199}
1200
1201/* Given a row r and two columns, return the column that would
1202 * lead to the lexicographically smallest increment in the sample
1203 * solution when leaving the basis in favor of the row.
1204 * Pivoting with column c will increment the sample value by a non-negative
1205 * constant times a_{V,c}/a_{r,c}, with a_{V,c} the elements of column c
1206 * corresponding to the non-parametric variables.
1207 * If variable v appears in a column c_v, then a_{v,c} = 1 iff c = c_v,
1208 * with all other entries in this virtual row equal to zero.
1209 * If variable v appears in a row, then a_{v,c} is the element in column c
1210 * of that row.
1211 *
1212 * Let v be the first variable with a_{v,c1}/a_{r,c1} != a_{v,c2}/a_{r,c2}.
1213 * Then if a_{v,c1}/a_{r,c1} < a_{v,c2}/a_{r,c2}, i.e.,
1214 * a_{v,c2} a_{r,c1} - a_{v,c1} a_{r,c2} > 0, c1 results in the minimal
1215 * increment. Otherwise, it's c2.
1216 */
1217static int lexmin_col_pair(struct isl_tab *tab,
1218 int row, int col1, int col2, isl_int tmp)
1219{
1220 int i;
1221 isl_int *tr;
1222
1223 tr = tab->mat->row[row] + 2 + tab->M;
1224
1225 for (i = tab->n_param; i < tab->n_var - tab->n_div; ++i) {
1226 int s1, s2;
1227 isl_int *r;
1228
1229 if (!tab->var[i].is_row) {
1230 if (tab->var[i].index == col1)
1231 return col2;
1232 if (tab->var[i].index == col2)
1233 return col1;
1234 continue;
1235 }
1236
1237 if (tab->var[i].index == row)
1238 continue;
1239
1240 r = tab->mat->row[tab->var[i].index] + 2 + tab->M;
1241 s1 = isl_int_sgn(r[col1]);
1242 s2 = isl_int_sgn(r[col2]);
1243 if (s1 == 0 && s2 == 0)
1244 continue;
1245 if (s1 < s2)
1246 return col1;
1247 if (s2 < s1)
1248 return col2;
1249
1250 isl_int_mul(tmp, r[col2], tr[col1]);
1251 isl_int_submul(tmp, r[col1], tr[col2]);
1252 if (isl_int_is_pos(tmp))
1253 return col1;
1254 if (isl_int_is_neg(tmp))
1255 return col2;
1256 }
1257 return -1;
1258}
1259
1260/* Does the index into the tab->var or tab->con array "index"
1261 * correspond to a variable in the context tableau?
1262 * In particular, it needs to be an index into the tab->var array and
1263 * it needs to refer to either one of the first tab->n_param variables or
1264 * one of the last tab->n_div variables.
1265 */
1266static int is_parameter_var(struct isl_tab *tab, int index)
1267{
1268 if (index < 0)
1269 return 0;
1270 if (index < tab->n_param)
1271 return 1;
1272 if (index >= tab->n_var - tab->n_div)
1273 return 1;
1274 return 0;
1275}
1276
1277/* Does column "col" of "tab" refer to a variable in the context tableau?
1278 */
1279static int col_is_parameter_var(struct isl_tab *tab, int col)
1280{
1281 return is_parameter_var(tab, tab->col_var[col]);
1282}
1283
1284/* Does row "row" of "tab" refer to a variable in the context tableau?
1285 */
1286static int row_is_parameter_var(struct isl_tab *tab, int row)
1287{
1288 return is_parameter_var(tab, tab->row_var[row]);
1289}
1290
1291/* Given a row in the tableau, find and return the column that would
1292 * result in the lexicographically smallest, but positive, increment
1293 * in the sample point.
1294 * If there is no such column, then return tab->n_col.
1295 * If anything goes wrong, return -1.
1296 */
1297static int lexmin_pivot_col(struct isl_tab *tab, int row)
1298{
1299 int j;
1300 int col = tab->n_col;
1301 isl_int *tr;
1302 isl_int tmp;
1303
1304 tr = tab->mat->row[row] + 2 + tab->M;
1305
1306 isl_int_init(tmp);
1307
1308 for (j = tab->n_dead; j < tab->n_col; ++j) {
1309 if (col_is_parameter_var(tab, j))
1310 continue;
1311
1312 if (!isl_int_is_pos(tr[j]))
1313 continue;
1314
1315 if (col == tab->n_col)
1316 col = j;
1317 else
1318 col = lexmin_col_pair(tab, row, col, j, tmp);
1319 isl_assert(tab->mat->ctx, col >= 0, goto error);
1320 }
1321
1322 isl_int_clear(tmp);
1323 return col;
1324error:
1325 isl_int_clear(tmp);
1326 return -1;
1327}
1328
1329/* Return the first known violated constraint, i.e., a non-negative
1330 * constraint that currently has an either obviously negative value
1331 * or a previously determined to be negative value.
1332 *
1333 * If any constraint has a negative coefficient for the big parameter,
1334 * if any, then we return one of these first.
1335 */
1336static int first_neg(struct isl_tab *tab)
1337{
1338 int row;
1339
1340 if (tab->M)
1341 for (row = tab->n_redundant; row < tab->n_row; ++row) {
1342 if (!isl_tab_var_from_row(tab, row)->is_nonneg)
1343 continue;
1344 if (!isl_int_is_neg(tab->mat->row[row][2]))
1345 continue;
1346 if (tab->row_sign)
1347 tab->row_sign[row] = isl_tab_row_neg;
1348 return row;
1349 }
1350 for (row = tab->n_redundant; row < tab->n_row; ++row) {
1351 if (!isl_tab_var_from_row(tab, row)->is_nonneg)
1352 continue;
1353 if (tab->row_sign) {
1354 if (tab->row_sign[row] == 0 &&
1355 is_obviously_neg(tab, row))
1356 tab->row_sign[row] = isl_tab_row_neg;
1357 if (tab->row_sign[row] != isl_tab_row_neg)
1358 continue;
1359 } else if (!is_obviously_neg(tab, row))
1360 continue;
1361 return row;
1362 }
1363 return -1;
1364}
1365
1366/* Check whether the invariant that all columns are lexico-positive
1367 * is satisfied. This function is not called from the current code
1368 * but is useful during debugging.
1369 */
1370static void check_lexpos(struct isl_tab *tab) __attribute__ ((unused));
1371static void check_lexpos(struct isl_tab *tab)
1372{
1373 unsigned off = 2 + tab->M;
1374 int col;
1375 int var;
1376 int row;
1377
1378 for (col = tab->n_dead; col < tab->n_col; ++col) {
1379 if (col_is_parameter_var(tab, col))
1380 continue;
1381 for (var = tab->n_param; var < tab->n_var - tab->n_div; ++var) {
1382 if (!tab->var[var].is_row) {
1383 if (tab->var[var].index == col)
1384 break;
1385 else
1386 continue;
1387 }
1388 row = tab->var[var].index;
1389 if (isl_int_is_zero(tab->mat->row[row][off + col]))
1390 continue;
1391 if (isl_int_is_pos(tab->mat->row[row][off + col]))
1392 break;
1393 fprintf(stderr, "lexneg column %d (row %d)\n",
1394 col, row);
1395 }
1396 if (var >= tab->n_var - tab->n_div)
1397 fprintf(stderr, "zero column %d\n", col);
1398 }
1399}
1400
1401/* Report to the caller that the given constraint is part of an encountered
1402 * conflict.
1403 */
1404static int report_conflicting_constraint(struct isl_tab *tab, int con)
1405{
1406 return tab->conflict(con, tab->conflict_user);
1407}
1408
1409/* Given a conflicting row in the tableau, report all constraints
1410 * involved in the row to the caller. That is, the row itself
1411 * (if it represents a constraint) and all constraint columns with
1412 * non-zero (and therefore negative) coefficients.
1413 */
1414static int report_conflict(struct isl_tab *tab, int row)
1415{
1416 int j;
1417 isl_int *tr;
1418
1419 if (!tab->conflict)
1420 return 0;
1421
1422 if (tab->row_var[row] < 0 &&
1423 report_conflicting_constraint(tab, ~tab->row_var[row]) < 0)
1424 return -1;
1425
1426 tr = tab->mat->row[row] + 2 + tab->M;
1427
1428 for (j = tab->n_dead; j < tab->n_col; ++j) {
1429 if (col_is_parameter_var(tab, j))
1430 continue;
1431
1432 if (!isl_int_is_neg(tr[j]))
1433 continue;
1434
1435 if (tab->col_var[j] < 0 &&
1436 report_conflicting_constraint(tab, ~tab->col_var[j]) < 0)
1437 return -1;
1438 }
1439
1440 return 0;
1441}
1442
1443/* Resolve all known or obviously violated constraints through pivoting.
1444 * In particular, as long as we can find any violated constraint, we
1445 * look for a pivoting column that would result in the lexicographically
1446 * smallest increment in the sample point. If there is no such column
1447 * then the tableau is infeasible.
1448 */
1449static int restore_lexmin(struct isl_tab *tab) WARN_UNUSED;
1450static int restore_lexmin(struct isl_tab *tab)
1451{
1452 int row, col;
1453
1454 if (!tab)
1455 return -1;
1456 if (tab->empty)
1457 return 0;
1458 while ((row = first_neg(tab)) != -1) {
1459 col = lexmin_pivot_col(tab, row);
1460 if (col >= tab->n_col) {
1461 if (report_conflict(tab, row) < 0)
1462 return -1;
1463 if (isl_tab_mark_empty(tab) < 0)
1464 return -1;
1465 return 0;
1466 }
1467 if (col < 0)
1468 return -1;
1469 if (isl_tab_pivot(tab, row, col) < 0)
1470 return -1;
1471 }
1472 return 0;
1473}
1474
1475/* Given a row that represents an equality, look for an appropriate
1476 * pivoting column.
1477 * In particular, if there are any non-zero coefficients among
1478 * the non-parameter variables, then we take the last of these
1479 * variables. Eliminating this variable in terms of the other
1480 * variables and/or parameters does not influence the property
1481 * that all column in the initial tableau are lexicographically
1482 * positive. The row corresponding to the eliminated variable
1483 * will only have non-zero entries below the diagonal of the
1484 * initial tableau. That is, we transform
1485 *
1486 * I I
1487 * 1 into a
1488 * I I
1489 *
1490 * If there is no such non-parameter variable, then we are dealing with
1491 * pure parameter equality and we pick any parameter with coefficient 1 or -1
1492 * for elimination. This will ensure that the eliminated parameter
1493 * always has an integer value whenever all the other parameters are integral.
1494 * If there is no such parameter then we return -1.
1495 */
1496static int last_var_col_or_int_par_col(struct isl_tab *tab, int row)
1497{
1498 unsigned off = 2 + tab->M;
1499 int i;
1500
1501 for (i = tab->n_var - tab->n_div - 1; i >= 0 && i >= tab->n_param; --i) {
1502 int col;
1503 if (tab->var[i].is_row)
1504 continue;
1505 col = tab->var[i].index;
1506 if (col <= tab->n_dead)
1507 continue;
1508 if (!isl_int_is_zero(tab->mat->row[row][off + col]))
1509 return col;
1510 }
1511 for (i = tab->n_dead; i < tab->n_col; ++i) {
1512 if (isl_int_is_one(tab->mat->row[row][off + i]))
1513 return i;
1514 if (isl_int_is_negone(tab->mat->row[row][off + i]))
1515 return i;
1516 }
1517 return -1;
1518}
1519
1520/* Add an equality that is known to be valid to the tableau.
1521 * We first check if we can eliminate a variable or a parameter.
1522 * If not, we add the equality as two inequalities.
1523 * In this case, the equality was a pure parameter equality and there
1524 * is no need to resolve any constraint violations.
1525 *
1526 * This function assumes that at least two more rows and at least
1527 * two more elements in the constraint array are available in the tableau.
1528 */
1529static struct isl_tab *add_lexmin_valid_eq(struct isl_tab *tab, isl_int *eq)
1530{
1531 int i;
1532 int r;
1533
1534 if (!tab)
1535 return NULL;
1536 r = isl_tab_add_row(tab, eq);
1537 if (r < 0)
1538 goto error;
1539
1540 r = tab->con[r].index;
1541 i = last_var_col_or_int_par_col(tab, r);
1542 if (i < 0) {
1543 tab->con[r].is_nonneg = 1;
1544 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
1545 goto error;
1546 isl_seq_neg(eq, eq, 1 + tab->n_var);
1547 r = isl_tab_add_row(tab, eq);
1548 if (r < 0)
1549 goto error;
1550 tab->con[r].is_nonneg = 1;
1551 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
1552 goto error;
1553 } else {
1554 if (isl_tab_pivot(tab, r, i) < 0)
1555 goto error;
1556 if (isl_tab_kill_col(tab, i) < 0)
1557 goto error;
1558 tab->n_eq++;
1559 }
1560
1561 return tab;
1562error:
1563 isl_tab_free(tab);
1564 return NULL;
1565}
1566
1567/* Check if the given row is a pure constant.
1568 */
1569static int is_constant(struct isl_tab *tab, int row)
1570{
1571 unsigned off = 2 + tab->M;
1572
1573 return !isl_seq_any_non_zero(tab->mat->row[row] + off + tab->n_dead,
1574 tab->n_col - tab->n_dead);
1575}
1576
1577/* Is the given row a parametric constant?
1578 * That is, does it only involve variables that also appear in the context?
1579 */
1580static int is_parametric_constant(struct isl_tab *tab, int row)
1581{
1582 unsigned off = 2 + tab->M;
1583 int col;
1584
1585 for (col = tab->n_dead; col < tab->n_col; ++col) {
1586 if (col_is_parameter_var(tab, col))
1587 continue;
1588 if (isl_int_is_zero(tab->mat->row[row][off + col]))
1589 continue;
1590 return 0;
1591 }
1592
1593 return 1;
1594}
1595
1596/* Add an equality that may or may not be valid to the tableau.
1597 * If the resulting row is a pure constant, then it must be zero.
1598 * Otherwise, the resulting tableau is empty.
1599 *
1600 * If the row is not a pure constant, then we add two inequalities,
1601 * each time checking that they can be satisfied.
1602 * In the end we try to use one of the two constraints to eliminate
1603 * a column.
1604 *
1605 * This function assumes that at least two more rows and at least
1606 * two more elements in the constraint array are available in the tableau.
1607 */
1608static int add_lexmin_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED;
1609static int add_lexmin_eq(struct isl_tab *tab, isl_int *eq)
1610{
1611 int r1, r2;
1612 int row;
1613 struct isl_tab_undo *snap;
1614
1615 if (!tab)
1616 return -1;
1617 snap = isl_tab_snap(tab);
1618 r1 = isl_tab_add_row(tab, eq);
1619 if (r1 < 0)
1620 return -1;
1621 tab->con[r1].is_nonneg = 1;
1622 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r1]) < 0)
1623 return -1;
1624
1625 row = tab->con[r1].index;
1626 if (is_constant(tab, row)) {
1627 if (!isl_int_is_zero(tab->mat->row[row][1]) ||
1628 (tab->M && !isl_int_is_zero(tab->mat->row[row][2]))) {
1629 if (isl_tab_mark_empty(tab) < 0)
1630 return -1;
1631 return 0;
1632 }
1633 if (isl_tab_rollback(tab, snap) < 0)
1634 return -1;
1635 return 0;
1636 }
1637
1638 if (restore_lexmin(tab) < 0)
1639 return -1;
1640 if (tab->empty)
1641 return 0;
1642
1643 isl_seq_neg(eq, eq, 1 + tab->n_var);
1644
1645 r2 = isl_tab_add_row(tab, eq);
1646 if (r2 < 0)
1647 return -1;
1648 tab->con[r2].is_nonneg = 1;
1649 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r2]) < 0)
1650 return -1;
1651
1652 if (restore_lexmin(tab) < 0)
1653 return -1;
1654 if (tab->empty)
1655 return 0;
1656
1657 if (!tab->con[r1].is_row) {
1658 if (isl_tab_kill_col(tab, tab->con[r1].index) < 0)
1659 return -1;
1660 } else if (!tab->con[r2].is_row) {
1661 if (isl_tab_kill_col(tab, tab->con[r2].index) < 0)
1662 return -1;
1663 }
1664
1665 if (tab->bmap) {
1666 tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
1668 return -1;
1669 isl_seq_neg(eq, eq, 1 + tab->n_var);
1670 tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
1671 isl_seq_neg(eq, eq, 1 + tab->n_var);
1673 return -1;
1674 if (!tab->bmap)
1675 return -1;
1676 }
1677
1678 return 0;
1679}
1680
1681/* Add an inequality to the tableau, resolving violations using
1682 * restore_lexmin.
1683 *
1684 * This function assumes that at least one more row and at least
1685 * one more element in the constraint array are available in the tableau.
1686 */
1687static struct isl_tab *add_lexmin_ineq(struct isl_tab *tab, isl_int *ineq)
1688{
1689 int r;
1690
1691 if (!tab)
1692 return NULL;
1693 if (tab->bmap) {
1694 tab->bmap = isl_basic_map_add_ineq(tab->bmap, ineq);
1696 goto error;
1697 if (!tab->bmap)
1698 goto error;
1699 }
1700 r = isl_tab_add_row(tab, ineq);
1701 if (r < 0)
1702 goto error;
1703 tab->con[r].is_nonneg = 1;
1704 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
1705 goto error;
1706 if (isl_tab_row_is_redundant(tab, tab->con[r].index)) {
1707 if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
1708 goto error;
1709 return tab;
1710 }
1711
1712 if (restore_lexmin(tab) < 0)
1713 goto error;
1714 if (!tab->empty && tab->con[r].is_row &&
1715 isl_tab_row_is_redundant(tab, tab->con[r].index))
1716 if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
1717 goto error;
1718 return tab;
1719error:
1720 isl_tab_free(tab);
1721 return NULL;
1722}
1723
1724/* Check if the coefficients of the parameters are all integral.
1725 */
1726static int integer_parameter(struct isl_tab *tab, int row)
1727{
1728 int i;
1729 int col;
1730 unsigned off = 2 + tab->M;
1731
1732 for (i = 0; i < tab->n_param; ++i) {
1733 /* Eliminated parameter */
1734 if (tab->var[i].is_row)
1735 continue;
1736 col = tab->var[i].index;
1737 if (!isl_int_is_divisible_by(tab->mat->row[row][off + col],
1738 tab->mat->row[row][0]))
1739 return 0;
1740 }
1741 for (i = 0; i < tab->n_div; ++i) {
1742 if (tab->var[tab->n_var - tab->n_div + i].is_row)
1743 continue;
1744 col = tab->var[tab->n_var - tab->n_div + i].index;
1745 if (!isl_int_is_divisible_by(tab->mat->row[row][off + col],
1746 tab->mat->row[row][0]))
1747 return 0;
1748 }
1749 return 1;
1750}
1751
1752/* Check if the coefficients of the non-parameter variables are all integral.
1753 */
1754static int integer_variable(struct isl_tab *tab, int row)
1755{
1756 int i;
1757 unsigned off = 2 + tab->M;
1758
1759 for (i = tab->n_dead; i < tab->n_col; ++i) {
1760 if (col_is_parameter_var(tab, i))
1761 continue;
1762 if (!isl_int_is_divisible_by(tab->mat->row[row][off + i],
1763 tab->mat->row[row][0]))
1764 return 0;
1765 }
1766 return 1;
1767}
1768
1769/* Check if the constant term is integral.
1770 */
1771static int integer_constant(struct isl_tab *tab, int row)
1772{
1773 return isl_int_is_divisible_by(tab->mat->row[row][1],
1774 tab->mat->row[row][0]);
1775}
1776
1777#define I_CST 1 << 0
1778#define I_PAR 1 << 1
1779#define I_VAR 1 << 2
1780
1781/* Check for next (non-parameter) variable after "var" (first if var == -1)
1782 * that is non-integer and therefore requires a cut and return
1783 * the index of the variable.
1784 * For parametric tableaus, there are three parts in a row,
1785 * the constant, the coefficients of the parameters and the rest.
1786 * For each part, we check whether the coefficients in that part
1787 * are all integral and if so, set the corresponding flag in *f.
1788 * If the constant and the parameter part are integral, then the
1789 * current sample value is integral and no cut is required
1790 * (irrespective of whether the variable part is integral).
1791 */
1792static int next_non_integer_var(struct isl_tab *tab, int var, int *f)
1793{
1794 var = var < 0 ? tab->n_param : var + 1;
1795
1796 for (; var < tab->n_var - tab->n_div; ++var) {
1797 int flags = 0;
1798 int row;
1799 if (!tab->var[var].is_row)
1800 continue;
1801 row = tab->var[var].index;
1802 if (integer_constant(tab, row))
1803 ISL_FL_SET(flags, I_CST);
1804 if (integer_parameter(tab, row))
1805 ISL_FL_SET(flags, I_PAR);
1806 if (ISL_FL_ISSET(flags, I_CST) && ISL_FL_ISSET(flags, I_PAR))
1807 continue;
1808 if (integer_variable(tab, row))
1809 ISL_FL_SET(flags, I_VAR);
1810 *f = flags;
1811 return var;
1812 }
1813 return -1;
1814}
1815
1816/* Check for first (non-parameter) variable that is non-integer and
1817 * therefore requires a cut and return the corresponding row.
1818 * For parametric tableaus, there are three parts in a row,
1819 * the constant, the coefficients of the parameters and the rest.
1820 * For each part, we check whether the coefficients in that part
1821 * are all integral and if so, set the corresponding flag in *f.
1822 * If the constant and the parameter part are integral, then the
1823 * current sample value is integral and no cut is required
1824 * (irrespective of whether the variable part is integral).
1825 */
1826static int first_non_integer_row(struct isl_tab *tab, int *f)
1827{
1828 int var = next_non_integer_var(tab, -1, f);
1829
1830 return var < 0 ? -1 : tab->var[var].index;
1831}
1832
1833/* Add a (non-parametric) cut to cut away the non-integral sample
1834 * value of the given row.
1835 *
1836 * If the row is given by
1837 *
1838 * m r = f + \sum_i a_i y_i
1839 *
1840 * then the cut is
1841 *
1842 * c = - {-f/m} + \sum_i {a_i/m} y_i >= 0
1843 *
1844 * The big parameter, if any, is ignored, since it is assumed to be big
1845 * enough to be divisible by any integer.
1846 * If the tableau is actually a parametric tableau, then this function
1847 * is only called when all coefficients of the parameters are integral.
1848 * The cut therefore has zero coefficients for the parameters.
1849 *
1850 * The current value is known to be negative, so row_sign, if it
1851 * exists, is set accordingly.
1852 *
1853 * Return the row of the cut or -1.
1854 */
1855static int add_cut(struct isl_tab *tab, int row)
1856{
1857 int i;
1858 int r;
1859 isl_int *r_row;
1860 unsigned off = 2 + tab->M;
1861
1862 if (isl_tab_extend_cons(tab, 1) < 0)
1863 return -1;
1864 r = isl_tab_allocate_con(tab);
1865 if (r < 0)
1866 return -1;
1867
1868 r_row = tab->mat->row[tab->con[r].index];
1869 isl_int_set(r_row[0], tab->mat->row[row][0]);
1870 isl_int_neg(r_row[1], tab->mat->row[row][1]);
1871 isl_int_fdiv_r(r_row[1], r_row[1], tab->mat->row[row][0]);
1872 isl_int_neg(r_row[1], r_row[1]);
1873 if (tab->M)
1874 isl_int_set_si(r_row[2], 0);
1875 for (i = 0; i < tab->n_col; ++i)
1876 isl_int_fdiv_r(r_row[off + i],
1877 tab->mat->row[row][off + i], tab->mat->row[row][0]);
1878
1879 tab->con[r].is_nonneg = 1;
1880 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
1881 return -1;
1882 if (tab->row_sign)
1883 tab->row_sign[tab->con[r].index] = isl_tab_row_neg;
1884
1885 return tab->con[r].index;
1886}
1887
1888#define CUT_ALL 1
1889#define CUT_ONE 0
1890
1891/* Given a non-parametric tableau, add cuts until an integer
1892 * sample point is obtained or until the tableau is determined
1893 * to be integer infeasible.
1894 * As long as there is any non-integer value in the sample point,
1895 * we add appropriate cuts, if possible, for each of these
1896 * non-integer values and then resolve the violated
1897 * cut constraints using restore_lexmin.
1898 * If one of the corresponding rows is equal to an integral
1899 * combination of variables/constraints plus a non-integral constant,
1900 * then there is no way to obtain an integer point and we return
1901 * a tableau that is marked empty.
1902 * The parameter cutting_strategy controls the strategy used when adding cuts
1903 * to remove non-integer points. CUT_ALL adds all possible cuts
1904 * before continuing the search. CUT_ONE adds only one cut at a time.
1905 */
1906static struct isl_tab *cut_to_integer_lexmin(struct isl_tab *tab,
1907 int cutting_strategy)
1908{
1909 int var;
1910 int row;
1911 int flags;
1912
1913 if (!tab)
1914 return NULL;
1915 if (tab->empty)
1916 return tab;
1917
1918 while ((var = next_non_integer_var(tab, -1, &flags)) != -1) {
1919 do {
1920 if (ISL_FL_ISSET(flags, I_VAR)) {
1921 if (isl_tab_mark_empty(tab) < 0)
1922 goto error;
1923 return tab;
1924 }
1925 row = tab->var[var].index;
1926 row = add_cut(tab, row);
1927 if (row < 0)
1928 goto error;
1929 if (cutting_strategy == CUT_ONE)
1930 break;
1931 } while ((var = next_non_integer_var(tab, var, &flags)) != -1);
1932 if (restore_lexmin(tab) < 0)
1933 goto error;
1934 if (tab->empty)
1935 break;
1936 }
1937 return tab;
1938error:
1939 isl_tab_free(tab);
1940 return NULL;
1941}
1942
1943/* Check whether all the currently active samples also satisfy the inequality
1944 * "ineq" (treated as an equality if eq is set).
1945 * Remove those samples that do not.
1946 */
1947static struct isl_tab *check_samples(struct isl_tab *tab, isl_int *ineq, int eq)
1948{
1949 int i;
1950 isl_int v;
1951
1952 if (!tab)
1953 return NULL;
1954
1955 isl_assert(tab->mat->ctx, tab->bmap, goto error);
1956 isl_assert(tab->mat->ctx, tab->samples, goto error);
1957 isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var, goto error);
1958
1959 isl_int_init(v);
1960 for (i = tab->n_outside; i < tab->n_sample; ++i) {
1961 int sgn;
1962 isl_seq_inner_product(ineq, tab->samples->row[i],
1963 1 + tab->n_var, &v);
1964 sgn = isl_int_sgn(v);
1965 if (eq ? (sgn == 0) : (sgn >= 0))
1966 continue;
1967 tab = isl_tab_drop_sample(tab, i);
1968 if (!tab)
1969 break;
1970 }
1971 isl_int_clear(v);
1972
1973 return tab;
1974error:
1975 isl_tab_free(tab);
1976 return NULL;
1977}
1978
1979/* Check whether the sample value of the tableau is finite,
1980 * i.e., either the tableau does not use a big parameter, or
1981 * all values of the variables are equal to the big parameter plus
1982 * some constant. This constant is the actual sample value.
1983 */
1984static int sample_is_finite(struct isl_tab *tab)
1985{
1986 int i;
1987
1988 if (!tab->M)
1989 return 1;
1990
1991 for (i = 0; i < tab->n_var; ++i) {
1992 int row;
1993 if (!tab->var[i].is_row)
1994 return 0;
1995 row = tab->var[i].index;
1996 if (isl_int_ne(tab->mat->row[row][0], tab->mat->row[row][2]))
1997 return 0;
1998 }
1999 return 1;
2000}
2001
2002/* Check if the context tableau of sol has any integer points.
2003 * Leave tab in empty state if no integer point can be found.
2004 * If an integer point can be found and if moreover it is finite,
2005 * then it is added to the list of sample values.
2006 *
2007 * This function is only called when none of the currently active sample
2008 * values satisfies the most recently added constraint.
2009 */
2010static struct isl_tab *check_integer_feasible(struct isl_tab *tab)
2011{
2012 struct isl_tab_undo *snap;
2013
2014 if (!tab)
2015 return NULL;
2016
2017 snap = isl_tab_snap(tab);
2018 if (isl_tab_push_basis(tab) < 0)
2019 goto error;
2020
2021 tab = cut_to_integer_lexmin(tab, CUT_ALL);
2022 if (!tab)
2023 goto error;
2024
2025 if (!tab->empty && sample_is_finite(tab)) {
2026 struct isl_vec *sample;
2027
2028 sample = isl_tab_get_sample_value(tab);
2029
2030 if (isl_tab_add_sample(tab, sample) < 0)
2031 goto error;
2032 }
2033
2034 if (!tab->empty && isl_tab_rollback(tab, snap) < 0)
2035 goto error;
2036
2037 return tab;
2038error:
2039 isl_tab_free(tab);
2040 return NULL;
2041}
2042
2043/* Check if any of the currently active sample values satisfies
2044 * the inequality "ineq" (an equality if eq is set).
2045 */
2046static int tab_has_valid_sample(struct isl_tab *tab, isl_int *ineq, int eq)
2047{
2048 int i;
2049 isl_int v;
2050
2051 if (!tab)
2052 return -1;
2053
2054 isl_assert(tab->mat->ctx, tab->bmap, return -1);
2055 isl_assert(tab->mat->ctx, tab->samples, return -1);
2056 isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var, return -1);
2057
2058 isl_int_init(v);
2059 for (i = tab->n_outside; i < tab->n_sample; ++i) {
2060 int sgn;
2061 isl_seq_inner_product(ineq, tab->samples->row[i],
2062 1 + tab->n_var, &v);
2063 sgn = isl_int_sgn(v);
2064 if (eq ? (sgn == 0) : (sgn >= 0))
2065 break;
2066 }
2067 isl_int_clear(v);
2068
2069 return i < tab->n_sample;
2070}
2071
2072/* Insert a div specified by "div" to the tableau "tab" at position "pos" and
2073 * return isl_bool_true if the div is obviously non-negative.
2074 */
2076 __isl_keep isl_vec *div,
2077 isl_stat (*add_ineq)(void *user, isl_int *), void *user)
2078{
2079 int i;
2080 int r;
2081 struct isl_mat *samples;
2082 int nonneg;
2083
2084 r = isl_tab_insert_div(tab, pos, div, add_ineq, user);
2085 if (r < 0)
2086 return isl_bool_error;
2087 nonneg = tab->var[r].is_nonneg;
2088 tab->var[r].frozen = 1;
2089
2090 samples = isl_mat_extend(tab->samples,
2091 tab->n_sample, 1 + tab->n_var);
2092 tab->samples = samples;
2093 if (!samples)
2094 return isl_bool_error;
2095 for (i = tab->n_outside; i < samples->n_row; ++i) {
2096 isl_seq_inner_product(div->el + 1, samples->row[i],
2097 div->size - 1, &samples->row[i][samples->n_col - 1]);
2098 isl_int_fdiv_q(samples->row[i][samples->n_col - 1],
2099 samples->row[i][samples->n_col - 1], div->el[0]);
2100 }
2101 tab->samples = isl_mat_move_cols(tab->samples, 1 + pos,
2102 1 + tab->n_var - 1, 1);
2103 if (!tab->samples)
2104 return isl_bool_error;
2105
2106 return isl_bool_ok(nonneg);
2107}
2108
2109/* Add a div specified by "div" to both the main tableau and
2110 * the context tableau. In case of the main tableau, we only
2111 * need to add an extra div. In the context tableau, we also
2112 * need to express the meaning of the div.
2113 * Return the index of the div or -1 if anything went wrong.
2114 *
2115 * The new integer division is added before any unknown integer
2116 * divisions in the context to ensure that it does not get
2117 * equated to some linear combination involving unknown integer
2118 * divisions.
2119 */
2120static int add_div(struct isl_tab *tab, struct isl_context *context,
2121 __isl_keep isl_vec *div)
2122{
2123 int r;
2124 int pos;
2125 isl_bool nonneg;
2126 struct isl_tab *context_tab = context->op->peek_tab(context);
2127
2128 if (!tab || !context_tab)
2129 goto error;
2130
2131 pos = context_tab->n_var - context->n_unknown;
2132 if ((nonneg = context->op->insert_div(context, pos, div)) < 0)
2133 goto error;
2134
2135 if (!context->op->is_ok(context))
2136 goto error;
2137
2138 pos = tab->n_var - context->n_unknown;
2139 if (isl_tab_extend_vars(tab, 1) < 0)
2140 goto error;
2141 r = isl_tab_insert_var(tab, pos);
2142 if (r < 0)
2143 goto error;
2144 if (nonneg)
2145 tab->var[r].is_nonneg = 1;
2146 tab->var[r].frozen = 1;
2147 tab->n_div++;
2148
2149 return tab->n_div - 1 - context->n_unknown;
2150error:
2151 context->op->invalidate(context);
2152 return -1;
2153}
2154
2155/* Return the position of the integer division that is equal to div/denom
2156 * if there is one. Otherwise, return a position beyond the integer divisions.
2157 */
2158static int find_div(struct isl_tab *tab, isl_int *div, isl_int denom)
2159{
2160 int i;
2163
2165 if (total < 0 || n_div < 0)
2166 return -1;
2167 for (i = 0; i < n_div; ++i) {
2168 if (isl_int_ne(tab->bmap->div[i][0], denom))
2169 continue;
2170 if (!isl_seq_eq(tab->bmap->div[i] + 1, div, 1 + total))
2171 continue;
2172 return i;
2173 }
2174 return n_div;
2175}
2176
2177/* Return the index of a div that corresponds to "div".
2178 * We first check if we already have such a div and if not, we create one.
2179 */
2180static int get_div(struct isl_tab *tab, struct isl_context *context,
2181 struct isl_vec *div)
2182{
2183 int d;
2184 struct isl_tab *context_tab = context->op->peek_tab(context);
2185 unsigned n_div;
2186
2187 if (!context_tab)
2188 return -1;
2189
2190 n_div = isl_basic_map_dim(context_tab->bmap, isl_dim_div);
2191 d = find_div(context_tab, div->el + 1, div->el[0]);
2192 if (d < 0)
2193 return -1;
2194 if (d < n_div)
2195 return d;
2196
2197 return add_div(tab, context, div);
2198}
2199
2200/* Add a parametric cut to cut away the non-integral sample value
2201 * of the given row.
2202 * Let a_i be the coefficients of the constant term and the parameters
2203 * and let b_i be the coefficients of the variables or constraints
2204 * in basis of the tableau.
2205 * Let q be the div q = floor(\sum_i {-a_i} y_i).
2206 *
2207 * The cut is expressed as
2208 *
2209 * c = \sum_i -{-a_i} y_i + \sum_i {b_i} x_i + q >= 0
2210 *
2211 * If q did not already exist in the context tableau, then it is added first.
2212 * If q is in a column of the main tableau then the "+ q" can be accomplished
2213 * by setting the corresponding entry to the denominator of the constraint.
2214 * If q happens to be in a row of the main tableau, then the corresponding
2215 * row needs to be added instead (taking care of the denominators).
2216 * Note that this is very unlikely, but perhaps not entirely impossible.
2217 *
2218 * The current value of the cut is known to be negative (or at least
2219 * non-positive), so row_sign is set accordingly.
2220 *
2221 * Return the row of the cut or -1.
2222 */
2223static int add_parametric_cut(struct isl_tab *tab, int row,
2224 struct isl_context *context)
2225{
2226 struct isl_vec *div;
2227 int d;
2228 int i;
2229 int r;
2230 isl_int *r_row;
2231 int col;
2232 int n;
2233 unsigned off = 2 + tab->M;
2234
2235 if (!context)
2236 return -1;
2237
2238 div = get_row_parameter_div(tab, row);
2239 if (!div)
2240 return -1;
2241
2242 n = tab->n_div - context->n_unknown;
2243 d = context->op->get_div(context, tab, div);
2244 isl_vec_free(div);
2245 if (d < 0)
2246 return -1;
2247
2248 if (isl_tab_extend_cons(tab, 1) < 0)
2249 return -1;
2250 r = isl_tab_allocate_con(tab);
2251 if (r < 0)
2252 return -1;
2253
2254 r_row = tab->mat->row[tab->con[r].index];
2255 isl_int_set(r_row[0], tab->mat->row[row][0]);
2256 isl_int_neg(r_row[1], tab->mat->row[row][1]);
2257 isl_int_fdiv_r(r_row[1], r_row[1], tab->mat->row[row][0]);
2258 isl_int_neg(r_row[1], r_row[1]);
2259 if (tab->M)
2260 isl_int_set_si(r_row[2], 0);
2261 for (i = 0; i < tab->n_param; ++i) {
2262 if (tab->var[i].is_row)
2263 continue;
2264 col = tab->var[i].index;
2265 isl_int_neg(r_row[off + col], tab->mat->row[row][off + col]);
2266 isl_int_fdiv_r(r_row[off + col], r_row[off + col],
2267 tab->mat->row[row][0]);
2268 isl_int_neg(r_row[off + col], r_row[off + col]);
2269 }
2270 for (i = 0; i < tab->n_div; ++i) {
2271 if (tab->var[tab->n_var - tab->n_div + i].is_row)
2272 continue;
2273 col = tab->var[tab->n_var - tab->n_div + i].index;
2274 isl_int_neg(r_row[off + col], tab->mat->row[row][off + col]);
2275 isl_int_fdiv_r(r_row[off + col], r_row[off + col],
2276 tab->mat->row[row][0]);
2277 isl_int_neg(r_row[off + col], r_row[off + col]);
2278 }
2279 for (i = 0; i < tab->n_col; ++i) {
2280 if (tab->col_var[i] >= 0 &&
2281 (tab->col_var[i] < tab->n_param ||
2282 tab->col_var[i] >= tab->n_var - tab->n_div))
2283 continue;
2284 isl_int_fdiv_r(r_row[off + i],
2285 tab->mat->row[row][off + i], tab->mat->row[row][0]);
2286 }
2287 if (tab->var[tab->n_var - tab->n_div + d].is_row) {
2288 isl_int gcd;
2289 int d_row = tab->var[tab->n_var - tab->n_div + d].index;
2291 isl_int_gcd(gcd, tab->mat->row[d_row][0], r_row[0]);
2292 isl_int_divexact(r_row[0], r_row[0], gcd);
2293 isl_int_divexact(gcd, tab->mat->row[d_row][0], gcd);
2294 isl_seq_combine(r_row + 1, gcd, r_row + 1,
2295 r_row[0], tab->mat->row[d_row] + 1,
2296 off - 1 + tab->n_col);
2297 isl_int_mul(r_row[0], r_row[0], tab->mat->row[d_row][0]);
2299 } else {
2300 col = tab->var[tab->n_var - tab->n_div + d].index;
2301 isl_int_set(r_row[off + col], tab->mat->row[row][0]);
2302 }
2303
2304 tab->con[r].is_nonneg = 1;
2305 if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
2306 return -1;
2307 if (tab->row_sign)
2308 tab->row_sign[tab->con[r].index] = isl_tab_row_neg;
2309
2310 row = tab->con[r].index;
2311
2312 if (d >= n && context->op->detect_equalities(context, tab) < 0)
2313 return -1;
2314
2315 return row;
2316}
2317
2318/* Construct a tableau for bmap that can be used for computing
2319 * the lexicographic minimum (or maximum) of bmap.
2320 * If not NULL, then dom is the domain where the minimum
2321 * should be computed. In this case, we set up a parametric
2322 * tableau with row signs (initialized to "unknown").
2323 * If M is set, then the tableau will use a big parameter.
2324 * If max is set, then a maximum should be computed instead of a minimum.
2325 * This means that for each variable x, the tableau will contain the variable
2326 * x' = M - x, rather than x' = M + x. This in turn means that the coefficient
2327 * of the variables in all constraints are negated prior to adding them
2328 * to the tableau.
2329 */
2331 __isl_keep isl_basic_set *dom, unsigned M, int max)
2332{
2333 int i;
2334 struct isl_tab *tab;
2335 unsigned n_var;
2336 unsigned o_var;
2338
2340 if (total < 0)
2341 return NULL;
2342 tab = isl_tab_alloc(bmap->ctx, 2 * bmap->n_eq + bmap->n_ineq + 1,
2343 total, M);
2344 if (!tab)
2345 return NULL;
2346
2348 if (dom) {
2349 isl_size dom_total;
2350 dom_total = isl_basic_set_dim(dom, isl_dim_all);
2351 if (dom_total < 0)
2352 goto error;
2353 tab->n_param = dom_total - dom->n_div;
2354 tab->n_div = dom->n_div;
2356 enum isl_tab_row_sign, tab->mat->n_row);
2357 if (tab->mat->n_row && !tab->row_sign)
2358 goto error;
2359 }
2361 if (isl_tab_mark_empty(tab) < 0)
2362 goto error;
2363 return tab;
2364 }
2365
2366 for (i = tab->n_param; i < tab->n_var - tab->n_div; ++i) {
2367 tab->var[i].is_nonneg = 1;
2368 tab->var[i].frozen = 1;
2369 }
2370 o_var = 1 + tab->n_param;
2371 n_var = tab->n_var - tab->n_param - tab->n_div;
2372 for (i = 0; i < bmap->n_eq; ++i) {
2373 if (max)
2374 isl_seq_neg(bmap->eq[i] + o_var,
2375 bmap->eq[i] + o_var, n_var);
2376 tab = add_lexmin_valid_eq(tab, bmap->eq[i]);
2377 if (max)
2378 isl_seq_neg(bmap->eq[i] + o_var,
2379 bmap->eq[i] + o_var, n_var);
2380 if (!tab || tab->empty)
2381 return tab;
2382 }
2383 if (bmap->n_eq && restore_lexmin(tab) < 0)
2384 goto error;
2385 for (i = 0; i < bmap->n_ineq; ++i) {
2386 if (max)
2387 isl_seq_neg(bmap->ineq[i] + o_var,
2388 bmap->ineq[i] + o_var, n_var);
2389 tab = add_lexmin_ineq(tab, bmap->ineq[i]);
2390 if (max)
2391 isl_seq_neg(bmap->ineq[i] + o_var,
2392 bmap->ineq[i] + o_var, n_var);
2393 if (!tab || tab->empty)
2394 return tab;
2395 }
2396 return tab;
2397error:
2398 isl_tab_free(tab);
2399 return NULL;
2400}
2401
2402/* Given a main tableau where more than one row requires a split,
2403 * determine and return the "best" row to split on.
2404 *
2405 * If any of the rows requiring a split only involves
2406 * variables that also appear in the context tableau,
2407 * then the negative part is guaranteed not to have a solution.
2408 * It is therefore best to split on any of these rows first.
2409 *
2410 * Otherwise,
2411 * given two rows in the main tableau, if the inequality corresponding
2412 * to the first row is redundant with respect to that of the second row
2413 * in the current tableau, then it is better to split on the second row,
2414 * since in the positive part, both rows will be positive.
2415 * (In the negative part a pivot will have to be performed and just about
2416 * anything can happen to the sign of the other row.)
2417 *
2418 * As a simple heuristic, we therefore select the row that makes the most
2419 * of the other rows redundant.
2420 *
2421 * Perhaps it would also be useful to look at the number of constraints
2422 * that conflict with any given constraint.
2423 *
2424 * best is the best row so far (-1 when we have not found any row yet).
2425 * best_r is the number of other rows made redundant by row best.
2426 * When best is still -1, bset_r is meaningless, but it is initialized
2427 * to some arbitrary value (0) anyway. Without this redundant initialization
2428 * valgrind may warn about uninitialized memory accesses when isl
2429 * is compiled with some versions of gcc.
2430 */
2431static int best_split(struct isl_tab *tab, struct isl_tab *context_tab)
2432{
2433 struct isl_tab_undo *snap;
2434 int split;
2435 int row;
2436 int best = -1;
2437 int best_r = 0;
2438
2439 if (isl_tab_extend_cons(context_tab, 2) < 0)
2440 return -1;
2441
2442 snap = isl_tab_snap(context_tab);
2443
2444 for (split = tab->n_redundant; split < tab->n_row; ++split) {
2445 struct isl_tab_undo *snap2;
2446 struct isl_vec *ineq = NULL;
2447 int r = 0;
2448 int ok;
2449
2450 if (!isl_tab_var_from_row(tab, split)->is_nonneg)
2451 continue;
2452 if (tab->row_sign[split] != isl_tab_row_any)
2453 continue;
2454
2455 if (is_parametric_constant(tab, split))
2456 return split;
2457
2458 ineq = get_row_parameter_ineq(tab, split);
2459 if (!ineq)
2460 return -1;
2461 ok = isl_tab_add_ineq(context_tab, ineq->el) >= 0;
2462 isl_vec_free(ineq);
2463 if (!ok)
2464 return -1;
2465
2466 snap2 = isl_tab_snap(context_tab);
2467
2468 for (row = tab->n_redundant; row < tab->n_row; ++row) {
2469 struct isl_tab_var *var;
2470
2471 if (row == split)
2472 continue;
2473 if (!isl_tab_var_from_row(tab, row)->is_nonneg)
2474 continue;
2475 if (tab->row_sign[row] != isl_tab_row_any)
2476 continue;
2477
2478 ineq = get_row_parameter_ineq(tab, row);
2479 if (!ineq)
2480 return -1;
2481 ok = isl_tab_add_ineq(context_tab, ineq->el) >= 0;
2482 isl_vec_free(ineq);
2483 if (!ok)
2484 return -1;
2485 var = &context_tab->con[context_tab->n_con - 1];
2486 if (!context_tab->empty &&
2487 !isl_tab_min_at_most_neg_one(context_tab, var))
2488 r++;
2489 if (isl_tab_rollback(context_tab, snap2) < 0)
2490 return -1;
2491 }
2492 if (best == -1 || r > best_r) {
2493 best = split;
2494 best_r = r;
2495 }
2496 if (isl_tab_rollback(context_tab, snap) < 0)
2497 return -1;
2498 }
2499
2500 return best;
2501}
2502
2504 struct isl_context *context)
2505{
2506 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2507 if (!clex->tab)
2508 return NULL;
2509 return isl_tab_peek_bset(clex->tab);
2510}
2511
2513{
2514 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2515 return clex->tab;
2516}
2517
2519 int check, int update)
2520{
2521 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2522 if (isl_tab_extend_cons(clex->tab, 2) < 0)
2523 goto error;
2524 if (add_lexmin_eq(clex->tab, eq) < 0)
2525 goto error;
2526 if (check) {
2527 int v = tab_has_valid_sample(clex->tab, eq, 1);
2528 if (v < 0)
2529 goto error;
2530 if (!v)
2531 clex->tab = check_integer_feasible(clex->tab);
2532 }
2533 if (update)
2534 clex->tab = check_samples(clex->tab, eq, 1);
2535 return;
2536error:
2537 isl_tab_free(clex->tab);
2538 clex->tab = NULL;
2539}
2540
2542 int check, int update)
2543{
2544 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2545 if (isl_tab_extend_cons(clex->tab, 1) < 0)
2546 goto error;
2547 clex->tab = add_lexmin_ineq(clex->tab, ineq);
2548 if (check) {
2549 int v = tab_has_valid_sample(clex->tab, ineq, 0);
2550 if (v < 0)
2551 goto error;
2552 if (!v)
2553 clex->tab = check_integer_feasible(clex->tab);
2554 }
2555 if (update)
2556 clex->tab = check_samples(clex->tab, ineq, 0);
2557 return;
2558error:
2559 isl_tab_free(clex->tab);
2560 clex->tab = NULL;
2561}
2562
2564{
2565 struct isl_context *context = (struct isl_context *)user;
2566 context_lex_add_ineq(context, ineq, 0, 0);
2567 return context->op->is_ok(context) ? isl_stat_ok : isl_stat_error;
2568}
2569
2570/* Check which signs can be obtained by "ineq" on all the currently
2571 * active sample values. See row_sign for more information.
2572 */
2573static enum isl_tab_row_sign tab_ineq_sign(struct isl_tab *tab, isl_int *ineq,
2574 int strict)
2575{
2576 int i;
2577 int sgn;
2578 isl_int tmp;
2580
2581 isl_assert(tab->mat->ctx, tab->samples, return isl_tab_row_unknown);
2582 isl_assert(tab->mat->ctx, tab->samples->n_col == 1 + tab->n_var,
2583 return isl_tab_row_unknown);
2584
2585 isl_int_init(tmp);
2586 for (i = tab->n_outside; i < tab->n_sample; ++i) {
2587 isl_seq_inner_product(tab->samples->row[i], ineq,
2588 1 + tab->n_var, &tmp);
2589 sgn = isl_int_sgn(tmp);
2590 if (sgn > 0 || (sgn == 0 && strict)) {
2591 if (res == isl_tab_row_unknown)
2593 if (res == isl_tab_row_neg)
2595 }
2596 if (sgn < 0) {
2597 if (res == isl_tab_row_unknown)
2599 if (res == isl_tab_row_pos)
2601 }
2602 if (res == isl_tab_row_any)
2603 break;
2604 }
2605 isl_int_clear(tmp);
2606
2607 return res;
2608}
2609
2611 isl_int *ineq, int strict)
2612{
2613 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2614 return tab_ineq_sign(clex->tab, ineq, strict);
2615}
2616
2617/* Check whether "ineq" can be added to the tableau without rendering
2618 * it infeasible.
2619 */
2621{
2622 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2623 struct isl_tab_undo *snap;
2624 int feasible;
2625
2626 if (!clex->tab)
2627 return -1;
2628
2629 if (isl_tab_extend_cons(clex->tab, 1) < 0)
2630 return -1;
2631
2632 snap = isl_tab_snap(clex->tab);
2633 if (isl_tab_push_basis(clex->tab) < 0)
2634 return -1;
2635 clex->tab = add_lexmin_ineq(clex->tab, ineq);
2636 clex->tab = check_integer_feasible(clex->tab);
2637 if (!clex->tab)
2638 return -1;
2639 feasible = !clex->tab->empty;
2640 if (isl_tab_rollback(clex->tab, snap) < 0)
2641 return -1;
2642
2643 return feasible;
2644}
2645
2646static int context_lex_get_div(struct isl_context *context, struct isl_tab *tab,
2647 struct isl_vec *div)
2648{
2649 return get_div(tab, context, div);
2650}
2651
2652/* Insert a div specified by "div" to the context tableau at position "pos" and
2653 * return isl_bool_true if the div is obviously non-negative.
2654 * context_tab_add_div will always return isl_bool_true, because all variables
2655 * in a isl_context_lex tableau are non-negative.
2656 * However, if we are using a big parameter in the context, then this only
2657 * reflects the non-negativity of the variable used to _encode_ the
2658 * div, i.e., div' = M + div, so we can't draw any conclusions.
2659 */
2661 __isl_keep isl_vec *div)
2662{
2663 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2664 isl_bool nonneg;
2665 nonneg = context_tab_insert_div(clex->tab, pos, div,
2667 if (nonneg < 0)
2668 return isl_bool_error;
2669 if (clex->tab->M)
2670 return isl_bool_false;
2671 return nonneg;
2672}
2673
2675 struct isl_tab *tab)
2676{
2677 return 0;
2678}
2679
2681 struct isl_tab *tab)
2682{
2683 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2684 struct isl_tab_undo *snap;
2685 int r;
2686
2687 snap = isl_tab_snap(clex->tab);
2688 if (isl_tab_push_basis(clex->tab) < 0)
2689 return -1;
2690 r = best_split(tab, clex->tab);
2691
2692 if (r >= 0 && isl_tab_rollback(clex->tab, snap) < 0)
2693 return -1;
2694
2695 return r;
2696}
2697
2699{
2700 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2701 if (!clex->tab)
2702 return -1;
2703 return clex->tab->empty;
2704}
2705
2707{
2708 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2709 struct isl_tab_undo *snap;
2710
2711 snap = isl_tab_snap(clex->tab);
2712 if (isl_tab_push_basis(clex->tab) < 0)
2713 return NULL;
2714 if (isl_tab_save_samples(clex->tab) < 0)
2715 return NULL;
2716
2717 return snap;
2718}
2719
2720static void context_lex_restore(struct isl_context *context, void *save)
2721{
2722 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2723 if (isl_tab_rollback(clex->tab, (struct isl_tab_undo *)save) < 0) {
2724 isl_tab_free(clex->tab);
2725 clex->tab = NULL;
2726 }
2727}
2728
2729static void context_lex_discard(void *save)
2730{
2731}
2732
2734{
2735 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2736 return !!clex->tab;
2737}
2738
2739/* For each variable in the context tableau, check if the variable can
2740 * only attain non-negative values. If so, mark the parameter as non-negative
2741 * in the main tableau. This allows for a more direct identification of some
2742 * cases of violated constraints.
2743 */
2745 struct isl_tab *context_tab)
2746{
2747 int i;
2748 struct isl_tab_undo *snap;
2749 struct isl_vec *ineq = NULL;
2750 struct isl_tab_var *var;
2751 int n;
2752
2753 if (context_tab->n_var == 0)
2754 return tab;
2755
2756 ineq = isl_vec_alloc(tab->mat->ctx, 1 + context_tab->n_var);
2757 if (!ineq)
2758 goto error;
2759
2760 if (isl_tab_extend_cons(context_tab, 1) < 0)
2761 goto error;
2762
2763 snap = isl_tab_snap(context_tab);
2764
2765 n = 0;
2766 isl_seq_clr(ineq->el, ineq->size);
2767 for (i = 0; i < context_tab->n_var; ++i) {
2768 isl_int_set_si(ineq->el[1 + i], 1);
2769 if (isl_tab_add_ineq(context_tab, ineq->el) < 0)
2770 goto error;
2771 var = &context_tab->con[context_tab->n_con - 1];
2772 if (!context_tab->empty &&
2773 !isl_tab_min_at_most_neg_one(context_tab, var)) {
2774 int j = i;
2775 if (i >= tab->n_param)
2776 j = i - tab->n_param + tab->n_var - tab->n_div;
2777 tab->var[j].is_nonneg = 1;
2778 n++;
2779 }
2780 isl_int_set_si(ineq->el[1 + i], 0);
2781 if (isl_tab_rollback(context_tab, snap) < 0)
2782 goto error;
2783 }
2784
2785 if (context_tab->M && n == context_tab->n_var) {
2786 context_tab->mat = isl_mat_drop_cols(context_tab->mat, 2, 1);
2787 context_tab->M = 0;
2788 }
2789
2790 isl_vec_free(ineq);
2791 return tab;
2792error:
2793 isl_vec_free(ineq);
2794 isl_tab_free(tab);
2795 return NULL;
2796}
2797
2799 struct isl_context *context, struct isl_tab *tab)
2800{
2801 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2802 struct isl_tab_undo *snap;
2803
2804 if (!tab)
2805 return NULL;
2806
2807 snap = isl_tab_snap(clex->tab);
2808 if (isl_tab_push_basis(clex->tab) < 0)
2809 goto error;
2810
2811 tab = tab_detect_nonnegative_parameters(tab, clex->tab);
2812
2813 if (isl_tab_rollback(clex->tab, snap) < 0)
2814 goto error;
2815
2816 return tab;
2817error:
2818 isl_tab_free(tab);
2819 return NULL;
2820}
2821
2823{
2824 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2825 isl_tab_free(clex->tab);
2826 clex->tab = NULL;
2827}
2828
2830 struct isl_context *context)
2831{
2832 struct isl_context_lex *clex = (struct isl_context_lex *)context;
2833 isl_tab_free(clex->tab);
2834 free(clex);
2835
2836 return NULL;
2837}
2838
2859
2861{
2862 struct isl_tab *tab;
2863
2864 if (!bset)
2865 return NULL;
2866 tab = tab_for_lexmin(bset_to_bmap(bset), NULL, 1, 0);
2867 if (isl_tab_track_bset(tab, bset) < 0)
2868 goto error;
2869 tab = isl_tab_init_samples(tab);
2870 return tab;
2871error:
2872 isl_tab_free(tab);
2873 return NULL;
2874}
2875
2877{
2878 struct isl_context_lex *clex;
2879
2880 if (!dom)
2881 return NULL;
2882
2883 clex = isl_alloc_type(dom->ctx, struct isl_context_lex);
2884 if (!clex)
2885 return NULL;
2886
2887 clex->context.op = &isl_context_lex_op;
2888
2890 if (restore_lexmin(clex->tab) < 0)
2891 goto error;
2892 clex->tab = check_integer_feasible(clex->tab);
2893 if (!clex->tab)
2894 goto error;
2895
2896 return &clex->context;
2897error:
2898 clex->context.op->free(&clex->context);
2899 return NULL;
2900}
2901
2902/* Representation of the context when using generalized basis reduction.
2903 *
2904 * "shifted" contains the offsets of the unit hypercubes that lie inside the
2905 * context. Any rational point in "shifted" can therefore be rounded
2906 * up to an integer point in the context.
2907 * If the context is constrained by any equality, then "shifted" is not used
2908 * as it would be empty.
2909 */
2916
2918 struct isl_context *context, struct isl_tab *tab)
2919{
2920 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
2921 if (!tab)
2922 return NULL;
2924}
2925
2927 struct isl_context *context)
2928{
2929 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
2930 if (!cgbr->tab)
2931 return NULL;
2932 return isl_tab_peek_bset(cgbr->tab);
2933}
2934
2936{
2937 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
2938 return cgbr->tab;
2939}
2940
2941/* Initialize the "shifted" tableau of the context, which
2942 * contains the constraints of the original tableau shifted
2943 * by the sum of all negative coefficients. This ensures
2944 * that any rational point in the shifted tableau can
2945 * be rounded up to yield an integer point in the original tableau.
2946 */
2947static void gbr_init_shifted(struct isl_context_gbr *cgbr)
2948{
2949 int i, j;
2950 struct isl_vec *cst;
2951 struct isl_basic_set *bset = isl_tab_peek_bset(cgbr->tab);
2953
2954 if (dim < 0)
2955 return;
2956 cst = isl_vec_alloc(cgbr->tab->mat->ctx, bset->n_ineq);
2957 if (!cst)
2958 return;
2959
2960 for (i = 0; i < bset->n_ineq; ++i) {
2961 isl_int_set(cst->el[i], bset->ineq[i][0]);
2962 for (j = 0; j < dim; ++j) {
2963 if (!isl_int_is_neg(bset->ineq[i][1 + j]))
2964 continue;
2965 isl_int_add(bset->ineq[i][0], bset->ineq[i][0],
2966 bset->ineq[i][1 + j]);
2967 }
2968 }
2969
2970 cgbr->shifted = isl_tab_from_basic_set(bset, 0);
2971
2972 for (i = 0; i < bset->n_ineq; ++i)
2973 isl_int_set(bset->ineq[i][0], cst->el[i]);
2974
2975 isl_vec_free(cst);
2976}
2977
2978/* Check if the shifted tableau is non-empty, and if so
2979 * use the sample point to construct an integer point
2980 * of the context tableau.
2981 */
2983{
2984 struct isl_vec *sample;
2985
2986 if (!cgbr->shifted)
2987 gbr_init_shifted(cgbr);
2988 if (!cgbr->shifted)
2989 return NULL;
2990 if (cgbr->shifted->empty)
2991 return isl_vec_alloc(cgbr->tab->mat->ctx, 0);
2992
2993 sample = isl_tab_get_sample_value(cgbr->shifted);
2994 sample = isl_vec_ceil(sample);
2995
2996 return sample;
2997}
2998
3001{
3002 int i;
3003
3004 if (!bset)
3005 return NULL;
3006
3007 for (i = 0; i < bset->n_eq; ++i)
3008 isl_int_set_si(bset->eq[i][0], 0);
3009
3010 for (i = 0; i < bset->n_ineq; ++i)
3011 isl_int_set_si(bset->ineq[i][0], 0);
3012
3013 return bset;
3014}
3015
3016static int use_shifted(struct isl_context_gbr *cgbr)
3017{
3018 if (!cgbr->tab)
3019 return 0;
3020 return cgbr->tab->bmap->n_eq == 0 && cgbr->tab->bmap->n_div == 0;
3021}
3022
3023static struct isl_vec *gbr_get_sample(struct isl_context_gbr *cgbr)
3024{
3025 struct isl_basic_set *bset;
3026 struct isl_basic_set *cone;
3027
3028 if (isl_tab_sample_is_integer(cgbr->tab))
3029 return isl_tab_get_sample_value(cgbr->tab);
3030
3031 if (use_shifted(cgbr)) {
3032 struct isl_vec *sample;
3033
3034 sample = gbr_get_shifted_sample(cgbr);
3035 if (!sample || sample->size > 0)
3036 return sample;
3037
3038 isl_vec_free(sample);
3039 }
3040
3041 if (!cgbr->cone) {
3042 bset = isl_tab_peek_bset(cgbr->tab);
3043 cgbr->cone = isl_tab_from_recession_cone(bset, 0);
3044 if (!cgbr->cone)
3045 return NULL;
3046 if (isl_tab_track_bset(cgbr->cone,
3047 isl_basic_set_copy(bset)) < 0)
3048 return NULL;
3049 }
3051 return NULL;
3052
3053 if (cgbr->cone->n_dead == cgbr->cone->n_col) {
3054 struct isl_vec *sample;
3055 struct isl_tab_undo *snap;
3056
3057 if (cgbr->tab->basis) {
3058 if (cgbr->tab->basis->n_col != 1 + cgbr->tab->n_var) {
3059 isl_mat_free(cgbr->tab->basis);
3060 cgbr->tab->basis = NULL;
3061 }
3062 cgbr->tab->n_zero = 0;
3063 cgbr->tab->n_unbounded = 0;
3064 }
3065
3066 snap = isl_tab_snap(cgbr->tab);
3067
3068 sample = isl_tab_sample(cgbr->tab);
3069
3070 if (!sample || isl_tab_rollback(cgbr->tab, snap) < 0) {
3071 isl_vec_free(sample);
3072 return NULL;
3073 }
3074
3075 return sample;
3076 }
3077
3082 cone = isl_basic_set_gauss(cone, NULL);
3083
3085 bset = isl_basic_set_update_from_tab(bset, cgbr->tab);
3086 bset = isl_basic_set_underlying_set(bset);
3087 bset = isl_basic_set_gauss(bset, NULL);
3088
3090}
3091
3093{
3094 struct isl_vec *sample;
3095
3096 if (!cgbr->tab)
3097 return;
3098
3099 if (cgbr->tab->empty)
3100 return;
3101
3102 sample = gbr_get_sample(cgbr);
3103 if (!sample)
3104 goto error;
3105
3106 if (sample->size == 0) {
3107 isl_vec_free(sample);
3108 if (isl_tab_mark_empty(cgbr->tab) < 0)
3109 goto error;
3110 return;
3111 }
3112
3113 if (isl_tab_add_sample(cgbr->tab, sample) < 0)
3114 goto error;
3115
3116 return;
3117error:
3118 isl_tab_free(cgbr->tab);
3119 cgbr->tab = NULL;
3120}
3121
3122static struct isl_tab *add_gbr_eq(struct isl_tab *tab, isl_int *eq)
3123{
3124 if (!tab)
3125 return NULL;
3126
3127 if (isl_tab_extend_cons(tab, 2) < 0)
3128 goto error;
3129
3130 if (isl_tab_add_eq(tab, eq) < 0)
3131 goto error;
3132
3133 return tab;
3134error:
3135 isl_tab_free(tab);
3136 return NULL;
3137}
3138
3139/* Add the equality described by "eq" to the context.
3140 * If "check" is set, then we check if the context is empty after
3141 * adding the equality.
3142 * If "update" is set, then we check if the samples are still valid.
3143 *
3144 * We do not explicitly add shifted copies of the equality to
3145 * cgbr->shifted since they would conflict with each other.
3146 * Instead, we directly mark cgbr->shifted empty.
3147 */
3149 int check, int update)
3150{
3151 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3152
3153 cgbr->tab = add_gbr_eq(cgbr->tab, eq);
3154
3155 if (cgbr->shifted && !cgbr->shifted->empty && use_shifted(cgbr)) {
3156 if (isl_tab_mark_empty(cgbr->shifted) < 0)
3157 goto error;
3158 }
3159
3160 if (cgbr->cone && cgbr->cone->n_col != cgbr->cone->n_dead) {
3161 if (isl_tab_extend_cons(cgbr->cone, 2) < 0)
3162 goto error;
3163 if (isl_tab_add_eq(cgbr->cone, eq) < 0)
3164 goto error;
3165 }
3166
3167 if (check) {
3168 int v = tab_has_valid_sample(cgbr->tab, eq, 1);
3169 if (v < 0)
3170 goto error;
3171 if (!v)
3173 }
3174 if (update)
3175 cgbr->tab = check_samples(cgbr->tab, eq, 1);
3176 return;
3177error:
3178 isl_tab_free(cgbr->tab);
3179 cgbr->tab = NULL;
3180}
3181
3182static void add_gbr_ineq(struct isl_context_gbr *cgbr, isl_int *ineq)
3183{
3184 if (!cgbr->tab)
3185 return;
3186
3187 if (isl_tab_extend_cons(cgbr->tab, 1) < 0)
3188 goto error;
3189
3190 if (isl_tab_add_ineq(cgbr->tab, ineq) < 0)
3191 goto error;
3192
3193 if (cgbr->shifted && !cgbr->shifted->empty && use_shifted(cgbr)) {
3194 int i;
3195 isl_size dim;
3196 dim = isl_basic_map_dim(cgbr->tab->bmap, isl_dim_all);
3197 if (dim < 0)
3198 goto error;
3199
3200 if (isl_tab_extend_cons(cgbr->shifted, 1) < 0)
3201 goto error;
3202
3203 for (i = 0; i < dim; ++i) {
3204 if (!isl_int_is_neg(ineq[1 + i]))
3205 continue;
3206 isl_int_add(ineq[0], ineq[0], ineq[1 + i]);
3207 }
3208
3209 if (isl_tab_add_ineq(cgbr->shifted, ineq) < 0)
3210 goto error;
3211
3212 for (i = 0; i < dim; ++i) {
3213 if (!isl_int_is_neg(ineq[1 + i]))
3214 continue;
3215 isl_int_sub(ineq[0], ineq[0], ineq[1 + i]);
3216 }
3217 }
3218
3219 if (cgbr->cone && cgbr->cone->n_col != cgbr->cone->n_dead) {
3220 if (isl_tab_extend_cons(cgbr->cone, 1) < 0)
3221 goto error;
3222 if (isl_tab_add_ineq(cgbr->cone, ineq) < 0)
3223 goto error;
3224 }
3225
3226 return;
3227error:
3228 isl_tab_free(cgbr->tab);
3229 cgbr->tab = NULL;
3230}
3231
3233 int check, int update)
3234{
3235 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3236
3237 add_gbr_ineq(cgbr, ineq);
3238 if (!cgbr->tab)
3239 return;
3240
3241 if (check) {
3242 int v = tab_has_valid_sample(cgbr->tab, ineq, 0);
3243 if (v < 0)
3244 goto error;
3245 if (!v)
3247 }
3248 if (update)
3249 cgbr->tab = check_samples(cgbr->tab, ineq, 0);
3250 return;
3251error:
3252 isl_tab_free(cgbr->tab);
3253 cgbr->tab = NULL;
3254}
3255
3257{
3258 struct isl_context *context = (struct isl_context *)user;
3259 context_gbr_add_ineq(context, ineq, 0, 0);
3260 return context->op->is_ok(context) ? isl_stat_ok : isl_stat_error;
3261}
3262
3264 isl_int *ineq, int strict)
3265{
3266 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3267 return tab_ineq_sign(cgbr->tab, ineq, strict);
3268}
3269
3270/* Check whether "ineq" can be added to the tableau without rendering
3271 * it infeasible.
3272 */
3274{
3275 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3276 struct isl_tab_undo *snap;
3277 struct isl_tab_undo *shifted_snap = NULL;
3278 struct isl_tab_undo *cone_snap = NULL;
3279 int feasible;
3280
3281 if (!cgbr->tab)
3282 return -1;
3283
3284 if (isl_tab_extend_cons(cgbr->tab, 1) < 0)
3285 return -1;
3286
3287 snap = isl_tab_snap(cgbr->tab);
3288 if (cgbr->shifted)
3289 shifted_snap = isl_tab_snap(cgbr->shifted);
3290 if (cgbr->cone)
3291 cone_snap = isl_tab_snap(cgbr->cone);
3292 add_gbr_ineq(cgbr, ineq);
3294 if (!cgbr->tab)
3295 return -1;
3296 feasible = !cgbr->tab->empty;
3297 if (isl_tab_rollback(cgbr->tab, snap) < 0)
3298 return -1;
3299 if (shifted_snap) {
3300 if (isl_tab_rollback(cgbr->shifted, shifted_snap))
3301 return -1;
3302 } else if (cgbr->shifted) {
3303 isl_tab_free(cgbr->shifted);
3304 cgbr->shifted = NULL;
3305 }
3306 if (cone_snap) {
3307 if (isl_tab_rollback(cgbr->cone, cone_snap))
3308 return -1;
3309 } else if (cgbr->cone) {
3310 isl_tab_free(cgbr->cone);
3311 cgbr->cone = NULL;
3312 }
3313
3314 return feasible;
3315}
3316
3317/* Return the column of the last of the variables associated to
3318 * a column that has a non-zero coefficient.
3319 * This function is called in a context where only coefficients
3320 * of parameters or divs can be non-zero.
3321 */
3322static int last_non_zero_var_col(struct isl_tab *tab, isl_int *p)
3323{
3324 int i;
3325 int col;
3326
3327 if (tab->n_var == 0)
3328 return -1;
3329
3330 for (i = tab->n_var - 1; i >= 0; --i) {
3331 if (i >= tab->n_param && i < tab->n_var - tab->n_div)
3332 continue;
3333 if (tab->var[i].is_row)
3334 continue;
3335 col = tab->var[i].index;
3336 if (!isl_int_is_zero(p[col]))
3337 return col;
3338 }
3339
3340 return -1;
3341}
3342
3343/* Look through all the recently added equalities in the context
3344 * to see if we can propagate any of them to the main tableau.
3345 *
3346 * The newly added equalities in the context are encoded as pairs
3347 * of inequalities starting at inequality "first".
3348 *
3349 * We tentatively add each of these equalities to the main tableau
3350 * and if this happens to result in a row with a final coefficient
3351 * that is one or negative one, we use it to kill a column
3352 * in the main tableau. Otherwise, we discard the tentatively
3353 * added row.
3354 * This tentative addition of equality constraints turns
3355 * on the undo facility of the tableau. Turn it off again
3356 * at the end, assuming it was turned off to begin with.
3357 *
3358 * Return 0 on success and -1 on failure.
3359 */
3361 struct isl_tab *tab, unsigned first)
3362{
3363 int i;
3364 struct isl_vec *eq = NULL;
3365 isl_bool needs_undo;
3366
3367 needs_undo = isl_tab_need_undo(tab);
3368 if (needs_undo < 0)
3369 goto error;
3370 eq = isl_vec_alloc(tab->mat->ctx, 1 + tab->n_var);
3371 if (!eq)
3372 goto error;
3373
3374 if (isl_tab_extend_cons(tab, (cgbr->tab->bmap->n_ineq - first)/2) < 0)
3375 goto error;
3376
3377 isl_seq_clr(eq->el + 1 + tab->n_param,
3378 tab->n_var - tab->n_param - tab->n_div);
3379 for (i = first; i < cgbr->tab->bmap->n_ineq; i += 2) {
3380 int j;
3381 int r;
3382 struct isl_tab_undo *snap;
3383 snap = isl_tab_snap(tab);
3384
3385 isl_seq_cpy(eq->el, cgbr->tab->bmap->ineq[i], 1 + tab->n_param);
3386 isl_seq_cpy(eq->el + 1 + tab->n_var - tab->n_div,
3387 cgbr->tab->bmap->ineq[i] + 1 + tab->n_param,
3388 tab->n_div);
3389
3390 r = isl_tab_add_row(tab, eq->el);
3391 if (r < 0)
3392 goto error;
3393 r = tab->con[r].index;
3394 j = last_non_zero_var_col(tab, tab->mat->row[r] + 2 + tab->M);
3395 if (j < 0 || j < tab->n_dead ||
3396 !isl_int_is_one(tab->mat->row[r][0]) ||
3397 (!isl_int_is_one(tab->mat->row[r][2 + tab->M + j]) &&
3398 !isl_int_is_negone(tab->mat->row[r][2 + tab->M + j]))) {
3399 if (isl_tab_rollback(tab, snap) < 0)
3400 goto error;
3401 continue;
3402 }
3403 if (isl_tab_pivot(tab, r, j) < 0)
3404 goto error;
3405 if (isl_tab_kill_col(tab, j) < 0)
3406 goto error;
3407
3408 if (restore_lexmin(tab) < 0)
3409 goto error;
3410 }
3411
3412 if (!needs_undo)
3413 isl_tab_clear_undo(tab);
3414 isl_vec_free(eq);
3415
3416 return 0;
3417error:
3418 isl_vec_free(eq);
3419 isl_tab_free(cgbr->tab);
3420 cgbr->tab = NULL;
3421 return -1;
3422}
3423
3425 struct isl_tab *tab)
3426{
3427 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3428 unsigned n_ineq;
3429
3430 if (!cgbr->cone) {
3431 struct isl_basic_set *bset = isl_tab_peek_bset(cgbr->tab);
3432 cgbr->cone = isl_tab_from_recession_cone(bset, 0);
3433 if (!cgbr->cone)
3434 goto error;
3435 if (isl_tab_track_bset(cgbr->cone,
3436 isl_basic_set_copy(bset)) < 0)
3437 goto error;
3438 }
3440 goto error;
3441
3442 n_ineq = cgbr->tab->bmap->n_ineq;
3443 cgbr->tab = isl_tab_detect_equalities(cgbr->tab, cgbr->cone);
3444 if (!cgbr->tab)
3445 return -1;
3446 if (cgbr->tab->bmap->n_ineq > n_ineq &&
3447 propagate_equalities(cgbr, tab, n_ineq) < 0)
3448 return -1;
3449
3450 return 0;
3451error:
3452 isl_tab_free(cgbr->tab);
3453 cgbr->tab = NULL;
3454 return -1;
3455}
3456
3457static int context_gbr_get_div(struct isl_context *context, struct isl_tab *tab,
3458 struct isl_vec *div)
3459{
3460 return get_div(tab, context, div);
3461}
3462
3464 __isl_keep isl_vec *div)
3465{
3466 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3467 if (cgbr->cone) {
3468 int r, o_div;
3469 isl_size n_div;
3470
3471 n_div = isl_basic_map_dim(cgbr->cone->bmap, isl_dim_div);
3472 if (n_div < 0)
3473 return isl_bool_error;
3474 o_div = cgbr->cone->n_var - n_div;
3475
3476 if (isl_tab_extend_cons(cgbr->cone, 3) < 0)
3477 return isl_bool_error;
3478 if (isl_tab_extend_vars(cgbr->cone, 1) < 0)
3479 return isl_bool_error;
3480 if ((r = isl_tab_insert_var(cgbr->cone, pos)) <0)
3481 return isl_bool_error;
3482
3483 cgbr->cone->bmap = isl_basic_map_insert_div(cgbr->cone->bmap,
3484 r - o_div, div);
3485 if (!cgbr->cone->bmap)
3486 return isl_bool_error;
3488 &cgbr->cone->var[r]) < 0)
3489 return isl_bool_error;
3490 }
3491 return context_tab_insert_div(cgbr->tab, pos, div,
3493}
3494
3496 struct isl_tab *tab)
3497{
3498 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3499 struct isl_tab_undo *snap;
3500 int r;
3501
3502 snap = isl_tab_snap(cgbr->tab);
3503 r = best_split(tab, cgbr->tab);
3504
3505 if (r >= 0 && isl_tab_rollback(cgbr->tab, snap) < 0)
3506 return -1;
3507
3508 return r;
3509}
3510
3512{
3513 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3514 if (!cgbr->tab)
3515 return -1;
3516 return cgbr->tab->empty;
3517}
3518
3524
3526{
3527 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3528 struct isl_gbr_tab_undo *snap;
3529
3530 if (!cgbr->tab)
3531 return NULL;
3532
3533 snap = isl_alloc_type(cgbr->tab->mat->ctx, struct isl_gbr_tab_undo);
3534 if (!snap)
3535 return NULL;
3536
3537 snap->tab_snap = isl_tab_snap(cgbr->tab);
3538 if (isl_tab_save_samples(cgbr->tab) < 0)
3539 goto error;
3540
3541 if (cgbr->shifted)
3542 snap->shifted_snap = isl_tab_snap(cgbr->shifted);
3543 else
3544 snap->shifted_snap = NULL;
3545
3546 if (cgbr->cone)
3547 snap->cone_snap = isl_tab_snap(cgbr->cone);
3548 else
3549 snap->cone_snap = NULL;
3550
3551 return snap;
3552error:
3553 free(snap);
3554 return NULL;
3555}
3556
3557static void context_gbr_restore(struct isl_context *context, void *save)
3558{
3559 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3560 struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save;
3561 if (!snap)
3562 goto error;
3563 if (isl_tab_rollback(cgbr->tab, snap->tab_snap) < 0)
3564 goto error;
3565
3566 if (snap->shifted_snap) {
3567 if (isl_tab_rollback(cgbr->shifted, snap->shifted_snap) < 0)
3568 goto error;
3569 } else if (cgbr->shifted) {
3570 isl_tab_free(cgbr->shifted);
3571 cgbr->shifted = NULL;
3572 }
3573
3574 if (snap->cone_snap) {
3575 if (isl_tab_rollback(cgbr->cone, snap->cone_snap) < 0)
3576 goto error;
3577 } else if (cgbr->cone) {
3578 isl_tab_free(cgbr->cone);
3579 cgbr->cone = NULL;
3580 }
3581
3582 free(snap);
3583
3584 return;
3585error:
3586 free(snap);
3587 isl_tab_free(cgbr->tab);
3588 cgbr->tab = NULL;
3589}
3590
3591static void context_gbr_discard(void *save)
3592{
3593 struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save;
3594 free(snap);
3595}
3596
3598{
3599 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3600 return !!cgbr->tab;
3601}
3602
3604{
3605 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3606 isl_tab_free(cgbr->tab);
3607 cgbr->tab = NULL;
3608}
3609
3611 struct isl_context *context)
3612{
3613 struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
3614 isl_tab_free(cgbr->tab);
3615 isl_tab_free(cgbr->shifted);
3616 isl_tab_free(cgbr->cone);
3617 free(cgbr);
3618
3619 return NULL;
3620}
3621
3642
3644{
3645 struct isl_context_gbr *cgbr;
3646
3647 if (!dom)
3648 return NULL;
3649
3650 cgbr = isl_calloc_type(dom->ctx, struct isl_context_gbr);
3651 if (!cgbr)
3652 return NULL;
3653
3654 cgbr->context.op = &isl_context_gbr_op;
3655
3656 cgbr->shifted = NULL;
3657 cgbr->cone = NULL;
3658 cgbr->tab = isl_tab_from_basic_set(dom, 1);
3659 cgbr->tab = isl_tab_init_samples(cgbr->tab);
3660 if (!cgbr->tab)
3661 goto error;
3663
3664 return &cgbr->context;
3665error:
3666 cgbr->context.op->free(&cgbr->context);
3667 return NULL;
3668}
3669
3670/* Allocate a context corresponding to "dom".
3671 * The representation specific fields are initialized by
3672 * isl_context_lex_alloc or isl_context_gbr_alloc.
3673 * The shared "n_unknown" field is initialized to the number
3674 * of final unknown integer divisions in "dom".
3675 */
3677{
3678 struct isl_context *context;
3679 int first;
3680 isl_size n_div;
3681
3682 if (!dom)
3683 return NULL;
3684
3685 if (dom->ctx->opt->context == ISL_CONTEXT_LEXMIN)
3687 else
3689
3690 if (!context)
3691 return NULL;
3692
3694 n_div = isl_basic_set_dim(dom, isl_dim_div);
3695 if (first < 0 || n_div < 0)
3696 return context->op->free(context);
3697 context->n_unknown = n_div - first;
3698
3699 return context;
3700}
3701
3702/* Initialize some common fields of "sol", which keeps track
3703 * of the solution of an optimization problem on "bmap" over
3704 * the domain "dom".
3705 * If "max" is set, then a maximization problem is being solved, rather than
3706 * a minimization problem, which means that the variables in the
3707 * tableau have value "M - x" rather than "M + x".
3708 */
3710 __isl_keep isl_basic_set *dom, int max)
3711{
3714 sol->dec_level.sol = sol;
3715 sol->max = max;
3716 sol->n_out = isl_basic_map_dim(bmap, isl_dim_out);
3717 sol->space = isl_basic_map_get_space(bmap);
3718
3719 sol->context = isl_context_alloc(dom);
3720 if (sol->n_out < 0 || !sol->space || !sol->context)
3721 return isl_stat_error;
3722
3723 return isl_stat_ok;
3724}
3725
3726/* Construct an isl_sol_map structure for accumulating the solution.
3727 * If track_empty is set, then we also keep track of the parts
3728 * of the context where there is no solution.
3729 * If max is set, then we are solving a maximization, rather than
3730 * a minimization problem, which means that the variables in the
3731 * tableau have value "M - x" rather than "M + x".
3732 */
3734 __isl_take isl_basic_set *dom, int track_empty, int max)
3735{
3736 struct isl_sol_map *sol_map = NULL;
3737 isl_space *space;
3738
3739 if (!bmap)
3740 goto error;
3741
3742 sol_map = isl_calloc_type(bmap->ctx, struct isl_sol_map);
3743 if (!sol_map)
3744 goto error;
3745
3746 sol_map->sol.free = &sol_map_free;
3747 if (sol_init(&sol_map->sol, bmap, dom, max) < 0)
3748 goto error;
3749 sol_map->sol.add = &sol_map_add_wrap;
3750 sol_map->sol.add_empty = track_empty ? &sol_map_add_empty_wrap : NULL;
3751 space = isl_space_copy(sol_map->sol.space);
3752 sol_map->map = isl_map_alloc_space(space, 1, ISL_MAP_DISJOINT);
3753 if (!sol_map->map)
3754 goto error;
3755
3756 if (track_empty) {
3758 1, ISL_SET_DISJOINT);
3759 if (!sol_map->empty)
3760 goto error;
3761 }
3762
3763 isl_basic_set_free(dom);
3764 return &sol_map->sol;
3765error:
3766 isl_basic_set_free(dom);
3767 sol_free(&sol_map->sol);
3768 return NULL;
3769}
3770
3771/* Check whether all coefficients of (non-parameter) variables
3772 * are non-positive, meaning that no pivots can be performed on the row.
3773 */
3774static int is_critical(struct isl_tab *tab, int row)
3775{
3776 int j;
3777 unsigned off = 2 + tab->M;
3778
3779 for (j = tab->n_dead; j < tab->n_col; ++j) {
3780 if (col_is_parameter_var(tab, j))
3781 continue;
3782
3783 if (isl_int_is_pos(tab->mat->row[row][off + j]))
3784 return 0;
3785 }
3786
3787 return 1;
3788}
3789
3790/* Check whether the inequality represented by vec is strict over the integers,
3791 * i.e., there are no integer values satisfying the constraint with
3792 * equality. This happens if the gcd of the coefficients is not a divisor
3793 * of the constant term. If so, scale the constraint down by the gcd
3794 * of the coefficients.
3795 */
3796static int is_strict(struct isl_vec *vec)
3797{
3798 isl_int gcd;
3799 int strict = 0;
3800
3802 isl_seq_gcd(vec->el + 1, vec->size - 1, &gcd);
3803 if (!isl_int_is_one(gcd)) {
3804 strict = !isl_int_is_divisible_by(vec->el[0], gcd);
3805 isl_int_fdiv_q(vec->el[0], vec->el[0], gcd);
3806 isl_seq_scale_down(vec->el + 1, vec->el + 1, gcd, vec->size-1);
3807 }
3809
3810 return strict;
3811}
3812
3813/* Determine the sign of the given row of the main tableau.
3814 * The result is one of
3815 * isl_tab_row_pos: always non-negative; no pivot needed
3816 * isl_tab_row_neg: always non-positive; pivot
3817 * isl_tab_row_any: can be both positive and negative; split
3818 *
3819 * We first handle some simple cases
3820 * - the row sign may be known already
3821 * - the row may be obviously non-negative
3822 * - the parametric constant may be equal to that of another row
3823 * for which we know the sign. This sign will be either "pos" or
3824 * "any". If it had been "neg" then we would have pivoted before.
3825 *
3826 * If none of these cases hold, we check the value of the row for each
3827 * of the currently active samples. Based on the signs of these values
3828 * we make an initial determination of the sign of the row.
3829 *
3830 * all zero -> unk(nown)
3831 * all non-negative -> pos
3832 * all non-positive -> neg
3833 * both negative and positive -> all
3834 *
3835 * If we end up with "all", we are done.
3836 * Otherwise, we perform a check for positive and/or negative
3837 * values as follows.
3838 *
3839 * samples neg unk pos
3840 * <0 ? Y N Y N
3841 * pos any pos
3842 * >0 ? Y N Y N
3843 * any neg any neg
3844 *
3845 * There is no special sign for "zero", because we can usually treat zero
3846 * as either non-negative or non-positive, whatever works out best.
3847 * However, if the row is "critical", meaning that pivoting is impossible
3848 * then we don't want to limp zero with the non-positive case, because
3849 * then we we would lose the solution for those values of the parameters
3850 * where the value of the row is zero. Instead, we treat 0 as non-negative
3851 * ensuring a split if the row can attain both zero and negative values.
3852 * The same happens when the original constraint was one that could not
3853 * be satisfied with equality by any integer values of the parameters.
3854 * In this case, we normalize the constraint, but then a value of zero
3855 * for the normalized constraint is actually a positive value for the
3856 * original constraint, so again we need to treat zero as non-negative.
3857 * In both these cases, we have the following decision tree instead:
3858 *
3859 * all non-negative -> pos
3860 * all negative -> neg
3861 * both negative and non-negative -> all
3862 *
3863 * samples neg pos
3864 * <0 ? Y N
3865 * any pos
3866 * >=0 ? Y N
3867 * any neg
3868 */
3869static enum isl_tab_row_sign row_sign(struct isl_tab *tab,
3870 struct isl_sol *sol, int row)
3871{
3872 struct isl_vec *ineq = NULL;
3874 int critical;
3875 int strict;
3876 int row2;
3877
3878 if (tab->row_sign[row] != isl_tab_row_unknown)
3879 return tab->row_sign[row];
3880 if (is_obviously_nonneg(tab, row))
3881 return isl_tab_row_pos;
3882 for (row2 = tab->n_redundant; row2 < tab->n_row; ++row2) {
3883 if (tab->row_sign[row2] == isl_tab_row_unknown)
3884 continue;
3885 if (identical_parameter_line(tab, row, row2))
3886 return tab->row_sign[row2];
3887 }
3888
3889 critical = is_critical(tab, row);
3890
3891 ineq = get_row_parameter_ineq(tab, row);
3892 if (!ineq)
3893 goto error;
3894
3895 strict = is_strict(ineq);
3896
3897 res = sol->context->op->ineq_sign(sol->context, ineq->el,
3898 critical || strict);
3899
3901 /* test for negative values */
3902 int feasible;
3903 isl_seq_neg(ineq->el, ineq->el, ineq->size);
3904 isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
3905
3906 feasible = sol->context->op->test_ineq(sol->context, ineq->el);
3907 if (feasible < 0)
3908 goto error;
3909 if (!feasible)
3911 else
3914 if (res == isl_tab_row_neg) {
3915 isl_seq_neg(ineq->el, ineq->el, ineq->size);
3916 isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
3917 }
3918 }
3919
3920 if (res == isl_tab_row_neg) {
3921 /* test for positive values */
3922 int feasible;
3923 if (!critical && !strict)
3924 isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
3925
3926 feasible = sol->context->op->test_ineq(sol->context, ineq->el);
3927 if (feasible < 0)
3928 goto error;
3929 if (feasible)
3931 }
3932
3933 isl_vec_free(ineq);
3934 return res;
3935error:
3936 isl_vec_free(ineq);
3937 return isl_tab_row_unknown;
3938}
3939
3940static void find_solutions(struct isl_sol *sol, struct isl_tab *tab);
3941
3942/* Find solutions for values of the parameters that satisfy the given
3943 * inequality.
3944 *
3945 * We currently take a snapshot of the context tableau that is reset
3946 * when we return from this function, while we make a copy of the main
3947 * tableau, leaving the original main tableau untouched.
3948 * These are fairly arbitrary choices. Making a copy also of the context
3949 * tableau would obviate the need to undo any changes made to it later,
3950 * while taking a snapshot of the main tableau could reduce memory usage.
3951 * If we were to switch to taking a snapshot of the main tableau,
3952 * we would have to keep in mind that we need to save the row signs
3953 * and that we need to do this before saving the current basis
3954 * such that the basis has been restore before we restore the row signs.
3955 */
3956static void find_in_pos(struct isl_sol *sol, struct isl_tab *tab, isl_int *ineq)
3957{
3958 void *saved;
3959
3960 if (!sol->context)
3961 goto error;
3962
3963 tab = isl_tab_dup(tab);
3964 if (!tab)
3965 goto error;
3966
3967 saved = sol->context->op->save(sol->context);
3968
3969 sol_context_add_ineq(sol, ineq, 0, 1);
3970
3971 find_solutions(sol, tab);
3972
3973 if (!sol->error)
3974 sol->context->op->restore(sol->context, saved);
3975 else
3976 sol->context->op->discard(saved);
3977 return;
3978error:
3979 sol->error = 1;
3980}
3981
3982/* Record the absence of solutions for those values of the parameters
3983 * that do not satisfy the given inequality with equality.
3984 */
3985static void no_sol_in_strict(struct isl_sol *sol,
3986 struct isl_tab *tab, struct isl_vec *ineq)
3987{
3988 int empty;
3989 void *saved;
3990
3991 if (!sol->context || sol->error)
3992 goto error;
3993 saved = sol->context->op->save(sol->context);
3994
3995 isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
3996
3997 sol_context_add_ineq(sol, ineq->el, 1, 0);
3998
3999 empty = tab->empty;
4000 tab->empty = 1;
4001 sol_add(sol, tab);
4002 tab->empty = empty;
4003
4004 isl_int_add_ui(ineq->el[0], ineq->el[0], 1);
4005
4006 sol->context->op->restore(sol->context, saved);
4007 if (!sol->context->op->is_ok(sol->context))
4008 goto error;
4009 return;
4010error:
4011 sol->error = 1;
4012}
4013
4014/* Reset all row variables that are marked to have a sign that may
4015 * be both positive and negative to have an unknown sign.
4016 */
4017static void reset_any_to_unknown(struct isl_tab *tab)
4018{
4019 int row;
4020
4021 for (row = tab->n_redundant; row < tab->n_row; ++row) {
4022 if (!isl_tab_var_from_row(tab, row)->is_nonneg)
4023 continue;
4024 if (tab->row_sign[row] == isl_tab_row_any)
4025 tab->row_sign[row] = isl_tab_row_unknown;
4026 }
4027}
4028
4029/* Compute the lexicographic minimum of the set represented by the main
4030 * tableau "tab" within the context "sol->context_tab".
4031 * On entry the sample value of the main tableau is lexicographically
4032 * less than or equal to this lexicographic minimum.
4033 * Pivots are performed until a feasible point is found, which is then
4034 * necessarily equal to the minimum, or until the tableau is found to
4035 * be infeasible. Some pivots may need to be performed for only some
4036 * feasible values of the context tableau. If so, the context tableau
4037 * is split into a part where the pivot is needed and a part where it is not.
4038 *
4039 * Whenever we enter the main loop, the main tableau is such that no
4040 * "obvious" pivots need to be performed on it, where "obvious" means
4041 * that the given row can be seen to be negative without looking at
4042 * the context tableau. In particular, for non-parametric problems,
4043 * no pivots need to be performed on the main tableau.
4044 * The caller of find_solutions is responsible for making this property
4045 * hold prior to the first iteration of the loop, while restore_lexmin
4046 * is called before every other iteration.
4047 *
4048 * Inside the main loop, we first examine the signs of the rows of
4049 * the main tableau within the context of the context tableau.
4050 * If we find a row that is always non-positive for all values of
4051 * the parameters satisfying the context tableau and negative for at
4052 * least one value of the parameters, we perform the appropriate pivot
4053 * and start over. An exception is the case where no pivot can be
4054 * performed on the row. In this case, we require that the sign of
4055 * the row is negative for all values of the parameters (rather than just
4056 * non-positive). This special case is handled inside row_sign, which
4057 * will say that the row can have any sign if it determines that it can
4058 * attain both negative and zero values.
4059 *
4060 * If we can't find a row that always requires a pivot, but we can find
4061 * one or more rows that require a pivot for some values of the parameters
4062 * (i.e., the row can attain both positive and negative signs), then we split
4063 * the context tableau into two parts, one where we force the sign to be
4064 * non-negative and one where we force is to be negative.
4065 * The non-negative part is handled by a recursive call (through find_in_pos).
4066 * Upon returning from this call, we continue with the negative part and
4067 * perform the required pivot.
4068 *
4069 * If no such rows can be found, all rows are non-negative and we have
4070 * found a (rational) feasible point. If we only wanted a rational point
4071 * then we are done.
4072 * Otherwise, we check if all values of the sample point of the tableau
4073 * are integral for the variables. If so, we have found the minimal
4074 * integral point and we are done.
4075 * If the sample point is not integral, then we need to make a distinction
4076 * based on whether the constant term is non-integral or the coefficients
4077 * of the parameters. Furthermore, in order to decide how to handle
4078 * the non-integrality, we also need to know whether the coefficients
4079 * of the other columns in the tableau are integral. This leads
4080 * to the following table. The first two rows do not correspond
4081 * to a non-integral sample point and are only mentioned for completeness.
4082 *
4083 * constant parameters other
4084 *
4085 * int int int |
4086 * int int rat | -> no problem
4087 *
4088 * rat int int -> fail
4089 *
4090 * rat int rat -> cut
4091 *
4092 * int rat rat |
4093 * rat rat rat | -> parametric cut
4094 *
4095 * int rat int |
4096 * rat rat int | -> split context
4097 *
4098 * If the parametric constant is completely integral, then there is nothing
4099 * to be done. If the constant term is non-integral, but all the other
4100 * coefficient are integral, then there is nothing that can be done
4101 * and the tableau has no integral solution.
4102 * If, on the other hand, one or more of the other columns have rational
4103 * coefficients, but the parameter coefficients are all integral, then
4104 * we can perform a regular (non-parametric) cut.
4105 * Finally, if there is any parameter coefficient that is non-integral,
4106 * then we need to involve the context tableau. There are two cases here.
4107 * If at least one other column has a rational coefficient, then we
4108 * can perform a parametric cut in the main tableau by adding a new
4109 * integer division in the context tableau.
4110 * If all other columns have integral coefficients, then we need to
4111 * enforce that the rational combination of parameters (c + \sum a_i y_i)/m
4112 * is always integral. We do this by introducing an integer division
4113 * q = floor((c + \sum a_i y_i)/m) and stipulating that its argument should
4114 * always be integral in the context tableau, i.e., m q = c + \sum a_i y_i.
4115 * Since q is expressed in the tableau as
4116 * c + \sum a_i y_i - m q >= 0
4117 * -c - \sum a_i y_i + m q + m - 1 >= 0
4118 * it is sufficient to add the inequality
4119 * -c - \sum a_i y_i + m q >= 0
4120 * In the part of the context where this inequality does not hold, the
4121 * main tableau is marked as being empty.
4122 */
4123static void find_solutions(struct isl_sol *sol, struct isl_tab *tab)
4124{
4125 struct isl_context *context;
4126 int r;
4127
4128 if (!tab || sol->error)
4129 goto error;
4130
4131 context = sol->context;
4132
4133 if (tab->empty)
4134 goto done;
4135 if (context->op->is_empty(context))
4136 goto done;
4137
4138 for (r = 0; r >= 0 && tab && !tab->empty; r = restore_lexmin(tab)) {
4139 int flags;
4140 int row;
4141 enum isl_tab_row_sign sgn;
4142 int split = -1;
4143 int n_split = 0;
4144
4145 for (row = tab->n_redundant; row < tab->n_row; ++row) {
4146 if (!isl_tab_var_from_row(tab, row)->is_nonneg)
4147 continue;
4148 sgn = row_sign(tab, sol, row);
4149 if (!sgn)
4150 goto error;
4151 tab->row_sign[row] = sgn;
4152 if (sgn == isl_tab_row_any)
4153 n_split++;
4154 if (sgn == isl_tab_row_any && split == -1)
4155 split = row;
4156 if (sgn == isl_tab_row_neg)
4157 break;
4158 }
4159 if (row < tab->n_row)
4160 continue;
4161 if (split != -1) {
4162 struct isl_vec *ineq;
4163 if (n_split != 1)
4164 split = context->op->best_split(context, tab);
4165 if (split < 0)
4166 goto error;
4167 ineq = get_row_parameter_ineq(tab, split);
4168 if (!ineq)
4169 goto error;
4170 is_strict(ineq);
4173 sol_inc_level(sol);
4174 find_in_pos(sol, tab, ineq->el);
4176 isl_seq_neg(ineq->el, ineq->el, ineq->size);
4177 isl_int_sub_ui(ineq->el[0], ineq->el[0], 1);
4178 sol_context_add_ineq(sol, ineq->el, 0, 1);
4179 isl_vec_free(ineq);
4180 if (sol->error)
4181 goto error;
4182 continue;
4183 }
4184 if (tab->rational)
4185 break;
4186 row = first_non_integer_row(tab, &flags);
4187 if (row < 0)
4188 break;
4189 if (ISL_FL_ISSET(flags, I_PAR)) {
4190 if (ISL_FL_ISSET(flags, I_VAR)) {
4191 if (isl_tab_mark_empty(tab) < 0)
4192 goto error;
4193 break;
4194 }
4195 row = add_cut(tab, row);
4196 } else if (ISL_FL_ISSET(flags, I_VAR)) {
4197 struct isl_vec *div;
4198 struct isl_vec *ineq;
4199 int d;
4200 div = get_row_split_div(tab, row);
4201 if (!div)
4202 goto error;
4203 d = context->op->get_div(context, tab, div);
4204 isl_vec_free(div);
4205 if (d < 0)
4206 goto error;
4207 ineq = ineq_for_div(context->op->peek_basic_set(context), d);
4208 if (!ineq)
4209 goto error;
4210 sol_inc_level(sol);
4211 no_sol_in_strict(sol, tab, ineq);
4212 isl_seq_neg(ineq->el, ineq->el, ineq->size);
4213 sol_context_add_ineq(sol, ineq->el, 1, 1);
4214 isl_vec_free(ineq);
4215 if (sol->error || !context->op->is_ok(context))
4216 goto error;
4217 tab = set_row_cst_to_div(tab, row, d);
4218 if (context->op->is_empty(context))
4219 break;
4220 } else
4221 row = add_parametric_cut(tab, row, context);
4222 if (row < 0)
4223 goto error;
4224 }
4225 if (r < 0)
4226 goto error;
4227done:
4228 sol_add(sol, tab);
4229 isl_tab_free(tab);
4230 return;
4231error:
4232 isl_tab_free(tab);
4233 sol->error = 1;
4234}
4235
4236/* Does "sol" contain a pair of partial solutions that could potentially
4237 * be merged?
4238 *
4239 * We currently only check that "sol" is not in an error state
4240 * and that there are at least two partial solutions of which the final two
4241 * are defined at the same level.
4242 */
4244{
4245 if (sol->error)
4246 return 0;
4247 if (!sol->partial)
4248 return 0;
4249 if (!sol->partial->next)
4250 return 0;
4251 return sol->partial->level == sol->partial->next->level;
4252}
4253
4254/* Compute the lexicographic minimum of the set represented by the main
4255 * tableau "tab" within the context "sol->context_tab".
4256 *
4257 * As a preprocessing step, we first transfer all the purely parametric
4258 * equalities from the main tableau to the context tableau, i.e.,
4259 * parameters that have been pivoted to a row.
4260 * These equalities are ignored by the main algorithm, because the
4261 * corresponding rows may not be marked as being non-negative.
4262 * In parts of the context where the added equality does not hold,
4263 * the main tableau is marked as being empty.
4264 *
4265 * Before we embark on the actual computation, we save a copy
4266 * of the context. When we return, we check if there are any
4267 * partial solutions that can potentially be merged. If so,
4268 * we perform a rollback to the initial state of the context.
4269 * The merging of partial solutions happens inside calls to
4270 * sol_dec_level that are pushed onto the undo stack of the context.
4271 * If there are no partial solutions that can potentially be merged
4272 * then the rollback is skipped as it would just be wasted effort.
4273 */
4274static void find_solutions_main(struct isl_sol *sol, struct isl_tab *tab)
4275{
4276 int row;
4277 void *saved;
4278
4279 if (!tab)
4280 goto error;
4281
4282 sol->level = 0;
4283
4284 for (row = tab->n_redundant; row < tab->n_row; ++row) {
4285 int p;
4286 struct isl_vec *eq;
4287
4288 if (!row_is_parameter_var(tab, row))
4289 continue;
4290 if (tab->row_var[row] < tab->n_param)
4291 p = tab->row_var[row];
4292 else
4293 p = tab->row_var[row]
4294 + tab->n_param - (tab->n_var - tab->n_div);
4295
4296 eq = isl_vec_alloc(tab->mat->ctx, 1+tab->n_param+tab->n_div);
4297 if (!eq)
4298 goto error;
4299 get_row_parameter_line(tab, row, eq->el);
4300 isl_int_neg(eq->el[1 + p], tab->mat->row[row][0]);
4301 eq = isl_vec_normalize(eq);
4302
4303 sol_inc_level(sol);
4304 no_sol_in_strict(sol, tab, eq);
4305
4306 isl_seq_neg(eq->el, eq->el, eq->size);
4307 sol_inc_level(sol);
4308 no_sol_in_strict(sol, tab, eq);
4309 isl_seq_neg(eq->el, eq->el, eq->size);
4310
4311 sol_context_add_eq(sol, eq->el, 1, 1);
4312
4313 isl_vec_free(eq);
4314
4315 if (isl_tab_mark_redundant(tab, row) < 0)
4316 goto error;
4317
4318 if (sol->context->op->is_empty(sol->context))
4319 break;
4320
4321 row = tab->n_redundant - 1;
4322 }
4323
4324 saved = sol->context->op->save(sol->context);
4325
4326 find_solutions(sol, tab);
4327
4329 sol->context->op->restore(sol->context, saved);
4330 else
4331 sol->context->op->discard(saved);
4332
4333 sol->level = 0;
4334 sol_pop(sol);
4335
4336 return;
4337error:
4338 isl_tab_free(tab);
4339 sol->error = 1;
4340}
4341
4342/* Is the local variable "div" of "bmap" an integer division
4343 * with a known expression that does not involve the "n" variables
4344 * starting at "first"?
4345 */
4347 unsigned div, unsigned first, unsigned n)
4348{
4349 isl_bool unknown, involves;
4350
4351 unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
4352 if (unknown < 0 || unknown)
4353 return isl_bool_not(unknown);
4354 involves = isl_basic_map_div_expr_involves_vars(bmap, div, first, n);
4355 return isl_bool_not(involves);
4356}
4357
4358/* Check if integer division "div" of "src" also occurs in "dst",
4359 * where the integer division "div" is known to involve
4360 * only the first "n_shared" variables.
4361 * If so, return its position within the local variables.
4362 * Otherwise, return a position beyond the local variables.
4363 */
4365 __isl_keep isl_basic_map *src, unsigned div, unsigned n_shared)
4366{
4367 int i;
4369 isl_size n_div;
4370
4372 n_div = isl_basic_map_dim(dst, isl_dim_div);
4373 if (total < 0 || n_div < 0)
4374 return isl_size_error;
4375
4376 for (i = 0; i < n_div; ++i) {
4377 isl_bool ok;
4378
4379 ok = is_known_div_not_involving(dst, i,
4380 n_shared, total - n_shared);
4381 if (ok < 0)
4382 return isl_size_error;
4383 if (!ok)
4384 continue;
4385 if (isl_seq_eq(dst->div[i], src->div[div], 2 + n_shared))
4386 return i;
4387 }
4388 return n_div;
4389}
4390
4391/* Check if integer division "div" of "dom" also occurs in "bmap".
4392 * If so, return its position within the divs.
4393 * Otherwise, return a position beyond the integer divisions.
4394 */
4396 __isl_keep isl_basic_set *dom, unsigned div)
4397{
4398 isl_size d_v_div;
4399 isl_size n_div, d_n_div;
4400 isl_bool ok;
4401
4402 d_v_div = isl_basic_set_var_offset(dom, isl_dim_div);
4403 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4404 d_n_div = isl_basic_set_dim(dom, isl_dim_div);
4405 if (d_v_div < 0 || n_div < 0 || d_n_div < 0)
4406 return isl_size_error;
4407
4409 d_v_div, d_n_div);
4410 if (ok < 0)
4411 return isl_size_error;
4412 if (!ok)
4413 return n_div;
4414
4415 return find_div_involving_only(bmap, bset_to_bmap(dom), div, d_v_div);
4416}
4417
4418/* Copy integer division "div" of "bmap", which is known to only involve
4419 * the first "n_shared" variables, to "dom" at position "dom_div".
4420 */
4423 unsigned div, unsigned n_shared, unsigned dom_div)
4424{
4425 isl_vec *v;
4427
4429 if (total < 0)
4430 return isl_basic_set_free(dom);
4431
4432 v = isl_vec_alloc(isl_basic_set_get_ctx(dom), 1 + 1 + total);
4433 if (!v)
4434 return isl_basic_set_free(dom);
4435
4436 isl_seq_cpy(v->el, bmap->div[div], 1 + 1 + n_shared);
4437 isl_seq_clr(v->el + 1 + 1 + n_shared, total - n_shared);
4438 dom = isl_basic_set_insert_div(dom, dom_div, v);
4439 dom = isl_basic_set_add_div_constraints(dom, dom_div);
4440 isl_vec_free(v);
4441
4442 return dom;
4443}
4444
4445/* Copy the integer divisions of "bmap" that only involve variables in "dom" and
4446 * that do not already appear in "dom" to "dom".
4447 */
4450{
4451 int i;
4452 isl_size dom_n_div, bmap_n_div, total;
4453 isl_size v_out;
4454
4455 dom_n_div = isl_basic_set_dim(dom, isl_dim_div);
4456 bmap_n_div = isl_basic_map_dim(bmap, isl_dim_div);
4459 if (dom_n_div < 0 || bmap_n_div < 0 || total < 0 || v_out < 0)
4460 return isl_basic_set_free(dom);
4461
4462 for (i = 0; i < bmap_n_div; ++i) {
4463 isl_bool ok;
4464 isl_size pos;
4465
4466 ok = is_known_div_not_involving(bmap, i, v_out, total - v_out);
4467 if (ok < 0)
4468 return isl_basic_set_free(dom);
4469 if (!ok)
4470 continue;
4472 bmap, i, v_out);
4473 if (pos < 0)
4474 return isl_basic_set_free(dom);
4475 if (pos < dom_n_div)
4476 continue;
4477 dom = copy_div(dom, bmap, i, v_out, dom_n_div++);
4478 }
4479
4480 return dom;
4481}
4482
4483/* The correspondence between the variables in the main tableau,
4484 * the context tableau, and the input map and domain is as follows.
4485 * The first n_param and the last n_div variables of the main tableau
4486 * form the variables of the context tableau.
4487 * In the basic map, these n_param variables correspond to the
4488 * parameters and the input dimensions. In the domain, they correspond
4489 * to the parameters and the set dimensions.
4490 * The n_div variables correspond to the integer divisions in the domain.
4491 * To ensure that everything lines up, we may need to copy some of the
4492 * integer divisions of the domain to the map. These have to be placed
4493 * in the same order as those in the context and they have to be placed
4494 * after any other integer divisions that the map may have.
4495 * This function performs the required reordering.
4496 */
4499{
4500 int i;
4501 int common = 0;
4502 int other;
4503 isl_size bmap_n_div, dom_n_div;
4504
4505 bmap_n_div = isl_basic_map_dim(bmap, isl_dim_div);
4506 dom_n_div = isl_basic_set_dim(dom, isl_dim_div);
4507 if (bmap_n_div < 0 || dom_n_div < 0)
4508 return isl_basic_map_free(bmap);
4509
4510 for (i = 0; i < dom_n_div; ++i) {
4511 isl_size pos;
4512
4513 pos = find_context_div(bmap, dom, i);
4514 if (pos < 0)
4515 return isl_basic_map_free(bmap);
4516 if (pos < bmap_n_div)
4517 common++;
4518 }
4519 other = bmap_n_div - common;
4520 if (dom_n_div - common > 0) {
4521 bmap = isl_basic_map_cow(bmap);
4522 bmap = isl_basic_map_extend(bmap, dom_n_div - common, 0, 0);
4523 if (!bmap)
4524 return NULL;
4525 }
4526 for (i = 0; i < dom_n_div; ++i) {
4527 isl_size pos = find_context_div(bmap, dom, i);
4528 if (pos < 0)
4529 bmap = isl_basic_map_free(bmap);
4530 if (pos >= bmap_n_div) {
4532 if (pos < 0)
4533 goto error;
4534 isl_int_set_si(bmap->div[pos][0], 0);
4535 bmap_n_div++;
4536 }
4537 if (pos != other + i)
4538 bmap = isl_basic_map_swap_div(bmap, pos, other + i);
4539 }
4540 return bmap;
4541error:
4542 isl_basic_map_free(bmap);
4543 return NULL;
4544}
4545
4546/* Base case of isl_tab_basic_map_partial_lexopt, after removing
4547 * some obvious symmetries.
4548 *
4549 * We make sure the divs in the domain are properly ordered,
4550 * because they will be added one by one in the given order
4551 * during the construction of the solution map.
4552 * Furthermore, make sure that the known integer divisions
4553 * appear before any unknown integer division because the solution
4554 * may depend on the known integer divisions, while anything that
4555 * depends on any variable starting from the first unknown integer
4556 * division is ignored in sol_pma_add.
4557 * First copy over any integer divisions from "bmap" that do not
4558 * already appear in "dom". This ensures that the tableau
4559 * will not be split on the corresponding integer division constraints
4560 * since they will be known to hold in "dom".
4561 */
4564 __isl_give isl_set **empty, int max,
4565 struct isl_sol *(*init)(__isl_keep isl_basic_map *bmap,
4566 __isl_take isl_basic_set *dom, int track_empty, int max))
4567{
4568 struct isl_tab *tab;
4569 struct isl_sol *sol = NULL;
4570 struct isl_context *context;
4571
4572 dom = copy_divs(dom, bmap);
4573 dom = isl_basic_set_sort_divs(dom);
4574 bmap = align_context_divs(bmap, dom);
4575 sol = init(bmap, dom, !!empty, max);
4576 if (!sol)
4577 goto error;
4578
4579 context = sol->context;
4580 if (isl_basic_set_plain_is_empty(context->op->peek_basic_set(context)))
4581 /* nothing */;
4582 else if (isl_basic_map_plain_is_empty(bmap)) {
4583 if (sol->add_empty)
4584 sol->add_empty(sol,
4585 isl_basic_set_copy(context->op->peek_basic_set(context)));
4586 } else {
4587 tab = tab_for_lexmin(bmap,
4588 context->op->peek_basic_set(context), 1, max);
4589 tab = context->op->detect_nonnegative_parameters(context, tab);
4590 find_solutions_main(sol, tab);
4591 }
4592 if (sol->error)
4593 goto error;
4594
4595 isl_basic_map_free(bmap);
4596 return sol;
4597error:
4598 sol_free(sol);
4599 isl_basic_map_free(bmap);
4600 return NULL;
4601}
4602
4603/* Base case of isl_tab_basic_map_partial_lexopt, after removing
4604 * some obvious symmetries.
4605 *
4606 * We call basic_map_partial_lexopt_base_sol and extract the results.
4607 */
4610 __isl_give isl_set **empty, int max)
4611{
4612 isl_map *result = NULL;
4613 struct isl_sol *sol;
4614 struct isl_sol_map *sol_map;
4615
4617 &sol_map_init);
4618 if (!sol)
4619 return NULL;
4620 sol_map = (struct isl_sol_map *) sol;
4621
4622 result = isl_map_copy(sol_map->map);
4623 if (empty)
4624 *empty = isl_set_copy(sol_map->empty);
4625 sol_free(&sol_map->sol);
4626 return result;
4627}
4628
4629/* Return a count of the number of occurrences of the "n" first
4630 * variables in the inequality constraints of "bmap".
4631 */
4633 int n)
4634{
4635 int i, j;
4636 isl_ctx *ctx;
4637 int *occurrences;
4638
4639 if (!bmap)
4640 return NULL;
4641 ctx = isl_basic_map_get_ctx(bmap);
4642 occurrences = isl_calloc_array(ctx, int, n);
4643 if (!occurrences)
4644 return NULL;
4645
4646 for (i = 0; i < bmap->n_ineq; ++i) {
4647 for (j = 0; j < n; ++j) {
4648 if (!isl_int_is_zero(bmap->ineq[i][1 + j]))
4649 occurrences[j]++;
4650 }
4651 }
4652
4653 return occurrences;
4654}
4655
4656/* Do all of the "n" variables with non-zero coefficients in "c"
4657 * occur in exactly a single constraint.
4658 * "occurrences" is an array of length "n" containing the number
4659 * of occurrences of each of the variables in the inequality constraints.
4660 */
4661static int single_occurrence(int n, isl_int *c, int *occurrences)
4662{
4663 int i;
4664
4665 for (i = 0; i < n; ++i) {
4666 if (isl_int_is_zero(c[i]))
4667 continue;
4668 if (occurrences[i] != 1)
4669 return 0;
4670 }
4671
4672 return 1;
4673}
4674
4675/* Do all of the "n" initial variables that occur in inequality constraint
4676 * "ineq" of "bmap" only occur in that constraint?
4677 */
4679 int n)
4680{
4681 int i, j;
4682
4683 for (i = 0; i < n; ++i) {
4684 if (isl_int_is_zero(bmap->ineq[ineq][1 + i]))
4685 continue;
4686 for (j = 0; j < bmap->n_ineq; ++j) {
4687 if (j == ineq)
4688 continue;
4689 if (!isl_int_is_zero(bmap->ineq[j][1 + i]))
4690 return 0;
4691 }
4692 }
4693
4694 return 1;
4695}
4696
4697/* Structure used during detection of parallel constraints.
4698 * n_in: number of "input" variables: isl_dim_param + isl_dim_in
4699 * n_out: number of "output" variables: isl_dim_out + isl_dim_div
4700 * val: the coefficients of the output variables
4701 */
4703 unsigned n_in;
4704 unsigned n_out;
4706};
4707
4708/* Check whether the coefficients of the output variables
4709 * of the constraint in "entry" are equal to info->val.
4710 */
4711static isl_bool constraint_equal(const void *entry, const void *val)
4712{
4713 isl_int **row = (isl_int **)entry;
4714 const struct isl_constraint_equal_info *info = val;
4715 int eq;
4716
4717 eq = isl_seq_eq((*row) + 1 + info->n_in, info->val, info->n_out);
4718 return isl_bool_ok(eq);
4719}
4720
4721/* Check whether "bmap" has a pair of constraints that have
4722 * the same coefficients for the output variables.
4723 * Note that the coefficients of the existentially quantified
4724 * variables need to be zero since the existentially quantified
4725 * of the result are usually not the same as those of the input.
4726 * Furthermore, check that each of the input variables that occur
4727 * in those constraints does not occur in any other constraint.
4728 * If so, return true and return the row indices of the two constraints
4729 * in *first and *second.
4730 */
4732 int *first, int *second)
4733{
4734 int i;
4735 isl_ctx *ctx;
4736 int *occurrences = NULL;
4737 struct isl_hash_table *table = NULL;
4738 struct isl_hash_table_entry *entry;
4739 struct isl_constraint_equal_info info;
4740 isl_size nparam, n_in, n_out, n_div;
4741
4742 ctx = isl_basic_map_get_ctx(bmap);
4743 table = isl_hash_table_alloc(ctx, bmap->n_ineq);
4744 if (!table)
4745 goto error;
4746
4747 nparam = isl_basic_map_dim(bmap, isl_dim_param);
4750 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4751 if (nparam < 0 || n_in < 0 || n_out < 0 || n_div < 0)
4752 goto error;
4753 info.n_in = nparam + n_in;
4754 occurrences = count_occurrences(bmap, info.n_in);
4755 if (info.n_in && !occurrences)
4756 goto error;
4757 info.n_out = n_out + n_div;
4758 for (i = 0; i < bmap->n_ineq; ++i) {
4759 uint32_t hash;
4760
4761 info.val = bmap->ineq[i] + 1 + info.n_in;
4762 if (!isl_seq_any_non_zero(info.val, n_out))
4763 continue;
4764 if (isl_seq_any_non_zero(info.val + n_out, n_div))
4765 continue;
4766 if (!single_occurrence(info.n_in, bmap->ineq[i] + 1,
4767 occurrences))
4768 continue;
4769 hash = isl_seq_get_hash(info.val, info.n_out);
4770 entry = isl_hash_table_find(ctx, table, hash,
4771 constraint_equal, &info, 1);
4772 if (!entry)
4773 goto error;
4774 if (entry->data)
4775 break;
4776 entry->data = &bmap->ineq[i];
4777 }
4778
4779 if (i < bmap->n_ineq) {
4780 *first = ((isl_int **)entry->data) - bmap->ineq;
4781 *second = i;
4782 }
4783
4784 isl_hash_table_free(ctx, table);
4785 free(occurrences);
4786
4787 return isl_bool_ok(i < bmap->n_ineq);
4788error:
4789 isl_hash_table_free(ctx, table);
4790 free(occurrences);
4791 return isl_bool_error;
4792}
4793
4794/* Given a set of upper bounds in "var", add constraints to "bset"
4795 * that make the i-th bound smallest.
4796 *
4797 * In particular, if there are n bounds b_i, then add the constraints
4798 *
4799 * b_i <= b_j for j > i
4800 * b_i < b_j for j < i
4801 */
4803 __isl_keep isl_mat *var, int i)
4804{
4805 isl_ctx *ctx;
4806 int j, k;
4807
4808 ctx = isl_mat_get_ctx(var);
4809
4810 for (j = 0; j < var->n_row; ++j) {
4811 if (j == i)
4812 continue;
4814 if (k < 0)
4815 goto error;
4816 isl_seq_combine(bset->ineq[k], ctx->one, var->row[j],
4817 ctx->negone, var->row[i], var->n_col);
4818 isl_int_set_si(bset->ineq[k][var->n_col], 0);
4819 if (j < i)
4820 isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1);
4821 }
4822
4823 bset = isl_basic_set_finalize(bset);
4824
4825 return bset;
4826error:
4827 isl_basic_set_free(bset);
4828 return NULL;
4829}
4830
4831/* Given a set of upper bounds on the last "input" variable m,
4832 * construct a set that assigns the minimal upper bound to m, i.e.,
4833 * construct a set that divides the space into cells where one
4834 * of the upper bounds is smaller than all the others and assign
4835 * this upper bound to m.
4836 *
4837 * In particular, if there are n bounds b_i, then the result
4838 * consists of n basic sets, each one of the form
4839 *
4840 * m = b_i
4841 * b_i <= b_j for j > i
4842 * b_i < b_j for j < i
4843 */
4846{
4847 int i, k;
4848 isl_basic_set *bset = NULL;
4849 isl_set *set = NULL;
4850
4851 if (!space || !var)
4852 goto error;
4853
4855 var->n_row, ISL_SET_DISJOINT);
4856
4857 for (i = 0; i < var->n_row; ++i) {
4859 1, var->n_row - 1);
4861 if (k < 0)
4862 goto error;
4863 isl_seq_cpy(bset->eq[k], var->row[i], var->n_col);
4864 isl_int_set_si(bset->eq[k][var->n_col], -1);
4865 bset = select_minimum(bset, var, i);
4866 set = isl_set_add_basic_set(set, bset);
4867 }
4868
4869 isl_space_free(space);
4871 return set;
4872error:
4873 isl_basic_set_free(bset);
4875 isl_space_free(space);
4877 return NULL;
4878}
4879
4880/* Given that the last input variable of "bmap" represents the minimum
4881 * of the bounds in "cst", check whether we need to split the domain
4882 * based on which bound attains the minimum.
4883 *
4884 * A split is needed when the minimum appears in an integer division
4885 * or in an equality. Otherwise, it is only needed if it appears in
4886 * an upper bound that is different from the upper bounds on which it
4887 * is defined.
4888 */
4890 __isl_keep isl_mat *cst)
4891{
4892 int i, j;
4893 isl_bool involves;
4895 unsigned pos;
4896
4897 pos = cst->n_col - 1;
4899 if (total < 0)
4900 return isl_bool_error;
4901
4902 involves = isl_basic_map_any_div_involves_vars(bmap, pos, 1);
4903 if (involves < 0 || involves)
4904 return involves;
4905
4906 for (i = 0; i < bmap->n_eq; ++i)
4907 if (!isl_int_is_zero(bmap->eq[i][1 + pos]))
4908 return isl_bool_true;
4909
4910 for (i = 0; i < bmap->n_ineq; ++i) {
4911 if (isl_int_is_nonneg(bmap->ineq[i][1 + pos]))
4912 continue;
4913 if (!isl_int_is_negone(bmap->ineq[i][1 + pos]))
4914 return isl_bool_true;
4915 if (isl_seq_any_non_zero(bmap->ineq[i] + 1 + pos + 1,
4916 total - pos - 1))
4917 return isl_bool_true;
4918
4919 for (j = 0; j < cst->n_row; ++j)
4920 if (isl_seq_eq(bmap->ineq[i], cst->row[j], cst->n_col))
4921 break;
4922 if (j >= cst->n_row)
4923 return isl_bool_true;
4924 }
4925
4926 return isl_bool_false;
4927}
4928
4929/* Given that the last set variable of "bset" represents the minimum
4930 * of the bounds in "cst", check whether we need to split the domain
4931 * based on which bound attains the minimum.
4932 *
4933 * We simply call need_split_basic_map here. This is safe because
4934 * the position of the minimum is computed from "cst" and not
4935 * from "bmap".
4936 */
4938 __isl_keep isl_mat *cst)
4939{
4940 return need_split_basic_map(bset_to_bmap(bset), cst);
4941}
4942
4943/* Given that the last set variable of "set" represents the minimum
4944 * of the bounds in "cst", check whether we need to split the domain
4945 * based on which bound attains the minimum.
4946 */
4948{
4949 int i;
4950
4951 for (i = 0; i < set->n; ++i) {
4953
4954 split = need_split_basic_set(set->p[i], cst);
4955 if (split < 0 || split)
4956 return split;
4957 }
4958
4959 return isl_bool_false;
4960}
4961
4962/* Given a map of which the last input variable is the minimum
4963 * of the bounds in "cst", split each basic set in the set
4964 * in pieces where one of the bounds is (strictly) smaller than the others.
4965 * This subdivision is given in "min_expr".
4966 * The variable is subsequently projected out.
4967 *
4968 * We only do the split when it is needed.
4969 * For example if the last input variable m = min(a,b) and the only
4970 * constraints in the given basic set are lower bounds on m,
4971 * i.e., l <= m = min(a,b), then we can simply project out m
4972 * to obtain l <= a and l <= b, without having to split on whether
4973 * m is equal to a or b.
4974 */
4976 __isl_take isl_set *min_expr, __isl_take isl_mat *cst)
4977{
4978 isl_size n_in;
4979 int i;
4980 isl_space *space;
4981 isl_map *res;
4982
4983 n_in = isl_map_dim(opt, isl_dim_in);
4984 if (n_in < 0 || !min_expr || !cst)
4985 goto error;
4986
4987 space = isl_map_get_space(opt);
4988 space = isl_space_drop_dims(space, isl_dim_in, n_in - 1, 1);
4989 res = isl_map_empty(space);
4990
4991 for (i = 0; i < opt->n; ++i) {
4992 isl_map *map;
4994
4996 split = need_split_basic_map(opt->p[i], cst);
4997 if (split < 0)
4998 map = isl_map_free(map);
4999 else if (split)
5001 isl_set_copy(min_expr));
5003
5005 }
5006
5007 isl_map_free(opt);
5008 isl_set_free(min_expr);
5009 isl_mat_free(cst);
5010 return res;
5011error:
5012 isl_map_free(opt);
5013 isl_set_free(min_expr);
5014 isl_mat_free(cst);
5015 return NULL;
5016}
5017
5018/* Given a set of which the last set variable is the minimum
5019 * of the bounds in "cst", split each basic set in the set
5020 * in pieces where one of the bounds is (strictly) smaller than the others.
5021 * This subdivision is given in "min_expr".
5022 * The variable is subsequently projected out.
5023 */
5025 __isl_take isl_set *min_expr, __isl_take isl_mat *cst)
5026{
5027 isl_map *map;
5028
5029 map = isl_map_from_domain(empty);
5030 map = split_domain(map, min_expr, cst);
5031 empty = isl_map_domain(map);
5032
5033 return empty;
5034}
5035
5038 __isl_give isl_set **empty, int max);
5039
5040/* This function is called from basic_map_partial_lexopt_symm.
5041 * The last variable of "bmap" and "dom" corresponds to the minimum
5042 * of the bounds in "cst". "map_space" is the space of the original
5043 * input relation (of basic_map_partial_lexopt_symm) and "set_space"
5044 * is the space of the original domain.
5045 *
5046 * We recursively call basic_map_partial_lexopt and then plug in
5047 * the definition of the minimum in the result.
5048 */
5051 __isl_give isl_set **empty, int max, __isl_take isl_mat *cst,
5052 __isl_take isl_space *map_space, __isl_take isl_space *set_space)
5053{
5054 isl_map *opt;
5055 isl_set *min_expr;
5056
5057 min_expr = set_minimum(isl_basic_set_get_space(dom), isl_mat_copy(cst));
5058
5059 opt = basic_map_partial_lexopt(bmap, dom, empty, max);
5060
5061 if (empty) {
5062 *empty = split(*empty,
5063 isl_set_copy(min_expr), isl_mat_copy(cst));
5064 *empty = isl_set_reset_space(*empty, set_space);
5065 }
5066
5067 opt = split_domain(opt, min_expr, cst);
5068 opt = isl_map_reset_space(opt, map_space);
5069
5070 return opt;
5071}
5072
5073/* Extract a domain from "bmap" for the purpose of computing
5074 * a lexicographic optimum.
5075 *
5076 * This function is only called when the caller wants to compute a full
5077 * lexicographic optimum, i.e., without specifying a domain. In this case,
5078 * the caller is not interested in the part of the domain space where
5079 * there is no solution and the domain can be initialized to those constraints
5080 * of "bmap" that only involve the parameters and the input dimensions.
5081 * This relieves the parametric programming engine from detecting those
5082 * inequalities and transferring them to the context. More importantly,
5083 * it ensures that those inequalities are transferred first and not
5084 * intermixed with inequalities that actually split the domain.
5085 *
5086 * If the caller does not require the absence of existentially quantified
5087 * variables in the result (i.e., if ISL_OPT_QE is not set in "flags"),
5088 * then the actual domain of "bmap" can be used. This ensures that
5089 * the domain does not need to be split at all just to separate out
5090 * pieces of the domain that do not have a solution from piece that do.
5091 * This domain cannot be used in general because it may involve
5092 * (unknown) existentially quantified variables which will then also
5093 * appear in the solution.
5094 */
5096 unsigned flags)
5097{
5098 isl_size n_div;
5100
5101 n_div = isl_basic_map_dim(bmap, isl_dim_div);
5103 if (n_div < 0 || n_out < 0)
5104 return NULL;
5105 bmap = isl_basic_map_copy(bmap);
5106 if (ISL_FL_ISSET(flags, ISL_OPT_QE)) {
5108 isl_dim_div, 0, n_div);
5110 isl_dim_out, 0, n_out);
5111 }
5112 return isl_basic_map_domain(bmap);
5113}
5114
5115#undef TYPE
5116#define TYPE isl_map
5117#undef SUFFIX
5118#define SUFFIX
5119#define isl_map_pullback_multi_aff isl_map_preimage_domain_multi_aff
5120#include "isl_tab_lexopt_templ.c"
5121
5122/* Extract the subsequence of the sample value of "tab"
5123 * starting at "pos" and of length "len".
5124 */
5126 int pos, int len)
5127{
5128 int i;
5129 isl_ctx *ctx;
5130 isl_vec *v;
5131
5132 ctx = isl_tab_get_ctx(tab);
5133 v = isl_vec_alloc(ctx, len);
5134 if (!v)
5135 return NULL;
5136 for (i = 0; i < len; ++i) {
5137 if (!tab->var[pos + i].is_row) {
5138 isl_int_set_si(v->el[i], 0);
5139 } else {
5140 int row;
5141
5142 row = tab->var[pos + i].index;
5143 isl_int_divexact(v->el[i], tab->mat->row[row][1],
5144 tab->mat->row[row][0]);
5145 }
5146 }
5147
5148 return v;
5149}
5150
5151/* Check if the sequence of variables starting at "pos"
5152 * represents a trivial solution according to "trivial".
5153 * That is, is the result of applying "trivial" to this sequence
5154 * equal to the zero vector?
5155 */
5156static isl_bool region_is_trivial(struct isl_tab *tab, int pos,
5157 __isl_keep isl_mat *trivial)
5158{
5159 isl_size n, len;
5160 isl_vec *v;
5162
5163 n = isl_mat_rows(trivial);
5164 if (n < 0)
5165 return isl_bool_error;
5166
5167 if (n == 0)
5168 return isl_bool_false;
5169
5170 len = isl_mat_cols(trivial);
5171 if (len < 0)
5172 return isl_bool_error;
5173 v = extract_sample_sequence(tab, pos, len);
5174 v = isl_mat_vec_product(isl_mat_copy(trivial), v);
5176 isl_vec_free(v);
5177
5178 return is_trivial;
5179}
5180
5181/* Global internal data for isl_tab_basic_set_non_trivial_lexmin.
5182 *
5183 * "n_op" is the number of initial coordinates to optimize,
5184 * as passed to isl_tab_basic_set_non_trivial_lexmin.
5185 * "region" is the "n_region"-sized array of regions passed
5186 * to isl_tab_basic_set_non_trivial_lexmin.
5187 *
5188 * "tab" is the tableau that corresponds to the ILP problem.
5189 * "local" is an array of local data structure, one for each
5190 * (potential) level of the backtracking procedure of
5191 * isl_tab_basic_set_non_trivial_lexmin.
5192 * "v" is a pre-allocated vector that can be used for adding
5193 * constraints to the tableau.
5194 *
5195 * "sol" contains the best solution found so far.
5196 * It is initialized to a vector of size zero.
5197 */
5209
5210/* Return the index of the first trivial region, "n_region" if all regions
5211 * are non-trivial or -1 in case of error.
5212 */
5214{
5215 int i;
5216
5217 for (i = 0; i < data->n_region; ++i) {
5218 isl_bool trivial;
5219 trivial = region_is_trivial(data->tab, data->region[i].pos,
5220 data->region[i].trivial);
5221 if (trivial < 0)
5222 return -1;
5223 if (trivial)
5224 return i;
5225 }
5226
5227 return data->n_region;
5228}
5229
5230/* Check if the solution is optimal, i.e., whether the first
5231 * n_op entries are zero.
5232 */
5233static int is_optimal(__isl_keep isl_vec *sol, int n_op)
5234{
5235 int i;
5236
5237 for (i = 0; i < n_op; ++i)
5238 if (!isl_int_is_zero(sol->el[1 + i]))
5239 return 0;
5240 return 1;
5241}
5242
5243/* Add constraints to "tab" that ensure that any solution is significantly
5244 * better than that represented by "sol". That is, find the first
5245 * relevant (within first n_op) non-zero coefficient and force it (along
5246 * with all previous coefficients) to be zero.
5247 * If the solution is already optimal (all relevant coefficients are zero),
5248 * then just mark the table as empty.
5249 * "n_zero" is the number of coefficients that have been forced zero
5250 * by previous calls to this function at the same level.
5251 * Return the updated number of forced zero coefficients or -1 on error.
5252 *
5253 * This function assumes that at least 2 * (n_op - n_zero) more rows and
5254 * at least 2 * (n_op - n_zero) more elements in the constraint array
5255 * are available in the tableau.
5256 */
5257static int force_better_solution(struct isl_tab *tab,
5258 __isl_keep isl_vec *sol, int n_op, int n_zero)
5259{
5260 int i, n;
5261 isl_ctx *ctx;
5262 isl_vec *v = NULL;
5263
5264 if (!sol)
5265 return -1;
5266
5267 for (i = n_zero; i < n_op; ++i)
5268 if (!isl_int_is_zero(sol->el[1 + i]))
5269 break;
5270
5271 if (i == n_op) {
5272 if (isl_tab_mark_empty(tab) < 0)
5273 return -1;
5274 return n_op;
5275 }
5276
5277 ctx = isl_vec_get_ctx(sol);
5278 v = isl_vec_alloc(ctx, 1 + tab->n_var);
5279 if (!v)
5280 return -1;
5281
5282 n = i + 1;
5283 for (; i >= n_zero; --i) {
5284 v = isl_vec_clr(v);
5285 isl_int_set_si(v->el[1 + i], -1);
5286 if (add_lexmin_eq(tab, v->el) < 0)
5287 goto error;
5288 }
5289
5290 isl_vec_free(v);
5291 return n;
5292error:
5293 isl_vec_free(v);
5294 return -1;
5295}
5296
5297/* Fix triviality direction "dir" of the given region to zero.
5298 *
5299 * This function assumes that at least two more rows and at least
5300 * two more elements in the constraint array are available in the tableau.
5301 */
5303 int dir, struct isl_lexmin_data *data)
5304{
5305 isl_size len;
5306
5307 data->v = isl_vec_clr(data->v);
5308 if (!data->v)
5309 return isl_stat_error;
5310 len = isl_mat_cols(region->trivial);
5311 if (len < 0)
5312 return isl_stat_error;
5313 isl_seq_cpy(data->v->el + 1 + region->pos, region->trivial->row[dir],
5314 len);
5315 if (add_lexmin_eq(tab, data->v->el) < 0)
5316 return isl_stat_error;
5317
5318 return isl_stat_ok;
5319}
5320
5321/* This function selects case "side" for non-triviality region "region",
5322 * assuming all the equality constraints have been imposed already.
5323 * In particular, the triviality direction side/2 is made positive
5324 * if side is even and made negative if side is odd.
5325 *
5326 * This function assumes that at least one more row and at least
5327 * one more element in the constraint array are available in the tableau.
5328 */
5329static struct isl_tab *pos_neg(struct isl_tab *tab,
5330 struct isl_trivial_region *region,
5331 int side, struct isl_lexmin_data *data)
5332{
5333 isl_size len;
5334
5335 data->v = isl_vec_clr(data->v);
5336 if (!data->v)
5337 goto error;
5338 isl_int_set_si(data->v->el[0], -1);
5339 len = isl_mat_cols(region->trivial);
5340 if (len < 0)
5341 goto error;
5342 if (side % 2 == 0)
5343 isl_seq_cpy(data->v->el + 1 + region->pos,
5344 region->trivial->row[side / 2], len);
5345 else
5346 isl_seq_neg(data->v->el + 1 + region->pos,
5347 region->trivial->row[side / 2], len);
5348 return add_lexmin_ineq(tab, data->v->el);
5349error:
5350 isl_tab_free(tab);
5351 return NULL;
5352}
5353
5354/* Local data at each level of the backtracking procedure of
5355 * isl_tab_basic_set_non_trivial_lexmin.
5356 *
5357 * "update" is set if a solution has been found in the current case
5358 * of this level, such that a better solution needs to be enforced
5359 * in the next case.
5360 * "n_zero" is the number of initial coordinates that have already
5361 * been forced to be zero at this level.
5362 * "region" is the non-triviality region considered at this level.
5363 * "side" is the index of the current case at this level.
5364 * "n" is the number of triviality directions.
5365 * "snap" is a snapshot of the tableau holding a state that needs
5366 * to be satisfied by all subsequent cases.
5367 */
5376
5377/* Initialize the global data structure "data" used while solving
5378 * the ILP problem "bset".
5379 */
5382{
5383 isl_ctx *ctx;
5384
5385 ctx = isl_basic_set_get_ctx(bset);
5386
5387 data->tab = tab_for_lexmin(bset, NULL, 0, 0);
5388 if (!data->tab)
5389 return isl_stat_error;
5390
5391 data->v = isl_vec_alloc(ctx, 1 + data->tab->n_var);
5392 if (!data->v)
5393 return isl_stat_error;
5394 data->local = isl_calloc_array(ctx, struct isl_local_region,
5395 data->n_region);
5396 if (data->n_region && !data->local)
5397 return isl_stat_error;
5398
5399 data->sol = isl_vec_alloc(ctx, 0);
5400
5401 return isl_stat_ok;
5402}
5403
5404/* Mark all outer levels as requiring a better solution
5405 * in the next cases.
5406 */
5407static void update_outer_levels(struct isl_lexmin_data *data, int level)
5408{
5409 int i;
5410
5411 for (i = 0; i < level; ++i)
5412 data->local[i].update = 1;
5413}
5414
5415/* Initialize "local" to refer to region "region" and
5416 * to initiate processing at this level.
5417 */
5418static isl_stat init_local_region(struct isl_local_region *local, int region,
5419 struct isl_lexmin_data *data)
5420{
5421 isl_size n = isl_mat_rows(data->region[region].trivial);
5422
5423 if (n < 0)
5424 return isl_stat_error;
5425 local->n = n;
5426 local->region = region;
5427 local->side = 0;
5428 local->update = 0;
5429 local->n_zero = 0;
5430
5431 return isl_stat_ok;
5432}
5433
5434/* What to do next after entering a level of the backtracking procedure.
5435 *
5436 * error: some error has occurred; abort
5437 * done: an optimal solution has been found; stop search
5438 * backtrack: backtrack to the previous level
5439 * handle: add the constraints for the current level and
5440 * move to the next level
5441 */
5448
5449/* Have all cases of the current region been considered?
5450 * If there are n directions, then there are 2n cases.
5451 *
5452 * The constraints in the current tableau are imposed
5453 * in all subsequent cases. This means that if the current
5454 * tableau is empty, then none of those cases should be considered
5455 * anymore and all cases have effectively been considered.
5456 */
5457static int finished_all_cases(struct isl_local_region *local,
5458 struct isl_lexmin_data *data)
5459{
5460 if (data->tab->empty)
5461 return 1;
5462 return local->side >= 2 * local->n;
5463}
5464
5465/* Enter level "level" of the backtracking search and figure out
5466 * what to do next. "init" is set if the level was entered
5467 * from a higher level and needs to be initialized.
5468 * Otherwise, the level is entered as a result of backtracking and
5469 * the tableau needs to be restored to a position that can
5470 * be used for the next case at this level.
5471 * The snapshot is assumed to have been saved in the previous case,
5472 * before the constraints specific to that case were added.
5473 *
5474 * In the initialization case, the local region is initialized
5475 * to point to the first violated region.
5476 * If the constraints of all regions are satisfied by the current
5477 * sample of the tableau, then tell the caller to continue looking
5478 * for a better solution or to stop searching if an optimal solution
5479 * has been found.
5480 *
5481 * If the tableau is empty or if all cases at the current level
5482 * have been considered, then the caller needs to backtrack as well.
5483 */
5484static enum isl_next enter_level(int level, int init,
5485 struct isl_lexmin_data *data)
5486{
5487 struct isl_local_region *local = &data->local[level];
5488
5489 if (init) {
5490 int r;
5491
5492 data->tab = cut_to_integer_lexmin(data->tab, CUT_ONE);
5493 if (!data->tab)
5494 return isl_next_error;
5495 if (data->tab->empty)
5496 return isl_next_backtrack;
5497 r = first_trivial_region(data);
5498 if (r < 0)
5499 return isl_next_error;
5500 if (r == data->n_region) {
5501 update_outer_levels(data, level);
5502 isl_vec_free(data->sol);
5503 data->sol = isl_tab_get_sample_value(data->tab);
5504 if (!data->sol)
5505 return isl_next_error;
5506 if (is_optimal(data->sol, data->n_op))
5507 return isl_next_done;
5508 return isl_next_backtrack;
5509 }
5510 if (level >= data->n_region)
5512 "nesting level too deep",
5513 return isl_next_error);
5514 if (init_local_region(local, r, data) < 0)
5515 return isl_next_error;
5516 if (isl_tab_extend_cons(data->tab,
5517 2 * local->n + 2 * data->n_op) < 0)
5518 return isl_next_error;
5519 } else {
5520 if (isl_tab_rollback(data->tab, local->snap) < 0)
5521 return isl_next_error;
5522 }
5523
5524 if (finished_all_cases(local, data))
5525 return isl_next_backtrack;
5526 return isl_next_handle;
5527}
5528
5529/* If a solution has been found in the previous case at this level
5530 * (marked by local->update being set), then add constraints
5531 * that enforce a better solution in the present and all following cases.
5532 * The constraints only need to be imposed once because they are
5533 * included in the snapshot (taken in pick_side) that will be used in
5534 * subsequent cases.
5535 */
5537 struct isl_lexmin_data *data)
5538{
5539 if (!local->update)
5540 return isl_stat_ok;
5541
5542 local->n_zero = force_better_solution(data->tab,
5543 data->sol, data->n_op, local->n_zero);
5544 if (local->n_zero < 0)
5545 return isl_stat_error;
5546
5547 local->update = 0;
5548
5549 return isl_stat_ok;
5550}
5551
5552/* Add constraints to data->tab that select the current case (local->side)
5553 * at the current level.
5554 *
5555 * If the linear combinations v should not be zero, then the cases are
5556 * v_0 >= 1
5557 * v_0 <= -1
5558 * v_0 = 0 and v_1 >= 1
5559 * v_0 = 0 and v_1 <= -1
5560 * v_0 = 0 and v_1 = 0 and v_2 >= 1
5561 * v_0 = 0 and v_1 = 0 and v_2 <= -1
5562 * ...
5563 * in this order.
5564 *
5565 * A snapshot is taken after the equality constraint (if any) has been added
5566 * such that the next case can start off from this position.
5567 * The rollback to this position is performed in enter_level.
5568 */
5570 struct isl_lexmin_data *data)
5571{
5572 struct isl_trivial_region *region;
5573 int side, base;
5574
5575 region = &data->region[local->region];
5576 side = local->side;
5577 base = 2 * (side/2);
5578
5579 if (side == base && base >= 2 &&
5580 fix_zero(data->tab, region, base / 2 - 1, data) < 0)
5581 return isl_stat_error;
5582
5583 local->snap = isl_tab_snap(data->tab);
5584 if (isl_tab_push_basis(data->tab) < 0)
5585 return isl_stat_error;
5586
5587 data->tab = pos_neg(data->tab, region, side, data);
5588 if (!data->tab)
5589 return isl_stat_error;
5590 return isl_stat_ok;
5591}
5592
5593/* Free the memory associated to "data".
5594 */
5595static void clear_lexmin_data(struct isl_lexmin_data *data)
5596{
5597 free(data->local);
5598 isl_vec_free(data->v);
5599 isl_tab_free(data->tab);
5600}
5601
5602/* Return the lexicographically smallest non-trivial solution of the
5603 * given ILP problem.
5604 *
5605 * All variables are assumed to be non-negative.
5606 *
5607 * n_op is the number of initial coordinates to optimize.
5608 * That is, once a solution has been found, we will only continue looking
5609 * for solutions that result in significantly better values for those
5610 * initial coordinates. That is, we only continue looking for solutions
5611 * that increase the number of initial zeros in this sequence.
5612 *
5613 * A solution is non-trivial, if it is non-trivial on each of the
5614 * specified regions. Each region represents a sequence of
5615 * triviality directions on a sequence of variables that starts
5616 * at a given position. A solution is non-trivial on such a region if
5617 * at least one of the triviality directions is non-zero
5618 * on that sequence of variables.
5619 *
5620 * Whenever a conflict is encountered, all constraints involved are
5621 * reported to the caller through a call to "conflict".
5622 *
5623 * We perform a simple branch-and-bound backtracking search.
5624 * Each level in the search represents an initially trivial region
5625 * that is forced to be non-trivial.
5626 * At each level we consider 2 * n cases, where n
5627 * is the number of triviality directions.
5628 * In terms of those n directions v_i, we consider the cases
5629 * v_0 >= 1
5630 * v_0 <= -1
5631 * v_0 = 0 and v_1 >= 1
5632 * v_0 = 0 and v_1 <= -1
5633 * v_0 = 0 and v_1 = 0 and v_2 >= 1
5634 * v_0 = 0 and v_1 = 0 and v_2 <= -1
5635 * ...
5636 * in this order.
5637 */
5639 __isl_take isl_basic_set *bset, int n_op, int n_region,
5640 struct isl_trivial_region *region,
5641 int (*conflict)(int con, void *user), void *user)
5642{
5643 struct isl_lexmin_data data = { n_op, n_region, region };
5644 int level, init;
5645
5646 if (!bset)
5647 return NULL;
5648
5649 if (init_lexmin_data(&data, bset) < 0)
5650 goto error;
5651 data.tab->conflict = conflict;
5652 data.tab->conflict_user = user;
5653
5654 level = 0;
5655 init = 1;
5656
5657 while (level >= 0) {
5658 enum isl_next next;
5659 struct isl_local_region *local = &data.local[level];
5660
5661 next = enter_level(level, init, &data);
5662 if (next < 0)
5663 goto error;
5664 if (next == isl_next_done)
5665 break;
5666 if (next == isl_next_backtrack) {
5667 level--;
5668 init = 0;
5669 continue;
5670 }
5671
5672 if (better_next_side(local, &data) < 0)
5673 goto error;
5674 if (pick_side(local, &data) < 0)
5675 goto error;
5676
5677 local->side++;
5678 level++;
5679 init = 1;
5680 }
5681
5682 clear_lexmin_data(&data);
5683 isl_basic_set_free(bset);
5684
5685 return data.sol;
5686error:
5687 clear_lexmin_data(&data);
5688 isl_basic_set_free(bset);
5689 isl_vec_free(data.sol);
5690 return NULL;
5691}
5692
5693/* Wrapper for a tableau that is used for computing
5694 * the lexicographically smallest rational point of a non-negative set.
5695 * This point is represented by the sample value of "tab",
5696 * unless "tab" is empty.
5697 */
5702
5703/* Free "tl" and return NULL.
5704 */
5706{
5707 if (!tl)
5708 return NULL;
5709 isl_ctx_deref(tl->ctx);
5710 isl_tab_free(tl->tab);
5711 free(tl);
5712
5713 return NULL;
5714}
5715
5716/* Construct an isl_tab_lexmin for computing
5717 * the lexicographically smallest rational point in "bset",
5718 * assuming that all variables are non-negative.
5719 */
5722{
5723 isl_ctx *ctx;
5724 isl_tab_lexmin *tl;
5725
5726 if (!bset)
5727 return NULL;
5728
5729 ctx = isl_basic_set_get_ctx(bset);
5730 tl = isl_calloc_type(ctx, struct isl_tab_lexmin);
5731 if (!tl)
5732 goto error;
5733 tl->ctx = ctx;
5734 isl_ctx_ref(ctx);
5735 tl->tab = tab_for_lexmin(bset, NULL, 0, 0);
5736 isl_basic_set_free(bset);
5737 if (!tl->tab)
5738 return isl_tab_lexmin_free(tl);
5739 return tl;
5740error:
5741 isl_basic_set_free(bset);
5743 return NULL;
5744}
5745
5746/* Return the dimension of the set represented by "tl".
5747 */
5749{
5750 return tl ? tl->tab->n_var : -1;
5751}
5752
5753/* Add the equality with coefficients "eq" to "tl", updating the optimal
5754 * solution if needed.
5755 * The equality is added as two opposite inequality constraints.
5756 */
5758 isl_int *eq)
5759{
5760 unsigned n_var;
5761
5762 if (!tl || !eq)
5763 return isl_tab_lexmin_free(tl);
5764
5765 if (isl_tab_extend_cons(tl->tab, 2) < 0)
5766 return isl_tab_lexmin_free(tl);
5767 n_var = tl->tab->n_var;
5768 isl_seq_neg(eq, eq, 1 + n_var);
5769 tl->tab = add_lexmin_ineq(tl->tab, eq);
5770 isl_seq_neg(eq, eq, 1 + n_var);
5771 tl->tab = add_lexmin_ineq(tl->tab, eq);
5772
5773 if (!tl->tab)
5774 return isl_tab_lexmin_free(tl);
5775
5776 return tl;
5777}
5778
5779/* Add cuts to "tl" until the sample value reaches an integer value or
5780 * until the result becomes empty.
5781 */
5784{
5785 if (!tl)
5786 return NULL;
5787 tl->tab = cut_to_integer_lexmin(tl->tab, CUT_ONE);
5788 if (!tl->tab)
5789 return isl_tab_lexmin_free(tl);
5790 return tl;
5791}
5792
5793/* Return the lexicographically smallest rational point in the basic set
5794 * from which "tl" was constructed.
5795 * If the original input was empty, then return a zero-length vector.
5796 */
5798{
5799 if (!tl)
5800 return NULL;
5801 if (tl->tab->empty)
5802 return isl_vec_alloc(tl->ctx, 0);
5803 else
5804 return isl_tab_get_sample_value(tl->tab);
5805}
5806
5812
5813static void sol_pma_free(struct isl_sol *sol)
5814{
5815 struct isl_sol_pma *sol_pma = (struct isl_sol_pma *) sol;
5816 isl_pw_multi_aff_free(sol_pma->pma);
5817 isl_set_free(sol_pma->empty);
5818}
5819
5820/* This function is called for parts of the context where there is
5821 * no solution, with "bset" corresponding to the context tableau.
5822 * Simply add the basic set to the set "empty".
5823 */
5826{
5827 if (!bset || !sol->empty)
5828 goto error;
5829
5830 sol->empty = isl_set_grow(sol->empty, 1);
5831 bset = isl_basic_set_simplify(bset);
5832 bset = isl_basic_set_finalize(bset);
5833 sol->empty = isl_set_add_basic_set(sol->empty, bset);
5834 if (!sol->empty)
5835 sol->sol.error = 1;
5836 return;
5837error:
5838 isl_basic_set_free(bset);
5839 sol->sol.error = 1;
5840}
5841
5842/* Given a basic set "dom" that represents the context and a tuple of
5843 * affine expressions "maff" defined over this domain, construct
5844 * an isl_pw_multi_aff with a single cell corresponding to "dom" and
5845 * the affine expressions in "maff".
5846 */
5847static void sol_pma_add(struct isl_sol_pma *sol,
5849{
5851
5852 dom = isl_basic_set_simplify(dom);
5853 dom = isl_basic_set_finalize(dom);
5856 if (!sol->pma)
5857 sol->sol.error = 1;
5858}
5859
5862{
5863 sol_pma_add_empty((struct isl_sol_pma *)sol, bset);
5864}
5865
5866static void sol_pma_add_wrap(struct isl_sol *sol,
5868{
5869 sol_pma_add((struct isl_sol_pma *)sol, dom, ma);
5870}
5871
5872/* Construct an isl_sol_pma structure for accumulating the solution.
5873 * If track_empty is set, then we also keep track of the parts
5874 * of the context where there is no solution.
5875 * If max is set, then we are solving a maximization, rather than
5876 * a minimization problem, which means that the variables in the
5877 * tableau have value "M - x" rather than "M + x".
5878 */
5880 __isl_take isl_basic_set *dom, int track_empty, int max)
5881{
5882 struct isl_sol_pma *sol_pma = NULL;
5883 isl_space *space;
5884
5885 if (!bmap)
5886 goto error;
5887
5888 sol_pma = isl_calloc_type(bmap->ctx, struct isl_sol_pma);
5889 if (!sol_pma)
5890 goto error;
5891
5892 sol_pma->sol.free = &sol_pma_free;
5893 if (sol_init(&sol_pma->sol, bmap, dom, max) < 0)
5894 goto error;
5895 sol_pma->sol.add = &sol_pma_add_wrap;
5896 sol_pma->sol.add_empty = track_empty ? &sol_pma_add_empty_wrap : NULL;
5897 space = isl_space_copy(sol_pma->sol.space);
5898 sol_pma->pma = isl_pw_multi_aff_empty(space);
5899 if (!sol_pma->pma)
5900 goto error;
5901
5902 if (track_empty) {
5904 1, ISL_SET_DISJOINT);
5905 if (!sol_pma->empty)
5906 goto error;
5907 }
5908
5909 isl_basic_set_free(dom);
5910 return &sol_pma->sol;
5911error:
5912 isl_basic_set_free(dom);
5913 sol_free(&sol_pma->sol);
5914 return NULL;
5915}
5916
5917/* Base case of isl_tab_basic_map_partial_lexopt, after removing
5918 * some obvious symmetries.
5919 *
5920 * We call basic_map_partial_lexopt_base_sol and extract the results.
5921 */
5924 __isl_give isl_set **empty, int max)
5925{
5926 isl_pw_multi_aff *result = NULL;
5927 struct isl_sol *sol;
5928 struct isl_sol_pma *sol_pma;
5929
5931 &sol_pma_init);
5932 if (!sol)
5933 return NULL;
5934 sol_pma = (struct isl_sol_pma *) sol;
5935
5936 result = isl_pw_multi_aff_copy(sol_pma->pma);
5937 if (empty)
5938 *empty = isl_set_copy(sol_pma->empty);
5939 sol_free(&sol_pma->sol);
5940 return result;
5941}
5942
5943/* Given that the last input variable of "maff" represents the minimum
5944 * of some bounds, check whether we need to plug in the expression
5945 * of the minimum.
5946 *
5947 * In particular, check if the last input variable appears in any
5948 * of the expressions in "maff".
5949 */
5951{
5952 int i;
5953 isl_size n_in;
5954 unsigned pos;
5955
5956 n_in = isl_multi_aff_dim(maff, isl_dim_in);
5957 if (n_in < 0)
5958 return isl_bool_error;
5959 pos = n_in - 1;
5960
5961 for (i = 0; i < maff->n; ++i) {
5962 isl_bool involves;
5963
5964 involves = isl_aff_involves_dims(maff->u.p[i],
5965 isl_dim_in, pos, 1);
5966 if (involves < 0 || involves)
5967 return involves;
5968 }
5969
5970 return isl_bool_false;
5971}
5972
5973/* Given a set of upper bounds on the last "input" variable m,
5974 * construct a piecewise affine expression that selects
5975 * the minimal upper bound to m, i.e.,
5976 * divide the space into cells where one
5977 * of the upper bounds is smaller than all the others and select
5978 * this upper bound on that cell.
5979 *
5980 * In particular, if there are n bounds b_i, then the result
5981 * consists of n cell, each one of the form
5982 *
5983 * b_i <= b_j for j > i
5984 * b_i < b_j for j < i
5985 *
5986 * The affine expression on this cell is
5987 *
5988 * b_i
5989 */
5992{
5993 int i;
5994 isl_aff *aff = NULL;
5995 isl_basic_set *bset = NULL;
5996 isl_pw_aff *paff = NULL;
5997 isl_space *pw_space;
5998 isl_local_space *ls = NULL;
5999
6000 if (!space || !var)
6001 goto error;
6002
6004 pw_space = isl_space_copy(space);
6005 pw_space = isl_space_from_domain(pw_space);
6006 pw_space = isl_space_add_dims(pw_space, isl_dim_out, 1);
6007 paff = isl_pw_aff_alloc_size(pw_space, var->n_row);
6008
6009 for (i = 0; i < var->n_row; ++i) {
6010 isl_pw_aff *paff_i;
6011
6014 0, var->n_row - 1);
6015 if (!aff || !bset)
6016 goto error;
6017 isl_int_set_si(aff->v->el[0], 1);
6018 isl_seq_cpy(aff->v->el + 1, var->row[i], var->n_col);
6019 isl_int_set_si(aff->v->el[1 + var->n_col], 0);
6020 bset = select_minimum(bset, var, i);
6022 paff = isl_pw_aff_add_disjoint(paff, paff_i);
6023 }
6024
6026 isl_space_free(space);
6028 return paff;
6029error:
6031 isl_basic_set_free(bset);
6032 isl_pw_aff_free(paff);
6034 isl_space_free(space);
6036 return NULL;
6037}
6038
6039/* Given a piecewise multi-affine expression of which the last input variable
6040 * is the minimum of the bounds in "cst", plug in the value of the minimum.
6041 * This minimum expression is given in "min_expr_pa".
6042 * The set "min_expr" contains the same information, but in the form of a set.
6043 * The variable is subsequently projected out.
6044 *
6045 * The implementation is similar to those of "split" and "split_domain".
6046 * If the variable appears in a given expression, then minimum expression
6047 * is plugged in. Otherwise, if the variable appears in the constraints
6048 * and a split is required, then the domain is split. Otherwise, no split
6049 * is performed.
6050 */
6053 __isl_take isl_set *min_expr, __isl_take isl_mat *cst)
6054{
6055 isl_size n_in;
6056 int i;
6057 isl_space *space;
6059
6060 if (!opt || !min_expr || !cst)
6061 goto error;
6062
6063 n_in = isl_pw_multi_aff_dim(opt, isl_dim_in);
6064 if (n_in < 0)
6065 goto error;
6066 space = isl_pw_multi_aff_get_space(opt);
6067 space = isl_space_drop_dims(space, isl_dim_in, n_in - 1, 1);
6068 res = isl_pw_multi_aff_empty(space);
6069
6070 for (i = 0; i < opt->n; ++i) {
6071 isl_bool subs;
6073
6074 pma = isl_pw_multi_aff_alloc(isl_set_copy(opt->p[i].set),
6075 isl_multi_aff_copy(opt->p[i].maff));
6076 subs = need_substitution(opt->p[i].maff);
6077 if (subs < 0) {
6079 } else if (subs) {
6081 n_in - 1, min_expr_pa);
6082 } else {
6084 split = need_split_set(opt->p[i].set, cst);
6085 if (split < 0)
6087 else if (split)
6089 isl_set_copy(min_expr));
6090 }
6092 isl_dim_in, n_in - 1, 1);
6093
6095 }
6096
6098 isl_pw_aff_free(min_expr_pa);
6099 isl_set_free(min_expr);
6100 isl_mat_free(cst);
6101 return res;
6102error:
6104 isl_pw_aff_free(min_expr_pa);
6105 isl_set_free(min_expr);
6106 isl_mat_free(cst);
6107 return NULL;
6108}
6109
6112 __isl_give isl_set **empty, int max);
6113
6114/* This function is called from basic_map_partial_lexopt_symm.
6115 * The last variable of "bmap" and "dom" corresponds to the minimum
6116 * of the bounds in "cst". "map_space" is the space of the original
6117 * input relation (of basic_map_partial_lexopt_symm) and "set_space"
6118 * is the space of the original domain.
6119 *
6120 * We recursively call basic_map_partial_lexopt and then plug in
6121 * the definition of the minimum in the result.
6122 */
6126 __isl_give isl_set **empty, int max, __isl_take isl_mat *cst,
6127 __isl_take isl_space *map_space, __isl_take isl_space *set_space)
6128{
6129 isl_pw_multi_aff *opt;
6130 isl_pw_aff *min_expr_pa;
6131 isl_set *min_expr;
6132
6133 min_expr = set_minimum(isl_basic_set_get_space(dom), isl_mat_copy(cst));
6134 min_expr_pa = set_minimum_pa(isl_basic_set_get_space(dom),
6135 isl_mat_copy(cst));
6136
6137 opt = basic_map_partial_lexopt_pw_multi_aff(bmap, dom, empty, max);
6138
6139 if (empty) {
6140 *empty = split(*empty,
6141 isl_set_copy(min_expr), isl_mat_copy(cst));
6142 *empty = isl_set_reset_space(*empty, set_space);
6143 }
6144
6145 opt = split_domain_pma(opt, min_expr_pa, min_expr, cst);
6146 opt = isl_pw_multi_aff_reset_space(opt, map_space);
6147
6148 return opt;
6149}
6150
6151#undef TYPE
6152#define TYPE isl_pw_multi_aff
6153#undef SUFFIX
6154#define SUFFIX _pw_multi_aff
6155#include "isl_tab_lexopt_templ.c"
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_empty(__isl_take isl_space *space)
__isl_export __isl_give isl_space * isl_pw_multi_aff_get_space(__isl_keep isl_pw_multi_aff *pma)
__isl_null isl_aff * isl_aff_free(__isl_take isl_aff *aff)
Definition isl_aff.c:449
__isl_export __isl_give isl_pw_multi_aff * isl_pw_multi_aff_intersect_domain(__isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set)
isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1, __isl_keep isl_pw_multi_aff *pma2)
Definition isl_aff.c:7241
__isl_give isl_pw_aff * isl_pw_aff_alloc(__isl_take isl_set *set, __isl_take isl_aff *aff)
__isl_null isl_pw_aff * isl_pw_aff_free(__isl_take isl_pw_aff *pwaff)
isl_size isl_pw_multi_aff_dim(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type)
__isl_null isl_pw_multi_aff * isl_pw_multi_aff_free(__isl_take isl_pw_multi_aff *pma)
isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, enum isl_dim_type type, unsigned first, unsigned n)
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_copy(__isl_keep isl_pw_multi_aff *pma)
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_alloc(__isl_take isl_set *set, __isl_take isl_multi_aff *maff)
struct isl_multi_aff isl_multi_aff
Definition aff_type.h:29
static __isl_give isl_basic_map * bset_to_bmap(__isl_take isl_basic_set *bset)
Definition bset_to_bmap.c:7
#define __isl_take
Definition ctx.h:23
#define isl_calloc_type(ctx, type)
Definition ctx.h:131
isl_stat
Definition ctx.h:85
@ isl_stat_error
Definition ctx.h:86
@ isl_stat_ok
Definition ctx.h:87
#define __isl_give
Definition ctx.h:20
#define isl_size_error
Definition ctx.h:99
#define __isl_null
Definition ctx.h:29
#define ISL_FL_ISSET(l, f)
Definition ctx.h:114
#define isl_die(ctx, errno, msg, code)
Definition ctx.h:139
void isl_ctx_deref(struct isl_ctx *ctx)
Definition isl_ctx.c:287
#define isl_assert(ctx, test, code)
Definition ctx.h:154
isl_bool isl_bool_ok(int b)
Definition isl_ctx.c:58
@ isl_error_invalid
Definition ctx.h:81
@ isl_error_internal
Definition ctx.h:80
#define isl_calloc_array(ctx, type, n)
Definition ctx.h:134
#define ISL_F_ISSET(p, f)
Definition ctx.h:119
#define __isl_keep
Definition ctx.h:26
int isl_size
Definition ctx.h:98
#define isl_alloc_type(ctx, type)
Definition ctx.h:130
void isl_ctx_ref(struct isl_ctx *ctx)
Definition isl_ctx.c:282
isl_bool isl_bool_not(isl_bool b)
Definition isl_ctx.c:44
isl_bool
Definition ctx.h:90
@ isl_bool_false
Definition ctx.h:92
@ isl_bool_true
Definition ctx.h:93
@ isl_bool_error
Definition ctx.h:91
#define ISL_FL_SET(l, f)
Definition ctx.h:112
m
Definition guard1-0.c:2
void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table)
Definition isl_hash.c:143
struct isl_hash_table_entry * isl_hash_table_find(struct isl_ctx *ctx, struct isl_hash_table *table, uint32_t key_hash, isl_bool(*eq)(const void *entry, const void *val), const void *val, int reserve)
Definition isl_hash.c:157
struct isl_hash_table * isl_hash_table_alloc(struct isl_ctx *ctx, int min_size)
Definition isl_hash.c:123
__isl_export __isl_give ISL_HMAP __isl_take ISL_KEY __isl_take ISL_VAL * val
Definition hmap.h:32
isl_stat isl_stat void * user
Definition hmap.h:39
int GMPQAPI sgn(mp_rat op)
void GMPZAPI gcd(mp_int rop, mp_int op1, mp_int op2)
void GMPQAPI init(mp_rat x)
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_substitute(__isl_take isl_pw_multi_aff *pma, unsigned pos, __isl_keep isl_pw_aff *subs)
Definition isl_aff.c:5860
__isl_give isl_aff * isl_aff_normalize(__isl_take isl_aff *aff)
Definition isl_aff.c:1704
__isl_give isl_aff * isl_aff_alloc(__isl_take isl_local_space *ls)
Definition isl_aff.c:124
__isl_give isl_basic_map * isl_basic_map_from_multi_aff2(__isl_take isl_multi_aff *maff, int rational)
__isl_give isl_pw_aff * isl_pw_aff_alloc_size(__isl_take isl_space *space, int n)
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_add_disjoint(__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_project_out(__isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned first, unsigned n)
__isl_give isl_pw_aff * isl_pw_aff_add_disjoint(__isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2)
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_reset_space(__isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space)
struct isl_tab * isl_tab_detect_equalities(struct isl_tab *tab, struct isl_tab *tab_cone)
static __isl_give isl_ast_expr * var(struct isl_ast_add_term_data *data, enum isl_dim_type type, int pos)
#define WARN_UNUSED
#define __attribute__(x)
#define isl_int_is_nonneg(i)
Definition isl_int.h:37
#define isl_int_is_zero(i)
Definition isl_int.h:31
#define isl_int_is_one(i)
Definition isl_int.h:32
#define isl_int_is_pos(i)
Definition isl_int.h:34
#define isl_int_is_negone(i)
Definition isl_int.h:33
#define isl_int_is_neg(i)
Definition isl_int.h:35
#define isl_int_gcd(r, i, j)
Definition isl_int_gmp.h:42
#define isl_int_neg(r, i)
Definition isl_int_gmp.h:24
#define isl_int_add_ui(r, i, j)
Definition isl_int_gmp.h:27
#define isl_int_add(r, i, j)
Definition isl_int_gmp.h:30
#define isl_int_ne(i, j)
Definition isl_int_gmp.h:58
#define isl_int_is_divisible_by(i, j)
Definition isl_int_gmp.h:69
#define isl_int_fdiv_r(r, i, j)
Definition isl_int_gmp.h:50
#define isl_int_set(r, i)
Definition isl_int_gmp.h:14
#define isl_int_divexact(r, i, j)
Definition isl_int_gmp.h:44
#define isl_int_sgn(i)
Definition isl_int_gmp.h:54
#define isl_int_mul(r, i, j)
Definition isl_int_gmp.h:32
#define isl_int_set_si(r, i)
Definition isl_int_gmp.h:15
mpz_t isl_int
Definition isl_int_gmp.h:9
#define isl_int_sub_ui(r, i, j)
Definition isl_int_gmp.h:28
#define isl_int_fdiv_q(r, i, j)
Definition isl_int_gmp.h:49
#define isl_int_sub(r, i, j)
Definition isl_int_gmp.h:31
#define isl_int_init(i)
Definition isl_int_gmp.h:11
#define isl_int_clear(i)
Definition isl_int_gmp.h:12
#define isl_int_submul(r, i, j)
Definition isl_int_gmp.h:39
__isl_give isl_basic_set * isl_basic_set_alloc_space(__isl_take isl_space *space, unsigned extra, unsigned n_eq, unsigned n_ineq)
Definition isl_map.c:1361
isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap, enum isl_dim_type type)
Definition isl_map.c:147
__isl_give isl_basic_map * isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap, isl_int *ineq)
Definition isl_map.c:1843
isl_bool isl_basic_map_any_div_involves_vars(__isl_keep isl_basic_map *bmap, unsigned first, unsigned n)
Definition isl_map.c:2882
__isl_give isl_set * isl_set_alloc_space(__isl_take isl_space *space, int n, unsigned flags)
Definition isl_map.c:3977
isl_bool isl_basic_map_div_expr_involves_vars(__isl_keep isl_basic_map *bmap, int div, unsigned first, unsigned n)
Definition isl_map.c:2834
__isl_give isl_basic_set * isl_basic_set_dup(__isl_keep isl_basic_set *bset)
Definition isl_map.c:1457
__isl_give isl_set * isl_set_add_basic_set(__isl_take isl_set *set, __isl_take isl_basic_set *bset)
Definition isl_map.c:4048
__isl_give isl_basic_set * isl_basic_set_insert_div(__isl_take isl_basic_set *bset, int pos, __isl_keep isl_vec *div)
Definition isl_map.c:1942
int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set *bset)
Definition isl_map.c:8665
__isl_give isl_map * isl_map_reset_space(__isl_take isl_map *map, __isl_take isl_space *space)
Definition isl_map.c:6467
int isl_basic_set_alloc_equality(__isl_keep isl_basic_set *bset)
Definition isl_map.c:1666
static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
Definition isl_map.c:73
int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap)
Definition isl_map.c:1870
isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap, int div)
Definition isl_map.c:8631
isl_size isl_basic_set_var_offset(__isl_keep isl_basic_set *bset, enum isl_dim_type type)
Definition isl_map.c:169
__isl_give isl_basic_map * isl_basic_map_cow(__isl_take isl_basic_map *bmap)
Definition isl_map.c:2064
__isl_give isl_basic_map * isl_basic_map_insert_div(__isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
Definition isl_map.c:1909
__isl_give isl_basic_set * isl_basic_set_sort_divs(__isl_take isl_basic_set *bset)
Definition isl_map.c:10207
__isl_give isl_basic_set * isl_basic_set_underlying_set(__isl_take isl_basic_set *bset)
Definition isl_map.c:6267
__isl_give isl_map * isl_map_alloc_space(__isl_take isl_space *space, int n, unsigned flags)
Definition isl_map.c:6857
__isl_give isl_basic_set * isl_basic_set_add_div_constraints(__isl_take isl_basic_set *bset, unsigned pos)
Definition isl_map.c:6183
__isl_give isl_set * isl_set_grow(__isl_take isl_set *set, int n)
Definition isl_map.c:4019
__isl_give isl_basic_map * isl_basic_map_extend(__isl_take isl_basic_map *base, unsigned extra, unsigned n_eq, unsigned n_ineq)
Definition isl_map.c:1996
__isl_give isl_map * isl_map_add_basic_map(__isl_take isl_map *map, __isl_take isl_basic_map *bmap)
Definition isl_map.c:7016
__isl_give isl_map * isl_map_grow(__isl_take isl_map *map, int n)
Definition isl_map.c:3990
__isl_give isl_basic_map * isl_basic_map_swap_div(__isl_take isl_basic_map *bmap, int a, int b)
Definition isl_map.c:2483
int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set *bset)
Definition isl_map.c:1762
#define ISL_BASIC_MAP_EMPTY
#define ISL_MAP_DISJOINT
#define ISL_BASIC_MAP_RATIONAL
__isl_give isl_basic_set * isl_basic_set_simplify(__isl_take isl_basic_set *bset)
#define isl_set
__isl_give isl_basic_set * isl_basic_set_gauss(__isl_take isl_basic_set *bset, int *progress)
__isl_give isl_basic_set * isl_basic_set_finalize(__isl_take isl_basic_set *bset)
#define isl_basic_set
#define ISL_SET_DISJOINT
#define ISL_CONTEXT_LEXMIN
__isl_give isl_vec * isl_basic_set_sample_with_cone(__isl_take isl_basic_set *bset, __isl_take isl_basic_set *cone)
Definition isl_sample.c:946
__isl_give isl_vec * isl_tab_sample(struct isl_tab *tab)
Definition isl_sample.c:381
static int is_trivial(struct isl_sched_node *node, __isl_keep isl_vec *sol)
void isl_seq_fdiv_q(isl_int *dst, isl_int *src, isl_int m, unsigned len)
Definition isl_seq.c:102
void isl_seq_combine(isl_int *dst, isl_int m1, isl_int *src1, isl_int m2, isl_int *src2, unsigned len)
Definition isl_seq.c:116
void isl_seq_inner_product(isl_int *p1, isl_int *p2, unsigned len, isl_int *prod)
Definition isl_seq.c:301
void isl_seq_scale_down(isl_int *dst, isl_int *src, isl_int m, unsigned len)
Definition isl_seq.c:88
void isl_seq_gcd(isl_int *p, unsigned len, isl_int *gcd)
Definition isl_seq.c:260
void isl_seq_fdiv_r(isl_int *dst, isl_int *src, isl_int m, unsigned len)
Definition isl_seq.c:109
void isl_seq_clr(isl_int *p, unsigned len)
Definition isl_seq.c:14
void isl_seq_scale(isl_int *dst, isl_int *src, isl_int m, unsigned len)
Definition isl_seq.c:81
void isl_seq_cpy(isl_int *dst, isl_int *src, unsigned len)
Definition isl_seq.c:42
uint32_t isl_seq_get_hash(isl_int *p, unsigned len)
Definition isl_seq.c:357
int isl_seq_eq(isl_int *p1, isl_int *p2, unsigned len)
Definition isl_seq.c:173
int isl_seq_any_non_zero(isl_int *p, unsigned len)
Definition isl_seq.c:230
void isl_seq_neg(isl_int *dst, isl_int *src, unsigned len)
Definition isl_seq.c:35
struct isl_tab * isl_tab_drop_sample(struct isl_tab *tab, int s)
Definition isl_tab.c:925
int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var)
Definition isl_tab.c:1466
void isl_tab_free(struct isl_tab *tab)
Definition isl_tab.c:206
isl_stat isl_tab_push_basis(struct isl_tab *tab)
Definition isl_tab.c:846
void isl_tab_clear_undo(struct isl_tab *tab)
Definition isl_tab.c:3780
int isl_tab_insert_var(struct isl_tab *tab, int r)
Definition isl_tab.c:1773
isl_stat isl_tab_track_bset(struct isl_tab *tab, __isl_take isl_basic_set *bset)
Definition isl_tab.c:4251
struct isl_tab * isl_tab_init_samples(struct isl_tab *tab)
Definition isl_tab.c:877
int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new)
Definition isl_tab.c:153
int isl_tab_add_sample(struct isl_tab *tab, __isl_take isl_vec *sample)
Definition isl_tab.c:896
struct isl_tab_var * isl_tab_var_from_row(struct isl_tab *tab, int i)
Definition isl_tab.c:573
isl_stat isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
Definition isl_tab.c:2120
int isl_tab_mark_redundant(struct isl_tab *tab, int row)
Definition isl_tab.c:968
__isl_keep isl_basic_set * isl_tab_peek_bset(struct isl_tab *tab)
Definition isl_tab.c:4256
int isl_tab_pivot(struct isl_tab *tab, int row, int col)
Definition isl_tab.c:1137
isl_stat isl_tab_push_callback(struct isl_tab *tab, struct isl_tab_callback *callback)
Definition isl_tab.c:859
int isl_tab_add_row(struct isl_tab *tab, isl_int *line)
Definition isl_tab.c:1824
struct isl_tab_undo * isl_tab_snap(struct isl_tab *tab)
Definition isl_tab.c:3756
int isl_tab_kill_col(struct isl_tab *tab, int col)
Definition isl_tab.c:1571
__isl_give isl_basic_set * isl_basic_set_update_from_tab(__isl_take isl_basic_set *bset, struct isl_tab *tab)
Definition isl_tab.c:2665
struct isl_tab * isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset, int parametric)
Definition isl_tab.c:2444
isl_stat isl_tab_mark_empty(struct isl_tab *tab)
Definition isl_tab.c:1008
isl_stat isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq)
Definition isl_tab.c:1908
__isl_give isl_vec * isl_tab_get_sample_value(struct isl_tab *tab)
Definition isl_tab.c:2577
isl_ctx * isl_tab_get_ctx(struct isl_tab *tab)
Definition isl_tab.c:100
int isl_tab_sample_is_integer(struct isl_tab *tab)
Definition isl_tab.c:2535
isl_bool isl_tab_need_undo(struct isl_tab *tab)
Definition isl_tab.c:3767
struct isl_tab * isl_tab_dup(struct isl_tab *tab)
Definition isl_tab.c:225
struct isl_tab * isl_tab_alloc(struct isl_ctx *ctx, unsigned n_row, unsigned n_var, unsigned M)
Definition isl_tab.c:33
isl_stat isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type)
Definition isl_tab.c:837
int isl_tab_row_is_redundant(struct isl_tab *tab, int row)
Definition isl_tab.c:744
int isl_tab_detect_implicit_equalities(struct isl_tab *tab)
Definition isl_tab.c:2981
int isl_tab_insert_div(struct isl_tab *tab, int pos, __isl_keep isl_vec *div, isl_stat(*add_ineq)(void *user, isl_int *), void *user)
Definition isl_tab.c:2333
__isl_give struct isl_tab * isl_tab_from_basic_set(__isl_keep isl_basic_set *bset, int track)
Definition isl_tab.c:2436
isl_stat isl_tab_push_var(struct isl_tab *tab, enum isl_tab_undo_type type, struct isl_tab_var *var)
Definition isl_tab.c:826
isl_stat isl_tab_save_samples(struct isl_tab *tab)
Definition isl_tab.c:945
isl_stat isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap)
Definition isl_tab.c:4098
int isl_tab_allocate_con(struct isl_tab *tab)
Definition isl_tab.c:1689
int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new)
Definition isl_tab.c:105
isl_tab_row_sign
Definition isl_tab.h:130
@ isl_tab_row_unknown
Definition isl_tab.h:131
@ isl_tab_row_pos
Definition isl_tab.h:132
@ isl_tab_row_any
Definition isl_tab.h:134
@ isl_tab_row_neg
Definition isl_tab.h:133
#define ISL_OPT_QE
Definition isl_tab.h:257
@ isl_tab_undo_bmap_ineq
Definition isl_tab.h:42
@ isl_tab_undo_nonneg
Definition isl_tab.h:35
@ isl_tab_undo_bmap_div
Definition isl_tab.h:44
static void sol_map_add_empty_wrap(struct isl_sol *sol, struct isl_basic_set *bset)
static struct isl_sol * basic_map_partial_lexopt_base_sol(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max, struct isl_sol *(*init)(__isl_keep isl_basic_map *bmap, __isl_take isl_basic_set *dom, int track_empty, int max))
static void sol_pop_one(struct isl_sol *sol)
static void sol_pma_add_wrap(struct isl_sol *sol, __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma)
static void find_solutions_main(struct isl_sol *sol, struct isl_tab *tab)
static void context_lex_add_ineq(struct isl_context *context, isl_int *ineq, int check, int update)
static struct isl_tab * context_gbr_peek_tab(struct isl_context *context)
static __isl_give isl_vec * ineq_for_div(__isl_keep isl_basic_set *bset, unsigned div)
static isl_stat combine_initial_if_equal(struct isl_sol *sol)
static int context_gbr_test_ineq(struct isl_context *context, isl_int *ineq)
static int last_var_col_or_int_par_col(struct isl_tab *tab, int row)
static isl_stat context_lex_add_ineq_wrap(void *user, isl_int *ineq)
static void sol_map_add_empty(struct isl_sol_map *sol, struct isl_basic_set *bset)
static struct isl_tab * add_lexmin_ineq(struct isl_tab *tab, isl_int *ineq)
static int context_gbr_detect_equalities(struct isl_context *context, struct isl_tab *tab)
static isl_stat fix_zero(struct isl_tab *tab, struct isl_trivial_region *region, int dir, struct isl_lexmin_data *data)
static __isl_give struct isl_tab * tab_for_lexmin(__isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *dom, unsigned M, int max)
static struct isl_tab * set_row_cst_to_div(struct isl_tab *tab, int row, int div)
#define I_PAR
static int integer_constant(struct isl_tab *tab, int row)
static void sol_pma_add_empty(struct isl_sol_pma *sol, __isl_take isl_basic_set *bset)
static int finished_all_cases(struct isl_local_region *local, struct isl_lexmin_data *data)
static int context_lex_is_ok(struct isl_context *context)
static void sol_context_add_ineq(struct isl_sol *sol, isl_int *ineq, int check, int update)
static isl_bool region_is_trivial(struct isl_tab *tab, int pos, __isl_keep isl_mat *trivial)
static int lexmin_col_pair(struct isl_tab *tab, int row, int col1, int col2, isl_int tmp)
static struct isl_sol * sol_pma_init(__isl_keep isl_basic_map *bmap, __isl_take isl_basic_set *dom, int track_empty, int max)
static int is_parametric_constant(struct isl_tab *tab, int row)
static isl_stat sol_init(struct isl_sol *sol, __isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *dom, int max)
static int last_non_zero_var_col(struct isl_tab *tab, isl_int *p)
static int first_non_integer_row(struct isl_tab *tab, int *f)
struct isl_context_op isl_context_gbr_op
struct isl_context_op isl_context_lex_op
static int context_gbr_is_empty(struct isl_context *context)
static int is_optimal(__isl_keep isl_vec *sol, int n_op)
static struct isl_tab * context_lex_detect_nonnegative_parameters(struct isl_context *context, struct isl_tab *tab)
static __isl_give isl_map * basic_map_partial_lexopt_base(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max)
__isl_give isl_vec * isl_tab_basic_set_non_trivial_lexmin(__isl_take isl_basic_set *bset, int n_op, int n_region, struct isl_trivial_region *region, int(*conflict)(int con, void *user), void *user)
static void sol_push_sol(struct isl_sol *sol, __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma)
__isl_null isl_tab_lexmin * isl_tab_lexmin_free(__isl_take isl_tab_lexmin *tl)
static __isl_give isl_pw_multi_aff * basic_map_partial_lexopt_symm_core_pw_multi_aff(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max, __isl_take isl_mat *cst, __isl_take isl_space *map_space, __isl_take isl_space *set_space)
static isl_bool need_split_set(__isl_keep isl_set *set, __isl_keep isl_mat *cst)
static int sol_has_mergeable_solutions(struct isl_sol *sol)
static isl_stat init_lexmin_data(struct isl_lexmin_data *data, __isl_keep isl_basic_set *bset)
static isl_bool is_known_div_not_involving(__isl_keep isl_basic_map *bmap, unsigned div, unsigned first, unsigned n)
static void check_gbr_integer_feasible(struct isl_context_gbr *cgbr)
static int sample_is_finite(struct isl_tab *tab)
static int tab_has_valid_sample(struct isl_tab *tab, isl_int *ineq, int eq)
static __isl_give isl_pw_multi_aff * basic_map_partial_lexopt_base_pw_multi_aff(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max)
static int is_critical(struct isl_tab *tab, int row)
static void scale_rows(struct isl_mat *mat, isl_int m, int n_row)
static struct isl_vec * gbr_get_shifted_sample(struct isl_context_gbr *cgbr)
static void sol_pma_add_empty_wrap(struct isl_sol *sol, __isl_take isl_basic_set *bset)
static int all_single_occurrence(__isl_keep isl_basic_map *bmap, int ineq, int n)
static enum isl_tab_row_sign row_sign(struct isl_tab *tab, struct isl_sol *sol, int row)
static int context_gbr_best_split(struct isl_context *context, struct isl_tab *tab)
int isl_tab_lexmin_dim(__isl_keep isl_tab_lexmin *tl)
static isl_stat better_next_side(struct isl_local_region *local, struct isl_lexmin_data *data)
static int context_lex_get_div(struct isl_context *context, struct isl_tab *tab, struct isl_vec *div)
static __isl_give isl_set * split(__isl_take isl_set *empty, __isl_take isl_set *min_expr, __isl_take isl_mat *cst)
static void context_gbr_discard(void *save)
static void find_in_pos(struct isl_sol *sol, struct isl_tab *tab, isl_int *ineq)
static void * context_gbr_save(struct isl_context *context)
static isl_bool same_solution(struct isl_partial_sol *s1, struct isl_partial_sol *s2)
static void update_outer_levels(struct isl_lexmin_data *data, int level)
static int get_div(struct isl_tab *tab, struct isl_context *context, struct isl_vec *div)
static int context_gbr_get_div(struct isl_context *context, struct isl_tab *tab, struct isl_vec *div)
static int first_neg(struct isl_tab *tab)
static isl_size find_div_involving_only(__isl_keep isl_basic_map *dst, __isl_keep isl_basic_map *src, unsigned div, unsigned n_shared)
static struct isl_vec * get_row_split_div(struct isl_tab *tab, int row)
static __isl_give isl_basic_set * copy_div(__isl_take isl_basic_set *dom, __isl_keep isl_basic_map *bmap, unsigned div, unsigned n_shared, unsigned dom_div)
static enum isl_tab_row_sign tab_ineq_sign(struct isl_tab *tab, isl_int *ineq, int strict)
static isl_stat context_gbr_add_ineq_wrap(void *user, isl_int *ineq)
#define CUT_ALL
static int best_split(struct isl_tab *tab, struct isl_tab *context_tab)
static struct isl_sol * sol_map_init(__isl_keep isl_basic_map *bmap, __isl_take isl_basic_set *dom, int track_empty, int max)
static enum isl_next enter_level(int level, int init, struct isl_lexmin_data *data)
static int restore_lexmin(struct isl_tab *tab) WARN_UNUSED
static struct isl_tab * context_gbr_detect_nonnegative_parameters(struct isl_context *context, struct isl_tab *tab)
static struct isl_vec * gbr_get_sample(struct isl_context_gbr *cgbr)
static isl_bool context_lex_insert_div(struct isl_context *context, int pos, __isl_keep isl_vec *div)
static struct isl_context * isl_context_gbr_alloc(__isl_keep isl_basic_set *dom)
static void gbr_init_shifted(struct isl_context_gbr *cgbr)
static struct isl_tab * check_samples(struct isl_tab *tab, isl_int *ineq, int eq)
static __isl_give isl_pw_multi_aff * split_domain_pma(__isl_take isl_pw_multi_aff *opt, __isl_take isl_pw_aff *min_expr_pa, __isl_take isl_set *min_expr, __isl_take isl_mat *cst)
static __isl_give isl_basic_set * extract_domain(__isl_keep isl_basic_map *bmap, unsigned flags)
static __isl_null struct isl_context * context_gbr_free(struct isl_context *context)
static int next_non_integer_var(struct isl_tab *tab, int var, int *f)
static int row_is_parameter_var(struct isl_tab *tab, int row)
static __isl_give isl_map * basic_map_partial_lexopt_symm_core(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max, __isl_take isl_mat *cst, __isl_take isl_space *map_space, __isl_take isl_space *set_space)
static __isl_give isl_vec * extract_sample_sequence(struct isl_tab *tab, int pos, int len)
static int context_lex_best_split(struct isl_context *context, struct isl_tab *tab)
#define I_CST
static void sol_free(struct isl_sol *sol)
static void sol_pop(struct isl_sol *sol)
static isl_bool parallel_constraints(__isl_keep isl_basic_map *bmap, int *first, int *second)
isl_next
@ isl_next_backtrack
@ isl_next_done
@ isl_next_handle
@ isl_next_error
static struct isl_vec * get_row_parameter_ineq(struct isl_tab *tab, int row)
static __isl_give isl_map * basic_map_partial_lexopt(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max)
static void sol_map_free(struct isl_sol *sol)
static isl_bool need_split_basic_map(__isl_keep isl_basic_map *bmap, __isl_keep isl_mat *cst)
static void no_sol_in_strict(struct isl_sol *sol, struct isl_tab *tab, struct isl_vec *ineq)
static struct isl_tab * tab_detect_nonnegative_parameters(struct isl_tab *tab, struct isl_tab *context_tab)
static isl_bool need_substitution(__isl_keep isl_multi_aff *maff)
static int is_parameter_var(struct isl_tab *tab, int index)
static __isl_give isl_basic_set * select_minimum(__isl_take isl_basic_set *bset, __isl_keep isl_mat *var, int i)
static struct isl_tab * context_lex_peek_tab(struct isl_context *context)
static __isl_give int * count_occurrences(__isl_keep isl_basic_map *bmap, int n)
static void reset_any_to_unknown(struct isl_tab *tab)
static __isl_give isl_basic_map * align_context_divs(__isl_take isl_basic_map *bmap, __isl_keep isl_basic_set *dom)
static __isl_give isl_basic_set * drop_constant_terms(__isl_take isl_basic_set *bset)
static int is_strict(struct isl_vec *vec)
static void context_lex_discard(void *save)
static struct isl_context * isl_context_lex_alloc(struct isl_basic_set *dom)
static isl_stat combine_initial_into_second(struct isl_sol *sol)
static void sol_inc_level(struct isl_sol *sol)
static int force_better_solution(struct isl_tab *tab, __isl_keep isl_vec *sol, int n_op, int n_zero)
static struct isl_basic_set * context_gbr_peek_basic_set(struct isl_context *context)
static __isl_give isl_basic_set * copy_divs(__isl_take isl_basic_set *dom, __isl_keep isl_basic_map *bmap)
static isl_bool need_split_basic_set(__isl_keep isl_basic_set *bset, __isl_keep isl_mat *cst)
static void check_lexpos(struct isl_tab *tab) __attribute__((unused))
static isl_bool equal_on_domain(__isl_keep isl_multi_aff *ma1, __isl_keep isl_multi_aff *ma2, __isl_keep isl_basic_set *dom)
static void context_gbr_invalidate(struct isl_context *context)
static int context_gbr_is_ok(struct isl_context *context)
static void swap_initial(struct isl_sol *sol)
static void sol_pma_add(struct isl_sol_pma *sol, __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *maff)
static int lexmin_pivot_col(struct isl_tab *tab, int row)
static struct isl_tab * context_tab_for_lexmin(__isl_take isl_basic_set *bset)
static enum isl_tab_row_sign context_gbr_ineq_sign(struct isl_context *context, isl_int *ineq, int strict)
static void context_lex_restore(struct isl_context *context, void *save)
static int context_lex_detect_equalities(struct isl_context *context, struct isl_tab *tab)
static int add_cut(struct isl_tab *tab, int row)
static int add_parametric_cut(struct isl_tab *tab, int row, struct isl_context *context)
static void context_gbr_restore(struct isl_context *context, void *save)
static void context_lex_invalidate(struct isl_context *context)
static int use_shifted(struct isl_context_gbr *cgbr)
static void sol_map_add_wrap(struct isl_sol *sol, __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma)
static void context_lex_add_eq(struct isl_context *context, isl_int *eq, int check, int update)
static int is_obviously_neg(struct isl_tab *tab, int row)
static isl_stat sol_dec_level_wrap(struct isl_tab_callback *cb)
static struct isl_tab * check_integer_feasible(struct isl_tab *tab)
static int single_occurrence(int n, isl_int *c, int *occurrences)
static struct isl_tab * add_gbr_eq(struct isl_tab *tab, isl_int *eq)
static void clear_lexmin_data(struct isl_lexmin_data *data)
static struct isl_basic_set * context_lex_peek_basic_set(struct isl_context *context)
static int integer_variable(struct isl_tab *tab, int row)
static int identical_parameter_line(struct isl_tab *tab, int row1, int row2)
static int find_div(struct isl_tab *tab, isl_int *div, isl_int denom)
static __isl_give isl_map * split_domain(__isl_take isl_map *opt, __isl_take isl_set *min_expr, __isl_take isl_mat *cst)
static isl_stat init_local_region(struct isl_local_region *local, int region, struct isl_lexmin_data *data)
#define I_VAR
static enum isl_tab_row_sign context_lex_ineq_sign(struct isl_context *context, isl_int *ineq, int strict)
static int is_obviously_nonneg(struct isl_tab *tab, int row)
static __isl_null struct isl_context * context_lex_free(struct isl_context *context)
static struct isl_tab * pos_neg(struct isl_tab *tab, struct isl_trivial_region *region, int side, struct isl_lexmin_data *data)
static int context_lex_test_ineq(struct isl_context *context, isl_int *ineq)
static __isl_give isl_set * set_minimum(__isl_take isl_space *space, __isl_take isl_mat *var)
static __isl_give isl_multi_aff * set_from_affine_matrix(__isl_take isl_multi_aff *ma, __isl_take isl_local_space *ls, __isl_take isl_mat *M)
static struct isl_tab * add_lexmin_valid_eq(struct isl_tab *tab, isl_int *eq)
static struct isl_vec * get_row_parameter_div(struct isl_tab *tab, int row)
static int col_is_parameter_var(struct isl_tab *tab, int col)
#define CUT_ONE
static struct isl_basic_set * sol_domain(struct isl_sol *sol)
__isl_give isl_tab_lexmin * isl_tab_lexmin_cut_to_integer(__isl_take isl_tab_lexmin *tl)
static __isl_give isl_pw_aff * set_minimum_pa(__isl_take isl_space *space, __isl_take isl_mat *var)
static isl_stat pick_side(struct isl_local_region *local, struct isl_lexmin_data *data)
static void sol_pma_free(struct isl_sol *sol)
static isl_size find_context_div(__isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *dom, unsigned div)
static int context_lex_is_empty(struct isl_context *context)
static isl_bool context_gbr_insert_div(struct isl_context *context, int pos, __isl_keep isl_vec *div)
static int add_div(struct isl_tab *tab, struct isl_context *context, __isl_keep isl_vec *div)
static int propagate_equalities(struct isl_context_gbr *cgbr, struct isl_tab *tab, unsigned first)
static int report_conflict(struct isl_tab *tab, int row)
static void find_solutions(struct isl_sol *sol, struct isl_tab *tab)
static void * context_lex_save(struct isl_context *context)
static int add_lexmin_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED
__isl_give isl_vec * isl_tab_lexmin_get_solution(__isl_keep isl_tab_lexmin *tl)
static __isl_give isl_pw_multi_aff * basic_map_partial_lexopt_pw_multi_aff(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty, int max)
static int report_conflicting_constraint(struct isl_tab *tab, int con)
static void sol_dec_level(struct isl_sol *sol)
static void get_row_parameter_line(struct isl_tab *tab, int row, isl_int *line)
static void context_gbr_add_eq(struct isl_context *context, isl_int *eq, int check, int update)
static struct isl_tab * cut_to_integer_lexmin(struct isl_tab *tab, int cutting_strategy)
static void sol_map_add(struct isl_sol_map *sol, __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma)
static void sol_push_sol_mat(struct isl_sol *sol, __isl_take isl_basic_set *dom, __isl_take isl_mat *M)
static void normalize_div(__isl_keep isl_vec *div)
static int integer_parameter(struct isl_tab *tab, int row)
static void sol_add(struct isl_sol *sol, struct isl_tab *tab)
static isl_bool context_tab_insert_div(struct isl_tab *tab, int pos, __isl_keep isl_vec *div, isl_stat(*add_ineq)(void *user, isl_int *), void *user)
static int first_trivial_region(struct isl_lexmin_data *data)
__isl_give isl_tab_lexmin * isl_tab_lexmin_add_eq(__isl_take isl_tab_lexmin *tl, isl_int *eq)
static void add_gbr_ineq(struct isl_context_gbr *cgbr, isl_int *ineq)
static isl_bool constraint_equal(const void *entry, const void *val)
__isl_give isl_tab_lexmin * isl_tab_lexmin_from_basic_set(__isl_take isl_basic_set *bset)
static isl_stat check_final_columns_are_zero(__isl_keep isl_mat *M, unsigned first)
static void context_gbr_add_ineq(struct isl_context *context, isl_int *ineq, int check, int update)
static struct isl_context * isl_context_alloc(__isl_keep isl_basic_set *dom)
static int is_constant(struct isl_tab *tab, int row)
static void sol_context_add_eq(struct isl_sol *sol, isl_int *eq, int check, int update)
const char * set
Definition isl_test.c:1364
const char * ma
Definition isl_test.c:7330
const char * map
Definition isl_test.c:1734
int equal
Definition isl_test.c:7663
const char * pma
Definition isl_test.c:2962
const char * p
Definition isl_test.c:8397
const char * context
Definition isl_test.c:1735
const char * aff
Definition isl_test.c:7073
const char * res
Definition isl_test.c:783
const char * ma1
Definition isl_test.c:9208
const char * cone
Definition isl_test.c:1365
const char * f
Definition isl_test.c:8396
static __isl_give isl_union_map * total(__isl_take isl_union_map *umap, __isl_give isl_map *(*fn)(__isl_take isl_map *))
isl_bool isl_vec_is_zero(__isl_keep isl_vec *vec)
Definition isl_vec.c:334
__isl_give isl_local_space * isl_local_space_from_space(__isl_take isl_space *space)
__isl_give isl_local_space * isl_local_space_drop_dims(__isl_take isl_local_space *ls, enum isl_dim_type type, unsigned first, unsigned n)
isl_size isl_local_space_dim(__isl_keep isl_local_space *ls, enum isl_dim_type type)
__isl_null isl_local_space * isl_local_space_free(__isl_take isl_local_space *ls)
__isl_give isl_local_space * isl_local_space_copy(__isl_keep isl_local_space *ls)
__isl_give isl_basic_set * isl_basic_map_domain(__isl_take isl_basic_map *bmap)
Definition isl_map.c:6602
__isl_export __isl_give isl_set * isl_map_domain(__isl_take isl_map *bmap)
Definition isl_map.c:8777
__isl_give isl_space * isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
Definition isl_map.c:417
__isl_give isl_map * isl_map_union_disjoint(__isl_take isl_map *map1, __isl_take isl_map *map2)
Definition isl_map.c:8875
isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
Definition isl_map.c:10089
__isl_give isl_basic_map * isl_basic_map_drop_constraints_involving_dims(__isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first, unsigned n)
Definition isl_map.c:3666
__isl_give isl_map * isl_map_copy(__isl_keep isl_map *map)
Definition isl_map.c:1494
__isl_null isl_basic_map * isl_basic_map_free(__isl_take isl_basic_map *bmap)
Definition isl_map.c:1503
isl_ctx * isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
Definition isl_map.c:382
__isl_export __isl_give isl_space * isl_map_get_space(__isl_keep isl_map *map)
Definition isl_map.c:599
isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap, enum isl_dim_type type)
Definition isl_map.c:83
__isl_export __isl_give isl_map * isl_map_intersect_domain(__isl_take isl_map *map, __isl_take isl_set *set)
Definition isl_map.c:9001
__isl_export __isl_give isl_map * isl_map_empty(__isl_take isl_space *space)
Definition isl_map.c:6957
isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
Definition isl_map.c:113
__isl_export __isl_give isl_basic_map * isl_basic_map_intersect_domain(__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
Definition isl_map.c:4118
__isl_give isl_map * isl_map_from_domain(__isl_take isl_set *set)
Definition isl_map.c:6836
__isl_null isl_map * isl_map_free(__isl_take isl_map *map)
Definition isl_map.c:7040
__isl_constructor __isl_give isl_map * isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
Definition isl_map.c:4037
__isl_give isl_basic_map * isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
Definition isl_map.c:1479
__isl_give isl_map * isl_map_remove_dims(__isl_take isl_map *map, enum isl_dim_type type, unsigned first, unsigned n)
Definition isl_map.c:3870
__isl_give isl_mat * isl_mat_copy(__isl_keep isl_mat *mat)
Definition isl_mat.c:202
isl_size isl_mat_cols(__isl_keep isl_mat *mat)
Definition isl_mat.c:262
isl_size isl_mat_rows(__isl_keep isl_mat *mat)
Definition isl_mat.c:257
__isl_give isl_vec * isl_mat_vec_product(__isl_take isl_mat *mat, __isl_take isl_vec *vec)
Definition isl_mat.c:450
__isl_null isl_mat * isl_mat_free(__isl_take isl_mat *mat)
Definition isl_mat.c:240
__isl_give isl_mat * isl_mat_alloc(isl_ctx *ctx, unsigned n_row, unsigned n_col)
Definition isl_mat.c:53
isl_ctx * isl_mat_get_ctx(__isl_keep isl_mat *mat)
Definition isl_mat.c:25
__isl_give isl_mat * isl_mat_extend(__isl_take isl_mat *mat, unsigned n_row, unsigned n_col)
Definition isl_mat.c:91
__isl_give isl_mat * isl_mat_drop_cols(__isl_take isl_mat *mat, unsigned col, unsigned n)
Definition isl_mat.c:1506
__isl_give isl_mat * isl_mat_move_cols(__isl_take isl_mat *mat, unsigned dst_col, unsigned src_col, unsigned n)
Definition isl_mat.c:1865
isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset, enum isl_dim_type type)
Definition isl_map.c:202
__isl_give isl_set * isl_set_reset_space(__isl_take isl_set *set, __isl_take isl_space *space)
Definition isl_map.c:6523
__isl_give isl_set * isl_basic_set_compute_divs(__isl_take isl_basic_set *bset)
Definition isl_map.c:8767
__isl_give isl_space * isl_basic_set_get_space(__isl_keep isl_basic_set *bset)
Definition isl_map.c:422
__isl_null isl_basic_set * isl_basic_set_free(__isl_take isl_basic_set *bset)
Definition isl_map.c:1523
isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
Definition isl_map.c:10096
__isl_null isl_set * isl_set_free(__isl_take isl_set *set)
Definition isl_map.c:4055
__isl_give isl_set * isl_set_copy(__isl_keep isl_set *set)
Definition isl_map.c:1470
__isl_give isl_local_space * isl_basic_set_get_local_space(__isl_keep isl_basic_set *bset)
Definition isl_map.c:524
isl_ctx * isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset)
Definition isl_map.c:387
__isl_constructor __isl_give isl_set * isl_set_from_basic_set(__isl_take isl_basic_set *bset)
Definition isl_map.c:4024
__isl_give isl_basic_set * isl_basic_set_copy(__isl_keep isl_basic_set *bset)
Definition isl_map.c:1465
__isl_null isl_space * isl_space_free(__isl_take isl_space *space)
Definition isl_space.c:478
__isl_give isl_space * isl_space_from_domain(__isl_take isl_space *space)
Definition isl_space.c:2242
__isl_give isl_space * isl_space_copy(__isl_keep isl_space *space)
Definition isl_space.c:469
__isl_give isl_space * isl_space_drop_dims(__isl_take isl_space *space, enum isl_dim_type type, unsigned first, unsigned num)
Definition isl_space.c:2141
__isl_give isl_space * isl_space_add_dims(__isl_take isl_space *space, enum isl_dim_type type, unsigned n)
Definition isl_space.c:1262
@ isl_dim_param
Definition space_type.h:15
@ isl_dim_in
Definition space_type.h:16
@ isl_dim_all
Definition space_type.h:20
@ isl_dim_div
Definition space_type.h:19
@ isl_dim_out
Definition space_type.h:17
struct isl_ctx * ctx
isl_int ** ineq
struct isl_tab * cone
struct isl_tab * shifted
struct isl_tab * tab
struct isl_context context
struct isl_tab * tab
struct isl_context context
int(* is_empty)(struct isl_context *context)
struct isl_tab *(* peek_tab)(struct isl_context *context)
Definition isl_tab_pip.c:77
int(* test_ineq)(struct isl_context *context, isl_int *ineq)
Definition isl_tab_pip.c:94
enum isl_tab_row_sign(* ineq_sign)(struct isl_context *context, isl_int *ineq, int strict)
Definition isl_tab_pip.c:91
int(* detect_equalities)(struct isl_context *context, struct isl_tab *tab)
void(* discard)(void *)
__isl_null struct isl_context *(* free)(struct isl_context *context)
void(* restore)(struct isl_context *context, void *)
void *(* save)(struct isl_context *context)
void(* add_eq)(struct isl_context *context, isl_int *eq, int check, int update)
Definition isl_tab_pip.c:81
int(* best_split)(struct isl_context *context, struct isl_tab *tab)
void(* invalidate)(struct isl_context *context)
int(* get_div)(struct isl_context *context, struct isl_tab *tab, struct isl_vec *div)
Definition isl_tab_pip.c:96
isl_bool(* insert_div)(struct isl_context *context, int pos, __isl_keep isl_vec *div)
Definition isl_tab_pip.c:99
void(* add_ineq)(struct isl_context *context, isl_int *ineq, int check, int update)
Definition isl_tab_pip.c:86
struct isl_basic_set *(* peek_basic_set)(struct isl_context *context)
Definition isl_tab_pip.c:75
int(* is_ok)(struct isl_context *context)
struct isl_context_op * op
isl_int normalize_gcd
isl_int one
isl_int negone
struct isl_tab_undo * shifted_snap
struct isl_tab_undo * cone_snap
struct isl_tab_undo * tab_snap
Definition hash.h:45
void * data
Definition hash.h:47
struct isl_trivial_region * region
struct isl_local_region * local
struct isl_tab * tab
struct isl_tab_undo * snap
unsigned n_row
unsigned n_col
struct isl_ctx * ctx
isl_int ** row
isl_multi_aff * ma
struct isl_partial_sol * next
struct isl_basic_set * dom
struct isl_tab_callback callback
struct isl_sol * sol
struct isl_set * empty
struct isl_sol sol
struct isl_map * map
isl_set * empty
struct isl_sol sol
isl_pw_multi_aff * pma
isl_space * space
void(* add)(struct isl_sol *sol, __isl_take isl_basic_set *dom, __isl_take isl_multi_aff *ma)
isl_size n_out
struct isl_sol_callback dec_level
struct isl_context * context
struct isl_partial_sol * partial
void(* free)(struct isl_sol *sol)
void(* add_empty)(struct isl_sol *sol, struct isl_basic_set *bset)
int rational
isl_stat(* run)(struct isl_tab_callback *cb)
Definition isl_tab.h:53
struct isl_tab * tab
int index
Definition isl_tab.h:21
unsigned frozen
Definition isl_tab.h:27
unsigned is_nonneg
Definition isl_tab.h:23
unsigned is_row
Definition isl_tab.h:22
struct isl_mat * mat
Definition isl_tab.h:137
unsigned n_con
Definition isl_tab.h:148
unsigned n_col
Definition isl_tab.h:140
void * conflict_user
Definition isl_tab.h:173
unsigned rational
Definition isl_tab.h:178
unsigned n_sample
Definition isl_tab.h:163
unsigned n_var
Definition isl_tab.h:144
int n_unbounded
Definition isl_tab.h:169
int * col_var
Definition isl_tab.h:154
unsigned empty
Definition isl_tab.h:179
unsigned n_eq
Definition isl_tab.h:149
struct isl_tab_var * con
Definition isl_tab.h:152
unsigned n_dead
Definition isl_tab.h:141
struct isl_basic_map * bmap
Definition isl_tab.h:161
struct isl_mat * samples
Definition isl_tab.h:166
unsigned M
Definition isl_tab.h:181
enum isl_tab_row_sign * row_sign
Definition isl_tab.h:155
int * row_var
Definition isl_tab.h:153
unsigned n_param
Definition isl_tab.h:145
unsigned n_redundant
Definition isl_tab.h:142
struct isl_mat * basis
Definition isl_tab.h:170
unsigned n_outside
Definition isl_tab.h:164
unsigned n_row
Definition isl_tab.h:139
unsigned n_div
Definition isl_tab.h:146
int n_zero
Definition isl_tab.h:168
struct isl_tab_var * var
Definition isl_tab.h:151
int(* conflict)(int con, void *user)
Definition isl_tab.h:172
isl_mat * trivial
Definition isl_tab.h:272
isl_int * el
struct isl_ctx * ctx
unsigned size
isl_ctx * isl_vec_get_ctx(__isl_keep isl_vec *vec)
Definition isl_vec.c:18
__isl_null isl_vec * isl_vec_free(__isl_take isl_vec *vec)
Definition isl_vec.c:234
__isl_give isl_vec * isl_vec_normalize(__isl_take isl_vec *vec)
Definition isl_vec.c:456
__isl_give isl_vec * isl_vec_clr(__isl_take isl_vec *vec)
Definition isl_vec.c:426
__isl_give isl_vec * isl_vec_alloc(isl_ctx *ctx, unsigned size)
Definition isl_vec.c:33
__isl_give isl_vec * isl_vec_ceil(__isl_take isl_vec *vec)
Definition isl_vec.c:443
n
Definition youcefn.c:8