isl_ilp.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. /*
  2. * Copyright 2008-2009 Katholieke Universiteit Leuven
  3. *
  4. * Use of this software is governed by the MIT license
  5. *
  6. * Written by Sven Verdoolaege, K.U.Leuven, Departement
  7. * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
  8. */
  9. #include <isl_ctx_private.h>
  10. #include <isl_map_private.h>
  11. #include <isl/ilp.h>
  12. #include <isl/union_set.h>
  13. #include "isl_sample.h"
  14. #include <isl_seq.h>
  15. #include "isl_equalities.h"
  16. #include <isl_aff_private.h>
  17. #include <isl_local_space_private.h>
  18. #include <isl_mat_private.h>
  19. #include <isl_val_private.h>
  20. #include <isl_vec_private.h>
  21. #include <isl_lp_private.h>
  22. #include <isl_ilp_private.h>
  23. /* Given a basic set "bset", construct a basic set U such that for
  24. * each element x in U, the whole unit box positioned at x is inside
  25. * the given basic set.
  26. * Note that U may not contain all points that satisfy this property.
  27. *
  28. * We simply add the sum of all negative coefficients to the constant
  29. * term. This ensures that if x satisfies the resulting constraints,
  30. * then x plus any sum of unit vectors satisfies the original constraints.
  31. */
  32. static __isl_give isl_basic_set *unit_box_base_points(
  33. __isl_take isl_basic_set *bset)
  34. {
  35. int i, j, k;
  36. struct isl_basic_set *unit_box = NULL;
  37. isl_size total;
  38. if (!bset)
  39. goto error;
  40. if (bset->n_eq != 0) {
  41. isl_space *space = isl_basic_set_get_space(bset);
  42. isl_basic_set_free(bset);
  43. return isl_basic_set_empty(space);
  44. }
  45. total = isl_basic_set_dim(bset, isl_dim_all);
  46. if (total < 0)
  47. goto error;
  48. unit_box = isl_basic_set_alloc_space(isl_basic_set_get_space(bset),
  49. 0, 0, bset->n_ineq);
  50. for (i = 0; i < bset->n_ineq; ++i) {
  51. k = isl_basic_set_alloc_inequality(unit_box);
  52. if (k < 0)
  53. goto error;
  54. isl_seq_cpy(unit_box->ineq[k], bset->ineq[i], 1 + total);
  55. for (j = 0; j < total; ++j) {
  56. if (isl_int_is_nonneg(unit_box->ineq[k][1 + j]))
  57. continue;
  58. isl_int_add(unit_box->ineq[k][0],
  59. unit_box->ineq[k][0], unit_box->ineq[k][1 + j]);
  60. }
  61. }
  62. isl_basic_set_free(bset);
  63. return unit_box;
  64. error:
  65. isl_basic_set_free(bset);
  66. isl_basic_set_free(unit_box);
  67. return NULL;
  68. }
  69. /* Find an integer point in "bset", preferably one that is
  70. * close to minimizing "f".
  71. *
  72. * We first check if we can easily put unit boxes inside bset.
  73. * If so, we take the best base point of any of the unit boxes we can find
  74. * and round it up to the nearest integer.
  75. * If not, we simply pick any integer point in "bset".
  76. */
  77. static __isl_give isl_vec *initial_solution(__isl_keep isl_basic_set *bset,
  78. isl_int *f)
  79. {
  80. enum isl_lp_result res;
  81. struct isl_basic_set *unit_box;
  82. struct isl_vec *sol;
  83. unit_box = unit_box_base_points(isl_basic_set_copy(bset));
  84. res = isl_basic_set_solve_lp(unit_box, 0, f, bset->ctx->one,
  85. NULL, NULL, &sol);
  86. if (res == isl_lp_ok) {
  87. isl_basic_set_free(unit_box);
  88. return isl_vec_ceil(sol);
  89. }
  90. isl_basic_set_free(unit_box);
  91. return isl_basic_set_sample_vec(isl_basic_set_copy(bset));
  92. }
  93. /* Restrict "bset" to those points with values for f in the interval [l, u].
  94. */
  95. static __isl_give isl_basic_set *add_bounds(__isl_take isl_basic_set *bset,
  96. isl_int *f, isl_int l, isl_int u)
  97. {
  98. int k;
  99. isl_size total;
  100. total = isl_basic_set_dim(bset, isl_dim_all);
  101. if (total < 0)
  102. return isl_basic_set_free(bset);
  103. bset = isl_basic_set_extend_constraints(bset, 0, 2);
  104. k = isl_basic_set_alloc_inequality(bset);
  105. if (k < 0)
  106. goto error;
  107. isl_seq_cpy(bset->ineq[k], f, 1 + total);
  108. isl_int_sub(bset->ineq[k][0], bset->ineq[k][0], l);
  109. k = isl_basic_set_alloc_inequality(bset);
  110. if (k < 0)
  111. goto error;
  112. isl_seq_neg(bset->ineq[k], f, 1 + total);
  113. isl_int_add(bset->ineq[k][0], bset->ineq[k][0], u);
  114. return bset;
  115. error:
  116. isl_basic_set_free(bset);
  117. return NULL;
  118. }
  119. /* Find an integer point in "bset" that minimizes f (in any) such that
  120. * the value of f lies inside the interval [l, u].
  121. * Return this integer point if it can be found.
  122. * Otherwise, return sol.
  123. *
  124. * We perform a number of steps until l > u.
  125. * In each step, we look for an integer point with value in either
  126. * the whole interval [l, u] or half of the interval [l, l+floor(u-l-1/2)].
  127. * The choice depends on whether we have found an integer point in the
  128. * previous step. If so, we look for the next point in half of the remaining
  129. * interval.
  130. * If we find a point, the current solution is updated and u is set
  131. * to its value minus 1.
  132. * If no point can be found, we update l to the upper bound of the interval
  133. * we checked (u or l+floor(u-l-1/2)) plus 1.
  134. */
  135. static __isl_give isl_vec *solve_ilp_search(__isl_keep isl_basic_set *bset,
  136. isl_int *f, isl_int *opt, __isl_take isl_vec *sol, isl_int l, isl_int u)
  137. {
  138. isl_int tmp;
  139. int divide = 1;
  140. isl_int_init(tmp);
  141. while (isl_int_le(l, u)) {
  142. struct isl_basic_set *slice;
  143. struct isl_vec *sample;
  144. if (!divide)
  145. isl_int_set(tmp, u);
  146. else {
  147. isl_int_sub(tmp, u, l);
  148. isl_int_fdiv_q_ui(tmp, tmp, 2);
  149. isl_int_add(tmp, tmp, l);
  150. }
  151. slice = add_bounds(isl_basic_set_copy(bset), f, l, tmp);
  152. sample = isl_basic_set_sample_vec(slice);
  153. if (!sample) {
  154. isl_vec_free(sol);
  155. sol = NULL;
  156. break;
  157. }
  158. if (sample->size > 0) {
  159. isl_vec_free(sol);
  160. sol = sample;
  161. isl_seq_inner_product(f, sol->el, sol->size, opt);
  162. isl_int_sub_ui(u, *opt, 1);
  163. divide = 1;
  164. } else {
  165. isl_vec_free(sample);
  166. if (!divide)
  167. break;
  168. isl_int_add_ui(l, tmp, 1);
  169. divide = 0;
  170. }
  171. }
  172. isl_int_clear(tmp);
  173. return sol;
  174. }
  175. /* Find an integer point in "bset" that minimizes f (if any).
  176. * If sol_p is not NULL then the integer point is returned in *sol_p.
  177. * The optimal value of f is returned in *opt.
  178. *
  179. * The algorithm maintains a currently best solution and an interval [l, u]
  180. * of values of f for which integer solutions could potentially still be found.
  181. * The initial value of the best solution so far is any solution.
  182. * The initial value of l is minimal value of f over the rationals
  183. * (rounded up to the nearest integer).
  184. * The initial value of u is the value of f at the initial solution minus 1.
  185. *
  186. * We then call solve_ilp_search to perform a binary search on the interval.
  187. */
  188. static enum isl_lp_result solve_ilp(__isl_keep isl_basic_set *bset,
  189. isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p)
  190. {
  191. enum isl_lp_result res;
  192. isl_int l, u;
  193. struct isl_vec *sol;
  194. res = isl_basic_set_solve_lp(bset, 0, f, bset->ctx->one,
  195. opt, NULL, &sol);
  196. if (res == isl_lp_ok && isl_int_is_one(sol->el[0])) {
  197. if (sol_p)
  198. *sol_p = sol;
  199. else
  200. isl_vec_free(sol);
  201. return isl_lp_ok;
  202. }
  203. isl_vec_free(sol);
  204. if (res == isl_lp_error || res == isl_lp_empty)
  205. return res;
  206. sol = initial_solution(bset, f);
  207. if (!sol)
  208. return isl_lp_error;
  209. if (sol->size == 0) {
  210. isl_vec_free(sol);
  211. return isl_lp_empty;
  212. }
  213. if (res == isl_lp_unbounded) {
  214. isl_vec_free(sol);
  215. return isl_lp_unbounded;
  216. }
  217. isl_int_init(l);
  218. isl_int_init(u);
  219. isl_int_set(l, *opt);
  220. isl_seq_inner_product(f, sol->el, sol->size, opt);
  221. isl_int_sub_ui(u, *opt, 1);
  222. sol = solve_ilp_search(bset, f, opt, sol, l, u);
  223. if (!sol)
  224. res = isl_lp_error;
  225. isl_int_clear(l);
  226. isl_int_clear(u);
  227. if (sol_p)
  228. *sol_p = sol;
  229. else
  230. isl_vec_free(sol);
  231. return res;
  232. }
  233. static enum isl_lp_result solve_ilp_with_eq(__isl_keep isl_basic_set *bset,
  234. int max, isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p)
  235. {
  236. isl_size dim;
  237. enum isl_lp_result res;
  238. struct isl_mat *T = NULL;
  239. struct isl_vec *v;
  240. bset = isl_basic_set_copy(bset);
  241. dim = isl_basic_set_dim(bset, isl_dim_all);
  242. if (dim < 0)
  243. goto error;
  244. v = isl_vec_alloc(bset->ctx, 1 + dim);
  245. if (!v)
  246. goto error;
  247. isl_seq_cpy(v->el, f, 1 + dim);
  248. bset = isl_basic_set_remove_equalities(bset, &T, NULL);
  249. v = isl_vec_mat_product(v, isl_mat_copy(T));
  250. if (!v)
  251. goto error;
  252. res = isl_basic_set_solve_ilp(bset, max, v->el, opt, sol_p);
  253. isl_vec_free(v);
  254. if (res == isl_lp_ok && sol_p) {
  255. *sol_p = isl_mat_vec_product(T, *sol_p);
  256. if (!*sol_p)
  257. res = isl_lp_error;
  258. } else
  259. isl_mat_free(T);
  260. isl_basic_set_free(bset);
  261. return res;
  262. error:
  263. isl_mat_free(T);
  264. isl_basic_set_free(bset);
  265. return isl_lp_error;
  266. }
  267. /* Find an integer point in "bset" that minimizes (or maximizes if max is set)
  268. * f (if any).
  269. * If sol_p is not NULL then the integer point is returned in *sol_p.
  270. * The optimal value of f is returned in *opt.
  271. *
  272. * If there is any equality among the points in "bset", then we first
  273. * project it out. Otherwise, we continue with solve_ilp above.
  274. */
  275. enum isl_lp_result isl_basic_set_solve_ilp(__isl_keep isl_basic_set *bset,
  276. int max, isl_int *f, isl_int *opt, __isl_give isl_vec **sol_p)
  277. {
  278. isl_size dim;
  279. enum isl_lp_result res;
  280. if (sol_p)
  281. *sol_p = NULL;
  282. if (isl_basic_set_check_no_params(bset) < 0)
  283. return isl_lp_error;
  284. if (isl_basic_set_plain_is_empty(bset))
  285. return isl_lp_empty;
  286. if (bset->n_eq)
  287. return solve_ilp_with_eq(bset, max, f, opt, sol_p);
  288. dim = isl_basic_set_dim(bset, isl_dim_all);
  289. if (dim < 0)
  290. return isl_lp_error;
  291. if (max)
  292. isl_seq_neg(f, f, 1 + dim);
  293. res = solve_ilp(bset, f, opt, sol_p);
  294. if (max) {
  295. isl_seq_neg(f, f, 1 + dim);
  296. isl_int_neg(*opt, *opt);
  297. }
  298. return res;
  299. }
  300. static enum isl_lp_result basic_set_opt(__isl_keep isl_basic_set *bset, int max,
  301. __isl_keep isl_aff *obj, isl_int *opt)
  302. {
  303. enum isl_lp_result res;
  304. if (!obj)
  305. return isl_lp_error;
  306. bset = isl_basic_set_copy(bset);
  307. bset = isl_basic_set_underlying_set(bset);
  308. res = isl_basic_set_solve_ilp(bset, max, obj->v->el + 1, opt, NULL);
  309. isl_basic_set_free(bset);
  310. return res;
  311. }
  312. enum isl_lp_result isl_basic_set_opt(__isl_keep isl_basic_set *bset, int max,
  313. __isl_keep isl_aff *obj, isl_int *opt)
  314. {
  315. int *exp1 = NULL;
  316. int *exp2 = NULL;
  317. isl_ctx *ctx;
  318. isl_mat *bset_div = NULL;
  319. isl_mat *div = NULL;
  320. enum isl_lp_result res;
  321. isl_size bset_n_div, obj_n_div;
  322. if (!bset || !obj)
  323. return isl_lp_error;
  324. ctx = isl_aff_get_ctx(obj);
  325. if (!isl_space_is_equal(bset->dim, obj->ls->dim))
  326. isl_die(ctx, isl_error_invalid,
  327. "spaces don't match", return isl_lp_error);
  328. if (!isl_int_is_one(obj->v->el[0]))
  329. isl_die(ctx, isl_error_unsupported,
  330. "expecting integer affine expression",
  331. return isl_lp_error);
  332. bset_n_div = isl_basic_set_dim(bset, isl_dim_div);
  333. obj_n_div = isl_aff_dim(obj, isl_dim_div);
  334. if (bset_n_div < 0 || obj_n_div < 0)
  335. return isl_lp_error;
  336. if (bset_n_div == 0 && obj_n_div == 0)
  337. return basic_set_opt(bset, max, obj, opt);
  338. bset = isl_basic_set_copy(bset);
  339. obj = isl_aff_copy(obj);
  340. bset_div = isl_basic_set_get_divs(bset);
  341. exp1 = isl_alloc_array(ctx, int, bset_n_div);
  342. exp2 = isl_alloc_array(ctx, int, obj_n_div);
  343. if (!bset_div || (bset_n_div && !exp1) || (obj_n_div && !exp2))
  344. goto error;
  345. div = isl_merge_divs(bset_div, obj->ls->div, exp1, exp2);
  346. bset = isl_basic_set_expand_divs(bset, isl_mat_copy(div), exp1);
  347. obj = isl_aff_expand_divs(obj, isl_mat_copy(div), exp2);
  348. res = basic_set_opt(bset, max, obj, opt);
  349. isl_mat_free(bset_div);
  350. isl_mat_free(div);
  351. free(exp1);
  352. free(exp2);
  353. isl_basic_set_free(bset);
  354. isl_aff_free(obj);
  355. return res;
  356. error:
  357. isl_mat_free(div);
  358. isl_mat_free(bset_div);
  359. free(exp1);
  360. free(exp2);
  361. isl_basic_set_free(bset);
  362. isl_aff_free(obj);
  363. return isl_lp_error;
  364. }
  365. /* Compute the minimum (maximum if max is set) of the integer affine
  366. * expression obj over the points in set and put the result in *opt.
  367. *
  368. * The parameters are assumed to have been aligned.
  369. */
  370. static enum isl_lp_result isl_set_opt_aligned(__isl_keep isl_set *set, int max,
  371. __isl_keep isl_aff *obj, isl_int *opt)
  372. {
  373. int i;
  374. enum isl_lp_result res;
  375. int empty = 1;
  376. isl_int opt_i;
  377. if (!set || !obj)
  378. return isl_lp_error;
  379. if (set->n == 0)
  380. return isl_lp_empty;
  381. res = isl_basic_set_opt(set->p[0], max, obj, opt);
  382. if (res == isl_lp_error || res == isl_lp_unbounded)
  383. return res;
  384. if (set->n == 1)
  385. return res;
  386. if (res == isl_lp_ok)
  387. empty = 0;
  388. isl_int_init(opt_i);
  389. for (i = 1; i < set->n; ++i) {
  390. res = isl_basic_set_opt(set->p[i], max, obj, &opt_i);
  391. if (res == isl_lp_error || res == isl_lp_unbounded) {
  392. isl_int_clear(opt_i);
  393. return res;
  394. }
  395. if (res == isl_lp_empty)
  396. continue;
  397. empty = 0;
  398. if (max ? isl_int_gt(opt_i, *opt) : isl_int_lt(opt_i, *opt))
  399. isl_int_set(*opt, opt_i);
  400. }
  401. isl_int_clear(opt_i);
  402. return empty ? isl_lp_empty : isl_lp_ok;
  403. }
  404. /* Compute the minimum (maximum if max is set) of the integer affine
  405. * expression obj over the points in set and put the result in *opt.
  406. */
  407. enum isl_lp_result isl_set_opt(__isl_keep isl_set *set, int max,
  408. __isl_keep isl_aff *obj, isl_int *opt)
  409. {
  410. enum isl_lp_result res;
  411. isl_bool aligned;
  412. if (!set || !obj)
  413. return isl_lp_error;
  414. aligned = isl_set_space_has_equal_params(set, obj->ls->dim);
  415. if (aligned < 0)
  416. return isl_lp_error;
  417. if (aligned)
  418. return isl_set_opt_aligned(set, max, obj, opt);
  419. set = isl_set_copy(set);
  420. obj = isl_aff_copy(obj);
  421. set = isl_set_align_params(set, isl_aff_get_domain_space(obj));
  422. obj = isl_aff_align_params(obj, isl_set_get_space(set));
  423. res = isl_set_opt_aligned(set, max, obj, opt);
  424. isl_set_free(set);
  425. isl_aff_free(obj);
  426. return res;
  427. }
  428. /* Convert the result of a function that returns an isl_lp_result
  429. * to an isl_val. The numerator of "v" is set to the optimal value
  430. * if lp_res is isl_lp_ok. "max" is set if a maximum was computed.
  431. *
  432. * Return "v" with denominator set to 1 if lp_res is isl_lp_ok.
  433. * Return NULL on error.
  434. * Return a NaN if lp_res is isl_lp_empty.
  435. * Return infinity or negative infinity if lp_res is isl_lp_unbounded,
  436. * depending on "max".
  437. */
  438. static __isl_give isl_val *convert_lp_result(enum isl_lp_result lp_res,
  439. __isl_take isl_val *v, int max)
  440. {
  441. isl_ctx *ctx;
  442. if (lp_res == isl_lp_ok) {
  443. isl_int_set_si(v->d, 1);
  444. return isl_val_normalize(v);
  445. }
  446. ctx = isl_val_get_ctx(v);
  447. isl_val_free(v);
  448. if (lp_res == isl_lp_error)
  449. return NULL;
  450. if (lp_res == isl_lp_empty)
  451. return isl_val_nan(ctx);
  452. if (max)
  453. return isl_val_infty(ctx);
  454. else
  455. return isl_val_neginfty(ctx);
  456. }
  457. /* Return the minimum (maximum if max is set) of the integer affine
  458. * expression "obj" over the points in "bset".
  459. *
  460. * Return infinity or negative infinity if the optimal value is unbounded and
  461. * NaN if "bset" is empty.
  462. *
  463. * Call isl_basic_set_opt and translate the results.
  464. */
  465. __isl_give isl_val *isl_basic_set_opt_val(__isl_keep isl_basic_set *bset,
  466. int max, __isl_keep isl_aff *obj)
  467. {
  468. isl_ctx *ctx;
  469. isl_val *res;
  470. enum isl_lp_result lp_res;
  471. if (!bset || !obj)
  472. return NULL;
  473. ctx = isl_aff_get_ctx(obj);
  474. res = isl_val_alloc(ctx);
  475. if (!res)
  476. return NULL;
  477. lp_res = isl_basic_set_opt(bset, max, obj, &res->n);
  478. return convert_lp_result(lp_res, res, max);
  479. }
  480. /* Return the maximum of the integer affine
  481. * expression "obj" over the points in "bset".
  482. *
  483. * Return infinity or negative infinity if the optimal value is unbounded and
  484. * NaN if "bset" is empty.
  485. */
  486. __isl_give isl_val *isl_basic_set_max_val(__isl_keep isl_basic_set *bset,
  487. __isl_keep isl_aff *obj)
  488. {
  489. return isl_basic_set_opt_val(bset, 1, obj);
  490. }
  491. /* Return the minimum (maximum if max is set) of the integer affine
  492. * expression "obj" over the points in "set".
  493. *
  494. * Return infinity or negative infinity if the optimal value is unbounded and
  495. * NaN if "set" is empty.
  496. *
  497. * Call isl_set_opt and translate the results.
  498. */
  499. __isl_give isl_val *isl_set_opt_val(__isl_keep isl_set *set, int max,
  500. __isl_keep isl_aff *obj)
  501. {
  502. isl_ctx *ctx;
  503. isl_val *res;
  504. enum isl_lp_result lp_res;
  505. if (!set || !obj)
  506. return NULL;
  507. ctx = isl_aff_get_ctx(obj);
  508. res = isl_val_alloc(ctx);
  509. if (!res)
  510. return NULL;
  511. lp_res = isl_set_opt(set, max, obj, &res->n);
  512. return convert_lp_result(lp_res, res, max);
  513. }
  514. /* Return the minimum of the integer affine
  515. * expression "obj" over the points in "set".
  516. *
  517. * Return infinity or negative infinity if the optimal value is unbounded and
  518. * NaN if "set" is empty.
  519. */
  520. __isl_give isl_val *isl_set_min_val(__isl_keep isl_set *set,
  521. __isl_keep isl_aff *obj)
  522. {
  523. return isl_set_opt_val(set, 0, obj);
  524. }
  525. /* Return the maximum of the integer affine
  526. * expression "obj" over the points in "set".
  527. *
  528. * Return infinity or negative infinity if the optimal value is unbounded and
  529. * NaN if "set" is empty.
  530. */
  531. __isl_give isl_val *isl_set_max_val(__isl_keep isl_set *set,
  532. __isl_keep isl_aff *obj)
  533. {
  534. return isl_set_opt_val(set, 1, obj);
  535. }
  536. /* Return the optimum (min or max depending on "max") of "v1" and "v2",
  537. * where either may be NaN, signifying an uninitialized value.
  538. * That is, if either is NaN, then return the other one.
  539. */
  540. static __isl_give isl_val *val_opt(__isl_take isl_val *v1,
  541. __isl_take isl_val *v2, int max)
  542. {
  543. if (!v1 || !v2)
  544. goto error;
  545. if (isl_val_is_nan(v1)) {
  546. isl_val_free(v1);
  547. return v2;
  548. }
  549. if (isl_val_is_nan(v2)) {
  550. isl_val_free(v2);
  551. return v1;
  552. }
  553. if (max)
  554. return isl_val_max(v1, v2);
  555. else
  556. return isl_val_min(v1, v2);
  557. error:
  558. isl_val_free(v1);
  559. isl_val_free(v2);
  560. return NULL;
  561. }
  562. /* Internal data structure for isl_pw_aff_opt_val.
  563. *
  564. * "max" is set if the maximum should be computed.
  565. * "res" contains the current optimum and is initialized to NaN.
  566. */
  567. struct isl_pw_aff_opt_data {
  568. int max;
  569. isl_val *res;
  570. };
  571. /* Update the optimum in data->res with respect to the affine function
  572. * "aff" defined over "set".
  573. */
  574. static isl_stat piece_opt(__isl_take isl_set *set, __isl_take isl_aff *aff,
  575. void *user)
  576. {
  577. struct isl_pw_aff_opt_data *data = user;
  578. isl_val *opt;
  579. opt = isl_set_opt_val(set, data->max, aff);
  580. isl_set_free(set);
  581. isl_aff_free(aff);
  582. data->res = val_opt(data->res, opt, data->max);
  583. if (!data->res)
  584. return isl_stat_error;
  585. return isl_stat_ok;
  586. }
  587. /* Return the minimum (maximum if "max" is set) of the integer piecewise affine
  588. * expression "pa" over its definition domain.
  589. *
  590. * Return infinity or negative infinity if the optimal value is unbounded and
  591. * NaN if the domain of "pa" is empty.
  592. *
  593. * Initialize the result to NaN and then update it for each of the pieces
  594. * in "pa".
  595. */
  596. static __isl_give isl_val *isl_pw_aff_opt_val(__isl_take isl_pw_aff *pa,
  597. int max)
  598. {
  599. struct isl_pw_aff_opt_data data = { max };
  600. data.res = isl_val_nan(isl_pw_aff_get_ctx(pa));
  601. if (isl_pw_aff_foreach_piece(pa, &piece_opt, &data) < 0)
  602. data.res = isl_val_free(data.res);
  603. isl_pw_aff_free(pa);
  604. return data.res;
  605. }
  606. #undef TYPE
  607. #define TYPE isl_pw_multi_aff
  608. #include "isl_ilp_opt_multi_val_templ.c"
  609. #undef TYPE
  610. #define TYPE isl_multi_pw_aff
  611. #include "isl_ilp_opt_multi_val_templ.c"
  612. /* Internal data structure for isl_union_pw_aff_opt_val.
  613. *
  614. * "max" is set if the maximum should be computed.
  615. * "res" contains the current optimum and is initialized to NaN.
  616. */
  617. struct isl_union_pw_aff_opt_data {
  618. int max;
  619. isl_val *res;
  620. };
  621. /* Update the optimum in data->res with the optimum of "pa".
  622. */
  623. static isl_stat pw_aff_opt(__isl_take isl_pw_aff *pa, void *user)
  624. {
  625. struct isl_union_pw_aff_opt_data *data = user;
  626. isl_val *opt;
  627. opt = isl_pw_aff_opt_val(pa, data->max);
  628. data->res = val_opt(data->res, opt, data->max);
  629. if (!data->res)
  630. return isl_stat_error;
  631. return isl_stat_ok;
  632. }
  633. /* Return the minimum (maximum if "max" is set) of the integer piecewise affine
  634. * expression "upa" over its definition domain.
  635. *
  636. * Return infinity or negative infinity if the optimal value is unbounded and
  637. * NaN if the domain of the expression is empty.
  638. *
  639. * Initialize the result to NaN and then update it
  640. * for each of the piecewise affine expressions in "upa".
  641. */
  642. static __isl_give isl_val *isl_union_pw_aff_opt_val(
  643. __isl_take isl_union_pw_aff *upa, int max)
  644. {
  645. struct isl_union_pw_aff_opt_data data = { max };
  646. data.res = isl_val_nan(isl_union_pw_aff_get_ctx(upa));
  647. if (isl_union_pw_aff_foreach_pw_aff(upa, &pw_aff_opt, &data) < 0)
  648. data.res = isl_val_free(data.res);
  649. isl_union_pw_aff_free(upa);
  650. return data.res;
  651. }
  652. /* Return the minimum of the integer piecewise affine
  653. * expression "upa" over its definition domain.
  654. *
  655. * Return negative infinity if the optimal value is unbounded and
  656. * NaN if the domain of the expression is empty.
  657. */
  658. __isl_give isl_val *isl_union_pw_aff_min_val(__isl_take isl_union_pw_aff *upa)
  659. {
  660. return isl_union_pw_aff_opt_val(upa, 0);
  661. }
  662. /* Return the maximum of the integer piecewise affine
  663. * expression "upa" over its definition domain.
  664. *
  665. * Return infinity if the optimal value is unbounded and
  666. * NaN if the domain of the expression is empty.
  667. */
  668. __isl_give isl_val *isl_union_pw_aff_max_val(__isl_take isl_union_pw_aff *upa)
  669. {
  670. return isl_union_pw_aff_opt_val(upa, 1);
  671. }
  672. /* Return a list of minima (maxima if "max" is set)
  673. * for each of the expressions in "mupa" over their domains.
  674. *
  675. * An element in the list is infinity or negative infinity if the optimal
  676. * value of the corresponding expression is unbounded and
  677. * NaN if the domain of the expression is empty.
  678. *
  679. * Iterate over all the expressions in "mupa" and collect the results.
  680. */
  681. static __isl_give isl_multi_val *isl_multi_union_pw_aff_opt_multi_val(
  682. __isl_take isl_multi_union_pw_aff *mupa, int max)
  683. {
  684. int i;
  685. isl_size n;
  686. isl_multi_val *mv;
  687. n = isl_multi_union_pw_aff_size(mupa);
  688. if (n < 0)
  689. mupa = isl_multi_union_pw_aff_free(mupa);
  690. if (!mupa)
  691. return NULL;
  692. mv = isl_multi_val_zero(isl_multi_union_pw_aff_get_space(mupa));
  693. for (i = 0; i < n; ++i) {
  694. isl_val *v;
  695. isl_union_pw_aff *upa;
  696. upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
  697. v = isl_union_pw_aff_opt_val(upa, max);
  698. mv = isl_multi_val_set_val(mv, i, v);
  699. }
  700. isl_multi_union_pw_aff_free(mupa);
  701. return mv;
  702. }
  703. /* Return a list of minima (maxima if "max" is set) over the points in "uset"
  704. * for each of the expressions in "obj".
  705. *
  706. * An element in the list is infinity or negative infinity if the optimal
  707. * value of the corresponding expression is unbounded and
  708. * NaN if the intersection of "uset" with the domain of the expression
  709. * is empty.
  710. */
  711. static __isl_give isl_multi_val *isl_union_set_opt_multi_union_pw_aff(
  712. __isl_keep isl_union_set *uset, int max,
  713. __isl_keep isl_multi_union_pw_aff *obj)
  714. {
  715. uset = isl_union_set_copy(uset);
  716. obj = isl_multi_union_pw_aff_copy(obj);
  717. obj = isl_multi_union_pw_aff_intersect_domain(obj, uset);
  718. return isl_multi_union_pw_aff_opt_multi_val(obj, max);
  719. }
  720. /* Return a list of minima over the points in "uset"
  721. * for each of the expressions in "obj".
  722. *
  723. * An element in the list is infinity or negative infinity if the optimal
  724. * value of the corresponding expression is unbounded and
  725. * NaN if the intersection of "uset" with the domain of the expression
  726. * is empty.
  727. */
  728. __isl_give isl_multi_val *isl_union_set_min_multi_union_pw_aff(
  729. __isl_keep isl_union_set *uset, __isl_keep isl_multi_union_pw_aff *obj)
  730. {
  731. return isl_union_set_opt_multi_union_pw_aff(uset, 0, obj);
  732. }
  733. /* Return a list of minima
  734. * for each of the expressions in "mupa" over their domains.
  735. *
  736. * An element in the list is negative infinity if the optimal
  737. * value of the corresponding expression is unbounded and
  738. * NaN if the domain of the expression is empty.
  739. */
  740. __isl_give isl_multi_val *isl_multi_union_pw_aff_min_multi_val(
  741. __isl_take isl_multi_union_pw_aff *mupa)
  742. {
  743. return isl_multi_union_pw_aff_opt_multi_val(mupa, 0);
  744. }
  745. /* Return a list of maxima
  746. * for each of the expressions in "mupa" over their domains.
  747. *
  748. * An element in the list is infinity if the optimal
  749. * value of the corresponding expression is unbounded and
  750. * NaN if the domain of the expression is empty.
  751. */
  752. __isl_give isl_multi_val *isl_multi_union_pw_aff_max_multi_val(
  753. __isl_take isl_multi_union_pw_aff *mupa)
  754. {
  755. return isl_multi_union_pw_aff_opt_multi_val(mupa, 1);
  756. }
  757. #undef BASE
  758. #define BASE basic_set
  759. #include "isl_ilp_opt_val_templ.c"
  760. /* Return the maximal value attained by the given set dimension,
  761. * independently of the parameter values and of any other dimensions.
  762. *
  763. * Return infinity if the optimal value is unbounded and
  764. * NaN if "bset" is empty.
  765. */
  766. __isl_give isl_val *isl_basic_set_dim_max_val(__isl_take isl_basic_set *bset,
  767. int pos)
  768. {
  769. return isl_basic_set_dim_opt_val(bset, 1, pos);
  770. }
  771. #undef BASE
  772. #define BASE set
  773. #include "isl_ilp_opt_val_templ.c"
  774. /* Return the minimal value attained by the given set dimension,
  775. * independently of the parameter values and of any other dimensions.
  776. *
  777. * Return negative infinity if the optimal value is unbounded and
  778. * NaN if "set" is empty.
  779. */
  780. __isl_give isl_val *isl_set_dim_min_val(__isl_take isl_set *set, int pos)
  781. {
  782. return isl_set_dim_opt_val(set, 0, pos);
  783. }
  784. /* Return the maximal value attained by the given set dimension,
  785. * independently of the parameter values and of any other dimensions.
  786. *
  787. * Return infinity if the optimal value is unbounded and
  788. * NaN if "set" is empty.
  789. */
  790. __isl_give isl_val *isl_set_dim_max_val(__isl_take isl_set *set, int pos)
  791. {
  792. return isl_set_dim_opt_val(set, 1, pos);
  793. }