Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
MultiInitialStateNFA.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/multimap>
29#include <alib/set>
30
31#include <core/components.hpp>
32
35
37
38#include <core/normalize.hpp>
41
42#include "NFA.h"
43#include "DFA.h"
44
45namespace automaton {
46
47class InputAlphabet;
48class States;
49class FinalStates;
50class InitialStates;
51
68template < class SymbolTypeT = DefaultSymbolType, class StateTypeT = DefaultStateType >
69class MultiInitialStateNFA final : public core::Components < MultiInitialStateNFA < SymbolTypeT, StateTypeT >, ext::set < SymbolTypeT >, component::Set, InputAlphabet, ext::set < StateTypeT >, component::Set, std::tuple < States, InitialStates, FinalStates > > {
70public:
71 typedef SymbolTypeT SymbolType;
72 typedef StateTypeT StateType;
73
74private:
79
80public:
86 explicit MultiInitialStateNFA ( );
87
97
98 /*
99 * \brief Creates a new instance of the automaton based on the Nondeterministic finite automaton.
100 *
101 * \param other the Nondeterministic finite automaton
102 */
103 explicit MultiInitialStateNFA ( const NFA < SymbolType, StateType > & other );
104
105 /*
106 * \brief Creates a new instance of the automaton based on the Deterministic finite automaton.
107 *
108 * \param other the Deterministic finite automaton
109 */
110 explicit MultiInitialStateNFA ( const DFA < SymbolType, StateType > & other );
111
118 return this->template accessComponent < InitialStates > ( ).get ( );
119 }
120
127 return std::move ( this->template accessComponent < InitialStates > ( ).get ( ) );
128 }
129
137 bool addInitialState ( StateType state ) {
138 return this->template accessComponent < InitialStates > ( ).add ( std::move ( state ) );
139 }
140
147 this->template accessComponent < InitialStates > ( ).set ( std::move ( states ) );
148 }
149
157 void removeInitialState ( const StateType & state ) {
158 this->template accessComponent < InitialStates > ( ).remove ( state );
159 }
160
166 const ext::set < StateType > & getStates ( ) const & {
167 return this->template accessComponent < States > ( ).get ( );
168 }
169
176 return std::move ( this->template accessComponent < States > ( ).get ( ) );
177 }
178
186 bool addState ( StateType state ) {
187 return this->template accessComponent < States > ( ).add ( std::move ( state ) );
188 }
189
196 this->template accessComponent < States > ( ).set ( std::move ( states ) );
197 }
198
206 void removeState ( const StateType & state ) {
207 this->template accessComponent < States > ( ).remove ( state );
208 }
209
216 return this->template accessComponent < FinalStates > ( ).get ( );
217 }
218
225 return std::move ( this->template accessComponent < FinalStates > ( ).get ( ) );
226 }
227
235 bool addFinalState ( StateType state ) {
236 return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
237 }
238
245 this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
246 }
247
255 void removeFinalState ( const StateType & state ) {
256 this->template accessComponent < FinalStates > ( ).remove ( state );
257 }
258
265 return this->template accessComponent < InputAlphabet > ( ).get ( );
266 }
267
274 return std::move ( this->template accessComponent < InputAlphabet > ( ).get ( ) );
275 }
276
284 bool addInputSymbol ( SymbolType symbol ) {
285 return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
286 }
287
294 this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
295 }
296
303 this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
304 }
305
313 void removeInputSymbol ( const SymbolType & symbol ) {
314 this->template accessComponent < InputAlphabet > ( ).remove ( symbol );
315 }
316
330 bool addTransition ( StateType from, SymbolType input, StateType to );
331
343 bool removeTransition ( const StateType & from, const SymbolType & input, const StateType & to );
344
351
357 ext::multimap < ext::pair < StateType, SymbolType >, StateType > && getTransitions ( ) &&;
358
366 auto getTransitionsFromState ( const StateType & from ) const;
367
375 ext::multimap < ext::pair < StateType, SymbolType >, StateType > getTransitionsToState ( const StateType & to ) const;
376
386 bool isDeterministic ( ) const;
387
397 bool isTotal ( ) const;
398
406 auto operator <=> ( const MultiInitialStateNFA & other ) const {
407 return std::tie ( getStates ( ), getInputAlphabet ( ), getInitialStates ( ), getFinalStates ( ), transitions ) <=> std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialStates ( ), other.getFinalStates ( ), other.getTransitions ( ) );
408 }
409
417 bool operator == ( const MultiInitialStateNFA & other ) const {
418 return std::tie ( getStates ( ), getInputAlphabet ( ), getInitialStates ( ), getFinalStates ( ), transitions ) == std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialStates ( ), other.getFinalStates ( ), other.getTransitions ( ) );
419 }
420
429 friend ext::ostream & operator << ( ext::ostream & out, const MultiInitialStateNFA & instance ) {
430 return out << "(MultiInitialStateNFA"
431 << " states = " << instance.getStates ( )
432 << " inputAlphabet = " << instance.getInputAlphabet ( )
433 << " initialStates = " << instance.getInitialStates ( )
434 << " finalStates = " << instance.getFinalStates ( )
435 << " transitions = " << instance.getTransitions ( )
436 << ")";
437 }
438};
439
445template < class T >
446class isMultiInitialStateNFA_impl : public std::false_type {};
447
456template < class SymbolType, class StateType >
458
464template < class T >
466
467template < class SymbolType, class StateType >
468MultiInitialStateNFA < SymbolType, StateType >::MultiInitialStateNFA ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, ext::set < StateType > initialStates, ext::set < StateType > finalStates ) : core::Components < MultiInitialStateNFA, ext::set < SymbolType >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, InitialStates, FinalStates > > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( initialStates ), std::move ( finalStates ) ) {
469}
470
471template < class SymbolType, class StateType >
473}
474
475template < class SymbolType, class StateType >
476MultiInitialStateNFA < SymbolType, StateType >::MultiInitialStateNFA ( const DFA < SymbolType, StateType > & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) {
477 transitions.insert ( other.getTransitions ( ).begin ( ), other.getTransitions ( ).end ( ) );
478}
479
480template < class SymbolType, class StateType >
481MultiInitialStateNFA < SymbolType, StateType >::MultiInitialStateNFA ( const NFA < SymbolType, StateType > & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) {
482 transitions = other.getTransitions ( );
483}
484
485template < class SymbolType, class StateType >
487 if ( ! getStates ( ).contains ( from ) )
488 throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist." );
489
490 if ( ! getInputAlphabet ( ).contains ( input ) )
491 throw AutomatonException ( "Input symbol \"" + ext::to_string ( input ) + "\" doesn't exist." );
492
493 if ( ! getStates ( ).contains ( to ) )
494 throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist." );
495
496 auto upper_bound = transitions.upper_bound ( ext::tie ( from, input ) );
497 auto lower_bound = transitions.lower_bound ( ext::tie ( from, input ) );
498 auto iter = std::lower_bound ( lower_bound, upper_bound, to, [ ] ( const auto & transition, const auto & target ) { return transition.second < target; } );
499 if ( iter != upper_bound && to >= iter->second )
500 return false;
501
502 ext::pair < StateType, SymbolType > key = ext::make_pair ( std::move ( from ), std::move ( input ) );
503 transitions.insert ( iter, std::make_pair ( std::move ( key ), std::move ( to ) ) );
504 return true;
505}
506
507template < class SymbolType, class StateType >
509 auto upper_bound = transitions.upper_bound ( ext::tie ( from, input ) );
510 auto lower_bound = transitions.lower_bound ( ext::tie ( from, input ) );
511 auto iter = std::find_if ( lower_bound, upper_bound, [ & ] ( const auto & transition ) { return transition.second == to; } );
512 if ( iter == upper_bound )
513 return false;
514
515 transitions.erase ( iter );
516 return true;
517}
518
519template < class SymbolType, class StateType >
521 return transitions;
522}
523
524template < class SymbolType, class StateType >
526 return std::move ( transitions );
527}
528
529template < class SymbolType, class StateType >
531 if ( ! getStates ( ).contains ( from ) )
532 throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" );
533
534 return transitions.equal_range ( ext::slice_comp ( from ) );
535}
536
537template < class SymbolType, class StateType >
539 if ( ! getStates ( ).contains ( to ) )
540 throw AutomatonException ( "State \"" + ext::to_string ( to ) + "\" doesn't exist" );
541
543
544 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : transitions )
545 if ( transition.second == to )
546 transitionsToState.insert ( transition );
547
548 return transitionsToState;
549}
550
551template < class SymbolType, class StateType >
553 if ( transitions.empty ( ) )
554 return true;
555
556 for ( auto iter = transitions.begin ( ); std::next ( iter ) != transitions.end ( ); ++ iter )
557 if ( iter->first == std::next ( iter )->first )
558 return false;
559
560 return getInitialStates ( ).size ( ) == 1;
561}
562
563template < class SymbolType, class StateType >
565 return isDeterministic ( ) && transitions.size ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( );
566}
567
568} /* namespace automaton */
569
570namespace core {
571
578template < class SymbolType, class StateType >
579class SetConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > {
580public:
590 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : automaton.getTransitions ( ) )
591 if ( transition.first.second == symbol )
592 return true;
593
594 return false;
595 }
596
606 return true;
607 }
608
616 }
617};
618
625template < class SymbolType, class StateType >
626class SetConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, StateType, automaton::States > {
627public:
637 if ( automaton.getInitialStates ( ).contains ( state ) )
638 return true;
639
640 if ( automaton.getFinalStates ( ).contains ( state ) )
641 return true;
642
643 for ( const std::pair < const ext::pair < StateType, SymbolType >, StateType > & transition : automaton.getTransitions ( ) )
644 if ( transition.first.first == state || transition.second == state )
645 return true;
646
647 return false;
648 }
649
659 return true;
660 }
661
669 }
670};
671
678template < class SymbolType, class StateType >
679class SetConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, StateType, automaton::FinalStates > {
680public:
690 return false;
691 }
692
702 return automaton.template accessComponent < automaton::States > ( ).get ( ).contains ( state );
703 }
704
712 }
713};
714
721template < class SymbolType, class StateType >
722class SetConstraint< automaton::MultiInitialStateNFA < SymbolType, StateType >, StateType, automaton::InitialStates > {
723public:
733 return false;
734 }
735
745 return automaton.template accessComponent < automaton::States > ( ).get ( ).contains ( state );
746 }
747
755 }
756};
757
763template < class SymbolType, class StateType >
764struct normalize < automaton::MultiInitialStateNFA < SymbolType, StateType > > {
766 ext::set < DefaultSymbolType > alphabet = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getInputAlphabet ( ) );
767 ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
768 ext::set < DefaultStateType > initialStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getInitialStates ( ) );
769 ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );
770
771 automaton::MultiInitialStateNFA < > res ( std::move ( states ), std::move ( alphabet ), std::move ( initialStates ), std::move ( finalStates ) );
772
773 for ( std::pair < ext::pair < StateType, SymbolType >, StateType > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
774 DefaultStateType from = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.first.first ) );
775 DefaultSymbolType input = alphabet::SymbolNormalize::normalizeSymbol ( std::move ( transition.first.second ) );
776 DefaultStateType target = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.second ) );
777
778 res.addTransition ( std::move ( from ), std::move ( input ), std::move ( target ) );
779 }
780
781 return res;
782 }
783};
784
785} /* namespace core */
786
787extern template class automaton::MultiInitialStateNFA < >;
788
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
Nondeterministic finite automaton with multiple initial states. Accepts regular languages.
Definition: MultiInitialStateNFA.h:69
void setStates(ext::set< StateType > states)
Definition: MultiInitialStateNFA.h:195
StateTypeT StateType
Definition: MultiInitialStateNFA.h:72
void removeFinalState(const StateType &state)
Definition: MultiInitialStateNFA.h:255
void removeState(const StateType &state)
Definition: MultiInitialStateNFA.h:206
bool removeTransition(const StateType &from, const SymbolType &input, const StateType &to)
Removes a transition from the automaton.
Definition: MultiInitialStateNFA.h:508
void addInputSymbols(ext::set< SymbolType > symbols)
Definition: MultiInitialStateNFA.h:293
ext::set< StateType > && getInitialStates() &&
Definition: MultiInitialStateNFA.h:126
bool isDeterministic() const
Determines whether the automaton is deterministic.
Definition: MultiInitialStateNFA.h:552
bool addInitialState(StateType state)
Definition: MultiInitialStateNFA.h:137
SymbolTypeT SymbolType
Definition: MultiInitialStateNFA.h:71
bool addState(StateType state)
Definition: MultiInitialStateNFA.h:186
bool addFinalState(StateType state)
Definition: MultiInitialStateNFA.h:235
ext::set< StateType > && getStates() &&
Definition: MultiInitialStateNFA.h:175
bool addInputSymbol(SymbolType symbol)
Definition: MultiInitialStateNFA.h:284
void setInitialStates(ext::set< StateType > states)
Definition: MultiInitialStateNFA.h:146
void setFinalStates(ext::set< StateType > states)
Definition: MultiInitialStateNFA.h:244
ext::set< SymbolType > && getInputAlphabet() &&
Definition: MultiInitialStateNFA.h:273
const ext::set< StateType > & getInitialStates() const &
Definition: MultiInitialStateNFA.h:117
const ext::set< StateType > & getStates() const &
Definition: MultiInitialStateNFA.h:166
const ext::multimap< ext::pair< StateType, SymbolType >, StateType > & getTransitions() const &
Definition: MultiInitialStateNFA.h:520
const ext::set< StateType > & getFinalStates() const &
Definition: MultiInitialStateNFA.h:215
MultiInitialStateNFA()
Creates a new instance of the automaton.
Definition: MultiInitialStateNFA.h:472
auto getTransitionsFromState(const StateType &from) const
Definition: MultiInitialStateNFA.h:530
ext::multimap< ext::pair< StateType, SymbolType >, StateType > getTransitionsToState(const StateType &to) const
Definition: MultiInitialStateNFA.h:538
ext::set< StateType > && getFinalStates() &&
Definition: MultiInitialStateNFA.h:224
friend ext::ostream & operator<<(ext::ostream &out, const MultiInitialStateNFA &instance)
Definition: MultiInitialStateNFA.h:429
void setInputAlphabet(ext::set< SymbolType > symbols)
Definition: MultiInitialStateNFA.h:302
void removeInitialState(const StateType &state)
Definition: MultiInitialStateNFA.h:157
const ext::set< SymbolType > & getInputAlphabet() const &
Definition: MultiInitialStateNFA.h:264
bool addTransition(StateType from, SymbolType input, StateType to)
Add a transition to the automaton.
Definition: MultiInitialStateNFA.h:486
void removeInputSymbol(const SymbolType &symbol)
Definition: MultiInitialStateNFA.h:313
bool operator==(const MultiInitialStateNFA &other) const
Definition: MultiInitialStateNFA.h:417
bool isTotal() const
Determines whether the automaton is total deterministic.
Definition: MultiInitialStateNFA.h:564
Nondeterministic finite automaton. Accepts regular languages.
Definition: NFA.h:66
Definition: MultiInitialStateNFA.h:446
Definition: components.hpp:181
static bool used(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const StateType &)
Definition: MultiInitialStateNFA.h:732
static bool available(const automaton::MultiInitialStateNFA< SymbolType, StateType > &automaton, const StateType &state)
Definition: MultiInitialStateNFA.h:744
static void valid(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const StateType &)
Definition: MultiInitialStateNFA.h:754
static bool used(const automaton::MultiInitialStateNFA< SymbolType, StateType > &automaton, const SymbolType &symbol)
Definition: MultiInitialStateNFA.h:589
static bool available(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const SymbolType &)
Definition: MultiInitialStateNFA.h:605
static void valid(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const SymbolType &)
Definition: MultiInitialStateNFA.h:615
static bool available(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const StateType &)
Definition: MultiInitialStateNFA.h:658
static bool used(const automaton::MultiInitialStateNFA< SymbolType, StateType > &automaton, const StateType &state)
Definition: MultiInitialStateNFA.h:636
static void valid(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const StateType &)
Definition: MultiInitialStateNFA.h:668
static void valid(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const StateType &)
Definition: MultiInitialStateNFA.h:711
static bool available(const automaton::MultiInitialStateNFA< SymbolType, StateType > &automaton, const StateType &state)
Definition: MultiInitialStateNFA.h:701
static bool used(const automaton::MultiInitialStateNFA< SymbolType, StateType > &, const StateType &)
Definition: MultiInitialStateNFA.h:689
Definition: setComponents.hpp:26
Class extending the multimap class from the standard library. Original reason is to allow printing of...
Definition: multimap.hpp:48
iterator insert(const T &key, const R &value)
Insert variant with explicit key and value parameters.
Definition: multimap.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 isMultiInitialStateNFA
Definition: MultiInitialStateNFA.h:465
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
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
auto & get(ext::ptr_array< Type, N > &tpl)
Specialisation of get function for pointer arrays.
Definition: ptr_array.hpp:693
static automaton::MultiInitialStateNFA< > eval(automaton::MultiInitialStateNFA< SymbolType, StateType > &&value)
Definition: MultiInitialStateNFA.h:765
Definition: normalize.hpp:13