00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __RELATIONS_HH
00018 # define __RELATIONS_HH
00019
00020 #include <algorithm>
00021 #include <unordered_map>
00022 #include <unordered_set>
00023 #include <iostream>
00024
00025 namespace aurelia {
00026
00027 template <typename T>
00028 struct set: std::unordered_set<T> {
00029 public:
00030 set() {}
00031
00032 explicit set(const T& t): std::unordered_set<T>() {
00033 this->insert(t);
00034 }
00035
00036 set(const set&) = default;
00037 set(set&&) = default;
00038 set& operator=(const set&) = default;
00039 set& operator=(set&& other) = default;
00040
00041 set operator|(const set& other) const {
00042 set ret = *this;
00043 ret.insert(other.begin(), other.end());
00044 return ret;
00045 }
00046
00047 set& operator|=(const set& other) {
00048 this->insert(other.begin(), other.end());
00049 return *this;
00050 }
00051
00052 bool has(const T& t) const {
00053 return this->find(t) != this->end();
00054 }
00055 };
00056
00057 template <typename T, typename U = T>
00058 struct rel_set: public std::unordered_multimap<T,U> {
00059 public:
00060 rel_set() {}
00061 explicit rel_set(const std::pair<T,U>& t)
00062 : std::unordered_multimap<T,U>() {
00063 this->insert(t);
00064 }
00065
00066 rel_set(const rel_set&) = default;
00067 rel_set(rel_set&&) = default;
00068 rel_set& operator=(const rel_set&) = default;
00069 rel_set& operator=(rel_set&& other) = default;
00070
00071 typename std::unordered_multimap<T,U>::iterator
00072 insert(const typename std::unordered_multimap<T,U>::value_type& v) {
00073 typename std::unordered_multimap<T,U>::iterator i = this->find(v.first);
00074 if (i == this->end())
00075 return this->std::unordered_multimap<T,U>::insert(v);
00076 for (;i != this->end(); ++i) {
00077 if ((*i).first != v.first)
00078 return this->std::unordered_multimap<T,U>::insert(v);
00079 if ((*i).second == v.second)
00080 return i;
00081 }
00082 return this->std::unordered_multimap<T,U>::insert(v);
00083 }
00084
00085 typename std::unordered_multimap<T,U>::iterator
00086 insert(const typename std::unordered_multimap<T,U>::const_iterator&,
00087 const typename std::unordered_multimap<T,U>::value_type& v) {
00088 return this->insert(v);
00089 }
00090
00091 template <typename Iterator>
00092 void insert(Iterator begin, Iterator end) {
00093 for (; begin != end; ++begin) {
00094 this->insert(*begin);
00095 }
00096 }
00097
00098 rel_set operator|(const rel_set& other) const {
00099 rel_set ret = *this;
00100 ret.insert(other.begin(), other.end());
00101 return ret;
00102 }
00103
00104 rel_set& operator|=(const rel_set& other) {
00105 this->insert(other.begin(), other.end());
00106 return *this;
00107 }
00108
00109 set<U> operator[](const T& key) const {
00110 set<U> ret;
00111 for (typename std::unordered_multimap<T,U>::const_iterator i =
00112 this->find(key);
00113 i != this->end(); ++i) {
00114 if ((*i).first != key)
00115 break ;
00116 ret.insert((*i).second);
00117 }
00118 return ret;
00119 }
00120
00121 rel_set operator*() const {
00122 rel_set<T> ret = *this;
00123 bool once_more = true;
00124 while (once_more) {
00125 once_more = false;
00126 rel_set<T> tmp = ret;
00127 for (typename rel_set<T>::iterator i = ret.begin();
00128 i != ret.end(); ++i) {
00129 for (typename rel_set<T>::iterator j =
00130 ret.find((*i).second);
00131 j != ret.end(); ++j) {
00132 if ((*j).first != (*i).second)
00133 break ;
00134 typename rel_set<T>::iterator k =
00135 ret.find((*i).first);
00136 for (; k != ret.end(); ++k) {
00137 if ((*k).first != (*i).first)
00138 break ;
00139 if ((*k).second == (*j).second)
00140 break ;
00141 }
00142 bool notfound = (k == ret.end());
00143 if (!notfound)
00144 notfound = ((*k).first != (*i).first);
00145 if (notfound) {
00146 tmp.insert(std::pair<T,T>((*i).first, (*j).second));
00147 once_more = true;
00148 }
00149 }
00150 }
00151 ret = tmp;
00152 }
00153 return ret;
00154 }
00155 };
00156
00157 template <typename T>
00158 set<T> carrier(const rel_set<T>& m) {
00159 set<T> ret;
00160 std::for_each(m.begin(), m.end(),
00161 [&ret](const std::pair<T,T>& in) {
00162 ret.insert(in.first);
00163 ret.insert(in.second);
00164 });
00165 return std::move(ret);
00166 }
00167
00168 template <typename Stream, typename T, typename U>
00169 Stream& operator<<(Stream& s, const std::pair<T, U>& p) {
00170 s << "<" << p.first << "," << p.second << ">";
00171 return s;
00172 }
00173
00174 template <typename Stream, typename T, typename U>
00175 Stream& operator<<(Stream& s, const rel_set<T, U>& m) {
00176 bool first = true;
00177 s << "{";
00178 std::for_each(m.begin(), m.end(),
00179 [&s, &first](const std::pair<T, U>& in) {
00180 if (first) first = false;
00181 else s << ",";
00182 s << in;
00183 });
00184 s << "}";
00185 return s;
00186 }
00187
00188 template <typename Stream, typename T>
00189 Stream& operator<<(Stream& s, const set<T>& m) {
00190 bool first = true;
00191 s << "{";
00192 std::for_each(m.begin(), m.end(),
00193 [&s, &first](const T& in) {
00194 if (first) first = false;
00195 else s << ",";
00196 s << in;
00197 });
00198 s << "}";
00199 return s;
00200 }
00201
00202 template <typename T>
00203 set<T> top(const rel_set<T>& m) {
00204 set<T> ret;
00205 std::for_each(m.begin(), m.end(),
00206 [&ret](const std::pair<T, T>& in) {
00207 ret.insert(in.first);
00208 });
00209 std::for_each(m.begin(), m.end(),
00210 [&ret](const std::pair<T, T>& in) {
00211 ret.erase(in.second);
00212 });
00213 return std::move(ret);
00214 }
00215
00216 template <typename T>
00217 set<T> bottom(const rel_set<T>& m) {
00218 set<T> ret;
00219 std::for_each(m.begin(), m.end(),
00220 [&m, &ret](const std::pair<T, T>& in) {
00221 if (m.find(in.second) == m.end())
00222 ret.insert(in.second);
00223 });
00224 return std::move(ret);
00225 }
00226
00227 template <typename T, typename U, typename V>
00228 rel_set<T, V> operator*(const rel_set<T, U>& a, const rel_set<U, V>& b) {
00229 rel_set<T, V> ret;
00230
00231 for (typename rel_set<T, U>::const_iterator i = a.begin();
00232 i != a.end(); ++i) {
00233 for (typename rel_set<U, V>::const_iterator j =
00234 b.find((*i).second);
00235 j != b.end(); ++j) {
00236 if ((*j).first != (*i).second)
00237 break ;
00238 ret.insert(std::pair<T,V>((*i).first, (*j).second));
00239 }
00240 }
00241
00242 return std::move(ret);
00243 }
00244
00245 template <typename T, typename U>
00246 rel_set<T, U> operator*(const set<T>& a, const set<U>& b) {
00247 rel_set<T, U> ret;
00248
00249 for (typename set<T>::const_iterator i = a.begin();
00250 i != a.end(); ++i) {
00251 for (typename set<U>::const_iterator j = b.begin();
00252 j != b.end(); ++j) {
00253 ret.insert(std::pair<T,U>((*i), (*j)));
00254 }
00255 }
00256
00257 return std::move(ret);
00258 }
00259
00260 template <typename T, typename U>
00261 set<T> domain(const rel_set<T, U>& a) {
00262 set<T> ret;
00263 std::for_each(a.begin(), a.end(),
00264 [&ret](const std::pair<T, U>& p) {
00265 ret.insert(p.first);
00266 });
00267 return std::move(ret);
00268 }
00269
00270 template <typename T>
00271 set<T> operator-(const set<T>& a, const set<T>& b) {
00272 set<T> ret;
00273 std::for_each(a.begin(), a.end(),
00274 [&b, &ret](const T& t) {
00275 if (b.find(t) == b.end())
00276 ret.insert(t);
00277 });
00278 return std::move(ret);
00279 }
00280
00281 template <typename T>
00282 set<T> reachX(const rel_set<T>& G, const set<T>& Start, const set<T>& Excl) {
00283 if (Start.empty())
00284 return Start;
00285 set<T> direct_reach;
00286 std::for_each(Start.begin(), Start.end(),
00287 [&direct_reach, &G, &Excl](const T& in) {
00288 direct_reach |= G[in] - Excl;
00289 });
00290 return Start | reachX(G, std::move(direct_reach), Excl | Start);
00291 }
00292
00293 }
00294
00295 #endif