1 /* Grid_Generator 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_Grid_Generator_defs_hh
25 #define PPL_Grid_Generator_defs_hh 1
26 
27 #include "Grid_Generator_types.hh"
28 #include "Grid_types.hh"
29 
30 #include "Variables_Set_types.hh"
31 #include "Grid_Generator_System_types.hh"
32 #include "Linear_System_types.hh"
33 
34 #include "Coefficient_defs.hh"
35 #include "Linear_Expression_defs.hh"
36 #include "Topology_types.hh"
37 #include "Expression_Hide_Inhomo_defs.hh"
38 #include "Expression_Hide_Last_defs.hh"
39 
40 #include "Grid_types.hh"
41 #include <iosfwd>
42 
43 namespace Parma_Polyhedra_Library {
44 
45 // Put these in the namespace here to declare them friend later.
46 
47 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
48 //! The basic comparison function.
49 /*! \relates Grid_Generator
50   \return
51   The returned absolute value can be \f$0\f$, \f$1\f$ or \f$2\f$.
52 
53   \param x
54   A row of coefficients;
55 
56   \param y
57   Another row.
58 
59   Compares \p x and \p y, where \p x and \p y may be of different size,
60   in which case the "missing" coefficients are assumed to be zero.
61   The comparison is such that:
62   -# equalities are smaller than inequalities;
63   -# lines are smaller than points and rays;
64   -# the ordering is lexicographic;
65   -# the positions compared are, in decreasing order of significance,
66      1, 2, ..., \p size(), 0;
67   -# the result is negative, zero, or positive if x is smaller than,
68      equal to, or greater than y, respectively;
69   -# when \p x and \p y are different, the absolute value of the
70      result is 1 if the difference is due to the coefficient in
71      position 0; it is 2 otherwise.
72 
73   When \p x and \p y represent the hyper-planes associated
74   to two equality or inequality constraints, the coefficient
75   at 0 is the known term.
76   In this case, the return value can be characterized as follows:
77   - -2, if \p x is smaller than \p y and they are \e not parallel;
78   - -1, if \p x is smaller than \p y and they \e are parallel;
79   -  0, if \p x and y are equal;
80   - +1, if \p y is smaller than \p x and they \e are parallel;
81   - +2, if \p y is smaller than \p x and they are \e not parallel.
82 */
83 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
84 int compare(const Grid_Generator& x, const Grid_Generator& y);
85 
86 namespace IO_Operators {
87 
88 //! Output operator.
89 /*! \relates Parma_Polyhedra_Library::Grid_Generator */
90 std::ostream& operator<<(std::ostream& s, const Grid_Generator& g);
91 
92 } // namespace IO_Operators
93 
94 //! Swaps \p x with \p y.
95 /*! \relates Grid_Generator */
96 void swap(Grid_Generator& x, Grid_Generator& y);
97 
98 } // namespace Parma_Polyhedra_Library
99 
100 //! A grid line, parameter or grid point.
101 /*! \ingroup PPL_CXX_interface
102   An object of the class Grid_Generator is one of the following:
103 
104   - a grid_line \f$\vect{l} = (a_0, \ldots, a_{n-1})^\transpose\f$;
105 
106   - a parameter
107     \f$\vect{q} = (\frac{a_0}{d}, \ldots, \frac{a_{n-1}}{d})^\transpose\f$;
108 
109   - a grid_point
110     \f$\vect{p} = (\frac{a_0}{d}, \ldots, \frac{a_{n-1}}{d})^\transpose\f$;
111 
112   where \f$n\f$ is the dimension of the space
113   and, for grid_points and parameters, \f$d > 0\f$ is the divisor.
114 
115   \par How to build a grid generator.
116   Each type of generator is built by applying the corresponding
117   function (<CODE>grid_line</CODE>, <CODE>parameter</CODE>
118   or <CODE>grid_point</CODE>) to a linear expression;
119   the space dimension of the generator is defined as the space dimension
120   of the corresponding linear expression.
121   Linear expressions used to define a generator should be homogeneous
122   (any constant term will be simply ignored).
123   When defining grid points and parameters, an optional Coefficient argument
124   can be used as a common <EM>divisor</EM> for all the coefficients
125   occurring in the provided linear expression;
126   the default value for this argument is 1.
127 
128   \par
129   In all the following examples it is assumed that variables
130   <CODE>x</CODE>, <CODE>y</CODE> and <CODE>z</CODE>
131   are defined as follows:
132   \code
133   Variable x(0);
134   Variable y(1);
135   Variable z(2);
136   \endcode
137 
138   \par Example 1
139   The following code builds a grid line with direction \f$x-y-z\f$
140   and having space dimension \f$3\f$:
141   \code
142   Grid_Generator l = grid_line(x - y - z);
143   \endcode
144   By definition, the origin of the space is not a line, so that
145   the following code throws an exception:
146   \code
147   Grid_Generator l = grid_line(0*x);
148   \endcode
149 
150   \par Example 2
151   The following code builds the parameter as the vector
152   \f$\vect{p} = (1, -1, -1)^\transpose \in \Rset^3\f$
153   which has the same direction as the line in Example 1:
154   \code
155   Grid_Generator q = parameter(x - y - z);
156   \endcode
157   Note that, unlike lines, for parameters, the length as well
158   as the direction of the vector represented by the code is significant.
159   Thus \p q is \e not the same as the parameter \p q1 defined by
160   \code
161   Grid_Generator q1 = parameter(2x - 2y - 2z);
162   \endcode
163   By definition, the origin of the space is not a parameter, so that
164   the following code throws an exception:
165   \code
166   Grid_Generator q = parameter(0*x);
167   \endcode
168 
169   \par Example 3
170   The following code builds the grid point
171   \f$\vect{p} = (1, 0, 2)^\transpose \in \Rset^3\f$:
172   \code
173   Grid_Generator p = grid_point(1*x + 0*y + 2*z);
174   \endcode
175   The same effect can be obtained by using the following code:
176   \code
177   Grid_Generator p = grid_point(x + 2*z);
178   \endcode
179   Similarly, the origin \f$\vect{0} \in \Rset^3\f$ can be defined
180   using either one of the following lines of code:
181   \code
182   Grid_Generator origin3 = grid_point(0*x + 0*y + 0*z);
183   Grid_Generator origin3_alt = grid_point(0*z);
184   \endcode
185   Note however that the following code would have defined
186   a different point, namely \f$\vect{0} \in \Rset^2\f$:
187   \code
188   Grid_Generator origin2 = grid_point(0*y);
189   \endcode
190   The following two lines of code both define the only grid point
191   having space dimension zero, namely \f$\vect{0} \in \Rset^0\f$.
192   In the second case we exploit the fact that the first argument
193   of the function <CODE>point</CODE> is optional.
194   \code
195   Grid_Generator origin0 = Generator::zero_dim_point();
196   Grid_Generator origin0_alt = grid_point();
197   \endcode
198 
199   \par Example 4
200   The grid point \f$\vect{p}\f$ specified in Example 3 above
201   can also be obtained with the following code,
202   where we provide a non-default value for the second argument
203   of the function <CODE>grid_point</CODE> (the divisor):
204   \code
205   Grid_Generator p = grid_point(2*x + 0*y + 4*z, 2);
206   \endcode
207   Obviously, the divisor can be used to specify
208   points having some non-integer (but rational) coordinates.
209   For instance, the grid point
210   \f$\vect{p1} = (-1.5, 3.2, 2.1)^\transpose \in \Rset^3\f$
211   can be specified by the following code:
212   \code
213   Grid_Generator p1 = grid_point(-15*x + 32*y + 21*z, 10);
214   \endcode
215   If a zero divisor is provided, an exception is thrown.
216 
217   \par Example 5
218   Parameters, like grid points can have a divisor.
219   For instance, the parameter
220   \f$\vect{q} = (1, 0, 2)^\transpose \in \Rset^3\f$ can be defined:
221   \code
222   Grid_Generator q = parameter(2*x + 0*y + 4*z, 2);
223   \endcode
224   Also, the divisor can be used to specify
225   parameters having some non-integer (but rational) coordinates.
226   For instance, the parameter
227   \f$\vect{q} = (-1.5, 3.2, 2.1)^\transpose \in \Rset^3\f$
228   can be defined:
229   \code
230   Grid_Generator q = parameter(-15*x + 32*y + 21*z, 10);
231   \endcode
232   If a zero divisor is provided, an exception is thrown.
233 
234   \par How to inspect a grid generator
235   Several methods are provided to examine a grid generator and extract
236   all the encoded information: its space dimension, its type and
237   the value of its integer coefficients and the value of the denominator.
238 
239   \par Example 6
240   The following code shows how it is possible to access each single
241   coefficient of a grid generator.
242   If <CODE>g1</CODE> is a grid point having coordinates
243   \f$(a_0, \ldots, a_{n-1})^\transpose\f$,
244   we construct the parameter <CODE>g2</CODE> having coordinates
245   \f$(a_0, 2 a_1, \ldots, (i+1)a_i, \ldots, n a_{n-1})^\transpose\f$.
246   \code
247   if (g1.is_point()) {
248     cout << "Grid point g1: " << g1 << endl;
249     Linear_Expression e;
250     for (dimension_type i = g1.space_dimension(); i-- > 0; )
251       e += (i + 1) * g1.coefficient(Variable(i)) * Variable(i);
252     Grid_Generator g2 = parameter(e, g1.divisor());
253     cout << "Parameter g2: " << g2 << endl;
254   }
255   else
256     cout << "Grid generator g1 is not a grid point." << endl;
257   \endcode
258   Therefore, for the grid point
259   \code
260   Grid_Generator g1 = grid_point(2*x - y + 3*z, 2);
261   \endcode
262   we would obtain the following output:
263   \code
264   Grid point g1: p((2*A - B + 3*C)/2)
265   Parameter g2: parameter((2*A - 2*B + 9*C)/2)
266   \endcode
267   When working with grid points and parameters, be careful not to confuse
268   the notion of <EM>coefficient</EM> with the notion of <EM>coordinate</EM>:
269   these are equivalent only when the divisor is 1.
270 */
271 class Parma_Polyhedra_Library::Grid_Generator {
272 public:
273 
274   //! The possible kinds of Grid_Generator objects.
275   enum Kind {
276     LINE_OR_EQUALITY = 0,
277     RAY_OR_POINT_OR_INEQUALITY = 1
278   };
279 
280   //! The representation used for new Grid_Generators.
281   /*!
282     \note The copy constructor and the copy constructor with specified size
283           use the representation of the original object, so that it is
284           indistinguishable from the original object.
285   */
286   static const Representation default_representation = SPARSE;
287 
288   //! Returns the line of direction \p e.
289   /*!
290     \exception std::invalid_argument
291     Thrown if the homogeneous part of \p e represents the origin of
292     the vector space.
293   */
294   static Grid_Generator grid_line(const Linear_Expression& e,
295                                   Representation r = default_representation);
296 
297   //! Returns the parameter of direction \p e and size \p e/d, with the same
298   //! representation as e.
299   /*!
300     Both \p e and \p d are optional arguments, with default values
301     Linear_Expression::zero() and Coefficient_one(), respectively.
302 
303     \exception std::invalid_argument
304     Thrown if \p d is zero.
305   */
306   static Grid_Generator parameter(const Linear_Expression& e
307                                   = Linear_Expression::zero(),
308                                   Coefficient_traits::const_reference d
309                                   = Coefficient_one(),
310                                   Representation r = default_representation);
311 
312   // TODO: Improve the documentation of this method.
313   //! Returns the parameter of direction and size \p Linear_Expression::zero() .
314   static Grid_Generator parameter(Representation r);
315 
316   //! Returns the parameter of direction and size \p e .
317   static Grid_Generator parameter(const Linear_Expression& e,
318                                   Representation r);
319 
320   //! Returns the point at \p e / \p d.
321   /*!
322     Both \p e and \p d are optional arguments, with default values
323     Linear_Expression::zero() and Coefficient_one(), respectively.
324 
325     \exception std::invalid_argument
326     Thrown if \p d is zero.
327   */
328   static Grid_Generator grid_point(const Linear_Expression& e
329                                    = Linear_Expression::zero(),
330                                    Coefficient_traits::const_reference d
331                                    = Coefficient_one(),
332                                    Representation r = default_representation);
333 
334   //! Returns the point at \p e .
335   static Grid_Generator grid_point(Representation r);
336 
337   //! Returns the point at \p e .
338   static Grid_Generator grid_point(const Linear_Expression& e,
339                                    Representation r);
340 
341   //! Returns the origin of the zero-dimensional space \f$\Rset^0\f$.
342   explicit Grid_Generator(Representation r = default_representation);
343 
344   //! Ordinary copy constructor.
345   //! The new Grid_Generator will have the same representation as g.
346   Grid_Generator(const Grid_Generator& g);
347 
348   //! Copy constructor with specified representation.
349   Grid_Generator(const Grid_Generator& g, Representation r);
350 
351   //! Copy constructor with specified space dimension.
352   //! The new Grid_Generator will have the same representation as g.
353   Grid_Generator(const Grid_Generator& g, dimension_type space_dim);
354 
355   //! Copy constructor with specified space dimension and representation.
356   Grid_Generator(const Grid_Generator& g, dimension_type space_dim,
357                  Representation r);
358 
359   //! Destructor.
360   ~Grid_Generator();
361 
362   //! Assignment operator.
363   Grid_Generator& operator=(const Grid_Generator& g);
364 
365   //! Returns the current representation of *this.
366   Representation representation() const;
367 
368   //! Converts *this to the specified representation.
369   void set_representation(Representation r);
370 
371   //! Returns the maximum space dimension a Grid_Generator can handle.
372   static dimension_type max_space_dimension();
373 
374   //! Returns the dimension of the vector space enclosing \p *this.
375   dimension_type space_dimension() const;
376 
377   //! Sets the dimension of the vector space enclosing \p *this to
378   //! \p space_dim .
379   void set_space_dimension(dimension_type space_dim);
380 
381   //! Swaps the coefficients of the variables \p v1 and \p v2 .
382   void swap_space_dimensions(Variable v1, Variable v2);
383 
384   //! Removes all the specified dimensions from the grid generator.
385   /*!
386     The space dimension of the variable with the highest space
387     dimension in \p vars must be at most the space dimension
388     of \p this.
389 
390     Always returns \p true. The return value is needed for compatibility with
391     the Generator class.
392   */
393   bool remove_space_dimensions(const Variables_Set& vars);
394 
395   //! Permutes the space dimensions of the grid generator.
396   /*
397     \param cycle
398     A vector representing a cycle of the permutation according to which the
399     space dimensions must be rearranged.
400 
401     The \p cycle vector represents a cycle of a permutation of space
402     dimensions.
403     For example, the permutation
404     \f$ \{ x_1 \mapsto x_2, x_2 \mapsto x_3, x_3 \mapsto x_1 \}\f$ can be
405     represented by the vector containing \f$ x_1, x_2, x_3 \f$.
406   */
407   void permute_space_dimensions(const std::vector<Variable>& cycle);
408 
409   //! Shift by \p n positions the coefficients of variables, starting from
410   //! the coefficient of \p v. This increases the space dimension by \p n.
411   void shift_space_dimensions(Variable v, dimension_type n);
412 
413   //! The generator type.
414   enum Type {
415     /*! The generator is a grid line. */
416     LINE,
417     /*! The generator is a parameter. */
418     PARAMETER,
419     /*! The generator is a grid point. */
420     POINT
421   };
422 
423   //! Returns the generator type of \p *this.
424   Type type() const;
425 
426   //! Returns <CODE>true</CODE> if and only if \p *this is a line.
427   bool is_line() const;
428 
429   //! Returns <CODE>true</CODE> if and only if \p *this is a parameter.
430   bool is_parameter() const;
431 
432   /*! \brief
433     Returns <CODE>true</CODE> if and only if \p *this is a line or
434     a parameter.
435   */
436   bool is_line_or_parameter() const;
437 
438   //! Returns <CODE>true</CODE> if and only if \p *this is a point.
439   bool is_point() const;
440 
441   /*! \brief
442     Returns <CODE>true</CODE> if and only if \p *this row represents a
443     parameter or a point.
444   */
445   bool is_parameter_or_point() const;
446 
447   //! Returns the coefficient of \p v in \p *this.
448   /*!
449     \exception std::invalid_argument
450     Thrown if the index of \p v is greater than or equal to the
451     space dimension of \p *this.
452   */
453   Coefficient_traits::const_reference coefficient(Variable v) const;
454 
455   //! Returns the divisor of \p *this.
456   /*!
457     \exception std::invalid_argument
458     Thrown if \p *this is a line.
459   */
460   Coefficient_traits::const_reference divisor() const;
461 
462   //! Initializes the class.
463   static void initialize();
464 
465   //! Finalizes the class.
466   static void finalize();
467 
468   //! Returns the origin of the zero-dimensional space \f$\Rset^0\f$.
469   static const Grid_Generator& zero_dim_point();
470 
471   /*! \brief
472     Returns a lower bound to the total size in bytes of the memory
473     occupied by \p *this.
474   */
475   memory_size_type total_memory_in_bytes() const;
476 
477   //! Returns the size in bytes of the memory managed by \p *this.
478   memory_size_type external_memory_in_bytes() const;
479 
480   /*! \brief
481     Returns <CODE>true</CODE> if and only if \p *this and \p y are
482     equivalent generators.
483 
484     Generators having different space dimensions are not equivalent.
485   */
486   bool is_equivalent_to(const Grid_Generator& y) const;
487 
488   //! Returns <CODE>true</CODE> if \p *this is identical to \p y.
489   /*!
490     This is faster than is_equivalent_to(), but it may return `false' even
491     for equivalent generators.
492   */
493   bool is_equal_to(const Grid_Generator& y) const;
494 
495   /*! \brief
496     Returns <CODE>true</CODE> if and only if all the homogeneous terms
497     of \p *this are \f$0\f$.
498   */
499   bool all_homogeneous_terms_are_zero() const;
500 
501   //! Checks if all the invariants are satisfied.
502   bool OK() const;
503 
504   PPL_OUTPUT_DECLARATIONS
505 
506   /*! \brief
507     Loads from \p s an ASCII representation (as produced by
508     ascii_dump(std::ostream&) const) and sets \p *this accordingly.
509     Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise.
510   */
511   bool ascii_load(std::istream& s);
512 
513   //! Swaps \p *this with \p y.
514   void m_swap(Grid_Generator& y);
515 
516   /*! \brief
517     Scales \p *this to be represented with a divisor of \p d (if
518     \*this is a parameter or point). Does nothing at all on lines.
519 
520     It is assumed that \p d is a multiple of the current divisor
521     and different from zero. The behavior is undefined if the assumption
522     does not hold.
523   */
524   void scale_to_divisor(Coefficient_traits::const_reference d);
525 
526   //! Sets the divisor of \p *this to \p d.
527   /*!
528     \exception std::invalid_argument
529     Thrown if \p *this is a line.
530   */
531   void set_divisor(Coefficient_traits::const_reference d);
532 
533   //! The type of the (adapted) internal expression.
534   typedef Expression_Hide_Last<Expression_Hide_Inhomo<Linear_Expression> >
535   expr_type;
536   //! Partial read access to the (adapted) internal expression.
537   expr_type expression() const;
538 
539 private:
540   Linear_Expression expr;
541 
542   Kind kind_;
543 
544   /*! \brief
545     Holds (between class initialization and finalization) a pointer to
546     the origin of the zero-dimensional space \f$\Rset^0\f$.
547   */
548   static const Grid_Generator* zero_dim_point_p;
549 
550   //! Constructs a Grid_Generator with the specified space dimension, kind
551   //! and topology.
552   Grid_Generator(dimension_type space_dim, Kind kind, Topology topology,
553                  Representation r = default_representation);
554 
555   // TODO: Avoid reducing the space dimension.
556   /*! \brief
557     Constructs a grid generator of type \p t from linear expression \p e,
558     stealing the underlying data structures from \p e.
559 
560     The last column in \p e becomes the parameter divisor column of
561     the new Grid_Generator.
562 
563     \note The new Grid_Generator will have the same representation as `e'.
564   */
565   Grid_Generator(Linear_Expression& e, Type t);
566 
567   //! Sets the dimension of the vector space enclosing \p *this to
568   //! \p space_dim .
569   //! Sets the space dimension of the rows in the system to \p space_dim .
570   /*!
571     This method is for internal use, it does *not* assert OK() at the end,
572     so it can be used for invalid objects.
573   */
574   void set_space_dimension_no_ok(dimension_type space_dim);
575 
576   /*! \brief
577     Returns <CODE>true</CODE> if \p *this is equal to \p gg in
578     dimension \p dim.
579   */
580   bool is_equal_at_dimension(dimension_type dim,
581                              const Grid_Generator& gg) const;
582 
583   /*! \brief
584     A print function, with fancy, more human-friendly output.
585 
586     This is used by operator<<().
587   */
588   void fancy_print(std::ostream& s) const;
589 
590   //! Converts the Grid_Generator into a parameter.
591   void set_is_parameter();
592 
593   //! Sets the Grid_Generator kind to <CODE>LINE_OR_EQUALITY</CODE>.
594   void set_is_line();
595 
596   //! Sets the Grid_Generator kind to <CODE>RAY_OR_POINT_OR_INEQUALITY</CODE>.
597   void set_is_parameter_or_point();
598 
599   //! \name Flags inspection methods
600   //@{
601   //! Returns the topological kind of \p *this.
602   Topology topology() const;
603 
604   /*! \brief
605     Returns <CODE>true</CODE> if and only if the topology
606     of \p *this row is not necessarily closed.
607   */
608   bool is_not_necessarily_closed() const;
609 
610   /*! \brief
611     Returns <CODE>true</CODE> if and only if the topology
612     of \p *this row is necessarily closed.
613   */
614   bool is_necessarily_closed() const;
615 
616   /*! \brief
617     Returns <CODE>true</CODE> if and only if \p *this row
618     represents a line or an equality.
619   */
620   bool is_line_or_equality() const;
621 
622   /*! \brief
623     Returns <CODE>true</CODE> if and only if \p *this row
624     represents a ray, a point or an inequality.
625   */
626   bool is_ray_or_point_or_inequality() const;
627   //@} // Flags inspection methods
628 
629   //! \name Flags coercion methods
630   //@{
631 
632   //! Sets to \p x the topological kind of \p *this row.
633   void set_topology(Topology x);
634 
635   //! Sets to \p NECESSARILY_CLOSED the topological kind of \p *this row.
636   void set_necessarily_closed();
637 
638   //! Sets to \p NOT_NECESSARILY_CLOSED the topological kind of \p *this row.
639   void set_not_necessarily_closed();
640 
641   //! Sets to \p LINE_OR_EQUALITY the kind of \p *this row.
642   void set_is_line_or_equality();
643 
644   //! Sets to \p RAY_OR_POINT_OR_INEQUALITY the kind of \p *this row.
645   void set_is_ray_or_point_or_inequality();
646   //@} // Flags coercion methods
647 
648   /*! \brief
649     Normalizes the sign of the coefficients so that the first non-zero
650     (homogeneous) coefficient of a line-or-equality is positive.
651   */
652   void sign_normalize();
653 
654   /*! \brief
655     Strong normalization: ensures that different Grid_Generator objects
656     represent different hyperplanes or hyperspaces.
657 
658     Applies both Grid_Generator::normalize() and Grid_Generator::sign_normalize().
659   */
660   void strong_normalize();
661 
662   /*! \brief
663     Returns <CODE>true</CODE> if and only if the coefficients are
664     strongly normalized.
665   */
666   bool check_strong_normalized() const;
667 
668   //! Linearly combines \p *this with \p y so that i-th coefficient is 0.
669   /*!
670     \param y
671     The Grid_Generator that will be combined with \p *this object;
672 
673     \param i
674     The index of the coefficient that has to become \f$0\f$.
675 
676     Computes a linear combination of \p *this and \p y having
677     the i-th coefficient equal to \f$0\f$. Then it assigns
678     the resulting Grid_Generator to \p *this and normalizes it.
679   */
680   void linear_combine(const Grid_Generator& y, dimension_type i);
681 
682   /*! \brief
683     Throw a <CODE>std::invalid_argument</CODE> exception containing
684     the appropriate error message.
685   */
686   void
687   throw_dimension_incompatible(const char* method,
688                                const char* name_var,
689                                const Variable v) const;
690 
691   /*! \brief
692     Throw a <CODE>std::invalid_argument</CODE> exception containing
693     the appropriate error message.
694   */
695   void
696   throw_invalid_argument(const char* method, const char* reason) const;
697 
698   friend std::ostream&
699   IO_Operators::operator<<(std::ostream& s, const Grid_Generator& g);
700 
701   friend int
702   compare(const Grid_Generator& x, const Grid_Generator& y);
703 
704   friend class Expression_Adapter<Grid_Generator>;
705   friend class Grid_Generator_System;
706   friend class Grid;
707   friend class Linear_System<Grid_Generator>;
708   friend class Scalar_Products;
709   friend class Topology_Adjusted_Scalar_Product_Sign;
710 };
711 
712 
713 namespace Parma_Polyhedra_Library {
714 
715 /*! \brief
716   Shorthand for
717   Grid_Generator::grid_line(const Linear_Expression& e, Representation r).
718 
719   \relates Grid_Generator
720 */
721 Grid_Generator
722 grid_line(const Linear_Expression& e,
723           Representation r = Grid_Generator::default_representation);
724 
725 /*! \brief
726   Shorthand for
727   Grid_Generator::parameter(const Linear_Expression& e, Coefficient_traits::const_reference d, Representation r).
728 
729   \relates Grid_Generator
730 */
731 Grid_Generator
732 parameter(const Linear_Expression& e = Linear_Expression::zero(),
733           Coefficient_traits::const_reference d = Coefficient_one(),
734           Representation r = Grid_Generator::default_representation);
735 
736 //! Shorthand for Grid_Generator::parameter(Representation r).
737 /*! \relates Grid_Generator */
738 Grid_Generator
739 parameter(Representation r);
740 
741 /*! \brief
742   Shorthand for
743   Grid_Generator::parameter(const Linear_Expression& e, Representation r).
744 
745   \relates Grid_Generator
746 */
747 Grid_Generator
748 parameter(const Linear_Expression& e, Representation r);
749 
750 /*! \brief
751   Shorthand for
752   Grid_Generator::grid_point(const Linear_Expression& e, Coefficient_traits::const_reference d, Representation r).
753 
754   \relates Grid_Generator
755 */
756 Grid_Generator
757 grid_point(const Linear_Expression& e = Linear_Expression::zero(),
758            Coefficient_traits::const_reference d = Coefficient_one(),
759            Representation r = Grid_Generator::default_representation);
760 
761 //! Shorthand for Grid_Generator::grid_point(Representation r).
762 /*! \relates Grid_Generator */
763 Grid_Generator
764 grid_point(Representation r);
765 
766 /*! \brief
767   Shorthand for
768   Grid_Generator::grid_point(const Linear_Expression& e, Representation r).
769 
770   \relates Grid_Generator
771 */
772 Grid_Generator
773 grid_point(const Linear_Expression& e, Representation r);
774 
775 //! Returns <CODE>true</CODE> if and only if \p x is equivalent to \p y.
776 /*! \relates Grid_Generator */
777 bool operator==(const Grid_Generator& x, const Grid_Generator& y);
778 
779 //! Returns <CODE>true</CODE> if and only if \p x is not equivalent to \p y.
780 /*! \relates Grid_Generator */
781 bool operator!=(const Grid_Generator& x, const Grid_Generator& y);
782 
783 
784 namespace IO_Operators {
785 
786 //! Output operator.
787 /*! \relates Parma_Polyhedra_Library::Grid_Generator */
788 std::ostream& operator<<(std::ostream& s, const Grid_Generator::Type& t);
789 
790 } // namespace IO_Operators
791 
792 } // namespace Parma_Polyhedra_Library
793 
794 #include "Grid_Generator_inlines.hh"
795 
796 #endif // !defined(PPL_Grid_Generator_defs_hh)
797