From 77df9f57643d16a97a9e724a1ec422a2d03aee95 Mon Sep 17 00:00:00 2001 From: Tomas Pecka <peckato1@fit.cvut.cz> Date: Sat, 29 Nov 2014 22:39:07 +0100 Subject: [PATCH] algo: automaton iteration --- alangop2/src/alangop.cpp | 28 +++- .../transform/AutomatonIteration.cpp | 125 ++++++++++++++++++ .../automaton/transform/AutomatonIteration.h | 59 +++++++++ .../AutomatonIterationEpsilonTransition.cpp | 125 ++++++++++++++++++ .../AutomatonIterationEpsilonTransition.h | 59 +++++++++ .../transform/AutomataConcatenationTest.cpp | 6 - .../transform/AutomatonIterationTest.cpp | 58 ++++++++ .../transform/AutomatonIterationTest.h | 19 +++ 8 files changed, 466 insertions(+), 13 deletions(-) create mode 100644 alib2algo/src/automaton/transform/AutomatonIteration.cpp create mode 100644 alib2algo/src/automaton/transform/AutomatonIteration.h create mode 100644 alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp create mode 100644 alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h create mode 100644 alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp create mode 100644 alib2algo/test-src/automaton/transform/AutomatonIterationTest.h diff --git a/alangop2/src/alangop.cpp b/alangop2/src/alangop.cpp index 3eeb3c533b..7c35665648 100644 --- a/alangop2/src/alangop.cpp +++ b/alangop2/src/alangop.cpp @@ -17,6 +17,8 @@ #include <automaton/transform/AutomataIntersectionCartesianProduct.h> #include <automaton/transform/AutomataUnionCartesianProduct.h> #include <automaton/transform/AutomataUnionEpsilonTransition.h> +#include <automaton/transform/AutomatonIterationEpsilonTransition.h> +#include <automaton/transform/AutomatonIteration.h> int main(int argc, char* argv[]) { @@ -29,6 +31,8 @@ int main(int argc, char* argv[]) { allowed.push_back("concatenationEpsilon"); allowed.push_back("concatenation"); allowed.push_back("intersectionCartesian"); + allowed.push_back("iterationEpsilon"); + allowed.push_back("iteration"); TCLAP::ValuesConstraint<std::string> allowedVals( allowed ); TCLAP::ValueArg<std::string> algorithm( "a", "algorithm", "Execute algorithm", true, "", &allowedVals); @@ -58,27 +62,37 @@ int main(int argc, char* argv[]) { } else { sax::SaxParseInterface::parseFile(a2.getValue(), a2Tokens); } - } else { + } else if(algorithm.getValue() != "iteration" && algorithm.getValue() != "iterationEpsilon") { sax::SaxParseInterface::parseStdin(a2Tokens); } automaton::Automaton automaton1 = alib::DataFactory::fromTokens<automaton::Automaton>(a1Tokens); - automaton::Automaton automaton2 = alib::DataFactory::fromTokens<automaton::Automaton>(a2Tokens); if( algorithm.getValue() == "unionEpsilon") { - alib::DataFactory::toStdout(automaton::transform::AutomataUnionEpsilonTransition::unification(automaton1, automaton2));; + automaton::Automaton automaton2 = alib::DataFactory::fromTokens<automaton::Automaton>(a2Tokens); + alib::DataFactory::toStdout(automaton::transform::AutomataUnionEpsilonTransition::unification(automaton1, automaton2)); return 0; } else if( algorithm.getValue() == "unionCartesian") { - alib::DataFactory::toStdout(automaton::transform::AutomataUnionCartesianProduct::unification(automaton1, automaton2));; + automaton::Automaton automaton2 = alib::DataFactory::fromTokens<automaton::Automaton>(a2Tokens); + alib::DataFactory::toStdout(automaton::transform::AutomataUnionCartesianProduct::unification(automaton1, automaton2)); return 0; } else if( algorithm.getValue() == "concatenationEpsilon") { - alib::DataFactory::toStdout(automaton::transform::AutomataConcatenationEpsilonTransition::concatenation(automaton1, automaton2));; + automaton::Automaton automaton2 = alib::DataFactory::fromTokens<automaton::Automaton>(a2Tokens); + alib::DataFactory::toStdout(automaton::transform::AutomataConcatenationEpsilonTransition::concatenation(automaton1, automaton2)); return 0; } else if( algorithm.getValue() == "concatenation") { - alib::DataFactory::toStdout(automaton::transform::AutomataConcatenation::concatenation(automaton1, automaton2));; + automaton::Automaton automaton2 = alib::DataFactory::fromTokens<automaton::Automaton>(a2Tokens); + alib::DataFactory::toStdout(automaton::transform::AutomataConcatenation::concatenation(automaton1, automaton2)); return 0; } else if( algorithm.getValue() == "intersectionCartesian") { - alib::DataFactory::toStdout(automaton::transform::AutomataIntersectionCartesianProduct::intersection(automaton1, automaton2));; + automaton::Automaton automaton2 = alib::DataFactory::fromTokens<automaton::Automaton>(a2Tokens); + alib::DataFactory::toStdout(automaton::transform::AutomataIntersectionCartesianProduct::intersection(automaton1, automaton2)); + return 0; + } else if( algorithm.getValue() == "iteration") { + alib::DataFactory::toStdout(automaton::transform::AutomatonIteration::iteration(automaton1)); + return 0; + } else if( algorithm.getValue() == "iterationEpsilon") { + alib::DataFactory::toStdout(automaton::transform::AutomatonIterationEpsilonTransition::iteration(automaton1)); return 0; } else { throw exception::AlibException( "Invalid algorithm" ); diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp new file mode 100644 index 0000000000..ad8dc7d4f1 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp @@ -0,0 +1,125 @@ +/* + * AutomatonIteration.cpp + * + * Created on: 29. 11. 2014 + * Author: Tomas Pecka + */ + +#include "AutomatonIteration.h" +#include <exception/AlibException.h> + +namespace automaton +{ + +namespace transform +{ + +automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& automaton) +{ + AutomatonBase* out; + automaton.getData().Accept((void*) &out, AutomatonIteration::AUTOMATON_ITERATION); + automaton::Automaton res(*out); + delete out; + return res; +} + +template<class T> +automaton::NFA AutomatonIteration::iteration(const T& automaton) +{ + automaton::NFA res(automaton); + + for(const auto& qf : res.getFinalStates()) + for(const auto& t : res.getTransitionsToState(qf)) + res.addTransition(t.first.first, t.first.second, res.getInitialState()); + + res.addFinalState(automaton.getInitialState()); + return res; +} + +void AutomatonIteration::Visit(void*, const automaton::EpsilonNFA&) const +{ + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void AutomatonIteration::Visit(void*, const automaton::CompactNFA&) const +{ + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void AutomatonIteration::Visit(void* data, const automaton::DFA& automaton) const +{ + AutomatonBase* &ret = *(AutomatonBase**) data; + ret = std::move(AutomatonIteration::iteration(automaton)).plunder(); +} + +void AutomatonIteration::Visit(void*, const automaton::ExtendedNFA&) const +{ + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void AutomatonIteration::Visit(void*, const automaton::MultiInitialStateNFA&) const +{ + throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); +} + +void AutomatonIteration::Visit(void* data, const automaton::NFA& automaton) const +{ + AutomatonBase* &ret = *(AutomatonBase**) data; + ret = std::move(AutomatonIteration::iteration(automaton)).plunder(); +} + +void AutomatonIteration::Visit(void*, const automaton::DPDA&) const +{ + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::NPDA&) const +{ + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::InputDrivenNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const +{ + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::SinglePopNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::SinglePopDPDA&) const +{ + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::VisiblyPushdownDPDA&) const +{ + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::VisiblyPushdownNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void AutomatonIteration::Visit(void*, const automaton::OneTapeDTM&) const +{ + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const AutomatonIteration AutomatonIteration::AUTOMATON_ITERATION; + +} /* namespace transform */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.h b/alib2algo/src/automaton/transform/AutomatonIteration.h new file mode 100644 index 0000000000..e19861e088 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomatonIteration.h @@ -0,0 +1,59 @@ +/* + * AutomatonIteration.h + * + * Created on: 29. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef AUTOMATON_ITERATION_H_ +#define AUTOMATON_ITERATION_H_ + +#include <automaton/Automaton.h> +#include <automaton/FSM/EpsilonNFA.h> + +namespace automaton +{ + +namespace transform +{ + +/** + * Iterates language given by automaton + * - For finite automaton A1, we create automaton L accepting L(A1)* + */ +class AutomatonIteration : public automaton::VisitableAutomatonBase::const_visitor_type +{ +public: + static automaton::Automaton iteration(const automaton::Automaton& automaton); + + template<class T> + static automaton::NFA iteration(const T& automaton); + +private: + void Visit(void* data, const automaton::CompactNFA& automaton) const; + void Visit(void* data, const automaton::DFA& automaton) const; + void Visit(void* data, const automaton::EpsilonNFA& automaton) const; + void Visit(void* data, const automaton::ExtendedNFA& automaton) const; + void Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const; + void Visit(void* data, const automaton::NFA& automaton) const; + + void Visit(void* data, const automaton::DPDA& automaton) const; + void Visit(void* data, const automaton::NPDA& automaton) const; + void Visit(void* data, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void* data, const automaton::SinglePopNPDA& automaton) const; + void Visit(void* data, const automaton::SinglePopDPDA& automaton) const; + void Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const; + void Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const; + + void Visit(void* data, const automaton::OneTapeDTM& automaton) const; + + static const AutomatonIteration AUTOMATON_ITERATION; +}; + +} /* namespace transform */ + +} /* namespace automaton */ + +#endif /* AUTOMATON_ITERATION_H_ */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp new file mode 100644 index 0000000000..6cf3b6a1a9 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp @@ -0,0 +1,125 @@ +/* + * AutomatonIterationEpsilonTransition.cpp + * + * Created on: 20. 11. 2014 + * Author: Tomas Pecka + */ + +#include "AutomatonIterationEpsilonTransition.h" +#include <exception/AlibException.h> + +namespace automaton +{ + +namespace transform +{ + +automaton::Automaton AutomatonIterationEpsilonTransition::iteration(const automaton::Automaton& automaton) +{ + AutomatonBase* out; + automaton.getData().Accept((void*) &out, AutomatonIterationEpsilonTransition::AUTOMATON_ITERATION_EPSILON_TRANSITION); + automaton::Automaton res(*out); + delete out; + return res; +} + +template<class T> +automaton::EpsilonNFA AutomatonIterationEpsilonTransition::iteration(const T& automaton) +{ + automaton::EpsilonNFA res(automaton); + + for(const auto&q : automaton.getFinalStates()) + res.addTransition(q, automaton.getInitialState()); + + res.addFinalState(automaton.getInitialState()); + return res; +} + +void AutomatonIterationEpsilonTransition::Visit(void* data, const automaton::EpsilonNFA& automaton) const +{ + AutomatonBase* &ret = *(AutomatonBase**) data; + ret = std::move(AutomatonIterationEpsilonTransition::iteration(automaton)).plunder(); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::CompactNFA&) const +{ + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void* data, const automaton::DFA& automaton) const +{ + AutomatonBase* &ret = *(AutomatonBase**) data; + ret = std::move(AutomatonIterationEpsilonTransition::iteration(automaton)).plunder(); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::ExtendedNFA&) const +{ + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::MultiInitialStateNFA&) const +{ + throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void* data, const automaton::NFA& automaton) const +{ + AutomatonBase* &ret = *(AutomatonBase**) data; + ret = std::move(AutomatonIterationEpsilonTransition::iteration(automaton)).plunder(); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::DPDA&) const +{ + throw exception::AlibException("Unsupported automaton type DPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::NPDA&) const +{ + throw exception::AlibException("Unsupported automaton type NPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::InputDrivenNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type InputDrivenNPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const +{ + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::SinglePopNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type SinglePopNPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::SinglePopDPDA&) const +{ + throw exception::AlibException("Unsupported automaton type SinglePopDPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownDPDA&) const +{ + throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::VisiblyPushdownNPDA&) const +{ + throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA"); +} + +void AutomatonIterationEpsilonTransition::Visit(void*, const automaton::OneTapeDTM&) const +{ + throw exception::AlibException("Unsupported automaton type OneTapeDTM"); +} + +const AutomatonIterationEpsilonTransition AutomatonIterationEpsilonTransition::AUTOMATON_ITERATION_EPSILON_TRANSITION; + +} /* namespace transform */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h new file mode 100644 index 0000000000..7329e8cfb5 --- /dev/null +++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h @@ -0,0 +1,59 @@ +/* + * AutomatonIterationEpsilonTransition.h + * + * Created on: 29. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef AUTOMATON_ITERATION_EPSILON_TRANSITION_H_ +#define AUTOMATON_ITERATION_EPSILON_TRANSITION_H_ + +#include <automaton/Automaton.h> +#include <automaton/FSM/EpsilonNFA.h> + +namespace automaton +{ + +namespace transform +{ + +/** + * Iterates language given by automaton + * - For finite automaton A1, we create automaton L accepting L(A1)* + */ +class AutomatonIterationEpsilonTransition : public automaton::VisitableAutomatonBase::const_visitor_type +{ +public: + static automaton::Automaton iteration(const automaton::Automaton& automaton); + + template<class T> + static automaton::EpsilonNFA iteration(const T& automaton); + +private: + void Visit(void* data, const automaton::CompactNFA& automaton) const; + void Visit(void* data, const automaton::DFA& automaton) const; + void Visit(void* data, const automaton::EpsilonNFA& automaton) const; + void Visit(void* data, const automaton::ExtendedNFA& automaton) const; + void Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const; + void Visit(void* data, const automaton::NFA& automaton) const; + + void Visit(void* data, const automaton::DPDA& automaton) const; + void Visit(void* data, const automaton::NPDA& automaton) const; + void Visit(void* data, const automaton::InputDrivenNPDA& automaton) const; + void Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const; + void Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const; + void Visit(void* data, const automaton::SinglePopNPDA& automaton) const; + void Visit(void* data, const automaton::SinglePopDPDA& automaton) const; + void Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const; + void Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const; + + void Visit(void* data, const automaton::OneTapeDTM& automaton) const; + + static const AutomatonIterationEpsilonTransition AUTOMATON_ITERATION_EPSILON_TRANSITION; +}; + +} /* namespace transform */ + +} /* namespace automaton */ + +#endif /* AUTOMATON_ITERATION_EPSILON_H_ */ diff --git a/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp b/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp index 27cfc8e72a..4acd4ed33f 100644 --- a/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp +++ b/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp @@ -78,12 +78,6 @@ void AutomataConcatenationTest::testAutomataConcatenation() { automaton::Automaton umdfa12(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemover::remove(u12))))); automaton::Automaton umdfa21(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemover::remove(u21))))); automaton::Automaton umdfa22(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemover::remove(u22))))); - alib::DataFactory::toStdout(umdfa); - alib::DataFactory::toStdout(umdfa11); - alib::DataFactory::toStdout(umdfa12); - alib::DataFactory::toStdout(umdfa21); - alib::DataFactory::toStdout(umdfa22); - CPPUNIT_ASSERT(umdfa11 == umdfa); CPPUNIT_ASSERT(umdfa12 == umdfa); diff --git a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp new file mode 100644 index 0000000000..ae36365dda --- /dev/null +++ b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp @@ -0,0 +1,58 @@ +#include <list> +#include "AutomatonIterationTest.h" + +#include "automaton/transform/AutomatonIteration.h" +#include "automaton/transform/AutomatonIterationEpsilonTransition.h" + +#include "automaton/simplify/MinimizeBrzozowski.h" +#include "automaton/simplify/Normalize.h" +#include "automaton/simplify/EpsilonRemover.h" +#include "automaton/simplify/Trim.h" +#include "automaton/simplify/Total.h" +#include "automaton/determinize/Determinize.h" + +#include <factory/DataFactory.hpp> + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +CPPUNIT_TEST_SUITE_REGISTRATION( AutomatonIterationTest ); + +void AutomatonIterationTest::setUp() { +} + +void AutomatonIterationTest::tearDown() { +} + +void AutomatonIterationTest::testAutomatonIteration() { + + // Melichar 2.83 + automaton::State q1(1), q2(2), q3(3); + alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b')); + + automaton::DFA m1(q1); + m1.setStates({q1, q2, q3}); + m1.addFinalState(q3); + m1.setInputSymbols({a, b}); + m1.addTransition(q1, a, q2); + m1.addTransition(q2, b, q2); + m1.addTransition(q2, a, q3); + + automaton::NFA res(q1); + res.setStates({q1, q2, q3}); + res.setInputSymbols({a, b}); + res.setFinalStates({q1, q3}); + res.addTransition(q1, a, q2); + res.addTransition(q2, b, q2); + res.addTransition(q2, a, q3); + res.addTransition(q2, a, q1); + + automaton::Automaton i2 = automaton::transform::AutomatonIterationEpsilonTransition::iteration(automaton::Automaton(m1)); + automaton::Automaton i1 = automaton::transform::AutomatonIteration::iteration(automaton::Automaton(m1)); + + automaton::Automaton mdfa1 (automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemover::remove(i1))))); + automaton::Automaton mdfa2 (automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemover::remove(i2))))); + automaton::Automaton mdfa3 (automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemover::remove(res))))); + + CPPUNIT_ASSERT(mdfa1 == mdfa2); + CPPUNIT_ASSERT(mdfa1 == mdfa3); +} diff --git a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.h b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.h new file mode 100644 index 0000000000..28119050ac --- /dev/null +++ b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.h @@ -0,0 +1,19 @@ +#ifndef AUTOMATA_ITER_TEST_H_ +#define AUTOMATA_ITER_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class AutomatonIterationTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( AutomatonIterationTest ); + CPPUNIT_TEST( testAutomatonIteration ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testAutomatonIteration(); +}; + +#endif /* AUTOMATA_ITER_TEST_H_ */ -- GitLab