2 * Copyright 2010 INRIA Saclay
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 #include <isl_map_private.h>
13 #include <isl_space_private.h>
15 #include <isl_aff_private.h>
16 #include <isl_mat_private.h>
17 #include <isl_factorization.h>
20 * Let C be a cone and define
22 * C' := { y | forall x in C : y x >= 0 }
24 * C' contains the coefficients of all linear constraints
25 * that are valid for C.
26 * Furthermore, C'' = C.
28 * If C is defined as { x | A x >= 0 }
29 * then any element in C' must be a non-negative combination
30 * of the rows of A, i.e., y = t A with t >= 0. That is,
32 * C' = { y | exists t >= 0 : y = t A }
34 * If any of the rows in A actually represents an equality, then
35 * also negative combinations of this row are allowed and so the
36 * non-negativity constraint on the corresponding element of t
39 * A polyhedron P = { x | b + A x >= 0 } can be represented
40 * in homogeneous coordinates by the cone
41 * C = { [z,x] | b z + A x >= and z >= 0 }
42 * The valid linear constraints on C correspond to the valid affine
44 * This is essentially Farkas' lemma.
48 * [ w y ] = [t_0 t] [ b A ]
52 * C' = { w, y | exists t_0, t >= 0 : y = t A and w = t_0 + t b }
55 * C' = { w, y | exists t >= 0 : y = t A and w - t b >= 0 }
57 * In practice, we introduce an extra variable (w), shifting all
58 * other variables to the right, and an extra inequality
59 * (w - t b >= 0) corresponding to the positivity constraint on
60 * the homogeneous coordinate.
62 * When going back from coefficients to solutions, we immediately
63 * plug in 1 for z, which corresponds to shifting all variables
64 * to the left, with the leftmost ending up in the constant position.
67 /* Add the given prefix to all named isl_dim_set dimensions in "space".
69 static __isl_give isl_space
*isl_space_prefix(__isl_take isl_space
*space
,
75 size_t prefix_len
= strlen(prefix
);
80 ctx
= isl_space_get_ctx(space
);
81 nvar
= isl_space_dim(space
, isl_dim_set
);
83 return isl_space_free(space
);
85 for (i
= 0; i
< nvar
; ++i
) {
89 name
= isl_space_get_dim_name(space
, isl_dim_set
, i
);
93 prefix_name
= isl_alloc_array(ctx
, char,
94 prefix_len
+ strlen(name
) + 1);
97 memcpy(prefix_name
, prefix
, prefix_len
);
98 strcpy(prefix_name
+ prefix_len
, name
);
100 space
= isl_space_set_dim_name(space
,
101 isl_dim_set
, i
, prefix_name
);
107 isl_space_free(space
);
111 /* Given a dimension specification of the solutions space, construct
112 * a dimension specification for the space of coefficients.
114 * In particular transform
120 * { coefficients[[cst, params] -> S] }
122 * and prefix each dimension name with "c_".
124 static __isl_give isl_space
*isl_space_coefficients(__isl_take isl_space
*space
)
126 isl_space
*space_param
;
130 nvar
= isl_space_dim(space
, isl_dim_set
);
131 nparam
= isl_space_dim(space
, isl_dim_param
);
132 if (nvar
< 0 || nparam
< 0)
133 return isl_space_free(space
);
134 space_param
= isl_space_copy(space
);
135 space_param
= isl_space_drop_dims(space_param
, isl_dim_set
, 0, nvar
);
136 space_param
= isl_space_move_dims(space_param
, isl_dim_set
, 0,
137 isl_dim_param
, 0, nparam
);
138 space_param
= isl_space_prefix(space_param
, "c_");
139 space_param
= isl_space_insert_dims(space_param
, isl_dim_set
, 0, 1);
140 space_param
= isl_space_set_dim_name(space_param
,
141 isl_dim_set
, 0, "c_cst");
142 space
= isl_space_drop_dims(space
, isl_dim_param
, 0, nparam
);
143 space
= isl_space_prefix(space
, "c_");
144 space
= isl_space_join(isl_space_from_domain(space_param
),
145 isl_space_from_range(space
));
146 space
= isl_space_wrap(space
);
147 space
= isl_space_set_tuple_name(space
, isl_dim_set
, "coefficients");
152 /* Drop the given prefix from all named dimensions of type "type" in "space".
154 static __isl_give isl_space
*isl_space_unprefix(__isl_take isl_space
*space
,
155 enum isl_dim_type type
, const char *prefix
)
159 size_t prefix_len
= strlen(prefix
);
161 n
= isl_space_dim(space
, type
);
163 return isl_space_free(space
);
165 for (i
= 0; i
< n
; ++i
) {
168 name
= isl_space_get_dim_name(space
, type
, i
);
171 if (strncmp(name
, prefix
, prefix_len
))
174 space
= isl_space_set_dim_name(space
,
175 type
, i
, name
+ prefix_len
);
181 /* Given a dimension specification of the space of coefficients, construct
182 * a dimension specification for the space of solutions.
184 * In particular transform
186 * { coefficients[[cst, params] -> S] }
192 * and drop the "c_" prefix from the dimension names.
194 static __isl_give isl_space
*isl_space_solutions(__isl_take isl_space
*space
)
198 space
= isl_space_unwrap(space
);
199 space
= isl_space_drop_dims(space
, isl_dim_in
, 0, 1);
200 space
= isl_space_unprefix(space
, isl_dim_in
, "c_");
201 space
= isl_space_unprefix(space
, isl_dim_out
, "c_");
202 nparam
= isl_space_dim(space
, isl_dim_in
);
204 return isl_space_free(space
);
205 space
= isl_space_move_dims(space
,
206 isl_dim_param
, 0, isl_dim_in
, 0, nparam
);
207 space
= isl_space_range(space
);
212 /* Return the rational universe basic set in the given space.
214 static __isl_give isl_basic_set
*rational_universe(__isl_take isl_space
*space
)
218 bset
= isl_basic_set_universe(space
);
219 bset
= isl_basic_set_set_rational(bset
);
224 /* Compute the dual of "bset" by applying Farkas' lemma.
225 * As explained above, we add an extra dimension to represent
226 * the coefficient of the constant term when going from solutions
227 * to coefficients (shift == 1) and we drop the extra dimension when going
228 * in the opposite direction (shift == -1).
229 * The dual can be created in an arbitrary space.
230 * The caller is responsible for putting the result in the appropriate space.
232 * If "bset" is (obviously) empty, then the way this emptiness
233 * is represented by the constraints does not allow for the application
234 * of the standard farkas algorithm. We therefore handle this case
235 * specifically and return the universe basic set.
237 static __isl_give isl_basic_set
*farkas(__isl_take isl_basic_set
*bset
,
243 isl_basic_set
*dual
= NULL
;
246 total
= isl_basic_set_dim(bset
, isl_dim_all
);
248 return isl_basic_set_free(bset
);
250 ctx
= isl_basic_set_get_ctx(bset
);
251 space
= isl_space_set_alloc(ctx
, 0, total
+ shift
);
252 if (isl_basic_set_plain_is_empty(bset
)) {
253 isl_basic_set_free(bset
);
254 return rational_universe(space
);
257 dual
= isl_basic_set_alloc_space(space
, bset
->n_eq
+ bset
->n_ineq
,
258 total
, bset
->n_ineq
+ (shift
> 0));
259 dual
= isl_basic_set_set_rational(dual
);
261 for (i
= 0; i
< bset
->n_eq
+ bset
->n_ineq
; ++i
) {
262 k
= isl_basic_set_alloc_div(dual
);
265 isl_int_set_si(dual
->div
[k
][0], 0);
268 for (i
= 0; i
< total
; ++i
) {
269 k
= isl_basic_set_alloc_equality(dual
);
272 isl_seq_clr(dual
->eq
[k
], 1 + shift
+ total
);
273 isl_int_set_si(dual
->eq
[k
][1 + shift
+ i
], -1);
274 for (j
= 0; j
< bset
->n_eq
; ++j
)
275 isl_int_set(dual
->eq
[k
][1 + shift
+ total
+ j
],
277 for (j
= 0; j
< bset
->n_ineq
; ++j
)
278 isl_int_set(dual
->eq
[k
][1 + shift
+ total
+ bset
->n_eq
+ j
],
279 bset
->ineq
[j
][1 + i
]);
282 for (i
= 0; i
< bset
->n_ineq
; ++i
) {
283 k
= isl_basic_set_alloc_inequality(dual
);
286 isl_seq_clr(dual
->ineq
[k
],
287 1 + shift
+ total
+ bset
->n_eq
+ bset
->n_ineq
);
288 isl_int_set_si(dual
->ineq
[k
][1 + shift
+ total
+ bset
->n_eq
+ i
], 1);
292 k
= isl_basic_set_alloc_inequality(dual
);
295 isl_seq_clr(dual
->ineq
[k
], 2 + total
);
296 isl_int_set_si(dual
->ineq
[k
][1], 1);
297 for (j
= 0; j
< bset
->n_eq
; ++j
)
298 isl_int_neg(dual
->ineq
[k
][2 + total
+ j
],
300 for (j
= 0; j
< bset
->n_ineq
; ++j
)
301 isl_int_neg(dual
->ineq
[k
][2 + total
+ bset
->n_eq
+ j
],
305 dual
= isl_basic_set_remove_divs(dual
);
306 dual
= isl_basic_set_simplify(dual
);
307 dual
= isl_basic_set_finalize(dual
);
309 isl_basic_set_free(bset
);
312 isl_basic_set_free(bset
);
313 isl_basic_set_free(dual
);
317 /* Construct a basic set containing the tuples of coefficients of all
318 * valid affine constraints on the given basic set, ignoring
319 * the space of input and output and without any further decomposition.
321 static __isl_give isl_basic_set
*isl_basic_set_coefficients_base(
322 __isl_take isl_basic_set
*bset
)
324 return farkas(bset
, 1);
327 /* Return the inverse mapping of "morph".
329 static __isl_give isl_mat
*peek_inv(__isl_keep isl_morph
*morph
)
331 return morph
? morph
->inv
: NULL
;
334 /* Return a copy of the inverse mapping of "morph".
336 static __isl_give isl_mat
*get_inv(__isl_keep isl_morph
*morph
)
338 return isl_mat_copy(peek_inv(morph
));
341 /* Information about a single factor within isl_basic_set_coefficients_product.
343 * "start" is the position of the first coefficient (beyond
344 * the one corresponding to the constant term) in this factor.
345 * "dim" is the number of coefficients (other than
346 * the one corresponding to the constant term) in this factor.
347 * "n_line" is the number of lines in "coeff".
348 * "n_ray" is the number of rays (other than lines) in "coeff".
349 * "n_vertex" is the number of vertices in "coeff".
351 * While iterating over the vertices,
352 * "pos" represents the inequality constraint corresponding
353 * to the current vertex.
355 struct isl_coefficients_factor_data
{
356 isl_basic_set
*coeff
;
365 /* Internal data structure for isl_basic_set_coefficients_product.
366 * "n" is the number of factors in the factorization.
367 * "pos" is the next factor that will be considered.
368 * "start_next" is the position of the first coefficient (beyond
369 * the one corresponding to the constant term) in the next factor.
370 * "factors" contains information about the individual "n" factors.
372 struct isl_coefficients_product_data
{
376 struct isl_coefficients_factor_data
*factors
;
379 /* Initialize the internal data structure for
380 * isl_basic_set_coefficients_product.
382 static isl_stat
isl_coefficients_product_data_init(isl_ctx
*ctx
,
383 struct isl_coefficients_product_data
*data
, int n
)
387 data
->start_next
= 0;
388 data
->factors
= isl_calloc_array(ctx
,
389 struct isl_coefficients_factor_data
, n
);
391 return isl_stat_error
;
395 /* Free all memory allocated in "data".
397 static void isl_coefficients_product_data_clear(
398 struct isl_coefficients_product_data
*data
)
403 for (i
= 0; i
< data
->n
; ++i
) {
404 isl_basic_set_free(data
->factors
[i
].coeff
);
410 /* Does inequality "ineq" in the (dual) basic set "bset" represent a ray?
411 * In particular, does it have a zero denominator
412 * (i.e., a zero coefficient for the constant term)?
414 static int is_ray(__isl_keep isl_basic_set
*bset
, int ineq
)
416 return isl_int_is_zero(bset
->ineq
[ineq
][1]);
419 /* isl_factorizer_every_factor_basic_set callback that
420 * constructs a basic set containing the tuples of coefficients of all
421 * valid affine constraints on the factor "bset" and
422 * extracts further information that will be used
423 * when combining the results over the different factors.
425 static isl_bool
isl_basic_set_coefficients_factor(
426 __isl_keep isl_basic_set
*bset
, void *user
)
428 struct isl_coefficients_product_data
*data
= user
;
429 isl_basic_set
*coeff
;
430 isl_size n_eq
, n_ineq
, dim
;
431 int i
, n_ray
, n_vertex
;
433 coeff
= isl_basic_set_coefficients_base(isl_basic_set_copy(bset
));
434 data
->factors
[data
->pos
].coeff
= coeff
;
436 return isl_bool_error
;
438 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
439 n_eq
= isl_basic_set_n_equality(coeff
);
440 n_ineq
= isl_basic_set_n_inequality(coeff
);
441 if (dim
< 0 || n_eq
< 0 || n_ineq
< 0)
442 return isl_bool_error
;
443 n_ray
= n_vertex
= 0;
444 for (i
= 0; i
< n_ineq
; ++i
) {
445 if (is_ray(coeff
, i
))
450 data
->factors
[data
->pos
].start
= data
->start_next
;
451 data
->factors
[data
->pos
].dim
= dim
;
452 data
->factors
[data
->pos
].n_line
= n_eq
;
453 data
->factors
[data
->pos
].n_ray
= n_ray
;
454 data
->factors
[data
->pos
].n_vertex
= n_vertex
;
456 data
->start_next
+= dim
;
458 return isl_bool_true
;
461 /* Clear an entry in the product, given that there is a "total" number
462 * of coefficients (other than that of the constant term).
464 static void clear_entry(isl_int
*entry
, int total
)
466 isl_seq_clr(entry
, 1 + 1 + total
);
469 /* Set the part of the entry corresponding to factor "data",
470 * from the factor coefficients in "src".
472 static void set_factor(isl_int
*entry
, isl_int
*src
,
473 struct isl_coefficients_factor_data
*data
)
475 isl_seq_cpy(entry
+ 1 + 1 + data
->start
, src
+ 1 + 1, data
->dim
);
478 /* Set the part of the entry corresponding to factor "data",
479 * from the factor coefficients in "src" multiplied by "f".
481 static void scale_factor(isl_int
*entry
, isl_int
*src
, isl_int f
,
482 struct isl_coefficients_factor_data
*data
)
484 isl_seq_scale(entry
+ 1 + 1 + data
->start
, src
+ 1 + 1, f
, data
->dim
);
487 /* Add all lines from the given factor to "bset",
488 * given that there is a "total" number of coefficients
489 * (other than that of the constant term).
491 static __isl_give isl_basic_set
*add_lines(__isl_take isl_basic_set
*bset
,
492 struct isl_coefficients_factor_data
*factor
, int total
)
496 for (i
= 0; i
< factor
->n_line
; ++i
) {
499 k
= isl_basic_set_alloc_equality(bset
);
501 return isl_basic_set_free(bset
);
502 clear_entry(bset
->eq
[k
], total
);
503 set_factor(bset
->eq
[k
], factor
->coeff
->eq
[i
], factor
);
509 /* Add all rays (other than lines) from the given factor to "bset",
510 * given that there is a "total" number of coefficients
511 * (other than that of the constant term).
513 static __isl_give isl_basic_set
*add_rays(__isl_take isl_basic_set
*bset
,
514 struct isl_coefficients_factor_data
*data
, int total
)
517 int n_ineq
= data
->n_ray
+ data
->n_vertex
;
519 for (i
= 0; i
< n_ineq
; ++i
) {
522 if (!is_ray(data
->coeff
, i
))
525 k
= isl_basic_set_alloc_inequality(bset
);
527 return isl_basic_set_free(bset
);
528 clear_entry(bset
->ineq
[k
], total
);
529 set_factor(bset
->ineq
[k
], data
->coeff
->ineq
[i
], data
);
535 /* Move to the first vertex of the given factor starting
536 * at inequality constraint "start", setting factor->pos and
537 * returning 1 if a vertex is found.
539 static int factor_first_vertex(struct isl_coefficients_factor_data
*factor
,
543 int n
= factor
->n_ray
+ factor
->n_vertex
;
545 for (j
= start
; j
< n
; ++j
) {
546 if (is_ray(factor
->coeff
, j
))
555 /* Move to the first constraint in each factor starting at "first"
556 * that represents a vertex.
557 * In particular, skip the initial constraints that correspond to rays.
559 static void first_vertex(struct isl_coefficients_product_data
*data
, int first
)
563 for (i
= first
; i
< data
->n
; ++i
)
564 factor_first_vertex(&data
->factors
[i
], 0);
567 /* Move to the next vertex in the product.
568 * In particular, move to the next vertex of the last factor.
569 * If all vertices of this last factor have already been considered,
570 * then move to the next vertex of the previous factor(s)
571 * until a factor is found that still has a next vertex.
572 * Once such a next vertex has been found, the subsequent
573 * factors are reset to the first vertex.
574 * Return 1 if any next vertex was found.
576 static int next_vertex(struct isl_coefficients_product_data
*data
)
580 for (i
= data
->n
- 1; i
>= 0; --i
) {
581 struct isl_coefficients_factor_data
*factor
= &data
->factors
[i
];
583 if (!factor_first_vertex(factor
, factor
->pos
+ 1))
585 first_vertex(data
, i
+ 1);
592 /* Add a vertex to the product "bset" combining the currently selected
593 * vertices of the factors.
595 * In the dual representation, the constant term is always zero.
596 * The vertex itself is the sum of the contributions of the factors
597 * with a shared denominator in position 1.
599 * First compute the shared denominator (lcm) and
600 * then scale the numerators to this shared denominator.
602 static __isl_give isl_basic_set
*add_vertex(__isl_take isl_basic_set
*bset
,
603 struct isl_coefficients_product_data
*data
)
609 k
= isl_basic_set_alloc_inequality(bset
);
611 return isl_basic_set_free(bset
);
615 isl_int_set_si(lcm
, 1);
616 for (i
= 0; i
< data
->n
; ++i
) {
617 struct isl_coefficients_factor_data
*factor
= &data
->factors
[i
];
618 isl_basic_set
*coeff
= factor
->coeff
;
619 int pos
= factor
->pos
;
620 isl_int_lcm(lcm
, lcm
, coeff
->ineq
[pos
][1]);
622 isl_int_set_si(bset
->ineq
[k
][0], 0);
623 isl_int_set(bset
->ineq
[k
][1], lcm
);
625 for (i
= 0; i
< data
->n
; ++i
) {
626 struct isl_coefficients_factor_data
*factor
= &data
->factors
[i
];
627 isl_basic_set
*coeff
= factor
->coeff
;
628 int pos
= factor
->pos
;
629 isl_int_divexact(f
, lcm
, coeff
->ineq
[pos
][1]);
630 scale_factor(bset
->ineq
[k
], coeff
->ineq
[pos
], f
, factor
);
639 /* Combine the duals of the factors in the factorization of a basic set
640 * to form the dual of the entire basic set.
641 * The dual share the coefficient of the constant term.
642 * All other coefficients are specific to a factor.
643 * Any constraint not involving the coefficient of the constant term
644 * can therefor simply be copied into the appropriate position.
645 * This includes all equality constraints since the coefficient
646 * of the constant term can always be increased and therefore
647 * never appears in an equality constraint.
648 * The inequality constraints involving the coefficient of
649 * the constant term need to be combined across factors.
650 * In particular, if this coefficient needs to be greater than or equal
651 * to some linear combination of the other coefficients in each factor,
652 * then it needs to be greater than or equal to the sum of
653 * these linear combinations across the factors.
655 * Alternatively, the constraints of the dual can be seen
656 * as the vertices, rays and lines of the original basic set.
657 * Clearly, rays and lines can simply be copied,
658 * while vertices needs to be combined across factors.
659 * This means that the number of rays and lines in the product
660 * is equal to the sum of the numbers in the factors,
661 * while the number of vertices is the product
662 * of the number of vertices in the factors. Note that each
663 * factor has at least one vertex.
664 * The only exception is when the factor is the dual of an obviously empty set,
665 * in which case a universe dual is created.
666 * In this case, return a universe dual for the product as well.
668 * While constructing the vertices, look for the first combination
669 * of inequality constraints that represent a vertex,
670 * construct the corresponding vertex and then move on
671 * to the next combination of inequality constraints until
672 * all combinations have been considered.
674 static __isl_give isl_basic_set
*construct_product(isl_ctx
*ctx
,
675 struct isl_coefficients_product_data
*data
)
678 int n_line
, n_ray
, n_vertex
;
681 isl_basic_set
*product
;
686 total
= data
->start_next
;
691 for (i
= 0; i
< data
->n
; ++i
) {
692 n_line
+= data
->factors
[i
].n_line
;
693 n_ray
+= data
->factors
[i
].n_ray
;
694 n_vertex
*= data
->factors
[i
].n_vertex
;
697 space
= isl_space_set_alloc(ctx
, 0, 1 + total
);
699 return rational_universe(space
);
700 product
= isl_basic_set_alloc_space(space
, 0, n_line
, n_ray
+ n_vertex
);
701 product
= isl_basic_set_set_rational(product
);
703 for (i
= 0; i
< data
->n
; ++i
)
704 product
= add_lines(product
, &data
->factors
[i
], total
);
705 for (i
= 0; i
< data
->n
; ++i
)
706 product
= add_rays(product
, &data
->factors
[i
], total
);
708 first_vertex(data
, 0);
710 product
= add_vertex(product
, data
);
711 } while (next_vertex(data
));
716 /* Given a factorization "f" of a basic set,
717 * construct a basic set containing the tuples of coefficients of all
718 * valid affine constraints on the product of the factors, ignoring
719 * the space of input and output.
720 * Note that this product may not be equal to the original basic set,
721 * if a non-trivial transformation is involved.
722 * This is handled by the caller.
724 * Compute the tuples of coefficients for each factor separately and
725 * then combine the results.
727 static __isl_give isl_basic_set
*isl_basic_set_coefficients_product(
728 __isl_take isl_factorizer
*f
)
730 struct isl_coefficients_product_data data
;
732 isl_basic_set
*coeff
;
735 ctx
= isl_factorizer_get_ctx(f
);
736 if (isl_coefficients_product_data_init(ctx
, &data
, f
->n_group
) < 0)
737 f
= isl_factorizer_free(f
);
738 every
= isl_factorizer_every_factor_basic_set(f
,
739 &isl_basic_set_coefficients_factor
, &data
);
740 isl_factorizer_free(f
);
742 coeff
= construct_product(ctx
, &data
);
745 isl_coefficients_product_data_clear(&data
);
750 /* Given a factorization "f" of a basic set,
751 * construct a basic set containing the tuples of coefficients of all
752 * valid affine constraints on the basic set, ignoring
753 * the space of input and output.
755 * The factorization may involve a linear transformation of the basic set.
756 * In particular, the transformed basic set is formulated
757 * in terms of x' = U x, i.e., x = V x', with V = U^{-1}.
758 * The dual is then computed in terms of y' with y'^t [z; x'] >= 0.
759 * Plugging in y' = [1 0; 0 V^t] y yields
760 * y^t [1 0; 0 V] [z; x'] >= 0, i.e., y^t [z; x] >= 0, which is
761 * the desired set of coefficients y.
762 * Note that this transformation to y' only needs to be applied
763 * if U is not the identity matrix.
765 static __isl_give isl_basic_set
*isl_basic_set_coefficients_morphed_product(
766 __isl_take isl_factorizer
*f
)
768 isl_bool is_identity
;
772 isl_basic_set
*coeff
;
776 is_identity
= isl_mat_is_scaled_identity(peek_inv(f
->morph
));
780 return isl_basic_set_coefficients_product(f
);
782 inv
= get_inv(f
->morph
);
783 inv
= isl_mat_transpose(inv
);
784 inv
= isl_mat_lin_to_aff(inv
);
786 coeff
= isl_basic_set_coefficients_product(f
);
787 space
= isl_space_map_from_set(isl_basic_set_get_space(coeff
));
788 ma
= isl_multi_aff_from_aff_mat(space
, inv
);
789 coeff
= isl_basic_set_preimage_multi_aff(coeff
, ma
);
793 isl_factorizer_free(f
);
797 /* Construct a basic set containing the tuples of coefficients of all
798 * valid affine constraints on the given basic set, ignoring
799 * the space of input and output.
801 * The caller has already checked that "bset" does not involve
802 * any local variables. It may have parameters, though.
803 * Treat them as regular variables internally.
804 * This is especially important for the factorization,
805 * since the (original) parameters should be taken into account
806 * explicitly in this factorization.
808 * Check if the basic set can be factorized.
809 * If so, compute constraints on the coefficients of the factors
810 * separately and combine the results.
811 * Otherwise, compute the results for the input basic set as a whole.
813 static __isl_give isl_basic_set
*basic_set_coefficients(
814 __isl_take isl_basic_set
*bset
)
819 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
821 return isl_basic_set_free(bset
);
822 bset
= isl_basic_set_move_dims(bset
, isl_dim_set
, 0,
823 isl_dim_param
, 0, nparam
);
825 f
= isl_basic_set_factorizer(bset
);
827 return isl_basic_set_free(bset
);
828 if (f
->n_group
> 0) {
829 isl_basic_set_free(bset
);
830 return isl_basic_set_coefficients_morphed_product(f
);
832 isl_factorizer_free(f
);
833 return isl_basic_set_coefficients_base(bset
);
836 /* Construct a basic set containing the tuples of coefficients of all
837 * valid affine constraints on the given basic set.
839 __isl_give isl_basic_set
*isl_basic_set_coefficients(
840 __isl_take isl_basic_set
*bset
)
847 isl_die(bset
->ctx
, isl_error_invalid
,
848 "input set not allowed to have local variables",
851 space
= isl_basic_set_get_space(bset
);
852 space
= isl_space_coefficients(space
);
854 bset
= basic_set_coefficients(bset
);
855 bset
= isl_basic_set_reset_space(bset
, space
);
858 isl_basic_set_free(bset
);
862 /* Construct a basic set containing the elements that satisfy all
863 * affine constraints whose coefficient tuples are
864 * contained in the given basic set.
866 __isl_give isl_basic_set
*isl_basic_set_solutions(
867 __isl_take isl_basic_set
*bset
)
874 isl_die(bset
->ctx
, isl_error_invalid
,
875 "input set not allowed to have local variables",
878 space
= isl_basic_set_get_space(bset
);
879 space
= isl_space_solutions(space
);
881 bset
= farkas(bset
, -1);
882 bset
= isl_basic_set_reset_space(bset
, space
);
885 isl_basic_set_free(bset
);
889 /* Construct a basic set containing the tuples of coefficients of all
890 * valid affine constraints on the given set.
892 __isl_give isl_basic_set
*isl_set_coefficients(__isl_take isl_set
*set
)
895 isl_basic_set
*coeff
;
900 isl_space
*space
= isl_set_get_space(set
);
901 space
= isl_space_coefficients(space
);
903 return rational_universe(space
);
906 coeff
= isl_basic_set_coefficients(isl_basic_set_copy(set
->p
[0]));
908 for (i
= 1; i
< set
->n
; ++i
) {
909 isl_basic_set
*bset
, *coeff_i
;
910 bset
= isl_basic_set_copy(set
->p
[i
]);
911 coeff_i
= isl_basic_set_coefficients(bset
);
912 coeff
= isl_basic_set_intersect(coeff
, coeff_i
);
919 /* Wrapper around isl_basic_set_coefficients for use
920 * as a isl_basic_set_list_map callback.
922 static __isl_give isl_basic_set
*coefficients_wrap(
923 __isl_take isl_basic_set
*bset
, void *user
)
925 return isl_basic_set_coefficients(bset
);
928 /* Replace the elements of "list" by the result of applying
929 * isl_basic_set_coefficients to them.
931 __isl_give isl_basic_set_list
*isl_basic_set_list_coefficients(
932 __isl_take isl_basic_set_list
*list
)
934 return isl_basic_set_list_map(list
, &coefficients_wrap
, NULL
);
937 /* Construct a basic set containing the elements that satisfy all
938 * affine constraints whose coefficient tuples are
939 * contained in the given set.
941 __isl_give isl_basic_set
*isl_set_solutions(__isl_take isl_set
*set
)
949 isl_space
*space
= isl_set_get_space(set
);
950 space
= isl_space_solutions(space
);
952 return rational_universe(space
);
955 sol
= isl_basic_set_solutions(isl_basic_set_copy(set
->p
[0]));
957 for (i
= 1; i
< set
->n
; ++i
) {
958 isl_basic_set
*bset
, *sol_i
;
959 bset
= isl_basic_set_copy(set
->p
[i
]);
960 sol_i
= isl_basic_set_solutions(bset
);
961 sol
= isl_basic_set_intersect(sol
, sol_i
);