1 /* Grid Generator class implementation: inline functions.
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_inlines_hh
25 #define PPL_Grid_Generator_inlines_hh 1
26 
27 namespace Parma_Polyhedra_Library {
28 
29 inline bool
is_necessarily_closed() const30 Grid_Generator::is_necessarily_closed() const {
31   return true;
32 }
33 
34 inline bool
is_not_necessarily_closed() const35 Grid_Generator::is_not_necessarily_closed() const {
36   return false;
37 }
38 
39 inline bool
is_line_or_equality() const40 Grid_Generator::is_line_or_equality() const {
41   return (kind_ == LINE_OR_EQUALITY);
42 }
43 
44 inline bool
is_ray_or_point_or_inequality() const45 Grid_Generator::is_ray_or_point_or_inequality() const {
46   return (kind_ == RAY_OR_POINT_OR_INEQUALITY);
47 }
48 
49 inline Topology
topology() const50 Grid_Generator::topology() const {
51   return NECESSARILY_CLOSED;
52 }
53 
54 inline void
set_is_line_or_equality()55 Grid_Generator::set_is_line_or_equality() {
56   kind_ = LINE_OR_EQUALITY;
57 }
58 
59 inline void
set_is_ray_or_point_or_inequality()60 Grid_Generator::set_is_ray_or_point_or_inequality() {
61   kind_ = RAY_OR_POINT_OR_INEQUALITY;
62 }
63 
64 inline void
set_topology(Topology x)65 Grid_Generator::set_topology(Topology x) {
66   PPL_USED(x);
67   PPL_ASSERT(x == NECESSARILY_CLOSED);
68 }
69 
70 inline void
set_necessarily_closed()71 Grid_Generator::set_necessarily_closed() {
72   set_topology(NECESSARILY_CLOSED);
73 }
74 
75 inline void
set_not_necessarily_closed()76 Grid_Generator::set_not_necessarily_closed() {
77   set_topology(NOT_NECESSARILY_CLOSED);
78 }
79 
80 inline
Grid_Generator(Linear_Expression & e,Type type)81 Grid_Generator::Grid_Generator(Linear_Expression& e, Type type) {
82   swap(expr, e);
83   if (type == LINE) {
84     kind_ = LINE_OR_EQUALITY;
85   }
86   else {
87     kind_ = RAY_OR_POINT_OR_INEQUALITY;
88   }
89   PPL_ASSERT(OK());
90 }
91 
92 inline
Grid_Generator(Representation r)93 Grid_Generator::Grid_Generator(Representation r)
94   : expr(Coefficient_one(), r),
95     kind_(RAY_OR_POINT_OR_INEQUALITY) {
96   expr.set_space_dimension(1);
97   PPL_ASSERT(OK());
98 }
99 
100 inline
Grid_Generator(const Grid_Generator & g)101 Grid_Generator::Grid_Generator(const Grid_Generator& g)
102   : expr(g.expr),
103     kind_(g.kind_) {
104 }
105 
106 inline
Grid_Generator(const Grid_Generator & g,Representation r)107 Grid_Generator::Grid_Generator(const Grid_Generator& g, Representation r)
108   : expr(g.expr, r),
109     kind_(g.kind_) {
110 }
111 
112 inline
Grid_Generator(dimension_type space_dim,Kind kind,Topology topology,Representation r)113 Grid_Generator::Grid_Generator(dimension_type space_dim, Kind kind,
114                                Topology topology, Representation r)
115   : expr(r),
116     kind_(kind) {
117   PPL_USED(topology);
118   PPL_ASSERT(topology == NECESSARILY_CLOSED);
119   expr.set_space_dimension(space_dim + 1);
120   PPL_ASSERT(space_dimension() == space_dim);
121 }
122 
123 inline
Grid_Generator(const Grid_Generator & g,dimension_type space_dim)124 Grid_Generator::Grid_Generator(const Grid_Generator& g,
125                                dimension_type space_dim)
126   : expr(g.expr, space_dim + 1),
127     kind_(g.kind_) {
128   PPL_ASSERT(OK());
129   PPL_ASSERT(space_dimension() == space_dim);
130 }
131 
132 inline
Grid_Generator(const Grid_Generator & g,dimension_type space_dim,Representation r)133 Grid_Generator::Grid_Generator(const Grid_Generator& g,
134                                dimension_type space_dim, Representation r)
135   : expr(g.expr, space_dim + 1, r),
136     kind_(g.kind_) {
137   PPL_ASSERT(OK());
138   PPL_ASSERT(space_dimension() == space_dim);
139 }
140 
141 inline
~Grid_Generator()142 Grid_Generator::~Grid_Generator() {
143 }
144 
145 inline Grid_Generator::expr_type
expression() const146 Grid_Generator::expression() const {
147   return expr_type(expr, true);
148 }
149 
150 inline Representation
representation() const151 Grid_Generator::representation() const {
152   return expr.representation();
153 }
154 
155 inline void
set_representation(Representation r)156 Grid_Generator::set_representation(Representation r) {
157   expr.set_representation(r);
158 }
159 
160 inline dimension_type
max_space_dimension()161 Grid_Generator::max_space_dimension() {
162   return Linear_Expression::max_space_dimension() - 1;
163 }
164 
165 inline dimension_type
space_dimension() const166 Grid_Generator::space_dimension() const {
167   return expression().space_dimension();
168 }
169 
170 inline void
set_space_dimension(dimension_type space_dim)171 Grid_Generator::set_space_dimension(dimension_type space_dim) {
172   const dimension_type old_space_dim = space_dimension();
173   if (space_dim > old_space_dim) {
174     expr.set_space_dimension(space_dim + 1);
175     expr.swap_space_dimensions(Variable(space_dim), Variable(old_space_dim));
176   }
177   else {
178     expr.swap_space_dimensions(Variable(space_dim), Variable(old_space_dim));
179     expr.set_space_dimension(space_dim + 1);
180   }
181   PPL_ASSERT(space_dimension() == space_dim);
182 }
183 
184 inline void
set_space_dimension_no_ok(dimension_type space_dim)185 Grid_Generator::set_space_dimension_no_ok(dimension_type space_dim) {
186   set_space_dimension(space_dim);
187 }
188 
189 inline void
shift_space_dimensions(Variable v,dimension_type n)190 Grid_Generator::shift_space_dimensions(Variable v, dimension_type n) {
191   expr.shift_space_dimensions(v, n);
192 }
193 
194 inline Grid_Generator::Type
type() const195 Grid_Generator::type() const {
196   if (is_line()) {
197     return LINE;
198   }
199   return is_point() ? POINT : PARAMETER;
200 }
201 
202 inline bool
is_line() const203 Grid_Generator::is_line() const {
204   return is_line_or_equality();
205 }
206 
207 inline bool
is_parameter() const208 Grid_Generator::is_parameter() const {
209   return is_parameter_or_point() && is_line_or_parameter();
210 }
211 
212 inline bool
is_line_or_parameter() const213 Grid_Generator::is_line_or_parameter() const {
214   return expr.inhomogeneous_term() == 0;
215 }
216 
217 inline bool
is_point() const218 Grid_Generator::is_point() const {
219   return !is_line_or_parameter();
220 }
221 
222 inline bool
is_parameter_or_point() const223 Grid_Generator::is_parameter_or_point() const {
224   return is_ray_or_point_or_inequality();
225 }
226 
227 inline void
set_divisor(Coefficient_traits::const_reference d)228 Grid_Generator::set_divisor(Coefficient_traits::const_reference d) {
229   PPL_ASSERT(!is_line());
230   if (is_line_or_parameter()) {
231     expr.set_coefficient(Variable(space_dimension()), d);
232   }
233   else {
234     expr.set_inhomogeneous_term(d);
235   }
236 }
237 
238 inline Coefficient_traits::const_reference
divisor() const239 Grid_Generator::divisor() const {
240   if (is_line()) {
241     throw_invalid_argument("divisor()", "*this is a line");
242   }
243   if (is_line_or_parameter()) {
244     return expr.coefficient(Variable(space_dimension()));
245   }
246   else {
247     return expr.inhomogeneous_term();
248   }
249 }
250 
251 inline bool
is_equal_at_dimension(dimension_type dim,const Grid_Generator & y) const252 Grid_Generator::is_equal_at_dimension(dimension_type dim,
253                                       const Grid_Generator& y) const {
254   const Grid_Generator& x = *this;
255   return x.expr.get(dim) * y.divisor() == y.expr.get(dim) * x.divisor();
256 }
257 
258 inline void
set_is_line()259 Grid_Generator::set_is_line() {
260   set_is_line_or_equality();
261 }
262 
263 inline void
set_is_parameter_or_point()264 Grid_Generator::set_is_parameter_or_point() {
265   set_is_ray_or_point_or_inequality();
266 }
267 
268 inline Grid_Generator&
operator =(const Grid_Generator & g)269 Grid_Generator::operator=(const Grid_Generator& g) {
270   Grid_Generator tmp = g;
271   swap(*this, tmp);
272 
273   return *this;
274 }
275 
276 inline Coefficient_traits::const_reference
coefficient(const Variable v) const277 Grid_Generator::coefficient(const Variable v) const {
278   if (v.space_dimension() > space_dimension()) {
279     throw_dimension_incompatible("coefficient(v)", "v", v);
280   }
281   return expr.coefficient(v);
282 }
283 
284 inline memory_size_type
total_memory_in_bytes() const285 Grid_Generator::total_memory_in_bytes() const {
286   return sizeof(*this) + external_memory_in_bytes();
287 }
288 
289 inline memory_size_type
external_memory_in_bytes() const290 Grid_Generator::external_memory_in_bytes() const {
291   return expr.external_memory_in_bytes();
292 }
293 
294 inline const Grid_Generator&
zero_dim_point()295 Grid_Generator::zero_dim_point() {
296   PPL_ASSERT(zero_dim_point_p != 0);
297   return *zero_dim_point_p;
298 }
299 
300 inline void
strong_normalize()301 Grid_Generator::strong_normalize() {
302   PPL_ASSERT(!is_parameter());
303   expr.normalize();
304   sign_normalize();
305 }
306 
307 inline void
m_swap(Grid_Generator & y)308 Grid_Generator::m_swap(Grid_Generator& y) {
309   using std::swap;
310   swap(expr, y.expr);
311   swap(kind_, y.kind_);
312 }
313 
314 /*! \relates Grid_Generator */
315 inline bool
operator ==(const Grid_Generator & x,const Grid_Generator & y)316 operator==(const Grid_Generator& x, const Grid_Generator& y) {
317   return x.is_equivalent_to(y);
318 }
319 
320 /*! \relates Grid_Generator */
321 inline bool
operator !=(const Grid_Generator & x,const Grid_Generator & y)322 operator!=(const Grid_Generator& x, const Grid_Generator& y) {
323   return !(x == y);
324 }
325 
326 /*! \relates Grid_Generator */
327 inline Grid_Generator
grid_line(const Linear_Expression & e,Representation r)328 grid_line(const Linear_Expression& e, Representation r) {
329   return Grid_Generator::grid_line(e, r);
330 }
331 
332 /*! \relates Grid_Generator */
333 inline Grid_Generator
parameter(const Linear_Expression & e,Coefficient_traits::const_reference d,Representation r)334 parameter(const Linear_Expression& e,
335           Coefficient_traits::const_reference d, Representation r) {
336   return Grid_Generator::parameter(e, d, r);
337 }
338 
339 /*! \relates Grid_Generator */
340 inline Grid_Generator
parameter(Representation r)341 parameter(Representation r) {
342   return Grid_Generator::parameter(r);
343 }
344 
345 /*! \relates Grid_Generator */
346 inline Grid_Generator
parameter(const Linear_Expression & e,Representation r)347 parameter(const Linear_Expression& e, Representation r) {
348   return Grid_Generator::parameter(e, r);
349 }
350 
351 /*! \relates Grid_Generator */
352 inline Grid_Generator
grid_point(const Linear_Expression & e,Coefficient_traits::const_reference d,Representation r)353 grid_point(const Linear_Expression& e,
354            Coefficient_traits::const_reference d, Representation r) {
355   return Grid_Generator::grid_point(e, d, r);
356 }
357 
358 /*! \relates Grid_Generator */
359 inline Grid_Generator
grid_point(Representation r)360 grid_point(Representation r) {
361   return Grid_Generator::grid_point(r);
362 }
363 
364 /*! \relates Grid_Generator */
365 inline Grid_Generator
grid_point(const Linear_Expression & e,Representation r)366 grid_point(const Linear_Expression& e, Representation r) {
367   return Grid_Generator::grid_point(e, r);
368 }
369 
370 /*! \relates Grid_Generator */
371 inline void
swap(Grid_Generator & x,Grid_Generator & y)372 swap(Grid_Generator& x, Grid_Generator& y) {
373   x.m_swap(y);
374 }
375 
376 } // namespace Parma_Polyhedra_Library
377 
378 #endif // !defined(PPL_Grid_Generator_inlines_hh)
379