From 5143cde0aa40b751680d447bc3b0c52f1cebc9ee Mon Sep 17 00:00:00 2001 From: vhavlena Date: Fri, 29 Sep 2023 16:33:52 +0200 Subject: [PATCH] concat: fix when this == aut --- src/nfa/concatenation.cc | 13 +++++++++---- tests/nfa/nfa-concatenation.cc | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/nfa/concatenation.cc b/src/nfa/concatenation.cc index 31d2ae772..f522994e1 100644 --- a/src/nfa/concatenation.cc +++ b/src/nfa/concatenation.cc @@ -32,21 +32,26 @@ Nfa& Nfa::concatenate(const Nfa& aut) { return st + n; }; + // copy the information about aut to save the case when this is the same object as aut. + utils::SparseSet aut_initial = aut.initial; + utils::SparseSet aut_final = aut.final; + size_t aut_n = aut.num_of_states(); + this->delta.allocate(n); this->delta.append(aut.delta.renumber_targets(upd_fnc)); // set accepting states utils::SparseSet new_fin{}; - new_fin.reserve(n+aut.num_of_states()); - for(const State& aut_fin : aut.final) { + new_fin.reserve(n+aut_n); + for(const State& aut_fin : aut_final) { new_fin.insert(upd_fnc(aut_fin)); } // connect both parts - for(const State& ini : aut.initial) { + for(const State& ini : aut_initial) { const StatePost& ini_post = this->delta[upd_fnc(ini)]; // is ini state also final? - bool is_final = aut.final[ini]; + bool is_final = aut_final[ini]; for(const State& fin : this->final) { if(is_final) { new_fin.insert(fin); diff --git a/tests/nfa/nfa-concatenation.cc b/tests/nfa/nfa-concatenation.cc index 8bc8f831f..9e1f72ee6 100644 --- a/tests/nfa/nfa-concatenation.cc +++ b/tests/nfa/nfa-concatenation.cc @@ -730,6 +730,24 @@ TEST_CASE("mata::nfa::concatenate() inplace") { CHECK(!result.is_lang_empty()); } + SECTION("the same automata") { + Nfa lhs{}; + + lhs.add_state(); + lhs.initial.insert(0); + lhs.final.insert(0); + lhs.delta.add(0, 58, 0); + lhs.delta.add(0, 65, 0); + lhs.delta.add(0, 102, 0); + lhs.delta.add(0, 112, 0); + lhs.delta.add(0, 115, 0); + lhs.delta.add(0, 116, 0); + + size_t lhs_size = lhs.num_of_states(); + Nfa result = lhs.concatenate(lhs); + CHECK(result.num_of_states() == lhs_size * 2); + } + } TEST_CASE("Concat_inplace performance", "[.profiling]") {