24 #include "ppl-config.h"
32 #include "assertions.hh"
36 #ifndef ENSURE_SORTEDNESS
37 #define ENSURE_SORTEDNESS 0
55 delete [] simplify_num_saturators_p;
56 simplify_num_saturators_p = 0;
57 simplify_num_saturators_size = 0;
69 cs_end = cs.
end(); i != cs_end; ++i) {
70 if (i->is_equality()) {
82 if (con_sys.has_no_rows()) {
87 swap(const_cast<Constraint_System&>(con_sys), unsat_cs);
91 PPL_ASSERT(con_sys.space_dimension() == space_dim);
92 PPL_ASSERT(con_sys.num_rows() == 1);
93 PPL_ASSERT(con_sys[0].is_inconsistent());
100 PPL_ASSERT(con_sys.num_rows() == 0 && con_sys.space_dimension() == 0);
107 if (has_pending_generators()) {
108 process_pending_generators();
110 else if (!constraints_are_up_to_date()) {
111 update_constraints();
115 #if ENSURE_SORTEDNESS
118 if (!has_pending_constraints())
119 obtain_sorted_constraints();
128 if (is_necessarily_closed()) {
132 strongly_minimize_constraints();
134 return constraints();
139 if (marked_empty()) {
140 PPL_ASSERT(gen_sys.has_no_rows());
143 if (gen_sys.space_dimension() != space_dim) {
146 swap(const_cast<Generator_System&>(gen_sys), gs);
151 if (space_dim == 0) {
152 PPL_ASSERT(gen_sys.num_rows() == 0 && gen_sys.space_dimension() == 0);
159 if ((has_pending_constraints() && !process_pending_constraints())
160 || (!generators_are_up_to_date() && !update_generators())) {
162 PPL_ASSERT(gen_sys.has_no_rows());
165 if (gen_sys.space_dimension() != space_dim) {
168 swap(const_cast<Generator_System&>(gen_sys), gs);
174 #if ENSURE_SORTEDNESS
177 if (!has_pending_generators())
178 obtain_sorted_generators();
184 if (!is_necessarily_closed()
185 && generators_are_minimized() && !has_pending_generators()) {
186 obtain_sorted_generators();
196 if (is_necessarily_closed()) {
200 strongly_minimize_generators();
212 throw_dimension_incompatible(
"relation_with(c)",
"c", c);
215 if (marked_empty()) {
220 if (space_dim == 0) {
244 if ((has_pending_constraints() && !process_pending_constraints())
245 || (!generators_are_up_to_date() && !update_generators())) {
251 return gen_sys.relation_with(c);
258 throw_dimension_incompatible(
"relation_with(g)",
"g", g);
262 if (marked_empty()) {
268 if (space_dim == 0) {
272 if (has_pending_generators()) {
273 process_pending_generators();
275 else if (!constraints_are_up_to_date()) {
276 update_constraints();
279 con_sys.satisfies_all_constraints(g)
288 if (space_dim < cg_space_dim) {
289 throw_dimension_incompatible(
"relation_with(cg)",
"cg", cg);
294 return relation_with(c);
297 if (marked_empty()) {
303 if (space_dim == 0) {
313 if ((has_pending_constraints() && !process_pending_constraints())
314 || (!generators_are_up_to_date() && !update_generators())) {
329 gs_end = gen_sys.end(); gs_i != gs_end; ++gs_i) {
330 if (gs_i->is_point()) {
346 signed_distance = sp_point % modulus;
347 if (signed_distance == 0) {
349 return relation_with(expr == 0);
353 expr += signed_distance;
356 const bool positive = (signed_distance > 0);
357 const Constraint first_halfspace = positive ? (expr >= 0) : (expr <= 0);
373 const Constraint second_halfspace = positive ? (expr <= 0) : (expr >= 0);
389 if (marked_empty()) {
393 if (space_dim == 0) {
396 if (!has_pending_generators() && constraints_are_up_to_date()) {
399 if (!con_sys[i].is_tautological()) {
407 PPL_ASSERT(!has_pending_constraints() && generators_are_up_to_date());
414 switch (gen_sys[i].type()) {
426 if (has_pending_generators()) {
429 PPL_ASSERT(generators_are_minimized());
430 if (num_lines == space_dim) {
431 PPL_ASSERT(num_rays == 0);
434 PPL_ASSERT(num_lines < space_dim);
440 switch (gen_sys[i].type()) {
453 if (num_pending_rays == 0 && num_pending_lines == 0) {
458 if (num_lines + num_pending_lines < space_dim) {
460 = space_dim - (num_lines + num_pending_lines);
463 if (num_rays + num_pending_rays <= num_dims_missing) {
470 if (generators_are_minimized()) {
472 PPL_ASSERT(num_rays == 0 || num_lines < space_dim);
473 return num_lines == space_dim;
479 if (num_lines < space_dim && num_lines + num_rays <= space_dim) {
486 if (has_pending_generators()) {
487 process_pending_generators();
489 else if (!constraints_are_minimized()) {
492 if (is_necessarily_closed()) {
493 return con_sys.num_rows() == 1
494 && con_sys[0].is_inequality()
495 && con_sys[0].is_tautological();
499 if (con_sys.num_rows() != 2
500 || con_sys[0].is_equality()
501 || con_sys[1].is_equality()) {
510 obtain_sorted_constraints();
530 || (has_pending_constraints() && !process_pending_constraints())
531 || (!generators_are_up_to_date() && !update_generators())) {
538 if (gen_sys[i].is_line_or_ray()) {
551 if (is_necessarily_closed()) {
557 || (has_something_pending() && !process_pending())) {
562 PPL_ASSERT(!has_something_pending());
564 if (generators_are_minimized()) {
572 bool gen_sys_i_has_no_matching_point =
true;
578 gen_sys_i_has_no_matching_point =
false;
582 if (gen_sys_i_has_no_matching_point) {
593 strongly_minimize_constraints();
594 return marked_empty() || !con_sys.has_strict_inequalities();
600 if (marked_empty()) {
605 if (space_dim == 0) {
610 if (has_pending_constraints() && !process_pending()) {
617 PPL_ASSERT(!has_pending_constraints());
618 if (generators_are_up_to_date()) {
620 if (gen_sys[i].is_point() && gen_sys[i].divisor() == 1) {
626 #if 0 // TEMPORARILY DISABLED.
642 cs_end = cs.
end(); cs_i != cs_end; ++cs_i) {
651 if (homogeneous_gcd == 0) {
658 if (homogeneous_gcd != 1) {
659 le /= homogeneous_gcd;
663 gcd_assign(gcd, homogeneous_gcd, inhomogeneous);
664 if (gcd == homogeneous_gcd) {
667 mip.add_constraint(
le >= 0);
672 if (inhomogeneous == 0) {
674 mip.add_constraint(c);
681 if (homogeneous_gcd == 0) {
687 else if (homogeneous_gcd == 1) {
690 mip.add_constraint(c);
693 PPL_ASSERT(homogeneous_gcd > 1);
699 gcd_assign(gcd, homogeneous_gcd, inhomogeneous);
700 PPL_ASSERT(gcd == 1);
709 assign_r(rational_inhomogeneous.get_num(),
711 assign_r(rational_inhomogeneous.get_den(),
717 tightened_inhomogeneous *= homogeneous_gcd;
718 le += tightened_inhomogeneous;
719 mip.add_constraint(le >= 0);
724 #endif // TEMPORARY WORKAROUND.
725 return mip.is_satisfiable();
732 if (space_dim < var_space_dim) {
733 throw_dimension_incompatible(
"constrains(v)",
"v", var);
737 if (marked_empty()) {
741 if (generators_are_up_to_date() && !has_pending_constraints()) {
745 if (constraints_are_up_to_date() && !has_pending_generators()) {
748 goto syntactic_check;
750 if (generators_are_minimized()) {
758 if (gen_sys[i].is_line()) {
763 if (num_lines == space_dim) {
771 bool have_positive_ray =
false;
772 bool have_negative_ray =
false;
786 if (have_negative_ray) {
790 have_positive_ray =
true;
793 else if (have_positive_ray) {
797 have_negative_ray =
true;
808 if (has_pending_generators()) {
809 process_pending_generators();
811 else if (!constraints_are_up_to_date()) {
812 update_constraints();
814 goto syntactic_check;
824 if (con_sys[i].coefficient(var) != 0) {
839 if (con_sys.topology() != gen_sys.topology()) {
841 cerr <<
"Constraints and generators have different topologies!"
852 if (marked_empty()) {
853 if (check_not_empty) {
856 cerr <<
"Empty polyhedron!" << endl;
864 if (has_something_pending()) {
866 cerr <<
"The polyhedron is empty, "
867 <<
"but it has something pending" << endl;
871 if (con_sys.has_no_rows()) {
875 if (con_sys.space_dimension() != space_dim) {
877 cerr <<
"The polyhedron is in a space of dimension "
879 <<
" while the system of constraints is in a space of dimension "
880 << con_sys.space_dimension()
885 if (con_sys.num_rows() != 1) {
887 cerr <<
"The system of constraints for an empty polyhedron "
888 <<
"has more then one row"
893 if (!con_sys[0].is_inconsistent()) {
895 cerr <<
"Empty polyhedron with a satisfiable system of constraints"
908 if (space_dim == 0) {
909 if (has_something_pending()) {
911 cerr <<
"Zero-dimensional polyhedron with something pending"
916 if (!con_sys.has_no_rows() || !gen_sys.has_no_rows()) {
918 cerr <<
"Zero-dimensional polyhedron with a non-empty"
920 <<
"system of constraints or generators."
930 if (!constraints_are_up_to_date() && !generators_are_up_to_date()) {
932 cerr <<
"Polyhedron not empty, not zero-dimensional"
934 <<
"and with neither constraints nor generators up-to-date!"
946 if (constraints_are_up_to_date()) {
947 if (con_sys.space_dimension() != space_dim) {
949 cerr <<
"Incompatible size! (con_sys and space_dim)"
954 if (sat_c_is_up_to_date()) {
955 if (con_sys.first_pending_row() != sat_c.num_columns()) {
957 cerr <<
"Incompatible size! (con_sys and sat_c)"
963 if (sat_g_is_up_to_date()) {
964 if (con_sys.first_pending_row() != sat_g.num_rows()) {
966 cerr <<
"Incompatible size! (con_sys and sat_g)"
972 if (generators_are_up_to_date()) {
973 if (con_sys.space_dimension() != gen_sys.space_dimension()) {
975 cerr <<
"Incompatible size! (con_sys and gen_sys)"
983 if (generators_are_up_to_date()) {
984 if (gen_sys.space_dimension() != space_dim) {
986 cerr <<
"Incompatible size! (gen_sys and space_dim)"
991 if (sat_c_is_up_to_date()) {
992 if (gen_sys.first_pending_row() != sat_c.num_rows()) {
994 cerr <<
"Incompatible size! (gen_sys and sat_c)"
1000 if (sat_g_is_up_to_date()) {
1001 if (gen_sys.first_pending_row() != sat_g.num_columns()) {
1003 cerr <<
"Incompatible size! (gen_sys and sat_g)"
1009 if (gen_sys.first_pending_row() == 0) {
1011 cerr <<
"Up-to-date generator system with all rows pending!"
1019 if (!gen_sys.has_no_rows() && !gen_sys.has_points()) {
1021 cerr <<
"Non-empty generator system declared up-to-date "
1028 #if 0 // To be activated when Status keeps strong minimization flags.
1039 if (!is_necessarily_closed()) {
1044 if (!gen_sys[i].is_line_or_ray()) {
1045 if (gen_sys[i][eps_index] > 0) {
1049 ++num_closure_points;
1053 if (num_points > num_closure_points) {
1055 cerr <<
"# POINTS > # CLOSURE_POINTS" << endl;
1063 if (generators_are_minimized()) {
1071 - gen_sys.first_pending_row());
1075 minimize(
false, copy_of_gen_sys, new_con_sys, new_sat_c);
1078 || gs_without_pending.
num_lines() != copy_num_lines
1081 cerr <<
"Generators are declared minimized, but they are not!\n"
1082 <<
"Here is the minimized form of the generators:\n";
1102 if (copy_num_lines == 0) {
1107 if (copy_of_gen_sys != gs_without_pending) {
1109 cerr <<
"Generators are declared minimized, but they are not!\n"
1110 <<
"(we are in the case:\n"
1111 <<
"dimension of lineality space equal to 0)\n"
1112 <<
"Here is the minimized form of the generators:\n";
1122 if (constraints_are_up_to_date()) {
1123 if (con_sys.first_pending_row() == 0) {
1125 cerr <<
"Up-to-date constraint system with all rows pending!"
1137 bool no_positivity_constraint =
true;
1139 if (con_sys[i].inhomogeneous_term() != 0) {
1140 no_positivity_constraint =
false;
1144 if (no_positivity_constraint) {
1146 cerr <<
"Non-empty constraint system has no positivity constraint"
1152 if (!is_necessarily_closed()) {
1156 bool no_epsilon_geq_zero =
true;
1158 if (con_sys[i].epsilon_coefficient() > 0) {
1159 no_epsilon_geq_zero =
false;
1163 if (no_epsilon_geq_zero) {
1165 cerr <<
"Non-empty constraint system for NNC polyhedron "
1166 <<
"has no epsilon >= 0 constraint"
1175 - con_sys.first_pending_row());
1179 if (check_not_empty || constraints_are_minimized()) {
1182 empty = minimize(
true, copy_of_con_sys, new_gen_sys, new_sat_g);
1185 if (empty && check_not_empty) {
1187 cerr <<
"Unsatisfiable system of constraints!"
1193 if (constraints_are_minimized()) {
1202 cerr <<
"Constraints are declared minimized, but they are not!\n"
1203 <<
"Here is the minimized form of the constraints:\n";
1223 if (cs_without_pending != copy_of_con_sys) {
1225 cerr <<
"Constraints are declared minimized, but they are not!\n"
1226 <<
"Here is the minimized form of the constraints:\n";
1235 if (sat_c_is_up_to_date()) {
1238 const Bit_Row tmp_sat = sat_c[i];
1241 if (sat_j == tmp_sat[j]) {
1243 cerr <<
"sat_c is declared up-to-date, but it is not!"
1251 if (sat_g_is_up_to_date()) {
1254 const Bit_Row tmp_sat = sat_g[i];
1257 if (sat_j == tmp_sat[j]) {
1259 cerr <<
"sat_g is declared up-to-date, but it is not!"
1267 if (has_pending_constraints()) {
1268 if (con_sys.num_pending_rows() == 0) {
1270 cerr <<
"The polyhedron is declared to have pending constraints, "
1271 <<
"but con_sys has no pending rows!"
1278 if (has_pending_generators()) {
1279 if (gen_sys.num_pending_rows() == 0) {
1281 cerr <<
"The polyhedron is declared to have pending generators, "
1282 <<
"but gen_sys has no pending rows!"
1293 cerr <<
"Here is the guilty polyhedron:"
1313 throw_topology_incompatible(
"add_constraint(c)",
"c", c);
1319 throw_dimension_incompatible(
"add_constraint(c)",
"c", c);
1322 if (!marked_empty()) {
1333 throw_dimension_incompatible(
"add_congruence(cg)",
"cg", cg);
1346 throw_invalid_argument(
"add_congruence(cg)",
1347 "cg is a non-trivial, proper congruence");
1352 if (marked_empty()) {
1355 if (space_dim == 0) {
1372 throw_topology_incompatible(
"add_generator(g)",
"g", g);
1377 if (space_dim < g_space_dim) {
1378 throw_dimension_incompatible(
"add_generator(g)",
"g", g);
1381 if (space_dim == 0) {
1385 if (marked_empty()) {
1387 throw_invalid_generator(
"add_generator(g)",
"g");
1390 set_zero_dim_univ();
1393 PPL_ASSERT_HEAVY(OK());
1398 || (has_pending_constraints() && !process_pending_constraints())
1399 || (!generators_are_up_to_date() && !update_generators())) {
1403 throw_invalid_generator(
"add_generator(g)",
"g");
1409 gen_sys.adjust_topology_and_space_dimension(topology(), space_dim);
1410 if (!is_necessarily_closed()) {
1415 gen_sys.sys.rows.back().set_epsilon_coefficient(0);
1416 gen_sys.sys.rows.back().expr.normalize();
1417 PPL_ASSERT(gen_sys.sys.rows.back().OK());
1418 PPL_ASSERT(gen_sys.sys.OK());
1433 gen_sys.adjust_topology_and_space_dimension(topology(), space_dim);
1437 set_generators_minimized();
1440 PPL_ASSERT(generators_are_up_to_date());
1441 const bool has_pending = can_have_something_pending();
1446 gen_sys.insert_pending(g);
1451 if (!is_necessarily_closed() && g.
is_point()) {
1456 gen_sys.sys.rows.back().set_epsilon_coefficient(0);
1457 gen_sys.sys.rows.back().expr.normalize();
1458 PPL_ASSERT(gen_sys.sys.rows.back().OK());
1459 PPL_ASSERT(gen_sys.sys.OK());
1462 gen_sys.insert_pending(g);
1509 set_generators_pending();
1514 clear_generators_minimized();
1515 clear_constraints_up_to_date();
1518 PPL_ASSERT_HEAVY(OK());
1528 i_end = cs.
end(); i != i_end; ++i) {
1529 if (i->is_strict_inequality()
1530 && !i->is_inconsistent()) {
1531 throw_topology_incompatible(
"add_recycled_constraints(cs)",
1543 if (space_dim < cs_space_dim) {
1544 throw_dimension_incompatible(
"add_recycled_constraints(cs)",
"cs", cs);
1551 if (space_dim == 0) {
1565 if (marked_empty()) {
1570 if (has_pending_generators()) {
1571 process_pending_generators();
1573 else if (!constraints_are_up_to_date()) {
1574 update_constraints();
1581 const bool adding_pending = can_have_something_pending();
1585 if (adding_pending) {
1587 set_constraints_pending();
1592 clear_constraints_minimized();
1593 clear_generators_up_to_date();
1598 PPL_ASSERT_HEAVY(OK());
1605 add_recycled_constraints(cs_copy);
1612 throw_topology_incompatible(
"add_recycled_generators(gs)",
"gs", gs);
1617 if (space_dim < gs_space_dim) {
1618 throw_dimension_incompatible(
"add_recycled_generators(gs)",
"gs", gs);
1628 if (space_dim == 0) {
1630 throw_invalid_generators(
"add_recycled_generators(gs)",
"gs");
1632 set_zero_dim_univ();
1633 PPL_ASSERT_HEAVY(OK(
true));
1642 if (!is_necessarily_closed()) {
1647 if ((has_pending_constraints() && !process_pending_constraints())
1648 || (!generators_are_up_to_date() && !minimize())) {
1652 throw_invalid_generators(
"add_recycled_generators(gs)",
"gs");
1656 if (gen_sys.num_pending_rows() > 0) {
1661 gen_sys.sys.index_first_pending = gen_sys.num_rows();
1662 gen_sys.set_sorted(
false);
1664 set_generators_up_to_date();
1666 PPL_ASSERT_HEAVY(OK());
1670 if (can_have_something_pending()) {
1675 gs.
sys.rows[i].set_topology(topology());
1680 set_generators_pending();
1687 gs.
sys.rows[i].set_topology(topology());
1693 clear_constraints_up_to_date();
1694 clear_generators_minimized();
1696 PPL_ASSERT_HEAVY(OK(
true));
1703 add_recycled_generators(gs_copy);
1710 throw_dimension_incompatible(
"add_congruences(cgs)",
"cgs", cgs);
1714 bool inserted =
false;
1716 cgs_end = cgs.
end(); i != cgs_end; ++i) {
1733 throw_invalid_argument(
"add_congruences(cgs)",
1734 "cgs has a non-trivial, proper congruence");
1740 add_recycled_constraints(cs);
1748 throw_dimension_incompatible(
"refine_with_constraint(c)",
"c", c);
1751 if (!marked_empty()) {
1760 throw_dimension_incompatible(
"refine_with_congruence(cg)",
"cg", cg);
1764 if (marked_empty()) {
1769 if (space_dim == 0) {
1789 if (space_dim < cs_space_dim) {
1790 throw_dimension_incompatible(
"refine_with_constraints(cs)a",
1798 if (space_dim == 0) {
1812 if (marked_empty()) {
1817 if (has_pending_generators()) {
1818 process_pending_generators();
1820 else if (!constraints_are_up_to_date()) {
1821 update_constraints();
1824 const bool adding_pending = can_have_something_pending();
1831 if (adding_pending) {
1846 if (adding_pending) {
1847 con_sys.insert_pending(nc_expr == 0);
1850 con_sys.insert(nc_expr == 0);
1854 if (adding_pending) {
1855 con_sys.insert_pending(nc_expr >= 0);
1858 con_sys.insert(nc_expr >= 0);
1864 if (adding_pending) {
1865 set_constraints_pending();
1869 clear_constraints_minimized();
1870 clear_generators_up_to_date();
1875 PPL_ASSERT_HEAVY(OK());
1882 throw_dimension_incompatible(
"refine_with_congruences(cgs)",
"cgs", cgs);
1886 bool inserted =
false;
1888 cgs_end = cgs.
end(); i != cgs_end; ++i) {
1889 if (i->is_equality()) {
1897 else if (i->is_inconsistent()) {
1905 add_recycled_constraints(cs);
1913 throw_dimension_incompatible(
"unconstrain(var)", var.
space_dimension());
1917 || (has_pending_constraints() && !process_pending_constraints())
1918 || (!generators_are_up_to_date() && !update_generators())) {
1923 PPL_ASSERT(generators_are_up_to_date());
1926 if (can_have_something_pending()) {
1928 set_generators_pending();
1934 clear_generators_minimized();
1935 clear_constraints_up_to_date();
1937 PPL_ASSERT_HEAVY(OK(
true));
1950 if (space_dim < min_space_dim) {
1951 throw_dimension_incompatible(
"unconstrain(vs)", min_space_dim);
1956 || (has_pending_constraints() && !process_pending_constraints())
1957 || (!generators_are_up_to_date() && !update_generators())) {
1962 PPL_ASSERT(generators_are_up_to_date());
1965 Variables_Set::const_iterator vsi = vars.begin();
1966 Variables_Set::const_iterator vsi_end = vars.end();
1967 if (can_have_something_pending()) {
1968 for ( ; vsi != vsi_end; ++vsi) {
1971 set_generators_pending();
1974 for ( ; vsi != vsi_end; ++vsi) {
1979 clear_generators_minimized();
1980 clear_constraints_up_to_date();
1982 PPL_ASSERT_HEAVY(OK(
true));
1990 throw_topology_incompatible(
"intersection_assign(y)",
"y", y);
1994 throw_dimension_incompatible(
"intersection_assign(y)",
"y", y);
2055 PPL_ASSERT_HEAVY(x.
OK() && y.
OK());
2060 struct Ruled_Out_Pair {
2065 struct Ruled_Out_Less_Than {
2066 bool operator()(
const Ruled_Out_Pair& x,
2067 const Ruled_Out_Pair& y)
const {
2068 return x.num_ruled_out > y.num_ruled_out;
2080 drop_redundant_inequalities(std::vector<const PPL::Constraint*>& ineqs_p,
2086 PPL_ASSERT(num_rows > 0);
2089 PPL_ASSERT(space_dim > 0 && space_dim >= rank);
2097 if (sat[i].
empty()) {
2102 const dimension_type num_sat = num_cols_sat - sat[i].count_ones();
2103 if (num_sat < min_sat) {
2112 if (ineqs_p[i] != 0) {
2115 if (ineqs_p[j] != 0 && i != j
2116 && subset_or_equal(sat[j], sat[i], strict_subset)) {
2117 if (strict_subset) {
2133 template <
typename Linear_System1,
typename Row2>
2138 PPL_ASSERT(eq.is_line_or_equality());
2142 if (rank == eq_sys_num_rows) {
2148 PPL_ASSERT(rank == eq_sys_num_rows - 1);
2149 eq_sys.remove_trailing_rows(1);
2159 throw_topology_incompatible(
"simplify_using_context_assign(y)",
"y", y);
2163 throw_dimension_incompatible(
"simplify_using_context_assign(y)",
"y", y);
2196 switch (y_con_sys_i.
type()) {
2198 ph.refine_no_check(
le == 1);
2201 ph.refine_no_check(
le <= -1);
2204 ph.refine_no_check(
le == 0);
2208 PPL_ASSERT_HEAVY(OK());
2227 std::vector<bool> redundant_by_y(x_cs_num_rows,
false);
2231 redundant_by_y[i] =
true;
2232 ++num_redundant_by_y;
2238 if (num_redundant_by_y < x_cs_num_rows) {
2243 const bool x_first = (x_cs_num_rows > y_cs_num_rows);
2252 if (!redundant_by_y[i]) {
2293 std::vector<Ruled_Out_Pair>
2294 ruled_out_vec(x_cs_num_rows - num_redundant_by_y);
2296 if (!redundant_by_y[i]) {
2301 y_gs_end = y_gs.
end(); k != y_gs_end; ++k) {
2303 const int sp_sign = sps(g, c);
2379 ++num_ruled_out_generators;
2381 ruled_out_vec[j].constraint_index = i;
2382 ruled_out_vec[j].num_ruled_out = num_ruled_out_generators;
2386 std::sort(ruled_out_vec.begin(), ruled_out_vec.end(),
2387 Ruled_Out_Less_Than());
2389 for (std::vector<Ruled_Out_Pair>::const_iterator
2390 j = ruled_out_vec.begin(),
2391 ruled_out_vec_end = ruled_out_vec.end();
2392 j != ruled_out_vec_end;
2404 const_cast<Constraint&
>(
c).mark_as_necessarily_closed();
2407 const_cast<Constraint&
>(
c).mark_as_not_necessarily_closed();
2410 const_cast<Constraint&
>(
c).mark_as_not_necessarily_closed();
2438 PPL_ASSERT_HEAVY(x.
OK());
2456 while (x_cs[x_cs_num_eq].is_equality()) {
2460 while (y_cs[y_cs_num_eq].is_equality()) {
2464 while (z_cs[z_cs_num_eq].is_equality()) {
2467 PPL_ASSERT(x_cs_num_eq <= z_cs_num_eq && y_cs_num_eq <= z_cs_num_eq);
2472 const dimension_type needed_non_redundant_eq = z_cs_num_eq - y_cs_num_eq;
2474 if (needed_non_redundant_eq > 0) {
2483 if (add_to_system_and_check_independence(eqs, x_cs_i)) {
2485 non_redundant_eq.
insert(x_cs_i);
2486 ++num_non_redundant_eq;
2487 if (num_non_redundant_eq == needed_non_redundant_eq) {
2497 PPL_ASSERT(eqs.num_rows() <= z_cs_num_eq);
2498 PPL_ASSERT(num_non_redundant_eq <= needed_non_redundant_eq);
2499 PPL_ASSERT(z_cs_num_eq - eqs.num_rows()
2500 == needed_non_redundant_eq - num_non_redundant_eq);
2505 std::vector<const Constraint*> non_redundant_ineq_p;
2509 non_redundant_ineq_p.push_back(&y_cs[i]);
2513 if (!redundant_by_y[i]) {
2514 non_redundant_ineq_p.push_back(&x_cs[i]);
2518 = non_redundant_ineq_p.size();
2519 const dimension_type y_cs_num_ineq = y_cs_num_rows - y_cs_num_eq;
2525 const Constraint& non_redundant_ineq_i = *(non_redundant_ineq_p[i]);
2532 if (sat_i.
empty() && num_non_redundant_eq < needed_non_redundant_eq) {
2536 PPL_ASSERT(i >= y_cs_num_ineq);
2541 if (add_to_system_and_check_independence(eqs, masked_eq)) {
2543 non_redundant_eq.
insert(non_redundant_ineq_i);
2544 ++num_non_redundant_eq;
2549 PPL_ASSERT(num_non_redundant_eq == needed_non_redundant_eq);
2551 drop_redundant_inequalities(non_redundant_ineq_p, x.
topology(),
2555 swap(result_cs, non_redundant_eq);
2559 i < non_redundant_ineq_p_size;
2561 if (non_redundant_ineq_p[i] != 0) {
2562 result_cs.
insert(*non_redundant_ineq_p[i]);
2571 PPL_ASSERT_HEAVY(x.
OK());
2580 throw_topology_incompatible(
"poly_hull_assign(y)",
"y", y);
2584 throw_dimension_incompatible(
"poly_hull_assign(y)",
"y", y);
2644 PPL_ASSERT_HEAVY(x.
OK(
true) && y.
OK(
true));
2652 throw_topology_incompatible(
"poly_difference_assign(y)",
"y", y);
2656 throw_dimension_incompatible(
"poly_difference_assign(y)",
"y", y);
2695 y_cs_end = y_cs.
end(); i != y_cs_end; ++i) {
2712 if (is_necessarily_closed()) {
2723 if (is_necessarily_closed()) {
2738 *
this = new_polyhedron;
2740 PPL_ASSERT_HEAVY(OK());
2747 Coefficient_traits::const_reference denominator) {
2749 if (denominator == 0) {
2750 throw_invalid_argument(
"affine_image(v, e, d)",
"d == 0");
2756 throw_dimension_incompatible(
"affine_image(v, e, d)",
"e", expr);
2760 if (space_dim < var_space_dim) {
2761 throw_dimension_incompatible(
"affine_image(v, e, d)",
"v", var);
2763 if (marked_empty()) {
2771 if (generators_are_up_to_date()) {
2774 if (denominator > 0) {
2775 gen_sys.affine_image(var, expr, denominator);
2778 gen_sys.affine_image(var, -expr, -denominator);
2781 if (constraints_are_up_to_date()) {
2786 Coefficient_traits::const_reference
c = expr.
coefficient(var);
2790 con_sys.affine_preimage(var, inverse, c);
2798 con_sys.affine_preimage(var, inverse, -c);
2805 if (has_something_pending()) {
2806 remove_pending_to_obtain_generators();
2808 else if (!generators_are_up_to_date()) {
2811 if (!marked_empty()) {
2814 if (denominator > 0) {
2815 gen_sys.affine_image(var, expr, denominator);
2818 gen_sys.affine_image(var, -expr, -denominator);
2821 clear_constraints_up_to_date();
2822 clear_generators_minimized();
2823 clear_sat_c_up_to_date();
2824 clear_sat_g_up_to_date();
2827 PPL_ASSERT_HEAVY(OK());
2835 Coefficient_traits::const_reference denominator) {
2837 if (denominator == 0) {
2838 throw_invalid_argument(
"affine_preimage(v, e, d)",
"d == 0");
2845 throw_dimension_incompatible(
"affine_preimage(v, e, d)",
"e", expr);
2849 if (space_dim < var_space_dim) {
2850 throw_dimension_incompatible(
"affine_preimage(v, e, d)",
"v", var);
2853 if (marked_empty()) {
2860 if (constraints_are_up_to_date()) {
2863 if (denominator > 0) {
2864 con_sys.affine_preimage(var, expr, denominator);
2867 con_sys.affine_preimage(var, -expr, -denominator);
2870 if (generators_are_up_to_date()) {
2875 Coefficient_traits::const_reference
c = expr.
coefficient(var);
2879 gen_sys.affine_image(var, inverse, c);
2887 gen_sys.affine_image(var, inverse, -c);
2894 if (has_something_pending()) {
2895 remove_pending_to_obtain_constraints();
2897 else if (!constraints_are_up_to_date()) {
2902 if (denominator > 0) {
2903 con_sys.affine_preimage(var, expr, denominator);
2906 con_sys.affine_preimage(var, -expr, -denominator);
2909 clear_generators_up_to_date();
2910 clear_constraints_minimized();
2911 clear_sat_c_up_to_date();
2912 clear_sat_g_up_to_date();
2914 PPL_ASSERT_HEAVY(OK());
2922 Coefficient_traits::const_reference denominator) {
2924 if (denominator == 0) {
2925 throw_invalid_argument(
"bounded_affine_image(v, lb, ub, d)",
"d == 0");
2931 if (space_dim < var_space_dim) {
2932 throw_dimension_incompatible(
"bounded_affine_image(v, lb, ub, d)",
2938 if (space_dim < lb_space_dim) {
2939 throw_dimension_incompatible(
"bounded_affine_image(v, lb, ub, d)",
2943 if (space_dim < ub_space_dim) {
2944 throw_dimension_incompatible(
"bounded_affine_image(v, lb, ub, d)",
2949 if (marked_empty()) {
2956 generalized_affine_image(var,
2960 if (denominator > 0) {
2961 refine_no_check(lb_expr <= denominator*var);
2964 refine_no_check(denominator*var <= lb_expr);
2969 generalized_affine_image(var,
2973 if (denominator > 0) {
2974 refine_no_check(denominator*var <= ub_expr);
2977 refine_no_check(ub_expr <= denominator*var);
2984 add_space_dimensions_and_embed(1);
2986 refine_no_check(denominator*new_var == ub_expr);
2988 generalized_affine_image(var,
2992 if (!marked_empty()) {
2994 refine_no_check(new_var >= var);
2997 remove_higher_space_dimensions(space_dim-1);
2999 PPL_ASSERT_HEAVY(OK());
3007 Coefficient_traits::const_reference denominator) {
3009 if (denominator == 0) {
3010 throw_invalid_argument(
"bounded_affine_preimage(v, lb, ub, d)",
"d == 0");
3016 if (space_dim < var_space_dim) {
3017 throw_dimension_incompatible(
"bounded_affine_preimage(v, lb, ub, d)",
3023 if (space_dim < lb_space_dim) {
3024 throw_dimension_incompatible(
"bounded_affine_preimage(v, lb, ub, d)",
3028 if (space_dim < ub_space_dim) {
3029 throw_dimension_incompatible(
"bounded_affine_preimage(v, lb, ub, d)",
3034 if (marked_empty()) {
3040 if (denominator > 0) {
3041 refine_no_check(lb_expr <= denominator*var);
3042 refine_no_check(denominator*var <= ub_expr);
3045 refine_no_check(ub_expr <= denominator*var);
3046 refine_no_check(denominator*var <= lb_expr);
3054 add_space_dimensions_and_embed(1);
3057 if (constraints_are_up_to_date()) {
3058 con_sys.swap_space_dimensions(var, new_var);
3060 if (generators_are_up_to_date()) {
3061 gen_sys.swap_space_dimensions(var, new_var);
3066 if (denominator > 0) {
3067 refine_no_check(lb_expr <= denominator*new_var);
3068 refine_no_check(denominator*new_var <= ub_expr);
3071 refine_no_check(ub_expr <= denominator*new_var);
3072 refine_no_check(denominator*new_var <= lb_expr);
3075 remove_higher_space_dimensions(space_dim-1);
3077 PPL_ASSERT_HEAVY(OK());
3085 Coefficient_traits::const_reference denominator) {
3087 if (denominator == 0) {
3088 throw_invalid_argument(
"generalized_affine_image(v, r, e, d)",
"d == 0");
3095 throw_dimension_incompatible(
"generalized_affine_image(v, r, e, d)",
3100 if (space_dim < var_space_dim) {
3101 throw_dimension_incompatible(
"generalized_affine_image(v, r, e, d)",
3106 if (is_necessarily_closed()
3108 throw_invalid_argument(
"generalized_affine_image(v, r, e, d)",
3109 "r is a strict relation symbol");
3113 throw_invalid_argument(
"generalized_affine_image(v, r, e, d)",
3114 "r is the disequality relation symbol");
3118 affine_image(var, expr, denominator);
3120 if (relsym ==
EQUAL) {
3132 add_generator(ray(-var));
3135 add_generator(ray(var));
3142 PPL_ASSERT(!is_necessarily_closed());
3145 add_generator(ray((relsym ==
GREATER_THAN) ? var : -var));
3154 const Generator& gen_i = gen_sys.sys.rows[i];
3158 gen_sys.sys.rows.push_back(
Generator(gen_i));
3160 Generator& old_gen = gen_sys.sys.rows[i];
3161 Generator& new_gen = gen_sys.sys.rows.back();
3165 PPL_ASSERT(old_gen.
OK());
3168 new_gen.
expr += var;
3171 new_gen.
expr -= var;
3174 PPL_ASSERT(new_gen.
OK());
3178 gen_sys.set_sorted(
false);
3179 gen_sys.unset_pending_rows();
3180 PPL_ASSERT(gen_sys.sys.OK());
3182 clear_constraints_up_to_date();
3183 clear_generators_minimized();
3184 clear_sat_c_up_to_date();
3185 clear_sat_g_up_to_date();
3193 PPL_ASSERT_HEAVY(OK());
3201 Coefficient_traits::const_reference denominator) {
3203 if (denominator == 0) {
3204 throw_invalid_argument(
"generalized_affine_preimage(v, r, e, d)",
3212 throw_dimension_incompatible(
"generalized_affine_preimage(v, r, e, d)",
3217 if (space_dim < var_space_dim) {
3218 throw_dimension_incompatible(
"generalized_affine_preimage(v, r, e, d)",
3223 if (is_necessarily_closed()
3225 throw_invalid_argument(
"generalized_affine_preimage(v, r, e, d)",
3226 "r is a strict relation symbol");
3230 throw_invalid_argument(
"generalized_affine_preimage(v, r, e, d)",
3231 "r is the disequality relation symbol");
3235 if (relsym ==
EQUAL) {
3236 affine_preimage(var, expr, denominator);
3264 if (var_coefficient != 0) {
3266 = expr - (denominator + var_coefficient) * var;
3268 neg_assign(inverse_denominator, var_coefficient);
3270 = (
sgn(denominator) ==
sgn(inverse_denominator))
3271 ? relsym : reversed_relsym;
3272 generalized_affine_image(var, inverse_relsym, inverse_expr,
3273 inverse_denominator);
3282 = (denominator > 0) ? relsym : reversed_relsym;
3283 switch (corrected_relsym) {
3285 refine_no_check(denominator*var < expr);
3288 refine_no_check(denominator*var <= expr);
3291 refine_no_check(denominator*var >= expr);
3294 refine_no_check(denominator*var > expr);
3302 PPL_ASSERT_HEAVY(OK());
3313 if (space_dim < lhs_space_dim) {
3314 throw_dimension_incompatible(
"generalized_affine_image(e1, r, e2)",
3320 if (space_dim < rhs_space_dim) {
3321 throw_dimension_incompatible(
"generalized_affine_image(e1, r, e2)",
3326 if (is_necessarily_closed()
3328 throw_invalid_argument(
"generalized_affine_image(e1, r, e2)",
3329 "r is a strict relation symbol");
3333 throw_invalid_argument(
"generalized_affine_image(e1, r, e2)",
3334 "r is the disequality relation symbol");
3337 if (marked_empty()) {
3347 if (lhs_space_dim == 0) {
3350 refine_no_check(lhs < rhs);
3353 refine_no_check(lhs <= rhs);
3356 refine_no_check(lhs == rhs);
3359 refine_no_check(lhs >= rhs);
3362 refine_no_check(lhs > rhs);
3378 i = lhs.
begin(), i_end = lhs.
end(); i != i_end; ++i) {
3379 new_lines.
insert(line(i.variable()));
3388 add_space_dimensions_and_embed(1);
3392 refine_no_check(new_var == rhs);
3395 add_recycled_generators(new_lines);
3402 refine_no_check(lhs < new_var);
3405 refine_no_check(lhs <= new_var);
3408 refine_no_check(lhs == new_var);
3411 refine_no_check(lhs >= new_var);
3414 refine_no_check(lhs > new_var);
3423 remove_higher_space_dimensions(space_dim-1);
3436 add_recycled_generators(new_lines);
3442 refine_no_check(lhs < rhs);
3445 refine_no_check(lhs <= rhs);
3448 refine_no_check(lhs == rhs);
3451 refine_no_check(lhs >= rhs);
3454 refine_no_check(lhs > rhs);
3462 PPL_ASSERT_HEAVY(OK());
3473 if (space_dim < lhs_space_dim) {
3474 throw_dimension_incompatible(
"generalized_affine_preimage(e1, r, e2)",
3480 if (space_dim < rhs_space_dim) {
3481 throw_dimension_incompatible(
"generalized_affine_preimage(e1, r, e2)",
3486 if (is_necessarily_closed()
3488 throw_invalid_argument(
"generalized_affine_preimage(e1, r, e2)",
3489 "r is a strict relation symbol");
3493 throw_invalid_argument(
"generalized_affine_preimage(e1, r, e2)",
3494 "r is the disequality relation symbol");
3497 if (marked_empty()) {
3507 if (lhs_space_dim == 0) {
3508 generalized_affine_image(lhs, relsym, rhs);
3518 i = lhs.
begin(), i_end = lhs.
end(); i != i_end; ++i) {
3519 new_lines.
insert(line(i.variable()));
3528 add_space_dimensions_and_embed(1);
3532 refine_no_check(new_var == lhs);
3535 add_recycled_generators(new_lines);
3541 refine_no_check(new_var < rhs);
3544 refine_no_check(new_var <= rhs);
3547 refine_no_check(new_var == rhs);
3550 refine_no_check(new_var >= rhs);
3553 refine_no_check(new_var > rhs);
3562 remove_higher_space_dimensions(space_dim-1);
3572 refine_no_check(lhs < rhs);
3575 refine_no_check(lhs <= rhs);
3578 refine_no_check(lhs == rhs);
3581 refine_no_check(lhs >= rhs);
3584 refine_no_check(lhs > rhs);
3597 add_recycled_generators(new_lines);
3599 PPL_ASSERT_HEAVY(OK());
3607 throw_topology_incompatible(
"time_elapse_assign(y)",
"y", y);
3611 throw_dimension_incompatible(
"time_elapse_assign(y)",
"y", y);
3647 swap(g, gs.
sys.rows[gs_num_rows]);
3654 swap(g, gs.
sys.rows[gs_num_rows]);
3676 if (gs[i].is_point()) {
3681 swap(p, gs.
sys.rows[gs_num_rows]);
3698 gs.
sys.rows.resize(gs_num_rows);
3701 PPL_ASSERT(gs.
sys.OK());
3707 if (gs_num_rows == 0) {
3728 PPL_ASSERT_HEAVY(x.
OK(
true) && y.
OK(
true));
3737 throw_dimension_incompatible(
"frequency(e, ...)",
"e", expr);
3746 if (space_dim == 0) {
3759 || (has_pending_constraints() && !process_pending_constraints())
3760 || (!generators_are_up_to_date() && !update_generators())) {
3770 bool first_candidate =
true;
3775 const Generator& gen_sys_i = gen_sys[i];
3779 const int sp_sign =
sgn(sp);
3792 candidate.canonicalize();
3793 if (first_candidate) {
3795 first_candidate =
false;
3798 else if (candidate !=
value) {
3808 val_n = value.get_num();
3809 val_d = value.get_den();
3819 if (is_necessarily_closed()) {
3823 if (marked_empty() || space_dim == 0) {
3833 if (has_pending_constraints() && !process_pending_constraints()) {
3839 if (!has_pending_generators() && constraints_are_up_to_date()) {
3840 bool changed =
false;
3854 PPL_ASSERT(con_sys.sys.OK());
3858 con_sys.set_sorted(
false);
3862 clear_generators_up_to_date();
3863 clear_constraints_minimized();
3868 PPL_ASSERT(generators_are_up_to_date());
3870 gen_sys.add_corresponding_points();
3871 if (can_have_something_pending()) {
3872 set_generators_pending();
3877 gen_sys.unset_pending_rows();
3878 gen_sys.set_sorted(
false);
3880 clear_constraints_up_to_date();
3881 clear_generators_minimized();
3884 PPL_ASSERT_HEAVY(OK());
3932 throw_topology_incompatible(
"contains(y)",
"y", y);
3937 throw_dimension_incompatible(
"contains(y)",
"y", y);
3966 s <<
"space_dim " << space_dim <<
"\n";
3967 status.ascii_dump(s);
3969 << (constraints_are_up_to_date() ?
"" :
"not_")
3972 con_sys.ascii_dump(s);
3974 << (generators_are_up_to_date() ?
"" :
"not_")
3977 gen_sys.ascii_dump(s);
3979 sat_c.ascii_dump(s);
3981 sat_g.ascii_dump(s);
3991 if (!(s >> str) || str !=
"space_dim") {
3995 if (!(s >> space_dim)) {
3999 if (!status.ascii_load(s)) {
4003 if (!(s >> str) || str !=
"con_sys") {
4007 if (!(s >> str) || (str !=
"(not_up-to-date)" && str !=
"(up-to-date)")) {
4011 if (!con_sys.ascii_load(s)) {
4015 if (!(s >> str) || str !=
"gen_sys") {
4019 if (!(s >> str) || (str !=
"(not_up-to-date)" && str !=
"(up-to-date)")) {
4023 if (!gen_sys.ascii_load(s)) {
4027 if (!(s >> str) || str !=
"sat_c") {
4031 if (!sat_c.ascii_load(s)) {
4035 if (!(s >> str) || str !=
"sat_g") {
4039 if (!sat_g.ascii_load(s)) {
4044 PPL_ASSERT_HEAVY(OK());
4051 con_sys.external_memory_in_bytes()
4052 + gen_sys.external_memory_in_bytes()
4053 + sat_c.external_memory_in_bytes()
4054 + sat_g.external_memory_in_bytes();
4063 unsigned complexity_threshold,
4064 bool wrap_individually) {
4065 if (is_necessarily_closed()) {
4067 vars, w, r, o, cs_p,
4068 complexity_threshold, wrap_individually,
4073 vars, w, r, o, cs_p,
4074 complexity_threshold, wrap_individually,
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.
void topological_closure_assign()
Assigns to *this its topological closure.
void refine_with_congruence(const Congruence &cg)
Uses a copy of congruence cg to refine *this.
Enable_If< Is_Native_Or_Checked< To >::value &&Is_Special< From >::value, Result >::type assign_r(To &to, const From &, Rounding_Dir dir)
Scalar product sign function object depending on topology.
An iterator over a system of constraints.
bool is_tautological() const
Returns true if and only if *this is a tautology (i.e., an always true constraint).
dimension_type space_dimension() const
Returns the dimension of the smallest vector space enclosing all the variables whose indexes are in t...
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 merge_rows_assign(const Generator_System &y)
Assigns to *this the result of merging its rows with those of y, obtaining a sorted system...
Coefficient_traits::const_reference modulus() const
Returns a const reference to the modulus of *this.
A linear equality or inequality.
const_iterator begin() const
bool is_equality() const
Returns true if and only if *this is an equality constraint.
void swap(CO_Tree &x, CO_Tree &y)
void clear_constraints_up_to_date()
Sets status to express that constraints are no longer up-to-date.
void affine_preimage(Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the affine preimage of *this under the function mapping variable var to the affine e...
static const Generator_System & zero_dim_univ()
Returns the singleton system containing only Generator::zero_dim_point().
void insert_pending(const Constraint &c)
Inserts in *this a copy of the constraint c, increasing the number of space dimensions if needed...
An iterator over a system of generators.
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...
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.
bool is_necessarily_closed() const
Returns true if and only if the topology of *this row is necessarily closed.
An std::set of variables' indexes.
bool constrains(Variable var) const
Returns true if and only if var is constrained in *this.
void poly_difference_assign(const Polyhedron &y)
Assigns to *this the poly-difference of *this and y.
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.
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 simplify()
Applies Gaussian elimination and back-substitution so as to provide a partial simplification of the s...
void set_constraints_pending()
Sets status to express that constraints are pending.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void remove_trailing_rows(dimension_type n)
Makes the system shrink by removing its n trailing rows.
void merge_rows_assign(const Constraint_System &y)
Assigns to *this the result of merging its rows with those of y, obtaining a sorted system...
bool is_inconsistent() const
Returns true if and only if *this is inconsistent (i.e., an always false congruence).
Enable_If< Is_Native_Or_Checked< T >::value, void >::type ascii_dump(std::ostream &s, const T &t)
void add_congruences(const Congruence_System &cgs)
Adds a copy of the congruences in cgs to *this, if all the congruences can be exactly represented by ...
void add_constraint(const Constraint &c)
Adds a copy of constraint c to the system of constraints of *this (without minimizing the result)...
static Generator ray(const Linear_Expression &e, Representation r=default_representation)
Returns the ray of direction e.
void bounded_affine_image(Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the image of *this with respect to the bounded affine relation . ...
void affine_image(Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the affine image of *this under the function mapping variable var to the affine expr...
std::ostream & operator<<(std::ostream &s, const Ask_Tell< D > &x)
static const Constraint_System & zero_dim_empty()
Returns the singleton system containing only Constraint::zero_dim_false().
bool contains_integer_point() const
Returns true if and only if *this contains at least one integer point.
void insert(const Constraint &c)
Inserts in *this a copy of the constraint c, increasing the number of space dimensions if needed...
bool is_disjoint_from(const Polyhedron &y) const
Returns true if and only if *this and y are disjoint.
const_iterator end() const
Returns the past-the-end const_iterator.
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 update_generators() const
Updates generators starting from constraints and minimizes them.
void set(unsigned long k)
Sets the bit in position k.
The standard C++ namespace.
expr_type expression() const
Partial read access to the (adapted) internal expression.
dimension_type last_nonzero() const
expr_type expression() const
Partial read access to the (adapted) internal expression.
static bool add_to_system_and_check_independence(Linear_System1 &eq_sys, const Row2 &eq)
bool is_sorted() const
Returns the value of the sortedness flag.
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 set_coefficient(Variable v, Coefficient_traits::const_reference n)
Sets the coefficient of v in *this to n.
static Poly_Con_Relation saturates()
The polyhedron is included in the set of points saturating the constraint.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
bool is_topologically_closed() const
Returns true if and only if *this is a topologically closed subset of the vector space.
void set_inhomogeneous_term(Coefficient_traits::const_reference n)
Sets the inhomogeneous term of *this to n.
A row in a matrix of bits.
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...
void add_constraint(const Constraint &c)
Adds a copy of constraint c to the MIP problem.
const_iterator begin() const
Returns the const_iterator pointing to the first constraint, if *this is not empty; otherwise...
void bounded_affine_preimage(Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the preimage of *this with respect to the bounded affine relation ...
bool is_matching_closure_point(const Generator &p) const
Returns true if and only if the closure point *this has the same coordinates of the point p...
bool is_sorted() const
Returns the value of the sortedness flag.
Coefficient_traits::const_reference coefficient(Variable v) const
Returns the coefficient of v in *this.
bool frequency(const Linear_Expression &expr, Coefficient &freq_n, Coefficient &freq_d, Coefficient &val_n, Coefficient &val_d) const
Returns true if and only if there exist a unique value val such that *this saturates the equality exp...
void add_recycled_constraints(Constraint_System &cs)
Adds the constraints in cs to the system of constraints of *this (without minimizing the result)...
dimension_type id() const
Returns the index of the Cartesian axis associated to the variable.
static Generator line(const Linear_Expression &e, Representation r=default_representation)
Returns the line of direction e.
bool is_proper_congruence() const
Returns true if the modulus is greater than zero.
bool can_have_something_pending() const
Returns true if the polyhedron can have something pending.
void refine_with_constraint(const Constraint &c)
Uses a copy of constraint c to refine *this.
A dimension of the vector space.
Bounded_Integer_Type_Overflow
bool have_a_common_variable(const Linear_Expression &x, Variable first, Variable last) const
Returns true if there is a variable from index first (included) to index last (excluded) whose coeffi...
Rounding_Dir inverse(Rounding_Dir dir)
bool is_strict_inequality() const
Returns true if and only if *this is a strict inequality constraint.
The base class for convex polyhedra.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool is_inequality() const
Returns true if and only if *this is an inequality constraint (either strict or non-strict).
bool satisfied_by_all_generators(const Constraint &c) const
Returns true if all the generators satisfy c.
void add_recycled_generators(Generator_System &gs)
Adds the generators in gs to the system of generators of *this (without minimizing the result)...
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.
bool is_canonical(const mpq_class &x)
Returns true if and only if x is in canonical form.
void clear()
Removes all the generators from the generator system and sets its space dimension to 0...
void add_generators(const Generator_System &gs)
Adds a copy of the generators in gs to the system of generators of *this (without minimizing the resu...
Constraint_System con_sys
The system of constraints.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
static void finalize()
Finalizes the class.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
dimension_type num_equalities() const
Returns the number of equality constraints.
bool is_universe() const
Returns true if and only if *this is a universe polyhedron.
Relation_Symbol
Relation symbols.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool is_equality() const
Returns true if *this is an equality.
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.
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.
The problem is unfeasible.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
Greater than or equal to.
Bounded_Integer_Type_Width
void wrap_assign(const Variables_Set &vars, Bounded_Integer_Type_Width w, Bounded_Integer_Type_Representation r, Bounded_Integer_Type_Overflow o, const Constraint_System *cs_p=0, unsigned complexity_threshold=16, bool wrap_individually=true)
Wraps the specified dimensions of the vector space.
const_iterator end() const
Returns the past-the-end const_iterator.
void optimal_value(Coefficient &numer, Coefficient &denom) const
Sets numer and denom so that is the solution of the optimization problem.
void refine_with_constraints(const Constraint_System &cs)
Uses a copy of the constraints in cs to refine *this.
void insert_pending(const Generator_System &r)
Adds a copy of the rows of `y' to the pending part of `*this'.
A Mixed Integer (linear) Programming problem.
const Generator_System & generators() const
Returns the system of generators.
bool eq(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
bool is_inconsistent() const
Returns true if and only if *this is inconsistent (i.e., an always false constraint).
const Generator_System & minimized_generators() const
Returns the system of generators, with no redundant generator.
bool empty() const
Returns true if no bit is set in the row.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
void intersection_assign(const Polyhedron &y)
Assigns to *this the intersection of *this and y.
const_iterator begin() const
Returns the const_iterator pointing to the first congruence, if this is not empty; otherwise...
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.
bool is_tautological() const
Returns true if and only if *this is a tautology (i.e., an always true congruence).
void process_pending_generators() const
Processes the pending generators and obtains a minimized polyhedron.
void wrap_assign(PSET &pointset, const Variables_Set &vars, const Bounded_Integer_Type_Width w, const Bounded_Integer_Type_Representation r, const Bounded_Integer_Type_Overflow o, const Constraint_System *cs_p, const unsigned complexity_threshold, const bool wrap_individually, const char *class_name)
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.
dimension_type num_rays() const
Returns the number of rays of the system.
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 sort_rows()
Sorts the non-pending rows (in growing order) and eliminates duplicated ones.
The universe element, i.e., the whole vector space.
void add_constraints(const Constraint_System &cs)
Adds a copy of the constraints in cs to the system of constraints of *this (without minimizing the re...
static Generator point(const Linear_Expression &e=Linear_Expression::zero(), Coefficient_traits::const_reference d=Coefficient_one(), Representation r=default_representation)
Returns the point at e / d.
dimension_type num_columns() const
Returns the number of columns of *this.
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 neg_assign(GMP_Integer &x)
void set_empty()
Sets status to express that the polyhedron is empty, clearing all corresponding matrices.
#define PPL_OUTPUT_DEFINITIONS(class_name)
The entire library is confined to this namespace.
An iterator over a system of congruences.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
void set_is_line_or_equality()
Sets to LINE_OR_EQUALITY the kind of *this row.
void set_epsilon_coefficient(Coefficient_traits::const_reference n)
Sets the epsilon coefficient to n. The generator must be NNC.
void remove_trailing_rows(dimension_type n)
Makes the system shrink by removing its n trailing rows.
void strong_normalize()
Strongly normalizes the system.
bool contains(const Polyhedron &y) const
Returns true if and only if *this contains y.
void poly_hull_assign(const Polyhedron &y)
Assigns to *this the poly-hull of *this and 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.
const_iterator end() const
Returns the past-the-end const_iterator.
Coefficient_traits::const_reference epsilon_coefficient() const
Returns the epsilon coefficient. The constraint must be NNC.
const_iterator begin() const
Returns the const_iterator pointing to the first generator, if *this is not empty; otherwise...
Linear_System< Generator > sys
void add_congruence(const Congruence &cg)
Adds a copy of congruence cg to *this, if cg can be exactly represented by a polyhedron.
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.
static dimension_type * simplify_num_saturators_p
Pointer to an array used by simplify().
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.
bool simplify_using_context_assign(const Polyhedron &y)
Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned...
bool OK() const
Checks if all the invariants are satisfied.
Coefficient_traits::const_reference coefficient(Variable v) const
Returns the coefficient of v in *this.
const_iterator end() const
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static size_t simplify_num_saturators_size
Dimension of an array used by simplify().
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...
void generalized_affine_preimage(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the preimage of *this with respect to the generalized affine relation ...
bool operator==(const Box< ITV > &x, const Box< ITV > &y)
static int sign(const Linear_Expression &x, const Linear_Expression &y)
Returns the sign of the scalar product between x and y.
bool is_necessarily_closed() const
Returns true if and only if the topology of *this row is necessarily closed.
Three_Valued_Boolean quick_equivalence_test(const Polyhedron &y) const
Polynomial but incomplete equivalence test between polyhedra.
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.
static void assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the scalar product of x and y and assigns it to z.
size_t memory_size_type
An unsigned integral type for representing memory size in bytes.
Coefficient_traits::const_reference divisor() const
If *this is either a point or a closure point, returns its divisor.
void time_elapse_assign(const Polyhedron &y)
Assigns to *this the result of computing the time-elapse between *this and y.
dimension_type num_rows() const
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
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.
void generalized_affine_image(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the image of *this with respect to the generalized affine relation ...
void set_generators_pending()
Sets status to express that generators are pending.
void unconstrain(Variable var)
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *...
void insert(const Generator &g)
Inserts in *this a copy of the generator g, increasing the number of space dimensions if needed...
const Constraint_System & minimized_constraints() const
Returns the system of constraints, with no redundant constraint.
void strong_normalize()
Strongly normalizes the system.
bool has_closure_points() const
Returns true if and only if *this contains one or more closure points.
bool is_line() const
Returns true if and only if *this is a line.
void refine_with_congruences(const Congruence_System &cgs)
Uses a copy of the congruences in cgs to refine *this.
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 sign_normalize()
Normalizes the sign of the coefficients so that the first non-zero (homogeneous) coefficient of a lin...
static Poly_Con_Relation strictly_intersects()
The polyhedron intersects the set of points satisfying the constraint, but it is not included in it...
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.
The relation between a polyhedron and a generator.
Bounded_Integer_Type_Representation
void unset_pending_rows()
Sets the index to indicate that the system has no pending rows.
bool is_bounded() const
Returns true if and only if *this is a bounded polyhedron.
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.
The problem has an optimal solution.
void clear_generators_minimized()
Sets status to express that generators are no longer minimized.
static void initialize()
Initializes the class.
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.
The relation between a polyhedron and a constraint.
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.
bool has_strict_inequalities() const
Returns true if and only if *this contains one or more strict inequality constraints.