diff --git a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e6352dee80f445ea6609ee03bf5965ed6c6c3f15 --- /dev/null +++ b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp @@ -0,0 +1,67 @@ +/* + * MinimizeBrzozowski.cpp + * + * Created on: 18. 11. 2014 + * Author: Tomas Pecka + */ + +#include "MinimizeBrzozowski.h" + +#include <exception/AlibException.h> +#include <automaton/Automaton.h> +#include <automaton/FSM/MultiInitialStateNFA.h> + +#include "../transform/ReverseFSM.h" +#include "../determinize/Determinize.h" + +namespace automaton { + +namespace simplify { + +automaton::Automaton MinimizeBrzozowski::minimize(const automaton::Automaton& automaton) { + automaton::Automaton* out = NULL; + automaton.getData().Accept((void*) &out, MinimizeBrzozowski::MINIMIZE_BRZOZOWSKI); + automaton::Automaton res = std::move(*out); + delete out; + return res; +} + +automaton::DFA MinimizeBrzozowski::minimize(const automaton::DFA& dfa) { + return automaton::determinize::Determinize::determinize(automaton::transform::ReverseFSM::convert(automaton::determinize::Determinize::determinize(automaton::transform::ReverseFSM::convert(dfa)))); +} + +automaton::DFA MinimizeBrzozowski::minimize(const automaton::NFA& nfa) { + return automaton::determinize::Determinize::determinize(automaton::transform::ReverseFSM::convert(automaton::determinize::Determinize::determinize(automaton::transform::ReverseFSM::convert(nfa)))); +} + +void MinimizeBrzozowski::Visit(void*, const automaton::EpsilonNFA&) const { + throw exception::AlibException("Unsupported automaton type EpsilonNFA"); +} + +void MinimizeBrzozowski::Visit(void* data, const automaton::DFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->minimize(automaton)); +} + +void MinimizeBrzozowski::Visit(void*, const automaton::MultiInitialStateNFA&) const { + throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA"); +} + +void MinimizeBrzozowski::Visit(void* data, const automaton::NFA& automaton) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->minimize(automaton)); +} + +void MinimizeBrzozowski::Visit(void*, const automaton::ExtendedNFA& ) const { + throw exception::AlibException("Unsupported automaton type ExtendedNFA"); +} + +void MinimizeBrzozowski::Visit(void*, const automaton::CompactNFA& ) const { + throw exception::AlibException("Unsupported automaton type CompactNFA"); +} + +const MinimizeBrzozowski MinimizeBrzozowski::MINIMIZE_BRZOZOWSKI; + +} /* namespace simplify */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h new file mode 100644 index 0000000000000000000000000000000000000000..c21dc2d49b4ea58cac444d820cf6535943f6c319 --- /dev/null +++ b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h @@ -0,0 +1,43 @@ +/* + * MinimizeBrzozowski.cpp + * + * Created on: 18. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef MINIMIZE_BRZOZOWSKI_H_ +#define MINIMIZE_BRZOZOWSKI_H_ + +#include <automaton/Automaton.h> +#include <automaton/FSM/DFA.h> + +namespace automaton { + +namespace simplify { + +class MinimizeBrzozowski : public automaton::VisitableConstFSMBase { +public: + /** + * @param dfa automaton to minimize + */ + static automaton::Automaton minimize(const automaton::Automaton& dfa); + + static automaton::DFA minimize(const automaton::DFA& dfa); + static automaton::DFA minimize(const automaton::NFA& nfa); + +protected: + void Visit(void*, const automaton::EpsilonNFA& automaton) const; + void Visit(void*, const automaton::MultiInitialStateNFA& automaton) const; + void Visit(void*, const automaton::NFA& automaton) const; + void Visit(void*, const automaton::DFA& automaton) const; + void Visit(void*, const automaton::ExtendedNFA& automaton) const; + void Visit(void*, const automaton::CompactNFA& automaton) const; + + static const MinimizeBrzozowski MINIMIZE_BRZOZOWSKI; +}; + +} /* namespace simplify */ + +} /* namespace automaton */ + +#endif /* MINIMIZE_BRZOZOWSKI_H_ */ diff --git a/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef1daf2b4080d49f85ff999a68f7576f902d94ad --- /dev/null +++ b/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp @@ -0,0 +1,38 @@ +#include <list> +#include "minimizeBrzozowskiTest.h" + +#include "automaton/simplify/MinimizeBrzozowski.h" +#include "automaton/simplify/Minimize.h" +#include "automaton/simplify/Trim.h" +#include "automaton/simplify/Normalize.h" + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +CPPUNIT_TEST_SUITE_REGISTRATION( minimizeBrzozowskiTest ); + +void minimizeBrzozowskiTest::setUp() { +} + +void minimizeBrzozowskiTest::tearDown() { +} + +void minimizeBrzozowskiTest::testMinimizeBrzozowski() { + automaton::DFA automaton(automaton::State(1)); + + automaton.addState(automaton::State(1)); + automaton.addState(automaton::State(2)); + automaton.addState(automaton::State(3)); + automaton.addInputSymbol(alphabet::symbolFrom("a")); + automaton.addInputSymbol(alphabet::symbolFrom("b")); + + automaton.addTransition(automaton::State(1), alphabet::symbolFrom("a"), automaton::State(2)); + automaton.addTransition(automaton::State(2), alphabet::symbolFrom("b"), automaton::State(1)); + + automaton.addFinalState(automaton::State(3)); + + automaton::DFA minimizedHopcroft = automaton::simplify::Minimize::minimize(automaton); + automaton::DFA minimizedBrzozowski = automaton::simplify::MinimizeBrzozowski::minimize(automaton); + + CPPUNIT_ASSERT(minimizedHopcroft.getStates().size() == 3); + CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(minimizedHopcroft)) == automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(minimizedBrzozowski))); +} diff --git a/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.h b/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.h new file mode 100644 index 0000000000000000000000000000000000000000..0039075c8bd7e0694a142f36f6ee72a73709e47c --- /dev/null +++ b/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.h @@ -0,0 +1,19 @@ +#ifndef MINIMIZE_BRZOZOWSKI_TEST_H_ +#define MINIMIZE_BRZOZOWSKI_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class minimizeBrzozowskiTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( minimizeBrzozowskiTest ); + CPPUNIT_TEST( testMinimizeBrzozowski ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testMinimizeBrzozowski(); +}; + +#endif // MINIMIZE_BRZOZOWSKI_TEST_H_