From 5b09086b825e6b221bd193079187021dcc8a2571 Mon Sep 17 00:00:00 2001 From: Christoph Schwering Date: Fri, 26 May 2017 18:21:11 +1000 Subject: [PATCH] Replaced Grounder::SortedTermMap with generic internal::MultiIntSet. The naming of the classes in intmap.h is suboptimal. --- src/limbo/grounder.h | 52 ++---------- src/limbo/internal/intmap.h | 160 +++++++++++++++++++++++++++++------- src/limbo/internal/iter.h | 18 ++-- tests/grounder.cc | 2 +- tests/intmap.cc | 4 +- tests/iter.cc | 36 ++++---- 6 files changed, 164 insertions(+), 108 deletions(-) diff --git a/src/limbo/grounder.h b/src/limbo/grounder.h index b331bd8..5c4b822 100644 --- a/src/limbo/grounder.h +++ b/src/limbo/grounder.h @@ -76,44 +76,8 @@ class Grounder { typedef std::unordered_set LiteralAssignmentSet; - class SortedTermSet : public internal::IntMap { - public: - typedef TermSet::value_type value_type; - - using internal::IntMap::IntMap; - - size_t insert(Term t) { - auto p = (*this)[t.sort()].insert(t); - return p.second ? 1 : 0; - } - - void erase(Term t) { - (*this)[t.sort()].erase(t); - } - - size_t insert(const TermSet& terms) { - size_t n = 0; - for (Term t : terms) { - n += insert(t); - } - return n; - } - - size_t insert(const SortedTermSet& terms) { - size_t n = 0; - for (const TermSet& set : terms.values()) { - for (Term t : set) { - n += insert(t); - } - } - return n; - } - - bool contains(Term t) const { - const TermSet& ts = (*this)[t.sort()]; - return ts.find(t) != ts.end(); - } - }; + struct GetSort { Symbol::Sort operator()(Term t) const { return t.sort(); } }; + typedef internal::MultiIntSet SortedTermSet; Grounder(Symbol::Factory* sf, Term::Factory* tf) : sf_(sf), tf_(tf) {} Grounder(const Grounder&) = delete; @@ -303,12 +267,12 @@ class Grounder { class Assignments { public: struct GetRange { - GetRange(const SortedTermSet& substitutes) : substitutes_(substitutes) {} - std::pair> operator()(const Term x) const { - return std::make_pair(x, std::make_pair(substitutes_[x.sort()].begin(), substitutes_[x.sort()].end())); + GetRange(const SortedTermSet* substitutes) : substitutes_(substitutes) {} + std::pair operator()(const Term x) const { + return std::make_pair(x, substitutes_->values(x)); } private: - const SortedTermSet& substitutes_; + const SortedTermSet* substitutes_; }; typedef internal::transform_iterator domain_codomain_iterator; typedef internal::mapping_iterator mapping_iterator; @@ -316,8 +280,8 @@ class Grounder { Assignments(const TermSet& vars, const SortedTermSet* substitutes) : vars_(vars), substitutes_(substitutes) {} mapping_iterator begin() const { - return mapping_iterator(domain_codomain_iterator(vars_.begin(), GetRange(*substitutes_)), - domain_codomain_iterator(vars_.end(), GetRange(*substitutes_))); + return mapping_iterator(domain_codomain_iterator(vars_.begin(), GetRange(substitutes_)), + domain_codomain_iterator(vars_.end(), GetRange(substitutes_))); } mapping_iterator end() const { return mapping_iterator(); } diff --git a/src/limbo/internal/intmap.h b/src/limbo/internal/intmap.h index be088db..957d9d9 100644 --- a/src/limbo/internal/intmap.h +++ b/src/limbo/internal/intmap.h @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include @@ -23,35 +25,34 @@ namespace limbo { namespace internal { template -class IntMap : public std::vector { +class IntMap { public: - typedef std::vector parent; - typedef T value_type; - - using std::vector::vector; + typedef std::vector Vec; + typedef typename Vec::value_type value_type; + typedef typename Vec::reference reference; + typedef typename Vec::const_reference const_reference; void set_null_value(const T& null) { null_ = null; } - typename parent::reference operator[](Key pos) { - typename parent::size_type pos_int = static_cast(pos); - if (pos_int >= parent::size()) { - parent::resize(pos_int + 1, null_); + reference operator[](Key key) { + typename Vec::size_type key_int = static_cast(key); + if (key_int >= n_keys()) { + vec_.resize(key_int + 1, null_); } - return parent::operator[](pos_int); + return vec_[key_int]; } - typename parent::const_reference operator[](Key pos) const { - return const_cast(this)->operator[](pos); + typename Vec::const_reference operator[](Key key) const { + return const_cast(*this)[key]; } + size_t n_keys() const { return vec_.size(); } + struct Keys { typedef internal::int_iterator iterator; - explicit Keys(const IntMap* owner) : owner(owner) {} - iterator begin() const { return iterator(0); } - iterator end() const { return iterator(static_cast(owner->size())); } - + iterator end() const { return iterator(static_cast(owner->n_keys())); } private: const IntMap* owner; }; @@ -60,33 +61,27 @@ class IntMap : public std::vector { struct Values { explicit Values(IntMap* owner) : owner(owner) {} - - typename parent::iterator begin() const { return owner->parent::begin(); } - typename parent::iterator end() const { return owner->parent::end(); } - + typename Vec::iterator begin() const { return owner->vec_.begin(); } + typename Vec::iterator end() const { return owner->vec_.end(); } private: IntMap* owner; }; - Values values() { return Values(this); } - struct ConstValues { explicit ConstValues(const IntMap* owner) : owner(owner) {} - - typename parent::const_iterator begin() const { return owner->parent::begin(); } - typename parent::const_iterator end() const { return owner->parent::end(); } - + typename Vec::const_iterator begin() const { return owner->vec_.begin(); } + typename Vec::const_iterator end() const { return owner->vec_.end(); } private: const IntMap* owner; }; - ConstValues cvalues() const { return ConstValues(this); } - ConstValues values() const { return cvalues(); } + Values values() { return Values(this); } + ConstValues values() const { return ConstValues(this); } template static IntMap Zip(const IntMap& m1, const IntMap& m2, BinaryFunction f) { IntMap m; - size_t s = std::max(m1.size(), m2.size()); + size_t s = std::max(m1.n_keys(), m2.n_keys()); for (size_t i = 0; i < s; ++i) { m[i] = f(m1[i], m2[i]); } @@ -95,14 +90,117 @@ class IntMap : public std::vector { template void Zip(const IntMap& m, BinaryFunction f) { - size_t s = std::max(parent::size(), m.size()); + size_t s = std::max(n_keys(), m.n_keys()); for (size_t i = 0; i < s; ++i) { - (*this)[i] = f((*this)[i], m[i]); + vec_[i] = f(vec_[i], m[i]); } } protected: T null_ = T(); + Vec vec_; +}; + +template +class MultiIntMap { + public: + typedef IntMap> Base; + typedef T value_type; + + typename Base::reference operator[](Key key) { return map_[key]; } + typename Base::const_reference operator[](Key key) const { return map_[key]; } + + size_t insert(Key key, const T& val) { + auto p = map_[key].insert(val); + return p.second ? 1 : 0; + } + + void erase(Key key, const T& val) { + map_[key].erase(val); + } + + bool contains(Key key, const T& val) const { + const value_type& s = map_[key]; + return s.find(val) != s.end(); + } + + size_t n_keys() const { return map_.n_keys(); } + + typedef typename Base::Keys Keys; + + Keys keys() const { return Keys(&map_); } + + struct PosValues { + explicit PosValues(const MultiIntMap* owner, Key key) : owner(owner), key(key) {} + typename Base::value_type::const_iterator begin() const { return owner->map_[key].begin(); } + typename Base::value_type::const_iterator end() const { return owner->map_[key].end(); } + private: + const MultiIntMap* owner; + Key key; + }; + + PosValues values(Key key) const { return PosValues(this, key); } + + struct Values { + typedef flatten_iterator iterator; + explicit Values(MultiIntMap* owner) : owner(owner) {} + iterator begin() const { return owner->map_.values().begin(); } + iterator end() const { return owner->map_.values().end(); } + private: + MultiIntMap* owner; + }; + + Values values() const { return Values(this); } + + private: + Base map_; +}; + +template::type> +class MultiIntSet { + public: + typedef MultiIntMap Parent; + typedef typename Parent::Base Base; + typedef T value_type; + + explicit MultiIntSet(UnaryFunction key = UnaryFunction()) : key_(key) {} + + typename Base::reference operator[](Key key) { return map_[key]; } + typename Base::const_reference operator[](Key key) const { return map_[key]; } + + size_t insert(const T& val) { return map_.insert(key_(val), val); } + + void erase(const T& val) { map_.erase(key_(val), val); } + + template + size_t insert(const Collection& vals) { map_.insert(vals); } + + size_t insert(const MultiIntSet& set) { + size_t n = 0; + for (Key key : set.keys()) { + for (const T& val : set.values(key)) { + n += insert(val); + } + } + return n; + } + + bool contains(const T& val) const { return map_.contains(key_(val)); } + + size_t n_keys() const { return map_.n_keys(); } + + typedef typename Parent::Keys Keys; + typedef typename Parent::PosValues PosValues; + typedef typename Parent::Values Values; + + Keys keys() const { return map_.keys(); } + PosValues values(Key key) const { return map_.values(key); } + PosValues values(const T& val) const { return values(key_(val)); } + Values values() const { return map_.values(); } + + private: + UnaryFunction key_; + Parent map_; }; } // namespace internal diff --git a/src/limbo/internal/iter.h b/src/limbo/internal/iter.h index 7f154b3..d7ae814 100644 --- a/src/limbo/internal/iter.h +++ b/src/limbo/internal/iter.h @@ -365,18 +365,18 @@ filter_range(Range r, UnaryPredicate pred) { } template -struct mapping_iterator { +class mapping_iterator { public: typedef DomainType domain_type; typedef CodomainInputIt codomain_iterator; typedef typename CodomainInputIt::value_type codomain_type; struct value_type { - value_type(const mapping_iterator& owner) : owner_(owner) {} + value_type(const mapping_iterator* owner) : owner(owner) {} internal::Maybe operator()(domain_type x) const { - auto it = owner_.dcd_.find(x); - if (it != owner_.dcd_.end()) { + auto it = owner->dcd_.find(x); + if (it != owner->dcd_.end()) { auto& cd = it->second; assert(cd.current != cd.end); const codomain_type y = *cd.current; @@ -386,11 +386,11 @@ struct mapping_iterator { } } - bool operator==(const value_type& a) const { return owner_ == a.owner_; } + bool operator==(const value_type& a) const { return *owner == *a->owner; } bool operator!=(const value_type& a) const { return !(*this == a); } private: - const mapping_iterator& owner_; + const mapping_iterator* owner; }; typedef std::ptrdiff_t difference_type; @@ -407,8 +407,8 @@ struct mapping_iterator { explicit mapping_iterator(InputIt begin, InputIt end) { for (; begin != end; ++begin) { domain_type x = begin->first; - codomain_iterator y1 = begin->second.first; - codomain_iterator y2 = begin->second.second; + codomain_iterator y1 = begin->second.begin(); + codomain_iterator y2 = begin->second.end(); dcd_.insert(std::make_pair(x, CodomainState(y1, y2))); } iter_ = Just(dcd_.end()); @@ -420,7 +420,7 @@ struct mapping_iterator { bool operator==(const mapping_iterator& it) const { return iter_ == it.iter_ && (!iter_ || dcd_ == it.dcd_); } bool operator!=(const mapping_iterator& it) const { return !(*this == it); } - value_type operator*() const { return value_type(*this); } + value_type operator*() const { return value_type(this); } mapping_iterator& operator++() { for (iter_ = Just(dcd_.begin()); iter_.val != dcd_.end(); ++iter_.val) { diff --git a/tests/grounder.cc b/tests/grounder.cc index 0f572b9..dbba832 100644 --- a/tests/grounder.cc +++ b/tests/grounder.cc @@ -230,7 +230,7 @@ TEST(GrounderTest, Ground_SplitTerms_Names) { //std::cout << terms << std::endl; EXPECT_NE(x3.sort(), n1.sort()); EXPECT_NE(x3.sort(), a.sort()); - EXPECT_EQ(names.size(), 2); + EXPECT_EQ(names.n_keys(), 2); EXPECT_EQ(n1.symbol().sort(), a.sort()); EXPECT_EQ(x3.symbol().sort(), g.sort()); EXPECT_EQ(x3.symbol().sort(), h.sort()); diff --git a/tests/intmap.cc b/tests/intmap.cc index 9b0e448..7939da5 100644 --- a/tests/intmap.cc +++ b/tests/intmap.cc @@ -20,7 +20,7 @@ TEST(IntMapTest, general) { EXPECT_EQ(map[2], "two"); EXPECT_EQ(length(map.keys()), 3); EXPECT_EQ(length(map.values()), 3); - EXPECT_EQ(map.size(), 3); + EXPECT_EQ(map.n_keys(), 3); const IntMap map2 = map; EXPECT_EQ(length(map2.keys()), 3); @@ -42,7 +42,7 @@ TEST(IntMapTest, general) { map[4] = "four"; EXPECT_EQ(length(map.keys()), 5); EXPECT_EQ(length(map.values()), 5); - EXPECT_EQ(map.size(), 5); + EXPECT_EQ(map.n_keys(), 5); EXPECT_EQ(map[0], "zero"); EXPECT_EQ(map[1], "one"); EXPECT_EQ(map[2], "two"); diff --git a/tests/iter.cc b/tests/iter.cc index f02a241..87d3835 100644 --- a/tests/iter.cc +++ b/tests/iter.cc @@ -153,7 +153,7 @@ TEST(IterTest, filter_range) { TEST(IterTest, maping_iterator) { { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; map domain_codomain{}; auto begin = iterator(domain_codomain.cbegin(), domain_codomain.cend()); @@ -164,11 +164,10 @@ TEST(IterTest, maping_iterator) { } { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; - vec one{11}; map domain_codomain{ - {1, {one.begin(), one.end()}} + {1, {11}}, }; auto begin = iterator(domain_codomain.cbegin(), domain_codomain.cend()); auto end = iterator(); @@ -181,13 +180,13 @@ TEST(IterTest, maping_iterator) { EXPECT_EQ(begin, end); } { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; vec one{11}; vec two{22}; map domain_codomain{ - {1, {one.begin(), one.end()}}, - {2, {two.begin(), two.end()}} + {1, {11}}, + {2, {22}}, }; auto begin = iterator(domain_codomain.cbegin(), domain_codomain.cend()); auto end = iterator(); @@ -201,7 +200,7 @@ TEST(IterTest, maping_iterator) { } { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; vec one{11}; vec two{22, 23}; @@ -225,7 +224,7 @@ TEST(IterTest, maping_iterator) { } { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; vec one{11, 12}; vec two{22}; @@ -249,13 +248,11 @@ TEST(IterTest, maping_iterator) { } { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; - vec one{11, 12}; - vec two{22, 23}; map domain_codomain{ - {1, {one.begin(), one.end()}}, - {2, {two.begin(), two.end()}} + {1, {11, 12}}, + {2, {22, 23}}, }; auto begin = iterator(domain_codomain.cbegin(), domain_codomain.cend()); auto end = iterator(); @@ -281,15 +278,12 @@ TEST(IterTest, maping_iterator) { } { typedef std::vector vec; - typedef std::map> map; + typedef std::map map; typedef mapping_iterator iterator; - vec one{11, 12}; - vec two{22, 23}; - vec three{33, 34}; map domain_codomain{ - {1, {one.begin(), one.end()}}, - {2, {two.begin(), two.end()}}, - {3, {three.begin(), three.end()}} + {1, {11, 12}}, + {2, {22, 23}}, + {3, {33, 34}}, }; auto begin = iterator(domain_codomain.cbegin(), domain_codomain.cend()); auto end = iterator(); -- GitLab