1 /* Grid 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_inlines_hh
25 #define PPL_Grid_inlines_hh 1
26 
27 #include "Grid_Generator_defs.hh"
28 #include "Grid_Generator_System_defs.hh"
29 #include "Grid_Generator_System_inlines.hh"
30 #include <algorithm>
31 
32 namespace Parma_Polyhedra_Library {
33 
34 inline bool
marked_empty() const35 Grid::marked_empty() const {
36   return status.test_empty();
37 }
38 
39 inline bool
congruences_are_up_to_date() const40 Grid::congruences_are_up_to_date() const {
41   return status.test_c_up_to_date();
42 }
43 
44 inline bool
generators_are_up_to_date() const45 Grid::generators_are_up_to_date() const {
46   return status.test_g_up_to_date();
47 }
48 
49 inline bool
congruences_are_minimized() const50 Grid::congruences_are_minimized() const {
51   return status.test_c_minimized();
52 }
53 
54 inline bool
generators_are_minimized() const55 Grid::generators_are_minimized() const {
56   return status.test_g_minimized();
57 }
58 
59 inline void
set_generators_up_to_date()60 Grid::set_generators_up_to_date() {
61   status.set_g_up_to_date();
62 }
63 
64 inline void
set_congruences_up_to_date()65 Grid::set_congruences_up_to_date() {
66   status.set_c_up_to_date();
67 }
68 
69 inline void
set_congruences_minimized()70 Grid::set_congruences_minimized() {
71   set_congruences_up_to_date();
72   status.set_c_minimized();
73 }
74 
75 inline void
set_generators_minimized()76 Grid::set_generators_minimized() {
77   set_generators_up_to_date();
78   status.set_g_minimized();
79 }
80 
81 inline void
clear_empty()82 Grid::clear_empty() {
83   status.reset_empty();
84 }
85 
86 inline void
clear_congruences_minimized()87 Grid::clear_congruences_minimized() {
88   status.reset_c_minimized();
89 }
90 
91 inline void
clear_generators_minimized()92 Grid::clear_generators_minimized() {
93   status.reset_g_minimized();
94 }
95 
96 inline void
clear_congruences_up_to_date()97 Grid::clear_congruences_up_to_date() {
98   clear_congruences_minimized();
99   status.reset_c_up_to_date();
100   // Can get rid of con_sys here.
101 }
102 
103 inline void
clear_generators_up_to_date()104 Grid::clear_generators_up_to_date() {
105   clear_generators_minimized();
106   status.reset_g_up_to_date();
107   // Can get rid of gen_sys here.
108 }
109 
110 inline dimension_type
max_space_dimension()111 Grid::max_space_dimension() {
112   // One dimension is reserved to have a value of type dimension_type
113   // that does not represent a legal dimension.
114   return std::min(std::numeric_limits<dimension_type>::max() - 1,
115                   std::min(Congruence_System::max_space_dimension(),
116                            Grid_Generator_System::max_space_dimension()
117                            )
118                   );
119 }
120 
121 inline
Grid(dimension_type num_dimensions,const Degenerate_Element kind)122 Grid::Grid(dimension_type num_dimensions,
123            const Degenerate_Element kind)
124   : con_sys(),
125     gen_sys(check_space_dimension_overflow(num_dimensions,
126                                            max_space_dimension(),
127                                            "PPL::Grid::",
128                                            "Grid(n, k)",
129                                            "n exceeds the maximum "
130                                            "allowed space dimension")) {
131   construct(num_dimensions, kind);
132   PPL_ASSERT(OK());
133 }
134 
135 inline
Grid(const Congruence_System & cgs)136 Grid::Grid(const Congruence_System& cgs)
137   : con_sys(check_space_dimension_overflow(cgs.space_dimension(),
138                                            max_space_dimension(),
139                                            "PPL::Grid::",
140                                            "Grid(cgs)",
141                                            "the space dimension of cgs "
142                                            "exceeds the maximum allowed "
143                                            "space dimension")),
144     gen_sys(cgs.space_dimension()) {
145   Congruence_System cgs_copy(cgs);
146   construct(cgs_copy);
147 }
148 
149 inline
Grid(Congruence_System & cgs,Recycle_Input)150 Grid::Grid(Congruence_System& cgs, Recycle_Input)
151   : con_sys(check_space_dimension_overflow(cgs.space_dimension(),
152                                            max_space_dimension(),
153                                            "PPL::Grid::",
154                                            "Grid(cgs, recycle)",
155                                            "the space dimension of cgs "
156                                            "exceeds the maximum allowed "
157                                            "space dimension")),
158     gen_sys(cgs.space_dimension()) {
159   construct(cgs);
160 }
161 
162 inline
Grid(const Grid_Generator_System & ggs)163 Grid::Grid(const Grid_Generator_System& ggs)
164   : con_sys(check_space_dimension_overflow(ggs.space_dimension(),
165                                            max_space_dimension(),
166                                            "PPL::Grid::",
167                                            "Grid(ggs)",
168                                            "the space dimension of ggs "
169                                            "exceeds the maximum allowed "
170                                            "space dimension")),
171     gen_sys(ggs.space_dimension()) {
172   Grid_Generator_System ggs_copy(ggs);
173   construct(ggs_copy);
174 }
175 
176 inline
Grid(Grid_Generator_System & ggs,Recycle_Input)177 Grid::Grid(Grid_Generator_System& ggs, Recycle_Input)
178   : con_sys(check_space_dimension_overflow(ggs.space_dimension(),
179                                            max_space_dimension(),
180                                            "PPL::Grid::",
181                                            "Grid(ggs, recycle)",
182                                            "the space dimension of ggs "
183                                            "exceeds the maximum allowed "
184                                            "space dimension")),
185     gen_sys(ggs.space_dimension()) {
186   construct(ggs);
187 }
188 
189 template <typename U>
190 inline
Grid(const BD_Shape<U> & bd,Complexity_Class)191 Grid::Grid(const BD_Shape<U>& bd, Complexity_Class)
192   : con_sys(check_space_dimension_overflow(bd.space_dimension(),
193                                            max_space_dimension(),
194                                            "PPL::Grid::",
195                                            "Grid(bd)",
196                                            "the space dimension of bd "
197                                            "exceeds the maximum allowed "
198                                            "space dimension")),
199     gen_sys(bd.space_dimension()) {
200   Congruence_System cgs = bd.congruences();
201   construct(cgs);
202 }
203 
204 template <typename U>
205 inline
Grid(const Octagonal_Shape<U> & os,Complexity_Class)206 Grid::Grid(const Octagonal_Shape<U>& os, Complexity_Class)
207   : con_sys(check_space_dimension_overflow(os.space_dimension(),
208                                            max_space_dimension(),
209                                            "PPL::Grid::",
210                                            "Grid(os)",
211                                            "the space dimension of os "
212                                            "exceeds the maximum allowed "
213                                            "space dimension")),
214     gen_sys(os.space_dimension()) {
215   Congruence_System cgs = os.congruences();
216   construct(cgs);
217 }
218 
219 inline
~Grid()220 Grid::~Grid() {
221 }
222 
223 inline dimension_type
space_dimension() const224 Grid::space_dimension() const {
225   return space_dim;
226 }
227 
228 inline memory_size_type
total_memory_in_bytes() const229 Grid::total_memory_in_bytes() const {
230   return sizeof(*this) + external_memory_in_bytes();
231 }
232 
233 inline int32_t
hash_code() const234 Grid::hash_code() const {
235   return hash_code_from_dimension(space_dimension());
236 }
237 
238 inline Constraint_System
constraints() const239 Grid::constraints() const {
240   return Constraint_System(congruences());
241 }
242 
243 inline Constraint_System
minimized_constraints() const244 Grid::minimized_constraints() const {
245   return Constraint_System(minimized_congruences());
246 }
247 
248 inline void
m_swap(Grid & y)249 Grid::m_swap(Grid& y) {
250   using std::swap;
251   swap(con_sys, y.con_sys);
252   swap(gen_sys, y.gen_sys);
253   swap(status, y.status);
254   swap(space_dim, y.space_dim);
255   swap(dim_kinds, y.dim_kinds);
256 }
257 
258 inline void
add_congruence(const Congruence & cg)259 Grid::add_congruence(const Congruence& cg) {
260   // Dimension-compatibility check.
261   if (space_dim < cg.space_dimension()) {
262     throw_dimension_incompatible("add_congruence(cg)", "cg", cg);
263   }
264 
265   if (!marked_empty()) {
266     add_congruence_no_check(cg);
267   }
268 }
269 
270 inline void
add_congruences(const Congruence_System & cgs)271 Grid::add_congruences(const Congruence_System& cgs) {
272   // TODO: this is just an executable specification.
273   // Space dimension compatibility check.
274   if (space_dim < cgs.space_dimension()) {
275     throw_dimension_incompatible("add_congruences(cgs)", "cgs", cgs);
276   }
277 
278   if (!marked_empty()) {
279     Congruence_System cgs_copy = cgs;
280     add_recycled_congruences(cgs_copy);
281   }
282 }
283 
284 inline void
refine_with_congruence(const Congruence & cg)285 Grid::refine_with_congruence(const Congruence& cg) {
286   add_congruence(cg);
287 }
288 
289 inline void
refine_with_congruences(const Congruence_System & cgs)290 Grid::refine_with_congruences(const Congruence_System& cgs) {
291   add_congruences(cgs);
292 }
293 
294 inline bool
can_recycle_constraint_systems()295 Grid::can_recycle_constraint_systems() {
296   return true;
297 }
298 
299 inline bool
can_recycle_congruence_systems()300 Grid::can_recycle_congruence_systems() {
301   return true;
302 }
303 
304 inline void
add_constraint(const Constraint & c)305 Grid::add_constraint(const Constraint& c) {
306   // Space dimension compatibility check.
307   if (space_dim < c.space_dimension()) {
308     throw_dimension_incompatible("add_constraint(c)", "c", c);
309   }
310   if (!marked_empty()) {
311     add_constraint_no_check(c);
312   }
313 }
314 
315 inline void
add_recycled_constraints(Constraint_System & cs)316 Grid::add_recycled_constraints(Constraint_System& cs) {
317   // TODO: really recycle the constraints.
318   add_constraints(cs);
319 }
320 
321 inline bool
bounds_from_above(const Linear_Expression & expr) const322 Grid::bounds_from_above(const Linear_Expression& expr) const {
323   return bounds(expr, "bounds_from_above(e)");
324 }
325 
326 inline bool
bounds_from_below(const Linear_Expression & expr) const327 Grid::bounds_from_below(const Linear_Expression& expr) const {
328   return bounds(expr, "bounds_from_below(e)");
329 }
330 
331 inline bool
maximize(const Linear_Expression & expr,Coefficient & sup_n,Coefficient & sup_d,bool & maximum) const332 Grid::maximize(const Linear_Expression& expr,
333                Coefficient& sup_n, Coefficient& sup_d, bool& maximum) const {
334   return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum);
335 }
336 
337 inline bool
maximize(const Linear_Expression & expr,Coefficient & sup_n,Coefficient & sup_d,bool & maximum,Generator & point) const338 Grid::maximize(const Linear_Expression& expr,
339                Coefficient& sup_n, Coefficient& sup_d, bool& maximum,
340                Generator& point) const {
341   return max_min(expr, "maximize(e, ...)", sup_n, sup_d, maximum, &point);
342 }
343 
344 inline bool
minimize(const Linear_Expression & expr,Coefficient & inf_n,Coefficient & inf_d,bool & minimum) const345 Grid::minimize(const Linear_Expression& expr,
346                Coefficient& inf_n, Coefficient& inf_d, bool& minimum) const {
347   return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum);
348 }
349 
350 inline bool
minimize(const Linear_Expression & expr,Coefficient & inf_n,Coefficient & inf_d,bool & minimum,Generator & point) const351 Grid::minimize(const Linear_Expression& expr,
352                Coefficient& inf_n, Coefficient& inf_d, bool& minimum,
353                Generator& point) const {
354   return max_min(expr, "minimize(e, ...)", inf_n, inf_d, minimum, &point);
355 }
356 
357 inline void
normalize_divisors(Grid_Generator_System & sys)358 Grid::normalize_divisors(Grid_Generator_System& sys) {
359   PPL_DIRTY_TEMP_COEFFICIENT(divisor);
360   divisor = 1;
361   normalize_divisors(sys, divisor);
362 }
363 
364 /*! \relates Grid */
365 inline bool
operator !=(const Grid & x,const Grid & y)366 operator!=(const Grid& x, const Grid& y) {
367   return !(x == y);
368 }
369 
370 inline bool
strictly_contains(const Grid & y) const371 Grid::strictly_contains(const Grid& y) const {
372   const Grid& x = *this;
373   return x.contains(y) && !y.contains(x);
374 }
375 
376 inline void
topological_closure_assign()377 Grid::topological_closure_assign() {
378 }
379 
380 /*! \relates Grid */
381 inline void
swap(Grid & x,Grid & y)382 swap(Grid& x, Grid& y) {
383   x.m_swap(y);
384 }
385 
386 } // namespace Parma_Polyhedra_Library
387 
388 #endif // !defined(PPL_Grid_inlines_hh)
389