5 #include <isl_stream.h>
6 #include <barvinok/barvinok.h>
10 #include <barvinok/bernstein.h>
13 typedef void *(*isc_bin_op_fn
)(void *lhs
, void *rhs
);
15 enum isl_token_type op
;
23 isl_pw_qpolynomial
*pwqp
;
24 isl_pw_qpolynomial
*res
;
27 static int eval_at(__isl_take isl_point
*pnt
, void *user
)
29 struct iscc_at
*at
= (struct iscc_at
*) user
;
33 set
= isl_set_from_point(isl_point_copy(pnt
));
34 qp
= isl_pw_qpolynomial_eval(isl_pw_qpolynomial_copy(at
->pwqp
), pnt
);
36 at
->res
= isl_pw_qpolynomial_add_disjoint(at
->res
,
37 isl_pw_qpolynomial_alloc(set
, qp
));
42 __isl_give isl_pw_qpolynomial
*isl_pw_qpolynomial_at(
43 __isl_take isl_pw_qpolynomial
*pwqp
, __isl_take isl_set
*set
)
48 at
.res
= isl_pw_qpolynomial_zero(isl_set_get_dim(set
));
50 isl_set_foreach_point(set
, eval_at
, &at
);
52 isl_pw_qpolynomial_free(pwqp
);
59 isl_pw_qpolynomial_fold
*pwf
;
60 isl_pw_qpolynomial
*res
;
63 static int eval_fold_at(__isl_take isl_point
*pnt
, void *user
)
65 struct iscc_fold_at
*at
= (struct iscc_fold_at
*) user
;
69 set
= isl_set_from_point(isl_point_copy(pnt
));
70 qp
= isl_pw_qpolynomial_fold_eval(isl_pw_qpolynomial_fold_copy(at
->pwf
),
73 at
->res
= isl_pw_qpolynomial_add_disjoint(at
->res
,
74 isl_pw_qpolynomial_alloc(set
, qp
));
79 __isl_give isl_pw_qpolynomial
*isl_pw_qpolynomial_fold_at(
80 __isl_take isl_pw_qpolynomial_fold
*pwf
, __isl_take isl_set
*set
)
82 struct iscc_fold_at at
;
85 at
.res
= isl_pw_qpolynomial_zero(isl_set_get_dim(set
));
87 isl_set_foreach_point(set
, eval_fold_at
, &at
);
89 isl_pw_qpolynomial_fold_free(pwf
);
95 struct isc_bin_op bin_ops
[] = {
96 { '+', isl_obj_set
, isl_obj_set
,
98 (isc_bin_op_fn
) &isl_set_union
},
99 { '+', isl_obj_map
, isl_obj_map
,
101 (isc_bin_op_fn
) &isl_map_union
},
102 { '-', isl_obj_set
, isl_obj_set
,
104 (isc_bin_op_fn
) &isl_set_subtract
},
105 { '-', isl_obj_map
, isl_obj_map
,
107 (isc_bin_op_fn
) &isl_map_subtract
},
108 { '*', isl_obj_set
, isl_obj_set
,
110 (isc_bin_op_fn
) &isl_set_intersect
},
111 { '*', isl_obj_map
, isl_obj_map
,
113 (isc_bin_op_fn
) &isl_map_intersect
},
114 { '+', isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
115 isl_obj_pw_qpolynomial
,
116 (isc_bin_op_fn
) &isl_pw_qpolynomial_add
},
117 { '-', isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
118 isl_obj_pw_qpolynomial
,
119 (isc_bin_op_fn
) &isl_pw_qpolynomial_sub
},
120 { '*', isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
121 isl_obj_pw_qpolynomial
,
122 (isc_bin_op_fn
) &isl_pw_qpolynomial_mul
},
123 { '@', isl_obj_pw_qpolynomial
, isl_obj_set
,
124 isl_obj_pw_qpolynomial
,
125 (isc_bin_op_fn
) &isl_pw_qpolynomial_at
},
126 { '@', isl_obj_pw_qpolynomial_fold
, isl_obj_set
,
127 isl_obj_pw_qpolynomial
,
128 (isc_bin_op_fn
) &isl_pw_qpolynomial_fold_at
},
132 __isl_give isl_set
*set_sample(__isl_take isl_set
*set
)
134 return isl_set_from_basic_set(isl_set_sample(set
));
137 __isl_give isl_map
*map_sample(__isl_take isl_map
*map
)
139 return isl_map_from_basic_map(isl_map_sample(map
));
142 typedef void *(*isc_un_op_fn
)(void *arg
);
144 enum isl_token_type op
;
149 struct isc_named_un_op
{
153 struct isc_named_un_op named_un_ops
[] = {
154 {"card", { -1, isl_obj_set
, isl_obj_pw_qpolynomial
,
155 (isc_un_op_fn
) &isl_set_card
} },
156 {"card", { -1, isl_obj_map
, isl_obj_pw_qpolynomial
,
157 (isc_un_op_fn
) &isl_map_card
} },
158 {"dom", { -1, isl_obj_map
, isl_obj_set
,
159 (isc_un_op_fn
) &isl_map_domain
} },
160 {"ran", { -1, isl_obj_map
, isl_obj_set
,
161 (isc_un_op_fn
) &isl_map_range
} },
162 {"lexmin", { -1, isl_obj_map
, isl_obj_map
,
163 (isc_un_op_fn
) &isl_map_lexmin
} },
164 {"lexmax", { -1, isl_obj_map
, isl_obj_map
,
165 (isc_un_op_fn
) &isl_map_lexmax
} },
166 {"lexmin", { -1, isl_obj_set
, isl_obj_set
,
167 (isc_un_op_fn
) &isl_set_lexmin
} },
168 {"lexmax", { -1, isl_obj_set
, isl_obj_set
,
169 (isc_un_op_fn
) &isl_set_lexmax
} },
170 {"sample", { -1, isl_obj_set
, isl_obj_set
,
171 (isc_un_op_fn
) &set_sample
} },
172 {"sample", { -1, isl_obj_map
, isl_obj_map
,
173 (isc_un_op_fn
) &map_sample
} },
174 {"sum", { -1, isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial
,
175 (isc_un_op_fn
) &isl_pw_qpolynomial_sum
} },
177 {"ub", { -1, isl_obj_pw_qpolynomial
, isl_obj_pw_qpolynomial_fold
,
178 (isc_un_op_fn
) &isl_pw_qpolynomial_upper_bound
} },
183 struct isl_named_obj
{
188 static void free_obj(struct isl_obj obj
)
190 obj
.type
->free(obj
.v
);
193 static int same_name(const void *entry
, const void *val
)
195 const struct isl_named_obj
*named
= (const struct isl_named_obj
*)entry
;
197 return !strcmp(named
->name
, val
);
200 static int do_assign(struct isl_ctx
*ctx
, struct isl_hash_table
*table
,
201 char *name
, struct isl_obj obj
)
203 struct isl_hash_table_entry
*entry
;
205 struct isl_named_obj
*named
;
207 name_hash
= isl_hash_string(isl_hash_init(), name
);
208 entry
= isl_hash_table_find(ctx
, table
, name_hash
, same_name
, name
, 1);
213 free_obj(named
->obj
);
216 named
= isl_alloc_type(ctx
, struct isl_named_obj
);
231 static struct isl_obj
stored_obj(struct isl_ctx
*ctx
,
232 struct isl_hash_table
*table
, char *name
)
234 struct isl_obj obj
= { isl_obj_none
, NULL
};
235 struct isl_hash_table_entry
*entry
;
238 name_hash
= isl_hash_string(isl_hash_init(), name
);
239 entry
= isl_hash_table_find(ctx
, table
, name_hash
, same_name
, name
, 0);
241 struct isl_named_obj
*named
;
247 obj
.v
= obj
.type
->copy(obj
.v
);
251 static struct isc_bin_op
*read_bin_op_if_available(struct isl_stream
*s
,
255 struct isl_token
*tok
;
257 tok
= isl_stream_next_token(s
);
264 if (bin_ops
[i
].op
!= tok
->type
)
266 if (bin_ops
[i
].lhs
!= lhs
)
273 isl_stream_push_token(s
, tok
);
278 static struct isc_un_op
*read_prefix_un_op_if_available(struct isl_stream
*s
)
281 struct isl_token
*tok
;
283 tok
= isl_stream_next_token(s
);
288 if (!named_un_ops
[i
].op
.op
)
290 if (named_un_ops
[i
].op
.op
!= tok
->type
)
294 return &named_un_ops
[i
].op
;
297 isl_stream_push_token(s
, tok
);
302 static struct isc_un_op
*find_matching_un_op(struct isc_un_op
*like
,
308 if (!named_un_ops
[i
].op
.op
)
310 if (named_un_ops
[i
].op
.op
!= like
->op
)
312 if (named_un_ops
[i
].op
.arg
!= arg
)
315 return &named_un_ops
[i
].op
;
321 static int is_assign(struct isl_stream
*s
)
323 struct isl_token
*tok
;
324 struct isl_token
*tok2
;
327 tok
= isl_stream_next_token(s
);
330 if (tok
->type
!= ISL_TOKEN_IDENT
) {
331 isl_stream_push_token(s
, tok
);
335 tok2
= isl_stream_next_token(s
);
337 isl_stream_push_token(s
, tok
);
340 assign
= tok2
->type
== ISL_TOKEN_DEF
;
341 isl_stream_push_token(s
, tok2
);
342 isl_stream_push_token(s
, tok
);
347 static struct isl_obj
read_obj(struct isl_stream
*s
,
348 struct isl_hash_table
*table
);
349 static struct isl_obj
read_expr(struct isl_stream
*s
,
350 struct isl_hash_table
*table
);
352 static struct isl_obj
read_un_op_expr(struct isl_stream
*s
,
353 struct isl_hash_table
*table
, struct isc_un_op
*op
)
355 struct isl_obj obj
= { isl_obj_none
, NULL
};
357 obj
= read_obj(s
, table
);
359 op
= find_matching_un_op(op
, obj
.type
);
361 isl_assert(s
->ctx
, op
, goto error
);
362 obj
.v
= op
->fn(obj
.v
);
368 obj
.type
= isl_obj_none
;
373 static struct isl_obj
read_obj(struct isl_stream
*s
,
374 struct isl_hash_table
*table
)
376 struct isl_obj obj
= { isl_obj_none
, NULL
};
378 struct isc_un_op
*op
= NULL
;
380 if (isl_stream_eat_if_available(s
, '(')) {
381 obj
= read_expr(s
, table
);
382 if (isl_stream_eat(s
, ')'))
387 op
= read_prefix_un_op_if_available(s
);
389 return read_un_op_expr(s
, table
, op
);
391 name
= isl_stream_read_ident_if_available(s
);
393 obj
= stored_obj(s
->ctx
, table
, name
);
395 obj
= isl_stream_read_obj(s
);
402 obj
.type
= isl_obj_none
;
407 static struct isl_obj
read_expr(struct isl_stream
*s
,
408 struct isl_hash_table
*table
)
410 struct isl_obj obj
= { isl_obj_none
, NULL
};
411 struct isl_obj right_obj
= { isl_obj_none
, NULL
};
413 obj
= read_obj(s
, table
);
415 struct isc_bin_op
*op
= NULL
;
417 op
= read_bin_op_if_available(s
, obj
.type
);
421 right_obj
= read_obj(s
, table
);
423 isl_assert(s
->ctx
, right_obj
.type
== op
->rhs
, goto error
);
424 obj
.v
= op
->fn(obj
.v
, right_obj
.v
);
432 obj
.type
= isl_obj_none
;
437 static void read_line(struct isl_stream
*s
, struct isl_hash_table
*table
)
439 struct isl_obj obj
= { isl_obj_none
, NULL
};
442 struct isc_bin_op
*op
= NULL
;
444 if (isl_stream_is_empty(s
))
447 assign
= is_assign(s
);
449 lhs
= isl_stream_read_ident_if_available(s
);
450 if (isl_stream_eat(s
, ISL_TOKEN_DEF
))
454 obj
= read_expr(s
, table
);
455 if (obj
.type
== isl_obj_none
|| obj
.v
== NULL
)
457 if (isl_stream_eat(s
, ';'))
461 if (do_assign(s
->ctx
, table
, lhs
, obj
))
464 obj
.type
->print(obj
.v
, stdout
);
474 int free_cb(void *entry
)
476 struct isl_named_obj
*named
= entry
;
478 free_obj(named
->obj
);
485 static void register_named_ops(struct isl_stream
*s
)
490 if (!named_un_ops
[i
].name
)
492 named_un_ops
[i
].op
.op
= isl_stream_register_keyword(s
,
493 named_un_ops
[i
].name
);
494 assert(named_un_ops
[i
].op
.op
!= ISL_TOKEN_ERROR
);
498 int main(int argc
, char **argv
)
501 struct isl_stream
*s
;
502 struct isl_hash_table
*table
;
504 ctx
= isl_ctx_alloc();
505 s
= isl_stream_new_file(ctx
, stdin
);
507 table
= isl_hash_table_alloc(ctx
, 10);
510 register_named_ops(s
);
512 while (!feof(stdin
)) {
516 isl_hash_table_foreach(ctx
, table
, free_cb
);
517 isl_hash_table_free(ctx
, table
);