Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
RegularEquationSolver.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <queue>
9
10#include <ext/algorithm>
11
12#include <alib/map>
13#include <alib/deque>
14
16
20
21namespace equations {
22
26template < class TerminalSymbolType, class VariableSymbolType >
28public:
29 virtual ~RegularEquationSolver ( ) noexcept = default;
30
36 void addVariableSymbol ( const VariableSymbolType & symbol );
37
44 void removeVariableSymbol ( const VariableSymbolType & symbol );
45
51 void setVariableSymbols ( const ext::set < VariableSymbolType > & newSymbols );
52
60 void addEquation ( const VariableSymbolType & from, const VariableSymbolType & to, const regexp::UnboundedRegExpElement < TerminalSymbolType > & eq );
61
68 void addEquation ( const VariableSymbolType & from, const regexp::UnboundedRegExpElement < TerminalSymbolType > & eq );
69
76 regexp::UnboundedRegExp < TerminalSymbolType > solve ( const VariableSymbolType & solveFor );
77
78protected:
83 virtual regexp::UnboundedRegExp < TerminalSymbolType > eliminate ( ) = 0;
84
89 void sortSymbolsByDepth ( const VariableSymbolType & solveFor );
90
94 ext::deque < VariableSymbolType > nonterminalSymbolsByDepth;
95
99 ext::map < std::pair < VariableSymbolType, VariableSymbolType >, regexp::UnboundedRegExpAlternation < TerminalSymbolType > > equationTransition;
100
104 ext::map < VariableSymbolType, regexp::UnboundedRegExpAlternation < TerminalSymbolType > > equationFinal;
105
109 ext::set < VariableSymbolType > nonterminalSymbols;
110};
111
112template < class TerminalSymbolType, class VariableSymbolType >
113void RegularEquationSolver < TerminalSymbolType, VariableSymbolType >::setVariableSymbols ( const ext::set < VariableSymbolType > & newSymbols ) {
116
117 std::set_difference ( nonterminalSymbols.begin ( ), nonterminalSymbols.end ( ), newSymbols.begin ( ), newSymbols.end ( ), std::inserter ( removed, removed.end ( ) ) );
118 std::set_difference ( newSymbols.begin ( ), newSymbols.end ( ), nonterminalSymbols.begin ( ), nonterminalSymbols.end ( ), std::inserter ( added, added.end ( ) ) );
119
120 for ( const VariableSymbolType & symbol : removed ) {
121 removeVariableSymbol ( symbol );
122 }
123
124 for ( const VariableSymbolType & symbol : added ) {
125 addVariableSymbol ( symbol );
126 }
127}
128
129template < class TerminalSymbolType, class VariableSymbolType >
131 for ( const auto & kv : equationTransition ) {
132 const VariableSymbolType & from = kv.first.first;
133 const VariableSymbolType & to = kv.first.second;
135
136 if ( ( from == symbol || to == symbol ) && !alt.getElements ( ).empty ( ) ) {
137 throw exception::CommonException ( "Symbol '" + ext::to_string ( symbol ) + "' is in use." );
138 }
139 }
140
141 for ( const auto & kv : equationFinal ) {
142 const VariableSymbolType & from = kv.first;
144
145 if ( from == symbol && !alt.getElements ( ).empty ( ) ) {
146 throw exception::CommonException ( "Symbol '" + ext::to_string ( from ) + "' is in use." );
147 }
148 }
149
150
151 nonterminalSymbols.erase ( nonterminalSymbols.find ( symbol ) );
152 equationFinal.erase ( equationFinal.find ( symbol ) );
153
154 for ( const VariableSymbolType & variable : nonterminalSymbols ) {
155 equationTransition.erase ( equationTransition.find ( std::make_pair ( variable, symbol ) ) );
156 equationTransition.erase ( equationTransition.find ( std::make_pair ( symbol, variable ) ) );
157 }
158
159 equationTransition.erase ( equationTransition.find ( std::make_pair ( symbol, symbol ) ) );
160}
161
162template < class TerminalSymbolType, class VariableSymbolType >
164 for ( const VariableSymbolType & variable : nonterminalSymbols) {
167 }
168
170
171 nonterminalSymbols.insert ( symbol );
173}
174
175template < class TerminalSymbolType, class VariableSymbolType >
177 if ( nonterminalSymbols.count ( from ) == 0 ) {
178 throw exception::CommonException ( "Symbol from ('" + ext::to_string ( from ) + "') is not in equation system." );
179 }
180
181 if ( nonterminalSymbols.count ( to ) == 0 ) {
182 throw exception::CommonException ( "Symbol to ('" + ext::to_string ( to ) + "') is not in equation system." );
183 }
184
185 equationTransition.find ( std::make_pair ( from, to ) )->second.appendElement ( eq );
186}
187
188template < class TerminalSymbolType, class VariableSymbolType >
190 if ( nonterminalSymbols.count ( from ) == 0 ) {
191 throw exception::CommonException ( "Symbol from ('" + ext::to_string ( from ) + "') is not in equation system." );
192 }
193
194 equationFinal.find ( from )->second.appendElement ( eq );
195}
196
197template < class TerminalSymbolType, class VariableSymbolType >
200 std::queue < VariableSymbolType > queue;
201
202 visited.insert ( solveFor );
203 queue.push ( solveFor );
204
205 while ( ! queue.empty ( ) ) {
206 VariableSymbolType variable = std::move ( queue.front ( ) );
207 queue.pop ( );
208
209 nonterminalSymbolsByDepth.push_back ( variable );
210
211 for ( const auto & kv : equationTransition )
212 // find all transitions from current symbol that are non-empty, enqueue transition'variable target symbol
213 if ( kv.first.first == variable && !kv.second.getElements ( ).empty ( ) && visited.insert ( kv.first.second ).second )
214 queue.push ( kv.first.second );
215 }
216}
217
218template < class TerminalSymbolType, class VariableSymbolType >
220 if ( nonterminalSymbols.count ( solveFor ) == 0 ) {
221 throw exception::CommonException ( "Symbol solveFor ('" + ext::to_string ( solveFor ) + "') is not in equation system." );
222 }
223
224 /*
225 * Firstly, organize states by depth so we can output better looking
226 * expressions. We need to solve equation system for automaton's initial state,
227 * so lets start with the deepest ones and walk towards the initial one.
228 */
229 sortSymbolsByDepth ( solveFor );
230 return eliminate ( );
231}
232
233} /* namespace equations */
234
Definition: RegularEquationSolver.h:27
ext::set< VariableSymbolType > nonterminalSymbols
Definition: RegularEquationSolver.h:109
ext::map< VariableSymbolType, regexp::UnboundedRegExpAlternation< TerminalSymbolType > > equationFinal
Definition: RegularEquationSolver.h:104
void addEquation(const VariableSymbolType &from, const VariableSymbolType &to, const regexp::UnboundedRegExpElement< TerminalSymbolType > &eq)
Definition: RegularEquationSolver.h:176
virtual regexp::UnboundedRegExp< TerminalSymbolType > eliminate()=0
regexp::UnboundedRegExp< TerminalSymbolType > solve(const VariableSymbolType &solveFor)
Definition: RegularEquationSolver.h:219
void addVariableSymbol(const VariableSymbolType &symbol)
Definition: RegularEquationSolver.h:163
void setVariableSymbols(const ext::set< VariableSymbolType > &newSymbols)
Definition: RegularEquationSolver.h:113
ext::deque< VariableSymbolType > nonterminalSymbolsByDepth
Definition: RegularEquationSolver.h:94
virtual ~RegularEquationSolver() noexcept=default
ext::map< std::pair< VariableSymbolType, VariableSymbolType >, regexp::UnboundedRegExpAlternation< TerminalSymbolType > > equationTransition
Definition: RegularEquationSolver.h:99
void removeVariableSymbol(const VariableSymbolType &symbol)
Definition: RegularEquationSolver.h:130
void sortSymbolsByDepth(const VariableSymbolType &solveFor)
Definition: RegularEquationSolver.h:198
Basic exception from which all other exceptions are derived.
Definition: CommonException.h:21
Definition: set.hpp:44
auto end() &
Inherited behavior of end for non-const instance.
Definition: set.hpp:129
Represents the alternation operator in the regular expression. The node can have 0 to n children in l...
Definition: UnboundedRegExpAlternation.h:44
const ext::ptr_vector< UnboundedRegExpElement< SymbolType > > & getElements() const
Definition: UnboundedRegExpAlternation.h:185
Definition: UnboundedRegExpElement.h:62
Unbounded regular expression represents regular expression. It describes regular languages....
Definition: UnboundedRegExp.h:80
ext::set< ext::tuple< StateType, StateType, SymbolType > > visited
Definition: Compaction.h:81
Definition: LeftRegularEquationSolver.h:13
Definition: sigHandler.cpp:20
std::string to_string(const T &value)
To string method designated for objects that can be casted to string.
Definition: string.hpp:131
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: ToAutomaton.h:15
Definition: FordFulkerson.hpp:16