Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
DFA.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 <ostream>
27
28#include <alib/map>
29#include <alib/set>
30
31#include <ext/range>
32
33#include <core/components.hpp>
34
37
39
40#include <core/normalize.hpp>
43
44namespace automaton {
45
46class InputAlphabet;
47class States;
48class FinalStates;
49class InitialState;
50
70template < class SymbolTypeT = DefaultSymbolType, class StateTypeT = DefaultStateType >
71class DFA final : public core::Components < DFA < SymbolTypeT, StateTypeT >, ext::set < SymbolTypeT >, component::Set, InputAlphabet, ext::set < StateTypeT >, component::Set, std::tuple < States, FinalStates >, StateTypeT, component::Value, InitialState > {
72public:
73 typedef SymbolTypeT SymbolType;
74 typedef StateTypeT StateType;
75
76private:
81
82public:
88 explicit DFA ( StateType initialState );
89
98 explicit DFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates );
99
105 const StateType & getInitialState ( ) const & {
106 return this-> template accessComponent < InitialState > ( ).get ( );
107 }
108
115 return std::move ( this-> template accessComponent < InitialState > ( ).get ( ) );
116 }
117
125 bool setInitialState ( StateType state ) {
126 return this-> template accessComponent < InitialState > ( ).set ( std::move ( state ) );
127 }
128
134 const ext::set < StateType > & getStates ( ) const & {
135 return this-> template accessComponent < States > ( ).get ( );
136 }
137
144 return std::move ( this-> template accessComponent < States > ( ).get ( ) );
145 }
146
154 bool addState ( StateType state ) {
155 return this-> template accessComponent < States > ( ).add ( std::move ( state ) );
156 }
157
164 this-> template accessComponent < States > ( ).set ( std::move ( states ) );
165 }
166
174 void removeState ( const StateType & state ) {
175 this-> template accessComponent < States > ( ).remove ( state );
176 }
177
184 return this-> template accessComponent < FinalStates > ( ).get ( );
185 }
186
193 return std::move ( this-> template accessComponent < FinalStates > ( ).get ( ) );
194 }
195
203 bool addFinalState ( StateType state ) {
204 return this-> template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
205 }
206
213 this-> template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
214 }
215
223 void removeFinalState ( const StateType & state ) {
224 this-> template accessComponent < FinalStates > ( ).remove ( state );
225 }
226
233 return this-> template accessComponent < InputAlphabet > ( ).get ( );
234 }
235
242 return std::move ( this-> template accessComponent < InputAlphabet > ( ).get ( ) );
243 }
244
252 bool addInputSymbol ( SymbolType symbol ) {
253 return this-> template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
254 }
255
262 this-> template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
263 }
264
271 this-> template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
272 }
273
281 void removeInputSymbol ( const SymbolType & symbol ) {
282 this-> template accessComponent < InputAlphabet > ( ).remove ( symbol );
283 }
284
298 bool addTransition ( StateType from, SymbolType input, StateType to );
299
311 bool removeTransition ( const StateType & from, const SymbolType & input, const StateType & to );
312
319
325 ext::map < ext::pair < StateType, SymbolType >, StateType > && getTransitions ( ) &&;
326
334 ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > getTransitionsFromState ( const StateType & from ) const;
335
343 ext::map < ext::pair < StateType, SymbolType >, StateType > getTransitionsToState ( const StateType & to ) const;
344
353 bool isTotal ( ) const;
354
362 auto operator <=> ( const DFA & other ) const {
363 return std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions ) <=> std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.transitions );
364 }
365
373 bool operator == ( const DFA & other ) const {
374 return std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions ) == std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.transitions );
375 }
376
385 friend ext::ostream & operator << ( ext::ostream & out, const DFA & instance ) {
386 return out << "(DFA"
387 << " states = " << instance.getStates ( )
388 << " inputAlphabet = " << instance.getInputAlphabet ( )
389 << " initialState = " << instance.getInitialState ( )
390 << " finalStates = " << instance.getFinalStates ( )
391 << " transitions = " << instance.getTransitions ( )
392 << ")";
393 }
394};
395
401template < class T >
402class isDFA_impl : public std::false_type {};
403
412template < class SymbolType, class StateType >
413class isDFA_impl < DFA < SymbolType, StateType > > : public std::true_type {};
414
420template < class T >
421constexpr bool isDFA = isDFA_impl < T > { };
422
423template<class SymbolType, class StateType >
424DFA<SymbolType, StateType>::DFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, StateType initialState, ext::set < StateType > finalStates ) : core::Components < DFA, ext::set < SymbolType >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates >, StateType, component::Value, InitialState > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( finalStates ), std::move ( initialState ) ) {
425}
426
427template<class SymbolType, class StateType >
428DFA<SymbolType, StateType>::DFA ( StateType initialState ) : DFA ( ext::set < StateType > { initialState }, ext::set < SymbolType > { }, initialState, ext::set < StateType > { } ) {
429}
430
431template<class SymbolType, class StateType >
433 if ( ! getStates ( ).contains ( from ) )
434 throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist." );
435
436 if ( ! getInputAlphabet ( ).contains ( input ) )
437 throw AutomatonException ( "Input symbol \"" + ext::to_string ( input ) + "\" doesn't exist." );
438
439 if ( ! getStates ( ).contains ( to ) )
440 throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist." );
441
442 ext::pair < StateType, SymbolType > key = ext::make_pair ( std::move ( from ), std::move ( input ) );
443 auto iter = transitions.find ( key );
444
445 if ( iter != transitions.end ( ) ) {
446 if ( iter->second == to )
447 return false;
448 else
449 throw AutomatonException ( "Transition from this state and symbol already exists (\"" + ext::to_string ( key.first ) + "\", \"" + ext::to_string ( key.second ) + "\") -> \"" + ext::to_string ( to ) + "\"." );
450 }
451
452 transitions.insert ( std::move ( key ), std::move ( to ) );
453 return true;
454}
455
456template<class SymbolType, class StateType >
457bool DFA<SymbolType, StateType>::removeTransition ( const StateType & from, const SymbolType & input, const StateType & to ) {
459
460 auto iter = transitions.find ( key );
461
462 if ( iter == transitions.end ( ) )
463 return false;
464
465 if ( iter->second != to )
466 return false;
467
468 transitions.erase ( iter );
469 return true;
470}
471
472template<class SymbolType, class StateType >
474 return transitions;
475}
476
477template<class SymbolType, class StateType >
479 return std::move ( transitions );
480}
481
482template<class SymbolType, class StateType >
484 if ( ! getStates ( ).contains ( from ) )
485 throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" );
486
487 auto lower = transitions.lower_bound ( ext::slice_comp ( from ) );
488 auto upper = transitions.upper_bound ( ext::slice_comp ( from ) );
489
490 return ext::make_iterator_range ( lower, upper );
491}
492
493template<class SymbolType, class StateType >
495 if ( ! getStates ( ).contains ( to ) )
496 throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist" );
497
499
500 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : transitions )
501 if ( transition.second == to )
502 transitionsToState.insert ( transition );
503
504 return transitionsToState;
505}
506
507template<class SymbolType, class StateType >
509 return transitions.size ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( );
510}
511
512} /* namespace automaton */
513
514namespace core {
515
522template<class SymbolType, class StateType >
523class SetConstraint< automaton::DFA<SymbolType, StateType>, SymbolType, automaton::InputAlphabet > {
524public:
533 static bool used ( const automaton::DFA<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
534 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : automaton.getTransitions ( ) )
535 if ( transition.first.second == symbol )
536 return true;
537
538 return false;
539 }
540
550 return true;
551 }
552
559 static void valid ( const automaton::DFA<SymbolType, StateType> &, const SymbolType & ) {
560 }
561
562};
563
570template<class SymbolType, class StateType >
571class SetConstraint< automaton::DFA<SymbolType, StateType>, StateType, automaton::States > {
572public:
581 static bool used ( const automaton::DFA<SymbolType, StateType> & automaton, const StateType & state ) {
582 if ( automaton.getInitialState ( ) == state )
583 return true;
584
585 if ( automaton.getFinalStates ( ).contains ( state ) )
586 return true;
587
588 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & t : automaton.getTransitions ( ) )
589 if ( ( t.first.first == state ) || ( t.second == state ) )
590 return true;
591
592 return false;
593 }
594
604 return true;
605 }
606
613 static void valid ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
614 }
615
616};
617
624template<class SymbolType, class StateType >
625class SetConstraint< automaton::DFA<SymbolType, StateType>, StateType, automaton::FinalStates > {
626public:
635 static bool used ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
636 return false;
637 }
638
648 return automaton.getStates ( ).contains ( state );
649 }
650
657 static void valid ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
658 }
659
660};
661
668template<class SymbolType, class StateType >
669class ElementConstraint< automaton::DFA<SymbolType, StateType>, StateType, automaton::InitialState > {
670public:
680 return automaton.getStates ( ).contains ( state );
681 }
682
689 static void valid ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
690 }
691
692};
693
699template < class SymbolType, class StateType >
700struct normalize < automaton::DFA < SymbolType, StateType > > {
702 ext::set < DefaultSymbolType > alphabet = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getInputAlphabet ( ) );
703 ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
704 DefaultStateType initialState = automaton::AutomatonNormalize::normalizeState ( std::move ( value ).getInitialState ( ) );
705 ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );
706
707 automaton::DFA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( initialState ), std::move ( finalStates ) );
708
709 for ( std::pair < ext::pair < StateType, SymbolType >, StateType > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
710 DefaultStateType from = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.first.first ) );
711 DefaultSymbolType input = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( transition.first.second ) );
712 DefaultStateType to = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.second ) );
713
714 res.addTransition ( std::move ( from ), std::move ( input ), std::move ( to ) );
715 }
716
717 return res;
718 }
719};
720
721} /* namespace core */
722
723extern template class automaton::DFA < >;
724
static ext::set< DefaultSymbolType > normalizeAlphabet(ext::set< SymbolType > &&symbols)
Definition: SymbolNormalize.h:50
static DefaultSymbolType normalizeSymbol(SymbolType &&symbol)
Definition: SymbolNormalize.h:68
Definition: AutomatonException.h:15
static DefaultStateType normalizeState(StateType &&state)
Definition: AutomatonNormalize.h:76
static ext::multiset< DefaultStateType > normalizeStates(ext::multiset< StateType > &&states)
Definition: AutomatonNormalize.h:49
Deterministic finite automaton. Accepts regular languages.
Definition: DFA.h:71
const ext::set< StateType > & getFinalStates() const &
Definition: DFA.h:183
bool setInitialState(StateType state)
Definition: DFA.h:125
bool removeTransition(const StateType &from, const SymbolType &input, const StateType &to)
Removes a transition from the automaton.
Definition: DFA.h:457
const ext::map< ext::pair< StateType, SymbolType >, StateType > & getTransitions() const &
Definition: DFA.h:473
void removeInputSymbol(const SymbolType &symbol)
Definition: DFA.h:281
void setFinalStates(ext::set< StateType > states)
Definition: DFA.h:212
friend ext::ostream & operator<<(ext::ostream &out, const DFA &instance)
Definition: DFA.h:385
StateTypeT StateType
Definition: DFA.h:74
bool addFinalState(StateType state)
Definition: DFA.h:203
const StateType & getInitialState() const &
Definition: DFA.h:105
bool operator==(const DFA &other) const
Definition: DFA.h:373
bool addInputSymbol(SymbolType symbol)
Definition: DFA.h:252
const ext::set< SymbolType > & getInputAlphabet() const &
Definition: DFA.h:232
ext::set< StateType > && getFinalStates() &&
Definition: DFA.h:192
DFA(StateType initialState)
Creates a new instance of the automaton with a concrete initial state.
Definition: DFA.h:428
ext::set< SymbolType > && getInputAlphabet() &&
Definition: DFA.h:241
bool isTotal() const
Determines whether the automaton is total.
Definition: DFA.h:508
const ext::set< StateType > & getStates() const &
Definition: DFA.h:134
bool addTransition(StateType from, SymbolType input, StateType to)
Add a transition to the automaton.
Definition: DFA.h:432
SymbolTypeT SymbolType
Definition: DFA.h:73
void removeState(const StateType &state)
Definition: DFA.h:174
void addInputSymbols(ext::set< SymbolType > symbols)
Definition: DFA.h:261
bool addState(StateType state)
Definition: DFA.h:154
ext::map< ext::pair< StateType, SymbolType >, StateType > getTransitionsToState(const StateType &to) const
Definition: DFA.h:494
ext::set< StateType > && getStates() &&
Definition: DFA.h:143
void setInputAlphabet(ext::set< SymbolType > symbols)
Definition: DFA.h:270
StateType && getInitialState() &&
Definition: DFA.h:114
void setStates(ext::set< StateType > states)
Definition: DFA.h:163
void removeFinalState(const StateType &state)
Definition: DFA.h:223
ext::iterator_range< typename ext::map< ext::pair< StateType, SymbolType >, StateType >::const_iterator > getTransitionsFromState(const StateType &from) const
Definition: DFA.h:483
Definition: DFA.h:402
Definition: components.hpp:181
static bool available(const automaton::DFA< SymbolType, StateType > &automaton, const StateType &state)
Definition: DFA.h:679
static void valid(const automaton::DFA< SymbolType, StateType > &, const StateType &)
Definition: DFA.h:689
Definition: components.hpp:25
static bool available(const automaton::DFA< SymbolType, StateType > &, const StateType &)
Definition: DFA.h:603
static bool used(const automaton::DFA< SymbolType, StateType > &automaton, const StateType &state)
Definition: DFA.h:581
static void valid(const automaton::DFA< SymbolType, StateType > &, const StateType &)
Definition: DFA.h:613
static bool used(const automaton::DFA< SymbolType, StateType > &, const StateType &)
Definition: DFA.h:635
static void valid(const automaton::DFA< SymbolType, StateType > &, const StateType &)
Definition: DFA.h:657
static bool available(const automaton::DFA< SymbolType, StateType > &automaton, const StateType &state)
Definition: DFA.h:647
static bool used(const automaton::DFA< SymbolType, StateType > &automaton, const SymbolType &symbol)
Definition: DFA.h:533
static void valid(const automaton::DFA< SymbolType, StateType > &, const SymbolType &)
Definition: DFA.h:559
static bool available(const automaton::DFA< SymbolType, StateType > &, const SymbolType &)
Definition: DFA.h:549
Definition: setComponents.hpp:26
Implementation of iterator_range, i.e. pair of iterators. The class provides most notably begin and e...
Definition: range.hpp:24
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
std::pair< iterator, bool > insert(const T &key, const R &value)
Insert variant with explicit key and value parameters.
Definition: map.hpp:118
Definition: ostream.h:14
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
Definition: Object.h:16
Definition: BarSymbol.cpp:12
typename T::StateType StateType
Definition: ToGrammarLeftRG.h:64
typename T::SymbolType SymbolType
Definition: ReachableStates.h:176
return res
Definition: MinimizeByPartitioning.h:145
Definition: ToGrammar.h:31
constexpr bool isDFA
Definition: DFA.h:421
Definition: components.hpp:13
Definition: normalize.hpp:10
Definition: sigHandler.cpp:20
constexpr tuple< Elements &... > tie(Elements &... args) noexcept
Helper of extended tuple of references construction. The tuple is constructed to reffer to values in ...
Definition: tuple.hpp:218
reference_mover< T > make_mover(T &param)
Move adaptor construction function specialized to lvalue reference parameter.
Definition: iterator.hpp:468
SliceComp< Ts ... > slice_comp(const Ts &... inst)
Definition: functional.hpp:95
bool contains(InputIt first, InputIt last, const Element &elem)
Linear version of search in a range of values.
Definition: algorithm.hpp:170
std::string to_string(const T &value)
To string method designated for objects that can be casted to string.
Definition: string.hpp:131
iterator_range< Iter > make_iterator_range(Iter begin, Iter end)
Helper to create iterator_range from two iterators.
Definition: range.hpp:235
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: FordFulkerson.hpp:16
auto & get(ext::ptr_array< Type, N > &tpl)
Specialisation of get function for pointer arrays.
Definition: ptr_array.hpp:693
static automaton::DFA< > eval(automaton::DFA< SymbolType, StateType > &&value)
Definition: DFA.h:701
Definition: normalize.hpp:13