1 /* Pointset_Powerset 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_Pointset_Powerset_inlines_hh
25 #define PPL_Pointset_Powerset_inlines_hh 1
26
27 #include "Constraint_defs.hh"
28 #include "Constraint_System_defs.hh"
29 #include "Constraint_System_inlines.hh"
30 #include "Congruence_defs.hh"
31 #include "Congruence_System_defs.hh"
32 #include "Congruence_System_inlines.hh"
33 #include "C_Polyhedron_defs.hh"
34 #include "NNC_Polyhedron_defs.hh"
35 #include <algorithm>
36 #include <deque>
37
38 namespace Parma_Polyhedra_Library {
39
40 template <typename PSET>
41 inline dimension_type
space_dimension() const42 Pointset_Powerset<PSET>::space_dimension() const {
43 return space_dim;
44 }
45
46 template <typename PSET>
47 inline dimension_type
max_space_dimension()48 Pointset_Powerset<PSET>::max_space_dimension() {
49 return PSET::max_space_dimension();
50 }
51
52 template <typename PSET>
53 inline
Pointset_Powerset(dimension_type num_dimensions,Degenerate_Element kind)54 Pointset_Powerset<PSET>::Pointset_Powerset(dimension_type num_dimensions,
55 Degenerate_Element kind)
56 : Base(), space_dim(num_dimensions) {
57 Pointset_Powerset& x = *this;
58 if (kind == UNIVERSE) {
59 x.sequence.push_back(Determinate<PSET>(PSET(num_dimensions, kind)));
60 }
61 PPL_ASSERT_HEAVY(x.OK());
62 }
63
64 template <typename PSET>
65 inline
Pointset_Powerset(const Pointset_Powerset & y,Complexity_Class)66 Pointset_Powerset<PSET>::Pointset_Powerset(const Pointset_Powerset& y,
67 Complexity_Class)
68 : Base(y), space_dim(y.space_dim) {
69 }
70
71 template <typename PSET>
72 inline
Pointset_Powerset(const C_Polyhedron & ph,Complexity_Class complexity)73 Pointset_Powerset<PSET>::Pointset_Powerset(const C_Polyhedron& ph,
74 Complexity_Class complexity)
75 : Base(), space_dim(ph.space_dimension()) {
76 Pointset_Powerset& x = *this;
77 if (complexity == ANY_COMPLEXITY) {
78 if (ph.is_empty()) {
79 return;
80 }
81 }
82 else {
83 x.reduced = false;
84 }
85 x.sequence.push_back(Determinate<PSET>(PSET(ph, complexity)));
86 x.reduced = false;
87 PPL_ASSERT_HEAVY(OK());
88 }
89
90 template <typename PSET>
91 inline
Pointset_Powerset(const NNC_Polyhedron & ph,Complexity_Class complexity)92 Pointset_Powerset<PSET>::Pointset_Powerset(const NNC_Polyhedron& ph,
93 Complexity_Class complexity)
94 : Base(), space_dim(ph.space_dimension()) {
95 Pointset_Powerset& x = *this;
96 if (complexity == ANY_COMPLEXITY) {
97 if (ph.is_empty()) {
98 return;
99 }
100 }
101 else {
102 x.reduced = false;
103 }
104 x.sequence.push_back(Determinate<PSET>(PSET(ph, complexity)));
105 PPL_ASSERT_HEAVY(OK());
106 }
107
108 template <typename PSET>
109 inline
Pointset_Powerset(const Grid & gr,Complexity_Class)110 Pointset_Powerset<PSET>::Pointset_Powerset(const Grid& gr,
111 Complexity_Class)
112 : Base(), space_dim(gr.space_dimension()) {
113 Pointset_Powerset& x = *this;
114 if (!gr.is_empty()) {
115 x.sequence.push_back(Determinate<PSET>(PSET(gr)));
116 }
117 PPL_ASSERT_HEAVY(OK());
118 }
119
120 template <typename PSET>
121 template <typename QH1, typename QH2, typename R>
122 inline
123 Pointset_Powerset<PSET>
Pointset_Powerset(const Partially_Reduced_Product<QH1,QH2,R> & prp,Complexity_Class complexity)124 ::Pointset_Powerset(const Partially_Reduced_Product<QH1, QH2, R>& prp,
125 Complexity_Class complexity)
126 : Base(), space_dim(prp.space_dimension()) {
127 Pointset_Powerset& x = *this;
128 if (complexity == ANY_COMPLEXITY) {
129 if (prp.is_empty()) {
130 return;
131 }
132 }
133 else {
134 x.reduced = false;
135 }
136 x.sequence.push_back(Determinate<PSET>(PSET(prp, complexity)));
137 x.reduced = false;
138 PPL_ASSERT_HEAVY(OK());
139 }
140
141 template <typename PSET>
142 template <typename Interval>
Pointset_Powerset(const Box<Interval> & box,Complexity_Class)143 Pointset_Powerset<PSET>::Pointset_Powerset(const Box<Interval>& box,
144 Complexity_Class)
145 : Base(), space_dim(box.space_dimension()) {
146 Pointset_Powerset& x = *this;
147 if (!box.is_empty()) {
148 x.sequence.push_back(Determinate<PSET>(PSET(box)));
149 }
150 PPL_ASSERT_HEAVY(OK());
151 }
152
153 template <typename PSET>
154 template <typename T>
Pointset_Powerset(const Octagonal_Shape<T> & os,Complexity_Class)155 Pointset_Powerset<PSET>::Pointset_Powerset(const Octagonal_Shape<T>& os,
156 Complexity_Class)
157 : Base(), space_dim(os.space_dimension()) {
158 Pointset_Powerset& x = *this;
159 if (!os.is_empty()) {
160 x.sequence.push_back(Determinate<PSET>(PSET(os)));
161 }
162 PPL_ASSERT_HEAVY(OK());
163 }
164
165 template <typename PSET>
166 template <typename T>
Pointset_Powerset(const BD_Shape<T> & bds,Complexity_Class)167 Pointset_Powerset<PSET>::Pointset_Powerset(const BD_Shape<T>& bds,
168 Complexity_Class)
169 : Base(), space_dim(bds.space_dimension()) {
170 Pointset_Powerset& x = *this;
171 if (!bds.is_empty()) {
172 x.sequence.push_back(Determinate<PSET>(PSET(bds)));
173 }
174 PPL_ASSERT_HEAVY(OK());
175 }
176
177 template <typename PSET>
178 inline
Pointset_Powerset(const Constraint_System & cs)179 Pointset_Powerset<PSET>::Pointset_Powerset(const Constraint_System& cs)
180 : Base(Determinate<PSET>(cs)), space_dim(cs.space_dimension()) {
181 PPL_ASSERT_HEAVY(OK());
182 }
183
184 template <typename PSET>
185 inline
Pointset_Powerset(const Congruence_System & cgs)186 Pointset_Powerset<PSET>::Pointset_Powerset(const Congruence_System& cgs)
187 : Base(Determinate<PSET>(cgs)), space_dim(cgs.space_dimension()) {
188 PPL_ASSERT_HEAVY(OK());
189 }
190
191 template <typename PSET>
192 inline Pointset_Powerset<PSET>&
operator =(const Pointset_Powerset & y)193 Pointset_Powerset<PSET>::operator=(const Pointset_Powerset& y) {
194 Pointset_Powerset& x = *this;
195 x.Base::operator=(y);
196 x.space_dim = y.space_dim;
197 return x;
198 }
199
200 template <typename PSET>
201 inline void
m_swap(Pointset_Powerset & y)202 Pointset_Powerset<PSET>::m_swap(Pointset_Powerset& y) {
203 Pointset_Powerset& x = *this;
204 x.Base::m_swap(y);
205 using std::swap;
206 swap(x.space_dim, y.space_dim);
207 }
208
209 template <typename PSET>
210 template <typename QH>
211 inline Pointset_Powerset<PSET>&
operator =(const Pointset_Powerset<QH> & y)212 Pointset_Powerset<PSET>::operator=(const Pointset_Powerset<QH>& y) {
213 Pointset_Powerset& x = *this;
214 Pointset_Powerset<PSET> ps(y);
215 swap(x, ps);
216 return x;
217 }
218
219 template <typename PSET>
220 inline void
intersection_assign(const Pointset_Powerset & y)221 Pointset_Powerset<PSET>::intersection_assign(const Pointset_Powerset& y) {
222 Pointset_Powerset& x = *this;
223 x.pairwise_apply_assign(y,
224 Det_PSET::lift_op_assign(std::mem_fun_ref(&PSET::intersection_assign)));
225 }
226
227 template <typename PSET>
228 inline void
time_elapse_assign(const Pointset_Powerset & y)229 Pointset_Powerset<PSET>::time_elapse_assign(const Pointset_Powerset& y) {
230 Pointset_Powerset& x = *this;
231 x.pairwise_apply_assign(y,
232 Det_PSET::lift_op_assign(std::mem_fun_ref(&PSET::time_elapse_assign)));
233 }
234
235 template <typename PSET>
236 inline Poly_Con_Relation
relation_with(const Constraint & c) const237 Pointset_Powerset<PSET>::relation_with(const Constraint& c) const {
238 return relation_with_aux(c);
239 }
240
241 template <typename PSET>
242 inline Poly_Con_Relation
relation_with(const Congruence & cg) const243 Pointset_Powerset<PSET>::relation_with(const Congruence& cg) const {
244 return relation_with_aux(cg);
245 }
246
247 template <typename PSET>
248 inline bool
249 Pointset_Powerset<PSET>
geometrically_covers(const Pointset_Powerset & y) const250 ::geometrically_covers(const Pointset_Powerset& y) const {
251 // This code is only used when PSET is an abstraction of NNC_Polyhedron.
252 const Pointset_Powerset<NNC_Polyhedron> xx(*this);
253 const Pointset_Powerset<NNC_Polyhedron> yy(y);
254 return xx.geometrically_covers(yy);
255 }
256
257 template <typename PSET>
258 inline bool
259 Pointset_Powerset<PSET>
geometrically_equals(const Pointset_Powerset & y) const260 ::geometrically_equals(const Pointset_Powerset& y) const {
261 // This code is only used when PSET is an abstraction of NNC_Polyhedron.
262 const Pointset_Powerset<NNC_Polyhedron> xx(*this);
263 const Pointset_Powerset<NNC_Polyhedron> yy(y);
264 return xx.geometrically_covers(yy) && yy.geometrically_covers(xx);
265 }
266
267 template <>
268 inline bool
269 Pointset_Powerset<Grid>
geometrically_equals(const Pointset_Powerset & y) const270 ::geometrically_equals(const Pointset_Powerset& y) const {
271 const Pointset_Powerset& x = *this;
272 return x.geometrically_covers(y) && y.geometrically_covers(x);
273 }
274
275 template <>
276 inline bool
277 Pointset_Powerset<NNC_Polyhedron>
geometrically_equals(const Pointset_Powerset & y) const278 ::geometrically_equals(const Pointset_Powerset& y) const {
279 const Pointset_Powerset& x = *this;
280 return x.geometrically_covers(y) && y.geometrically_covers(x);
281 }
282
283 template <typename PSET>
284 inline memory_size_type
external_memory_in_bytes() const285 Pointset_Powerset<PSET>::external_memory_in_bytes() const {
286 return Base::external_memory_in_bytes();
287 }
288
289 template <typename PSET>
290 inline memory_size_type
total_memory_in_bytes() const291 Pointset_Powerset<PSET>::total_memory_in_bytes() const {
292 return sizeof(*this) + external_memory_in_bytes();
293 }
294
295 template <typename PSET>
296 inline int32_t
hash_code() const297 Pointset_Powerset<PSET>::hash_code() const {
298 return hash_code_from_dimension(space_dimension());
299 }
300
301 template <typename PSET>
302 inline void
303 Pointset_Powerset<PSET>
difference_assign(const Pointset_Powerset & y)304 ::difference_assign(const Pointset_Powerset& y) {
305 // This code is only used when PSET is an abstraction of NNC_Polyhedron.
306 Pointset_Powerset<NNC_Polyhedron> nnc_this(*this);
307 Pointset_Powerset<NNC_Polyhedron> nnc_y(y);
308 nnc_this.difference_assign(nnc_y);
309 *this = nnc_this;
310 }
311
312 /*! \relates Pointset_Powerset */
313 template <typename PSET>
314 inline bool
check_containment(const PSET & ph,const Pointset_Powerset<PSET> & ps)315 check_containment(const PSET& ph, const Pointset_Powerset<PSET>& ps) {
316 // This code is only used when PSET is an abstraction of NNC_Polyhedron.
317 const NNC_Polyhedron ph_nnc = NNC_Polyhedron(ph.constraints());
318 const Pointset_Powerset<NNC_Polyhedron> ps_nnc(ps);
319 return check_containment(ph_nnc, ps_nnc);
320 }
321
322 /*! \relates Pointset_Powerset */
323 template <>
324 inline bool
check_containment(const C_Polyhedron & ph,const Pointset_Powerset<C_Polyhedron> & ps)325 check_containment(const C_Polyhedron& ph,
326 const Pointset_Powerset<C_Polyhedron>& ps) {
327 return check_containment(NNC_Polyhedron(ph),
328 Pointset_Powerset<NNC_Polyhedron>(ps));
329 }
330
331 /*! \relates Pointset_Powerset */
332 template <typename PSET>
333 inline void
swap(Pointset_Powerset<PSET> & x,Pointset_Powerset<PSET> & y)334 swap(Pointset_Powerset<PSET>& x, Pointset_Powerset<PSET>& y) {
335 x.m_swap(y);
336 }
337
338 } // namespace Parma_Polyhedra_Library
339
340 #endif // !defined(PPL_Pointset_Powerset_inlines_hh)
341