00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef PPL_Octagonal_Shape_inlines_hh
00026 #define PPL_Octagonal_Shape_inlines_hh 1
00027
00028 #include "Constraint_System.defs.hh"
00029 #include "Constraint_System.inlines.hh"
00030 #include "C_Polyhedron.defs.hh"
00031 #include "Grid.defs.hh"
00032 #include "BD_Shape.defs.hh"
00033 #include "Poly_Con_Relation.defs.hh"
00034 #include "Poly_Gen_Relation.defs.hh"
00035 #include "wrap_assign.hh"
00036 #include "assert.hh"
00037 #include <algorithm>
00038
00039 namespace Parma_Polyhedra_Library {
00040
00041 namespace Implementation {
00042
00043 namespace Octagonal_Shapes {
00044
00045 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00046
00047
00048 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00049 inline dimension_type
00050 coherent_index(const dimension_type i) {
00051 return (i % 2 != 0) ? i-1 : i+1;
00052 }
00053
00054 }
00055
00056 }
00057
00058 template <typename T>
00059 inline dimension_type
00060 Octagonal_Shape<T>::max_space_dimension() {
00061 return OR_Matrix<N>::max_num_rows()/2;
00062 }
00063
00064 template <typename T>
00065 inline bool
00066 Octagonal_Shape<T>::marked_zero_dim_univ() const {
00067 return status.test_zero_dim_univ();
00068 }
00069
00070 template <typename T>
00071 inline bool
00072 Octagonal_Shape<T>::marked_strongly_closed() const {
00073 return status.test_strongly_closed();
00074 }
00075
00076 template <typename T>
00077 inline bool
00078 Octagonal_Shape<T>::marked_empty() const {
00079 return status.test_empty();
00080 }
00081
00082 template <typename T>
00083 inline void
00084 Octagonal_Shape<T>::set_zero_dim_univ() {
00085 status.set_zero_dim_univ();
00086 }
00087
00088 template <typename T>
00089 inline void
00090 Octagonal_Shape<T>::set_empty() {
00091 status.set_empty();
00092 }
00093
00094 template <typename T>
00095 inline void
00096 Octagonal_Shape<T>::set_strongly_closed() {
00097 status.set_strongly_closed();
00098 }
00099
00100 template <typename T>
00101 inline void
00102 Octagonal_Shape<T>::reset_strongly_closed() {
00103 status.reset_strongly_closed();
00104 }
00105
00106 template <typename T>
00107 inline
00108 Octagonal_Shape<T>::Octagonal_Shape(const dimension_type num_dimensions,
00109 const Degenerate_Element kind)
00110 : matrix(num_dimensions), space_dim(num_dimensions), status() {
00111 if (kind == EMPTY)
00112 set_empty();
00113 else if (num_dimensions > 0)
00114
00115 set_strongly_closed();
00116 PPL_ASSERT(OK());
00117 }
00118
00119 template <typename T>
00120 inline
00121 Octagonal_Shape<T>::Octagonal_Shape(const Octagonal_Shape& y, Complexity_Class)
00122 : matrix(y.matrix), space_dim(y.space_dim), status(y.status) {
00123 }
00124
00125 template <typename T>
00126 template <typename U>
00127 inline
00128 Octagonal_Shape<T>::Octagonal_Shape(const Octagonal_Shape<U>& y,
00129 Complexity_Class)
00130
00131
00132 : matrix((y.strong_closure_assign(), y.matrix)),
00133 space_dim(y.space_dim),
00134 status() {
00135
00136 if (y.marked_empty())
00137 set_empty();
00138 else if (y.marked_zero_dim_univ())
00139 set_zero_dim_univ();
00140 }
00141
00142 template <typename T>
00143 inline
00144 Octagonal_Shape<T>::Octagonal_Shape(const Constraint_System& cs)
00145 : matrix(cs.space_dimension()),
00146 space_dim(cs.space_dimension()),
00147 status() {
00148 if (cs.space_dimension() > 0)
00149
00150 set_strongly_closed();
00151 add_constraints(cs);
00152 }
00153
00154 template <typename T>
00155 inline
00156 Octagonal_Shape<T>::Octagonal_Shape(const Congruence_System& cgs)
00157 : matrix(cgs.space_dimension()),
00158 space_dim(cgs.space_dimension()),
00159 status() {
00160 if (cgs.space_dimension() > 0)
00161
00162 set_strongly_closed();
00163 add_congruences(cgs);
00164 }
00165
00166 template <typename T>
00167 template <typename Interval>
00168 inline
00169 Octagonal_Shape<T>::Octagonal_Shape(const Box<Interval>& box,
00170 Complexity_Class)
00171 : matrix(box.space_dimension()),
00172 space_dim(box.space_dimension()),
00173 status() {
00174
00175 if (box.is_empty())
00176 set_empty();
00177 else if (box.space_dimension() > 0) {
00178
00179 set_strongly_closed();
00180 refine_with_constraints(box.constraints());
00181 }
00182 }
00183
00184 template <typename T>
00185 inline
00186 Octagonal_Shape<T>::Octagonal_Shape(const Grid& grid,
00187 Complexity_Class)
00188 : matrix(grid.space_dimension()),
00189 space_dim(grid.space_dimension()),
00190 status() {
00191 if (grid.space_dimension() > 0)
00192
00193 set_strongly_closed();
00194
00195 refine_with_congruences(grid.minimized_congruences());
00196 }
00197
00198 template <typename T>
00199 template <typename U>
00200 inline
00201 Octagonal_Shape<T>::Octagonal_Shape(const BD_Shape<U>& bd,
00202 Complexity_Class)
00203 : matrix(bd.space_dimension()),
00204 space_dim(bd.space_dimension()),
00205 status() {
00206
00207 if (bd.is_empty())
00208 set_empty();
00209 else if (bd.space_dimension() > 0) {
00210
00211 set_strongly_closed();
00212 refine_with_constraints(bd.constraints());
00213 }
00214 }
00215
00216 template <typename T>
00217 inline Congruence_System
00218 Octagonal_Shape<T>::congruences() const {
00219 return minimized_congruences();
00220 }
00221
00222 template <typename T>
00223 inline Octagonal_Shape<T>&
00224 Octagonal_Shape<T>::operator=(const Octagonal_Shape& y) {
00225 matrix = y.matrix;
00226 space_dim = y.space_dim;
00227 status = y.status;
00228 return *this;
00229 }
00230
00231 template <typename T>
00232 inline
00233 Octagonal_Shape<T>::~Octagonal_Shape() {
00234 }
00235
00236 template <typename T>
00237 inline void
00238 Octagonal_Shape<T>::swap(Octagonal_Shape& y) {
00239 std::swap(matrix, y.matrix);
00240 std::swap(space_dim, y.space_dim);
00241 std::swap(status, y.status);
00242 }
00243
00244 template <typename T>
00245 inline dimension_type
00246 Octagonal_Shape<T>::space_dimension() const {
00247 return space_dim;
00248 }
00249
00250 template <typename T>
00251 inline bool
00252 Octagonal_Shape<T>::is_discrete() const {
00253 return affine_dimension() == 0;
00254 }
00255
00256 template <typename T>
00257 inline bool
00258 Octagonal_Shape<T>::is_empty() const {
00259 strong_closure_assign();
00260 return marked_empty();
00261 }
00262
00263 template <typename T>
00264 inline bool
00265 Octagonal_Shape<T>::bounds_from_above(const Linear_Expression& expr) const {
00266 return bounds(expr, true);
00267 }
00268
00269 template <typename T>
00270 inline bool
00271 Octagonal_Shape<T>::bounds_from_below(const Linear_Expression& expr) const {
00272 return bounds(expr, false);
00273 }
00274
00275 template <typename T>
00276 inline bool
00277 Octagonal_Shape<T>::maximize(const Linear_Expression& expr,
00278 Coefficient& sup_n, Coefficient& sup_d,
00279 bool& maximum) const {
00280 return max_min(expr, true, sup_n, sup_d, maximum);
00281 }
00282
00283 template <typename T>
00284 inline bool
00285 Octagonal_Shape<T>::maximize(const Linear_Expression& expr,
00286 Coefficient& sup_n, Coefficient& sup_d,
00287 bool& maximum,
00288 Generator& g) const {
00289 return max_min(expr, true, sup_n, sup_d, maximum, g);
00290 }
00291
00292 template <typename T>
00293 inline bool
00294 Octagonal_Shape<T>::minimize(const Linear_Expression& expr,
00295 Coefficient& inf_n, Coefficient& inf_d,
00296 bool& minimum) const {
00297 return max_min(expr, false, inf_n, inf_d, minimum);
00298 }
00299
00300 template <typename T>
00301 inline bool
00302 Octagonal_Shape<T>::minimize(const Linear_Expression& expr,
00303 Coefficient& inf_n, Coefficient& inf_d,
00304 bool& minimum,
00305 Generator& g) const {
00306 return max_min(expr, false, inf_n, inf_d, minimum, g);
00307 }
00308
00309 template <typename T>
00310 inline bool
00311 Octagonal_Shape<T>::is_topologically_closed() const {
00312 return true;
00313 }
00314
00315 template <typename T>
00316 inline void
00317 Octagonal_Shape<T>::topological_closure_assign() {
00318 }
00319
00321 template <typename T>
00322 inline bool
00323 operator==(const Octagonal_Shape<T>& x, const Octagonal_Shape<T>& y) {
00324 if (x.space_dim != y.space_dim)
00325
00326 return false;
00327
00328
00329 if (x.space_dim == 0) {
00330 if (x.marked_empty())
00331 return y.marked_empty();
00332 else
00333 return !y.marked_empty();
00334 }
00335
00336 x.strong_closure_assign();
00337 y.strong_closure_assign();
00338
00339
00340 if (x.marked_empty())
00341 return y.marked_empty();
00342 if (y.marked_empty())
00343 return false;
00344
00345 return x.matrix == y.matrix;
00346 }
00347
00349 template <typename T>
00350 inline bool
00351 operator!=(const Octagonal_Shape<T>& x, const Octagonal_Shape<T>& y) {
00352 return !(x == y);
00353 }
00354
00355 template <typename T>
00356 inline const typename Octagonal_Shape<T>::coefficient_type&
00357 Octagonal_Shape<T>::matrix_at(const dimension_type i,
00358 const dimension_type j) const {
00359 PPL_ASSERT(i < matrix.num_rows() && j < matrix.num_rows());
00360 using namespace Implementation::Octagonal_Shapes;
00361 return (j < matrix.row_size(i))
00362 ? matrix[i][j]
00363 : matrix[coherent_index(j)][coherent_index(i)];
00364 }
00365
00366 template <typename T>
00367 inline typename Octagonal_Shape<T>::coefficient_type&
00368 Octagonal_Shape<T>::matrix_at(const dimension_type i,
00369 const dimension_type j) {
00370 PPL_ASSERT(i < matrix.num_rows() && j < matrix.num_rows());
00371 using namespace Implementation::Octagonal_Shapes;
00372 return (j < matrix.row_size(i))
00373 ? matrix[i][j]
00374 : matrix[coherent_index(j)][coherent_index(i)];
00375 }
00376
00377 template <typename T>
00378 inline Constraint_System
00379 Octagonal_Shape<T>::minimized_constraints() const {
00380 strong_reduction_assign();
00381 return constraints();
00382 }
00383
00384 template <typename T>
00385 inline void
00386 Octagonal_Shape<T>::add_octagonal_constraint(const dimension_type i,
00387 const dimension_type j,
00388 const N& k) {
00389
00390 #ifndef NDEBUG
00391 PPL_ASSERT(i < 2*space_dim && j < 2*space_dim && i != j);
00392 typename OR_Matrix<N>::row_iterator m_i = matrix.row_begin() + i;
00393 PPL_ASSERT(j < m_i.row_size());
00394 #endif
00395 N& r_i_j = matrix[i][j];
00396 if (r_i_j > k) {
00397 r_i_j = k;
00398 if (marked_strongly_closed())
00399 reset_strongly_closed();
00400 }
00401 }
00402
00403 template <typename T>
00404 inline void
00405 Octagonal_Shape<T>
00406 ::add_octagonal_constraint(const dimension_type i,
00407 const dimension_type j,
00408 Coefficient_traits::const_reference num,
00409 Coefficient_traits::const_reference den) {
00410 #ifndef NDEBUG
00411
00412 PPL_ASSERT(i < 2*space_dim && j < 2*space_dim && i != j);
00413 typename OR_Matrix<N>::row_iterator m_i = matrix.row_begin() + i;
00414 PPL_ASSERT(j < m_i.row_size());
00415 PPL_ASSERT(den != 0);
00416 #endif
00417 PPL_DIRTY_TEMP(N, k);
00418 div_round_up(k, num, den);
00419 add_octagonal_constraint(i, j, k);
00420 }
00421
00422 template <typename T>
00423 inline void
00424 Octagonal_Shape<T>::add_constraints(const Constraint_System& cs) {
00425 for (Constraint_System::const_iterator i = cs.begin(),
00426 i_end = cs.end(); i != i_end; ++i)
00427 add_constraint(*i);
00428 }
00429
00430 template <typename T>
00431 inline void
00432 Octagonal_Shape<T>::add_recycled_constraints(Constraint_System& cs) {
00433 add_constraints(cs);
00434 }
00435
00436 template <typename T>
00437 inline void
00438 Octagonal_Shape<T>::add_recycled_congruences(Congruence_System& cgs) {
00439 add_congruences(cgs);
00440 }
00441
00442 template <typename T>
00443 inline void
00444 Octagonal_Shape<T>::add_congruences(const Congruence_System& cgs) {
00445 for (Congruence_System::const_iterator i = cgs.begin(),
00446 cgs_end = cgs.end(); i != cgs_end; ++i)
00447 add_congruence(*i);
00448 }
00449
00450 template <typename T>
00451 inline void
00452 Octagonal_Shape<T>::refine_with_constraint(const Constraint& c) {
00453
00454 if (c.space_dimension() > space_dimension())
00455 throw_dimension_incompatible("refine_with_constraint(c)", c);
00456
00457 if (!marked_empty())
00458 refine_no_check(c);
00459 }
00460
00461 template <typename T>
00462 inline void
00463 Octagonal_Shape<T>::refine_with_constraints(const Constraint_System& cs) {
00464
00465 if (cs.space_dimension() > space_dimension())
00466 throw_generic("refine_with_constraints(cs)",
00467 "cs and *this are space-dimension incompatible");
00468
00469 for (Constraint_System::const_iterator i = cs.begin(),
00470 cs_end = cs.end(); !marked_empty() && i != cs_end; ++i)
00471 refine_no_check(*i);
00472 }
00473
00474 template <typename T>
00475 inline void
00476 Octagonal_Shape<T>::refine_with_congruence(const Congruence& cg) {
00477 const dimension_type cg_space_dim = cg.space_dimension();
00478
00479 if (cg_space_dim > space_dimension())
00480 throw_dimension_incompatible("refine_with_congruence(cg)", cg);
00481
00482 if (!marked_empty())
00483 refine_no_check(cg);
00484 }
00485
00486 template <typename T>
00487 void
00488 Octagonal_Shape<T>::refine_with_congruences(const Congruence_System& cgs) {
00489
00490 if (cgs.space_dimension() > space_dimension())
00491 throw_generic("refine_with_congruences(cgs)",
00492 "cgs and *this are space-dimension incompatible");
00493
00494 for (Congruence_System::const_iterator i = cgs.begin(),
00495 cgs_end = cgs.end(); !marked_empty() && i != cgs_end; ++i)
00496 refine_no_check(*i);
00497 }
00498
00499 template <typename T>
00500 inline void
00501 Octagonal_Shape<T>::refine_no_check(const Congruence& cg) {
00502 PPL_ASSERT(!marked_empty());
00503 PPL_ASSERT(cg.space_dimension() <= space_dimension());
00504
00505 if (cg.is_proper_congruence()) {
00506 if (cg.is_inconsistent())
00507 set_empty();
00508
00509 return;
00510 }
00511
00512 PPL_ASSERT(cg.is_equality());
00513 Constraint c(cg);
00514 refine_no_check(c);
00515 }
00516
00517 template <typename T>
00518 inline bool
00519 Octagonal_Shape<T>::can_recycle_constraint_systems() {
00520 return false;
00521 }
00522
00523 template <typename T>
00524 inline bool
00525 Octagonal_Shape<T>::can_recycle_congruence_systems() {
00526 return false;
00527 }
00528
00529 template <typename T>
00530 inline void
00531 Octagonal_Shape<T>
00532 ::remove_higher_space_dimensions(const dimension_type new_dimension) {
00533
00534 if (new_dimension > space_dim)
00535 throw_dimension_incompatible("remove_higher_space_dimension(nd)",
00536 new_dimension);
00537
00538
00539
00540 if (new_dimension == space_dim) {
00541 PPL_ASSERT(OK());
00542 return;
00543 }
00544
00545 strong_closure_assign();
00546 matrix.shrink(new_dimension);
00547
00548
00549 if (new_dimension == 0 && !marked_empty())
00550 set_zero_dim_univ();
00551 space_dim = new_dimension;
00552 PPL_ASSERT(OK());
00553 }
00554
00555 template <typename T>
00556 void
00557 Octagonal_Shape<T>::wrap_assign(const Variables_Set& vars,
00558 Bounded_Integer_Type_Width w,
00559 Bounded_Integer_Type_Representation r,
00560 Bounded_Integer_Type_Overflow o,
00561 const Constraint_System* pcs,
00562 unsigned complexity_threshold,
00563 bool wrap_individually) {
00564 Implementation::wrap_assign(*this,
00565 vars, w, r, o, pcs,
00566 complexity_threshold, wrap_individually,
00567 "Octagonal_Shape");
00568 }
00569
00570 template <typename T>
00571 inline void
00572 Octagonal_Shape<T>::widening_assign(const Octagonal_Shape& y, unsigned* tp) {
00573 BHMZ05_widening_assign(y, tp);
00574 }
00575
00576 template <typename T>
00577 inline void
00578 Octagonal_Shape<T>::CC76_extrapolation_assign(const Octagonal_Shape& y,
00579 unsigned* tp) {
00580 static N stop_points[] = {
00581 N(-2, ROUND_UP),
00582 N(-1, ROUND_UP),
00583 N( 0, ROUND_UP),
00584 N( 1, ROUND_UP),
00585 N( 2, ROUND_UP)
00586 };
00587 CC76_extrapolation_assign(y,
00588 stop_points,
00589 stop_points
00590 + sizeof(stop_points)/sizeof(stop_points[0]),
00591 tp);
00592 }
00593
00594 template <typename T>
00595 inline void
00596 Octagonal_Shape<T>::time_elapse_assign(const Octagonal_Shape& y) {
00597
00598 if (space_dimension() != y.space_dimension())
00599 throw_dimension_incompatible("time_elapse_assign(y)", y);
00600
00601 C_Polyhedron px(constraints());
00602 C_Polyhedron py(y.constraints());
00603 px.time_elapse_assign(py);
00604 Octagonal_Shape<T> x(px);
00605 swap(x);
00606 PPL_ASSERT(OK());
00607 }
00608
00609 template <typename T>
00610 inline bool
00611 Octagonal_Shape<T>::strictly_contains(const Octagonal_Shape& y) const {
00612 const Octagonal_Shape<T>& x = *this;
00613 return x.contains(y) && !y.contains(x);
00614 }
00615
00617 template <typename Temp, typename To, typename T>
00618 inline bool
00619 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00620 const Octagonal_Shape<T>& x,
00621 const Octagonal_Shape<T>& y,
00622 const Rounding_Dir dir,
00623 Temp& tmp0,
00624 Temp& tmp1,
00625 Temp& tmp2) {
00626
00627 if (x.space_dim != y.space_dim)
00628 return false;
00629
00630
00631 if (x.space_dim == 0) {
00632 if (x.marked_empty() == y.marked_empty())
00633 assign_r(r, 0, ROUND_NOT_NEEDED);
00634 else
00635 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00636 return true;
00637 }
00638
00639
00640 x.strong_closure_assign();
00641 y.strong_closure_assign();
00642
00643
00644
00645 if (x.marked_empty() || y.marked_empty()) {
00646 if (x.marked_empty() == y.marked_empty())
00647 assign_r(r, 0, ROUND_NOT_NEEDED);
00648 else
00649 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00650 return true;
00651 }
00652
00653 return rectilinear_distance_assign(r, x.matrix, y.matrix, dir,
00654 tmp0, tmp1, tmp2);
00655 }
00656
00658 template <typename Temp, typename To, typename T>
00659 inline bool
00660 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00661 const Octagonal_Shape<T>& x,
00662 const Octagonal_Shape<T>& y,
00663 const Rounding_Dir dir) {
00664 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
00665 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
00666 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
00667 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
00668 return rectilinear_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
00669 }
00670
00672 template <typename To, typename T>
00673 inline bool
00674 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00675 const Octagonal_Shape<T>& x,
00676 const Octagonal_Shape<T>& y,
00677 const Rounding_Dir dir) {
00678 return rectilinear_distance_assign<To, To, T>(r, x, y, dir);
00679 }
00680
00682 template <typename Temp, typename To, typename T>
00683 inline bool
00684 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00685 const Octagonal_Shape<T>& x,
00686 const Octagonal_Shape<T>& y,
00687 const Rounding_Dir dir,
00688 Temp& tmp0,
00689 Temp& tmp1,
00690 Temp& tmp2) {
00691
00692 if (x.space_dim != y.space_dim)
00693 return false;
00694
00695
00696 if (x.space_dim == 0) {
00697 if (x.marked_empty() == y.marked_empty())
00698 assign_r(r, 0, ROUND_NOT_NEEDED);
00699 else
00700 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00701 return true;
00702 }
00703
00704
00705 x.strong_closure_assign();
00706 y.strong_closure_assign();
00707
00708
00709
00710 if (x.marked_empty() || y.marked_empty()) {
00711 if (x.marked_empty() == y.marked_empty())
00712 assign_r(r, 0, ROUND_NOT_NEEDED);
00713 else
00714 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00715 return true;
00716 }
00717
00718 return euclidean_distance_assign(r, x.matrix, y.matrix, dir,
00719 tmp0, tmp1, tmp2);
00720 }
00721
00723 template <typename Temp, typename To, typename T>
00724 inline bool
00725 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00726 const Octagonal_Shape<T>& x,
00727 const Octagonal_Shape<T>& y,
00728 const Rounding_Dir dir) {
00729 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
00730 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
00731 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
00732 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
00733 return euclidean_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
00734 }
00735
00737 template <typename To, typename T>
00738 inline bool
00739 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00740 const Octagonal_Shape<T>& x,
00741 const Octagonal_Shape<T>& y,
00742 const Rounding_Dir dir) {
00743 return euclidean_distance_assign<To, To, T>(r, x, y, dir);
00744 }
00745
00747 template <typename Temp, typename To, typename T>
00748 inline bool
00749 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00750 const Octagonal_Shape<T>& x,
00751 const Octagonal_Shape<T>& y,
00752 const Rounding_Dir dir,
00753 Temp& tmp0,
00754 Temp& tmp1,
00755 Temp& tmp2) {
00756
00757 if (x.space_dim != y.space_dim)
00758 return false;
00759
00760
00761 if (x.space_dim == 0) {
00762 if (x.marked_empty() == y.marked_empty())
00763 assign_r(r, 0, ROUND_NOT_NEEDED);
00764 else
00765 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00766 return true;
00767 }
00768
00769
00770 x.strong_closure_assign();
00771 y.strong_closure_assign();
00772
00773
00774
00775 if (x.marked_empty() || y.marked_empty()) {
00776 if (x.marked_empty() == y.marked_empty())
00777 assign_r(r, 0, ROUND_NOT_NEEDED);
00778 else
00779 assign_r(r, PLUS_INFINITY, ROUND_NOT_NEEDED);
00780 return true;
00781 }
00782
00783 return l_infinity_distance_assign(r, x.matrix, y.matrix, dir,
00784 tmp0, tmp1, tmp2);
00785 }
00786
00788 template <typename Temp, typename To, typename T>
00789 inline bool
00790 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00791 const Octagonal_Shape<T>& x,
00792 const Octagonal_Shape<T>& y,
00793 const Rounding_Dir dir) {
00794 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
00795 PPL_DIRTY_TEMP(Checked_Temp, tmp0);
00796 PPL_DIRTY_TEMP(Checked_Temp, tmp1);
00797 PPL_DIRTY_TEMP(Checked_Temp, tmp2);
00798 return l_infinity_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
00799 }
00800
00802 template <typename To, typename T>
00803 inline bool
00804 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00805 const Octagonal_Shape<T>& x,
00806 const Octagonal_Shape<T>& y,
00807 const Rounding_Dir dir) {
00808 return l_infinity_distance_assign<To, To, T>(r, x, y, dir);
00809 }
00810
00811 template <typename T>
00812 inline memory_size_type
00813 Octagonal_Shape<T>::total_memory_in_bytes() const {
00814 return sizeof(*this) + external_memory_in_bytes();
00815 }
00816
00817 template <typename T>
00818 inline int32_t
00819 Octagonal_Shape<T>::hash_code() const {
00820 return space_dimension() & 0x7fffffff;
00821 }
00822
00823 template <typename T>
00824 inline void
00825 Octagonal_Shape<T>::drop_some_non_integer_points_helper(N& elem) {
00826 if (!is_integer(elem)) {
00827 #ifndef NDEBUG
00828 Result r =
00829 #endif
00830 floor_assign_r(elem, elem, ROUND_DOWN);
00831 PPL_ASSERT(r == V_EQ);
00832 reset_strongly_closed();
00833 }
00834 }
00835
00836 }
00837
00838 namespace std {
00839
00841 template <typename T>
00842 inline void
00843 swap(Parma_Polyhedra_Library::Octagonal_Shape<T>& x,
00844 Parma_Polyhedra_Library::Octagonal_Shape<T>& y) {
00845 x.swap(y);
00846 }
00847
00848 }
00849
00850 #endif // !defined(PPL_Octagonal_Shape_inlines_hh)