PPL  1.2
Ask_Tell_inlines.hh
Go to the documentation of this file.
1 /* Ask_Tell 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_Ask_Tell_inlines_hh
25 #define PPL_Ask_Tell_inlines_hh 1
26 
27 #include <algorithm>
28 #include "assertions.hh"
29 
30 // Temporary!!!
31 #include <iostream>
32 
33 namespace Parma_Polyhedra_Library {
34 
35 template <typename D>
36 Ask_Tell_Pair<D>::Ask_Tell_Pair(const D& ask, const D& tell)
37  : a(ask), t(tell) {
38 }
39 
40 template <typename D>
41 const D&
43  return a;
44 }
45 
46 template <typename D>
47 D&
49  return a;
50 }
51 
52 template <typename D>
53 const D&
55  return t;
56 }
57 
58 template <typename D>
59 D&
61  return t;
62 }
63 
64 template <typename D>
65 bool
67  const Ask_Tell_Pair<D>& x = *this;
68  const D& x_ask = x.ask();
69  const D& x_tell = x.tell();
70  const D& y_ask = y.ask();
71  const D& y_tell = y.tell();
72  if (!y_ask.definitely_entails(x_ask)) {
73  return false;
74  }
75  else if (x_tell.definitely_entails(y_tell)) {
76  return true;
77  }
78  // The following test can be omitted.
79  else if (x_tell.definitely_entails(y_ask)) {
80  return false;
81  }
82  else {
83  D x_tell_y_ask = x_tell;
84  x_tell_y_ask.meet_assign(y_ask);
85  return x_tell_y_ask.definitely_entails(y_tell);
86  }
87 }
88 
89 template <typename D>
91  : sequence(), normalized(true) {
92 }
93 
94 template <typename D>
96  : sequence(y.sequence), normalized(y.normalized) {
97 }
98 
99 template <typename D>
100 Ask_Tell<D>::Ask_Tell(const D& ask, const D& tell)
101  : sequence(), normalized(true) {
102  if (!tell.is_top()) {
103  pair_insert(ask, tell);
104  }
105 }
106 
107 template <typename D>
108 inline
110 }
111 
112 template <typename D>
115  sequence = y.sequence;
116  normalized = y.normalized;
117  return *this;
118 }
119 
120 template <typename D>
121 inline void
123  swap(sequence, y.sequence);
124  swap(normalized, y.normalized);
125 }
126 
127 template <typename D>
128 typename Ask_Tell<D>::iterator
130  return sequence.begin();
131 }
132 
133 template <typename D>
136  return sequence.begin();
137 }
138 
139 template <typename D>
140 typename Ask_Tell<D>::iterator
142  return sequence.end();
143 }
144 
145 template <typename D>
148  return sequence.end();
149 }
150 
151 template <typename D>
154  return sequence.rbegin();
155 }
156 
157 template <typename D>
160  return sequence.rbegin();
161 }
162 
163 template <typename D>
166  return sequence.rend();
167 }
168 
169 template <typename D>
172  return sequence.rend();
173 }
174 
175 template <typename D>
176 typename Ask_Tell<D>::size_type
178  return sequence.size();
179 }
180 
181 template <typename D>
182 void
183 Ask_Tell<D>::pair_insert_good(const D& ask, const D& tell) {
184  PPL_ASSERT_HEAVY(!ask.definitely_entails(tell));
185  sequence.push_back(Ask_Tell_Pair<D>(ask, tell));
186  normalized = false;
187 }
188 
189 template <typename D>
190 void
191 Ask_Tell<D>::pair_insert(const D& ask, const D& tell) {
192  if (tell.definitely_entails(ask)) {
193  pair_insert_good(ask, tell);
194  }
195  else {
196  D new_tell = tell;
197  new_tell.meet_assign(ask);
198  pair_insert_good(ask, new_tell);
199  }
200 }
201 
202 template <typename D>
203 void
205  if (normalized) {
206  return;
207  }
208 
209  Ask_Tell& x = const_cast<Ask_Tell&>(*this);
210  x.reduce();
211  x.deduce();
212  x.absorb();
213  normalized = true;
214 
215  PPL_ASSERT_HEAVY(OK());
216 }
217 
218 template <typename D>
219 bool
221  if (!normalized && check_normalized()) {
222  normalized = true;
223  }
224  return normalized;
225 }
226 
227 template <typename D>
228 bool
230  const Ask_Tell<D>& x = *this;
231  x.normalize();
232  y.normalize();
233  bool found = true;
234  for (const_iterator x_begin = x.begin(), x_end = x.end(), y_end = y.end(),
235  yi = y.begin(); found && yi != y_end; ++yi) {
236  found = false;
237  for (const_iterator xi = x_begin; !found && xi != x_end; ++xi)
238  found = xi->definitely_entails(*yi);
239  }
240  return found;
241 }
242 
243 template <typename D>
245 Ask_Tell<D>::add_pair(const D& ask, const D& tell) {
246  if (!ask.definitely_entails(tell)) {
247  pair_insert(ask, tell);
248  }
249  PPL_ASSERT_HEAVY(OK());
250  return *this;
251 }
252 
254 template <typename D>
255 inline
256 bool operator==(const Ask_Tell<D>& x, const Ask_Tell<D>& y) {
257  return x.definitely_entails(y) && y.definitely_entails(x);
258 }
259 
261 template <typename D>
262 inline
263 bool operator!=(const Ask_Tell<D>& x, const Ask_Tell<D>& y) {
264  return !(x == y);
265 }
266 
267 template <typename D>
268 bool
270  return sequence.empty();
271 }
272 
273 template <typename D>
274 bool
276  // Must normalize for correctness.
277  const_iterator xi = begin();
278  const_iterator x_end = end();
279  return xi != x_end
280  && xi->ask().is_top() && xi->tell().is_bottom()
281  && ++xi == x_end;
282 }
283 
284 template <typename D>
285 bool
287  return sequence.empty();
288 }
289 
290 template <typename D>
291 void
293  if (!y.empty()) {
294  std::copy(y.begin(), y.end(), back_inserter(sequence));
295  normalized = false;
296  }
297  PPL_ASSERT_HEAVY(OK());
298 }
299 
300 // Hiding
301 
302 template <typename D>
303 bool
304 Ask_Tell<D>::probe(const D& tell, const D& ask) const {
305  const_iterator yi;
306  bool tell_changed;
307 
308  D xtell(tell);
309  tell_changed = true;
310  while (tell_changed) {
311  tell_changed = false;
312  for (yi = begin(); yi != end(); ++yi) {
313  if (xtell.definitely_entails(yi->ask())
314  && !xtell.definitely_entails(yi->tell())) {
315  xtell.meet_assign(yi->tell());
316  if (xtell.definitely_entails(ask)) {
317  return true;
318  }
319  tell_changed = true;
320  }
321  }
322  }
323  return false;
324 }
325 
327 template <typename D>
328 inline void
330  x.m_swap(y);
331 }
332 
333 } // namespace Parma_Polyhedra_Library
334 
335 #endif // !defined(PPL_Ask_Tell_inlines_hh)
bool probe(const D &tellv, const D &askv) const
void normalize() const
Normalizes the pairs in *this.
iterator begin()
Returns an iterator pointing to the first pair, if *this is not empty; otherwise, returns the past-th...
void swap(CO_Tree &x, CO_Tree &y)
const D & ask() const
Const accessor to the ask component.
bool definitely_entails(const Ask_Tell_Pair &y) const
Returns true if *this definitely entails y. Returns false if *this may not entail y (i...
Ask_Tell & operator=(const Ask_Tell &y)
The assignment operator. (*this and y can be dimension-incompatible.)
void swap(Ask_Tell< D > &x, Ask_Tell< D > &y)
Ask_Tell()
Default constructor: builds the top of the ask-and-tell constraint system (i.e., the empty system)...
bool empty() const
Returns true if and only if there are no pairs in *this.
bool is_bottom() const
Returns true if and only if *this is the bottom element of the ask-and-tell constraint system (i...
void m_swap(Ask_Tell &y)
Swaps *this with y.
bool operator==(const Ask_Tell< D > &x, const Ask_Tell< D > &y)
bool operator!=(const Ask_Tell< D > &x, const Ask_Tell< D > &y)
size_type size() const
Returns the number of pairs.
iterator end()
Returns the past-the-end iterator.
Ask_Tell_Pair(const D &ask, const D &tell)
Pair constructor.
std::reverse_iterator< iterator > reverse_iterator
The reverse iterator type built from Powerset::iterator.
std::reverse_iterator< const_iterator > const_reverse_iterator
The reverse iterator type built from Powerset::const_iterator.
Sequence sequence
The sequence container holding the pairs/.
reverse_iterator rbegin()
Returns a reverse_iterator pointing to the last pair, if *this is not empty; otherwise, returns the before-the-start reverse_iterator.
bool is_normalized() const
Returns true if and only if *this is normalized.
bool definitely_entails(const Ask_Tell &y) const
Returns true if *this definitely entails y. Returns false if *this may not entail y (i...
void meet_assign(const Ask_Tell &y)
Assigns to *this the meet of *this and y.
bool is_top() const
Returns true if and only if *this is the top element of the ask-and-tell constraint system (i...
A const_iterator on a sequence of read-only objects.
Ask_Tell & add_pair(const Ask_Tell_Pair< D > &p)
Adds to *this the pair p.
The entire library is confined to this namespace.
Definition: version.hh:61
const D & tell() const
Const accessor to the ask component.
void pair_insert_good(const D &a, const D &t)
bool normalized
If true, *this is normalized.
A pair of ask and tell descriptions.
An iterator on a sequence of read-only objects.
reverse_iterator rend()
Returns the before-the-start reverse_iterator.
void pair_insert(const D &a, const D &t)
The ask and tell construction on a base-level domain.