Home | History | Annotate | Line # | Download | only in dist
      1  1.1  mrg /*
      2  1.1  mrg  * Copyright 2008-2009 Katholieke Universiteit Leuven
      3  1.1  mrg  * Copyright 2010      INRIA Saclay
      4  1.1  mrg  * Copyright 2012-2013 Ecole Normale Superieure
      5  1.1  mrg  * Copyright 2019,2022 Cerebras Systems
      6  1.1  mrg  *
      7  1.1  mrg  * Use of this software is governed by the MIT license
      8  1.1  mrg  *
      9  1.1  mrg  * Written by Sven Verdoolaege, K.U.Leuven, Departement
     10  1.1  mrg  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
     11  1.1  mrg  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
     12  1.1  mrg  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
     13  1.1  mrg  * and Ecole Normale Superieure, 45 rue dUlm, 75230 Paris, France
     14  1.1  mrg  * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
     15  1.1  mrg  */
     16  1.1  mrg 
     17  1.1  mrg #include <ctype.h>
     18  1.1  mrg #include <stdio.h>
     19  1.1  mrg #include <string.h>
     20  1.1  mrg #include <isl_ctx_private.h>
     21  1.1  mrg #include <isl_map_private.h>
     22  1.1  mrg #include <isl_id_private.h>
     23  1.1  mrg #include <isl/set.h>
     24  1.1  mrg #include <isl_seq.h>
     25  1.1  mrg #include <isl_stream_private.h>
     26  1.1  mrg #include <isl/obj.h>
     27  1.1  mrg #include "isl_polynomial_private.h"
     28  1.1  mrg #include <isl/union_set.h>
     29  1.1  mrg #include <isl/union_map.h>
     30  1.1  mrg #include <isl_mat_private.h>
     31  1.1  mrg #include <isl_aff_private.h>
     32  1.1  mrg #include <isl_vec_private.h>
     33  1.1  mrg #include <isl/list.h>
     34  1.1  mrg #include <isl_val_private.h>
     35  1.1  mrg 
     36  1.1  mrg struct variable {
     37  1.1  mrg 	char    	    	*name;
     38  1.1  mrg 	int	     		 pos;
     39  1.1  mrg 	struct variable		*next;
     40  1.1  mrg };
     41  1.1  mrg 
     42  1.1  mrg struct vars {
     43  1.1  mrg 	struct isl_ctx	*ctx;
     44  1.1  mrg 	int		 n;
     45  1.1  mrg 	struct variable	*v;
     46  1.1  mrg };
     47  1.1  mrg 
     48  1.1  mrg static struct vars *vars_new(struct isl_ctx *ctx)
     49  1.1  mrg {
     50  1.1  mrg 	struct vars *v;
     51  1.1  mrg 	v = isl_alloc_type(ctx, struct vars);
     52  1.1  mrg 	if (!v)
     53  1.1  mrg 		return NULL;
     54  1.1  mrg 	v->ctx = ctx;
     55  1.1  mrg 	v->n = 0;
     56  1.1  mrg 	v->v = NULL;
     57  1.1  mrg 	return v;
     58  1.1  mrg }
     59  1.1  mrg 
     60  1.1  mrg static void variable_free(struct variable *var)
     61  1.1  mrg {
     62  1.1  mrg 	while (var) {
     63  1.1  mrg 		struct variable *next = var->next;
     64  1.1  mrg 		free(var->name);
     65  1.1  mrg 		free(var);
     66  1.1  mrg 		var = next;
     67  1.1  mrg 	}
     68  1.1  mrg }
     69  1.1  mrg 
     70  1.1  mrg static void vars_free(struct vars *v)
     71  1.1  mrg {
     72  1.1  mrg 	if (!v)
     73  1.1  mrg 		return;
     74  1.1  mrg 	variable_free(v->v);
     75  1.1  mrg 	free(v);
     76  1.1  mrg }
     77  1.1  mrg 
     78  1.1  mrg static void vars_drop(struct vars *v, int n)
     79  1.1  mrg {
     80  1.1  mrg 	struct variable *var;
     81  1.1  mrg 
     82  1.1  mrg 	if (!v || !v->v)
     83  1.1  mrg 		return;
     84  1.1  mrg 
     85  1.1  mrg 	v->n -= n;
     86  1.1  mrg 
     87  1.1  mrg 	var = v->v;
     88  1.1  mrg 	while (--n >= 0) {
     89  1.1  mrg 		struct variable *next = var->next;
     90  1.1  mrg 		free(var->name);
     91  1.1  mrg 		free(var);
     92  1.1  mrg 		var = next;
     93  1.1  mrg 	}
     94  1.1  mrg 	v->v = var;
     95  1.1  mrg }
     96  1.1  mrg 
     97  1.1  mrg static struct variable *variable_new(struct vars *v, const char *name, int len,
     98  1.1  mrg 				int pos)
     99  1.1  mrg {
    100  1.1  mrg 	struct variable *var;
    101  1.1  mrg 	var = isl_calloc_type(v->ctx, struct variable);
    102  1.1  mrg 	if (!var)
    103  1.1  mrg 		goto error;
    104  1.1  mrg 	var->name = strdup(name);
    105  1.1  mrg 	var->name[len] = '\0';
    106  1.1  mrg 	var->pos = pos;
    107  1.1  mrg 	var->next = v->v;
    108  1.1  mrg 	return var;
    109  1.1  mrg error:
    110  1.1  mrg 	variable_free(v->v);
    111  1.1  mrg 	return NULL;
    112  1.1  mrg }
    113  1.1  mrg 
    114  1.1  mrg static int vars_pos(struct vars *v, const char *s, int len)
    115  1.1  mrg {
    116  1.1  mrg 	int pos;
    117  1.1  mrg 	struct variable *q;
    118  1.1  mrg 
    119  1.1  mrg 	if (len == -1)
    120  1.1  mrg 		len = strlen(s);
    121  1.1  mrg 	for (q = v->v; q; q = q->next) {
    122  1.1  mrg 		if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0')
    123  1.1  mrg 			break;
    124  1.1  mrg 	}
    125  1.1  mrg 	if (q)
    126  1.1  mrg 		pos = q->pos;
    127  1.1  mrg 	else {
    128  1.1  mrg 		pos = v->n;
    129  1.1  mrg 		v->v = variable_new(v, s, len, v->n);
    130  1.1  mrg 		if (!v->v)
    131  1.1  mrg 			return -1;
    132  1.1  mrg 		v->n++;
    133  1.1  mrg 	}
    134  1.1  mrg 	return pos;
    135  1.1  mrg }
    136  1.1  mrg 
    137  1.1  mrg static int vars_add_anon(struct vars *v)
    138  1.1  mrg {
    139  1.1  mrg 	v->v = variable_new(v, "", 0, v->n);
    140  1.1  mrg 
    141  1.1  mrg 	if (!v->v)
    142  1.1  mrg 		return -1;
    143  1.1  mrg 	v->n++;
    144  1.1  mrg 
    145  1.1  mrg 	return 0;
    146  1.1  mrg }
    147  1.1  mrg 
    148  1.1  mrg /* Obtain next token, with some preprocessing.
    149  1.1  mrg  * In particular, evaluate expressions of the form x^y,
    150  1.1  mrg  * with x and y values.
    151  1.1  mrg  */
    152  1.1  mrg static struct isl_token *next_token(__isl_keep isl_stream *s)
    153  1.1  mrg {
    154  1.1  mrg 	struct isl_token *tok, *tok2;
    155  1.1  mrg 
    156  1.1  mrg 	tok = isl_stream_next_token(s);
    157  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE)
    158  1.1  mrg 		return tok;
    159  1.1  mrg 	if (!isl_stream_eat_if_available(s, '^'))
    160  1.1  mrg 		return tok;
    161  1.1  mrg 	tok2 = isl_stream_next_token(s);
    162  1.1  mrg 	if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
    163  1.1  mrg 		isl_stream_error(s, tok2, "expecting constant value");
    164  1.1  mrg 		goto error;
    165  1.1  mrg 	}
    166  1.1  mrg 
    167  1.1  mrg 	isl_int_pow_ui(tok->u.v, tok->u.v, isl_int_get_ui(tok2->u.v));
    168  1.1  mrg 
    169  1.1  mrg 	isl_token_free(tok2);
    170  1.1  mrg 	return tok;
    171  1.1  mrg error:
    172  1.1  mrg 	isl_token_free(tok);
    173  1.1  mrg 	isl_token_free(tok2);
    174  1.1  mrg 	return NULL;
    175  1.1  mrg }
    176  1.1  mrg 
    177  1.1  mrg /* Read an isl_val from "s".
    178  1.1  mrg  *
    179  1.1  mrg  * The following token sequences are recognized
    180  1.1  mrg  *
    181  1.1  mrg  *	"infty"		->	infty
    182  1.1  mrg  *	"-" "infty"	->	-infty
    183  1.1  mrg  *	"NaN"		->	NaN
    184  1.1  mrg  *	n "/" d		->	n/d
    185  1.1  mrg  *	"-" n "/" d	->	-n/d
    186  1.1  mrg  *	v		->	v
    187  1.1  mrg  *	"-" v		->	-v
    188  1.1  mrg  *
    189  1.1  mrg  * where n, d and v are integer constants.
    190  1.1  mrg  */
    191  1.1  mrg __isl_give isl_val *isl_stream_read_val(__isl_keep isl_stream *s)
    192  1.1  mrg {
    193  1.1  mrg 	struct isl_token *tok = NULL;
    194  1.1  mrg 	struct isl_token *tok2 = NULL;
    195  1.1  mrg 	int sign = 1;
    196  1.1  mrg 	isl_val *val;
    197  1.1  mrg 
    198  1.1  mrg 	if (isl_stream_eat_if_available(s, '-'))
    199  1.1  mrg 		sign = -1;
    200  1.1  mrg 	tok = next_token(s);
    201  1.1  mrg 	if (!tok) {
    202  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
    203  1.1  mrg 		goto error;
    204  1.1  mrg 	}
    205  1.1  mrg 	if (tok->type == ISL_TOKEN_INFTY) {
    206  1.1  mrg 		isl_token_free(tok);
    207  1.1  mrg 		if (sign > 0)
    208  1.1  mrg 			return isl_val_infty(s->ctx);
    209  1.1  mrg 		else
    210  1.1  mrg 			return isl_val_neginfty(s->ctx);
    211  1.1  mrg 	}
    212  1.1  mrg 	if (sign > 0 && tok->type == ISL_TOKEN_NAN) {
    213  1.1  mrg 		isl_token_free(tok);
    214  1.1  mrg 		return isl_val_nan(s->ctx);
    215  1.1  mrg 	}
    216  1.1  mrg 	if (tok->type != ISL_TOKEN_VALUE) {
    217  1.1  mrg 		isl_stream_error(s, tok, "expecting value");
    218  1.1  mrg 		goto error;
    219  1.1  mrg 	}
    220  1.1  mrg 
    221  1.1  mrg 	if (sign < 0)
    222  1.1  mrg 		isl_int_neg(tok->u.v, tok->u.v);
    223  1.1  mrg 
    224  1.1  mrg 	if (isl_stream_eat_if_available(s, '/')) {
    225  1.1  mrg 		tok2 = next_token(s);
    226  1.1  mrg 		if (!tok2) {
    227  1.1  mrg 			isl_stream_error(s, NULL, "unexpected EOF");
    228  1.1  mrg 			goto error;
    229  1.1  mrg 		}
    230  1.1  mrg 		if (tok2->type != ISL_TOKEN_VALUE) {
    231  1.1  mrg 			isl_stream_error(s, tok2, "expecting value");
    232  1.1  mrg 			goto error;
    233  1.1  mrg 		}
    234  1.1  mrg 		val = isl_val_rat_from_isl_int(s->ctx, tok->u.v, tok2->u.v);
    235  1.1  mrg 		val = isl_val_normalize(val);
    236  1.1  mrg 	} else {
    237  1.1  mrg 		val = isl_val_int_from_isl_int(s->ctx, tok->u.v);
    238  1.1  mrg 	}
    239  1.1  mrg 
    240  1.1  mrg 	isl_token_free(tok);
    241  1.1  mrg 	isl_token_free(tok2);
    242  1.1  mrg 	return val;
    243  1.1  mrg error:
    244  1.1  mrg 	isl_token_free(tok);
    245  1.1  mrg 	isl_token_free(tok2);
    246  1.1  mrg 	return NULL;
    247  1.1  mrg }
    248  1.1  mrg 
    249  1.1  mrg #undef TYPE_BASE
    250  1.1  mrg #define TYPE_BASE	val
    251  1.1  mrg #include "isl_read_from_str_templ.c"
    252  1.1  mrg 
    253  1.1  mrg static isl_stat accept_cst_factor(__isl_keep isl_stream *s, isl_int *f)
    254  1.1  mrg {
    255  1.1  mrg 	struct isl_token *tok;
    256  1.1  mrg 
    257  1.1  mrg 	if (isl_stream_eat_if_available(s, '-'))
    258  1.1  mrg 		isl_int_neg(*f, *f);
    259  1.1  mrg 	tok = next_token(s);
    260  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
    261  1.1  mrg 		isl_stream_error(s, tok, "expecting constant value");
    262  1.1  mrg 		goto error;
    263  1.1  mrg 	}
    264  1.1  mrg 
    265  1.1  mrg 	isl_int_mul(*f, *f, tok->u.v);
    266  1.1  mrg 
    267  1.1  mrg 	isl_token_free(tok);
    268  1.1  mrg 
    269  1.1  mrg 	if (isl_stream_eat_if_available(s, '*'))
    270  1.1  mrg 		return accept_cst_factor(s, f);
    271  1.1  mrg 
    272  1.1  mrg 	return isl_stat_ok;
    273  1.1  mrg error:
    274  1.1  mrg 	isl_token_free(tok);
    275  1.1  mrg 	return isl_stat_error;
    276  1.1  mrg }
    277  1.1  mrg 
    278  1.1  mrg /* Given an affine expression aff, return an affine expression
    279  1.1  mrg  * for aff % d, with d the next token on the stream, which is
    280  1.1  mrg  * assumed to be a constant.
    281  1.1  mrg  *
    282  1.1  mrg  * We introduce an integer division q = [aff/d] and the result
    283  1.1  mrg  * is set to aff - d q.
    284  1.1  mrg  */
    285  1.1  mrg static __isl_give isl_pw_aff *affine_mod(__isl_keep isl_stream *s,
    286  1.1  mrg 	struct vars *v, __isl_take isl_pw_aff *aff)
    287  1.1  mrg {
    288  1.1  mrg 	struct isl_token *tok;
    289  1.1  mrg 	isl_pw_aff *q;
    290  1.1  mrg 
    291  1.1  mrg 	tok = next_token(s);
    292  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
    293  1.1  mrg 		isl_stream_error(s, tok, "expecting constant value");
    294  1.1  mrg 		goto error;
    295  1.1  mrg 	}
    296  1.1  mrg 
    297  1.1  mrg 	q = isl_pw_aff_copy(aff);
    298  1.1  mrg 	q = isl_pw_aff_scale_down(q, tok->u.v);
    299  1.1  mrg 	q = isl_pw_aff_floor(q);
    300  1.1  mrg 	q = isl_pw_aff_scale(q, tok->u.v);
    301  1.1  mrg 
    302  1.1  mrg 	aff = isl_pw_aff_sub(aff, q);
    303  1.1  mrg 
    304  1.1  mrg 	isl_token_free(tok);
    305  1.1  mrg 	return aff;
    306  1.1  mrg error:
    307  1.1  mrg 	isl_pw_aff_free(aff);
    308  1.1  mrg 	isl_token_free(tok);
    309  1.1  mrg 	return NULL;
    310  1.1  mrg }
    311  1.1  mrg 
    312  1.1  mrg static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s,
    313  1.1  mrg 	__isl_take isl_space *space, struct vars *v);
    314  1.1  mrg static __isl_give isl_pw_aff_list *accept_affine_list(__isl_keep isl_stream *s,
    315  1.1  mrg 	__isl_take isl_space *space, struct vars *v);
    316  1.1  mrg 
    317  1.1  mrg static __isl_give isl_pw_aff *accept_minmax(__isl_keep isl_stream *s,
    318  1.1  mrg 	__isl_take isl_space *space, struct vars *v)
    319  1.1  mrg {
    320  1.1  mrg 	struct isl_token *tok;
    321  1.1  mrg 	isl_pw_aff_list *list = NULL;
    322  1.1  mrg 	int min;
    323  1.1  mrg 
    324  1.1  mrg 	tok = isl_stream_next_token(s);
    325  1.1  mrg 	if (!tok)
    326  1.1  mrg 		goto error;
    327  1.1  mrg 	min = tok->type == ISL_TOKEN_MIN;
    328  1.1  mrg 	isl_token_free(tok);
    329  1.1  mrg 
    330  1.1  mrg 	if (isl_stream_eat(s, '('))
    331  1.1  mrg 		goto error;
    332  1.1  mrg 
    333  1.1  mrg 	list = accept_affine_list(s, isl_space_copy(space), v);
    334  1.1  mrg 	if (!list)
    335  1.1  mrg 		goto error;
    336  1.1  mrg 
    337  1.1  mrg 	if (isl_stream_eat(s, ')'))
    338  1.1  mrg 		goto error;
    339  1.1  mrg 
    340  1.1  mrg 	isl_space_free(space);
    341  1.1  mrg 	return min ? isl_pw_aff_list_min(list) : isl_pw_aff_list_max(list);
    342  1.1  mrg error:
    343  1.1  mrg 	isl_space_free(space);
    344  1.1  mrg 	isl_pw_aff_list_free(list);
    345  1.1  mrg 	return NULL;
    346  1.1  mrg }
    347  1.1  mrg 
    348  1.1  mrg /* Divide "pa" by an integer constant read from the stream.
    349  1.1  mrg  */
    350  1.1  mrg static __isl_give isl_pw_aff *pw_aff_div_by_cst(__isl_keep isl_stream *s,
    351  1.1  mrg 	__isl_take isl_pw_aff *pa)
    352  1.1  mrg {
    353  1.1  mrg 	struct isl_token *tok;
    354  1.1  mrg 
    355  1.1  mrg 	tok = next_token(s);
    356  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
    357  1.1  mrg 		isl_stream_error(s, tok, "expecting denominator");
    358  1.1  mrg 		isl_token_free(tok);
    359  1.1  mrg 		return isl_pw_aff_free(pa);
    360  1.1  mrg 	}
    361  1.1  mrg 
    362  1.1  mrg 	pa = isl_pw_aff_scale_down(pa,  tok->u.v);
    363  1.1  mrg 
    364  1.1  mrg 	isl_token_free(tok);
    365  1.1  mrg 
    366  1.1  mrg 	return pa;
    367  1.1  mrg }
    368  1.1  mrg 
    369  1.1  mrg /* Return the (signed) value that is next on the stream,
    370  1.1  mrg  * using "next" to read the next token and printing "msg" in case of an error.
    371  1.1  mrg  */
    372  1.1  mrg static struct isl_token *next_signed_value_fn(__isl_keep isl_stream *s,
    373  1.1  mrg 	struct isl_token *(*next)(__isl_keep isl_stream *s), char *msg)
    374  1.1  mrg {
    375  1.1  mrg 	struct isl_token *tok;
    376  1.1  mrg 	int sign = 1;
    377  1.1  mrg 
    378  1.1  mrg 	if (isl_stream_eat_if_available(s, '-'))
    379  1.1  mrg 		sign = -1;
    380  1.1  mrg 	tok = next(s);
    381  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
    382  1.1  mrg 		isl_stream_error(s, tok, msg);
    383  1.1  mrg 		isl_token_free(tok);
    384  1.1  mrg 		return NULL;
    385  1.1  mrg 	}
    386  1.1  mrg 	if (sign < 0)
    387  1.1  mrg 		isl_int_neg(tok->u.v, tok->u.v);
    388  1.1  mrg 	return tok;
    389  1.1  mrg }
    390  1.1  mrg 
    391  1.1  mrg /* Return the (signed) value that is next on the stream,
    392  1.1  mrg  * printing "msg" in case of an error.
    393  1.1  mrg  */
    394  1.1  mrg static struct isl_token *next_signed_value(__isl_keep isl_stream *s, char *msg)
    395  1.1  mrg {
    396  1.1  mrg 	return next_signed_value_fn(s, &isl_stream_next_token, msg);
    397  1.1  mrg }
    398  1.1  mrg 
    399  1.1  mrg /* Return the (signed) value that is next on the stream,
    400  1.1  mrg  * provided it is on the same line,
    401  1.1  mrg  * printing "msg" in case of an error.
    402  1.1  mrg  */
    403  1.1  mrg static struct isl_token *next_signed_value_on_same_line(
    404  1.1  mrg 	__isl_keep isl_stream *s, char *msg)
    405  1.1  mrg {
    406  1.1  mrg 	return next_signed_value_fn(s,
    407  1.1  mrg 				    &isl_stream_next_token_on_same_line, msg);
    408  1.1  mrg }
    409  1.1  mrg 
    410  1.1  mrg /* Is "tok" the start of an integer division?
    411  1.1  mrg  */
    412  1.1  mrg static int is_start_of_div(struct isl_token *tok)
    413  1.1  mrg {
    414  1.1  mrg 	if (!tok)
    415  1.1  mrg 		return 0;
    416  1.1  mrg 	if (tok->type == '[')
    417  1.1  mrg 		return 1;
    418  1.1  mrg 	if (tok->type == ISL_TOKEN_FLOOR)
    419  1.1  mrg 		return 1;
    420  1.1  mrg 	if (tok->type == ISL_TOKEN_CEIL)
    421  1.1  mrg 		return 1;
    422  1.1  mrg 	if (tok->type == ISL_TOKEN_FLOORD)
    423  1.1  mrg 		return 1;
    424  1.1  mrg 	if (tok->type == ISL_TOKEN_CEILD)
    425  1.1  mrg 		return 1;
    426  1.1  mrg 	return 0;
    427  1.1  mrg }
    428  1.1  mrg 
    429  1.1  mrg /* Read an integer division from "s" and return it as an isl_pw_aff.
    430  1.1  mrg  *
    431  1.1  mrg  * The integer division can be of the form
    432  1.1  mrg  *
    433  1.1  mrg  *	[<affine expression>]
    434  1.1  mrg  *	floor(<affine expression>)
    435  1.1  mrg  *	ceil(<affine expression>)
    436  1.1  mrg  *	floord(<affine expression>,<denominator>)
    437  1.1  mrg  *	ceild(<affine expression>,<denominator>)
    438  1.1  mrg  */
    439  1.1  mrg static __isl_give isl_pw_aff *accept_div(__isl_keep isl_stream *s,
    440  1.1  mrg 	__isl_take isl_space *space, struct vars *v)
    441  1.1  mrg {
    442  1.1  mrg 	int f = 0;
    443  1.1  mrg 	int c = 0;
    444  1.1  mrg 	int extra = 0;
    445  1.1  mrg 	isl_pw_aff *pwaff = NULL;
    446  1.1  mrg 
    447  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD))
    448  1.1  mrg 		extra = f = 1;
    449  1.1  mrg 	else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEILD))
    450  1.1  mrg 		extra = c = 1;
    451  1.1  mrg 	else if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOOR))
    452  1.1  mrg 		f = 1;
    453  1.1  mrg 	else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEIL))
    454  1.1  mrg 		c = 1;
    455  1.1  mrg 	if (f || c) {
    456  1.1  mrg 		if (isl_stream_eat(s, '('))
    457  1.1  mrg 			goto error;
    458  1.1  mrg 	} else {
    459  1.1  mrg 		if (isl_stream_eat(s, '['))
    460  1.1  mrg 			goto error;
    461  1.1  mrg 	}
    462  1.1  mrg 
    463  1.1  mrg 	pwaff = accept_affine(s, isl_space_copy(space), v);
    464  1.1  mrg 
    465  1.1  mrg 	if (extra) {
    466  1.1  mrg 		if (isl_stream_eat(s, ','))
    467  1.1  mrg 			goto error;
    468  1.1  mrg 
    469  1.1  mrg 		pwaff = pw_aff_div_by_cst(s, pwaff);
    470  1.1  mrg 	}
    471  1.1  mrg 
    472  1.1  mrg 	if (c)
    473  1.1  mrg 		pwaff = isl_pw_aff_ceil(pwaff);
    474  1.1  mrg 	else
    475  1.1  mrg 		pwaff = isl_pw_aff_floor(pwaff);
    476  1.1  mrg 
    477  1.1  mrg 	if (f || c) {
    478  1.1  mrg 		if (isl_stream_eat(s, ')'))
    479  1.1  mrg 			goto error;
    480  1.1  mrg 	} else {
    481  1.1  mrg 		if (isl_stream_eat(s, ']'))
    482  1.1  mrg 			goto error;
    483  1.1  mrg 	}
    484  1.1  mrg 
    485  1.1  mrg 	isl_space_free(space);
    486  1.1  mrg 	return pwaff;
    487  1.1  mrg error:
    488  1.1  mrg 	isl_space_free(space);
    489  1.1  mrg 	isl_pw_aff_free(pwaff);
    490  1.1  mrg 	return NULL;
    491  1.1  mrg }
    492  1.1  mrg 
    493  1.1  mrg static __isl_give isl_pw_aff *accept_affine_factor(__isl_keep isl_stream *s,
    494  1.1  mrg 	__isl_take isl_space *space, struct vars *v)
    495  1.1  mrg {
    496  1.1  mrg 	struct isl_token *tok = NULL;
    497  1.1  mrg 	isl_pw_aff *res = NULL;
    498  1.1  mrg 
    499  1.1  mrg 	tok = next_token(s);
    500  1.1  mrg 	if (!tok) {
    501  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
    502  1.1  mrg 		goto error;
    503  1.1  mrg 	}
    504  1.1  mrg 
    505  1.1  mrg 	if (tok->type == ISL_TOKEN_AFF) {
    506  1.1  mrg 		res = isl_pw_aff_copy(tok->u.pwaff);
    507  1.1  mrg 		isl_token_free(tok);
    508  1.1  mrg 	} else if (tok->type == ISL_TOKEN_IDENT) {
    509  1.1  mrg 		int n = v->n;
    510  1.1  mrg 		int pos = vars_pos(v, tok->u.s, -1);
    511  1.1  mrg 		isl_aff *aff;
    512  1.1  mrg 
    513  1.1  mrg 		if (pos < 0)
    514  1.1  mrg 			goto error;
    515  1.1  mrg 		if (pos >= n) {
    516  1.1  mrg 			vars_drop(v, v->n - n);
    517  1.1  mrg 			isl_stream_error(s, tok, "unknown identifier");
    518  1.1  mrg 			goto error;
    519  1.1  mrg 		}
    520  1.1  mrg 
    521  1.1  mrg 		aff = isl_aff_zero_on_domain(isl_local_space_from_space(isl_space_copy(space)));
    522  1.1  mrg 		if (!aff)
    523  1.1  mrg 			goto error;
    524  1.1  mrg 		aff->v = isl_vec_set_element_si(aff->v, 2 + pos, 1);
    525  1.1  mrg 		if (!aff->v)
    526  1.1  mrg 			aff = isl_aff_free(aff);
    527  1.1  mrg 		res = isl_pw_aff_from_aff(aff);
    528  1.1  mrg 		isl_token_free(tok);
    529  1.1  mrg 	} else if (tok->type == ISL_TOKEN_VALUE) {
    530  1.1  mrg 		if (isl_stream_eat_if_available(s, '*') ||
    531  1.1  mrg 		    isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
    532  1.1  mrg 			if (isl_stream_eat_if_available(s, '-'))
    533  1.1  mrg 				isl_int_neg(tok->u.v, tok->u.v);
    534  1.1  mrg 			res = accept_affine_factor(s, isl_space_copy(space), v);
    535  1.1  mrg 			res = isl_pw_aff_scale(res, tok->u.v);
    536  1.1  mrg 		} else {
    537  1.1  mrg 			isl_local_space *ls;
    538  1.1  mrg 			isl_aff *aff;
    539  1.1  mrg 			ls = isl_local_space_from_space(isl_space_copy(space));
    540  1.1  mrg 			aff = isl_aff_zero_on_domain(ls);
    541  1.1  mrg 			aff = isl_aff_add_constant(aff, tok->u.v);
    542  1.1  mrg 			res = isl_pw_aff_from_aff(aff);
    543  1.1  mrg 		}
    544  1.1  mrg 		isl_token_free(tok);
    545  1.1  mrg 	} else if (tok->type == '(') {
    546  1.1  mrg 		isl_token_free(tok);
    547  1.1  mrg 		tok = NULL;
    548  1.1  mrg 		res = accept_affine(s, isl_space_copy(space), v);
    549  1.1  mrg 		if (!res)
    550  1.1  mrg 			goto error;
    551  1.1  mrg 		if (isl_stream_eat(s, ')'))
    552  1.1  mrg 			goto error;
    553  1.1  mrg 	} else if (is_start_of_div(tok)) {
    554  1.1  mrg 		isl_stream_push_token(s, tok);
    555  1.1  mrg 		tok = NULL;
    556  1.1  mrg 		res = accept_div(s, isl_space_copy(space), v);
    557  1.1  mrg 	} else if (tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX) {
    558  1.1  mrg 		isl_stream_push_token(s, tok);
    559  1.1  mrg 		tok = NULL;
    560  1.1  mrg 		res = accept_minmax(s, isl_space_copy(space), v);
    561  1.1  mrg 	} else {
    562  1.1  mrg 		isl_stream_error(s, tok, "expecting factor");
    563  1.1  mrg 		goto error;
    564  1.1  mrg 	}
    565  1.1  mrg 	if (isl_stream_eat_if_available(s, '%') ||
    566  1.1  mrg 	    isl_stream_eat_if_available(s, ISL_TOKEN_MOD)) {
    567  1.1  mrg 		isl_space_free(space);
    568  1.1  mrg 		return affine_mod(s, v, res);
    569  1.1  mrg 	}
    570  1.1  mrg 	if (isl_stream_eat_if_available(s, '*')) {
    571  1.1  mrg 		isl_int f;
    572  1.1  mrg 		isl_int_init(f);
    573  1.1  mrg 		isl_int_set_si(f, 1);
    574  1.1  mrg 		if (accept_cst_factor(s, &f) < 0) {
    575  1.1  mrg 			isl_int_clear(f);
    576  1.1  mrg 			goto error2;
    577  1.1  mrg 		}
    578  1.1  mrg 		res = isl_pw_aff_scale(res, f);
    579  1.1  mrg 		isl_int_clear(f);
    580  1.1  mrg 	}
    581  1.1  mrg 	if (isl_stream_eat_if_available(s, '/'))
    582  1.1  mrg 		res = pw_aff_div_by_cst(s, res);
    583  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_INT_DIV))
    584  1.1  mrg 		res = isl_pw_aff_floor(pw_aff_div_by_cst(s, res));
    585  1.1  mrg 
    586  1.1  mrg 	isl_space_free(space);
    587  1.1  mrg 	return res;
    588  1.1  mrg error:
    589  1.1  mrg 	isl_token_free(tok);
    590  1.1  mrg error2:
    591  1.1  mrg 	isl_pw_aff_free(res);
    592  1.1  mrg 	isl_space_free(space);
    593  1.1  mrg 	return NULL;
    594  1.1  mrg }
    595  1.1  mrg 
    596  1.1  mrg /* Return a piecewise affine expression defined on the specified domain
    597  1.1  mrg  * that represents NaN.
    598  1.1  mrg  */
    599  1.1  mrg static __isl_give isl_pw_aff *nan_on_domain(__isl_keep isl_space *space)
    600  1.1  mrg {
    601  1.1  mrg 	return isl_pw_aff_nan_on_domain_space(isl_space_copy(space));
    602  1.1  mrg }
    603  1.1  mrg 
    604  1.1  mrg static __isl_give isl_pw_aff *accept_affine(__isl_keep isl_stream *s,
    605  1.1  mrg 	__isl_take isl_space *space, struct vars *v)
    606  1.1  mrg {
    607  1.1  mrg 	struct isl_token *tok = NULL;
    608  1.1  mrg 	isl_local_space *ls;
    609  1.1  mrg 	isl_pw_aff *res;
    610  1.1  mrg 	int op = 1;
    611  1.1  mrg 	int sign = 1;
    612  1.1  mrg 
    613  1.1  mrg 	ls = isl_local_space_from_space(isl_space_copy(space));
    614  1.1  mrg 	res = isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
    615  1.1  mrg 	if (!res)
    616  1.1  mrg 		goto error;
    617  1.1  mrg 
    618  1.1  mrg 	for (;;) {
    619  1.1  mrg 		tok = next_token(s);
    620  1.1  mrg 		if (!tok) {
    621  1.1  mrg 			isl_stream_error(s, NULL, "unexpected EOF");
    622  1.1  mrg 			goto error;
    623  1.1  mrg 		}
    624  1.1  mrg 		if (tok->type == '-') {
    625  1.1  mrg 			sign = -sign;
    626  1.1  mrg 			isl_token_free(tok);
    627  1.1  mrg 			continue;
    628  1.1  mrg 		}
    629  1.1  mrg 		if (tok->type == '(' || is_start_of_div(tok) ||
    630  1.1  mrg 		    tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX ||
    631  1.1  mrg 		    tok->type == ISL_TOKEN_IDENT ||
    632  1.1  mrg 		    tok->type == ISL_TOKEN_VALUE ||
    633  1.1  mrg 		    tok->type == ISL_TOKEN_AFF) {
    634  1.1  mrg 			isl_pw_aff *term;
    635  1.1  mrg 			if (tok->type == ISL_TOKEN_VALUE && sign < 0) {
    636  1.1  mrg 				isl_int_neg(tok->u.v, tok->u.v);
    637  1.1  mrg 				sign = 1;
    638  1.1  mrg 			}
    639  1.1  mrg 			isl_stream_push_token(s, tok);
    640  1.1  mrg 			tok = NULL;
    641  1.1  mrg 			term = accept_affine_factor(s,
    642  1.1  mrg 						    isl_space_copy(space), v);
    643  1.1  mrg 			if (op * sign < 0)
    644  1.1  mrg 				res = isl_pw_aff_sub(res, term);
    645  1.1  mrg 			else
    646  1.1  mrg 				res = isl_pw_aff_add(res, term);
    647  1.1  mrg 			if (!res)
    648  1.1  mrg 				goto error;
    649  1.1  mrg 		} else if (tok->type == ISL_TOKEN_NAN) {
    650  1.1  mrg 			res = isl_pw_aff_add(res, nan_on_domain(space));
    651  1.1  mrg 		} else {
    652  1.1  mrg 			isl_stream_error(s, tok, "unexpected isl_token");
    653  1.1  mrg 			isl_stream_push_token(s, tok);
    654  1.1  mrg 			isl_pw_aff_free(res);
    655  1.1  mrg 			isl_space_free(space);
    656  1.1  mrg 			return NULL;
    657  1.1  mrg 		}
    658  1.1  mrg 		isl_token_free(tok);
    659  1.1  mrg 
    660  1.1  mrg 		tok = next_token(s);
    661  1.1  mrg 		sign = 1;
    662  1.1  mrg 		if (tok && tok->type == '-') {
    663  1.1  mrg 			op = -1;
    664  1.1  mrg 			isl_token_free(tok);
    665  1.1  mrg 		} else if (tok && tok->type == '+') {
    666  1.1  mrg 			op = 1;
    667  1.1  mrg 			isl_token_free(tok);
    668  1.1  mrg 		} else {
    669  1.1  mrg 			if (tok)
    670  1.1  mrg 				isl_stream_push_token(s, tok);
    671  1.1  mrg 			break;
    672  1.1  mrg 		}
    673  1.1  mrg 	}
    674  1.1  mrg 
    675  1.1  mrg 	isl_space_free(space);
    676  1.1  mrg 	return res;
    677  1.1  mrg error:
    678  1.1  mrg 	isl_space_free(space);
    679  1.1  mrg 	isl_token_free(tok);
    680  1.1  mrg 	isl_pw_aff_free(res);
    681  1.1  mrg 	return NULL;
    682  1.1  mrg }
    683  1.1  mrg 
    684  1.1  mrg /* Is "type" the type of a comparison operator between lists
    685  1.1  mrg  * of affine expressions?
    686  1.1  mrg  */
    687  1.1  mrg static int is_list_comparator_type(int type)
    688  1.1  mrg {
    689  1.1  mrg 	switch (type) {
    690  1.1  mrg 	case ISL_TOKEN_LEX_LT:
    691  1.1  mrg 	case ISL_TOKEN_LEX_GT:
    692  1.1  mrg 	case ISL_TOKEN_LEX_LE:
    693  1.1  mrg 	case ISL_TOKEN_LEX_GE:
    694  1.1  mrg 		return 1;
    695  1.1  mrg 	default:
    696  1.1  mrg 		return 0;
    697  1.1  mrg 	}
    698  1.1  mrg }
    699  1.1  mrg 
    700  1.1  mrg static int is_comparator(struct isl_token *tok)
    701  1.1  mrg {
    702  1.1  mrg 	if (!tok)
    703  1.1  mrg 		return 0;
    704  1.1  mrg 	if (is_list_comparator_type(tok->type))
    705  1.1  mrg 		return 1;
    706  1.1  mrg 
    707  1.1  mrg 	switch (tok->type) {
    708  1.1  mrg 	case ISL_TOKEN_LT:
    709  1.1  mrg 	case ISL_TOKEN_GT:
    710  1.1  mrg 	case ISL_TOKEN_LE:
    711  1.1  mrg 	case ISL_TOKEN_GE:
    712  1.1  mrg 	case ISL_TOKEN_NE:
    713  1.1  mrg 	case '=':
    714  1.1  mrg 		return 1;
    715  1.1  mrg 	default:
    716  1.1  mrg 		return 0;
    717  1.1  mrg 	}
    718  1.1  mrg }
    719  1.1  mrg 
    720  1.1  mrg static __isl_give isl_map *read_formula(__isl_keep isl_stream *s,
    721  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational);
    722  1.1  mrg static __isl_give isl_pw_aff *accept_extended_affine(__isl_keep isl_stream *s,
    723  1.1  mrg 	__isl_take isl_space *space, struct vars *v, int rational);
    724  1.1  mrg 
    725  1.1  mrg /* Accept a ternary operator, given the first argument.
    726  1.1  mrg  */
    727  1.1  mrg static __isl_give isl_pw_aff *accept_ternary(__isl_keep isl_stream *s,
    728  1.1  mrg 	__isl_take isl_map *cond, struct vars *v, int rational)
    729  1.1  mrg {
    730  1.1  mrg 	isl_space *space;
    731  1.1  mrg 	isl_pw_aff *pwaff1 = NULL, *pwaff2 = NULL, *pa_cond;
    732  1.1  mrg 
    733  1.1  mrg 	if (!cond)
    734  1.1  mrg 		return NULL;
    735  1.1  mrg 
    736  1.1  mrg 	if (isl_stream_eat(s, '?'))
    737  1.1  mrg 		goto error;
    738  1.1  mrg 
    739  1.1  mrg 	space = isl_space_wrap(isl_map_get_space(cond));
    740  1.1  mrg 	pwaff1 = accept_extended_affine(s, space, v, rational);
    741  1.1  mrg 	if (!pwaff1)
    742  1.1  mrg 		goto error;
    743  1.1  mrg 
    744  1.1  mrg 	if (isl_stream_eat(s, ':'))
    745  1.1  mrg 		goto error;
    746  1.1  mrg 
    747  1.1  mrg 	space = isl_pw_aff_get_domain_space(pwaff1);
    748  1.1  mrg 	pwaff2 = accept_extended_affine(s, space, v, rational);
    749  1.1  mrg 	if (!pwaff2)
    750  1.1  mrg 		goto error;
    751  1.1  mrg 
    752  1.1  mrg 	pa_cond = isl_set_indicator_function(isl_map_wrap(cond));
    753  1.1  mrg 	return isl_pw_aff_cond(pa_cond, pwaff1, pwaff2);
    754  1.1  mrg error:
    755  1.1  mrg 	isl_map_free(cond);
    756  1.1  mrg 	isl_pw_aff_free(pwaff1);
    757  1.1  mrg 	isl_pw_aff_free(pwaff2);
    758  1.1  mrg 	return NULL;
    759  1.1  mrg }
    760  1.1  mrg 
    761  1.1  mrg /* Set *line and *col to those of the next token, if any.
    762  1.1  mrg  */
    763  1.1  mrg static void set_current_line_col(__isl_keep isl_stream *s, int *line, int *col)
    764  1.1  mrg {
    765  1.1  mrg 	struct isl_token *tok;
    766  1.1  mrg 
    767  1.1  mrg 	tok = isl_stream_next_token(s);
    768  1.1  mrg 	if (!tok)
    769  1.1  mrg 		return;
    770  1.1  mrg 
    771  1.1  mrg 	*line = tok->line;
    772  1.1  mrg 	*col = tok->col;
    773  1.1  mrg 	isl_stream_push_token(s, tok);
    774  1.1  mrg }
    775  1.1  mrg 
    776  1.1  mrg /* Push a token encapsulating "pa" onto "s", with the given
    777  1.1  mrg  * line and column.
    778  1.1  mrg  */
    779  1.1  mrg static isl_stat push_aff(__isl_keep isl_stream *s, int line, int col,
    780  1.1  mrg 	__isl_take isl_pw_aff *pa)
    781  1.1  mrg {
    782  1.1  mrg 	struct isl_token *tok;
    783  1.1  mrg 
    784  1.1  mrg 	tok = isl_token_new(s->ctx, line, col, 0);
    785  1.1  mrg 	if (!tok)
    786  1.1  mrg 		goto error;
    787  1.1  mrg 	tok->type = ISL_TOKEN_AFF;
    788  1.1  mrg 	tok->u.pwaff = pa;
    789  1.1  mrg 	isl_stream_push_token(s, tok);
    790  1.1  mrg 
    791  1.1  mrg 	return isl_stat_ok;
    792  1.1  mrg error:
    793  1.1  mrg 	isl_pw_aff_free(pa);
    794  1.1  mrg 	return isl_stat_error;
    795  1.1  mrg }
    796  1.1  mrg 
    797  1.1  mrg /* Is the next token a comparison operator?
    798  1.1  mrg  */
    799  1.1  mrg static int next_is_comparator(__isl_keep isl_stream *s)
    800  1.1  mrg {
    801  1.1  mrg 	int is_comp;
    802  1.1  mrg 	struct isl_token *tok;
    803  1.1  mrg 
    804  1.1  mrg 	tok = isl_stream_next_token(s);
    805  1.1  mrg 	if (!tok)
    806  1.1  mrg 		return 0;
    807  1.1  mrg 
    808  1.1  mrg 	is_comp = is_comparator(tok);
    809  1.1  mrg 	isl_stream_push_token(s, tok);
    810  1.1  mrg 
    811  1.1  mrg 	return is_comp;
    812  1.1  mrg }
    813  1.1  mrg 
    814  1.1  mrg /* Accept an affine expression that may involve ternary operators.
    815  1.1  mrg  * We first read an affine expression.
    816  1.1  mrg  * If it is not followed by a comparison operator, we simply return it.
    817  1.1  mrg  * Otherwise, we assume the affine expression is part of the first
    818  1.1  mrg  * argument of a ternary operator and try to parse that.
    819  1.1  mrg  */
    820  1.1  mrg static __isl_give isl_pw_aff *accept_extended_affine(__isl_keep isl_stream *s,
    821  1.1  mrg 	__isl_take isl_space *space, struct vars *v, int rational)
    822  1.1  mrg {
    823  1.1  mrg 	isl_map *cond;
    824  1.1  mrg 	isl_pw_aff *pwaff;
    825  1.1  mrg 	int line = -1, col = -1;
    826  1.1  mrg 
    827  1.1  mrg 	set_current_line_col(s, &line, &col);
    828  1.1  mrg 
    829  1.1  mrg 	pwaff = accept_affine(s, space, v);
    830  1.1  mrg 	if (rational)
    831  1.1  mrg 		pwaff = isl_pw_aff_set_rational(pwaff);
    832  1.1  mrg 	if (!pwaff)
    833  1.1  mrg 		return NULL;
    834  1.1  mrg 	if (!next_is_comparator(s))
    835  1.1  mrg 		return pwaff;
    836  1.1  mrg 
    837  1.1  mrg 	space = isl_pw_aff_get_domain_space(pwaff);
    838  1.1  mrg 	cond = isl_map_universe(isl_space_unwrap(space));
    839  1.1  mrg 
    840  1.1  mrg 	if (push_aff(s, line, col, pwaff) < 0)
    841  1.1  mrg 		cond = isl_map_free(cond);
    842  1.1  mrg 	if (!cond)
    843  1.1  mrg 		return NULL;
    844  1.1  mrg 
    845  1.1  mrg 	cond = read_formula(s, v, cond, rational);
    846  1.1  mrg 
    847  1.1  mrg 	return accept_ternary(s, cond, v, rational);
    848  1.1  mrg }
    849  1.1  mrg 
    850  1.1  mrg static __isl_give isl_map *read_var_def(__isl_keep isl_stream *s,
    851  1.1  mrg 	__isl_take isl_map *map, enum isl_dim_type type, struct vars *v,
    852  1.1  mrg 	int rational)
    853  1.1  mrg {
    854  1.1  mrg 	isl_pw_aff *def;
    855  1.1  mrg 	isl_size pos;
    856  1.1  mrg 	isl_map *def_map;
    857  1.1  mrg 
    858  1.1  mrg 	if (type == isl_dim_param)
    859  1.1  mrg 		pos = isl_map_dim(map, isl_dim_param);
    860  1.1  mrg 	else {
    861  1.1  mrg 		pos = isl_map_dim(map, isl_dim_in);
    862  1.1  mrg 		if (type == isl_dim_out) {
    863  1.1  mrg 			isl_size n_out = isl_map_dim(map, isl_dim_out);
    864  1.1  mrg 			if (pos < 0 || n_out < 0)
    865  1.1  mrg 				return isl_map_free(map);
    866  1.1  mrg 			pos += n_out;
    867  1.1  mrg 		}
    868  1.1  mrg 		type = isl_dim_in;
    869  1.1  mrg 	}
    870  1.1  mrg 	if (pos < 0)
    871  1.1  mrg 		return isl_map_free(map);
    872  1.1  mrg 	--pos;
    873  1.1  mrg 
    874  1.1  mrg 	def = accept_extended_affine(s, isl_space_wrap(isl_map_get_space(map)),
    875  1.1  mrg 					v, rational);
    876  1.1  mrg 	def_map = isl_map_from_pw_aff(def);
    877  1.1  mrg 	def_map = isl_map_equate(def_map, type, pos, isl_dim_out, 0);
    878  1.1  mrg 	def_map = isl_set_unwrap(isl_map_domain(def_map));
    879  1.1  mrg 
    880  1.1  mrg 	map = isl_map_intersect(map, def_map);
    881  1.1  mrg 
    882  1.1  mrg 	return map;
    883  1.1  mrg }
    884  1.1  mrg 
    885  1.1  mrg static __isl_give isl_pw_aff_list *accept_affine_list(__isl_keep isl_stream *s,
    886  1.1  mrg 	__isl_take isl_space *space, struct vars *v)
    887  1.1  mrg {
    888  1.1  mrg 	isl_pw_aff *pwaff;
    889  1.1  mrg 	isl_pw_aff_list *list;
    890  1.1  mrg 	struct isl_token *tok = NULL;
    891  1.1  mrg 
    892  1.1  mrg 	pwaff = accept_affine(s, isl_space_copy(space), v);
    893  1.1  mrg 	list = isl_pw_aff_list_from_pw_aff(pwaff);
    894  1.1  mrg 	if (!list)
    895  1.1  mrg 		goto error;
    896  1.1  mrg 
    897  1.1  mrg 	for (;;) {
    898  1.1  mrg 		tok = isl_stream_next_token(s);
    899  1.1  mrg 		if (!tok) {
    900  1.1  mrg 			isl_stream_error(s, NULL, "unexpected EOF");
    901  1.1  mrg 			goto error;
    902  1.1  mrg 		}
    903  1.1  mrg 		if (tok->type != ',') {
    904  1.1  mrg 			isl_stream_push_token(s, tok);
    905  1.1  mrg 			break;
    906  1.1  mrg 		}
    907  1.1  mrg 		isl_token_free(tok);
    908  1.1  mrg 
    909  1.1  mrg 		pwaff = accept_affine(s, isl_space_copy(space), v);
    910  1.1  mrg 		list = isl_pw_aff_list_concat(list,
    911  1.1  mrg 				isl_pw_aff_list_from_pw_aff(pwaff));
    912  1.1  mrg 		if (!list)
    913  1.1  mrg 			goto error;
    914  1.1  mrg 	}
    915  1.1  mrg 
    916  1.1  mrg 	isl_space_free(space);
    917  1.1  mrg 	return list;
    918  1.1  mrg error:
    919  1.1  mrg 	isl_space_free(space);
    920  1.1  mrg 	isl_pw_aff_list_free(list);
    921  1.1  mrg 	return NULL;
    922  1.1  mrg }
    923  1.1  mrg 
    924  1.1  mrg static __isl_give isl_map *read_defined_var_list(__isl_keep isl_stream *s,
    925  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
    926  1.1  mrg {
    927  1.1  mrg 	struct isl_token *tok;
    928  1.1  mrg 
    929  1.1  mrg 	while ((tok = isl_stream_next_token(s)) != NULL) {
    930  1.1  mrg 		int p;
    931  1.1  mrg 		int n = v->n;
    932  1.1  mrg 
    933  1.1  mrg 		if (tok->type != ISL_TOKEN_IDENT)
    934  1.1  mrg 			break;
    935  1.1  mrg 
    936  1.1  mrg 		p = vars_pos(v, tok->u.s, -1);
    937  1.1  mrg 		if (p < 0)
    938  1.1  mrg 			goto error;
    939  1.1  mrg 		if (p < n) {
    940  1.1  mrg 			isl_stream_error(s, tok, "expecting unique identifier");
    941  1.1  mrg 			goto error;
    942  1.1  mrg 		}
    943  1.1  mrg 
    944  1.1  mrg 		map = isl_map_add_dims(map, isl_dim_out, 1);
    945  1.1  mrg 
    946  1.1  mrg 		isl_token_free(tok);
    947  1.1  mrg 		tok = isl_stream_next_token(s);
    948  1.1  mrg 		if (tok && tok->type == '=') {
    949  1.1  mrg 			isl_token_free(tok);
    950  1.1  mrg 			map = read_var_def(s, map, isl_dim_out, v, rational);
    951  1.1  mrg 			tok = isl_stream_next_token(s);
    952  1.1  mrg 		}
    953  1.1  mrg 
    954  1.1  mrg 		if (!tok || tok->type != ',')
    955  1.1  mrg 			break;
    956  1.1  mrg 
    957  1.1  mrg 		isl_token_free(tok);
    958  1.1  mrg 	}
    959  1.1  mrg 	if (tok)
    960  1.1  mrg 		isl_stream_push_token(s, tok);
    961  1.1  mrg 
    962  1.1  mrg 	return map;
    963  1.1  mrg error:
    964  1.1  mrg 	isl_token_free(tok);
    965  1.1  mrg 	isl_map_free(map);
    966  1.1  mrg 	return NULL;
    967  1.1  mrg }
    968  1.1  mrg 
    969  1.1  mrg static int next_is_tuple(__isl_keep isl_stream *s)
    970  1.1  mrg {
    971  1.1  mrg 	struct isl_token *tok;
    972  1.1  mrg 	int is_tuple;
    973  1.1  mrg 
    974  1.1  mrg 	tok = isl_stream_next_token(s);
    975  1.1  mrg 	if (!tok)
    976  1.1  mrg 		return 0;
    977  1.1  mrg 	if (tok->type == '[') {
    978  1.1  mrg 		isl_stream_push_token(s, tok);
    979  1.1  mrg 		return 1;
    980  1.1  mrg 	}
    981  1.1  mrg 	if (tok->type != ISL_TOKEN_IDENT && !tok->is_keyword) {
    982  1.1  mrg 		isl_stream_push_token(s, tok);
    983  1.1  mrg 		return 0;
    984  1.1  mrg 	}
    985  1.1  mrg 
    986  1.1  mrg 	is_tuple = isl_stream_next_token_is(s, '[');
    987  1.1  mrg 
    988  1.1  mrg 	isl_stream_push_token(s, tok);
    989  1.1  mrg 
    990  1.1  mrg 	return is_tuple;
    991  1.1  mrg }
    992  1.1  mrg 
    993  1.1  mrg /* Does the next token mark the end of a tuple element?
    994  1.1  mrg  */
    995  1.1  mrg static int next_is_end_tuple_element(__isl_keep isl_stream *s)
    996  1.1  mrg {
    997  1.1  mrg 	return isl_stream_next_token_is(s, ',') ||
    998  1.1  mrg 	    isl_stream_next_token_is(s, ']');
    999  1.1  mrg }
   1000  1.1  mrg 
   1001  1.1  mrg /* Is the next token one that necessarily forms the start of a condition?
   1002  1.1  mrg  */
   1003  1.1  mrg static int next_is_condition_start(__isl_keep isl_stream *s)
   1004  1.1  mrg {
   1005  1.1  mrg 	return isl_stream_next_token_is(s, ISL_TOKEN_EXISTS) ||
   1006  1.1  mrg 	    isl_stream_next_token_is(s, ISL_TOKEN_NOT) ||
   1007  1.1  mrg 	    isl_stream_next_token_is(s, ISL_TOKEN_TRUE) ||
   1008  1.1  mrg 	    isl_stream_next_token_is(s, ISL_TOKEN_FALSE) ||
   1009  1.1  mrg 	    isl_stream_next_token_is(s, ISL_TOKEN_MAP);
   1010  1.1  mrg }
   1011  1.1  mrg 
   1012  1.1  mrg /* Is "pa" an expression in term of earlier dimensions?
   1013  1.1  mrg  * The alternative is that the dimension is defined to be equal to itself,
   1014  1.1  mrg  * meaning that it has a universe domain and an expression that depends
   1015  1.1  mrg  * on itself.  "i" is the position of the expression in a sequence
   1016  1.1  mrg  * of "n" expressions.  The final dimensions of "pa" correspond to
   1017  1.1  mrg  * these "n" expressions.
   1018  1.1  mrg  */
   1019  1.1  mrg static isl_bool pw_aff_is_expr(__isl_keep isl_pw_aff *pa, int i, int n)
   1020  1.1  mrg {
   1021  1.1  mrg 	isl_aff *aff;
   1022  1.1  mrg 
   1023  1.1  mrg 	if (!pa)
   1024  1.1  mrg 		return isl_bool_error;
   1025  1.1  mrg 	if (pa->n != 1)
   1026  1.1  mrg 		return isl_bool_true;
   1027  1.1  mrg 	if (!isl_set_plain_is_universe(pa->p[0].set))
   1028  1.1  mrg 		return isl_bool_true;
   1029  1.1  mrg 
   1030  1.1  mrg 	aff = pa->p[0].aff;
   1031  1.1  mrg 	if (isl_int_is_zero(aff->v->el[aff->v->size - n + i]))
   1032  1.1  mrg 		return isl_bool_true;
   1033  1.1  mrg 	return isl_bool_false;
   1034  1.1  mrg }
   1035  1.1  mrg 
   1036  1.1  mrg /* Does the tuple contain any dimensions that are defined
   1037  1.1  mrg  * in terms of earlier dimensions?
   1038  1.1  mrg  */
   1039  1.1  mrg static isl_bool tuple_has_expr(__isl_keep isl_multi_pw_aff *tuple)
   1040  1.1  mrg {
   1041  1.1  mrg 	int i;
   1042  1.1  mrg 	isl_size n;
   1043  1.1  mrg 	isl_bool has_expr = isl_bool_false;
   1044  1.1  mrg 	isl_pw_aff *pa;
   1045  1.1  mrg 
   1046  1.1  mrg 	n = isl_multi_pw_aff_dim(tuple, isl_dim_out);
   1047  1.1  mrg 	if (n < 0)
   1048  1.1  mrg 		return isl_bool_error;
   1049  1.1  mrg 	for (i = 0; i < n; ++i) {
   1050  1.1  mrg 		pa = isl_multi_pw_aff_get_pw_aff(tuple, i);
   1051  1.1  mrg 		has_expr = pw_aff_is_expr(pa, i, n);
   1052  1.1  mrg 		isl_pw_aff_free(pa);
   1053  1.1  mrg 		if (has_expr < 0 || has_expr)
   1054  1.1  mrg 			break;
   1055  1.1  mrg 	}
   1056  1.1  mrg 
   1057  1.1  mrg 	return has_expr;
   1058  1.1  mrg }
   1059  1.1  mrg 
   1060  1.1  mrg /* Set the name of dimension "pos" in "space" to "name".
   1061  1.1  mrg  * During printing, we add primes if the same name appears more than once
   1062  1.1  mrg  * to distinguish the occurrences.  Here, we remove those primes from "name"
   1063  1.1  mrg  * before setting the name of the dimension.
   1064  1.1  mrg  */
   1065  1.1  mrg static __isl_give isl_space *space_set_dim_name(__isl_take isl_space *space,
   1066  1.1  mrg 	int pos, char *name)
   1067  1.1  mrg {
   1068  1.1  mrg 	char *prime;
   1069  1.1  mrg 
   1070  1.1  mrg 	if (!name)
   1071  1.1  mrg 		return space;
   1072  1.1  mrg 
   1073  1.1  mrg 	prime = strchr(name, '\'');
   1074  1.1  mrg 	if (prime)
   1075  1.1  mrg 		*prime = '\0';
   1076  1.1  mrg 	space = isl_space_set_dim_name(space, isl_dim_out, pos, name);
   1077  1.1  mrg 	if (prime)
   1078  1.1  mrg 		*prime = '\'';
   1079  1.1  mrg 
   1080  1.1  mrg 	return space;
   1081  1.1  mrg }
   1082  1.1  mrg 
   1083  1.1  mrg /* Set the name of the last (output) dimension of "space" to "name",
   1084  1.1  mrg  * ignoring any primes in "name".
   1085  1.1  mrg  */
   1086  1.1  mrg static __isl_give isl_space *space_set_last_dim_name(
   1087  1.1  mrg 	__isl_take isl_space *space, char *name)
   1088  1.1  mrg {
   1089  1.1  mrg 	isl_size pos;
   1090  1.1  mrg 
   1091  1.1  mrg 	pos = isl_space_dim(space, isl_dim_out);
   1092  1.1  mrg 	if (pos < 0)
   1093  1.1  mrg 		return isl_space_free(space);
   1094  1.1  mrg 	return space_set_dim_name(space, pos - 1, name);
   1095  1.1  mrg }
   1096  1.1  mrg 
   1097  1.1  mrg /* Construct an isl_pw_aff defined on a "space" (with v->n variables)
   1098  1.1  mrg  * that is equal to the last of those variables.
   1099  1.1  mrg  */
   1100  1.1  mrg static __isl_give isl_pw_aff *identity_tuple_el_on_space(
   1101  1.1  mrg 	__isl_take isl_space *space, struct vars *v)
   1102  1.1  mrg {
   1103  1.1  mrg 	isl_aff *aff;
   1104  1.1  mrg 
   1105  1.1  mrg 	aff = isl_aff_zero_on_domain(isl_local_space_from_space(space));
   1106  1.1  mrg 	aff = isl_aff_add_coefficient_si(aff, isl_dim_in, v->n - 1, 1);
   1107  1.1  mrg 	return isl_pw_aff_from_aff(aff);
   1108  1.1  mrg }
   1109  1.1  mrg 
   1110  1.1  mrg /* Construct an isl_pw_aff defined on the domain space of "pa"
   1111  1.1  mrg  * that is equal to the last variable in "v".
   1112  1.1  mrg  *
   1113  1.1  mrg  * That is, if D is the domain space of "pa", then construct
   1114  1.1  mrg  *
   1115  1.1  mrg  *	D[..., i] -> i.
   1116  1.1  mrg  */
   1117  1.1  mrg static __isl_give isl_pw_aff *init_range(__isl_keep isl_pw_aff *pa,
   1118  1.1  mrg 	struct vars *v)
   1119  1.1  mrg {
   1120  1.1  mrg 	isl_space *space;
   1121  1.1  mrg 
   1122  1.1  mrg 	space = isl_pw_aff_get_domain_space(pa);
   1123  1.1  mrg 	return identity_tuple_el_on_space(space, v);
   1124  1.1  mrg }
   1125  1.1  mrg 
   1126  1.1  mrg /* Impose the lower bound "lower" on the variable represented by "range_pa".
   1127  1.1  mrg  *
   1128  1.1  mrg  * In particular, "range_pa" is of the form
   1129  1.1  mrg  *
   1130  1.1  mrg  *	D[..., i] -> i : C
   1131  1.1  mrg  *
   1132  1.1  mrg  * with D also the domains space of "lower' and "C" some constraints.
   1133  1.1  mrg  *
   1134  1.1  mrg  * Return the expression
   1135  1.1  mrg  *
   1136  1.1  mrg  *	D[..., i] -> i : C and i >= lower
   1137  1.1  mrg  */
   1138  1.1  mrg static __isl_give isl_pw_aff *set_lower(__isl_take isl_pw_aff *range_pa,
   1139  1.1  mrg 	__isl_take isl_pw_aff *lower)
   1140  1.1  mrg {
   1141  1.1  mrg 	isl_set *range;
   1142  1.1  mrg 
   1143  1.1  mrg 	range = isl_pw_aff_ge_set(isl_pw_aff_copy(range_pa), lower);
   1144  1.1  mrg 	return isl_pw_aff_intersect_domain(range_pa, range);
   1145  1.1  mrg }
   1146  1.1  mrg 
   1147  1.1  mrg /* Impose the upper bound "upper" on the variable represented by "range_pa".
   1148  1.1  mrg  *
   1149  1.1  mrg  * In particular, "range_pa" is of the form
   1150  1.1  mrg  *
   1151  1.1  mrg  *	D[..., i] -> i : C
   1152  1.1  mrg  *
   1153  1.1  mrg  * with D also the domains space of "upper' and "C" some constraints.
   1154  1.1  mrg  *
   1155  1.1  mrg  * Return the expression
   1156  1.1  mrg  *
   1157  1.1  mrg  *	D[..., i] -> i : C and i <= upper
   1158  1.1  mrg  */
   1159  1.1  mrg static __isl_give isl_pw_aff *set_upper(__isl_take isl_pw_aff *range_pa,
   1160  1.1  mrg 	__isl_take isl_pw_aff *upper)
   1161  1.1  mrg {
   1162  1.1  mrg 	isl_set *range;
   1163  1.1  mrg 
   1164  1.1  mrg 	range = isl_pw_aff_le_set(isl_pw_aff_copy(range_pa), upper);
   1165  1.1  mrg 	return isl_pw_aff_intersect_domain(range_pa, range);
   1166  1.1  mrg }
   1167  1.1  mrg 
   1168  1.1  mrg /* Construct a piecewise affine expression corresponding
   1169  1.1  mrg  * to the last variable in "v" that is greater than or equal to "pa".
   1170  1.1  mrg  *
   1171  1.1  mrg  * In particular, if D is the domain space of "pa",
   1172  1.1  mrg  * then construct the expression
   1173  1.1  mrg  *
   1174  1.1  mrg  *	D[..., i] -> i,
   1175  1.1  mrg  *
   1176  1.1  mrg  * impose lower bound "pa" and return
   1177  1.1  mrg  *
   1178  1.1  mrg  *	D[..., i] -> i : i >= pa
   1179  1.1  mrg  */
   1180  1.1  mrg static __isl_give isl_pw_aff *construct_lower(__isl_take isl_pw_aff *pa,
   1181  1.1  mrg 	struct vars *v)
   1182  1.1  mrg {
   1183  1.1  mrg 	return set_lower(init_range(pa, v), pa);
   1184  1.1  mrg }
   1185  1.1  mrg 
   1186  1.1  mrg /* Construct a piecewise affine expression corresponding
   1187  1.1  mrg  * to the last variable in "v" that is smaller than or equal to "pa".
   1188  1.1  mrg  *
   1189  1.1  mrg  * In particular, if D is the domain space of "pa",
   1190  1.1  mrg  * then construct the expression
   1191  1.1  mrg  *
   1192  1.1  mrg  *	D[..., i] -> i,
   1193  1.1  mrg  *
   1194  1.1  mrg  * impose lower bound "pa" and return
   1195  1.1  mrg  *
   1196  1.1  mrg  *	D[..., i] -> i : i <= pa
   1197  1.1  mrg  */
   1198  1.1  mrg static __isl_give isl_pw_aff *construct_upper(__isl_take isl_pw_aff *pa,
   1199  1.1  mrg 	struct vars *v)
   1200  1.1  mrg {
   1201  1.1  mrg 	return set_upper(init_range(pa, v), pa);
   1202  1.1  mrg }
   1203  1.1  mrg 
   1204  1.1  mrg /* Construct a piecewise affine expression corresponding
   1205  1.1  mrg  * to the last variable in "v" that ranges between "pa" and "pa2".
   1206  1.1  mrg  *
   1207  1.1  mrg  * In particular, if D is the domain space of "pa" (and "pa2"),
   1208  1.1  mrg  * then construct the expression
   1209  1.1  mrg  *
   1210  1.1  mrg  *	D[..., i] -> i,
   1211  1.1  mrg  *
   1212  1.1  mrg  * impose lower bound "pa" and upper bound "pa2" and return
   1213  1.1  mrg  *
   1214  1.1  mrg  *	D[..., i] -> i : pa <= i <= pa2
   1215  1.1  mrg  */
   1216  1.1  mrg static __isl_give isl_pw_aff *construct_range(__isl_take isl_pw_aff *pa,
   1217  1.1  mrg 	__isl_take isl_pw_aff *pa2, struct vars *v)
   1218  1.1  mrg {
   1219  1.1  mrg 	return set_upper(set_lower(init_range(pa, v), pa), pa2);
   1220  1.1  mrg }
   1221  1.1  mrg 
   1222  1.1  mrg static int resolve_paren_expr(__isl_keep isl_stream *s,
   1223  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational);
   1224  1.1  mrg 
   1225  1.1  mrg /* Given that the (piecewise) affine expression "pa"
   1226  1.1  mrg  * has just been parsed, followed by a colon,
   1227  1.1  mrg  * continue parsing as part of a piecewise affine expression.
   1228  1.1  mrg  *
   1229  1.1  mrg  * In particular, check if the colon is followed by a condition.
   1230  1.1  mrg  * If so, parse the conditions(a) on "pa" and include them in the domain.
   1231  1.1  mrg  * Otherwise, if the colon is followed by another (piecewise) affine expression
   1232  1.1  mrg  * then consider the two expressions as endpoints of a range of values and
   1233  1.1  mrg  * return a piecewise affine expression that takes values in that range.
   1234  1.1  mrg  * Note that an affine expression followed by a comparison operator
   1235  1.1  mrg  * is considered to be part of a condition.
   1236  1.1  mrg  * If the colon is not followed by anything (inside the tuple element),
   1237  1.1  mrg  * then consider "pa" as a lower bound on a range of values without upper bound
   1238  1.1  mrg  * and return a piecewise affine expression that takes values in that range.
   1239  1.1  mrg  */
   1240  1.1  mrg static __isl_give isl_pw_aff *update_piecewise_affine_colon(
   1241  1.1  mrg 	__isl_take isl_pw_aff *pa, __isl_keep isl_stream *s,
   1242  1.1  mrg 	struct vars *v, int rational)
   1243  1.1  mrg {
   1244  1.1  mrg 	isl_space *dom_space;
   1245  1.1  mrg 	isl_map *map;
   1246  1.1  mrg 
   1247  1.1  mrg 	dom_space = isl_pw_aff_get_domain_space(pa);
   1248  1.1  mrg 	map = isl_map_universe(isl_space_from_domain(dom_space));
   1249  1.1  mrg 
   1250  1.1  mrg 	if (isl_stream_next_token_is(s, '('))
   1251  1.1  mrg 		if (resolve_paren_expr(s, v, isl_map_copy(map), rational))
   1252  1.1  mrg 			goto error;
   1253  1.1  mrg 	if (next_is_end_tuple_element(s)) {
   1254  1.1  mrg 		isl_map_free(map);
   1255  1.1  mrg 		return construct_lower(pa, v);
   1256  1.1  mrg 	}
   1257  1.1  mrg 	if (!next_is_condition_start(s)) {
   1258  1.1  mrg 		int line = -1, col = -1;
   1259  1.1  mrg 		isl_space *space;
   1260  1.1  mrg 		isl_pw_aff *pa2;
   1261  1.1  mrg 
   1262  1.1  mrg 		set_current_line_col(s, &line, &col);
   1263  1.1  mrg 		space = isl_space_wrap(isl_map_get_space(map));
   1264  1.1  mrg 		pa2 = accept_affine(s, space, v);
   1265  1.1  mrg 		if (rational)
   1266  1.1  mrg 			pa2 = isl_pw_aff_set_rational(pa2);
   1267  1.1  mrg 		if (!next_is_comparator(s)) {
   1268  1.1  mrg 			isl_map_free(map);
   1269  1.1  mrg 			pa2 = isl_pw_aff_domain_factor_domain(pa2);
   1270  1.1  mrg 			return construct_range(pa, pa2, v);
   1271  1.1  mrg 		}
   1272  1.1  mrg 		if (push_aff(s, line, col, pa2) < 0)
   1273  1.1  mrg 			goto error;
   1274  1.1  mrg 	}
   1275  1.1  mrg 
   1276  1.1  mrg 	map = read_formula(s, v, map, rational);
   1277  1.1  mrg 	pa = isl_pw_aff_intersect_domain(pa, isl_map_domain(map));
   1278  1.1  mrg 
   1279  1.1  mrg 	return pa;
   1280  1.1  mrg error:
   1281  1.1  mrg 	isl_map_free(map);
   1282  1.1  mrg 	isl_pw_aff_free(pa);
   1283  1.1  mrg 	return NULL;
   1284  1.1  mrg }
   1285  1.1  mrg 
   1286  1.1  mrg /* Accept a piecewise affine expression.
   1287  1.1  mrg  *
   1288  1.1  mrg  * At the outer level, the piecewise affine expression may be of the form
   1289  1.1  mrg  *
   1290  1.1  mrg  *	aff1 : condition1; aff2 : conditions2; ...
   1291  1.1  mrg  *
   1292  1.1  mrg  * or one of
   1293  1.1  mrg  *
   1294  1.1  mrg  *	aff :
   1295  1.1  mrg  *	aff1 : aff2
   1296  1.1  mrg  *	: aff
   1297  1.1  mrg  *	:
   1298  1.1  mrg  *
   1299  1.1  mrg  * or simply
   1300  1.1  mrg  *
   1301  1.1  mrg  *	aff
   1302  1.1  mrg  *
   1303  1.1  mrg  * each of the affine expressions may in turn include ternary operators.
   1304  1.1  mrg  *
   1305  1.1  mrg  * If the first token is a colon, then the expression must be
   1306  1.1  mrg  * ":" or ": aff2", depending on whether anything follows the colon
   1307  1.1  mrg  * inside the tuple element.
   1308  1.1  mrg  * The first is considered to represent an arbitrary value.
   1309  1.1  mrg  * The second is considered to represent a range of values
   1310  1.1  mrg  * with the given upper bound and no lower bound.
   1311  1.1  mrg  *
   1312  1.1  mrg  * There may be parentheses around some subexpression of "aff1"
   1313  1.1  mrg  * around "aff1" itself, around "aff1 : condition1" and/or
   1314  1.1  mrg  * around the entire piecewise affine expression.
   1315  1.1  mrg  * We therefore remove the opening parenthesis (if any) from the stream
   1316  1.1  mrg  * in case the closing parenthesis follows the colon, but if the closing
   1317  1.1  mrg  * parenthesis is the first thing in the stream after the parsed affine
   1318  1.1  mrg  * expression, we push the parsed expression onto the stream and parse
   1319  1.1  mrg  * again in case the parentheses enclose some subexpression of "aff1".
   1320  1.1  mrg  */
   1321  1.1  mrg static __isl_give isl_pw_aff *accept_piecewise_affine(__isl_keep isl_stream *s,
   1322  1.1  mrg 	__isl_take isl_space *space, struct vars *v, int rational)
   1323  1.1  mrg {
   1324  1.1  mrg 	isl_pw_aff *res;
   1325  1.1  mrg 	isl_space *res_space;
   1326  1.1  mrg 
   1327  1.1  mrg 	if (isl_stream_eat_if_available(s, ':')) {
   1328  1.1  mrg 		if (next_is_end_tuple_element(s))
   1329  1.1  mrg 			return identity_tuple_el_on_space(space, v);
   1330  1.1  mrg 		else
   1331  1.1  mrg 			return construct_upper(accept_affine(s, space, v), v);
   1332  1.1  mrg 	}
   1333  1.1  mrg 
   1334  1.1  mrg 	res_space = isl_space_from_domain(isl_space_copy(space));
   1335  1.1  mrg 	res_space = isl_space_add_dims(res_space, isl_dim_out, 1);
   1336  1.1  mrg 	res = isl_pw_aff_empty(res_space);
   1337  1.1  mrg 	do {
   1338  1.1  mrg 		isl_pw_aff *pa;
   1339  1.1  mrg 		int seen_paren;
   1340  1.1  mrg 		int line = -1, col = -1;
   1341  1.1  mrg 
   1342  1.1  mrg 		set_current_line_col(s, &line, &col);
   1343  1.1  mrg 		seen_paren = isl_stream_eat_if_available(s, '(');
   1344  1.1  mrg 		if (seen_paren)
   1345  1.1  mrg 			pa = accept_piecewise_affine(s, isl_space_copy(space),
   1346  1.1  mrg 							v, rational);
   1347  1.1  mrg 		else
   1348  1.1  mrg 			pa = accept_extended_affine(s, isl_space_copy(space),
   1349  1.1  mrg 							v, rational);
   1350  1.1  mrg 		if (seen_paren && isl_stream_eat_if_available(s, ')')) {
   1351  1.1  mrg 			seen_paren = 0;
   1352  1.1  mrg 			if (push_aff(s, line, col, pa) < 0)
   1353  1.1  mrg 				goto error;
   1354  1.1  mrg 			pa = accept_extended_affine(s, isl_space_copy(space),
   1355  1.1  mrg 							v, rational);
   1356  1.1  mrg 		}
   1357  1.1  mrg 		if (pa && isl_stream_eat_if_available(s, ':'))
   1358  1.1  mrg 			pa = update_piecewise_affine_colon(pa, s, v, rational);
   1359  1.1  mrg 
   1360  1.1  mrg 		res = isl_pw_aff_union_add(res, pa);
   1361  1.1  mrg 
   1362  1.1  mrg 		if (!res || (seen_paren && isl_stream_eat(s, ')')))
   1363  1.1  mrg 			goto error;
   1364  1.1  mrg 	} while (isl_stream_eat_if_available(s, ';'));
   1365  1.1  mrg 
   1366  1.1  mrg 	isl_space_free(space);
   1367  1.1  mrg 
   1368  1.1  mrg 	return res;
   1369  1.1  mrg error:
   1370  1.1  mrg 	isl_space_free(space);
   1371  1.1  mrg 	return isl_pw_aff_free(res);
   1372  1.1  mrg }
   1373  1.1  mrg 
   1374  1.1  mrg /* Read an affine expression from "s" for use in read_tuple.
   1375  1.1  mrg  *
   1376  1.1  mrg  * accept_extended_affine requires a wrapped space as input.
   1377  1.1  mrg  * read_tuple on the other hand expects each isl_pw_aff
   1378  1.1  mrg  * to have an anonymous space.  We therefore adjust the space
   1379  1.1  mrg  * of the isl_pw_aff before returning it.
   1380  1.1  mrg  */
   1381  1.1  mrg static __isl_give isl_pw_aff *read_tuple_var_def(__isl_keep isl_stream *s,
   1382  1.1  mrg 	struct vars *v, int rational)
   1383  1.1  mrg {
   1384  1.1  mrg 	isl_space *space;
   1385  1.1  mrg 	isl_pw_aff *def;
   1386  1.1  mrg 
   1387  1.1  mrg 	space = isl_space_wrap(isl_space_alloc(s->ctx, 0, v->n, 0));
   1388  1.1  mrg 
   1389  1.1  mrg 	def = accept_piecewise_affine(s, space, v, rational);
   1390  1.1  mrg 	def = isl_pw_aff_domain_factor_domain(def);
   1391  1.1  mrg 
   1392  1.1  mrg 	return def;
   1393  1.1  mrg }
   1394  1.1  mrg 
   1395  1.1  mrg /* Read a list of tuple elements by calling "read_el" on each of them and
   1396  1.1  mrg  * return a space with the same number of set dimensions derived from
   1397  1.1  mrg  * the parameter space "space" and possibly updated by "read_el".
   1398  1.1  mrg  * The elements in the list are separated by either "," or "][".
   1399  1.1  mrg  * If "comma" is set then only "," is allowed.
   1400  1.1  mrg  */
   1401  1.1  mrg static __isl_give isl_space *read_tuple_list(__isl_keep isl_stream *s,
   1402  1.1  mrg 	struct vars *v, __isl_take isl_space *space, int rational, int comma,
   1403  1.1  mrg 	__isl_give isl_space *(*read_el)(__isl_keep isl_stream *s,
   1404  1.1  mrg 		struct vars *v, __isl_take isl_space *space, int rational,
   1405  1.1  mrg 		void *user),
   1406  1.1  mrg 	void *user)
   1407  1.1  mrg {
   1408  1.1  mrg 	if (!space)
   1409  1.1  mrg 		return NULL;
   1410  1.1  mrg 
   1411  1.1  mrg 	space = isl_space_set_from_params(space);
   1412  1.1  mrg 
   1413  1.1  mrg 	if (isl_stream_next_token_is(s, ']'))
   1414  1.1  mrg 		return space;
   1415  1.1  mrg 
   1416  1.1  mrg 	for (;;) {
   1417  1.1  mrg 		struct isl_token *tok;
   1418  1.1  mrg 
   1419  1.1  mrg 		space = isl_space_add_dims(space, isl_dim_set, 1);
   1420  1.1  mrg 
   1421  1.1  mrg 		space = read_el(s, v, space, rational, user);
   1422  1.1  mrg 		if (!space)
   1423  1.1  mrg 			return NULL;
   1424  1.1  mrg 
   1425  1.1  mrg 		tok = isl_stream_next_token(s);
   1426  1.1  mrg 		if (!comma && tok && tok->type == ']' &&
   1427  1.1  mrg 		    isl_stream_next_token_is(s, '[')) {
   1428  1.1  mrg 			isl_token_free(tok);
   1429  1.1  mrg 			tok = isl_stream_next_token(s);
   1430  1.1  mrg 		} else if (!tok || tok->type != ',') {
   1431  1.1  mrg 			if (tok)
   1432  1.1  mrg 				isl_stream_push_token(s, tok);
   1433  1.1  mrg 			break;
   1434  1.1  mrg 		}
   1435  1.1  mrg 
   1436  1.1  mrg 		isl_token_free(tok);
   1437  1.1  mrg 	}
   1438  1.1  mrg 
   1439  1.1  mrg 	return space;
   1440  1.1  mrg }
   1441  1.1  mrg 
   1442  1.1  mrg /* Read a tuple space from "s" derived from the parameter space "space".
   1443  1.1  mrg  * Call "read_el" on each element in the tuples.
   1444  1.1  mrg  */
   1445  1.1  mrg static __isl_give isl_space *read_tuple_space(__isl_keep isl_stream *s,
   1446  1.1  mrg 	struct vars *v, __isl_take isl_space *space, int rational, int comma,
   1447  1.1  mrg 	__isl_give isl_space *(*read_el)(__isl_keep isl_stream *s,
   1448  1.1  mrg 		struct vars *v, __isl_take isl_space *space, int rational,
   1449  1.1  mrg 		void *user),
   1450  1.1  mrg 	void *user)
   1451  1.1  mrg {
   1452  1.1  mrg 	struct isl_token *tok;
   1453  1.1  mrg 	char *name = NULL;
   1454  1.1  mrg 	isl_space *res = NULL;
   1455  1.1  mrg 
   1456  1.1  mrg 	tok = isl_stream_next_token(s);
   1457  1.1  mrg 	if (!tok)
   1458  1.1  mrg 		goto error;
   1459  1.1  mrg 	if (tok->type == ISL_TOKEN_IDENT || tok->is_keyword) {
   1460  1.1  mrg 		name = strdup(tok->u.s);
   1461  1.1  mrg 		isl_token_free(tok);
   1462  1.1  mrg 		if (!name)
   1463  1.1  mrg 			goto error;
   1464  1.1  mrg 	} else
   1465  1.1  mrg 		isl_stream_push_token(s, tok);
   1466  1.1  mrg 	if (isl_stream_eat(s, '['))
   1467  1.1  mrg 		goto error;
   1468  1.1  mrg 	if (next_is_tuple(s)) {
   1469  1.1  mrg 		isl_space *out;
   1470  1.1  mrg 		res = read_tuple_space(s, v, isl_space_copy(space),
   1471  1.1  mrg 					rational, comma, read_el, user);
   1472  1.1  mrg 		if (isl_stream_eat(s, ISL_TOKEN_TO))
   1473  1.1  mrg 			goto error;
   1474  1.1  mrg 		out = read_tuple_space(s, v, isl_space_copy(space),
   1475  1.1  mrg 					rational, comma, read_el, user);
   1476  1.1  mrg 		res = isl_space_product(res, out);
   1477  1.1  mrg 	} else
   1478  1.1  mrg 		res = read_tuple_list(s, v, isl_space_copy(space),
   1479  1.1  mrg 					rational, comma, read_el, user);
   1480  1.1  mrg 	if (!res || isl_stream_eat(s, ']'))
   1481  1.1  mrg 		goto error;
   1482  1.1  mrg 
   1483  1.1  mrg 	if (name) {
   1484  1.1  mrg 		res = isl_space_set_tuple_name(res, isl_dim_set, name);
   1485  1.1  mrg 		free(name);
   1486  1.1  mrg 	}
   1487  1.1  mrg 
   1488  1.1  mrg 	isl_space_free(space);
   1489  1.1  mrg 	return res;
   1490  1.1  mrg error:
   1491  1.1  mrg 	free(name);
   1492  1.1  mrg 	isl_space_free(res);
   1493  1.1  mrg 	isl_space_free(space);
   1494  1.1  mrg 	return NULL;
   1495  1.1  mrg }
   1496  1.1  mrg 
   1497  1.1  mrg /* Construct an isl_pw_aff defined on a space with v->n variables
   1498  1.1  mrg  * that is equal to the last of those variables.
   1499  1.1  mrg  */
   1500  1.1  mrg static __isl_give isl_pw_aff *identity_tuple_el(struct vars *v)
   1501  1.1  mrg {
   1502  1.1  mrg 	isl_space *space;
   1503  1.1  mrg 
   1504  1.1  mrg 	space = isl_space_set_alloc(v->ctx, 0, v->n);
   1505  1.1  mrg 	return identity_tuple_el_on_space(space, v);
   1506  1.1  mrg }
   1507  1.1  mrg 
   1508  1.1  mrg /* This function is called for each element in a tuple inside read_tuple.
   1509  1.1  mrg  * Add a new variable to "v" and construct a corresponding isl_pw_aff defined
   1510  1.1  mrg  * over a space containing all variables in "v" defined so far.
   1511  1.1  mrg  * The isl_pw_aff expresses the new variable in terms of earlier variables
   1512  1.1  mrg  * if a definition is provided.  Otherwise, it is represented as being
   1513  1.1  mrg  * equal to itself.
   1514  1.1  mrg  * Add the isl_pw_aff to *list.
   1515  1.1  mrg  * If the new variable was named, then adjust "space" accordingly and
   1516  1.1  mrg  * return the updated space.
   1517  1.1  mrg  */
   1518  1.1  mrg static __isl_give isl_space *read_tuple_pw_aff_el(__isl_keep isl_stream *s,
   1519  1.1  mrg 	struct vars *v, __isl_take isl_space *space, int rational, void *user)
   1520  1.1  mrg {
   1521  1.1  mrg 	isl_pw_aff_list **list = (isl_pw_aff_list **) user;
   1522  1.1  mrg 	isl_pw_aff *pa;
   1523  1.1  mrg 	struct isl_token *tok;
   1524  1.1  mrg 	int new_name = 0;
   1525  1.1  mrg 
   1526  1.1  mrg 	tok = next_token(s);
   1527  1.1  mrg 	if (!tok) {
   1528  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   1529  1.1  mrg 		return isl_space_free(space);
   1530  1.1  mrg 	}
   1531  1.1  mrg 
   1532  1.1  mrg 	if (tok->type == ISL_TOKEN_IDENT) {
   1533  1.1  mrg 		int n = v->n;
   1534  1.1  mrg 		int p = vars_pos(v, tok->u.s, -1);
   1535  1.1  mrg 		if (p < 0)
   1536  1.1  mrg 			goto error;
   1537  1.1  mrg 		new_name = p >= n;
   1538  1.1  mrg 	}
   1539  1.1  mrg 
   1540  1.1  mrg 	if (tok->type == '*') {
   1541  1.1  mrg 		if (vars_add_anon(v) < 0)
   1542  1.1  mrg 			goto error;
   1543  1.1  mrg 		isl_token_free(tok);
   1544  1.1  mrg 		pa = identity_tuple_el(v);
   1545  1.1  mrg 	} else if (new_name) {
   1546  1.1  mrg 		space = space_set_last_dim_name(space, v->v->name);
   1547  1.1  mrg 		isl_token_free(tok);
   1548  1.1  mrg 		if (isl_stream_eat_if_available(s, '='))
   1549  1.1  mrg 			pa = read_tuple_var_def(s, v, rational);
   1550  1.1  mrg 		else
   1551  1.1  mrg 			pa = identity_tuple_el(v);
   1552  1.1  mrg 	} else {
   1553  1.1  mrg 		isl_stream_push_token(s, tok);
   1554  1.1  mrg 		tok = NULL;
   1555  1.1  mrg 		if (vars_add_anon(v) < 0)
   1556  1.1  mrg 			goto error;
   1557  1.1  mrg 		pa = read_tuple_var_def(s, v, rational);
   1558  1.1  mrg 	}
   1559  1.1  mrg 
   1560  1.1  mrg 	*list = isl_pw_aff_list_add(*list, pa);
   1561  1.1  mrg 	if (!*list)
   1562  1.1  mrg 		return isl_space_free(space);
   1563  1.1  mrg 
   1564  1.1  mrg 	return space;
   1565  1.1  mrg error:
   1566  1.1  mrg 	isl_token_free(tok);
   1567  1.1  mrg 	return isl_space_free(space);
   1568  1.1  mrg }
   1569  1.1  mrg 
   1570  1.1  mrg /* Read a tuple and represent it as an isl_multi_pw_aff.
   1571  1.1  mrg  * The range space of the isl_multi_pw_aff is the space of the tuple.
   1572  1.1  mrg  * The domain space is an anonymous space
   1573  1.1  mrg  * with a dimension for each variable in the set of variables in "v",
   1574  1.1  mrg  * including the variables in the range.
   1575  1.1  mrg  * If a given dimension is not defined in terms of earlier dimensions in
   1576  1.1  mrg  * the input, then the corresponding isl_pw_aff is set equal to one time
   1577  1.1  mrg  * the variable corresponding to the dimension being defined.
   1578  1.1  mrg  *
   1579  1.1  mrg  * The elements in the tuple are collected in a list by read_tuple_pw_aff_el.
   1580  1.1  mrg  * Each element in this list is defined over a space representing
   1581  1.1  mrg  * the variables defined so far.  We need to adjust the earlier
   1582  1.1  mrg  * elements to have as many variables in the domain as the final
   1583  1.1  mrg  * element in the list.
   1584  1.1  mrg  */
   1585  1.1  mrg static __isl_give isl_multi_pw_aff *read_tuple(__isl_keep isl_stream *s,
   1586  1.1  mrg 	struct vars *v, int rational, int comma)
   1587  1.1  mrg {
   1588  1.1  mrg 	int i;
   1589  1.1  mrg 	isl_size n;
   1590  1.1  mrg 	isl_space *space;
   1591  1.1  mrg 	isl_pw_aff_list *list;
   1592  1.1  mrg 
   1593  1.1  mrg 	space = isl_space_params_alloc(v->ctx, 0);
   1594  1.1  mrg 	list = isl_pw_aff_list_alloc(s->ctx, 0);
   1595  1.1  mrg 	space = read_tuple_space(s, v, space, rational, comma,
   1596  1.1  mrg 				&read_tuple_pw_aff_el, &list);
   1597  1.1  mrg 	n = isl_space_dim(space, isl_dim_set);
   1598  1.1  mrg 	if (n < 0)
   1599  1.1  mrg 		space = isl_space_free(space);
   1600  1.1  mrg 	for (i = 0; i + 1 < n; ++i) {
   1601  1.1  mrg 		isl_pw_aff *pa;
   1602  1.1  mrg 
   1603  1.1  mrg 		pa = isl_pw_aff_list_get_pw_aff(list, i);
   1604  1.1  mrg 		pa = isl_pw_aff_add_dims(pa, isl_dim_in, n - (i + 1));
   1605  1.1  mrg 		list = isl_pw_aff_list_set_pw_aff(list, i, pa);
   1606  1.1  mrg 	}
   1607  1.1  mrg 
   1608  1.1  mrg 	space = isl_space_from_range(space);
   1609  1.1  mrg 	space = isl_space_add_dims(space, isl_dim_in, v->n);
   1610  1.1  mrg 	return isl_multi_pw_aff_from_pw_aff_list(space, list);
   1611  1.1  mrg }
   1612  1.1  mrg 
   1613  1.1  mrg /* Add the tuple represented by the isl_multi_pw_aff "tuple" to "map".
   1614  1.1  mrg  * We first create the appropriate space in "map" based on the range
   1615  1.1  mrg  * space of this isl_multi_pw_aff.  Then, we add equalities based
   1616  1.1  mrg  * on the affine expressions.  These live in an anonymous space,
   1617  1.1  mrg  * however, so we first need to reset the space to that of "map".
   1618  1.1  mrg  */
   1619  1.1  mrg static __isl_give isl_map *map_from_tuple(__isl_take isl_multi_pw_aff *tuple,
   1620  1.1  mrg 	__isl_take isl_map *map, enum isl_dim_type type, struct vars *v,
   1621  1.1  mrg 	int rational)
   1622  1.1  mrg {
   1623  1.1  mrg 	int i;
   1624  1.1  mrg 	isl_size n;
   1625  1.1  mrg 	isl_ctx *ctx;
   1626  1.1  mrg 	isl_space *space = NULL;
   1627  1.1  mrg 
   1628  1.1  mrg 	n = isl_multi_pw_aff_dim(tuple, isl_dim_out);
   1629  1.1  mrg 	if (!map || n < 0)
   1630  1.1  mrg 		goto error;
   1631  1.1  mrg 	ctx = isl_multi_pw_aff_get_ctx(tuple);
   1632  1.1  mrg 	space = isl_space_range(isl_multi_pw_aff_get_space(tuple));
   1633  1.1  mrg 	if (!space)
   1634  1.1  mrg 		goto error;
   1635  1.1  mrg 
   1636  1.1  mrg 	if (type == isl_dim_param) {
   1637  1.1  mrg 		if (isl_space_has_tuple_name(space, isl_dim_set) ||
   1638  1.1  mrg 		    isl_space_is_wrapping(space)) {
   1639  1.1  mrg 			isl_die(ctx, isl_error_invalid,
   1640  1.1  mrg 				"parameter tuples cannot be named or nested",
   1641  1.1  mrg 				goto error);
   1642  1.1  mrg 		}
   1643  1.1  mrg 		map = isl_map_add_dims(map, type, n);
   1644  1.1  mrg 		for (i = 0; i < n; ++i) {
   1645  1.1  mrg 			isl_id *id;
   1646  1.1  mrg 			if (!isl_space_has_dim_name(space, isl_dim_set, i))
   1647  1.1  mrg 				isl_die(ctx, isl_error_invalid,
   1648  1.1  mrg 					"parameters must be named",
   1649  1.1  mrg 					goto error);
   1650  1.1  mrg 			id = isl_space_get_dim_id(space, isl_dim_set, i);
   1651  1.1  mrg 			map = isl_map_set_dim_id(map, isl_dim_param, i, id);
   1652  1.1  mrg 		}
   1653  1.1  mrg 	} else if (type == isl_dim_in) {
   1654  1.1  mrg 		isl_set *set;
   1655  1.1  mrg 
   1656  1.1  mrg 		set = isl_set_universe(isl_space_copy(space));
   1657  1.1  mrg 		if (rational)
   1658  1.1  mrg 			set = isl_set_set_rational(set);
   1659  1.1  mrg 		set = isl_set_intersect_params(set, isl_map_params(map));
   1660  1.1  mrg 		map = isl_map_from_domain(set);
   1661  1.1  mrg 	} else {
   1662  1.1  mrg 		isl_set *set;
   1663  1.1  mrg 
   1664  1.1  mrg 		set = isl_set_universe(isl_space_copy(space));
   1665  1.1  mrg 		if (rational)
   1666  1.1  mrg 			set = isl_set_set_rational(set);
   1667  1.1  mrg 		map = isl_map_from_domain_and_range(isl_map_domain(map), set);
   1668  1.1  mrg 	}
   1669  1.1  mrg 
   1670  1.1  mrg 	for (i = 0; i < n; ++i) {
   1671  1.1  mrg 		isl_pw_aff *pa;
   1672  1.1  mrg 		isl_space *space;
   1673  1.1  mrg 		isl_aff *aff;
   1674  1.1  mrg 		isl_set *set;
   1675  1.1  mrg 		isl_map *map_i;
   1676  1.1  mrg 
   1677  1.1  mrg 		pa = isl_multi_pw_aff_get_pw_aff(tuple, i);
   1678  1.1  mrg 		space = isl_pw_aff_get_domain_space(pa);
   1679  1.1  mrg 		aff = isl_aff_zero_on_domain(isl_local_space_from_space(space));
   1680  1.1  mrg 		aff = isl_aff_add_coefficient_si(aff,
   1681  1.1  mrg 						isl_dim_in, v->n - n + i, -1);
   1682  1.1  mrg 		pa = isl_pw_aff_add(pa, isl_pw_aff_from_aff(aff));
   1683  1.1  mrg 		if (rational)
   1684  1.1  mrg 			pa = isl_pw_aff_set_rational(pa);
   1685  1.1  mrg 		set = isl_pw_aff_zero_set(pa);
   1686  1.1  mrg 		map_i = isl_map_from_range(set);
   1687  1.1  mrg 		map_i = isl_map_reset_space(map_i, isl_map_get_space(map));
   1688  1.1  mrg 		map = isl_map_intersect(map, map_i);
   1689  1.1  mrg 	}
   1690  1.1  mrg 
   1691  1.1  mrg 	isl_space_free(space);
   1692  1.1  mrg 	isl_multi_pw_aff_free(tuple);
   1693  1.1  mrg 	return map;
   1694  1.1  mrg error:
   1695  1.1  mrg 	isl_space_free(space);
   1696  1.1  mrg 	isl_multi_pw_aff_free(tuple);
   1697  1.1  mrg 	isl_map_free(map);
   1698  1.1  mrg 	return NULL;
   1699  1.1  mrg }
   1700  1.1  mrg 
   1701  1.1  mrg /* Read a tuple from "s" and add it to "map".
   1702  1.1  mrg  * The tuple is initially represented as an isl_multi_pw_aff and
   1703  1.1  mrg  * then added to "map".
   1704  1.1  mrg  */
   1705  1.1  mrg static __isl_give isl_map *read_map_tuple(__isl_keep isl_stream *s,
   1706  1.1  mrg 	__isl_take isl_map *map, enum isl_dim_type type, struct vars *v,
   1707  1.1  mrg 	int comma)
   1708  1.1  mrg {
   1709  1.1  mrg 	isl_bool rational;
   1710  1.1  mrg 	isl_multi_pw_aff *tuple;
   1711  1.1  mrg 
   1712  1.1  mrg 	rational = isl_map_is_rational(map);
   1713  1.1  mrg 	if (rational < 0)
   1714  1.1  mrg 		return isl_map_free(map);
   1715  1.1  mrg 	tuple = read_tuple(s, v, rational, comma);
   1716  1.1  mrg 	if (!tuple)
   1717  1.1  mrg 		return isl_map_free(map);
   1718  1.1  mrg 
   1719  1.1  mrg 	return map_from_tuple(tuple, map, type, v, rational);
   1720  1.1  mrg }
   1721  1.1  mrg 
   1722  1.1  mrg /* Read the parameter domain of an expression from "s" (if any) and
   1723  1.1  mrg  * check that it does not involve any constraints.
   1724  1.1  mrg  * "v" contains a description of the identifiers parsed so far
   1725  1.1  mrg  * (of which there should not be any at this point) and is extended
   1726  1.1  mrg  * by this function.
   1727  1.1  mrg  */
   1728  1.1  mrg static __isl_give isl_set *read_universe_params(__isl_keep isl_stream *s,
   1729  1.1  mrg 	struct vars *v)
   1730  1.1  mrg {
   1731  1.1  mrg 	isl_set *dom;
   1732  1.1  mrg 
   1733  1.1  mrg 	dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0));
   1734  1.1  mrg 	if (next_is_tuple(s)) {
   1735  1.1  mrg 		dom = read_map_tuple(s, dom, isl_dim_param, v, 0);
   1736  1.1  mrg 		if (isl_stream_eat(s, ISL_TOKEN_TO))
   1737  1.1  mrg 			return isl_set_free(dom);
   1738  1.1  mrg 	}
   1739  1.1  mrg 	if (!isl_set_plain_is_universe(dom))
   1740  1.1  mrg 		isl_die(s->ctx, isl_error_invalid,
   1741  1.1  mrg 			"expecting universe parameter domain",
   1742  1.1  mrg 			return isl_set_free(dom));
   1743  1.1  mrg 
   1744  1.1  mrg 	return dom;
   1745  1.1  mrg }
   1746  1.1  mrg 
   1747  1.1  mrg /* Read the parameter domain of an expression from "s" (if any),
   1748  1.1  mrg  * check that it does not involve any constraints and return its space.
   1749  1.1  mrg  * "v" contains a description of the identifiers parsed so far
   1750  1.1  mrg  * (of which there should not be any at this point) and is extended
   1751  1.1  mrg  * by this function.
   1752  1.1  mrg  */
   1753  1.1  mrg static __isl_give isl_space *read_params(__isl_keep isl_stream *s,
   1754  1.1  mrg 	struct vars *v)
   1755  1.1  mrg {
   1756  1.1  mrg 	isl_space *space;
   1757  1.1  mrg 	isl_set *set;
   1758  1.1  mrg 
   1759  1.1  mrg 	set = read_universe_params(s, v);
   1760  1.1  mrg 	space = isl_set_get_space(set);
   1761  1.1  mrg 	isl_set_free(set);
   1762  1.1  mrg 
   1763  1.1  mrg 	return space;
   1764  1.1  mrg }
   1765  1.1  mrg 
   1766  1.1  mrg /* This function is called for each element in a tuple inside read_space_tuples.
   1767  1.1  mrg  * Add a new variable to "v" and adjust "space" accordingly
   1768  1.1  mrg  * if the variable has a name.
   1769  1.1  mrg  */
   1770  1.1  mrg static __isl_give isl_space *read_tuple_id(__isl_keep isl_stream *s,
   1771  1.1  mrg 	struct vars *v, __isl_take isl_space *space, int rational, void *user)
   1772  1.1  mrg {
   1773  1.1  mrg 	struct isl_token *tok;
   1774  1.1  mrg 
   1775  1.1  mrg 	tok = next_token(s);
   1776  1.1  mrg 	if (!tok) {
   1777  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   1778  1.1  mrg 		return isl_space_free(space);
   1779  1.1  mrg 	}
   1780  1.1  mrg 
   1781  1.1  mrg 	if (tok->type == ISL_TOKEN_IDENT) {
   1782  1.1  mrg 		int n = v->n;
   1783  1.1  mrg 		int p = vars_pos(v, tok->u.s, -1);
   1784  1.1  mrg 		if (p < 0)
   1785  1.1  mrg 			goto error;
   1786  1.1  mrg 		if (p < n) {
   1787  1.1  mrg 			isl_stream_error(s, tok, "expecting fresh identifier");
   1788  1.1  mrg 			goto error;
   1789  1.1  mrg 		}
   1790  1.1  mrg 		space = space_set_last_dim_name(space, v->v->name);
   1791  1.1  mrg 	} else if (tok->type == '*') {
   1792  1.1  mrg 		if (vars_add_anon(v) < 0)
   1793  1.1  mrg 			goto error;
   1794  1.1  mrg 	} else {
   1795  1.1  mrg 		isl_stream_error(s, tok, "expecting identifier or '*'");
   1796  1.1  mrg 		goto error;
   1797  1.1  mrg 	}
   1798  1.1  mrg 
   1799  1.1  mrg 	isl_token_free(tok);
   1800  1.1  mrg 	return space;
   1801  1.1  mrg error:
   1802  1.1  mrg 	isl_token_free(tok);
   1803  1.1  mrg 	return isl_space_free(space);
   1804  1.1  mrg }
   1805  1.1  mrg 
   1806  1.1  mrg /* Given a parameter space "params", extend it with one or two tuples
   1807  1.1  mrg  * read from "s".
   1808  1.1  mrg  * "v" contains a description of the identifiers parsed so far and is extended
   1809  1.1  mrg  * by this function.
   1810  1.1  mrg  */
   1811  1.1  mrg static __isl_give isl_space *read_space_tuples(__isl_keep isl_stream *s,
   1812  1.1  mrg 	struct vars *v, __isl_take isl_space *params)
   1813  1.1  mrg {
   1814  1.1  mrg 	isl_space *space, *ran;
   1815  1.1  mrg 
   1816  1.1  mrg 	space = read_tuple_space(s, v, isl_space_copy(params), 1, 1,
   1817  1.1  mrg 				&read_tuple_id, NULL);
   1818  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) {
   1819  1.1  mrg 		ran = read_tuple_space(s, v, isl_space_copy(params), 1, 1,
   1820  1.1  mrg 					&read_tuple_id, NULL);
   1821  1.1  mrg 		space = isl_space_unwrap(isl_space_product(space, ran));
   1822  1.1  mrg 	}
   1823  1.1  mrg 	isl_space_free(params);
   1824  1.1  mrg 
   1825  1.1  mrg 	return space;
   1826  1.1  mrg }
   1827  1.1  mrg 
   1828  1.1  mrg /* Read an isl_space object from "s".
   1829  1.1  mrg  *
   1830  1.1  mrg  * First read the parameters (if any).
   1831  1.1  mrg  *
   1832  1.1  mrg  * Then check if the description is of the special form "{ : }",
   1833  1.1  mrg  * in which case it represents a parameter space.
   1834  1.1  mrg  * Otherwise, it has one or two tuples.
   1835  1.1  mrg  */
   1836  1.1  mrg __isl_give isl_space *isl_stream_read_space(__isl_keep isl_stream *s)
   1837  1.1  mrg {
   1838  1.1  mrg 	struct vars *v;
   1839  1.1  mrg 	isl_space *space;
   1840  1.1  mrg 
   1841  1.1  mrg 	v = vars_new(s->ctx);
   1842  1.1  mrg 	if (!v)
   1843  1.1  mrg 		return NULL;
   1844  1.1  mrg 	space = read_params(s, v);
   1845  1.1  mrg 
   1846  1.1  mrg 	if (isl_stream_eat(s, '{'))
   1847  1.1  mrg 		goto error;
   1848  1.1  mrg 
   1849  1.1  mrg 	if (!isl_stream_eat_if_available(s, ':'))
   1850  1.1  mrg 		space = read_space_tuples(s, v, space);
   1851  1.1  mrg 
   1852  1.1  mrg 	if (isl_stream_eat(s, '}'))
   1853  1.1  mrg 		goto error;
   1854  1.1  mrg 
   1855  1.1  mrg 	vars_free(v);
   1856  1.1  mrg 	return space;
   1857  1.1  mrg error:
   1858  1.1  mrg 	vars_free(v);
   1859  1.1  mrg 	isl_space_free(space);
   1860  1.1  mrg 	return NULL;
   1861  1.1  mrg }
   1862  1.1  mrg 
   1863  1.1  mrg #undef TYPE_BASE
   1864  1.1  mrg #define TYPE_BASE	space
   1865  1.1  mrg #include "isl_read_from_str_templ.c"
   1866  1.1  mrg 
   1867  1.1  mrg /* Given two equal-length lists of piecewise affine expression with the space
   1868  1.1  mrg  * of "set" as domain, construct a set in the same space that expresses
   1869  1.1  mrg  * that "left" and "right" satisfy the comparison "type".
   1870  1.1  mrg  *
   1871  1.1  mrg  * A space is constructed of the same dimension as the number of elements
   1872  1.1  mrg  * in the two lists.  The comparison is then expressed in a map from
   1873  1.1  mrg  * this space to itself and wrapped into a set.  Finally the two lists
   1874  1.1  mrg  * of piecewise affine expressions are plugged into this set.
   1875  1.1  mrg  *
   1876  1.1  mrg  * Let S be the space of "set" and T the constructed space.
   1877  1.1  mrg  * The lists are first changed into two isl_multi_pw_affs in S -> T and
   1878  1.1  mrg  * then combined into an isl_multi_pw_aff in S -> [T -> T],
   1879  1.1  mrg  * while the comparison is first expressed in T -> T, then [T -> T]
   1880  1.1  mrg  * and finally in S.
   1881  1.1  mrg  */
   1882  1.1  mrg static __isl_give isl_set *list_cmp(__isl_keep isl_set *set, int type,
   1883  1.1  mrg 	__isl_take isl_pw_aff_list *left, __isl_take isl_pw_aff_list *right)
   1884  1.1  mrg {
   1885  1.1  mrg 	isl_space *space;
   1886  1.1  mrg 	isl_size n;
   1887  1.1  mrg 	isl_multi_pw_aff *mpa1, *mpa2;
   1888  1.1  mrg 
   1889  1.1  mrg 	n = isl_pw_aff_list_n_pw_aff(left);
   1890  1.1  mrg 	if (!set || n < 0 || !right)
   1891  1.1  mrg 		goto error;
   1892  1.1  mrg 
   1893  1.1  mrg 	space = isl_set_get_space(set);
   1894  1.1  mrg 	space = isl_space_from_domain(space);
   1895  1.1  mrg 	space = isl_space_add_dims(space, isl_dim_out, n);
   1896  1.1  mrg 	mpa1 = isl_multi_pw_aff_from_pw_aff_list(isl_space_copy(space), left);
   1897  1.1  mrg 	mpa2 = isl_multi_pw_aff_from_pw_aff_list(isl_space_copy(space), right);
   1898  1.1  mrg 	mpa1 = isl_multi_pw_aff_range_product(mpa1, mpa2);
   1899  1.1  mrg 
   1900  1.1  mrg 	space = isl_space_range(space);
   1901  1.1  mrg 	switch (type) {
   1902  1.1  mrg 	case ISL_TOKEN_LEX_LT:
   1903  1.1  mrg 		set = isl_map_wrap(isl_map_lex_lt(space));
   1904  1.1  mrg 		break;
   1905  1.1  mrg 	case ISL_TOKEN_LEX_GT:
   1906  1.1  mrg 		set = isl_map_wrap(isl_map_lex_gt(space));
   1907  1.1  mrg 		break;
   1908  1.1  mrg 	case ISL_TOKEN_LEX_LE:
   1909  1.1  mrg 		set = isl_map_wrap(isl_map_lex_le(space));
   1910  1.1  mrg 		break;
   1911  1.1  mrg 	case ISL_TOKEN_LEX_GE:
   1912  1.1  mrg 		set = isl_map_wrap(isl_map_lex_ge(space));
   1913  1.1  mrg 		break;
   1914  1.1  mrg 	default:
   1915  1.1  mrg 		isl_multi_pw_aff_free(mpa1);
   1916  1.1  mrg 		isl_space_free(space);
   1917  1.1  mrg 		isl_die(isl_set_get_ctx(set), isl_error_internal,
   1918  1.1  mrg 			"unhandled list comparison type", return NULL);
   1919  1.1  mrg 	}
   1920  1.1  mrg 	set = isl_set_preimage_multi_pw_aff(set, mpa1);
   1921  1.1  mrg 	return set;
   1922  1.1  mrg error:
   1923  1.1  mrg 	isl_pw_aff_list_free(left);
   1924  1.1  mrg 	isl_pw_aff_list_free(right);
   1925  1.1  mrg 	return NULL;
   1926  1.1  mrg }
   1927  1.1  mrg 
   1928  1.1  mrg /* Construct constraints of the form
   1929  1.1  mrg  *
   1930  1.1  mrg  *	a op b
   1931  1.1  mrg  *
   1932  1.1  mrg  * where a is an element in "left", op is an operator of type "type" and
   1933  1.1  mrg  * b is an element in "right", add the constraints to "set" and return
   1934  1.1  mrg  * the result.
   1935  1.1  mrg  * "rational" is set if the constraints should be treated as
   1936  1.1  mrg  * a rational constraints.
   1937  1.1  mrg  *
   1938  1.1  mrg  * If "type" is the type of a comparison operator between lists
   1939  1.1  mrg  * of affine expressions, then a single (compound) constraint
   1940  1.1  mrg  * is constructed by list_cmp instead.
   1941  1.1  mrg  */
   1942  1.1  mrg static __isl_give isl_set *construct_constraints(
   1943  1.1  mrg 	__isl_take isl_set *set, int type,
   1944  1.1  mrg 	__isl_keep isl_pw_aff_list *left, __isl_keep isl_pw_aff_list *right,
   1945  1.1  mrg 	int rational)
   1946  1.1  mrg {
   1947  1.1  mrg 	isl_set *cond;
   1948  1.1  mrg 
   1949  1.1  mrg 	left = isl_pw_aff_list_copy(left);
   1950  1.1  mrg 	right = isl_pw_aff_list_copy(right);
   1951  1.1  mrg 	if (rational) {
   1952  1.1  mrg 		left = isl_pw_aff_list_set_rational(left);
   1953  1.1  mrg 		right = isl_pw_aff_list_set_rational(right);
   1954  1.1  mrg 	}
   1955  1.1  mrg 	if (is_list_comparator_type(type))
   1956  1.1  mrg 		cond = list_cmp(set, type, left, right);
   1957  1.1  mrg 	else if (type == ISL_TOKEN_LE)
   1958  1.1  mrg 		cond = isl_pw_aff_list_le_set(left, right);
   1959  1.1  mrg 	else if (type == ISL_TOKEN_GE)
   1960  1.1  mrg 		cond = isl_pw_aff_list_ge_set(left, right);
   1961  1.1  mrg 	else if (type == ISL_TOKEN_LT)
   1962  1.1  mrg 		cond = isl_pw_aff_list_lt_set(left, right);
   1963  1.1  mrg 	else if (type == ISL_TOKEN_GT)
   1964  1.1  mrg 		cond = isl_pw_aff_list_gt_set(left, right);
   1965  1.1  mrg 	else if (type == ISL_TOKEN_NE)
   1966  1.1  mrg 		cond = isl_pw_aff_list_ne_set(left, right);
   1967  1.1  mrg 	else
   1968  1.1  mrg 		cond = isl_pw_aff_list_eq_set(left, right);
   1969  1.1  mrg 
   1970  1.1  mrg 	return isl_set_intersect(set, cond);
   1971  1.1  mrg }
   1972  1.1  mrg 
   1973  1.1  mrg /* Read a constraint from "s", add it to "map" and return the result.
   1974  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   1975  1.1  mrg  * "rational" is set if the constraint should be treated as
   1976  1.1  mrg  * a rational constraint.
   1977  1.1  mrg  * The constraint read from "s" may be applied to multiple pairs
   1978  1.1  mrg  * of affine expressions and may be chained.
   1979  1.1  mrg  * In particular, a list of affine expressions is read, followed
   1980  1.1  mrg  * by a comparison operator and another list of affine expressions.
   1981  1.1  mrg  * The comparison operator is then applied to each pair of elements
   1982  1.1  mrg  * in the two lists and the results are added to "map".
   1983  1.1  mrg  * However, if the operator expects two lists of affine expressions,
   1984  1.1  mrg  * then it is applied directly to those lists and the two lists
   1985  1.1  mrg  * are required to have the same length.
   1986  1.1  mrg  * If the next token is another comparison operator, then another
   1987  1.1  mrg  * list of affine expressions is read and the process repeats.
   1988  1.1  mrg  *
   1989  1.1  mrg  * The processing is performed on a wrapped copy of "map" because
   1990  1.1  mrg  * an affine expression cannot have a binary relation as domain.
   1991  1.1  mrg  */
   1992  1.1  mrg static __isl_give isl_map *add_constraint(__isl_keep isl_stream *s,
   1993  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   1994  1.1  mrg {
   1995  1.1  mrg 	struct isl_token *tok;
   1996  1.1  mrg 	int type;
   1997  1.1  mrg 	isl_pw_aff_list *list1 = NULL, *list2 = NULL;
   1998  1.1  mrg 	isl_size n1, n2;
   1999  1.1  mrg 	isl_set *set;
   2000  1.1  mrg 
   2001  1.1  mrg 	set = isl_map_wrap(map);
   2002  1.1  mrg 	list1 = accept_affine_list(s, isl_set_get_space(set), v);
   2003  1.1  mrg 	if (!list1)
   2004  1.1  mrg 		goto error;
   2005  1.1  mrg 	tok = isl_stream_next_token(s);
   2006  1.1  mrg 	if (!is_comparator(tok)) {
   2007  1.1  mrg 		isl_stream_error(s, tok, "missing operator");
   2008  1.1  mrg 		if (tok)
   2009  1.1  mrg 			isl_stream_push_token(s, tok);
   2010  1.1  mrg 		goto error;
   2011  1.1  mrg 	}
   2012  1.1  mrg 	type = tok->type;
   2013  1.1  mrg 	isl_token_free(tok);
   2014  1.1  mrg 	for (;;) {
   2015  1.1  mrg 		list2 = accept_affine_list(s, isl_set_get_space(set), v);
   2016  1.1  mrg 		n1 = isl_pw_aff_list_n_pw_aff(list1);
   2017  1.1  mrg 		n2 = isl_pw_aff_list_n_pw_aff(list2);
   2018  1.1  mrg 		if (n1 < 0 || n2 < 0)
   2019  1.1  mrg 			goto error;
   2020  1.1  mrg 		if (is_list_comparator_type(type) && n1 != n2) {
   2021  1.1  mrg 			isl_stream_error(s, NULL,
   2022  1.1  mrg 					"list arguments not of same size");
   2023  1.1  mrg 			goto error;
   2024  1.1  mrg 		}
   2025  1.1  mrg 
   2026  1.1  mrg 		set = construct_constraints(set, type, list1, list2, rational);
   2027  1.1  mrg 		isl_pw_aff_list_free(list1);
   2028  1.1  mrg 		list1 = list2;
   2029  1.1  mrg 
   2030  1.1  mrg 		if (!next_is_comparator(s))
   2031  1.1  mrg 			break;
   2032  1.1  mrg 		tok = isl_stream_next_token(s);
   2033  1.1  mrg 		type = tok->type;
   2034  1.1  mrg 		isl_token_free(tok);
   2035  1.1  mrg 	}
   2036  1.1  mrg 	isl_pw_aff_list_free(list1);
   2037  1.1  mrg 
   2038  1.1  mrg 	return isl_set_unwrap(set);
   2039  1.1  mrg error:
   2040  1.1  mrg 	isl_pw_aff_list_free(list1);
   2041  1.1  mrg 	isl_pw_aff_list_free(list2);
   2042  1.1  mrg 	isl_set_free(set);
   2043  1.1  mrg 	return NULL;
   2044  1.1  mrg }
   2045  1.1  mrg 
   2046  1.1  mrg static __isl_give isl_map *read_exists(__isl_keep isl_stream *s,
   2047  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   2048  1.1  mrg {
   2049  1.1  mrg 	int n = v->n;
   2050  1.1  mrg 	int seen_paren = isl_stream_eat_if_available(s, '(');
   2051  1.1  mrg 
   2052  1.1  mrg 	map = isl_map_from_domain(isl_map_wrap(map));
   2053  1.1  mrg 	map = read_defined_var_list(s, v, map, rational);
   2054  1.1  mrg 
   2055  1.1  mrg 	if (isl_stream_eat(s, ':'))
   2056  1.1  mrg 		goto error;
   2057  1.1  mrg 
   2058  1.1  mrg 	map = read_formula(s, v, map, rational);
   2059  1.1  mrg 	map = isl_set_unwrap(isl_map_domain(map));
   2060  1.1  mrg 
   2061  1.1  mrg 	vars_drop(v, v->n - n);
   2062  1.1  mrg 	if (seen_paren && isl_stream_eat(s, ')'))
   2063  1.1  mrg 		goto error;
   2064  1.1  mrg 
   2065  1.1  mrg 	return map;
   2066  1.1  mrg error:
   2067  1.1  mrg 	isl_map_free(map);
   2068  1.1  mrg 	return NULL;
   2069  1.1  mrg }
   2070  1.1  mrg 
   2071  1.1  mrg /* Parse an expression between parentheses and push the result
   2072  1.1  mrg  * back on the stream.
   2073  1.1  mrg  *
   2074  1.1  mrg  * The parsed expression may be either an affine expression
   2075  1.1  mrg  * or a condition.  The first type is pushed onto the stream
   2076  1.1  mrg  * as an isl_pw_aff, while the second is pushed as an isl_map.
   2077  1.1  mrg  *
   2078  1.1  mrg  * If the initial token indicates the start of a condition,
   2079  1.1  mrg  * we parse it as such.
   2080  1.1  mrg  * Otherwise, we first parse an affine expression and push
   2081  1.1  mrg  * that onto the stream.  If the affine expression covers the
   2082  1.1  mrg  * entire expression between parentheses, we return.
   2083  1.1  mrg  * Otherwise, we assume that the affine expression is the
   2084  1.1  mrg  * start of a condition and continue parsing.
   2085  1.1  mrg  */
   2086  1.1  mrg static int resolve_paren_expr(__isl_keep isl_stream *s,
   2087  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   2088  1.1  mrg {
   2089  1.1  mrg 	struct isl_token *tok, *tok2;
   2090  1.1  mrg 	int has_paren;
   2091  1.1  mrg 	int line, col;
   2092  1.1  mrg 	isl_pw_aff *pwaff;
   2093  1.1  mrg 
   2094  1.1  mrg 	tok = isl_stream_next_token(s);
   2095  1.1  mrg 	if (!tok || tok->type != '(')
   2096  1.1  mrg 		goto error;
   2097  1.1  mrg 
   2098  1.1  mrg 	if (isl_stream_next_token_is(s, '('))
   2099  1.1  mrg 		if (resolve_paren_expr(s, v, isl_map_copy(map), rational))
   2100  1.1  mrg 			goto error;
   2101  1.1  mrg 
   2102  1.1  mrg 	if (next_is_condition_start(s)) {
   2103  1.1  mrg 		map = read_formula(s, v, map, rational);
   2104  1.1  mrg 		if (isl_stream_eat(s, ')'))
   2105  1.1  mrg 			goto error;
   2106  1.1  mrg 		tok->type = ISL_TOKEN_MAP;
   2107  1.1  mrg 		tok->u.map = map;
   2108  1.1  mrg 		isl_stream_push_token(s, tok);
   2109  1.1  mrg 		return 0;
   2110  1.1  mrg 	}
   2111  1.1  mrg 
   2112  1.1  mrg 	tok2 = isl_stream_next_token(s);
   2113  1.1  mrg 	if (!tok2)
   2114  1.1  mrg 		goto error;
   2115  1.1  mrg 	line = tok2->line;
   2116  1.1  mrg 	col = tok2->col;
   2117  1.1  mrg 	isl_stream_push_token(s, tok2);
   2118  1.1  mrg 
   2119  1.1  mrg 	pwaff = accept_affine(s, isl_space_wrap(isl_map_get_space(map)), v);
   2120  1.1  mrg 	if (!pwaff)
   2121  1.1  mrg 		goto error;
   2122  1.1  mrg 
   2123  1.1  mrg 	has_paren = isl_stream_eat_if_available(s, ')');
   2124  1.1  mrg 
   2125  1.1  mrg 	if (push_aff(s, line, col, pwaff) < 0)
   2126  1.1  mrg 		goto error;
   2127  1.1  mrg 
   2128  1.1  mrg 	if (has_paren) {
   2129  1.1  mrg 		isl_token_free(tok);
   2130  1.1  mrg 		isl_map_free(map);
   2131  1.1  mrg 		return 0;
   2132  1.1  mrg 	}
   2133  1.1  mrg 
   2134  1.1  mrg 	map = read_formula(s, v, map, rational);
   2135  1.1  mrg 	if (isl_stream_eat(s, ')'))
   2136  1.1  mrg 		goto error;
   2137  1.1  mrg 
   2138  1.1  mrg 	tok->type = ISL_TOKEN_MAP;
   2139  1.1  mrg 	tok->u.map = map;
   2140  1.1  mrg 	isl_stream_push_token(s, tok);
   2141  1.1  mrg 
   2142  1.1  mrg 	return 0;
   2143  1.1  mrg error:
   2144  1.1  mrg 	isl_token_free(tok);
   2145  1.1  mrg 	isl_map_free(map);
   2146  1.1  mrg 	return -1;
   2147  1.1  mrg }
   2148  1.1  mrg 
   2149  1.1  mrg static __isl_give isl_map *read_conjunct(__isl_keep isl_stream *s,
   2150  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   2151  1.1  mrg {
   2152  1.1  mrg 	if (isl_stream_next_token_is(s, '('))
   2153  1.1  mrg 		if (resolve_paren_expr(s, v, isl_map_copy(map), rational))
   2154  1.1  mrg 			goto error;
   2155  1.1  mrg 
   2156  1.1  mrg 	if (isl_stream_next_token_is(s, ISL_TOKEN_MAP)) {
   2157  1.1  mrg 		struct isl_token *tok;
   2158  1.1  mrg 		tok = isl_stream_next_token(s);
   2159  1.1  mrg 		if (!tok)
   2160  1.1  mrg 			goto error;
   2161  1.1  mrg 		isl_map_free(map);
   2162  1.1  mrg 		map = isl_map_copy(tok->u.map);
   2163  1.1  mrg 		isl_token_free(tok);
   2164  1.1  mrg 		return map;
   2165  1.1  mrg 	}
   2166  1.1  mrg 
   2167  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
   2168  1.1  mrg 		return read_exists(s, v, map, rational);
   2169  1.1  mrg 
   2170  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
   2171  1.1  mrg 		return map;
   2172  1.1  mrg 
   2173  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) {
   2174  1.1  mrg 		isl_space *space = isl_map_get_space(map);
   2175  1.1  mrg 		isl_map_free(map);
   2176  1.1  mrg 		return isl_map_empty(space);
   2177  1.1  mrg 	}
   2178  1.1  mrg 
   2179  1.1  mrg 	return add_constraint(s, v, map, rational);
   2180  1.1  mrg error:
   2181  1.1  mrg 	isl_map_free(map);
   2182  1.1  mrg 	return NULL;
   2183  1.1  mrg }
   2184  1.1  mrg 
   2185  1.1  mrg static __isl_give isl_map *read_conjuncts(__isl_keep isl_stream *s,
   2186  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   2187  1.1  mrg {
   2188  1.1  mrg 	isl_map *res;
   2189  1.1  mrg 	int negate;
   2190  1.1  mrg 
   2191  1.1  mrg 	negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
   2192  1.1  mrg 	res = read_conjunct(s, v, isl_map_copy(map), rational);
   2193  1.1  mrg 	if (negate)
   2194  1.1  mrg 		res = isl_map_subtract(isl_map_copy(map), res);
   2195  1.1  mrg 
   2196  1.1  mrg 	while (res && isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
   2197  1.1  mrg 		isl_map *res_i;
   2198  1.1  mrg 
   2199  1.1  mrg 		negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
   2200  1.1  mrg 		res_i = read_conjunct(s, v, isl_map_copy(map), rational);
   2201  1.1  mrg 		if (negate)
   2202  1.1  mrg 			res = isl_map_subtract(res, res_i);
   2203  1.1  mrg 		else
   2204  1.1  mrg 			res = isl_map_intersect(res, res_i);
   2205  1.1  mrg 	}
   2206  1.1  mrg 
   2207  1.1  mrg 	isl_map_free(map);
   2208  1.1  mrg 	return res;
   2209  1.1  mrg }
   2210  1.1  mrg 
   2211  1.1  mrg static __isl_give isl_map *read_disjuncts(__isl_keep isl_stream *s,
   2212  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   2213  1.1  mrg {
   2214  1.1  mrg 	isl_map *res;
   2215  1.1  mrg 
   2216  1.1  mrg 	if (isl_stream_next_token_is(s, '}'))
   2217  1.1  mrg 		return map;
   2218  1.1  mrg 
   2219  1.1  mrg 	res = read_conjuncts(s, v, isl_map_copy(map), rational);
   2220  1.1  mrg 	while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
   2221  1.1  mrg 		isl_map *res_i;
   2222  1.1  mrg 
   2223  1.1  mrg 		res_i = read_conjuncts(s, v, isl_map_copy(map), rational);
   2224  1.1  mrg 		res = isl_map_union(res, res_i);
   2225  1.1  mrg 	}
   2226  1.1  mrg 
   2227  1.1  mrg 	isl_map_free(map);
   2228  1.1  mrg 	return res;
   2229  1.1  mrg }
   2230  1.1  mrg 
   2231  1.1  mrg /* Read a first order formula from "s", add the corresponding
   2232  1.1  mrg  * constraints to "map" and return the result.
   2233  1.1  mrg  *
   2234  1.1  mrg  * In particular, read a formula of the form
   2235  1.1  mrg  *
   2236  1.1  mrg  *	a
   2237  1.1  mrg  *
   2238  1.1  mrg  * or
   2239  1.1  mrg  *
   2240  1.1  mrg  *	a implies b
   2241  1.1  mrg  *
   2242  1.1  mrg  * where a and b are disjunctions.
   2243  1.1  mrg  *
   2244  1.1  mrg  * In the first case, map is replaced by
   2245  1.1  mrg  *
   2246  1.1  mrg  *	map \cap { [..] : a }
   2247  1.1  mrg  *
   2248  1.1  mrg  * In the second case, it is replaced by
   2249  1.1  mrg  *
   2250  1.1  mrg  *	(map \setminus { [..] : a}) \cup (map \cap { [..] : b })
   2251  1.1  mrg  */
   2252  1.1  mrg static __isl_give isl_map *read_formula(__isl_keep isl_stream *s,
   2253  1.1  mrg 	struct vars *v, __isl_take isl_map *map, int rational)
   2254  1.1  mrg {
   2255  1.1  mrg 	isl_map *res;
   2256  1.1  mrg 
   2257  1.1  mrg 	res = read_disjuncts(s, v, isl_map_copy(map), rational);
   2258  1.1  mrg 
   2259  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_IMPLIES)) {
   2260  1.1  mrg 		isl_map *res2;
   2261  1.1  mrg 
   2262  1.1  mrg 		res = isl_map_subtract(isl_map_copy(map), res);
   2263  1.1  mrg 		res2 = read_disjuncts(s, v, map, rational);
   2264  1.1  mrg 		res = isl_map_union(res, res2);
   2265  1.1  mrg 	} else
   2266  1.1  mrg 		isl_map_free(map);
   2267  1.1  mrg 
   2268  1.1  mrg 	return res;
   2269  1.1  mrg }
   2270  1.1  mrg 
   2271  1.1  mrg static isl_size polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
   2272  1.1  mrg {
   2273  1.1  mrg 	isl_size n_out, n_in, n_param, n_div;
   2274  1.1  mrg 
   2275  1.1  mrg 	n_param = isl_basic_map_dim(bmap, isl_dim_param);
   2276  1.1  mrg 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   2277  1.1  mrg 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   2278  1.1  mrg 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   2279  1.1  mrg 	if (n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
   2280  1.1  mrg 		return isl_size_error;
   2281  1.1  mrg 
   2282  1.1  mrg 	if (pos < n_out)
   2283  1.1  mrg 		return 1 + n_param + n_in + pos;
   2284  1.1  mrg 	pos -= n_out;
   2285  1.1  mrg 
   2286  1.1  mrg 	if (pos < n_in)
   2287  1.1  mrg 		return 1 + n_param + pos;
   2288  1.1  mrg 	pos -= n_in;
   2289  1.1  mrg 
   2290  1.1  mrg 	if (pos < n_div)
   2291  1.1  mrg 		return 1 + n_param + n_in + n_out + pos;
   2292  1.1  mrg 	pos -= n_div;
   2293  1.1  mrg 
   2294  1.1  mrg 	if (pos < n_param)
   2295  1.1  mrg 		return 1 + pos;
   2296  1.1  mrg 
   2297  1.1  mrg 	return 0;
   2298  1.1  mrg }
   2299  1.1  mrg 
   2300  1.1  mrg static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
   2301  1.1  mrg 	__isl_keep isl_stream *s, __isl_take isl_basic_map *bmap)
   2302  1.1  mrg {
   2303  1.1  mrg 	int j;
   2304  1.1  mrg 	struct isl_token *tok;
   2305  1.1  mrg 	int type;
   2306  1.1  mrg 	int k;
   2307  1.1  mrg 	isl_int *c;
   2308  1.1  mrg 	isl_size total;
   2309  1.1  mrg 
   2310  1.1  mrg 	if (!bmap)
   2311  1.1  mrg 		return NULL;
   2312  1.1  mrg 
   2313  1.1  mrg 	tok = isl_stream_next_token(s);
   2314  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
   2315  1.1  mrg 		isl_stream_error(s, tok, "expecting coefficient");
   2316  1.1  mrg 		isl_token_free(tok);
   2317  1.1  mrg 		goto error;
   2318  1.1  mrg 	}
   2319  1.1  mrg 	if (!tok->on_new_line) {
   2320  1.1  mrg 		isl_stream_error(s, tok, "coefficient should appear on new line");
   2321  1.1  mrg 		isl_token_free(tok);
   2322  1.1  mrg 		goto error;
   2323  1.1  mrg 	}
   2324  1.1  mrg 
   2325  1.1  mrg 	type = isl_int_get_si(tok->u.v);
   2326  1.1  mrg 	isl_token_free(tok);
   2327  1.1  mrg 
   2328  1.1  mrg 	isl_assert(s->ctx, type == 0 || type == 1, goto error);
   2329  1.1  mrg 	if (type == 0) {
   2330  1.1  mrg 		k = isl_basic_map_alloc_equality(bmap);
   2331  1.1  mrg 		c = bmap->eq[k];
   2332  1.1  mrg 	} else {
   2333  1.1  mrg 		k = isl_basic_map_alloc_inequality(bmap);
   2334  1.1  mrg 		c = bmap->ineq[k];
   2335  1.1  mrg 	}
   2336  1.1  mrg 	if (k < 0)
   2337  1.1  mrg 		goto error;
   2338  1.1  mrg 
   2339  1.1  mrg 	total = isl_basic_map_dim(bmap, isl_dim_all);
   2340  1.1  mrg 	if (total < 0)
   2341  1.1  mrg 		return isl_basic_map_free(bmap);
   2342  1.1  mrg 	for (j = 0; j < 1 + total; ++j) {
   2343  1.1  mrg 		isl_size pos;
   2344  1.1  mrg 		tok = next_signed_value_on_same_line(s,
   2345  1.1  mrg 					"expecting coefficient on same line");
   2346  1.1  mrg 		if (!tok)
   2347  1.1  mrg 			goto error;
   2348  1.1  mrg 		pos = polylib_pos_to_isl_pos(bmap, j);
   2349  1.1  mrg 		if (pos >= 0)
   2350  1.1  mrg 			isl_int_set(c[pos], tok->u.v);
   2351  1.1  mrg 		isl_token_free(tok);
   2352  1.1  mrg 		if (pos < 0)
   2353  1.1  mrg 			return isl_basic_map_free(bmap);
   2354  1.1  mrg 	}
   2355  1.1  mrg 
   2356  1.1  mrg 	return bmap;
   2357  1.1  mrg error:
   2358  1.1  mrg 	isl_basic_map_free(bmap);
   2359  1.1  mrg 	return NULL;
   2360  1.1  mrg }
   2361  1.1  mrg 
   2362  1.1  mrg static __isl_give isl_basic_map *basic_map_read_polylib(
   2363  1.1  mrg 	__isl_keep isl_stream *s)
   2364  1.1  mrg {
   2365  1.1  mrg 	int i;
   2366  1.1  mrg 	struct isl_token *tok;
   2367  1.1  mrg 	struct isl_token *tok2;
   2368  1.1  mrg 	int n_row, n_col;
   2369  1.1  mrg 	int on_new_line;
   2370  1.1  mrg 	unsigned in = 0, out, local = 0;
   2371  1.1  mrg 	struct isl_basic_map *bmap = NULL;
   2372  1.1  mrg 	int nparam = 0;
   2373  1.1  mrg 
   2374  1.1  mrg 	tok = isl_stream_next_token(s);
   2375  1.1  mrg 	if (!tok) {
   2376  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   2377  1.1  mrg 		return NULL;
   2378  1.1  mrg 	}
   2379  1.1  mrg 	tok2 = isl_stream_next_token(s);
   2380  1.1  mrg 	if (!tok2) {
   2381  1.1  mrg 		isl_token_free(tok);
   2382  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   2383  1.1  mrg 		return NULL;
   2384  1.1  mrg 	}
   2385  1.1  mrg 	if (tok->type != ISL_TOKEN_VALUE || tok2->type != ISL_TOKEN_VALUE) {
   2386  1.1  mrg 		isl_token_free(tok2);
   2387  1.1  mrg 		isl_token_free(tok);
   2388  1.1  mrg 		isl_stream_error(s, NULL,
   2389  1.1  mrg 				 "expecting constraint matrix dimensions");
   2390  1.1  mrg 		return NULL;
   2391  1.1  mrg 	}
   2392  1.1  mrg 	n_row = isl_int_get_si(tok->u.v);
   2393  1.1  mrg 	n_col = isl_int_get_si(tok2->u.v);
   2394  1.1  mrg 	on_new_line = tok2->on_new_line;
   2395  1.1  mrg 	isl_token_free(tok2);
   2396  1.1  mrg 	isl_token_free(tok);
   2397  1.1  mrg 	isl_assert(s->ctx, !on_new_line, return NULL);
   2398  1.1  mrg 	isl_assert(s->ctx, n_row >= 0, return NULL);
   2399  1.1  mrg 	isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
   2400  1.1  mrg 	tok = isl_stream_next_token_on_same_line(s);
   2401  1.1  mrg 	if (tok) {
   2402  1.1  mrg 		if (tok->type != ISL_TOKEN_VALUE) {
   2403  1.1  mrg 			isl_stream_error(s, tok,
   2404  1.1  mrg 				    "expecting number of output dimensions");
   2405  1.1  mrg 			isl_token_free(tok);
   2406  1.1  mrg 			goto error;
   2407  1.1  mrg 		}
   2408  1.1  mrg 		out = isl_int_get_si(tok->u.v);
   2409  1.1  mrg 		isl_token_free(tok);
   2410  1.1  mrg 
   2411  1.1  mrg 		tok = isl_stream_next_token_on_same_line(s);
   2412  1.1  mrg 		if (!tok || tok->type != ISL_TOKEN_VALUE) {
   2413  1.1  mrg 			isl_stream_error(s, tok,
   2414  1.1  mrg 				    "expecting number of input dimensions");
   2415  1.1  mrg 			isl_token_free(tok);
   2416  1.1  mrg 			goto error;
   2417  1.1  mrg 		}
   2418  1.1  mrg 		in = isl_int_get_si(tok->u.v);
   2419  1.1  mrg 		isl_token_free(tok);
   2420  1.1  mrg 
   2421  1.1  mrg 		tok = isl_stream_next_token_on_same_line(s);
   2422  1.1  mrg 		if (!tok || tok->type != ISL_TOKEN_VALUE) {
   2423  1.1  mrg 			isl_stream_error(s, tok,
   2424  1.1  mrg 				    "expecting number of existentials");
   2425  1.1  mrg 			isl_token_free(tok);
   2426  1.1  mrg 			goto error;
   2427  1.1  mrg 		}
   2428  1.1  mrg 		local = isl_int_get_si(tok->u.v);
   2429  1.1  mrg 		isl_token_free(tok);
   2430  1.1  mrg 
   2431  1.1  mrg 		tok = isl_stream_next_token_on_same_line(s);
   2432  1.1  mrg 		if (!tok || tok->type != ISL_TOKEN_VALUE) {
   2433  1.1  mrg 			isl_stream_error(s, tok,
   2434  1.1  mrg 				    "expecting number of parameters");
   2435  1.1  mrg 			isl_token_free(tok);
   2436  1.1  mrg 			goto error;
   2437  1.1  mrg 		}
   2438  1.1  mrg 		nparam = isl_int_get_si(tok->u.v);
   2439  1.1  mrg 		isl_token_free(tok);
   2440  1.1  mrg 		if (n_col != 1 + out + in + local + nparam + 1) {
   2441  1.1  mrg 			isl_stream_error(s, NULL,
   2442  1.1  mrg 				    "dimensions don't match");
   2443  1.1  mrg 			goto error;
   2444  1.1  mrg 		}
   2445  1.1  mrg 	} else
   2446  1.1  mrg 		out = n_col - 2 - nparam;
   2447  1.1  mrg 	bmap = isl_basic_map_alloc(s->ctx, nparam, in, out, local, n_row, n_row);
   2448  1.1  mrg 	if (!bmap)
   2449  1.1  mrg 		return NULL;
   2450  1.1  mrg 
   2451  1.1  mrg 	for (i = 0; i < local; ++i) {
   2452  1.1  mrg 		int k = isl_basic_map_alloc_div(bmap);
   2453  1.1  mrg 		if (k < 0)
   2454  1.1  mrg 			goto error;
   2455  1.1  mrg 		isl_seq_clr(bmap->div[k], 1 + 1 + nparam + in + out + local);
   2456  1.1  mrg 	}
   2457  1.1  mrg 
   2458  1.1  mrg 	for (i = 0; i < n_row; ++i)
   2459  1.1  mrg 		bmap = basic_map_read_polylib_constraint(s, bmap);
   2460  1.1  mrg 
   2461  1.1  mrg 	if (!bmap)
   2462  1.1  mrg 		return NULL;
   2463  1.1  mrg 
   2464  1.1  mrg 	tok = isl_stream_next_token_on_same_line(s);
   2465  1.1  mrg 	if (tok) {
   2466  1.1  mrg 		isl_stream_error(s, tok, "unexpected extra token on line");
   2467  1.1  mrg 		isl_token_free(tok);
   2468  1.1  mrg 		goto error;
   2469  1.1  mrg 	}
   2470  1.1  mrg 
   2471  1.1  mrg 	bmap = isl_basic_map_simplify(bmap);
   2472  1.1  mrg 	bmap = isl_basic_map_finalize(bmap);
   2473  1.1  mrg 	return bmap;
   2474  1.1  mrg error:
   2475  1.1  mrg 	isl_basic_map_free(bmap);
   2476  1.1  mrg 	return NULL;
   2477  1.1  mrg }
   2478  1.1  mrg 
   2479  1.1  mrg static __isl_give isl_map *map_read_polylib(__isl_keep isl_stream *s)
   2480  1.1  mrg {
   2481  1.1  mrg 	struct isl_token *tok;
   2482  1.1  mrg 	struct isl_token *tok2;
   2483  1.1  mrg 	int i, n;
   2484  1.1  mrg 	struct isl_map *map;
   2485  1.1  mrg 
   2486  1.1  mrg 	tok = isl_stream_next_token(s);
   2487  1.1  mrg 	if (!tok) {
   2488  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   2489  1.1  mrg 		return NULL;
   2490  1.1  mrg 	}
   2491  1.1  mrg 	tok2 = isl_stream_next_token_on_same_line(s);
   2492  1.1  mrg 	if (tok2 && tok2->type == ISL_TOKEN_VALUE) {
   2493  1.1  mrg 		isl_stream_push_token(s, tok2);
   2494  1.1  mrg 		isl_stream_push_token(s, tok);
   2495  1.1  mrg 		return isl_map_from_basic_map(basic_map_read_polylib(s));
   2496  1.1  mrg 	}
   2497  1.1  mrg 	if (tok2) {
   2498  1.1  mrg 		isl_stream_error(s, tok2, "unexpected token");
   2499  1.1  mrg 		isl_stream_push_token(s, tok2);
   2500  1.1  mrg 		isl_stream_push_token(s, tok);
   2501  1.1  mrg 		return NULL;
   2502  1.1  mrg 	}
   2503  1.1  mrg 	n = isl_int_get_si(tok->u.v);
   2504  1.1  mrg 	isl_token_free(tok);
   2505  1.1  mrg 
   2506  1.1  mrg 	isl_assert(s->ctx, n >= 1, return NULL);
   2507  1.1  mrg 
   2508  1.1  mrg 	map = isl_map_from_basic_map(basic_map_read_polylib(s));
   2509  1.1  mrg 
   2510  1.1  mrg 	for (i = 1; map && i < n; ++i)
   2511  1.1  mrg 		map = isl_map_union(map,
   2512  1.1  mrg 			isl_map_from_basic_map(basic_map_read_polylib(s)));
   2513  1.1  mrg 
   2514  1.1  mrg 	return map;
   2515  1.1  mrg }
   2516  1.1  mrg 
   2517  1.1  mrg static int optional_power(__isl_keep isl_stream *s)
   2518  1.1  mrg {
   2519  1.1  mrg 	int pow;
   2520  1.1  mrg 	struct isl_token *tok;
   2521  1.1  mrg 
   2522  1.1  mrg 	tok = isl_stream_next_token(s);
   2523  1.1  mrg 	if (!tok)
   2524  1.1  mrg 		return 1;
   2525  1.1  mrg 	if (tok->type != '^') {
   2526  1.1  mrg 		isl_stream_push_token(s, tok);
   2527  1.1  mrg 		return 1;
   2528  1.1  mrg 	}
   2529  1.1  mrg 	isl_token_free(tok);
   2530  1.1  mrg 	tok = isl_stream_next_token(s);
   2531  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
   2532  1.1  mrg 		isl_stream_error(s, tok, "expecting exponent");
   2533  1.1  mrg 		if (tok)
   2534  1.1  mrg 			isl_stream_push_token(s, tok);
   2535  1.1  mrg 		return 1;
   2536  1.1  mrg 	}
   2537  1.1  mrg 	pow = isl_int_get_si(tok->u.v);
   2538  1.1  mrg 	isl_token_free(tok);
   2539  1.1  mrg 	return pow;
   2540  1.1  mrg }
   2541  1.1  mrg 
   2542  1.1  mrg static __isl_give isl_pw_qpolynomial *read_term(__isl_keep isl_stream *s,
   2543  1.1  mrg 	__isl_keep isl_map *map, struct vars *v);
   2544  1.1  mrg 
   2545  1.1  mrg static __isl_give isl_pw_qpolynomial *read_factor(__isl_keep isl_stream *s,
   2546  1.1  mrg 	__isl_keep isl_map *map, struct vars *v)
   2547  1.1  mrg {
   2548  1.1  mrg 	isl_pw_qpolynomial *pwqp;
   2549  1.1  mrg 	struct isl_token *tok;
   2550  1.1  mrg 
   2551  1.1  mrg 	tok = next_token(s);
   2552  1.1  mrg 	if (!tok) {
   2553  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   2554  1.1  mrg 		return NULL;
   2555  1.1  mrg 	}
   2556  1.1  mrg 	if (tok->type == '(') {
   2557  1.1  mrg 		int pow;
   2558  1.1  mrg 
   2559  1.1  mrg 		isl_token_free(tok);
   2560  1.1  mrg 		pwqp = read_term(s, map, v);
   2561  1.1  mrg 		if (!pwqp)
   2562  1.1  mrg 			return NULL;
   2563  1.1  mrg 		if (isl_stream_eat(s, ')'))
   2564  1.1  mrg 			goto error;
   2565  1.1  mrg 		pow = optional_power(s);
   2566  1.1  mrg 		pwqp = isl_pw_qpolynomial_pow(pwqp, pow);
   2567  1.1  mrg 	} else if (tok->type == ISL_TOKEN_VALUE) {
   2568  1.1  mrg 		struct isl_token *tok2;
   2569  1.1  mrg 		isl_qpolynomial *qp;
   2570  1.1  mrg 
   2571  1.1  mrg 		tok2 = isl_stream_next_token(s);
   2572  1.1  mrg 		if (tok2 && tok2->type == '/') {
   2573  1.1  mrg 			isl_token_free(tok2);
   2574  1.1  mrg 			tok2 = next_token(s);
   2575  1.1  mrg 			if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
   2576  1.1  mrg 				isl_stream_error(s, tok2, "expected denominator");
   2577  1.1  mrg 				isl_token_free(tok);
   2578  1.1  mrg 				isl_token_free(tok2);
   2579  1.1  mrg 				return NULL;
   2580  1.1  mrg 			}
   2581  1.1  mrg 			qp = isl_qpolynomial_rat_cst_on_domain(isl_map_get_space(map),
   2582  1.1  mrg 						    tok->u.v, tok2->u.v);
   2583  1.1  mrg 			isl_token_free(tok2);
   2584  1.1  mrg 		} else {
   2585  1.1  mrg 			isl_stream_push_token(s, tok2);
   2586  1.1  mrg 			qp = isl_qpolynomial_cst_on_domain(isl_map_get_space(map),
   2587  1.1  mrg 						tok->u.v);
   2588  1.1  mrg 		}
   2589  1.1  mrg 		isl_token_free(tok);
   2590  1.1  mrg 		pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
   2591  1.1  mrg 	} else if (tok->type == ISL_TOKEN_INFTY) {
   2592  1.1  mrg 		isl_qpolynomial *qp;
   2593  1.1  mrg 		isl_token_free(tok);
   2594  1.1  mrg 		qp = isl_qpolynomial_infty_on_domain(isl_map_get_space(map));
   2595  1.1  mrg 		pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
   2596  1.1  mrg 	} else if (tok->type == ISL_TOKEN_NAN) {
   2597  1.1  mrg 		isl_qpolynomial *qp;
   2598  1.1  mrg 		isl_token_free(tok);
   2599  1.1  mrg 		qp = isl_qpolynomial_nan_on_domain(isl_map_get_space(map));
   2600  1.1  mrg 		pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
   2601  1.1  mrg 	} else if (tok->type == ISL_TOKEN_IDENT) {
   2602  1.1  mrg 		int n = v->n;
   2603  1.1  mrg 		int pos = vars_pos(v, tok->u.s, -1);
   2604  1.1  mrg 		int pow;
   2605  1.1  mrg 		isl_qpolynomial *qp;
   2606  1.1  mrg 		if (pos < 0) {
   2607  1.1  mrg 			isl_token_free(tok);
   2608  1.1  mrg 			return NULL;
   2609  1.1  mrg 		}
   2610  1.1  mrg 		if (pos >= n) {
   2611  1.1  mrg 			vars_drop(v, v->n - n);
   2612  1.1  mrg 			isl_stream_error(s, tok, "unknown identifier");
   2613  1.1  mrg 			isl_token_free(tok);
   2614  1.1  mrg 			return NULL;
   2615  1.1  mrg 		}
   2616  1.1  mrg 		isl_token_free(tok);
   2617  1.1  mrg 		pow = optional_power(s);
   2618  1.1  mrg 		qp = isl_qpolynomial_var_pow_on_domain(isl_map_get_space(map), pos, pow);
   2619  1.1  mrg 		pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
   2620  1.1  mrg 	} else if (is_start_of_div(tok)) {
   2621  1.1  mrg 		isl_pw_aff *pwaff;
   2622  1.1  mrg 		int pow;
   2623  1.1  mrg 
   2624  1.1  mrg 		isl_stream_push_token(s, tok);
   2625  1.1  mrg 		pwaff = accept_div(s, isl_map_get_space(map), v);
   2626  1.1  mrg 		pow = optional_power(s);
   2627  1.1  mrg 		pwqp = isl_pw_qpolynomial_from_pw_aff(pwaff);
   2628  1.1  mrg 		pwqp = isl_pw_qpolynomial_pow(pwqp, pow);
   2629  1.1  mrg 	} else if (tok->type == '-') {
   2630  1.1  mrg 		isl_token_free(tok);
   2631  1.1  mrg 		pwqp = read_factor(s, map, v);
   2632  1.1  mrg 		pwqp = isl_pw_qpolynomial_neg(pwqp);
   2633  1.1  mrg 	} else {
   2634  1.1  mrg 		isl_stream_error(s, tok, "unexpected isl_token");
   2635  1.1  mrg 		isl_stream_push_token(s, tok);
   2636  1.1  mrg 		return NULL;
   2637  1.1  mrg 	}
   2638  1.1  mrg 
   2639  1.1  mrg 	if (isl_stream_eat_if_available(s, '*') ||
   2640  1.1  mrg 	    isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
   2641  1.1  mrg 		isl_pw_qpolynomial *pwqp2;
   2642  1.1  mrg 
   2643  1.1  mrg 		pwqp2 = read_factor(s, map, v);
   2644  1.1  mrg 		pwqp = isl_pw_qpolynomial_mul(pwqp, pwqp2);
   2645  1.1  mrg 	}
   2646  1.1  mrg 
   2647  1.1  mrg 	return pwqp;
   2648  1.1  mrg error:
   2649  1.1  mrg 	isl_pw_qpolynomial_free(pwqp);
   2650  1.1  mrg 	return NULL;
   2651  1.1  mrg }
   2652  1.1  mrg 
   2653  1.1  mrg static __isl_give isl_pw_qpolynomial *read_term(__isl_keep isl_stream *s,
   2654  1.1  mrg 	__isl_keep isl_map *map, struct vars *v)
   2655  1.1  mrg {
   2656  1.1  mrg 	struct isl_token *tok;
   2657  1.1  mrg 	isl_pw_qpolynomial *pwqp;
   2658  1.1  mrg 
   2659  1.1  mrg 	pwqp = read_factor(s, map, v);
   2660  1.1  mrg 
   2661  1.1  mrg 	for (;;) {
   2662  1.1  mrg 		tok = next_token(s);
   2663  1.1  mrg 		if (!tok)
   2664  1.1  mrg 			return pwqp;
   2665  1.1  mrg 
   2666  1.1  mrg 		if (tok->type == '+') {
   2667  1.1  mrg 			isl_pw_qpolynomial *pwqp2;
   2668  1.1  mrg 
   2669  1.1  mrg 			isl_token_free(tok);
   2670  1.1  mrg 			pwqp2 = read_factor(s, map, v);
   2671  1.1  mrg 			pwqp = isl_pw_qpolynomial_add(pwqp, pwqp2);
   2672  1.1  mrg 		} else if (tok->type == '-') {
   2673  1.1  mrg 			isl_pw_qpolynomial *pwqp2;
   2674  1.1  mrg 
   2675  1.1  mrg 			isl_token_free(tok);
   2676  1.1  mrg 			pwqp2 = read_factor(s, map, v);
   2677  1.1  mrg 			pwqp = isl_pw_qpolynomial_sub(pwqp, pwqp2);
   2678  1.1  mrg 		} else {
   2679  1.1  mrg 			isl_stream_push_token(s, tok);
   2680  1.1  mrg 			break;
   2681  1.1  mrg 		}
   2682  1.1  mrg 	}
   2683  1.1  mrg 
   2684  1.1  mrg 	return pwqp;
   2685  1.1  mrg }
   2686  1.1  mrg 
   2687  1.1  mrg static __isl_give isl_map *read_optional_formula(__isl_keep isl_stream *s,
   2688  1.1  mrg 	__isl_take isl_map *map, struct vars *v, int rational)
   2689  1.1  mrg {
   2690  1.1  mrg 	struct isl_token *tok;
   2691  1.1  mrg 
   2692  1.1  mrg 	tok = isl_stream_next_token(s);
   2693  1.1  mrg 	if (!tok) {
   2694  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   2695  1.1  mrg 		goto error;
   2696  1.1  mrg 	}
   2697  1.1  mrg 	if (tok->type == ':' ||
   2698  1.1  mrg 	    (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
   2699  1.1  mrg 		isl_token_free(tok);
   2700  1.1  mrg 		map = read_formula(s, v, map, rational);
   2701  1.1  mrg 	} else
   2702  1.1  mrg 		isl_stream_push_token(s, tok);
   2703  1.1  mrg 
   2704  1.1  mrg 	return map;
   2705  1.1  mrg error:
   2706  1.1  mrg 	isl_map_free(map);
   2707  1.1  mrg 	return NULL;
   2708  1.1  mrg }
   2709  1.1  mrg 
   2710  1.1  mrg static struct isl_obj obj_read_poly(__isl_keep isl_stream *s,
   2711  1.1  mrg 	__isl_take isl_map *map, struct vars *v, int n)
   2712  1.1  mrg {
   2713  1.1  mrg 	struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL };
   2714  1.1  mrg 	isl_pw_qpolynomial *pwqp;
   2715  1.1  mrg 	struct isl_set *set;
   2716  1.1  mrg 
   2717  1.1  mrg 	pwqp = read_term(s, map, v);
   2718  1.1  mrg 	map = read_optional_formula(s, map, v, 0);
   2719  1.1  mrg 	set = isl_map_range(map);
   2720  1.1  mrg 
   2721  1.1  mrg 	pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set);
   2722  1.1  mrg 
   2723  1.1  mrg 	vars_drop(v, v->n - n);
   2724  1.1  mrg 
   2725  1.1  mrg 	obj.v = pwqp;
   2726  1.1  mrg 	return obj;
   2727  1.1  mrg }
   2728  1.1  mrg 
   2729  1.1  mrg static struct isl_obj obj_read_poly_or_fold(__isl_keep isl_stream *s,
   2730  1.1  mrg 	__isl_take isl_set *set, struct vars *v, int n)
   2731  1.1  mrg {
   2732  1.1  mrg 	int min, max;
   2733  1.1  mrg 	struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
   2734  1.1  mrg 	isl_pw_qpolynomial *pwqp;
   2735  1.1  mrg 	isl_pw_qpolynomial_fold *pwf = NULL;
   2736  1.1  mrg 	enum isl_fold fold;
   2737  1.1  mrg 
   2738  1.1  mrg 	max = isl_stream_eat_if_available(s, ISL_TOKEN_MAX);
   2739  1.1  mrg 	min = !max && isl_stream_eat_if_available(s, ISL_TOKEN_MIN);
   2740  1.1  mrg 	if (!min && !max)
   2741  1.1  mrg 		return obj_read_poly(s, set, v, n);
   2742  1.1  mrg 	fold = max ? isl_fold_max : isl_fold_min;
   2743  1.1  mrg 
   2744  1.1  mrg 	if (isl_stream_eat(s, '('))
   2745  1.1  mrg 		goto error;
   2746  1.1  mrg 
   2747  1.1  mrg 	pwqp = read_term(s, set, v);
   2748  1.1  mrg 	pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(fold, pwqp);
   2749  1.1  mrg 
   2750  1.1  mrg 	while (isl_stream_eat_if_available(s, ',')) {
   2751  1.1  mrg 		isl_pw_qpolynomial_fold *pwf_i;
   2752  1.1  mrg 		pwqp = read_term(s, set, v);
   2753  1.1  mrg 		pwf_i = isl_pw_qpolynomial_fold_from_pw_qpolynomial(fold, pwqp);
   2754  1.1  mrg 		pwf = isl_pw_qpolynomial_fold_fold(pwf, pwf_i);
   2755  1.1  mrg 	}
   2756  1.1  mrg 
   2757  1.1  mrg 	if (isl_stream_eat(s, ')'))
   2758  1.1  mrg 		goto error;
   2759  1.1  mrg 
   2760  1.1  mrg 	set = read_optional_formula(s, set, v, 0);
   2761  1.1  mrg 	pwf = isl_pw_qpolynomial_fold_intersect_domain(pwf, set);
   2762  1.1  mrg 
   2763  1.1  mrg 	vars_drop(v, v->n - n);
   2764  1.1  mrg 
   2765  1.1  mrg 	obj.v = pwf;
   2766  1.1  mrg 	return obj;
   2767  1.1  mrg error:
   2768  1.1  mrg 	isl_set_free(set);
   2769  1.1  mrg 	isl_pw_qpolynomial_fold_free(pwf);
   2770  1.1  mrg 	obj.type = isl_obj_none;
   2771  1.1  mrg 	return obj;
   2772  1.1  mrg }
   2773  1.1  mrg 
   2774  1.1  mrg static int is_rational(__isl_keep isl_stream *s)
   2775  1.1  mrg {
   2776  1.1  mrg 	struct isl_token *tok;
   2777  1.1  mrg 
   2778  1.1  mrg 	tok = isl_stream_next_token(s);
   2779  1.1  mrg 	if (!tok)
   2780  1.1  mrg 		return 0;
   2781  1.1  mrg 	if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) {
   2782  1.1  mrg 		isl_token_free(tok);
   2783  1.1  mrg 		isl_stream_eat(s, ':');
   2784  1.1  mrg 		return 1;
   2785  1.1  mrg 	}
   2786  1.1  mrg 
   2787  1.1  mrg 	isl_stream_push_token(s, tok);
   2788  1.1  mrg 
   2789  1.1  mrg 	return 0;
   2790  1.1  mrg }
   2791  1.1  mrg 
   2792  1.1  mrg static struct isl_obj obj_read_body(__isl_keep isl_stream *s,
   2793  1.1  mrg 	__isl_take isl_map *map, struct vars *v)
   2794  1.1  mrg {
   2795  1.1  mrg 	struct isl_token *tok;
   2796  1.1  mrg 	struct isl_obj obj = { isl_obj_set, NULL };
   2797  1.1  mrg 	int n = v->n;
   2798  1.1  mrg 	int rational;
   2799  1.1  mrg 
   2800  1.1  mrg 	rational = is_rational(s);
   2801  1.1  mrg 	if (rational)
   2802  1.1  mrg 		map = isl_map_set_rational(map);
   2803  1.1  mrg 
   2804  1.1  mrg 	if (isl_stream_next_token_is(s, ':')) {
   2805  1.1  mrg 		obj.type = isl_obj_set;
   2806  1.1  mrg 		obj.v = read_optional_formula(s, map, v, rational);
   2807  1.1  mrg 		return obj;
   2808  1.1  mrg 	}
   2809  1.1  mrg 
   2810  1.1  mrg 	if (!next_is_tuple(s))
   2811  1.1  mrg 		return obj_read_poly_or_fold(s, map, v, n);
   2812  1.1  mrg 
   2813  1.1  mrg 	map = read_map_tuple(s, map, isl_dim_in, v, 0);
   2814  1.1  mrg 	if (!map)
   2815  1.1  mrg 		goto error;
   2816  1.1  mrg 	tok = isl_stream_next_token(s);
   2817  1.1  mrg 	if (!tok)
   2818  1.1  mrg 		goto error;
   2819  1.1  mrg 	if (tok->type == ISL_TOKEN_TO) {
   2820  1.1  mrg 		obj.type = isl_obj_map;
   2821  1.1  mrg 		isl_token_free(tok);
   2822  1.1  mrg 		if (!next_is_tuple(s)) {
   2823  1.1  mrg 			isl_set *set = isl_map_domain(map);
   2824  1.1  mrg 			return obj_read_poly_or_fold(s, set, v, n);
   2825  1.1  mrg 		}
   2826  1.1  mrg 		map = read_map_tuple(s, map, isl_dim_out, v, 0);
   2827  1.1  mrg 		if (!map)
   2828  1.1  mrg 			goto error;
   2829  1.1  mrg 	} else {
   2830  1.1  mrg 		map = isl_map_domain(map);
   2831  1.1  mrg 		isl_stream_push_token(s, tok);
   2832  1.1  mrg 	}
   2833  1.1  mrg 
   2834  1.1  mrg 	map = read_optional_formula(s, map, v, rational);
   2835  1.1  mrg 
   2836  1.1  mrg 	vars_drop(v, v->n - n);
   2837  1.1  mrg 
   2838  1.1  mrg 	obj.v = map;
   2839  1.1  mrg 	return obj;
   2840  1.1  mrg error:
   2841  1.1  mrg 	isl_map_free(map);
   2842  1.1  mrg 	obj.type = isl_obj_none;
   2843  1.1  mrg 	return obj;
   2844  1.1  mrg }
   2845  1.1  mrg 
   2846  1.1  mrg static struct isl_obj to_union(isl_ctx *ctx, struct isl_obj obj)
   2847  1.1  mrg {
   2848  1.1  mrg 	if (obj.type == isl_obj_map) {
   2849  1.1  mrg 		obj.v = isl_union_map_from_map(obj.v);
   2850  1.1  mrg 		obj.type = isl_obj_union_map;
   2851  1.1  mrg 	} else if (obj.type == isl_obj_set) {
   2852  1.1  mrg 		obj.v = isl_union_set_from_set(obj.v);
   2853  1.1  mrg 		obj.type = isl_obj_union_set;
   2854  1.1  mrg 	} else if (obj.type == isl_obj_pw_qpolynomial) {
   2855  1.1  mrg 		obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
   2856  1.1  mrg 		obj.type = isl_obj_union_pw_qpolynomial;
   2857  1.1  mrg 	} else if (obj.type == isl_obj_pw_qpolynomial_fold) {
   2858  1.1  mrg 		obj.v = isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj.v);
   2859  1.1  mrg 		obj.type = isl_obj_union_pw_qpolynomial_fold;
   2860  1.1  mrg 	} else
   2861  1.1  mrg 		isl_assert(ctx, 0, goto error);
   2862  1.1  mrg 	return obj;
   2863  1.1  mrg error:
   2864  1.1  mrg 	obj.type->free(obj.v);
   2865  1.1  mrg 	obj.type = isl_obj_none;
   2866  1.1  mrg 	return obj;
   2867  1.1  mrg }
   2868  1.1  mrg 
   2869  1.1  mrg static struct isl_obj obj_add(__isl_keep isl_stream *s,
   2870  1.1  mrg 	struct isl_obj obj1, struct isl_obj obj2)
   2871  1.1  mrg {
   2872  1.1  mrg 	if (obj2.type == isl_obj_none || !obj2.v)
   2873  1.1  mrg 		goto error;
   2874  1.1  mrg 	if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set)
   2875  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2876  1.1  mrg 	if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set)
   2877  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2878  1.1  mrg 	if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map)
   2879  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2880  1.1  mrg 	if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map)
   2881  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2882  1.1  mrg 	if (obj1.type == isl_obj_pw_qpolynomial &&
   2883  1.1  mrg 	    obj2.type == isl_obj_union_pw_qpolynomial)
   2884  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2885  1.1  mrg 	if (obj1.type == isl_obj_union_pw_qpolynomial &&
   2886  1.1  mrg 	    obj2.type == isl_obj_pw_qpolynomial)
   2887  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2888  1.1  mrg 	if (obj1.type == isl_obj_pw_qpolynomial_fold &&
   2889  1.1  mrg 	    obj2.type == isl_obj_union_pw_qpolynomial_fold)
   2890  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2891  1.1  mrg 	if (obj1.type == isl_obj_union_pw_qpolynomial_fold &&
   2892  1.1  mrg 	    obj2.type == isl_obj_pw_qpolynomial_fold)
   2893  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2894  1.1  mrg 	if (obj1.type != obj2.type) {
   2895  1.1  mrg 		isl_stream_error(s, NULL,
   2896  1.1  mrg 				"attempt to combine incompatible objects");
   2897  1.1  mrg 		goto error;
   2898  1.1  mrg 	}
   2899  1.1  mrg 	if (!obj1.type->add)
   2900  1.1  mrg 		isl_die(s->ctx, isl_error_internal,
   2901  1.1  mrg 			"combination not supported on object type", goto error);
   2902  1.1  mrg 	if (obj1.type == isl_obj_map && !isl_map_has_equal_space(obj1.v, obj2.v)) {
   2903  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2904  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2905  1.1  mrg 	}
   2906  1.1  mrg 	if (obj1.type == isl_obj_set && !isl_set_has_equal_space(obj1.v, obj2.v)) {
   2907  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2908  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2909  1.1  mrg 	}
   2910  1.1  mrg 	if (obj1.type == isl_obj_pw_qpolynomial &&
   2911  1.1  mrg 	    !isl_pw_qpolynomial_has_equal_space(obj1.v, obj2.v)) {
   2912  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2913  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2914  1.1  mrg 	}
   2915  1.1  mrg 	if (obj1.type == isl_obj_pw_qpolynomial_fold &&
   2916  1.1  mrg 	    !isl_pw_qpolynomial_fold_has_equal_space(obj1.v, obj2.v)) {
   2917  1.1  mrg 		obj1 = to_union(s->ctx, obj1);
   2918  1.1  mrg 		obj2 = to_union(s->ctx, obj2);
   2919  1.1  mrg 	}
   2920  1.1  mrg 	obj1.v = obj1.type->add(obj1.v, obj2.v);
   2921  1.1  mrg 	return obj1;
   2922  1.1  mrg error:
   2923  1.1  mrg 	obj1.type->free(obj1.v);
   2924  1.1  mrg 	obj2.type->free(obj2.v);
   2925  1.1  mrg 	obj1.type = isl_obj_none;
   2926  1.1  mrg 	obj1.v = NULL;
   2927  1.1  mrg 	return obj1;
   2928  1.1  mrg }
   2929  1.1  mrg 
   2930  1.1  mrg /* Are the first two tokens on "s", "domain" (either as a string
   2931  1.1  mrg  * or as an identifier) followed by ":"?
   2932  1.1  mrg  */
   2933  1.1  mrg static int next_is_domain_colon(__isl_keep isl_stream *s)
   2934  1.1  mrg {
   2935  1.1  mrg 	struct isl_token *tok;
   2936  1.1  mrg 	char *name;
   2937  1.1  mrg 	int res;
   2938  1.1  mrg 
   2939  1.1  mrg 	tok = isl_stream_next_token(s);
   2940  1.1  mrg 	if (!tok)
   2941  1.1  mrg 		return 0;
   2942  1.1  mrg 	if (tok->type != ISL_TOKEN_IDENT && tok->type != ISL_TOKEN_STRING) {
   2943  1.1  mrg 		isl_stream_push_token(s, tok);
   2944  1.1  mrg 		return 0;
   2945  1.1  mrg 	}
   2946  1.1  mrg 
   2947  1.1  mrg 	name = isl_token_get_str(s->ctx, tok);
   2948  1.1  mrg 	res = !strcmp(name, "domain") && isl_stream_next_token_is(s, ':');
   2949  1.1  mrg 	free(name);
   2950  1.1  mrg 
   2951  1.1  mrg 	isl_stream_push_token(s, tok);
   2952  1.1  mrg 
   2953  1.1  mrg 	return res;
   2954  1.1  mrg }
   2955  1.1  mrg 
   2956  1.1  mrg /* Do the first tokens on "s" look like a schedule?
   2957  1.1  mrg  *
   2958  1.1  mrg  * The root of a schedule is always a domain node, so the first thing
   2959  1.1  mrg  * we expect in the stream is a domain key, i.e., "domain" followed
   2960  1.1  mrg  * by ":".  If the schedule was printed in YAML flow style, then
   2961  1.1  mrg  * we additionally expect a "{" to open the outer mapping.
   2962  1.1  mrg  */
   2963  1.1  mrg static int next_is_schedule(__isl_keep isl_stream *s)
   2964  1.1  mrg {
   2965  1.1  mrg 	struct isl_token *tok;
   2966  1.1  mrg 	int is_schedule;
   2967  1.1  mrg 
   2968  1.1  mrg 	tok = isl_stream_next_token(s);
   2969  1.1  mrg 	if (!tok)
   2970  1.1  mrg 		return 0;
   2971  1.1  mrg 	if (tok->type != '{') {
   2972  1.1  mrg 		isl_stream_push_token(s, tok);
   2973  1.1  mrg 		return next_is_domain_colon(s);
   2974  1.1  mrg 	}
   2975  1.1  mrg 
   2976  1.1  mrg 	is_schedule = next_is_domain_colon(s);
   2977  1.1  mrg 	isl_stream_push_token(s, tok);
   2978  1.1  mrg 
   2979  1.1  mrg 	return is_schedule;
   2980  1.1  mrg }
   2981  1.1  mrg 
   2982  1.1  mrg /* Read an isl_schedule from "s" and store it in an isl_obj.
   2983  1.1  mrg  */
   2984  1.1  mrg static struct isl_obj schedule_read(__isl_keep isl_stream *s)
   2985  1.1  mrg {
   2986  1.1  mrg 	struct isl_obj obj;
   2987  1.1  mrg 
   2988  1.1  mrg 	obj.type = isl_obj_schedule;
   2989  1.1  mrg 	obj.v = isl_stream_read_schedule(s);
   2990  1.1  mrg 
   2991  1.1  mrg 	return obj;
   2992  1.1  mrg }
   2993  1.1  mrg 
   2994  1.1  mrg /* Read a disjunction of object bodies from "s".
   2995  1.1  mrg  * That is, read the inside of the braces, but not the braces themselves.
   2996  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   2997  1.1  mrg  * "map" contains information about the parameters.
   2998  1.1  mrg  */
   2999  1.1  mrg static struct isl_obj obj_read_disjuncts(__isl_keep isl_stream *s,
   3000  1.1  mrg 	struct vars *v, __isl_keep isl_map *map)
   3001  1.1  mrg {
   3002  1.1  mrg 	struct isl_obj obj = { isl_obj_set, NULL };
   3003  1.1  mrg 
   3004  1.1  mrg 	if (isl_stream_next_token_is(s, '}')) {
   3005  1.1  mrg 		obj.type = isl_obj_union_set;
   3006  1.1  mrg 		obj.v = isl_union_set_empty(isl_map_get_space(map));
   3007  1.1  mrg 		return obj;
   3008  1.1  mrg 	}
   3009  1.1  mrg 
   3010  1.1  mrg 	for (;;) {
   3011  1.1  mrg 		struct isl_obj o;
   3012  1.1  mrg 		o = obj_read_body(s, isl_map_copy(map), v);
   3013  1.1  mrg 		if (!obj.v)
   3014  1.1  mrg 			obj = o;
   3015  1.1  mrg 		else
   3016  1.1  mrg 			obj = obj_add(s, obj, o);
   3017  1.1  mrg 		if (obj.type == isl_obj_none || !obj.v)
   3018  1.1  mrg 			return obj;
   3019  1.1  mrg 		if (!isl_stream_eat_if_available(s, ';'))
   3020  1.1  mrg 			break;
   3021  1.1  mrg 		if (isl_stream_next_token_is(s, '}'))
   3022  1.1  mrg 			break;
   3023  1.1  mrg 	}
   3024  1.1  mrg 
   3025  1.1  mrg 	return obj;
   3026  1.1  mrg }
   3027  1.1  mrg 
   3028  1.1  mrg static struct isl_obj obj_read(__isl_keep isl_stream *s)
   3029  1.1  mrg {
   3030  1.1  mrg 	isl_map *map = NULL;
   3031  1.1  mrg 	struct isl_token *tok;
   3032  1.1  mrg 	struct vars *v = NULL;
   3033  1.1  mrg 	struct isl_obj obj = { isl_obj_set, NULL };
   3034  1.1  mrg 
   3035  1.1  mrg 	if (next_is_schedule(s))
   3036  1.1  mrg 		return schedule_read(s);
   3037  1.1  mrg 
   3038  1.1  mrg 	tok = next_token(s);
   3039  1.1  mrg 	if (!tok) {
   3040  1.1  mrg 		isl_stream_error(s, NULL, "unexpected EOF");
   3041  1.1  mrg 		goto error;
   3042  1.1  mrg 	}
   3043  1.1  mrg 	if (tok->type == ISL_TOKEN_VALUE) {
   3044  1.1  mrg 		struct isl_token *tok2;
   3045  1.1  mrg 		struct isl_map *map;
   3046  1.1  mrg 
   3047  1.1  mrg 		tok2 = isl_stream_next_token(s);
   3048  1.1  mrg 		if (!tok2 || tok2->type != ISL_TOKEN_VALUE ||
   3049  1.1  mrg 		    isl_int_is_neg(tok2->u.v)) {
   3050  1.1  mrg 			if (tok2)
   3051  1.1  mrg 				isl_stream_push_token(s, tok2);
   3052  1.1  mrg 			obj.type = isl_obj_val;
   3053  1.1  mrg 			obj.v = isl_val_int_from_isl_int(s->ctx, tok->u.v);
   3054  1.1  mrg 			isl_token_free(tok);
   3055  1.1  mrg 			return obj;
   3056  1.1  mrg 		}
   3057  1.1  mrg 		isl_stream_push_token(s, tok2);
   3058  1.1  mrg 		isl_stream_push_token(s, tok);
   3059  1.1  mrg 		map = map_read_polylib(s);
   3060  1.1  mrg 		if (!map)
   3061  1.1  mrg 			goto error;
   3062  1.1  mrg 		if (isl_map_may_be_set(map))
   3063  1.1  mrg 			obj.v = isl_map_range(map);
   3064  1.1  mrg 		else {
   3065  1.1  mrg 			obj.type = isl_obj_map;
   3066  1.1  mrg 			obj.v = map;
   3067  1.1  mrg 		}
   3068  1.1  mrg 		return obj;
   3069  1.1  mrg 	}
   3070  1.1  mrg 	v = vars_new(s->ctx);
   3071  1.1  mrg 	if (!v) {
   3072  1.1  mrg 		isl_stream_push_token(s, tok);
   3073  1.1  mrg 		goto error;
   3074  1.1  mrg 	}
   3075  1.1  mrg 	map = isl_map_universe(isl_space_params_alloc(s->ctx, 0));
   3076  1.1  mrg 	if (tok->type == '[') {
   3077  1.1  mrg 		isl_stream_push_token(s, tok);
   3078  1.1  mrg 		map = read_map_tuple(s, map, isl_dim_param, v, 0);
   3079  1.1  mrg 		if (!map)
   3080  1.1  mrg 			goto error;
   3081  1.1  mrg 		tok = isl_stream_next_token(s);
   3082  1.1  mrg 		if (!tok || tok->type != ISL_TOKEN_TO) {
   3083  1.1  mrg 			isl_stream_error(s, tok, "expecting '->'");
   3084  1.1  mrg 			if (tok)
   3085  1.1  mrg 				isl_stream_push_token(s, tok);
   3086  1.1  mrg 			goto error;
   3087  1.1  mrg 		}
   3088  1.1  mrg 		isl_token_free(tok);
   3089  1.1  mrg 		tok = isl_stream_next_token(s);
   3090  1.1  mrg 	}
   3091  1.1  mrg 	if (!tok || tok->type != '{') {
   3092  1.1  mrg 		isl_stream_error(s, tok, "expecting '{'");
   3093  1.1  mrg 		if (tok)
   3094  1.1  mrg 			isl_stream_push_token(s, tok);
   3095  1.1  mrg 		goto error;
   3096  1.1  mrg 	}
   3097  1.1  mrg 	isl_token_free(tok);
   3098  1.1  mrg 
   3099  1.1  mrg 	tok = isl_stream_next_token(s);
   3100  1.1  mrg 	if (!tok)
   3101  1.1  mrg 		;
   3102  1.1  mrg 	else if (tok->type == ISL_TOKEN_IDENT && !strcmp(tok->u.s, "Sym")) {
   3103  1.1  mrg 		isl_token_free(tok);
   3104  1.1  mrg 		if (isl_stream_eat(s, '='))
   3105  1.1  mrg 			goto error;
   3106  1.1  mrg 		map = read_map_tuple(s, map, isl_dim_param, v, 1);
   3107  1.1  mrg 		if (!map)
   3108  1.1  mrg 			goto error;
   3109  1.1  mrg 	} else
   3110  1.1  mrg 		isl_stream_push_token(s, tok);
   3111  1.1  mrg 
   3112  1.1  mrg 	obj = obj_read_disjuncts(s, v, map);
   3113  1.1  mrg 	if (obj.type == isl_obj_none || !obj.v)
   3114  1.1  mrg 		goto error;
   3115  1.1  mrg 
   3116  1.1  mrg 	tok = isl_stream_next_token(s);
   3117  1.1  mrg 	if (tok && tok->type == '}') {
   3118  1.1  mrg 		isl_token_free(tok);
   3119  1.1  mrg 	} else {
   3120  1.1  mrg 		isl_stream_error(s, tok, "unexpected isl_token");
   3121  1.1  mrg 		if (tok)
   3122  1.1  mrg 			isl_token_free(tok);
   3123  1.1  mrg 		goto error;
   3124  1.1  mrg 	}
   3125  1.1  mrg 
   3126  1.1  mrg 	vars_free(v);
   3127  1.1  mrg 	isl_map_free(map);
   3128  1.1  mrg 
   3129  1.1  mrg 	return obj;
   3130  1.1  mrg error:
   3131  1.1  mrg 	isl_map_free(map);
   3132  1.1  mrg 	obj.type->free(obj.v);
   3133  1.1  mrg 	if (v)
   3134  1.1  mrg 		vars_free(v);
   3135  1.1  mrg 	obj.v = NULL;
   3136  1.1  mrg 	return obj;
   3137  1.1  mrg }
   3138  1.1  mrg 
   3139  1.1  mrg struct isl_obj isl_stream_read_obj(__isl_keep isl_stream *s)
   3140  1.1  mrg {
   3141  1.1  mrg 	return obj_read(s);
   3142  1.1  mrg }
   3143  1.1  mrg 
   3144  1.1  mrg __isl_give isl_map *isl_stream_read_map(__isl_keep isl_stream *s)
   3145  1.1  mrg {
   3146  1.1  mrg 	struct isl_obj obj;
   3147  1.1  mrg 
   3148  1.1  mrg 	obj = obj_read(s);
   3149  1.1  mrg 	if (obj.v)
   3150  1.1  mrg 		isl_assert(s->ctx, obj.type == isl_obj_map ||
   3151  1.1  mrg 				   obj.type == isl_obj_set, goto error);
   3152  1.1  mrg 
   3153  1.1  mrg 	if (obj.type == isl_obj_set)
   3154  1.1  mrg 		obj.v = isl_map_from_range(obj.v);
   3155  1.1  mrg 
   3156  1.1  mrg 	return obj.v;
   3157  1.1  mrg error:
   3158  1.1  mrg 	obj.type->free(obj.v);
   3159  1.1  mrg 	return NULL;
   3160  1.1  mrg }
   3161  1.1  mrg 
   3162  1.1  mrg __isl_give isl_set *isl_stream_read_set(__isl_keep isl_stream *s)
   3163  1.1  mrg {
   3164  1.1  mrg 	struct isl_obj obj;
   3165  1.1  mrg 
   3166  1.1  mrg 	obj = obj_read(s);
   3167  1.1  mrg 	if (obj.v) {
   3168  1.1  mrg 		if (obj.type == isl_obj_map && isl_map_may_be_set(obj.v)) {
   3169  1.1  mrg 			obj.v = isl_map_range(obj.v);
   3170  1.1  mrg 			obj.type = isl_obj_set;
   3171  1.1  mrg 		}
   3172  1.1  mrg 		isl_assert(s->ctx, obj.type == isl_obj_set, goto error);
   3173  1.1  mrg 	}
   3174  1.1  mrg 
   3175  1.1  mrg 	return obj.v;
   3176  1.1  mrg error:
   3177  1.1  mrg 	obj.type->free(obj.v);
   3178  1.1  mrg 	return NULL;
   3179  1.1  mrg }
   3180  1.1  mrg 
   3181  1.1  mrg __isl_give isl_union_map *isl_stream_read_union_map(__isl_keep isl_stream *s)
   3182  1.1  mrg {
   3183  1.1  mrg 	struct isl_obj obj;
   3184  1.1  mrg 
   3185  1.1  mrg 	obj = obj_read(s);
   3186  1.1  mrg 	if (obj.type == isl_obj_map) {
   3187  1.1  mrg 		obj.type = isl_obj_union_map;
   3188  1.1  mrg 		obj.v = isl_union_map_from_map(obj.v);
   3189  1.1  mrg 	}
   3190  1.1  mrg 	if (obj.type == isl_obj_set) {
   3191  1.1  mrg 		obj.type = isl_obj_union_set;
   3192  1.1  mrg 		obj.v = isl_union_set_from_set(obj.v);
   3193  1.1  mrg 	}
   3194  1.1  mrg 	if (obj.v && obj.type == isl_obj_union_set &&
   3195  1.1  mrg 	    isl_union_set_is_empty(obj.v))
   3196  1.1  mrg 		obj.type = isl_obj_union_map;
   3197  1.1  mrg 	if (obj.v && obj.type != isl_obj_union_map)
   3198  1.1  mrg 		isl_die(s->ctx, isl_error_invalid, "invalid input", goto error);
   3199  1.1  mrg 
   3200  1.1  mrg 	return obj.v;
   3201  1.1  mrg error:
   3202  1.1  mrg 	obj.type->free(obj.v);
   3203  1.1  mrg 	return NULL;
   3204  1.1  mrg }
   3205  1.1  mrg 
   3206  1.1  mrg /* Extract an isl_union_set from "obj".
   3207  1.1  mrg  * This only works if the object was detected as either a set
   3208  1.1  mrg  * (in which case it is converted to a union set) or a union set.
   3209  1.1  mrg  */
   3210  1.1  mrg static __isl_give isl_union_set *extract_union_set(isl_ctx *ctx,
   3211  1.1  mrg 	struct isl_obj obj)
   3212  1.1  mrg {
   3213  1.1  mrg 	if (obj.type == isl_obj_set) {
   3214  1.1  mrg 		obj.type = isl_obj_union_set;
   3215  1.1  mrg 		obj.v = isl_union_set_from_set(obj.v);
   3216  1.1  mrg 	}
   3217  1.1  mrg 	if (obj.v)
   3218  1.1  mrg 		isl_assert(ctx, obj.type == isl_obj_union_set, goto error);
   3219  1.1  mrg 
   3220  1.1  mrg 	return obj.v;
   3221  1.1  mrg error:
   3222  1.1  mrg 	obj.type->free(obj.v);
   3223  1.1  mrg 	return NULL;
   3224  1.1  mrg }
   3225  1.1  mrg 
   3226  1.1  mrg /* Read an isl_union_set from "s".
   3227  1.1  mrg  * First read a generic object and then try and extract
   3228  1.1  mrg  * an isl_union_set from that.
   3229  1.1  mrg  */
   3230  1.1  mrg __isl_give isl_union_set *isl_stream_read_union_set(__isl_keep isl_stream *s)
   3231  1.1  mrg {
   3232  1.1  mrg 	struct isl_obj obj;
   3233  1.1  mrg 
   3234  1.1  mrg 	obj = obj_read(s);
   3235  1.1  mrg 	return extract_union_set(s->ctx, obj);
   3236  1.1  mrg }
   3237  1.1  mrg 
   3238  1.1  mrg static __isl_give isl_basic_map *isl_stream_read_basic_map(
   3239  1.1  mrg 	__isl_keep isl_stream *s)
   3240  1.1  mrg {
   3241  1.1  mrg 	struct isl_obj obj;
   3242  1.1  mrg 	struct isl_map *map;
   3243  1.1  mrg 	struct isl_basic_map *bmap;
   3244  1.1  mrg 
   3245  1.1  mrg 	obj = obj_read(s);
   3246  1.1  mrg 	if (obj.v && (obj.type != isl_obj_map && obj.type != isl_obj_set))
   3247  1.1  mrg 		isl_die(s->ctx, isl_error_invalid, "not a (basic) set or map",
   3248  1.1  mrg 			goto error);
   3249  1.1  mrg 	map = obj.v;
   3250  1.1  mrg 	if (!map)
   3251  1.1  mrg 		return NULL;
   3252  1.1  mrg 
   3253  1.1  mrg 	if (map->n > 1)
   3254  1.1  mrg 		isl_die(s->ctx, isl_error_invalid,
   3255  1.1  mrg 			"set or map description involves "
   3256  1.1  mrg 			"more than one disjunct", goto error);
   3257  1.1  mrg 
   3258  1.1  mrg 	if (map->n == 0)
   3259  1.1  mrg 		bmap = isl_basic_map_empty(isl_map_get_space(map));
   3260  1.1  mrg 	else
   3261  1.1  mrg 		bmap = isl_basic_map_copy(map->p[0]);
   3262  1.1  mrg 
   3263  1.1  mrg 	isl_map_free(map);
   3264  1.1  mrg 
   3265  1.1  mrg 	return bmap;
   3266  1.1  mrg error:
   3267  1.1  mrg 	obj.type->free(obj.v);
   3268  1.1  mrg 	return NULL;
   3269  1.1  mrg }
   3270  1.1  mrg 
   3271  1.1  mrg /* Read an isl_basic_set object from "s".
   3272  1.1  mrg  */
   3273  1.1  mrg __isl_give isl_basic_set *isl_stream_read_basic_set(__isl_keep isl_stream *s)
   3274  1.1  mrg {
   3275  1.1  mrg 	isl_basic_map *bmap;
   3276  1.1  mrg 	bmap = isl_stream_read_basic_map(s);
   3277  1.1  mrg 	if (!bmap)
   3278  1.1  mrg 		return NULL;
   3279  1.1  mrg 	if (!isl_basic_map_may_be_set(bmap))
   3280  1.1  mrg 		isl_die(s->ctx, isl_error_invalid,
   3281  1.1  mrg 			"input is not a set", goto error);
   3282  1.1  mrg 	return isl_basic_map_range(bmap);
   3283  1.1  mrg error:
   3284  1.1  mrg 	isl_basic_map_free(bmap);
   3285  1.1  mrg 	return NULL;
   3286  1.1  mrg }
   3287  1.1  mrg 
   3288  1.1  mrg __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
   3289  1.1  mrg 	FILE *input)
   3290  1.1  mrg {
   3291  1.1  mrg 	struct isl_basic_map *bmap;
   3292  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3293  1.1  mrg 	if (!s)
   3294  1.1  mrg 		return NULL;
   3295  1.1  mrg 	bmap = isl_stream_read_basic_map(s);
   3296  1.1  mrg 	isl_stream_free(s);
   3297  1.1  mrg 	return bmap;
   3298  1.1  mrg }
   3299  1.1  mrg 
   3300  1.1  mrg __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
   3301  1.1  mrg 	FILE *input)
   3302  1.1  mrg {
   3303  1.1  mrg 	isl_basic_set *bset;
   3304  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3305  1.1  mrg 	if (!s)
   3306  1.1  mrg 		return NULL;
   3307  1.1  mrg 	bset = isl_stream_read_basic_set(s);
   3308  1.1  mrg 	isl_stream_free(s);
   3309  1.1  mrg 	return bset;
   3310  1.1  mrg }
   3311  1.1  mrg 
   3312  1.1  mrg #undef TYPE_BASE
   3313  1.1  mrg #define TYPE_BASE	basic_map
   3314  1.1  mrg #include "isl_read_from_str_templ.c"
   3315  1.1  mrg 
   3316  1.1  mrg #undef TYPE_BASE
   3317  1.1  mrg #define TYPE_BASE	basic_set
   3318  1.1  mrg #include "isl_read_from_str_templ.c"
   3319  1.1  mrg 
   3320  1.1  mrg __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
   3321  1.1  mrg 	FILE *input)
   3322  1.1  mrg {
   3323  1.1  mrg 	struct isl_map *map;
   3324  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3325  1.1  mrg 	if (!s)
   3326  1.1  mrg 		return NULL;
   3327  1.1  mrg 	map = isl_stream_read_map(s);
   3328  1.1  mrg 	isl_stream_free(s);
   3329  1.1  mrg 	return map;
   3330  1.1  mrg }
   3331  1.1  mrg 
   3332  1.1  mrg #undef TYPE_BASE
   3333  1.1  mrg #define TYPE_BASE	map
   3334  1.1  mrg #include "isl_read_from_str_templ.c"
   3335  1.1  mrg 
   3336  1.1  mrg __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
   3337  1.1  mrg 	FILE *input)
   3338  1.1  mrg {
   3339  1.1  mrg 	isl_set *set;
   3340  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3341  1.1  mrg 	if (!s)
   3342  1.1  mrg 		return NULL;
   3343  1.1  mrg 	set = isl_stream_read_set(s);
   3344  1.1  mrg 	isl_stream_free(s);
   3345  1.1  mrg 	return set;
   3346  1.1  mrg }
   3347  1.1  mrg 
   3348  1.1  mrg #undef TYPE_BASE
   3349  1.1  mrg #define TYPE_BASE	set
   3350  1.1  mrg #include "isl_read_from_str_templ.c"
   3351  1.1  mrg 
   3352  1.1  mrg __isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
   3353  1.1  mrg 	FILE *input)
   3354  1.1  mrg {
   3355  1.1  mrg 	isl_union_map *umap;
   3356  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3357  1.1  mrg 	if (!s)
   3358  1.1  mrg 		return NULL;
   3359  1.1  mrg 	umap = isl_stream_read_union_map(s);
   3360  1.1  mrg 	isl_stream_free(s);
   3361  1.1  mrg 	return umap;
   3362  1.1  mrg }
   3363  1.1  mrg 
   3364  1.1  mrg #undef TYPE_BASE
   3365  1.1  mrg #define TYPE_BASE	union_map
   3366  1.1  mrg #include "isl_read_from_str_templ.c"
   3367  1.1  mrg 
   3368  1.1  mrg __isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx,
   3369  1.1  mrg 	FILE *input)
   3370  1.1  mrg {
   3371  1.1  mrg 	isl_union_set *uset;
   3372  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3373  1.1  mrg 	if (!s)
   3374  1.1  mrg 		return NULL;
   3375  1.1  mrg 	uset = isl_stream_read_union_set(s);
   3376  1.1  mrg 	isl_stream_free(s);
   3377  1.1  mrg 	return uset;
   3378  1.1  mrg }
   3379  1.1  mrg 
   3380  1.1  mrg #undef TYPE_BASE
   3381  1.1  mrg #define TYPE_BASE	union_set
   3382  1.1  mrg #include "isl_read_from_str_templ.c"
   3383  1.1  mrg 
   3384  1.1  mrg static __isl_give isl_vec *isl_vec_read_polylib(__isl_keep isl_stream *s)
   3385  1.1  mrg {
   3386  1.1  mrg 	struct isl_vec *vec = NULL;
   3387  1.1  mrg 	struct isl_token *tok;
   3388  1.1  mrg 	unsigned size;
   3389  1.1  mrg 	int j;
   3390  1.1  mrg 
   3391  1.1  mrg 	tok = isl_stream_next_token(s);
   3392  1.1  mrg 	if (!tok || tok->type != ISL_TOKEN_VALUE) {
   3393  1.1  mrg 		isl_stream_error(s, tok, "expecting vector length");
   3394  1.1  mrg 		goto error;
   3395  1.1  mrg 	}
   3396  1.1  mrg 
   3397  1.1  mrg 	size = isl_int_get_si(tok->u.v);
   3398  1.1  mrg 	isl_token_free(tok);
   3399  1.1  mrg 
   3400  1.1  mrg 	vec = isl_vec_alloc(s->ctx, size);
   3401  1.1  mrg 
   3402  1.1  mrg 	for (j = 0; j < size; ++j) {
   3403  1.1  mrg 		tok = next_signed_value(s, "expecting constant value");
   3404  1.1  mrg 		if (!tok)
   3405  1.1  mrg 			goto error;
   3406  1.1  mrg 		isl_int_set(vec->el[j], tok->u.v);
   3407  1.1  mrg 		isl_token_free(tok);
   3408  1.1  mrg 	}
   3409  1.1  mrg 
   3410  1.1  mrg 	return vec;
   3411  1.1  mrg error:
   3412  1.1  mrg 	isl_token_free(tok);
   3413  1.1  mrg 	isl_vec_free(vec);
   3414  1.1  mrg 	return NULL;
   3415  1.1  mrg }
   3416  1.1  mrg 
   3417  1.1  mrg static __isl_give isl_vec *vec_read(__isl_keep isl_stream *s)
   3418  1.1  mrg {
   3419  1.1  mrg 	return isl_vec_read_polylib(s);
   3420  1.1  mrg }
   3421  1.1  mrg 
   3422  1.1  mrg __isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input)
   3423  1.1  mrg {
   3424  1.1  mrg 	isl_vec *v;
   3425  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3426  1.1  mrg 	if (!s)
   3427  1.1  mrg 		return NULL;
   3428  1.1  mrg 	v = vec_read(s);
   3429  1.1  mrg 	isl_stream_free(s);
   3430  1.1  mrg 	return v;
   3431  1.1  mrg }
   3432  1.1  mrg 
   3433  1.1  mrg __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial(
   3434  1.1  mrg 	__isl_keep isl_stream *s)
   3435  1.1  mrg {
   3436  1.1  mrg 	struct isl_obj obj;
   3437  1.1  mrg 
   3438  1.1  mrg 	obj = obj_read(s);
   3439  1.1  mrg 	if (obj.v)
   3440  1.1  mrg 		isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial,
   3441  1.1  mrg 			   goto error);
   3442  1.1  mrg 
   3443  1.1  mrg 	return obj.v;
   3444  1.1  mrg error:
   3445  1.1  mrg 	obj.type->free(obj.v);
   3446  1.1  mrg 	return NULL;
   3447  1.1  mrg }
   3448  1.1  mrg 
   3449  1.1  mrg #undef TYPE_BASE
   3450  1.1  mrg #define TYPE_BASE	pw_qpolynomial
   3451  1.1  mrg #include "isl_read_from_str_templ.c"
   3452  1.1  mrg 
   3453  1.1  mrg __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_file(isl_ctx *ctx,
   3454  1.1  mrg 		FILE *input)
   3455  1.1  mrg {
   3456  1.1  mrg 	isl_pw_qpolynomial *pwqp;
   3457  1.1  mrg 	isl_stream *s = isl_stream_new_file(ctx, input);
   3458  1.1  mrg 	if (!s)
   3459  1.1  mrg 		return NULL;
   3460  1.1  mrg 	pwqp = isl_stream_read_pw_qpolynomial(s);
   3461  1.1  mrg 	isl_stream_free(s);
   3462  1.1  mrg 	return pwqp;
   3463  1.1  mrg }
   3464  1.1  mrg 
   3465  1.1  mrg /* Read an isl_pw_qpolynomial_fold from "s".
   3466  1.1  mrg  * First read a generic object and
   3467  1.1  mrg  * then check that it is an isl_pw_qpolynomial_fold.
   3468  1.1  mrg  */
   3469  1.1  mrg __isl_give isl_pw_qpolynomial_fold *isl_stream_read_pw_qpolynomial_fold(
   3470  1.1  mrg 	__isl_keep isl_stream *s)
   3471  1.1  mrg {
   3472  1.1  mrg 	struct isl_obj obj;
   3473  1.1  mrg 
   3474  1.1  mrg 	obj = obj_read(s);
   3475  1.1  mrg 	if (obj.v && obj.type != isl_obj_pw_qpolynomial_fold)
   3476  1.1  mrg 		isl_die(s->ctx, isl_error_invalid, "invalid input", goto error);
   3477  1.1  mrg 
   3478  1.1  mrg 	return obj.v;
   3479  1.1  mrg error:
   3480  1.1  mrg 	obj.type->free(obj.v);
   3481  1.1  mrg 	return NULL;
   3482  1.1  mrg }
   3483  1.1  mrg 
   3484  1.1  mrg #undef TYPE_BASE
   3485  1.1  mrg #define TYPE_BASE	pw_qpolynomial_fold
   3486  1.1  mrg #include "isl_read_from_str_templ.c"
   3487  1.1  mrg 
   3488  1.1  mrg /* Is the next token an identifier not in "v"?
   3489  1.1  mrg  */
   3490  1.1  mrg static int next_is_fresh_ident(__isl_keep isl_stream *s, struct vars *v)
   3491  1.1  mrg {
   3492  1.1  mrg 	int n = v->n;
   3493  1.1  mrg 	int fresh;
   3494  1.1  mrg 	struct isl_token *tok;
   3495  1.1  mrg 
   3496  1.1  mrg 	tok = isl_stream_next_token(s);
   3497  1.1  mrg 	if (!tok)
   3498  1.1  mrg 		return 0;
   3499  1.1  mrg 	fresh = tok->type == ISL_TOKEN_IDENT && vars_pos(v, tok->u.s, -1) >= n;
   3500  1.1  mrg 	isl_stream_push_token(s, tok);
   3501  1.1  mrg 
   3502  1.1  mrg 	vars_drop(v, v->n - n);
   3503  1.1  mrg 
   3504  1.1  mrg 	return fresh;
   3505  1.1  mrg }
   3506  1.1  mrg 
   3507  1.1  mrg /* First read the domain of the affine expression, which may be
   3508  1.1  mrg  * a parameter space or a set.
   3509  1.1  mrg  * The tricky part is that we don't know if the domain is a set or not,
   3510  1.1  mrg  * so when we are trying to read the domain, we may actually be reading
   3511  1.1  mrg  * the affine expression itself (defined on a parameter domains)
   3512  1.1  mrg  * If the tuple we are reading is named, we assume it's the domain.
   3513  1.1  mrg  * Also, if inside the tuple, the first thing we find is a nested tuple
   3514  1.1  mrg  * or a new identifier, we again assume it's the domain.
   3515  1.1  mrg  * Finally, if the tuple is empty, then it must be the domain
   3516  1.1  mrg  * since it does not contain an affine expression.
   3517  1.1  mrg  * Otherwise, we assume we are reading an affine expression.
   3518  1.1  mrg  */
   3519  1.1  mrg static __isl_give isl_set *read_aff_domain(__isl_keep isl_stream *s,
   3520  1.1  mrg 	__isl_take isl_set *dom, struct vars *v)
   3521  1.1  mrg {
   3522  1.1  mrg 	struct isl_token *tok, *tok2;
   3523  1.1  mrg 	int is_empty;
   3524  1.1  mrg 
   3525  1.1  mrg 	tok = isl_stream_next_token(s);
   3526  1.1  mrg 	if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
   3527  1.1  mrg 		isl_stream_push_token(s, tok);
   3528  1.1  mrg 		return read_map_tuple(s, dom, isl_dim_set, v, 0);
   3529  1.1  mrg 	}
   3530  1.1  mrg 	if (!tok || tok->type != '[') {
   3531  1.1  mrg 		isl_stream_error(s, tok, "expecting '['");
   3532  1.1  mrg 		goto error;
   3533  1.1  mrg 	}
   3534  1.1  mrg 	tok2 = isl_stream_next_token(s);
   3535  1.1  mrg 	is_empty = tok2 && tok2->type == ']';
   3536  1.1  mrg 	if (tok2)
   3537  1.1  mrg 		isl_stream_push_token(s, tok2);
   3538  1.1  mrg 	if (is_empty || next_is_tuple(s) || next_is_fresh_ident(s, v)) {
   3539  1.1  mrg 		isl_stream_push_token(s, tok);
   3540  1.1  mrg 		dom = read_map_tuple(s, dom, isl_dim_set, v, 0);
   3541  1.1  mrg 	} else
   3542  1.1  mrg 		isl_stream_push_token(s, tok);
   3543  1.1  mrg 
   3544  1.1  mrg 	return dom;
   3545  1.1  mrg error:
   3546  1.1  mrg 	if (tok)
   3547  1.1  mrg 		isl_stream_push_token(s, tok);
   3548  1.1  mrg 	isl_set_free(dom);
   3549  1.1  mrg 	return NULL;
   3550  1.1  mrg }
   3551  1.1  mrg 
   3552  1.1  mrg /* Read an affine expression from "s".
   3553  1.1  mrg  */
   3554  1.1  mrg __isl_give isl_aff *isl_stream_read_aff(__isl_keep isl_stream *s)
   3555  1.1  mrg {
   3556  1.1  mrg 	isl_aff *aff;
   3557  1.1  mrg 	isl_multi_aff *ma;
   3558  1.1  mrg 	isl_size dim;
   3559  1.1  mrg 
   3560  1.1  mrg 	ma = isl_stream_read_multi_aff(s);
   3561  1.1  mrg 	dim = isl_multi_aff_dim(ma, isl_dim_out);
   3562  1.1  mrg 	if (dim < 0)
   3563  1.1  mrg 		goto error;
   3564  1.1  mrg 	if (dim != 1)
   3565  1.1  mrg 		isl_die(s->ctx, isl_error_invalid,
   3566  1.1  mrg 			"expecting single affine expression",
   3567  1.1  mrg 			goto error);
   3568  1.1  mrg 
   3569  1.1  mrg 	aff = isl_multi_aff_get_aff(ma, 0);
   3570  1.1  mrg 	isl_multi_aff_free(ma);
   3571  1.1  mrg 	return aff;
   3572  1.1  mrg error:
   3573  1.1  mrg 	isl_multi_aff_free(ma);
   3574  1.1  mrg 	return NULL;
   3575  1.1  mrg }
   3576  1.1  mrg 
   3577  1.1  mrg /* Read a piecewise affine expression from "s" with domain (space) "dom".
   3578  1.1  mrg  */
   3579  1.1  mrg static __isl_give isl_pw_aff *read_pw_aff_with_dom(__isl_keep isl_stream *s,
   3580  1.1  mrg 	__isl_take isl_set *dom, struct vars *v)
   3581  1.1  mrg {
   3582  1.1  mrg 	isl_pw_aff *pwaff = NULL;
   3583  1.1  mrg 
   3584  1.1  mrg 	if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO))
   3585  1.1  mrg 		goto error;
   3586  1.1  mrg 
   3587  1.1  mrg 	if (isl_stream_eat(s, '['))
   3588  1.1  mrg 		goto error;
   3589  1.1  mrg 
   3590  1.1  mrg 	pwaff = accept_affine(s, isl_set_get_space(dom), v);
   3591  1.1  mrg 
   3592  1.1  mrg 	if (isl_stream_eat(s, ']'))
   3593  1.1  mrg 		goto error;
   3594  1.1  mrg 
   3595  1.1  mrg 	dom = read_optional_formula(s, dom, v, 0);
   3596  1.1  mrg 	pwaff = isl_pw_aff_intersect_domain(pwaff, dom);
   3597  1.1  mrg 
   3598  1.1  mrg 	return pwaff;
   3599  1.1  mrg error:
   3600  1.1  mrg 	isl_set_free(dom);
   3601  1.1  mrg 	isl_pw_aff_free(pwaff);
   3602  1.1  mrg 	return NULL;
   3603  1.1  mrg }
   3604  1.1  mrg 
   3605  1.1  mrg /* Read an affine expression, together with optional constraints
   3606  1.1  mrg  * on the domain from "s".  "dom" represents the initial constraints
   3607  1.1  mrg  * on the parameter domain.
   3608  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   3609  1.1  mrg  */
   3610  1.1  mrg static __isl_give isl_pw_aff *read_conditional_aff(__isl_keep isl_stream *s,
   3611  1.1  mrg 	__isl_take isl_set *dom, struct vars *v)
   3612  1.1  mrg {
   3613  1.1  mrg 	isl_set *aff_dom;
   3614  1.1  mrg 	isl_pw_aff *pa;
   3615  1.1  mrg 	int n;
   3616  1.1  mrg 
   3617  1.1  mrg 	n = v->n;
   3618  1.1  mrg 	aff_dom = read_aff_domain(s, dom, v);
   3619  1.1  mrg 	pa = read_pw_aff_with_dom(s, aff_dom, v);
   3620  1.1  mrg 	vars_drop(v, v->n - n);
   3621  1.1  mrg 
   3622  1.1  mrg 	return pa;
   3623  1.1  mrg }
   3624  1.1  mrg 
   3625  1.1  mrg #undef BASE
   3626  1.1  mrg #define BASE	aff
   3627  1.1  mrg #include "isl_stream_read_pw_with_params_templ.c"
   3628  1.1  mrg 
   3629  1.1  mrg #undef TYPE_BASE
   3630  1.1  mrg #define TYPE_BASE	aff
   3631  1.1  mrg #include "isl_read_from_str_templ.c"
   3632  1.1  mrg 
   3633  1.1  mrg #undef TYPE_BASE
   3634  1.1  mrg #define TYPE_BASE	pw_aff
   3635  1.1  mrg #include "isl_stream_read_with_params_templ.c"
   3636  1.1  mrg #include "isl_read_from_str_templ.c"
   3637  1.1  mrg 
   3638  1.1  mrg /* Given that "pa" is the element at position "pos" of a tuple
   3639  1.1  mrg  * returned by read_tuple, check that it does not involve any
   3640  1.1  mrg  * output/set dimensions (appearing at the "n" positions starting at "first"),
   3641  1.1  mrg  * remove those from the domain and replace the domain space
   3642  1.1  mrg  * with "domain_space".
   3643  1.1  mrg  *
   3644  1.1  mrg  * In particular, the result of read_tuple is of the form
   3645  1.1  mrg  * [input, output] -> [output], with anonymous domain.
   3646  1.1  mrg  * The function read_tuple accepts tuples where some output or
   3647  1.1  mrg  * set dimensions are defined in terms of other output or set dimensions
   3648  1.1  mrg  * since this function is also used to read maps.  As a special case,
   3649  1.1  mrg  * read_tuple also accepts dimensions that are defined in terms of themselves
   3650  1.1  mrg  * (i.e., that are not defined).
   3651  1.1  mrg  * These cases are not allowed here.
   3652  1.1  mrg  */
   3653  1.1  mrg static __isl_give isl_pw_aff *separate_tuple_entry(__isl_take isl_pw_aff *pa,
   3654  1.1  mrg 	int pos, unsigned first, unsigned n, __isl_take isl_space *domain_space)
   3655  1.1  mrg {
   3656  1.1  mrg 	isl_bool involves;
   3657  1.1  mrg 
   3658  1.1  mrg 	involves = isl_pw_aff_involves_dims(pa, isl_dim_in, first, pos + 1);
   3659  1.1  mrg 	if (involves < 0) {
   3660  1.1  mrg 		pa =  isl_pw_aff_free(pa);
   3661  1.1  mrg 	} else if (involves) {
   3662  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   3663  1.1  mrg 			"not an affine expression",
   3664  1.1  mrg 			pa = isl_pw_aff_free(pa));
   3665  1.1  mrg 	}
   3666  1.1  mrg 	pa = isl_pw_aff_drop_dims(pa, isl_dim_in, first, n);
   3667  1.1  mrg 	pa = isl_pw_aff_reset_domain_space(pa, domain_space);
   3668  1.1  mrg 
   3669  1.1  mrg 	return pa;
   3670  1.1  mrg }
   3671  1.1  mrg 
   3672  1.1  mrg /* Set entry "pos" of "mpa" to the corresponding entry in "tuple",
   3673  1.1  mrg  * as obtained from read_tuple().
   3674  1.1  mrg  * The "n" output dimensions also appear among the input dimensions
   3675  1.1  mrg  * at position "first".
   3676  1.1  mrg  *
   3677  1.1  mrg  * The entry is not allowed to depend on any (other) output dimensions.
   3678  1.1  mrg  */
   3679  1.1  mrg static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_tuple_entry(
   3680  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *tuple_el,
   3681  1.1  mrg 	int pos, unsigned first, unsigned n)
   3682  1.1  mrg {
   3683  1.1  mrg 	isl_space *space;
   3684  1.1  mrg 	isl_pw_aff *pa;
   3685  1.1  mrg 
   3686  1.1  mrg 	space = isl_multi_pw_aff_get_domain_space(mpa);
   3687  1.1  mrg 	pa = separate_tuple_entry(tuple_el, pos, first, n, space);
   3688  1.1  mrg 	return isl_multi_pw_aff_set_pw_aff(mpa, pos, pa);
   3689  1.1  mrg }
   3690  1.1  mrg 
   3691  1.1  mrg #undef BASE
   3692  1.1  mrg #define BASE pw_aff
   3693  1.1  mrg 
   3694  1.1  mrg #include <isl_multi_from_tuple_templ.c>
   3695  1.1  mrg 
   3696  1.1  mrg /* Read a tuple of piecewise affine expressions,
   3697  1.1  mrg  * including optional constraints on the domain from "s".
   3698  1.1  mrg  * "dom" represents the initial constraints on the domain.
   3699  1.1  mrg  *
   3700  1.1  mrg  * The input format is similar to that of a map, except that any conditions
   3701  1.1  mrg  * on the domains should be specified inside the tuple since each
   3702  1.1  mrg  * piecewise affine expression may have a different domain.
   3703  1.1  mrg  * However, additional, shared conditions can also be specified.
   3704  1.1  mrg  * This is especially useful for setting the explicit domain
   3705  1.1  mrg  * of a zero-dimensional isl_multi_pw_aff.
   3706  1.1  mrg  *
   3707  1.1  mrg  * The isl_multi_pw_aff may live in either a set or a map space.
   3708  1.1  mrg  * First read the first tuple and check if it is followed by a "->".
   3709  1.1  mrg  * If so, convert the tuple into the domain of the isl_multi_pw_aff and
   3710  1.1  mrg  * read in the next tuple.  This tuple (or the first tuple if it was
   3711  1.1  mrg  * not followed by a "->") is then converted into an isl_multi_pw_aff
   3712  1.1  mrg  * through a call to isl_multi_pw_aff_from_tuple.
   3713  1.1  mrg  * The domain of the result is intersected with the domain.
   3714  1.1  mrg  *
   3715  1.1  mrg  * Note that the last tuple may introduce new identifiers,
   3716  1.1  mrg  * but these cannot be referenced in the description of the domain.
   3717  1.1  mrg  */
   3718  1.1  mrg static __isl_give isl_multi_pw_aff *read_conditional_multi_pw_aff(
   3719  1.1  mrg 	__isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v)
   3720  1.1  mrg {
   3721  1.1  mrg 	isl_multi_pw_aff *tuple;
   3722  1.1  mrg 	isl_multi_pw_aff *mpa;
   3723  1.1  mrg 	int n = v->n;
   3724  1.1  mrg 	int n_dom;
   3725  1.1  mrg 
   3726  1.1  mrg 	n_dom = v->n;
   3727  1.1  mrg 	tuple = read_tuple(s, v, 0, 0);
   3728  1.1  mrg 	if (!tuple)
   3729  1.1  mrg 		goto error;
   3730  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) {
   3731  1.1  mrg 		isl_map *map = map_from_tuple(tuple, dom, isl_dim_in, v, 0);
   3732  1.1  mrg 		dom = isl_map_domain(map);
   3733  1.1  mrg 		n_dom = v->n;
   3734  1.1  mrg 		tuple = read_tuple(s, v, 0, 0);
   3735  1.1  mrg 		if (!tuple)
   3736  1.1  mrg 			goto error;
   3737  1.1  mrg 	}
   3738  1.1  mrg 	mpa = isl_multi_pw_aff_from_tuple(isl_set_get_space(dom), tuple);
   3739  1.1  mrg 	if (!mpa)
   3740  1.1  mrg 		dom = isl_set_free(dom);
   3741  1.1  mrg 
   3742  1.1  mrg 	vars_drop(v, v->n - n_dom);
   3743  1.1  mrg 	dom = read_optional_formula(s, dom, v, 0);
   3744  1.1  mrg 
   3745  1.1  mrg 	vars_drop(v, v->n - n);
   3746  1.1  mrg 
   3747  1.1  mrg 	mpa = isl_multi_pw_aff_intersect_domain(mpa, dom);
   3748  1.1  mrg 
   3749  1.1  mrg 	return mpa;
   3750  1.1  mrg error:
   3751  1.1  mrg 	isl_set_free(dom);
   3752  1.1  mrg 	return NULL;
   3753  1.1  mrg }
   3754  1.1  mrg 
   3755  1.1  mrg /* Read a tuple of affine expressions, together with optional constraints
   3756  1.1  mrg  * on the domain from "s".  "dom" represents the initial constraints
   3757  1.1  mrg  * on the domain.
   3758  1.1  mrg  *
   3759  1.1  mrg  * Read a tuple of piecewise affine expressions with optional constraints and
   3760  1.1  mrg  * convert the result to an isl_pw_multi_aff on the shared domain.
   3761  1.1  mrg  */
   3762  1.1  mrg static __isl_give isl_pw_multi_aff *read_conditional_multi_aff(
   3763  1.1  mrg 	__isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v)
   3764  1.1  mrg {
   3765  1.1  mrg 	isl_multi_pw_aff *mpa;
   3766  1.1  mrg 
   3767  1.1  mrg 	mpa = read_conditional_multi_pw_aff(s, dom, v);
   3768  1.1  mrg 	return isl_pw_multi_aff_from_multi_pw_aff(mpa);
   3769  1.1  mrg }
   3770  1.1  mrg 
   3771  1.1  mrg /* Read an isl_union_pw_multi_aff from "s" with parameter domain "dom".
   3772  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   3773  1.1  mrg  *
   3774  1.1  mrg  * In particular, read a sequence
   3775  1.1  mrg  * of zero or more tuples of affine expressions with optional conditions and
   3776  1.1  mrg  * add them up.
   3777  1.1  mrg  */
   3778  1.1  mrg static __isl_give isl_union_pw_multi_aff *
   3779  1.1  mrg isl_stream_read_with_params_union_pw_multi_aff(__isl_keep isl_stream *s,
   3780  1.1  mrg 	__isl_keep isl_set *dom, struct vars *v)
   3781  1.1  mrg {
   3782  1.1  mrg 	isl_union_pw_multi_aff *upma;
   3783  1.1  mrg 
   3784  1.1  mrg 	upma = isl_union_pw_multi_aff_empty(isl_set_get_space(dom));
   3785  1.1  mrg 
   3786  1.1  mrg 	do {
   3787  1.1  mrg 		isl_pw_multi_aff *pma;
   3788  1.1  mrg 		isl_union_pw_multi_aff *upma2;
   3789  1.1  mrg 
   3790  1.1  mrg 		if (isl_stream_next_token_is(s, '}'))
   3791  1.1  mrg 			break;
   3792  1.1  mrg 
   3793  1.1  mrg 		pma = read_conditional_multi_aff(s, isl_set_copy(dom), v);
   3794  1.1  mrg 		upma2 = isl_union_pw_multi_aff_from_pw_multi_aff(pma);
   3795  1.1  mrg 		upma = isl_union_pw_multi_aff_union_add(upma, upma2);
   3796  1.1  mrg 		if (!upma)
   3797  1.1  mrg 			return NULL;
   3798  1.1  mrg 	} while (isl_stream_eat_if_available(s, ';'));
   3799  1.1  mrg 
   3800  1.1  mrg 	return upma;
   3801  1.1  mrg }
   3802  1.1  mrg 
   3803  1.1  mrg #undef BASE
   3804  1.1  mrg #define BASE	multi_aff
   3805  1.1  mrg #include "isl_stream_read_pw_with_params_templ.c"
   3806  1.1  mrg 
   3807  1.1  mrg #undef TYPE_BASE
   3808  1.1  mrg #define TYPE_BASE	pw_multi_aff
   3809  1.1  mrg #include "isl_stream_read_with_params_templ.c"
   3810  1.1  mrg #include "isl_read_from_str_templ.c"
   3811  1.1  mrg 
   3812  1.1  mrg #undef TYPE_BASE
   3813  1.1  mrg #define TYPE_BASE	union_pw_multi_aff
   3814  1.1  mrg #include "isl_stream_read_with_params_templ.c"
   3815  1.1  mrg #include "isl_read_from_str_templ.c"
   3816  1.1  mrg 
   3817  1.1  mrg #undef BASE
   3818  1.1  mrg #define BASE val
   3819  1.1  mrg 
   3820  1.1  mrg #include <isl_multi_read_no_explicit_domain_templ.c>
   3821  1.1  mrg 
   3822  1.1  mrg #undef BASE
   3823  1.1  mrg #define BASE id
   3824  1.1  mrg 
   3825  1.1  mrg #include <isl_multi_read_no_explicit_domain_templ.c>
   3826  1.1  mrg 
   3827  1.1  mrg /* Set entry "pos" of "ma" to the corresponding entry in "tuple",
   3828  1.1  mrg  * as obtained from read_tuple().
   3829  1.1  mrg  * The "n" output dimensions also appear among the input dimensions
   3830  1.1  mrg  * at position "first".
   3831  1.1  mrg  *
   3832  1.1  mrg  * The entry is not allowed to depend on any (other) output dimensions.
   3833  1.1  mrg  */
   3834  1.1  mrg static __isl_give isl_multi_aff *isl_multi_aff_set_tuple_entry(
   3835  1.1  mrg 	__isl_take isl_multi_aff *ma, __isl_take isl_pw_aff *tuple_el,
   3836  1.1  mrg 	int pos, unsigned first, unsigned n)
   3837  1.1  mrg {
   3838  1.1  mrg 	isl_space *space;
   3839  1.1  mrg 	isl_pw_aff *pa;
   3840  1.1  mrg 	isl_aff *aff;
   3841  1.1  mrg 
   3842  1.1  mrg 	space = isl_multi_aff_get_domain_space(ma);
   3843  1.1  mrg 	pa = separate_tuple_entry(tuple_el, pos, first, n, space);
   3844  1.1  mrg 	aff = isl_pw_aff_as_aff(pa);
   3845  1.1  mrg 	return isl_multi_aff_set_aff(ma, pos, aff);
   3846  1.1  mrg }
   3847  1.1  mrg 
   3848  1.1  mrg #undef BASE
   3849  1.1  mrg #define BASE aff
   3850  1.1  mrg 
   3851  1.1  mrg #include <isl_multi_from_tuple_templ.c>
   3852  1.1  mrg 
   3853  1.1  mrg /* Read a multi-affine expression from "s".
   3854  1.1  mrg  * If the multi-affine expression has a domain, then the tuple
   3855  1.1  mrg  * representing this domain cannot involve any affine expressions.
   3856  1.1  mrg  * The tuple representing the actual expressions needs to consist
   3857  1.1  mrg  * of only affine expressions.
   3858  1.1  mrg  */
   3859  1.1  mrg __isl_give isl_multi_aff *isl_stream_read_multi_aff(__isl_keep isl_stream *s)
   3860  1.1  mrg {
   3861  1.1  mrg 	struct vars *v;
   3862  1.1  mrg 	isl_multi_pw_aff *tuple = NULL;
   3863  1.1  mrg 	isl_space *dom_space = NULL;
   3864  1.1  mrg 	isl_multi_aff *ma = NULL;
   3865  1.1  mrg 
   3866  1.1  mrg 	v = vars_new(s->ctx);
   3867  1.1  mrg 	if (!v)
   3868  1.1  mrg 		return NULL;
   3869  1.1  mrg 
   3870  1.1  mrg 	dom_space = read_params(s, v);
   3871  1.1  mrg 	if (!dom_space)
   3872  1.1  mrg 		goto error;
   3873  1.1  mrg 	if (isl_stream_eat(s, '{'))
   3874  1.1  mrg 		goto error;
   3875  1.1  mrg 
   3876  1.1  mrg 	tuple = read_tuple(s, v, 0, 0);
   3877  1.1  mrg 	if (!tuple)
   3878  1.1  mrg 		goto error;
   3879  1.1  mrg 	if (isl_stream_eat_if_available(s, ISL_TOKEN_TO)) {
   3880  1.1  mrg 		isl_space *space;
   3881  1.1  mrg 		isl_bool has_expr;
   3882  1.1  mrg 
   3883  1.1  mrg 		has_expr = tuple_has_expr(tuple);
   3884  1.1  mrg 		if (has_expr < 0)
   3885  1.1  mrg 			goto error;
   3886  1.1  mrg 		if (has_expr)
   3887  1.1  mrg 			isl_die(s->ctx, isl_error_invalid,
   3888  1.1  mrg 				"expecting universe domain", goto error);
   3889  1.1  mrg 		space = isl_space_range(isl_multi_pw_aff_get_space(tuple));
   3890  1.1  mrg 		dom_space = isl_space_align_params(space, dom_space);
   3891  1.1  mrg 		isl_multi_pw_aff_free(tuple);
   3892  1.1  mrg 		tuple = read_tuple(s, v, 0, 0);
   3893  1.1  mrg 		if (!tuple)
   3894  1.1  mrg 			goto error;
   3895  1.1  mrg 	}
   3896  1.1  mrg 
   3897  1.1  mrg 	if (isl_stream_eat(s, '}'))
   3898  1.1  mrg 		goto error;
   3899  1.1  mrg 
   3900  1.1  mrg 	ma = isl_multi_aff_from_tuple(dom_space, tuple);
   3901  1.1  mrg 
   3902  1.1  mrg 	vars_free(v);
   3903  1.1  mrg 	return ma;
   3904  1.1  mrg error:
   3905  1.1  mrg 	isl_multi_pw_aff_free(tuple);
   3906  1.1  mrg 	vars_free(v);
   3907  1.1  mrg 	isl_space_free(dom_space);
   3908  1.1  mrg 	isl_multi_aff_free(ma);
   3909  1.1  mrg 	return NULL;
   3910  1.1  mrg }
   3911  1.1  mrg 
   3912  1.1  mrg #undef TYPE_BASE
   3913  1.1  mrg #define TYPE_BASE	multi_aff
   3914  1.1  mrg #include "isl_read_from_str_templ.c"
   3915  1.1  mrg 
   3916  1.1  mrg /* Read an isl_multi_pw_aff from "s" with parameter domain "dom"..
   3917  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   3918  1.1  mrg  */
   3919  1.1  mrg static __isl_give isl_multi_pw_aff *isl_stream_read_with_params_multi_pw_aff(
   3920  1.1  mrg 	__isl_keep isl_stream *s, __isl_keep isl_set *dom, struct vars *v)
   3921  1.1  mrg {
   3922  1.1  mrg 	return read_conditional_multi_pw_aff(s, isl_set_copy(dom), v);
   3923  1.1  mrg }
   3924  1.1  mrg 
   3925  1.1  mrg #undef TYPE_BASE
   3926  1.1  mrg #define TYPE_BASE	multi_pw_aff
   3927  1.1  mrg #include "isl_stream_read_with_params_templ.c"
   3928  1.1  mrg #include "isl_read_from_str_templ.c"
   3929  1.1  mrg 
   3930  1.1  mrg /* Read the body of an isl_union_pw_aff from "s" with parameter domain "dom".
   3931  1.1  mrg  */
   3932  1.1  mrg static __isl_give isl_union_pw_aff *read_union_pw_aff_with_dom(
   3933  1.1  mrg 	__isl_keep isl_stream *s, __isl_take isl_set *dom, struct vars *v)
   3934  1.1  mrg {
   3935  1.1  mrg 	isl_pw_aff *pa;
   3936  1.1  mrg 	isl_union_pw_aff *upa = NULL;
   3937  1.1  mrg 	isl_set *aff_dom;
   3938  1.1  mrg 	int n;
   3939  1.1  mrg 
   3940  1.1  mrg 	n = v->n;
   3941  1.1  mrg 	aff_dom = read_aff_domain(s, isl_set_copy(dom), v);
   3942  1.1  mrg 	pa = read_pw_aff_with_dom(s, aff_dom, v);
   3943  1.1  mrg 	vars_drop(v, v->n - n);
   3944  1.1  mrg 
   3945  1.1  mrg 	upa = isl_union_pw_aff_from_pw_aff(pa);
   3946  1.1  mrg 
   3947  1.1  mrg 	while (isl_stream_eat_if_available(s, ';')) {
   3948  1.1  mrg 		isl_pw_aff *pa_i;
   3949  1.1  mrg 		isl_union_pw_aff *upa_i;
   3950  1.1  mrg 
   3951  1.1  mrg 		n = v->n;
   3952  1.1  mrg 		aff_dom = read_aff_domain(s, isl_set_copy(dom), v);
   3953  1.1  mrg 		pa_i = read_pw_aff_with_dom(s, aff_dom, v);
   3954  1.1  mrg 		vars_drop(v, v->n - n);
   3955  1.1  mrg 
   3956  1.1  mrg 		upa_i = isl_union_pw_aff_from_pw_aff(pa_i);
   3957  1.1  mrg 		upa = isl_union_pw_aff_union_add(upa, upa_i);
   3958  1.1  mrg 	}
   3959  1.1  mrg 
   3960  1.1  mrg 	isl_set_free(dom);
   3961  1.1  mrg 	return upa;
   3962  1.1  mrg }
   3963  1.1  mrg 
   3964  1.1  mrg /* Read an isl_union_pw_aff from "s" with parameter domain "dom".
   3965  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   3966  1.1  mrg  */
   3967  1.1  mrg static __isl_give isl_union_pw_aff *isl_stream_read_with_params_union_pw_aff(
   3968  1.1  mrg 	__isl_keep isl_stream *s, __isl_keep isl_set *dom, struct vars *v)
   3969  1.1  mrg {
   3970  1.1  mrg 	return read_union_pw_aff_with_dom(s, isl_set_copy(dom), v);
   3971  1.1  mrg }
   3972  1.1  mrg 
   3973  1.1  mrg #undef TYPE_BASE
   3974  1.1  mrg #define TYPE_BASE	union_pw_aff
   3975  1.1  mrg #include "isl_stream_read_with_params_templ.c"
   3976  1.1  mrg #include "isl_read_from_str_templ.c"
   3977  1.1  mrg 
   3978  1.1  mrg /* This function is called for each element in a tuple inside
   3979  1.1  mrg  * isl_stream_read_multi_union_pw_aff.
   3980  1.1  mrg  *
   3981  1.1  mrg  * Read a '{', the union piecewise affine expression body and a '}' and
   3982  1.1  mrg  * add the isl_union_pw_aff to *list.
   3983  1.1  mrg  */
   3984  1.1  mrg static __isl_give isl_space *read_union_pw_aff_el(__isl_keep isl_stream *s,
   3985  1.1  mrg 	struct vars *v, __isl_take isl_space *space, int rational, void *user)
   3986  1.1  mrg {
   3987  1.1  mrg 	isl_set *dom;
   3988  1.1  mrg 	isl_union_pw_aff *upa;
   3989  1.1  mrg 	isl_union_pw_aff_list **list = (isl_union_pw_aff_list **) user;
   3990  1.1  mrg 
   3991  1.1  mrg 	dom = isl_set_universe(isl_space_params(isl_space_copy(space)));
   3992  1.1  mrg 	if (isl_stream_eat(s, '{'))
   3993  1.1  mrg 		goto error;
   3994  1.1  mrg 	upa = read_union_pw_aff_with_dom(s, dom, v);
   3995  1.1  mrg 	*list = isl_union_pw_aff_list_add(*list, upa);
   3996  1.1  mrg 	if (isl_stream_eat(s, '}'))
   3997  1.1  mrg 		return isl_space_free(space);
   3998  1.1  mrg 	if (!*list)
   3999  1.1  mrg 		return isl_space_free(space);
   4000  1.1  mrg 	return space;
   4001  1.1  mrg error:
   4002  1.1  mrg 	isl_set_free(dom);
   4003  1.1  mrg 	return isl_space_free(space);
   4004  1.1  mrg }
   4005  1.1  mrg 
   4006  1.1  mrg /* Do the next tokens in "s" correspond to an empty tuple?
   4007  1.1  mrg  * In particular, does the stream start with a '[', followed by a ']',
   4008  1.1  mrg  * not followed by a "->"?
   4009  1.1  mrg  */
   4010  1.1  mrg static int next_is_empty_tuple(__isl_keep isl_stream *s)
   4011  1.1  mrg {
   4012  1.1  mrg 	struct isl_token *tok, *tok2, *tok3;
   4013  1.1  mrg 	int is_empty_tuple = 0;
   4014  1.1  mrg 
   4015  1.1  mrg 	tok = isl_stream_next_token(s);
   4016  1.1  mrg 	if (!tok)
   4017  1.1  mrg 		return 0;
   4018  1.1  mrg 	if (tok->type != '[') {
   4019  1.1  mrg 		isl_stream_push_token(s, tok);
   4020  1.1  mrg 		return 0;
   4021  1.1  mrg 	}
   4022  1.1  mrg 
   4023  1.1  mrg 	tok2 = isl_stream_next_token(s);
   4024  1.1  mrg 	if (tok2 && tok2->type == ']') {
   4025  1.1  mrg 		tok3 = isl_stream_next_token(s);
   4026  1.1  mrg 		is_empty_tuple = !tok || tok->type != ISL_TOKEN_TO;
   4027  1.1  mrg 		if (tok3)
   4028  1.1  mrg 			isl_stream_push_token(s, tok3);
   4029  1.1  mrg 	}
   4030  1.1  mrg 	if (tok2)
   4031  1.1  mrg 		isl_stream_push_token(s, tok2);
   4032  1.1  mrg 	isl_stream_push_token(s, tok);
   4033  1.1  mrg 
   4034  1.1  mrg 	return is_empty_tuple;
   4035  1.1  mrg }
   4036  1.1  mrg 
   4037  1.1  mrg /* Do the next tokens in "s" correspond to a tuple of parameters?
   4038  1.1  mrg  * In particular, does the stream start with a '[' that is not
   4039  1.1  mrg  * followed by a '{' or a nested tuple?
   4040  1.1  mrg  */
   4041  1.1  mrg static int next_is_param_tuple(__isl_keep isl_stream *s)
   4042  1.1  mrg {
   4043  1.1  mrg 	struct isl_token *tok, *tok2;
   4044  1.1  mrg 	int is_tuple;
   4045  1.1  mrg 
   4046  1.1  mrg 	tok = isl_stream_next_token(s);
   4047  1.1  mrg 	if (!tok)
   4048  1.1  mrg 		return 0;
   4049  1.1  mrg 	if (tok->type != '[' || next_is_tuple(s)) {
   4050  1.1  mrg 		isl_stream_push_token(s, tok);
   4051  1.1  mrg 		return 0;
   4052  1.1  mrg 	}
   4053  1.1  mrg 
   4054  1.1  mrg 	tok2 = isl_stream_next_token(s);
   4055  1.1  mrg 	is_tuple = tok2 && tok2->type != '{';
   4056  1.1  mrg 	if (tok2)
   4057  1.1  mrg 		isl_stream_push_token(s, tok2);
   4058  1.1  mrg 	isl_stream_push_token(s, tok);
   4059  1.1  mrg 
   4060  1.1  mrg 	return is_tuple;
   4061  1.1  mrg }
   4062  1.1  mrg 
   4063  1.1  mrg /* Read the core of a body of an isl_multi_union_pw_aff from "s",
   4064  1.1  mrg  * i.e., everything except the parameter specification and
   4065  1.1  mrg  * without shared domain constraints.
   4066  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   4067  1.1  mrg  * The parameters, if any, are specified by "space".
   4068  1.1  mrg  *
   4069  1.1  mrg  * The body is of the form
   4070  1.1  mrg  *
   4071  1.1  mrg  *	[{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }]
   4072  1.1  mrg  *
   4073  1.1  mrg  * Read the tuple, collecting the individual isl_union_pw_aff
   4074  1.1  mrg  * elements in a list and construct the result from the tuple space and
   4075  1.1  mrg  * the list.
   4076  1.1  mrg  */
   4077  1.1  mrg static __isl_give isl_multi_union_pw_aff *read_multi_union_pw_aff_body_core(
   4078  1.1  mrg 	__isl_keep isl_stream *s, struct vars *v, __isl_take isl_space *space)
   4079  1.1  mrg {
   4080  1.1  mrg 	isl_union_pw_aff_list *list;
   4081  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   4082  1.1  mrg 
   4083  1.1  mrg 	list = isl_union_pw_aff_list_alloc(s->ctx, 0);
   4084  1.1  mrg 	space = read_tuple_space(s, v, space, 1, 0,
   4085  1.1  mrg 				&read_union_pw_aff_el, &list);
   4086  1.1  mrg 	mupa = isl_multi_union_pw_aff_from_union_pw_aff_list(space, list);
   4087  1.1  mrg 
   4088  1.1  mrg 	return mupa;
   4089  1.1  mrg }
   4090  1.1  mrg 
   4091  1.1  mrg /* Read the body of an isl_union_set from "s",
   4092  1.1  mrg  * i.e., everything except the parameter specification.
   4093  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   4094  1.1  mrg  * The parameters, if any, are specified by "space".
   4095  1.1  mrg  *
   4096  1.1  mrg  * First read a generic disjunction of object bodies and then try and extract
   4097  1.1  mrg  * an isl_union_set from that.
   4098  1.1  mrg  */
   4099  1.1  mrg static __isl_give isl_union_set *read_union_set_body(__isl_keep isl_stream *s,
   4100  1.1  mrg 	struct vars *v, __isl_take isl_space *space)
   4101  1.1  mrg {
   4102  1.1  mrg 	struct isl_obj obj = { isl_obj_set, NULL };
   4103  1.1  mrg 	isl_map *map;
   4104  1.1  mrg 
   4105  1.1  mrg 	map = isl_set_universe(space);
   4106  1.1  mrg 	if (isl_stream_eat(s, '{') < 0)
   4107  1.1  mrg 		goto error;
   4108  1.1  mrg 	obj = obj_read_disjuncts(s, v, map);
   4109  1.1  mrg 	if (isl_stream_eat(s, '}') < 0)
   4110  1.1  mrg 		goto error;
   4111  1.1  mrg 	isl_map_free(map);
   4112  1.1  mrg 
   4113  1.1  mrg 	return extract_union_set(s->ctx, obj);
   4114  1.1  mrg error:
   4115  1.1  mrg 	obj.type->free(obj.v);
   4116  1.1  mrg 	isl_map_free(map);
   4117  1.1  mrg 	return NULL;
   4118  1.1  mrg }
   4119  1.1  mrg 
   4120  1.1  mrg /* Read the body of an isl_multi_union_pw_aff from "s",
   4121  1.1  mrg  * i.e., everything except the parameter specification.
   4122  1.1  mrg  * "v" contains a description of the identifiers parsed so far.
   4123  1.1  mrg  * The parameters, if any, are specified by "space".
   4124  1.1  mrg  *
   4125  1.1  mrg  * In particular, handle the special case with shared domain constraints.
   4126  1.1  mrg  * These are specified as
   4127  1.1  mrg  *
   4128  1.1  mrg  *	([...] : ...)
   4129  1.1  mrg  *
   4130  1.1  mrg  * and are especially useful for setting the explicit domain
   4131  1.1  mrg  * of a zero-dimensional isl_multi_union_pw_aff.
   4132  1.1  mrg  * The core isl_multi_union_pw_aff body ([...]) is read by
   4133  1.1  mrg  * read_multi_union_pw_aff_body_core.
   4134  1.1  mrg  */
   4135  1.1  mrg static __isl_give isl_multi_union_pw_aff *read_multi_union_pw_aff_body(
   4136  1.1  mrg 	__isl_keep isl_stream *s, struct vars *v, __isl_take isl_space *space)
   4137  1.1  mrg {
   4138  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   4139  1.1  mrg 
   4140  1.1  mrg 	if (!isl_stream_next_token_is(s, '('))
   4141  1.1  mrg 		return read_multi_union_pw_aff_body_core(s, v, space);
   4142  1.1  mrg 
   4143  1.1  mrg 	if (isl_stream_eat(s, '(') < 0)
   4144  1.1  mrg 		goto error;
   4145  1.1  mrg 	mupa = read_multi_union_pw_aff_body_core(s, v, isl_space_copy(space));
   4146  1.1  mrg 	if (isl_stream_eat_if_available(s, ':')) {
   4147  1.1  mrg 		isl_union_set *dom;
   4148  1.1  mrg 
   4149  1.1  mrg 		dom = read_union_set_body(s, v, space);
   4150  1.1  mrg 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
   4151  1.1  mrg 	} else {
   4152  1.1  mrg 		isl_space_free(space);
   4153  1.1  mrg 	}
   4154  1.1  mrg 	if (isl_stream_eat(s, ')') < 0)
   4155  1.1  mrg 		return isl_multi_union_pw_aff_free(mupa);
   4156  1.1  mrg 
   4157  1.1  mrg 	return mupa;
   4158  1.1  mrg error:
   4159  1.1  mrg 	isl_space_free(space);
   4160  1.1  mrg 	return NULL;
   4161  1.1  mrg }
   4162  1.1  mrg 
   4163  1.1  mrg /* Read an isl_multi_union_pw_aff from "s".
   4164  1.1  mrg  *
   4165  1.1  mrg  * The input has the form
   4166  1.1  mrg  *
   4167  1.1  mrg  *	[{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }]
   4168  1.1  mrg  *
   4169  1.1  mrg  * or
   4170  1.1  mrg  *
   4171  1.1  mrg  *	[..] -> [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }]
   4172  1.1  mrg  *
   4173  1.1  mrg  * Additionally, a shared domain may be specified as
   4174  1.1  mrg  *
   4175  1.1  mrg  *	([..] : ...)
   4176  1.1  mrg  *
   4177  1.1  mrg  * or
   4178  1.1  mrg  *
   4179  1.1  mrg  *	[..] -> ([..] : ...)
   4180  1.1  mrg  *
   4181  1.1  mrg  * The first case is handled by the caller, the second case
   4182  1.1  mrg  * is handled by read_multi_union_pw_aff_body.
   4183  1.1  mrg  *
   4184  1.1  mrg  * We first check for the special case of an empty tuple "[]".
   4185  1.1  mrg  * Then we check if there are any parameters.
   4186  1.1  mrg  * Finally, read the tuple and construct the result.
   4187  1.1  mrg  */
   4188  1.1  mrg static __isl_give isl_multi_union_pw_aff *read_multi_union_pw_aff_core(
   4189  1.1  mrg 	__isl_keep isl_stream *s)
   4190  1.1  mrg {
   4191  1.1  mrg 	struct vars *v;
   4192  1.1  mrg 	isl_set *dom = NULL;
   4193  1.1  mrg 	isl_space *space;
   4194  1.1  mrg 	isl_multi_union_pw_aff *mupa = NULL;
   4195  1.1  mrg 
   4196  1.1  mrg 	if (next_is_empty_tuple(s)) {
   4197  1.1  mrg 		if (isl_stream_eat(s, '['))
   4198  1.1  mrg 			return NULL;
   4199  1.1  mrg 		if (isl_stream_eat(s, ']'))
   4200  1.1  mrg 			return NULL;
   4201  1.1  mrg 		space = isl_space_set_alloc(s->ctx, 0, 0);
   4202  1.1  mrg 		return isl_multi_union_pw_aff_zero(space);
   4203  1.1  mrg 	}
   4204  1.1  mrg 
   4205  1.1  mrg 	v = vars_new(s->ctx);
   4206  1.1  mrg 	if (!v)
   4207  1.1  mrg 		return NULL;
   4208  1.1  mrg 
   4209  1.1  mrg 	dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0));
   4210  1.1  mrg 	if (next_is_param_tuple(s)) {
   4211  1.1  mrg 		dom = read_map_tuple(s, dom, isl_dim_param, v, 0);
   4212  1.1  mrg 		if (isl_stream_eat(s, ISL_TOKEN_TO))
   4213  1.1  mrg 			goto error;
   4214  1.1  mrg 	}
   4215  1.1  mrg 	space = isl_set_get_space(dom);
   4216  1.1  mrg 	isl_set_free(dom);
   4217  1.1  mrg 	mupa = read_multi_union_pw_aff_body(s, v, space);
   4218  1.1  mrg 
   4219  1.1  mrg 	vars_free(v);
   4220  1.1  mrg 
   4221  1.1  mrg 	return mupa;
   4222  1.1  mrg error:
   4223  1.1  mrg 	vars_free(v);
   4224  1.1  mrg 	isl_set_free(dom);
   4225  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   4226  1.1  mrg 	return NULL;
   4227  1.1  mrg }
   4228  1.1  mrg 
   4229  1.1  mrg /* Read an isl_multi_union_pw_aff from "s".
   4230  1.1  mrg  *
   4231  1.1  mrg  * In particular, handle the special case with shared domain constraints.
   4232  1.1  mrg  * These are specified as
   4233  1.1  mrg  *
   4234  1.1  mrg  *	([...] : ...)
   4235  1.1  mrg  *
   4236  1.1  mrg  * and are especially useful for setting the explicit domain
   4237  1.1  mrg  * of a zero-dimensional isl_multi_union_pw_aff.
   4238  1.1  mrg  * The core isl_multi_union_pw_aff ([...]) is read by
   4239  1.1  mrg  * read_multi_union_pw_aff_core.
   4240  1.1  mrg  */
   4241  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_stream_read_multi_union_pw_aff(
   4242  1.1  mrg 	__isl_keep isl_stream *s)
   4243  1.1  mrg {
   4244  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   4245  1.1  mrg 
   4246  1.1  mrg 	if (!isl_stream_next_token_is(s, '('))
   4247  1.1  mrg 		return read_multi_union_pw_aff_core(s);
   4248  1.1  mrg 
   4249  1.1  mrg 	if (isl_stream_eat(s, '(') < 0)
   4250  1.1  mrg 		return NULL;
   4251  1.1  mrg 	mupa = read_multi_union_pw_aff_core(s);
   4252  1.1  mrg 	if (isl_stream_eat_if_available(s, ':')) {
   4253  1.1  mrg 		isl_union_set *dom;
   4254  1.1  mrg 
   4255  1.1  mrg 		dom = isl_stream_read_union_set(s);
   4256  1.1  mrg 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
   4257  1.1  mrg 	}
   4258  1.1  mrg 	if (isl_stream_eat(s, ')') < 0)
   4259  1.1  mrg 		return isl_multi_union_pw_aff_free(mupa);
   4260  1.1  mrg 	return mupa;
   4261  1.1  mrg }
   4262  1.1  mrg 
   4263  1.1  mrg #undef TYPE_BASE
   4264  1.1  mrg #define TYPE_BASE	multi_union_pw_aff
   4265  1.1  mrg #include "isl_read_from_str_templ.c"
   4266  1.1  mrg 
   4267  1.1  mrg __isl_give isl_union_pw_qpolynomial *isl_stream_read_union_pw_qpolynomial(
   4268  1.1  mrg 	__isl_keep isl_stream *s)
   4269  1.1  mrg {
   4270  1.1  mrg 	struct isl_obj obj;
   4271  1.1  mrg 
   4272  1.1  mrg 	obj = obj_read(s);
   4273  1.1  mrg 	if (obj.type == isl_obj_pw_qpolynomial) {
   4274  1.1  mrg 		obj.type = isl_obj_union_pw_qpolynomial;
   4275  1.1  mrg 		obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
   4276  1.1  mrg 	}
   4277  1.1  mrg 	if (obj.v)
   4278  1.1  mrg 		isl_assert(s->ctx, obj.type == isl_obj_union_pw_qpolynomial,
   4279  1.1  mrg 			   goto error);
   4280  1.1  mrg 
   4281  1.1  mrg 	return obj.v;
   4282  1.1  mrg error:
   4283  1.1  mrg 	obj.type->free(obj.v);
   4284  1.1  mrg 	return NULL;
   4285  1.1  mrg }
   4286  1.1  mrg 
   4287  1.1  mrg #undef TYPE_BASE
   4288  1.1  mrg #define TYPE_BASE	union_pw_qpolynomial
   4289  1.1  mrg #include "isl_read_from_str_templ.c"
   4290