allow parameters and dimensions to be named
[platform/upstream/isl.git] / isl_map_polylib.c
1 #include "isl_set.h"
2 #include "isl_map.h"
3 #include "isl_seq.h"
4 #include "isl_map_polylib.h"
5 #include "isl_map_private.h"
6
7 static void copy_values_from(isl_int *dst, Value *src, unsigned n)
8 {
9         int i;
10
11         for (i = 0; i < n; ++i)
12                 value_assign(dst[i], src[i]);
13 }
14
15 static void copy_values_to(Value *dst, isl_int *src, unsigned n)
16 {
17         int i;
18
19         for (i = 0; i < n; ++i)
20                 value_assign(dst[i], src[i]);
21 }
22
23 static void copy_constraint_from(isl_int *dst, Value *src,
24                 unsigned nparam, unsigned dim, unsigned extra)
25 {
26         copy_values_from(dst, src+1+dim+extra+nparam, 1);
27         copy_values_from(dst+1, src+1+dim+extra, nparam);
28         copy_values_from(dst+1+nparam, src+1, dim);
29         copy_values_from(dst+1+nparam+dim, src+1+dim, extra);
30 }
31
32 static void copy_constraint_to(Value *dst, isl_int *src,
33                 unsigned nparam, unsigned dim, unsigned extra)
34 {
35         copy_values_to(dst+1+dim+extra+nparam, src, 1);
36         copy_values_to(dst+1+dim+extra, src+1, nparam);
37         copy_values_to(dst+1, src+1+nparam, dim);
38         copy_values_to(dst+1+dim, src+1+nparam+dim, extra);
39 }
40
41 static int add_equality(struct isl_ctx *ctx, struct isl_basic_map *bmap,
42                          Value *constraint)
43 {
44         unsigned nparam;
45         unsigned n_in;
46         unsigned n_out;
47         int i = isl_basic_map_alloc_equality(bmap);
48         if (i < 0)
49                 return -1;
50         nparam = isl_basic_map_n_param(bmap);
51         n_in = isl_basic_map_n_in(bmap);
52         n_out = isl_basic_map_n_out(bmap);
53         copy_constraint_from(bmap->eq[i], constraint, nparam,
54                              n_in + n_out, bmap->extra);
55         return 0;
56 }
57
58 static int add_inequality(struct isl_ctx *ctx, struct isl_basic_map *bmap,
59                          Value *constraint)
60 {
61         unsigned nparam;
62         unsigned n_in;
63         unsigned n_out;
64         int i = isl_basic_map_alloc_inequality(bmap);
65         if (i < 0)
66                 return -1;
67         nparam = isl_basic_map_n_param(bmap);
68         n_in = isl_basic_map_n_in(bmap);
69         n_out = isl_basic_map_n_out(bmap);
70         copy_constraint_from(bmap->ineq[i], constraint, nparam,
71                              n_in + n_out, bmap->extra);
72         return 0;
73 }
74
75 static struct isl_basic_map *copy_constraints(
76                         struct isl_ctx *ctx, struct isl_basic_map *bmap,
77                         Polyhedron *P)
78 {
79         int i;
80         unsigned total = isl_basic_map_total_dim(bmap);
81
82         for (i = 0; i < P->NbConstraints; ++i) {
83                 if (value_zero_p(P->Constraint[i][0])) {
84                         if (add_equality(ctx, bmap, P->Constraint[i]))
85                                 goto error;
86                 } else {
87                         if (add_inequality(ctx, bmap, P->Constraint[i]))
88                                 goto error;
89                 }
90         }
91         for (i = 0; i < bmap->extra; ++i) {
92                 int j = isl_basic_map_alloc_div(bmap);
93                 if (j == -1)
94                         goto error;
95                 isl_seq_clr(bmap->div[j], 1+1+total);
96         }
97         return bmap;
98 error:
99         isl_basic_map_free(bmap);
100         return NULL;
101 }
102
103 struct isl_basic_set *isl_basic_set_new_from_polylib(
104                         struct isl_ctx *ctx,
105                         Polyhedron *P, struct isl_dim *dim)
106 {
107         isl_assert(ctx, dim->n_in == 0, return NULL);
108
109         return (struct isl_basic_set *)
110                 isl_basic_map_new_from_polylib(ctx, P, dim);
111 }
112
113 struct isl_basic_map *isl_basic_map_new_from_polylib(
114                         struct isl_ctx *ctx, Polyhedron *P,
115                         struct isl_dim *dim)
116 {
117         struct isl_basic_map *bmap;
118         unsigned extra;
119
120         isl_assert(ctx, P, goto error);
121         isl_assert(ctx, P->Dimension >= isl_dim_total(dim), goto error);
122
123         extra = P->Dimension - isl_dim_total(dim);
124         bmap = isl_basic_map_alloc_dim(ctx, dim, extra,
125                                         P->NbEq, P->NbConstraints - P->NbEq);
126         if (!bmap)
127                 return NULL;
128
129         bmap = copy_constraints(ctx, bmap, P);
130         bmap = isl_basic_map_simplify(bmap);
131         return isl_basic_map_finalize(bmap);
132 error:
133         isl_dim_free(dim);
134         return NULL;
135 }
136
137 struct isl_set *isl_set_new_from_polylib(struct isl_ctx *ctx,
138                         Polyhedron *D, struct isl_dim *dim)
139 {
140         struct isl_set *set = NULL;
141         Polyhedron *P;
142         int n = 0;
143
144         if (!dim)
145                 return NULL;
146         isl_assert(ctx, dim->n_in == 0, goto error);
147
148         for (P = D; P; P = P->next)
149                 ++n;
150
151         set = isl_set_alloc_dim(ctx, isl_dim_copy(dim), n, ISL_MAP_DISJOINT);
152         if (!set)
153                 goto error;
154
155         for (P = D; P; P = P->next)
156                 isl_set_add(set,
157                     isl_basic_set_new_from_polylib(ctx, P, isl_dim_copy(dim)));
158         isl_dim_free(dim);
159         set = isl_set_remove_empty_parts(set);
160         return set;
161 error:
162         isl_dim_free(dim);
163         return NULL;
164 }
165
166 struct isl_map *isl_map_new_from_polylib(struct isl_ctx *ctx,
167                         Polyhedron *D,
168                         struct isl_dim *dim)
169 {
170         struct isl_map *map = NULL;
171         Polyhedron *P;
172         int n = 0;
173
174         for (P = D; P; P = P->next)
175                 ++n;
176
177         map = isl_map_alloc_dim(ctx, isl_dim_copy(dim), n, ISL_MAP_DISJOINT);
178         if (!map)
179                 goto error;
180
181         for (P = D; P; P = P->next)
182                 isl_map_add(map,
183                     isl_basic_map_new_from_polylib(ctx, P, isl_dim_copy(dim)));
184         isl_dim_free(dim);
185         map = isl_map_remove_empty_parts(map);
186         return map;
187 error:
188         isl_dim_free(dim);
189         return NULL;
190 }
191
192 Polyhedron *isl_basic_map_to_polylib(struct isl_basic_map *bmap)
193 {
194         int i;
195         Matrix *M;
196         Polyhedron *P;
197         unsigned off;
198         unsigned nparam;
199         unsigned n_in;
200         unsigned n_out;
201
202         if (!bmap)
203                 return NULL;
204
205         nparam = isl_basic_map_n_param(bmap);
206         n_in = isl_basic_map_n_in(bmap);
207         n_out = isl_basic_map_n_out(bmap);
208         M = Matrix_Alloc(bmap->n_eq + bmap->n_ineq,
209                  1 + n_in + n_out + bmap->n_div + nparam + 1);
210         for (i = 0; i < bmap->n_eq; ++i) {
211                 value_set_si(M->p[i][0], 0);
212                 copy_constraint_to(M->p[i], bmap->eq[i],
213                            nparam, n_in + n_out, bmap->n_div);
214         }
215         off = bmap->n_eq;
216         for (i = 0; i < bmap->n_ineq; ++i) {
217                 value_set_si(M->p[off+i][0], 1);
218                 copy_constraint_to(M->p[off+i], bmap->ineq[i],
219                            nparam, n_in + n_out, bmap->n_div);
220         }
221         P = Constraints2Polyhedron(M, bmap->ctx->MaxRays);
222         Matrix_Free(M);
223
224         return P;
225 }
226
227 Polyhedron *isl_map_to_polylib(struct isl_map *map)
228 {
229         int i;
230         Polyhedron *R = NULL;
231         Polyhedron **next = &R;
232
233         if (!map)
234                 return NULL;
235
236         for (i = 0; i < map->n; ++i) {
237                 *next = isl_basic_map_to_polylib(map->p[i]);
238                 next = &(*next)->next;
239         }
240
241         return R ? R : Empty_Polyhedron(isl_dim_total(map->dim));
242 }
243
244 Polyhedron *isl_basic_set_to_polylib(struct isl_basic_set *bset)
245 {
246         return isl_basic_map_to_polylib((struct isl_basic_map *)bset);
247 }
248
249 Polyhedron *isl_set_to_polylib(struct isl_set *set)
250 {
251         return isl_map_to_polylib((struct isl_map *)set);
252 }