PPL  1.2
Pointset_Ask_Tell_templates.hh
Go to the documentation of this file.
1 /* Pointset_Ask_Tell class implementation: non-inline template 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_Ask_Tell_templates_hh
25 #define PPL_Pointset_Ask_Tell_templates_hh 1
26 
27 #include "Constraint_defs.hh"
30 #include "C_Polyhedron_defs.hh"
31 #include "NNC_Polyhedron_defs.hh"
32 #include "Variables_Set_defs.hh"
33 #include <algorithm>
34 #include <deque>
35 #include <string>
36 #include <iostream>
37 #include <sstream>
38 #include <stdexcept>
39 
40 namespace Parma_Polyhedra_Library {
41 
42 template <typename PSET>
43 void
45  Pointset_Ask_Tell& x = *this;
46  if (x.space_dimension() != ph.space_dimension()) {
47  std::ostringstream s;
48  s << "PPL::Pointset_Ask_Tell<PSET>::add_disjunct(ph):\n"
49  << "this->space_dimension() == " << x.space_dimension() << ", "
50  << "ph.space_dimension() == " << ph.space_dimension() << ".";
51  throw std::invalid_argument(s.str());
52  }
53  x.sequence.push_back(Determinate<PSET>(ph));
54  x.reduced = false;
55  PPL_ASSERT_HEAVY(x.OK());
56 }
57 
58 template <>
59 template <typename QH>
62  : Base(), space_dim(y.space_dimension()) {
63  Pointset_Ask_Tell& x = *this;
64  for (typename Pointset_Ask_Tell<QH>::const_iterator i = y.begin(),
65  y_end = y.end(); i != y_end; ++i) {
67  nnc_ask(NNC_Polyhedron(i->ask().pointset().constraints()));
69  nnc_tell(NNC_Polyhedron(i->tell().pointset().constraints()));
70  x.sequence.push_back(Pair(nnc_ask, nnc_tell));
71  }
72  // FIXME: the following is a bug!
73  x.normalized = y.normalized;
74  PPL_ASSERT_HEAVY(x.OK());
75 }
76 
77 template <>
78 template <typename QH>
81  : Base(), space_dim(y.space_dimension()) {
82  Pointset_Ask_Tell& x = *this;
83  for (typename Pointset_Ask_Tell<QH>::const_iterator i = y.begin(),
84  y_end = y.end(); i != y_end; ++i) {
86  c_ask(C_Polyhedron(i->ask().pointset().constraints()));
88  c_tell(C_Polyhedron(i->tell().pointset().constraints()));
89  x.sequence.push_back(Pair(c_ask, c_tell));
90  }
91 
92  // Note: in general, normalization of `y' does not propagate to `x',
93  // because the approximation potentially introduced by the conversion
94  // may have made uncomparable elements in `y' to become comparable in `x'.
95  x.normalized = false;
96  PPL_ASSERT_HEAVY(x.OK());
97 }
98 
99 template <typename PSET>
100 void
102  Pointset_Ask_Tell& x = *this;
103  for (const_iterator yi = y.begin(), y_end = y.end(); yi != y_end; ++yi) {
104  Det_PSET ask(PSET(space_dim, UNIVERSE));
105  ask.concatenate_assign(yi->ask());
106  Det_PSET tell(PSET(space_dim, UNIVERSE));
107  tell.concatenate_assign(yi->tell());
108  x.sequence.push_back(Pair(ask, tell));
109  }
110  space_dim += y.space_dim;
111  if (x.normalized) {
112  x.normalized = y.normalized;
113  }
114  PPL_ASSERT_HEAVY(x.OK());
115 }
116 
117 template <typename PSET>
118 void
120  Pointset_Ask_Tell& x = *this;
121  for (Sequence_iterator si = x.sequence.begin(),
122  s_end = x.sequence.end(); si != s_end; ++si) {
123  si->pointset().add_constraint(c);
124  }
125  x.reduced = false;
126  PPL_ASSERT_HEAVY(x.OK());
127 }
128 
129 template <typename PSET>
130 void
132  Pointset_Ask_Tell& x = *this;
133  for (Sequence_iterator si = x.sequence.begin(),
134  s_end = x.sequence.end(); si != s_end; ++si) {
135  si->pointset().add_constraints(cs);
136  }
137  x.reduced = false;
138  PPL_ASSERT_HEAVY(x.OK());
139 }
140 
141 template <typename PSET>
142 void
144  Pointset_Ask_Tell& x = *this;
145  for (Sequence_iterator si = x.sequence.begin(),
146  s_end = x.sequence.end(); si != s_end; ++si) {
147  si->pointset().unconstrain(var);
148  }
149  x.reduced = false;
150  PPL_ASSERT_HEAVY(x.OK());
151 }
152 
153 template <typename PSET>
154 void
156  Pointset_Ask_Tell& x = *this;
157  for (Sequence_iterator si = x.sequence.begin(),
158  s_end = x.sequence.end(); si != s_end; ++si) {
159  si->pointset().unconstrain(vars);
160  }
161  x.reduced = false;
162  PPL_ASSERT_HEAVY(x.OK());
163 }
164 
165 template <typename PSET>
166 void
168  Pointset_Ask_Tell& x = *this;
169  for (Sequence_iterator si = x.sequence.begin(),
170  s_end = x.sequence.end(); si != s_end; ++si) {
171  si->pointset().add_space_dimensions_and_embed(m);
172  }
173  x.space_dim += m;
174  PPL_ASSERT_HEAVY(x.OK());
175 }
176 
177 template <typename PSET>
178 void
180  Pointset_Ask_Tell& x = *this;
181  for (Sequence_iterator si = x.sequence.begin(),
182  s_end = x.sequence.end(); si != s_end; ++si) {
183  si->pointset().add_space_dimensions_and_project(m);
184  }
185  x.space_dim += m;
186  PPL_ASSERT_HEAVY(x.OK());
187 }
188 
189 template <typename PSET>
190 void
193  Pointset_Ask_Tell& x = *this;
194  Variables_Set::size_type num_removed = vars.size();
195  if (num_removed > 0) {
196  for (Sequence_iterator si = x.sequence.begin(),
197  s_end = x.sequence.end(); si != s_end; ) {
198  PSET& ask = si->ask().pointset();
199  PSET& tell = si->tell().pointset();
200  ask.remove_space_dimensions(vars);
201  tell.remove_space_dimensions(vars);
202  if (tell.contains(ask)) {
203  si = x.sequence.erase(si);
204  s_end = x.sequence.end();
205  }
206  else {
207  x.normalized = false;
208  ++si;
209  }
210  }
211  x.space_dim -= num_removed;
212  PPL_ASSERT_HEAVY(x.OK());
213  }
214 }
215 
216 template <typename PSET>
217 void
219  new_dimension) {
220  Pointset_Ask_Tell& x = *this;
221  if (new_dimension < x.space_dim) {
222  for (Sequence_iterator si = x.sequence.begin(),
223  s_end = x.sequence.end(); si != s_end; ++si) {
224  si->ask().pointset().remove_higher_space_dimensions(new_dimension);
225  si->tell().pointset().remove_higher_space_dimensions(new_dimension);
226  x.reduced = false;
227  }
228  x.space_dim = new_dimension;
229  PPL_ASSERT_HEAVY(x.OK());
230  }
231 }
232 
233 template <typename PSET>
234 template <typename Partial_Function>
235 void
237  Pointset_Ask_Tell& x = *this;
238  if (x.is_bottom()) {
239  dimension_type n = 0;
240  for (dimension_type i = x.space_dim; i-- > 0; ) {
241  dimension_type new_i;
242  if (pfunc.maps(i, new_i)) {
243  ++n;
244  }
245  }
246  x.space_dim = n;
247  }
248  else {
249  Sequence_iterator s_begin = x.sequence.begin();
250  for (Sequence_iterator si = s_begin,
251  s_end = x.sequence.end(); si != s_end; ++si) {
252  si->pointset().map_space_dimensions(pfunc);
253  }
254  x.space_dim = s_begin->pointset().space_dimension();
255  x.reduced = false;
256  }
257  PPL_ASSERT_HEAVY(x.OK());
258 }
259 
260 template <typename PSET>
261 void
262 Pointset_Ask_Tell<PSET>::ascii_dump(std::ostream& s) const {
263  const Pointset_Ask_Tell& x = *this;
264  s << "size " << x.size()
265  << "\nspace_dim " << x.space_dim
266  << "\n";
267  for (const_iterator xi = x.begin(), x_end = x.end(); xi != x_end; ++xi) {
268  xi->pointset().ascii_dump(s);
269  }
270 }
271 
273 
274 template <typename PSET>
275 bool
276 Pointset_Ask_Tell<PSET>::ascii_load(std::istream& s) {
277  Pointset_Ask_Tell& x = *this;
278  std::string str;
279 
280  if (!(s >> str) || str != "size") {
281  return false;
282  }
283 
284  size_type sz;
285 
286  if (!(s >> sz)) {
287  return false;
288  }
289 
290  if (!(s >> str) || str != "space_dim") {
291  return false;
292  }
293 
294  if (!(s >> x.space_dim)) {
295  return false;
296  }
297 
299  while (sz-- > 0) {
300  PSET ph;
301  if (!ph.ascii_load(s)) {
302  return false;
303  }
304  new_x.add_disjunct(ph);
305  }
306  swap(x, new_x);
307 
308  // Check invariants.
309  PPL_ASSERT_HEAVY(x.OK());
310  return true;
311 }
312 
313 template <typename PSET>
314 bool
316  const Pointset_Ask_Tell& x = *this;
317  for (const_iterator xi = x.begin(), x_end = x.end(); xi != x_end; ++xi) {
318  const PSET& ask_i = xi->ask().pointset();
319  const PSET& tell_i = xi->tell().pointset();
320  if (ask_i.space_dimension() != x.space_dim
321  || tell_i.space_dimension() != x.space_dim) {
322 #ifndef NDEBUG
323  std::cerr << "Space dimension mismatch: is ("
324  << ask_i.space_dimension()
325  << " -> "
326  << tell_i.space_dimension()
327  << ") in an element of the sequence,\nshould be "
328  << x.space_dim << "."
329  << std::endl;
330 #endif
331  return false;
332  }
333  }
334  return x.Base::OK();
335 }
336 
337 } // namespace Parma_Polyhedra_Library
338 
339 #endif // !defined(PPL_Pointset_Ask_Tell_templates_hh)
iterator begin()
Returns an iterator pointing to the first pair, if *this is not empty; otherwise, returns the past-th...
The empty element, i.e., the empty set.
A linear equality or inequality.
void swap(CO_Tree &x, CO_Tree &y)
size_t dimension_type
An unsigned integral type for representing space dimensions.
void remove_higher_space_dimensions(dimension_type new_dimension)
Removes the higher space dimensions so that the resulting space will have dimension new_dimension...
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
An std::set of variables' indexes.
Pointset_Ask_Tell(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds a universe (top) or empty (bottom) Pointset_Ask_Tell.
void add_constraints(const Constraint_System &cs)
Intersects *this with the constraints in cs.
void concatenate_assign(const Determinate &y)
Assigns to *this the concatenation of *this and y, taken in this order.
The standard C++ namespace.
#define PPL_OUTPUT_TEMPLATE_DEFINITIONS(type_symbol, class_prefix)
bool is_bottom() const
Returns true if and only if *this is the bottom element of the ask-and-tell constraint system (i...
size_type size() const
Returns the number of pairs.
A wrapper for PPL pointsets, providing them with a determinate constraint system interface, as defined in [Bag98].
void unconstrain(Variable var)
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *...
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified space dimensions.
A dimension of the vector space.
void add_space_dimensions_and_embed(dimension_type m)
Adds m new dimensions to the vector space containing *this and embeds each polyhedron in *this in the...
Sequence sequence
The sequence container holding the pairs/.
void add_disjunct(const PSET &ph)
Adds to *this the disjunct ph.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
The ask-and-tell construction instantiated on PPL polyhedra.
void concatenate_assign(const Pointset_Ask_Tell &y)
Assigns to *this the concatenation of *this and y.
A not necessarily closed convex polyhedron.
void map_space_dimensions(const Partial_Function &pfunc)
Remaps the dimensions of the vector space according to a partial function.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
A closed convex polyhedron.
bool OK() const
Checks if all the invariants are satisfied.
dimension_type space_dim
The number of dimensions of the enclosing vector space.
The universe element, i.e., the whole vector space.
A const_iterator on a sequence of read-only objects.
void add_constraint(const Constraint &c)
Intersects *this with constraint c.
The entire library is confined to this namespace.
Definition: version.hh:61
void add_space_dimensions_and_project(dimension_type m)
Adds m new dimensions to the vector space containing *this without embedding the polyhedra in *this i...
bool normalized
If true, *this is normalized.
A pair of ask and tell descriptions.
bool maps(dimension_type i, dimension_type &j) const
If *this maps i to a value k, assigns k to j and returns true; otherwise, j is unchanged and false is...
Coefficient c
Definition: PIP_Tree.cc:64
The ask and tell construction on a base-level domain.