1 /* Pointset_Powerset 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_Pointset_Powerset_defs_hh 25 #define PPL_Pointset_Powerset_defs_hh 26 27 #include "Pointset_Powerset_types.hh" 28 #include "globals_defs.hh" 29 #include "BHRZ03_Certificate_types.hh" 30 #include "Constraint_types.hh" 31 #include "Constraint_System_types.hh" 32 #include "Congruence_types.hh" 33 #include "Congruence_System_types.hh" 34 #include "C_Polyhedron_defs.hh" 35 #include "NNC_Polyhedron_defs.hh" 36 #include "Polyhedron_defs.hh" 37 #include "Grid_defs.hh" 38 #include "Partially_Reduced_Product_defs.hh" 39 #include "Variables_Set_types.hh" 40 #include "Determinate_defs.hh" 41 #include "Powerset_defs.hh" 42 #include "Poly_Con_Relation_defs.hh" 43 #include "Poly_Gen_Relation_defs.hh" 44 #include <iosfwd> 45 #include <list> 46 #include <map> 47 48 //! The powerset construction instantiated on PPL pointset domains. 49 /*! \ingroup PPL_CXX_interface 50 \warning 51 At present, the supported instantiations for the 52 disjunct domain template \p PSET are the simple pointset domains: 53 <CODE>C_Polyhedron</CODE>, 54 <CODE>NNC_Polyhedron</CODE>, 55 <CODE>Grid</CODE>, 56 <CODE>Octagonal_Shape\<T\></CODE>, 57 <CODE>BD_Shape\<T\></CODE>, 58 <CODE>Box\<T\></CODE>. 59 */ 60 template <typename PSET> 61 class Parma_Polyhedra_Library::Pointset_Powerset 62 : public Parma_Polyhedra_Library::Powerset 63 <Parma_Polyhedra_Library::Determinate<PSET> > { 64 public: 65 typedef PSET element_type; 66 67 private: 68 typedef Determinate<PSET> Det_PSET; 69 typedef Powerset<Det_PSET> Base; 70 71 public: 72 //! Returns the maximum space dimension a Pointset_Powerset<PSET> can handle. 73 static dimension_type max_space_dimension(); 74 75 //! \name Constructors 76 //@{ 77 78 //! Builds a universe (top) or empty (bottom) Pointset_Powerset. 79 /*! 80 \param num_dimensions 81 The number of dimensions of the vector space enclosing the powerset; 82 83 \param kind 84 Specifies whether the universe or the empty powerset has to be built. 85 */ 86 explicit 87 Pointset_Powerset(dimension_type num_dimensions = 0, 88 Degenerate_Element kind = UNIVERSE); 89 90 //! Ordinary copy constructor. 91 /*! 92 The complexity argument is ignored. 93 */ 94 Pointset_Powerset(const Pointset_Powerset& y, 95 Complexity_Class complexity = ANY_COMPLEXITY); 96 97 /*! \brief 98 Conversion constructor: the type <CODE>QH</CODE> of the disjuncts 99 in the source powerset is different from <CODE>PSET</CODE>. 100 101 \param y 102 The powerset to be used to build the new powerset. 103 104 \param complexity 105 The maximal complexity of any algorithms used. 106 */ 107 template <typename QH> 108 explicit Pointset_Powerset(const Pointset_Powerset<QH>& y, 109 Complexity_Class complexity = ANY_COMPLEXITY); 110 111 /*! \brief 112 Creates a Pointset_Powerset from a product 113 This will be created as a single disjunct of type PSET that 114 approximates the product. 115 */ 116 template <typename QH1, typename QH2, typename R> 117 explicit 118 Pointset_Powerset(const Partially_Reduced_Product<QH1, QH2, R>& prp, 119 Complexity_Class complexity = ANY_COMPLEXITY); 120 121 /*! \brief 122 Creates a Pointset_Powerset with a single disjunct approximating 123 the system of constraints \p cs. 124 */ 125 explicit Pointset_Powerset(const Constraint_System& cs); 126 127 /*! \brief 128 Creates a Pointset_Powerset with a single disjunct approximating 129 the system of congruences \p cgs. 130 */ 131 explicit Pointset_Powerset(const Congruence_System& cgs); 132 133 134 //! Builds a pointset_powerset out of a closed polyhedron. 135 /*! 136 Builds a powerset that is either empty (if the polyhedron is found 137 to be empty) or contains a single disjunct approximating the 138 polyhedron; this must only use algorithms that do not exceed the 139 specified complexity. The powerset inherits the space dimension 140 of the polyhedron. 141 142 \param ph 143 The closed polyhedron to be used to build the powerset. 144 145 \param complexity 146 The maximal complexity of any algorithms used. 147 148 \exception std::length_error 149 Thrown if the space dimension of \p ph exceeds the maximum 150 allowed space dimension. 151 */ 152 explicit Pointset_Powerset(const C_Polyhedron& ph, 153 Complexity_Class complexity = ANY_COMPLEXITY); 154 155 //! Builds a pointset_powerset out of an nnc polyhedron. 156 /*! 157 Builds a powerset that is either empty (if the polyhedron is found 158 to be empty) or contains a single disjunct approximating the 159 polyhedron; this must only use algorithms that do not exceed the 160 specified complexity. The powerset inherits the space dimension 161 of the polyhedron. 162 163 \param ph 164 The closed polyhedron to be used to build the powerset. 165 166 \param complexity 167 The maximal complexity of any algorithms used. 168 169 \exception std::length_error 170 Thrown if the space dimension of \p ph exceeds the maximum 171 allowed space dimension. 172 */ 173 explicit Pointset_Powerset(const NNC_Polyhedron& ph, 174 Complexity_Class complexity = ANY_COMPLEXITY); 175 176 177 //! Builds a pointset_powerset out of a grid. 178 /*! 179 If the grid is nonempty, builds a powerset containing a single 180 disjunct approximating the grid. Builds the empty powerset 181 otherwise. The powerset inherits the space dimension of the grid. 182 183 \param gr 184 The grid to be used to build the powerset. 185 186 \param complexity 187 This argument is ignored. 188 189 \exception std::length_error 190 Thrown if the space dimension of \p gr exceeds the maximum 191 allowed space dimension. 192 */ 193 explicit Pointset_Powerset(const Grid& gr, 194 Complexity_Class complexity = ANY_COMPLEXITY); 195 196 //! Builds a pointset_powerset out of an octagonal shape. 197 /*! 198 If the octagonal shape is nonempty, builds a powerset 199 containing a single disjunct approximating the octagonal 200 shape. Builds the empty powerset otherwise. The powerset 201 inherits the space dimension of the octagonal shape. 202 203 \param os 204 The octagonal shape to be used to build the powerset. 205 206 \param complexity 207 This argument is ignored. 208 209 \exception std::length_error 210 Thrown if the space dimension of \p os exceeds the maximum 211 allowed space dimension. 212 */ 213 template <typename T> 214 explicit Pointset_Powerset(const Octagonal_Shape<T>& os, 215 Complexity_Class complexity = ANY_COMPLEXITY); 216 217 //! Builds a pointset_powerset out of a bd shape. 218 /*! 219 If the bd shape is nonempty, builds a powerset containing a 220 single disjunct approximating the bd shape. Builds the empty 221 powerset otherwise. The powerset inherits the space dimension 222 of the bd shape. 223 224 \param bds 225 The bd shape to be used to build the powerset. 226 227 \param complexity 228 This argument is ignored. 229 230 \exception std::length_error 231 Thrown if the space dimension of \p bds exceeds the maximum 232 allowed space dimension. 233 */ 234 template <typename T> 235 explicit Pointset_Powerset(const BD_Shape<T>& bds, 236 Complexity_Class complexity = ANY_COMPLEXITY); 237 238 //! Builds a pointset_powerset out of a box. 239 /*! 240 If the box is nonempty, builds a powerset containing a single 241 disjunct approximating the box. Builds the empty powerset 242 otherwise. The powerset inherits the space dimension of the box. 243 244 \param box 245 The box to be used to build the powerset. 246 247 \param complexity 248 This argument is ignored. 249 250 \exception std::length_error 251 Thrown if the space dimension of \p box exceeds the maximum 252 allowed space dimension. 253 */ 254 template <typename Interval> 255 explicit Pointset_Powerset(const Box<Interval>& box, 256 Complexity_Class complexity = ANY_COMPLEXITY); 257 258 //@} // Constructors and Destructor 259 260 //! \name Member Functions that Do Not Modify the Pointset_Powerset 261 //@{ 262 263 //! Returns the dimension of the vector space enclosing \p *this. 264 dimension_type space_dimension() const; 265 266 //! Returns the dimension of the vector space enclosing \p *this. 267 dimension_type affine_dimension() const; 268 269 /*! \brief 270 Returns <CODE>true</CODE> if and only if \p *this is 271 an empty powerset. 272 */ 273 bool is_empty() const; 274 275 /*! \brief 276 Returns <CODE>true</CODE> if and only if \p *this 277 is the top element of the powerset lattice. 278 */ 279 bool is_universe() const; 280 281 /*! \brief 282 Returns <CODE>true</CODE> if and only if all the disjuncts 283 in \p *this are topologically closed. 284 */ 285 bool is_topologically_closed() const; 286 287 /*! \brief 288 Returns <CODE>true</CODE> if and only if all elements in \p *this 289 are bounded. 290 */ 291 bool is_bounded() const; 292 293 //! Returns <CODE>true</CODE> if and only if \p *this and \p y are disjoint. 294 /*! 295 \exception std::invalid_argument 296 Thrown if \p x and \p y are topology-incompatible or 297 dimension-incompatible. 298 */ 299 bool is_disjoint_from(const Pointset_Powerset& y) const; 300 301 //! Returns <CODE>true</CODE> if and only if \p *this is discrete. 302 bool is_discrete() const; 303 304 /*! \brief 305 Returns <CODE>true</CODE> if and only if \p var is constrained in 306 \p *this. 307 308 \exception std::invalid_argument 309 Thrown if \p var is not a space dimension of \p *this. 310 311 \note 312 A variable is constrained if there exists a non-redundant disjunct 313 that is constraining the variable: this definition relies on the 314 powerset lattice structure and may be somewhat different from the 315 geometric intuition. 316 For instance, variable \f$x\f$ is constrained in the powerset 317 \f[ 318 \mathit{ps} = \bigl\{ \{ x \geq 0 \}, \{ x \leq 0 \} \bigr\}, 319 \f] 320 even though \f$\mathit{ps}\f$ is geometrically equal to the 321 whole vector space. 322 */ 323 bool constrains(Variable var) const; 324 325 /*! \brief 326 Returns <CODE>true</CODE> if and only if \p expr is 327 bounded from above in \p *this. 328 329 \exception std::invalid_argument 330 Thrown if \p expr and \p *this are dimension-incompatible. 331 */ 332 bool bounds_from_above(const Linear_Expression& expr) const; 333 334 /*! \brief 335 Returns <CODE>true</CODE> if and only if \p expr is 336 bounded from below in \p *this. 337 338 \exception std::invalid_argument 339 Thrown if \p expr and \p *this are dimension-incompatible. 340 */ 341 bool bounds_from_below(const Linear_Expression& expr) const; 342 343 /*! \brief 344 Returns <CODE>true</CODE> if and only if \p *this is not empty 345 and \p expr is bounded from above in \p *this, in which case 346 the supremum value is computed. 347 348 \param expr 349 The linear expression to be maximized subject to \p *this; 350 351 \param sup_n 352 The numerator of the supremum value; 353 354 \param sup_d 355 The denominator of the supremum value; 356 357 \param maximum 358 <CODE>true</CODE> if and only if the supremum is also the maximum value. 359 360 \exception std::invalid_argument 361 Thrown if \p expr and \p *this are dimension-incompatible. 362 363 If \p *this is empty or \p expr is not bounded from above, 364 <CODE>false</CODE> is returned and \p sup_n, \p sup_d 365 and \p maximum are left untouched. 366 */ 367 bool maximize(const Linear_Expression& expr, 368 Coefficient& sup_n, Coefficient& sup_d, bool& maximum) const; 369 370 /*! \brief 371 Returns <CODE>true</CODE> if and only if \p *this is not empty 372 and \p expr is bounded from above in \p *this, in which case 373 the supremum value and a point where \p expr reaches it are computed. 374 375 \param expr 376 The linear expression to be maximized subject to \p *this; 377 378 \param sup_n 379 The numerator of the supremum value; 380 381 \param sup_d 382 The denominator of the supremum value; 383 384 \param maximum 385 <CODE>true</CODE> if and only if the supremum is also the maximum value; 386 387 \param g 388 When maximization succeeds, will be assigned the point or 389 closure point where \p expr reaches its supremum value. 390 391 \exception std::invalid_argument 392 Thrown if \p expr and \p *this are dimension-incompatible. 393 394 If \p *this is empty or \p expr is not bounded from above, 395 <CODE>false</CODE> is returned and \p sup_n, \p sup_d, \p maximum 396 and \p g are left untouched. 397 */ 398 bool maximize(const Linear_Expression& expr, 399 Coefficient& sup_n, Coefficient& sup_d, bool& maximum, 400 Generator& g) const; 401 402 /*! \brief 403 Returns <CODE>true</CODE> if and only if \p *this is not empty 404 and \p expr is bounded from below in \p *this, in which case 405 the infimum value is computed. 406 407 \param expr 408 The linear expression to be minimized subject to \p *this; 409 410 \param inf_n 411 The numerator of the infimum value; 412 413 \param inf_d 414 The denominator of the infimum value; 415 416 \param minimum 417 <CODE>true</CODE> if and only if the infimum is also the minimum value. 418 419 \exception std::invalid_argument 420 Thrown if \p expr and \p *this are dimension-incompatible. 421 422 If \p *this is empty or \p expr is not bounded from below, 423 <CODE>false</CODE> is returned and \p inf_n, \p inf_d 424 and \p minimum are left untouched. 425 */ 426 bool minimize(const Linear_Expression& expr, 427 Coefficient& inf_n, Coefficient& inf_d, bool& minimum) const; 428 429 430 /*! \brief 431 Returns <CODE>true</CODE> if and only if \p *this is not empty 432 and \p expr is bounded from below in \p *this, in which case 433 the infimum value and a point where \p expr reaches it are computed. 434 435 \param expr 436 The linear expression to be minimized subject to \p *this; 437 438 \param inf_n 439 The numerator of the infimum value; 440 441 \param inf_d 442 The denominator of the infimum value; 443 444 \param minimum 445 <CODE>true</CODE> if and only if the infimum is also the minimum value; 446 447 \param g 448 When minimization succeeds, will be assigned a point or 449 closure point where \p expr reaches its infimum value. 450 451 \exception std::invalid_argument 452 Thrown if \p expr and \p *this are dimension-incompatible. 453 454 If \p *this is empty or \p expr is not bounded from below, 455 <CODE>false</CODE> is returned and \p inf_n, \p inf_d, \p minimum 456 and \p g are left untouched. 457 */ 458 bool minimize(const Linear_Expression& expr, 459 Coefficient& inf_n, Coefficient& inf_d, bool& minimum, 460 Generator& g) const; 461 462 /*! \brief 463 Returns <CODE>true</CODE> if and only if \p *this geometrically 464 covers \p y, i.e., if any point (in some element) of \p y is also 465 a point (of some element) of \p *this. 466 467 \exception std::invalid_argument 468 Thrown if \p *this and \p y are dimension-incompatible. 469 470 \warning 471 This may be <EM>really</EM> expensive! 472 */ 473 bool geometrically_covers(const Pointset_Powerset& y) const; 474 475 /*! \brief 476 Returns <CODE>true</CODE> if and only if \p *this is geometrically 477 equal to \p y, i.e., if (the elements of) \p *this and \p y 478 contain the same set of points. 479 480 \exception std::invalid_argument 481 Thrown if \p *this and \p y are dimension-incompatible. 482 483 \warning 484 This may be <EM>really</EM> expensive! 485 */ 486 bool geometrically_equals(const Pointset_Powerset& y) const; 487 488 /*! \brief 489 Returns <CODE>true</CODE> if and only if each disjunct 490 of \p y is contained in a disjunct of \p *this. 491 492 \exception std::invalid_argument 493 Thrown if \p *this and \p y are topology-incompatible or 494 dimension-incompatible. 495 */ 496 bool contains(const Pointset_Powerset& y) const; 497 498 /*! \brief 499 Returns <CODE>true</CODE> if and only if each disjunct 500 of \p y is strictly contained in a disjunct of \p *this. 501 502 \exception std::invalid_argument 503 Thrown if \p *this and \p y are topology-incompatible or 504 dimension-incompatible. 505 */ 506 bool strictly_contains(const Pointset_Powerset& y) const; 507 508 /*! \brief 509 Returns <CODE>true</CODE> if and only if \p *this 510 contains at least one integer point. 511 */ 512 bool contains_integer_point() const; 513 514 /*! \brief 515 Returns the relations holding between the powerset \p *this 516 and the constraint \p c. 517 518 \exception std::invalid_argument 519 Thrown if \p *this and constraint \p c are dimension-incompatible. 520 */ 521 Poly_Con_Relation relation_with(const Constraint& c) const; 522 523 /*! \brief 524 Returns the relations holding between the powerset \p *this 525 and the generator \p g. 526 527 \exception std::invalid_argument 528 Thrown if \p *this and generator \p g are dimension-incompatible. 529 */ 530 Poly_Gen_Relation relation_with(const Generator& g) const; 531 532 /*! \brief 533 Returns the relations holding between the powerset \p *this 534 and the congruence \p c. 535 536 \exception std::invalid_argument 537 Thrown if \p *this and congruence \p c are dimension-incompatible. 538 */ 539 Poly_Con_Relation relation_with(const Congruence& cg) const; 540 541 /*! \brief 542 Returns a lower bound to the total size in bytes of the memory 543 occupied by \p *this. 544 */ 545 memory_size_type total_memory_in_bytes() const; 546 547 /*! \brief 548 Returns a lower bound to the size in bytes of the memory 549 managed by \p *this. 550 */ 551 memory_size_type external_memory_in_bytes() const; 552 553 /*! \brief 554 Returns a 32-bit hash code for \p *this. 555 556 If \p x and \p y are such that <CODE>x == y</CODE>, 557 then <CODE>x.hash_code() == y.hash_code()</CODE>. 558 */ 559 int32_t hash_code() const; 560 561 //! Checks if all the invariants are satisfied. 562 bool OK() const; 563 564 //@} // Member Functions that Do Not Modify the Pointset_Powerset 565 566 //! \name Space Dimension Preserving Member Functions that May Modify the Pointset_Powerset 567 //@{ 568 569 //! Adds to \p *this the disjunct \p ph. 570 /*! 571 \exception std::invalid_argument 572 Thrown if \p *this and \p ph are dimension-incompatible. 573 */ 574 void add_disjunct(const PSET& ph); 575 576 //! Intersects \p *this with constraint \p c. 577 /*! 578 \exception std::invalid_argument 579 Thrown if \p *this and constraint \p c are topology-incompatible 580 or dimension-incompatible. 581 */ 582 void add_constraint(const Constraint& c); 583 584 /*! \brief 585 Use the constraint \p c to refine \p *this. 586 587 \param c 588 The constraint to be used for refinement. 589 590 \exception std::invalid_argument 591 Thrown if \p *this and \p c are dimension-incompatible. 592 */ 593 void refine_with_constraint(const Constraint& c); 594 595 //! Intersects \p *this with the constraints in \p cs. 596 /*! 597 \param cs 598 The constraints to intersect with. 599 600 \exception std::invalid_argument 601 Thrown if \p *this and \p cs are topology-incompatible or 602 dimension-incompatible. 603 */ 604 void add_constraints(const Constraint_System& cs); 605 606 /*! \brief 607 Use the constraints in \p cs to refine \p *this. 608 609 \param cs 610 The constraints to be used for refinement. 611 612 \exception std::invalid_argument 613 Thrown if \p *this and \p cs are dimension-incompatible. 614 */ 615 void refine_with_constraints(const Constraint_System& cs); 616 617 //! Intersects \p *this with congruence \p cg. 618 /*! 619 \exception std::invalid_argument 620 Thrown if \p *this and congruence \p cg are topology-incompatible 621 or dimension-incompatible. 622 */ 623 void add_congruence(const Congruence& cg); 624 625 /*! \brief 626 Use the congruence \p cg to refine \p *this. 627 628 \param cg 629 The congruence to be used for refinement. 630 631 \exception std::invalid_argument 632 Thrown if \p *this and \p cg are dimension-incompatible. 633 */ 634 void refine_with_congruence(const Congruence& cg); 635 636 //! Intersects \p *this with the congruences in \p cgs. 637 /*! 638 \param cgs 639 The congruences to intersect with. 640 641 \exception std::invalid_argument 642 Thrown if \p *this and \p cgs are topology-incompatible or 643 dimension-incompatible. 644 */ 645 void add_congruences(const Congruence_System& cgs); 646 647 /*! \brief 648 Use the congruences in \p cgs to refine \p *this. 649 650 \param cgs 651 The congruences to be used for refinement. 652 653 \exception std::invalid_argument 654 Thrown if \p *this and \p cgs are dimension-incompatible. 655 */ 656 void refine_with_congruences(const Congruence_System& cgs); 657 658 /*! \brief 659 Computes the \ref Cylindrification "cylindrification" of \p *this with 660 respect to space dimension \p var, assigning the result to \p *this. 661 662 \param var 663 The space dimension that will be unconstrained. 664 665 \exception std::invalid_argument 666 Thrown if \p var is not a space dimension of \p *this. 667 */ 668 void unconstrain(Variable var); 669 670 /*! \brief 671 Computes the \ref Cylindrification "cylindrification" of \p *this with 672 respect to the set of space dimensions \p vars, 673 assigning the result to \p *this. 674 675 \param vars 676 The set of space dimension that will be unconstrained. 677 678 \exception std::invalid_argument 679 Thrown if \p *this is dimension-incompatible with one of the 680 Variable objects contained in \p vars. 681 */ 682 void unconstrain(const Variables_Set& vars); 683 684 /*! \brief 685 Possibly tightens \p *this by dropping some points with non-integer 686 coordinates. 687 688 \param complexity 689 The maximal complexity of any algorithms used. 690 691 \note 692 Currently there is no optimality guarantee, not even if 693 \p complexity is <CODE>ANY_COMPLEXITY</CODE>. 694 */ 695 void drop_some_non_integer_points(Complexity_Class complexity 696 = ANY_COMPLEXITY); 697 698 /*! \brief 699 Possibly tightens \p *this by dropping some points with non-integer 700 coordinates for the space dimensions corresponding to \p vars. 701 702 \param vars 703 Points with non-integer coordinates for these variables/space-dimensions 704 can be discarded. 705 706 \param complexity 707 The maximal complexity of any algorithms used. 708 709 \note 710 Currently there is no optimality guarantee, not even if 711 \p complexity is <CODE>ANY_COMPLEXITY</CODE>. 712 */ 713 void drop_some_non_integer_points(const Variables_Set& vars, 714 Complexity_Class complexity 715 = ANY_COMPLEXITY); 716 717 //! Assigns to \p *this its topological closure. 718 void topological_closure_assign(); 719 720 //! Assigns to \p *this the intersection of \p *this and \p y. 721 /*! 722 The result is obtained by intersecting each disjunct in \p *this 723 with each disjunct in \p y and collecting all these intersections. 724 */ 725 void intersection_assign(const Pointset_Powerset& y); 726 727 /*! \brief 728 Assigns to \p *this an (a smallest) 729 over-approximation as a powerset of the disjunct domain of the 730 set-theoretical difference of \p *this and \p y. 731 732 \exception std::invalid_argument 733 Thrown if \p *this and \p y are dimension-incompatible. 734 */ 735 void difference_assign(const Pointset_Powerset& y); 736 737 /*! \brief 738 Assigns to \p *this a \ref Powerset_Meet_Preserving_Simplification 739 "meet-preserving simplification" of \p *this with respect to \p y. 740 If \c false is returned, then the intersection is empty. 741 742 \exception std::invalid_argument 743 Thrown if \p *this and \p y are topology-incompatible or 744 dimension-incompatible. 745 */ 746 bool simplify_using_context_assign(const Pointset_Powerset& y); 747 748 /*! \brief 749 Assigns to \p *this the 750 \ref Single_Update_Affine_Functions "affine image" 751 of \p *this under the function mapping variable \p var to the 752 affine expression specified by \p expr and \p denominator. 753 754 \param var 755 The variable to which the affine expression is assigned; 756 757 \param expr 758 The numerator of the affine expression; 759 760 \param denominator 761 The denominator of the affine expression (optional argument with 762 default value 1). 763 764 \exception std::invalid_argument 765 Thrown if \p denominator is zero or if \p expr and \p *this are 766 dimension-incompatible or if \p var is not a space dimension of 767 \p *this. 768 */ 769 void affine_image(Variable var, 770 const Linear_Expression& expr, 771 Coefficient_traits::const_reference denominator 772 = Coefficient_one()); 773 774 /*! \brief 775 Assigns to \p *this the 776 \ref Single_Update_Affine_Functions "affine preimage" 777 of \p *this under the function mapping variable \p var to the 778 affine expression specified by \p expr and \p denominator. 779 780 \param var 781 The variable to which the affine expression is assigned; 782 783 \param expr 784 The numerator of the affine expression; 785 786 \param denominator 787 The denominator of the affine expression (optional argument with 788 default value 1). 789 790 \exception std::invalid_argument 791 Thrown if \p denominator is zero or if \p expr and \p *this are 792 dimension-incompatible or if \p var is not a space dimension of 793 \p *this. 794 */ 795 void affine_preimage(Variable var, 796 const Linear_Expression& expr, 797 Coefficient_traits::const_reference denominator 798 = Coefficient_one()); 799 800 /*! \brief 801 Assigns to \p *this the image of \p *this with respect to the 802 \ref Generalized_Affine_Relations "generalized affine relation" 803 \f$\mathrm{var}' \relsym \frac{\mathrm{expr}}{\mathrm{denominator}}\f$, 804 where \f$\mathord{\relsym}\f$ is the relation symbol encoded 805 by \p relsym. 806 807 \param var 808 The left hand side variable of the generalized affine relation; 809 810 \param relsym 811 The relation symbol; 812 813 \param expr 814 The numerator of the right hand side affine expression; 815 816 \param denominator 817 The denominator of the right hand side affine expression (optional 818 argument with default value 1). 819 820 \exception std::invalid_argument 821 Thrown if \p denominator is zero or if \p expr and \p *this are 822 dimension-incompatible or if \p var is not a space dimension of \p *this 823 or if \p *this is a C_Polyhedron and \p relsym is a strict 824 relation symbol. 825 */ 826 void generalized_affine_image(Variable var, 827 Relation_Symbol relsym, 828 const Linear_Expression& expr, 829 Coefficient_traits::const_reference denominator 830 = Coefficient_one()); 831 832 /*! \brief 833 Assigns to \p *this the preimage of \p *this with respect to the 834 \ref Generalized_Affine_Relations "generalized affine relation" 835 \f$\mathrm{var}' \relsym \frac{\mathrm{expr}}{\mathrm{denominator}}\f$, 836 where \f$\mathord{\relsym}\f$ is the relation symbol encoded 837 by \p relsym. 838 839 \param var 840 The left hand side variable of the generalized affine relation; 841 842 \param relsym 843 The relation symbol; 844 845 \param expr 846 The numerator of the right hand side affine expression; 847 848 \param denominator 849 The denominator of the right hand side affine expression (optional 850 argument with default value 1). 851 852 \exception std::invalid_argument 853 Thrown if \p denominator is zero or if \p expr and \p *this are 854 dimension-incompatible or if \p var is not a space dimension of \p *this 855 or if \p *this is a C_Polyhedron and \p relsym is a strict 856 relation symbol. 857 */ 858 void 859 generalized_affine_preimage(Variable var, 860 Relation_Symbol relsym, 861 const Linear_Expression& expr, 862 Coefficient_traits::const_reference denominator 863 = Coefficient_one()); 864 865 /*! \brief 866 Assigns to \p *this the image of \p *this with respect to the 867 \ref Generalized_Affine_Relations "generalized affine relation" 868 \f$\mathrm{lhs}' \relsym \mathrm{rhs}\f$, where 869 \f$\mathord{\relsym}\f$ is the relation symbol encoded by \p relsym. 870 871 \param lhs 872 The left hand side affine expression; 873 874 \param relsym 875 The relation symbol; 876 877 \param rhs 878 The right hand side affine expression. 879 880 \exception std::invalid_argument 881 Thrown if \p *this is dimension-incompatible with \p lhs or \p rhs 882 or if \p *this is a C_Polyhedron and \p relsym is a strict 883 relation symbol. 884 */ 885 void generalized_affine_image(const Linear_Expression& lhs, 886 Relation_Symbol relsym, 887 const Linear_Expression& rhs); 888 889 /*! \brief 890 Assigns to \p *this the preimage of \p *this with respect to the 891 \ref Generalized_Affine_Relations "generalized affine relation" 892 \f$\mathrm{lhs}' \relsym \mathrm{rhs}\f$, where 893 \f$\mathord{\relsym}\f$ is the relation symbol encoded by \p relsym. 894 895 \param lhs 896 The left hand side affine expression; 897 898 \param relsym 899 The relation symbol; 900 901 \param rhs 902 The right hand side affine expression. 903 904 \exception std::invalid_argument 905 Thrown if \p *this is dimension-incompatible with \p lhs or \p rhs 906 or if \p *this is a C_Polyhedron and \p relsym is a strict 907 relation symbol. 908 */ 909 void generalized_affine_preimage(const Linear_Expression& lhs, 910 Relation_Symbol relsym, 911 const Linear_Expression& rhs); 912 913 /*! 914 \brief 915 Assigns to \p *this the image of \p *this with respect to the 916 \ref Single_Update_Bounded_Affine_Relations "bounded affine relation" 917 \f$\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} 918 \leq \mathrm{var}' 919 \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}\f$. 920 921 \param var 922 The variable updated by the affine relation; 923 924 \param lb_expr 925 The numerator of the lower bounding affine expression; 926 927 \param ub_expr 928 The numerator of the upper bounding affine expression; 929 930 \param denominator 931 The (common) denominator for the lower and upper bounding 932 affine expressions (optional argument with default value 1). 933 934 \exception std::invalid_argument 935 Thrown if \p denominator is zero or if \p lb_expr (resp., \p ub_expr) 936 and \p *this are dimension-incompatible or if \p var is not a space 937 dimension of \p *this. 938 */ 939 void bounded_affine_image(Variable var, 940 const Linear_Expression& lb_expr, 941 const Linear_Expression& ub_expr, 942 Coefficient_traits::const_reference denominator 943 = Coefficient_one()); 944 945 /*! 946 \brief 947 Assigns to \p *this the preimage of \p *this with respect to the 948 \ref Single_Update_Bounded_Affine_Relations "bounded affine relation" 949 \f$\frac{\mathrm{lb\_expr}}{\mathrm{denominator}} 950 \leq \mathrm{var}' 951 \leq \frac{\mathrm{ub\_expr}}{\mathrm{denominator}}\f$. 952 953 \param var 954 The variable updated by the affine relation; 955 956 \param lb_expr 957 The numerator of the lower bounding affine expression; 958 959 \param ub_expr 960 The numerator of the upper bounding affine expression; 961 962 \param denominator 963 The (common) denominator for the lower and upper bounding 964 affine expressions (optional argument with default value 1). 965 966 \exception std::invalid_argument 967 Thrown if \p denominator is zero or if \p lb_expr (resp., \p ub_expr) 968 and \p *this are dimension-incompatible or if \p var is not a space 969 dimension of \p *this. 970 */ 971 void bounded_affine_preimage(Variable var, 972 const Linear_Expression& lb_expr, 973 const Linear_Expression& ub_expr, 974 Coefficient_traits::const_reference denominator 975 = Coefficient_one()); 976 977 /*! \brief 978 Assigns to \p *this the result of computing the 979 \ref Time_Elapse_Operator "time-elapse" between \p *this and \p y. 980 981 The result is obtained by computing the pairwise 982 \ref Time_Elapse_Operator "time elapse" of each disjunct 983 in \p *this with each disjunct in \p y. 984 */ 985 void time_elapse_assign(const Pointset_Powerset& y); 986 987 /*! \brief 988 \ref Wrapping_Operator "Wraps" the specified dimensions of the 989 vector space. 990 991 \param vars 992 The set of Variable objects corresponding to the space dimensions 993 to be wrapped. 994 995 \param w 996 The width of the bounded integer type corresponding to 997 all the dimensions to be wrapped. 998 999 \param r 1000 The representation of the bounded integer type corresponding to 1001 all the dimensions to be wrapped. 1002 1003 \param o 1004 The overflow behavior of the bounded integer type corresponding to 1005 all the dimensions to be wrapped. 1006 1007 \param cs_p 1008 Possibly null pointer to a constraint system whose variables 1009 are contained in \p vars. If <CODE>*cs_p</CODE> depends on 1010 variables not in \p vars, the behavior is undefined. 1011 When non-null, the pointed-to constraint system is assumed to 1012 represent the conditional or looping construct guard with respect 1013 to which wrapping is performed. Since wrapping requires the 1014 computation of upper bounds and due to non-distributivity of 1015 constraint refinement over upper bounds, passing a constraint 1016 system in this way can be more precise than refining the result of 1017 the wrapping operation with the constraints in <CODE>*cs_p</CODE>. 1018 1019 \param complexity_threshold 1020 A precision parameter of the \ref Wrapping_Operator "wrapping operator": 1021 higher values result in possibly improved precision. 1022 1023 \param wrap_individually 1024 <CODE>true</CODE> if the dimensions should be wrapped individually 1025 (something that results in much greater efficiency to the detriment of 1026 precision). 1027 1028 \exception std::invalid_argument 1029 Thrown if <CODE>*cs_p</CODE> is dimension-incompatible with 1030 \p vars, or if \p *this is dimension-incompatible \p vars or with 1031 <CODE>*cs_p</CODE>. 1032 */ 1033 void wrap_assign(const Variables_Set& vars, 1034 Bounded_Integer_Type_Width w, 1035 Bounded_Integer_Type_Representation r, 1036 Bounded_Integer_Type_Overflow o, 1037 const Constraint_System* cs_p = 0, 1038 unsigned complexity_threshold = 16, 1039 bool wrap_individually = true); 1040 1041 /*! \brief 1042 Assign to \p *this the result of (recursively) merging together 1043 the pairs of disjuncts whose upper-bound is the same as their 1044 set-theoretical union. 1045 1046 On exit, for all the pairs \f$\cP\f$, \f$\cQ\f$ of different disjuncts 1047 in \p *this, we have \f$\cP \uplus \cQ \neq \cP \union \cQ\f$. 1048 */ 1049 void pairwise_reduce(); 1050 1051 /*! \brief 1052 Assigns to \p *this the result of applying the 1053 \ref pps_bgp99_extrapolation "BGP99 extrapolation operator" 1054 to \p *this and \p y, using the widening function \p widen_fun 1055 and the cardinality threshold \p max_disjuncts. 1056 1057 \param y 1058 A powerset that <EM>must</EM> definitely entail \p *this; 1059 1060 \param widen_fun 1061 The widening function to be used on polyhedra objects. It is obtained 1062 from the corresponding widening method by using the helper function 1063 Parma_Polyhedra_Library::widen_fun_ref. Legal values are, e.g., 1064 <CODE>widen_fun_ref(&Polyhedron::H79_widening_assign)</CODE> and 1065 <CODE>widen_fun_ref(&Polyhedron::limited_H79_extrapolation_assign, cs)</CODE>; 1066 1067 \param max_disjuncts 1068 The maximum number of disjuncts occurring in the powerset \p *this 1069 <EM>before</EM> starting the computation. If this number is exceeded, 1070 some of the disjuncts in \p *this are collapsed (i.e., joined together). 1071 1072 \exception std::invalid_argument 1073 Thrown if \p *this and \p y are dimension-incompatible. 1074 1075 For a description of the extrapolation operator, 1076 see \ref BGP99 "[BGP99]" and \ref BHZ03b "[BHZ03b]". 1077 */ 1078 template <typename Widening> 1079 void BGP99_extrapolation_assign(const Pointset_Powerset& y, 1080 Widening widen_fun, 1081 unsigned max_disjuncts); 1082 1083 /*! \brief 1084 Assigns to \p *this the result of computing the 1085 \ref pps_certificate_widening "BHZ03-widening" 1086 between \p *this and \p y, using the widening function \p widen_fun 1087 certified by the convergence certificate \p Cert. 1088 1089 \param y 1090 The finite powerset computed in the previous iteration step. 1091 It <EM>must</EM> definitely entail \p *this; 1092 1093 \param widen_fun 1094 The widening function to be used on disjuncts. 1095 It is obtained from the corresponding widening method by using 1096 the helper function widen_fun_ref. Legal values are, e.g., 1097 <CODE>widen_fun_ref(&Polyhedron::H79_widening_assign)</CODE> and 1098 <CODE>widen_fun_ref(&Polyhedron::limited_H79_extrapolation_assign, cs)</CODE>. 1099 1100 \exception std::invalid_argument 1101 Thrown if \p *this and \p y are dimension-incompatible. 1102 1103 \warning 1104 In order to obtain a proper widening operator, the template parameter 1105 \p Cert should be a finite convergence certificate for the base-level 1106 widening function \p widen_fun; otherwise, an extrapolation operator is 1107 obtained. 1108 For a description of the methods that should be provided 1109 by \p Cert, see BHRZ03_Certificate or H79_Certificate. 1110 */ 1111 template <typename Cert, typename Widening> 1112 void BHZ03_widening_assign(const Pointset_Powerset& y, Widening widen_fun); 1113 1114 //@} // Space Dimension Preserving Member Functions that May Modify [...] 1115 1116 //! \name Member Functions that May Modify the Dimension of the Vector Space 1117 //@{ 1118 1119 /*! \brief 1120 The assignment operator 1121 (\p *this and \p y can be dimension-incompatible). 1122 */ 1123 Pointset_Powerset& operator=(const Pointset_Powerset& y); 1124 1125 /*! \brief 1126 Conversion assignment: the type <CODE>QH</CODE> of the disjuncts 1127 in the source powerset is different from <CODE>PSET</CODE> 1128 (\p *this and \p y can be dimension-incompatible). 1129 */ 1130 template <typename QH> 1131 Pointset_Powerset& operator=(const Pointset_Powerset<QH>& y); 1132 1133 //! Swaps \p *this with \p y. 1134 void m_swap(Pointset_Powerset& y); 1135 1136 /*! \brief 1137 Adds \p m new dimensions to the vector space containing \p *this 1138 and embeds each disjunct in \p *this in the new space. 1139 */ 1140 void add_space_dimensions_and_embed(dimension_type m); 1141 1142 /*! \brief 1143 Adds \p m new dimensions to the vector space containing \p *this 1144 without embedding the disjuncts in \p *this in the new space. 1145 */ 1146 void add_space_dimensions_and_project(dimension_type m); 1147 1148 //! Assigns to \p *this the concatenation of \p *this and \p y. 1149 /*! 1150 The result is obtained by computing the pairwise 1151 \ref Concatenating_Polyhedra "concatenation" of each disjunct 1152 in \p *this with each disjunct in \p y. 1153 */ 1154 void concatenate_assign(const Pointset_Powerset& y); 1155 1156 //! Removes all the specified space dimensions. 1157 /*! 1158 \param vars 1159 The set of Variable objects corresponding to the space dimensions 1160 to be removed. 1161 1162 \exception std::invalid_argument 1163 Thrown if \p *this is dimension-incompatible with one of the 1164 Variable objects contained in \p vars. 1165 */ 1166 void remove_space_dimensions(const Variables_Set& vars); 1167 1168 /*! \brief 1169 Removes the higher space dimensions so that the resulting space 1170 will have dimension \p new_dimension. 1171 1172 \exception std::invalid_argument 1173 Thrown if \p new_dimensions is greater than the space dimension 1174 of \p *this. 1175 */ 1176 void remove_higher_space_dimensions(dimension_type new_dimension); 1177 1178 /*! \brief 1179 Remaps the dimensions of the vector space according to 1180 a partial function. 1181 1182 See also Polyhedron::map_space_dimensions. 1183 */ 1184 template <typename Partial_Function> 1185 void map_space_dimensions(const Partial_Function& pfunc); 1186 1187 //! Creates \p m copies of the space dimension corresponding to \p var. 1188 /*! 1189 \param var 1190 The variable corresponding to the space dimension to be replicated; 1191 1192 \param m 1193 The number of replicas to be created. 1194 1195 \exception std::invalid_argument 1196 Thrown if \p var does not correspond to a dimension of the vector 1197 space. 1198 1199 \exception std::length_error 1200 Thrown if adding \p m new space dimensions would cause the vector 1201 space to exceed dimension <CODE>max_space_dimension()</CODE>. 1202 1203 If \p *this has space dimension \f$n\f$, with \f$n > 0\f$, 1204 and <CODE>var</CODE> has space dimension \f$k \leq n\f$, 1205 then the \f$k\f$-th space dimension is 1206 \ref Expanding_One_Dimension_of_the_Vector_Space_to_Multiple_Dimensions 1207 "expanded" to \p m new space dimensions 1208 \f$n\f$, \f$n+1\f$, \f$\dots\f$, \f$n+m-1\f$. 1209 */ 1210 void expand_space_dimension(Variable var, dimension_type m); 1211 1212 //! Folds the space dimensions in \p vars into \p dest. 1213 /*! 1214 \param vars 1215 The set of Variable objects corresponding to the space dimensions 1216 to be folded; 1217 1218 \param dest 1219 The variable corresponding to the space dimension that is the 1220 destination of the folding operation. 1221 1222 \exception std::invalid_argument 1223 Thrown if \p *this is dimension-incompatible with \p dest or with 1224 one of the Variable objects contained in \p vars. Also 1225 thrown if \p dest is contained in \p vars. 1226 1227 If \p *this has space dimension \f$n\f$, with \f$n > 0\f$, 1228 <CODE>dest</CODE> has space dimension \f$k \leq n\f$, 1229 \p vars is a set of variables whose maximum space dimension 1230 is also less than or equal to \f$n\f$, and \p dest is not a member 1231 of \p vars, then the space dimensions corresponding to 1232 variables in \p vars are 1233 \ref Folding_Multiple_Dimensions_of_the_Vector_Space_into_One_Dimension 1234 "folded" into the \f$k\f$-th space dimension. 1235 */ 1236 void fold_space_dimensions(const Variables_Set& vars, Variable dest); 1237 1238 //@} // Member Functions that May Modify the Dimension of the Vector Space 1239 1240 public: 1241 typedef typename Base::size_type size_type; 1242 typedef typename Base::value_type value_type; 1243 typedef typename Base::iterator iterator; 1244 typedef typename Base::const_iterator const_iterator; 1245 typedef typename Base::reverse_iterator reverse_iterator; 1246 typedef typename Base::const_reverse_iterator const_reverse_iterator; 1247 1248 PPL_OUTPUT_DECLARATIONS 1249 1250 /*! \brief 1251 Loads from \p s an ASCII representation (as produced by 1252 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 1253 Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise. 1254 */ 1255 bool ascii_load(std::istream& s); 1256 1257 private: 1258 typedef typename Base::Sequence Sequence; 1259 typedef typename Base::Sequence_iterator Sequence_iterator; 1260 typedef typename Base::Sequence_const_iterator Sequence_const_iterator; 1261 1262 //! The number of dimensions of the enclosing vector space. 1263 dimension_type space_dim; 1264 1265 /*! \brief 1266 Assigns to \p dest a \ref Powerset_Meet_Preserving_Simplification 1267 "powerset meet-preserving enlargement" of itself with respect to 1268 \p *this. If \c false is returned, then the intersection is empty. 1269 1270 \note 1271 It is assumed that \p *this and \p dest are topology-compatible 1272 and dimension-compatible. 1273 */ 1274 bool intersection_preserving_enlarge_element(PSET& dest) const; 1275 1276 /*! \brief 1277 Assigns to \p *this the result of applying the BGP99 heuristics 1278 to \p *this and \p y, using the widening function \p widen_fun. 1279 */ 1280 template <typename Widening> 1281 void BGP99_heuristics_assign(const Pointset_Powerset& y, Widening widen_fun); 1282 1283 //! Records in \p cert_ms the certificates for this set of disjuncts. 1284 template <typename Cert> 1285 void collect_certificates(std::map<Cert, size_type, 1286 typename Cert::Compare>& cert_ms) const; 1287 1288 /*! \brief 1289 Returns <CODE>true</CODE> if and only if the current set of disjuncts 1290 is stabilizing with respect to the multiset of certificates \p y_cert_ms. 1291 */ 1292 template <typename Cert> 1293 bool is_cert_multiset_stabilizing(const std::map<Cert, size_type, 1294 typename Cert::Compare>& 1295 y_cert_ms) const; 1296 1297 /*! \brief 1298 Template helper: common implementation for constraints 1299 and congruences. 1300 */ 1301 template <typename Cons_or_Congr> 1302 Poly_Con_Relation relation_with_aux(const Cons_or_Congr& c) const; 1303 1304 // FIXME: here it should be enough to befriend the template constructor 1305 // template <typename QH> 1306 // Pointset_Powerset(const Pointset_Powerset<QH>&), 1307 // but, apparently, this cannot be done. 1308 friend class Pointset_Powerset<NNC_Polyhedron>; 1309 }; 1310 1311 namespace Parma_Polyhedra_Library { 1312 1313 //! Swaps \p x with \p y. 1314 /*! \relates Pointset_Powerset */ 1315 template <typename PSET> 1316 void swap(Pointset_Powerset<PSET>& x, Pointset_Powerset<PSET>& y); 1317 1318 //! Partitions \p q with respect to \p p. 1319 /*! \relates Pointset_Powerset 1320 Let \p p and \p q be two polyhedra. 1321 The function returns an object <CODE>r</CODE> of type 1322 <CODE>std::pair\<PSET, Pointset_Powerset\<NNC_Polyhedron\> \></CODE> 1323 such that 1324 - <CODE>r.first</CODE> is the intersection of \p p and \p q; 1325 - <CODE>r.second</CODE> has the property that all its elements are 1326 pairwise disjoint and disjoint from \p p; 1327 - the set-theoretical union of <CODE>r.first</CODE> with all the 1328 elements of <CODE>r.second</CODE> gives \p q (i.e., <CODE>r</CODE> 1329 is the representation of a partition of \p q). 1330 1331 \if Include_Implementation_Details 1332 1333 See 1334 <A HREF="http://bugseng.com/products/ppl/Documentation/bibliography#Srivastava93"> 1335 this paper</A> for more information about the implementation. 1336 \endif 1337 */ 1338 template <typename PSET> 1339 std::pair<PSET, Pointset_Powerset<NNC_Polyhedron> > 1340 linear_partition(const PSET& p, const PSET& q); 1341 1342 /*! \brief 1343 Returns <CODE>true</CODE> if and only if the union of 1344 the NNC polyhedra in \p ps contains the NNC polyhedron \p ph. 1345 1346 \relates Pointset_Powerset 1347 */ 1348 bool 1349 check_containment(const NNC_Polyhedron& ph, 1350 const Pointset_Powerset<NNC_Polyhedron>& ps); 1351 1352 1353 /*! \brief 1354 Partitions the grid \p q with respect to grid \p p if and only if 1355 such a partition is finite. 1356 1357 \relates Parma_Polyhedra_Library::Pointset_Powerset 1358 Let \p p and \p q be two grids. 1359 The function returns an object <CODE>r</CODE> of type 1360 <CODE>std::pair\<PSET, Pointset_Powerset\<Grid\> \></CODE> 1361 such that 1362 - <CODE>r.first</CODE> is the intersection of \p p and \p q; 1363 - If there is a finite partition of \p q with respect to \p p 1364 the Boolean <CODE>finite_partition</CODE> is set to true and 1365 <CODE>r.second</CODE> has the property that all its elements are 1366 pairwise disjoint and disjoint from \p p and the set-theoretical 1367 union of <CODE>r.first</CODE> with all the elements of 1368 <CODE>r.second</CODE> gives \p q (i.e., <CODE>r</CODE> 1369 is the representation of a partition of \p q). 1370 - Otherwise the Boolean <CODE>finite_partition</CODE> is set to false 1371 and the singleton set that contains \p q is stored in 1372 <CODE>r.second</CODE>r. 1373 */ 1374 std::pair<Grid, Pointset_Powerset<Grid> > 1375 approximate_partition(const Grid& p, const Grid& q, bool& finite_partition); 1376 1377 /*! \brief 1378 Returns <CODE>true</CODE> if and only if the union of 1379 the grids \p ps contains the grid \p g. 1380 1381 \relates Pointset_Powerset 1382 */ 1383 bool 1384 check_containment(const Grid& ph, 1385 const Pointset_Powerset<Grid>& ps); 1386 1387 /*! \brief 1388 Returns <CODE>true</CODE> if and only if the union of 1389 the objects in \p ps contains \p ph. 1390 1391 \relates Pointset_Powerset 1392 \note 1393 It is assumed that the template parameter PSET can be converted 1394 without precision loss into an NNC_Polyhedron; otherwise, 1395 an incorrect result might be obtained. 1396 */ 1397 template <typename PSET> 1398 bool 1399 check_containment(const PSET& ph, const Pointset_Powerset<PSET>& ps); 1400 1401 // CHECKME: according to the Intel compiler, the declaration of the 1402 // following specialization (of the class template parameter) should come 1403 // before the declaration of the corresponding full specialization 1404 // (where the member template parameter is specialized too). 1405 template <> 1406 template <typename QH> 1407 Pointset_Powerset<NNC_Polyhedron> 1408 ::Pointset_Powerset(const Pointset_Powerset<QH>& y, 1409 Complexity_Class); 1410 1411 // Non-inline full specializations should be declared here 1412 // so as to inhibit multiple instantiations of the generic template. 1413 template <> 1414 template <> 1415 Pointset_Powerset<NNC_Polyhedron> 1416 ::Pointset_Powerset(const Pointset_Powerset<C_Polyhedron>& y, 1417 Complexity_Class); 1418 1419 template <> 1420 template <> 1421 Pointset_Powerset<NNC_Polyhedron> 1422 ::Pointset_Powerset(const Pointset_Powerset<Grid>& y, 1423 Complexity_Class); 1424 1425 template <> 1426 template <> 1427 Pointset_Powerset<C_Polyhedron> 1428 ::Pointset_Powerset(const Pointset_Powerset<NNC_Polyhedron>& y, 1429 Complexity_Class); 1430 1431 template <> 1432 void 1433 Pointset_Powerset<NNC_Polyhedron> 1434 ::difference_assign(const Pointset_Powerset& y); 1435 1436 template <> 1437 void 1438 Pointset_Powerset<Grid> 1439 ::difference_assign(const Pointset_Powerset& y); 1440 1441 template <> 1442 bool 1443 Pointset_Powerset<NNC_Polyhedron> 1444 ::geometrically_covers(const Pointset_Powerset& y) const; 1445 1446 template <> 1447 bool 1448 Pointset_Powerset<Grid> 1449 ::geometrically_covers(const Pointset_Powerset& y) const; 1450 1451 } // namespace Parma_Polyhedra_Library 1452 1453 #include "Pointset_Powerset_inlines.hh" 1454 #include "Pointset_Powerset_templates.hh" 1455 1456 #endif // !defined(PPL_Pointset_Powerset_defs_hh) 1457