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