nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Copyright 2008-2009 Katholieke Universiteit Leuven |
||
3 | * |
||
4 | * Use of this software is governed by the GNU LGPLv2.1 license |
||
5 | * |
||
6 | * Written by Sven Verdoolaege, K.U.Leuven, Departement |
||
7 | * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium |
||
8 | */ |
||
9 | |||
10 | #ifndef ISL_TAB_H |
||
11 | #define ISL_TAB_H |
||
12 | |||
13 | #include <isl/lp.h> |
||
14 | #include <isl/map.h> |
||
15 | #include <isl/mat.h> |
||
16 | #include <isl/set.h> |
||
17 | |||
18 | struct isl_tab_var { |
||
19 | int index; |
||
20 | unsigned is_row : 1; |
||
21 | unsigned is_nonneg : 1; |
||
22 | unsigned is_zero : 1; |
||
23 | unsigned is_redundant : 1; |
||
24 | unsigned marked : 1; |
||
25 | unsigned frozen : 1; |
||
26 | unsigned negated : 1; |
||
27 | }; |
||
28 | |||
29 | enum isl_tab_undo_type { |
||
30 | isl_tab_undo_bottom, |
||
31 | isl_tab_undo_empty, |
||
32 | isl_tab_undo_nonneg, |
||
33 | isl_tab_undo_redundant, |
||
34 | isl_tab_undo_freeze, |
||
35 | isl_tab_undo_zero, |
||
36 | isl_tab_undo_allocate, |
||
37 | isl_tab_undo_relax, |
||
38 | isl_tab_undo_bmap_ineq, |
||
39 | isl_tab_undo_bmap_eq, |
||
40 | isl_tab_undo_bmap_div, |
||
41 | isl_tab_undo_saved_basis, |
||
42 | isl_tab_undo_drop_sample, |
||
43 | isl_tab_undo_saved_samples, |
||
44 | isl_tab_undo_callback, |
||
45 | }; |
||
46 | |||
47 | struct isl_tab_callback { |
||
48 | int (*run)(struct isl_tab_callback *cb); |
||
49 | }; |
||
50 | |||
51 | union isl_tab_undo_val { |
||
52 | int var_index; |
||
53 | int *col_var; |
||
54 | int n; |
||
55 | struct isl_tab_callback *callback; |
||
56 | }; |
||
57 | |||
58 | struct isl_tab_undo { |
||
59 | enum isl_tab_undo_type type; |
||
60 | union isl_tab_undo_val u; |
||
61 | struct isl_tab_undo *next; |
||
62 | }; |
||
63 | |||
64 | /* The tableau maintains equality relations. |
||
65 | * Each column and each row is associated to a variable or a constraint. |
||
66 | * The "value" of an inequality constraint is the value of the corresponding |
||
67 | * slack variable. |
||
68 | * The "row_var" and "col_var" arrays map column and row indices |
||
69 | * to indices in the "var" and "con" arrays. The elements of these |
||
70 | * arrays maintain extra information about the variables and the constraints. |
||
71 | * Each row expresses the corresponding row variable as an affine expression |
||
72 | * of the column variables. |
||
73 | * The first two columns in the matrix contain the common denominator of |
||
74 | * the row and the numerator of the constant term. |
||
75 | * If "M" is set, then the third column represents the "big parameter". |
||
76 | * The third (M = 0) or fourth (M = 1) column |
||
77 | * in the matrix is called column 0 with respect to the col_var array. |
||
78 | * The sample value of the tableau is the value that assigns zero |
||
79 | * to all the column variables and the constant term of each affine |
||
80 | * expression to the corresponding row variable. |
||
81 | * The operations on the tableau maintain the property that the sample |
||
82 | * value satisfies the non-negativity constraints (usually on the slack |
||
83 | * variables). |
||
84 | * |
||
85 | * The big parameter represents an arbitrarily big (and divisible) |
||
86 | * positive number. If present, then the sign of a row is determined |
||
87 | * lexicographically, with the sign of the big parameter coefficient |
||
88 | * considered first. The big parameter is only used while |
||
89 | * solving PILP problems. |
||
90 | * |
||
91 | * The first n_dead column variables have their values fixed to zero. |
||
92 | * The corresponding tab_vars are flagged "is_zero". |
||
93 | * Some of the rows that have have zero coefficients in all but |
||
94 | * the dead columns are also flagged "is_zero". |
||
95 | * |
||
96 | * The first n_redundant rows correspond to inequality constraints |
||
97 | * that are always satisfied for any value satisfying the non-redundant |
||
98 | * rows. The corresponding tab_vars are flagged "is_redundant". |
||
99 | * A row variable that is flagged "is_zero" is also flagged "is_redundant" |
||
100 | * since the constraint has been reduced to 0 = 0 and is therefore always |
||
101 | * satisfied. |
||
102 | * |
||
103 | * There are "n_var" variables in total. The first "n_param" of these |
||
104 | * are called parameters and the last "n_div" of these are called divs. |
||
105 | * The basic tableau operations makes no distinction between different |
||
106 | * kinds of variables. These special variables are only used while |
||
107 | * solving PILP problems. |
||
108 | * |
||
109 | * Dead columns and redundant rows are detected on the fly. |
||
110 | * However, the basic operations do not ensure that all dead columns |
||
111 | * or all redundant rows are detected. |
||
112 | * isl_tab_detect_implicit_equalities and isl_tab_detect_redundant can be used |
||
113 | * to perform and exhaustive search for dead columns and redundant rows. |
||
114 | * |
||
115 | * The samples matrix contains "n_sample" integer points that have at some |
||
116 | * point been elements satisfying the tableau. The first "n_outside" |
||
117 | * of them no longer satisfy the tableau. They are kept because they |
||
118 | * can be reinstated during rollback when the constraint that cut them |
||
119 | * out is removed. These samples are only maintained for the context |
||
120 | * tableau while solving PILP problems. |
||
121 | * |
||
122 | * If "preserve" is set, then we want to keep all constraints in the |
||
123 | * tableau, even if they turn out to be redundant. |
||
124 | */ |
||
125 | enum isl_tab_row_sign { |
||
126 | isl_tab_row_unknown = 0, |
||
127 | isl_tab_row_pos, |
||
128 | isl_tab_row_neg, |
||
129 | isl_tab_row_any, |
||
130 | }; |
||
131 | struct isl_tab { |
||
132 | struct isl_mat *mat; |
||
133 | |||
134 | unsigned n_row; |
||
135 | unsigned n_col; |
||
136 | unsigned n_dead; |
||
137 | unsigned n_redundant; |
||
138 | |||
139 | unsigned n_var; |
||
140 | unsigned n_param; |
||
141 | unsigned n_div; |
||
142 | unsigned max_var; |
||
143 | unsigned n_con; |
||
144 | unsigned n_eq; |
||
145 | unsigned max_con; |
||
146 | struct isl_tab_var *var; |
||
147 | struct isl_tab_var *con; |
||
148 | int *row_var; /* v >= 0 -> var v; v < 0 -> con ~v */ |
||
149 | int *col_var; /* v >= 0 -> var v; v < 0 -> con ~v */ |
||
150 | enum isl_tab_row_sign *row_sign; |
||
151 | |||
152 | struct isl_tab_undo bottom; |
||
153 | struct isl_tab_undo *top; |
||
154 | |||
155 | struct isl_vec *dual; |
||
156 | struct isl_basic_map *bmap; |
||
157 | |||
158 | unsigned n_sample; |
||
159 | unsigned n_outside; |
||
160 | int *sample_index; |
||
161 | struct isl_mat *samples; |
||
162 | |||
163 | int n_zero; |
||
164 | int n_unbounded; |
||
165 | struct isl_mat *basis; |
||
166 | |||
167 | int (*conflict)(int con, void *user); |
||
168 | void *conflict_user; |
||
169 | |||
170 | unsigned strict_redundant : 1; |
||
171 | unsigned need_undo : 1; |
||
172 | unsigned preserve : 1; |
||
173 | unsigned rational : 1; |
||
174 | unsigned empty : 1; |
||
175 | unsigned in_undo : 1; |
||
176 | unsigned M : 1; |
||
177 | unsigned cone : 1; |
||
178 | }; |
||
179 | |||
180 | struct isl_tab *isl_tab_alloc(struct isl_ctx *ctx, |
||
181 | unsigned n_row, unsigned n_var, unsigned M); |
||
182 | void isl_tab_free(struct isl_tab *tab); |
||
183 | |||
184 | __isl_give struct isl_tab *isl_tab_from_basic_map( |
||
185 | __isl_keep isl_basic_map *bmap, int track); |
||
186 | __isl_give struct isl_tab *isl_tab_from_basic_set( |
||
187 | __isl_keep isl_basic_set *bset, int track); |
||
188 | struct isl_tab *isl_tab_from_recession_cone(struct isl_basic_set *bset, |
||
189 | int parametric); |
||
190 | int isl_tab_cone_is_bounded(struct isl_tab *tab); |
||
191 | struct isl_basic_map *isl_basic_map_update_from_tab(struct isl_basic_map *bmap, |
||
192 | struct isl_tab *tab); |
||
193 | struct isl_basic_set *isl_basic_set_update_from_tab(struct isl_basic_set *bset, |
||
194 | struct isl_tab *tab); |
||
195 | int isl_tab_detect_implicit_equalities(struct isl_tab *tab) WARN_UNUSED; |
||
196 | int isl_tab_detect_redundant(struct isl_tab *tab) WARN_UNUSED; |
||
197 | #define ISL_TAB_SAVE_DUAL (1 << 0) |
||
198 | enum isl_lp_result isl_tab_min(struct isl_tab *tab, |
||
199 | isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, |
||
200 | unsigned flags) WARN_UNUSED; |
||
201 | |||
202 | struct isl_tab *isl_tab_extend(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; |
||
203 | int isl_tab_add_ineq(struct isl_tab *tab, isl_int *ineq) WARN_UNUSED; |
||
204 | int isl_tab_add_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; |
||
205 | int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq) WARN_UNUSED; |
||
206 | |||
207 | int isl_tab_freeze_constraint(struct isl_tab *tab, int con) WARN_UNUSED; |
||
208 | |||
209 | int isl_tab_track_bmap(struct isl_tab *tab, __isl_take isl_basic_map *bmap) WARN_UNUSED; |
||
210 | int isl_tab_track_bset(struct isl_tab *tab, __isl_take isl_basic_set *bset) WARN_UNUSED; |
||
211 | __isl_keep isl_basic_set *isl_tab_peek_bset(struct isl_tab *tab); |
||
212 | |||
213 | int isl_tab_is_equality(struct isl_tab *tab, int con); |
||
214 | int isl_tab_is_redundant(struct isl_tab *tab, int con); |
||
215 | |||
216 | int isl_tab_sample_is_integer(struct isl_tab *tab); |
||
217 | struct isl_vec *isl_tab_get_sample_value(struct isl_tab *tab); |
||
218 | |||
219 | enum isl_ineq_type { |
||
220 | isl_ineq_error = -1, |
||
221 | isl_ineq_redundant, |
||
222 | isl_ineq_separate, |
||
223 | isl_ineq_cut, |
||
224 | isl_ineq_adj_eq, |
||
225 | isl_ineq_adj_ineq, |
||
226 | }; |
||
227 | |||
228 | enum isl_ineq_type isl_tab_ineq_type(struct isl_tab *tab, isl_int *ineq); |
||
229 | |||
230 | struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab); |
||
231 | int isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap) WARN_UNUSED; |
||
232 | |||
233 | struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con) WARN_UNUSED; |
||
234 | int isl_tab_select_facet(struct isl_tab *tab, int con) WARN_UNUSED; |
||
235 | |||
236 | void isl_tab_dump(__isl_keep struct isl_tab *tab); |
||
237 | |||
238 | struct isl_map *isl_tab_basic_map_partial_lexopt( |
||
239 | struct isl_basic_map *bmap, struct isl_basic_set *dom, |
||
240 | struct isl_set **empty, int max); |
||
241 | __isl_give isl_pw_multi_aff *isl_basic_map_partial_lexopt_pw_multi_aff( |
||
242 | __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, |
||
243 | __isl_give isl_set **empty, int max); |
||
244 | |||
245 | /* An isl_region represents a sequence of consecutive variables. |
||
246 | * pos is the location (starting at 0) of the first variable in the sequence. |
||
247 | */ |
||
248 | struct isl_region { |
||
249 | int pos; |
||
250 | int len; |
||
251 | }; |
||
252 | |||
253 | __isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin( |
||
254 | __isl_take isl_basic_set *bset, int n_op, int n_region, |
||
255 | struct isl_region *region, |
||
256 | int (*conflict)(int con, void *user), void *user); |
||
257 | __isl_give isl_vec *isl_tab_basic_set_non_neg_lexmin( |
||
258 | __isl_take isl_basic_set *bset); |
||
259 | |||
260 | /* private */ |
||
261 | |||
262 | struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i); |
||
263 | int isl_tab_mark_redundant(struct isl_tab *tab, int row) WARN_UNUSED; |
||
264 | int isl_tab_mark_empty(struct isl_tab *tab) WARN_UNUSED; |
||
265 | struct isl_tab *isl_tab_dup(struct isl_tab *tab); |
||
266 | struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2); |
||
267 | int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; |
||
268 | int isl_tab_allocate_con(struct isl_tab *tab) WARN_UNUSED; |
||
269 | int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new) WARN_UNUSED; |
||
270 | int isl_tab_allocate_var(struct isl_tab *tab) WARN_UNUSED; |
||
271 | int isl_tab_pivot(struct isl_tab *tab, int row, int col) WARN_UNUSED; |
||
272 | int isl_tab_add_row(struct isl_tab *tab, isl_int *line) WARN_UNUSED; |
||
273 | int isl_tab_row_is_redundant(struct isl_tab *tab, int row); |
||
274 | int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var); |
||
275 | int isl_tab_sign_of_max(struct isl_tab *tab, int con); |
||
276 | int isl_tab_kill_col(struct isl_tab *tab, int col) WARN_UNUSED; |
||
277 | |||
278 | int isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type) WARN_UNUSED; |
||
279 | int isl_tab_push_var(struct isl_tab *tab, |
||
280 | enum isl_tab_undo_type type, struct isl_tab_var *var) WARN_UNUSED; |
||
281 | int isl_tab_push_basis(struct isl_tab *tab) WARN_UNUSED; |
||
282 | |||
283 | struct isl_tab *isl_tab_init_samples(struct isl_tab *tab) WARN_UNUSED; |
||
284 | struct isl_tab *isl_tab_add_sample(struct isl_tab *tab, |
||
285 | __isl_take isl_vec *sample) WARN_UNUSED; |
||
286 | struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s); |
||
287 | int isl_tab_save_samples(struct isl_tab *tab) WARN_UNUSED; |
||
288 | |||
289 | struct isl_tab *isl_tab_detect_equalities(struct isl_tab *tab, |
||
290 | struct isl_tab *tab_cone) WARN_UNUSED; |
||
291 | |||
292 | int isl_tab_push_callback(struct isl_tab *tab, |
||
293 | struct isl_tab_callback *callback) WARN_UNUSED; |
||
294 | |||
295 | int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div, |
||
296 | int (*add_ineq)(void *user, isl_int *), void *user); |
||
297 | |||
298 | #endif |