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