diff --git a/.gitignore b/.gitignore index 8c277efa2dc19ddee0de9ab1ccefbe812c98ce32..9fb9db37f64008a762c83f67d82ff6c9226b69fb 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ Doxyfile documentation/* +bin/* +**/bin +**/obj diff --git a/acat/makefile b/acat/makefile index 2921dd1af3ec76cee85bd4c5b138981ddcea16a3..96ad4cb446cb47b648699e7bb2e69b5b9e001057 100644 --- a/acat/makefile +++ b/acat/makefile @@ -1,13 +1,20 @@ -APPLICATION=acat -CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -LDFLAGS= -L ../alib -lxml2 -lalib +CC=g++ +EXECUTIBLE=acat +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L ../alib/bin -lxml2 -lalib +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) -SOURCES = src/*.cpp +all: $(SOURCES) bin/$(EXECUTIBLE) -all: - g++ $(CXXFLAGS) $(SOURCES) - g++ $(LDFLAGS) *.o -o $(APPLICATION) +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ clean: - $(RM) *.o *.d $(APPLICATION) + $(RM) -r *.o *.d bin obj diff --git a/aconvert.dot/makefile b/aconvert.dot/makefile index 5be1ed48cce675ba753cb980b0c3f22832e373b5..a2e1c7e6f56909ca1dc58a309125a2a24c79221b 100644 --- a/aconvert.dot/makefile +++ b/aconvert.dot/makefile @@ -1,13 +1,20 @@ -APPLICATION=aconvert.dot -CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -LDFLAGS= -L ../alib -lxml2 -lalib +CC=g++ +EXECUTIBLE=aconvert.dot +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L ../alib/bin -lxml2 -lalib +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) -SOURCES = src/*.cpp +all: $(SOURCES) bin/$(EXECUTIBLE) -all: - g++ $(CXXFLAGS) $(SOURCES) - g++ $(LDFLAGS) *.o -o $(APPLICATION) +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ clean: - $(RM) *.o *.d $(APPLICATION) + $(RM) -r *.o *.d bin obj diff --git a/aconvert.gastex/makefile b/aconvert.gastex/makefile index 452c48558e1cbc13268820a456699ff963c37594..46efb94eceaee61285237ff86f49fa7816e06427 100644 --- a/aconvert.gastex/makefile +++ b/aconvert.gastex/makefile @@ -1,13 +1,20 @@ -APPLICATION=aconvert.gastex -CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -LDFLAGS= -L ../alib -lxml2 -lalib +CC=g++ +EXECUTIBLE=aconvert.gastex +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L ../alib/bin -lxml2 -lalib +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) -SOURCES = src/*.cpp +all: $(SOURCES) bin/$(EXECUTIBLE) -all: - g++ $(CXXFLAGS) $(SOURCES) - g++ $(LDFLAGS) *.o -o $(APPLICATION) +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ clean: - $(RM) *.o *.d $(APPLICATION) + $(RM) -r *.o *.d bin obj diff --git a/aconvert/makefile b/aconvert/makefile index f285c3717ec843277bf4adbfd8de2a43196c2fb0..a02e63209cfa9e94c892323331fd72e16bdc7f1e 100644 --- a/aconvert/makefile +++ b/aconvert/makefile @@ -1,13 +1,20 @@ -APPLICATION=aconvert -CXXFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -LDFLAGS= -L ../alib -lxml2 -lalib +CC=g++ +EXECUTIBLE=aconvert +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L ../alib/bin -lxml2 -lalib +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) -SOURCES = src/*.cpp +all: $(SOURCES) bin/$(EXECUTIBLE) -all: - g++ $(CXXFLAGS) $(SOURCES) - g++ $(LDFLAGS) *.o -o $(APPLICATION) +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ clean: - $(RM) *.o *.d $(APPLICATION) + $(RM) -r *.o *.d bin obj diff --git a/alib/makefile b/alib/makefile index 6d1a3f5044f28a72b55b7a2ed38087894214d11d..73250891cf3c3a53e5638f01a4d6dfcf63a6a572 100644 --- a/alib/makefile +++ b/alib/makefile @@ -1,13 +1,20 @@ +CC=g++ LIBRARY=libalib.so -CXXFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I/usr/include/libxml2/ +CCFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I/usr/include/libxml2/ LDFLAGS= -shared -lxml2 +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) -SOURCES = src/automaton/*.cpp src/automaton/TM/*.cpp src/automaton/FSM/*.cpp src/automaton/PDA/*cpp src/automaton/exception/*.cpp src/regexp/*.cpp src/grammar/*.cpp src/grammar/Regular/*.cpp src/grammar/Linear/*.cpp src/grammar/Unrestricted/*.cpp src/grammar/ContextSensitive/*.cpp src/grammar/ContextFree/*.cpp src/sax/*.cpp src/alphabet/*.cpp src/*.cpp +all: $(SOURCES) bin/$(LIBRARY) -all: - g++ $(CXXFLAGS) $(SOURCES) - g++ $(LDFLAGS) *.o -o $(LIBRARY) +bin/$(LIBRARY): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ clean: - $(RM) *.o *.d $(LIBRARY) + $(RM) -r *.o *.d bin obj diff --git a/aminimize/aminimize b/aminimize/aminimize new file mode 100755 index 0000000000000000000000000000000000000000..b2e934a7b987719ca5177a36bb85151f7234a035 Binary files /dev/null and b/aminimize/aminimize differ diff --git a/aminimize/makefile b/aminimize/makefile new file mode 100644 index 0000000000000000000000000000000000000000..386f490424c05116b84b569208da51d39ba2b383 --- /dev/null +++ b/aminimize/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aminimize +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L ../alib/bin -lxml2 -lalib + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aminimize/src/Minimize.cpp b/aminimize/src/Minimize.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94834d87b40134778a60245c7244628a56eabe0a --- /dev/null +++ b/aminimize/src/Minimize.cpp @@ -0,0 +1,121 @@ +/* + * Minimize.cpp + * + * Created on: Dec 9, 2013 + * Author: honza + */ + +#include "Minimize.h" + +#include <map> +#include <set> +#include <sstream> +#include <iostream> + +#include "alphabet/Symbol.h" +#include "automaton/FSM/TransitionFSM.h" + +automaton::State fromInteger(int number) { + std::stringstream ss; + ss << number; + return automaton::State(ss.str()); +} + +automaton::FSM Minimize::minimize(automaton::FSM& fsm) { + std::map<automaton::State, std::map<alphabet::Symbol, automaton::State > > refactor; + + for(std::set<automaton::TransitionFSM>::const_iterator iter = fsm.getTransitions().begin(); iter != fsm.getTransitions().end(); iter++) { + if(refactor.find(iter->getFrom()) == refactor.end()) { + refactor.insert(std::pair<automaton::State, std::map<alphabet::Symbol, automaton::State> >(iter->getFrom(), std::map<alphabet::Symbol, automaton::State>())); + } + refactor[iter->getFrom()].insert(std::pair<alphabet::Symbol, automaton::State>(iter->getInput(), iter->getTo())); + } + + std::map<automaton::State, automaton::State> toEquvivalentStates1;//original state to equivalent state + std::map<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> > minimizedTransitionFunction1; //mapped to the original state + + std::map<automaton::State, automaton::State> toEquvivalentStates2; + std::map<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> > minimizedTransitionFunction2; + + for(auto iter = fsm.getStates().begin(); iter != fsm.getStates().end(); iter++) { + if(fsm.getFinalStates().count(*iter) == 0) { // not a final state + toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter, automaton::State("0"))); + } else { + toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter, automaton::State("1"))); + } + } + + for(auto iter = refactor.begin(); iter != refactor.end(); iter++) { + automaton::State from = toEquvivalentStates2.find(iter->first)->second; + std::set<std::pair<alphabet::Symbol, automaton::State> > transitionFunction; + + for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + transitionFunction.insert(std::pair<alphabet::Symbol, automaton::State>(iter2->first, toEquvivalentStates2.find(iter2->second)->second)); + } + + std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > > key(from, transitionFunction); + + if(minimizedTransitionFunction2.find(key) == minimizedTransitionFunction2.end()) { + minimizedTransitionFunction2.insert(std::pair<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> >(key, std::set<automaton::State>())); + } + minimizedTransitionFunction2[key].insert(iter->first); + } + + do { + toEquvivalentStates1 = toEquvivalentStates2; + minimizedTransitionFunction1 = minimizedTransitionFunction2; + + toEquvivalentStates2.clear(); + minimizedTransitionFunction2.clear(); + + int number = 0; + for(auto iter = minimizedTransitionFunction1.begin(); iter != minimizedTransitionFunction1.end(); iter++) { + for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter2, fromInteger(number))); + } + number++; + } + + for(auto iter = refactor.begin(); iter != refactor.end(); iter++) { + automaton::State from = toEquvivalentStates2.find(iter->first)->second; + std::set<std::pair<alphabet::Symbol, automaton::State> > transitionFunction; + + for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + transitionFunction.insert(std::pair<alphabet::Symbol, automaton::State>(iter2->first, toEquvivalentStates2.find(iter2->second)->second)); + } + + std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > > key(from, transitionFunction); + + if(minimizedTransitionFunction2.find(key) == minimizedTransitionFunction2.end()) { + minimizedTransitionFunction2.insert(std::pair<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> >(key, std::set<automaton::State>())); + } + + minimizedTransitionFunction2[key].insert(iter->first); + + } + + } while(toEquvivalentStates1 != toEquvivalentStates2); + + automaton::FSM result; + for(auto iter = fsm.getInputAlphabet().begin(); iter != fsm.getInputAlphabet().end(); iter++) { + result.addInputSymbol(*iter); + } + + for(auto iter = minimizedTransitionFunction2.begin(); iter != minimizedTransitionFunction2.end(); iter++) { + result.addState(iter->first.first); + if(fsm.getFinalStates().find(*(iter->second.begin())) != fsm.getFinalStates().end()) {//TODO improve using intersection + result.addFinalState(iter->first.first); + } + if(iter->second.find(*(fsm.getInitialStates().begin())) != iter->second.end()) { //TODO improve using intersection + result.addInitialState(iter->first.first); + } + } + + for(auto iter = minimizedTransitionFunction2.begin(); iter != minimizedTransitionFunction2.end(); iter++) { + for(auto iter2 = iter->first.second.begin(); iter2 != iter->first.second.end(); iter2++) { + result.addTransition(iter->first.first, iter2->first, iter2->second); + } + } + + return result; +} diff --git a/aminimize/src/Minimize.h b/aminimize/src/Minimize.h new file mode 100644 index 0000000000000000000000000000000000000000..51db0171dad5b1908f7fdc7f79e5600c32247a5e --- /dev/null +++ b/aminimize/src/Minimize.h @@ -0,0 +1,19 @@ +/* + * Minimize.h + * + * Created on: Dec 9, 2013 + * Author: honza + */ + +#ifndef MINIMIZE_H_ +#define MINIMIZE_H_ + +#include "automaton/FSM/FSM.h" + +class Minimize { +public: + static automaton::FSM minimize(automaton::FSM& fsm); + +}; + +#endif /* MINIMIZE_H_ */ diff --git a/aminimize/src/aminimize.cpp b/aminimize/src/aminimize.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f4e5a4e0ed7d3299407e6316f57fb7520d20b5d6 --- /dev/null +++ b/aminimize/src/aminimize.cpp @@ -0,0 +1,57 @@ +//============================================================================ +// Name : aminimize.cpp +// Author : Jan Travnicek +//============================================================================ + +#include <iostream> +#include <string> +#include <set> + +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "automaton/AutomatonParser.h" + +#include "Minimize.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 minimize.\nUsage: aminimize automaton.xml\n"; + return -1; + } + + if (argc == 2) { + automaton = AutomatonFactory::fromFile(argv[1]); + if(!AutomatonFactory::isFSM(automaton)) { + cout << "Automaton minimize require deterministic finite automaton\n"; + return 1; + } + + automaton::FSM fsm = AutomatonFactory::buildFSM(automaton); + if(!fsm.isDeterministic()) { + cout << "Automaton minimize require deterministic finite automaton\n"; + return 1; + } + + automaton::FSM res = Minimize::minimize(fsm); + res.toXML(cout); + + return 0; + } + cout << "Automaton minimize require finite automaton\n"; + return 1; + + } catch (AlibException& e) { + cout << e.getCause() << endl; + return 0; + } + +} diff --git a/makefile b/makefile index 52cc33dfa4ba118f9ea7e57a8617c7d582f6d525..86e7d04447117b75d39873517f49dc39473fd393 100644 --- a/makefile +++ b/makefile @@ -2,28 +2,30 @@ APPPATH = /usr/bin LIBPATH = /usr/lib/ BINFOLDER = bin -SUBDIRS = alib acat aconvert aconvert.dot aconvert.gastex +SUBDIRS = alib acat aconvert aconvert.dot aconvert.gastex aminimize .PHONY: subdirs $(SUBDIRS) all: $(SUBDIRS) copy + $(SUBDIRS): $(MAKE) -C $@ copy: rm -rf $(BINFOLDER) mkdir $(BINFOLDER) - cp alib/libalib.so $(BINFOLDER) - cp alib/libalib.so $(BINFOLDER) - cp acat/acat $(BINFOLDER) - cp aconvert/aconvert $(BINFOLDER) - cp aconvert.dot/aconvert.dot $(BINFOLDER) - cp aconvert.gastex/aconvert.gastex $(BINFOLDER) + cp alib/bin/libalib.so $(BINFOLDER) + cp acat/bin/acat $(BINFOLDER) + cp aconvert/bin/aconvert $(BINFOLDER) + cp aconvert.dot/bin/aconvert.dot $(BINFOLDER) + cp aconvert.gastex/bin/aconvert.gastex $(BINFOLDER) + cp aminimize/bin/aminimize $(BINFOLDER) install: - cp alib/libalib.so $(LIBPATH) - cp acat/acat $(APPPATH) - cp aconvert/aconvert $(APPPATH) - cp aconvert.dot/aconvert.dot $(APPPATH) - cp aconvert.gastex/aconvert.gastex $(APPPATH) + cp alib/bin/libalib.so $(LIBPATH) + cp acat/bin/acat $(APPPATH) + cp aconvert/bin/aconvert $(APPPATH) + cp aconvert.dot/bin/aconvert.dot $(APPPATH) + cp aconvert.gastex/bin/aconvert.gastex $(APPPATH) + cp aminimize/bin/aminimize $(APPPATH) uninstall: rm $(LIBPATH)/libalib.so @@ -31,3 +33,4 @@ uninstall: rm $(APPPATH)/aconvert rm $(APPPATH)/aconvert.dot rm $(APPPATH)/aconvert.gastex + rm $(APPPATH)/aminimize