34 #ifndef MC2LIB_SETS_HPP_    35 #define MC2LIB_SETS_HPP_    39 #include <unordered_map>    40 #include <unordered_set>    62   return (mask & all) == all;
    75   return (mask & any) != 0;
    92   explicit Set(Container s) : 
set_(std::move(s)) {}
    99   const Container& 
get() 
const { 
return set_; }
   112   const Element& 
Insert(
const Element& e, 
bool assert_unique = 
false) {
   113     auto result = 
set_.insert(e);
   114     assert(!assert_unique || result.second);
   115     return *result.first;
   125   const Element& 
Insert(Element&& e, 
bool assert_unique = 
false) {
   126     auto result = 
set_.emplace(std::move(e));
   127     assert(!assert_unique || result.second);
   128     return *result.first;
   137   bool Erase(
const Element& e, 
bool assert_exists = 
false) {
   138     auto result = 
set_.erase(e);
   139     assert(!assert_exists || result != 0);
   143   template <
class FilterFunc>
   147     for (
const auto& e : 
set_) {
   173       set_ = std::move(rhs.set_);
   175       set_.insert(rhs.set_.begin(), rhs.set_.end());
   191       for (
const auto& e : rhs.
get()) {
   204       for (
auto it = 
set_.begin(); it != 
set_.end();) {
   222     if (
size() > s.
size()) 
return false;
   224     for (
const auto& e : 
set_) {
   248   return std::move(lhs);
   254   return std::move(rhs);
   260   return std::move(lhs);
   272   return std::move(lhs);
   284   return std::move(lhs);
   291   for (
const auto& e : rhs.
get()) {
   303   return std::move(lhs);
   309   return std::move(rhs);
   315   return std::move(lhs);
   323   typedef typename Ts::template MapContainer<Set<Ts>> 
Container;
   325   typedef std::pair<Element, Element> 
Tuple;
   327   typedef std::vector<Element> 
Path;
   339   static constexpr Properties kNone = 0x0;
   340   static constexpr Properties kTransitiveClosure = 0x1;
   341   static constexpr Properties kReflexiveClosure = 0x2;
   342   static constexpr Properties kReflexiveTransitiveClosure =
   343       kTransitiveClosure | kReflexiveClosure;
   349   explicit Relation(Container r) : props_(kNone), rel_(std::move(r)) {}
   355   const Container& 
get() 
const { 
return rel_; }
   357   Properties 
props()
 const { 
return props_; }
   379     const auto props = props_;
   384   void Insert(
const Element& e1, 
const Element& e2,
   385               bool assert_unique = 
false) {
   386     rel_[e1].Insert(e2, assert_unique);
   389   void Insert(
const Element& e1, Element&& e2, 
bool assert_unique = 
false) {
   390     rel_[e1].Insert(std::move(e2), assert_unique);
   394     if (e2s.
empty()) 
return;
   399     if (e2s.empty()) 
return;
   400     rel_[e1] |= std::move(e2s);
   403   bool Erase(
const Element& e1, 
const Element& e2, 
bool assert_exists = 
false) {
   405     if (Contains__(e1)) {
   406       bool result = rel_[e1].Erase(e2, assert_exists);
   408       if (rel_[e1].
empty()) {
   419     if (Contains__(e1)) {
   422       if (rel_[e1].
empty()) {
   435     std::size_t total = 0;
   438       const auto dom = Domain();
   439       for (
const auto& e : dom.get()) {
   440         total += Reachable(e).size();
   443       for (
const auto& tuples : rel_) {
   444         total += tuples.second.size();
   456   template <
class Func>
   458     const auto dom = Domain();
   460     for (
const auto& e1 : dom.get()) {
   461       const auto reach = Reachable(e1);
   462       for (
const auto& e2 : reach.get()) {
   467     return std::move(func);
   476     if (props() == kNone) {
   482     for_each([&result](
const Element& e1, 
const Element& e2) {
   495     if (props() == kNone) {
   501     for_each([&result](
const Element& e1, 
const Element& e2) {
   506     rel_ = std::move(result.
rel_);
   510   template <
class FilterFunc>
   514     for_each([&filterFunc, &result](
const Element& e1, 
const Element& e2) {
   515       if (filterFunc(e1, e2)) {
   529     for_each([&result](
const Element& e1, 
const Element& e2) {
   543       const auto rhs_domain = rhs.
Domain();
   544       for (
const auto& e : rhs_domain.get()) {
   548       for (
const auto& tuples : rhs.
get()) {
   549         rel_[tuples.first] |= tuples.second;
   563       const auto rhs_domain = rhs.
Domain();
   564       for (
const auto& e : rhs_domain.get()) {
   568       for (
const auto& tuples : rhs.
get()) {
   569         Erase(tuples.first, tuples.second);
   582     for (
auto it = rel_.begin(); it != rel_.end();) {
   585       if (it->second.empty()) {
   605     return (props() ? Eval() : *
this).rel_ ==
   620   bool R(
const Element& e1, 
const Element& e2, Path* path = 
nullptr)
 const {
   621     if (e1 == e2 && all_props(kReflexiveClosure)) {
   623         if (path != 
nullptr) {
   634     if (path != 
nullptr) {
   637       bool result = R_search(e1, &e2, &visited, &visiting);
   639         GetPath(path, &e1, &e2, &visiting);
   645     return R_search(e1, &e2, &visited);
   659     if (all_props(kReflexiveClosure) && InOn(e)) {
   663     if (!all_props(kTransitiveClosure)) {
   664       const auto tuples = rel_.find(e);
   665       if (tuples != rel_.end()) {
   666         visited |= tuples->second;
   672     if (!R_search(e, &e, &visited, 
nullptr, kNone,
   673                   SearchMode::kRelatedVisitAll)) {
   674       if (!all_props(kReflexiveClosure)) {
   683     return Irreflexive(kNone, cyclic);
   687     return Irreflexive(kTransitiveClosure, cyclic);
   694     if (all_props(kTransitiveClosure)) {
   698     for (
const auto& tuples1 : rel_) {
   699       for (
const auto& e1 : tuples1.second.get()) {
   700         const auto tuples2 = rel_.find(e1);
   701         if (tuples2 != rel_.end()) {
   702           for (
const auto& e2 : tuples2->second.get()) {
   703             if (!R(tuples1.first, e2)) {
   718     for (
const auto& e1 : on.
get()) {
   719       for (
const auto& e2 : on.
get()) {
   720         if (!R(e1, e2) && !R(e2, e1)) {
   733     for (
const auto& e1 : on.
get()) {
   734       for (
const auto& e2 : on.
get()) {
   735         if (e1 != e2 && !R(e1, e2) && !R(e2, e1)) {
   746     for (
const auto& tuples : rel_) {
   747       if (!on.
Contains(tuples.first) && !tuples.second.SubsetEq(on)) {
   752     return Transitive() && !Irreflexive();
   756     return WeakPartialOrder(on) && TotalOn(on);
   761     for (
const auto& tuples : rel_) {
   762       if (!on.
Contains(tuples.first) && !tuples.second.SubsetEq(on)) {
   767     return Transitive() && Irreflexive();
   771     return StrictPartialOrder(on) && ConnexOn(on);
   774   bool InOn(
const Element& e)
 const {
   778       for (
const auto& tuples : rel_) {
   779         if (tuples.second.Contains(e)) {
   789     if (all_props(kReflexiveClosure)) {
   793     return Contains__(e);
   797     if (all_props(kReflexiveClosure)) {
   801     for (
const auto& tuples : rel_) {
   802       if (Reachable(tuples.first).Contains(e)) {
   812     for (
const auto& tuples : rel_) {
   814       res |= tuples.second;
   820     if (all_props(kReflexiveClosure)) {
   829     for (
const auto& tuples : rel_) {
   837     if (all_props(kReflexiveClosure)) {
   843     for (
const auto& tuples : rel_) {
   844       res |= Reachable(tuples.first);
   851     const Relation diff = (*
this - rhs);
   860   typedef typename Ts::template MapContainer<bool> 
FlagSet;
   885   bool Contains__(
const Element& e)
 const { 
return rel_.find(e) != rel_.end(); }
   890   void GetPath(Path* out, 
const Element* start, 
const Element* end,
   892                SearchMode mode = SearchMode::kRelated)
 const {
   893     assert(out != 
nullptr && start != 
nullptr && visiting != 
nullptr);
   895     out->push_back(*start);
   896     (*visiting)[*start] = 
false;
   898     while (start != 
nullptr) {
   899       const Set<Ts>& next = rel_.find(*start)->second;
   902       for (
const auto& e : next.
get()) {
   903         const auto se = visiting->find(e);
   904         if (se != visiting->end() && se->second) {
   913     const Set<Ts>& next = rel_.find(out->back())->second;
   914     if (mode == SearchMode::kFindCycle) {
   915       assert(end == 
nullptr);
   917       for (
const auto& e : *out) {
   925       assert(end != 
nullptr);
   931       out->push_back(*end);
   944     local_props |= props_;
   947       if (cyclic != 
nullptr) {
   949         cyclic->push_back(rel_.begin()->first);
   950         cyclic->push_back(rel_.begin()->first);
   959     for (
const auto& tuples : rel_) {
   960       if (R_search(tuples.first, 
nullptr, &visited, &visiting, local_props,
   961                    SearchMode::kFindCycle)) {
   962         if (cyclic != 
nullptr) {
   963           GetPath(cyclic, &tuples.first, 
nullptr, &visiting,
   964                   SearchMode::kFindCycle);
   988                 FlagSet* visiting = 
nullptr, Properties local_props = kNone,
   989                 SearchMode mode = SearchMode::kRelated)
 const {
   991     assert(visited != 
nullptr);
   994     local_props |= props_;
   996     const bool is_tran_cl = 
AllBitmask(local_props, kTransitiveClosure);
   998     R_impl search(
this, visited, visiting, is_tran_cl, mode);
  1000     if (e2 == 
nullptr) {
  1007       assert(mode == SearchMode::kFindCycle);
  1012         assert(visiting != 
nullptr);
  1013         return search.DfsRecFindCycle(e1);
  1016       assert(mode != SearchMode::kFindCycle);
  1019     return search.DfsRec(e1, *e2);
  1031           visiting_(visiting),
  1032           is_tran_cl_(is_tran_cl),
  1039     bool DfsRec(
const Element& e1, 
const Element& e2)
 const {
  1040       const auto tuples = src_->get().find(e1);
  1042       if (tuples == src_->get().end()) {
  1046       if (visiting_ != 
nullptr) {
  1047         (*visiting_)[e1] = 
true;
  1050       bool result = 
false;
  1051       visited_->Insert(e1);
  1053       for (
const auto& e : tuples->second.get()) {
  1055           if (mode_ == SearchMode::kRelatedVisitAll) {
  1063           if (!visited_->Contains(e)) {
  1064             if (DfsRec(e, e2)) {
  1065               if (mode_ == SearchMode::kRelatedVisitAll) {
  1076             visited_->Insert(e);
  1083       if (visiting_ != 
nullptr) {
  1084         (*visiting_)[e1] = 
false;
  1099       const auto tuples = src_->get().find(start);
  1101       if (tuples == src_->get().end()) {
  1105       (*visiting_)[start] = 
true;
  1106       visited_->Insert(start);
  1108       for (
const auto& e : tuples->second.get()) {
  1109         if (!visited_->Contains(e)) {
  1110           if (DfsRecFindCycle(e)) {
  1114           const auto se = visiting_->find(e);
  1115           if (se != visiting_->end() && se->second) {
  1122       (*visiting_)[start] = 
false;
  1143   for (
const auto& e1 : lhs.
get()) {
  1144     for (
const auto& e2 : rhs.
get()) {
  1162   return std::move(lhs);
  1168   return std::move(rhs);
  1174   return std::move(lhs);
  1187   return std::move(lhs);
  1199   return std::move(lhs);
  1207   const auto lhs_domain = lhs.
Domain();
  1208   for (
const auto& e : lhs_domain.get()) {
  1211     res.
Insert(e, std::move(intersect));
  1220   return std::move(lhs);
  1226   return std::move(rhs);
  1232   return std::move(lhs);
  1245       : rels_(std::move(rels)) {}
  1279     if (rels_.empty()) {
  1285     assert(rels_.size() == 1);
  1298     rels_.reserve(rels_.size() + rels.size());
  1299     rels_.insert(rels_.end(), rels.begin(), rels.end());
  1325     this->Add(std::move(rhs));
  1330     this->Add(rhs.
rels_);
  1335     while (this->rels_.size() > 1) {
  1336       std::size_t from_idx = this->rels_.size() - 2;
  1337       const auto& first = this->rels_[from_idx];
  1338       const auto& last = this->rels_.back();
  1342       first.
for_each([&er, &last](
const Element& e1, 
const Element& e2) {
  1343         if (last.InDomain(e2)) {
  1344           er.
Insert(e1, last.Reachable(e2));
  1348       this->rels_.erase(this->rels_.end() - 2, this->rels_.end());
  1349       this->rels_.push_back(std::move(er));
  1358     if (this->rels_.empty()) {
  1360     } 
else if (this->rels_.size() == 1) {
  1361       return this->rels_.back();
  1364     const auto potential_domain = this->rels_.front().
Domain();
  1365     const auto potential_range = this->rels_.back().Range();
  1367     for (
const auto& e1 : potential_domain.get()) {
  1368       for (
const auto& e2 : potential_range.get()) {
  1387   bool R(
const Element& e1, 
const Element& e2,
  1389          std::size_t seq = 0)
 const {
  1390     if (this->rels_.empty()) {
  1394     assert(seq < this->rels_.size());
  1396     if (seq + 1 < this->rels_.size()) {
  1397       const auto& rel = this->rels_[seq];
  1398       std::size_t path_size = 0;
  1400       const Set<Ts> reach = rel.Reachable(e1);
  1401       for (
const auto& e : reach.
get()) {
  1402         if (path != 
nullptr) {
  1403           path_size = path->
size();
  1408         if (R(e, e2, path, seq + 1)) {
  1412         if (path != 
nullptr) {
  1414           assert(path_size < path->
size());
  1415           path->erase(path->begin() + path_size, path->end());
  1422     return this->rels_[seq].R(e1, e2, path);
  1433     if (this->rels_.empty()) {
  1437     const auto domain = this->rels_.front().Domain();
  1438     for (
const auto& e : domain.get()) {
  1439       if (R(e, e, cyclic)) {
  1459   return std::move(lhs);
  1466   return res += std::move(rhs);
  1471   lhs += std::move(rhs);
  1472   return std::move(lhs);
  1486   return std::move(lhs);
  1499   return std::move(lhs);
  1509 template <
class E, 
class Hash = 
typename E::Hash>
 bool StrictPartialOrder(const Set< Ts > &on) const
Definition: sets.hpp:759
std::unordered_map< Element, T, std::hash< types::Addr > > MapContainer
Definition: sets.hpp:1516
bool AnyBitmask(T mask, T any)
Definition: sets.hpp:73
Set< Ts > operator &(const Set< Ts > &lhs, const Set< Ts > &rhs)
Definition: sets.hpp:288
bool InDomain(const Element &e) const
Definition: sets.hpp:788
RelationOp< Ts > & EvalInplace() override
Definition: sets.hpp:1334
bool Transitive() const
Definition: sets.hpp:693
bool operator==(const Set &rhs) const
Definition: sets.hpp:101
Helper class to instantiate types used by Set, Relation, etc. 
Definition: sets.hpp:1510
bool Irreflexive(Path *cyclic=nullptr) const
Definition: sets.hpp:682
const Relation * src_
Definition: sets.hpp:1127
bool DfsRecFindCycle(const Element &start) const
Definition: sets.hpp:1094
bool WeakTotalOrder(const Set< Ts > &on) const
Definition: sets.hpp:755
Set< Ts > operator|(const Set< Ts > &lhs, const Set< Ts > &rhs)
Definition: sets.hpp:240
bool operator==(const Relation &rhs) const
Definition: sets.hpp:604
void Add(const Relation< Ts > &er)
Definition: sets.hpp:1293
void Insert(const Element &e1, Set< Ts > &&e2s)
Definition: sets.hpp:398
RelationOp()
Definition: sets.hpp:1242
std::unordered_set< Element, Hash > SetContainer
Definition: sets.hpp:1513
Set< Ts > Range() const
Definition: sets.hpp:836
Set< Ts > Reachable(const Element &e) const
Definition: sets.hpp:656
Properties clear_props()
Definition: sets.hpp:378
bool InOn(const Element &e) const
Definition: sets.hpp:774
Ts::SetContainer Container
Definition: sets.hpp:88
bool SubsetEq(const Relation &rhs) const
Definition: sets.hpp:850
Set & operator &=(const Set &rhs)
Definition: sets.hpp:202
std::size_t size() const
Definition: sets.hpp:217
Set & operator-=(const Set &rhs)
Definition: sets.hpp:184
Relation Inverse() const
Definition: sets.hpp:526
Set< Ts > operator-(const Set< Ts > &lhs, const Set< Ts > &rhs)
Definition: sets.hpp:264
bool operator!=(const Relation &rhs) const
Definition: sets.hpp:609
SearchMode
Definition: sets.hpp:865
Container rel_
Definition: sets.hpp:1136
Relation< Ts > operator*(const Set< Ts > &lhs, const Set< Ts > &rhs)
Definition: sets.hpp:1140
RelationOp(std::vector< Relation< Ts >> rels)
Definition: sets.hpp:1244
bool R_search(const Element &e1, const Element *e2, Set< Ts > *visited, FlagSet *visiting=nullptr, Properties local_props=kNone, SearchMode mode=SearchMode::kRelated) const
Definition: sets.hpp:987
Properties props() const
Definition: sets.hpp:357
void Add(Relation< Ts > &&er)
Definition: sets.hpp:1295
void Erase(const Element &e1, const Set< Ts > &e2s)
Definition: sets.hpp:418
RelationSeq< Ts > operator+(const RelationSeq< Ts > &lhs, const Relation< Ts > &rhs)
Definition: sets.hpp:1449
const Element & Insert(const Element &e, bool assert_unique=false)
Definition: sets.hpp:112
bool Erase(const Element &e1, const Element &e2, bool assert_exists=false)
Definition: sets.hpp:403
Set & operator|=(Set &&rhs)
Definition: sets.hpp:171
bool Irreflexive(typename Relation< Ts >::Path *cyclic=nullptr) const
Definition: sets.hpp:1432
Set & operator|=(const Set &rhs)
Definition: sets.hpp:163
std::vector< Element > Path
Definition: sets.hpp:327
Set< Ts > On() const
Definition: sets.hpp:810
bool AllBitmask(T mask, T all)
Definition: sets.hpp:60
std::pair< Element, Element > Tuple
Definition: sets.hpp:325
bool empty() const
Definition: sets.hpp:598
Definition: sets.hpp:1240
bool ConnexOn(const Set< Ts > &on) const
Definition: sets.hpp:732
Ts::template MapContainer< Set< Ts > > Container
Definition: sets.hpp:323
RelationSeq()
Definition: sets.hpp:1314
unsigned Properties
Definition: sets.hpp:335
Relation & operator &=(const Relation &rhs)
Definition: sets.hpp:579
Set< Ts > * visited_
Definition: sets.hpp:1128
RelationSeq & operator+=(const Relation< Ts > &rhs)
Definition: sets.hpp:1319
bool Irreflexive(Properties local_props, Path *cyclic) const
Definition: sets.hpp:943
std::size_t size() const
Definition: sets.hpp:434
RelationSeq(std::vector< Relation< Ts >> v)
Definition: sets.hpp:1316
Func for_each(Func func) const
Definition: sets.hpp:457
Relation & EvalInplace()
Definition: sets.hpp:494
const Container & get() const
Definition: sets.hpp:99
void Clear()
Definition: sets.hpp:156
bool Contains(const Element &e) const
Definition: sets.hpp:158
Relation Eval() const
Definition: sets.hpp:475
Container set_
Definition: sets.hpp:236
Properties props_
Definition: sets.hpp:1135
void Clear()
Definition: sets.hpp:1269
Set()
Definition: sets.hpp:90
Set< Ts > Domain() const
Definition: sets.hpp:819
Abstracts over container library's set implementation. 
Definition: sets.hpp:85
bool WeakPartialOrder(const Set< Ts > &on) const
Definition: sets.hpp:744
void Insert(const Element &e1, Element &&e2, bool assert_unique=false)
Definition: sets.hpp:389
bool operator!=(const Set &rhs) const
Definition: sets.hpp:103
bool TotalOn(const Set< Ts > &on) const
Definition: sets.hpp:717
Ts::Element Element
Definition: sets.hpp:1312
const Container & get() const
Definition: sets.hpp:355
bool StrictTotalOrder(const Set< Ts > &on) const
Definition: sets.hpp:770
Relation & unset_props(Properties props)
Definition: sets.hpp:369
FlagSet * visiting_
Definition: sets.hpp:1129
Definition: sets.hpp:1025
Relation()
Definition: sets.hpp:347
bool Erase(const Element &e, bool assert_exists=false)
Definition: sets.hpp:137
Set Filter(FilterFunc filterFunc) const
Definition: sets.hpp:144
bool R(const Element &e1, const Element &e2, Path *path=nullptr) const
Definition: sets.hpp:620
bool DfsRec(const Element &e1, const Element &e2) const
Definition: sets.hpp:1039
bool any_props(Properties any) const
Definition: sets.hpp:376
const Element & Insert(Element &&e, bool assert_unique=false)
Definition: sets.hpp:125
Relation< Ts > Eval() const override
Definition: sets.hpp:1355
SearchMode mode_
Definition: sets.hpp:1131
std::vector< Relation< Ts > > rels_
Definition: sets.hpp:1303
Relation & operator|=(const Relation &rhs)
Definition: sets.hpp:539
Relation Filter(FilterFunc filterFunc) const
Definition: sets.hpp:511
void Insert(const Element &e1, const Element &e2, bool assert_unique=false)
Definition: sets.hpp:384
Relation< Ts > EvalClear()
Definition: sets.hpp:1278
Relation(Container r)
Definition: sets.hpp:349
Relation & operator-=(const Relation &rhs)
Definition: sets.hpp:559
Ts::Element Element
Definition: sets.hpp:87
void GetPath(Path *out, const Element *start, const Element *end, FlagSet *visiting, SearchMode mode=SearchMode::kRelated) const
Definition: sets.hpp:890
Definition: sets.hpp:1310
Relation & add_props(Properties props)
Definition: sets.hpp:364
R_impl(const Relation *src, Set< Ts > *visited, FlagSet *visiting, bool is_tran_cl, SearchMode mode)
Definition: sets.hpp:1027
bool Subset(const Set &s) const
Definition: sets.hpp:233
RelationSeq & operator+=(const RelationSeq &rhs)
Definition: sets.hpp:1329
bool Subset(const Relation &rhs) const
Definition: sets.hpp:855
bool InRange(const Element &e) const
Definition: sets.hpp:796
bool SubsetEq(const Set &s) const
Definition: sets.hpp:221
void Add(const std::vector< Relation< Ts >> &rels)
Definition: sets.hpp:1297
bool R(const Element &e1, const Element &e2, typename Relation< Ts >::Path *path=nullptr, std::size_t seq=0) const
Definition: sets.hpp:1387
bool Acyclic(Path *cyclic=nullptr) const
Definition: sets.hpp:686
E Element
Definition: sets.hpp:1511
Set(Container s)
Definition: sets.hpp:92
bool Contains__(const Element &e) const
Definition: sets.hpp:885
bool empty() const
Definition: sets.hpp:219
RelationSeq & operator+=(Relation< Ts > &&rhs)
Definition: sets.hpp:1324
Ts::Element Element
Definition: sets.hpp:321
sets::Types< Event > ::template MapContainer< bool > FlagSet
Definition: sets.hpp:860
void Clear()
Definition: sets.hpp:596
void Insert(const Element &e1, const Set< Ts > &e2s)
Definition: sets.hpp:393
bool is_tran_cl_
Definition: sets.hpp:1130
bool all_props(Properties all) const
Definition: sets.hpp:374
Relation & set_props(Properties props)
Definition: sets.hpp:359