1 /* Octagonal_Shape class declaration. 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5 This file is part of the Parma Polyhedra Library (PPL). 6 7 The PPL is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The PPL is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21 For the most up-to-date information see the Parma Polyhedra Library 22 site: http://bugseng.com/products/ppl/ . */ 23 24 #ifndef PPL_Octagonal_Shape_defs_hh 25 #define PPL_Octagonal_Shape_defs_hh 1 26 27 #include "Octagonal_Shape_types.hh" 28 #include "globals_types.hh" 29 #include "Constraint_types.hh" 30 #include "Generator_types.hh" 31 #include "Congruence_types.hh" 32 #include "Linear_Expression_types.hh" 33 #include "Constraint_System_types.hh" 34 #include "Generator_System_types.hh" 35 #include "Congruence_System_types.hh" 36 #include "OR_Matrix_defs.hh" 37 #include "Poly_Con_Relation_defs.hh" 38 #include "Poly_Gen_Relation_defs.hh" 39 #include "Polyhedron_types.hh" 40 #include "Box_types.hh" 41 #include "Grid_types.hh" 42 #include "BD_Shape_types.hh" 43 #include "Variable_defs.hh" 44 #include "Variables_Set_types.hh" 45 #include "Checked_Number_defs.hh" 46 #include "WRD_coefficient_types_defs.hh" 47 #include "Bit_Row_defs.hh" 48 #include "Interval_types.hh" 49 #include "Linear_Form_types.hh" 50 #include <vector> 51 #include <cstddef> 52 #include <climits> 53 #include <iosfwd> 54 55 namespace Parma_Polyhedra_Library { 56 57 namespace IO_Operators { 58 59 //! Output operator. 60 /*! \relates Parma_Polyhedra_Library::Octagonal_Shape 61 Writes a textual representation of \p oct on \p s: 62 <CODE>false</CODE> is written if \p oct is an empty polyhedron; 63 <CODE>true</CODE> is written if \p oct is a universe polyhedron; 64 a system of constraints defining \p oct is written otherwise, 65 all constraints separated by ", ". 66 */ 67 template <typename T> 68 std::ostream& 69 operator<<(std::ostream& s, const Octagonal_Shape<T>& oct); 70 71 } // namespace IO_Operators 72 73 //! Swaps \p x with \p y. 74 /*! \relates Octagonal_Shape */ 75 template <typename T> 76 void swap(Octagonal_Shape<T>& x, Octagonal_Shape<T>& y); 77 78 /*! \brief 79 Returns <CODE>true</CODE> if and only if \p x and \p y are the same octagon. 80 81 \relates Octagonal_Shape 82 Note that \p x and \p y may be dimension-incompatible shapes: 83 in this case, the value <CODE>false</CODE> is returned. 84 */ 85 template <typename T> 86 bool operator==(const Octagonal_Shape<T>& x, const Octagonal_Shape<T>& y); 87 88 /*! \brief 89 Returns <CODE>true</CODE> if and only if \p x and \p y are different shapes. 90 91 \relates Octagonal_Shape 92 Note that \p x and \p y may be dimension-incompatible shapes: 93 in this case, the value <CODE>true</CODE> is returned. 94 */ 95 template <typename T> 96 bool operator!=(const Octagonal_Shape<T>& x, const Octagonal_Shape<T>& y); 97 98 //! Computes the rectilinear (or Manhattan) distance between \p x and \p y. 99 /*! \relates Octagonal_Shape 100 If the rectilinear distance between \p x and \p y is defined, 101 stores an approximation of it into \p r and returns <CODE>true</CODE>; 102 returns <CODE>false</CODE> otherwise. 103 104 The direction of the approximation is specified by \p dir. 105 106 All computations are performed using variables of type 107 <CODE>Checked_Number\<To, Extended_Number_Policy\></CODE>. 108 */ 109 template <typename To, typename T> 110 bool rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 111 const Octagonal_Shape<T>& x, 112 const Octagonal_Shape<T>& y, 113 Rounding_Dir dir); 114 115 //! Computes the rectilinear (or Manhattan) distance between \p x and \p y. 116 /*! \relates Octagonal_Shape 117 If the rectilinear distance between \p x and \p y is defined, 118 stores an approximation of it into \p r and returns <CODE>true</CODE>; 119 returns <CODE>false</CODE> otherwise. 120 121 The direction of the approximation is specified by \p dir. 122 123 All computations are performed using variables of type 124 <CODE>Checked_Number\<Temp, Extended_Number_Policy\></CODE>. 125 */ 126 template <typename Temp, typename To, typename T> 127 bool rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 128 const Octagonal_Shape<T>& x, 129 const Octagonal_Shape<T>& y, 130 Rounding_Dir dir); 131 132 //! Computes the rectilinear (or Manhattan) distance between \p x and \p y. 133 /*! \relates Octagonal_Shape 134 If the rectilinear distance between \p x and \p y is defined, 135 stores an approximation of it into \p r and returns <CODE>true</CODE>; 136 returns <CODE>false</CODE> otherwise. 137 138 The direction of the approximation is specified by \p dir. 139 140 All computations are performed using the temporary variables 141 \p tmp0, \p tmp1 and \p tmp2. 142 */ 143 template <typename Temp, typename To, typename T> 144 bool rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 145 const Octagonal_Shape<T>& x, 146 const Octagonal_Shape<T>& y, 147 Rounding_Dir dir, 148 Temp& tmp0, 149 Temp& tmp1, 150 Temp& tmp2); 151 152 //! Computes the euclidean distance between \p x and \p y. 153 /*! \relates Octagonal_Shape 154 If the euclidean distance between \p x and \p y is defined, 155 stores an approximation of it into \p r and returns <CODE>true</CODE>; 156 returns <CODE>false</CODE> otherwise. 157 158 The direction of the approximation is specified by \p dir. 159 160 All computations are performed using variables of type 161 <CODE>Checked_Number\<To, Extended_Number_Policy\></CODE>. 162 */ 163 template <typename To, typename T> 164 bool euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 165 const Octagonal_Shape<T>& x, 166 const Octagonal_Shape<T>& y, 167 Rounding_Dir dir); 168 169 //! Computes the euclidean distance between \p x and \p y. 170 /*! \relates Octagonal_Shape 171 If the euclidean distance between \p x and \p y is defined, 172 stores an approximation of it into \p r and returns <CODE>true</CODE>; 173 returns <CODE>false</CODE> otherwise. 174 175 The direction of the approximation is specified by \p dir. 176 177 All computations are performed using variables of type 178 <CODE>Checked_Number\<Temp, Extended_Number_Policy\></CODE>. 179 */ 180 template <typename Temp, typename To, typename T> 181 bool euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 182 const Octagonal_Shape<T>& x, 183 const Octagonal_Shape<T>& y, 184 Rounding_Dir dir); 185 186 //! Computes the euclidean distance between \p x and \p y. 187 /*! \relates Octagonal_Shape 188 If the euclidean distance between \p x and \p y is defined, 189 stores an approximation of it into \p r and returns <CODE>true</CODE>; 190 returns <CODE>false</CODE> otherwise. 191 192 The direction of the approximation is specified by \p dir. 193 194 All computations are performed using the temporary variables 195 \p tmp0, \p tmp1 and \p tmp2. 196 */ 197 template <typename Temp, typename To, typename T> 198 bool euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 199 const Octagonal_Shape<T>& x, 200 const Octagonal_Shape<T>& y, 201 Rounding_Dir dir, 202 Temp& tmp0, 203 Temp& tmp1, 204 Temp& tmp2); 205 206 //! Computes the \f$L_\infty\f$ distance between \p x and \p y. 207 /*! \relates Octagonal_Shape 208 If the \f$L_\infty\f$ distance between \p x and \p y is defined, 209 stores an approximation of it into \p r and returns <CODE>true</CODE>; 210 returns <CODE>false</CODE> otherwise. 211 212 The direction of the approximation is specified by \p dir. 213 214 All computations are performed using variables of type 215 <CODE>Checked_Number\<To, Extended_Number_Policy\></CODE>. 216 */ 217 template <typename To, typename T> 218 bool l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 219 const Octagonal_Shape<T>& x, 220 const Octagonal_Shape<T>& y, 221 Rounding_Dir dir); 222 223 //! Computes the \f$L_\infty\f$ distance between \p x and \p y. 224 /*! \relates Octagonal_Shape 225 If the \f$L_\infty\f$ distance between \p x and \p y is defined, 226 stores an approximation of it into \p r and returns <CODE>true</CODE>; 227 returns <CODE>false</CODE> otherwise. 228 229 The direction of the approximation is specified by \p dir. 230 231 All computations are performed using variables of type 232 <CODE>Checked_Number\<Temp, Extended_Number_Policy\></CODE>. 233 */ 234 template <typename Temp, typename To, typename T> 235 bool l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 236 const Octagonal_Shape<T>& x, 237 const Octagonal_Shape<T>& y, 238 Rounding_Dir dir); 239 240 //! Computes the \f$L_\infty\f$ distance between \p x and \p y. 241 /*! \relates Octagonal_Shape 242 If the \f$L_\infty\f$ distance between \p x and \p y is defined, 243 stores an approximation of it into \p r and returns <CODE>true</CODE>; 244 returns <CODE>false</CODE> otherwise. 245 246 The direction of the approximation is specified by \p dir. 247 248 All computations are performed using the temporary variables 249 \p tmp0, \p tmp1 and \p tmp2. 250 */ 251 template <typename Temp, typename To, typename T> 252 bool l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 253 const Octagonal_Shape<T>& x, 254 const Octagonal_Shape<T>& y, 255 Rounding_Dir dir, 256 Temp& tmp0, 257 Temp& tmp1, 258 Temp& tmp2); 259 260 // This class contains some helper functions that need to be friends of 261 // Linear_Expression. 262 class Octagonal_Shape_Helper { 263 public: 264 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 265 //! Decodes the constraint \p c as an octagonal difference. 266 /*! \relates Octagonal_Shape 267 \return 268 <CODE>true</CODE> if the constraint \p c is an octagonal difference; 269 <CODE>false</CODE> otherwise. 270 271 \param c 272 The constraint to be decoded. 273 274 \param c_space_dim 275 The space dimension of the constraint \p c (it is <EM>assumed</EM> 276 to match the actual space dimension of \p c). 277 278 \param c_num_vars 279 If <CODE>true</CODE> is returned, then it will be set to the number 280 of variables having a non-zero coefficient. The only legal values 281 will therefore be 0, 1 and 2. 282 283 \param c_first_var 284 If <CODE>true</CODE> is returned and if \p c_num_vars is not set to 0, 285 then it will be set to the index of the first variable having 286 a non-zero coefficient in \p c. 287 288 \param c_second_var 289 If <CODE>true</CODE> is returned and if \p c_num_vars is set to 2, 290 then it will be set to the index of the second variable having 291 a non-zero coefficient in \p c. 292 293 \param c_coeff 294 If <CODE>true</CODE> is returned and if \p c_num_vars is not set to 0, 295 then it will be set to the value of the first non-zero coefficient 296 in \p c. 297 298 \param c_term 299 If <CODE>true</CODE> is returned and if \p c_num_vars is not set to 0, 300 then it will be set to the right value of the inhomogeneous term 301 of \p c. 302 */ 303 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS) 304 static bool extract_octagonal_difference(const Constraint& c, 305 dimension_type c_space_dim, 306 dimension_type& c_num_vars, 307 dimension_type& c_first_var, 308 dimension_type& c_second_var, 309 Coefficient& c_coeff, 310 Coefficient& c_term); 311 }; 312 313 } // namespace Parma_Polyhedra_Library 314 315 //! An octagonal shape. 316 /*! \ingroup PPL_CXX_interface 317 The class template Octagonal_Shape<T> allows for the efficient 318 representation of a restricted kind of <EM>topologically closed</EM> 319 convex polyhedra called <EM>octagonal shapes</EM> (OSs, for short). 320 The name comes from the fact that, in a vector space of dimension 2, 321 bounded OSs are polygons with at most eight sides. 322 The closed affine half-spaces that characterize the OS can be expressed 323 by constraints of the form 324 \f[ 325 ax_i + bx_j \leq k 326 \f] 327 where \f$a, b \in \{-1, 0, 1\}\f$ and \f$k\f$ is a rational number, 328 which are called <EM>octagonal constraints</EM>. 329 330 Based on the class template type parameter \p T, a family of extended 331 numbers is built and used to approximate the inhomogeneous term of 332 octagonal constraints. These extended numbers provide a representation 333 for the value \f$+\infty\f$, as well as <EM>rounding-aware</EM> 334 implementations for several arithmetic functions. 335 The value of the type parameter \p T may be one of the following: 336 - a bounded precision integer type (e.g., \c int32_t or \c int64_t); 337 - a bounded precision floating point type (e.g., \c float or \c double); 338 - an unbounded integer or rational type, as provided by GMP 339 (i.e., \c mpz_class or \c mpq_class). 340 341 The user interface for OSs is meant to be as similar as possible to 342 the one developed for the polyhedron class C_Polyhedron. 343 344 The OS domain <EM>optimally supports</EM>: 345 - tautological and inconsistent constraints and congruences; 346 - octagonal constraints; 347 - non-proper congruences (i.e., equalities) that are expressible 348 as octagonal constraints. 349 350 Depending on the method, using a constraint or congruence that is not 351 optimally supported by the domain will either raise an exception or 352 result in a (possibly non-optimal) upward approximation. 353 354 A constraint is octagonal if it has the form 355 \f[ 356 \pm a_i x_i \pm a_j x_j \relsym b 357 \f] 358 where \f$\mathord{\relsym} \in \{ \leq, =, \geq \}\f$ and 359 \f$a_i\f$, \f$a_j\f$, \f$b\f$ are integer coefficients such that 360 \f$a_i = 0\f$, or \f$a_j = 0\f$, or \f$a_i = a_j\f$. 361 The user is warned that the above octagonal Constraint object 362 will be mapped into a \e correct and \e optimal approximation that, 363 depending on the expressive power of the chosen template argument \p T, 364 may loose some precision. 365 Also note that strict constraints are not octagonal. 366 367 For instance, a Constraint object encoding \f$3x + 3y \leq 1\f$ will be 368 approximated by: 369 - \f$x + y \leq 1\f$, 370 if \p T is a (bounded or unbounded) integer type; 371 - \f$x + y \leq \frac{1}{3}\f$, 372 if \p T is the unbounded rational type \c mpq_class; 373 - \f$x + y \leq k\f$, where \f$k > \frac{1}{3}\f$, 374 if \p T is a floating point type (having no exact representation 375 for \f$\frac{1}{3}\f$). 376 377 On the other hand, depending from the context, a Constraint object 378 encoding \f$3x - y \leq 1\f$ will be either upward approximated 379 (e.g., by safely ignoring it) or it will cause an exception. 380 381 In the following examples it is assumed that the type argument \p T 382 is one of the possible instances listed above and that variables 383 \c x, \c y and \c z are defined (where they are used) as follows: 384 \code 385 Variable x(0); 386 Variable y(1); 387 Variable z(2); 388 \endcode 389 390 \par Example 1 391 The following code builds an OS corresponding to a cube in \f$\Rset^3\f$, 392 given as a system of constraints: 393 \code 394 Constraint_System cs; 395 cs.insert(x >= 0); 396 cs.insert(x <= 3); 397 cs.insert(y >= 0); 398 cs.insert(y <= 3); 399 cs.insert(z >= 0); 400 cs.insert(z <= 3); 401 Octagonal_Shape<T> oct(cs); 402 \endcode 403 In contrast, the following code will raise an exception, 404 since constraints 7, 8, and 9 are not octagonal: 405 \code 406 Constraint_System cs; 407 cs.insert(x >= 0); 408 cs.insert(x <= 3); 409 cs.insert(y >= 0); 410 cs.insert(y <= 3); 411 cs.insert(z >= 0); 412 cs.insert(z <= 3); 413 cs.insert(x - 3*y <= 5); // (7) 414 cs.insert(x - y + z <= 5); // (8) 415 cs.insert(x + y + z <= 5); // (9) 416 Octagonal_Shape<T> oct(cs); 417 \endcode 418 */ 419 template <typename T> 420 class Parma_Polyhedra_Library::Octagonal_Shape { 421 private: 422 /*! \brief 423 The (extended) numeric type of the inhomogeneous term of 424 the inequalities defining an OS. 425 */ 426 #ifndef NDEBUG 427 typedef Checked_Number<T, Debug_WRD_Extended_Number_Policy> N; 428 #else 429 typedef Checked_Number<T, WRD_Extended_Number_Policy> N; 430 #endif 431 432 public: 433 434 //! The numeric base type upon which OSs are built. 435 typedef T coefficient_type_base; 436 437 /*! \brief 438 The (extended) numeric type of the inhomogeneous term of the 439 inequalities defining an OS. 440 */ 441 typedef N coefficient_type; 442 443 //! Returns the maximum space dimension that an OS can handle. 444 static dimension_type max_space_dimension(); 445 446 /*! \brief 447 Returns false indicating that this domain cannot recycle constraints 448 */ 449 static bool can_recycle_constraint_systems(); 450 451 /*! \brief 452 Returns false indicating that this domain cannot recycle congruences 453 */ 454 static bool can_recycle_congruence_systems(); 455 456 //! \name Constructors, Assignment, Swap and Destructor 457 //@{ 458 459 //! Builds an universe or empty OS of the specified space dimension. 460 /*! 461 \param num_dimensions 462 The number of dimensions of the vector space enclosing the OS; 463 464 \param kind 465 Specifies whether the universe or the empty OS has to be built. 466 */ 467 explicit Octagonal_Shape(dimension_type num_dimensions = 0, 468 Degenerate_Element kind = UNIVERSE); 469 470 //! Ordinary copy constructor. 471 /*! 472 The complexity argument is ignored. 473 */ 474 Octagonal_Shape(const Octagonal_Shape& y, 475 Complexity_Class complexity = ANY_COMPLEXITY); 476 477 //! Builds a conservative, upward approximation of \p y. 478 /*! 479 The complexity argument is ignored. 480 */ 481 template <typename U> 482 explicit Octagonal_Shape(const Octagonal_Shape<U>& y, 483 Complexity_Class complexity = ANY_COMPLEXITY); 484 485 //! Builds an OS from the system of constraints \p cs. 486 /*! 487 The OS inherits the space dimension of \p cs. 488 489 \param cs 490 A system of octagonal constraints. 491 492 \exception std::invalid_argument 493 Thrown if \p cs contains a constraint which is not optimally supported 494 by the Octagonal shape domain. 495 */ 496 explicit Octagonal_Shape(const Constraint_System& cs); 497 498 //! Builds an OS from a system of congruences. 499 /*! 500 The OS inherits the space dimension of \p cgs 501 502 \param cgs 503 A system of congruences. 504 505 \exception std::invalid_argument 506 Thrown if \p cgs contains a congruence which is not optimally supported 507 by the Octagonal shape domain. 508 */ 509 explicit Octagonal_Shape(const Congruence_System& cgs); 510 511 //! Builds an OS from the system of generators \p gs. 512 /*! 513 Builds the smallest OS containing the polyhedron defined by \p gs. 514 The OS inherits the space dimension of \p gs. 515 516 \exception std::invalid_argument 517 Thrown if the system of generators is not empty but has no points. 518 */ 519 explicit Octagonal_Shape(const Generator_System& gs); 520 521 //! Builds an OS from the polyhedron \p ph. 522 /*! 523 Builds an OS containing \p ph using algorithms whose complexity 524 does not exceed the one specified by \p complexity. If 525 \p complexity is \p ANY_COMPLEXITY, then the OS built is the 526 smallest one containing \p ph. 527 */ 528 explicit Octagonal_Shape(const Polyhedron& ph, 529 Complexity_Class complexity = ANY_COMPLEXITY); 530 531 //! Builds an OS out of a box. 532 /*! 533 The OS inherits the space dimension of the box. 534 The built OS is the most precise OS that includes the box. 535 536 \param box 537 The box representing the OS to be built. 538 539 \param complexity 540 This argument is ignored as the algorithm used has 541 polynomial complexity. 542 543 \exception std::length_error 544 Thrown if the space dimension of \p box exceeds the maximum 545 allowed space dimension. 546 */ 547 template <typename Interval> 548 explicit Octagonal_Shape(const Box<Interval>& box, 549 Complexity_Class complexity = ANY_COMPLEXITY); 550 551 //! Builds an OS that approximates a grid. 552 /*! 553 The OS inherits the space dimension of the grid. 554 The built OS is the most precise OS that includes the grid. 555 556 \param grid 557 The grid used to build the OS. 558 559 \param complexity 560 This argument is ignored as the algorithm used has 561 polynomial complexity. 562 563 \exception std::length_error 564 Thrown if the space dimension of \p grid exceeds the maximum 565 allowed space dimension. 566 */ 567 explicit Octagonal_Shape(const Grid& grid, 568 Complexity_Class complexity = ANY_COMPLEXITY); 569 570 //! Builds an OS from a BD shape. 571 /*! 572 The OS inherits the space dimension of the BD shape. 573 The built OS is the most precise OS that includes the BD shape. 574 575 \param bd 576 The BD shape used to build the OS. 577 578 \param complexity 579 This argument is ignored as the algorithm used has 580 polynomial complexity. 581 582 \exception std::length_error 583 Thrown if the space dimension of \p bd exceeds the maximum 584 allowed space dimension. 585 */ 586 template <typename U> 587 explicit Octagonal_Shape(const BD_Shape<U>& bd, 588 Complexity_Class complexity = ANY_COMPLEXITY); 589 590 /*! \brief 591 The assignment operator. 592 (\p *this and \p y can be dimension-incompatible.) 593 */ 594 Octagonal_Shape& operator=(const Octagonal_Shape& y); 595 596 /*! \brief 597 Swaps \p *this with octagon \p y. 598 (\p *this and \p y can be dimension-incompatible.) 599 */ 600 void m_swap(Octagonal_Shape& y); 601 602 //! Destructor. 603 ~Octagonal_Shape(); 604 605 //@} Constructors, Assignment, Swap and Destructor 606 607 //! \name Member Functions that Do Not Modify the Octagonal_Shape 608 //@{ 609 610 //! Returns the dimension of the vector space enclosing \p *this. 611 dimension_type space_dimension() const; 612 613 /*! \brief 614 Returns \f$0\f$, if \p *this is empty; otherwise, returns the 615 \ref Affine_Independence_and_Affine_Dimension "affine dimension" 616 of \p *this. 617 */ 618 dimension_type affine_dimension() const; 619 620 //! Returns the system of constraints defining \p *this. 621 Constraint_System constraints() const; 622 623 //! Returns a minimized system of constraints defining \p *this. 624 Constraint_System minimized_constraints() const; 625 626 //! Returns a system of (equality) congruences satisfied by \p *this. 627 Congruence_System congruences() const; 628 629 /*! \brief 630 Returns a minimal system of (equality) congruences 631 satisfied by \p *this with the same affine dimension as \p *this. 632 */ 633 Congruence_System minimized_congruences() const; 634 635 //! Returns <CODE>true</CODE> if and only if \p *this contains \p y. 636 /*! 637 \exception std::invalid_argument 638 Thrown if \p *this and \p y are dimension-incompatible. 639 */ 640 bool contains(const Octagonal_Shape& y) const; 641 642 //! Returns <CODE>true</CODE> if and only if \p *this strictly contains \p y. 643 /*! 644 \exception std::invalid_argument 645 Thrown if \p *this and \p y are dimension-incompatible. 646 */ 647 bool strictly_contains(const Octagonal_Shape& y) const; 648 649 //! Returns <CODE>true</CODE> if and only if \p *this and \p y are disjoint. 650 /*! 651 \exception std::invalid_argument 652 Thrown if \p x and \p y are topology-incompatible or 653 dimension-incompatible. 654 */ 655 bool is_disjoint_from(const Octagonal_Shape& y) const; 656 657 /*! \brief 658 Returns the relations holding between \p *this and the constraint \p c. 659 660 \exception std::invalid_argument 661 Thrown if \p *this and constraint \p c are dimension-incompatible. 662 */ 663 Poly_Con_Relation relation_with(const Constraint& c) const; 664 665 /*! \brief 666 Returns the relations holding between \p *this and the congruence \p cg. 667 668 \exception std::invalid_argument 669 Thrown if \p *this and \p cg are dimension-incompatible. 670 */ 671 Poly_Con_Relation relation_with(const Congruence& cg) const; 672 673 /*! \brief 674 Returns the relations holding between \p *this and the generator \p g. 675 676 \exception std::invalid_argument 677 Thrown if \p *this and generator \p g are dimension-incompatible. 678 */ 679 Poly_Gen_Relation relation_with(const Generator& g) const; 680 681 //! Returns <CODE>true</CODE> if and only if \p *this is an empty OS. 682 bool is_empty() const; 683 684 //! Returns <CODE>true</CODE> if and only if \p *this is a universe OS. 685 bool is_universe() const; 686 687 //! Returns <CODE>true</CODE> if and only if \p *this is discrete. 688 bool is_discrete() const; 689 690 /*! \brief 691 Returns <CODE>true</CODE> if and only if \p *this 692 is a bounded OS. 693 */ 694 bool is_bounded() const; 695 696 /*! \brief 697 Returns <CODE>true</CODE> if and only if \p *this 698 is a topologically closed subset of the vector space. 699 */ 700 bool is_topologically_closed() const; 701 702 /*! \brief 703 Returns <CODE>true</CODE> if and only if \p *this 704 contains (at least) an integer point. 705 */ 706 bool contains_integer_point() const; 707 708 /*! \brief 709 Returns <CODE>true</CODE> if and only if \p var is constrained in 710 \p *this. 711 712 \exception std::invalid_argument 713 Thrown if \p var is not a space dimension of \p *this. 714 */ 715 bool constrains(Variable var) const; 716 717 /*! \brief 718 Returns <CODE>true</CODE> if and only if \p expr is 719 bounded from above in \p *this. 720 721 \exception std::invalid_argument 722 Thrown if \p expr and \p *this are dimension-incompatible. 723 */ 724 bool bounds_from_above(const Linear_Expression& expr) const; 725 726 /*! \brief 727 Returns <CODE>true</CODE> if and only if \p expr is 728 bounded from below in \p *this. 729 730 \exception std::invalid_argument 731 Thrown if \p expr and \p *this are dimension-incompatible. 732 */ 733 bool bounds_from_below(const Linear_Expression& expr) const; 734 735 /*! \brief 736 Returns <CODE>true</CODE> if and only if \p *this is not empty 737 and \p expr is bounded from above in \p *this, in which case 738 the supremum value is computed. 739 740 \param expr 741 The linear expression to be maximized subject to \p *this; 742 743 \param sup_n 744 The numerator of the supremum value; 745 746 \param sup_d 747 The denominator of the supremum value; 748 749 \param maximum 750 <CODE>true</CODE> if and only if the supremum is also the maximum value. 751 752 \exception std::invalid_argument 753 Thrown if \p expr and \p *this are dimension-incompatible. 754 755 If \p *this is empty or \p expr is not bounded from above, 756 <CODE>false</CODE> is returned and \p sup_n, \p sup_d 757 and \p maximum are left untouched. 758 */ 759 bool maximize(const Linear_Expression& expr, 760 Coefficient& sup_n, Coefficient& sup_d, bool& maximum) const; 761 762 /*! \brief 763 Returns <CODE>true</CODE> if and only if \p *this is not empty 764 and \p expr is bounded from above in \p *this, in which case 765 the supremum value and a point where \p expr reaches it are computed. 766 767 \param expr 768 The linear expression to be maximized subject to \p *this; 769 770 \param sup_n 771 The numerator of the supremum value; 772 773 \param sup_d 774 The denominator of the supremum value; 775 776 \param maximum 777 <CODE>true</CODE> if and only if the supremum is also the maximum value; 778 779 \param g 780 When maximization succeeds, will be assigned the point or 781 closure point where \p expr reaches its supremum value. 782 783 \exception std::invalid_argument 784 Thrown if \p expr and \p *this are dimension-incompatible. 785 786 If \p *this is empty or \p expr is not bounded from above, 787 <CODE>false</CODE> is returned and \p sup_n, \p sup_d, \p maximum 788 and \p g are left untouched. 789 */ 790 bool maximize(const Linear_Expression& expr, 791 Coefficient& sup_n, Coefficient& sup_d, bool& maximum, 792 Generator& g) const; 793 794 /*! \brief 795 Returns <CODE>true</CODE> if and only if \p *this is not empty 796 and \p expr is bounded from below in \p *this, in which case 797 the infimum value is computed. 798 799 \param expr 800 The linear expression to be minimized subject to \p *this; 801 802 \param inf_n 803 The numerator of the infimum value; 804 805 \param inf_d 806 The denominator of the infimum value; 807 808 \param minimum 809 <CODE>true</CODE> if and only if the infimum is also the minimum value. 810 811 \exception std::invalid_argument 812 Thrown if \p expr and \p *this are dimension-incompatible. 813 814 If \p *this is empty or \p expr is not bounded from below, 815 <CODE>false</CODE> is returned and \p inf_n, \p inf_d 816 and \p minimum are left untouched. 817 */ 818 bool minimize(const Linear_Expression& expr, 819 Coefficient& inf_n, Coefficient& inf_d, bool& minimum) const; 820 821 /*! \brief 822 Returns <CODE>true</CODE> if and only if \p *this is not empty 823 and \p expr is bounded from below in \p *this, in which case 824 the infimum value and a point where \p expr reaches it are computed. 825 826 \param expr 827 The linear expression to be minimized subject to \p *this; 828 829 \param inf_n 830 The numerator of the infimum value; 831 832 \param inf_d 833 The denominator of the infimum value; 834 835 \param minimum 836 <CODE>true</CODE> if and only if the infimum is also the minimum value; 837 838 \param g 839 When minimization succeeds, will be assigned a point or 840 closure point where \p expr reaches its infimum value. 841 842 \exception std::invalid_argument 843 Thrown if \p expr and \p *this are dimension-incompatible. 844 845 If \p *this is empty or \p expr is not bounded from below, 846 <CODE>false</CODE> is returned and \p inf_n, \p inf_d, \p minimum 847 and \p g are left untouched. 848 */ 849 bool minimize(const Linear_Expression& expr, 850 Coefficient& inf_n, Coefficient& inf_d, bool& minimum, 851 Generator& g) const; 852 853 /*! \brief 854 Returns <CODE>true</CODE> if and only if there exist a 855 unique value \p val such that \p *this 856 saturates the equality <CODE>expr = val</CODE>. 857 858 \param expr 859 The linear expression for which the frequency is needed; 860 861 \param freq_n 862 If <CODE>true</CODE> is returned, the value is set to \f$0\f$; 863 Present for interface compatibility with class Grid, where 864 the \ref Grid_Frequency "frequency" can have a non-zero value; 865 866 \param freq_d 867 If <CODE>true</CODE> is returned, the value is set to \f$1\f$; 868 869 \param val_n 870 The numerator of \p val; 871 872 \param val_d 873 The denominator of \p val; 874 875 \exception std::invalid_argument 876 Thrown if \p expr and \p *this are dimension-incompatible. 877 878 If <CODE>false</CODE> is returned, then \p freq_n, \p freq_d, 879 \p val_n and \p val_d are left untouched. 880 */ 881 bool frequency(const Linear_Expression& expr, 882 Coefficient& freq_n, Coefficient& freq_d, 883 Coefficient& val_n, Coefficient& val_d) const; 884 885 //! Checks if all the invariants are satisfied. 886 bool OK() const; 887 888 //@} Member Functions that Do Not Modify the Octagonal_Shape 889 890 //! \name Space-Dimension Preserving Member Functions that May Modify the Octagonal_Shape 891 //@{ 892 893 /*! \brief 894 Adds a copy of constraint \p c to the system of constraints 895 defining \p *this. 896 897 \param c 898 The constraint to be added. 899 900 \exception std::invalid_argument 901 Thrown if \p *this and constraint \p c are dimension-incompatible, 902 or \p c is not optimally supported by the OS domain. 903 */ 904 void add_constraint(const Constraint& c); 905 906 /*! \brief 907 Adds the constraints in \p cs to the system of constraints 908 defining \p *this. 909 910 \param cs 911 The constraints that will be added. 912 913 \exception std::invalid_argument 914 Thrown if \p *this and \p cs are dimension-incompatible, 915 or \p cs contains a constraint which is not optimally supported 916 by the OS domain. 917 */ 918 void add_constraints(const Constraint_System& cs); 919 920 /*! \brief 921 Adds the constraints in \p cs to the system of constraints 922 of \p *this. 923 924 \param cs 925 The constraint system to be added to \p *this. The constraints in 926 \p cs may be recycled. 927 928 \exception std::invalid_argument 929 Thrown if \p *this and \p cs are dimension-incompatible, 930 or \p cs contains a constraint which is not optimally supported 931 by the OS domain. 932 933 \warning 934 The only assumption that can be made on \p cs upon successful or 935 exceptional return is that it can be safely destroyed. 936 */ 937 void add_recycled_constraints(Constraint_System& cs); 938 939 /*! \brief 940 Adds to \p *this a constraint equivalent to the congruence \p cg. 941 942 \param cg 943 The congruence to be added. 944 945 \exception std::invalid_argument 946 Thrown if \p *this and congruence \p cg are dimension-incompatible, 947 or \p cg is not optimally supported by the OS domain. 948 */ 949 void add_congruence(const Congruence& cg); 950 951 /*! \brief 952 Adds to \p *this constraints equivalent to the congruences in \p cgs. 953 954 \param cgs 955 The congruences to be added. 956 957 \exception std::invalid_argument 958 Thrown if \p *this and \p cgs are dimension-incompatible, 959 or \p cgs contains a congruence which is not optimally supported 960 by the OS domain. 961 */ 962 void add_congruences(const Congruence_System& cgs); 963 964 /*! \brief 965 Adds to \p *this constraints equivalent to the congruences in \p cgs. 966 967 \param cgs 968 The congruence system to be added to \p *this. The congruences in 969 \p cgs may be recycled. 970 971 \exception std::invalid_argument 972 Thrown if \p *this and \p cgs are dimension-incompatible, 973 or \p cgs contains a congruence which is not optimally supported 974 by the OS domain. 975 976 \warning 977 The only assumption that can be made on \p cgs upon successful or 978 exceptional return is that it can be safely destroyed. 979 */ 980 void add_recycled_congruences(Congruence_System& cgs); 981 982 /*! \brief 983 Uses a copy of constraint \p c to refine the system of octagonal 984 constraints defining \p *this. 985 986 \param c 987 The constraint. If it is not a octagonal constraint, it will be ignored. 988 989 \exception std::invalid_argument 990 Thrown if \p *this and constraint \p c are dimension-incompatible. 991 */ 992 void refine_with_constraint(const Constraint& c); 993 994 /*! \brief 995 Uses a copy of congruence \p cg to refine the system of 996 octagonal constraints of \p *this. 997 998 \param cg 999 The congruence. If it is not a octagonal equality, it 1000 will be ignored. 1001 1002 \exception std::invalid_argument 1003 Thrown if \p *this and congruence \p cg are dimension-incompatible. 1004 */ 1005 void refine_with_congruence(const Congruence& cg); 1006 1007 /*! \brief 1008 Uses a copy of the constraints in \p cs to refine the system of 1009 octagonal constraints defining \p *this. 1010 1011 \param cs 1012 The constraint system to be used. Constraints that are not octagonal 1013 are ignored. 1014 1015 \exception std::invalid_argument 1016 Thrown if \p *this and \p cs are dimension-incompatible. 1017 */ 1018 void refine_with_constraints(const Constraint_System& cs); 1019 1020 /*! \brief 1021 Uses a copy of the congruences in \p cgs to refine the system of 1022 octagonal constraints defining \p *this. 1023 1024 \param cgs 1025 The congruence system to be used. Congruences that are not octagonal 1026 equalities are ignored. 1027 1028 \exception std::invalid_argument 1029 Thrown if \p *this and \p cgs are dimension-incompatible. 1030 */ 1031 void refine_with_congruences(const Congruence_System& cgs); 1032 1033 /*! \brief 1034 Refines the system of octagonal constraints defining \p *this using 1035 the constraint expressed by \p left \f$\leq\f$ \p right. 1036 1037 \param left 1038 The linear form on intervals with floating point boundaries that 1039 is at the left of the comparison operator. All of its coefficients 1040 MUST be bounded. 1041 1042 \param right 1043 The linear form on intervals with floating point boundaries that 1044 is at the right of the comparison operator. All of its coefficients 1045 MUST be bounded. 1046 1047 \exception std::invalid_argument 1048 Thrown if \p left (or \p right) is dimension-incompatible with \p *this. 1049 1050 This function is used in abstract interpretation to model a filter 1051 that is generated by a comparison of two expressions that are correctly 1052 approximated by \p left and \p right respectively. 1053 */ 1054 template <typename Interval_Info> 1055 void refine_with_linear_form_inequality( 1056 const Linear_Form< Interval<T, Interval_Info> >& left, 1057 const Linear_Form< Interval<T, Interval_Info> >& right); 1058 1059 /*! \brief 1060 Refines the system of octagonal constraints defining \p *this using 1061 the constraint expressed by \p left \f$\relsym\f$ \p right, where 1062 \f$\relsym\f$ is the relation symbol specified by \p relsym. 1063 1064 \param left 1065 The linear form on intervals with floating point boundaries that 1066 is at the left of the comparison operator. All of its coefficients 1067 MUST be bounded. 1068 1069 \param right 1070 The linear form on intervals with floating point boundaries that 1071 is at the right of the comparison operator. All of its coefficients 1072 MUST be bounded. 1073 1074 \param relsym 1075 The relation symbol. 1076 1077 \exception std::invalid_argument 1078 Thrown if \p left (or \p right) is dimension-incompatible with \p *this. 1079 1080 \exception std::runtime_error 1081 Thrown if \p relsym is not a valid relation symbol. 1082 1083 This function is used in abstract interpretation to model a filter 1084 that is generated by a comparison of two expressions that are correctly 1085 approximated by \p left and \p right respectively. 1086 */ 1087 template <typename Interval_Info> 1088 void generalized_refine_with_linear_form_inequality( 1089 const Linear_Form< Interval<T, Interval_Info> >& left, 1090 const Linear_Form< Interval<T, Interval_Info> >& right, 1091 Relation_Symbol relsym); 1092 1093 /*! \brief 1094 Computes the \ref Cylindrification "cylindrification" of \p *this with 1095 respect to space dimension \p var, assigning the result to \p *this. 1096 1097 \param var 1098 The space dimension that will be unconstrained. 1099 1100 \exception std::invalid_argument 1101 Thrown if \p var is not a space dimension of \p *this. 1102 */ 1103 void unconstrain(Variable var); 1104 1105 /*! \brief 1106 Computes the \ref Cylindrification "cylindrification" of \p *this with 1107 respect to the set of space dimensions \p vars, 1108 assigning the result to \p *this. 1109 1110 \param vars 1111 The set of space dimension that will be unconstrained. 1112 1113 \exception std::invalid_argument 1114 Thrown if \p *this is dimension-incompatible with one of the 1115 Variable objects contained in \p vars. 1116 */ 1117 void unconstrain(const Variables_Set& vars); 1118 1119 //! Assigns to \p *this the intersection of \p *this and \p y. 1120 /*! 1121 \exception std::invalid_argument 1122 Thrown if \p *this and \p y are dimension-incompatible. 1123 */ 1124 void intersection_assign(const Octagonal_Shape& y); 1125 1126 /*! \brief 1127 Assigns to \p *this the smallest OS that contains 1128 the convex union of \p *this and \p y. 1129 1130 \exception std::invalid_argument 1131 Thrown if \p *this and \p y are dimension-incompatible. 1132 */ 1133 void upper_bound_assign(const Octagonal_Shape& y); 1134 1135 /*! \brief 1136 If the upper bound of \p *this and \p y is exact, it is assigned 1137 to \p *this and <CODE>true</CODE> is returned, 1138 otherwise <CODE>false</CODE> is returned. 1139 1140 \exception std::invalid_argument 1141 Thrown if \p *this and \p y are dimension-incompatible. 1142 1143 Implementation is based on Theorem 6.3 of \ref BHZ09b "[BHZ09b]". 1144 */ 1145 bool upper_bound_assign_if_exact(const Octagonal_Shape& y); 1146 1147 /*! \brief 1148 If the \e integer upper bound of \p *this and \p y is exact, 1149 it is assigned to \p *this and <CODE>true</CODE> is returned; 1150 otherwise <CODE>false</CODE> is returned. 1151 1152 \exception std::invalid_argument 1153 Thrown if \p *this and \p y are dimension-incompatible. 1154 1155 \note 1156 This operator is only available when the class template parameter 1157 \c T is bound to an integer data type. 1158 1159 \note 1160 The integer upper bound of two rational OS is the smallest 1161 rational OS containing all the integral points in the two arguments. 1162 In general, the result is \e not an upper bound for the two input 1163 arguments, as it may cut away non-integral portions of the two 1164 rational shapes. 1165 1166 Implementation is based on Theorem 6.8 of \ref BHZ09b "[BHZ09b]". 1167 */ 1168 bool integer_upper_bound_assign_if_exact(const Octagonal_Shape& y); 1169 1170 /*! \brief 1171 Assigns to \p *this the smallest octagon containing 1172 the set difference of \p *this and \p y. 1173 1174 \exception std::invalid_argument 1175 Thrown if \p *this and \p y are dimension-incompatible. 1176 */ 1177 void difference_assign(const Octagonal_Shape& y); 1178 1179 /*! \brief 1180 Assigns to \p *this a \ref Meet_Preserving_Simplification 1181 "meet-preserving simplification" of \p *this with respect to \p y. 1182 If \c false is returned, then the intersection is empty. 1183 1184 \exception std::invalid_argument 1185 Thrown if \p *this and \p y are topology-incompatible or 1186 dimension-incompatible. 1187 */ 1188 bool simplify_using_context_assign(const Octagonal_Shape& y); 1189 1190 /*! \brief 1191 Assigns to \p *this the \ref affine_relation "affine image" 1192 of \p *this under the function mapping variable \p var into the 1193 affine expression specified by \p expr and \p denominator. 1194 1195 \param var 1196 The variable to which the affine expression is assigned. 1197 1198 \param expr 1199 The numerator of the affine expression. 1200 1201 \param denominator 1202 The denominator of the affine expression. 1203 1204 \exception std::invalid_argument 1205 Thrown if \p denominator is zero or if \p expr and \p *this 1206 are dimension-incompatible or if \p var is not a dimension of \p *this. 1207 */ 1208 void affine_image(Variable var, 1209 const Linear_Expression& expr, 1210 Coefficient_traits::const_reference denominator 1211 = Coefficient_one()); 1212 1213 // FIXME: To be completed. 1214 /*! \brief 1215 Assigns to \p *this the \ref affine_form_relation "affine form image" 1216 of \p *this under the function mapping variable \p var into the 1217 affine expression(s) specified by \p lf. 1218 1219 \param var 1220 The variable to which the affine expression is assigned. 1221 1222 \param lf 1223 The linear form on intervals with floating point boundaries that 1224 defines the affine expression(s). ALL of its coefficients MUST be bounded. 1225 1226 \exception std::invalid_argument 1227 Thrown if \p lf and \p *this are dimension-incompatible or if \p var 1228 is not a dimension of \p *this. 1229 1230 This function is used in abstract interpretation to model an assignment 1231 of a value that is correctly overapproximated by \p lf to the 1232 floating point variable represented by \p var. 1233 */ 1234 template <typename Interval_Info> 1235 void affine_form_image(Variable var, 1236 const Linear_Form< Interval<T, Interval_Info> >& lf); 1237 1238 /*! \brief 1239 Assigns to \p *this the \ref affine_relation "affine preimage" 1240 of \p *this under the function mapping variable \p var into the 1241 affine expression specified by \p expr and \p denominator. 1242 1243 \param var 1244 The variable to which the affine expression is substituted. 1245 1246 \param expr 1247 The numerator of the affine expression. 1248 1249 \param denominator 1250 The denominator of the affine expression. 1251 1252 \exception std::invalid_argument 1253 Thrown if \p denominator is zero or if \p expr and \p *this 1254 are dimension-incompatible or if \p var is not a dimension of \p *this. 1255 */ 1256 void affine_preimage(Variable var, 1257 const Linear_Expression& expr, 1258 Coefficient_traits::const_reference denominator 1259 = Coefficient_one()); 1260 1261 /*! \brief 1262 Assigns to \p *this the image of \p *this with respect to the 1263 \ref Generalized_Affine_Relations "generalized affine transfer function" 1264 \f$\mathrm{var}' \relsym \frac{\mathrm{expr}}{\mathrm{denominator}}\f$, 1265 where \f$\mathord{\relsym}\f$ is the relation symbol encoded 1266 by \p relsym. 1267 1268 \param var 1269 The left hand side variable of the generalized affine transfer function. 1270 1271 \param relsym 1272 The relation symbol. 1273 1274 \param expr 1275 The numerator of the right hand side affine expression. 1276 1277 \param denominator 1278 The denominator of the right hand side affine expression. 1279 1280 \exception std::invalid_argument 1281 Thrown if \p denominator is zero or if \p expr and \p *this 1282 are dimension-incompatible or if \p var is not a dimension of \p *this 1283 or if \p relsym is a strict relation symbol. 1284 */ 1285 void generalized_affine_image(Variable var, 1286 Relation_Symbol relsym, 1287 const Linear_Expression& expr, 1288 Coefficient_traits::const_reference denominator 1289 = Coefficient_one()); 1290 1291 /*! \brief 1292 Assigns to \p *this the image of \p *this with respect to the 1293 \ref Generalized_Affine_Relations "generalized affine transfer function" 1294 \f$\mathrm{lhs}' \relsym \mathrm{rhs}\f$, where 1295 \f$\mathord{\relsym}\f$ is the relation symbol encoded by \p relsym. 1296 1297 \param lhs 1298 The left hand side affine expression. 1299 1300 \param relsym 1301 The relation symbol. 1302 1303 \param rhs 1304 The right hand side affine expression. 1305 1306 \exception std::invalid_argument 1307 Thrown if \p *this is dimension-incompatible with \p lhs or \p rhs 1308 or if \p relsym is a strict relation symbol. 1309 */ 1310 void generalized_affine_image(const Linear_Expression& lhs, 1311 Relation_Symbol relsym, 1312 const Linear_Expression& rhs); 1313 1314 /*! 1315 \brief 1316 Assigns to \p *this the image of \p *this with respect to the 1317 \ref Single_Update_Bounded_Affine_Relations "bounded affine relation" 1318 \f$\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} 1319 \leq \mathrm{var}' 1320 \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}\f$. 1321 1322 \param var 1323 The variable updated by the affine relation; 1324 1325 \param lb_expr 1326 The numerator of the lower bounding affine expression; 1327 1328 \param ub_expr 1329 The numerator of the upper bounding affine expression; 1330 1331 \param denominator 1332 The (common) denominator for the lower and upper bounding 1333 affine expressions (optional argument with default value 1). 1334 1335 \exception std::invalid_argument 1336 Thrown if \p denominator is zero or if \p lb_expr (resp., \p ub_expr) 1337 and \p *this are dimension-incompatible or if \p var is not a space 1338 dimension of \p *this. 1339 */ 1340 void bounded_affine_image(Variable var, 1341 const Linear_Expression& lb_expr, 1342 const Linear_Expression& ub_expr, 1343 Coefficient_traits::const_reference denominator 1344 = Coefficient_one()); 1345 1346 /*! \brief 1347 Assigns to \p *this the preimage of \p *this with respect to the 1348 \ref Generalized_Affine_Relations "affine relation" 1349 \f$\mathrm{var}' \relsym \frac{\mathrm{expr}}{\mathrm{denominator}}\f$, 1350 where \f$\mathord{\relsym}\f$ is the relation symbol encoded 1351 by \p relsym. 1352 1353 \param var 1354 The left hand side variable of the generalized affine transfer function. 1355 1356 \param relsym 1357 The relation symbol. 1358 1359 \param expr 1360 The numerator of the right hand side affine expression. 1361 1362 \param denominator 1363 The denominator of the right hand side affine expression. 1364 1365 \exception std::invalid_argument 1366 Thrown if \p denominator is zero or if \p expr and \p *this 1367 are dimension-incompatible or if \p var is not a dimension 1368 of \p *this or if \p relsym is a strict relation symbol. 1369 */ 1370 void generalized_affine_preimage(Variable var, 1371 Relation_Symbol relsym, 1372 const Linear_Expression& expr, 1373 Coefficient_traits::const_reference 1374 denominator = Coefficient_one()); 1375 1376 /*! \brief 1377 Assigns to \p *this the preimage of \p *this with respect to the 1378 \ref Generalized_Affine_Relations "generalized affine relation" 1379 \f$\mathrm{lhs}' \relsym \mathrm{rhs}\f$, where 1380 \f$\mathord{\relsym}\f$ is the relation symbol encoded by \p relsym. 1381 1382 \param lhs 1383 The left hand side affine expression; 1384 1385 \param relsym 1386 The relation symbol; 1387 1388 \param rhs 1389 The right hand side affine expression. 1390 1391 \exception std::invalid_argument 1392 Thrown if \p *this is dimension-incompatible with \p lhs or \p rhs 1393 or if \p relsym is a strict relation symbol. 1394 */ 1395 void generalized_affine_preimage(const Linear_Expression& lhs, 1396 Relation_Symbol relsym, 1397 const Linear_Expression& rhs); 1398 1399 /*! 1400 \brief 1401 Assigns to \p *this the preimage of \p *this with respect to the 1402 \ref Single_Update_Bounded_Affine_Relations "bounded affine relation" 1403 \f$\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} 1404 \leq \mathrm{var}' 1405 \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}\f$. 1406 1407 \param var 1408 The variable updated by the affine relation; 1409 1410 \param lb_expr 1411 The numerator of the lower bounding affine expression; 1412 1413 \param ub_expr 1414 The numerator of the upper bounding affine expression; 1415 1416 \param denominator 1417 The (common) denominator for the lower and upper bounding 1418 affine expressions (optional argument with default value 1). 1419 1420 \exception std::invalid_argument 1421 Thrown if \p denominator is zero or if \p lb_expr (resp., \p ub_expr) 1422 and \p *this are dimension-incompatible or if \p var is not a space 1423 dimension of \p *this. 1424 */ 1425 void bounded_affine_preimage(Variable var, 1426 const Linear_Expression& lb_expr, 1427 const Linear_Expression& ub_expr, 1428 Coefficient_traits::const_reference denominator 1429 = Coefficient_one()); 1430 1431 /*! \brief 1432 Assigns to \p *this the result of computing the 1433 \ref Time_Elapse_Operator "time-elapse" between \p *this and \p y. 1434 1435 \exception std::invalid_argument 1436 Thrown if \p *this and \p y are dimension-incompatible. 1437 */ 1438 void time_elapse_assign(const Octagonal_Shape& y); 1439 1440 /*! \brief 1441 \ref Wrapping_Operator "Wraps" the specified dimensions of the 1442 vector space. 1443 1444 \param vars 1445 The set of Variable objects corresponding to the space dimensions 1446 to be wrapped. 1447 1448 \param w 1449 The width of the bounded integer type corresponding to 1450 all the dimensions to be wrapped. 1451 1452 \param r 1453 The representation of the bounded integer type corresponding to 1454 all the dimensions to be wrapped. 1455 1456 \param o 1457 The overflow behavior of the bounded integer type corresponding to 1458 all the dimensions to be wrapped. 1459 1460 \param cs_p 1461 Possibly null pointer to a constraint system whose variables 1462 are contained in \p vars. If <CODE>*cs_p</CODE> depends on 1463 variables not in \p vars, the behavior is undefined. 1464 When non-null, the pointed-to constraint system is assumed to 1465 represent the conditional or looping construct guard with respect 1466 to which wrapping is performed. Since wrapping requires the 1467 computation of upper bounds and due to non-distributivity of 1468 constraint refinement over upper bounds, passing a constraint 1469 system in this way can be more precise than refining the result of 1470 the wrapping operation with the constraints in <CODE>*cs_p</CODE>. 1471 1472 \param complexity_threshold 1473 A precision parameter of the \ref Wrapping_Operator "wrapping operator": 1474 higher values result in possibly improved precision. 1475 1476 \param wrap_individually 1477 <CODE>true</CODE> if the dimensions should be wrapped individually 1478 (something that results in much greater efficiency to the detriment of 1479 precision). 1480 1481 \exception std::invalid_argument 1482 Thrown if <CODE>*cs_p</CODE> is dimension-incompatible with 1483 \p vars, or if \p *this is dimension-incompatible \p vars or with 1484 <CODE>*cs_p</CODE>. 1485 */ 1486 void wrap_assign(const Variables_Set& vars, 1487 Bounded_Integer_Type_Width w, 1488 Bounded_Integer_Type_Representation r, 1489 Bounded_Integer_Type_Overflow o, 1490 const Constraint_System* cs_p = 0, 1491 unsigned complexity_threshold = 16, 1492 bool wrap_individually = true); 1493 1494 /*! \brief 1495 Possibly tightens \p *this by dropping some points with non-integer 1496 coordinates. 1497 1498 \param complexity 1499 The maximal complexity of any algorithms used. 1500 1501 \note 1502 Currently there is no optimality guarantee, not even if 1503 \p complexity is <CODE>ANY_COMPLEXITY</CODE>. 1504 */ 1505 void drop_some_non_integer_points(Complexity_Class complexity 1506 = ANY_COMPLEXITY); 1507 1508 /*! \brief 1509 Possibly tightens \p *this by dropping some points with non-integer 1510 coordinates for the space dimensions corresponding to \p vars. 1511 1512 \param vars 1513 Points with non-integer coordinates for these variables/space-dimensions 1514 can be discarded. 1515 1516 \param complexity 1517 The maximal complexity of any algorithms used. 1518 1519 \note 1520 Currently there is no optimality guarantee, not even if 1521 \p complexity is <CODE>ANY_COMPLEXITY</CODE>. 1522 */ 1523 void drop_some_non_integer_points(const Variables_Set& vars, 1524 Complexity_Class complexity 1525 = ANY_COMPLEXITY); 1526 1527 //! Assigns to \p *this its topological closure. 1528 void topological_closure_assign(); 1529 1530 /*! \brief 1531 Assigns to \p *this the result of computing the 1532 \ref CC76_extrapolation "CC76-extrapolation" between \p *this and \p y. 1533 1534 \param y 1535 An OS that <EM>must</EM> be contained in \p *this. 1536 1537 \param tp 1538 An optional pointer to an unsigned variable storing the number of 1539 available tokens (to be used when applying the 1540 \ref Widening_with_Tokens "widening with tokens" delay technique). 1541 1542 \exception std::invalid_argument 1543 Thrown if \p *this and \p y are dimension-incompatible. 1544 */ 1545 void CC76_extrapolation_assign(const Octagonal_Shape& y, unsigned* tp = 0); 1546 1547 /*! \brief 1548 Assigns to \p *this the result of computing the 1549 \ref CC76_extrapolation "CC76-extrapolation" between \p *this and \p y. 1550 1551 \param y 1552 An OS that <EM>must</EM> be contained in \p *this. 1553 1554 \param first 1555 An iterator that points to the first stop_point. 1556 1557 \param last 1558 An iterator that points to the last stop_point. 1559 1560 \param tp 1561 An optional pointer to an unsigned variable storing the number of 1562 available tokens (to be used when applying the 1563 \ref Widening_with_Tokens "widening with tokens" delay technique). 1564 1565 \exception std::invalid_argument 1566 Thrown if \p *this and \p y are dimension-incompatible. 1567 */ 1568 template <typename Iterator> 1569 void CC76_extrapolation_assign(const Octagonal_Shape& y, 1570 Iterator first, Iterator last, 1571 unsigned* tp = 0); 1572 1573 /*! \brief 1574 Assigns to \p *this the result of computing the 1575 \ref BHMZ05_widening "BHMZ05-widening" between \p *this and \p y. 1576 1577 \param y 1578 An OS that <EM>must</EM> be contained in \p *this. 1579 1580 \param tp 1581 An optional pointer to an unsigned variable storing the number of 1582 available tokens (to be used when applying the 1583 \ref Widening_with_Tokens "widening with tokens" delay technique). 1584 1585 \exception std::invalid_argument 1586 Thrown if \p *this and \p y are dimension-incompatible. 1587 */ 1588 void BHMZ05_widening_assign(const Octagonal_Shape& y, unsigned* tp = 0); 1589 1590 //! Same as BHMZ05_widening_assign(y, tp). 1591 void widening_assign(const Octagonal_Shape& y, unsigned* tp = 0); 1592 1593 /*! \brief 1594 Improves the result of the \ref BHMZ05_widening "BHMZ05-widening" 1595 computation by also enforcing those constraints in \p cs that are 1596 satisfied by all the points of \p *this. 1597 1598 \param y 1599 An OS that <EM>must</EM> be contained in \p *this. 1600 1601 \param cs 1602 The system of constraints used to improve the widened OS. 1603 1604 \param tp 1605 An optional pointer to an unsigned variable storing the number of 1606 available tokens (to be used when applying the 1607 \ref Widening_with_Tokens "widening with tokens" delay technique). 1608 1609 \exception std::invalid_argument 1610 Thrown if \p *this, \p y and \p cs are dimension-incompatible or 1611 if there is in \p cs a strict inequality. 1612 */ 1613 void limited_BHMZ05_extrapolation_assign(const Octagonal_Shape& y, 1614 const Constraint_System& cs, 1615 unsigned* tp = 0); 1616 1617 /*! \brief 1618 Restores from \p y the constraints of \p *this, lost by 1619 \ref CC76_extrapolation "CC76-extrapolation" applications. 1620 1621 \param y 1622 An OS that <EM>must</EM> contain \p *this. 1623 1624 \exception std::invalid_argument 1625 Thrown if \p *this and \p y are dimension-incompatible. 1626 */ 1627 void CC76_narrowing_assign(const Octagonal_Shape& y); 1628 1629 /*! \brief 1630 Improves the result of the \ref CC76_extrapolation "CC76-extrapolation" 1631 computation by also enforcing those constraints in \p cs that are 1632 satisfied by all the points of \p *this. 1633 1634 \param y 1635 An OS that <EM>must</EM> be contained in \p *this. 1636 1637 \param cs 1638 The system of constraints used to improve the widened OS. 1639 1640 \param tp 1641 An optional pointer to an unsigned variable storing the number of 1642 available tokens (to be used when applying the 1643 \ref Widening_with_Tokens "widening with tokens" delay technique). 1644 1645 \exception std::invalid_argument 1646 Thrown if \p *this, \p y and \p cs are dimension-incompatible or 1647 if \p cs contains a strict inequality. 1648 */ 1649 void limited_CC76_extrapolation_assign(const Octagonal_Shape& y, 1650 const Constraint_System& cs, 1651 unsigned* tp = 0); 1652 1653 //@} Space-Dimension Preserving Member Functions that May Modify [...] 1654 1655 //! \name Member Functions that May Modify the Dimension of the Vector Space 1656 //@{ 1657 1658 //! Adds \p m new dimensions and embeds the old OS into the new space. 1659 /*! 1660 \param m 1661 The number of dimensions to add. 1662 1663 The new dimensions will be those having the highest indexes in the new OS, 1664 which is characterized by a system of constraints in which the variables 1665 running through the new dimensions are not constrained. 1666 For instance, when starting from the OS \f$\cO \sseq \Rset^2\f$ 1667 and adding a third dimension, the result will be the OS 1668 \f[ 1669 \bigl\{\, 1670 (x, y, z)^\transpose \in \Rset^3 1671 \bigm| 1672 (x, y)^\transpose \in \cO 1673 \,\bigr\}. 1674 \f] 1675 */ 1676 void add_space_dimensions_and_embed(dimension_type m); 1677 1678 /*! \brief 1679 Adds \p m new dimensions to the OS 1680 and does not embed it in the new space. 1681 1682 \param m 1683 The number of dimensions to add. 1684 1685 The new dimensions will be those having the highest indexes 1686 in the new OS, which is characterized by a system 1687 of constraints in which the variables running through 1688 the new dimensions are all constrained to be equal to 0. 1689 For instance, when starting from the OS \f$\cO \sseq \Rset^2\f$ 1690 and adding a third dimension, the result will be the OS 1691 \f[ 1692 \bigl\{\, 1693 (x, y, 0)^\transpose \in \Rset^3 1694 \bigm| 1695 (x, y)^\transpose \in \cO 1696 \,\bigr\}. 1697 \f] 1698 */ 1699 void add_space_dimensions_and_project(dimension_type m); 1700 1701 /*! \brief 1702 Assigns to \p *this the \ref Concatenating_Polyhedra "concatenation" 1703 of \p *this and \p y, taken in this order. 1704 1705 \exception std::length_error 1706 Thrown if the concatenation would cause the vector space 1707 to exceed dimension <CODE>max_space_dimension()</CODE>. 1708 */ 1709 void concatenate_assign(const Octagonal_Shape& y); 1710 1711 //! Removes all the specified dimensions. 1712 /*! 1713 \param vars 1714 The set of Variable objects corresponding to the dimensions to be removed. 1715 1716 \exception std::invalid_argument 1717 Thrown if \p *this is dimension-incompatible with one of the Variable 1718 objects contained in \p vars. 1719 */ 1720 void remove_space_dimensions(const Variables_Set& vars); 1721 1722 /*! \brief 1723 Removes the higher dimensions so that the resulting space 1724 will have dimension \p new_dimension. 1725 1726 \exception std::invalid_argument 1727 Thrown if \p new_dimension is greater than the space dimension 1728 of \p *this. 1729 */ 1730 void remove_higher_space_dimensions(dimension_type new_dimension); 1731 1732 /*! \brief 1733 Remaps the dimensions of the vector space according to 1734 a \ref Mapping_the_Dimensions_of_the_Vector_Space "partial function". 1735 1736 \param pfunc 1737 The partial function specifying the destiny of each dimension. 1738 1739 The template type parameter Partial_Function must provide 1740 the following methods. 1741 \code 1742 bool has_empty_codomain() const 1743 \endcode 1744 returns <CODE>true</CODE> if and only if the represented partial 1745 function has an empty codomain (i.e., it is always undefined). 1746 The <CODE>has_empty_codomain()</CODE> method will always be called 1747 before the methods below. However, if 1748 <CODE>has_empty_codomain()</CODE> returns <CODE>true</CODE>, none 1749 of the functions below will be called. 1750 \code 1751 dimension_type max_in_codomain() const 1752 \endcode 1753 returns the maximum value that belongs to the codomain 1754 of the partial function. 1755 \code 1756 bool maps(dimension_type i, dimension_type& j) const 1757 \endcode 1758 Let \f$f\f$ be the represented function and \f$k\f$ be the value 1759 of \p i. If \f$f\f$ is defined in \f$k\f$, then \f$f(k)\f$ is 1760 assigned to \p j and <CODE>true</CODE> is returned. 1761 If \f$f\f$ is undefined in \f$k\f$, then <CODE>false</CODE> is 1762 returned. 1763 1764 The result is undefined if \p pfunc does not encode a partial 1765 function with the properties described in the 1766 \ref Mapping_the_Dimensions_of_the_Vector_Space "specification of the mapping operator". 1767 */ 1768 template <typename Partial_Function> 1769 void map_space_dimensions(const Partial_Function& pfunc); 1770 1771 //! Creates \p m copies of the space dimension corresponding to \p var. 1772 /*! 1773 \param var 1774 The variable corresponding to the space dimension to be replicated; 1775 1776 \param m 1777 The number of replicas to be created. 1778 1779 \exception std::invalid_argument 1780 Thrown if \p var does not correspond to a dimension of the vector space. 1781 1782 \exception std::length_error 1783 Thrown if adding \p m new space dimensions would cause the 1784 vector space to exceed dimension <CODE>max_space_dimension()</CODE>. 1785 1786 If \p *this has space dimension \f$n\f$, with \f$n > 0\f$, 1787 and <CODE>var</CODE> has space dimension \f$k \leq n\f$, 1788 then the \f$k\f$-th space dimension is 1789 \ref expand_space_dimension "expanded" to \p m new space dimensions 1790 \f$n\f$, \f$n+1\f$, \f$\dots\f$, \f$n+m-1\f$. 1791 */ 1792 void expand_space_dimension(Variable var, dimension_type m); 1793 1794 //! Folds the space dimensions in \p vars into \p dest. 1795 /*! 1796 \param vars 1797 The set of Variable objects corresponding to the space dimensions 1798 to be folded; 1799 1800 \param dest 1801 The variable corresponding to the space dimension that is the 1802 destination of the folding operation. 1803 1804 \exception std::invalid_argument 1805 Thrown if \p *this is dimension-incompatible with \p dest or with 1806 one of the Variable objects contained in \p vars. 1807 Also thrown if \p dest is contained in \p vars. 1808 1809 If \p *this has space dimension \f$n\f$, with \f$n > 0\f$, 1810 <CODE>dest</CODE> has space dimension \f$k \leq n\f$, 1811 \p vars is a set of variables whose maximum space dimension 1812 is also less than or equal to \f$n\f$, and \p dest is not a member 1813 of \p vars, then the space dimensions corresponding to 1814 variables in \p vars are \ref fold_space_dimensions "folded" 1815 into the \f$k\f$-th space dimension. 1816 */ 1817 void fold_space_dimensions(const Variables_Set& vars, Variable dest); 1818 1819 //! Applies to \p dest the interval constraints embedded in \p *this. 1820 /*! 1821 \param dest 1822 The object to which the constraints will be added. 1823 1824 \exception std::invalid_argument 1825 Thrown if \p *this is dimension-incompatible with \p dest. 1826 1827 The template type parameter U must provide the following methods. 1828 \code 1829 dimension_type space_dimension() const 1830 \endcode 1831 returns the space dimension of the object. 1832 \code 1833 void set_empty() 1834 \endcode 1835 sets the object to an empty object. 1836 \code 1837 bool restrict_lower(dimension_type dim, const T& lb) 1838 \endcode 1839 restricts the object by applying the lower bound \p lb to the space 1840 dimension \p dim and returns <CODE>false</CODE> if and only if the 1841 object becomes empty. 1842 \code 1843 bool restrict_upper(dimension_type dim, const T& ub) 1844 \endcode 1845 restricts the object by applying the upper bound \p ub to the space 1846 dimension \p dim and returns <CODE>false</CODE> if and only if the 1847 object becomes empty. 1848 */ 1849 template <typename U> 1850 void export_interval_constraints(U& dest) const; 1851 1852 //! Refines \p store with the constraints defining \p *this. 1853 /*! 1854 \param store 1855 The interval floating point abstract store to refine. 1856 */ 1857 template <typename Interval_Info> 1858 void refine_fp_interval_abstract_store( 1859 Box< Interval<T, Interval_Info> >& store) const; 1860 1861 //@} // Member Functions that May Modify the Dimension of the Vector Space 1862 1863 PPL_OUTPUT_DECLARATIONS 1864 1865 /*! \brief 1866 Loads from \p s an ASCII representation (as produced by 1867 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 1868 Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise. 1869 */ 1870 bool ascii_load(std::istream& s); 1871 1872 //! Returns the total size in bytes of the memory occupied by \p *this. 1873 memory_size_type total_memory_in_bytes() const; 1874 1875 //! Returns the size in bytes of the memory managed by \p *this. 1876 memory_size_type external_memory_in_bytes() const; 1877 1878 /*! \brief 1879 Returns a 32-bit hash code for \p *this. 1880 1881 If \p x and \p y are such that <CODE>x == y</CODE>, 1882 then <CODE>x.hash_code() == y.hash_code()</CODE>. 1883 */ 1884 int32_t hash_code() const; 1885 1886 friend bool 1887 operator==<T>(const Octagonal_Shape<T>& x, const Octagonal_Shape<T>& y); 1888 1889 template <typename Temp, typename To, typename U> 1890 friend bool Parma_Polyhedra_Library 1891 ::rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 1892 const Octagonal_Shape<U>& x, 1893 const Octagonal_Shape<U>& y, 1894 const Rounding_Dir dir, 1895 Temp& tmp0, Temp& tmp1, Temp& tmp2); 1896 template <typename Temp, typename To, typename U> 1897 friend bool Parma_Polyhedra_Library 1898 ::euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 1899 const Octagonal_Shape<U>& x, 1900 const Octagonal_Shape<U>& y, 1901 const Rounding_Dir dir, 1902 Temp& tmp0, Temp& tmp1, Temp& tmp2); 1903 template <typename Temp, typename To, typename U> 1904 friend bool Parma_Polyhedra_Library 1905 ::l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r, 1906 const Octagonal_Shape<U>& x, 1907 const Octagonal_Shape<U>& y, 1908 const Rounding_Dir dir, 1909 Temp& tmp0, Temp& tmp1, Temp& tmp2); 1910 1911 private: 1912 template <typename U> friend class Parma_Polyhedra_Library::Octagonal_Shape; 1913 template <typename Interval> friend class Parma_Polyhedra_Library::Box; 1914 1915 //! The matrix that represents the octagonal shape. 1916 OR_Matrix<N> matrix; 1917 1918 //! Dimension of the space of the octagonal shape. 1919 dimension_type space_dim; 1920 1921 // Please, do not move the following include directive: 1922 // `Og_Status_idefs.hh' must be included exactly at this point. 1923 // And please do not remove the space separating `#' from `include': 1924 // this ensures that the directive will not be moved during the 1925 // procedure that automatically creates the library's include file 1926 // (see `Makefile.am' in the `src' directory). 1927 #define PPL_IN_Octagonal_Shape_CLASS 1928 #include "Og_Status_idefs.hh" 1929 #undef PPL_IN_Octagonal_Shape_CLASS 1930 1931 //! The status flags to keep track of the internal state. 1932 Status status; 1933 1934 //! Returns <CODE>true</CODE> if the OS is the zero-dimensional universe. 1935 bool marked_zero_dim_univ() const; 1936 1937 //! Returns <CODE>true</CODE> if the OS is known to be empty. 1938 /*! 1939 The return value <CODE>false</CODE> does not necessarily 1940 implies that \p *this is non-empty. 1941 */ 1942 bool marked_empty() const; 1943 1944 /*! \brief 1945 Returns <CODE>true</CODE> if \c this->matrix is known to be 1946 strongly closed. 1947 1948 The return value <CODE>false</CODE> does not necessarily 1949 implies that \c this->matrix is not strongly closed. 1950 */ 1951 bool marked_strongly_closed() const; 1952 1953 //! Turns \p *this into a zero-dimensional universe OS. 1954 void set_zero_dim_univ(); 1955 1956 //! Turns \p *this into an empty OS. 1957 void set_empty(); 1958 1959 //! Marks \p *this as strongly closed. 1960 void set_strongly_closed(); 1961 1962 //! Marks \p *this as possibly not strongly closed. 1963 void reset_strongly_closed(); 1964 1965 N& matrix_at(dimension_type i, dimension_type j); 1966 const N& matrix_at(dimension_type i, dimension_type j) const; 1967 1968 /*! \brief 1969 Returns an upper bound for \p lf according to the constraints 1970 embedded in \p *this. 1971 1972 \p lf must be a linear form on intervals with floating point coefficients. 1973 If all coefficients in \p lf are bounded, then \p result will become a 1974 correct overapproximation of the value of \p lf when variables in 1975 \p lf satisfy the constraints expressed by \p *this. Otherwise the 1976 behavior of the method is undefined. 1977 */ 1978 template <typename Interval_Info> 1979 void linear_form_upper_bound( 1980 const Linear_Form< Interval<T, Interval_Info> >& lf, 1981 N& result) const; 1982 1983 // FIXME: this function is currently not used. Consider removing it. 1984 static void interval_coefficient_upper_bound(const N& var_ub, 1985 const N& minus_var_ub, 1986 const N& int_ub, const N& int_lb, 1987 N& result); 1988 1989 /*! \brief 1990 Uses the constraint \p c to refine \p *this. 1991 1992 \param c 1993 The constraint to be added. Non-octagonal constraints are ignored. 1994 1995 \warning 1996 If \p c and \p *this are dimension-incompatible, 1997 the behavior is undefined. 1998 */ 1999 void refine_no_check(const Constraint& c); 2000 2001 /*! \brief 2002 Uses the congruence \p cg to refine \p *this. 2003 2004 \param cg 2005 The congruence to be added. 2006 Nontrivial proper congruences are ignored. 2007 Non-octagonal equalities are ignored. 2008 2009 \warning 2010 If \p cg and \p *this are dimension-incompatible, 2011 the behavior is undefined. 2012 */ 2013 void refine_no_check(const Congruence& cg); 2014 2015 //! Adds the constraint <CODE>matrix[i][j] <= k</CODE>. 2016 void add_octagonal_constraint(dimension_type i, 2017 dimension_type j, 2018 const N& k); 2019 2020 //! Adds the constraint <CODE>matrix[i][j] <= numer/denom</CODE>. 2021 void add_octagonal_constraint(dimension_type i, 2022 dimension_type j, 2023 Coefficient_traits::const_reference numer, 2024 Coefficient_traits::const_reference denom); 2025 2026 /*! \brief 2027 Adds to the Octagonal_Shape the constraint 2028 \f$\mathrm{var} \relsym \frac{\mathrm{expr}}{\mathrm{denominator}}\f$. 2029 2030 Note that the coefficient of \p var in \p expr is null. 2031 */ 2032 void refine(Variable var, 2033 Relation_Symbol relsym, 2034 const Linear_Expression& expr, 2035 Coefficient_traits::const_reference denominator 2036 = Coefficient_one()); 2037 2038 //! Removes all the constraints on variable \p v_id. 2039 void forget_all_octagonal_constraints(dimension_type v_id); 2040 2041 //! Removes all binary constraints on variable \p v_id. 2042 void forget_binary_octagonal_constraints(dimension_type v_id); 2043 2044 //! An helper function for the computation of affine relations. 2045 /*! 2046 For each variable index \c u_id (less than or equal to \p last_id 2047 and different from \p v_id), deduce constraints of the form 2048 <CODE>v - u \<= k</CODE> and <CODE>v + u \<= k</CODE>, 2049 starting from \p ub_v, which is an upper bound for \c v 2050 computed according to \p sc_expr and \p sc_denom. 2051 2052 Strong-closure will be able to deduce the constraints 2053 <CODE>v - u \<= ub_v - lb_u</CODE> and <CODE>v + u \<= ub_v + ub_u</CODE>. 2054 We can be more precise if variable \c u played an active role in the 2055 computation of the upper bound for \c v. 2056 2057 Namely, if the corresponding coefficient 2058 <CODE>q == sc_expr[u]/sc_denom</CODE> of \c u in \p sc_expr 2059 is greater than zero, we can improve the bound for <CODE>v - u</CODE>. 2060 In particular: 2061 - if <CODE>q \>= 1</CODE>, then <CODE>v - u \<= ub_v - ub_u</CODE>; 2062 - if <CODE>0 \< q \< 1</CODE>, then 2063 <CODE>v - u \<= ub_v - (q*ub_u + (1-q)*lb_u)</CODE>. 2064 2065 Conversely, if \c q is less than zero, we can improve the bound for 2066 <CODE>v + u</CODE>. In particular: 2067 - if <CODE>q \<= -1</CODE>, then <CODE>v + u \<= ub_v + lb_u</CODE>; 2068 - if <CODE>-1 \< q \< 0</CODE>, then 2069 <CODE>v + u \<= ub_v + ((-q)*lb_u + (1+q)*ub_u)</CODE>. 2070 */ 2071 void deduce_v_pm_u_bounds(dimension_type v_id, 2072 dimension_type last_id, 2073 const Linear_Expression& sc_expr, 2074 Coefficient_traits::const_reference sc_denom, 2075 const N& ub_v); 2076 2077 //! An helper function for the computation of affine relations. 2078 /*! 2079 For each variable index \c u_id (less than or equal to \p last_id 2080 and different from \p v_id), deduce constraints of the form 2081 <CODE>-v + u \<= k</CODE> and <CODE>-v - u \<= k</CODE>, 2082 starting from \p minus_lb_v, which is the negation of a lower bound 2083 for \c v computed according to \p sc_expr and \p sc_denom. 2084 2085 Strong-closure will be able to deduce the constraints 2086 <CODE>-v - u \<= -lb_v - lb_u</CODE> and 2087 <CODE>-v + u \<= -lb_v + ub_u</CODE>. 2088 We can be more precise if variable \c u played an active role in the 2089 computation of (the negation of) the lower bound for \c v. 2090 2091 Namely, if the corresponding coefficient 2092 <CODE>q == sc_expr[u]/sc_denom</CODE> of \c u in \p sc_expr 2093 is greater than zero, we can improve the bound for <CODE>-v + u</CODE>. 2094 In particular: 2095 - if <CODE>q \>= 1</CODE>, then <CODE>-v + u \<= -lb_v + lb_u</CODE>; 2096 - if <CODE>0 \< q \< 1</CODE>, then 2097 <CODE>-v + u \<= -lb_v + (q*lb_u + (1-q)*ub_u)</CODE>. 2098 2099 Conversely, if \c q is less than zero, we can improve the bound for 2100 <CODE>-v - u</CODE>. In particular: 2101 - if <CODE>q \<= -1</CODE>, then <CODE>-v - u \<= -lb_v - ub_u</CODE>; 2102 - if <CODE>-1 \< q \< 0</CODE>, then 2103 <CODE>-v - u \<= -lb_v - ((-q)*ub_u + (1+q)*lb_u)</CODE>. 2104 */ 2105 void deduce_minus_v_pm_u_bounds(dimension_type v_id, 2106 dimension_type last_id, 2107 const Linear_Expression& sc_expr, 2108 Coefficient_traits::const_reference sc_denom, 2109 const N& minus_lb_v); 2110 2111 /*! \brief 2112 Adds to \p limiting_octagon the octagonal differences in \p cs 2113 that are satisfied by \p *this. 2114 */ 2115 void get_limiting_octagon(const Constraint_System& cs, 2116 Octagonal_Shape& limiting_octagon) const; 2117 //! Compute the (zero-equivalence classes) successor relation. 2118 /*! 2119 It is assumed that the octagon is not empty and strongly closed. 2120 */ 2121 void compute_successors(std::vector<dimension_type>& successor) const; 2122 2123 //! Compute the leaders of zero-equivalence classes. 2124 /*! 2125 It is assumed that the OS is not empty and strongly closed. 2126 */ 2127 void compute_leaders(std::vector<dimension_type>& successor, 2128 std::vector<dimension_type>& no_sing_leaders, 2129 bool& exist_sing_class, 2130 dimension_type& sing_leader) const; 2131 2132 //! Compute the leaders of zero-equivalence classes. 2133 /*! 2134 It is assumed that the OS is not empty and strongly closed. 2135 */ 2136 void compute_leaders(std::vector<dimension_type>& leaders) const; 2137 2138 /*! \brief 2139 Stores into \p non_redundant information about the matrix entries 2140 that are non-redundant (i.e., they will occur in the strongly 2141 reduced matrix). 2142 2143 It is assumed that the OS is not empty and strongly closed; 2144 moreover, argument \p non_redundant is assumed to be empty. 2145 */ 2146 void non_redundant_matrix_entries(std::vector<Bit_Row>& non_redundant) const; 2147 2148 //! Removes the redundant constraints from \c this->matrix. 2149 void strong_reduction_assign() const; 2150 2151 /*! \brief 2152 Returns <CODE>true</CODE> if and only if \c this->matrix 2153 is strongly reduced. 2154 */ 2155 bool is_strongly_reduced() const; 2156 2157 /*! \brief 2158 Returns <CODE>true</CODE> if in the octagon taken two at a time 2159 unary constraints, there is also the constraint that represent their sum. 2160 */ 2161 bool is_strong_coherent() const; 2162 2163 bool tight_coherence_would_make_empty() const; 2164 2165 //! Assigns to \c this->matrix its strong closure. 2166 /*! 2167 Strong closure is a necessary condition for the precision and/or 2168 the correctness of many methods. It explicitly records into \c matrix 2169 those constraints that are implicitly obtainable by the other ones, 2170 therefore obtaining a canonical representation for the OS. 2171 */ 2172 void strong_closure_assign() const; 2173 2174 //! Applies the strong-coherence step to \c this->matrix. 2175 void strong_coherence_assign(); 2176 2177 //! Assigns to \c this->matrix its tight closure. 2178 /*! 2179 \note 2180 This is \e not marked as a <code>const</code> method, 2181 as it may modify the rational-valued geometric shape by cutting away 2182 non-integral points. The method is only available if the template 2183 parameter \c T is bound to an integer data type. 2184 */ 2185 void tight_closure_assign(); 2186 2187 /*! \brief 2188 Incrementally computes strong closure, assuming that only 2189 constraints affecting variable \p var need to be considered. 2190 2191 \note 2192 It is assumed that \c *this, which was strongly closed, has only been 2193 modified by adding constraints affecting variable \p var. If this 2194 assumption is not satisfied, i.e., if a non-redundant constraint not 2195 affecting variable \p var has been added, the behavior is undefined. 2196 Worst-case complexity is \f$O(n^2)\f$. 2197 */ 2198 void incremental_strong_closure_assign(Variable var) const; 2199 2200 //! Checks if and how \p expr is bounded in \p *this. 2201 /*! 2202 Returns <CODE>true</CODE> if and only if \p from_above is 2203 <CODE>true</CODE> and \p expr is bounded from above in \p *this, 2204 or \p from_above is <CODE>false</CODE> and \p expr is bounded 2205 from below in \p *this. 2206 2207 \param expr 2208 The linear expression to test; 2209 2210 \param from_above 2211 <CODE>true</CODE> if and only if the boundedness of interest is 2212 "from above". 2213 2214 \exception std::invalid_argument 2215 Thrown if \p expr and \p *this are dimension-incompatible. 2216 */ 2217 bool bounds(const Linear_Expression& expr, bool from_above) const; 2218 2219 //! Maximizes or minimizes \p expr subject to \p *this. 2220 /*! 2221 \param expr 2222 The linear expression to be maximized or minimized subject to \p 2223 *this; 2224 2225 \param maximize 2226 <CODE>true</CODE> if maximization is what is wanted; 2227 2228 \param ext_n 2229 The numerator of the extremum value; 2230 2231 \param ext_d 2232 The denominator of the extremum value; 2233 2234 \param included 2235 <CODE>true</CODE> if and only if the extremum of \p expr can 2236 actually be reached in \p * this; 2237 2238 \exception std::invalid_argument 2239 Thrown if \p expr and \p *this are dimension-incompatible. 2240 2241 If \p *this is empty or \p expr is not bounded in the appropriate 2242 direction, <CODE>false</CODE> is returned and \p ext_n, \p ext_d and 2243 \p included are left untouched. 2244 */ 2245 bool max_min(const Linear_Expression& expr, 2246 bool maximize, 2247 Coefficient& ext_n, Coefficient& ext_d, bool& included) const; 2248 2249 //! Maximizes or minimizes \p expr subject to \p *this. 2250 /*! 2251 \param expr 2252 The linear expression to be maximized or minimized subject to \p 2253 *this; 2254 2255 \param maximize 2256 <CODE>true</CODE> if maximization is what is wanted; 2257 2258 \param ext_n 2259 The numerator of the extremum value; 2260 2261 \param ext_d 2262 The denominator of the extremum value; 2263 2264 \param included 2265 <CODE>true</CODE> if and only if the extremum of \p expr can 2266 actually be reached in \p * this; 2267 2268 \param g 2269 When maximization or minimization succeeds, will be assigned 2270 a point or closure point where \p expr reaches the 2271 corresponding extremum value. 2272 2273 \exception std::invalid_argument 2274 Thrown if \p expr and \p *this are dimension-incompatible. 2275 2276 If \p *this is empty or \p expr is not bounded in the appropriate 2277 direction, <CODE>false</CODE> is returned and \p ext_n, \p ext_d, 2278 \p included and \p g are left untouched. 2279 */ 2280 bool max_min(const Linear_Expression& expr, 2281 bool maximize, 2282 Coefficient& ext_n, Coefficient& ext_d, bool& included, 2283 Generator& g) const; 2284 2285 void drop_some_non_integer_points_helper(N& elem); 2286 2287 friend std::ostream& 2288 Parma_Polyhedra_Library::IO_Operators 2289 ::operator<<<>(std::ostream& s, const Octagonal_Shape<T>& c); 2290 2291 //! \name Exception Throwers 2292 //@{ 2293 void throw_dimension_incompatible(const char* method, 2294 const Octagonal_Shape& y) const; 2295 2296 void throw_dimension_incompatible(const char* method, 2297 dimension_type required_dim) const; 2298 2299 void throw_dimension_incompatible(const char* method, 2300 const Constraint& c) const; 2301 2302 void throw_dimension_incompatible(const char* method, 2303 const Congruence& cg) const; 2304 2305 void throw_dimension_incompatible(const char* method, 2306 const Generator& g) const; 2307 2308 void throw_dimension_incompatible(const char* method, 2309 const char* le_name, 2310 const Linear_Expression& le) const; 2311 2312 template <typename C> 2313 void throw_dimension_incompatible(const char* method, 2314 const char* lf_name, 2315 const Linear_Form<C>& lf) const; 2316 2317 static void throw_constraint_incompatible(const char* method); 2318 2319 static void throw_expression_too_complex(const char* method, 2320 const Linear_Expression& le); 2321 2322 static void throw_invalid_argument(const char* method, const char* reason); 2323 //@} // Exception Throwers 2324 }; 2325 2326 #include "Og_Status_inlines.hh" 2327 #include "Octagonal_Shape_inlines.hh" 2328 #include "Octagonal_Shape_templates.hh" 2329 2330 #endif // !defined(PPL_Octagonal_Shape_defs_hh) 2331