reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
/*
 * Copyright 2010      INRIA Saclay
 * Copyright 2012      Ecole Normale Superieure
 *
 * Use of this software is governed by the MIT license
 *
 * Written by Sven Verdoolaege,
 * INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
 */

/* Function for computing the lexicographic optimum of a map
 * in the form of either an isl_map or an isl_pw_multi_aff.
 */

#define xSF(TYPE,SUFFIX) TYPE ## SUFFIX
#define SF(TYPE,SUFFIX) xSF(TYPE,SUFFIX)

/* Compute the lexicographic minimum (or maximum if "flags" includes
 * ISL_OPT_MAX) of "bmap" over the domain "dom" and return the result.
 * If "empty" is not NULL, then *empty is assigned a set that
 * contains those parts of the domain where there is no solution.
 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
 * should be computed over the domain of "bmap".  "empty" is also NULL
 * in this case.
 * If "bmap" is marked as rational (ISL_BASIC_MAP_RATIONAL),
 * then the rational optimum is computed.  Otherwise, the integral optimum
 * is computed.
 */
static __isl_give TYPE *SF(isl_basic_map_partial_lexopt,SUFFIX)(
	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
	__isl_give isl_set **empty, unsigned flags)
{
	return SF(isl_tab_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty,
							    flags);
}

__isl_give TYPE *SF(isl_basic_map_partial_lexmax,SUFFIX)(
	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
	__isl_give isl_set **empty)
{
	unsigned flags = ISL_OPT_MAX;
	return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, flags);
}

__isl_give TYPE *SF(isl_basic_map_partial_lexmin,SUFFIX)(
	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
	__isl_give isl_set **empty)
{
	unsigned flags = 0;
	return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, flags);
}

__isl_give TYPE *SF(isl_basic_set_partial_lexmin,SUFFIX)(
	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom,
	__isl_give isl_set **empty)
{
	return SF(isl_basic_map_partial_lexmin,SUFFIX)(bset, dom, empty);
}

__isl_give TYPE *SF(isl_basic_set_partial_lexmax,SUFFIX)(
	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom,
	__isl_give isl_set **empty)
{
	return SF(isl_basic_map_partial_lexmax,SUFFIX)(bset, dom, empty);
}

/* Given a basic map "bmap", compute the lexicographically minimal
 * (or maximal) image element for each domain element in dom.
 * If empty is not NULL, then set *empty to those elements in dom
 * that do not have an image element.
 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
 * should be computed over the domain of "bmap".  "empty" is also NULL
 * in this case.
 *
 * We first make sure the basic sets in dom are disjoint and then
 * simply collect the results over each of the basic sets separately.
 * We could probably improve the efficiency a bit by moving the union
 * domain down into the parametric integer programming.
 *
 * If a full optimum is being computed (i.e., "flags" includes ISL_OPT_FULL),
 * then no domain is given and there is then also no need to consider
 * the disjuncts of the domain.
 */
static __isl_give TYPE *SF(basic_map_partial_lexopt,SUFFIX)(
	__isl_take isl_basic_map *bmap, __isl_take isl_set *dom,
	__isl_give isl_set **empty, unsigned flags)
{
	int i;
	TYPE *res;
	isl_set *all_empty;

	if (ISL_FL_ISSET(flags, ISL_OPT_FULL))
		return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, NULL,
								empty, flags);

	dom = isl_set_make_disjoint(dom);
	if (!dom)
		goto error;

	if (isl_set_plain_is_empty(dom)) {
		isl_space *space = isl_basic_map_get_space(bmap);
		if (empty)
			*empty = dom;
		else
			isl_set_free(dom);
		isl_basic_map_free(bmap);
		return EMPTY(space);
	}

	res = SF(isl_basic_map_partial_lexopt,SUFFIX)(isl_basic_map_copy(bmap),
			isl_basic_set_copy(dom->p[0]), empty, flags);

	if (empty)
		all_empty = *empty;
	for (i = 1; i < dom->n; ++i) {
		TYPE *res_i;

		res_i = SF(isl_basic_map_partial_lexopt,SUFFIX)(
				isl_basic_map_copy(bmap),
				isl_basic_set_copy(dom->p[i]), empty, flags);

		res = ADD(res, res_i);
		if (empty)
			all_empty = isl_set_union_disjoint(all_empty, *empty);
	}

	if (empty)
		*empty = all_empty;
	isl_set_free(dom);
	isl_basic_map_free(bmap);
	return res;
error:
	if (empty)
		*empty = NULL;
	isl_set_free(dom);
	isl_basic_map_free(bmap);
	return NULL;
}

/* Compute the lexicographic minimum (or maximum if "flags" includes
 * ISL_OPT_MAX) of "bmap" over its domain.
 */
__isl_give TYPE *SF(isl_basic_map_lexopt,SUFFIX)(
	__isl_take isl_basic_map *bmap, unsigned flags)
{
	ISL_FL_SET(flags, ISL_OPT_FULL);
	return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, NULL, NULL, flags);
}

__isl_give TYPE *SF(isl_basic_map_lexmin,SUFFIX)(__isl_take isl_basic_map *bmap)
{
	return SF(isl_basic_map_lexopt,SUFFIX)(bmap, 0);
}

static __isl_give TYPE *SF(isl_map_partial_lexopt_aligned,SUFFIX)(
	__isl_take isl_map *map, __isl_take isl_set *dom,
	__isl_give isl_set **empty, unsigned flags);
/* This function is currently only used when TYPE is defined as isl_map. */
static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)(
	__isl_take isl_map *map, __isl_take isl_set *dom,
	__isl_give isl_set **empty, unsigned flags)
	__attribute__ ((unused));

/* Given a map "map", compute the lexicographically minimal
 * (or maximal) image element for each domain element in dom.
 * Set *empty to those elements in dom that do not have an image element.
 *
 * Align parameters if needed and then call isl_map_partial_lexopt_aligned.
 */
static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)(
	__isl_take isl_map *map, __isl_take isl_set *dom,
	__isl_give isl_set **empty, unsigned flags)
{
	isl_bool aligned;

	aligned = isl_map_set_has_equal_params(map, dom);
	if (aligned < 0)
		goto error;
	if (aligned)
		return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom,
								empty, flags);
	if (!isl_space_has_named_params(map->dim) ||
	    !isl_space_has_named_params(dom->dim))
		isl_die(map->ctx, isl_error_invalid,
			"unaligned unnamed parameters", goto error);
	map = isl_map_align_params(map, isl_map_get_space(dom));
	dom = isl_map_align_params(dom, isl_map_get_space(map));
	return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom, empty,
							flags);
error:
	if (empty)
		*empty = NULL;
	isl_set_free(dom);
	isl_map_free(map);
	return NULL;
}

/* Compute the lexicographic minimum (or maximum if "flags" includes
 * ISL_OPT_MAX) of "map" over its domain.
 */
__isl_give TYPE *SF(isl_map_lexopt,SUFFIX)(__isl_take isl_map *map,
	unsigned flags)
{
	ISL_FL_SET(flags, ISL_OPT_FULL);
	return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, NULL, NULL,
							flags);
}

__isl_give TYPE *SF(isl_map_lexmin,SUFFIX)(__isl_take isl_map *map)
{
	return SF(isl_map_lexopt,SUFFIX)(map, 0);
}

__isl_give TYPE *SF(isl_map_lexmax,SUFFIX)(__isl_take isl_map *map)
{
	return SF(isl_map_lexopt,SUFFIX)(map, ISL_OPT_MAX);
}

__isl_give TYPE *SF(isl_set_lexmin,SUFFIX)(__isl_take isl_set *set)
{
	return SF(isl_map_lexmin,SUFFIX)(set);
}

__isl_give TYPE *SF(isl_set_lexmax,SUFFIX)(__isl_take isl_set *set)
{
	return SF(isl_map_lexmax,SUFFIX)(set);
}