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