00001 #ifndef RELATION_OPS_HPP
00002 #define RELATION_OPS_HPP
00003
00004 #include <algorithm>
00005 #include <iterator>
00006 #include <deque>
00007 #include <vector>
00008 #include <map>
00009 #include <set>
00010
00011
00012
00013 #include "wali/ref_ptr.hpp"
00014 #include "wali/KeyContainer.hpp"
00015
00016 namespace wali {
00017 namespace relations {
00018 using std::set;
00019 using std::map;
00020 using std::pair;
00021 using std::make_pair;
00022
00023
00024
00025 template<typename Subject>
00026 class TernaryRelation
00027 {
00028 map<pair<Subject, Subject>, set<Subject> > relation2_1;
00029
00030 typedef map<pair<Subject, Subject>, set<Subject> > Map;
00031
00032 public:
00033
00034 class Iterator
00035 {
00036 public:
00037 typedef Triple<Subject, Subject, Subject> Tuple;
00038
00039 private:
00040 typedef typename Map::const_iterator MapIter;
00041 typedef typename set<Subject>::const_iterator SetIter;
00042
00043
00044 MapIter map_iter;
00045 MapIter end_map_iter;
00046
00047
00048 SetIter set_iter;
00049 SetIter end_set_iter;
00050
00051 Tuple cur_tuple;
00052
00053 void set_tuple() {
00054 assert(!at_end());
00055 assert(set_iter != end_set_iter);
00056 assert(end_set_iter == map_iter->second.end());
00057
00058 cur_tuple.first = map_iter->first.first;
00059 cur_tuple.second = map_iter->first.second;
00060 cur_tuple.third = *set_iter;
00061 }
00062
00063 public:
00064
00065
00066 Iterator(MapIter start_outer, MapIter end_outer) {
00067 map_iter = start_outer;
00068 end_map_iter = end_outer;
00069
00070 if (map_iter != end_map_iter) {
00071 set_iter = map_iter->second.begin();
00072 end_set_iter = map_iter->second.end();
00073 }
00074 }
00075
00076
00077 static Iterator begin(Map & relation) {
00078 return Iterator(relation.begin(), relation.end());
00079 }
00080
00081 static Iterator end(Map & relation) {
00082 return Iterator(relation.end(), relation.end());
00083 }
00084
00085
00086 bool at_end() const {
00087 return (map_iter == end_map_iter);
00088 }
00089
00090
00091
00092
00093
00094
00095 void operator++() {
00096 assert(!at_end());
00097 assert(set_iter != end_set_iter);
00098 assert(end_set_iter == map_iter->second.end());
00099
00100
00101
00102
00103
00104
00105 ++set_iter;
00106 if(set_iter == end_set_iter) {
00107 advance_map();
00108 }
00109 }
00110
00111
00112 void operator++(int) {
00113 this->operator++();
00114 }
00115
00116
00117
00118 Tuple const & operator*() const {
00119 assert(!at_end());
00120 set_tuple();
00121 return cur_tuple;
00122 }
00123
00124
00125 Tuple const * operator->() const {
00126 assert(!at_end());
00127 const_cast<Iterator*>(this)->set_tuple();
00128 return &cur_tuple;
00129 }
00130
00131
00132 bool operator==(Iterator other) const {
00133
00134
00135
00136
00137 return (map_iter == other.map_iter
00138 && (map_iter == end_map_iter
00139 || set_iter == other.set_iter));
00140 }
00141
00142
00143 bool operator!=(Iterator other) const {
00144 return !(*this == other);
00145 }
00146
00147
00148 void advance_map() {
00149 assert(!at_end());
00150 ++map_iter;
00151 if(map_iter != end_map_iter) {
00152 set_iter = map_iter->second.begin();
00153 end_set_iter = map_iter->second.end();
00154 }
00155 }
00156 };
00157
00158 public:
00159 typedef Iterator iterator;
00160 typedef Iterator const_iterator;
00161
00162 bool insert(Triple<Subject, Subject, Subject> const & tuple) {
00163 return relation2_1[make_pair(tuple.first, tuple.second)].insert(tuple.third).second;
00164 }
00165
00166 iterator begin() { return Iterator::begin(relation2_1); }
00167 const_iterator begin() const { return Iterator::begin(const_cast<Map&>(relation2_1)); }
00168 iterator end() { return Iterator::end(relation2_1); }
00169 const_iterator end() const { return Iterator::end(const_cast<Map&>(relation2_1)); }
00170
00171 size_t size() const {
00172 int ret = 0;
00173 for(typename Map::const_iterator iter = relation2_1.begin();
00174 iter != relation2_1.end(); ++iter) {
00175 ret += iter->second.size();
00176 }
00177 return ret;
00178 }
00179
00180
00181
00182 pair<iterator, iterator> equal_range(pair<Subject, Subject> key) const {
00183
00184
00185 typename Map::const_iterator store_iter = relation2_1.find(key);
00186 typename Map::const_iterator next_map = store_iter;
00187
00188
00189
00190
00191
00192
00193 if(store_iter != relation2_1.end()) {
00194 ++next_map;
00195 }
00196
00197 Iterator start(store_iter, next_map);
00198 Iterator finish(next_map, next_map);
00199
00200 return make_pair(start, finish);
00201 }
00202
00203 bool operator==(TernaryRelation const & other) const {
00204 return relation2_1 == other.relation2_1;
00205 }
00206 };
00207
00208
00209 #if 0
00210 template<typename a, typename b>
00211 struct pairhash {
00212 private:
00213 const std::tr1::hash<a> ah;
00214 const std::tr1::hash<b> bh;
00215 public:
00216 pairhash() : ah(), bh() {}
00217 size_t operator()(const std::pair<a, b> &p) const {
00218 return ah(p.first) ^ bh(p.second);
00219 }
00220 };
00221 #endif
00222
00223
00224 template<typename State>
00225 struct RelationTypedefs
00226 {
00227
00228
00229 typedef std::set<pair<State, State> > BinaryRelation;
00230 typedef wali::relations::TernaryRelation<State> TernaryRelation;
00231 };
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 template<typename State>
00243 void
00244 compose(typename RelationTypedefs<State>::BinaryRelation & out_result,
00245 typename RelationTypedefs<State>::BinaryRelation const & r1,
00246 typename RelationTypedefs<State>::BinaryRelation const & r2)
00247 {
00248 typedef typename RelationTypedefs<State>::BinaryRelation::const_iterator Iterator;
00249
00250 std::multimap<State, State> r2_map(r2.begin(), r2.end());
00251 typedef typename std::multimap<State, State>::const_iterator BigIterator;
00252
00253
00254 for(Iterator r1_iter = r1.begin(); r1_iter != r1.end(); ++r1_iter)
00255 {
00256 State x = r1_iter->first;
00257 State y = r1_iter->second;
00258
00259
00260 pair<BigIterator, BigIterator> range = r2_map.equal_range(y);
00261 for(BigIterator r2_iter = range.first; r2_iter != range.second; ++r2_iter)
00262 {
00263
00264 out_result.insert(make_pair(x, r2_iter->second));
00265
00266 }
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 template<typename OutRelation, typename State, typename Symbol>
00279 void
00280 project_symbol_3(OutRelation & out_result,
00281 std::set<Triple<State, Symbol, State> > const & delta,
00282 Symbol alpha)
00283 {
00284 typedef typename std::set<Triple<State, Symbol, State> >::const_iterator Iterator;
00285
00286 for(Iterator cur_trans = delta.begin(); cur_trans != delta.end(); ++cur_trans)
00287 {
00288 State source = cur_trans->first;
00289 Symbol symb = cur_trans->second;
00290 State target = cur_trans->third;
00291
00292 if(symb == alpha)
00293 {
00294 out_result.insert(make_pair(source, target));
00295 }
00296 }
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 template<typename State>
00311 void
00312 merge(typename RelationTypedefs<State>::BinaryRelation & out_result,
00313 typename RelationTypedefs<State>::BinaryRelation const & r_exit,
00314 typename RelationTypedefs<State>::BinaryRelation const & r_call,
00315 typename RelationTypedefs<State>::TernaryRelation const & delta_r)
00316 {
00317 typedef typename RelationTypedefs<State>::BinaryRelation::const_iterator Iterator;
00318
00319 typename RelationTypedefs<State>::BinaryRelation temp;
00320
00321
00322 for(Iterator exit_iter = r_exit.begin(); exit_iter != r_exit.end(); ++exit_iter)
00323 {
00324
00325 typedef typename RelationTypedefs<State>::TernaryRelation::const_iterator BigIterator;
00326 pair<BigIterator, BigIterator> range =
00327 delta_r.equal_range(make_pair(exit_iter->second, exit_iter->first));
00328
00329 for(BigIterator ret_trans = range.first; ret_trans != range.second; ++ret_trans) {
00330 if(exit_iter->first == ret_trans->second && exit_iter->second == ret_trans->first) {
00331 temp.insert(make_pair(exit_iter->first, ret_trans->third));
00332 }
00333 }
00334 }
00335
00336 compose<State>(out_result, r_call, temp);
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 template<typename State, typename Symbol>
00349 void
00350 project_symbol_4(typename RelationTypedefs<State>::TernaryRelation & out_result,
00351 std::set<Quad<State, State, Symbol, State> > const & delta,
00352 Symbol alpha)
00353 {
00354 typedef typename set<Quad<State, State, Symbol, State> >::const_iterator Iterator;
00355
00356 for(Iterator cur_trans = delta.begin(); cur_trans != delta.end(); ++cur_trans)
00357 {
00358 State source = cur_trans->first;
00359 State pred = cur_trans->second;
00360 Symbol symb = cur_trans->third;
00361 State target = cur_trans->fourth;
00362
00363 if(symb == alpha)
00364 {
00365 bool added = out_result.insert(Triple<State, State, State>(source, pred, target));
00366 assert(added);
00367 }
00368 }
00369 }
00370
00371
00372 template<typename State>
00373 State biggest(State s1, State s2, State s3)
00374 {
00375 return std::max(s1, std::max(s2, s3));
00376 }
00377
00378 template<typename State>
00379 void
00380 transitive_closure_no_remap(typename RelationTypedefs<State>::BinaryRelation & out_result,
00381 typename RelationTypedefs<State>::BinaryRelation const & r)
00382 {
00383 typedef typename RelationTypedefs<State>::BinaryRelation::const_iterator Iterator;
00384
00385
00386 State largest_state = State();
00387 for(Iterator edge = r.begin(); edge != r.end(); ++edge)
00388 {
00389 largest_state = biggest(largest_state, edge->first, edge->second);
00390 }
00391
00392 largest_state = largest_state + 1;
00393
00394
00395 assert(largest_state < 4000);
00396
00397
00398
00399 std::vector<std::deque<bool> > matrix(largest_state);
00400 for(size_t i = 0; i<matrix.size(); ++i)
00401 {
00402 matrix[i].resize(largest_state);
00403 }
00404
00405
00406 for(size_t source=1; source<largest_state; ++source)
00407 {
00408 matrix[source][source] = 1;
00409 }
00410
00411 for(Iterator edge = r.begin(); edge != r.end(); ++edge)
00412 {
00413 matrix[edge->first][edge->second] = 1;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 for(size_t k = 0; k < largest_state; ++k)
00440 for(size_t i = 0; i < largest_state; ++i)
00441 for(size_t j = 0; j < largest_state; ++j)
00442 matrix[i][j] = matrix[i][j] || (matrix[i][k] && matrix[k][j]);
00443
00444
00445
00446 for(size_t source=0; source<largest_state; ++source)
00447 {
00448 for(size_t target=0; target<largest_state; ++target)
00449 {
00450 if(matrix[source][target])
00451 {
00452 out_result.insert(make_pair(source,target));
00453 }
00454 }
00455 }
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 template<typename State>
00470 void
00471 transitive_closure(typename RelationTypedefs<State>::BinaryRelation & out_result,
00472 typename RelationTypedefs<State>::BinaryRelation const & r)
00473 {
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 if (r.empty()) return;
00503
00504 typedef typename RelationTypedefs<State>::BinaryRelation BinaryRelation;
00505 typedef typename RelationTypedefs<State>::BinaryRelation::const_iterator Iterator;
00506
00507
00508 std::map<State, State> forward;
00509 std::map<State, State> backward;
00510
00511 BinaryRelation r_canonical;
00512 State next_canonical = 1;
00513
00514
00515
00516
00517
00518 for(Iterator edge_original = r.begin(); edge_original != r.end(); ++edge_original)
00519 {
00520 State src_original = edge_original->first;
00521 State tgt_original = edge_original->second;
00522
00523 if (forward.find(src_original) == forward.end()) {
00524
00525
00526 forward[src_original] = next_canonical;
00527 backward[next_canonical] = src_original;
00528 ++next_canonical;
00529 }
00530
00531 if (forward.find(tgt_original) == forward.end()) {
00532
00533
00534 forward[tgt_original] = next_canonical;
00535 backward[next_canonical] = tgt_original;
00536 ++next_canonical;
00537 }
00538
00539 State src_canonical = forward[src_original];
00540 State tgt_canonical = forward[tgt_original];
00541
00542 r_canonical.insert(std::make_pair(src_canonical, tgt_canonical));
00543 }
00544
00545
00546
00547 BinaryRelation canonical_closure;
00548 transitive_closure_no_remap<State>(canonical_closure, r_canonical);
00549
00550
00551
00552 for(Iterator edge_canonical = canonical_closure.begin();
00553 edge_canonical != canonical_closure.end(); ++edge_canonical)
00554 {
00555 State src_canonical = edge_canonical->first;
00556 State tgt_canonical = edge_canonical->second;
00557
00558 if (backward.find(src_canonical) == backward.end()) {
00559 std:: cout << " ERROR: cannot find original key for canonical key " << src_canonical << std::endl;
00560 std:: cout << " related to canonical key " << tgt_canonical << std::endl;
00561 }
00562
00563 assert(backward.find(src_canonical) != backward.end());
00564 assert(backward.find(tgt_canonical) != backward.end());
00565
00566 State src_original = backward[src_canonical];
00567 State tgt_original = backward[tgt_canonical];
00568
00569 out_result.insert(std::make_pair(src_original, tgt_original));
00570 }
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 template<typename Relation>
00582 void
00583 intersect(Relation & out_result,
00584 Relation const & r1,
00585 Relation const & r2)
00586 {
00587 std::set_intersection(r1.begin(), r1.end(),
00588 r2.begin(), r2.end(),
00589 std::inserter(out_result, out_result.begin()));
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599 template<typename Relation>
00600 void
00601 union_(Relation & out_result,
00602 Relation const & r1,
00603 Relation const & r2)
00604 {
00605 std::set_union(r1.begin(), r1.end(),
00606 r2.begin(), r2.end(),
00607 std::inserter(out_result, out_result.begin()));
00608 }
00609 }
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619 #endif