diff --git a/include/mata/nfa/nfa.hh b/include/mata/nfa/nfa.hh index e9aa8aefa..e3cabb2b1 100644 --- a/include/mata/nfa/nfa.hh +++ b/include/mata/nfa/nfa.hh @@ -104,14 +104,25 @@ public: State add_state(State state); /** - * Inserts a @p word into the NFA from a source state @p src to a target state @p tgt. + * Inserts a @p word into the NFA from a source state @p source to a target state @p target. * Creates new states along the path of the @p word. * - * @param src The source state where the word begins. It must already be a part of the automaton. + * @param source The source state where the word begins. It must already be a part of the automaton. * @param word The nonempty word to be inserted into the NFA. - * @param tgt The target state where the word ends. It must already be a part of the automaton. + * @param target The target state where the word ends. + * @return The state @p target where the inserted @p word ends. */ - void insert_word(const State src, const Word &word, const State tgt); + State insert_word(State source, const Word& word, State target); + + /** + * Inserts a @p word into the NFA from a source state @p source to a new target state. + * Creates new states along the path of the @p word. + * + * @param source The source state where the word begins. It must already be a part of the automaton. + * @param word The nonempty word to be inserted into the NFA. + * @return The newly created target state where the inserted @p word ends. + */ + State insert_word(State source, const Word& word); /** * @brief Get the current number of states in the whole automaton. diff --git a/include/mata/nft/nft.hh b/include/mata/nft/nft.hh index 95fba48ce..d25e584bf 100644 --- a/include/mata/nft/nft.hh +++ b/include/mata/nft/nft.hh @@ -143,33 +143,71 @@ public: State add_state_with_level(State state, Level level); /** - * Inserts a @p word into the NFT from a source state @p src to a target state @p tgt. + * Inserts a @p word into the NFT from a source state @p source to a target state @p target. * Creates new states along the path of the @p word. * * If the length of @p word is less than @c num_of_levels, then the last symbol of @p word - * will form a transition going directly from the last inner state to @p tgt. The level - * of the state @p tgt must be 0 or greater than the level of the last inner state. + * will form a transition going directly from the last inner state to @p target. The level + * of the state @p target must be 0 or greater than the level of the last inner state. * - * @param src The source state where the word begins. It must already be a part of the transducer. + * @param source The source state where the word begins. It must already be a part of the transducer. * @param word The nonempty word to be inserted into the NFA. - * @param tgt The target state where the word ends. It must already be a part of the transducer. + * @param target The target state where the word ends. + * @return The state @p target where the inserted @p word ends. */ - void insert_word(const State src, const Word &word, const State tgt); + State insert_word(State source, const Word &word, State target); /** - * Inserts a word, which is created by interleaving parts from @p word_part_on_level, into the NFT - * from a source state @p src to a target state @p tgt, creating new states along its path. + * @brief Inserts a @p word into the NFT from a source state @p source to a newly created target state, creating + * new states along the path of the @p word. * - * The length of the inserted word equals @c num_of_levels * the maximum word length in the vector @p word_part_on_level. - * At least one Word in @p word_part_on_level must be nonempty. - * The vector @p word_part_on_level must have a size equal to @c num_of_levels. + * If the length of @p word is less than @c num_of_levels, then the last symbol of @p word + * will form a transition going directly from the last inner state to the newly created target. + * + * @param source The source state where the word begins. It must already be a part of the transducer. + * @param word The nonempty word to be inserted into the NFA. + * @return The newly created target where the inserted word ends. + */ + State insert_word(State source, const Word &word); + + /** + * @brief Inserts a word, which is created by interleaving parts from @p word_parts_on_levels, into the NFT + * from a source state @p source to a target state @p target, creating new states along the path of @p word. + * + * The length of the inserted word equals @c num_of_levels * the maximum word length in the vector @p word_parts_on_levels. + * At least one Word in @p word_parts_on_levels must be nonempty. + * The vector @p word_parts_on_levels must have a size equal to @c num_of_levels. + * Words shorter than the maximum word length are interpreted as words followed by a sequence of epsilons to match the maximum length. + * + * @param source The source state where the word begins. This state must already exist in the transducer and must be of a level 0. + * @param word_parts_on_levels The vector of word parts, with each part corresponding to a different level. + * @param target The target state where the word ends. + * @return The state @p target where the inserted @p word_parts_on_levels ends. + */ + State insert_word_by_parts(State source, const std::vector& word_parts_on_levels, State target); + + /** + * @brief Inserts a word, which is created by interleaving parts from @p word_parts_on_levels, into the NFT + * from a source state @p source to a target state @p target, creating new states along the path of @p word. + * + * The length of the inserted word equals @c num_of_levels * the maximum word length in the vector @p word_parts_on_levels. + * At least one Word in @p word_parts_on_levels must be nonempty. + * The vector @p word_parts_on_levels must have a size equal to @c num_of_levels. * Words shorter than the maximum word length are interpreted as words followed by a sequence of epsilons to match the maximum length. * - * @param src The source state where the word begins. This state must already exist in the transducer and must be of a level 0. - * @param word_part_on_level The vector of word parts, with each part corresponding to a different level. - * @param tgt The target state where the word ends. This state must already exist in the transducer and must be of a level 0. + * @param source The source state where the word begins. This state must already exist in the transducer and must be of a level 0. + * @param word_parts_on_levels The vector of word parts, with each part corresponding to a different level. + * @return The newly created target where the inserted @p word_parts_on_levels ends. */ - void insert_word_by_parts(const State src, const std::vector &word_part_on_level, const State tgt); + State insert_word_by_parts(State source, const std::vector& word_parts_on_levels); + + /** + * Inserts identity transitions into the NFT. + * + * @param state The state where the identity transition will be inserted. This serves as both the source and target state. + * @param symbol The vector of symbols used for the identity transition. Identity will be created for each symbol in the vector. + */ + void insert_identity(State state, const std::vector& symbols); /** * Inserts an identity transition into the NFT. diff --git a/src/nfa/nfa.cc b/src/nfa/nfa.cc index 40d5a5719..2e4956ef8 100644 --- a/src/nfa/nfa.cc +++ b/src/nfa/nfa.cc @@ -544,20 +544,21 @@ State Nfa::add_state(State state) { return state; } -void Nfa::insert_word(const State src, const Word &word, const State tgt) { +State Nfa::insert_word(const State source, const Word &word, const State target) { assert(!word.empty()); - assert(src < num_of_states()); - assert(tgt < num_of_states()); + const size_t num_of_states_orig{ num_of_states() }; + assert(source < num_of_states_orig); + assert(target < num_of_states_orig); const size_t word_len = word.size(); if (word_len == 1) { - delta.add(src, word[0], tgt); - return; + delta.add(source, word[0], target); + return target; } - // Add transition src --> inner_state. + // Add transition source --> inner_state. State inner_state = add_state(); - delta.add(src, word[0], inner_state); + delta.add(source, word[0], inner_state); // Add transitions inner_state --> inner_state State prev_state = inner_state; @@ -567,10 +568,13 @@ void Nfa::insert_word(const State src, const Word &word, const State tgt) { prev_state = inner_state; } - // Add transition inner_state --> tgt - delta.add(prev_state, word[word_len - 1], tgt); + // Add transition inner_state --> target + delta.add(prev_state, word[word_len - 1], target); + return target; } +State Nfa::insert_word(const State source, const Word &word) { return insert_word(source, word, add_state()); } + size_t Nfa::num_of_states() const { return std::max({ static_cast(initial.domain_size()), diff --git a/src/nft/nft.cc b/src/nft/nft.cc index 0200a8f5a..5e5eb5adc 100644 --- a/src/nft/nft.cc +++ b/src/nft/nft.cc @@ -305,42 +305,46 @@ State Nft::add_state_with_level(const State state, const Level level) { return Nfa::add_state(state); } -void Nft::insert_word(const State src, const Word &word, const State tgt) { +State Nft::insert_word(const State source, const Word &word, const State target) { assert(0 < num_of_levels); + const size_t num_of_states_orig{ num_of_states() }; + assert(source < num_of_states_orig); + assert(target < num_of_states_orig); - const State first_new_state = num_of_states(); - Nfa::insert_word(src, word, tgt); + const State first_new_state = num_of_states_orig; + const State word_tgt = Nfa::insert_word(source, word, target); const size_t num_of_states_after = num_of_states(); - const Level src_lvl = levels[src]; + const Level src_lvl = levels[source]; + Level lvl = (num_of_levels == 1 ) ? src_lvl : (src_lvl + 1); State state{ first_new_state }; for (; state < num_of_states_after; state++, lvl = (lvl + 1) % static_cast(num_of_levels)){ add_state_with_level(state, lvl); } - assert(levels[tgt] == 0 || levels[num_of_states_after - 1] < levels[tgt]); -} + assert(levels[word_tgt] == 0 || levels[num_of_states_after - 1] < levels[word_tgt]); -void Nft::insert_identity(const State state, const Symbol symbol) { - insert_word(state, Word(num_of_levels, symbol), state); + return word_tgt; } -void Nft::insert_word_by_parts(const State src, const std::vector &word_part_on_level, const State tgt) { +State Nft::insert_word(const State source, const Word &word) { return insert_word(source, word, add_state()); } + +State Nft::insert_word_by_parts(const State source, const std::vector &word_parts_on_levels, const State target) { assert(0 < num_of_levels); - assert(word_part_on_level.size() == num_of_levels); - assert(src < num_of_states()); - assert(tgt < num_of_states()); - assert(levels[src] == 0); - assert(levels[tgt] == 0); + assert(word_parts_on_levels.size() == num_of_levels); + const size_t num_of_states_orig{ num_of_states() }; + assert(source < num_of_states_orig); + assert(target < num_of_states_orig); + assert(levels[source] == 0); + assert(levels[target] == 0); if (num_of_levels == 1) { - Nft::insert_word(src, word_part_on_level[0], tgt); - return; + return Nft::insert_word(source, word_parts_on_levels[0], target); } size_t max_word_part_len = std::max_element( - word_part_on_level.begin(), - word_part_on_level.end(), + word_parts_on_levels.begin(), + word_parts_on_levels.end(), [](const Word& a, const Word& b) { return a.size() < b.size(); } )->size(); assert(0 < max_word_part_len); @@ -348,22 +352,22 @@ void Nft::insert_word_by_parts(const State src, const std::vector &word_pa std::vector word_part_it_v(num_of_levels); for (Level lvl{ 0 }; lvl < num_of_levels; lvl++) { - word_part_it_v[lvl] = word_part_on_level[lvl].begin(); + word_part_it_v[lvl] = word_parts_on_levels[lvl].begin(); } // This function retrieves the next symbol from a word part at a specified level and advances the corresponding iterator. // Returns EPSILON when the iterator reaches the end of the word part. auto get_next_symbol = [&](Level lvl) { - if (word_part_it_v[lvl] == word_part_on_level[lvl].end()) { + if (word_part_it_v[lvl] == word_parts_on_levels[lvl].end()) { return EPSILON; } return *(word_part_it_v[lvl]++); }; - // Add transition src --> inner_state. + // Add transition source --> inner_state. Level inner_lvl = (num_of_levels == 1 ) ? 0 : 1; State inner_state = add_state_with_level(inner_lvl); - delta.add(src, get_next_symbol(0), inner_state); + delta.add(source, get_next_symbol(0), inner_state); // Add transition inner_state --> inner_state State prev_state = inner_state; @@ -376,8 +380,23 @@ void Nft::insert_word_by_parts(const State src, const std::vector &word_pa prev_lvl = inner_lvl; } - // Add transition inner_state --> tgt. - delta.add(prev_state, get_next_symbol(prev_lvl), tgt); + // Add transition inner_state --> target. + delta.add(prev_state, get_next_symbol(prev_lvl), target); + return target; +} + +State Nft::insert_word_by_parts(const State source, const std::vector &word_parts_on_levels) { + return insert_word_by_parts(source, word_parts_on_levels, add_state()); +} + +void Nft::insert_identity(const State state, const std::vector &symbols) { + for (const Symbol symbol : symbols) { + insert_identity(state, symbol); + } +} + +void Nft::insert_identity(const State state, const Symbol symbol) { + insert_word(state, Word(num_of_levels, symbol), state); } void Nft::clear() { diff --git a/tests/nfa/nfa.cc b/tests/nfa/nfa.cc index 7a04c7ad6..68930fa1b 100644 --- a/tests/nfa/nfa.cc +++ b/tests/nfa/nfa.cc @@ -3001,7 +3001,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("Insert 'a'") { SECTION("src < tgt") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(1, {'a'}, 3); + State new_tgt = nfa.insert_word(1, {'a'}, 3); + CHECK(new_tgt == 3); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(1, 'a', 3); @@ -3011,7 +3012,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("src < tgt && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(1, {'a'}, 4); + State new_tgt = nfa.insert_word(1, {'a'}, 4); + CHECK(new_tgt == 4); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(1, 'a', 4); @@ -3021,7 +3023,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("tgt < src") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(3, {'a'}, 1); + State new_tgt = nfa.insert_word(3, {'a'}, 1); + CHECK(new_tgt == 1); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(3, 'a', 1); @@ -3032,7 +3035,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("tgt < src && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(4, {'a'}, 1); + State new_tgt = nfa.insert_word(4, {'a'}, 1); + CHECK(new_tgt == 1); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(4, 'a', 1); @@ -3042,7 +3046,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("self-loop") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(3, {'a'}, 3); + State new_tgt = nfa.insert_word(3, {'a'}, 3); + CHECK(new_tgt == 3); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(3, 'a', 3); @@ -3052,19 +3057,35 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("self-loop && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(4, {'a'}, 4); + State new_tgt = nfa.insert_word(4, {'a'}, 4); + CHECK(new_tgt == 4); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(4, 'a', 4); CHECK(are_equivalent(nfa, expected)); } + + SECTION("tgt is not specified") { + nfa = Nfa(delta, { 0 }); + State new_tgt = nfa.insert_word(1, {'a'}); + nfa.final.insert(new_tgt); + + expected = Nfa(3, { 0 }, { 2 }); + expected.delta.add(0, 0, 1); + expected.delta.add(0, 4, 0); + expected.delta.add(1, 5, 1); + expected.delta.add(1, 'a', 2); + + CHECK(are_equivalent(nfa, expected)); + } } SECTION("Insert 'ab'") { SECTION("src < tgt") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(1, {'a', 'b'}, 3); + State new_tgt = nfa.insert_word(1, {'a', 'b'}, 3); + CHECK(new_tgt == 3); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(1, 'a', 5); @@ -3075,7 +3096,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("src < tgt && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(1, {'a', 'b'}, 4); + State new_tgt = nfa.insert_word(1, {'a', 'b'}, 4); + CHECK(new_tgt == 4); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(1, 'a', 5); @@ -3086,7 +3108,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("tgt < src") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(3, {'a', 'b'}, 1); + State new_tgt = nfa.insert_word(3, {'a', 'b'}, 1); + CHECK(new_tgt == 1); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(3, 'a', 5); @@ -3098,7 +3121,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("tgt < src && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(4, {'a', 'b'}, 1); + State new_tgt = nfa.insert_word(4, {'a', 'b'}, 1); + CHECK(new_tgt == 1); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(4, 'a', 5); @@ -3109,7 +3133,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("self-loop") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(3, {'a', 'b'}, 3); + State new_tgt = nfa.insert_word(3, {'a', 'b'}, 3); + CHECK(new_tgt == 3); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(3, 'a', 5); @@ -3120,7 +3145,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("self-loop && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(4, {'a', 'b'}, 4); + State new_tgt = nfa.insert_word(4, {'a', 'b'}, 4); + CHECK(new_tgt == 4); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(4, 'a', 5); @@ -3128,12 +3154,29 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { CHECK(are_equivalent(nfa, expected)); } + + SECTION("tgt is not specified") { + nfa = Nfa(delta, { 0 }); + State new_tgt = nfa.insert_word(1, {'a', 'b'}); + nfa.final.insert(new_tgt); + + expected = Nfa(4, { 0 }, { 3 }); + expected.delta.add(0, 0, 1); + expected.delta.add(0, 4, 0); + expected.delta.add(1, 5, 1); + expected.delta.add(1, 'a', 2); + expected.delta.add(2, 'b', 3); + + CHECK(are_equivalent(nfa, expected)); + } + } SECTION("Insert 'abcd'") { SECTION("src < tgt") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(1, {'a', 'b', 'c', 'd'}, 3); + State new_tgt = nfa.insert_word(1, {'a', 'b', 'c', 'd'}, 3); + CHECK(new_tgt == 3); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(1, 'a', 5); @@ -3146,7 +3189,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("src < tgt && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(1, {'a', 'b', 'c', 'd'}, 4); + State new_tgt = nfa.insert_word(1, {'a', 'b', 'c', 'd'}, 4); + CHECK(new_tgt == 4); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(1, 'a', 5); @@ -3159,7 +3203,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("tgt < src") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(3, {'a', 'b', 'c', 'd'}, 1); + State new_tgt = nfa.insert_word(3, {'a', 'b', 'c', 'd'}, 1); + CHECK(new_tgt == 1); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(3, 'a', 5); @@ -3173,7 +3218,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("tgt < src && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(4, {'a', 'b', 'c', 'd'}, 1); + State new_tgt = nfa.insert_word(4, {'a', 'b', 'c', 'd'}, 1); + CHECK(new_tgt == 1); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(4, 'a', 5); @@ -3186,7 +3232,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("self-loop") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(3, {'a', 'b', 'c', 'd'}, 3); + State new_tgt = nfa.insert_word(3, {'a', 'b', 'c', 'd'}, 3); + CHECK(new_tgt == 3); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(3, 'a', 5); @@ -3199,7 +3246,8 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { SECTION("self-loop && final.contains(tgt)") { nfa = Nfa(delta, { 0 }, { 4 }); - nfa.insert_word(4, {'a', 'b', 'c', 'd'}, 4); + State new_tgt = nfa.insert_word(4, {'a', 'b', 'c', 'd'}, 4); + CHECK(new_tgt == 4); expected = Nfa(delta, { 0 }, { 4 }); expected.delta.add(4, 'a', 5); @@ -3209,5 +3257,22 @@ TEST_CASE("mata::nfa::Nfa::insert_word()") { CHECK(are_equivalent(nfa, expected)); } + + SECTION("tgt is not specified") { + nfa = Nfa(delta, { 0 }); + State new_tgt = nfa.insert_word(1, {'a', 'b', 'c', 'd'}); + nfa.final.insert(new_tgt); + + expected = Nfa(6, { 0 }, { 5 }); + expected.delta.add(0, 0, 1); + expected.delta.add(0, 4, 0); + expected.delta.add(1, 5, 1); + expected.delta.add(1, 'a', 2); + expected.delta.add(2, 'b', 3); + expected.delta.add(3, 'c', 4); + expected.delta.add(4, 'd', 5); + + CHECK(are_equivalent(nfa, expected)); + } } } diff --git a/tests/nft/nft.cc b/tests/nft/nft.cc index c4451d0ac..4b039492c 100644 --- a/tests/nft/nft.cc +++ b/tests/nft/nft.cc @@ -4283,7 +4283,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("Insert 'a'") { SECTION("num_of_levels == 1") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 1); - nft.insert_word(1, {'a'}, 3); + State new_tgt = nft.insert_word(1, {'a'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 1); expected.delta.add(1, 'a', 3); @@ -4293,7 +4294,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("num_of_levels == 3") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 3); - nft.insert_word(1, {'a'}, 3); + State new_tgt = nft.insert_word(1, {'a'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 3); expected.delta.add(1, 'a', 3); @@ -4303,7 +4305,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("self-loop, num_of_levels == 1") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 1); - nft.insert_word(3, {'a'}, 3); + State new_tgt = nft.insert_word(3, {'a'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 1); expected.delta.add(3, 'a', 3); @@ -4313,7 +4316,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("self-loop, num_of_levels == 3") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 3); - nft.insert_word(3, {'a'}, 3); + State new_tgt = nft.insert_word(3, {'a'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 3); expected.delta.add(3, 'a', 3); @@ -4321,12 +4325,27 @@ TEST_CASE("mata::nft::Nft::insert_word()") { CHECK(are_equivalent(nft, expected)); } + SECTION("tgt is not specified") { + nft = Nft(delta, { 0 }, {}, { 0, 0, 0, 0, 0 }, 1); + State new_tgt = nft.insert_word(1, {'a'}); + nft.final.insert(new_tgt); + + expected = Nft(3, { 0 }, { 2 }, { 0, 0, 0, 0}, 1); + expected.delta.add(0, 0, 1); + expected.delta.add(0, 4, 0); + expected.delta.add(1, 5, 1); + expected.delta.add(1, 'a', 2); + + CHECK(are_equivalent(nft, expected)); + } + } SECTION("Insert 'ab'") { SECTION("num_of_levels == 1") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 1); - nft.insert_word(1, {'a', 'b'}, 3); + State new_tgt = nft.insert_word(1, {'a', 'b'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 0 }, 1); expected.delta.add(1, 'a', 5); @@ -4337,7 +4356,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("num_of_levels == 3") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 3); - nft.insert_word(1, {'a', 'b'}, 3); + State new_tgt = nft.insert_word(1, {'a', 'b'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 1 }, 3); expected.delta.add(1, 'a', 5); @@ -4348,7 +4368,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("self-loop, num_of_levels == 1") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 1); - nft.insert_word(3, {'a', 'b'}, 3); + State new_tgt = nft.insert_word(3, {'a', 'b'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 0 }, 1); expected.delta.add(3, 'a', 5); @@ -4359,7 +4380,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("self-loop, num_of_levels == 3") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0 }, 3); - nft.insert_word(3, {'a', 'b'}, 3); + State new_tgt = nft.insert_word(3, {'a', 'b'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 1 }, 3); expected.delta.add(3, 'a', 5); @@ -4367,12 +4389,28 @@ TEST_CASE("mata::nft::Nft::insert_word()") { CHECK(are_equivalent(nft, expected)); } + + SECTION("tgt is not specified") { + nft = Nft(delta, { 0 }, {}, { 0, 0, 0, 0, 0 }, 1); + State new_tgt = nft.insert_word(1, {'a', 'b'}); + nft.final.insert(new_tgt); + + expected = Nft(4, { 0 }, { 3 }, { 0, 0, 0, 0, 0 }, 1); + expected.delta.add(0, 0, 1); + expected.delta.add(0, 4, 0); + expected.delta.add(1, 5, 1); + expected.delta.add(1, 'a', 2); + expected.delta.add(2, 'b', 3); + + CHECK(are_equivalent(nft, expected)); + } } SECTION("Insert 'abcd'") { SECTION("num_of_levels == 1") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0}, 1); - nft.insert_word(1, {'a', 'b', 'c', 'd'}, 3); + State new_tgt = nft.insert_word(1, {'a', 'b', 'c', 'd'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 0, 0, 0}, 1); expected.delta.add(1, 'a', 5); @@ -4385,7 +4423,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("num_of_levels == 3") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0}, 3); - nft.insert_word(1, {'a', 'b', 'c', 'd'}, 3); + State new_tgt = nft.insert_word(1, {'a', 'b', 'c', 'd'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 1, 2, 0}, 3); expected.delta.add(1, 'a', 5); @@ -4398,7 +4437,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("self-loop, num_of_levels == 1") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0}, 1); - nft.insert_word(3, {'a', 'b', 'c', 'd'}, 3); + State new_tgt = nft.insert_word(3, {'a', 'b', 'c', 'd'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 0, 0, 0}, 1); expected.delta.add(3, 'a', 5); @@ -4411,7 +4451,8 @@ TEST_CASE("mata::nft::Nft::insert_word()") { SECTION("self-loop, num_of_levels == 3") { nft = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0}, 3); - nft.insert_word(3, {'a', 'b', 'c', 'd'}, 3); + State new_tgt = nft.insert_word(3, {'a', 'b', 'c', 'd'}, 3); + CHECK(new_tgt == 3); expected = Nft(delta, { 0 }, { 4 }, { 0, 0, 0, 0, 0, 1, 2, 0}, 3); expected.delta.add(3, 'a', 5); @@ -4421,6 +4462,23 @@ TEST_CASE("mata::nft::Nft::insert_word()") { CHECK(are_equivalent(nft, expected)); } + + SECTION("tgt is not specified") { + nft = Nft(delta, { 0 }, {}, { 0, 0, 0, 0, 0 }, 1); + State new_tgt = nft.insert_word(1, {'a', 'b', 'c', 'd'}); + nft.final.insert(new_tgt); + + expected = Nft(6, { 0 }, { 5 }, { 0, 0, 0, 0, 0, 0, 0 }, 1); + expected.delta.add(0, 0, 1); + expected.delta.add(0, 4, 0); + expected.delta.add(1, 5, 1); + expected.delta.add(1, 'a', 2); + expected.delta.add(2, 'b', 3); + expected.delta.add(3, 'c', 4); + expected.delta.add(4, 'd', 5); + + CHECK(are_equivalent(nft, expected)); + } } } @@ -4479,37 +4537,82 @@ TEST_CASE("mata::nft::Nft::insert_identity()") { delta.add(1, 'b', 2); SECTION("num_of_levels == 1") { - nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 1); - nft.insert_identity(1, 'c'); - expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 1); - expected.delta.add(1, 'c', 1); + SECTION("symbols cnt == 1") { + nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 1); + nft.insert_identity(1, 'c'); - CHECK(are_equivalent(nft, expected)); + expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 1); + expected.delta.add(1, 'c', 1); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("symbols cnt == 2") { + nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 1); + nft.insert_identity(1, {'c', 'd'}); + + expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1 }, 1); + expected.insert_identity(1, 'c'); + expected.insert_identity(1, 'd'); + + CHECK(are_equivalent(nft, expected)); + } } SECTION("num_of_levels == 2") { - nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 2); - nft.insert_identity(1, 'c'); - expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1 }, 2); - expected.delta.add(1, 'c', 3); - expected.delta.add(3, 'c', 1); + SECTION("symbols cnt == 1") { + nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 2); + nft.insert_identity(1, 'c'); - CHECK(are_equivalent(nft, expected)); + expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1 }, 2); + expected.delta.add(1, 'c', 3); + expected.delta.add(3, 'c', 1); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("symbols cnt == 2") { + nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 2); + nft.insert_identity(1, {'c', 'd'}); + + expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1 }, 2); + expected.insert_identity(1, 'c'); + expected.insert_identity(1, 'd'); + + CHECK(are_equivalent(nft, expected)); + } } SECTION("num_of_levels == 4") { - nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 4); - nft.insert_identity(1, 'c'); - expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1, 2, 3 }, 4); - expected.delta.add(1, 'c', 3); - expected.delta.add(3, 'c', 4); - expected.delta.add(4, 'c', 5); - expected.delta.add(5, 'c', 1); + SECTION("symbols cnt == 1") { + nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 4); + nft.insert_identity(1, 'c'); - CHECK(are_equivalent(nft, expected)); + expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1, 2, 3 }, 4); + expected.delta.add(1, 'c', 3); + expected.delta.add(3, 'c', 4); + expected.delta.add(4, 'c', 5); + expected.delta.add(5, 'c', 1); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("symbols cnt == 4") { + nft = Nft(delta, { 0 }, { 2 }, { 0, 0, 0 }, 4); + nft.insert_identity(1, {'c', 'd', 'e', 'f'}); + + expected = Nft(delta, { 0 }, { 2 }, { 0, 0, 0, 1, 2, 3 }, 4); + expected.insert_identity(1, 'c'); + expected.insert_identity(1, 'd'); + expected.insert_identity(1, 'e'); + expected.insert_identity(1, 'f'); + + CHECK(are_equivalent(nft, expected)); + + } } } @@ -4563,7 +4666,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("num_of_levels == 1 && word_part.size() == 1") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 1); - nft.insert_word_by_parts(0, { {'a'} } , 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a'} } , 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 1); expected.delta.add(0, 'a', 1); @@ -4573,7 +4677,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("num_of_levels == 1 && word_part.size() == 2") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 1); - nft.insert_word_by_parts(0, { {'a', 'b'} } , 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'} } , 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 0 }, 1); expected.delta.add(0, 'a', 2); @@ -4584,7 +4689,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("num_of_levels == 1 && word_part.size() == 4") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 0, 0, 0 }, 1); - nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 0, 0, 0 }, 1); expected.delta.add(0, 'a', 2); @@ -4607,7 +4713,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 1") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 2); - nft.insert_word_by_parts(0, { {'a'}, {'b'} } , 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a'}, {'b'} } , 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1 }, 2); expected.delta.add(0, 'a', 2); @@ -4617,7 +4724,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 2") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 2); - nft.insert_word_by_parts(0, { {'a', 'b'}, {'c', 'd'} } , 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'}, {'c', 'd'} } , 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 0, 1 }, 2); expected.delta.add(0, 'a', 2); @@ -4630,7 +4738,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 4") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 2); - nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 0, 1, 0, 1, 0, 1 }, 2); expected.delta.add(0, 'a', 2); @@ -4650,7 +4759,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 1") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 4); - nft.insert_word_by_parts(0, { {'a'}, {'b'}, {'c'}, {'d'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a'}, {'b'}, {'c'}, {'d'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 2, 3 }, 4); expected.delta.add(0, 'a', 2); @@ -4663,7 +4773,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 2") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 4); - nft.insert_word_by_parts(0, { {'a', 'b'}, {'c', 'd'}, {'e', 'f'}, {'g', 'h'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'}, {'c', 'd'}, {'e', 'f'}, {'g', 'h'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3 }, 4); expected.delta.add(0, 'a', 2); @@ -4680,7 +4791,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 4") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 4); - nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'}, {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'}, {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 }, 4); expected.delta.add(0, 'a', 2); @@ -4705,6 +4817,146 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { } } + SECTION("The target state is not specified.") { + Delta delta; + delta.add(0, 'w', 0); + delta.add(0, 'y', 1); + delta.add(1, 'x', 1); + delta.add(1, 'z', 0); + + SECTION("num_of_levels == 2") { + SECTION("word_part.size() == 1") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 2); + State new_tgt = nft.insert_word_by_parts(0, { {'a'}, {'b'} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 3 }, { 0, 0, 1, 0 }, 2); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'b', 3); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("word_part.size() == 2") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 2); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'}, {'c', 'd'} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 5 }, { 0, 0, 1, 0, 1, 0 }, 2); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'c', 3); + expected.delta.add(3, 'b', 4); + expected.delta.add(4, 'd', 5); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("word_part.size() == 4") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 2); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 9 }, { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, 2); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'e', 3); + expected.delta.add(3, 'b', 4); + expected.delta.add(4, 'f', 5); + expected.delta.add(5, 'c', 6); + expected.delta.add(6, 'g', 7); + expected.delta.add(7, 'd', 8); + expected.delta.add(8, 'h', 9); + + CHECK(are_equivalent(nft, expected)); + } + } + + SECTION("num_of_levels == 4") { + SECTION("word_part.size() == 1") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 4); + State new_tgt = nft.insert_word_by_parts(0, { {'a'}, {'b'}, {'c'}, {'d'} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 5 }, { 0, 0, 1, 2, 3, 0 }, 4); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'b', 3); + expected.delta.add(3, 'c', 4); + expected.delta.add(4, 'd', 5); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("word_part.size() == 2") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 4); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'}, {'c', 'd'}, {'e', 'f'}, {'g', 'h'} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 9 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3, 0 }, 4); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'c', 3); + expected.delta.add(3, 'e', 4); + expected.delta.add(4, 'g', 5); + expected.delta.add(5, 'b', 6); + expected.delta.add(6, 'd', 7); + expected.delta.add(7, 'f', 8); + expected.delta.add(8, 'h', 9); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("word_part.size() == 4") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 4); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'}, {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 17 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0 }, 4); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'e', 3); + expected.delta.add(3, 'i', 4); + expected.delta.add(4, 'm', 5); + expected.delta.add(5, 'b', 6); + expected.delta.add(6, 'f', 7); + expected.delta.add(7, 'j', 8); + expected.delta.add(8, 'n', 9); + expected.delta.add(9, 'c', 10); + expected.delta.add(10, 'g', 11); + expected.delta.add(11, 'k', 12); + expected.delta.add(12, 'o', 13); + expected.delta.add(13, 'd', 14); + expected.delta.add(14, 'h', 15); + expected.delta.add(15, 'l', 16); + expected.delta.add(16, 'p', 17); + + CHECK(are_equivalent(nft, expected)); + } + + SECTION("The lengths of word pats dont have the same length.") { + nft = Nft(delta, { 0, 1 }, {}, { 0, 0 }, 4); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'}, {'e', 'f', 'g', 'h'}, {'i', 'j', 'k', 'l'}, {} }); + nft.final.insert(new_tgt); + + expected = Nft(delta, { 0, 1 }, { 17 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0 }, 4); + expected.delta.add(0, 'a', 2); + expected.delta.add(2, 'e', 3); + expected.delta.add(3, 'i', 4); + expected.delta.add(4, EPSILON, 5); + expected.delta.add(5, 'b', 6); + expected.delta.add(6, 'f', 7); + expected.delta.add(7, 'j', 8); + expected.delta.add(8, EPSILON, 9); + expected.delta.add(9, EPSILON, 10); + expected.delta.add(10, 'g', 11); + expected.delta.add(11, 'k', 12); + expected.delta.add(12, EPSILON, 13); + expected.delta.add(13, EPSILON, 14); + expected.delta.add(14, 'h', 15); + expected.delta.add(15, 'l', 16); + expected.delta.add(16, EPSILON, 17); + + CHECK(are_equivalent(nft, expected)); + } + } + } + SECTION("The lengths of word parts dont have to match.") { Delta delta; delta.add(0, 'w', 0); @@ -4715,7 +4967,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("num_of_levels == 2") { SECTION("word_part.size() == 1") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 2); - nft.insert_word_by_parts(0, { {}, {'b'} } , 1); + State new_tgt = nft.insert_word_by_parts(0, { {}, {'b'} } , 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1 }, 2); expected.delta.add(0, EPSILON, 2); @@ -4726,7 +4979,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 2") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 2); - nft.insert_word_by_parts(0, { {'a', 'b'}, {'c'} } , 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b'}, {'c'} } , 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 0, 1 }, 2); expected.delta.add(0, 'a', 2); @@ -4739,7 +4993,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 4") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 2); - nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a', 'b', 'c', 'd'}, {'e'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 0, 1, 0, 1, 0, 1 }, 2); expected.delta.add(0, 'a', 2); @@ -4758,7 +5013,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("num_of_levels == 4") { SECTION("word_part.size() == 1") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 4); - nft.insert_word_by_parts(0, { {'a'}, {}, {'c'}, {} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a'}, {}, {'c'}, {} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 2, 3 }, 4); expected.delta.add(0, 'a', 2); @@ -4771,7 +5027,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 2") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 4); - nft.insert_word_by_parts(0, { {'a'}, {'c', 'd'}, {}, {'g'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {'a'}, {'c', 'd'}, {}, {'g'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3 }, 4); expected.delta.add(0, 'a', 2); @@ -4788,7 +5045,8 @@ TEST_CASE("mata::nft::Nft::insert_word_by_parts()") { SECTION("word_part.size() == 4") { nft = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0 }, 4); - nft.insert_word_by_parts(0, { {}, {'e', 'f'}, {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'} }, 1); + State new_tgt = nft.insert_word_by_parts(0, { {}, {'e', 'f'}, {'i', 'j', 'k', 'l'}, {'m', 'n', 'o', 'p'} }, 1); + CHECK(new_tgt == 1); expected = Nft(delta, { 0, 1 }, { 0, 1 }, { 0, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 }, 4); expected.delta.add(0, EPSILON, 2);