From 1a9d2ec9dc717e014d2c0a4a93cc4290a51846d4 Mon Sep 17 00:00:00 2001 From: kalashnikovni Date: Mon, 8 Apr 2024 08:25:14 -0300 Subject: [PATCH] New version of topsort --- eval/defs.hpp | 4 +- eval/visitors/eval_expr.cpp | 47 ++-- sbg/map.cpp | 7 + sbg/map.hpp | 1 + sbg/ord_pw_mdinter.cpp | 6 +- sbg/ord_pw_mdinter.hpp | 1 + sbg/sbg_algorithms.cpp | 432 ++++++++---------------------------- sbg/sbg_algorithms.hpp | 84 ++----- sbg/unord_pw_mdinter.cpp | 6 +- sbg/unord_pw_mdinter.hpp | 1 + test/rl33_scc.test | 87 ++++++++ test/topsort1.test | 6 +- 12 files changed, 242 insertions(+), 440 deletions(-) create mode 100644 test/rl33_scc.test diff --git a/eval/defs.hpp b/eval/defs.hpp index 2ff1158..25f5cc2 100755 --- a/eval/defs.hpp +++ b/eval/defs.hpp @@ -68,9 +68,7 @@ typedef std::variant SBGBaseType; typedef std::variant - , LIB::MatchInfo - , LIB::VertexOrder - , LIB::VertexOrder> InfoBaseType; + , LIB::MatchInfo> InfoBaseType; typedef std::variant(debug_) + MapBaseType result = std::visit( + ts_visitor_, g, std::variant(debug_) ); return result; } @@ -754,7 +743,7 @@ ExprBaseType EvalExpression::operator()(AST::Call v) const SBGBaseType g = std::visit(EvalGraph{}, eval_args[0]); NatBaseType copies = std::visit(EvalNatBT{}, eval_args[1]); NatBaseType k = std::visit(EvalNatBT{}, eval_args[2]); - InfoBaseType result = std::visit( + MapBaseType result = std::visit( match_scc_ts_visitor_, g, copies, k, std::variant(debug_) ); return result; diff --git a/sbg/map.cpp b/sbg/map.cpp index 9d6413b..eee6e25 100755 --- a/sbg/map.cpp +++ b/sbg/map.cpp @@ -107,6 +107,13 @@ SetPiece image(SetPiece mdi, Exp mdle) template SBGMap::SBGMap() : dom_(Set()), exp_(Exp()) {} template +SBGMap::SBGMap(Util::MD_NAT x, Exp exp) : dom_(), exp_() { + SetPiece mdi(x); + compatible(mdi, exp); + dom_ = Set(mdi); + exp_ = exp; +} +template SBGMap::SBGMap(Interval i, LExp le) : dom_(), exp_() { compatible(i, le); dom_ = Set(SetPiece(i)); diff --git a/sbg/map.hpp b/sbg/map.hpp index 43368e3..0b735de 100755 --- a/sbg/map.hpp +++ b/sbg/map.hpp @@ -47,6 +47,7 @@ struct SBGMap { member_class(Exp, exp); SBGMap(); + SBGMap(Util::MD_NAT x, Exp exp); SBGMap(Interval i, LExp le); SBGMap(SetPiece mdi, Exp exp); SBGMap(Set dom, Exp exp); diff --git a/sbg/ord_pw_mdinter.cpp b/sbg/ord_pw_mdinter.cpp index 1d2096a..01441a3 100755 --- a/sbg/ord_pw_mdinter.cpp +++ b/sbg/ord_pw_mdinter.cpp @@ -50,8 +50,10 @@ std::ostream &operator<<(std::ostream &out, const MDInterOrdSet &ii) // OrdPWMDInter ------------------------------------------------------------------ OrdPWMDInter::OrdPWMDInter() : pieces_() {} -OrdPWMDInter::OrdPWMDInter(Interval i) : pieces_() -{ +OrdPWMDInter::OrdPWMDInter(Util::MD_NAT x) : pieces_() { + pieces_.insert(SetPiece(x)); +} +OrdPWMDInter::OrdPWMDInter(Interval i) : pieces_() { if (!i.isEmpty()) pieces_.insert(SetPiece(i)); } diff --git a/sbg/ord_pw_mdinter.hpp b/sbg/ord_pw_mdinter.hpp index edb6d10..0b3bb12 100755 --- a/sbg/ord_pw_mdinter.hpp +++ b/sbg/ord_pw_mdinter.hpp @@ -68,6 +68,7 @@ struct OrdPWMDInter { * @brief Constructors don't check if intervals are disjoint (performance). */ OrdPWMDInter(); + OrdPWMDInter(Util::MD_NAT x); OrdPWMDInter(Interval i); OrdPWMDInter(SetPiece mdi); OrdPWMDInter(MDInterOrdSet container); diff --git a/sbg/sbg_algorithms.cpp b/sbg/sbg_algorithms.cpp index 714bb7b..72b0a51 100755 --- a/sbg/sbg_algorithms.cpp +++ b/sbg/sbg_algorithms.cpp @@ -826,169 +826,129 @@ std::set SBGSCC::transformResult(PWMap scc) // Topological sort ------------------------------------------------------------ // ----------------------------------------------------------------------------- -template -VertexOrder::VertexOrder() : container_() {} - -member_imp_temp( - template, VertexOrder, std::vector, container -); - -template -void VertexOrder::emplaceBack(const Set &s) { container_.emplace_back(s); } - -template -bool VertexOrder::operator==(const VertexOrder &other) const -{ - if (container_.size() != other.container_.size()) - return false; - - for (unsigned int j = 0; j < container_.size(); ++j) - if (container_[j] != other.container_[j]) - return false; - - return true; -} - -template -bool VertexOrder::operator!=(const VertexOrder &other) const -{ - return !(*this == other); -} - -template -std::ostream &operator<<(std::ostream &out, const VertexOrder &vo) -{ - for (const Set &s : vo.container()) - out << s; - - return out; -} - template SBGTopSort::SBGTopSort() - : dsbg_(), mapB_(), mapD_(), disordered_(), rec_map_(), debug_(false) {} + : dsbg_(), smap_(), E_(), mapB_(), mapD_(), unordered_(), not_dependant_() + , visitedE_(), end_(), new_end_(), dom_(), exp_(), debug_(false) {} template SBGTopSort::SBGTopSort(DSBGraph dsbg, bool debug) - : dsbg_(dsbg), mapB_(dsbg.mapB()), mapD_(dsbg.mapD()), disordered_(dsbg.V()) - , rec_map_(), debug_(debug) {} + : dsbg_(dsbg), smap_(), E_(dsbg.E()), mapB_(dsbg.mapB()), mapD_(dsbg.mapD()) + , unordered_(dsbg.V()), not_dependant_(), visitedE_(), end_(), new_end_() + , dom_(), exp_(), debug_(debug) { + not_dependant_ = dsbg.V().difference(mapB().image()); + end_ = not_dependant_.minElem(); + new_end_ = end_; +} member_imp_temp(template, SBGTopSort, DSBGraph, dsbg); +member_imp_temp(template, SBGTopSort, PWMap, smap); +member_imp_temp(template, SBGTopSort, Set, E); member_imp_temp(template, SBGTopSort, PWMap, mapB); member_imp_temp(template, SBGTopSort, PWMap, mapD); -member_imp_temp(template, SBGTopSort, Set, disordered); -member_imp_temp(template, SBGTopSort, PWMap, rec_map); +member_imp_temp(template, SBGTopSort, Set, unordered); +member_imp_temp(template, SBGTopSort, Set, not_dependant); +member_imp_temp(template, SBGTopSort, Set, visitedE); +member_imp_temp(template, SBGTopSort, Util::MD_NAT, end); +member_imp_temp(template, SBGTopSort, Util::MD_NAT, new_end); +member_imp_temp(template, SBGTopSort, Set, dom); +member_imp_temp(template, SBGTopSort, Exp, exp); member_imp_temp(template, SBGTopSort, bool, debug); template -void SBGTopSort::findRecursions() +void SBGTopSort::calculateExp() { - PW res; - - DSBGraph aux_dsbg = dsbg(); - PW subE_map = aux_dsbg.subE_map(); - - Set visited; - Util::NAT dims = subE_map.nmbrDims(); - unsigned int k = 1; - RecInfo rec_info; - for (const SBGMap &map : subE_map) { - Set visited_ith = map.dom().intersection(visited); - - if (visited_ith.isEmpty()) { - Util::MD_NAT x = map.dom().midElem(); - Set first{SetPiece(x)}, last; - - Set v_start = aux_dsbg.mapD().image(first); // Ending vertex of start - Set start_ith = aux_dsbg.mapB().preImage(v_start); // Following edge from the start - Set start_path = first, end_path, rec_path; - - if (start_ith.intersection(map.dom()).isEmpty()) { - unsigned j = 0; - for (; j < aux_dsbg.Vmap().size(); ++j) { - start_path = start_path.cup(start_ith); - if (!start_ith.intersection(map.dom()).isEmpty()) { - last = start_ith.intersection(map.dom()); - end_path = last; - break; - } - - v_start = aux_dsbg.mapD().image(start_ith); // Ending vertex of start_ith - start_ith = aux_dsbg.mapB().preImage(v_start); // Following edge from the start_ith - } - - if (!last.isEmpty()) { - Set v_end = aux_dsbg.mapB().image(last); // Starting vertex of end - Set end_ith = aux_dsbg.mapD().preImage(v_end); // Following edge from the end + Exp res; - for (unsigned int l = 0; l < j; l++) { - end_path = end_path.concatenation(end_ith); - - v_end = aux_dsbg.mapB().image(end_ith); // Starting vertex of end_ith - end_ith = aux_dsbg.mapD().preImage(v_end); // Following edge from end_ith - } - } - - rec_path = start_path.intersection(end_path); - rec_path = subE_map.preImage(subE_map.image(rec_path)); - } + Util::MD_NAT aux_end = end(), aux_ne = new_end(); + Util::RATIONAL one(1, 1); + for (unsigned int j = 0; j < end().size(); ++j) { + Util::RATIONAL x1(aux_end[j]), x2(aux_ne[j]); + res.emplaceBack(LExp(1, x1 - x2)); + } - else - rec_path = subE_map.preImage(subE_map.image(first)); + set_exp(res); - if (!rec_path.isEmpty()) { - visited = visited.cup(rec_path); - Util::MD_NAT id(dims, k); - rec_map_ref().emplaceBack(SBGMap(rec_path, Exp(id))); - ++k; - } - } - } + return; } template -Set SBGTopSort::topSortStep() +void SBGTopSort::topSortStep() { - // Vertices without outgoing edges - Set nth = disordered().difference(mapB().image()); - - // Ingoing edges to nth - Set ingoing = mapD().preImage(nth); - - // Recursive edges in paths where ingoing participate - Set rec_es = rec_map().image(ingoing); - Set ingoing_plus = ingoing.cup(rec_map().preImage(rec_es)); + Set end_set(end()); + set_dom(end_set); + + Set nd = not_dependant(); + PW Vmap = dsbg().Vmap(); + Set vend = Vmap.preImage(Vmap.image(end_set)); + vend = nd.intersection(vend).difference(end_set); + if (vend.isEmpty()) { + Set ne_set(nd.minElem()); + set_dom(ne_set); + set_new_end(nd.minElem()); + Set vnew_end = Vmap.preImage(Vmap.image(ne_set)); + vnew_end = unordered().intersection(vnew_end); + if (!vnew_end.difference(nd).isEmpty()) + set_dom(vnew_end); + set_E(E().difference(mapD().preImage(ne_set))); + calculateExp(); + set_end(new_end()); + } + else { + set_dom(vend); + set_new_end(vend.minElem()); + calculateExp(); + set_end(vend.maxElem()); + } + + smap_ref().emplaceBack(SBGMap(dom(), exp())); - Set domB_minus = mapB().dom().difference(ingoing_plus); - Set domD_minus = mapD().dom().difference(ingoing_plus); - set_mapB(mapB().restrict(domB_minus)); - set_mapD(mapD().restrict(domD_minus)); + return; +} - set_disordered(disordered().difference(nth)); +template +void SBGTopSort::updateStatus() +{ + Set ordv = smap().dom(); + Set ordB = mapB().preImage(ordv), ordD = mapD().preImage(ordv); + Set orde = ordB.intersection(ordD); + + ordv = mapB().image(orde).cup(mapD().image(orde)); + Set ingoing = mapD().preImage(ordv); + Set newE = E().difference(orde); + newE = newE.difference(ingoing); + set_E(newE); + + if (!orde.intersection(visitedE()).isEmpty()) + set_end(smap().dom().difference(smap().image()).minElem()); + + PW subE = dsbg().subE_map(); + Set SE = subE.preImage(subE.image(newE)); + set_visitedE(visitedE().cup(SE)); + + set_mapB(mapB().restrict(newE)); + set_mapD(mapD().restrict(newE)); + + set_unordered(unordered().difference(dom())); + set_not_dependant(unordered().difference(mapB().image())); - return nth; + return; } template -VertexOrder SBGTopSort::calculate() +PWMap SBGTopSort::calculate() { if (debug()) Util::SBG_LOG << "Topological sort dsbg:\n" << dsbg() << "\n\n"; - VertexOrder res; - - findRecursions(); - if (debug()) - Util::SBG_LOG << "rec_map: " << rec_map() << "\n\n"; - do { - Set nth = topSortStep(); - if (!nth.isEmpty()) - res.emplaceBack(nth); - } while (!disordered().isEmpty()); + while (!unordered().isEmpty()) { + topSortStep(); + updateStatus(); + } if (debug()) - Util::SBG_LOG << "Topological sort result:\n" << res << "\n\n"; + Util::SBG_LOG << "Topological sort result:\n" << smap() << "\n\n"; - return res; + return smap(); } // Template instantiations ----------------------------------------------------- @@ -1017,15 +977,6 @@ template struct SBGMatching; template struct SBGSCC; template struct SBGSCC; -template struct VertexOrder; -template std::ostream &operator<<( - std::ostream &out, const BaseVO &vo -); -template struct VertexOrder; -template std::ostream &operator<<( - std::ostream &out, const CanonVO &vo -); - template struct SBGTopSort; template struct SBGTopSort; @@ -1133,196 +1084,9 @@ DSBGraph buildSortFromSCC( template BaseDSBG buildSortFromSCC(const BaseSCC &scc, const BasePWMap &rmap); template CanonDSBG buildSortFromSCC(const CanonSCC &scc, const CanonPWMap &rmap); -SVOrder::SVOrder() : order_() {} -SVOrder::SVOrder(SVOrder::SVVector order) : order_(order) {} - -member_imp(SVOrder, SVOrder::SVVector, order); - -bool SVOrder::operator==(const SVOrder &other) const -{ - return order_ == other.order_; -} -bool SVOrder::operator!=(const SVOrder &other) const -{ - return order_ != other.order_; -} - -std::ostream &operator<<(std::ostream &out, const SVOrder &svo) -{ - unsigned int j = 0; - for (; j < svo.order_.size() - 1; ++j) - out << svo.order_[j] << " - "; - out << svo.order_[j]; - - return out; -} - -std::ostream &operator<<(std::ostream &out, const MD_INT &x) -{ - unsigned int sz = x.size(); - - if (sz == 1) - out << x[0]; - - if (sz > 1) { - out << "("; - for (unsigned int j = 0; j < x.size()-1; ++j) - out << x[j] << ", "; - out << x[sz-1]; - out << ")"; - } - - return out; -} - -BoundsElement::BoundsElement() : first_(), step_(), last_() {} -BoundsElement::BoundsElement( - Util::MD_NAT first, MD_INT step, Util::MD_NAT last -) - : first_(first), step_(step), last_(last) {} - -member_imp(BoundsElement, Util::MD_NAT, first); -member_imp(BoundsElement, MD_INT, step); -member_imp(BoundsElement, Util::MD_NAT, last); - -bool BoundsElement::operator==(const BoundsElement &other) const -{ - return first_ == other.first_ && step_ == other.step_ && last_ == other.last_; -} - -bool BoundsElement::operator!=(const BoundsElement &other) const -{ - return !(*this == other); -} - -std::ostream &operator<<(std::ostream &out, const BoundsElement &be) -{ - out << "#" << be.first_ << ":" << be.step_ << ":" << be.last_ << "#"; - - return out; -} - -std::ostream &operator<<(std::ostream &out, const BoundsInfo &bi) -{ - for (const auto &be : bi) - out << "bounds_info[" << be.first << "] = " << be.second << "\n"; - - return out; -} - -RecElement::RecElement() : sv_order_(), bounds_() {} -RecElement::RecElement(SVOrder sv_order, BoundsInfo bounds) - : sv_order_(sv_order), bounds_(bounds) {} - -member_imp(RecElement, SVOrder, sv_order); -member_imp(RecElement, BoundsInfo, bounds); - -bool RecElement::operator==(const RecElement &other) const -{ - return sv_order_ == other.sv_order_ && bounds_ == other.bounds_; -} - -bool RecElement::operator!=(const RecElement &other) const -{ - return !(*this == other); -} - -std::ostream &operator<<(std::ostream &out, const RecElement &re) -{ - out << re.sv_order_ << "\n" << re.bounds_; - - return out; -} - -std::ostream &operator<<(std::ostream &out, const RecInfo &ri) -{ - for (const auto &re : ri) { - out << "Recursion id: " << re.first; - out << "\n=========================\n" << re.second << "\n"; - } - - return out; -} - -template -RecElement getRecElem( - const DSBGraph &dsbg, Set rec_path, PWMap og_map -) -{ - PWMap auxB = dsbg.mapB(), auxD = dsbg.mapD(); - Set recB = auxB.image(rec_path), recD = auxD.image(rec_path); - // Vertices without outgoing edges - Set take_out = recD.difference(recB); - - BoundsInfo bounds_info; - Set rec_vs = recB.cup(recD); - - SVOrder::SVVector order; - Util::MD_NAT id = dsbg.Vmap().image(take_out).minElem(); - do { - Set rec_take_out = rec_vs.intersection(dsbg.Vmap().preImage(Set(SetPiece(id)))); - Set og_subset = og_map.preImage(og_map.image(take_out)); - Util::MD_NAT x = take_out.minElem(), og_min = og_subset.minElem(); - bool cond = x == rec_take_out.minElem(); - - Util::MD_NAT first(x.size(), 0), last(x.size(), 0); - MD_INT step(x.size(), 0); - - Set rec_other = rec_take_out.difference(take_out); - Util::MD_NAT other_min = rec_other.minElem(); - Util::MD_NAT other_max = rec_other.maxElem(); - for (unsigned int j = 0; j < x.size(); ++j) { - first[j] = x[j] - og_min[j] + 1; - step[j] = cond ? other_min[j] - x[j] : other_max[j] - x[j]; - last[j] = cond ? rec_take_out.maxElem()[j] : rec_take_out.minElem()[j]; - last[j] = Util::NAT(last[j] - og_min[j] + 1); - } - BoundsElement b_elem(first, step, last); - bounds_info[id] = b_elem; - - order.emplace_back(id); - Set ingoing = auxD.preImage(take_out).intersection(rec_path); - take_out = auxB.image(ingoing); - id = dsbg.Vmap().image(take_out).minElem(); - } while (id != order[0]); - - return RecElement(SVOrder(order), bounds_info); -} - -template RecElement getRecElem -( - const BaseDSBG &dsbg, UnordSet rec_path, BasePWMap og_map -); -template RecElement getRecElem -( - const CanonDSBG &dsbg, OrdSet rec_path, CanonPWMap og_map -); - -template -RecInfo buildRecursionInfo( - const DSBGraph &dsbg, PWMap rec_map, PWMap og_map -) -{ - RecInfo res; - - for (const SBGMap &map : rec_map) { - Util::MD_NAT id = map.image().minElem(); - res[id] = getRecElem(dsbg, map.dom(), og_map); - } - - return res; -} - -template RecInfo buildRecursionInfo( - const BaseDSBG &dsbg, BasePWMap rec_path, BasePWMap og_map -); -template RecInfo buildRecursionInfo( - const CanonDSBG &dsbg, CanonPWMap rec_path, CanonPWMap og_map -); - template void buildJson( - const Set &matching, std::set scc, const VertexOrder &order + const Set &matching, std::set scc ) { // 1. Parse a JSON string into DOM. @@ -1342,10 +1106,10 @@ void buildJson( ss2 << s; s.SetString(ss2.str().c_str(), strlen(ss2.str().c_str()), d.GetAllocator()); - rapidjson::Value &o = d["order"]; - std::stringstream ss3; - ss3 << order; - o.SetString(ss3.str().c_str(), strlen(ss3.str().c_str()), d.GetAllocator()); + //rapidjson::Value &o = d["order"]; + //std::stringstream ss3; + //ss3 << order; + //o.SetString(ss3.str().c_str(), strlen(ss3.str().c_str()), d.GetAllocator()); // 3. Stringify the DOM FILE *fp = fopen("output.json", "w"); @@ -1361,11 +1125,11 @@ void buildJson( template void buildJson ( - const UnordSet &match, std::set scc, const BaseVO &order + const UnordSet &match, std::set scc ); template void buildJson ( - const OrdSet &match, std::set scc, const CanonVO &order + const OrdSet &match, std::set scc ); } // namespace LIB diff --git a/sbg/sbg_algorithms.hpp b/sbg/sbg_algorithms.hpp index 76fb38a..5c9e75f 100755 --- a/sbg/sbg_algorithms.hpp +++ b/sbg/sbg_algorithms.hpp @@ -236,25 +236,33 @@ struct SBGTopSort { member_class(DSBGraph, dsbg); //----------------------------- + member_class(PW, smap); + + member_class(Set, E); member_class(PW, mapB); member_class(PW, mapD); - member_class(Set, disordered); + member_class(Set, unordered); + member_class(Set, not_dependant); + member_class(Set, visitedE); + + member_class(Util::MD_NAT, end); + member_class(Util::MD_NAT, new_end); - // Auxiliary map where recursive paths are grouped as pertaining to the same - // subset-edge - member_class(PW, rec_map); + member_class(Set, dom); + member_class(Exp, exp); member_class(bool, debug); SBGTopSort(); SBGTopSort(DSBGraph dsbg, bool debug); - VertexOrder calculate(); + PW calculate(); private: - void findRecursions(); // Find all possible recursions - Set topSortStep(); + void calculateExp(); + void topSortStep(); + void updateStatus(); }; typedef SBGTopSort BaseTopSort; @@ -268,69 +276,9 @@ DSBGraph buildSCCFromMatching(const SBGMatching &match); template DSBGraph buildSortFromSCC(const SBGSCC &scc, const PWMap &rmap); -// Save the order in which the set-vertices appear in a recursion -struct SVOrder { - using SVVector = std::vector; - - member_class(SVVector, order); - - SVOrder(); - SVOrder(SVVector order); - - bool operator==(const SVOrder &other) const; - bool operator!=(const SVOrder &other) const; -}; -std::ostream &operator<<(std::ostream &out, const SVOrder &svo); - -typedef std::vector MD_INT; - -// Save the order in which vertices are taken out in a recursion -struct BoundsElement { - member_class(Util::MD_NAT, first); - member_class(MD_INT, step); - member_class(Util::MD_NAT, last); - - BoundsElement(); - BoundsElement( - Util::MD_NAT first, MD_INT step, Util::MD_NAT last - ); - - bool operator==(const BoundsElement &other) const; - bool operator!=(const BoundsElement &other) const; -}; -std::ostream &operator<<(std::ostream &out, const BoundsElement &be); - -typedef std::map BoundsInfo; -std::ostream &operator<<(std::ostream &out, const BoundsInfo &bi); - -struct RecElement { - member_class(SVOrder, sv_order); - member_class(BoundsInfo, bounds); - - RecElement(); - RecElement(SVOrder sv_order, BoundsInfo bi); - - bool operator==(const RecElement &other) const; - bool operator!=(const RecElement &other) const; -}; -std::ostream &operator<<(std::ostream &out, const RecElement &re); - -typedef std::map RecInfo; -std::ostream &operator<<(std::ostream &out, const RecInfo &ri); - -template -RecElement getRecElem( - const DSBGraph &dsbg, Set rec_path, PWMap og_map -); - -template -RecInfo buildRecursionInfo( - const DSBGraph &dsbg, PWMap rec_map, PWMap og_map -); - template void buildJson( - const Set &matching, std::set scc, const VertexOrder &order + const Set &matching, std::set scc ); } // namespace LIB diff --git a/sbg/unord_pw_mdinter.cpp b/sbg/unord_pw_mdinter.cpp index b4b235c..69e46e2 100755 --- a/sbg/unord_pw_mdinter.cpp +++ b/sbg/unord_pw_mdinter.cpp @@ -49,12 +49,14 @@ std::ostream &operator<<(std::ostream &out, const MDInterUnordSet &ii) //////////////////////////////////////////////////////////////////////////////// UnordPWMDInter::UnordPWMDInter() : pieces_() {} +UnordPWMDInter::UnordPWMDInter(Util::MD_NAT x) : pieces_() { + pieces_.insert(SetPiece(x)); +} UnordPWMDInter::UnordPWMDInter(Interval i) : pieces_() { if (!i.isEmpty()) pieces_.insert(SetPiece(i)); } -UnordPWMDInter::UnordPWMDInter(SetPiece mdi) : pieces_() -{ +UnordPWMDInter::UnordPWMDInter(SetPiece mdi) : pieces_(){ if (!mdi.isEmpty()) pieces_.emplace_hint(pieces_.end(), mdi); } diff --git a/sbg/unord_pw_mdinter.hpp b/sbg/unord_pw_mdinter.hpp index 6a4906b..5c59e2c 100755 --- a/sbg/unord_pw_mdinter.hpp +++ b/sbg/unord_pw_mdinter.hpp @@ -50,6 +50,7 @@ struct UnordPWMDInter { member_class(MDInterUnordSet, pieces); UnordPWMDInter(); + UnordPWMDInter(Util::MD_NAT x); UnordPWMDInter(Interval i); UnordPWMDInter(SetPiece mdi); UnordPWMDInter(MDInterUnordSet c); diff --git a/test/rl33_scc.test b/test/rl33_scc.test new file mode 100644 index 0000000..de8004c --- /dev/null +++ b/test/rl33_scc.test @@ -0,0 +1,87 @@ +/* +model testRL3 + //iR[i] and iR[i+1] can be computed out of each other + //uL[i] and uL[i+1] can be computed out of each other + //All variables form a large algebraic loop + + constant Integer N=5; + Real iL[N],iR[N],uL[N]; + parameter Real L=1,R=1,L1=1,U=1,R0=1; +equation + for i in 1:N loop + L*der(iL[i])=uL[i]; // der(iL[1:N]) + end for; + for i in 1:N-1 loop + iR[i]-iR[i+1]-iL[i]=0; // iR[2:N] + uL[i]-uL[i+1]-R*iR[i+1]=0; // uL[1:N-1] + end for; + U-uL[1]-R*iR[1]=0; // iR[1] + uL[N]-(iR[N]-iL[N])*R0=0; // uL[N] +end testRL3; +*/ + +N = 100000 + +V1 = N +V2 = N-1+V1 +V3 = N-1+V2 +V4 = 1+V3 +V5 = 1+V4 + +E1 = N-1 // V1 - V3 +E2 = 1+E1 // V1 - V5 +E3 = N-2+E2 // V2 - V2 +E4 = 1+E3 // V2 - V4 +E5 = N-1+E4 // V3 - V2 +E6 = N-2+E5 // V3 - V3 +E7 = 1+E6 // V3 - V5 +E8 = 1+E7 // V4 - V3 +E9 = 1+E8 // V5 - V2 + +off1d = r(V3, 1)-r(E1, 1) +off2d = r(V5, 1)-r(E2, 1) +off3d = r(V2, 1)-r(E3, 1)-1 +off4d = r(V4, 1)-r(E4, 1) +off5d = r(V2, 1)-r(E5, 1) +off6d = r(V3, 1)-r(E6, 1) +off7d = r(V5, 1)-r(E7, 1) +off8d = r(V3, 1)-r(E8, 1)-N+2 +off9d = r(V2, 1)-r(E9, 1) + +off1b = r(V1, 1)-r(E1, 1)-1 +off2b = r(V1, 1)-r(E2, 1) +off3b = r(V2, 1)-r(E3, 1) +off4b = r(V2, 1)-r(E4, 1)-N+2 +off5b = r(V3, 1)-r(E5, 1) +off6b = r(V3, 1)-r(E6, 1)-1 +off7b = r(V3, 1)-r(E7, 1) +off8b = r(V4, 1)-r(E8, 1) +off9b = r(V5, 1)-r(E9, 1) + +V %= {[1:1:V1], [V1+1:1:V2], [V2+1:1:V3], [V3+1:1:V4], [V4+1:1:V5]}; +Vmap %= <<{[1:1:V1]} -> 0*x+1, {[V1+1:1:V2]} -> 0*x+2, {[V2+1:1:V3]} -> 0*x+3 + , {[V3+1:1:V4]} -> 0*x+4, {[V4+1:1:V5]} -> 0*x+5>>; +mapB %= <<{[1:1:E1]} -> 1*x+off1b, {[E1+1:1:E2]} -> 1*x+off2b, {[E2+1:1:E3]} -> 1*x+off3b + , {[E3+1:1:E4]} -> 1*x+off4b, {[E4+1:1:E5]} -> 1*x+off5b, {[E5+1:1:E6]} -> 1*x+off6b + , {[E6+1:1:E7]} -> 1*x+off7b, {[E7+1:1:E8]} -> 1*x+off8b, {[E8+1:1:E9]} -> 1*x+off9b>>; +mapD %= <<{[1:1:E1]} -> 1*x+off1d, {[E1+1:1:E2]} -> 1*x+off2d, {[E2+1:1:E3]} -> 1*x+off3d + , {[E3+1:1:E4]} -> 1*x+off4d, {[E4+1:1:E5]} -> 1*x+off5d, {[E5+1:1:E6]} -> 1*x+off6d + , {[E6+1:1:E7]} -> 1*x+off7d, {[E7+1:1:E8]} -> 1*x+off8d, {[E8+1:1:E9]} -> 1*x+off9d>>; +Emap %= <<{[1:1:E1]} -> 0*x+1, {[E1+1:1:E2]} -> 0*x+2, {[E2+1:1:E3]} -> 0*x+3 + , {[E3+1:1:E4]} -> 0*x+4, {[E4+1:1:E5]} -> 0*x+5, {[E5+1:1:E6]} -> 0*x+6 + , {[E6+1:1:E7]} -> 0*x+7, {[E7+1:1:E8]} -> 0*x+8, {[E8+1:1:E9]} -> 0*x+9>>; + +scc( +V %= {[1:1:V1], [V1+1:1:V2], [V2+1:1:V3], [V3+1:1:V4], [V4+1:1:V5]}; +Vmap %= <<{[1:1:V1]} -> 0*x+1, {[V1+1:1:V2]} -> 0*x+2, {[V2+1:1:V3]} -> 0*x+3 + , {[V3+1:1:V4]} -> 0*x+4, {[V4+1:1:V5]} -> 0*x+5>>; +mapB %= <<{[1:1:E1]} -> 1*x+off1b, {[E1+1:1:E2]} -> 1*x+off2b, {[E2+1:1:E3]} -> 1*x+off3b + , {[E3+1:1:E4]} -> 1*x+off4b, {[E4+1:1:E5]} -> 1*x+off5b, {[E5+1:1:E6]} -> 1*x+off6b + , {[E6+1:1:E7]} -> 1*x+off7b, {[E7+1:1:E8]} -> 1*x+off8b, {[E8+1:1:E9]} -> 1*x+off9b>>; +mapD %= <<{[1:1:E1]} -> 1*x+off1d, {[E1+1:1:E2]} -> 1*x+off2d, {[E2+1:1:E3]} -> 1*x+off3d + , {[E3+1:1:E4]} -> 1*x+off4d, {[E4+1:1:E5]} -> 1*x+off5d, {[E5+1:1:E6]} -> 1*x+off6d + , {[E6+1:1:E7]} -> 1*x+off7d, {[E7+1:1:E8]} -> 1*x+off8d, {[E8+1:1:E9]} -> 1*x+off9d>>; +Emap %= <<{[1:1:E1]} -> 0*x+1, {[E1+1:1:E2]} -> 0*x+2, {[E2+1:1:E3]} -> 0*x+3 + , {[E3+1:1:E4]} -> 0*x+4, {[E4+1:1:E5]} -> 0*x+5, {[E5+1:1:E6]} -> 0*x+6 + , {[E6+1:1:E7]} -> 0*x+7, {[E7+1:1:E8]} -> 0*x+8, {[E8+1:1:E9]} -> 0*x+9>>; +) diff --git a/test/topsort1.test b/test/topsort1.test index 03ebf99..fbc7578 100644 --- a/test/topsort1.test +++ b/test/topsort1.test @@ -16,14 +16,16 @@ off2d = N-1 off3d = 1 V %= {[1:1:V1], [V1+1:1:V2], [V2+1:1:V3]}; -Vmap %= <<{[1:1:V1]} -> 0*x+1, {[V1+1:1:V2]} -> 0*x+2, {[V2+1:1:V3]} -> 0*x+3>>; +Vmap %= <<{[1:1:V1]} -> 0*x+1, {[V1+1:1:V2]} -> 0*x+2, {[V2+1:1:V3-1]} -> 0*x+3 + , {[V3:1:V3]} -> 0*x+4>>; mapB %= <<{[1:1:E1]} -> 1*x+0, {[E1+1:1:E2]} -> 1*x+off2d, {[E2+1:1:E3]} -> 1*x-off3b>>; mapD %= <<{[1:1:E1]} -> 1*x+off1d, {[E1+1:1:E2]} -> 1*x+0, {[E2+1:1:E3]} -> 1*x+off3d>>; Emap %= <<{[1:1:E1]} -> 0*x+1, {[E1+1:1:E2], [E2+1:1:E3]} -> 0*x+2>>; sort( V %= {[1:1:V1], [V1+1:1:V2], [V2+1:1:V3]}; - Vmap %= <<{[1:1:V1]} -> 0*x+1, {[V1+1:1:V2]} -> 0*x+2, {[V2+1:1:V3]} -> 0*x+3>>; + Vmap %= <<{[1:1:V1]} -> 0*x+1, {[V1+1:1:V2]} -> 0*x+2, {[V2+1:1:V3-1]} -> 0*x+3 + , {[V3:1:V3]} -> 0*x+4>>; mapB %= <<{[1:1:E1]} -> 1*x+0, {[E1+1:1:E2]} -> 1*x+off2d, {[E2+1:1:E3]} -> 1*x-off3b>>; mapD %= <<{[1:1:E1]} -> 1*x+off1d, {[E1+1:1:E2]} -> 1*x+0, {[E2+1:1:E3]} -> 1*x+off3d>>; Emap %= <<{[1:1:E1]} -> 0*x+1, {[E1+1:1:E2], [E2+1:1:E3]} -> 0*x+2>>;