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