diff --git a/alib2algo/src/normalize/dfa/NormalizeDFA.cpp b/alib2algo/src/normalize/dfa/NormalizeDFA.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d69cd4fa1d21669b48311ccdeaf6a5d8615d5e4d --- /dev/null +++ b/alib2algo/src/normalize/dfa/NormalizeDFA.cpp @@ -0,0 +1,74 @@ +/* + * NormalizeDFA.cpp + * + * Created on: Dec 9, 2013 + * Author: JanTravnicek */ + +#include "NormalizeDFA.h" + +#include <map> +#include <deque> +#include <vector> +#include <set> +#include <algorithm> +#include <sstream> +#include <iostream> +#include "exception/AlibException.h" + +#include "alphabet/Symbol.h" +#include "label/Label.h" +#include "label/IntegerLabel.h" + +namespace normalize { + +automaton::State fromInteger(int number) { + return automaton::State(label::Label(label::IntegerLabel(number))); +} + +automaton::DFA NormalizeDFA::normalize(automaton::DFA& fsm) { + int counter = 0; + std::map<automaton::State, int > normalizationData; + std::deque<automaton::State > processingData; + + normalizationData.insert(std::pair<automaton::State, int>(fsm.getInitialState(), counter++)); + processingData.push_back(fsm.getInitialState()); + + while(!processingData.empty()) { + automaton::State current = processingData.front(); + processingData.pop_front(); + + std::map<std::pair<automaton::State, alphabet::Symbol>, automaton::State> transitionsMap = fsm.getTransitionsFromState(current); + // Transitions are trivialy sorted by input symbol (from state is the same) + + for(auto iter = fsm.getTransitions().begin(); iter != fsm.getTransitions().end(); iter++) { + if(normalizationData.find(iter->second) == normalizationData.end()) { + normalizationData.insert(std::pair<automaton::State, int>(iter->second, counter++)); + processingData.push_back(iter->second); + } + } + } + + if(normalizationData.size() != fsm.getStates().size()) { + throw exception::AlibException("Automaton normalize require minimal deterministic finite automaton"); + } + + automaton::DFA result(fromInteger(normalizationData.find(fsm.getInitialState())->second)); + + result.setInputSymbols(fsm.getInputAlphabet()); + + for(auto iter = fsm.getStates().begin(); iter != fsm.getStates().end(); iter++) { + result.addState(fromInteger(normalizationData.find(*iter)->second)); + } + + for(auto iter = fsm.getFinalStates().begin(); iter != fsm.getFinalStates().end(); iter++) { + result.addFinalState(fromInteger(normalizationData.find(*iter)->second)); + } + + for(auto iter = fsm.getTransitions().begin(); iter != fsm.getTransitions().end(); iter++) { + result.addTransition(fromInteger(normalizationData.find(iter->first.first)->second), iter->first.second, fromInteger(normalizationData.find(iter->second)->second)); + } + + return result; +} + +} diff --git a/alib2algo/src/normalize/dfa/NormalizeDFA.h b/alib2algo/src/normalize/dfa/NormalizeDFA.h new file mode 100644 index 0000000000000000000000000000000000000000..9980cbad5bc957de97a94e19e2fbc6ac946e8f72 --- /dev/null +++ b/alib2algo/src/normalize/dfa/NormalizeDFA.h @@ -0,0 +1,23 @@ +/* + * NormalizeDFA.h + * + * Created on: Dec 9, 2013 + * Author: Jan Travnicek + */ + +#ifndef NORMALIZE_DFA_H_ +#define NORMALIZE_DFA_H_ + +#include "automaton/FSM/DFA.h" + +namespace normalize { + +class NormalizeDFA { +public: + static automaton::DFA normalize(automaton::DFA& dfa); + +}; + +} + +#endif /* NORMALIZE_DFA_H_ */ diff --git a/alib2algo/test-src/normalize/normalizeTest.cpp b/alib2algo/test-src/normalize/normalizeTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f2a10cf3483318737dd2bcdaffaf4613fef048bf --- /dev/null +++ b/alib2algo/test-src/normalize/normalizeTest.cpp @@ -0,0 +1,39 @@ +#include <list> +#include "normalizeTest.h" + +#include "label/StringLabel.h" +#include "label/IntegerLabel.h" +#include "label/Label.h" +#include "alphabet/LabeledSymbol.h" + +#include "normalize/dfa/NormalizeDFA.h" + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) + +CPPUNIT_TEST_SUITE_REGISTRATION( normalizeTest ); + +void normalizeTest::setUp() { +} + +void normalizeTest::tearDown() { +} + +void normalizeTest::testNormalize() { + automaton::DFA automaton(automaton::State(label::Label(label::IntegerLabel(1)))); + + automaton.addState(automaton::State(label::Label(label::IntegerLabel(1)))); + automaton.addState(automaton::State(label::Label(label::IntegerLabel(2)))); + automaton.addState(automaton::State(label::Label(label::IntegerLabel(3)))); + automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a"))))); + automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b"))))); + + automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), automaton::State(label::Label(label::IntegerLabel(2)))); + automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(2))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), automaton::State(label::Label(label::IntegerLabel(3)))); + + automaton.addFinalState(automaton::State(label::Label(label::IntegerLabel(3)))); + + automaton::DFA normalized = normalize::NormalizeDFA::normalize(automaton); + + CPPUNIT_ASSERT(normalized.getStates().size() == 3); + +} diff --git a/alib2algo/test-src/normalize/normalizeTest.h b/alib2algo/test-src/normalize/normalizeTest.h new file mode 100644 index 0000000000000000000000000000000000000000..3f915a48618e92b23cda43113a761c04100bc110 --- /dev/null +++ b/alib2algo/test-src/normalize/normalizeTest.h @@ -0,0 +1,19 @@ +#ifndef NORMALIZE_TEST_H_ +#define NORMALIZE_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class normalizeTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( normalizeTest ); + CPPUNIT_TEST( testNormalize ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testNormalize(); +}; + +#endif // NORMALIZE_TEST_H_ diff --git a/anormalize/makefile b/anormalize/makefile deleted file mode 100644 index e05c42a1e0668fd3763ffc0ae8d5f5ebad7fd9d6..0000000000000000000000000000000000000000 --- a/anormalize/makefile +++ /dev/null @@ -1,20 +0,0 @@ -CC=g++ -EXECUTABLE=anormalize -CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. - -SOURCES=$(shell find src/ -name *cpp) -OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) - -all: $(SOURCES) bin/$(EXECUTABLE) - -bin/$(EXECUTABLE): $(OBJECTS) - mkdir -p bin - $(CC) $(OBJECTS) -o $@ $(LDFLAGS) - -obj/%.o: src/%.cpp - mkdir -p $(dir $@) - $(CC) $(CCFLAGS) $< -o $@ - -clean: - $(RM) -r *.o *.d bin obj diff --git a/anormalize/src/Normalize.cpp b/anormalize/src/Normalize.cpp deleted file mode 100644 index d5bfa73f2d0a3034be41e9e820d486941eb5d1b6..0000000000000000000000000000000000000000 --- a/anormalize/src/Normalize.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Normalize.cpp - * - * Created on: Dec 9, 2013 - * Author: honza - */ - -#include "Normalize.h" - -#include <map> -#include <deque> -#include <vector> -#include <set> -#include <algorithm> -#include <sstream> -#include <iostream> -#include "AlibException.h" - -#include "alphabet/Symbol.h" -#include "automaton/FSM/TransitionFSM.h" - -automaton::State fromInteger(int number) { - std::stringstream ss; - ss << number; - return automaton::State(ss.str()); -} - -bool transitionSymbolComparator(const automaton::TransitionFSM& a, const automaton::TransitionFSM& b) { - return a.getInput() < b.getInput(); -} - -automaton::FSM Normalize::normalize(automaton::FSM& fsm) { - int counter = 0; - std::map<automaton::State, int > normalizationData; - std::deque<automaton::State > processingData; - - normalizationData.insert(std::pair<automaton::State, int>(*(fsm.getInitialStates().begin()), counter++)); - processingData.push_back(*(fsm.getInitialStates().begin())); - - while(!processingData.empty()) { - automaton::State current = processingData.front(); - processingData.pop_front(); - - const std::set<automaton::TransitionFSM> transitionsSet = fsm.getTransitionsFromState(current); - std::vector<automaton::TransitionFSM> transitions; - - std::copy(transitionsSet.begin(), transitionsSet.end(), std::back_inserter(transitions)); - std::sort (transitions.begin(), transitions.end(), transitionSymbolComparator); - - for(auto iter = transitions.begin(); iter != transitions.end(); iter++) { - if(normalizationData.find(iter->getTo()) == normalizationData.end()) { - normalizationData.insert(std::pair<automaton::State, int>(iter->getTo(), counter++)); - processingData.push_back(iter->getTo()); - } - } - } - - if(normalizationData.size() != fsm.getStates().size()) { - throw alib::AlibException("Automaton normalize require minimal deterministic finite automaton"); - } - - automaton::FSM result; - for(auto iter = fsm.getInputAlphabet().begin(); iter != fsm.getInputAlphabet().end(); iter++) { - result.addInputSymbol(*iter); - } - - for(auto iter = fsm.getStates().begin(); iter != fsm.getStates().end(); iter++) { - result.addState(fromInteger(normalizationData.find(*iter)->second)); - } - - for(auto iter = fsm.getInitialStates().begin(); iter != fsm.getInitialStates().end(); iter++) { - result.addInitialState(fromInteger(normalizationData.find(*iter)->second)); - } - - for(auto iter = fsm.getFinalStates().begin(); iter != fsm.getFinalStates().end(); iter++) { - result.addFinalState(fromInteger(normalizationData.find(*iter)->second)); - } - - for(auto iter = fsm.getTransitions().begin(); iter != fsm.getTransitions().end(); iter++) { - result.addTransition(fromInteger(normalizationData.find(iter->getFrom())->second), iter->getInput(), fromInteger(normalizationData.find(iter->getTo())->second)); - } - - return result; -} diff --git a/anormalize/src/Normalize.h b/anormalize/src/Normalize.h deleted file mode 100644 index b88cba329d6e08a8b34620a6bbe0fe5978c62a8c..0000000000000000000000000000000000000000 --- a/anormalize/src/Normalize.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Normalize.h - * - * Created on: Dec 9, 2013 - * Author: honza - */ - -#ifndef NORMALIZE_H -#define NORMALIZE_H - -#include "automaton/FSM/FSM.h" - -class Normalize { -public: - static automaton::FSM normalize(automaton::FSM& fsm); - -}; - -#endif /* NORMALIZE_H */ diff --git a/anormalize/src/anormalize.cpp b/anormalize/src/anormalize.cpp deleted file mode 100644 index 04d426d48fb282e38bf4d52da98ca7fba751f2d4..0000000000000000000000000000000000000000 --- a/anormalize/src/anormalize.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//============================================================================ -// Name : aminimize.cpp -// Author : Jan Travnicek -//============================================================================ - -#include <iostream> -#include <string> -#include <set> - -#include "AutomatonFactory.h" -#include "AlibException.h" -#include "automaton/AutomatonParser.h" - -#include "Normalize.h" - -using namespace std; -using namespace automaton; -using namespace alib; - -int main(int argc, char** argv) { - - UnknownAutomaton automaton; - - try { - - if (argc == 2 && string("-h").compare(argv[1]) == 0) { - cout << "Automaton normalize.\nUsage: anormalize automaton.xml\n"; - return -1; - } else if (argc == 1 || (argc == 2 && string("--").compare(argv[1]) == 0)) { - automaton = AutomatonFactory::fromStdin(); - if(!AutomatonFactory::isFSM(automaton)) { - cout << "Automaton normalize require minimal deterministic finite automaton\n"; - return 1; - } - } else if (argc == 2) { - automaton = AutomatonFactory::fromFile(argv[1]); - if(!AutomatonFactory::isFSM(automaton)) { - cout << "Automaton normalize require minimal deterministic finite automaton\n"; - return 1; - } - } else { - cout << "Automaton normalize require finite automaton\n"; - return 1; - } - automaton::FSM fsm = AutomatonFactory::buildFSM(automaton); - if(!fsm.isDeterministic()) { - cout << "Automaton normalize require minimal deterministic finite automaton\n"; - return 1; - } - - automaton::FSM res = Normalize::normalize(fsm); - res.toXML(cout); - - return 0; - - } catch (AlibException& e) { - cout << e.getCause() << endl; - return 0; - } - -} diff --git a/anormalize2/makefile b/anormalize2/makefile new file mode 100644 index 0000000000000000000000000000000000000000..1171e3d55d81e7a2b2e7e9bbfb08180e66798891 --- /dev/null +++ b/anormalize2/makefile @@ -0,0 +1,73 @@ +SHELL:=/bin/bash +EXECUTABLE:=anormalize2 + +LDFLAGS= -L../alib2data/lib -L../alib2algo/lib -rdynamic -lxml2 -lalib2data -lalib2algo -Wl,-rpath,. + +OBJECTS:=$(patsubst src/%.cpp, obj/%.o, $(shell find src/ -name *cpp)) + +.PHONY: all build clean + +all: build + + + +bin/$(EXECUTABLE): obj/ $(OBJECTS) + mkdir -p bin + $(CXX) $(OBJECTS) -o $@ $(LDFLAGS) + +obj/makefile: makefile + mkdir -p $(dir $@) + echo "SHELL:=/bin/bash" >> $@ + echo "SRCDIR:=" >> $@ + echo "DEPTH:=" >> $@ + echo "" >> $@ + echo "CXXFLAGS:= -std=c++11 -Og -g -c -Wall -pedantic -Wextra -I../../\$$(DEPTH)alib2data/src/ -I../../\$$(DEPTH)alib2algo/src -I/usr/include/libxml2/" >> $@ + echo "" >> $@ + echo "SOURCES:= \$$(shell find ../\$$(DEPTH)src/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")" >> $@ + echo "DEPENDENCIES:= \$$(patsubst ../\$$(DEPTH)src/\$$(SRCDIR)%.cpp, ../\$$(DEPTH)obj/\$$(SRCDIR)%.d, \$$(SOURCES))" >> $@ + echo "OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))" >> $@ + echo "SOURCES_DIRS:= \$$(shell find ../\$$(DEPTH)src/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)" >> $@ + echo "OBJECTS_DIRS:= \$$(patsubst ../\$$(DEPTH)src/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))" >> $@ + echo "OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))" >> $@ + echo "" >> $@ + echo ".PHONY: all" >> $@ + echo ".PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)" >> $@ + echo "" >> $@ + echo "all: \$$(OBJECTS_DIRS) \$$(OBJECTS)" >> $@ + echo "" >> $@ + echo "%.d:" >> $@ + echo " @echo \"\$$(shell sha1sum <<< \"\$$@\" | sed \"s/ -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -MM \\$$\$$(CXXFLAGS) \$$(patsubst ../\$$(DEPTH)obj/\$$(SRCDIR)%.d,../\$$(DEPTH)src/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst ../\$$(DEPTH)obj/\$$(SRCDIR)%.d,../\$$(DEPTH)src/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\" >> \$$@" >> $@ + echo " @echo \"\$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/ -//g\"))\" >> \$$@" >> $@ + echo " @echo \" \\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\" >> \$$@" >> $@ + echo "" >> $@ + echo "%/makefile:" >> $@ + echo " mkdir -p \$$(dir \$$@)" >> $@ + echo " cp makefile \$$@" >> $@ + echo "" >> $@ + echo "%/: FORCE | %/makefile" >> $@ + echo " @accesstime=\`stat -c %Y \$$@\` && \\" >> $@ + echo " \$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ DEPTH=\$$(DEPTH)../ && \\" >> $@ + echo " accesstime2=\`stat -c %Y \$$@\` && \\" >> $@ + echo " if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\" >> $@ + echo " touch .; \\" >> $@ + echo " fi" >> $@ + echo "" >> $@ + echo "FORCE:" >> $@ + echo "" >> $@ + echo "-include \$$(DEPENDENCIES)" >> $@ + +obj/: FORCE | obj/makefile + $(MAKE) -C $@ + +$(OBJECTS): obj/ + + +build: bin/$(EXECUTABLE) + + + +clean: + $(RM) -r *.o *.d bin lib obj test-bin test-obj + +FORCE: + diff --git a/anormalize2/src/anormalize.cpp b/anormalize2/src/anormalize.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0c76be0727c4378c6b59953a7e04254d5db3b60a --- /dev/null +++ b/anormalize2/src/anormalize.cpp @@ -0,0 +1,45 @@ +//============================================================================ +// Name : anormalize.cpp +// Author : Jan Travnicek +//============================================================================ + +#include <iostream> +#include <string> +#include <set> + +#include "exception/AlibException.h" +#include "factory/DataFactory.hpp" +#include "normalize/dfa/NormalizeDFA.h" + +int main(int argc, char** argv) { + + try { + + automaton::DFA* automatonPointer = NULL; + + if (argc == 2 && std::string("-h").compare(argv[1]) == 0) { + std::cout << "Automaton normalize." << std::endl << "Usage: anormalize automaton.xml" << std::endl; + return -1; + } else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) { + automatonPointer = static_cast<automaton::DFA*>(std::move(alib::DataFactory::fromStdin<automaton::DFA>()).plunder()); + } else if (argc == 2) { + automatonPointer = static_cast<automaton::DFA*>(std::move(alib::DataFactory::fromFile<automaton::DFA>(argv[1])).plunder()); + } else { + std::cout << "Automaton normalize require deterministic finite automaton" << std::endl; + return 1; + } + + automaton::DFA res = normalize::NormalizeDFA::normalize(*automatonPointer); + alib::DataFactory::toStdout(res); + + delete automatonPointer; + + return 0; + + } catch (const exception::AlibException& exception) { + alib::DataFactory::toStdout(exception); + return 1; + } catch(...) { + return 127; + } +}