25 #include "ppl-config.h"
31 #include "assertions.hh"
37 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
47 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
55 : con_sys(topol, default_con_sys_repr),
56 gen_sys(topol, default_gen_sys_repr),
65 else if (num_dimensions > 0) {
71 PPL_ASSERT_HEAVY(
OK());
75 : con_sys(y.topology(), default_con_sys_repr),
76 gen_sys(y.topology(), default_gen_sys_repr),
78 space_dim(y.space_dim) {
96 : con_sys(topol, default_con_sys_repr),
97 gen_sys(topol, default_gen_sys_repr),
108 if (!cs_copy.adjust_topology_and_space_dimension(topol, cs_copy_space_dim)) {
111 :
"NNC_Polyhedron(cs)",
"cs", cs_copy);
135 if (cs_copy[i].is_inconsistent()) {
142 PPL_ASSERT_HEAVY(
OK());
148 : con_sys(topol, default_con_sys_repr),
149 gen_sys(topol, default_gen_sys_repr),
159 ?
"C_Polyhedron(cs, recycle)"
160 :
"NNC_Polyhedron(cs, recycle)",
"cs", cs);
185 if (cs[i].is_inconsistent()) {
192 PPL_ASSERT_HEAVY(
OK());
196 : con_sys(topol, default_con_sys_repr),
197 gen_sys(topol, default_gen_sys_repr),
207 PPL_ASSERT_HEAVY(
OK());
215 :
"NNC_Polyhedron(gs)",
"gs");
225 :
"NNC_Polyhedron(gs)",
"gs", gs_copy);
228 if (gs_copy_space_dim > 0) {
250 PPL_ASSERT_HEAVY(
OK());
258 PPL_ASSERT_HEAVY(
OK());
264 : con_sys(topol, default_con_sys_repr),
265 gen_sys(topol, default_gen_sys_repr),
275 PPL_ASSERT_HEAVY(
OK());
282 ?
"C_Polyhedron(gs, recycle)"
283 :
"NNC_Polyhedron(gs, recycle)",
"gs");
290 ?
"C_Polyhedron(gs, recycle)"
291 :
"NNC_Polyhedron(gs, recycle)",
"gs", gs);
294 if (gs_space_dim > 0) {
315 PPL_ASSERT_HEAVY(
OK());
323 PPL_ASSERT_HEAVY(
OK());
329 PPL_ASSERT(topology() == y.
topology());
334 else if (space_dim == 0) {
340 con_sys.assign_with_pending(y.
con_sys);
343 gen_sys.assign_with_pending(y.
gen_sys);
358 PPL_ASSERT(topology() == y.
topology());
360 PPL_ASSERT(!marked_empty() && !y.
marked_empty() && space_dim > 0);
364 if (x.is_necessarily_closed()) {
366 bool css_normalized =
false;
374 const dimension_type x_num_equalities = x.con_sys.num_equalities();
380 css_normalized = (x_num_equalities == 0);
395 if (x_num_lines == 0) {
397 x.obtain_sorted_generators();
408 if (css_normalized) {
410 x.obtain_sorted_constraints();
427 PPL_ASSERT(topology() == y.
topology());
429 PPL_ASSERT(!marked_empty() && !y.
marked_empty() && space_dim > 0);
434 if (x.has_pending_constraints() && !x.process_pending_constraints()) {
443 if (!x.generators_are_up_to_date() && !x.update_generators()) {
450 if (!x.generators_are_minimized()) {
458 PPL_ASSERT_HEAVY(x.OK());
459 PPL_ASSERT_HEAVY(y.
OK());
464 if (x.is_necessarily_closed()) {
570 const bool from_above)
const {
574 if (space_dim < expr_space_dim) {
575 throw_dimension_incompatible((from_above
576 ?
"bounds_from_above(e)"
577 :
"bounds_from_below(e)"),
"e", expr);
583 || (has_pending_constraints() && !process_pending_constraints())
584 || (!generators_are_up_to_date() && !update_generators())) {
595 || (from_above && sp_sign > 0)
596 || (!from_above && sp_sign < 0))) {
616 if (space_dim < expr_space_dim) {
617 throw_dimension_incompatible((maximize
619 :
"minimize(e, ...)"),
"e", expr);
623 if (space_dim == 0) {
624 if (marked_empty()) {
638 || (has_pending_constraints() && !process_pending_constraints())
639 || (!generators_are_up_to_date() && !update_generators())) {
649 bool first_candidate =
true;
663 const int sp_sign =
sgn(sp);
666 || (maximize && sp_sign > 0)
667 || (!maximize && sp_sign < 0))) {
680 candidate.canonicalize();
681 const bool g_is_point = gen_sys_i.
is_point();
684 && (candidate > extremum
687 && candidate == extremum)))
689 && (candidate < extremum
692 && candidate == extremum)))) {
694 first_candidate =
false;
695 extremum = candidate;
697 ext_included = g_is_point;
709 PPL_ASSERT(!first_candidate);
710 ext_n = extremum.get_num();
711 ext_d = extremum.get_den();
712 included = ext_included;
713 g = gen_sys[ext_position];
720 status.set_zero_dim_univ();
738 PPL_ASSERT(space_dim > 0 && !marked_empty());
739 PPL_ASSERT(has_pending_constraints() && !has_pending_generators());
757 PPL_ASSERT_HEAVY(OK(
true));
772 PPL_ASSERT_HEAVY(OK(!empty));
778 PPL_ASSERT(space_dim > 0 && !marked_empty());
779 PPL_ASSERT(has_pending_generators() && !has_pending_constraints());
797 PPL_ASSERT_HEAVY(OK(
true));
811 PPL_ASSERT(has_something_pending());
830 PPL_ASSERT_HEAVY(OK(
true));
835 PPL_ASSERT(has_something_pending());
847 PPL_ASSERT_HEAVY(OK(
true));
860 PPL_ASSERT(space_dim > 0);
861 PPL_ASSERT(!marked_empty());
862 PPL_ASSERT(generators_are_up_to_date());
864 PPL_ASSERT(!has_something_pending());
879 PPL_ASSERT(space_dim > 0);
880 PPL_ASSERT(!marked_empty());
881 PPL_ASSERT(constraints_are_up_to_date());
883 PPL_ASSERT(!has_something_pending());
906 PPL_ASSERT(constraints_are_minimized());
907 PPL_ASSERT(generators_are_minimized());
908 PPL_ASSERT(!sat_c_is_up_to_date());
925 PPL_ASSERT(sp_sign >= 0);
941 PPL_ASSERT(constraints_are_minimized());
942 PPL_ASSERT(generators_are_minimized());
943 PPL_ASSERT(!sat_g_is_up_to_date());
960 PPL_ASSERT(sp_sign >= 0);
976 PPL_ASSERT(constraints_are_up_to_date());
1000 PPL_ASSERT(con_sys.check_sorted());
1005 PPL_ASSERT(generators_are_up_to_date());
1029 PPL_ASSERT(gen_sys.check_sorted());
1034 PPL_ASSERT(constraints_are_up_to_date());
1035 PPL_ASSERT(constraints_are_minimized());
1065 PPL_ASSERT(con_sys.check_sorted());
1070 PPL_ASSERT(generators_are_up_to_date());
1101 PPL_ASSERT(gen_sys.check_sorted());
1107 if (marked_empty()) {
1110 if (space_dim == 0) {
1115 if (has_something_pending()) {
1116 const bool not_empty = process_pending();
1117 PPL_ASSERT_HEAVY(OK());
1123 if (constraints_are_minimized() && generators_are_minimized()) {
1133 if (constraints_are_up_to_date()) {
1135 const bool ret = update_generators();
1136 PPL_ASSERT_HEAVY(OK());
1140 PPL_ASSERT(generators_are_up_to_date());
1141 update_constraints();
1142 PPL_ASSERT_HEAVY(OK());
1149 PPL_ASSERT(!is_necessarily_closed());
1165 if (!sat_g_is_up_to_date()) {
1166 PPL_ASSERT(sat_c_is_up_to_date());
1175 Bit_Row sat_all_but_closure_points;
1180 switch (gen_sys[i].type()) {
1182 sat_all_but_rays.
set(i);
1185 sat_all_but_points.
set(i);
1188 sat_all_but_closure_points.
set(i);
1197 sat_lines_and_rays(sat_all_but_points, sat_all_but_closure_points);
1199 sat_lines_and_closure_points(sat_all_but_rays, sat_all_but_points);
1201 sat_lines(sat_lines_and_rays, sat_lines_and_closure_points);
1206 bool changed =
false;
1207 bool found_eps_leq_one =
false;
1218 if (cs[i].is_strict_inequality()) {
1221 sat_ci.
union_assign(sat[i], sat_lines_and_closure_points);
1222 if (sat_ci == sat_lines) {
1224 if (!found_eps_leq_one) {
1230 found_eps_leq_one =
true;
1251 bool eps_redundant =
false;
1253 if (i != j && cs[j].is_strict_inequality()
1254 && subset_or_equal(sat[j], sat_ci)) {
1259 eps_redundant =
true;
1267 if (!eps_redundant) {
1289 if (!found_eps_leq_one) {
1318 PPL_ASSERT_HEAVY(OK());
1324 PPL_ASSERT(!is_necessarily_closed());
1341 if (!sat_c_is_up_to_date()) {
1342 PPL_ASSERT(sat_g_is_up_to_date());
1348 Bit_Row sat_all_but_strict_ineq;
1352 if (con_sys[i].is_strict_inequality()) {
1353 sat_all_but_strict_ineq.
set(i);
1358 bool changed =
false;
1374 const Bit_Row sat_gs_i(sat[i], sat_all_but_strict_ineq);
1378 bool eps_redundant =
false;
1381 if (i != j && g2.
is_point() && subset_or_equal(sat[j], sat_gs_i)) {
1386 swap(g, gs.
sys.rows[gs_rows]);
1387 swap(sat[i], sat[gs_rows]);
1388 eps_redundant =
true;
1393 if (!eps_redundant) {
1413 if (gs_rows < old_gs_rows) {
1414 gs.
sys.rows.resize(gs_rows);
1427 PPL_ASSERT(gs.
sys.OK());
1429 PPL_ASSERT_HEAVY(OK());
1435 PPL_ASSERT(!marked_empty());
1439 if (space_dim == 0) {
1447 if (has_pending_generators()) {
1448 process_pending_generators();
1450 else if (!constraints_are_up_to_date()) {
1451 update_constraints();
1454 const bool adding_pending = can_have_something_pending();
1459 if (adding_pending) {
1460 con_sys.insert_pending(c);
1473 if (adding_pending) {
1474 con_sys.insert_pending(nc_expr == 0);
1477 con_sys.insert(nc_expr == 0);
1481 if (adding_pending) {
1482 con_sys.insert_pending(nc_expr >= 0);
1485 con_sys.insert(nc_expr >= 0);
1490 if (adding_pending) {
1491 set_constraints_pending();
1495 clear_constraints_minimized();
1496 clear_generators_up_to_date();
1501 PPL_ASSERT_HEAVY(OK());
1559 if (x_affine_dim > y_affine_dim) {
1562 else if (x_affine_dim < y_affine_dim) {
1583 x_gs_red_in_y.
set(i);
1584 ++num_x_gs_red_in_y;
1592 y_gs_red_in_x.
set(i);
1593 ++num_y_gs_red_in_x;
1599 if (num_y_gs_red_in_x == y_gs_num_rows) {
1603 if (num_x_gs_red_in_y == x_gs_num_rows) {
1612 if (num_x_gs_red_in_y == 0 || num_y_gs_red_in_x == 0) {
1636 if (row_union != all_ones) {
1644 if (!y_gs_red_in_x[j]) {
1645 add_generator(y_gs[j]);
1649 PPL_ASSERT_HEAVY(OK());
1674 Bit_Row x_gs_non_redundant_in_y;
1675 Bit_Row x_points_non_redundant_in_y;
1681 x_closure_points.
set(i);
1686 x_gs_non_redundant_in_y.
set(i);
1687 ++num_x_gs_non_redundant_in_y;
1689 x_points_non_redundant_in_y.
set(i);
1694 if (num_x_gs_non_redundant_in_y == 0) {
1700 Bit_Row y_gs_non_redundant_in_x;
1701 Bit_Row y_points_non_redundant_in_x;
1707 y_closure_points.
set(i);
1712 y_gs_non_redundant_in_x.
set(i);
1713 ++num_y_gs_non_redundant_in_x;
1715 y_points_non_redundant_in_x.
set(i);
1720 if (num_y_gs_non_redundant_in_x == 0) {
1724 Bit_Row x_non_points_non_redundant_in_y;
1725 x_non_points_non_redundant_in_y
1727 x_points_non_redundant_in_y);
1736 Bit_Row x_points_non_redundant_in_y_closure;
1739 i = x_points_non_redundant_in_y.
next(i)) {
1747 if (sp_sign < 0 || (y_c.
is_equality() && sp_sign > 0)) {
1748 x_points_non_redundant_in_y_closure.
set(i);
1777 if (!tmp_set.
empty()) {
1782 x_cs_condition_3.
set(i);
1784 x_gs_condition_3.
union_assign(x_gs_condition_3, tmp_set);
1790 if (!tmp_set.
empty()) {
1799 Bit_Row y_non_points_non_redundant_in_x;
1800 y_non_points_non_redundant_in_x
1802 y_points_non_redundant_in_x);
1806 Bit_Row y_points_non_redundant_in_x_closure;
1809 i = y_points_non_redundant_in_x.
next(i)) {
1817 if (sp_sign < 0 || (x_c.
is_equality() && sp_sign > 0)) {
1818 y_points_non_redundant_in_x_closure.
set(i);
1843 if (!tmp_set.
empty()) {
1848 y_cs_condition_3.
set(i);
1850 y_gs_condition_3.
union_assign(y_gs_condition_3, tmp_set);
1856 if (!tmp_set.
empty()) {
1864 if (x_cs_condition_3.
empty() && y_cs_condition_3.
empty()) {
1868 if (y_gs_non_redundant_in_x[j]) {
1869 add_generator(y_gs[j]);
1878 if (y_gs_non_redundant_in_x[j]) {
1893 Bit_Row x_gs_condition_3_not_in_y;
1902 PPL_ASSERT(sp_sign >= 0);
1904 x_gs_condition_3.
clear(j);
1905 x_gs_condition_3_not_in_y.set(j);
1908 if (x_gs_condition_3.
empty()) {
1916 Bit_Row y_gs_condition_3_not_in_x;
1918 if (x_cs[i].is_strict_inequality()) {
1925 PPL_ASSERT(sp_sign >= 0);
1927 y_gs_condition_3.
clear(j);
1928 y_gs_condition_3_not_in_x.
set(j);
1931 if (y_gs_condition_3.
empty()) {
1943 if (ub_cs[i].is_strict_inequality()) {
1947 j = x_gs_condition_3_not_in_y.next(j)) {
1951 PPL_ASSERT(sp_sign >= 0);
1953 x_gs_condition_3_not_in_y.clear(j);
1958 j = y_gs_condition_3_not_in_x.
next(j)) {
1962 PPL_ASSERT(sp_sign >= 0);
1964 y_gs_condition_3_not_in_x.
clear(j);
1970 if (!(x_gs_condition_3_not_in_y.empty()
1971 && y_gs_condition_3_not_in_x.
empty())) {
1993 if (!y_inters_hyperplane.
contains(ub_inters_hyperplane)) {
2012 if (!x_inters_hyperplane.
contains(ub_inters_hyperplane)) {
2071 std::vector<bool> x_gs_red_in_y(x_gs_num_rows,
false);
2075 x_gs_red_in_y[i] =
true;
2076 ++num_x_gs_red_in_y;
2079 std::vector<bool> y_gs_red_in_x(y_gs_num_rows,
false);
2083 y_gs_red_in_x[i] =
true;
2084 ++num_y_gs_red_in_x;
2090 if (num_x_gs_red_in_y == 0 && num_y_gs_red_in_x == 0) {
2095 if (num_y_gs_red_in_x == y_gs_num_rows) {
2099 if (num_x_gs_red_in_y == x_gs_num_rows) {
2109 std::vector<bool> x_cs_red_in_y(x_cs_num_rows,
false);
2113 x_cs_red_in_y[i] =
true;
2124 std::vector<bool> y_cs_red_in_x(y_cs_num_rows,
false);
2128 y_cs_red_in_x[i] =
true;
2144 if (x_gs_red_in_y[i]) {
2150 if (y_gs_red_in_x[j]) {
2162 const bool illegal_ray
2166 PPL_ASSERT(!(illegal_ray && (x_g_is_line || y_g_is_line)));
2181 PPL_ASSERT(mid_g.
OK());
2191 if (!x_g_is_line && y_g_is_line) {
2196 PPL_ASSERT(mid_g.
OK());
2203 else if (x_g_is_line && !y_g_is_line) {
2208 PPL_ASSERT(mid_g.
OK());
2223 if (!y_gs_red_in_x[j]) {
2224 add_generator(y_gs[j]);
2227 PPL_ASSERT_HEAVY(OK());
2235 if (vars_p != 0 && vars_p->empty()) {
2240 if (marked_empty()) {
2246 if (space_dim == 0) {
2252 if (has_pending_generators()) {
2258 process_pending_generators();
2261 if (!constraints_are_up_to_date()) {
2267 update_constraints();
2271 if (!is_necessarily_closed() && has_pending_constraints()) {
2275 else if (!process_pending_constraints()) {
2281 PPL_ASSERT(!has_pending_generators() && constraints_are_up_to_date());
2282 PPL_ASSERT(is_necessarily_closed() || !has_pending_constraints());
2284 bool changed =
false;
2287 const bool con_sys_was_sorted = con_sys.is_sorted();
2293 if (vars_p->find(i) == vars_p->end()) {
2304 if (!other_vars.empty()) {
2312 if (!is_necessarily_closed()) {
2330 if (gcd != 0 && gcd != 1) {
2344 const int c_0_sign =
sgn(c_0);
2355 con_sys.set_sorted(!changed && con_sys_was_sorted);
2356 PPL_ASSERT(con_sys.sys.OK());
2359 if (is_necessarily_closed()) {
2368 clear_generators_up_to_date();
2369 clear_constraints_minimized();
2371 PPL_ASSERT_HEAVY(OK());
2377 PPL_ASSERT(!is_necessarily_closed());
2382 throw_dimension_incompatible(
"positive_time_elapse_assign(y)",
"y", y);
2415 new_gs.
sys.set_sorted(
false);
2425 swap(g, new_gs.
sys.rows[num_rows]);
2428 new_gs.
sys.rows.resize(num_rows);
2435 PPL_ASSERT(new_gs.
sys.OK());
2450 PPL_ASSERT(gs->OK());
2474 new_g.expr.set_inhomogeneous_term(new_divisor);
2475 if (new_g.is_not_necessarily_closed()) {
2478 new_g.expr.normalize();
2479 PPL_ASSERT(new_g.OK());
2490 PPL_ASSERT(g_as_a_ray.
OK());
2492 new_gs.
insert(g_as_a_ray);
2509 PPL_ASSERT(new_gs.
sys.OK());
2513 swap(gen_sys, new_gs);
2515 gen_sys.set_sorted(
false);
2516 clear_generators_minimized();
2518 set_generators_up_to_date();
2520 clear_constraints_up_to_date();
2522 PPL_ASSERT_HEAVY(x.
OK(
true) && y.
OK(
true));
2527 const char* reason)
const {
2528 std::ostringstream s;
2530 if (is_necessarily_closed()) {
2536 s <<
"Polyhedron::" << method <<
":" << std::endl
2538 throw std::invalid_argument(s.str());
2543 const char* ph_name,
2545 std::ostringstream s;
2547 if (is_necessarily_closed()) {
2553 s <<
"Polyhedron::" << method <<
":" << std::endl
2554 << ph_name <<
" is a ";
2561 s <<
"Polyhedron." << std::endl;
2562 throw std::invalid_argument(s.str());
2569 PPL_ASSERT(is_necessarily_closed());
2570 std::ostringstream s;
2571 s <<
"PPL::C_Polyhedron::" << method <<
":" << std::endl
2572 << c_name <<
" is a strict inequality.";
2573 throw std::invalid_argument(s.str());
2580 PPL_ASSERT(is_necessarily_closed());
2581 std::ostringstream s;
2582 s <<
"PPL::C_Polyhedron::" << method <<
":" << std::endl
2583 << g_name <<
" is a closure point.";
2584 throw std::invalid_argument(s.str());
2589 const char* cs_name,
2591 PPL_ASSERT(is_necessarily_closed());
2592 std::ostringstream s;
2593 s <<
"PPL::C_Polyhedron::" << method <<
":" << std::endl
2594 << cs_name <<
" contains strict inequalities.";
2595 throw std::invalid_argument(s.str());
2600 const char* gs_name,
2602 std::ostringstream s;
2603 s <<
"PPL::C_Polyhedron::" << method <<
":" << std::endl
2604 << gs_name <<
" contains closure points.";
2605 throw std::invalid_argument(s.str());
2610 const char* other_name,
2612 std::ostringstream s;
2614 << (is_necessarily_closed() ?
"C_" :
"NNC_")
2615 <<
"Polyhedron::" << method <<
":\n"
2616 <<
"this->space_dimension() == " << space_dimension() <<
", "
2617 << other_name <<
".space_dimension() == " << other_dim <<
".";
2618 throw std::invalid_argument(s.str());
2623 const char* ph_name,
2631 const char* le_name,
2652 const char* cg_name,
2659 const char* cs_name,
2667 const char* gs_name,
2675 const char* cgs_name,
2677 throw_dimension_incompatible(method, cgs_name, cgs.
space_dimension());
2682 const char* var_name,
2684 std::ostringstream s;
2686 if (is_necessarily_closed()) {
2692 s <<
"Polyhedron::" << method <<
":" << std::endl
2693 <<
"this->space_dimension() == " << space_dimension() <<
", "
2694 << var_name <<
".space_dimension() == " << var.
space_dimension() <<
".";
2695 throw std::invalid_argument(s.str());
2702 std::ostringstream s;
2704 if (is_necessarily_closed()) {
2710 s <<
"Polyhedron::" << method <<
":" << std::endl
2711 <<
"this->space_dimension() == " << space_dimension()
2712 <<
", required space dimension == " << required_space_dim <<
".";
2713 throw std::invalid_argument(s.str());
2721 const char* reason) {
2723 ?
"PPL::C_Polyhedron::" :
"PPL::NNC_Polyhedron::";
2731 const char* reason) {
2733 topol, method, reason);
2738 const char* g_name)
const {
2739 std::ostringstream s;
2741 if (is_necessarily_closed()) {
2747 s <<
"Polyhedron::" << method <<
":" << std::endl
2748 <<
"*this is an empty polyhedron and "
2749 << g_name <<
" is not a point.";
2750 throw std::invalid_argument(s.str());
2755 const char* gs_name)
const {
2756 std::ostringstream s;
2758 if (is_necessarily_closed()) {
2764 s <<
"Polyhedron::" << method <<
":" << std::endl
2765 <<
"*this is an empty polyhedron and" << std::endl
2766 <<
"the non-empty generator system " << gs_name <<
" contains no points.";
2767 throw std::invalid_argument(s.str());
bool has_pending_constraints() const
Returns true if there are pending constraints.
bool constraints_are_minimized() const
Returns true if the system of constraints is minimized.
static int homogeneous_sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the homogeneous scalar product of x and y, where the inhomogeneous terms are igno...
Enable_If< Is_Native_Or_Checked< To >::value &&Is_Special< From >::value, Result >::type assign_r(To &to, const From &, Rounding_Dir dir)
bool is_tautological() const
Returns true if and only if *this is a tautology (i.e., an always true constraint).
void drop_some_non_integer_points(Complexity_Class complexity=ANY_COMPLEXITY)
Possibly tightens *this by dropping some points with non-integer coordinates.
void set_until(unsigned long k)
Sets bits up to position k (excluded).
bool marked_empty() const
Returns true if the polyhedron is known to be empty.
The empty element, i.e., the empty set.
static Poly_Con_Relation is_disjoint()
The polyhedron and the set of points satisfying the constraint are disjoint.
static Poly_Gen_Relation subsumes()
Adding the generator would not change the polyhedron.
void sort_and_remove_with_sat(Bit_Matrix &sat)
Sorts the system, removing duplicates, keeping the saturation matrix consistent.
void set_optimization_mode(Optimization_Mode mode)
Sets the optimization mode to mode.
void set_sat_g_up_to_date()
Sets status to express that sat_g is up-to-date.
A linear equality or inequality.
bool is_equality() const
Returns true if and only if *this is an equality constraint.
void swap(CO_Tree &x, CO_Tree &y)
bool minimize() const
Applies (weak) minimization to both the constraints and generators.
void clear_constraints_up_to_date()
Sets status to express that constraints are no longer up-to-date.
bool strongly_minimize_constraints() const
Applies strong minimization to the constraints of an NNC polyhedron.
bool adjust_topology_and_space_dimension(Topology new_topology, dimension_type new_space_dim)
Adjusts *this so that it matches the new_topology and new_space_dim (adding or removing columns if ne...
bool remove_pending_to_obtain_generators() const
Lazily integrates the pending descriptions of the polyhedron to obtain a generator system without pen...
static bool implies(flags_t x, flags_t y)
True if and only if the conjunction x implies the conjunction y.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void update_constraints() const
Updates constraints starting from generators and minimizes them.
Type type() const
Returns the constraint type of *this.
void intersection_assign(const Bit_Row &x, const Bit_Row &y)
Assigns to *this the set-theoretic intersection of x and y.
bool is_necessarily_closed() const
Returns true if and only if the topology of *this row is necessarily closed.
bool max_min(const Linear_Expression &expr, bool maximize, Coefficient &ext_n, Coefficient &ext_d, bool &included, Generator &g) const
Maximizes or minimizes expr subject to *this.
An std::set of variables' indexes.
void resize(dimension_type new_n_rows, dimension_type new_n_columns)
Resizes the matrix copying the old contents.
Generator_System gen_sys
The system of generators.
A line, ray, point or closure point.
Linear_Expression expr
The linear expression encoding *this.
void add_constraints(const Constraint_System &cs)
Adds a copy of the constraints in cs to the MIP problem.
bool generators_are_minimized() const
Returns true if the system of generators is minimized.
bool is_empty() const
Returns true if and only if *this is an empty polyhedron.
void union_assign(const Bit_Row &x, const Bit_Row &y)
Assigns to *this the set-theoretic union of x and y.
bool is_line_or_ray() const
Returns true if and only if *this is a line or a ray.
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
void set_generators_up_to_date()
Sets status to express that generators are up-to-date.
void clear_pending_generators()
Sets status to express that there are no longer pending generators.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void assign_with_pending(const Constraint_System &y)
Full assignment operator: pending rows are copied as pending.
void add_constraint(const Constraint &c)
Adds a copy of constraint c to the system of constraints of *this (without minimizing the result)...
bool strongly_minimize_generators() const
Applies strong minimization to the generators of an NNC polyhedron.
void insert(const Constraint &c)
Inserts in *this a copy of the constraint c, increasing the number of space dimensions if needed...
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static Poly_Con_Relation is_included()
The polyhedron is included in the set of points satisfying the constraint.
bool sat_c_is_up_to_date() const
Returns true if the saturation matrix sat_c is up-to-date.
dimension_type num_pending_rows() const
Returns the number of rows that are in the pending part of the system.
void set(unsigned long k)
Sets the bit in position k.
bool update_generators() const
Updates generators starting from constraints and minimizes them.
void set_constraints_up_to_date()
Sets status to express that constraints are up-to-date.
void difference_assign(const Bit_Row &x, const Bit_Row &y)
Assigns to *this the set-theoretic difference of x and y.
void swap(Polyhedron &x, Polyhedron &y)
Swaps x with y.
bool is_sorted() const
Returns the value of the sortedness flag.
bool sat_g_is_up_to_date() const
Returns true if the saturation matrix sat_g is up-to-date.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
bool has_points() const
Returns true if and only if *this contains one or more points.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
const Constraint_System & constraints() const
Returns the system of constraints.
void clear(unsigned long k)
Clears the bit in position k.
void assign_with_pending(const Generator_System &y)
Full assignment operator: pending rows are copied as pending.
void set_inhomogeneous_term(Coefficient_traits::const_reference n)
Sets the inhomogeneous term of *this to n.
A row in a matrix of bits.
Polyhedron & operator=(const Polyhedron &y)
The assignment operator. (*this and y can be dimension-incompatible.)
void obtain_sorted_constraints() const
Sorts the matrix of constraints keeping status consistency.
Coefficient gcd(dimension_type start, dimension_type end) const
Returns the gcd of the nonzero coefficients in [start,end). Returns zero if all the coefficients in t...
Polyhedron(Topology topol, dimension_type num_dimensions, Degenerate_Element kind)
Builds a polyhedron having the specified properties.
bool BFT00_poly_hull_assign_if_exact(const Polyhedron &y)
If the poly-hull of *this and y is exact it is assigned to *this and true is returned, otherwise false is returned.
void mark_as_not_necessarily_closed()
Marks the last dimension as the epsilon dimension.
bool is_sorted() const
Returns the value of the sortedness flag.
A dimension of the vector space.
bool is_strict_inequality() const
Returns true if and only if *this is a strict inequality constraint.
void sort_pending_and_remove_duplicates()
Sorts the pending rows and eliminates those that also occur in the non-pending part of the system...
Complexity_Class
Complexity pseudo-classes.
The base class for convex polyhedra.
void remove_row(dimension_type i, bool keep_sorted=false)
Makes the system shrink by removing its i-th row.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_sat_c_up_to_date()
Sets status to express that sat_c is up-to-date.
bool BHZ09_C_poly_hull_assign_if_exact(const Polyhedron &y)
void update_sat_g() const
Updates sat_g using the updated constraints and generators.
bool is_inequality() const
Returns true if and only if *this is an inequality constraint (either strict or non-strict).
The problem is unbounded.
void throw_invalid_generators(const char *method, const char *gs_name) const
Topology topology() const
Returns the topological kind of the polyhedron.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
void throw_invalid_argument(const char *method, const char *reason) const
Constraint_System con_sys
The system of constraints.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static int reduced_sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the reduced scalar product of x and y, where the coefficient of x is ignored...
void clear_pending_constraints()
Sets status to express that there are no longer pending constraints.
dimension_type num_equalities() const
Returns the number of equality constraints.
static dimension_type check_space_dimension_overflow(dimension_type dim, dimension_type max, const Topology topol, const char *method, const char *reason)
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
Degenerate_Element
Kinds of degenerate abstract elements.
Type type() const
Returns the generator type of *this.
bool constraints_are_up_to_date() const
Returns true if the system of constraints is up-to-date.
void clear()
Clears the matrix deallocating all its rows.
bool OK() const
Checks if all the invariants are satisfied.
void refine_no_check(const Constraint &c)
Uses a copy of constraint c to refine the system of constraints of *this.
void throw_topology_incompatible(const char *method, const char *ph_name, const Polyhedron &ph) const
The problem is unfeasible.
bool BHZ09_NNC_poly_hull_assign_if_exact(const Polyhedron &y)
void obtain_sorted_generators_with_sat_g() const
Sorts the matrix of generators and updates sat_g.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void obtain_sorted_constraints_with_sat_c() const
Sorts the matrix of constraints and updates sat_c.
dimension_type check_space_dimension_overflow(const dimension_type dim, const dimension_type max, const char *domain, const char *method, const char *reason)
Bit_Matrix sat_g
The saturation matrix having generators on its columns.
void set_generators_minimized()
Sets status to express that generators are minimized.
static dimension_type max_space_dimension()
Returns the maximum space dimension all kinds of Polyhedron can handle.
A Mixed Integer (linear) Programming problem.
void sort_and_remove_with_sat(Bit_Matrix &sat)
Sorts the system, removing duplicates, keeping the saturation matrix consistent.
bool is_inconsistent() const
Returns true if and only if *this is inconsistent (i.e., an always false constraint).
void sign_normalize()
Normalizes the sign of the coefficients so that the first non-zero (homogeneous) coefficient of a lin...
bool empty() const
Returns true if no bit is set in the row.
unsigned long first() const
Returns the index of the first set bit or ULONG_MAX if no bit is set.
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
bool all_homogeneous_terms_are_zero() const
Returns true if and only if all the homogeneous terms of *this are .
bool is_point() const
Returns true if and only if *this is a point.
void process_pending_generators() const
Processes the pending generators and obtains a minimized polyhedron.
bool all_homogeneous_terms_are_zero() const
Returns true if and only if all the homogeneous terms of *this are zero.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void add_generator(const Generator &g)
Adds a copy of generator g to the system of generators of *this (without minimizing the result)...
void sort_rows()
Sorts the non-pending rows (in growing order) and eliminates duplicated ones.
Status status
The status flags to keep track of the polyhedron's internal state.
bool is_included_in(const Polyhedron &y) const
Returns true if and only if *this is included in y.
void set_epsilon_coefficient(Coefficient_traits::const_reference n)
Sets the epsilon coefficient to n. The constraint must be NNC.
#define PPL_DIRTY_TEMP(T, id)
void convert_into_non_necessarily_closed()
void sort_rows()
Sorts the non-pending rows (in growing order) and eliminates duplicated ones.
void positive_time_elapse_assign_impl(const Polyhedron &y)
Assuming *this is NNC, assigns to *this the result of the "positive time-elapse" between *this and y...
void remove_pending_to_obtain_constraints() const
Lazily integrates the pending descriptions of the polyhedron to obtain a constraint system without pe...
void add_corresponding_closure_points()
For each unmatched point in *this, adds the corresponding closure point.
bool minimize(const Linear_Expression &expr, Coefficient &inf_n, Coefficient &inf_d, bool &minimum) const
Returns true if and only if *this is not empty and expr is bounded from below in *this, in which case the infimum value is computed.
void set_empty()
Sets status to express that the polyhedron is empty, clearing all corresponding matrices.
void set_is_ray_or_point_or_inequality()
Sets to RAY_OR_POINT_OR_INEQUALITY the kind of *this row.
The entire library is confined to this namespace.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
void insert(Variable v)
Inserts the index of variable v into the set.
bool bounds(const Linear_Expression &expr, bool from_above) const
Checks if and how expr is bounded in *this.
void set_sorted(bool b)
Sets the sortedness flag of the system to b.
void set_epsilon_coefficient(Coefficient_traits::const_reference n)
Sets the epsilon coefficient to n. The generator must be NNC.
Maximization is requested.
void upper_bound_assign(const Polyhedron &y)
Same as poly_hull_assign(y).
bool contains(const Polyhedron &y) const
Returns true if and only if *this contains y.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static const Constraint & epsilon_leq_one()
The zero-dimension space constraint (used to implement NNC polyhedra).
bool is_necessarily_closed() const
Returns true if and only if the polyhedron is necessarily closed.
Coefficient_traits::const_reference epsilon_coefficient() const
Returns the epsilon coefficient. The constraint must be NNC.
Linear_System< Generator > sys
Coefficient_traits::const_reference epsilon_coefficient() const
Returns the epsilon coefficient. The generator must be NNC.
static const Constraint & zero_dim_positivity()
The true (zero-dimension space) constraint , also known as positivity constraint. ...
void clear_sat_g_up_to_date()
Sets status to express that sat_g is no longer up-to-date.
void unset_pending_rows()
Sets the index to indicate that the system has no pending rows.
dimension_type num_lines() const
Returns the number of lines of the system.
void set_objective_function(const Linear_Expression &obj)
Sets the objective function to obj.
MIP_Problem_Status solve() const
Optimizes the MIP problem.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
bool process_pending_constraints() const
Processes the pending constraints and obtains a minimized polyhedron.
void clear_constraints_minimized()
Sets status to express that constraints are no longer minimized.
void add_low_level_constraints()
Adds low-level constraints to the constraint system.
bool OK() const
Checks if all the invariants are satisfied.
int sgn(Boundary_Type type, const T &x, const Info &info)
static void homogeneous_assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the homogeneous scalar product of x and y, where the inhomogeneous terms are ignored...
static int sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the scalar product between x and y.
void exact_div_assign(Coefficient_traits::const_reference c, dimension_type start, dimension_type end)
void update_sat_c() const
Updates sat_c using the updated constraints and generators.
Three_Valued_Boolean quick_equivalence_test(const Polyhedron &y) const
Polynomial but incomplete equivalence test between polyhedra.
void obtain_sorted_generators() const
Sorts the matrix of generators keeping status consistency.
unsigned long next(unsigned long position) const
Returns the index of the first set bit after position or ULONG_MAX if no bit after position is set...
bool BHZ09_poly_hull_assign_if_exact(const Polyhedron &y)
bool has_pending_generators() const
Returns true if there are pending generators.
dimension_type affine_dimension() const
Returns , if *this is empty; otherwise, returns the affine dimension of *this.
void set_sorted(bool b)
Sets the sortedness flag of the system to b.
void clear_sat_c_up_to_date()
Sets status to express that sat_c is no longer up-to-date.
dimension_type num_pending_rows() const
Returns the number of rows that are in the pending part of the system.
void sort_pending_and_remove_duplicates()
Sorts the pending rows and eliminates those that also occur in the non-pending part of the system...
Bit_Matrix sat_c
The saturation matrix having constraints on its columns.
dimension_type num_rows() const
void throw_invalid_generator(const char *method, const char *g_name) const
void set_constraints_minimized()
Sets status to express that constraints are minimized.
void add_space_dimensions_and_embed(dimension_type m)
Adds m new space dimensions and embeds the old MIP problem in the new vector space.
expr_type expression() const
Partial read access to the (adapted) internal expression.
#define PPL_UNINITIALIZED(type, name)
void upper_bound_assign(std::map< dimension_type, Linear_Form< FP_Interval_Type > > &ls1, const std::map< dimension_type, Linear_Form< FP_Interval_Type > > &ls2)
bool is_line_or_equality() const
Returns true if and only if *this row represents a line or an equality.
void insert(const Generator &g)
Inserts in *this a copy of the generator g, increasing the number of space dimensions if needed...
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool is_line() const
Returns true if and only if *this is a line.
bool adjust_topology_and_space_dimension(Topology new_topology, dimension_type new_space_dim)
Adjusts *this so that it matches new_topology and new_space_dim (adding or removing columns if needed...
dimension_type num_rows() const
void mark_as_necessarily_closed()
Marks the epsilon dimension as a standard dimension.
static Poly_Gen_Relation nothing()
The assertion that says nothing.
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
void clear_generators_up_to_date()
Sets status to express that generators are no longer up-to-date.
void unset_pending_rows()
Sets the index to indicate that the system has no pending rows.
bool all_zeroes(const Variables_Set &vars) const
Returns true if the coefficient of each variable in vars is zero.
void set_zero_dim_univ()
Sets status to express that the polyhedron is the universe 0-dimension vector space, clearing all corresponding matrices.
Topology
Kinds of polyhedra domains.
void transpose_assign(const Bit_Matrix &y)
Makes *this a transposed copy of y.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
Poly_Con_Relation relation_with(const Constraint &c) const
Returns the relations holding between the polyhedron *this and the constraint c.
MIP_Problem_Status
Possible outcomes of the MIP_Problem solver.
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
bool has_something_pending() const
Returns true if there are either pending constraints or pending generators.
bool is_closure_point() const
Returns true if and only if *this is a closure point.