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