Merge branch 'maint'
authorSven Verdoolaege <skimo@kotnet.org>
Sat, 22 Jan 2011 12:22:15 +0000 (13:22 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Sat, 22 Jan 2011 12:22:15 +0000 (13:22 +0100)
34 files changed:
Makefile.am
doc/user.pod
include/isl/constraint.h
include/isl/ctx.h
include/isl/dim.h
include/isl/map.h
include/isl/options.h
include/isl/polynomial.h
include/isl/set.h
include/isl/stream.h
include/isl/union_map.h
include/isl/union_set.h
include/isl/vec.h
isl.py [new file with mode: 0644]
isl_constraint.c
isl_convex_hull.c
isl_dim.c
isl_fold.c
isl_input.c
isl_map.c
isl_map_subtract.c
isl_morph.c
isl_morph.h
isl_options.c
isl_output.c
isl_polynomial.c
isl_sample.c
isl_stream.c
isl_tab.c
isl_test.c
isl_union_map.c
isl_vec.c
polyhedron_minimize.c
polyhedron_sample.c

index 578981d..54088f5 100644 (file)
@@ -197,6 +197,7 @@ EXTRA_DIST = \
        basis_reduction_templ.c \
        isl_pw_templ.c \
        isl_union_templ.c \
+       isl.py \
        doc/chicago.bst \
        doc/chicago.sty \
        doc/implementation.tex \
@@ -218,3 +219,11 @@ pkgconfig_DATA = $(pkgconfig_libfile)
 
 gitversion.h: @GIT_HEAD@
        echo '#define GIT_HEAD_ID "'@GIT_HEAD_VERSION@'"' > $@
+
+install-data-local: $(srcdir)/isl.py
+       @libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p}" \
+                $(builddir)/libisl.la`; \
+       case $$libisl in \
+       '') echo Cannot find isl library name. GDB bindings not installed.;; \
+       *) echo $(INSTALL_DATA) $(srcdir)/isl.py $(libdir)/$$libisl-gdb.py; \
+       $(INSTALL_DATA) $(srcdir)/isl.py $(libdir)/$$libisl-gdb.py; esac
index e0eb54b..23e7aa2 100644 (file)
@@ -55,6 +55,15 @@ to C<isl/header.h>.
 
 =back
 
+=head3 Changes since isl-0.05
+
+=over
+
+=item * The functions C<isl_printer_print_basic_set> and
+C<isl_printer_print_basic_map> no longer print a newline.
+
+=back
+
 =head1 Installation
 
 The source of C<isl> can be obtained either as a tarball
@@ -1290,6 +1299,24 @@ basic set or relation.
        __isl_give isl_union_map *isl_union_map_coalesce(
                __isl_take isl_union_map *umap);
 
+=item * Detecting equalities
+
+       __isl_give isl_basic_set *isl_basic_set_detect_equalities(
+                __isl_take isl_basic_set *bset);
+       __isl_give isl_basic_map *isl_basic_map_detect_equalities(
+                __isl_take isl_basic_map *bmap);
+       __isl_give isl_set *isl_set_detect_equalities(
+               __isl_take isl_set *set);
+       __isl_give isl_map *isl_map_detect_equalities(
+               __isl_take isl_map *map);
+       __isl_give isl_union_set *isl_union_set_detect_equalities(
+               __isl_take isl_union_set *uset);
+       __isl_give isl_union_map *isl_union_map_detect_equalities(
+               __isl_take isl_union_map *umap);
+
+Simplify the representation of a set or relation by detecting implicit
+equalities.
+
 =item * Convex hull
 
        __isl_give isl_basic_set *isl_set_convex_hull(
@@ -1306,6 +1333,8 @@ variables, then the result of these operations is currently undefined.
                __isl_take isl_set *set);
        __isl_give isl_basic_map *isl_map_simple_hull(
                __isl_take isl_map *map);
+       __isl_give isl_union_map *isl_union_map_simple_hull(
+               __isl_take isl_union_map *umap);
 
 These functions compute a single basic set or relation
 that contains the whole input set or relation.
@@ -1418,6 +1447,8 @@ Remove any internal structure of domain (and range) of the given
 set or relation.  If there is any such internal structure in the input,
 then the name of the space is also removed.
 
+       __isl_give isl_basic_set *isl_basic_set_flatten(
+               __isl_take isl_basic_set *bset);
        __isl_give isl_set *isl_set_flatten(
                __isl_take isl_set *set);
        __isl_give isl_map *isl_map_flatten(
@@ -1560,6 +1591,43 @@ the same (number of) parameters.
                __isl_take isl_union_map *umap1,
                __isl_take isl_union_map *umap2);
 
+=item * Cartesian Product
+
+       __isl_give isl_set *isl_set_product(
+               __isl_take isl_set *set1,
+               __isl_take isl_set *set2);
+       __isl_give isl_union_set *isl_union_set_product(
+               __isl_take isl_union_set *uset1,
+               __isl_take isl_union_set *uset2);
+       __isl_give isl_basic_map *isl_basic_map_range_product(
+               __isl_take isl_basic_map *bmap1,
+               __isl_take isl_basic_map *bmap2);
+       __isl_give isl_map *isl_map_range_product(
+               __isl_take isl_map *map1,
+               __isl_take isl_map *map2);
+       __isl_give isl_union_map *isl_union_map_range_product(
+               __isl_take isl_union_map *umap1,
+               __isl_take isl_union_map *umap2);
+       __isl_give isl_map *isl_map_product(
+               __isl_take isl_map *map1,
+               __isl_take isl_map *map2);
+       __isl_give isl_union_map *isl_union_map_product(
+               __isl_take isl_union_map *umap1,
+               __isl_take isl_union_map *umap2);
+
+The above functions compute the cross product of the given
+sets or relations.  The domains and ranges of the results
+are wrapped maps between domains and ranges of the inputs.
+To obtain a ``flat'' product, use the following functions
+instead.
+
+       __isl_give isl_set *isl_set_flat_product(
+               __isl_take isl_set *set1,
+               __isl_take isl_set *set2);
+       __isl_give isl_map *isl_map_flat_product(
+               __isl_take isl_map *map1,
+               __isl_take isl_map *map2);
+
 =item * Simplification
 
        __isl_give isl_basic_set *isl_basic_set_gist(
@@ -2248,22 +2316,35 @@ In future, the operation will also exploit the context
 to simplify the quasipolynomial reductions associated to each cell.
 
        __isl_give isl_pw_qpolynomial_fold *
+       isl_set_apply_pw_qpolynomial_fold(
+               __isl_take isl_set *set,
+               __isl_take isl_pw_qpolynomial_fold *pwf,
+               int *tight);
+       __isl_give isl_pw_qpolynomial_fold *
        isl_map_apply_pw_qpolynomial_fold(
                __isl_take isl_map *map,
                __isl_take isl_pw_qpolynomial_fold *pwf,
                int *tight);
        __isl_give isl_union_pw_qpolynomial_fold *
+       isl_union_set_apply_union_pw_qpolynomial_fold(
+               __isl_take isl_union_set *uset,
+               __isl_take isl_union_pw_qpolynomial_fold *upwf,
+               int *tight);
+       __isl_give isl_union_pw_qpolynomial_fold *
        isl_union_map_apply_union_pw_qpolynomial_fold(
                __isl_take isl_union_map *umap,
                __isl_take isl_union_pw_qpolynomial_fold *upwf,
                int *tight);
 
-These functions
+The functions taking a map
 compose the given map with the given piecewise quasipolynomial reduction.
 That is, compute a bound (of the same type as C<pwf> or C<upwf> itself)
 over all elements in the intersection of the range of the map
 and the domain of the piecewise quasipolynomial reduction
 as a function of an element in the domain of the map.
+The functions taking a set compute a bound over all elements in the
+intersection of the set and the domain of the
+piecewise quasipolynomial reduction.
 
 =head2 Dependence Analysis
 
index 369f499..970709a 100644 (file)
@@ -79,8 +79,12 @@ void isl_constraint_get_constant(__isl_keep isl_constraint *constraint,
 void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint,
        enum isl_dim_type type, int pos, isl_int *v);
 void isl_constraint_set_constant(__isl_keep isl_constraint *constraint, isl_int v);
+void isl_constraint_set_constant_si(__isl_keep isl_constraint *constraint,
+       int v);
 void isl_constraint_set_coefficient(__isl_keep isl_constraint *constraint,
        enum isl_dim_type type, int pos, isl_int v);
+void isl_constraint_set_coefficient_si(__isl_keep isl_constraint *constraint,
+       enum isl_dim_type type, int pos, int v);
 
 __isl_give isl_div *isl_constraint_div(__isl_keep isl_constraint *constraint,
        int pos);
index daf4ef7..456d3dd 100644 (file)
@@ -64,7 +64,8 @@ enum isl_error {
        isl_error_none = 0,
        isl_error_unknown,
        isl_error_internal,
-       isl_error_invalid
+       isl_error_invalid,
+       isl_error_unsupported
 };
 struct isl_ctx {
        int                     ref;
index 41361d6..e4cfd85 100644 (file)
@@ -61,6 +61,8 @@ __isl_give isl_dim *isl_dim_insert(__isl_take isl_dim *dim,
 __isl_give isl_dim *isl_dim_join(__isl_take isl_dim *left,
        __isl_take isl_dim *right);
 struct isl_dim *isl_dim_product(struct isl_dim *left, struct isl_dim *right);
+__isl_give isl_dim *isl_dim_range_product(__isl_take isl_dim *left,
+       __isl_take isl_dim *right);
 struct isl_dim *isl_dim_map(struct isl_dim *dim);
 __isl_give isl_dim *isl_dim_reverse(__isl_take isl_dim *dim);
 __isl_give isl_dim *isl_dim_drop(__isl_take isl_dim *dim,
index a660e1a..f9b6786 100644 (file)
@@ -157,8 +157,10 @@ __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
                FILE *input, int nparam);
 __isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx,
                const char *str, int nparam);
+void isl_basic_map_dump(__isl_keep isl_basic_map *bmap);
 void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
        const char *prefix, const char *suffix, unsigned output_format);
+void isl_map_dump(__isl_keep isl_map *map);
 void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
        unsigned output_format);
 __isl_give isl_printer *isl_printer_print_basic_map(
@@ -206,7 +208,8 @@ int isl_basic_map_foreach_lexmin(__isl_keep isl_basic_map *bmap,
                  void *user),
        void *user);
 
-void isl_basic_map_dump(__isl_keep isl_basic_map *bmap, FILE *out, int indent);
+void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
+       FILE *out, int indent);
 
 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map);
 __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
@@ -268,7 +271,12 @@ __isl_give isl_map *isl_map_apply_domain(
 __isl_give isl_map *isl_map_apply_range(
                __isl_take isl_map *map1,
                __isl_take isl_map *map2);
-struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2);
+__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
+       __isl_take isl_map *map2);
+__isl_give isl_basic_map *isl_basic_map_range_product(
+       __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2);
+__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
+       __isl_take isl_map *map2);
 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
        __isl_take isl_map *map2);
 __isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
@@ -322,6 +330,7 @@ __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map);
 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset);
 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set);
 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map);
+__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset);
 __isl_give isl_set *isl_set_flatten(__isl_take isl_set *set);
 __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set);
 __isl_give isl_set *isl_map_domain(__isl_take isl_map *bmap);
@@ -357,7 +366,7 @@ __isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap);
 __isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map);
 __isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map);
 
-void isl_map_dump(__isl_keep isl_map *map, FILE *out, int indent);
+void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent);
 
 int isl_map_fast_input_is_fixed(struct isl_map *map,
                unsigned in, isl_int *val);
index 790972f..673c272 100644 (file)
@@ -54,6 +54,10 @@ struct isl_options {
        int                     bernstein_triangulate;
 
        int                     pip_symmetry;
+
+       #define                 ISL_CONVEX_HULL_WRAP    0
+       #define                 ISL_CONVEX_HULL_FM      1
+       int                     convex;
 };
 
 ISL_ARG_DECL(isl_options, struct isl_options, isl_options_arg)
index b88cba2..7c950c2 100644 (file)
@@ -63,6 +63,8 @@ __isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1,
        __isl_take isl_qpolynomial *qp2);
 __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_qpolynomial *qp,
        unsigned power);
+__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int(
+       __isl_take isl_qpolynomial *qp, isl_int v);
 
 __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
        __isl_take isl_qpolynomial *qp, enum isl_dim_type type,
@@ -118,6 +120,7 @@ __isl_give isl_printer *isl_printer_print_qpolynomial(
        __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp);
 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
        unsigned output_format);
+void isl_qpolynomial_dump(__isl_keep isl_qpolynomial *qp);
 
 struct isl_pw_qpolynomial;
 typedef struct isl_pw_qpolynomial isl_pw_qpolynomial;
@@ -210,6 +213,7 @@ __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
        __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp);
 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
        unsigned output_format);
+void isl_pw_qpolynomial_dump(__isl_keep isl_pw_qpolynomial *pwqp);
 
 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_coalesce(
        __isl_take isl_pw_qpolynomial *pwqp);
@@ -232,6 +236,7 @@ enum isl_fold {
 struct isl_qpolynomial_fold;
 typedef struct isl_qpolynomial_fold isl_qpolynomial_fold;
 
+isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold);
 enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold);
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
@@ -270,8 +275,11 @@ int isl_qpolynomial_fold_foreach_qpolynomial(
        __isl_keep isl_qpolynomial_fold *fold,
        int (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user);
 
+__isl_give isl_printer *isl_printer_print_qpolynomial_fold(
+       __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold);
 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold, FILE *out,
        unsigned output_format);
+void isl_qpolynomial_fold_dump(__isl_keep isl_qpolynomial_fold *fold);
 
 struct isl_pw_qpolynomial_fold;
 typedef struct isl_pw_qpolynomial_fold isl_pw_qpolynomial_fold;
@@ -352,6 +360,7 @@ __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
        __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf);
 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
        FILE *out, unsigned output_format);
+void isl_pw_qpolynomial_fold_dump(__isl_keep isl_pw_qpolynomial_fold *pwf);
 
 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_coalesce(
        __isl_take isl_pw_qpolynomial_fold *pwf);
@@ -367,6 +376,9 @@ __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_bound(
        __isl_take isl_pw_qpolynomial *pwqp, enum isl_fold type, int *tight);
 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_bound(
        __isl_take isl_pw_qpolynomial_fold *pwf, int *tight);
+__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold(
+       __isl_take isl_set *set, __isl_take isl_pw_qpolynomial_fold *pwf,
+       int *tight);
 __isl_give isl_pw_qpolynomial_fold *isl_map_apply_pw_qpolynomial_fold(
        __isl_take isl_map *map, __isl_take isl_pw_qpolynomial_fold *pwf,
        int *tight);
@@ -494,6 +506,9 @@ __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
 __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_bound(
        __isl_take isl_union_pw_qpolynomial *upwqp,
        enum isl_fold type, int *tight);
+__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold(
+       __isl_take isl_union_set *uset,
+       __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight);
 __isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomial_fold(
        __isl_take isl_union_map *umap,
        __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight);
index 98bf156..8382362 100644 (file)
@@ -67,7 +67,7 @@ __isl_give isl_basic_set *isl_basic_set_universe_like_set(
 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
        isl_int min, isl_int max);
 struct isl_basic_set *isl_basic_set_positive_orthant(struct isl_dim *dims);
-void isl_basic_set_dump(__isl_keep isl_basic_set *bset,
+void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset,
                                FILE *out, int indent);
 struct isl_basic_set *isl_basic_set_swap_vars(
                struct isl_basic_set *bset, unsigned n);
@@ -85,7 +85,8 @@ __isl_give isl_basic_set *isl_basic_set_remove_dims(
 struct isl_basic_set *isl_basic_set_simplify(struct isl_basic_set *bset);
 __isl_give isl_basic_set *isl_basic_set_detect_equalities(
                                                __isl_take isl_basic_set *bset);
-struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list);
+__isl_give isl_basic_set *isl_basic_set_list_product(
+       __isl_take struct isl_basic_set_list *list);
 
 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
                FILE *input, int nparam);
@@ -95,6 +96,8 @@ __isl_give isl_set *isl_set_read_from_file(isl_ctx *ctx,
                FILE *input, int nparam);
 __isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx,
                const char *str, int nparam);
+void isl_basic_set_dump(__isl_keep isl_basic_set *bset);
+void isl_set_dump(__isl_keep isl_set *set);
 __isl_give isl_printer *isl_printer_print_basic_set(
        __isl_take isl_printer *printer, __isl_keep isl_basic_set *bset);
 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *printer,
@@ -185,7 +188,8 @@ struct isl_set *isl_set_union_disjoint(
 __isl_give isl_set *isl_set_union(
                __isl_take isl_set *set1,
                __isl_take isl_set *set2);
-struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2);
+__isl_give isl_set *isl_set_product(__isl_take isl_set *set1,
+       __isl_take isl_set *set2);
 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
        __isl_take isl_set *set2);
 __isl_give isl_set *isl_set_intersect(
@@ -229,11 +233,12 @@ __isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset,
        enum isl_dim_type type, unsigned first, unsigned n);
 __isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
        enum isl_dim_type type, unsigned first, unsigned n);
+__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set);
 __isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set);
 __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
        enum isl_dim_type type, unsigned first, unsigned n);
 
-void isl_set_dump(__isl_keep isl_set *set, FILE *out, int indent);
+void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent);
 struct isl_set *isl_set_swap_vars(struct isl_set *set, unsigned n);
 int isl_set_fast_is_empty(__isl_keep isl_set *set);
 int isl_set_fast_is_universe(__isl_keep isl_set *set);
index 12e17f5..695aeed 100644 (file)
@@ -35,6 +35,7 @@ struct isl_token {
        enum isl_token_type  type;
 
        unsigned int on_new_line : 1;
+       unsigned is_keyword : 1;
        int line;
        int col;
 
index c119e0c..dad469d 100644 (file)
@@ -30,11 +30,17 @@ __isl_give isl_union_map *isl_union_map_domain_map(
        __isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_map_range_map(
        __isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_from_domain(
+       __isl_take isl_union_set *uset);
+__isl_give isl_union_map *isl_union_map_from_range(
+       __isl_take isl_union_set *uset);
 
 __isl_give isl_union_map *isl_union_map_affine_hull(
        __isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_map_polyhedral_hull(
        __isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_simple_hull(
+       __isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_map_coalesce(
        __isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_map_compute_divs(
@@ -52,6 +58,8 @@ __isl_give isl_union_map *isl_union_map_intersect(
        __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
        __isl_take isl_union_map *umap2);
+__isl_give isl_union_map *isl_union_map_range_product(
+       __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
        __isl_take isl_union_map *context);
 
@@ -68,6 +76,8 @@ __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
        __isl_take isl_union_set *domain, __isl_take isl_union_set *range);
 
+__isl_give isl_union_map *isl_union_map_detect_equalities(
+       __isl_keep isl_union_map *umap);
 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset);
 
@@ -104,6 +114,7 @@ __isl_give isl_union_map *isl_union_map_read_from_str(struct isl_ctx *ctx,
        const char *str);
 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
        __isl_keep isl_union_map *umap);
+void isl_union_map_dump(__isl_keep isl_union_map *umap);
 
 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset);
index ecfc678..4f08664 100644 (file)
@@ -16,10 +16,14 @@ void isl_union_set_free(__isl_take isl_union_set *uset);
 isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset);
 __isl_give isl_dim *isl_union_set_get_dim(__isl_keep isl_union_set *uset);
 
+__isl_give isl_union_set *isl_union_set_detect_equalities(
+       __isl_take isl_union_set *uset);
 __isl_give isl_union_set *isl_union_set_affine_hull(
        __isl_take isl_union_set *uset);
 __isl_give isl_union_set *isl_union_set_polyhedral_hull(
        __isl_take isl_union_set *uset);
+__isl_give isl_union_set *isl_union_set_simple_hull(
+       __isl_take isl_union_set *uset);
 __isl_give isl_union_set *isl_union_set_coalesce(
        __isl_take isl_union_set *uset);
 __isl_give isl_union_set *isl_union_set_compute_divs(
@@ -75,6 +79,7 @@ __isl_give isl_union_set *isl_union_set_read_from_str(struct isl_ctx *ctx,
        const char *str);
 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
        __isl_keep isl_union_set *uset);
+void isl_union_set_dump(__isl_keep isl_union_set *uset);
 
 #if defined(__cplusplus)
 }
index a50a6fa..5a2f365 100644 (file)
@@ -15,6 +15,7 @@
 #include <isl/int.h>
 #include <isl/ctx.h>
 #include <isl/blk.h>
+#include <isl/printer.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -37,7 +38,9 @@ struct isl_vec *isl_vec_copy(struct isl_vec *vec);
 struct isl_vec *isl_vec_cow(struct isl_vec *vec);
 void isl_vec_free(struct isl_vec *vec);
 
-void isl_vec_dump(struct isl_vec *vec, FILE *out, int indent);
+void isl_vec_dump(__isl_keep isl_vec *vec);
+__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer,
+       __isl_keep isl_vec *vec);
 
 void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm);
 struct isl_vec *isl_vec_ceil(struct isl_vec *vec);
diff --git a/isl.py b/isl.py
new file mode 100644 (file)
index 0000000..6382f63
--- /dev/null
+++ b/isl.py
@@ -0,0 +1,100 @@
+import gdb
+import re
+
+# GDB Pretty Printers for most isl objects
+class IslObjectPrinter:
+       """Print an isl object"""
+       def __init__ (self, val, type):
+                self.val = val
+                self.type = type
+
+       def to_string (self):
+                # Cast val to a void pointer to stop gdb using this pretty
+                # printer for the pointer which would lead to an infinite loop.
+                void_ptr = gdb.lookup_type('void').pointer()
+                value = str(self.val.cast(void_ptr))
+                printer = gdb.parse_and_eval("isl_printer_to_str(isl_"
+                                             + str(self.type)
+                                            + "_get_ctx(" + value + "))")
+                printer = gdb.parse_and_eval("isl_printer_print_"
+                                             + str(self.type) + "("
+                                             + str(printer) + ", "
+                                             + value + ")")
+                string = gdb.parse_and_eval("(char*)isl_printer_get_str("
+                                            + str(printer) + ")")
+                gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")")
+                return string
+
+       def display_hint (self):
+                return 'string'
+
+class IslIntPrinter:
+       """Print an isl_int """
+       def __init__ (self, val):
+                self.val = val
+
+       def to_string (self):
+                # Cast val to a void pointer to stop gdb using this pretty
+                # printer for the pointer which would lead to an infinite loop.
+                void_ptr = gdb.lookup_type('void').pointer()
+                value = str(self.val.cast(void_ptr))
+
+                context = gdb.parse_and_eval("isl_ctx_alloc()")
+                printer = gdb.parse_and_eval("isl_printer_to_str("
+                                             + str(context) + ")")
+                printer = gdb.parse_and_eval("isl_printer_print_isl_int("
+                                             + str(printer) + ", "
+                                             + value + ")")
+                string = gdb.parse_and_eval("(char*)isl_printer_get_str("
+                                            + str(printer) + ")")
+                gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")")
+                gdb.parse_and_eval("isl_ctx_free(" + str(context) + ")")
+                return string
+
+       def display_hint (self):
+                return 'string'
+
+class IslPrintCommand (gdb.Command):
+        """Print an isl value."""
+        def __init__ (self):
+                super (IslPrintCommand, self).__init__ ("islprint",
+                                                        gdb.COMMAND_OBSCURE)
+        def invoke (self, arg, from_tty):
+                arg = gdb.parse_and_eval(arg);
+                printer = str_lookup_function(arg)
+
+                if printer == None:
+                        print "No isl printer for this type"
+                        return
+
+                print printer.to_string()
+
+IslPrintCommand()
+
+def str_lookup_function (val):
+       if val.type.code != gdb.TYPE_CODE_PTR:
+               if str(val.type) == "isl_int":
+                       return IslIntPrinter(val)
+                else:
+                        return None
+
+       lookup_tag = val.type.target()
+       regex = re.compile ("^isl_(.*)$")
+
+       if lookup_tag == None:
+               return None
+
+       m = regex.match (str(lookup_tag))
+
+       if m:
+                # Those types of printers defined in isl.
+                if m.group(1) in ["basic_set", "set", "union_set", "basic_map",
+                                  "map", "union_map", "qpolynomial",
+                                  "pw_qpolynomial", "pw_qpolynomial_fold",
+                                  "union_pw_qpolynomial",
+                                  "union_pw_qpolynomial_fold"]:
+                        return IslObjectPrinter(val, m.group(1))
+        return None
+
+# Do not register the pretty printer.
+# gdb.current_objfile().pretty_printers.append(str_lookup_function)
index 760f9e5..1fa0680 100644 (file)
@@ -357,6 +357,14 @@ void isl_constraint_set_constant(struct isl_constraint *constraint, isl_int v)
        isl_int_set(constraint->line[0][0], v);
 }
 
+void isl_constraint_set_constant_si(__isl_keep isl_constraint *constraint,
+       int v)
+{
+       if (!constraint)
+               return;
+       isl_int_set_si(constraint->line[0][0], v);
+}
+
 void isl_constraint_set_coefficient(struct isl_constraint *constraint,
        enum isl_dim_type type, int pos, isl_int v)
 {
@@ -367,6 +375,16 @@ void isl_constraint_set_coefficient(struct isl_constraint *constraint,
        isl_int_set(constraint->line[0][offset(constraint, type) + pos], v);
 }
 
+void isl_constraint_set_coefficient_si(__isl_keep isl_constraint *constraint,
+       enum isl_dim_type type, int pos, int v)
+{
+       if (!constraint)
+               return;
+
+       isl_assert(constraint->ctx, pos < n(constraint, type), return);
+       isl_int_set_si(constraint->line[0][offset(constraint, type) + pos], v);
+}
+
 void isl_constraint_clear(struct isl_constraint *constraint)
 {
        unsigned total;
index 40cca1b..260bbd4 100644 (file)
@@ -1352,6 +1352,9 @@ static struct isl_basic_set *convex_hull_pair(struct isl_basic_set *bset1,
        isl_basic_set *lin, *aff;
        int bounded1, bounded2;
 
+       if (bset1->ctx->opt->convex == ISL_CONVEX_HULL_FM)
+               return convex_hull_pair_elim(bset1, bset2);
+
        aff = isl_set_affine_hull(isl_basic_set_union(isl_basic_set_copy(bset1),
                                                    isl_basic_set_copy(bset2)));
        if (!aff)
@@ -1807,7 +1810,8 @@ static struct isl_basic_set *uset_convex_hull(struct isl_set *set)
        if (isl_set_n_dim(set) == 1)
                return convex_hull_1d(set);
 
-       if (isl_set_is_bounded(set))
+       if (isl_set_is_bounded(set) &&
+           set->ctx->opt->convex == ISL_CONVEX_HULL_WRAP)
                return uset_convex_hull_wrap(set);
 
        lin = uset_combined_lineality_space(isl_set_copy(set));
index 2ada2e1..b94a59b 100644 (file)
--- a/isl_dim.c
+++ b/isl_dim.c
@@ -722,6 +722,33 @@ error:
        return NULL;
 }
 
+__isl_give isl_dim *isl_dim_range_product(__isl_take isl_dim *left,
+       __isl_take isl_dim *right)
+{
+       isl_dim *dom, *ran1, *ran2, *nest;
+
+       if (!left || !right)
+               goto error;
+
+       isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param),
+                       goto error);
+       if (!isl_dim_match(left, isl_dim_in, right, isl_dim_in))
+               isl_die(left->ctx, isl_error_invalid,
+                       "domains need to match", goto error);
+
+       dom = isl_dim_domain(isl_dim_copy(left));
+
+       ran1 = isl_dim_range(left);
+       ran2 = isl_dim_range(right);
+       nest = isl_dim_wrap(isl_dim_join(isl_dim_reverse(ran1), ran2));
+
+       return isl_dim_join(isl_dim_reverse(dom), nest);
+error:
+       isl_dim_free(left);
+       isl_dim_free(right);
+       return NULL;
+}
+
 struct isl_dim *isl_dim_map(struct isl_dim *dim)
 {
        struct isl_name **names = NULL;
index 3e3599f..b6ca0ce 100644 (file)
@@ -44,6 +44,11 @@ error:
        return NULL;
 }
 
+isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold)
+{
+       return fold ? fold->dim->ctx : NULL;
+}
+
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_dim(
        __isl_take isl_qpolynomial_fold *fold, __isl_take isl_dim *dim)
 {
@@ -1386,6 +1391,16 @@ error:
        return NULL;
 }
 
+__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold(
+       __isl_take isl_set *set, __isl_take isl_pw_qpolynomial_fold *pwf,
+       int *tight)
+{
+       isl_map *map;
+
+       map = isl_map_from_range(set);
+       return isl_map_apply_pw_qpolynomial_fold(map, pwf, tight);
+}
+
 struct isl_apply_fold_data {
        isl_union_pw_qpolynomial_fold *upwf;
        isl_union_pw_qpolynomial_fold *res;
@@ -1466,6 +1481,13 @@ error:
        return NULL;
 }
 
+__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold(
+       __isl_take isl_union_set *uset,
+       __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight)
+{
+       return isl_union_map_apply_union_pw_qpolynomial_fold(uset, upwf, tight);
+}
+
 /* Reorder the dimension of "fold" according to the given reordering.
  */
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign(
index 58ed3fd..dca1442 100644 (file)
@@ -183,6 +183,54 @@ error:
        return -1;
 }
 
+/* Given an affine expression aff, return an affine expression
+ * for aff % d, with d the next token on the stream, which is
+ * assumed to be a constant.
+ *
+ * We introduce an integer division q = [aff/d] and the result
+ * is set to aff - d q.
+ */
+static __isl_give isl_vec *affine_mod(struct isl_stream *s,
+       struct vars *v, __isl_take isl_vec *aff)
+{
+       struct isl_token *tok;
+       struct variable *var;
+       isl_vec *mod;
+
+       tok = isl_stream_next_token(s);
+       if (!tok || tok->type != ISL_TOKEN_VALUE) {
+               isl_stream_error(s, tok, "expecting constant value");
+               goto error;
+       }
+
+       if (vars_add_anon(v) < 0)
+               goto error;
+
+       var = v->v;
+
+       var->def = isl_vec_alloc(s->ctx, 2 + v->n);
+       if (!var->def)
+               goto error;
+       isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
+       isl_int_set_si(var->def->el[1 + aff->size], 0);
+       isl_int_set(var->def->el[0], tok->u.v);
+
+       mod = isl_vec_alloc(v->ctx, 1 + v->n);
+       if (!mod)
+               goto error;
+
+       isl_seq_cpy(mod->el, aff->el, aff->size);
+       isl_int_neg(mod->el[aff->size], tok->u.v);
+
+       isl_vec_free(aff);
+       isl_token_free(tok);
+       return mod;
+error:
+       isl_vec_free(aff);
+       isl_token_free(tok);
+       return NULL;
+}
+
 static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v);
 static int read_div_definition(struct isl_stream *s, struct vars *v);
 
@@ -249,6 +297,8 @@ static __isl_give isl_vec *accept_affine_factor(struct isl_stream *s,
                isl_stream_error(s, tok, "expecting factor");
                goto error;
        }
+       if (isl_stream_eat_if_available(s, '%'))
+               return affine_mod(s, v, aff);
        if (isl_stream_eat_if_available(s, '*')) {
                isl_int f;
                isl_int_init(f);
@@ -665,7 +715,7 @@ static int next_is_tuple(struct isl_stream *s)
                isl_stream_push_token(s, tok);
                return 1;
        }
-       if (tok->type != ISL_TOKEN_IDENT) {
+       if (tok->type != ISL_TOKEN_IDENT && !tok->is_keyword) {
                isl_stream_push_token(s, tok);
                return 0;
        }
@@ -701,7 +751,7 @@ static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
        char *name = NULL;
 
        tok = isl_stream_next_token(s);
-       if (tok && tok->type == ISL_TOKEN_IDENT) {
+       if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
                name = strdup(tok->u.s);
                if (!name)
                        goto error;
index 611c946..64a8833 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -1559,6 +1559,78 @@ __isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
                                                              type, first, n);
 }
 
+/* Return true if the definition of the given div is unknown or depends
+ * on unknown divs.
+ */
+static int div_is_unknown(__isl_keep isl_basic_map *bmap, int div)
+{
+       int i;
+       unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
+
+       if (isl_int_is_zero(bmap->div[div][0]))
+               return 1;
+
+       for (i = bmap->n_div - 1; i >= 0; --i) {
+               if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
+                       continue;
+               if (div_is_unknown(bmap, i))
+                       return 1;
+       }
+
+       return 0;
+}
+
+/* Remove all divs that are unknown or defined in terms of unknown divs.
+ */
+__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
+       __isl_take isl_basic_map *bmap)
+{
+       int i;
+
+       if (!bmap)
+               return NULL;
+
+       for (i = bmap->n_div - 1; i >= 0; --i) {
+               if (!div_is_unknown(bmap, i))
+                       continue;
+               bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
+       }
+
+       return bmap;
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
+{
+       int i;
+
+       if (!map)
+               return NULL;
+       if (map->n == 0)
+               return map;
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
+               if (!map->p[i])
+                       goto error;
+       }
+       return map;
+error:
+       isl_map_free(map);
+       return NULL;
+}
+
+__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set)
+{
+       return (isl_set *)isl_map_remove_unknown_divs((isl_map *)set);
+}
+
 __isl_give isl_basic_set *isl_basic_set_remove_dims(
        __isl_take isl_basic_set *bset,
        enum isl_dim_type type, unsigned first, unsigned n)
@@ -1722,7 +1794,8 @@ static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
        }
 }
 
-void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
+void isl_basic_set_print_internal(struct isl_basic_set *bset,
+       FILE *out, int indent)
 {
        if (!bset) {
                fprintf(out, "null basic set\n");
@@ -1736,7 +1809,8 @@ void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
        dump((struct isl_basic_map *)bset, out, indent);
 }
 
-void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent)
+void isl_basic_map_print_internal(struct isl_basic_map *bmap,
+       FILE *out, int indent)
 {
        if (!bmap) {
                fprintf(out, "null basic map\n");
@@ -1912,7 +1986,7 @@ void isl_set_free(struct isl_set *set)
        free(set);
 }
 
-void isl_set_dump(struct isl_set *set, FILE *out, int indent)
+void isl_set_print_internal(struct isl_set *set, FILE *out, int indent)
 {
        int i;
 
@@ -1928,11 +2002,11 @@ void isl_set_dump(struct isl_set *set, FILE *out, int indent)
        for (i = 0; i < set->n; ++i) {
                fprintf(out, "%*s", indent, "");
                fprintf(out, "basic set %d:\n", i);
-               isl_basic_set_dump(set->p[i], out, indent+4);
+               isl_basic_set_print_internal(set->p[i], out, indent+4);
        }
 }
 
-void isl_map_dump(struct isl_map *map, FILE *out, int indent)
+void isl_map_print_internal(struct isl_map *map, FILE *out, int indent)
 {
        int i;
 
@@ -1949,7 +2023,7 @@ void isl_map_dump(struct isl_map *map, FILE *out, int indent)
        for (i = 0; i < map->n; ++i) {
                fprintf(out, "%*s", indent, "");
                fprintf(out, "basic map %d:\n", i);
-               isl_basic_map_dump(map->p[i], out, indent+4);
+               isl_basic_map_print_internal(map->p[i], out, indent+4);
        }
 }
 
@@ -1957,7 +2031,6 @@ struct isl_basic_map *isl_basic_map_intersect_domain(
                struct isl_basic_map *bmap, struct isl_basic_set *bset)
 {
        struct isl_basic_map *bmap_domain;
-       struct isl_dim *dim;
 
        if (!bmap || !bset)
                goto error;
@@ -1974,8 +2047,7 @@ struct isl_basic_map *isl_basic_map_intersect_domain(
                goto error;
        bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
                        bset->n_div, bset->n_eq, bset->n_ineq);
-       dim = isl_dim_reverse(isl_dim_copy(bset->dim));
-       bmap_domain = isl_basic_map_from_basic_set(bset, dim);
+       bmap_domain = isl_basic_map_from_domain(bset);
        bmap = add_constraints(bmap, bmap_domain, 0, 0);
 
        bmap = isl_basic_map_simplify(bmap);
@@ -2300,7 +2372,6 @@ __isl_give isl_basic_map *isl_basic_map_insert(__isl_take isl_basic_map *bmap,
        res = isl_basic_map_alloc_dim(res_dim,
                        bmap->n_div, bmap->n_eq, bmap->n_ineq);
        res = add_constraints_dim_map(res, bmap, dim_map);
-       res = isl_basic_map_simplify(res);
        return isl_basic_map_finalize(res);
 }
 
@@ -4593,7 +4664,7 @@ struct isl_set *isl_basic_set_partial_lexmax(
                        dom, empty);
 }
 
-/* Given a basic map "bmap", compute the lexicograhically minimal
+/* Given a basic map "bmap", compute the lexicographically minimal
  * (or maximal) image element for each domain element in dom.
  * Set *empty to those elements in dom that do not have an image element.
  *
@@ -4645,7 +4716,7 @@ error:
        return NULL;
 }
 
-/* Given a map "map", compute the lexicograhically minimal
+/* Given a map "map", compute the lexicographically minimal
  * (or maximal) image element for each domain element in dom.
  * Set *empty to those elements in dom that do not have an image element.
  *
@@ -4657,16 +4728,46 @@ error:
  *
  * Let res^k and todo^k be the results after k steps and let i = k + 1.
  * Assume we are computing the lexicographical maximum.
- * We first intersect basic map i with a relation that maps elements
- * to elements that are lexicographically larger than the image elements
- * in res^k and the compute the maximum image element of this intersection.
- * The result ("better") corresponds to those image elements in basic map i
- * that are better than what we had before.  The remainder ("keep") are the
- * domain elements for which the image element in res_k was better.
- * We also compute the lexicographical maximum of basic map i in todo^k.
- * res^i is the result of the operation + better + those elements in
- *             res^k that we should keep
- * todo^i is the remainder of the maximum operation on todo^k.
+ * We first compute the lexicographically maximal element in basic map i.
+ * This results in a partial solution res_i and a subset todo_i.
+ * Then we combine these results with those obtain for the first k basic maps
+ * to obtain a result that is valid for the first k+1 basic maps.
+ * In particular, the set where there is no solution is the set where
+ * there is no solution for the first k basic maps and also no solution
+ * for the ith basic map, i.e.,
+ *
+ *     todo^i = todo^k * todo_i
+ *
+ * On dom(res^k) * dom(res_i), we need to pick the larger of the two
+ * solutions, arbitrarily breaking ties in favor of res^k.
+ * That is, when res^k(a) >= res_i(a), we pick res^k and
+ * when res^k(a) < res_i(a), we pick res_i.  (Here, ">=" and "<" denote
+ * the lexicographic order.)
+ * In practice, we compute
+ *
+ *     res^k * (res_i . "<=")
+ *
+ * and
+ *
+ *     res_i * (res^k . "<")
+ *
+ * Finally, we consider the symmetric difference of dom(res^k) and dom(res_i),
+ * where only one of res^k and res_i provides a solution and we simply pick
+ * that one, i.e.,
+ *
+ *     res^k * todo_i
+ * and
+ *     res_i * todo^k
+ *
+ * Note that we only compute these intersections when dom(res^k) intersects
+ * dom(res_i).  Otherwise, the only effect of these intersections is to
+ * potentially break up res^k and res_i into smaller pieces.
+ * We want to avoid such splintering as much as possible.
+ * In fact, an earlier implementation of this function would look for
+ * better results in the domain of res^k and for extra results in todo^k,
+ * but this would always result in a splintering according to todo^k,
+ * even when the domain of basic map i is disjoint from the domains of
+ * the previous basic maps.
  */
 static __isl_give isl_map *isl_map_partial_lexopt(
                __isl_take isl_map *map, __isl_take isl_set *dom,
@@ -4691,32 +4792,38 @@ static __isl_give isl_map *isl_map_partial_lexopt(
                                        isl_set_copy(dom), &todo, max);
 
        for (i = 1; i < map->n; ++i) {
-               struct isl_map *lt;
-               struct isl_map *better;
-               struct isl_set *keep;
-               struct isl_map *res_i;
-               struct isl_set *todo_i;
-               struct isl_dim *dim = isl_map_get_dim(res);
-
-               dim = isl_dim_range(dim);
-               if (max)
-                       lt = isl_map_lex_lt(dim);
-               else
-                       lt = isl_map_lex_gt(dim);
-               lt = isl_map_apply_range(isl_map_copy(res), lt);
-               lt = isl_map_intersect(lt,
-                       isl_map_from_basic_map(isl_basic_map_copy(map->p[i])));
-               better = isl_map_partial_lexopt(lt,
-                       isl_map_domain(isl_map_copy(res)),
-                       &keep, max);
+               isl_map *lt, *le;
+               isl_map *res_i;
+               isl_set *todo_i;
+               isl_dim *dim = isl_dim_range(isl_map_get_dim(res));
 
                res_i = basic_map_partial_lexopt(isl_basic_map_copy(map->p[i]),
-                                               todo, &todo_i, max);
+                                       isl_set_copy(dom), &todo_i, max);
+
+               if (max) {
+                       lt = isl_map_lex_lt(isl_dim_copy(dim));
+                       le = isl_map_lex_le(dim);
+               } else {
+                       lt = isl_map_lex_gt(isl_dim_copy(dim));
+                       le = isl_map_lex_ge(dim);
+               }
+               lt = isl_map_apply_range(isl_map_copy(res), lt);
+               lt = isl_map_intersect(lt, isl_map_copy(res_i));
+               le = isl_map_apply_range(isl_map_copy(res_i), le);
+               le = isl_map_intersect(le, isl_map_copy(res));
+
+               if (!isl_map_is_empty(lt) || !isl_map_is_empty(le)) {
+                       res = isl_map_intersect_domain(res,
+                                                       isl_set_copy(todo_i));
+                       res_i = isl_map_intersect_domain(res_i,
+                                                       isl_set_copy(todo));
+               }
 
-               res = isl_map_intersect_domain(res, keep);
                res = isl_map_union_disjoint(res, res_i);
-               res = isl_map_union_disjoint(res, better);
-               todo = todo_i;
+               res = isl_map_union_disjoint(res, lt);
+               res = isl_map_union_disjoint(res, le);
+
+               todo = isl_set_intersect(todo, todo_i);
        }
 
        isl_set_free(dom);
@@ -6827,7 +6934,8 @@ error:
 
 /* Return the Cartesian product of the basic sets in list (in the given order).
  */
-struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list)
+__isl_give isl_basic_set *isl_basic_set_list_product(
+       __isl_take struct isl_basic_set_list *list)
 {
        int i;
        unsigned dim;
@@ -6921,9 +7029,57 @@ error:
        return NULL;
 }
 
-/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
- */
-struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
+__isl_give isl_basic_map *isl_basic_map_range_product(
+       __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
+{
+       isl_dim *dim_result = NULL;
+       isl_basic_map *bmap;
+       unsigned in, out1, out2, nparam, total, pos;
+       struct isl_dim_map *dim_map1, *dim_map2;
+
+       if (!bmap1 || !bmap2)
+               goto error;
+
+       dim_result = isl_dim_range_product(isl_dim_copy(bmap1->dim),
+                                          isl_dim_copy(bmap2->dim));
+
+       in = isl_basic_map_dim(bmap1, isl_dim_in);
+       out1 = isl_basic_map_n_out(bmap1);
+       out2 = isl_basic_map_n_out(bmap2);
+       nparam = isl_basic_map_n_param(bmap1);
+
+       total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
+       dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
+       dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
+       isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
+       isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
+       isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
+       isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
+       isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
+       isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
+       isl_dim_map_div(dim_map1, bmap1, pos += out2);
+       isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
+
+       bmap = isl_basic_map_alloc_dim(dim_result,
+                       bmap1->n_div + bmap2->n_div,
+                       bmap1->n_eq + bmap2->n_eq,
+                       bmap1->n_ineq + bmap2->n_ineq);
+       bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
+       bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
+       bmap = isl_basic_map_simplify(bmap);
+       return isl_basic_map_finalize(bmap);
+error:
+       isl_basic_map_free(bmap1);
+       isl_basic_map_free(bmap2);
+       return NULL;
+}
+
+static __isl_give isl_map *map_product(__isl_take isl_map *map1,
+       __isl_take isl_map *map2,
+       __isl_give isl_dim *(*dim_product)(__isl_take isl_dim *left,
+                                          __isl_take isl_dim *right),
+       __isl_give isl_basic_map *(*basic_map_product)(
+               __isl_take isl_basic_map *left, __isl_take isl_basic_map *right))
 {
        unsigned flags = 0;
        struct isl_map *result;
@@ -6939,17 +7095,16 @@ struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
            ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
                ISL_FL_SET(flags, ISL_MAP_DISJOINT);
 
-       result = isl_map_alloc_dim(isl_dim_product(isl_dim_copy(map1->dim),
-                                                  isl_dim_copy(map2->dim)),
+       result = isl_map_alloc_dim(dim_product(isl_dim_copy(map1->dim),
+                                              isl_dim_copy(map2->dim)),
                                map1->n * map2->n, flags);
        if (!result)
                goto error;
        for (i = 0; i < map1->n; ++i)
                for (j = 0; j < map2->n; ++j) {
                        struct isl_basic_map *part;
-                       part = isl_basic_map_product(
-                                   isl_basic_map_copy(map1->p[i]),
-                                   isl_basic_map_copy(map2->p[j]));
+                       part = basic_map_product(isl_basic_map_copy(map1->p[i]),
+                                                isl_basic_map_copy(map2->p[j]));
                        if (isl_basic_map_is_empty(part))
                                isl_basic_map_free(part);
                        else
@@ -6966,6 +7121,13 @@ error:
        return NULL;
 }
 
+/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
+ */
+struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
+{
+       return map_product(map1, map2, &isl_dim_product, &isl_basic_map_product);
+}
+
 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
  */
 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
@@ -6992,6 +7154,15 @@ __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
        return (isl_set *)isl_map_flat_product((isl_map *)set1, (isl_map *)set2);
 }
 
+/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
+ */
+__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
+       __isl_take isl_map *map2)
+{
+       return map_product(map1, map2, &isl_dim_range_product,
+                               &isl_basic_map_range_product);
+}
+
 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
 {
        int i;
@@ -7426,6 +7597,56 @@ int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
        return isl_basic_set_vars_get_sign(bset, first, n, signs);
 }
 
+/* Check if the given basic map is obviously single-valued.
+ * In particular, for each output dimension, check that there is
+ * an equality that defines the output dimension in terms of
+ * earlier dimensions.
+ */
+int isl_basic_map_fast_is_single_valued(__isl_keep isl_basic_map *bmap)
+{
+       int i, j;
+       unsigned total;
+       unsigned n_out;
+       unsigned o_out;
+
+       if (!bmap)
+               return -1;
+
+       total = 1 + isl_basic_map_total_dim(bmap);
+       n_out = isl_basic_map_dim(bmap, isl_dim_out);
+       o_out = isl_basic_map_offset(bmap, isl_dim_out);
+
+       for (i = 0; i < n_out; ++i) {
+               for (j = 0; j < bmap->n_eq; ++j) {
+                       if (isl_int_is_zero(bmap->eq[j][o_out + i]))
+                               continue;
+                       if (isl_seq_first_non_zero(bmap->eq[j] + o_out + i + 1,
+                                               total - (o_out + i + 1)) == -1)
+                               break;
+               }
+               if (j >= bmap->n_eq)
+                       return 0;
+       }
+
+       return 1;
+}
+
+/* Check if the given map is obviously single-valued.
+ */
+int isl_map_fast_is_single_valued(__isl_keep isl_map *map)
+{
+       int sv;
+
+       if (!map)
+               return -1;
+       if (map->n == 0)
+               return 1;
+       if (map->n >= 2)
+               return 0;
+
+       return isl_basic_map_fast_is_single_valued(map->p[0]);
+}
+
 /* Check if the given map is single-valued.
  * We simply compute
  *
@@ -7439,6 +7660,10 @@ int isl_map_is_single_valued(__isl_keep isl_map *map)
        isl_map *id;
        int sv;
 
+       sv = isl_map_fast_is_single_valued(map);
+       if (sv < 0 || sv)
+               return sv;
+
        test = isl_map_reverse(isl_map_copy(map));
        test = isl_map_apply_range(test, isl_map_copy(map));
 
@@ -7731,6 +7956,11 @@ error:
        return NULL;
 }
 
+__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
+{
+       return (isl_basic_set *)isl_basic_map_flatten((isl_basic_map *)bset);
+}
+
 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
 {
        int i;
index 59df4b1..452af60 100644 (file)
@@ -248,7 +248,7 @@ struct isl_diff_collector {
  * a negative value is treated as an error, but the calling
  * function can interpret the results based on the state of dc.
  *
- * Assumes that both bmap and map have known divs.
+ * Assumes that map has known divs.
  *
  * The difference is computed by a backtracking algorithm.
  * Each level corresponds to a basic map in "map".
@@ -592,7 +592,7 @@ static int map_diff_is_empty(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
 
 /* Return 1 if "bmap" contains a single element.
  */
-int isl_basic_map_is_singleton(__isl_keep isl_basic_map *bmap)
+int isl_basic_map_fast_is_singleton(__isl_keep isl_basic_map *bmap)
 {
        if (!bmap)
                return -1;
@@ -605,14 +605,14 @@ int isl_basic_map_is_singleton(__isl_keep isl_basic_map *bmap)
 
 /* Return 1 if "map" contains a single element.
  */
-int isl_map_is_singleton(__isl_keep isl_map *map)
+int isl_map_fast_is_singleton(__isl_keep isl_map *map)
 {
        if (!map)
                return -1;
        if (map->n != 1)
                return 0;
 
-       return isl_basic_map_is_singleton(map->p[0]);
+       return isl_basic_map_fast_is_singleton(map->p[0]);
 }
 
 /* Given a singleton basic map, extract the single element
@@ -671,6 +671,7 @@ error:
 
 /* Return 1 is the singleton map "map1" is a subset of "map2",
  * i.e., if the single element of "map1" is also an element of "map2".
+ * Assumes "map2" has known divs.
  */
 static int map_is_singleton_subset(__isl_keep isl_map *map1,
        __isl_keep isl_map *map2)
@@ -715,16 +716,13 @@ int isl_map_is_subset(struct isl_map *map1, struct isl_map *map2)
        if (isl_map_fast_is_universe(map2))
                return 1;
 
-       map1 = isl_map_compute_divs(isl_map_copy(map1));
        map2 = isl_map_compute_divs(isl_map_copy(map2));
-       if (isl_map_is_singleton(map1)) {
+       if (isl_map_fast_is_singleton(map1)) {
                is_subset = map_is_singleton_subset(map1, map2);
-               isl_map_free(map1);
                isl_map_free(map2);
                return is_subset;
        }
        is_subset = map_diff_is_empty(map1, map2);
-       isl_map_free(map1);
        isl_map_free(map2);
 
        return is_subset;
index 7e24907..d96de66 100644 (file)
@@ -757,3 +757,19 @@ __isl_give isl_morph *isl_basic_set_full_compression(
 
        return morph;
 }
+
+__isl_give isl_vec *isl_morph_vec(__isl_take isl_morph *morph,
+       __isl_take isl_vec *vec)
+{
+       if (!morph)
+               goto error;
+
+       vec = isl_mat_vec_product(isl_mat_copy(morph->map), vec);
+
+       isl_morph_free(morph);
+       return vec;
+error:
+       isl_morph_free(morph);
+       isl_vec_free(vec);
+       return NULL;
+}
index bbffe4b..f125cdc 100644 (file)
@@ -68,6 +68,8 @@ __isl_give isl_basic_set *isl_morph_basic_set(__isl_take isl_morph *morph,
        __isl_take isl_basic_set *bset);
 __isl_give isl_set *isl_morph_set(__isl_take isl_morph *morph,
        __isl_take isl_set *set);
+__isl_give isl_vec *isl_morph_vec(__isl_take isl_morph *morph,
+       __isl_take isl_vec *vec);
 
 #if defined(__cplusplus)
 }
index d7f4169..c603c2a 100644 (file)
@@ -75,6 +75,12 @@ static struct isl_arg_flags bernstein_recurse[] = {
        {0}
 };
 
+static struct isl_arg_choice convex[] = {
+       {"wrap",        ISL_CONVEX_HULL_WRAP},
+       {"fm",          ISL_CONVEX_HULL_FM},
+       {0}
+};
+
 static void print_version(void)
 {
        printf("%s", isl_version());
@@ -107,6 +113,8 @@ ISL_ARG_BOOL(struct isl_options, bernstein_triangulate, 0,
        "triangulate domains during Bernstein expansion")
 ISL_ARG_BOOL(struct isl_options, pip_symmetry, 0, "pip-symmetry", 1,
        "detect simple symmetries in PIP input")
+ISL_ARG_CHOICE(struct isl_options, convex, 0, "convex-hull", \
+       convex, ISL_CONVEX_HULL_WRAP, "convex hull algorithm to use")
 ISL_ARG_VERSION(print_version)
 ISL_ARG_END
 };
index b2d5625..7df6bcb 100644 (file)
@@ -650,7 +650,6 @@ static __isl_give isl_printer *isl_basic_map_print_isl(
        p = isl_printer_print_str(p, " : ");
        p = print_disjunct(bmap, bmap->dim, p, 0, latex);
        p = isl_printer_print_str(p, " }");
-       p = isl_printer_end_line(p);
        return p;
 }
 
@@ -669,7 +668,6 @@ static __isl_give isl_printer *isl_basic_set_print_isl(
        p = isl_printer_print_str(p, " : ");
        p = print_disjunct((isl_basic_map *)bset, bset->dim, p, 1, latex);
        p = isl_printer_print_str(p, " }");
-       p = isl_printer_end_line(p);
        return p;
 }
 
@@ -1168,6 +1166,62 @@ void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
        isl_printer_free(printer);
 }
 
+void isl_basic_map_dump(__isl_keep isl_basic_map *bmap)
+{
+       isl_printer *printer;
+
+       if (!bmap)
+               return;
+
+       printer = isl_printer_to_file(isl_basic_map_get_ctx(bmap), stderr);
+       printer = isl_printer_print_basic_map(printer, bmap);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
+void isl_basic_set_dump(__isl_keep isl_basic_set *bset)
+{
+       isl_printer *printer;
+
+       if (!bset)
+               return;
+
+       printer = isl_printer_to_file(isl_basic_set_get_ctx(bset), stderr);
+       printer = isl_printer_print_basic_set(printer, bset);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
+void isl_map_dump(__isl_keep isl_map *map)
+{
+       isl_printer *printer;
+
+       if (!map)
+               return;
+
+       printer = isl_printer_to_file(isl_map_get_ctx(map), stderr);
+       printer = isl_printer_print_map(printer, map);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
+void isl_set_dump(__isl_keep isl_set *set)
+{
+       isl_printer *printer;
+
+       if (!set)
+               return;
+
+       printer = isl_printer_to_file(isl_set_get_ctx(set), stderr);
+       printer = isl_printer_print_set(printer, set);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
 void isl_union_map_dump(__isl_keep isl_union_map *umap)
 {
        isl_printer *printer;
@@ -1211,6 +1265,64 @@ void isl_union_pw_qpolynomial_dump(__isl_keep isl_union_pw_qpolynomial *upwqp)
        isl_printer_free(printer);
 }
 
+void isl_qpolynomial_dump(__isl_keep isl_qpolynomial *qp)
+{
+       isl_printer *printer;
+
+       if (!qp)
+               return;
+
+       printer = isl_printer_to_file(isl_qpolynomial_get_ctx(qp), stderr);
+       printer = isl_printer_print_qpolynomial(printer, qp);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
+void isl_qpolynomial_fold_dump(__isl_keep isl_qpolynomial_fold *fold)
+{
+       isl_printer *printer;
+
+       if (!fold)
+               return;
+
+       printer = isl_printer_to_file(isl_qpolynomial_fold_get_ctx(fold),
+                                       stderr);
+       printer = isl_printer_print_qpolynomial_fold(printer, fold);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
+void isl_pw_qpolynomial_dump(__isl_keep isl_pw_qpolynomial *pwqp)
+{
+       isl_printer *printer;
+
+       if (!pwqp)
+               return;
+
+       printer = isl_printer_to_file(isl_pw_qpolynomial_get_ctx(pwqp), stderr);
+       printer = isl_printer_print_pw_qpolynomial(printer, pwqp);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
+void isl_pw_qpolynomial_fold_dump(__isl_keep isl_pw_qpolynomial_fold *pwf)
+{
+       isl_printer *printer;
+
+       if (!pwf)
+               return;
+
+       printer = isl_printer_to_file(
+                       isl_pw_qpolynomial_fold_get_ctx(pwf), stderr);
+       printer = isl_printer_print_pw_qpolynomial_fold(printer, pwf);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
+}
+
 void isl_union_pw_qpolynomial_fold_dump(
        __isl_keep isl_union_pw_qpolynomial_fold *upwf)
 {
@@ -1416,18 +1528,6 @@ static __isl_give isl_printer *qpolynomial_fold_print(
        return p;
 }
 
-__isl_give isl_printer *isl_printer_print_qpolynomial_fold(
-       __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
-{
-       if  (!p || !fold)
-               goto error;
-       p = qpolynomial_fold_print(fold, p);
-       return p;
-error:
-       isl_printer_free(p);
-       return NULL;
-}
-
 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
        FILE *out, unsigned output_format)
 {
@@ -1828,6 +1928,22 @@ static __isl_give isl_printer *print_qpolynomial_fold_c(
        return p;
 }
 
+__isl_give isl_printer *isl_printer_print_qpolynomial_fold(
+       __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
+{
+       if  (!p || !fold)
+               goto error;
+       if (p->output_format == ISL_FORMAT_ISL)
+               return qpolynomial_fold_print(fold, p);
+       else if (p->output_format == ISL_FORMAT_C)
+               return print_qpolynomial_fold_c(p, fold->dim, fold);
+       isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
+               goto error);
+error:
+       isl_printer_free(p);
+       return NULL;
+}
+
 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
        __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
 {
index f0ca434..4ae1bdf 100644 (file)
@@ -674,6 +674,48 @@ error:
        return NULL;
 }
 
+__isl_give struct isl_upoly *isl_upoly_cst_add_isl_int(
+       __isl_take struct isl_upoly *up, isl_int v)
+{
+       struct isl_upoly_cst *cst;
+
+       up = isl_upoly_cow(up);
+       if (!up)
+               return NULL;
+
+       cst = isl_upoly_as_cst(up);
+
+       isl_int_addmul(cst->n, cst->d, v);
+
+       return up;
+}
+
+__isl_give struct isl_upoly *isl_upoly_add_isl_int(
+       __isl_take struct isl_upoly *up, isl_int v)
+{
+       struct isl_upoly_rec *rec;
+
+       if (!up)
+               return NULL;
+
+       if (isl_upoly_is_cst(up))
+               return isl_upoly_cst_add_isl_int(up, v);
+
+       up = isl_upoly_cow(up);
+       rec = isl_upoly_as_rec(up);
+       if (!rec)
+               goto error;
+
+       rec->p[0] = isl_upoly_add_isl_int(rec->p[0], v);
+       if (!rec->p[0])
+               goto error;
+
+       return up;
+error:
+       isl_upoly_free(up);
+       return NULL;
+}
+
 __isl_give struct isl_upoly *isl_upoly_neg_cst(__isl_take struct isl_upoly *up)
 {
        struct isl_upoly_cst *cst;
@@ -1362,7 +1404,9 @@ __isl_give isl_qpolynomial *isl_qpolynomial_add_on_domain(
        __isl_take isl_qpolynomial *qp1,
        __isl_take isl_qpolynomial *qp2)
 {
-       return isl_qpolynomial_add(qp1, qp2);
+       qp1 = isl_qpolynomial_add(qp1, qp2);
+       qp1 = isl_qpolynomial_gist(qp1, isl_set_copy(dom));
+       return qp1;
 }
 
 __isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
@@ -1371,6 +1415,27 @@ __isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
        return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2));
 }
 
+__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int(
+       __isl_take isl_qpolynomial *qp, isl_int v)
+{
+       if (isl_int_is_zero(v))
+               return qp;
+
+       qp = isl_qpolynomial_cow(qp);
+       if (!qp)
+               return NULL;
+
+       qp->upoly = isl_upoly_add_isl_int(qp->upoly, v);
+       if (!qp->upoly)
+               goto error;
+
+       return qp;
+error:
+       isl_qpolynomial_free(qp);
+       return NULL;
+
+}
+
 __isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp)
 {
        qp = isl_qpolynomial_cow(qp);
index e12fb9c..e018bc7 100644 (file)
@@ -16,6 +16,7 @@
 #include "isl_equalities.h"
 #include "isl_tab.h"
 #include "isl_basis_reduction.h"
+#include <isl_factorization.h>
 #include <isl_point_private.h>
 
 static struct isl_vec *empty_sample(struct isl_basic_set *bset)
@@ -546,6 +547,76 @@ error:
        return NULL;
 }
 
+static struct isl_vec *sample_bounded(struct isl_basic_set *bset);
+
+/* Compute a sample point of the given basic set, based on the given,
+ * non-trivial factorization.
+ */
+static __isl_give isl_vec *factored_sample(__isl_take isl_basic_set *bset,
+       __isl_take isl_factorizer *f)
+{
+       int i, n;
+       isl_vec *sample = NULL;
+       isl_ctx *ctx;
+       unsigned nparam;
+       unsigned nvar;
+
+       ctx = isl_basic_set_get_ctx(bset);
+       if (!ctx)
+               goto error;
+
+       nparam = isl_basic_set_dim(bset, isl_dim_param);
+       nvar = isl_basic_set_dim(bset, isl_dim_set);
+
+       sample = isl_vec_alloc(ctx, 1 + isl_basic_set_total_dim(bset));
+       if (!sample)
+               goto error;
+       isl_int_set_si(sample->el[0], 1);
+
+       bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset);
+
+       for (i = 0, n = 0; i < f->n_group; ++i) {
+               isl_basic_set *bset_i;
+               isl_vec *sample_i;
+
+               bset_i = isl_basic_set_copy(bset);
+               bset_i = isl_basic_set_drop_constraints_involving(bset_i,
+                           nparam + n + f->len[i], nvar - n - f->len[i]);
+               bset_i = isl_basic_set_drop_constraints_involving(bset_i,
+                           nparam, n);
+               bset_i = isl_basic_set_drop(bset_i, isl_dim_set,
+                           n + f->len[i], nvar - n - f->len[i]);
+               bset_i = isl_basic_set_drop(bset_i, isl_dim_set, 0, n);
+
+               sample_i = sample_bounded(bset_i);
+               if (!sample_i)
+                       goto error;
+               if (sample_i->size == 0) {
+                       isl_basic_set_free(bset);
+                       isl_factorizer_free(f);
+                       isl_vec_free(sample);
+                       return sample_i;
+               }
+               isl_seq_cpy(sample->el + 1 + nparam + n,
+                           sample_i->el + 1, f->len[i]);
+               isl_vec_free(sample_i);
+
+               n += f->len[i];
+       }
+
+       f->morph = isl_morph_inverse(f->morph);
+       sample = isl_morph_vec(isl_morph_copy(f->morph), sample);
+
+       isl_basic_set_free(bset);
+       isl_factorizer_free(f);
+       return sample;
+error:
+       isl_basic_set_free(bset);
+       isl_factorizer_free(f);
+       isl_vec_free(sample);
+       return NULL;
+}
+
 /* Given a basic set that is known to be bounded, find and return
  * an integer point in the basic set, if there is any.
  *
@@ -559,6 +630,7 @@ static struct isl_vec *sample_bounded(struct isl_basic_set *bset)
        struct isl_ctx *ctx;
        struct isl_vec *sample;
        struct isl_tab *tab = NULL;
+       isl_factorizer *f;
 
        if (!bset)
                return NULL;
@@ -574,6 +646,13 @@ static struct isl_vec *sample_bounded(struct isl_basic_set *bset)
        if (bset->n_eq > 0)
                return sample_eq(bset, sample_bounded);
 
+       f = isl_basic_set_factorizer(bset);
+       if (!f)
+               goto error;
+       if (f->n_group != 0)
+               return factored_sample(bset, f);
+       isl_factorizer_free(f);
+               
        ctx = bset->ctx;
 
        tab = isl_tab_from_basic_set(bset);
index e114900..aada120 100644 (file)
@@ -73,6 +73,7 @@ static struct isl_token *isl_token_new(struct isl_ctx *ctx,
        tok->line = line;
        tok->col = col;
        tok->on_new_line = on_new_line;
+       tok->is_keyword = 0;
        return tok;
 }
 
@@ -82,7 +83,9 @@ void isl_token_free(struct isl_token *tok)
                return;
        if (tok->type == ISL_TOKEN_VALUE)
                isl_int_clear(tok->u.v);
-       else if (tok->type == ISL_TOKEN_IDENT || tok->type == ISL_TOKEN_STRING)
+       else if (tok->type == ISL_TOKEN_IDENT ||
+                tok->type == ISL_TOKEN_STRING ||
+                tok->is_keyword)
                free(tok->u.s);
        free(tok);
 }
@@ -97,6 +100,8 @@ void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg)
                        fprintf(stderr, "got '%c'\n", tok->type);
                else if (tok->type == ISL_TOKEN_IDENT)
                        fprintf(stderr, "got ident '%s'\n", tok->u.s);
+               else if (tok->is_keyword)
+                       fprintf(stderr, "got keyword '%s'\n", tok->u.s);
                else
                        fprintf(stderr, "got token type %d\n", tok->type);
        }
@@ -356,8 +361,11 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
                        isl_stream_ungetc(s, c);
                isl_stream_push_char(s, '\0');
                tok->type = check_keywords(s);
-               if (tok->type == ISL_TOKEN_IDENT)
-                       tok->u.s = strdup(s->buffer);
+               if (tok->type != ISL_TOKEN_IDENT)
+                       tok->is_keyword = 1;
+               tok->u.s = strdup(s->buffer);
+               if (!tok->u.s)
+                       goto error;
                return tok;
        }
        if (c == '"') {
index a747ec5..36ee808 100644 (file)
--- a/isl_tab.c
+++ b/isl_tab.c
@@ -3243,5 +3243,5 @@ void isl_tab_dump(struct isl_tab *tab, FILE *out, int indent)
        tab->mat->n_row = r;
        tab->mat->n_col = c;
        if (tab->bmap)
-               isl_basic_map_dump(tab->bmap, out, indent);
+               isl_basic_map_print_internal(tab->bmap, out, indent);
 }
index 08deb2a..90911b0 100644 (file)
@@ -67,6 +67,14 @@ void test_parse(struct isl_ctx *ctx)
        isl_map_free(map);
        isl_map_free(map2);
 
+       str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}";
+       map = isl_map_read_from_str(ctx, str, -1);
+       str = "{[new,old] -> [(new+1)%2,(old+1)%2]}";
+       map2 = isl_map_read_from_str(ctx, str, -1);
+       assert(isl_map_is_equal(map, map2));
+       isl_map_free(map);
+       isl_map_free(map2);
+
        test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }");
 }
 
@@ -566,10 +574,12 @@ void test_convex_hull_case(struct isl_ctx *ctx, const char *name)
        fclose(input);
 }
 
-void test_convex_hull(struct isl_ctx *ctx)
+void test_convex_hull_algo(struct isl_ctx *ctx, int convex)
 {
        const char *str1, *str2;
        isl_set *set1, *set2;
+       int orig_convex = ctx->opt->convex;
+       ctx->opt->convex = convex;
 
        test_convex_hull_case(ctx, "convex0");
        test_convex_hull_case(ctx, "convex1");
@@ -598,6 +608,14 @@ void test_convex_hull(struct isl_ctx *ctx)
        assert(isl_set_is_equal(set1, set2));
        isl_set_free(set1);
        isl_set_free(set2);
+
+       ctx->opt->convex = orig_convex;
+}
+
+void test_convex_hull(struct isl_ctx *ctx)
+{
+       test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM);
+       test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP);
 }
 
 void test_gist_case(struct isl_ctx *ctx, const char *name)
@@ -1141,7 +1159,7 @@ void test_lex(struct isl_ctx *ctx)
 void test_lexmin(struct isl_ctx *ctx)
 {
        const char *str;
-       isl_map *map;
+       isl_map *map, *map2;
        isl_set *set;
        isl_set *set2;
 
@@ -1170,6 +1188,36 @@ void test_lexmin(struct isl_ctx *ctx)
        set = isl_set_intersect(set, set2);
        assert(!isl_set_is_empty(set));
        isl_set_free(set);
+
+       str = "{ [x] -> [y] : x <= y <= 10; [x] -> [5] : -8 <= x <= 8 }";
+       map = isl_map_read_from_str(ctx, str, -1);
+       map = isl_map_lexmin(map);
+       str = "{ [x] -> [5] : 6 <= x <= 8; "
+               "[x] -> [x] : x <= 5 or (9 <= x <= 10) }";
+       map2 = isl_map_read_from_str(ctx, str, -1);
+       assert(isl_map_is_equal(map, map2));
+       isl_map_free(map);
+       isl_map_free(map2);
+
+       str = "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }";
+       map = isl_map_read_from_str(ctx, str, -1);
+       map2 = isl_map_copy(map);
+       map = isl_map_lexmin(map);
+       assert(isl_map_is_equal(map, map2));
+       isl_map_free(map);
+       isl_map_free(map2);
+
+       str = "{ [x] -> [y] : x = 4y; [x] -> [y] : x = 2y }";
+       map = isl_map_read_from_str(ctx, str, -1);
+       map = isl_map_lexmin(map);
+       str = "{ [x] -> [y] : (4y = x and x >= 0) or "
+               "(exists (e0 = [(x)/4], e1 = [(-2 + x)/4]: 2y = x and "
+               "4e1 = -2 + x and 4e0 <= -1 + x and 4e0 >= -3 + x)) or "
+               "(exists (e0 = [(x)/4]: 2y = x and 4e0 = x and x <= -4)) }";
+       map2 = isl_map_read_from_str(ctx, str, -1);
+       assert(isl_map_is_equal(map, map2));
+       isl_map_free(map);
+       isl_map_free(map2);
 }
 
 struct must_may {
index b794c36..667fa62 100644 (file)
@@ -877,6 +877,25 @@ __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
        return isl_union_map_product(uset1, uset2);
 }
 
+static int range_product_entry(void **entry, void *user)
+{
+       struct isl_union_map_bin_data *data = user;
+       isl_map *map2 = *entry;
+
+       map2 = isl_map_range_product(isl_map_copy(data->map),
+                                    isl_map_copy(map2));
+
+       data->res = isl_union_map_add_map(data->res, map2);
+
+       return 0;
+}
+
+__isl_give isl_union_map *isl_union_map_range_product(
+       __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
+{
+       return bin_op(umap1, umap2, &range_product_entry);
+}
+
 __isl_give isl_union_map *isl_union_map_from_range(
        __isl_take isl_union_set *uset)
 {
@@ -954,6 +973,27 @@ __isl_give isl_union_set *isl_union_set_polyhedral_hull(
        return isl_union_map_polyhedral_hull(uset);
 }
 
+static int simple_entry(void **entry, void *user)
+{
+       isl_map **map = (isl_map **)entry;
+
+       *map = isl_map_from_basic_map(isl_map_simple_hull(*map));
+
+       return *map ? 0 : -1;
+}
+
+__isl_give isl_union_map *isl_union_map_simple_hull(
+       __isl_take isl_union_map *umap)
+{
+       return un_op(umap, &simple_entry);
+}
+
+__isl_give isl_union_set *isl_union_set_simple_hull(
+       __isl_take isl_union_set *uset)
+{
+       return isl_union_map_simple_hull(uset);
+}
+
 static int inplace_entry(void **entry, void *user)
 {
        __isl_give isl_map *(*fn)(__isl_take isl_map *) = user;
@@ -998,6 +1038,18 @@ __isl_give isl_union_set *isl_union_set_coalesce(
        return isl_union_map_coalesce(uset);
 }
 
+__isl_give isl_union_map *isl_union_map_detect_equalities(
+       __isl_take isl_union_map *umap)
+{
+       return inplace(umap, &isl_map_detect_equalities);
+}
+
+__isl_give isl_union_set *isl_union_set_detect_equalities(
+       __isl_take isl_union_set *uset)
+{
+       return isl_union_map_detect_equalities(uset);
+}
+
 __isl_give isl_union_map *isl_union_map_compute_divs(
        __isl_take isl_union_map *umap)
 {
index 00b0332..38a55a7 100644 (file)
--- a/isl_vec.c
+++ b/isl_vec.c
@@ -128,22 +128,40 @@ void isl_vec_free(struct isl_vec *vec)
        free(vec);
 }
 
-void isl_vec_dump(struct isl_vec *vec, FILE *out, int indent)
+__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer,
+       __isl_keep isl_vec *vec)
 {
        int i;
 
-       if (!vec) {
-               fprintf(out, "%*snull vec\n", indent, "");
-               return;
-       }
+       if (!printer || !vec)
+               goto error;
 
-       fprintf(out, "%*s[", indent, "");
+       printer = isl_printer_print_str(printer, "[");
        for (i = 0; i < vec->size; ++i) {
                if (i)
-                   fprintf(out, ",");
-               isl_int_print(out, vec->el[i], 0);
+                       printer = isl_printer_print_str(printer, ",");
+               printer = isl_printer_print_isl_int(printer, vec->el[i]);
        }
-       fprintf(out, "]\n");
+       printer = isl_printer_print_str(printer, "]");
+
+       return printer;
+error:
+       isl_printer_free(printer);
+       return NULL;
+}
+
+void isl_vec_dump(struct isl_vec *vec)
+{
+       isl_printer *printer;
+
+       if (!vec)
+               return;
+
+       printer = isl_printer_to_file(vec->ctx, stderr);
+       printer = isl_printer_print_vec(printer, vec);
+       printer = isl_printer_end_line(printer);
+
+       isl_printer_free(printer);
 }
 
 __isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec)
index d27d290..94fe7f5 100644 (file)
@@ -62,6 +62,7 @@ int main(int argc, char **argv)
        isl_int opt;
        unsigned dim;
        enum isl_lp_result res;
+       isl_printer *p;
 
        isl_int_init(opt);
        bset = isl_basic_set_read_from_file(ctx, stdin, 0);
@@ -86,9 +87,12 @@ int main(int argc, char **argv)
                fprintf(stdout, "unbounded\n");
                break;
        case isl_lp_ok:
-               isl_vec_dump(sol, stdout, 0);
-               isl_int_print(stdout, opt, 0);
-               fprintf(stdout, "\n");
+               p = isl_printer_to_file(ctx, stdout);
+               p = isl_printer_print_vec(p, sol);
+               p = isl_printer_end_line(p);
+               p = isl_printer_print_isl_int(p, opt);
+               p = isl_printer_end_line(p);
+               isl_printer_free(p);
        }
        isl_basic_set_free(bset);
        isl_vec_free(obj);
index 7d4fe18..8716513 100644 (file)
@@ -17,10 +17,14 @@ int main(int argc, char **argv)
        struct isl_ctx *ctx = isl_ctx_alloc();
        struct isl_basic_set *bset;
        struct isl_vec *sample;
+       isl_printer *p;
 
        bset = isl_basic_set_read_from_file(ctx, stdin, 0);
        sample = isl_basic_set_sample_vec(isl_basic_set_copy(bset));
-       isl_vec_dump(sample, stdout, 0);
+       p = isl_printer_to_file(ctx, stdout);
+       p = isl_printer_print_vec(p, sample);
+       p = isl_printer_end_line(p);
+       isl_printer_free(p);
        assert(sample);
        if (sample->size > 0)
                assert(isl_basic_set_contains(bset, sample));