diff --git a/include/libsemigroups/knuth-bendix.hpp b/include/libsemigroups/knuth-bendix.hpp index 629e864ff..57b3745c7 100644 --- a/include/libsemigroups/knuth-bendix.hpp +++ b/include/libsemigroups/knuth-bendix.hpp @@ -194,16 +194,9 @@ namespace libsemigroups { Stats& operator=(Stats const&) noexcept = default; Stats& operator=(Stats&&) noexcept = default; - size_t max_stack_depth; - size_t max_word_length; - size_t max_active_word_length; - size_t max_active_rules; - size_t min_length_lhs_rule; - size_t prev_active_rules; - size_t prev_inactive_rules; - size_t prev_total_rules; - size_t total_rules; - std::unordered_set unique_lhs_rules; + size_t prev_active_rules; + size_t prev_inactive_rules; + size_t prev_total_rules; } _stats; //////////////////////////////////////////////////////////////////////// @@ -699,6 +692,7 @@ namespace libsemigroups { [[nodiscard]] size_t total_rules() const noexcept { return _rewriter.stats().total_rules; } + // TODO What do we do about doc-ing this? using rule_type = std::pair; // TODO update the doc, now returns a Range @@ -954,7 +948,9 @@ namespace libsemigroups { void overlap(Rule const* u, Rule const* v); - [[nodiscard]] size_t max_active_word_length() const; + [[nodiscard]] size_t max_active_word_length() const { + return _rewriter.max_active_word_length(); + } ////////////////////////////////////////////////////////////////////////// // Runner - pure virtual member functions - private diff --git a/include/libsemigroups/knuth-bendix.tpp b/include/libsemigroups/knuth-bendix.tpp index ed53a692c..f19b5c049 100644 --- a/include/libsemigroups/knuth-bendix.tpp +++ b/include/libsemigroups/knuth-bendix.tpp @@ -108,18 +108,9 @@ namespace libsemigroups { template typename KnuthBendix::Stats& KnuthBendix::Stats::init() noexcept { - max_stack_depth = 0; - max_word_length = 0; - max_active_word_length = 0; - max_active_rules = 0; - - min_length_lhs_rule = std::numeric_limits::max(); - prev_active_rules = 0; prev_inactive_rules = 0; prev_total_rules = 0; - total_rules = 0; - unique_lhs_rules.clear(); return *this; } @@ -214,9 +205,7 @@ namespace libsemigroups { _settings = that._settings; _gilman_graph = that._gilman_graph; _internal_is_same_as_external = that._internal_is_same_as_external; - _stats.min_length_lhs_rule = that._stats.min_length_lhs_rule; _presentation = that._presentation; - _stats.total_rules = that._stats.total_rules; overlap_policy(_settings.overlap_policy); @@ -429,14 +418,14 @@ namespace libsemigroups { // rc.divider(); // FIXME these are mostly 0, and should be obtained from the rewriter // probably - rc("KnuthBendix: max stack depth {}\n", - group_digits(_stats.max_stack_depth)); + // rc("KnuthBendix: max stack depth {}\n", + // group_digits(_rewriter.stats().max_stack_depth)); rc("KnuthBendix: max rule length {}\n", - group_digits(_stats.max_word_length)); + group_digits(_rewriter.stats().max_word_length)); rc("KnuthBendix: max active rule length {}\n", group_digits(max_active_word_length())); - rc("KnuthBendix: number of unique lhs {}\n", - group_digits(_stats.unique_lhs_rules.size())); + // rc("KnuthBendix: number of unique lhs {}\n", + // group_digits(_stats.unique_lhs_rules.size())); } report_no_prefix("{:-<95}\n", ""); @@ -600,7 +589,7 @@ namespace libsemigroups { // this seems to worsen performance on the test cases, so it remains // to see what the best option is for default behaviour. // TODO should we process rules here too? - _rewriter.process_pending_rules(); + // _rewriter.process_pending_rules(); if (confluent()) { pause = false; goto confluence_achieved; @@ -955,19 +944,6 @@ namespace libsemigroups { } } - template - size_t KnuthBendix::max_active_word_length() const { - auto comp = [](Rule const* p, Rule const* q) -> bool { - return p->lhs()->size() < q->lhs()->size(); - }; - auto max = std::max_element(_rewriter.begin(), _rewriter.end(), comp); - if (max != _rewriter.end()) { - _stats.max_active_word_length - = std::max(_stats.max_active_word_length, (*max)->lhs()->size()); - } - return _stats.max_active_word_length; - } - namespace knuth_bendix { // We are computing non_trivial_classes with respect to kb2 (the greater // congruence, with fewer classes) diff --git a/include/libsemigroups/rewriters.hpp b/include/libsemigroups/rewriters.hpp index 31bef0776..a4ff5df5a 100644 --- a/include/libsemigroups/rewriters.hpp +++ b/include/libsemigroups/rewriters.hpp @@ -157,11 +157,10 @@ namespace libsemigroups { Stats& operator=(Stats const&) noexcept = default; Stats& operator=(Stats&&) noexcept = default; - // TODO remove duplication with KnuthBendix::Stats - // size_t max_stack_depth; - // size_t max_word_length; - // size_t max_active_word_length; - // size_t max_active_rules; + // size_t max_stack_depth; // TODO Move to RewriterBase + size_t max_word_length; + size_t max_active_word_length; + size_t max_active_rules; size_t min_length_lhs_rule; uint64_t total_rules; // std::unordered_set unique_lhs_rules; @@ -171,7 +170,7 @@ namespace libsemigroups { std::list _active_rules; std::array _cursors; std::list _inactive_rules; - Stats _stats; + mutable Stats _stats; // REVIEW is this allowed to be mutable? public: Rules() = default; @@ -218,6 +217,8 @@ namespace libsemigroups { return _inactive_rules.size(); } + [[nodiscard]] size_t max_active_word_length() const; + iterator& cursor(size_t index) { LIBSEMIGROUPS_ASSERT(index < _cursors.size()); return _cursors[index]; diff --git a/src/rewriters.cpp b/src/rewriters.cpp index 2d14ee49c..9a65ab853 100644 --- a/src/rewriters.cpp +++ b/src/rewriters.cpp @@ -61,12 +61,12 @@ namespace libsemigroups { } Rules::Stats& Rules::Stats::init() noexcept { - // max_stack_depth = 0; - // max_word_length = 0; - // max_active_word_length = 0; - // max_active_rules = 0; - min_length_lhs_rule = std::numeric_limits::max(); - total_rules = 0; + // max_stack_depth = 0; //TODO Move to RewriterBase + max_word_length = 0; + max_active_word_length = 0; + max_active_rules = 0; + min_length_lhs_rule = std::numeric_limits::max(); + total_rules = 0; return *this; } @@ -153,10 +153,10 @@ namespace libsemigroups { void Rules::add_rule(Rule* rule) { LIBSEMIGROUPS_ASSERT(*rule->lhs() != *rule->rhs()); - // _stats.max_word_length - // = std::max(_stats.max_word_length, rule->lhs()->size()); - // _stats.max_active_rules - // = std::max(_stats.max_active_rules, number_of_active_rules()); + _stats.max_word_length + = std::max(_stats.max_word_length, rule->lhs()->size()); + _stats.max_active_rules + = std::max(_stats.max_active_rules, number_of_active_rules()); // _stats.unique_lhs_rules.insert(*rule->lhs()); rule->activate(); _active_rules.push_back(rule); @@ -171,6 +171,19 @@ namespace libsemigroups { _stats.min_length_lhs_rule = rule->lhs()->size(); } } + + size_t Rules::max_active_word_length() const { + auto comp = [](Rule const* p, Rule const* q) -> bool { + return p->lhs()->size() < q->lhs()->size(); + }; + auto max = std::max_element(begin(), end(), comp); + if (max != end()) { + _stats.max_active_word_length + = std::max(_stats.max_active_word_length, (*max)->lhs()->size()); + } + return _stats.max_active_word_length; + } + RewriterBase& RewriterBase::init() { Rules::init(); if (_requires_alphabet) { @@ -223,8 +236,8 @@ namespace libsemigroups { Rule* rule1; internal_string_type const* lhs; while (number_of_pending_rules() != 0) { - // _stats.max_stack_depth = std::max(_stats.max_stack_depth, - // _pending_rules.size()); + // stats().max_stack_depth + // = std::max(stats().max_stack_depth, _pending_rules.size()); rule1 = next_pending_rule(); LIBSEMIGROUPS_ASSERT(!rule1->active());