CBMC
interval_template.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 
10 #ifndef CPROVER_UTIL_INTERVAL_TEMPLATE_H
11 #define CPROVER_UTIL_INTERVAL_TEMPLATE_H
12 
13 #include <algorithm>
14 #include <iosfwd>
15 #include <ostream>
16 
17 #include "threeval.h"
18 
19 template<class T> class interval_templatet
20 {
21 public:
23  {
24  // this is 'top'
25  }
26 
27  explicit interval_templatet(const T &x):
28  lower_set(true),
29  upper_set(true),
30  lower(x),
31  upper(x)
32  {
33  }
34 
35  explicit interval_templatet(const T &l, const T &u):
36  lower_set(true),
37  upper_set(true),
38  lower(l),
39  upper(u)
40  {
41  }
42 
45 
46  const T &get_lower() const
47  {
48  return lower;
49  }
50 
51  const T &get_upper() const
52  {
53  return upper;
54  }
55 
56  bool empty() const
57  {
58  return upper_set && lower_set && lower>upper;
59  }
60 
61  bool is_bottom() const // equivalent to 'false'
62  {
63  return empty();
64  }
65 
66  bool is_top() const // equivalent to 'true'
67  {
68  return !lower_set && !upper_set;
69  }
70 
71  bool singleton() const
72  {
73  return upper_set && lower_set && lower==upper;
74  }
75 
76  // constraints
77  void make_le_than(const T &v) // add upper bound
78  {
79  if(upper_set)
80  {
81  if(upper>v)
82  upper=v;
83  }
84  else
85  {
86  upper_set=true;
87  upper=v;
88  }
89  }
90 
91  void make_ge_than(const T &v) // add lower bound
92  {
93  if(lower_set)
94  {
95  if(lower<v)
96  lower=v;
97  }
98  else
99  {
100  lower_set=true;
101  lower=v;
102  }
103  }
104 
105  // Union or disjunction
107  {
109  }
110 
111  // Intersection or conjunction
113  {
114  intersect_with(i);
115  }
116 
118  {
119  if(i.lower_set)
120  {
121  if(lower_set)
122  {
123  lower=std::max(lower, i.lower);
124  }
125  else
126  {
127  lower_set=true;
128  lower=i.lower;
129  }
130  }
131 
132  if(i.upper_set)
133  {
134  if(upper_set)
135  {
136  upper=std::min(upper, i.upper);
137  }
138  else
139  {
140  upper_set=true;
141  upper=i.upper;
142  }
143  }
144  }
145 
146  void make_bottom()
147  {
148  lower_set = upper_set = true;
149  upper = T();
150  lower = upper + 1;
151  }
152 
154  {
155  if(upper_set && i.upper_set)
156  upper = std::min(upper, i.upper);
157  if(lower_set && i.lower_set)
158  i.lower = std::max(lower, i.lower);
159  }
160 
162  {
164  if(singleton() && i.singleton() && lower == i.lower)
165  {
166  make_bottom();
167  i.make_bottom();
168  }
169  }
170 
172  {
173  if(i.lower_set && upper_set && upper <= i.lower)
174  return true;
175  else
176  return false;
177  }
178 
180  {
181  if(i.lower_set && upper_set && upper < i.lower)
182  return true;
183  else
184  return false;
185  }
186 
188  {
189  if(i.lower_set && lower_set)
190  lower=std::min(lower, i.lower);
191  else if(!i.lower_set && lower_set)
192  lower_set=false;
193 
194  if(i.upper_set && upper_set)
195  upper=std::max(upper, i.upper);
196  else if(!i.upper_set && upper_set)
197  upper_set=false;
198  }
199 };
200 
201 template<class T>
203 {
204  if(a.upper_set && b.lower_set && a.upper<=b.lower)
205  return tvt(true);
206  if(a.lower_set && b.upper_set && a.lower>b.upper)
207  return tvt(false);
208 
209  return tvt::unknown();
210 }
211 
212 template<class T>
214 {
215  return b<=a;
216 }
217 
218 template<class T>
220 {
221  return !(a>=b);
222 }
223 
224 template<class T>
226 {
227  return !(a<=b);
228 }
229 
230 template<class T>
232 {
233  if(a.lower_set!=b.lower_set)
234  return false;
235  if(a.upper_set!=b.upper_set)
236  return false;
237 
238  if(a.lower_set && a.lower!=b.lower)
239  return false;
240  if(a.upper_set && a.upper!=b.upper)
241  return false;
242 
243  return true;
244 }
245 
246 template<class T>
248 {
249  return !(a==b);
250 }
251 
252 template<class T>
254 {
256  i.upper_set=true;
257  i.upper=u;
258  return i;
259 }
260 
261 template<class T>
263 {
265  i.lower_set=true;
266  i.lower=l;
267  return i;
268 }
269 
270 template<class T>
271 std::ostream &operator << (std::ostream &out, const interval_templatet<T> &i)
272 {
273  if(i.lower_set)
274  out << '[' << i.lower;
275  else
276  out << ")-INF";
277 
278  out << ',';
279 
280  if(i.upper_set)
281  out << i.upper << ']';
282  else
283  out << "+INF(";
284 
285  return out;
286 }
287 
288 #endif // CPROVER_UTIL_INTERVAL_TEMPLATE_H
const T & get_upper() const
bool is_less_than(const interval_templatet &i)
bool is_less_than_eq(const interval_templatet &i)
void make_le_than(const T &v)
interval_templatet(const T &x)
void join(const interval_templatet< T > &i)
void make_ge_than(const T &v)
const T & get_lower() const
void make_less_than(interval_templatet &i)
void meet(const interval_templatet< T > &i)
bool is_bottom() const
interval_templatet(const T &l, const T &u)
void approx_union_with(const interval_templatet &i)
void intersect_with(const interval_templatet &i)
void make_less_than_eq(interval_templatet &i)
bool singleton() const
Definition: threeval.h:20
static tvt unknown()
Definition: threeval.h:33
std::ostream & operator<<(std::ostream &out, const interval_templatet< T > &i)
tvt operator<=(const interval_templatet< T > &a, const interval_templatet< T > &b)
tvt operator>(const interval_templatet< T > &a, const interval_templatet< T > &b)
interval_templatet< T > lower_interval(const T &l)
bool operator==(const interval_templatet< T > &a, const interval_templatet< T > &b)
bool operator!=(const interval_templatet< T > &a, const interval_templatet< T > &b)
tvt operator<(const interval_templatet< T > &a, const interval_templatet< T > &b)
interval_templatet< T > upper_interval(const T &u)
tvt operator>=(const interval_templatet< T > &a, const interval_templatet< T > &b)