add some functions for manipulating constraints
[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 constraint.bset->nparam;
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 constraint.bset->dim;
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         if (!isl_basic_set_constraint_is_valid(constraint))
104                 return;
105         isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return);
106         isl_int_set(*v, constraint.line[0][1 + constraint.bset->nparam + pos]);
107 }
108
109 void isl_basic_set_constraint_get_div(
110         struct isl_basic_set_constraint constraint, int pos, isl_int *v)
111 {
112         if (!isl_basic_set_constraint_is_valid(constraint))
113                 return;
114         isl_assert(constraint.bset->ctx, pos < constraint.bset->n_div, return);
115         isl_int_set(*v, constraint.line[0][1 + constraint.bset->nparam +
116                                                 constraint.bset->dim + pos]);
117 }
118
119 void isl_basic_set_constraint_get_param(
120         struct isl_basic_set_constraint constraint, int pos, isl_int *v)
121 {
122         if (!isl_basic_set_constraint_is_valid(constraint))
123                 return;
124         isl_assert(constraint.bset->ctx, pos < constraint.bset->nparam, return);
125         isl_int_set(*v, constraint.line[0][1 + pos]);
126 }
127
128 void isl_basic_set_constraint_set_dim(
129         struct isl_basic_set_constraint constraint, int pos, isl_int v)
130 {
131         if (!isl_basic_set_constraint_is_valid(constraint))
132                 return;
133         isl_assert(constraint.bset->ctx, constraint.bset->ref == 1, return);
134         isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return);
135         isl_int_set(constraint.line[0][1 + constraint.bset->nparam + pos], v);
136 }
137
138 void isl_basic_set_constraint_set_param(
139         struct isl_basic_set_constraint constraint, int pos, isl_int v)
140 {
141         if (!isl_basic_set_constraint_is_valid(constraint))
142                 return;
143         isl_assert(constraint.bset->ctx, constraint.bset->ref == 1, return);
144         isl_assert(constraint.bset->ctx, pos < constraint.bset->nparam, return);
145         isl_int_set(constraint.line[0][1 + pos], v);
146 }
147
148 void isl_basic_set_constraint_clear(struct isl_basic_set_constraint constraint)
149 {
150         struct isl_basic_set *bset = constraint.bset;
151         unsigned total;
152
153         if (!isl_basic_set_constraint_is_valid(constraint))
154                 return;
155         total = bset->nparam + bset->dim + bset->n_div;
156         isl_seq_clr(constraint.line[0], 1 + total);
157 }
158
159 int isl_basic_set_constraint_is_equality(
160         struct isl_basic_set_constraint constraint)
161 {
162         if (!isl_basic_set_constraint_is_valid(constraint))
163                 return -1;
164         return constraint.line < constraint.bset->eq + constraint.bset->n_eq;
165 }
166
167 int isl_basic_set_constraint_is_dim_lower_bound(
168         struct isl_basic_set_constraint constraint, int pos)
169 {
170         if (!isl_basic_set_constraint_is_valid(constraint))
171                 return -1;
172         isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return -1);
173         return isl_int_is_pos(constraint.line[0][1+constraint.bset->nparam+pos]);
174 }
175
176 int isl_basic_set_constraint_is_dim_upper_bound(
177         struct isl_basic_set_constraint constraint, int pos)
178 {
179         if (!isl_basic_set_constraint_is_valid(constraint))
180                 return -1;
181         isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return -1);
182         return isl_int_is_neg(constraint.line[0][1+constraint.bset->nparam+pos]);
183 }
184
185
186 struct isl_basic_set *isl_basic_set_from_constraint(
187         struct isl_basic_set_constraint constraint)
188 {
189         int k;
190         struct isl_basic_set *bset;
191         isl_int *c;
192         unsigned total;
193
194         if (!isl_basic_set_constraint_is_valid(constraint))
195                 return NULL;
196
197         bset = isl_basic_set_universe(constraint.bset->ctx,
198                                 constraint.bset->nparam, constraint.bset->dim);
199         bset = isl_basic_set_align_divs(bset, constraint.bset);
200         bset = isl_basic_set_extend(bset, bset->nparam, bset->dim, 0, 1, 1);
201         if (isl_basic_set_constraint_is_equality(constraint)) {
202                 k = isl_basic_set_alloc_equality(bset);
203                 if (k < 0)
204                         goto error;
205                 c = bset->eq[k];
206         }
207         else {
208                 k = isl_basic_set_alloc_inequality(bset);
209                 if (k < 0)
210                         goto error;
211                 c = bset->ineq[k];
212         }
213         total = bset->nparam + bset->dim + bset->n_div;
214         isl_seq_cpy(c, constraint.line[0], 1 + total);
215         return bset;
216 error:
217         isl_basic_set_free(bset);
218         return NULL;
219 }
220
221 int isl_basic_set_has_defining_equality(
222         struct isl_basic_set *bset, int pos,
223         struct isl_basic_set_constraint *constraint)
224 {
225         int i;
226
227         if (!bset)
228                 return -1;
229         isl_assert(bset->ctx, pos < bset->dim, return -1);
230         for (i = 0; i < bset->n_eq; ++i)
231                 if (!isl_int_is_zero(bset->eq[i][1 + bset->nparam + pos]) &&
232                     isl_seq_first_non_zero(bset->eq[i]+1+bset->nparam+pos+1,
233                                            bset->dim-pos-1) == -1) {
234                         constraint->bset = bset;
235                         constraint->line = &bset->eq[i];
236                         return 1;
237                 }
238         return 0;
239 }
240
241 int isl_basic_set_has_defining_inequalities(
242         struct isl_basic_set *bset, int pos,
243         struct isl_basic_set_constraint *lower,
244         struct isl_basic_set_constraint *upper)
245 {
246         int i, j;
247         unsigned total;
248         isl_int m;
249
250         if (!bset)
251                 return -1;
252         isl_assert(bset->ctx, pos < bset->dim, return -1);
253         total = bset->nparam + bset->dim + bset->n_div;
254         isl_int_init(m);
255         for (i = 0; i < bset->n_ineq; ++i) {
256                 if (isl_int_is_zero(bset->ineq[i][1 + bset->nparam + pos]))
257                         continue;
258                 if (isl_int_is_one(bset->ineq[i][1 + bset->nparam + pos]))
259                         continue;
260                 if (isl_int_is_negone(bset->ineq[i][1 + bset->nparam + pos]))
261                         continue;
262                 if (isl_seq_first_non_zero(bset->ineq[i]+1+bset->nparam+pos+1,
263                                                 bset->dim-pos-1) != -1)
264                         continue;
265                 for (j = i + i; j < bset->n_ineq; ++j) {
266                         if (!isl_seq_is_neg(bset->ineq[i]+1, bset->ineq[j]+1,
267                                             total))
268                                 continue;
269                         isl_int_add(m, bset->ineq[i][0], bset->ineq[j][0]);
270                         if (isl_int_abs_ge(m, bset->ineq[i][1+bset->nparam+pos]))
271                                 continue;
272
273                         lower->bset = bset;
274                         upper->bset = bset;
275                         if (isl_int_is_pos(bset->ineq[i][1+bset->nparam+pos])) {
276                                 lower->line = &bset->ineq[i];
277                                 upper->line = &bset->ineq[j];
278                         } else {
279                                 lower->line = &bset->ineq[j];
280                                 upper->line = &bset->ineq[i];
281                         }
282                         isl_int_clear(m);
283                         return 1;
284                 }
285         }
286         isl_int_clear(m);
287         return 0;
288 }