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