Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
BackwardBisimulation.h
Go to the documentation of this file.
1
6/*
7 * This file is part of Algorithms library toolkit.
8 * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
9
10 * Algorithms library toolkit is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14
15 * Algorithms library toolkit is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19
20 * You should have received a copy of the GNU General Public License
21 * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#pragma once
25
26#include <alib/set>
27#include <alib/map>
28
29#include <automaton/TA/DFTA.h>
30#include <automaton/TA/NFTA.h>
31
34
35#include <automaton/FSM/DFA.h>
36#include <automaton/FSM/NFA.h>
37
40
41namespace automaton {
42
43namespace properties {
44
50 template < class StateType >
51 static ext::set < ext::pair < StateType, StateType > > initial ( const ext::set < StateType > & states, const ext::set < StateType > & initials ) {
53
54 for ( const StateType & a : states ) {
55 for ( const StateType & b : states ) {
56 if ( initials.count ( a ) == initials.count ( b ) ) {
57 init.insert ( ext::make_pair ( a, b ) );
58 init.insert ( ext::make_pair ( b, a ) );
59 }
60 }
61 }
62
63 return init;
64 }
65
66public:
74 template < class SymbolType, class StateType >
76
84 template < class SymbolType, class StateType >
86
87 template < class SymbolType, class StateType >
89
90 template < class SymbolType, class StateType >
92
100 template < class SymbolType, class StateType >
102
110 template < class SymbolType, class StateType >
112
120 template < class SymbolType, class StateType >
122
130 template < class SymbolType, class StateType >
132};
133
134template < class SymbolType, class StateType >
137}
138
139template < class SymbolType, class StateType >
141 ext::set < ext::pair < StateType, StateType > > backwardBisimulation = initial ( fta.getStates ( ), { fta.getInitialState ( ) } );
142
143 bool changed;
144 do {
145 changed = false;
146
147 for ( const StateType & p : fta.getStates ( ) ) {
148 for ( const StateType & q : fta.getStates ( ) ) {
149 if ( ! backwardBisimulation.contains ( ext::make_pair ( p, q ) ) )
150 continue;
151
152 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & pTransition : fta.getTransitionsToState ( p ) ) {
153
154 bool exists = false;
155 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & qTransition : fta.getTransitionsToState ( q ) ) {
156 if ( qTransition.first.second != pTransition.first.second )
157 continue;
158
159 if ( backwardBisimulation.contains ( ext::make_pair ( pTransition.first.first, qTransition.first.first ) ) ) {
160 exists = true;
161 break;
162 }
163 }
164
165 if ( ! exists ) {
166 backwardBisimulation.erase ( ext::make_pair ( p, q ) );
167 backwardBisimulation.erase ( ext::make_pair ( q, p ) );
168 changed = true;
169 break;
170 }
171 }
172 }
173 }
174 } while ( changed );
175
177}
178
179template < class SymbolType, class StateType >
182}
183
184template < class SymbolType, class StateType >
187
188 bool changed;
189 do {
190 changed = false;
191
192 for ( const StateType & p : afnza.getStates ( ) ) {
193 for ( const StateType & q : afnza.getStates ( ) ) {
194 if ( ! backwardBisimulation.contains ( ext::make_pair ( p, q ) ) )
195 continue;
196
197 for ( const std::pair < const ext::variant < SymbolType, ext::pair < StateType, StateType > >, StateType > & pTransition : afnza.getTransitionsToState ( p ) ) {
198 if ( ! pTransition.first.template is < SymbolType > ( ) )
199 continue;
200
201 const SymbolType & pSource = pTransition.first.template get < SymbolType > ( );
202
203 bool exists = false;
204 for ( const std::pair < const ext::variant < SymbolType, ext::pair < StateType, StateType > >, StateType > & qTransition : afnza.getTransitionsToState ( q ) ) {
205 if ( ! qTransition.first.template is < SymbolType > ( ) )
206 continue;
207
208 const SymbolType & qSource = qTransition.first.template get < SymbolType > ( );
209
210 if ( qSource != pSource )
211 continue;
212
213 exists = true;
214 break;
215 }
216
217 if ( ! exists ) {
218 backwardBisimulation.erase ( ext::make_pair ( p, q ) );
219 backwardBisimulation.erase ( ext::make_pair ( q, p ) );
220 changed = true;
221 break;
222 }
223 }
224 }
225 }
226 } while ( changed );
227
228 do {
229 changed = false;
230
231 for ( const StateType & p : afnza.getStates ( ) ) {
232 for ( const StateType & q : afnza.getStates ( ) ) {
233 if ( ! backwardBisimulation.contains ( ext::make_pair ( p, q ) ) )
234 continue;
235
236 for ( const std::pair < const ext::variant < SymbolType, ext::pair < StateType, StateType > >, StateType > & pTransition : afnza.getTransitionsToState ( p ) ) {
237 if ( pTransition.first.template is < SymbolType > ( ) )
238 continue;
239
240 const ext::pair < StateType, StateType > & pSource = pTransition.first.template get < ext::pair < StateType, StateType > > ( );
241
242 bool exists = false;
243 for ( const std::pair < const ext::variant < SymbolType, ext::pair < StateType, StateType > >, StateType > & qTransition : afnza.getTransitionsToState ( q ) ) {
244 if ( qTransition.first.template is < SymbolType > ( ) )
245 continue;
246
247 const ext::pair < StateType, StateType > & qSource = qTransition.first.template get < ext::pair < StateType, StateType > > ( );
248
249 if ( backwardBisimulation.contains ( ext::make_pair ( pSource.first, qSource.first ) )
250 && backwardBisimulation.contains ( ext::make_pair ( pSource.second, qSource.second ) ) ) {
251 exists = true;
252 break;
253 }
254 }
255
256 if ( ! exists ) {
257 backwardBisimulation.erase ( ext::make_pair ( p, q ) );
258 backwardBisimulation.erase ( ext::make_pair ( q, p ) );
259 changed = true;
260 break;
261 }
262 }
263 }
264 }
265 } while ( changed );
266
268}
269
270template < class SymbolType, class StateType >
273}
274
275template < class SymbolType, class StateType >
278
279 bool changed;
280 do {
281 changed = false;
282
283 for ( const StateType & p : fta.getStates ( ) ) {
284 for ( const StateType & q : fta.getStates ( ) ) {
285 if ( ! backwardBisimulation.contains ( ext::make_pair ( p, q ) ) )
286 continue;
287
288 for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::vector < StateType > >, StateType > & pTransition : fta.getTransitionsToState ( p ) ) {
289
290 bool exists = false;
291 for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::vector < StateType > >, StateType > & qTransition : fta.getTransitionsToState ( q ) ) {
292 if ( qTransition.first.first != pTransition.first.first )
293 continue;
294
295 size_t inRelation = 0;
296 for ( size_t i = 0; i < pTransition.first.second.size ( ); ++ i ) {
297 if ( backwardBisimulation.contains ( ext::make_pair ( pTransition.first.second [ i ], qTransition.first.second [ i ] ) ) )
298 ++ inRelation;
299 }
300
301 if ( inRelation == pTransition.first.second.size ( ) ) {
302 exists = true;
303 break;
304 }
305 }
306
307 if ( ! exists ) {
308 backwardBisimulation.erase ( ext::make_pair ( p, q ) );
309 backwardBisimulation.erase ( ext::make_pair ( q, p ) );
310 changed = true;
311 break;
312 }
313 }
314 }
315 }
316 } while ( changed );
317
319}
320
321template < class SymbolType, class StateType >
324}
325
326template < class SymbolType, class StateType >
329
330 bool changed;
331 do {
332 changed = false;
333
334 for ( const StateType & p : fta.getStates ( ) ) {
335 for ( const StateType & q : fta.getStates ( ) ) {
336 if ( ! backwardBisimulation.contains ( ext::make_pair ( p, q ) ) )
337 continue;
338
339 for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & pTransition : fta.getTransitionsToState ( p ) ) {
340
342 for ( const StateType & state : pTransition.first.second ) {
343 auto lower = backwardBisimulation.lower_bound ( ext::slice_comp ( state ) );
344 pSource.insert ( lower->second );
345 }
346
347 bool exists = false;
348 for ( const std::pair < const ext::pair < common::ranked_symbol < SymbolType >, ext::multiset < StateType > >, StateType > & qTransition : fta.getTransitionsToState ( q ) ) {
349 if ( qTransition.first.first != pTransition.first.first )
350 continue;
351
353 for ( const StateType & state : qTransition.first.second ) {
354 auto lower = backwardBisimulation.lower_bound ( ext::slice_comp ( state ) );
355 qSource.insert ( lower->second );
356 }
357
358 if ( pSource == qSource ) {
359 exists = true;
360 break;
361 }
362 }
363
364 if ( ! exists ) {
365 backwardBisimulation.erase ( ext::make_pair ( p, q ) );
366 backwardBisimulation.erase ( ext::make_pair ( q, p ) );
367 changed = true;
368 break;
369 }
370 }
371 }
372 }
373 } while ( changed );
374
376}
377
378} /* namespace properties */
379
380} /* namespace automaton */
381
Deterministic Z-Automaton in Arc-Factored Normal Form. Computation model for unranked regular tree la...
Definition: ArcFactoredDeterministicZAutomaton.h:65
Nondeterministic Z-Automaton in Arc-Factored Normal Form. Computation model for unranked regular tree...
Definition: ArcFactoredNondeterministicZAutomaton.h:67
ext::multimap< ext::variant< SymbolType, ext::pair< StateType, StateType > >, StateType > getTransitionsToState(const StateType &q) const
Definition: ArcFactoredNondeterministicZAutomaton.h:309
const ext::set< StateType > & getStates() const &
Definition: ArcFactoredNondeterministicZAutomaton.h:105
Deterministic finite automaton. Accepts regular languages.
Definition: DFA.h:71
Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages.
Definition: DFTA.h:74
Nondeterministic finite automaton. Accepts regular languages.
Definition: NFA.h:66
const ext::set< StateType > & getStates() const &
Definition: NFA.h:136
ext::multimap< ext::pair< StateType, SymbolType >, StateType > getTransitionsToState(const StateType &to) const
Definition: NFA.h:502
Nondeterministic finite tree automaton without epsilon transitions. Accepts regular tree languages.
Definition: NFTA.h:72
const ext::set< StateType > & getStates() const &
Definition: NFTA.h:110
ext::multimap< ext::pair< common::ranked_symbol< SymbolType >, ext::vector< StateType > >, StateType > getTransitionsToState(const StateType &q) const
Definition: NFTA.h:310
Deterministic unordered finite tree automaton without epsilon transitions. Accepts regular tree langu...
Definition: UnorderedDFTA.h:72
Nondeterministic unordered finite tree automaton without epsilon transitions. Accepts regular tree la...
Definition: UnorderedNFTA.h:72
const ext::set< StateType > & getStates() const &
Definition: UnorderedNFTA.h:110
ext::multimap< ext::pair< common::ranked_symbol< SymbolType >, ext::multiset< StateType > >, StateType > getTransitionsToState(const StateType &q) const
Definition: UnorderedNFTA.h:310
Definition: BackwardBisimulation.h:49
static ext::set< ext::pair< StateType, StateType > > backwardBisimulation(const automaton::DFA< SymbolType, StateType > &fta)
Definition: BackwardBisimulation.h:135
Definition: ranked_symbol.hpp:20
Definition: multiset.hpp:44
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Definition: set.hpp:44
Implementation of the variant class allowing to store any type of those listed in the template parame...
Definition: variant.hpp:98
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
typename T::StateType StateType
Definition: ToGrammarLeftRG.h:64
int i
Definition: AllEpsilonClosure.h:118
typename T::SymbolType SymbolType
Definition: ReachableStates.h:176
q
Definition: SingleInitialStateEpsilonTransition.h:85
Definition: ToGrammar.h:31
SliceComp< Ts ... > slice_comp(const Ts &... inst)
Definition: functional.hpp:95
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79