brintos

brintos / llvm-project-archived public Read only

0
0
Text · 89.9 KiB · df49364 Raw
3374 lines · c
1/*2 * Copyright 2008-2009 Katholieke Universiteit Leuven3 * Copyright 2010      INRIA Saclay4 * Copyright 2012-2013 Ecole Normale Superieure5 * Copyright 2019      Cerebras Systems6 *7 * Use of this software is governed by the MIT license8 *9 * Written by Sven Verdoolaege, K.U.Leuven, Departement10 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium11 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,12 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 13 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France14 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA15 */16 17#include <stdlib.h>18#include <string.h>19#include <isl_ctx_private.h>20#include <isl_map_private.h>21#include <isl/set.h>22#include <isl_seq.h>23#include <isl_polynomial_private.h>24#include <isl_printer_private.h>25#include <isl_space_private.h>26#include <isl_mat_private.h>27#include <isl_vec_private.h>28#include <isl/union_set.h>29#include <isl/union_map.h>30#include <isl/constraint.h>31#include <isl_local.h>32#include <isl_local_space_private.h>33#include <isl_aff_private.h>34#include <isl_id_private.h>35#include <isl_val_private.h>36#include <isl_constraint_private.h>37#include <isl/ast_build.h>38#include <isl_sort.h>39#include <isl_output_private.h>40 41#include <bset_to_bmap.c>42#include <set_to_map.c>43#include <uset_to_umap.c>44 45static const char *s_to[2] = { " -> ", " \\to " };46static const char *s_and[2] = { " and ", " \\wedge " };47static const char *s_or[2] = { " or ", " \\vee " };48static const char *s_le[2] = { "<=", "\\le" };49static const char *s_ge[2] = { ">=", "\\ge" };50static const char *s_open_set[2] = { "{ ", "\\{\\, " };51static const char *s_close_set[2] = { " }", " \\,\\}" };52static const char *s_open_list[2] = { "[", "(" };53static const char *s_close_list[2] = { "]", ")" };54static const char *s_such_that[2] = { " : ", " \\mid " };55static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };56static const char *s_close_exists[2] = { ")", "" };57static const char *s_div_prefix[2] = { "e", "\\alpha_" };58static const char *s_mod[2] = { "mod", "\\bmod" };59static const char *s_param_prefix[2] = { "p", "p_" };60static const char *s_input_prefix[2] = { "i", "i_" };61static const char *s_output_prefix[2] = { "o", "o_" };62 63static __isl_give isl_printer *print_constraint_polylib(64	struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)65{66	int i;67	isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in);68	isl_size n_out = isl_basic_map_dim(bmap, isl_dim_out);69	isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param);70	isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];71 72	if (n_in < 0 || n_out < 0 || nparam < 0)73		return isl_printer_free(p);74 75	p = isl_printer_start_line(p);76	p = isl_printer_print_int(p, ineq);77	for (i = 0; i < n_out; ++i) {78		p = isl_printer_print_str(p, " ");79		p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);80	}81	for (i = 0; i < n_in; ++i) {82		p = isl_printer_print_str(p, " ");83		p = isl_printer_print_isl_int(p, c[1+nparam+i]);84	}85	for (i = 0; i < bmap->n_div; ++i) {86		p = isl_printer_print_str(p, " ");87		p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);88	}89	for (i = 0; i < nparam; ++i) {90		p = isl_printer_print_str(p, " ");91		p = isl_printer_print_isl_int(p, c[1+i]);92	}93	p = isl_printer_print_str(p, " ");94	p = isl_printer_print_isl_int(p, c[0]);95	p = isl_printer_end_line(p);96	return p;97}98 99static __isl_give isl_printer *print_constraints_polylib(100	struct isl_basic_map *bmap, __isl_take isl_printer *p)101{102	int i;103 104	p = isl_printer_set_isl_int_width(p, 5);105 106	for (i = 0; i < bmap->n_eq; ++i)107		p = print_constraint_polylib(bmap, 0, i, p);108	for (i = 0; i < bmap->n_ineq; ++i)109		p = print_constraint_polylib(bmap, 1, i, p);110 111	return p;112}113 114static __isl_give isl_printer *bset_print_constraints_polylib(115	struct isl_basic_set *bset, __isl_take isl_printer *p)116{117	return print_constraints_polylib(bset_to_bmap(bset), p);118}119 120static __isl_give isl_printer *isl_basic_map_print_polylib(121	__isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)122{123	isl_size total;124 125	total = isl_basic_map_dim(bmap, isl_dim_all);126	if (total < 0)127		return isl_printer_free(p);128	p = isl_printer_start_line(p);129	p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);130	p = isl_printer_print_str(p, " ");131	p = isl_printer_print_int(p, 1 + total + 1);132	if (ext) {133		isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in);134		isl_size n_out = isl_basic_map_dim(bmap, isl_dim_out);135		isl_size n_div = isl_basic_map_dim(bmap, isl_dim_div);136		isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param);137 138		if (n_in < 0 || n_out < 0 || n_div < 0 || nparam < 0)139			return isl_printer_free(p);140 141		p = isl_printer_print_str(p, " ");142		p = isl_printer_print_int(p, n_out);143		p = isl_printer_print_str(p, " ");144		p = isl_printer_print_int(p, n_in);145		p = isl_printer_print_str(p, " ");146		p = isl_printer_print_int(p, n_div);147		p = isl_printer_print_str(p, " ");148		p = isl_printer_print_int(p, nparam);149	}150	p = isl_printer_end_line(p);151	return print_constraints_polylib(bmap, p);152}153 154static __isl_give isl_printer *isl_basic_set_print_polylib(155	__isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)156{157	return isl_basic_map_print_polylib(bset_to_bmap(bset), p, ext);158}159 160static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,161	__isl_take isl_printer *p, int ext)162{163	int i;164 165	p = isl_printer_start_line(p);166	p = isl_printer_print_int(p, map->n);167	p = isl_printer_end_line(p);168	for (i = 0; i < map->n; ++i) {169		p = isl_printer_start_line(p);170		p = isl_printer_end_line(p);171		p = isl_basic_map_print_polylib(map->p[i], p, ext);172	}173	return p;174}175 176static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,177	__isl_take isl_printer *p, int ext)178{179	return isl_map_print_polylib(set_to_map(set), p, ext);180}181 182static isl_size count_same_name(__isl_keep isl_space *space,183	enum isl_dim_type type, unsigned pos, const char *name)184{185	enum isl_dim_type t;186	int p;187	isl_size s;188	int count = 0;189 190	for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {191		s = t == type ? pos : isl_space_dim(space, t);192		if (s < 0)193			return isl_size_error;194		for (p = 0; p < s; ++p) {195			const char *n = isl_space_get_dim_name(space, t, p);196			if (n && !strcmp(n, name))197				count++;198		}199	}200	return count;201}202 203/* Print the name of the variable of type "type" and position "pos"204 * in "space" to "p".205 */206static __isl_give isl_printer *print_name(__isl_keep isl_space *space,207	__isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,208	int latex)209{210	const char *name;211	char buffer[20];212	isl_size primes;213 214	name = type == isl_dim_div ? NULL215				   : isl_space_get_dim_name(space, type, pos);216 217	if (!name) {218		const char *prefix;219		if (type == isl_dim_param)220			prefix = s_param_prefix[latex];221		else if (type == isl_dim_div)222			prefix = s_div_prefix[latex];223		else if (isl_space_is_set(space) || type == isl_dim_in)224			prefix = s_input_prefix[latex];225		else226			prefix = s_output_prefix[latex];227		snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);228		name = buffer;229	}230	primes = count_same_name(space, name == buffer ? isl_dim_div : type,231				 pos, name);232	if (primes < 0)233		return isl_printer_free(p);234	p = isl_printer_print_str(p, name);235	while (primes-- > 0)236		p = isl_printer_print_str(p, "'");237	return p;238}239 240static isl_stat pos2type(__isl_keep isl_space *space,241	enum isl_dim_type *type, unsigned *pos)242{243	isl_size n_in = isl_space_dim(space, isl_dim_in);244	isl_size n_out = isl_space_dim(space, isl_dim_out);245	isl_size nparam = isl_space_dim(space, isl_dim_param);246 247	if (n_in < 0 || n_out < 0 || nparam < 0)248		return isl_stat_error;249 250	if (*pos < 1 + nparam) {251		*type = isl_dim_param;252		*pos -= 1;253	} else if (*pos < 1 + nparam + n_in) {254		*type = isl_dim_in;255		*pos -= 1 + nparam;256	} else if (*pos < 1 + nparam + n_in + n_out) {257		*type = isl_dim_out;258		*pos -= 1 + nparam + n_in;259	} else {260		*type = isl_dim_div;261		*pos -= 1 + nparam + n_in + n_out;262	}263 264	return isl_stat_ok;265}266 267/* Can the div expression of the integer division at position "row" of "div"268 * be printed?269 * In particular, are the div expressions available and does the selected270 * variable have a known explicit representation?271 * Furthermore, the Omega format does not allow any div expressions272 * to be printed.273 */274static isl_bool can_print_div_expr(__isl_keep isl_printer *p,275	__isl_keep isl_mat *div, int pos)276{277	if (p->output_format == ISL_FORMAT_OMEGA)278		return isl_bool_false;279	if (!div)280		return isl_bool_false;281	return isl_bool_not(isl_local_div_is_marked_unknown(div, pos));282}283 284static __isl_give isl_printer *print_div(__isl_keep isl_space *space,285	__isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);286 287static __isl_give isl_printer *print_term(__isl_keep isl_space *space,288	__isl_keep isl_mat *div,289	isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)290{291	enum isl_dim_type type;292	int print_div_def;293 294	if (!p || !space)295		return isl_printer_free(p);296 297	if (pos == 0)298		return isl_printer_print_isl_int(p, c);299 300	if (pos2type(space, &type, &pos) < 0)301		return isl_printer_free(p);302	print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos);303 304	if (isl_int_is_one(c))305		;306	else if (isl_int_is_negone(c))307		p = isl_printer_print_str(p, "-");308	else {309		p = isl_printer_print_isl_int(p, c);310		if (p->output_format == ISL_FORMAT_C || print_div_def)311			p = isl_printer_print_str(p, "*");312	}313	if (print_div_def)314		p = print_div(space, div, pos, p);315	else316		p = print_name(space, p, type, pos, latex);317	return p;318}319 320static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *space,321	__isl_keep isl_mat *div,322	__isl_take isl_printer *p, isl_int *c, int len)323{324	int i;325	int first;326 327	for (i = 0, first = 1; i < len; ++i) {328		int flip = 0;329		if (isl_int_is_zero(c[i]))330			continue;331		if (!first) {332			if (isl_int_is_neg(c[i])) {333				flip = 1;334				isl_int_neg(c[i], c[i]);335				p = isl_printer_print_str(p, " - ");336			} else 337				p = isl_printer_print_str(p, " + ");338		}339		first = 0;340		p = print_term(space, div, c[i], i, p, 0);341		if (flip)342			isl_int_neg(c[i], c[i]);343	}344	if (first)345		p = isl_printer_print_str(p, "0");346	return p;347}348 349/* Print an affine expression "c"350 * to "p", with the variable names taken from "space" and351 * the integer division definitions taken from "div".352 */353static __isl_give isl_printer *print_affine(__isl_take isl_printer *p,354	__isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c)355{356	isl_size n_div, total;357	unsigned len;358 359	total = isl_space_dim(space, isl_dim_all);360	n_div = isl_mat_rows(div);361	if (total < 0 || n_div < 0)362		return isl_printer_free(p);363	len = 1 + total + n_div;364	return print_affine_of_len(space, div, p, c, len);365}366 367/* offset is the offset of local_space inside data->type of data->space.368 */369static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,370	__isl_keep isl_space *local_space, enum isl_dim_type local_type,371	struct isl_print_space_data *data, int offset)372{373	int i;374	isl_size dim;375 376	if (data->space != local_space && local_type == isl_dim_out)377		offset += local_space->n_in;378 379	dim = isl_space_dim(local_space, local_type);380	if (dim < 0)381		return isl_printer_free(p);382	for (i = 0; i < dim; ++i) {383		if (i)384			p = isl_printer_print_str(p, ", ");385		if (data->print_dim)386			p = data->print_dim(p, data, offset + i);387		else388			p = print_name(data->space, p, data->type, offset + i,389					data->latex);390	}391	return p;392}393 394static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p,395	__isl_keep isl_space *space, enum isl_dim_type type)396{397	struct isl_print_space_data data = { .space = space, .type = type };398 399	return print_nested_var_list(p, space, type, &data, 0);400}401 402static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,403	__isl_keep isl_space *local_dim,404	struct isl_print_space_data *data, int offset);405 406static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,407	__isl_keep isl_space *local_space, enum isl_dim_type local_type,408	struct isl_print_space_data *data, int offset)409{410	const char *name = NULL;411	isl_size n = isl_space_dim(local_space, local_type);412 413	if (n < 0)414		return isl_printer_free(p);415	if ((local_type == isl_dim_in || local_type == isl_dim_out)) {416		name = isl_space_get_tuple_name(local_space, local_type);417		if (name) {418			if (data->latex)419				p = isl_printer_print_str(p, "\\mathrm{");420			p = isl_printer_print_str(p, name);421			if (data->latex)422				p = isl_printer_print_str(p, "}");423		}424	}425	if (!data->latex || n != 1 || name)426		p = isl_printer_print_str(p, s_open_list[data->latex]);427	if ((local_type == isl_dim_in || local_type == isl_dim_out) &&428	    local_space->nested[local_type - isl_dim_in]) {429		if (data->space != local_space && local_type == isl_dim_out)430			offset += local_space->n_in;431		p = print_nested_map_dim(p,432				local_space->nested[local_type - isl_dim_in],433				data, offset);434	} else435		p = print_nested_var_list(p, local_space, local_type, data,436					  offset);437	if (!data->latex || n != 1 || name)438		p = isl_printer_print_str(p, s_close_list[data->latex]);439	return p;440}441 442static __isl_give isl_printer *print_tuple(__isl_keep isl_space *space,443	__isl_take isl_printer *p, enum isl_dim_type type,444	struct isl_print_space_data *data)445{446	data->space = space;447	data->type = type;448	return print_nested_tuple(p, space, type, data, 0);449}450 451static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,452	__isl_keep isl_space *local_dim,453	struct isl_print_space_data *data, int offset)454{455	p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset);456	p = isl_printer_print_str(p, s_to[data->latex]);457	p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset);458 459	return p;460}461 462__isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,463	__isl_take isl_printer *p, int rational,464	struct isl_print_space_data *data)465{466	if (rational && !data->latex)467		p = isl_printer_print_str(p, "rat: ");468	if (isl_space_is_params(space))469		;470	else if (isl_space_is_set(space))471		p = print_tuple(space, p, isl_dim_set, data);472	else {473		p = print_tuple(space, p, isl_dim_in, data);474		p = isl_printer_print_str(p, s_to[data->latex]);475		p = print_tuple(space, p, isl_dim_out, data);476	}477 478	return p;479}480 481static __isl_give isl_printer *print_omega_parameters(482	__isl_keep isl_space *space, __isl_take isl_printer *p)483{484	isl_size nparam = isl_space_dim(space, isl_dim_param);485 486	if (nparam < 0)487		return isl_printer_free(p);488	if (nparam == 0)489		return p;490 491	p = isl_printer_start_line(p);492	p = isl_printer_print_str(p, "symbolic ");493	p = print_var_list(p, space, isl_dim_param);494	p = isl_printer_print_str(p, ";");495	p = isl_printer_end_line(p);496	return p;497}498 499/* Does the inequality constraint following "i" in "bmap"500 * have an opposite value for the same last coefficient?501 * "last" is the position of the last coefficient of inequality "i".502 * If the next constraint is a div constraint, then it is ignored503 * since div constraints are not printed.504 */505static isl_bool next_is_opposite(__isl_keep isl_basic_map *bmap, int i,506	int last)507{508	int r;509	isl_size total = isl_basic_map_dim(bmap, isl_dim_all);510	unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);511 512	if (total < 0)513		return isl_bool_error;514	if (i + 1 >= bmap->n_ineq)515		return isl_bool_false;516	if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)517		return isl_bool_false;518	if (last >= o_div) {519		isl_bool is_div;520		is_div = isl_basic_map_is_div_constraint(bmap,521					    bmap->ineq[i + 1], last - o_div);522		if (is_div < 0)523			return isl_bool_error;524		if (is_div)525			return isl_bool_false;526	}527	r = isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&528	    !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]);529	return isl_bool_ok(r);530}531 532/* Return a string representation of the operator used when533 * printing a constraint where the LHS is greater than or equal to the LHS534 * (sign > 0) or smaller than or equal to the LHS (sign < 0).535 * If "strict" is set, then return the strict version of the comparison536 * operator.537 */538static const char *constraint_op(int sign, int strict, int latex)539{540	if (strict)541		return sign < 0 ? "<" : ">";542	if (sign < 0)543		return s_le[latex];544	else545		return s_ge[latex];546}547 548/* Print one side of a constraint "c" to "p", with549 * the variable names taken from "space" and the integer division definitions550 * taken from "div".551 * "last" is the position of the last non-zero coefficient.552 * Let c' be the result of zeroing out this coefficient, then553 * the partial constraint554 *555 *	c' op556 *557 * is printed.558 */559static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p,560	__isl_keep isl_space *space, __isl_keep isl_mat *div,561	isl_int *c, int last, const char *op, int latex)562{563	isl_int_set_si(c[last], 0);564	p = print_affine(p, space, div, c);565 566	p = isl_printer_print_str(p, " ");567	p = isl_printer_print_str(p, op);568	p = isl_printer_print_str(p, " ");569 570	return p;571}572 573/* Print a constraint "c" to "p", with the variable names574 * taken from "space" and the integer division definitions taken from "div".575 * "last" is the position of the last non-zero coefficient, which is576 * moreover assumed to be negative.577 * Let c' be the result of zeroing out this coefficient, then578 * the constraint is printed in the form579 *580 *	-c[last] op c'581 */582static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p,583	__isl_keep isl_space *space, __isl_keep isl_mat *div,584	isl_int *c, int last, const char *op, int latex)585{586	isl_int_abs(c[last], c[last]);587 588	p = print_term(space, div, c[last], last, p, latex);589 590	p = isl_printer_print_str(p, " ");591	p = isl_printer_print_str(p, op);592	p = isl_printer_print_str(p, " ");593 594	isl_int_set_si(c[last], 0);595	p = print_affine(p, space, div, c);596 597	return p;598}599 600/* Given an integer division601 *602 *	floor(f/m)603 *604 * at position "pos" in "div", print the corresponding modulo expression605 *606 *	(f) mod m607 *608 * to "p".  The variable names are taken from "space", while any609 * nested integer division definitions are taken from "div".610 */611static __isl_give isl_printer *print_mod(__isl_take isl_printer *p,612	__isl_keep isl_space *space, __isl_keep isl_mat *div, int pos,613	int latex)614{615	if (!p || !div)616		return isl_printer_free(p);617 618	p = isl_printer_print_str(p, "(");619	p = print_affine_of_len(space, div, p,620				div->row[pos] + 1, div->n_col - 1);621	p = isl_printer_print_str(p, ") ");622	p = isl_printer_print_str(p, s_mod[latex]);623	p = isl_printer_print_str(p, " ");624	p = isl_printer_print_isl_int(p, div->row[pos][0]);625	return p;626}627 628/* Given an equality constraint with a non-zero coefficient "c"629 * in position "pos", is this term of the form630 *631 *	a m floor(g/m),632 *633 * with c = a m?634 * Return the position of the corresponding integer division if so.635 * Return the number of integer divisions if not.636 * Return isl_size_error on error.637 *638 * Modulo constraints are currently not printed in C format.639 * Other than that, "pos" needs to correspond to an integer division640 * with explicit representation and "c" needs to be a multiple641 * of the denominator of the integer division.642 */643static isl_size print_as_modulo_pos(__isl_keep isl_printer *p,644	__isl_keep isl_space *space, __isl_keep isl_mat *div, unsigned pos,645	isl_int c)646{647	isl_bool can_print;648	isl_size n_div;649	enum isl_dim_type type;650 651	n_div = isl_mat_rows(div);652	if (!p || !space || n_div < 0)653		return isl_size_error;654	if (p->output_format == ISL_FORMAT_C)655		return n_div;656	if (pos2type(space, &type, &pos) < 0)657		return isl_size_error;658	if (type != isl_dim_div)659		return n_div;660	can_print = can_print_div_expr(p, div, pos);661	if (can_print < 0)662		return isl_size_error;663	if (!can_print)664		return n_div;665	if (!isl_int_is_divisible_by(c, div->row[pos][0]))666		return n_div;667	return pos;668}669 670/* Print equality constraint "c" to "p" as a modulo constraint,671 * with the variable names taken from "space" and672 * the integer division definitions taken from "div".673 * "last" is the position of the last non-zero coefficient, which is674 * moreover assumed to be negative and a multiple of the denominator675 * of the corresponding integer division.  "div_pos" is the corresponding676 * position in the sequence of integer divisions.677 *678 * The equality is of the form679 *680 *	f - a m floor(g/m) = 0.681 *682 * Print it as683 *684 *	a (g mod m) = -f + a g685 */686static __isl_give isl_printer *print_eq_mod_constraint(687	__isl_take isl_printer *p, __isl_keep isl_space *space,688	__isl_keep isl_mat *div, unsigned div_pos,689	isl_int *c, int last, int latex)690{691	isl_ctx *ctx;692	int multiple;693 694	ctx = isl_printer_get_ctx(p);695	isl_int_divexact(c[last], c[last], div->row[div_pos][0]);696	isl_int_abs(c[last], c[last]);697	multiple = !isl_int_is_one(c[last]);698	if (multiple) {699		p = isl_printer_print_isl_int(p, c[last]);700		p = isl_printer_print_str(p, "*(");701	}702	p = print_mod(p, space, div, div_pos, latex);703	if (multiple)704		p = isl_printer_print_str(p, ")");705	p = isl_printer_print_str(p, " = ");706	isl_seq_combine(c, ctx->negone, c,707			    c[last], div->row[div_pos] + 1, last);708	isl_int_set_si(c[last], 0);709	p = print_affine(p, space, div, c);710	return p;711}712 713/* Print equality constraint "c" to "p", with the variable names714 * taken from "space" and the integer division definitions taken from "div".715 * "last" is the position of the last non-zero coefficient, which is716 * moreover assumed to be negative.717 *718 * If possible, print the equality constraint as a modulo constraint.719 */720static __isl_give isl_printer *print_eq_constraint(__isl_take isl_printer *p,721	__isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c,722	int last, int latex)723{724	isl_size n_div;725	isl_size div_pos;726 727	n_div = isl_mat_rows(div);728	div_pos = print_as_modulo_pos(p, space, div, last, c[last]);729	if (n_div < 0 || div_pos < 0)730		return isl_printer_free(p);731	if (div_pos < n_div)732		return print_eq_mod_constraint(p, space, div, div_pos,733						c, last, latex);734	return print_constraint(p, space, div, c, last, "=", latex);735}736 737/* Print the constraints of "bmap" to "p".738 * The names of the variables are taken from "space" and739 * the integer division definitions are taken from "div".740 * Div constraints are only printed in "dump" mode.741 * The constraints are sorted prior to printing (except in "dump" mode).742 *743 * If x is the last variable with a non-zero coefficient,744 * then a lower bound745 *746 *	f - a x >= 0747 *748 * is printed as749 *750 *	a x <= f751 *752 * while an upper bound753 *754 *	f + a x >= 0755 *756 * is printed as757 *758 *	a x >= -f759 *760 * If the next constraint has an opposite sign for the same last coefficient,761 * then it is printed as762 *763 *	f >= a x764 *765 * or766 *767 *	-f <= a x768 *769 * instead.  In fact, the "a x" part is not printed explicitly, but770 * reused from the next constraint, which is therefore treated as771 * a first constraint in the conjunction.772 *773 * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and774 * the comparison operator is replaced by the strict variant.775 * Essentially, ">= 1" is replaced by "> 0".776 */777static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,778	__isl_keep isl_space *space, __isl_keep isl_mat *div,779	__isl_take isl_printer *p, int latex)780{781	int i;782	isl_vec *c = NULL;783	int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);784	isl_size total = isl_basic_map_dim(bmap, isl_dim_all);785	unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);786	int first = 1;787	int dump;788 789	if (total < 0 || !p)790		return isl_printer_free(p);791	bmap = isl_basic_map_copy(bmap);792	dump = p->dump;793	if (!dump)794		bmap = isl_basic_map_sort_constraints(bmap);795	if (!bmap)796		goto error;797 798	c = isl_vec_alloc(bmap->ctx, 1 + total);799	if (!c)800		goto error;801 802	for (i = bmap->n_eq - 1; i >= 0; --i) {803		int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);804		if (l < 0) {805			if (i != bmap->n_eq - 1)806				p = isl_printer_print_str(p, s_and[latex]);807			p = isl_printer_print_str(p, "0 = 0");808			continue;809		}810		if (!first)811			p = isl_printer_print_str(p, s_and[latex]);812		if (isl_int_is_neg(bmap->eq[i][l]))813			isl_seq_cpy(c->el, bmap->eq[i], 1 + total);814		else815			isl_seq_neg(c->el, bmap->eq[i], 1 + total);816		p = print_eq_constraint(p, space, div, c->el, l, latex);817		first = 0;818	}819	for (i = 0; i < bmap->n_ineq; ++i) {820		isl_bool combine;821		int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);822		int strict;823		int s;824		const char *op;825		if (l < 0)826			continue;827		if (!dump && l >= o_div &&828		    can_print_div_expr(p, div, l - o_div)) {829			isl_bool is_div;830			is_div = isl_basic_map_is_div_constraint(bmap,831						    bmap->ineq[i], l - o_div);832			if (is_div < 0)833				goto error;834			if (is_div)835				continue;836		}837		if (!first)838			p = isl_printer_print_str(p, s_and[latex]);839		s = isl_int_sgn(bmap->ineq[i][l]);840		strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);841		if (s < 0)842			isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);843		else844			isl_seq_neg(c->el, bmap->ineq[i], 1 + total);845		if (strict)846			isl_int_set_si(c->el[0], 0);847		combine = dump ? isl_bool_false : next_is_opposite(bmap, i, l);848		if (combine < 0)849			goto error;850		if (combine) {851			op = constraint_op(-s, strict, latex);852			p = print_half_constraint(p, space, div, c->el, l,853						op, latex);854			first = 1;855		} else {856			op = constraint_op(s, strict, latex);857			p = print_constraint(p, space, div, c->el, l,858						op, latex);859			first = 0;860		}861	}862 863	isl_basic_map_free(bmap);864	isl_vec_free(c);865 866	return p;867error:868	isl_basic_map_free(bmap);869	isl_vec_free(c);870	isl_printer_free(p);871	return NULL;872}873 874static __isl_give isl_printer *print_div(__isl_keep isl_space *space,875	__isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)876{877	int c;878 879	if (!p || !div)880		return isl_printer_free(p);881 882	c = p->output_format == ISL_FORMAT_C;883	p = isl_printer_print_str(p, c ? "floord(" : "floor((");884	p = print_affine_of_len(space, div, p,885				div->row[pos] + 1, div->n_col - 1);886	p = isl_printer_print_str(p, c ? ", " : ")/");887	p = isl_printer_print_isl_int(p, div->row[pos][0]);888	p = isl_printer_print_str(p, ")");889	return p;890}891 892/* Print a comma separated list of div names, except those that have893 * a definition that can be printed.894 * If "print_defined_divs" is set, then those div names are printed895 * as well, along with their definitions.896 */897static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,898	__isl_keep isl_space *space, __isl_keep isl_mat *div, int latex,899	int print_defined_divs)900{901	int i;902	int first = 1;903	isl_size n_div;904 905	n_div = isl_mat_rows(div);906	if (!p || !space || n_div < 0)907		return isl_printer_free(p);908 909	for (i = 0; i < n_div; ++i) {910		if (!print_defined_divs && can_print_div_expr(p, div, i))911			continue;912		if (!first)913			p = isl_printer_print_str(p, ", ");914		p = print_name(space, p, isl_dim_div, i, latex);915		first = 0;916		if (!can_print_div_expr(p, div, i))917			continue;918		p = isl_printer_print_str(p, " = ");919		p = print_div(space, div, i, p);920	}921 922	return p;923}924 925/* Does printing an object with local variables described by "div"926 * require an "exists" clause?927 * That is, are there any local variables without an explicit representation?928 * An exists clause is also needed in "dump" mode because929 * explicit div representations are not printed inline in that case.930 */931static isl_bool need_exists(__isl_keep isl_printer *p, __isl_keep isl_mat *div)932{933	int i;934	isl_size n;935 936	n = isl_mat_rows(div);937	if (!p || n < 0)938		return isl_bool_error;939	if (n == 0)940		return isl_bool_false;941	if (p->dump)942		return isl_bool_true;943	for (i = 0; i < n; ++i)944		if (!can_print_div_expr(p, div, i))945			return isl_bool_true;946	return isl_bool_false;947}948 949/* Print the start of an exists clause, i.e.,950 *951 *	(exists variables:952 *953 * In dump mode, local variables with an explicit definition are printed954 * as well because they will not be printed inline.955 */956static __isl_give isl_printer *open_exists(__isl_take isl_printer *p,957	__isl_keep isl_space *space, __isl_keep isl_mat *div, int latex)958{959	int dump;960 961	if (!p)962		return NULL;963 964	dump = p->dump;965	p = isl_printer_print_str(p, s_open_exists[latex]);966	p = print_div_list(p, space, div, latex, dump);967	p = isl_printer_print_str(p, ": ");968 969	return p;970}971 972/* Remove the explicit representations of all local variables in "div".973 */974static __isl_give isl_mat *mark_all_unknown(__isl_take isl_mat *div)975{976	int i;977	isl_size n_div;978 979	n_div = isl_mat_rows(div);980	if (n_div < 0)981		return isl_mat_free(div);982 983	for (i = 0; i < n_div; ++i)984		div = isl_mat_set_element_si(div, i, 0, 0);985	return div;986}987 988/* Print the constraints of "bmap" to "p".989 * The names of the variables are taken from "space".990 * "latex" is set if the constraints should be printed in LaTeX format.991 * Do not print inline explicit div representations in "dump" mode.992 */993static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,994	__isl_keep isl_space *space, __isl_take isl_printer *p, int latex)995{996	int dump;997	isl_mat *div;998	isl_bool exists;999 1000	if (!p)1001		return NULL;1002	dump = p->dump;1003	div = isl_basic_map_get_divs(bmap);1004	exists = need_exists(p, div);1005	if (exists >= 0 && exists)1006		p = open_exists(p, space, div, latex);1007 1008	if (dump)1009		div = mark_all_unknown(div);1010	p = print_constraints(bmap, space, div, p, latex);1011	isl_mat_free(div);1012 1013	if (exists >= 0 && exists)1014		p = isl_printer_print_str(p, s_close_exists[latex]);1015	return p;1016}1017 1018/* Print a colon followed by the constraints of "bmap"1019 * to "p", provided there are any constraints.1020 * The names of the variables are taken from "space".1021 * "latex" is set if the constraints should be printed in LaTeX format.1022 */1023static __isl_give isl_printer *print_optional_disjunct(1024	__isl_keep isl_basic_map *bmap, __isl_keep isl_space *space,1025	__isl_take isl_printer *p, int latex)1026{1027	if (isl_basic_map_plain_is_universe(bmap))1028		return p;1029 1030	p = isl_printer_print_str(p, ": ");1031	p = print_disjunct(bmap, space, p, latex);1032 1033	return p;1034}1035 1036static __isl_give isl_printer *basic_map_print_omega(1037	__isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)1038{1039	p = isl_printer_print_str(p, "{ [");1040	p = print_var_list(p, bmap->dim, isl_dim_in);1041	p = isl_printer_print_str(p, "] -> [");1042	p = print_var_list(p, bmap->dim, isl_dim_out);1043	p = isl_printer_print_str(p, "] ");1044	p = print_optional_disjunct(bmap, bmap->dim, p, 0);1045	p = isl_printer_print_str(p, " }");1046	return p;1047}1048 1049static __isl_give isl_printer *basic_set_print_omega(1050	__isl_keep isl_basic_set *bset, __isl_take isl_printer *p)1051{1052	p = isl_printer_print_str(p, "{ [");1053	p = print_var_list(p, bset->dim, isl_dim_set);1054	p = isl_printer_print_str(p, "] ");1055	p = print_optional_disjunct(bset, bset->dim, p, 0);1056	p = isl_printer_print_str(p, " }");1057	return p;1058}1059 1060static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,1061	__isl_take isl_printer *p)1062{1063	int i;1064 1065	for (i = 0; i < map->n; ++i) {1066		if (i)1067			p = isl_printer_print_str(p, " union ");1068		p = basic_map_print_omega(map->p[i], p);1069	}1070	return p;1071}1072 1073static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,1074	__isl_take isl_printer *p)1075{1076	int i;1077 1078	for (i = 0; i < set->n; ++i) {1079		if (i)1080			p = isl_printer_print_str(p, " union ");1081		p = basic_set_print_omega(set->p[i], p);1082	}1083	return p;1084}1085 1086/* Print the list of parameters in "space", followed by an arrow, to "p",1087 * if there are any parameters.1088 */1089static __isl_give isl_printer *print_param_tuple(__isl_take isl_printer *p,1090	__isl_keep isl_space *space, struct isl_print_space_data *data)1091{1092	isl_size nparam;1093 1094	nparam = isl_space_dim(space, isl_dim_param);1095	if (!p || nparam < 0)1096		return isl_printer_free(p);1097	if (nparam == 0)1098		return p;1099 1100	p = print_tuple(space, p, isl_dim_param, data);1101	p = isl_printer_print_str(p, s_to[data->latex]);1102 1103	return p;1104}1105 1106static __isl_give isl_printer *isl_basic_map_print_isl(1107	__isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,1108	int latex)1109{1110	struct isl_print_space_data data = { .latex = latex };1111	int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);1112 1113	p = print_param_tuple(p, bmap->dim, &data);1114	p = isl_printer_print_str(p, "{ ");1115	p = isl_print_space(bmap->dim, p, rational, &data);1116	p = isl_printer_print_str(p, " : ");1117	p = print_disjunct(bmap, bmap->dim, p, latex);1118	p = isl_printer_print_str(p, " }");1119	return p;1120}1121 1122/* Print the disjuncts of a map (or set) "map" to "p".1123 * The names of the variables are taken from "space".1124 * "latex" is set if the constraints should be printed in LaTeX format.1125 */1126static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map,1127	__isl_keep isl_space *space, __isl_take isl_printer *p, int latex)1128{1129	int i;1130 1131	if (map->n == 0)1132		p = isl_printer_print_str(p, "false");1133	for (i = 0; i < map->n; ++i) {1134		if (i)1135			p = isl_printer_print_str(p, s_or[latex]);1136		if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)1137			p = isl_printer_print_str(p, "(");1138		p = print_disjunct(map->p[i], space, p, latex);1139		if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)1140			p = isl_printer_print_str(p, ")");1141	}1142	return p;1143}1144 1145/* Print the disjuncts of a map (or set) "map" to "p".1146 * The names of the variables are taken from "space".1147 * "hull" describes constraints shared by all disjuncts of "map".1148 * "latex" is set if the constraints should be printed in LaTeX format.1149 *1150 * Print the disjuncts as a conjunction of "hull" and1151 * the result of removing the constraints of "hull" from "map".1152 * If this result turns out to be the universe, then simply print "hull".1153 */1154static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map,1155	__isl_keep isl_space *space, __isl_take isl_basic_map *hull,1156	__isl_take isl_printer *p, int latex)1157{1158	isl_bool is_universe;1159 1160	p = print_disjunct(hull, space, p, latex);1161	map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);1162	is_universe = isl_map_plain_is_universe(map);1163	if (is_universe < 0)1164		goto error;1165	if (!is_universe) {1166		p = isl_printer_print_str(p, s_and[latex]);1167		p = isl_printer_print_str(p, "(");1168		p = print_disjuncts_core(map, space, p, latex);1169		p = isl_printer_print_str(p, ")");1170	}1171	isl_map_free(map);1172 1173	return p;1174error:1175	isl_map_free(map);1176	isl_printer_free(p);1177	return NULL;1178}1179 1180/* Print the disjuncts of a map (or set) "map" to "p".1181 * The names of the variables are taken from "space".1182 * "latex" is set if the constraints should be printed in LaTeX format.1183 *1184 * If there are at least two disjuncts and "dump" mode is not turned out,1185 * check for any shared constraints among all disjuncts.1186 * If there are any, then print them separately in print_disjuncts_in_hull.1187 */1188static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,1189	__isl_keep isl_space *space, __isl_take isl_printer *p, int latex)1190{1191	if (isl_map_plain_is_universe(map))1192		return p;1193 1194	p = isl_printer_print_str(p, s_such_that[latex]);1195	if (!p)1196		return NULL;1197 1198	if (!p->dump && map->n >= 2) {1199		isl_basic_map *hull;1200		isl_bool is_universe;1201 1202		hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));1203		is_universe = isl_basic_map_plain_is_universe(hull);1204		if (is_universe < 0)1205			p = isl_printer_free(p);1206		else if (!is_universe)1207			return print_disjuncts_in_hull(map, space, hull,1208							p, latex);1209		isl_basic_map_free(hull);1210	}1211 1212	return print_disjuncts_core(map, space, p, latex);1213}1214 1215/* Print the disjuncts of a map (or set).1216 * The names of the variables are taken from "space".1217 * "latex" is set if the constraints should be printed in LaTeX format.1218 *1219 * If the map turns out to be a universal parameter domain, then1220 * we need to print the colon.  Otherwise, the output looks identical1221 * to the empty set.1222 */1223static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,1224	__isl_keep isl_space *space, __isl_take isl_printer *p, int latex)1225{1226	if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))1227		return isl_printer_print_str(p, s_such_that[latex]);1228	else1229		return print_disjuncts(map, space, p, latex);1230}1231 1232/* Print the disjuncts of a set.1233 * The names of the variables are taken from "space".1234 * "latex" is set if the constraints should be printed in LaTeX format.1235 */1236static __isl_give isl_printer *print_disjuncts_set(__isl_keep isl_set *set,1237	__isl_keep isl_space *space, __isl_take isl_printer *p, int latex)1238{1239	return print_disjuncts_map(set_to_map(set), space, p, latex);1240}1241 1242struct isl_aff_split {1243	isl_basic_map *aff;1244	isl_map *map;1245};1246 1247static void free_split(__isl_take struct isl_aff_split *split, int n)1248{1249	int i;1250 1251	if (!split)1252		return;1253 1254	for (i = 0; i < n; ++i) {1255		isl_basic_map_free(split[i].aff);1256		isl_map_free(split[i].map);1257	}1258 1259	free(split);1260}1261 1262static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)1263{1264	int i, j;1265	isl_size nparam, n_in, n_out, total;1266 1267	bmap = isl_basic_map_cow(bmap);1268	if (!bmap)1269		return NULL;1270	bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);1271 1272	nparam = isl_basic_map_dim(bmap, isl_dim_param);1273	n_in = isl_basic_map_dim(bmap, isl_dim_in);1274	n_out = isl_basic_map_dim(bmap, isl_dim_out);1275	total = isl_basic_map_dim(bmap, isl_dim_all);1276	if (n_in < 0 || n_out < 0 || nparam < 0 || total < 0)1277		return isl_basic_map_free(bmap);1278 1279	for (i = bmap->n_eq - 1; i >= 0; --i) {1280		j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);1281		if (j >= nparam && j < nparam + n_in + n_out &&1282		    (isl_int_is_one(bmap->eq[i][1 + j]) ||1283		     isl_int_is_negone(bmap->eq[i][1 + j])))1284			continue;1285		if (isl_basic_map_drop_equality(bmap, i) < 0)1286			goto error;1287	}1288 1289	bmap = isl_basic_map_finalize(bmap);1290 1291	return bmap;1292error:1293	isl_basic_map_free(bmap);1294	return NULL;1295}1296 1297static int aff_split_cmp(const void *p1, const void *p2, void *user)1298{1299	const struct isl_aff_split *s1, *s2;1300	s1 = (const struct isl_aff_split *) p1;1301	s2 = (const struct isl_aff_split *) p2;1302 1303	return isl_basic_map_plain_cmp(s1->aff, s2->aff);1304}1305 1306static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,1307	__isl_keep isl_basic_map *aff)1308{1309	int i, j;1310	isl_size v_div;1311 1312	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);1313	if (v_div < 0 || !aff)1314		goto error;1315 1316	for (i = bmap->n_eq - 1; i >= 0; --i) {1317		if (isl_seq_first_non_zero(bmap->eq[i] + 1 + v_div,1318					    bmap->n_div) != -1)1319			continue;1320		for (j = 0; j < aff->n_eq; ++j) {1321			if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + v_div) &&1322			    !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + v_div))1323				continue;1324			if (isl_basic_map_drop_equality(bmap, i) < 0)1325				goto error;1326			break;1327		}1328	}1329 1330	return bmap;1331error:1332	isl_basic_map_free(bmap);1333	return NULL;1334}1335 1336static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)1337{1338	int i, n;1339	struct isl_aff_split *split;1340	isl_ctx *ctx;1341 1342	ctx = isl_map_get_ctx(map);1343	split = isl_calloc_array(ctx, struct isl_aff_split, map->n);1344	if (!split)1345		return NULL;1346 1347	for (i = 0; i < map->n; ++i) {1348		isl_basic_map *bmap;1349		split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));1350		bmap = isl_basic_map_copy(map->p[i]);1351		bmap = isl_basic_map_cow(bmap);1352		bmap = drop_aff(bmap, split[i].aff);1353		split[i].map = isl_map_from_basic_map(bmap);1354		if (!split[i].aff || !split[i].map)1355			goto error;1356	}1357 1358	if (isl_sort(split, map->n, sizeof(struct isl_aff_split),1359			&aff_split_cmp, NULL) < 0)1360		goto error;1361 1362	n = map->n;1363	for (i = n - 1; i >= 1; --i) {1364		if (!isl_basic_map_plain_is_equal(split[i - 1].aff,1365						 split[i].aff))1366			continue;1367		isl_basic_map_free(split[i].aff);1368		split[i - 1].map = isl_map_union(split[i - 1].map,1369						 split[i].map);1370		if (i != n - 1)1371			split[i] = split[n - 1];1372		split[n - 1].aff = NULL;1373		split[n - 1].map = NULL;1374		--n;1375	}1376 1377	return split;1378error:1379	free_split(split, map->n);1380	return NULL;1381}1382 1383static int defining_equality(__isl_keep isl_basic_map *eq,1384	__isl_keep isl_space *space, enum isl_dim_type type, int pos)1385{1386	int i;1387	isl_size total;1388 1389	total = isl_basic_map_dim(eq, isl_dim_all);1390	if (total < 0)1391		return -1;1392 1393	pos += isl_space_offset(space, type);1394 1395	for (i = 0; i < eq->n_eq; ++i) {1396		if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)1397			continue;1398		if (isl_int_is_one(eq->eq[i][1 + pos]))1399			isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);1400		return i;1401	}1402 1403	return -1;1404}1405 1406/* Print dimension "pos" of data->space to "p".1407 *1408 * data->user is assumed to be an isl_basic_map keeping track of equalities.1409 *1410 * If the current dimension is defined by these equalities, then print1411 * the corresponding expression, assigned to the name of the dimension1412 * if there is any.  Otherwise, print the name of the dimension.1413 */1414static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p,1415	struct isl_print_space_data *data, unsigned pos)1416{1417	isl_basic_map *eq = data->user;1418	int j;1419 1420	j = defining_equality(eq, data->space, data->type, pos);1421	if (j >= 0) {1422		if (isl_space_has_dim_name(data->space, data->type, pos)) {1423			p = print_name(data->space, p, data->type, pos,1424					data->latex);1425			p = isl_printer_print_str(p, " = ");1426		}1427		pos += 1 + isl_space_offset(data->space, data->type);1428		p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos);1429	} else {1430		p = print_name(data->space, p, data->type, pos, data->latex);1431	}1432 1433	return p;1434}1435 1436static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,1437	struct isl_aff_split *split, int n, __isl_keep isl_space *space)1438{1439	struct isl_print_space_data data = { 0 };1440	int i;1441	int rational;1442 1443	data.print_dim = &print_dim_eq;1444	for (i = 0; i < n; ++i) {1445		if (!split[i].map)1446			break;1447		rational = split[i].map->n > 0 &&1448		    ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);1449		if (i)1450			p = isl_printer_print_str(p, "; ");1451		data.user = split[i].aff;1452		p = isl_print_space(space, p, rational, &data);1453		p = print_disjuncts_map(split[i].map, space, p, 0);1454	}1455 1456	return p;1457}1458 1459static __isl_give isl_printer *print_body_map(__isl_take isl_printer *p,1460	__isl_keep isl_map *map)1461{1462	struct isl_print_space_data data = { 0 };1463	struct isl_aff_split *split = NULL;1464	int rational;1465 1466	if (!p || !map)1467		return isl_printer_free(p);1468	if (!p->dump && map->n > 0)1469		split = split_aff(map);1470	if (split) {1471		p = print_split_map(p, split, map->n, map->dim);1472	} else {1473		rational = map->n > 0 &&1474		    ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);1475		p = isl_print_space(map->dim, p, rational, &data);1476		p = print_disjuncts_map(map, map->dim, p, 0);1477	}1478	free_split(split, map->n);1479	return p;1480}1481 1482static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,1483	__isl_take isl_printer *p)1484{1485	struct isl_print_space_data data = { 0 };1486 1487	p = print_param_tuple(p, map->dim, &data);1488	p = isl_printer_print_str(p, s_open_set[0]);1489	p = print_body_map(p, map);1490	p = isl_printer_print_str(p, s_close_set[0]);1491	return p;1492}1493 1494static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,1495	__isl_take isl_printer *p, __isl_keep isl_basic_map *aff)1496{1497	struct isl_print_space_data data = { 0 };1498 1499	data.latex = 1;1500	p = print_param_tuple(p, map->dim, &data);1501	p = isl_printer_print_str(p, s_open_set[1]);1502	data.print_dim = &print_dim_eq;1503	data.user = aff;1504	p = isl_print_space(map->dim, p, 0, &data);1505	p = print_disjuncts_map(map, map->dim, p, 1);1506	p = isl_printer_print_str(p, s_close_set[1]);1507 1508	return p;1509}1510 1511static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,1512	__isl_take isl_printer *p)1513{1514	int i;1515	struct isl_aff_split *split = NULL;1516 1517	if (map->n > 0)1518		split = split_aff(map);1519 1520	if (!split)1521		return print_latex_map(map, p, NULL);1522 1523	for (i = 0; i < map->n; ++i) {1524		if (!split[i].map)1525			break;1526		if (i)1527			p = isl_printer_print_str(p, " \\cup ");1528		p = print_latex_map(split[i].map, p, split[i].aff);1529	}1530 1531	free_split(split, map->n);1532	return p;1533}1534 1535__isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,1536	__isl_keep isl_basic_map *bmap)1537{1538	if (!p || !bmap)1539		goto error;1540	if (p->output_format == ISL_FORMAT_ISL)1541		return isl_basic_map_print_isl(bmap, p, 0);1542	else if (p->output_format == ISL_FORMAT_OMEGA)1543		return basic_map_print_omega(bmap, p);1544	isl_assert(bmap->ctx, 0, goto error);1545error:1546	isl_printer_free(p);1547	return NULL;1548}1549 1550__isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,1551	__isl_keep isl_basic_set *bset)1552{1553	if (!p || !bset)1554		goto error;1555 1556	if (p->output_format == ISL_FORMAT_ISL)1557		return isl_basic_map_print_isl(bset, p, 0);1558	else if (p->output_format == ISL_FORMAT_POLYLIB)1559		return isl_basic_set_print_polylib(bset, p, 0);1560	else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)1561		return isl_basic_set_print_polylib(bset, p, 1);1562	else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)1563		return bset_print_constraints_polylib(bset, p);1564	else if (p->output_format == ISL_FORMAT_OMEGA)1565		return basic_set_print_omega(bset, p);1566	isl_assert(p->ctx, 0, goto error);1567error:1568	isl_printer_free(p);1569	return NULL;1570}1571 1572__isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,1573	__isl_keep isl_set *set)1574{1575	if (!p || !set)1576		goto error;1577	if (p->output_format == ISL_FORMAT_ISL)1578		return isl_map_print_isl(set_to_map(set), p);1579	else if (p->output_format == ISL_FORMAT_POLYLIB)1580		return isl_set_print_polylib(set, p, 0);1581	else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)1582		return isl_set_print_polylib(set, p, 1);1583	else if (p->output_format == ISL_FORMAT_OMEGA)1584		return isl_set_print_omega(set, p);1585	else if (p->output_format == ISL_FORMAT_LATEX)1586		return isl_map_print_latex(set_to_map(set), p);1587	isl_assert(set->ctx, 0, goto error);1588error:1589	isl_printer_free(p);1590	return NULL;1591}1592 1593__isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,1594	__isl_keep isl_map *map)1595{1596	if (!p || !map)1597		goto error;1598 1599	if (p->output_format == ISL_FORMAT_ISL)1600		return isl_map_print_isl(map, p);1601	else if (p->output_format == ISL_FORMAT_POLYLIB)1602		return isl_map_print_polylib(map, p, 0);1603	else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)1604		return isl_map_print_polylib(map, p, 1);1605	else if (p->output_format == ISL_FORMAT_OMEGA)1606		return isl_map_print_omega(map, p);1607	else if (p->output_format == ISL_FORMAT_LATEX)1608		return isl_map_print_latex(map, p);1609	isl_assert(map->ctx, 0, goto error);1610error:1611	isl_printer_free(p);1612	return NULL;1613}1614 1615struct isl_union_print_data {1616	isl_printer *p;1617	int first;1618};1619 1620#undef BASE1621#define BASE	map1622#include "isl_union_print_templ.c"1623 1624/* Print the body of "uset" (everything except the parameter declarations)1625 * to "p" in isl format.1626 */1627static __isl_give isl_printer *isl_printer_print_union_set_isl_body(1628	__isl_take isl_printer *p, __isl_keep isl_union_set *uset)1629{1630	return print_body_union_map(p, uset_to_umap(uset));1631}1632 1633static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user)1634{1635	struct isl_union_print_data *data;1636	data = (struct isl_union_print_data *)user;1637 1638	if (!data->first)1639		data->p = isl_printer_print_str(data->p, " \\cup ");1640	data->first = 0;1641 1642	data->p = isl_map_print_latex(map, data->p);1643	isl_map_free(map);1644 1645	return isl_stat_ok;1646}1647 1648static __isl_give isl_printer *isl_union_map_print_latex(1649	__isl_keep isl_union_map *umap, __isl_take isl_printer *p)1650{1651	struct isl_union_print_data data = { p, 1 };1652	isl_union_map_foreach_map(umap, &print_latex_map_body, &data);1653	p = data.p;1654	return p;1655}1656 1657__isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,1658	__isl_keep isl_union_map *umap)1659{1660	if (!p || !umap)1661		goto error;1662 1663	if (p->output_format == ISL_FORMAT_ISL)1664		return print_union_map_isl(p, umap);1665	if (p->output_format == ISL_FORMAT_LATEX)1666		return isl_union_map_print_latex(umap, p);1667 1668	isl_die(p->ctx, isl_error_invalid,1669		"invalid output format for isl_union_map", goto error);1670error:1671	isl_printer_free(p);1672	return NULL;1673}1674 1675__isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,1676	__isl_keep isl_union_set *uset)1677{1678	if (!p || !uset)1679		goto error;1680 1681	if (p->output_format == ISL_FORMAT_ISL)1682		return print_union_map_isl(p, uset_to_umap(uset));1683	if (p->output_format == ISL_FORMAT_LATEX)1684		return isl_union_map_print_latex(uset_to_umap(uset), p);1685 1686	isl_die(p->ctx, isl_error_invalid,1687		"invalid output format for isl_union_set", goto error);1688error:1689	isl_printer_free(p);1690	return NULL;1691}1692 1693static isl_size poly_rec_n_non_zero(__isl_keep isl_poly_rec *rec)1694{1695	int i;1696	int n;1697 1698	if (!rec)1699		return isl_size_error;1700 1701	for (i = 0, n = 0; i < rec->n; ++i) {1702		isl_bool is_zero = isl_poly_is_zero(rec->p[i]);1703 1704		if (is_zero < 0)1705			return isl_size_error;1706		if (!is_zero)1707			++n;1708	}1709 1710	return n;1711}1712 1713static __isl_give isl_printer *poly_print_cst(__isl_keep isl_poly *poly,1714	__isl_take isl_printer *p, int first)1715{1716	isl_poly_cst *cst;1717	int neg;1718 1719	cst = isl_poly_as_cst(poly);1720	if (!cst)1721		goto error;1722	neg = !first && isl_int_is_neg(cst->n);1723	if (!first)1724		p = isl_printer_print_str(p, neg ? " - " :  " + ");1725	if (neg)1726		isl_int_neg(cst->n, cst->n);1727	if (isl_int_is_zero(cst->d)) {1728		int sgn = isl_int_sgn(cst->n);1729		p = isl_printer_print_str(p, sgn < 0 ? "-infty" :1730					    sgn == 0 ? "NaN" : "infty");1731	} else1732		p = isl_printer_print_isl_int(p, cst->n);1733	if (neg)1734		isl_int_neg(cst->n, cst->n);1735	if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {1736		p = isl_printer_print_str(p, "/");1737		p = isl_printer_print_isl_int(p, cst->d);1738	}1739	return p;1740error:1741	isl_printer_free(p);1742	return NULL;1743}1744 1745static __isl_give isl_printer *print_base(__isl_take isl_printer *p,1746	__isl_keep isl_space *space, __isl_keep isl_mat *div, int var)1747{1748	isl_size total;1749 1750	total = isl_space_dim(space, isl_dim_all);1751	if (total < 0)1752		return isl_printer_free(p);1753	if (var < total)1754		p = print_term(space, NULL, space->ctx->one, 1 + var, p, 0);1755	else1756		p = print_div(space, div, var - total, p);1757	return p;1758}1759 1760static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,1761	__isl_keep isl_space *space, __isl_keep isl_mat *div, int var, int exp)1762{1763	p = print_base(p, space, div, var);1764	if (exp == 1)1765		return p;1766	if (p->output_format == ISL_FORMAT_C) {1767		int i;1768		for (i = 1; i < exp; ++i) {1769			p = isl_printer_print_str(p, "*");1770			p = print_base(p, space, div, var);1771		}1772	} else {1773		p = isl_printer_print_str(p, "^");1774		p = isl_printer_print_int(p, exp);1775	}1776	return p;1777}1778 1779/* Print the polynomial "poly" defined over the domain space "space" and1780 * local variables defined by "div" to "p".1781 */1782static __isl_give isl_printer *poly_print(__isl_keep isl_poly *poly,1783	__isl_keep isl_space *space, __isl_keep isl_mat *div,1784	__isl_take isl_printer *p)1785{1786	int i, first, print_parens;1787	isl_size n;1788	isl_bool is_cst;1789	isl_poly_rec *rec;1790 1791	is_cst = isl_poly_is_cst(poly);1792	if (!p || is_cst < 0 || !space || !div)1793		goto error;1794 1795	if (is_cst)1796		return poly_print_cst(poly, p, 1);1797 1798	rec = isl_poly_as_rec(poly);1799	n = poly_rec_n_non_zero(rec);1800	if (n < 0)1801		return isl_printer_free(p);1802	print_parens = n > 1;1803	if (print_parens)1804		p = isl_printer_print_str(p, "(");1805	for (i = 0, first = 1; i < rec->n; ++i) {1806		isl_bool is_zero = isl_poly_is_zero(rec->p[i]);1807		isl_bool is_one = isl_poly_is_one(rec->p[i]);1808		isl_bool is_negone = isl_poly_is_negone(rec->p[i]);1809		isl_bool is_cst = isl_poly_is_cst(rec->p[i]);1810 1811		if (is_zero < 0 || is_one < 0 || is_negone < 0)1812			return isl_printer_free(p);1813		if (is_zero)1814			continue;1815		if (is_negone) {1816			if (!i)1817				p = isl_printer_print_str(p, "-1");1818			else if (first)1819				p = isl_printer_print_str(p, "-");1820			else1821				p = isl_printer_print_str(p, " - ");1822		} else if (is_cst && !is_one)1823			p = poly_print_cst(rec->p[i], p, first);1824		else {1825			if (!first)1826				p = isl_printer_print_str(p, " + ");1827			if (i == 0 || !is_one)1828				p = poly_print(rec->p[i], space, div, p);1829		}1830		first = 0;1831		if (i == 0)1832			continue;1833		if (!is_one && !is_negone)1834			p = isl_printer_print_str(p, " * ");1835		p = print_pow(p, space, div, rec->poly.var, i);1836	}1837	if (print_parens)1838		p = isl_printer_print_str(p, ")");1839	return p;1840error:1841	isl_printer_free(p);1842	return NULL;1843}1844 1845static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,1846	__isl_keep isl_qpolynomial *qp)1847{1848	if (!p || !qp)1849		goto error;1850	p = poly_print(qp->poly, qp->dim, qp->div, p);1851	return p;1852error:1853	isl_printer_free(p);1854	return NULL;1855}1856 1857static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,1858	__isl_keep isl_qpolynomial *qp)1859{1860	struct isl_print_space_data data = { 0 };1861 1862	if (!p || !qp)1863		goto error;1864 1865	p = print_param_tuple(p, qp->dim, &data);1866	p = isl_printer_print_str(p, "{ ");1867	if (!isl_space_is_params(qp->dim)) {1868		p = isl_print_space(qp->dim, p, 0, &data);1869		p = isl_printer_print_str(p, " -> ");1870	}1871	p = print_qpolynomial(p, qp);1872	p = isl_printer_print_str(p, " }");1873	return p;1874error:1875	isl_printer_free(p);1876	return NULL;1877}1878 1879/* Print the quasi-polynomial "qp" to "p" in C format, with the variable names1880 * taken from the domain space "space".1881 */1882static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,1883	__isl_keep isl_space *space, __isl_keep isl_qpolynomial *qp)1884{1885	isl_bool is_one;1886	isl_val *den;1887 1888	den = isl_qpolynomial_get_den(qp);1889	qp = isl_qpolynomial_copy(qp);1890	qp = isl_qpolynomial_scale_val(qp, isl_val_copy(den));1891	is_one = isl_val_is_one(den);1892	if (is_one < 0)1893		p = isl_printer_free(p);1894	if (!is_one)1895		p = isl_printer_print_str(p, "(");1896	if (qp)1897		p = poly_print(qp->poly, space, qp->div, p);1898	else1899		p = isl_printer_free(p);1900	if (!is_one) {1901		p = isl_printer_print_str(p, ")/");1902		p = isl_printer_print_val(p, den);1903	}1904	isl_qpolynomial_free(qp);1905	isl_val_free(den);1906	return p;1907}1908 1909__isl_give isl_printer *isl_printer_print_qpolynomial(1910	__isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)1911{1912	if (!p || !qp)1913		goto error;1914 1915	if (p->output_format == ISL_FORMAT_ISL)1916		return print_qpolynomial_isl(p, qp);1917	else if (p->output_format == ISL_FORMAT_C)1918		return print_qpolynomial_c(p, qp->dim, qp);1919	else1920		isl_die(qp->dim->ctx, isl_error_unsupported,1921			"output format not supported for isl_qpolynomials",1922			goto error);1923error:1924	isl_printer_free(p);1925	return NULL;1926}1927 1928void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,1929	unsigned output_format)1930{1931	isl_printer *p;1932 1933	if  (!qp)1934		return;1935 1936	isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);1937	p = isl_printer_to_file(qp->dim->ctx, out);1938	p = isl_printer_print_qpolynomial(p, qp);1939	isl_printer_free(p);1940}1941 1942static __isl_give isl_printer *qpolynomial_fold_print(1943	__isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)1944{1945	int i;1946	isl_qpolynomial_list *list;1947	isl_size n;1948 1949	list = isl_qpolynomial_fold_peek_list(fold);1950	n = isl_qpolynomial_list_size(list);1951	if (n < 0)1952		return isl_printer_free(p);1953	if (fold->type == isl_fold_min)1954		p = isl_printer_print_str(p, "min");1955	else if (fold->type == isl_fold_max)1956		p = isl_printer_print_str(p, "max");1957	p = isl_printer_print_str(p, "(");1958	for (i = 0; i < n; ++i) {1959		isl_qpolynomial *qp;1960 1961		if (i)1962			p = isl_printer_print_str(p, ", ");1963		qp = isl_qpolynomial_list_peek(list, i);1964		p = print_qpolynomial(p, qp);1965	}1966	p = isl_printer_print_str(p, ")");1967	return p;1968}1969 1970void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,1971	FILE *out, unsigned output_format)1972{1973	isl_printer *p;1974 1975	if (!fold)1976		return;1977 1978	isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);1979 1980	p = isl_printer_to_file(fold->dim->ctx, out);1981	p = isl_printer_print_qpolynomial_fold(p, fold);1982 1983	isl_printer_free(p);1984}1985 1986static __isl_give isl_printer *print_body_pw_qpolynomial(1987	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)1988{1989	struct isl_print_space_data data = { 0 };1990	int i = 0;1991 1992	for (i = 0; i < pwqp->n; ++i) {1993		isl_space *space;1994 1995		if (i)1996			p = isl_printer_print_str(p, "; ");1997		space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp);1998		if (!isl_space_is_params(space)) {1999			p = isl_print_space(space, p, 0, &data);2000			p = isl_printer_print_str(p, " -> ");2001		}2002		p = print_qpolynomial(p, pwqp->p[i].qp);2003		p = print_disjuncts(set_to_map(pwqp->p[i].set), space, p, 0);2004		isl_space_free(space);2005	}2006 2007	return p;2008}2009 2010static __isl_give isl_printer *print_pw_qpolynomial_isl(2011	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)2012{2013	struct isl_print_space_data data = { 0 };2014 2015	if (!p || !pwqp)2016		goto error;2017 2018	p = print_param_tuple(p, pwqp->dim, &data);2019	p = isl_printer_print_str(p, "{ ");2020	if (pwqp->n == 0) {2021		if (!isl_space_is_set(pwqp->dim)) {2022			p = print_tuple(pwqp->dim, p, isl_dim_in, &data);2023			p = isl_printer_print_str(p, " -> ");2024		}2025		p = isl_printer_print_str(p, "0");2026	}2027	p = print_body_pw_qpolynomial(p, pwqp);2028	p = isl_printer_print_str(p, " }");2029	return p;2030error:2031	isl_printer_free(p);2032	return NULL;2033}2034 2035void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,2036	unsigned output_format)2037{2038	isl_printer *p;2039 2040	if (!pwqp)2041		return;2042 2043	p = isl_printer_to_file(pwqp->dim->ctx, out);2044	p = isl_printer_set_output_format(p, output_format);2045	p = isl_printer_print_pw_qpolynomial(p, pwqp);2046 2047	isl_printer_free(p);2048}2049 2050static __isl_give isl_printer *print_body_pw_qpolynomial_fold(2051	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)2052{2053	struct isl_print_space_data data = { 0 };2054	int i = 0;2055 2056	for (i = 0; i < pwf->n; ++i) {2057		isl_space *space;2058 2059		if (i)2060			p = isl_printer_print_str(p, "; ");2061		space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold);2062		if (!isl_space_is_params(space)) {2063			p = isl_print_space(space, p, 0, &data);2064			p = isl_printer_print_str(p, " -> ");2065		}2066		p = qpolynomial_fold_print(pwf->p[i].fold, p);2067		p = print_disjuncts(set_to_map(pwf->p[i].set), space, p, 0);2068		isl_space_free(space);2069	}2070 2071	return p;2072}2073 2074static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(2075	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)2076{2077	struct isl_print_space_data data = { 0 };2078 2079	p = print_param_tuple(p, pwf->dim, &data);2080	p = isl_printer_print_str(p, "{ ");2081	if (pwf->n == 0) {2082		if (!isl_space_is_set(pwf->dim)) {2083			p = print_tuple(pwf->dim, p, isl_dim_in, &data);2084			p = isl_printer_print_str(p, " -> ");2085		}2086		p = isl_printer_print_str(p, "0");2087	}2088	p = print_body_pw_qpolynomial_fold(p, pwf);2089	p = isl_printer_print_str(p, " }");2090	return p;2091}2092 2093static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,2094	__isl_keep isl_local_space *ls, isl_int *c);2095 2096/* We skip the constraint if it is implied by the div expression.2097 *2098 * *first indicates whether this is the first constraint in the conjunction and2099 * is updated if the constraint is actually printed.2100 */2101static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,2102	__isl_keep isl_local_space *ls, isl_int *c, const char *op, int *first)2103{2104	unsigned o_div;2105	isl_size n_div;2106	int div;2107 2108	o_div = isl_local_space_offset(ls, isl_dim_div);2109	n_div = isl_local_space_dim(ls, isl_dim_div);2110	if (n_div < 0)2111		return isl_printer_free(p);2112	div = isl_seq_last_non_zero(c + o_div, n_div);2113	if (div >= 0) {2114		isl_bool is_div = isl_local_space_is_div_constraint(ls, c, div);2115		if (is_div < 0)2116			return isl_printer_free(p);2117		if (is_div)2118			return p;2119	}2120 2121	if (!*first)2122		p = isl_printer_print_str(p, " && ");2123 2124	p = print_ls_affine_c(p, ls, c);2125	p = isl_printer_print_str(p, " ");2126	p = isl_printer_print_str(p, op);2127	p = isl_printer_print_str(p, " 0");2128 2129	*first = 0;2130 2131	return p;2132}2133 2134static __isl_give isl_printer *print_ls_partial_affine_c(2135	__isl_take isl_printer *p, __isl_keep isl_local_space *ls,2136	isl_int *c, unsigned len);2137 2138static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,2139	__isl_keep isl_space *space, __isl_keep isl_basic_set *bset)2140{2141	int i, j;2142	int first = 1;2143	isl_size n_div = isl_basic_set_dim(bset, isl_dim_div);2144	isl_size total = isl_basic_set_dim(bset, isl_dim_all);2145	isl_mat *div;2146	isl_local_space *ls;2147 2148	if (n_div < 0 || total < 0)2149		return isl_printer_free(p);2150 2151	total -= n_div;2152	div = isl_basic_set_get_divs(bset);2153	ls = isl_local_space_alloc_div(isl_space_copy(space), div);2154	for (i = 0; i < bset->n_eq; ++i) {2155		j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);2156		if (j < 0)2157			p = print_constraint_c(p, ls,2158						bset->eq[i], "==", &first);2159		else {2160			if (i)2161				p = isl_printer_print_str(p, " && ");2162			p = isl_printer_print_str(p, "(");2163			p = print_ls_partial_affine_c(p, ls, bset->eq[i],2164						   1 + total + j);2165			p = isl_printer_print_str(p, ") % ");2166			p = isl_printer_print_isl_int(p,2167						bset->eq[i][1 + total + j]);2168			p = isl_printer_print_str(p, " == 0");2169			first = 0;2170		}2171	}2172	for (i = 0; i < bset->n_ineq; ++i)2173		p = print_constraint_c(p, ls, bset->ineq[i], ">=", &first);2174	isl_local_space_free(ls);2175	return p;2176}2177 2178static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,2179	__isl_keep isl_space *space, __isl_keep isl_set *set)2180{2181	int i;2182 2183	if (!set)2184		return isl_printer_free(p);2185 2186	if (set->n == 0)2187		p = isl_printer_print_str(p, "0");2188 2189	for (i = 0; i < set->n; ++i) {2190		if (i)2191			p = isl_printer_print_str(p, " || ");2192		if (set->n > 1)2193			p = isl_printer_print_str(p, "(");2194		p = print_basic_set_c(p, space, set->p[i]);2195		if (set->n > 1)2196			p = isl_printer_print_str(p, ")");2197	}2198	return p;2199}2200 2201/* Print the piecewise quasi-polynomial "pwqp" to "p" in C format.2202 */2203static __isl_give isl_printer *print_pw_qpolynomial_c(2204	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)2205{2206	int i;2207	isl_space *space;2208 2209	space = isl_pw_qpolynomial_get_domain_space(pwqp);2210	if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set)) {2211		p = print_qpolynomial_c(p, space, pwqp->p[0].qp);2212		isl_space_free(space);2213		return p;2214	}2215 2216	for (i = 0; i < pwqp->n; ++i) {2217		p = isl_printer_print_str(p, "(");2218		p = print_set_c(p, space, pwqp->p[i].set);2219		p = isl_printer_print_str(p, ") ? (");2220		p = print_qpolynomial_c(p, space, pwqp->p[i].qp);2221		p = isl_printer_print_str(p, ") : ");2222	}2223 2224	isl_space_free(space);2225	p = isl_printer_print_str(p, "0");2226	return p;2227}2228 2229__isl_give isl_printer *isl_printer_print_pw_qpolynomial(2230	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)2231{2232	if (!p || !pwqp)2233		goto error;2234 2235	if (p->output_format == ISL_FORMAT_ISL)2236		return print_pw_qpolynomial_isl(p, pwqp);2237	else if (p->output_format == ISL_FORMAT_C)2238		return print_pw_qpolynomial_c(p, pwqp);2239	isl_assert(p->ctx, 0, goto error);2240error:2241	isl_printer_free(p);2242	return NULL;2243}2244 2245#undef BASE2246#define BASE	pw_qpolynomial2247#include "isl_union_print_templ.c"2248 2249__isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(2250	__isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)2251{2252	if (!p || !upwqp)2253		goto error;2254 2255	if (p->output_format == ISL_FORMAT_ISL)2256		return print_union_pw_qpolynomial_isl(p, upwqp);2257	isl_die(p->ctx, isl_error_invalid,2258		"invalid output format for isl_union_pw_qpolynomial",2259		goto error);2260error:2261	isl_printer_free(p);2262	return NULL;2263}2264 2265/* Print the quasi-polynomial reduction "fold" to "p" in C format,2266 * with the variable names taken from the domain space "space".2267 */2268static __isl_give isl_printer *print_qpolynomial_fold_c(2269	__isl_take isl_printer *p, __isl_keep isl_space *space,2270	__isl_keep isl_qpolynomial_fold *fold)2271{2272	int i;2273	isl_qpolynomial_list *list;2274	isl_size n;2275 2276	list = isl_qpolynomial_fold_peek_list(fold);2277	n = isl_qpolynomial_list_size(list);2278	if (n < 0)2279		return isl_printer_free(p);2280	for (i = 0; i < n - 1; ++i)2281		if (fold->type == isl_fold_min)2282			p = isl_printer_print_str(p, "min(");2283		else if (fold->type == isl_fold_max)2284			p = isl_printer_print_str(p, "max(");2285 2286	for (i = 0; i < n; ++i) {2287		isl_qpolynomial *qp;2288 2289		if (i)2290			p = isl_printer_print_str(p, ", ");2291		qp = isl_qpolynomial_list_peek(list, i);2292		p = print_qpolynomial_c(p, space, qp);2293		if (i)2294			p = isl_printer_print_str(p, ")");2295	}2296	return p;2297}2298 2299__isl_give isl_printer *isl_printer_print_qpolynomial_fold(2300	__isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)2301{2302	if  (!p || !fold)2303		goto error;2304	if (p->output_format == ISL_FORMAT_ISL)2305		return qpolynomial_fold_print(fold, p);2306	else if (p->output_format == ISL_FORMAT_C)2307		return print_qpolynomial_fold_c(p, fold->dim, fold);2308	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",2309		goto error);2310error:2311	isl_printer_free(p);2312	return NULL;2313}2314 2315/* Print the piecewise quasi-polynomial reduction "pwf" to "p" in C format.2316 */2317static __isl_give isl_printer *print_pw_qpolynomial_fold_c(2318	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)2319{2320	int i;2321	isl_space *space;2322 2323	space = isl_pw_qpolynomial_fold_get_domain_space(pwf);2324	if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set)) {2325		p = print_qpolynomial_fold_c(p, space, pwf->p[0].fold);2326		isl_space_free(space);2327		return p;2328	}2329 2330	for (i = 0; i < pwf->n; ++i) {2331		p = isl_printer_print_str(p, "(");2332		p = print_set_c(p, space, pwf->p[i].set);2333		p = isl_printer_print_str(p, ") ? (");2334		p = print_qpolynomial_fold_c(p, space, pwf->p[i].fold);2335		p = isl_printer_print_str(p, ") : ");2336	}2337 2338	isl_space_free(space);2339	p = isl_printer_print_str(p, "0");2340	return p;2341}2342 2343__isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(2344	__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)2345{2346	if (!p || !pwf)2347		goto error;2348 2349	if (p->output_format == ISL_FORMAT_ISL)2350		return print_pw_qpolynomial_fold_isl(p, pwf);2351	else if (p->output_format == ISL_FORMAT_C)2352		return print_pw_qpolynomial_fold_c(p, pwf);2353	isl_assert(p->ctx, 0, goto error);2354error:2355	isl_printer_free(p);2356	return NULL;2357}2358 2359void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,2360	FILE *out, unsigned output_format)2361{2362	isl_printer *p;2363 2364	if (!pwf)2365		return;2366 2367	p = isl_printer_to_file(pwf->dim->ctx, out);2368	p = isl_printer_set_output_format(p, output_format);2369	p = isl_printer_print_pw_qpolynomial_fold(p, pwf);2370 2371	isl_printer_free(p);2372}2373 2374#undef BASE2375#define BASE	pw_qpolynomial_fold2376#include "isl_union_print_templ.c"2377 2378__isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(2379	__isl_take isl_printer *p,2380	__isl_keep isl_union_pw_qpolynomial_fold *upwf)2381{2382	if (!p || !upwf)2383		goto error;2384 2385	if (p->output_format == ISL_FORMAT_ISL)2386		return print_union_pw_qpolynomial_fold_isl(p, upwf);2387	isl_die(p->ctx, isl_error_invalid,2388		"invalid output format for isl_union_pw_qpolynomial_fold",2389		goto error);2390error:2391	isl_printer_free(p);2392	return NULL;2393}2394 2395/* Print the isl_constraint "c" to "p".2396 */2397__isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,2398	__isl_keep isl_constraint *c)2399{2400	struct isl_print_space_data data = { 0 };2401	isl_local_space *ls;2402	isl_space *space;2403	isl_bool exists;2404 2405	if (!p || !c)2406		goto error;2407 2408	ls = isl_constraint_get_local_space(c);2409	if (!ls)2410		return isl_printer_free(p);2411	space = isl_local_space_get_space(ls);2412	p = print_param_tuple(p, space, &data);2413	p = isl_printer_print_str(p, "{ ");2414	p = isl_print_space(space, p, 0, &data);2415	p = isl_printer_print_str(p, " : ");2416	exists = need_exists(p, ls->div);2417	if (exists < 0)2418		p = isl_printer_free(p);2419	if (exists >= 0 && exists)2420		p = open_exists(p, space, ls->div, 0);2421	p = print_affine_of_len(space, ls->div, p, c->v->el, c->v->size);2422	if (isl_constraint_is_equality(c))2423		p = isl_printer_print_str(p, " = 0");2424	else2425		p = isl_printer_print_str(p, " >= 0");2426	if (exists >= 0 && exists)2427		p = isl_printer_print_str(p, s_close_exists[0]);2428	p = isl_printer_print_str(p, " }");2429	isl_space_free(space);2430	isl_local_space_free(ls);2431 2432	return p;2433error:2434	isl_printer_free(p);2435	return NULL;2436}2437 2438static __isl_give isl_printer *isl_printer_print_space_isl(2439	__isl_take isl_printer *p, __isl_keep isl_space *space)2440{2441	struct isl_print_space_data data = { 0 };2442 2443	if (!space)2444		goto error;2445 2446	p = print_param_tuple(p, space, &data);2447 2448	p = isl_printer_print_str(p, "{ ");2449	if (isl_space_is_params(space))2450		p = isl_printer_print_str(p, s_such_that[0]);2451	else2452		p = isl_print_space(space, p, 0, &data);2453	p = isl_printer_print_str(p, " }");2454 2455	return p;2456error:2457	isl_printer_free(p);2458	return NULL;2459}2460 2461__isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,2462	__isl_keep isl_space *space)2463{2464	if (!p || !space)2465		return isl_printer_free(p);2466	if (p->output_format == ISL_FORMAT_ISL)2467		return isl_printer_print_space_isl(p, space);2468	else if (p->output_format == ISL_FORMAT_OMEGA)2469		return print_omega_parameters(space, p);2470 2471	isl_die(isl_space_get_ctx(space), isl_error_unsupported,2472		"output format not supported for space",2473		return isl_printer_free(p));2474}2475 2476__isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,2477	__isl_keep isl_local_space *ls)2478{2479	struct isl_print_space_data data = { 0 };2480	isl_size n_div;2481 2482	n_div = isl_local_space_dim(ls, isl_dim_div);2483	if (n_div < 0)2484		goto error;2485 2486	p = print_param_tuple(p, ls->dim, &data);2487	p = isl_printer_print_str(p, "{ ");2488	p = isl_print_space(ls->dim, p, 0, &data);2489	if (n_div > 0) {2490		p = isl_printer_print_str(p, " : ");2491		p = isl_printer_print_str(p, s_open_exists[0]);2492		p = print_div_list(p, ls->dim, ls->div, 0, 1);2493		p = isl_printer_print_str(p, s_close_exists[0]);2494	} else if (isl_space_is_params(ls->dim))2495		p = isl_printer_print_str(p, s_such_that[0]);2496	p = isl_printer_print_str(p, " }");2497	return p;2498error:2499	isl_printer_free(p);2500	return NULL;2501}2502 2503/* Look for the last of the "n" integer divisions that is used in "aff" and2504 * that can be printed as a modulo and2505 * return the position of this integer division.2506 * Return "n" if no such integer division can be found.2507 * Return isl_size_error on error.2508 *2509 * In particular, look for an integer division that appears in "aff"2510 * with a coefficient that is a multiple of the denominator2511 * of the integer division.2512 * That is, check if the numerator of "aff" is of the form2513 *2514 *	f(...) + a m floor(g/m)2515 *2516 * and return the position of "floor(g/m)".2517 *2518 * Note that, unlike print_as_modulo_pos, no check needs to be made2519 * for whether the integer division can be printed, since it will2520 * need to be printed as an integer division anyway if it is not printed2521 * as a modulo.2522 */2523static isl_size last_modulo(__isl_keep isl_printer *p, __isl_keep isl_aff *aff,2524	unsigned n)2525{2526	isl_size o_div;2527	int i;2528 2529	if (n == 0)2530		return n;2531	o_div = isl_aff_domain_offset(aff, isl_dim_div);2532	if (o_div < 0)2533		return isl_size_error;2534	for (i = n - 1; i >= 0; --i) {2535		if (isl_int_is_zero(aff->v->el[1 + o_div + i]))2536			continue;2537		if (isl_int_is_divisible_by(aff->v->el[1 + o_div + i],2538					    aff->ls->div->row[i][0]))2539			return i;2540	}2541 2542	return n;2543}2544 2545/* Print the numerator of the affine expression "aff" to "p",2546 * with the variable names taken from "space".2547 */2548static __isl_give isl_printer *print_aff_num_base(__isl_take isl_printer *p,2549	__isl_keep isl_space *space, __isl_keep isl_aff *aff)2550{2551	isl_size total;2552 2553	total = isl_aff_domain_dim(aff, isl_dim_all);2554	if (total < 0)2555		return isl_printer_free(p);2556	p = print_affine_of_len(space, aff->ls->div, p,2557				aff->v->el + 1, 1 + total);2558 2559	return p;2560}2561 2562static __isl_give isl_printer *print_aff_num(__isl_take isl_printer *p,2563	__isl_keep isl_space *space, __isl_keep isl_aff *aff);2564 2565/* Print the modulo term "c" * ("aff" mod "mod") to "p",2566 * with the variable names taken from "space".2567 * If "first" is set, then this is the first term of an expression.2568 */2569static __isl_give isl_printer *print_mod_term(__isl_take isl_printer *p,2570	__isl_keep isl_space *space, __isl_keep isl_aff *aff, int first,2571	__isl_take isl_val *c, __isl_keep isl_val *mod)2572{2573	isl_bool is_one, is_neg;2574 2575	is_neg = isl_val_is_neg(c);2576	if (is_neg < 0)2577		p = isl_printer_free(p);2578	if (!first) {2579		if (is_neg)2580			c = isl_val_neg(c);2581		p = isl_printer_print_str(p, is_neg ? " - " : " + ");2582	}2583	is_one = isl_val_is_one(c);2584	if (is_one < 0)2585		p = isl_printer_free(p);2586	if (!is_one) {2587		p = isl_printer_print_val(p, c);2588		p = isl_printer_print_str(p, "*(");2589	}2590	p = isl_printer_print_str(p, "(");2591	p = print_aff_num(p, space, aff);2592	p = isl_printer_print_str(p, ")");2593	p = isl_printer_print_str(p, " mod ");2594	p = isl_printer_print_val(p, mod);2595	if (!is_one)2596		p = isl_printer_print_str(p, ")");2597 2598	isl_val_free(c);2599 2600	return p;2601}2602 2603/* Print the numerator of the affine expression "aff" to "p",2604 * with the variable names taken from "space",2605 * given that the numerator of "aff" is of the form2606 *2607 *	f(...) + a m floor(g/m)2608 *2609 * with "floor(g/m)" the integer division at position "last".2610 *2611 * First replace "aff" by its numerator and rewrite it as2612 *2613 *	f(...) + a g - a (g mod m)2614 *2615 * Recursively write out (the numerator of) "f(...) + a g"2616 * (which may involve other modulo expressions) and2617 * then write out "- a (g mod m)".2618 */2619static __isl_give isl_printer *print_aff_num_mod(__isl_take isl_printer *p,2620	__isl_keep isl_space *space, __isl_keep isl_aff *aff, unsigned last)2621{2622	isl_bool is_zero;2623	isl_val *a, *m;2624	isl_aff *div, *term;2625 2626	aff = isl_aff_copy(aff);2627	aff = isl_aff_scale_val(aff, isl_aff_get_denominator_val(aff));2628	a = isl_aff_get_coefficient_val(aff, isl_dim_div, last);2629	aff = isl_aff_set_coefficient_si(aff, isl_dim_div, last, 0);2630	div = isl_aff_get_div(aff, last);2631	m = isl_aff_get_denominator_val(div);2632	a = isl_val_div(a, isl_val_copy(m));2633	div = isl_aff_scale_val(div, isl_val_copy(m));2634	term = isl_aff_scale_val(isl_aff_copy(div), isl_val_copy(a));2635	aff = isl_aff_add(aff, term);2636 2637	is_zero = isl_aff_plain_is_zero(aff);2638	if (is_zero < 0) {2639		p = isl_printer_free(p);2640	} else {2641		if (!is_zero)2642			p = print_aff_num(p, space, aff);2643		a = isl_val_neg(a);2644		p = print_mod_term(p, space, div, is_zero, isl_val_copy(a), m);2645	}2646 2647	isl_val_free(a);2648	isl_val_free(m);2649	isl_aff_free(aff);2650	isl_aff_free(div);2651 2652	return p;2653}2654 2655/* Print the numerator of the affine expression "aff" to "p",2656 * with the variable names taken from "space",2657 * separating out any (obvious) modulo expressions.2658 *2659 * In particular, look for modulo expressions in "aff",2660 * separating them out if found and simply printing out "aff" otherwise.2661 */2662static __isl_give isl_printer *print_aff_num(__isl_take isl_printer *p,2663	__isl_keep isl_space *space, __isl_keep isl_aff *aff)2664{2665	isl_size n_div, mod;2666 2667	n_div = isl_aff_dim(aff, isl_dim_div);2668	if (n_div < 0)2669		return isl_printer_free(p);2670	mod = last_modulo(p, aff, n_div);2671	if (mod < 0)2672		return isl_printer_free(p);2673	if (mod < n_div)2674		return print_aff_num_mod(p, space, aff, mod);2675	else2676		return print_aff_num_base(p, space, aff);2677}2678 2679/* Print the (potentially rational) affine expression "aff" to "p",2680 * with the variable names taken from "space".2681 */2682static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,2683	__isl_keep isl_space *space, __isl_keep isl_aff *aff)2684{2685	if (isl_aff_is_nan(aff))2686		return isl_printer_print_str(p, "NaN");2687 2688	p = isl_printer_print_str(p, "(");2689	p = print_aff_num(p, space, aff);2690	if (isl_int_is_one(aff->v->el[0]))2691		p = isl_printer_print_str(p, ")");2692	else {2693		p = isl_printer_print_str(p, ")/");2694		p = isl_printer_print_isl_int(p, aff->v->el[0]);2695	}2696 2697	return p;2698}2699 2700static __isl_give isl_printer *print_body_aff(__isl_take isl_printer *p,2701	__isl_keep isl_aff *aff)2702{2703	struct isl_print_space_data data = { 0 };2704 2705	if (isl_space_is_params(aff->ls->dim))2706		;2707	else {2708		p = print_tuple(aff->ls->dim, p, isl_dim_set, &data);2709		p = isl_printer_print_str(p, " -> ");2710	}2711	p = isl_printer_print_str(p, "[");2712	p = print_aff_body(p, aff->ls->dim, aff);2713	p = isl_printer_print_str(p, "]");2714 2715	return p;2716}2717 2718static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,2719	__isl_keep isl_aff *aff)2720{2721	struct isl_print_space_data data = { 0 };2722 2723	if (!aff)2724		goto error;2725 2726	p = print_param_tuple(p, aff->ls->dim, &data);2727	p = isl_printer_print_str(p, "{ ");2728	p = print_body_aff(p, aff);2729	p = isl_printer_print_str(p, " }");2730	return p;2731error:2732	isl_printer_free(p);2733	return NULL;2734}2735 2736#undef BASE2737#define BASE	aff2738#include "isl_pw_print_templ.c"2739 2740static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,2741	__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)2742{2743	if (type == isl_dim_div) {2744		p = isl_printer_print_str(p, "floord(");2745		p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);2746		p = isl_printer_print_str(p, ", ");2747		p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);2748		p = isl_printer_print_str(p, ")");2749	} else {2750		const char *name;2751 2752		name = isl_space_get_dim_name(ls->dim, type, pos);2753		if (!name)2754			name = "UNNAMED";2755		p = isl_printer_print_str(p, name);2756	}2757	return p;2758}2759 2760static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,2761	__isl_keep isl_local_space *ls, isl_int c, unsigned pos)2762{2763	enum isl_dim_type type;2764 2765	if (!p || !ls)2766		return isl_printer_free(p);2767 2768	if (pos == 0)2769		return isl_printer_print_isl_int(p, c);2770 2771	if (isl_int_is_one(c))2772		;2773	else if (isl_int_is_negone(c))2774		p = isl_printer_print_str(p, "-");2775	else {2776		p = isl_printer_print_isl_int(p, c);2777		p = isl_printer_print_str(p, "*");2778	}2779	if (pos2type(ls->dim, &type, &pos) < 0)2780		return isl_printer_free(p);2781	p = print_ls_name_c(p, ls, type, pos);2782	return p;2783}2784 2785static __isl_give isl_printer *print_ls_partial_affine_c(2786	__isl_take isl_printer *p, __isl_keep isl_local_space *ls,2787	isl_int *c, unsigned len)2788{2789	int i;2790	int first;2791 2792	for (i = 0, first = 1; i < len; ++i) {2793		int flip = 0;2794		if (isl_int_is_zero(c[i]))2795			continue;2796		if (!first) {2797			if (isl_int_is_neg(c[i])) {2798				flip = 1;2799				isl_int_neg(c[i], c[i]);2800				p = isl_printer_print_str(p, " - ");2801			} else 2802				p = isl_printer_print_str(p, " + ");2803		}2804		first = 0;2805		p = print_ls_term_c(p, ls, c[i], i);2806		if (flip)2807			isl_int_neg(c[i], c[i]);2808	}2809	if (first)2810		p = isl_printer_print_str(p, "0");2811	return p;2812}2813 2814static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,2815	__isl_keep isl_local_space *ls, isl_int *c)2816{2817	isl_size total = isl_local_space_dim(ls, isl_dim_all);2818 2819	if (total < 0)2820		return isl_printer_free(p);2821	return print_ls_partial_affine_c(p, ls, c, 1 + total);2822}2823 2824static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,2825	__isl_keep isl_aff *aff)2826{2827	isl_size total;2828 2829	total = isl_aff_domain_dim(aff, isl_dim_all);2830	if (total < 0)2831		return isl_printer_free(p);2832	if (!isl_int_is_one(aff->v->el[0]))2833		p = isl_printer_print_str(p, "(");2834	p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);2835	if (!isl_int_is_one(aff->v->el[0])) {2836		p = isl_printer_print_str(p, ")/");2837		p = isl_printer_print_isl_int(p, aff->v->el[0]);2838	}2839	return p;2840}2841 2842/* In the C format, we cannot express that "pwaff" may be undefined2843 * on parts of the domain space.  We therefore assume that the expression2844 * will only be evaluated on its definition domain and compute the gist2845 * of each cell with respect to this domain.2846 */2847static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,2848	__isl_keep isl_pw_aff *pwaff)2849{2850	isl_set *domain;2851	isl_ast_build *build;2852	isl_ast_expr *expr;2853 2854	if (pwaff->n < 1)2855		isl_die(p->ctx, isl_error_unsupported,2856			"cannot print empty isl_pw_aff in C format",2857			return isl_printer_free(p));2858 2859	domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));2860	build = isl_ast_build_from_context(domain);2861	expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff));2862	p = isl_printer_print_ast_expr(p, expr);2863	isl_ast_expr_free(expr);2864	isl_ast_build_free(build);2865 2866	return p;2867}2868 2869__isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,2870	__isl_keep isl_aff *aff)2871{2872	if (!p || !aff)2873		goto error;2874 2875	if (p->output_format == ISL_FORMAT_ISL)2876		return print_aff_isl(p, aff);2877	else if (p->output_format == ISL_FORMAT_C)2878		return print_aff_c(p, aff);2879	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",2880		goto error);2881error:2882	isl_printer_free(p);2883	return NULL;2884}2885 2886__isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,2887	__isl_keep isl_pw_aff *pwaff)2888{2889	if (!p || !pwaff)2890		goto error;2891 2892	if (p->output_format == ISL_FORMAT_ISL)2893		return print_pw_aff_isl(p, pwaff);2894	else if (p->output_format == ISL_FORMAT_C)2895		return print_pw_aff_c(p, pwaff);2896	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",2897		goto error);2898error:2899	isl_printer_free(p);2900	return NULL;2901}2902 2903#undef BASE2904#define BASE	pw_aff2905#include "isl_union_print_templ.c"2906 2907/* Print the isl_union_pw_aff "upa" to "p".2908 *2909 * We currently only support an isl format.2910 */2911__isl_give isl_printer *isl_printer_print_union_pw_aff(2912	__isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)2913{2914	if (!p || !upa)2915		return isl_printer_free(p);2916 2917	if (p->output_format == ISL_FORMAT_ISL)2918		return print_union_pw_aff_isl(p, upa);2919	isl_die(isl_printer_get_ctx(p), isl_error_unsupported,2920		"unsupported output format", return isl_printer_free(p));2921}2922 2923/* Print dimension "pos" of data->space to "p".2924 *2925 * data->user is assumed to be an isl_multi_aff.2926 *2927 * If the current dimension is an output dimension, then print2928 * the corresponding expression.  Otherwise, print the name of the dimension.2929 * Make sure to use the domain space for printing names as2930 * that is the space that will be used for printing constraints (if any).2931 */2932static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p,2933	struct isl_print_space_data *data, unsigned pos)2934{2935	isl_multi_aff *ma = data->user;2936	isl_space *space;2937 2938	space = isl_multi_aff_get_domain_space(ma);2939	if (data->type == isl_dim_out) {2940		p = print_aff_body(p, space, ma->u.p[pos]);2941	} else {2942		enum isl_dim_type type = data->type;2943 2944		if (type == isl_dim_in)2945			type = isl_dim_set;2946		p = print_name(space, p, type, pos, data->latex);2947	}2948	isl_space_free(space);2949 2950	return p;2951}2952 2953static __isl_give isl_printer *print_body_multi_aff(__isl_take isl_printer *p,2954	__isl_keep isl_multi_aff *maff)2955{2956	struct isl_print_space_data data = { 0 };2957 2958	data.print_dim = &print_dim_ma;2959	data.user = maff;2960	return isl_print_space(maff->space, p, 0, &data);2961}2962 2963static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,2964	__isl_keep isl_multi_aff *maff)2965{2966	struct isl_print_space_data data = { 0 };2967 2968	if (!maff)2969		goto error;2970 2971	p = print_param_tuple(p, maff->space, &data);2972	p = isl_printer_print_str(p, "{ ");2973	p = print_body_multi_aff(p, maff);2974	p = isl_printer_print_str(p, " }");2975	return p;2976error:2977	isl_printer_free(p);2978	return NULL;2979}2980 2981__isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,2982	__isl_keep isl_multi_aff *maff)2983{2984	if (!p || !maff)2985		goto error;2986 2987	if (p->output_format == ISL_FORMAT_ISL)2988		return print_multi_aff_isl(p, maff);2989	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",2990		goto error);2991error:2992	isl_printer_free(p);2993	return NULL;2994}2995 2996#undef BASE2997#define BASE	multi_aff2998#include "isl_pw_print_templ.c"2999 3000/* Print the unnamed, single-dimensional piecewise multi affine expression "pma"3001 * to "p".3002 */3003static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(3004	__isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)3005{3006	int i;3007	isl_space *space;3008 3009	space = isl_pw_multi_aff_get_domain_space(pma);3010	for (i = 0; i < pma->n - 1; ++i) {3011		p = isl_printer_print_str(p, "(");3012		p = print_set_c(p, space, pma->p[i].set);3013		p = isl_printer_print_str(p, ") ? (");3014		p = print_aff_c(p, pma->p[i].maff->u.p[0]);3015		p = isl_printer_print_str(p, ") : ");3016	}3017	isl_space_free(space);3018 3019	return print_aff_c(p, pma->p[pma->n - 1].maff->u.p[0]);3020}3021 3022static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,3023	__isl_keep isl_pw_multi_aff *pma)3024{3025	isl_size n;3026	const char *name;3027 3028	if (!pma)3029		goto error;3030	if (pma->n < 1)3031		isl_die(p->ctx, isl_error_unsupported,3032			"cannot print empty isl_pw_multi_aff in C format",3033			goto error);3034	n = isl_pw_multi_aff_dim(pma, isl_dim_out);3035	if (n < 0)3036		return isl_printer_free(p);3037	name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);3038	if (!name && n == 1)3039		return print_unnamed_pw_multi_aff_c(p, pma);3040	if (!name)3041		isl_die(p->ctx, isl_error_unsupported,3042			"cannot print unnamed isl_pw_multi_aff in C format",3043			goto error);3044 3045	p = isl_printer_print_str(p, name);3046	if (n != 0)3047		isl_die(p->ctx, isl_error_unsupported,3048			"not supported yet", goto error);3049 3050	return p;3051error:3052	isl_printer_free(p);3053	return NULL;3054}3055 3056__isl_give isl_printer *isl_printer_print_pw_multi_aff(3057	__isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)3058{3059	if (!p || !pma)3060		goto error;3061 3062	if (p->output_format == ISL_FORMAT_ISL)3063		return print_pw_multi_aff_isl(p, pma);3064	if (p->output_format == ISL_FORMAT_C)3065		return print_pw_multi_aff_c(p, pma);3066	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",3067		goto error);3068error:3069	isl_printer_free(p);3070	return NULL;3071}3072 3073#undef BASE3074#define BASE	pw_multi_aff3075#include "isl_union_print_templ.c"3076 3077__isl_give isl_printer *isl_printer_print_union_pw_multi_aff(3078	__isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)3079{3080	if (!p || !upma)3081		goto error;3082 3083	if (p->output_format == ISL_FORMAT_ISL)3084		return print_union_pw_multi_aff_isl(p, upma);3085	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",3086		goto error);3087error:3088	isl_printer_free(p);3089	return NULL;3090}3091 3092/* Print dimension "pos" of data->space to "p".3093 *3094 * data->user is assumed to be an isl_multi_pw_aff.3095 *3096 * If the current dimension is an output dimension, then print3097 * the corresponding piecewise affine expression.3098 * Otherwise, print the name of the dimension.3099 * Make sure to use the same space in both cases.3100 * In particular, use the domain space for printing names as3101 * that is the space that is used for printing constraints.3102 */3103static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,3104	struct isl_print_space_data *data, unsigned pos)3105{3106	int i;3107	int need_parens;3108	isl_space *space;3109	isl_multi_pw_aff *mpa = data->user;3110	isl_pw_aff *pa;3111 3112	if (data->type != isl_dim_out) {3113		enum isl_dim_type type = data->type;3114 3115		if (type == isl_dim_in)3116			type = isl_dim_set;3117		space = isl_multi_pw_aff_get_domain_space(mpa);3118		p = print_name(space, p, type, pos, data->latex);3119		isl_space_free(space);3120		return p;3121	}3122 3123	pa = mpa->u.p[pos];3124	if (pa->n == 0)3125		return isl_printer_print_str(p, "(0 : false)");3126 3127	need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set);3128	if (need_parens)3129		p = isl_printer_print_str(p, "(");3130	space = isl_multi_pw_aff_get_domain_space(mpa);3131	for (i = 0; i < pa->n; ++i) {3132 3133		if (i)3134			p = isl_printer_print_str(p, "; ");3135		p = print_aff_body(p, space, pa->p[i].aff);3136		p = print_disjuncts(pa->p[i].set, space, p, 0);3137	}3138	isl_space_free(space);3139	if (need_parens)3140		p = isl_printer_print_str(p, ")");3141 3142	return p;3143}3144 3145/* Print "mpa" to "p" in isl format.3146 *3147 * If "mpa" is zero-dimensional and has a non-trivial explicit domain,3148 * then it is printed after the tuple of affine expressions.3149 */3150static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,3151	__isl_keep isl_multi_pw_aff *mpa)3152{3153	struct isl_print_space_data data = { 0 };3154	isl_bool has_domain;3155 3156	if (!mpa)3157		return isl_printer_free(p);3158 3159	p = print_param_tuple(p, mpa->space, &data);3160	p = isl_printer_print_str(p, "{ ");3161	data.print_dim = &print_dim_mpa;3162	data.user = mpa;3163	p = isl_print_space(mpa->space, p, 0, &data);3164	has_domain = isl_multi_pw_aff_has_non_trivial_domain(mpa);3165	if (has_domain < 0)3166		return isl_printer_free(p);3167	if (has_domain) {3168		isl_space *space;3169 3170		space = isl_space_domain(isl_space_copy(mpa->space));3171		p = print_disjuncts_set(mpa->u.dom, space, p, 0);3172		isl_space_free(space);3173	}3174	p = isl_printer_print_str(p, " }");3175	return p;3176}3177 3178__isl_give isl_printer *isl_printer_print_multi_pw_aff(3179	__isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)3180{3181	if (!p || !mpa)3182		return isl_printer_free(p);3183 3184	if (p->output_format == ISL_FORMAT_ISL)3185		return print_multi_pw_aff_isl(p, mpa);3186	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",3187		return isl_printer_free(p));3188}3189 3190/* Print dimension "pos" of data->space to "p".3191 *3192 * data->user is assumed to be an isl_multi_val.3193 *3194 * If the current dimension is an output dimension, then print3195 * the corresponding value.  Otherwise, print the name of the dimension.3196 */3197static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p,3198	struct isl_print_space_data *data, unsigned pos)3199{3200	isl_multi_val *mv = data->user;3201 3202	if (data->type == isl_dim_out)3203		return isl_printer_print_val(p, mv->u.p[pos]);3204	else3205		return print_name(data->space, p, data->type, pos, data->latex);3206}3207 3208/* Print the isl_multi_val "mv" to "p" in isl format.3209 */3210static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p,3211	__isl_keep isl_multi_val *mv)3212{3213	struct isl_print_space_data data = { 0 };3214 3215	if (!mv)3216		return isl_printer_free(p);3217 3218	p = print_param_tuple(p, mv->space, &data);3219	p = isl_printer_print_str(p, "{ ");3220	data.print_dim = &print_dim_mv;3221	data.user = mv;3222	p = isl_print_space(mv->space, p, 0, &data);3223	p = isl_printer_print_str(p, " }");3224	return p;3225}3226 3227/* Print the isl_multi_val "mv" to "p".3228 *3229 * Currently only supported in isl format.3230 */3231__isl_give isl_printer *isl_printer_print_multi_val(3232	__isl_take isl_printer *p, __isl_keep isl_multi_val *mv)3233{3234	if (!p || !mv)3235		return isl_printer_free(p);3236 3237	if (p->output_format == ISL_FORMAT_ISL)3238		return print_multi_val_isl(p, mv);3239	isl_die(p->ctx, isl_error_unsupported, "unsupported output format",3240		return isl_printer_free(p));3241}3242 3243/* Print dimension "pos" of data->space to "p".3244 *3245 * data->user is assumed to be an isl_multi_id.3246 *3247 * If the current dimension is an output dimension, then print3248 * the corresponding identifier.  Otherwise, print the name of the dimension.3249 */3250static __isl_give isl_printer *print_dim_mi(__isl_take isl_printer *p,3251	struct isl_print_space_data *data, unsigned pos)3252{3253	isl_multi_id *mi = data->user;3254 3255	if (data->type == isl_dim_out)3256		return isl_printer_print_id(p, mi->u.p[pos]);3257	else3258		return print_name(data->space, p, data->type, pos, data->latex);3259}3260 3261/* Print the isl_multi_id "mi" to "p" in isl format.3262 */3263static __isl_give isl_printer *print_multi_id_isl(__isl_take isl_printer *p,3264	__isl_keep isl_multi_id *mi)3265{3266	isl_space *space;3267	struct isl_print_space_data data = { 0 };3268 3269	space = isl_multi_id_peek_space(mi);3270	p = print_param_tuple(p, space, &data);3271	p = isl_printer_print_str(p, "{ ");3272	data.print_dim = &print_dim_mi;3273	data.user = mi;3274	p = isl_print_space(space, p, 0, &data);3275	p = isl_printer_print_str(p, " }");3276	return p;3277}3278 3279/* Print the isl_multi_id "mi" to "p".3280 *3281 * Currently only supported in isl format.3282 */3283__isl_give isl_printer *isl_printer_print_multi_id(3284	__isl_take isl_printer *p, __isl_keep isl_multi_id *mi)3285{3286	if (!p || !mi)3287		return isl_printer_free(p);3288 3289	if (p->output_format == ISL_FORMAT_ISL)3290		return print_multi_id_isl(p, mi);3291	isl_die(isl_printer_get_ctx(p), isl_error_unsupported,3292		"unsupported output format", return isl_printer_free(p));3293}3294 3295/* Print dimension "pos" of data->space to "p".3296 *3297 * data->user is assumed to be an isl_multi_union_pw_aff.3298 *3299 * The current dimension is necessarily a set dimension, so3300 * we print the corresponding isl_union_pw_aff, including3301 * the braces.3302 */3303static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p,3304	struct isl_print_space_data *data, unsigned pos)3305{3306	isl_multi_union_pw_aff *mupa = data->user;3307	isl_union_pw_aff *upa;3308 3309	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos);3310	p = print_body_union_pw_aff(p, upa);3311	isl_union_pw_aff_free(upa);3312 3313	return p;3314}3315 3316/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.3317 *3318 * If "mupa" is zero-dimensional and has a non-trivial explicit domain,3319 * then it is printed after the tuple of affine expressions.3320 * In order to clarify that this domain belongs to the expression,3321 * the tuple along with the domain are placed inside parentheses.3322 * If "mupa" has any parameters, then the opening parenthesis3323 * appears after the parameter declarations.3324 */3325static __isl_give isl_printer *print_multi_union_pw_aff_isl(3326	__isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)3327{3328	struct isl_print_space_data data = { 0 };3329	isl_bool has_domain;3330	isl_space *space;3331 3332	if (!mupa)3333		return isl_printer_free(p);3334	has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa);3335	if (has_domain < 0)3336		return isl_printer_free(p);3337 3338	space = isl_multi_union_pw_aff_get_space(mupa);3339	p = print_param_tuple(p, space, &data);3340 3341	if (has_domain)3342		p = isl_printer_print_str(p, "(");3343 3344	data.print_dim = &print_union_pw_aff_dim;3345	data.user = mupa;3346 3347	p = isl_print_space(space, p, 0, &data);3348	isl_space_free(space);3349 3350	if (has_domain) {3351		p = isl_printer_print_str(p, " : ");3352		p = isl_printer_print_union_set_isl_body(p, mupa->u.dom);3353		p = isl_printer_print_str(p, ")");3354	}3355 3356	return p;3357}3358 3359/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.3360 *3361 * We currently only support an isl format.3362 */3363__isl_give isl_printer *isl_printer_print_multi_union_pw_aff(3364	__isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)3365{3366	if (!p || !mupa)3367		return isl_printer_free(p);3368 3369	if (p->output_format == ISL_FORMAT_ISL)3370		return print_multi_union_pw_aff_isl(p, mupa);3371	isl_die(isl_printer_get_ctx(p), isl_error_unsupported,3372		"unsupported output format", return isl_printer_free(p));3373}3374