2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
10 #include <isl_ctx_private.h>
11 #include <isl_map_private.h>
12 #include "isl_basis_reduction.h"
16 #include <isl_val_private.h>
17 #include <isl_vec_private.h>
20 struct isl_scan_callback callback
;
25 static isl_stat
increment_counter(struct isl_scan_callback
*cb
,
26 __isl_take isl_vec
*sample
)
28 struct isl_counter
*cnt
= (struct isl_counter
*)cb
;
30 isl_int_add_ui(cnt
->count
, cnt
->count
, 1);
34 if (isl_int_is_zero(cnt
->max
) || isl_int_lt(cnt
->count
, cnt
->max
))
36 return isl_stat_error
;
39 static int increment_range(struct isl_scan_callback
*cb
, isl_int min
, isl_int max
)
41 struct isl_counter
*cnt
= (struct isl_counter
*)cb
;
43 isl_int_add(cnt
->count
, cnt
->count
, max
);
44 isl_int_sub(cnt
->count
, cnt
->count
, min
);
45 isl_int_add_ui(cnt
->count
, cnt
->count
, 1);
47 if (isl_int_is_zero(cnt
->max
) || isl_int_lt(cnt
->count
, cnt
->max
))
49 isl_int_set(cnt
->count
, cnt
->max
);
53 /* Call callback->add with the current sample value of the tableau "tab".
55 static int add_solution(struct isl_tab
*tab
, struct isl_scan_callback
*callback
)
57 struct isl_vec
*sample
;
61 sample
= isl_tab_get_sample_value(tab
);
65 return callback
->add(callback
, sample
);
68 static isl_stat
scan_0D(__isl_take isl_basic_set
*bset
,
69 struct isl_scan_callback
*callback
)
71 struct isl_vec
*sample
;
73 sample
= isl_vec_alloc(bset
->ctx
, 1);
74 isl_basic_set_free(bset
);
77 return isl_stat_error
;
79 isl_int_set_si(sample
->el
[0], 1);
81 return callback
->add(callback
, sample
);
84 /* Look for all integer points in "bset", which is assumed to be bounded,
85 * and call callback->add on each of them.
87 * We first compute a reduced basis for the set and then scan
88 * the set in the directions of this basis.
89 * We basically perform a depth first search, where in each level i
90 * we compute the range in the i-th basis vector direction, given
91 * fixed values in the directions of the previous basis vector.
92 * We then add an equality to the tableau fixing the value in the
93 * direction of the current basis vector to each value in the range
94 * in turn and then continue to the next level.
96 * The search is implemented iteratively. "level" identifies the current
97 * basis vector. "init" is true if we want the first value at the current
98 * level and false if we want the next value.
99 * Solutions are added in the leaves of the search tree, i.e., after
100 * we have fixed a value in each direction of the basis.
102 isl_stat
isl_basic_set_scan(__isl_take isl_basic_set
*bset
,
103 struct isl_scan_callback
*callback
)
106 struct isl_mat
*B
= NULL
;
107 struct isl_tab
*tab
= NULL
;
110 struct isl_tab_undo
**snap
;
113 enum isl_lp_result res
;
115 dim
= isl_basic_set_dim(bset
, isl_dim_all
);
117 bset
= isl_basic_set_free(bset
);
118 return isl_stat_error
;
122 return scan_0D(bset
, callback
);
124 min
= isl_vec_alloc(bset
->ctx
, dim
);
125 max
= isl_vec_alloc(bset
->ctx
, dim
);
126 snap
= isl_alloc_array(bset
->ctx
, struct isl_tab_undo
*, dim
);
128 if (!min
|| !max
|| !snap
)
131 tab
= isl_tab_from_basic_set(bset
, 0);
134 if (isl_tab_extend_cons(tab
, dim
+ 1) < 0)
137 tab
->basis
= isl_mat_identity(bset
->ctx
, 1 + dim
);
139 tab
= isl_tab_compute_reduced_basis(tab
);
142 B
= isl_mat_copy(tab
->basis
);
152 res
= isl_tab_min(tab
, B
->row
[1 + level
],
153 bset
->ctx
->one
, &min
->el
[level
], NULL
, 0);
154 if (res
== isl_lp_empty
)
156 if (res
== isl_lp_error
|| res
== isl_lp_unbounded
)
158 isl_seq_neg(B
->row
[1 + level
] + 1,
159 B
->row
[1 + level
] + 1, dim
);
160 res
= isl_tab_min(tab
, B
->row
[1 + level
],
161 bset
->ctx
->one
, &max
->el
[level
], NULL
, 0);
162 isl_seq_neg(B
->row
[1 + level
] + 1,
163 B
->row
[1 + level
] + 1, dim
);
164 isl_int_neg(max
->el
[level
], max
->el
[level
]);
165 if (res
== isl_lp_empty
)
167 if (res
== isl_lp_error
|| res
== isl_lp_unbounded
)
169 snap
[level
] = isl_tab_snap(tab
);
171 isl_int_add_ui(min
->el
[level
], min
->el
[level
], 1);
173 if (empty
|| isl_int_gt(min
->el
[level
], max
->el
[level
])) {
177 if (isl_tab_rollback(tab
, snap
[level
]) < 0)
181 if (level
== dim
- 1 && callback
->add
== increment_counter
) {
182 if (increment_range(callback
,
183 min
->el
[level
], max
->el
[level
]))
188 if (isl_tab_rollback(tab
, snap
[level
]) < 0)
192 isl_int_neg(B
->row
[1 + level
][0], min
->el
[level
]);
193 if (isl_tab_add_valid_eq(tab
, B
->row
[1 + level
]) < 0)
195 isl_int_set_si(B
->row
[1 + level
][0], 0);
196 if (level
< dim
- 1) {
201 if (add_solution(tab
, callback
) < 0)
204 if (isl_tab_rollback(tab
, snap
[level
]) < 0)
212 isl_basic_set_free(bset
);
220 isl_basic_set_free(bset
);
222 return isl_stat_error
;
225 isl_stat
isl_set_scan(__isl_take isl_set
*set
,
226 struct isl_scan_callback
*callback
)
230 if (!set
|| !callback
)
233 set
= isl_set_cow(set
);
234 set
= isl_set_make_disjoint(set
);
235 set
= isl_set_compute_divs(set
);
239 for (i
= 0; i
< set
->n
; ++i
)
240 if (isl_basic_set_scan(isl_basic_set_copy(set
->p
[i
]),
248 return isl_stat_error
;
251 int isl_basic_set_count_upto(__isl_keep isl_basic_set
*bset
,
252 isl_int max
, isl_int
*count
)
254 struct isl_counter cnt
= { { &increment_counter
} };
259 isl_int_init(cnt
.count
);
260 isl_int_init(cnt
.max
);
262 isl_int_set_si(cnt
.count
, 0);
263 isl_int_set(cnt
.max
, max
);
264 if (isl_basic_set_scan(isl_basic_set_copy(bset
), &cnt
.callback
) < 0 &&
265 isl_int_lt(cnt
.count
, cnt
.max
))
268 isl_int_set(*count
, cnt
.count
);
269 isl_int_clear(cnt
.max
);
270 isl_int_clear(cnt
.count
);
274 isl_int_clear(cnt
.count
);
278 int isl_set_count_upto(__isl_keep isl_set
*set
, isl_int max
, isl_int
*count
)
280 struct isl_counter cnt
= { { &increment_counter
} };
285 isl_int_init(cnt
.count
);
286 isl_int_init(cnt
.max
);
288 isl_int_set_si(cnt
.count
, 0);
289 isl_int_set(cnt
.max
, max
);
290 if (isl_set_scan(isl_set_copy(set
), &cnt
.callback
) < 0 &&
291 isl_int_lt(cnt
.count
, cnt
.max
))
294 isl_int_set(*count
, cnt
.count
);
295 isl_int_clear(cnt
.max
);
296 isl_int_clear(cnt
.count
);
300 isl_int_clear(cnt
.count
);
304 int isl_set_count(__isl_keep isl_set
*set
, isl_int
*count
)
308 return isl_set_count_upto(set
, set
->ctx
->zero
, count
);
311 /* Count the total number of elements in "set" (in an inefficient way) and
314 __isl_give isl_val
*isl_set_count_val(__isl_keep isl_set
*set
)
320 v
= isl_val_zero(isl_set_get_ctx(set
));
324 if (isl_set_count(set
, &v
->n
) < 0)