24 #ifndef PPL_BD_Shape_templates_hh
25 #define PPL_BD_Shape_templates_hh 1
39 #include "assertions.hh"
51 : dbm(cgs.space_dimension() + 1),
59 : dbm(gs.space_dimension() + 1), status(), redundancy_dbm() {
62 if (gs_begin == gs_end) {
72 bool dbm_initialized =
false;
73 bool point_seen =
false;
76 gs_i != gs_end; ++gs_i) {
83 if (!dbm_initialized) {
85 dbm_initialized =
true;
140 "the non-empty generator system gs "
141 "contains no points.");
146 gs_i != gs_end; ++gs_i) {
167 assign_r(dbm_0[i.variable().space_dimension()],
190 assign_r(dbm_0[i.variable().space_dimension()],
204 template <
typename T>
206 : dbm(), status(), redundancy_dbm() {
214 if (num_dimensions == 0) {
243 cs_end = ph.
con_sys.
end(); i != cs_end; ++i) {
244 if (i->is_inconsistent()) {
263 ph_cs_end = ph_cs.
end(); i != ph_cs_end; ++i) {
328 template <
typename T>
333 if (space_dim == 0) {
338 shortest_path_closure_assign();
339 if (marked_empty()) {
345 std::vector<dimension_type> predecessor;
346 compute_predecessors(predecessor);
353 if (predecessor[i] == i) {
360 template <
typename T>
365 shortest_path_closure_assign();
370 if (space_dim == 0) {
371 if (marked_empty()) {
377 if (marked_empty()) {
386 std::vector<dimension_type> leaders;
387 compute_leaders(leaders);
412 template <
typename T>
417 throw_dimension_incompatible(
"add_constraint(c)", c);
429 throw_invalid_argument(
"add_constraint(c)",
430 "strict inequalities are not allowed");
439 throw_invalid_argument(
"add_constraint(c)",
440 "c is not a bounded difference constraint");
454 const bool negative = (coeff < 0);
458 bool changed =
false;
459 N& x = negative ? dbm[i][j] : dbm[j][i];
469 N& y = negative ? dbm[j][i] : dbm[i][j];
482 if (changed && marked_shortest_path_closed()) {
483 reset_shortest_path_closed();
488 template <
typename T>
494 if (space_dimension() < cg_space_dim) {
495 throw_dimension_incompatible(
"add_congruence(cg)", cg);
507 throw_invalid_argument(
"add_congruence(cg)",
508 "cg is a non-trivial, proper congruence");
516 template <
typename T>
519 PPL_ASSERT(!marked_empty());
543 const bool negative = (coeff < 0);
544 N& x = negative ? dbm[i][j] : dbm[j][i];
545 N& y = negative ? dbm[j][i] : dbm[i][j];
549 bool changed =
false;
571 if (changed && marked_shortest_path_closed()) {
572 reset_shortest_path_closed();
577 template <
typename T>
594 if (x_space_dim == 0 && marked_empty()) {
595 dbm.grow(y_space_dim + 1);
606 add_space_dimensions_and_embed(y_space_dim);
608 for (
dimension_type i = x_space_dim + 1; i <= new_space_dim; ++i) {
610 dbm_i[0] = y.
dbm[i - x_space_dim][0];
611 dbm[0][i] = y.
dbm[0][i - x_space_dim];
612 for (
dimension_type j = x_space_dim + 1; j <= new_space_dim; ++j) {
613 dbm_i[j] = y.
dbm[i - x_space_dim][j - x_space_dim];
617 if (marked_shortest_path_closed()) {
618 reset_shortest_path_closed();
623 template <
typename T>
631 throw_dimension_incompatible(
"contains(y)", y);
633 if (x_space_dim == 0) {
678 if (x_dbm_i[j] < y_dbm_i[j]) {
686 template <
typename T>
692 throw_dimension_incompatible(
"is_disjoint_from(y)", y);
696 shortest_path_closure_assign();
697 if (marked_empty()) {
730 template <
typename T>
733 if (marked_empty()) {
739 if (space_dim == 0) {
755 template <
typename T>
758 shortest_path_closure_assign();
761 if (marked_empty() || space_dim == 0) {
780 template <
typename T>
788 if (space_dim == 0) {
802 bool all_integers =
true;
807 const N& dbm_i_j = dbm_i[j];
815 all_integers =
false;
824 return all_integers || !bds_z.
is_empty();
827 template <
typename T>
835 throw_dimension_incompatible(
"frequency(e, ...)",
"e", expr);
844 if (space_dim == 0) {
855 shortest_path_closure_assign();
857 if (marked_empty()) {
896 bool constant_v =
false;
934 template <
typename T>
939 if (space_dimension() < var_space_dim) {
940 throw_dimension_incompatible(
"constrains(v)",
"v", var);
942 shortest_path_closure_assign();
945 if (marked_empty()) {
949 const DB_Row<N>& dbm_v = dbm[var_space_dim];
962 template <
typename T>
966 PPL_ASSERT(!marked_empty() && marked_shortest_path_closed());
967 PPL_ASSERT(predecessor.size() == 0);
975 predecessor.reserve(predecessor_size);
977 predecessor.push_back(i);
981 if (i == predecessor[i]) {
984 if (j == predecessor[j]
995 template <
typename T>
998 PPL_ASSERT(!marked_empty() && marked_shortest_path_closed());
999 PPL_ASSERT(leaders.size() == 0);
1001 compute_predecessors(leaders);
1003 PPL_ASSERT(leaders[0] == 0);
1004 for (
dimension_type i = 1, l_size = leaders.size(); i != l_size; ++i) {
1006 PPL_ASSERT(leaders_i <= i);
1007 if (leaders_i != i) {
1009 PPL_ASSERT(leaders_leaders_i == leaders[leaders_leaders_i]);
1010 leaders[i] = leaders_leaders_i;
1015 template <
typename T>
1019 if (marked_empty()) {
1024 if (space_dim == 0) {
1030 if (!marked_shortest_path_reduced()) {
1041 std::vector<dimension_type> leader(space_dim + 1);
1057 leader[j] = leader[i];
1069 if (leader[k] == k) {
1072 if (leader[i] == i) {
1074 const Bit_Row& redundancy_i = redundancy_dbm[i];
1075 const N& x_i_k = x_i[k];
1077 if (leader[j] == j) {
1078 const N& x_i_j = x_i[j];
1080 add_assign_r(
c, x_i_k, x_k[j],
ROUND_UP);
1081 if (x_i_j >=
c && !redundancy_i[j]) {
1096 std::vector<dimension_type> var_conn(space_dim + 1);
1098 var_conn[i] = space_dim + 1;
1111 if (leader_i == i) {
1116 if (j != leader_j) {
1117 if (!redundancy_dbm[i][j]) {
1123 if (leader_j != i) {
1139 if (!redundancy_dbm[i][j]) {
1141 if (leader_i != leader_j) {
1167 std::vector<bool> just_checked(space_dim + 1);
1169 just_checked[i] =
false;
1175 if (!just_checked[i]) {
1179 if (v_con != space_dim + 1) {
1182 while (v_con != i) {
1183 just_checked[v_con] =
true;
1184 v_con = var_conn[v_con];
1187 if (just_checked[v_con]) {
1193 just_checked[i] =
true;
1200 template <
typename T>
1203 const bool from_above)
const {
1208 if (space_dim < expr_space_dim) {
1209 throw_dimension_incompatible((from_above
1210 ?
"bounds_from_above(e)"
1211 :
"bounds_from_below(e)"),
"e", expr);
1213 shortest_path_closure_assign();
1215 if (space_dim == 0 || marked_empty()) {
1220 const Constraint&
c = from_above ? expr <= 0 : expr >= 0;
1227 if (num_vars == 0) {
1232 const N& x = (coeff < 0) ? dbm[i][j] : dbm[j][i];
1239 MIP_Problem mip(space_dim, constraints(), expr, mode_bounds);
1245 template <
typename T>
1248 const bool maximize,
1250 bool& included)
const {
1255 if (space_dim < expr_space_dim) {
1256 throw_dimension_incompatible((maximize
1257 ?
"maximize(e, ...)"
1258 :
"minimize(e, ...)"),
"e", expr);
1261 if (space_dim == 0) {
1262 if (marked_empty()) {
1273 shortest_path_closure_assign();
1275 if (marked_empty()) {
1280 const Constraint&
c = maximize ? expr <= 0 : expr >= 0;
1289 MIP_Problem mip(space_dim, constraints(), expr, mode_max_min);
1302 if (num_vars == 0) {
1311 const N& x = (coeff < 0) ? dbm[i][j] : dbm[j][i];
1325 const int sign_i =
sgn(coeff_i);
1335 add_mul_assign_r(d, coeff_expr, x,
ROUND_UP);
1349 template <
typename T>
1352 const bool maximize,
1360 if (space_dim < expr_space_dim) {
1361 throw_dimension_incompatible((maximize
1362 ?
"maximize(e, ...)"
1363 :
"minimize(e, ...)"),
"e", expr);
1366 if (space_dim == 0) {
1367 if (marked_empty()) {
1379 shortest_path_closure_assign();
1381 if (marked_empty()) {
1386 MIP_Problem mip(space_dim, constraints(), expr, mode_max_min);
1397 template <
typename T>
1404 throw_dimension_incompatible(
"relation_with(cg)", cg);
1410 return relation_with(c);
1413 shortest_path_closure_assign();
1415 if (marked_empty()) {
1420 if (space_dim == 0) {
1436 bool bounded_below = minimize(le, min_numer, min_denom, min_included);
1440 if (!bounded_below) {
1452 bool bounded_above = maximize(le, max_numer, max_denom, max_included);
1456 if (!bounded_above) {
1464 min_value = min_numer / min_denom;
1466 signed_distance = min_value % modulus;
1467 min_value -= signed_distance;
1468 if (min_value * min_denom < min_numer) {
1469 min_value += modulus;
1474 max_value = max_numer / max_denom;
1475 signed_distance = max_value % modulus;
1476 max_value += signed_distance;
1477 if (max_value * max_denom > max_numer) {
1478 max_value -= modulus;
1483 if (max_value < min_value) {
1492 template <
typename T>
1499 if (c_space_dim > space_dim) {
1500 throw_dimension_incompatible(
"relation_with(c)", c);
1502 shortest_path_closure_assign();
1504 if (marked_empty()) {
1509 if (space_dim == 0) {
1552 bool bounded_above = maximize(
le, max_numer, max_denom, max_included);
1553 bool bounded_below = minimize(
le, min_numer, min_denom, min_included);
1554 if (!bounded_above) {
1555 if (!bounded_below) {
1559 switch (
sgn(min_numer)) {
1574 if (!bounded_below) {
1576 switch (
sgn(max_numer)) {
1591 switch (
sgn(max_numer)) {
1593 switch (
sgn(min_numer)) {
1613 if (min_numer == 0) {
1632 if (num_vars == 0) {
1658 const bool negative = (coeff < 0);
1659 const N& x = negative ? dbm[i][j] : dbm[j][i];
1660 const N& y = negative ? dbm[j][i] : dbm[i][j];
1722 if (q_x == d && q_y == d1) {
1762 template <
typename T>
1769 if (space_dim < g_space_dim) {
1770 throw_dimension_incompatible(
"relation_with(g)", g);
1772 shortest_path_closure_assign();
1774 if (marked_empty()) {
1779 if (space_dim == 0) {
1782 const bool is_line = g.
is_line();
1798 const Coefficient& g_coeff_y = (i > g_space_dim || i == 0)
1804 const N& dbm_ij = dbm_i[j];
1805 const N& dbm_ji = dbm[j][i];
1810 product = g_coeff_y;
1811 product -= g_coeff_x;
1813 if (!is_line_or_ray) {
1827 product = g_coeff_y;
1828 product -= g_coeff_x;
1830 if (!is_line_or_ray) {
1854 if (!is_line_or_ray) {
1878 template <
typename T>
1882 if (marked_empty() || marked_shortest_path_closed()) {
1887 if (num_dimensions == 0) {
1905 const N& x_dbm_i_k = x_dbm_i[k];
1908 const N& x_dbm_k_j = x_dbm_k[j];
1911 add_assign_r(sum, x_dbm_i_k, x_dbm_k_j,
ROUND_UP);
1922 N& x_dbm_hh = x.
dbm[h][h];
1923 if (
sgn(x_dbm_hh) < 0) {
1928 PPL_ASSERT(
sgn(x_dbm_hh) == 0);
1938 template <
typename T>
1942 if (marked_empty() || marked_shortest_path_closed()) {
1946 PPL_ASSERT(var.
id() < num_dimensions);
1965 const N& x_v_k = x_v[k];
1966 const N& x_k_v = x_k[v];
1975 const N& x_i_k = x_i[k];
1977 add_assign_r(sum, x_i_k, x_k_v,
ROUND_UP);
1980 const N& x_k_i = x_k[i];
1982 add_assign_r(sum, x_v_k, x_k_i,
ROUND_UP);
1990 const N& x_k_i = x_k[i];
1992 add_assign_r(sum, x_v_k, x_k_i,
ROUND_UP);
1998 else if (x_k_v_finite) {
2002 const N& x_i_k = x_i[k];
2004 add_assign_r(sum, x_i_k, x_k_v,
ROUND_UP);
2019 const N& x_i_v = x_i[v];
2022 const N& x_v_j = x_v[j];
2024 add_assign_r(sum, x_i_v, x_v_j,
ROUND_UP);
2034 N& x_dbm_hh = x.dbm[h][h];
2035 if (
sgn(x_dbm_hh) < 0) {
2040 PPL_ASSERT(
sgn(x_dbm_hh) == 0);
2047 x.set_shortest_path_closed();
2050 template <
typename T>
2054 if (marked_shortest_path_reduced()) {
2059 if (space_dim == 0) {
2063 shortest_path_closure_assign();
2066 if (marked_empty()) {
2073 std::vector<dimension_type> predecessor;
2074 compute_predecessors(predecessor);
2075 std::vector<dimension_type> leaders;
2076 compute_leader_indices(predecessor, leaders);
2079 Bit_Matrix redundancy(space_dim + 1, space_dim + 1);
2082 Bit_Row& red_0 = redundancy[0];
2087 redundancy[i] = red_0;
2095 Bit_Row& redundancy_i = redundancy[i];
2098 if (redundancy_i[j]) {
2099 const N& dbm_i_j = dbm_i[j];
2100 redundancy_i.
clear(j);
2103 add_assign_r(
c, dbm_i[k], dbm[k][j],
ROUND_UP);
2105 redundancy_i.
set(j);
2116 std::deque<bool> dealt_with(space_dim + 1,
false);
2120 if (i != predecessor[i] && !dealt_with[i]) {
2124 if (j == predecessor_j) {
2126 PPL_ASSERT(redundancy[i][j]);
2127 redundancy[i].
clear(j);
2133 PPL_ASSERT(redundancy[predecessor_j][j]);
2134 redundancy[predecessor_j].
clear(j);
2135 dealt_with[predecessor_j] =
true;
2147 PPL_ASSERT(is_shortest_path_reduced());
2150 template <
typename T>
2157 throw_dimension_incompatible(
"upper_bound_assign(y)", y);
2164 shortest_path_closure_assign();
2165 if (marked_empty()) {
2172 PPL_ASSERT(space_dim == 0 || marked_shortest_path_closed());
2177 N& dbm_ij = dbm_i[j];
2178 const N& y_dbm_ij = y_dbm_i[j];
2179 if (dbm_ij < y_dbm_ij) {
2186 if (marked_shortest_path_reduced()) {
2187 reset_shortest_path_reduced();
2192 template <
typename T>
2203 if (x_space_dim == 0) {
2246 if (x_red_i[j] && y_red_i[j]) {
2250 const N& x_dbm_ij = x_dbm_i[j];
2254 db_expr = zero_expr;
2265 if (x_dbm_ij >= y_dbm_i[j]) {
2266 env_cs.
insert(db_expr >= 0);
2270 x_cs_removed.
insert(db_expr == 0);
2274 const N& y_dbm_ij = y_dbm_i[j];
2275 const N& x_dbm_ij = x_dbm_i[j];
2279 db_expr = zero_expr;
2290 if (y_dbm_ij >= x_dbm_ij) {
2292 if (!x_red_i[j] && x_dbm_ij == y_dbm_ij) {
2295 env_cs.
insert(db_expr >= 0);
2299 y_cs_removed.
insert(db_expr == 0);
2305 if (x_cs_removed.
empty()) {
2309 if (y_cs_removed.
empty()) {
2325 i_end = x_cs_removed.
end(); i != i_end; ++i) {
2333 j_end = y_cs_removed.
end(); j != j_end; ++j) {
2337 switch (lp_ij.
solve()) {
2360 template <
typename T>
2361 template <
bool integer_upper_bound>
2366 "BD_Shape<T>::BHZ09_upper_bound_assign_if_exact(y):"
2367 " instantiating for integer upper bound,"
2368 " but T in not an integer datatype.");
2379 if (x_space_dim == 0) {
2403 ub.upper_bound_assign(y);
2410 if (integer_upper_bound) {
2425 const N& x_i_j = x_i[j];
2426 if (x_i_j < y_i[j]) {
2432 const N& ub_k_j = (k == j) ? temp_zero : ub_k[j];
2439 PPL_ASSERT(k != ell);
2440 const N& y_k_ell = y_k[ell];
2441 if (y_k_ell < x_k[ell]) {
2444 add_assign_r(lhs, x_i_j, y_k_ell,
ROUND_UP);
2445 const N& ub_i_ell = (i == ell) ? temp_zero : ub_i[ell];
2446 add_assign_r(rhs, ub_i_ell, ub_k_j,
ROUND_UP);
2447 if (integer_upper_bound) {
2468 template <
typename T>
2475 throw_dimension_incompatible(
"difference_assign(y)", y);
2496 if (space_dim == 0) {
2513 y_cs_end = y_cs.
end(); i != y_cs_end; ++i) {
2538 *
this = new_bd_shape;
2542 template <
typename T>
2549 throw_dimension_incompatible(
"simplify_using_context_assign(y)", y);
2580 for (j = 1; j <= dim; ++j) {
2589 for (i = 1; i <= dim; ++i) {
2598 for (i = 1; i <= dim; ++i) {
2600 for (j = 1; j <= dim; ++j) {
2615 PPL_ASSERT(i <= dim && j <= dim && (i > 0 || j > 0));
2632 const bool bool_result = !target.
is_empty();
2641 PPL_ASSERT(x_num_non_redundant > 0);
2654 std::vector<dimension_type> x_leaders;
2664 if (x_leaders[j] != 0) {
2668 if (x_dbm_0[j] < yy_dbm_0[j]) {
2669 res_dbm_0[j] = x_dbm_0[j];
2670 ++res_num_non_redundant;
2672 yy_dbm_0[j] = x_dbm_0[j];
2676 if (x.
dbm[j][0] < yy.
dbm[j][0]) {
2677 res.
dbm[j][0] = x.
dbm[j][0];
2678 ++res_num_non_redundant;
2680 yy.
dbm[j][0] = x.
dbm[j][0];
2689 if (res_num_non_redundant < x_num_non_redundant) {
2702 if (j == i || j == 0) {
2706 if (x.
dbm[i][j] < yy.
dbm[i][j]) {
2707 res.
dbm[i][j] = x.
dbm[i][j];
2708 ++res_num_non_redundant;
2710 yy.
dbm[i][j] = x.
dbm[i][j];
2714 if (x.
dbm[j][i] < yy.
dbm[j][i]) {
2715 res.
dbm[j][i] = x.
dbm[j][i];
2716 ++res_num_non_redundant;
2718 yy.
dbm[j][i] = x.
dbm[j][i];
2727 if (res_num_non_redundant < x_num_non_redundant) {
2739 if (i != x_leaders[i]) {
2747 if (j != x_leaders[j] || x_redundancy_dbm_i[j]) {
2750 N& yy_dbm_ij = yy_dbm_i[j];
2751 const N& x_dbm_ij = x_dbm_i[j];
2752 if (x_dbm_ij < yy_dbm_ij) {
2753 res_dbm_i[j] = x_dbm_ij;
2754 ++res_num_non_redundant;
2756 yy_dbm_ij = x_dbm_ij;
2758 PPL_ASSERT(i > 0 || j > 0);
2759 Variable var(((i > 0) ? i : j) - 1);
2763 if (res_num_non_redundant < x_num_non_redundant) {
2777 template <
typename T>
2786 const bool was_zero_dim_univ = (!marked_empty() && space_dim == 0);
2791 dbm.grow(new_space_dim + 1);
2795 if (marked_shortest_path_reduced()) {
2796 reset_shortest_path_reduced();
2800 if (was_zero_dim_univ) {
2801 set_shortest_path_closed();
2806 template <
typename T>
2818 if (space_dim == 0) {
2820 if (!marked_empty()) {
2829 set_shortest_path_closed();
2840 dbm.grow(new_space_dim + 1);
2844 for (
dimension_type i = space_dim + 1; i <= new_space_dim; ++i) {
2849 if (marked_shortest_path_closed()) {
2850 reset_shortest_path_closed();
2855 template <
typename T>
2870 if (old_space_dim < min_space_dim) {
2871 throw_dimension_incompatible(
"remove_space_dimensions(vs)", min_space_dim);
2874 shortest_path_closure_assign();
2878 const dimension_type new_space_dim = old_space_dim - vars.size();
2879 if (new_space_dim == 0) {
2880 dbm.resize_no_copy(1);
2881 if (!marked_empty()) {
2883 set_zero_dim_univ();
2890 if (marked_empty()) {
2891 dbm.resize_no_copy(new_space_dim + 1);
2898 if (marked_shortest_path_reduced()) {
2899 reset_shortest_path_reduced();
2904 Variables_Set::const_iterator vsi = vars.begin();
2905 Variables_Set::const_iterator vsi_end = vars.end();
2908 for (++vsi; vsi != vsi_end; ++vsi) {
2912 while (src < vsi_next) {
2914 swap(dbm[dst], dbm[src]);
2926 while (src <= old_space_dim) {
2928 swap(dbm[dst], dbm[src]);
2938 dbm.resize_no_copy(new_space_dim + 1);
2942 template <
typename T>
2943 template <
typename Partial_Function>
2948 if (space_dim == 0) {
2953 remove_higher_space_dimensions(0);
2960 if (new_space_dim < space_dim) {
2961 shortest_path_closure_assign();
2965 if (marked_empty()) {
2966 remove_higher_space_dimensions(new_space_dim);
2972 if (marked_shortest_path_reduced()) {
2973 reset_shortest_path_reduced();
2984 if (pfunc.
maps(j - 1, new_j)) {
2992 if (pfunc.
maps(i - 1, new_i)) {
2998 if (pfunc.
maps(j - 1, new_j)) {
3012 template <
typename T>
3019 throw_dimension_incompatible(
"intersection_assign(y)", y);
3023 if (marked_empty()) {
3034 if (space_dim == 0) {
3039 bool changed =
false;
3044 N& dbm_ij = dbm_i[j];
3045 const N& y_dbm_ij = y_dbm_i[j];
3046 if (dbm_ij > y_dbm_ij) {
3053 if (changed && marked_shortest_path_closed()) {
3054 reset_shortest_path_closed();
3059 template <
typename T>
3060 template <
typename Iterator>
3063 Iterator first, Iterator last,
3069 throw_dimension_incompatible(
"CC76_extrapolation_assign(y)", y);
3072 PPL_EXPECT_HEAVY(copy_contains(*
this, y));
3076 if (space_dim == 0) {
3079 shortest_path_closure_assign();
3081 if (marked_empty()) {
3090 if (tp != 0 && *tp > 0) {
3094 if (!contains(x_tmp)) {
3112 N& dbm_ij = dbm_i[j];
3113 const N& y_dbm_ij = y_dbm_i[j];
3114 if (y_dbm_ij < dbm_ij) {
3115 Iterator k = std::lower_bound(first, last, dbm_ij);
3127 reset_shortest_path_closed();
3131 template <
typename T>
3138 shortest_path_closure_assign();
3139 bool changed =
false;
3145 cs_end = cs.
end(); cs_i != cs_end; ++cs_i) {
3154 const bool negative = (coeff < 0);
3155 const N& x = negative ? dbm[i][j] : dbm[j][i];
3156 const N& y = negative ? dbm[j][i] : dbm[i][j];
3165 N& ls_x = negative ? ls_dbm[i][j] : ls_dbm[j][i];
3176 N& ls_x = negative ? ls_dbm[i][j] : ls_dbm[j][i];
3177 N& ls_y = negative ? ls_dbm[j][i] : ls_dbm[i][j];
3178 if ((ls_x >= d && ls_y > d1) || (ls_x > d && ls_y >= d1)) {
3196 template <
typename T>
3204 throw_dimension_incompatible(
"limited_CC76_extrapolation_assign(y, cs)",
3210 if (space_dim < cs_space_dim) {
3211 throw_invalid_argument(
"limited_CC76_extrapolation_assign(y, cs)",
3212 "cs is space_dimension incompatible");
3217 throw_invalid_argument(
"limited_CC76_extrapolation_assign(y, cs)",
3218 "cs has strict inequalities");
3223 if (space_dim == 0) {
3227 PPL_EXPECT_HEAVY(copy_contains(*
this, y));
3230 if (marked_empty()) {
3238 get_limiting_shape(cs, limiting_shape);
3239 CC76_extrapolation_assign(y, tp);
3240 intersection_assign(limiting_shape);
3243 template <
typename T>
3250 throw_dimension_incompatible(
"BHMZ05_widening_assign(y)", y);
3253 PPL_EXPECT_HEAVY(copy_contains(*
this, y));
3260 if (y_affine_dim == 0) {
3266 PPL_ASSERT(x_affine_dim >= y_affine_dim);
3267 if (x_affine_dim != y_affine_dim) {
3271 if (tp != 0 && *tp > 0) {
3275 if (!contains(x_tmp)) {
3292 N& dbm_ij = dbm_i[j];
3296 if (y_redundancy_i[j] || y_dbm_i[j] != dbm_ij) {
3305 reset_shortest_path_closed();
3309 template <
typename T>
3317 throw_dimension_incompatible(
"limited_BHMZ05_extrapolation_assign(y, cs)",
3323 if (space_dim < cs_space_dim) {
3324 throw_invalid_argument(
"limited_BHMZ05_extrapolation_assign(y, cs)",
3325 "cs is space-dimension incompatible");
3329 throw_invalid_argument(
"limited_BHMZ05_extrapolation_assign(y, cs)",
3330 "cs has strict inequalities");
3335 if (space_dim == 0) {
3339 PPL_EXPECT_HEAVY(copy_contains(*
this, y));
3342 if (marked_empty()) {
3350 get_limiting_shape(cs, limiting_shape);
3351 BHMZ05_widening_assign(y, tp);
3352 intersection_assign(limiting_shape);
3355 template <
typename T>
3362 throw_dimension_incompatible(
"CC76_narrowing_assign(y)", y);
3365 PPL_EXPECT_HEAVY(copy_contains(y, *
this));
3369 if (space_dim == 0) {
3377 shortest_path_closure_assign();
3379 if (marked_empty()) {
3384 bool changed =
false;
3389 N& dbm_ij = dbm_i[j];
3390 const N& y_dbm_ij = y_dbm_i[j];
3393 && dbm_ij != y_dbm_ij) {
3399 if (changed && marked_shortest_path_closed()) {
3400 reset_shortest_path_closed();
3405 template <
typename T>
3411 Coefficient_traits::const_reference sc_denom,
3413 PPL_ASSERT(sc_denom > 0);
3441 PPL_ASSERT(expr_u > 0);
3442 if (expr_u >= sc_denom) {
3444 sub_assign_r(dbm[u_dim][v], ub_v, dbm_0[u_dim],
ROUND_UP);
3448 const N& dbm_u0 = dbm_u[0];
3466 add_assign_r(dbm_u[v], ub_v, up_approx,
ROUND_UP);
3472 template <
typename T>
3478 Coefficient_traits::const_reference sc_denom,
3479 const N& minus_lb_v) {
3480 PPL_ASSERT(sc_denom > 0);
3502 const Variable u_var = u.variable();
3511 PPL_ASSERT(expr_u > 0);
3512 if (expr_u >= sc_denom) {
3515 sub_assign_r(dbm_v[u_dim], minus_lb_v, dbm[u_dim][0],
ROUND_UP);
3518 const N& dbm_0u = dbm_0[u_dim];
3536 add_assign_r(dbm_v[u_dim], up_approx, minus_lb_v,
ROUND_UP);
3542 template <
typename T>
3545 PPL_ASSERT(0 < v && v <= dbm.num_rows());
3553 template <
typename T>
3556 PPL_ASSERT(0 < v && v <= dbm.num_rows());
3564 template <
typename T>
3569 if (space_dimension() < var_space_dim) {
3570 throw_dimension_incompatible(
"unconstrain(var)", var_space_dim);
3574 shortest_path_closure_assign();
3577 if (marked_empty()) {
3580 forget_all_dbm_constraints(var_space_dim);
3582 reset_shortest_path_reduced();
3586 template <
typename T>
3596 if (space_dimension() < min_space_dim) {
3597 throw_dimension_incompatible(
"unconstrain(vs)", min_space_dim);
3601 shortest_path_closure_assign();
3604 if (marked_empty()) {
3607 for (Variables_Set::const_iterator vsi = vars.begin(),
3608 vsi_end = vars.end(); vsi != vsi_end; ++vsi) {
3609 forget_all_dbm_constraints(*vsi + 1);
3612 reset_shortest_path_reduced();
3616 template <
typename T>
3621 Coefficient_traits::const_reference denominator) {
3622 PPL_ASSERT(denominator != 0);
3625 PPL_ASSERT(v <= space_dimension());
3648 if (t == 1 && expr.
get(
Variable(w - 1)) != denominator) {
3664 add_dbm_constraint(0, v, b, denominator);
3665 add_dbm_constraint(v, 0, b, minus_denom);
3669 add_dbm_constraint(0, v, b, denominator);
3674 add_dbm_constraint(v, 0, b, minus_denom);
3686 PPL_ASSERT(expr.
get(
Variable(w - 1)) == denominator);
3692 add_dbm_constraint(w, v, d);
3696 add_dbm_constraint(v, w, d);
3701 add_dbm_constraint(w, v, d);
3707 add_dbm_constraint(v, w, d);
3720 const bool is_sc = (denominator > 0);
3724 const Coefficient& minus_sc_b = is_sc ? minus_b : b;
3725 const Coefficient& sc_denom = is_sc ? denominator : minus_denom;
3726 const Coefficient& minus_sc_denom = is_sc ? minus_denom : denominator;
3770 const int sign_i =
sgn(sc_i);
3771 PPL_ASSERT(sign_i != 0);
3775 if (pinf_count <= 1) {
3776 const N& approx_i = dbm_0[i_dim];
3778 add_mul_assign_r(sum, coeff_i, approx_i,
ROUND_UP);
3786 if (neg_pinf_count <= 1) {
3787 const N& approx_minus_i = dbm[i_dim][0];
3789 add_mul_assign_r(neg_sum, coeff_i, approx_minus_i,
ROUND_UP);
3793 neg_pinf_index = i_dim;
3798 PPL_ASSERT(sign_i < 0);
3803 if (pinf_count <= 1) {
3804 const N& approx_minus_i = dbm[i_dim][0];
3806 add_mul_assign_r(sum, coeff_i, approx_minus_i,
ROUND_UP);
3814 if (neg_pinf_count <= 1) {
3815 const N& approx_i = dbm_0[i_dim];
3817 add_mul_assign_r(neg_sum, coeff_i, approx_i,
ROUND_UP);
3821 neg_pinf_index = i_dim;
3827 if (pinf_count > 1 && neg_pinf_count > 1) {
3833 reset_shortest_path_closed();
3841 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
3844 if (pinf_count <= 1) {
3846 if (down_sc_denom != 1) {
3847 div_assign_r(sum, sum, down_sc_denom,
ROUND_UP);
3850 if (pinf_count == 0) {
3854 deduce_v_minus_u_bounds(v, w, sc_expr, sc_denom, sum);
3859 && sc_expr.
get(
Variable(pinf_index - 1)) == sc_denom) {
3861 dbm[pinf_index][v] = sum;
3867 if (neg_pinf_count <= 1) {
3869 if (down_sc_denom != 1) {
3870 div_assign_r(neg_sum, neg_sum, down_sc_denom,
ROUND_UP);
3873 if (neg_pinf_count == 0) {
3878 deduce_u_minus_v_bounds(v, w, sc_expr, sc_denom, neg_sum);
3881 else if (neg_pinf_index != v
3882 && sc_expr.
get(
Variable(neg_pinf_index - 1)) == sc_denom) {
3885 dbm[v][neg_pinf_index] = neg_sum;
3905 const int sign_i =
sgn(sc_i);
3906 PPL_ASSERT(sign_i != 0);
3908 const N& approx_i = (sign_i > 0) ? dbm_0[i_dim] : dbm[i_dim][0];
3910 if (++pinf_count > 1) {
3923 add_mul_assign_r(sum, coeff_i, approx_i,
ROUND_UP);
3927 if (sc_denom != 1) {
3934 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
3935 div_assign_r(sum, sum, down_sc_denom,
ROUND_UP);
3938 if (pinf_count == 0) {
3940 add_dbm_constraint(0, v, sum);
3942 deduce_v_minus_u_bounds(v, w, sc_expr, sc_denom, sum);
3944 else if (pinf_count == 1) {
3945 if (expr.
get(
Variable(pinf_index - 1)) == denominator) {
3947 add_dbm_constraint(pinf_index, v, sum);
3965 const int sign_i =
sgn(sc_i);
3966 PPL_ASSERT(sign_i != 0);
3968 const N& approx_i = (sign_i > 0) ? dbm[i_dim][0] : dbm_0[i_dim];
3970 if (++pinf_count > 1) {
3983 add_mul_assign_r(sum, coeff_i, approx_i,
ROUND_UP);
3987 if (sc_denom != 1) {
3994 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
3995 div_assign_r(sum, sum, down_sc_denom,
ROUND_UP);
3998 if (pinf_count == 0) {
4000 add_dbm_constraint(v, 0, sum);
4002 deduce_u_minus_v_bounds(v, w, sc_expr, sc_denom, sum);
4004 else if (pinf_count == 1) {
4006 && expr.
get(
Variable(pinf_index - 1)) == denominator) {
4009 add_dbm_constraint(v, pinf_index, sum);
4023 template <
typename T>
4027 Coefficient_traits::const_reference denominator) {
4029 if (denominator == 0) {
4030 throw_invalid_argument(
"affine_image(v, e, d)",
"d == 0");
4037 if (space_dim < expr_space_dim) {
4038 throw_dimension_incompatible(
"affine_image(v, e, d)",
"e", expr);
4042 if (v > space_dim) {
4043 throw_dimension_incompatible(
"affine_image(v, e, d)", var.
id());
4046 shortest_path_closure_assign();
4047 if (marked_empty()) {
4077 forget_all_dbm_constraints(v);
4079 if (marked_shortest_path_reduced()) {
4080 reset_shortest_path_reduced();
4083 add_dbm_constraint(0, v, b, denominator);
4084 add_dbm_constraint(v, 0, b, minus_denom);
4092 if (a == denominator || a == minus_denom) {
4096 if (a == denominator) {
4110 N& dbm_vi = dbm_v[i];
4111 add_assign_r(dbm_vi, dbm_vi,
c,
ROUND_UP);
4112 N& dbm_iv = dbm[i][v];
4113 add_assign_r(dbm_iv, dbm_iv, d,
ROUND_UP);
4121 forget_binary_dbm_constraints(v);
4124 swap(dbm[v][0], dbm[0][v]);
4126 reset_shortest_path_closed();
4132 N& dbm_v0 = dbm[v][0];
4133 add_assign_r(dbm_v0, dbm_v0,
c,
ROUND_UP);
4136 N& dbm_0v = dbm[0][v];
4137 add_assign_r(dbm_0v, dbm_0v, d,
ROUND_UP);
4145 forget_all_dbm_constraints(v);
4147 if (marked_shortest_path_reduced()) {
4148 reset_shortest_path_reduced();
4150 if (a == denominator) {
4152 add_dbm_constraint(w, v, b, denominator);
4153 add_dbm_constraint(v, w, b, minus_denom);
4159 const N& dbm_w0 = dbm[w][0];
4164 add_assign_r(dbm[0][v], d, dbm_w0,
ROUND_UP);
4165 reset_shortest_path_closed();
4167 const N& dbm_0w = dbm[0][w];
4172 add_assign_r(dbm[v][0], dbm_0w,
c,
ROUND_UP);
4173 reset_shortest_path_closed();
4194 const bool is_sc = (denominator > 0);
4198 const Coefficient& minus_sc_b = is_sc ? minus_b : b;
4199 const Coefficient& sc_denom = is_sc ? denominator : minus_denom;
4200 const Coefficient& minus_sc_denom = is_sc ? minus_denom : denominator;
4235 const int sign_i =
sgn(sc_i);
4239 if (pos_pinf_count <= 1) {
4240 const N& up_approx_i = dbm_0[i_dim];
4242 add_mul_assign_r(pos_sum, coeff_i, up_approx_i,
ROUND_UP);
4246 pos_pinf_index = i_dim;
4250 if (neg_pinf_count <= 1) {
4251 const N& up_approx_minus_i = dbm[i_dim][0];
4253 add_mul_assign_r(neg_sum, coeff_i, up_approx_minus_i,
ROUND_UP);
4257 neg_pinf_index = i_dim;
4262 PPL_ASSERT(sign_i < 0);
4267 if (pos_pinf_count <= 1) {
4268 const N& up_approx_minus_i = dbm[i_dim][0];
4270 add_mul_assign_r(pos_sum, coeff_i, up_approx_minus_i,
ROUND_UP);
4274 pos_pinf_index = i_dim;
4278 if (neg_pinf_count <= 1) {
4279 const N& up_approx_i = dbm_0[i_dim];
4281 add_mul_assign_r(neg_sum, coeff_i, up_approx_i,
ROUND_UP);
4285 neg_pinf_index = i_dim;
4292 forget_all_dbm_constraints(v);
4294 if (marked_shortest_path_reduced()) {
4295 reset_shortest_path_reduced();
4298 if (pos_pinf_count > 1 && neg_pinf_count > 1) {
4304 reset_shortest_path_closed();
4307 if (pos_pinf_count <= 1) {
4309 if (sc_denom != 1) {
4316 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
4317 div_assign_r(pos_sum, pos_sum, down_sc_denom,
ROUND_UP);
4320 if (pos_pinf_count == 0) {
4322 dbm[0][v] = pos_sum;
4324 deduce_v_minus_u_bounds(v, w, sc_expr, sc_denom, pos_sum);
4326 else if (pos_pinf_index != v
4327 && sc_expr.
get(
Variable(pos_pinf_index - 1)) == sc_denom) {
4329 dbm[pos_pinf_index][v] = pos_sum;
4334 if (neg_pinf_count <= 1) {
4336 if (sc_denom != 1) {
4343 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
4344 div_assign_r(neg_sum, neg_sum, down_sc_denom,
ROUND_UP);
4347 if (neg_pinf_count == 0) {
4352 deduce_u_minus_v_bounds(v, w, sc_expr, sc_denom, neg_sum);
4355 else if (neg_pinf_index != v
4356 && sc_expr.
get(
Variable(neg_pinf_index - 1)) == sc_denom) {
4359 dbm[v][neg_pinf_index] = neg_sum;
4366 template <
typename T>
4367 template <
typename Interval_Info>
4374 "BD_Shape<T>::affine_form_image(Variable, Linear_Form):"
4375 " T not a floating point type.");
4382 if (space_dim < lf_space_dim) {
4383 throw_dimension_incompatible(
"affine_form_image(var_id, l)",
"l", lf);
4387 if (space_dim < var_id) {
4388 throw_dimension_incompatible(
"affine_form_image(var_id, l)", var.
id());
4391 shortest_path_closure_assign();
4392 if (marked_empty()) {
4402 if (lf.coefficient(
Variable(i)) != 0) {
4413 const FP_Interval_Type& b = lf.inhomogeneous_term();
4422 inhomogeneous_affine_form_image(var_id, b);
4427 const FP_Interval_Type& w_coeff = lf.coefficient(
Variable(w_id - 1));
4428 if (w_coeff == 1 || w_coeff == -1) {
4429 one_variable_affine_form_image(var_id, b, w_coeff, w_id, space_dim);
4434 two_variables_affine_form_image(var_id, lf, space_dim);
4439 template <
typename T>
4440 template <
typename Interval_Info>
4451 forget_all_dbm_constraints(var_id);
4453 if (marked_shortest_path_reduced()) {
4454 reset_shortest_path_reduced();
4457 add_dbm_constraint(0, var_id, b_ub);
4458 add_dbm_constraint(var_id, 0, b_mlb);
4464 template <
typename T>
4465 template <
typename Interval_Info>
4479 bool is_w_coeff_one = (w_coeff == 1);
4481 if (w_id == var_id) {
4483 bool is_b_zero = (b_mlb == 0 && b_ub == 0);
4485 if (is_w_coeff_one) {
4495 N& dbm_vi = dbm_v[i];
4496 add_assign_r(dbm_vi, dbm_vi, b_mlb,
ROUND_UP);
4497 N& dbm_iv = dbm[i][var_id];
4498 add_assign_r(dbm_iv, dbm_iv, b_ub,
ROUND_UP);
4506 forget_binary_dbm_constraints(var_id);
4508 swap(dbm[var_id][0], dbm[0][var_id]);
4510 reset_shortest_path_closed();
4514 N& dbm_v0 = dbm[var_id][0];
4515 add_assign_r(dbm_v0, dbm_v0, b_mlb,
ROUND_UP);
4516 N& dbm_0v = dbm[0][var_id];
4517 add_assign_r(dbm_0v, dbm_0v, b_ub,
ROUND_UP);
4525 forget_all_dbm_constraints(var_id);
4527 if (marked_shortest_path_reduced()) {
4528 reset_shortest_path_reduced();
4530 if (is_w_coeff_one) {
4533 add_dbm_constraint(w_id, var_id, b_ub);
4534 add_dbm_constraint(var_id, w_id, b_mlb);
4539 const N& mlb_w = dbm[w_id][0];
4542 add_assign_r(dbm[0][var_id], b_ub, mlb_w,
ROUND_UP);
4543 reset_shortest_path_closed();
4545 const N& ub_w = dbm[0][w_id];
4548 add_assign_r(dbm[var_id][0], ub_w, b_mlb,
ROUND_UP);
4549 reset_shortest_path_closed();
4560 template <
typename T>
4561 template <
typename Interval_Info>
4567 if (marked_shortest_path_reduced()) {
4568 reset_shortest_path_reduced();
4570 reset_shortest_path_closed();
4579 for (
dimension_type curr_var = 1; curr_var < var_id; ++curr_var) {
4581 linear_form_upper_bound(lf - current, upper_bound);
4583 linear_form_upper_bound(minus_lf + current, upper_bound);
4586 for (
dimension_type curr_var = var_id + 1; curr_var <= space_dim;
4589 linear_form_upper_bound(lf - current, upper_bound);
4591 linear_form_upper_bound(minus_lf + current, upper_bound);
4596 linear_form_upper_bound(lf, lf_ub);
4598 linear_form_upper_bound(minus_lf, minus_lf_ub);
4603 template <
typename T>
4604 template <
typename Interval_Info>
4610 "Octagonal_Shape<T>::refine_with_linear_form_inequality:"
4611 " T not a floating point type.");
4614 PPL_ASSERT(!marked_empty());
4621 if (space_dim < left_space_dim) {
4622 throw_dimension_incompatible(
4623 "refine_with_linear_form_inequality(left, right)",
"left", left);
4626 if (space_dim < right_space_dim) {
4627 throw_dimension_incompatible(
4628 "refine_with_linear_form_inequality(left, right)",
"right", right);
4645 if (left.coefficient(
Variable(i)) != 0) {
4646 if (left_t++ == 1) {
4657 if (right.coefficient(
Variable(i)) != 0) {
4658 if (right_t++ == 1) {
4667 const FP_Interval_Type& left_w_coeff =
4668 left.coefficient(
Variable(left_w_id));
4669 const FP_Interval_Type& right_w_coeff =
4670 right.coefficient(
Variable(right_w_id));
4679 else if (right_w_coeff == 1 || right_w_coeff == -1) {
4680 left_inhomogeneous_refine(right_t, right_w_id, left, right);
4685 else if (left_t == 1) {
4686 if (left_w_coeff == 1 || left_w_coeff == -1) {
4687 if (right_t == 0 || (right_w_coeff == 1 || right_w_coeff == -1)) {
4688 left_one_var_refine(left_w_id, right_t, right_w_id, left, right);
4696 general_refine(left_w_id, right_w_id, left, right);
4700 template <
typename T>
4701 template <
typename U>
4706 if (space_dim > dest.space_dimension()) {
4707 throw std::invalid_argument(
4708 "BD_Shape<T>::export_interval_constraints");
4712 shortest_path_closure_assign();
4714 if (marked_empty()) {
4724 const N& u = dbm_0[i+1];
4726 if (!dest.restrict_upper(i, u.
raw_value())) {
4731 const N& negated_l = dbm[i+1][0];
4734 if (!dest.restrict_lower(i, tmp.raw_value())) {
4743 template <
typename T>
4744 template <
typename Interval_Info>
4756 const FP_Interval_Type& right_w_coeff =
4757 right.coefficient(
Variable(right_w_id));
4758 if (right_w_coeff == 1) {
4760 const FP_Interval_Type& left_a = left.inhomogeneous_term();
4761 const FP_Interval_Type& right_b = right.inhomogeneous_term();
4762 sub_assign_r(b_plus_minus_a_minus, right_b.upper(), left_a.lower(),
4764 add_dbm_constraint(right_w_id+1, 0, b_plus_minus_a_minus);
4768 if (right_w_coeff == -1) {
4770 const FP_Interval_Type& left_a = left.inhomogeneous_term();
4771 const FP_Interval_Type& right_b = right.inhomogeneous_term();
4772 sub_assign_r(b_plus_minus_a_minus, right_b.upper(), left_a.lower(),
4774 add_dbm_constraint(0, right_w_id+1, b_plus_minus_a_minus);
4781 template <
typename T>
4782 template <
typename Interval_Info>
4796 const FP_Interval_Type& left_w_coeff =
4797 left.coefficient(
Variable(left_w_id));
4799 if (left_w_coeff == 1) {
4801 const FP_Interval_Type& left_b = left.inhomogeneous_term();
4802 const FP_Interval_Type& right_a = right.inhomogeneous_term();
4803 sub_assign_r(a_plus_minus_b_minus, right_a.upper(), left_b.lower(),
4805 add_dbm_constraint(0, left_w_id+1, a_plus_minus_b_minus);
4809 if (left_w_coeff == -1) {
4811 const FP_Interval_Type& left_b = left.inhomogeneous_term();
4812 const FP_Interval_Type& right_a = right.inhomogeneous_term();
4813 sub_assign_r(a_plus_minus_b_minus, right_a.upper(), left_b.lower(),
4815 add_dbm_constraint(left_w_id+1, 0, a_plus_minus_b_minus);
4819 else if (right_t == 1) {
4824 const FP_Interval_Type& left_w_coeff =
4825 left.coefficient(
Variable(left_w_id));
4827 const FP_Interval_Type& right_w_coeff =
4828 right.coefficient(
Variable(right_w_id));
4830 bool is_left_coeff_one = (left_w_coeff == 1);
4831 bool is_left_coeff_minus_one = (left_w_coeff == -1);
4832 bool is_right_coeff_one = (right_w_coeff == 1);
4833 bool is_right_coeff_minus_one = (right_w_coeff == -1);
4834 if (left_w_id == right_w_id) {
4835 if ((is_left_coeff_one && is_right_coeff_one)
4837 (is_left_coeff_minus_one && is_right_coeff_minus_one)) {
4841 if (is_left_coeff_one && is_right_coeff_minus_one) {
4844 const FP_Interval_Type& left_b = left.inhomogeneous_term();
4845 const FP_Interval_Type& right_a = right.inhomogeneous_term();
4846 sub_assign_r(a_plus_minus_b_minus, right_a.upper(), left_b.lower(),
4848 div_2exp_assign_r(a_plus_minus_b_minus, a_plus_minus_b_minus, 1,
4850 add_dbm_constraint(0, left_w_id + 1, a_plus_minus_b_minus);
4853 if (is_left_coeff_minus_one && is_right_coeff_one) {
4856 const FP_Interval_Type& left_b = left.inhomogeneous_term();
4857 const FP_Interval_Type& right_a = right.inhomogeneous_term();
4858 sub_assign_r(a_plus_minus_b_minus, right_a.upper(), left_b.lower(),
4860 div_2exp_assign_r(a_plus_minus_b_minus, a_plus_minus_b_minus, 1,
4862 add_dbm_constraint(right_w_id + 1, 0, a_plus_minus_b_minus);
4866 else if (is_left_coeff_minus_one && is_right_coeff_one) {
4872 const FP_Interval_Type& left_b = left.inhomogeneous_term();
4873 const FP_Interval_Type& right_a = right.inhomogeneous_term();
4874 sub_assign_r(a_plus_minus_b_minus, right_a.upper(), left_b.lower(),
4877 ub = dbm[0][right_w_id + 1];
4879 add_assign_r(ub, ub, a_plus_minus_b_minus,
ROUND_UP);
4880 add_dbm_constraint(left_w_id + 1, 0, ub);
4882 ub = dbm[0][left_w_id + 1];
4884 add_assign_r(ub, ub, a_plus_minus_b_minus,
ROUND_UP);
4885 add_dbm_constraint(right_w_id + 1, 0, ub);
4889 if (is_left_coeff_one && is_right_coeff_minus_one) {
4895 const FP_Interval_Type& left_b = left.inhomogeneous_term();
4896 const FP_Interval_Type& right_a = right.inhomogeneous_term();
4897 sub_assign_r(a_plus_minus_b_minus, right_a.upper(), left_b.lower(),
4900 ub = dbm[right_w_id + 1][0];
4902 add_assign_r(ub, ub, a_plus_minus_b_minus,
ROUND_UP);
4903 add_dbm_constraint(0, left_w_id + 1, ub);
4905 ub = dbm[left_w_id + 1][0];
4907 add_assign_r(ub, ub, a_plus_minus_b_minus,
ROUND_UP);
4908 add_dbm_constraint(0, right_w_id + 1, ub);
4912 if (is_left_coeff_one && is_right_coeff_one) {
4914 const FP_Interval_Type& left_a = left.inhomogeneous_term();
4915 const FP_Interval_Type& right_c = right.inhomogeneous_term();
4916 sub_assign_r(c_plus_minus_a_minus, right_c.upper(), left_a.lower(),
4918 add_dbm_constraint(right_w_id+1, left_w_id+1, c_plus_minus_a_minus);
4921 if (is_left_coeff_minus_one && is_right_coeff_minus_one) {
4923 const FP_Interval_Type& left_a = left.inhomogeneous_term();
4924 const FP_Interval_Type& right_c = right.inhomogeneous_term();
4925 sub_assign_r(c_plus_minus_a_minus, right_c.upper(), left_a.lower(),
4927 add_dbm_constraint(left_w_id+1, right_w_id+1, c_plus_minus_a_minus);
4933 template <
typename T>
4934 template <
typename Interval_Info>
4944 right_minus_left -= left;
4953 for (
dimension_type first_v = 0; first_v < max_w_id; ++first_v) {
4955 second_v <= max_w_id; ++second_v) {
4956 const FP_Interval_Type& lfv_coefficient =
4957 left.coefficient(
Variable(first_v));
4958 const FP_Interval_Type& lsv_coefficient =
4959 left.coefficient(
Variable(second_v));
4960 const FP_Interval_Type& rfv_coefficient =
4961 right.coefficient(
Variable(first_v));
4962 const FP_Interval_Type& rsv_coefficient =
4963 right.coefficient(
Variable(second_v));
4966 bool do_update =
false;
4969 if (low_coeff != 0 || high_coeff != 0) {
4972 if (low_coeff != 0 || high_coeff != 0) {
4978 if (low_coeff != 0 || high_coeff != 0) {
4986 if (low_coeff != 0 || high_coeff != 0) {
4989 if (low_coeff != 0 || high_coeff != 0) {
4995 if (low_coeff != 0 || high_coeff != 0) {
5007 linear_form_upper_bound(right_minus_left - first + second,
5009 add_dbm_constraint(n_first_var, n_second_var, upper_bound);
5010 linear_form_upper_bound(right_minus_left + first - second,
5012 add_dbm_constraint(n_second_var, n_first_var, upper_bound);
5019 const FP_Interval_Type& lv_coefficient =
5021 const FP_Interval_Type& rv_coefficient =
5025 bool do_update =
false;
5028 if (low_coeff != 0 || high_coeff != 0) {
5034 if (low_coeff != 0 || high_coeff != 0) {
5042 linear_form_upper_bound(right_minus_left + var, upper_bound);
5043 add_dbm_constraint(0, n_var, upper_bound);
5044 linear_form_upper_bound(right_minus_left - var, upper_bound);
5045 add_dbm_constraint(n_var, 0, upper_bound);
5051 template <
typename T>
5052 template <
typename Interval_Info>
5060 "BD_Shape<T>::linear_form_upper_bound:"
5061 " T not a floating point type.");
5064 PPL_ASSERT(lf_space_dimension <= space_dimension());
5080 for (
dimension_type curr_var = 0, n_var = 0; curr_var < lf_space_dimension;
5082 n_var = curr_var + 1;
5083 const FP_Interval_Type&
5084 curr_coefficient = lf.coefficient(
Variable(curr_var));
5087 if (curr_lb != 0 || curr_ub != 0) {
5091 if (curr_lb == 1 && curr_ub == 1) {
5092 add_assign_r(result, result, std::max(curr_var_ub, curr_minus_var_ub),
5095 else if (curr_lb == -1 && curr_ub == -1) {
5096 neg_assign_r(negator, std::min(curr_var_ub, curr_minus_var_ub),
5098 add_assign_r(result, result, negator,
ROUND_UP);
5104 add_mul_assign_r(first_comparison_term, curr_var_ub, curr_ub,
5106 add_mul_assign_r(second_comparison_term, curr_var_ub, curr_lb,
5108 assign_r(first_comparison_term, std::max(first_comparison_term,
5109 second_comparison_term),
5112 add_mul_assign_r(second_comparison_term, curr_minus_var_ub, curr_ub,
5114 assign_r(first_comparison_term, std::max(first_comparison_term,
5115 second_comparison_term),
5118 add_mul_assign_r(second_comparison_term, curr_minus_var_ub, curr_lb,
5120 assign_r(first_comparison_term, std::max(first_comparison_term,
5121 second_comparison_term),
5124 add_assign_r(result, result, first_comparison_term,
ROUND_UP);
5130 template <
typename T>
5134 Coefficient_traits::const_reference denominator) {
5136 if (denominator == 0) {
5137 throw_invalid_argument(
"affine_preimage(v, e, d)",
"d == 0");
5144 if (space_dim < expr_space_dim) {
5145 throw_dimension_incompatible(
"affine_preimage(v, e, d)",
"e", expr);
5150 if (v > space_dim) {
5151 throw_dimension_incompatible(
"affine_preimage(v, e, d)", var.
id());
5154 shortest_path_closure_assign();
5155 if (marked_empty()) {
5181 forget_all_dbm_constraints(v);
5183 if (marked_shortest_path_reduced()) {
5184 reset_shortest_path_reduced();
5193 if (a == denominator || a == -denominator) {
5197 affine_image(var, denominator*var - b, a);
5202 forget_all_dbm_constraints(v);
5204 if (marked_shortest_path_reduced()) {
5205 reset_shortest_path_reduced();
5222 affine_image(var, inverse, expr_v);
5226 forget_all_dbm_constraints(v);
5228 if (marked_shortest_path_reduced()) {
5229 reset_shortest_path_reduced();
5235 template <
typename T>
5241 Coefficient_traits::const_reference denominator) {
5243 if (denominator == 0) {
5244 throw_invalid_argument(
"bounded_affine_image(v, lb, ub, d)",
"d == 0");
5250 if (v > bds_space_dim) {
5251 throw_dimension_incompatible(
"bounded_affine_image(v, lb, ub, d)",
5257 if (bds_space_dim < lb_space_dim) {
5258 throw_dimension_incompatible(
"bounded_affine_image(v, lb, ub, d)",
5262 if (bds_space_dim < ub_space_dim) {
5263 throw_dimension_incompatible(
"bounded_affine_image(v, lb, ub, d)",
5267 shortest_path_closure_assign();
5268 if (marked_empty()) {
5297 generalized_affine_image(var,
5302 add_dbm_constraint(0, v, b, denominator);
5310 if (a == denominator || a == minus_denom) {
5315 const Variable new_var(bds_space_dim);
5316 add_space_dimensions_and_embed(1);
5318 affine_image(new_var, ub_expr, denominator);
5320 shortest_path_closure_assign();
5321 PPL_ASSERT(!marked_empty());
5323 generalized_affine_image(var,
5328 add_constraint(var <= new_var);
5330 remove_higher_space_dimensions(bds_space_dim);
5337 generalized_affine_image(var,
5341 if (a == denominator) {
5343 add_dbm_constraint(w, v, b, denominator);
5349 const N& dbm_w0 = dbm[w][0];
5354 add_assign_r(dbm[0][v], d, dbm_w0,
ROUND_UP);
5355 reset_shortest_path_closed();
5373 const bool is_sc = (denominator > 0);
5377 const Coefficient& sc_denom = is_sc ? denominator : minus_denom;
5378 const Coefficient& minus_sc_denom = is_sc ? minus_denom : denominator;
5384 minus_expr = -ub_expr;
5408 const int sign_i =
sgn(sc_i);
5412 if (pos_pinf_count <= 1) {
5413 const N& up_approx_i = dbm_0[i_dim];
5415 add_mul_assign_r(pos_sum, coeff_i, up_approx_i,
ROUND_UP);
5419 pos_pinf_index = i_dim;
5424 PPL_ASSERT(sign_i < 0);
5429 if (pos_pinf_count <= 1) {
5430 const N& up_approx_minus_i = dbm[i_dim][0];
5432 add_mul_assign_r(pos_sum, coeff_i, up_approx_minus_i,
ROUND_UP);
5436 pos_pinf_index = i_dim;
5442 generalized_affine_image(var,
5447 if (pos_pinf_count > 1) {
5452 reset_shortest_path_closed();
5455 if (pos_pinf_count <= 1) {
5457 if (sc_denom != 1) {
5464 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
5465 div_assign_r(pos_sum, pos_sum, down_sc_denom,
ROUND_UP);
5468 if (pos_pinf_count == 0) {
5470 dbm[0][v] = pos_sum;
5472 deduce_v_minus_u_bounds(v, w, sc_expr, sc_denom, pos_sum);
5475 else if (pos_pinf_index != v
5476 && sc_expr.
get(
Variable(pos_pinf_index - 1)) == sc_denom) {
5478 dbm[pos_pinf_index][v] = pos_sum;
5484 template <
typename T>
5490 Coefficient_traits::const_reference denominator) {
5492 if (denominator == 0) {
5493 throw_invalid_argument(
"bounded_affine_preimage(v, lb, ub, d)",
"d == 0");
5499 if (v > space_dim) {
5500 throw_dimension_incompatible(
"bounded_affine_preimage(v, lb, ub, d)",
5506 if (space_dim < lb_space_dim) {
5507 throw_dimension_incompatible(
"bounded_affine_preimage(v, lb, ub, d)",
5511 if (space_dim < ub_space_dim) {
5512 throw_dimension_incompatible(
"bounded_affine_preimage(v, lb, ub, d)",
5516 shortest_path_closure_assign();
5517 if (marked_empty()) {
5523 lb_expr, denominator);
5529 ub_expr, denominator);
5537 add_space_dimensions_and_embed(1);
5539 = lb_expr - (lb_expr_v + denominator)*var;
5542 affine_image(new_var, lb_inverse, lb_inverse_denom);
5543 shortest_path_closure_assign();
5544 PPL_ASSERT(!marked_empty());
5546 ub_expr, denominator);
5547 if (
sgn(denominator) ==
sgn(lb_inverse_denom)) {
5548 add_constraint(var >= new_var);
5551 add_constraint(var <= new_var);
5554 remove_higher_space_dimensions(space_dim);
5557 template <
typename T>
5562 Coefficient_traits::const_reference
5565 if (denominator == 0) {
5566 throw_invalid_argument(
"generalized_affine_image(v, r, e, d)",
"d == 0");
5573 if (space_dim < expr_space_dim) {
5574 throw_dimension_incompatible(
"generalized_affine_image(v, r, e, d)",
5579 if (v > space_dim) {
5580 throw_dimension_incompatible(
"generalized_affine_image(v, r, e, d)",
5585 throw_invalid_argument(
"generalized_affine_image(v, r, e, d)",
5586 "r is a strict relation symbol");
5590 throw_invalid_argument(
"generalized_affine_image(v, r, e, d)",
5591 "r is the disequality relation symbol");
5593 if (relsym ==
EQUAL) {
5596 affine_image(var, expr, denominator);
5601 shortest_path_closure_assign();
5602 if (marked_empty()) {
5634 forget_all_dbm_constraints(v);
5636 reset_shortest_path_closed();
5640 add_dbm_constraint(0, v, b, denominator);
5645 add_dbm_constraint(v, 0, b, minus_denom);
5659 if (a == denominator || a == minus_denom) {
5668 reset_shortest_path_closed();
5669 if (a == denominator) {
5674 N& dbm_iv = dbm[i][v];
5675 add_assign_r(dbm_iv, dbm_iv, d,
ROUND_UP);
5683 N& dbm_v0 = dbm_v[0];
5684 add_assign_r(dbm_0[v], dbm_v0, d,
ROUND_UP);
5687 forget_binary_dbm_constraints(v);
5694 forget_all_dbm_constraints(v);
5696 if (marked_shortest_path_reduced()) {
5697 reset_shortest_path_reduced();
5699 if (a == denominator) {
5701 add_dbm_constraint(w, v, d);
5707 const N& dbm_w0 = dbm[w][0];
5710 add_assign_r(dbm_0[v], d, dbm_w0,
ROUND_UP);
5712 reset_shortest_path_closed();
5723 reset_shortest_path_closed();
5724 if (a == denominator) {
5729 N& dbm_vi = dbm_v[i];
5730 add_assign_r(dbm_vi, dbm_vi, d,
ROUND_UP);
5738 N& dbm_0v = dbm_0[v];
5739 add_assign_r(dbm_v[0], dbm_0v, d,
ROUND_UP);
5742 forget_binary_dbm_constraints(v);
5749 forget_all_dbm_constraints(v);
5751 if (marked_shortest_path_reduced()) {
5752 reset_shortest_path_reduced();
5754 if (a == denominator) {
5757 add_dbm_constraint(v, w, d);
5764 const N& dbm_0w = dbm_0[w];
5767 add_assign_r(dbm_v[0], dbm_0w, d,
ROUND_UP);
5769 reset_shortest_path_closed();
5792 const bool is_sc = (denominator > 0);
5796 const Coefficient& minus_sc_b = is_sc ? minus_b : b;
5797 const Coefficient& sc_denom = is_sc ? denominator : minus_denom;
5798 const Coefficient& minus_sc_denom = is_sc ? minus_denom : denominator;
5832 const int sign_i =
sgn(sc_i);
5833 PPL_ASSERT(sign_i != 0);
5835 const N& approx_i = (sign_i > 0) ? dbm_0[i_dim] : dbm[i_dim][0];
5837 if (++pinf_count > 1) {
5850 add_mul_assign_r(sum, coeff_i, approx_i,
ROUND_UP);
5854 forget_all_dbm_constraints(v);
5856 if (marked_shortest_path_reduced()) {
5857 reset_shortest_path_reduced();
5860 if (pinf_count > 1) {
5866 if (sc_denom != 1) {
5873 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
5874 div_assign_r(sum, sum, down_sc_denom,
ROUND_UP);
5877 if (pinf_count == 0) {
5879 add_dbm_constraint(0, v, sum);
5881 deduce_v_minus_u_bounds(v, w, sc_expr, sc_denom, sum);
5883 else if (pinf_count == 1) {
5885 && expr.
get(
Variable(pinf_index - 1)) == denominator) {
5887 add_dbm_constraint(pinf_index, v, sum);
5903 const int sign_i =
sgn(sc_i);
5904 PPL_ASSERT(sign_i != 0);
5907 const N& approx_i = (sign_i > 0) ? dbm[i_dim][0] : dbm_0[i_dim];
5909 if (++pinf_count > 1) {
5922 add_mul_assign_r(sum, coeff_i, approx_i,
ROUND_UP);
5926 forget_all_dbm_constraints(v);
5928 if (marked_shortest_path_reduced()) {
5929 reset_shortest_path_reduced();
5932 if (pinf_count > 1) {
5938 if (sc_denom != 1) {
5945 neg_assign_r(down_sc_denom, down_sc_denom,
ROUND_UP);
5946 div_assign_r(sum, sum, down_sc_denom,
ROUND_UP);
5949 if (pinf_count == 0) {
5951 add_dbm_constraint(v, 0, sum);
5953 deduce_u_minus_v_bounds(v, w, sc_expr, sc_denom, sum);
5955 else if (pinf_count == 1) {
5957 && expr.
get(
Variable(pinf_index - 1)) == denominator) {
5960 add_dbm_constraint(v, pinf_index, sum);
5973 template <
typename T>
5983 if (space_dim < lhs_space_dim) {
5984 throw_dimension_incompatible(
"generalized_affine_image(e1, r, e2)",
5990 if (space_dim < rhs_space_dim) {
5991 throw_dimension_incompatible(
"generalized_affine_image(e1, r, e2)",
5996 throw_invalid_argument(
"generalized_affine_image(e1, r, e2)",
5997 "r is a strict relation symbol");
6001 throw_invalid_argument(
"generalized_affine_image(e1, r, e2)",
6002 "r is the disequality relation symbol");
6005 shortest_path_closure_assign();
6006 if (marked_empty()) {
6035 refine_no_check(lhs <= rhs);
6038 refine_no_check(lhs == rhs);
6041 refine_no_check(lhs >= rhs);
6049 else if (t_lhs == 1) {
6066 generalized_affine_image(v, new_relsym, expr, denom);
6071 std::vector<Variable> lhs_vars;
6074 lhs_vars.push_back(i.variable());
6076 const dimension_type num_common_dims = std::min(lhs_space_dim, rhs_space_dim);
6081 forget_all_dbm_constraints(lhs_vars[i].
id() + 1);
6089 refine_no_check(lhs <= rhs);
6092 refine_no_check(lhs == rhs);
6095 refine_no_check(lhs >= rhs);
6106 #if 1 // Simplified computation (see the TODO note below).
6109 forget_all_dbm_constraints(lhs_vars[i].
id() + 1);
6111 #else // Currently unnecessarily complex computation.
6118 add_space_dimensions_and_embed(1);
6123 affine_image(new_var, rhs);
6126 shortest_path_closure_assign();
6127 PPL_ASSERT(!marked_empty());
6129 forget_all_dbm_constraints(lhs_vars[i].
id() + 1);
6139 refine_no_check(lhs <= new_var);
6142 refine_no_check(lhs == new_var);
6145 refine_no_check(lhs >= new_var);
6153 remove_higher_space_dimensions(space_dim-1);
6154 #endif // Currently unnecessarily complex computation.
6161 template <
typename T>
6166 Coefficient_traits::const_reference
6169 if (denominator == 0) {
6170 throw_invalid_argument(
"generalized_affine_preimage(v, r, e, d)",
6178 if (space_dim < expr_space_dim) {
6179 throw_dimension_incompatible(
"generalized_affine_preimage(v, r, e, d)",
6184 if (v > space_dim) {
6185 throw_dimension_incompatible(
"generalized_affine_preimage(v, r, e, d)",
6190 throw_invalid_argument(
"generalized_affine_preimage(v, r, e, d)",
6191 "r is a strict relation symbol");
6195 throw_invalid_argument(
"generalized_affine_preimage(v, r, e, d)",
6196 "r is the disequality relation symbol");
6198 if (relsym ==
EQUAL) {
6201 affine_preimage(var, expr, denominator);
6206 shortest_path_closure_assign();
6207 if (marked_empty()) {
6217 = expr - (expr_v + denominator)*var;
6221 = (
sgn(denominator) ==
sgn(inverse_denom)) ? relsym : reversed_relsym;
6222 generalized_affine_image(var, inverse_relsym, inverse, inverse_denom);
6226 refine(var, relsym, expr, denominator);
6233 forget_all_dbm_constraints(v);
6235 if (marked_shortest_path_reduced()) {
6236 reset_shortest_path_reduced();
6241 template <
typename T>
6251 if (bds_space_dim < lhs_space_dim) {
6252 throw_dimension_incompatible(
"generalized_affine_preimage(e1, r, e2)",
6258 if (bds_space_dim < rhs_space_dim) {
6259 throw_dimension_incompatible(
"generalized_affine_preimage(e1, r, e2)",
6264 throw_invalid_argument(
"generalized_affine_preimage(e1, r, e2)",
6265 "r is a strict relation symbol");
6269 throw_invalid_argument(
"generalized_affine_preimage(e1, r, e2)",
6270 "r is the disequality relation symbol");
6273 shortest_path_closure_assign();
6274 if (marked_empty()) {
6296 generalized_affine_image(lhs, relsym, rhs);
6299 else if (t_lhs == 1) {
6316 generalized_affine_preimage(v, new_relsym, expr, denom);
6321 std::vector<Variable> lhs_vars;
6324 lhs_vars.push_back(i.variable());
6326 const dimension_type num_common_dims = std::min(lhs_space_dim, rhs_space_dim);
6336 refine_no_check(lhs <= rhs);
6339 refine_no_check(lhs == rhs);
6342 refine_no_check(lhs >= rhs);
6356 forget_all_dbm_constraints(lhs_vars[i].
id() + 1);
6363 const Variable new_var(bds_space_dim);
6364 add_space_dimensions_and_embed(1);
6369 affine_image(new_var, lhs);
6372 shortest_path_closure_assign();
6373 PPL_ASSERT(!marked_empty());
6375 forget_all_dbm_constraints(lhs_vars[i].
id() + 1);
6386 refine_no_check(new_var <= rhs);
6389 refine_no_check(new_var == rhs);
6392 refine_no_check(new_var >= rhs);
6400 remove_higher_space_dimensions(bds_space_dim);
6407 template <
typename T>
6414 if (space_dim == 0) {
6415 if (marked_empty()) {
6421 if (marked_empty()) {
6426 if (marked_shortest_path_reduced()) {
6428 cs = minimized_constraints();
6438 const N& dbm_0j = dbm_0[j];
6439 const N& dbm_j0 = dbm[j][0];
6464 const N& dbm_ij = dbm_i[j];
6465 const N& dbm_ji = dbm[j][i];
6469 cs.
insert(a*x - a*y == b);
6475 cs.
insert(a*x - a*y <= b);
6479 cs.
insert(a*y - a*x <= b);
6487 template <
typename T>
6490 shortest_path_reduction_assign();
6495 if (space_dim == 0) {
6496 if (marked_empty()) {
6502 if (marked_empty()) {
6511 std::vector<dimension_type> leaders;
6512 compute_leaders(leaders);
6513 std::vector<dimension_type> leader_indices;
6514 compute_leader_indices(leaders, leader_indices);
6540 const Bit_Row& red_0 = redundancy_dbm[0];
6547 if (!redundancy_dbm[i][0]) {
6556 const Bit_Row& red_i = redundancy_dbm[i];
6563 if (!redundancy_dbm[j][i]) {
6572 template <
typename T>
6578 throw_dimension_incompatible(
"expand_space_dimension(v, m)",
"v", var);
6584 throw_invalid_argument(
"expand_dimension(v, m)",
6585 "adding m new space dimensions exceeds "
6586 "the maximum allowed space dimension");
6593 add_space_dimensions_and_embed(m);
6602 const N& dbm_i_v = dbm[i][v_id];
6603 const N& dbm_v_i = dbm_v[i];
6606 dbm[j][i] = dbm_v_i;
6611 if (marked_shortest_path_closed()) {
6612 reset_shortest_path_closed();
6617 template <
typename T>
6624 throw_dimension_incompatible(
"fold_space_dimensions(vs, v)",
6633 throw_dimension_incompatible(
"fold_space_dimensions(vs, v)",
6637 if (vars.find(dest.
id()) != vars.end()) {
6638 throw_invalid_argument(
"fold_space_dimensions(vs, v)",
6639 "v should not occur in vs");
6641 shortest_path_closure_assign();
6642 if (!marked_empty()) {
6649 for (Variables_Set::const_iterator i = vars.begin(),
6650 vs_end = vars.end(); i != vs_end; ++i) {
6652 const DB_Row<N>& dbm_to_be_folded_id = dbm[to_be_folded_id];
6654 max_assign(dbm[j][v_id], dbm[j][to_be_folded_id]);
6655 max_assign(dbm_v[j], dbm_to_be_folded_id[j]);
6659 remove_space_dimensions(vars);
6662 template <
typename T>
6669 shortest_path_closure_assign();
6670 if (space_dim == 0 || marked_empty()) {
6677 drop_some_non_integer_points_helper(dbm_i[j]);
6684 template <
typename T>
6691 if (space_dim < min_space_dim) {
6692 throw_dimension_incompatible(
"drop_some_non_integer_points(vs, cmpl)",
6698 shortest_path_closure_assign();
6699 if (marked_empty()) {
6702 const Variables_Set::const_iterator v_begin = vars.begin();
6703 const Variables_Set::const_iterator v_end = vars.end();
6704 PPL_ASSERT(v_begin != v_end);
6707 for (Variables_Set::const_iterator v_i = v_begin; v_i != v_end; ++v_i) {
6709 drop_some_non_integer_points_helper(dbm_0[i]);
6710 drop_some_non_integer_points_helper(dbm[i][0]);
6714 for (Variables_Set::const_iterator v_i = v_begin; v_i != v_end; ++v_i) {
6717 for (Variables_Set::const_iterator v_j = v_begin; v_j != v_end; ++v_j) {
6720 drop_some_non_integer_points_helper(dbm_i[j]);
6728 template <
typename T>
6730 IO_Operators::operator<<(std::ostream& s, const BD_Shape<T>& bds) {
6732 if (bds.is_universe()) {
6738 if (bds.marked_empty()) {
6746 const N& c_i_j = bds.dbm[i][j];
6747 const N& c_j_i = bds.dbm[j][i];
6759 s <<
" = " << c_i_j;
6763 if (
sgn(c_i_j) >= 0) {
6766 s << Variable(i - 1);
6767 s <<
" = " << c_i_j;
6772 s << Variable(j - 1);
6773 s <<
" = " << c_j_i;
6794 if (
sgn(c_j_i) >= 0) {
6797 s << Variable(j - 1);
6798 s <<
" <= " << c_j_i;
6803 s << Variable(i - 1);
6819 s <<
" <= " << c_i_j;
6823 if (
sgn(c_i_j) >= 0) {
6826 s << Variable(i - 1);
6827 s <<
" <= " << c_i_j;
6832 s << Variable(j - 1);
6846 template <
typename T>
6849 status.ascii_dump(s);
6853 redundancy_dbm.ascii_dump(s);
6858 template <typename T>
6861 if (!status.ascii_load(s)) {
6864 if (!dbm.ascii_load(s)) {
6867 if (!redundancy_dbm.ascii_load(s)) {
6873 template <
typename T>
6876 return dbm.external_memory_in_bytes()
6877 + redundancy_dbm.external_memory_in_bytes();
6880 template <
typename T>
6892 if (marked_empty()) {
6901 std::cerr <<
"BD_Shape::dbm[" << i <<
"][" << j <<
"] = "
6914 std::cerr <<
"BD_Shape::dbm[" << i <<
"][" << i <<
"] = "
6915 << dbm[i][i] <<
"! (+inf was expected.)"
6922 if (marked_shortest_path_closed()) {
6928 std::cerr <<
"BD_Shape is marked as closed but it is not!"
6938 if (std::numeric_limits<coefficient_type_base>::is_exact) {
6941 if (marked_shortest_path_reduced()) {
6948 std::cerr <<
"BD_Shape::dbm[" << i <<
"][" << j <<
"] = "
6949 << dbm[i][j] <<
" is marked as non-redundant!"
6961 std::cerr <<
"BD_Shape is marked as reduced but it is not!"
6973 template <
typename T>
6977 std::ostringstream s;
6978 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
6979 <<
"this->space_dimension() == " << space_dimension()
6981 throw std::invalid_argument(s.str());
6984 template <
typename T>
6988 std::ostringstream s;
6989 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
6990 <<
"this->space_dimension() == " << space_dimension()
6991 <<
", required dimension == " << required_dim <<
".";
6992 throw std::invalid_argument(s.str());
6995 template <
typename T>
6999 std::ostringstream s;
7000 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7001 <<
"this->space_dimension() == " << space_dimension()
7003 throw std::invalid_argument(s.str());
7006 template <
typename T>
7010 std::ostringstream s;
7011 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7012 <<
"this->space_dimension() == " << space_dimension()
7014 throw std::invalid_argument(s.str());
7017 template <
typename T>
7021 std::ostringstream s;
7022 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7023 <<
"this->space_dimension() == " << space_dimension()
7025 throw std::invalid_argument(s.str());
7028 template <
typename T>
7032 using namespace IO_Operators;
7033 std::ostringstream s;
7034 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7035 << le <<
" is too complex.";
7036 throw std::invalid_argument(s.str());
7040 template <
typename T>
7043 const char* le_name,
7045 std::ostringstream s;
7046 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7047 <<
"this->space_dimension() == " << space_dimension()
7048 <<
", " << le_name <<
"->space_dimension() == "
7050 throw std::invalid_argument(s.str());
7053 template <
typename T>
7054 template<
typename Interval_Info>
7057 const char* lf_name,
7059 Interval_Info> >& lf)
const {
7060 std::ostringstream s;
7061 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7062 <<
"this->space_dimension() == " << space_dimension()
7063 <<
", " << lf_name <<
"->space_dimension() == "
7064 << lf.space_dimension() <<
".";
7065 throw std::invalid_argument(s.str());
7068 template <
typename T>
7071 std::ostringstream s;
7072 s <<
"PPL::BD_Shape::" << method <<
":" << std::endl
7074 throw std::invalid_argument(s.str());
7079 #endif // !defined(PPL_BD_Shape_templates_hh)
bool marked_empty() const
Returns true if the BDS is known to be empty.
Minimization is requested.
bool has_pending_constraints() const
Returns true if there are pending constraints.
bool is_satisfiable() const
Checks satisfiability of *this.
bool constraints_are_minimized() const
Returns true if the system of constraints is minimized.
void BHMZ05_widening_assign(const BD_Shape &y, unsigned *tp=0)
Assigns to *this the result of computing the BHMZ05-widening of *this and y.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
Enable_If< Is_Native_Or_Checked< To >::value &&Is_Special< From >::value, Result >::type assign_r(To &to, const From &, Rounding_Dir dir)
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...
void limited_CC76_extrapolation_assign(const BD_Shape &y, const Constraint_System &cs, unsigned *tp=0)
Improves the result of the CC76-extrapolation computation by also enforcing those constraints in cs t...
void deduce_u_minus_v_bounds(dimension_type v, dimension_type last_v, const Linear_Expression &sc_expr, Coefficient_traits::const_reference sc_denom, const N &minus_lb_v)
An helper function for the computation of affine relations.
bool marked_empty() const
Returns true if the polyhedron is known to be empty.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type is_minus_infinity(const T &x)
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.
dimension_type max_space_dimension()
Returns the maximum space dimension this library can handle.
void set_optimization_mode(Optimization_Mode mode)
Sets the optimization mode to mode.
Coefficient_traits::const_reference modulus() const
Returns a const reference to the modulus of *this.
A linear equality or inequality.
void unconstrain(Variable var)
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *...
void left_inhomogeneous_refine(const dimension_type &right_t, const dimension_type &right_w_id, const Linear_Form< Interval< T, Interval_Info > > &left, const Linear_Form< Interval< T, Interval_Info > > &right)
Auxiliary function for refine with linear form that handle the general case: .
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)
Optimization_Mode
Possible optimization modes.
void set_space_dimension(dimension_type n)
Sets the dimension of the vector space enclosing *this to n .
An iterator over a system of generators.
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 insert(const Congruence &cg)
Inserts in *this a copy of the congruence cg, increasing the number of space dimensions if needed...
void set_space_dimension(dimension_type space_dim)
Sets the space dimension of the rows in the system to space_dim .
An std::set of variables' indexes.
Enable_If< Is_Native_Or_Checked< T >::value, void >::type numer_denom(const T &from, Coefficient &numer, Coefficient &denom)
Extract the numerator and denominator components of from.
void fold_space_dimensions(const Variables_Set &vars, Variable dest)
Folds the space dimensions in vars into dest.
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
void upper_bound_assign(const BD_Shape &y)
Assigns to *this the smallest BDS containing the union of *this and y.
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.
bool is_disjoint_from(const BD_Shape &y) const
Returns true if and only if *this and y are disjoint.
Coefficient_traits::const_reference get(dimension_type i) const
Returns the i-th coefficient.
A line, ray, point or closure point.
void map_space_dimensions(const Partial_Function &pfunc)
Remaps the dimensions of the vector space according to a partial function.
void add_constraints(const Constraint_System &cs)
Adds a copy of the constraints in cs to the MIP problem.
bool is_line_or_ray() const
Returns true if and only if *this is a line or a ray.
bool is_shortest_path_reduced() const
Returns true if and only if this->dbm is shortest-path closed and this->redundancy_dbm correctly flag...
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
BD_Shape(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a universe or empty BDS of the specified space dimension.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
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 concatenate_assign(const BD_Shape &y)
Assigns to *this the concatenation of *this and y, taken in this order.
void refine_with_constraints(const Constraint_System &cs)
Uses a copy of the constraints in cs to refine the system of bounded differences defining *this...
bool is_inconsistent() const
Returns true if and only if *this is inconsistent (i.e., an always false congruence).
void get_limiting_shape(const Constraint_System &cs, BD_Shape &limiting_shape) const
Adds to limiting_shape the bounded differences in cs that are satisfied by *this. ...
Enable_If< Has_Assign_Or_Swap< T >::value, void >::type assign_or_swap(T &to, T &from)
void drop_some_non_integer_points(Complexity_Class complexity=ANY_COMPLEXITY)
Possibly tightens *this by dropping some points with non-integer coordinates.
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 into the affine ex...
void m_swap(BD_Shape &y)
Swaps *this with y (*this and y can be dimension-incompatible).
void throw_dimension_incompatible(const char *method, const BD_Shape &y) const
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type is_integer(const T &x)
static const Constraint_System & zero_dim_empty()
Returns the singleton system containing only Constraint::zero_dim_false().
static const Constraint & zero_dim_false()
The unsatisfiable (zero-dimension space) constraint .
bool BFT00_upper_bound_assign_if_exact(const BD_Shape &y)
If the upper bound of *this and y is exact it is assigned to *this and true is returned, otherwise false is returned.
void insert(const Constraint &c)
Inserts in *this a copy of the constraint c, increasing the number of space dimensions if needed...
void CC76_extrapolation_assign(const BD_Shape &y, unsigned *tp=0)
Assigns to *this the result of computing the CC76-extrapolation between *this and y...
static const Congruence_System & zero_dim_empty()
Returns the system containing only Congruence::zero_dim_false().
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.
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.
#define PPL_OUTPUT_TEMPLATE_DEFINITIONS(type_symbol, class_prefix)
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 into the affine...
void affine_form_image(Variable var, const Linear_Form< Interval< T, Interval_Info > > &lf)
Assigns to *this the affine form image of *this under the function mapping variable var into the affi...
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 add_constraint(const Constraint &c)
Adds a copy of constraint c to the system of bounded differences defining *this.
bool has_empty_codomain() const
Returns true if and only if the represented partial function has an empty codomain (i...
void clear(unsigned long k)
Clears the bit in position k.
static Poly_Con_Relation saturates()
The polyhedron is included in the set of points saturating the constraint.
All input/output operators are confined to this namespace.
void evaluate_objective_function(const Generator &evaluating_point, Coefficient &numer, Coefficient &denom) const
Sets num and denom so that is the result of evaluating the objective function on evaluating_point...
A row in a matrix of bits.
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 affine relation , where is the relation symb...
void add_constraint(const Constraint &c)
Adds a copy of constraint c to the MIP problem.
void max_assign(N &x, const N &y)
Assigns to x the maximum between x and y.
const_iterator begin() const
Returns the const_iterator pointing to the first constraint, if *this is not empty; otherwise...
bool marked_shortest_path_closed() const
Returns true if the system of bounded differences is known to be shortest-path closed.
void set_zero_dim_univ()
Turns *this into an zero-dimensional universe BDS.
void inhomogeneous_affine_form_image(const dimension_type &var_id, const Interval< T, Interval_Info > &b)
Auxiliary function for affine form image that handle the general case: .
void compute_predecessors(std::vector< dimension_type > &predecessor) const
Compute the (zero-equivalence classes) predecessor relation.
Worst-case polynomial complexity.
Enable_If< Is_Native_Or_Checked< T >::value, void >::type div_round_up(T &to, Coefficient_traits::const_reference x, Coefficient_traits::const_reference y)
Divides x by y into to, rounding the result towards plus infinity.
Coefficient_traits::const_reference coefficient(Variable v) const
Returns the coefficient of v in *this.
dimension_type id() const
Returns the index of the Cartesian axis associated to the variable.
void add_space_dimensions_and_embed(dimension_type m)
Adds m new dimensions and embeds the old BDS into the new space.
const Generator & optimizing_point() const
Returns an optimal point for *this, if it exists.
bool is_proper_congruence() const
Returns true if the modulus is greater than zero.
bool is_empty() const
Returns true if and only if *this is an empty BDS.
void refine_no_check(const Constraint &c)
Uses the constraint c to refine *this.
void left_one_var_refine(const dimension_type &left_w_id, const dimension_type &right_t, const dimension_type &right_w_id, const Linear_Form< Interval< T, Interval_Info > > &left, const Linear_Form< Interval< T, Interval_Info > > &right)
Auxiliary function for refine with linear form that handle the general case: .
static const Congruence & zero_dim_false()
Returns a reference to the false (zero-dimension space) congruence .
A dimension of the vector space.
void shortest_path_closure_assign() const
Assigns to this->dbm its shortest-path closure.
bool bounds(const Linear_Expression &expr, bool from_above) const
Checks if and how expr is bounded in *this.
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.
Complexity_Class
Complexity pseudo-classes.
The base class for convex polyhedra.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
Worst-case exponential complexity but typically polynomial behavior.
The base class for the single rows of matrices.
bool is_inequality() const
Returns true if and only if *this is an inequality constraint (either strict or non-strict).
A wrapper for numeric types implementing a given policy.
The problem is unbounded.
bool generators_are_up_to_date() const
Returns true if the system of generators is up-to-date.
Constraint_System con_sys
The system of constraints.
bool all_zeroes(const Variables_Set &vars) const
Returns true if the coefficient of each variable in vars[i] is .
bool is_universe() const
Returns true if and only if *this is a universe BDS.
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 ...
void linear_form_upper_bound(const Linear_Form< Interval< T, Interval_Info > > &lf, N &result) const
#define PPL_COMPILE_TIME_CHECK(e, msg)
Produces a compilation error if the compile-time constant e does not evaluate to true ...
bool constrains(Variable var) const
Returns true if and only if var is constrained in *this.
void reset_shortest_path_closed()
Marks *this as possibly not shortest-path closed.
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.
void two_variables_affine_form_image(const dimension_type &var_id, const Linear_Form< Interval< T, Interval_Info > > &lf, const dimension_type &space_dim)
Auxiliary function for affine form image that handle the general case: .
bool empty() const
Returns true if and only if *this has no constraints.
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.
The problem is unfeasible.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool simplify_using_context_assign(const BD_Shape &y)
Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned...
Greater than or equal to.
static void throw_invalid_argument(const char *method, const char *reason)
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 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 affine relation , where is the relation s...
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...
A Mixed Integer (linear) Programming problem.
const_iterator end() const
Iterator pointing after the last nonzero variable coefficient.
const Generator_System & generators() const
Returns the system of generators.
void export_interval_constraints(U &dest) const
Applies to dest the interval constraints embedded in *this.
bool is_bounded() const
Returns true if and only if *this is a bounded BDS.
Coefficient_traits::const_reference get(dimension_type i) const
Returns the i -th coefficient.
bool is_inconsistent() const
Returns true if and only if *this is inconsistent (i.e., an always false constraint).
Constraint_System constraints() const
Returns a system of constraints defining *this.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
void difference_assign(const BD_Shape &y)
Assigns to *this the smallest BD shape containing the set difference of *this and y...
void intersection_assign(const BD_Shape &y)
Assigns to *this the intersection of *this and y.
Congruence_System minimized_congruences() const
Returns a minimal system of (equality) congruences satisfied by *this with the same affine dimension ...
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type is_plus_infinity(const T &x)
void refine(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Adds to the BDS the constraint .
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type is_additive_inverse(const T &x, const T &y)
Returns true if and only if .
bool is_tautological() const
Returns true if and only if *this is a tautology (i.e., an always true congruence).
void deduce_v_minus_u_bounds(dimension_type v, dimension_type last_v, const Linear_Expression &sc_expr, Coefficient_traits::const_reference sc_denom, const N &ub_v)
An helper function for the computation of affine relations.
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified dimensions.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
#define PPL_DIRTY_TEMP(T, id)
The universe element, i.e., the whole vector space.
A generic, not necessarily closed, possibly restricted interval.
dimension_type max_in_codomain() const
If the codomain is not empty, returns the maximum value in it.
Constraint_System minimized_constraints() const
Returns a minimized system of constraints defining *this.
bool OK() const
Returns true if and only if *this satisfies all its invariants.
void forget_binary_dbm_constraints(dimension_type v)
Removes all binary constraints on row/column v.
void one_variable_affine_form_image(const dimension_type &var_id, const Interval< T, Interval_Info > &b, const Interval< T, Interval_Info > &w_coeff, const dimension_type &w_id, const dimension_type &space_dim)
Auxiliary function for affine formimage" that handle the general case: .
void set_shortest_path_closed()
Marks *this as shortest-path closed.
Plus_Infinity PLUS_INFINITY
void neg_assign(GMP_Integer &x)
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
The entire library is confined to this namespace.
bool contains(const BD_Shape &y) const
Returns true if and only if *this contains y.
Maximization is requested.
Poly_Con_Relation relation_with(const Constraint &c) const
Returns the relations holding between *this and the constraint c.
void incremental_shortest_path_closure_assign(Variable var) const
Incrementally computes shortest-path closure, assuming that only constraints affecting variable var n...
void general_refine(const dimension_type &left_w_id, const dimension_type &right_w_id, const Linear_Form< Interval< T, Interval_Info > > &left, const Linear_Form< Interval< T, Interval_Info > > &right)
Auxiliary function for refine with linear form that handle the general case.
const_iterator end() const
Returns the past-the-end const_iterator.
const_iterator begin() const
Returns the const_iterator pointing to the first generator, if *this is not empty; otherwise...
A bounded difference shape.
void set_objective_function(const Linear_Expression &obj)
Sets the objective function to obj.
MIP_Problem_Status solve() const
Optimizes the MIP problem.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
base_type::const_iterator const_iterator
The type of const iterators on coefficients.
bool BHZ09_upper_bound_assign_if_exact(const BD_Shape &y)
If the upper bound of *this and y is exact it is assigned to *this and true is returned, otherwise false is returned.
Coefficient_traits::const_reference coefficient(Variable v) const
Returns the coefficient of v in *this.
const_iterator end() const
void compute_leaders(std::vector< dimension_type > &leaders) const
Compute the leaders of zero-equivalence classes.
int sgn(Boundary_Type type, const T &x, const Info &info)
void refine_with_linear_form_inequality(const Linear_Form< Interval< T, Interval_Info > > &left, const Linear_Form< Interval< T, Interval_Info > > &right)
Refines the system of BD_Shape constraints defining *this using the constraint expressed by left rig...
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
Bit_Matrix redundancy_dbm
A matrix indicating which constraints are redundant.
void forget_all_dbm_constraints(dimension_type v)
Removes all the constraints on row/column v.
void normalize2(Coefficient_traits::const_reference x, Coefficient_traits::const_reference y, Coefficient &n_x, Coefficient &n_y)
If is the GCD of x and y, the values of x and y divided by are assigned to n_x and n_y...
bool maps(dimension_type i, dimension_type &j) const
If *this maps i to a value k, assigns k to j and returns true; otherwise, j is unchanged and false is...
bool contains_integer_point() const
Returns true if and only if *this contains at least one integer point.
static void throw_expression_too_complex(const char *method, const Linear_Expression &le)
static bool extract_bounded_difference(const Constraint &c, dimension_type &c_num_vars, dimension_type &c_first_var, dimension_type &c_second_var, Coefficient &c_coeff)
Decodes the constraint c as a bounded difference.
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.
bool is_nonstrict_inequality() const
Returns true if and only if *this is a non-strict inequality constraint.
void reset_shortest_path_reduced()
Marks *this as possibly not shortest-path reduced.
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
void set_empty()
Turns *this into an empty BDS.
void CC76_narrowing_assign(const BD_Shape &y)
Assigns to *this the result of restoring in y the constraints of *this that were lost by CC76-extrapo...
expr_type expression() const
Partial read access to the (adapted) internal expression.
#define PPL_UNINITIALIZED(type, name)
void add_congruence(const Congruence &cg)
Adds a copy of congruence cg to the system of congruences of *this.
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)
void expand_space_dimension(Variable var, dimension_type m)
Creates m copies of the space dimension corresponding to var.
const_iterator begin() const
Iterator pointing to the first nonzero variable coefficient.
dimension_type affine_dimension() const
Returns , if *this is empty; otherwise, returns the affine dimension of *this.
The base class for the square matrices.
void min_assign(N &x, const N &y)
Assigns to x the minimum between x and y.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
T & raw_value()
Returns a reference to the underlying numeric value.
void shortest_path_reduction_assign() const
Assigns to this->dbm its shortest-path closure and records into this->redundancy_dbm which of the ent...
bool is_line() const
Returns true if and only if *this is a line.
void add_congruences(const Congruence_System &cgs)
Adds to *this constraints equivalent to the congruences in cgs.
static Poly_Con_Relation strictly_intersects()
The polyhedron intersects the set of points satisfying the constraint, but it is not included in it...
const_iterator lower_bound(Variable v) const
static Poly_Gen_Relation nothing()
The assertion that says nothing.
void add_space_dimensions_and_project(dimension_type m)
Adds m new dimensions to the BDS and does not embed it in the new vector space.
void limited_BHMZ05_extrapolation_assign(const BD_Shape &y, const Constraint_System &cs, unsigned *tp=0)
Improves the result of the BHMZ05-widening computation by also enforcing those constraints in cs that...
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
The relation between a polyhedron and a generator.
DB_Matrix< N > dbm
The matrix representing the system of bounded differences.
The problem has an optimal solution.
void set_shortest_path_reduced()
Marks *this as shortest-path closed.
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 has_strict_inequalities() const
Returns true if and only if *this contains one or more strict inequality constraints.