65d7f900bf27e5bff562a97cd7ce206f4079297b
[platform/upstream/isl.git] / isl_constraint.c
1 #include <isl_constraint.h>
2 #include "isl_map_private.h"
3
4 struct isl_basic_set *isl_basic_set_constraint_set(
5         struct isl_basic_set_constraint constraint)
6 {
7         return constraint.bset;
8 }
9
10 struct isl_basic_set_constraint isl_basic_set_constraint_invalid()
11 {
12         struct isl_basic_set_constraint c;
13         c.bset = NULL;
14         c.line = NULL;
15         return c;
16 }
17
18 struct isl_basic_set_constraint isl_basic_set_first_constraint(
19         struct isl_basic_set *bset)
20 {
21         struct isl_basic_set_constraint c;
22
23         if (!bset)
24                 return isl_basic_set_constraint_invalid();
25
26         if (bset->n_eq > 0) {
27                 c.bset = bset;
28                 c.line = &bset->eq[0];
29                 return c;
30         }
31
32         if (bset->n_ineq > 0) {
33                 c.bset = bset;
34                 c.line = &bset->ineq[0];
35                 return c;
36         }
37
38         return isl_basic_set_constraint_invalid();
39 }
40
41 struct isl_basic_set_constraint isl_basic_set_constraint_next(
42         struct isl_basic_set_constraint constraint)
43 {
44         struct isl_basic_set_constraint c = constraint;
45
46         c.line++;
47         if (c.line >= c.bset->eq + c.bset->n_eq && c.line < c.bset->ineq)
48                 c.line = c.bset->ineq;
49         if (c.line >= c.bset->ineq + c.bset->n_ineq)
50                 return isl_basic_set_constraint_invalid();
51         return c;
52 }
53
54 int isl_basic_set_constraint_is_valid(
55         struct isl_basic_set_constraint constraint)
56 {
57         return constraint.bset != NULL && constraint.line != NULL;
58 }
59
60 int isl_basic_set_constraint_is_equal(
61         struct isl_basic_set_constraint constraint1,
62         struct isl_basic_set_constraint constraint2)
63 {
64         return constraint1.bset == constraint2.bset &&
65                constraint1.line == constraint2.line;
66 }
67
68 int isl_basic_set_constraint_nparam(
69         struct isl_basic_set_constraint constraint)
70 {
71         if (!isl_basic_set_constraint_is_valid(constraint))
72                 return -1;
73         return isl_basic_set_n_param(constraint.bset);
74 }
75
76 int isl_basic_set_constraint_dim(
77         struct isl_basic_set_constraint constraint)
78 {
79         if (!isl_basic_set_constraint_is_valid(constraint))
80                 return -1;
81         return isl_basic_set_n_dim(constraint.bset);
82 }
83
84 int isl_basic_set_constraint_n_div(
85         struct isl_basic_set_constraint constraint)
86 {
87         if (!isl_basic_set_constraint_is_valid(constraint))
88                 return -1;
89         return constraint.bset->n_div;
90 }
91
92 void isl_basic_set_constraint_get_constant(
93         struct isl_basic_set_constraint constraint, isl_int *v)
94 {
95         if (!isl_basic_set_constraint_is_valid(constraint))
96                 return;
97         isl_int_set(*v, constraint.line[0][0]);
98 }
99
100 void isl_basic_set_constraint_get_dim(
101         struct isl_basic_set_constraint constraint, int pos, isl_int *v)
102 {
103         unsigned dim;
104         unsigned nparam;
105         if (!isl_basic_set_constraint_is_valid(constraint))
106                 return;
107         nparam = isl_basic_set_n_param(constraint.bset);
108         dim = isl_basic_set_n_dim(constraint.bset);
109         isl_assert(constraint.bset->ctx, pos < dim, return);
110         isl_int_set(*v, constraint.line[0][1 + nparam + pos]);
111 }
112
113 void isl_basic_set_constraint_get_div(
114         struct isl_basic_set_constraint constraint, int pos, isl_int *v)
115 {
116         unsigned dim;
117         unsigned nparam;
118         if (!isl_basic_set_constraint_is_valid(constraint))
119                 return;
120         nparam = isl_basic_set_n_param(constraint.bset);
121         dim = isl_basic_set_n_dim(constraint.bset);
122         isl_assert(constraint.bset->ctx, pos < constraint.bset->n_div, return);
123         isl_int_set(*v, constraint.line[0][1 + nparam + dim + pos]);
124 }
125
126 void isl_basic_set_constraint_get_param(
127         struct isl_basic_set_constraint constraint, int pos, isl_int *v)
128 {
129         unsigned nparam;
130         if (!isl_basic_set_constraint_is_valid(constraint))
131                 return;
132         nparam = isl_basic_set_n_param(constraint.bset);
133         isl_assert(constraint.bset->ctx, pos < nparam, return);
134         isl_int_set(*v, constraint.line[0][1 + pos]);
135 }
136
137 void isl_basic_set_constraint_set_dim(
138         struct isl_basic_set_constraint constraint, int pos, isl_int v)
139 {
140         unsigned dim;
141         unsigned nparam;
142         if (!isl_basic_set_constraint_is_valid(constraint))
143                 return;
144         isl_assert(constraint.bset->ctx, constraint.bset->ref == 1, return);
145         nparam = isl_basic_set_n_param(constraint.bset);
146         dim = isl_basic_set_n_dim(constraint.bset);
147         isl_assert(constraint.bset->ctx, pos < dim, return);
148         isl_int_set(constraint.line[0][1 + nparam + pos], v);
149 }
150
151 void isl_basic_set_constraint_set_param(
152         struct isl_basic_set_constraint constraint, int pos, isl_int v)
153 {
154         unsigned nparam;
155         if (!isl_basic_set_constraint_is_valid(constraint))
156                 return;
157         isl_assert(constraint.bset->ctx, constraint.bset->ref == 1, return);
158         nparam = isl_basic_set_n_param(constraint.bset);
159         isl_assert(constraint.bset->ctx, pos < nparam, return);
160         isl_int_set(constraint.line[0][1 + pos], v);
161 }
162
163 void isl_basic_set_constraint_clear(struct isl_basic_set_constraint constraint)
164 {
165         struct isl_basic_set *bset = constraint.bset;
166         unsigned total;
167
168         if (!isl_basic_set_constraint_is_valid(constraint))
169                 return;
170         total = isl_basic_set_total_dim(bset);
171         isl_seq_clr(constraint.line[0], 1 + total);
172 }
173
174 int isl_basic_set_constraint_is_equality(
175         struct isl_basic_set_constraint constraint)
176 {
177         if (!isl_basic_set_constraint_is_valid(constraint))
178                 return -1;
179         return constraint.line < constraint.bset->eq + constraint.bset->n_eq;
180 }
181
182 int isl_basic_set_constraint_is_dim_lower_bound(
183         struct isl_basic_set_constraint constraint, int pos)
184 {
185         unsigned dim;
186         unsigned nparam;
187         if (!isl_basic_set_constraint_is_valid(constraint))
188                 return -1;
189         nparam = isl_basic_set_n_param(constraint.bset);
190         dim = isl_basic_set_n_dim(constraint.bset);
191         isl_assert(constraint.bset->ctx, pos < dim, return -1);
192         return isl_int_is_pos(constraint.line[0][1+nparam+pos]);
193 }
194
195 int isl_basic_set_constraint_is_dim_upper_bound(
196         struct isl_basic_set_constraint constraint, int pos)
197 {
198         unsigned dim;
199         unsigned nparam;
200         if (!isl_basic_set_constraint_is_valid(constraint))
201                 return -1;
202         nparam = isl_basic_set_n_param(constraint.bset);
203         dim = isl_basic_set_n_dim(constraint.bset);
204         isl_assert(constraint.bset->ctx, pos < dim, return -1);
205         return isl_int_is_neg(constraint.line[0][1+nparam+pos]);
206 }
207
208
209 struct isl_basic_set *isl_basic_set_from_constraint(
210         struct isl_basic_set_constraint constraint)
211 {
212         int k;
213         struct isl_basic_set *bset;
214         isl_int *c;
215         unsigned dim;
216         unsigned nparam;
217         unsigned total;
218
219         if (!isl_basic_set_constraint_is_valid(constraint))
220                 return NULL;
221
222         bset = isl_basic_set_universe_like(constraint.bset);
223         bset = isl_basic_set_align_divs(bset, constraint.bset);
224         nparam = isl_basic_set_n_param(bset);
225         dim = isl_basic_set_n_dim(bset);
226         bset = isl_basic_set_extend(bset, nparam, dim, 0, 1, 1);
227         if (isl_basic_set_constraint_is_equality(constraint)) {
228                 k = isl_basic_set_alloc_equality(bset);
229                 if (k < 0)
230                         goto error;
231                 c = bset->eq[k];
232         }
233         else {
234                 k = isl_basic_set_alloc_inequality(bset);
235                 if (k < 0)
236                         goto error;
237                 c = bset->ineq[k];
238         }
239         total = isl_basic_set_total_dim(bset);
240         isl_seq_cpy(c, constraint.line[0], 1 + total);
241         return bset;
242 error:
243         isl_basic_set_free(bset);
244         return NULL;
245 }
246
247 int isl_basic_set_has_defining_equality(
248         struct isl_basic_set *bset, int pos,
249         struct isl_basic_set_constraint *constraint)
250 {
251         int i;
252         unsigned dim, nparam;
253
254         if (!bset)
255                 return -1;
256         nparam = isl_basic_set_n_param(bset);
257         dim = isl_basic_set_n_dim(bset);
258         isl_assert(bset->ctx, pos < dim, return -1);
259         for (i = 0; i < bset->n_eq; ++i)
260                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + pos]) &&
261                     isl_seq_first_non_zero(bset->eq[i]+1+nparam+pos+1,
262                                            dim-pos-1) == -1) {
263                         constraint->bset = bset;
264                         constraint->line = &bset->eq[i];
265                         return 1;
266                 }
267         return 0;
268 }
269
270 int isl_basic_set_has_defining_inequalities(
271         struct isl_basic_set *bset, int pos,
272         struct isl_basic_set_constraint *lower,
273         struct isl_basic_set_constraint *upper)
274 {
275         int i, j;
276         unsigned dim;
277         unsigned nparam;
278         unsigned total;
279         isl_int m;
280
281         if (!bset)
282                 return -1;
283         nparam = isl_basic_set_n_param(bset);
284         dim = isl_basic_set_n_dim(bset);
285         total = isl_basic_set_total_dim(bset);
286         isl_assert(bset->ctx, pos < dim, return -1);
287         isl_int_init(m);
288         for (i = 0; i < bset->n_ineq; ++i) {
289                 if (isl_int_is_zero(bset->ineq[i][1 + nparam + pos]))
290                         continue;
291                 if (isl_int_is_one(bset->ineq[i][1 + nparam + pos]))
292                         continue;
293                 if (isl_int_is_negone(bset->ineq[i][1 + nparam + pos]))
294                         continue;
295                 if (isl_seq_first_non_zero(bset->ineq[i]+1+nparam+pos+1,
296                                                 dim-pos-1) != -1)
297                         continue;
298                 for (j = i + i; j < bset->n_ineq; ++j) {
299                         if (!isl_seq_is_neg(bset->ineq[i]+1, bset->ineq[j]+1,
300                                             total))
301                                 continue;
302                         isl_int_add(m, bset->ineq[i][0], bset->ineq[j][0]);
303                         if (isl_int_abs_ge(m, bset->ineq[i][1+nparam+pos]))
304                                 continue;
305
306                         lower->bset = bset;
307                         upper->bset = bset;
308                         if (isl_int_is_pos(bset->ineq[i][1+nparam+pos])) {
309                                 lower->line = &bset->ineq[i];
310                                 upper->line = &bset->ineq[j];
311                         } else {
312                                 lower->line = &bset->ineq[j];
313                                 upper->line = &bset->ineq[i];
314                         }
315                         isl_int_clear(m);
316                         return 1;
317                 }
318         }
319         isl_int_clear(m);
320         return 0;
321 }