diff --git a/alib/src/alphabet/Symbol.cpp b/alib/src/alphabet/Symbol.cpp index c03d42d206922bd702909563243a0d4b43f15d88..b16010e82870a00571823f18cc478b699397e20b 100644 --- a/alib/src/alphabet/Symbol.cpp +++ b/alib/src/alphabet/Symbol.cpp @@ -25,6 +25,10 @@ bool Symbol::operator ==(const Symbol& other) const { return symbol == other.symbol; } +bool Symbol::operator >(const Symbol& other) const { + return symbol > other.symbol; +} + bool Symbol::operator !=(const Symbol& other) const { return symbol != other.symbol; } diff --git a/alib/src/alphabet/Symbol.h b/alib/src/alphabet/Symbol.h index a49c107b604ed648cd30b9a99b6a7b5cae9451a0..9b82e08a355cdef5843cdcedb027776e28b0a95c 100644 --- a/alib/src/alphabet/Symbol.h +++ b/alib/src/alphabet/Symbol.h @@ -33,6 +33,7 @@ public: bool operator <(const Symbol& other) const; bool operator ==(const Symbol& other) const; + bool operator >(const Symbol& other) const; bool operator !=(const Symbol& other) const; friend std::ostream& operator<<(std::ostream&, const Symbol&); diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp index 2103548d5353a39f940ef9bb52be9ab5cace74d4..2284faced6c636d5feb64dafb417ad1bf8a6b4fc 100644 --- a/alib/src/regexp/Alternation.cpp +++ b/alib/src/regexp/Alternation.cpp @@ -54,6 +54,81 @@ RegExpElement* Alternation::clone() const { return new Alternation(*this); } +bool Alternation::operator<(const RegExpElement& other) const { + return !(other > *this || other == *this); +} + +bool Alternation::operator==(const RegExpElement& other) const { + return other == *this; +} + +bool Alternation::operator>(const RegExpElement& other) const { + return !(other < *this || other == *this); +} + + +bool Alternation::operator<(const Concatenation&) const { + return true; +} + +bool Alternation::operator<(const Alternation& other) const { + int thisSize = this->elements.size(); + int otherSize = other.elements.size(); + if(thisSize < otherSize) return true; + if(thisSize > otherSize) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter < **otherIter) return true; + } + + return false; +} + +bool Alternation::operator==(const Alternation& other) const { + if(this->elements.size() != other.elements.size()) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter != **otherIter) return false; + } + + return true; +} + +bool Alternation::operator>(const Alternation& other) const { + int thisSize = this->elements.size(); + int otherSize = other.elements.size(); + if(thisSize < otherSize) return false; + if(thisSize > otherSize) return true; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter > **otherIter) return true; + } + + return false; +} + +bool Alternation::operator>(const Iteration&) const { + return true; +} + +bool Alternation::operator>(const RegExpSymbol&) const { + return true; +} + +bool Alternation::operator>(const RegExpEpsilon&) const { + return true; +} + +bool Alternation::operator>(const RegExpEmpty&) const { + return true; +} + bool Alternation::containsEmptyString() const { for(const auto& e : getElements()) if(e->containsEmptyString()) diff --git a/alib/src/regexp/Alternation.h b/alib/src/regexp/Alternation.h index c237a10498803856e2c026b74fce0869fe6d302e..cfeb34d6395ec965324fc80ab12a9f8abd3521b2 100644 --- a/alib/src/regexp/Alternation.h +++ b/alib/src/regexp/Alternation.h @@ -43,6 +43,19 @@ public: */ RegExpElement* clone() const; + virtual bool operator<(const RegExpElement&) const; + virtual bool operator==(const RegExpElement&) const; + virtual bool operator>(const RegExpElement&) const; + + virtual bool operator<(const Concatenation&) const; + virtual bool operator<(const Alternation&) const; + virtual bool operator==(const Alternation&) const; + virtual bool operator>(const Alternation&) const; + virtual bool operator>(const Iteration&) const; + virtual bool operator>(const RegExpSymbol&) const; + virtual bool operator>(const RegExpEpsilon&) const; + virtual bool operator>(const RegExpEmpty&) const; + /** * @copydoc RegExpElement::containsEmptyString() const */ diff --git a/alib/src/regexp/Concatenation.cpp b/alib/src/regexp/Concatenation.cpp index 1404382056ad880b652b129f1c561289555f48f4..395f02a4d65fad82f6d3b708c7a747fdb43aee7b 100644 --- a/alib/src/regexp/Concatenation.cpp +++ b/alib/src/regexp/Concatenation.cpp @@ -54,6 +54,81 @@ RegExpElement* Concatenation::clone() const { return new Concatenation(*this); } +bool Concatenation::operator<(const RegExpElement& other) const { + return !(other > *this || other == *this); +} + +bool Concatenation::operator==(const RegExpElement& other) const { + return other == *this; +} + +bool Concatenation::operator>(const RegExpElement& other) const { + return !(other < *this || other == *this); +} + + +bool Concatenation::operator<(const Concatenation& other) const { + int thisSize = this->elements.size(); + int otherSize = other.elements.size(); + if(thisSize < otherSize) return true; + if(thisSize > otherSize) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter < **otherIter) return true; + } + + return false; +} + +bool Concatenation::operator==(const Concatenation& other) const { + if(this->elements.size() != other.elements.size()) return false; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter != **otherIter) return false; + } + + return true; +} + +bool Concatenation::operator>(const Concatenation& other) const { + int thisSize = this->elements.size(); + int otherSize = other.elements.size(); + if(thisSize < otherSize) return false; + if(thisSize > otherSize) return true; + + auto thisIter = this->elements.begin(); + auto otherIter = other.elements.begin(); + for(; thisIter != this->elements.end(); thisIter++, otherIter++) { + if(**thisIter > **otherIter) return true; + } + + return false; +} + +bool Concatenation::operator>(const Alternation&) const { + return true; +} + +bool Concatenation::operator>(const Iteration&) const { + return true; +} + +bool Concatenation::operator>(const RegExpSymbol&) const { + return true; +} + +bool Concatenation::operator>(const RegExpEpsilon&) const { + return true; +} + +bool Concatenation::operator>(const RegExpEmpty&) const { + return true; +} + bool Concatenation::containsEmptyString() const { for( const auto& e : getElements()) if( ! e->containsEmptyString()) @@ -62,5 +137,4 @@ bool Concatenation::containsEmptyString() const { return true; } - } /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.h b/alib/src/regexp/Concatenation.h index e239009e0d5d44912e1816587a4b1dc0f5eac021..e35d05eac2b966fb4c2a98ededd1c31f99c1c35f 100644 --- a/alib/src/regexp/Concatenation.h +++ b/alib/src/regexp/Concatenation.h @@ -43,6 +43,19 @@ public: */ RegExpElement* clone() const; + virtual bool operator<(const RegExpElement&) const; + virtual bool operator==(const RegExpElement&) const; + virtual bool operator>(const RegExpElement&) const; + + virtual bool operator<(const Concatenation&) const; + virtual bool operator==(const Concatenation&) const; + virtual bool operator>(const Concatenation&) const; + virtual bool operator>(const Alternation&) const; + virtual bool operator>(const Iteration&) const; + virtual bool operator>(const RegExpSymbol&) const; + virtual bool operator>(const RegExpEpsilon&) const; + virtual bool operator>(const RegExpEmpty&) const; + /** * @copydoc RegExpElement::containsEmptyString() const */ diff --git a/alib/src/regexp/Iteration.cpp b/alib/src/regexp/Iteration.cpp index 3ea0614175d91a2205bd503dea9039764b8659d1..399a3ee371d46cd1596199f751d3c2799def4a46 100644 --- a/alib/src/regexp/Iteration.cpp +++ b/alib/src/regexp/Iteration.cpp @@ -65,6 +65,50 @@ RegExpElement* Iteration::clone() const { return new Iteration(*this); } +bool Iteration::operator<(const RegExpElement& other) const { + return !(other > *this || other == *this); +} + +bool Iteration::operator==(const RegExpElement& other) const { + return other == *this; +} + +bool Iteration::operator>(const RegExpElement& other) const { + return !(other < *this || other == *this); +} + +bool Iteration::operator<(const Concatenation&) const { + return true; +} + +bool Iteration::operator<(const Alternation&) const { + return true; +} + +bool Iteration::operator<(const Iteration& other) const { + return *(this->element) < *(other.element); +} + +bool Iteration::operator==(const Iteration& other) const { + return *(this->element) == *(other.element); +} + +bool Iteration::operator>(const Iteration& other) const { + return *(this->element) > *(other.element); +} + +bool Iteration::operator>(const RegExpSymbol&) const { + return true; +} + +bool Iteration::operator>(const RegExpEpsilon&) const { + return true; +} + +bool Iteration::operator>(const RegExpEmpty&) const { + return true; +} + bool Iteration::containsEmptyString() const { return true; } diff --git a/alib/src/regexp/Iteration.h b/alib/src/regexp/Iteration.h index 645519714732ed334b762bf8bdce5fc2cd0159a0..ab34a89deb1ef144f4661fd286404212121dd3cc 100644 --- a/alib/src/regexp/Iteration.h +++ b/alib/src/regexp/Iteration.h @@ -49,6 +49,19 @@ public: */ RegExpElement* clone() const; + virtual bool operator<(const RegExpElement&) const; + virtual bool operator==(const RegExpElement&) const; + virtual bool operator>(const RegExpElement&) const; + + virtual bool operator<(const Concatenation&) const; + virtual bool operator<(const Alternation&) const; + virtual bool operator<(const Iteration&) const; + virtual bool operator==(const Iteration&) const; + virtual bool operator>(const Iteration&) const; + virtual bool operator>(const RegExpSymbol&) const; + virtual bool operator>(const RegExpEpsilon&) const; + virtual bool operator>(const RegExpEmpty&) const; + /** * @copydoc RegExpElement::containsEmptyString() const */ diff --git a/alib/src/regexp/RegExp.cpp b/alib/src/regexp/RegExp.cpp index bf745304852efdef9267941a52f9e073186f9cc6..65b63e54a07c81bd448925f5dc9490030aed1712 100644 --- a/alib/src/regexp/RegExp.cpp +++ b/alib/src/regexp/RegExp.cpp @@ -90,4 +90,16 @@ ostream& operator <<(ostream& out, RegExp& regexp) { return out; } +bool RegExp::operator<(const RegExp& other) const { + return *(this->regExp) < *(other.regExp); +} + +bool RegExp::operator==(const RegExp& other) const { + return *(this->regExp) == *(other.regExp); +} + +bool RegExp::operator>(const RegExp& other) const { + return *(this->regExp) > *(other.regExp); +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExp.h b/alib/src/regexp/RegExp.h index 1242304c603afbdb73bbfaad0f5cb8899a7f29e0..def92709e7c4c2a71a2cf05931f046405ba064b8 100644 --- a/alib/src/regexp/RegExp.h +++ b/alib/src/regexp/RegExp.h @@ -1,4 +1,4 @@ -/* + /* * RegExp.h * * Created on: Nov 23, 2013 @@ -77,6 +77,10 @@ public: * @param regexp RegExp to print */ friend ostream& operator<<(ostream& out, RegExp& regexp); + + bool operator<(const RegExp&) const; + bool operator==(const RegExp&) const; + bool operator>(const RegExp&) const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpElement.cpp b/alib/src/regexp/RegExpElement.cpp index 25f706ba7a5b268057cf0052a7a962771a0d8855..4b1cfb88348cd72b4e19cf86437a2806eb2f259f 100644 --- a/alib/src/regexp/RegExpElement.cpp +++ b/alib/src/regexp/RegExpElement.cpp @@ -13,5 +13,84 @@ RegExpElement::~RegExpElement() { } +bool RegExpElement::operator!=(const RegExpElement& other) const { + return !(*this == other); +} + + +bool RegExpElement::operator<(const Concatenation& other) const { + return false; +} + +bool RegExpElement::operator<(const Alternation& other) const { + return false; +} + +bool RegExpElement::operator<(const Iteration& other) const { + return false; +} + +bool RegExpElement::operator<(const RegExpSymbol& other) const { + return false; +} + +bool RegExpElement::operator<(const RegExpEpsilon& other) const { + return false; +} + +bool RegExpElement::operator<(const RegExpEmpty& other) const { + return false; +} + + +bool RegExpElement::operator==(const Concatenation& other) const { + return false; +} + +bool RegExpElement::operator==(const Alternation& other) const { + return false; +} + +bool RegExpElement::operator==(const Iteration& other) const { + return false; +} + +bool RegExpElement::operator==(const RegExpSymbol& other) const { + return false; +} + +bool RegExpElement::operator==(const RegExpEpsilon& other) const { + return false; +} + + +bool RegExpElement::operator==(const RegExpEmpty& other) const { + return false; +} + +bool RegExpElement::operator>(const Concatenation& other) const { + return false; +} + +bool RegExpElement::operator>(const Alternation& other) const { + return false; +} + +bool RegExpElement::operator>(const Iteration& other) const { + return false; +} + +bool RegExpElement::operator>(const RegExpSymbol& other) const { + return false; +} + +bool RegExpElement::operator>(const RegExpEpsilon& other) const { + return false; +} + +bool RegExpElement::operator>(const RegExpEmpty& other) const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpElement.h b/alib/src/regexp/RegExpElement.h index ee7a13d2f2b190ecdbd48c2961caa2032cd98006..206c80759d6a31e8765f0d459935fe47f94fa31f 100644 --- a/alib/src/regexp/RegExpElement.h +++ b/alib/src/regexp/RegExpElement.h @@ -12,6 +12,14 @@ namespace regexp { using namespace std; + +class Alternation; +class Concatenation; +class Iteration; +class RegExpSymbol; +class RegExpEmpty; +class RegExpEpsilon; + /** * Abstract class representing element in the regular expression. Can be operator or symbol. */ @@ -25,6 +33,33 @@ public: */ virtual RegExpElement* clone() const = 0; + virtual bool operator<(const RegExpElement&) const = 0; + virtual bool operator==(const RegExpElement&) const = 0; + virtual bool operator>(const RegExpElement&) const = 0; + + virtual bool operator!=(const RegExpElement&) const; + + virtual bool operator<(const Concatenation&) const; + virtual bool operator<(const Alternation&) const; + virtual bool operator<(const Iteration&) const; + virtual bool operator<(const RegExpSymbol&) const; + virtual bool operator<(const RegExpEpsilon&) const; + virtual bool operator<(const RegExpEmpty&) const; + + virtual bool operator==(const Concatenation&) const; + virtual bool operator==(const Alternation&) const; + virtual bool operator==(const Iteration&) const; + virtual bool operator==(const RegExpSymbol&) const; + virtual bool operator==(const RegExpEpsilon&) const; + virtual bool operator==(const RegExpEmpty&) const; + + virtual bool operator>(const Concatenation&) const; + virtual bool operator>(const Alternation&) const; + virtual bool operator>(const Iteration&) const; + virtual bool operator>(const RegExpSymbol&) const; + virtual bool operator>(const RegExpEpsilon&) const; + virtual bool operator>(const RegExpEmpty&) const; + /** * @return true if this subtree of regexp matches empty string (epsilon) */ diff --git a/alib/src/regexp/RegExpEmpty.cpp b/alib/src/regexp/RegExpEmpty.cpp index fbfa0371c3bbeb86477577cb69084d81439e14ad..28683e657fe871d8038d2d4857e0aa06f6976c47 100644 --- a/alib/src/regexp/RegExpEmpty.cpp +++ b/alib/src/regexp/RegExpEmpty.cpp @@ -16,6 +16,43 @@ RegExpElement* RegExpEmpty::clone() const { return new RegExpEmpty(); } +bool RegExpEmpty::operator<(const RegExpElement& other) const { + return !(other > *this || other == *this); +} + +bool RegExpEmpty::operator==(const RegExpElement& other) const { + return other == *this; +} + +bool RegExpEmpty::operator>(const RegExpElement& other) const { + return !(other < *this || other == *this); +} + + +bool RegExpEmpty::operator<(const Concatenation&) const { + return true; +} + +bool RegExpEmpty::operator<(const Alternation&) const { + return true; +} + +bool RegExpEmpty::operator<(const Iteration&) const { + return true; +} + +bool RegExpEmpty::operator<(const RegExpSymbol&) const { + return true; +} + +bool RegExpEmpty::operator<(const RegExpEpsilon&) const { + return true; +} + +bool RegExpEmpty::operator==(const RegExpEmpty&) const { + return true; +} + bool RegExpEmpty::containsEmptyString() const { return false; } diff --git a/alib/src/regexp/RegExpEmpty.h b/alib/src/regexp/RegExpEmpty.h index dbdf6f4e9f5c89c79d1e4e938c3cadbc09ac4817..7fb80a8935aa801a0fc928214b2b62b2e33d2fec 100644 --- a/alib/src/regexp/RegExpEmpty.h +++ b/alib/src/regexp/RegExpEmpty.h @@ -26,6 +26,17 @@ public: */ RegExpElement* clone() const; + virtual bool operator<(const RegExpElement&) const; + virtual bool operator==(const RegExpElement&) const; + virtual bool operator>(const RegExpElement&) const; + + virtual bool operator<(const Concatenation&) const; + virtual bool operator<(const Alternation&) const; + virtual bool operator<(const Iteration&) const; + virtual bool operator<(const RegExpSymbol&) const; + virtual bool operator<(const RegExpEpsilon&) const; + virtual bool operator==(const RegExpEmpty&) const; + /** * @copydoc RegExpElement::containsEmptyString() const */ diff --git a/alib/src/regexp/RegExpEpsilon.cpp b/alib/src/regexp/RegExpEpsilon.cpp index 80b12b40763dc494af3712dc6d17936a258e41ad..0d7c64f1591e4bb5d412d4724bc3d2c5b4e6a6ce 100644 --- a/alib/src/regexp/RegExpEpsilon.cpp +++ b/alib/src/regexp/RegExpEpsilon.cpp @@ -16,6 +16,43 @@ RegExpElement* RegExpEpsilon::clone() const { return new RegExpEpsilon(); } +bool RegExpEpsilon::operator<(const RegExpElement& other) const { + return !(other > *this || other == *this); +} + +bool RegExpEpsilon::operator==(const RegExpElement& other) const { + return other == *this; +} + +bool RegExpEpsilon::operator>(const RegExpElement& other) const { + return !(other < *this || other == *this); +} + + +bool RegExpEpsilon::operator<(const Alternation&) const { + return true; +} + +bool RegExpEpsilon::operator<(const Concatenation&) const { + return true; +} + +bool RegExpEpsilon::operator<(const Iteration&) const { + return true; +} + +bool RegExpEpsilon::operator<(const RegExpSymbol&) const { + return true; +} + +bool RegExpEpsilon::operator==(const RegExpEpsilon&) const { + return true; +} + +bool RegExpEpsilon::operator>(const RegExpEmpty&) const { + return true; +} + bool RegExpEpsilon::containsEmptyString() const { return true; } diff --git a/alib/src/regexp/RegExpEpsilon.h b/alib/src/regexp/RegExpEpsilon.h index ff3bfb3d1c2440cd6520ecfb3841ba2ec5d79ace..351df1bde6edecfe2a062e7022d6c45fd1d81f6c 100644 --- a/alib/src/regexp/RegExpEpsilon.h +++ b/alib/src/regexp/RegExpEpsilon.h @@ -28,6 +28,17 @@ public: */ RegExpElement* clone() const; + virtual bool operator<(const RegExpElement&) const; + virtual bool operator==(const RegExpElement&) const; + virtual bool operator>(const RegExpElement&) const; + + virtual bool operator<(const Alternation&) const; + virtual bool operator<(const Concatenation&) const; + virtual bool operator<(const Iteration&) const; + virtual bool operator<(const RegExpSymbol&) const; + virtual bool operator==(const RegExpEpsilon&) const; + virtual bool operator>(const RegExpEmpty&) const; + /** * @copydoc RegExpElement::containsEmptyString() const */ diff --git a/alib/src/regexp/RegExpSymbol.cpp b/alib/src/regexp/RegExpSymbol.cpp index f460d554964dfc33ef510ca48d1dbf434757b8ce..1ecb2bcf901c5a45582414d6af11b56003c92833 100644 --- a/alib/src/regexp/RegExpSymbol.cpp +++ b/alib/src/regexp/RegExpSymbol.cpp @@ -21,6 +21,51 @@ RegExpElement* RegExpSymbol::clone() const { return new RegExpSymbol(this->symbol); } +bool RegExpSymbol::operator<(const RegExpElement& other) const { + return !(other > *this || other == *this); +} + +bool RegExpSymbol::operator==(const RegExpElement& other) const { + return other == *this; +} + +bool RegExpSymbol::operator>(const RegExpElement& other) const { + return !(other < *this || other == *this); +} + + +bool RegExpSymbol::operator<(const Concatenation&) const { + return true; +} + +bool RegExpSymbol::operator<(const Alternation&) const { + return true; +} + +bool RegExpSymbol::operator<(const Iteration&) const { + return true; +} + +bool RegExpSymbol::operator<(const RegExpSymbol& other) const { + return this->symbol < other.symbol; +} + +bool RegExpSymbol::operator==(const RegExpSymbol& other) const { + return this->symbol == other.symbol; +} + +bool RegExpSymbol::operator>(const RegExpSymbol& other) const { + return this->symbol > other.symbol; +} + +bool RegExpSymbol::operator>(const RegExpEpsilon&) const { + return true; +} + +bool RegExpSymbol::operator>(const RegExpEmpty&) const { + return true; +} + bool RegExpSymbol::containsEmptyString() const { return false; } diff --git a/alib/src/regexp/RegExpSymbol.h b/alib/src/regexp/RegExpSymbol.h index 588680bf2d35be94a1d26f154d2aed6f68e9f8f4..1b7b4982b145d8c4ee89870ee2f0210e91074157 100644 --- a/alib/src/regexp/RegExpSymbol.h +++ b/alib/src/regexp/RegExpSymbol.h @@ -30,6 +30,20 @@ public: */ RegExpElement* clone() const; + virtual bool operator<(const RegExpElement&) const; + virtual bool operator==(const RegExpElement&) const; + virtual bool operator>(const RegExpElement&) const; + + virtual bool operator<(const Concatenation&) const; + virtual bool operator<(const Alternation&) const; + virtual bool operator<(const Iteration&) const; + virtual bool operator<(const RegExpSymbol&) const; + virtual bool operator==(const RegExpSymbol&) const; + virtual bool operator>(const RegExpSymbol&) const; + virtual bool operator>(const RegExpEpsilon&) const; + virtual bool operator>(const RegExpEmpty&) const; + + /** * @copydoc RegExpElement::containsEmptyString() const */ diff --git a/aminimize/src/aminimize.cpp b/aminimize/src/aminimize.cpp index c564de72f586771a206d8fcee3f582bf62d910be..4562910785c458be57deca3d316ed7722a2713ce 100644 --- a/aminimize/src/aminimize.cpp +++ b/aminimize/src/aminimize.cpp @@ -26,7 +26,7 @@ int main(int argc, char** argv) { if (argc == 2 && string("-h").compare(argv[1]) == 0) { cout << "Automaton minimize.\nUsage: aminimize automaton.xml\n"; return -1; - } else if (argc == 1 || argc == 2 && string("--").compare(argv[1]) == 0) { + } else if (argc == 1 || (argc == 2 && string("--").compare(argv[1]) == 0)) { automaton = AutomatonFactory::fromStdin(); if(!AutomatonFactory::isFSM(automaton)) { cout << "Automaton minimize require deterministic finite automaton\n"; diff --git a/anormalize/makefile b/anormalize/makefile new file mode 100644 index 0000000000000000000000000000000000000000..e775f372fb9a9c20f86969e37aa5bfbff3c647b5 --- /dev/null +++ b/anormalize/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTABLE=anormalize +CCFLAGS= -g -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 new file mode 100644 index 0000000000000000000000000000000000000000..d5bfa73f2d0a3034be41e9e820d486941eb5d1b6 --- /dev/null +++ b/anormalize/src/Normalize.cpp @@ -0,0 +1,84 @@ +/* + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..b88cba329d6e08a8b34620a6bbe0fe5978c62a8c --- /dev/null +++ b/anormalize/src/Normalize.h @@ -0,0 +1,19 @@ +/* + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..04d426d48fb282e38bf4d52da98ca7fba751f2d4 --- /dev/null +++ b/anormalize/src/anormalize.cpp @@ -0,0 +1,61 @@ +//============================================================================ +// 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/examples/DFSM1IS.xml b/examples/DFSM1IS.xml new file mode 100644 index 0000000000000000000000000000000000000000..0f4d2d6039a8f8d4fab33f48c4e9701286224a56 --- /dev/null +++ b/examples/DFSM1IS.xml @@ -0,0 +1,66 @@ +<automaton> + <states> + <state>['A', 'C', 'S']</state> + <state>['A', 'S']</state> + <state>['B', 'S']</state> + <state>['S']</state> + <state>['X']</state> + </states> + <inputAlphabet> + <symbol>0</symbol> + <symbol>1</symbol> + </inputAlphabet> + <transitions> + <transition> + <from>['A', 'C', 'S']</from> + <input>0</input> + <to>['A', 'S']</to> + </transition> + <transition> + <from>['A', 'C', 'S']</from> + <input>1</input> + <to>['B', 'S']</to> + </transition> + <transition> + <from>['A', 'S']</from> + <input>0</input> + <to>['A', 'S']</to> + </transition> + <transition> + <from>['A', 'S']</from> + <input>1</input> + <to>['B', 'S']</to> + </transition> + <transition> + <from>['B', 'S']</from> + <input>0</input> + <to>['A', 'C', 'S']</to> + </transition> + <transition> + <from>['B', 'S']</from> + <input>1</input> + <to>['S']</to> + </transition> + <transition> + <from>['S']</from> + <input>0</input> + <to>['A', 'S']</to> + </transition> + <transition> + <from>['S']</from> + <input>1</input> + <to>['S']</to> + </transition> + <transition> + <from>['X']</from> + <input>1</input> + <to>['X']</to> + </transition> + </transitions> + <initialStates> + <state>['S']</state> + </initialStates> + <finalStates> + <state>['A', 'C', 'S']</state> + </finalStates> +</automaton> diff --git a/makefile b/makefile index c31bddb3b586a444ca65e7d2c8650b790d21cbf7..7e5356ff042671ad76f9ba8e7c83ca614753f917 100644 --- a/makefile +++ b/makefile @@ -4,8 +4,16 @@ BINFOLDER = bin CORE_LIB = alib SUBDIRS_LIBS = adeterminize libaderivation libaregexptree -SUBDIRS_BINS = acat aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aconvert.grammar aminimize adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adiff adiff.automaton adiff.grammar aepsilon atrim aderivation - +SUBDIRS_BINS = acat \ + aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aconvert.grammar \ + aminimize \ + adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 \ + adiff adiff.automaton adiff.grammar \ + aepsilon \ + atrim \ + anormalize \ + aconversions \ + aderivation SUBDIRS_WITH_MAKE = $(dir $(wildcard */makefile)) .PHONY: $(CORE_LIB) $(SUBDIRS_LIBS) $(SUBDIRS_BINS)