00001 #ifndef RELATION_OPS_PAIRED_HPP
00002 #define RELATION_OPS_PAIRED_HPP
00003
00004 #include <algorithm>
00005 #include <iterator>
00006 #include <cassert>
00007 #include <utility>
00008 #include <map>
00009 #include <set>
00010
00011 #define relations std_set_relations
00012 #include "RelationOps.hpp"
00013 #undef relations
00014 #define relations buddy_relations
00015 #include "RelationOpsBuddy.hpp"
00016 #undef relations
00017
00018 namespace wali {
00019 namespace relations {
00020 namespace wsr = wali::std_set_relations;
00021 namespace wbr = wali::buddy_relations;
00022
00023 typedef wsr::RelationTypedefs<unsigned long>::BinaryRelation wsrbr;
00024 typedef wbr::RelationTypedefs<unsigned long>::BinaryRelation wbrbr;
00025
00026 extern int count;
00027 inline
00028 void counter(char* vals, int size) {
00029 int numDontCares = 0;
00030 for (int i=0; i<size; ++i) {
00031 if (vals[i] < 0) {
00032 ++numDontCares;
00033 }
00034 }
00035
00036
00037
00038
00039
00040
00041 count += 1 << numDontCares;
00042 }
00043
00044 inline
00045 int bdd_rel_size(::bdd b, int factor) {
00046 count = 0;
00047
00048 bdd_allsat(b, counter);
00049
00050 assert(bdd_satcount(b) == count);
00051 return count/factor;
00052 }
00053
00054
00055 struct BinaryRelation {
00056 wsrbr set;
00057 wbrbr bdd;
00058
00059 BinaryRelation(unsigned int largest)
00060 : bdd(largest)
00061 {}
00062
00063 BinaryRelation()
00064 {}
00065
00066 bool insert(unsigned int leftVal, unsigned int rightVal)
00067 {
00068 return insert(std::make_pair(leftVal, rightVal));
00069 }
00070
00071 bool insert(std::pair<unsigned int, unsigned int> pair)
00072 {
00073 assert(check());
00074 bool added1 = set.insert(pair).second;
00075 bool added2 = bdd.insert(pair);
00076 assert(check());
00077 assert(added1 == added2);
00078 return added1;
00079 }
00080
00081 bool empty() const
00082 {
00083 assert(set.empty() == bdd.empty());
00084 return set.empty();
00085 }
00086
00087 bool operator== (BinaryRelation const & other) const {
00088 assert( (set == other.set) == (bdd == other.bdd) );
00089 return bdd == other.bdd;
00090 }
00091
00092 ::bdd getBdd() const {
00093 return bdd.getBdd();
00094 }
00095
00096 int bddSize() const {
00097 return bdd_rel_size(bdd.getBdd(), 256);
00098 }
00099
00100 int setSize() const {
00101 return set.size();
00102 }
00103
00104 bool check() const {
00105 return bddSize() == setSize();
00106 }
00107 };
00108
00109 struct TernaryRelation {
00110 wsr::RelationTypedefs<unsigned long>::TernaryRelation set;
00111 wbr::RelationTypedefs<unsigned long>::TernaryRelation bdd;
00112
00113 TernaryRelation(unsigned int largest)
00114 : bdd(largest)
00115 {}
00116
00117 TernaryRelation()
00118 {}
00119
00120 bool insert(unsigned int leftVal, unsigned int middleVal, unsigned int rightVal)
00121 {
00122 bool added1 = set.insert(Triple<unsigned long,unsigned long,unsigned long>(leftVal, middleVal, rightVal));
00123 bool added2 = bdd.insert(Triple<unsigned,unsigned,unsigned>(leftVal, middleVal, rightVal));
00124 assert(added1 == added2);
00125 return added1;
00126 }
00127
00128 bool insert(Triple<unsigned, unsigned, unsigned> triple)
00129 {
00130 return insert(triple.first, triple.second, triple.third);
00131 }
00132
00133 bool insert(Triple<unsigned long, unsigned long, unsigned long> triple)
00134 {
00135 return insert(triple.first, triple.second, triple.third);
00136 }
00137
00138 bool check() const {
00139 return bdd_rel_size(bdd.getBdd(), 16) == set.size();
00140 }
00141 };
00142
00143
00144
00145 template<typename State>
00146 struct RelationTypedefs
00147 {
00148 typedef wali::relations::BinaryRelation BinaryRelation;
00149 typedef wali::relations::TernaryRelation TernaryRelation;
00150 };
00151
00152
00153 using wbr::buddyInit;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 inline void
00181 compose(BinaryRelation & out_result,
00182 BinaryRelation const & r1,
00183 BinaryRelation const & r2)
00184 {
00185 wsr::compose<unsigned long>(out_result.set, r1.set, r2.set);
00186 wbr::compose(out_result.bdd, r1.bdd, r2.bdd);
00187 assert(out_result.check());
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 template<typename OutRelation, typename State, typename Symbol>
00200 void
00201 project_symbol_3_set(OutRelation & out_result,
00202 std::set<Triple<State, Symbol, State> > const & delta,
00203 Symbol alpha)
00204 {
00205 wsr::project_symbol_3<OutRelation, State, Symbol>(out_result, delta, alpha);
00206 }
00207
00208
00209 template<typename OutRelation, typename State, typename Symbol>
00210 void
00211 project_symbol_3(OutRelation & out_result,
00212 std::set<Triple<State, Symbol, State> > const & delta,
00213 Symbol alpha)
00214 {
00215 wsr::project_symbol_3<wsrbr, State, Symbol>(out_result.set, delta, alpha);
00216 wbr::project_symbol_3<wbrbr, State, Symbol>(out_result.bdd, delta, alpha);
00217 assert(out_result.check());
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 inline void
00232 merge(BinaryRelation & out_result,
00233 BinaryRelation const & r_exit,
00234 BinaryRelation const & r_call,
00235 TernaryRelation const & delta_r)
00236 {
00237 assert(out_result.check());
00238 assert(r_exit.check());
00239 assert(r_call.check());
00240 assert(delta_r.check());
00241 wsr::merge<unsigned long>(out_result.set, r_exit.set, r_call.set, delta_r.set);
00242 wbr::merge(out_result.bdd, r_exit.bdd, r_call.bdd, delta_r.bdd);
00243
00244 assert(out_result.check());
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 template<typename State, typename Symbol>
00257 void
00258 project_symbol_4(TernaryRelation & out_result,
00259 std::set<Quad<State, State, Symbol, State> > const & delta,
00260 Symbol alpha)
00261 {
00262 assert(out_result.check());
00263 wsr::project_symbol_4<State, Symbol>(out_result.set, delta, alpha);
00264 wbr::project_symbol_4<State, Symbol>(out_result.bdd, delta, alpha);
00265 assert(out_result.check());
00266 }
00267
00268
00269 template<typename State>
00270 State biggest(State s1, State s2, State s3)
00271 {
00272 return std::max(s1, std::max(s2, s3));
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 template<typename Relation>
00286 void
00287 transitive_closure(Relation & out_result,
00288 Relation const & r)
00289 {
00290 typedef typename Relation::const_iterator Iterator;
00291 typedef typename Relation::value_type::first_type State;
00292
00293 #ifndef NDEBUG
00294 const bool domain_and_codomain_are_the_same =
00295 boost::is_same<typename Relation::value_type::first_type,
00296 typename Relation::value_type::second_type>::value;
00297 BOOST_STATIC_ASSERT(domain_and_codomain_are_the_same);
00298 #endif
00299
00300
00301 State largest_state = State();
00302 for(Iterator edge = r.begin(); edge != r.end(); ++edge)
00303 {
00304 largest_state = biggest(largest_state, edge->first, edge->second);
00305 }
00306
00307 largest_state = largest_state + 1;
00308
00309 assert(largest_state < 2000);
00310
00311
00312
00313 std::vector<std::deque<bool> > matrix(largest_state);
00314 for(size_t i = 0; i<matrix.size(); ++i)
00315 {
00316 matrix[i].resize(largest_state);
00317 }
00318
00319 for(size_t source=0; source<largest_state; ++source)
00320 {
00321 matrix[source][source] = 1;
00322 }
00323
00324 for(Iterator edge = r.begin(); edge != r.end(); ++edge)
00325 {
00326 matrix[edge->first][edge->second] = 1;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 for(size_t k = 0; k < largest_state; ++k)
00353 for(size_t i = 0; i < largest_state; ++i)
00354 for(size_t j = 0; j < largest_state; ++j)
00355 matrix[i][j] = matrix[i][j] || (matrix[i][k] && matrix[k][j]);
00356
00357
00358
00359 for(size_t source=0; source<largest_state; ++source)
00360 {
00361 for(size_t target=0; target<largest_state; ++target)
00362 {
00363 if(matrix[source][target])
00364 {
00365 out_result.insert(std::make_pair(source,target));
00366 }
00367 }
00368 }
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378 inline void
00379 intersect(BinaryRelation & out_result,
00380 BinaryRelation const & r1,
00381 BinaryRelation const & r2)
00382 {
00383 wsr::intersect(out_result.set, r1.set, r2.set);
00384 wbr::intersect(out_result.bdd, r1.bdd, r2.bdd);
00385 assert(out_result.check());
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395 inline void
00396 union_(BinaryRelation & out_result,
00397 BinaryRelation const & r1,
00398 BinaryRelation const & r2)
00399 {
00400 assert(r1.check());
00401 assert(r2.check());
00402 wsr::union_(out_result.set, r1.set, r2.set);
00403 wbr::union_(out_result.bdd, r1.bdd, r2.bdd);
00404 assert(out_result.check());
00405 }
00406
00407
00408
00409 template<typename T>
00410 class VectorSet {
00411 typedef std::vector<T> Items;
00412 Items items;
00413
00414 public:
00415 typedef typename Items::iterator iterator;
00416 typedef typename Items::const_iterator const_iterator;
00417
00418 void insert(T const & item) {
00419 if (find(item) == end()) {
00420 items.push_back(item);
00421 }
00422 }
00423
00424 iterator find(T const & item) { return std::find(items.begin(), items.end(), item); }
00425 const_iterator find(T const & item) const { return std::find(items.begin(), items.end(), item); }
00426
00427 bool empty() const { return items.empty(); }
00428
00429 iterator begin() { return items.begin(); }
00430 const_iterator begin() const { return items.begin(); }
00431
00432 iterator end() { return items.end(); }
00433 const_iterator end() const { return items.end(); }
00434
00435 void erase(iterator i) { items.erase(i); }
00436 void erase(const_iterator i) { items.erase(i); }
00437 };
00438
00439 }
00440 }
00441
00442
00443
00444
00445
00446
00447
00448 #endif