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