Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
NondeterministicZAutomaton.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#include <alib/vector>
31
32#include <core/components.hpp>
33
36
38
39#include <core/normalize.hpp>
42
43namespace automaton {
44
45class InputAlphabet;
46class States;
47class FinalStates;
48
67template < class SymbolTypeT = DefaultSymbolType, class StateTypeT = DefaultStateType >
68class NondeterministicZAutomaton final : public core::Components < NondeterministicZAutomaton < SymbolTypeT, StateTypeT >, ext::set < SymbolTypeT >, component::Set, InputAlphabet, ext::set < StateTypeT >, component::Set, std::tuple < States, FinalStates > > {
69public:
70 typedef SymbolTypeT SymbolType;
71 typedef StateTypeT StateType;
72
73private:
78
79public:
83 explicit NondeterministicZAutomaton ( );
84
93
99 const ext::set < StateType > & getStates ( ) const & {
100 return this->template accessComponent < States > ( ).get ( );
101 }
102
109 return std::move ( this->template accessComponent < States > ( ).get ( ) );
110 }
111
119 bool addState ( StateType state ) {
120 return this->template accessComponent < States > ( ).add ( std::move ( state ) );
121 }
122
129 this->template accessComponent < States > ( ).set ( std::move ( states ) );
130 }
131
139 void removeState ( const StateType & state ) {
140 this->template accessComponent < States > ( ).remove ( state );
141 }
142
149 return this->template accessComponent < FinalStates > ( ).get ( );
150 }
151
158 return std::move ( this->template accessComponent < FinalStates > ( ).get ( ) );
159 }
160
168 bool addFinalState ( StateType state ) {
169 return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
170 }
171
178 this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
179 }
180
188 void removeFinalState ( const StateType & state ) {
189 this->template accessComponent < FinalStates > ( ).remove ( state );
190 }
191
198 return this->template accessComponent < InputAlphabet > ( ).get ( );
199 }
200
207 return std::move ( this->template accessComponent < InputAlphabet > ( ).get ( ) );
208 }
209
217 bool addInputSymbol ( SymbolType symbol ) {
218 return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
219 }
220
227 this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
228 }
229
236 this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
237 }
238
246 void removeInputSymbol ( const SymbolType & symbol ) {
247 this->template accessComponent < InputAlphabet > ( ).remove ( symbol );
248 }
249
264
277
284 return transitions;
285 }
286
293 return std::move ( transitions );
294 }
295
301
302 for ( const auto & transition : getTransitions ( ) ) {
303 if ( transition.second == q )
304 res.insert ( std::make_pair ( transition.first, q ) );
305 }
306
307 return res;
308 }
309
315
316 for ( const auto & transition : getTransitions ( ) ) {
317 if ( std::find ( transition.first.second.begin ( ), transition.first.second.end ( ), q ) != transition.first.second.end ( ) )
318 res.insert ( transition );
319 }
320
321 return res;
322 }
323
331 auto operator <=> ( const NondeterministicZAutomaton & other ) const {
332 return std::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions) <=> std::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
333 }
334
342 bool operator == ( const NondeterministicZAutomaton & other ) const {
343 return std::tie(getStates(), getInputAlphabet(), getFinalStates(), transitions) == std::tie(other.getStates(), other.getInputAlphabet(), other.getFinalStates(), other.transitions);
344 }
345
355 return out << "(NondeterministicZAutomaton "
356 << " states = " << instance.getStates ( )
357 << " inputAlphabet = " << instance.getInputAlphabet ( )
358 << " finalStates = " << instance.getFinalStates ( )
359 << " transitions = " << instance.getTransitions ( )
360 << ")";
361 }
362};
363
364template<class SymbolType, class StateType >
365NondeterministicZAutomaton < SymbolType, StateType >::NondeterministicZAutomaton ( ext::set < StateType > states, ext::set < SymbolType > inputAlphabet, ext::set < StateType > finalStates ) : core::Components < NondeterministicZAutomaton, ext::set < SymbolType >, component::Set, InputAlphabet, ext::set < StateType >, component::Set, std::tuple < States, FinalStates > > ( std::move ( inputAlphabet ), std::move ( states ), std::move ( finalStates ) ) {
366}
367
368template<class SymbolType, class StateType >
370}
371
372template<class SymbolType, class StateType >
374 if ( ! getInputAlphabet ( ).count ( symbol ) && ! getStates ( ).count ( symbol ) )
375 throw AutomatonException("Input symbol or state \"" + ext::to_string ( symbol ) + "\" doesn't exist.");
376
377 if (! getStates().count(next))
378 throw AutomatonException("State \"" + ext::to_string ( next ) + "\" doesn't exist.");
379
380 for ( const ext::variant < SymbolType, StateType > & it : prevStates) {
381 if ( ! getInputAlphabet ( ).count ( it ) && ! getStates ( ).count ( it ) )
382 throw AutomatonException("Input symbol or state \"" + ext::to_string ( it ) + "\" doesn't exist.");
383 }
384
385 auto upper_bound = transitions.upper_bound ( ext::tie ( symbol, prevStates ) );
386 auto lower_bound = transitions.lower_bound ( ext::tie ( symbol, prevStates ) );
387 auto iter = std::lower_bound ( lower_bound, upper_bound, next, [ ] ( const auto & transition, const auto & target ) { return transition.second < target; } );
388 if ( iter != upper_bound && next >= iter->second )
389 return false;
390
392 transitions.insert ( iter, std::make_pair ( std::move ( key ), std::move ( next ) ) );
393 return true;
394}
395
396template<class SymbolType, class StateType >
398 auto upper_bound = transitions.upper_bound ( ext::tie ( symbol, states ) );
399 auto lower_bound = transitions.lower_bound ( ext::tie ( symbol, states ) );
400 auto iter = std::find_if ( lower_bound, upper_bound, [ & ] ( const auto & transition ) { return transition.second == next; } );
401 if ( iter == upper_bound )
402 return false;
403
404 transitions.erase ( iter );
405 return true;
406}
407
408} /* namespace automaton */
409
410namespace core {
411
418template<class SymbolType, class StateType >
419class SetConstraint< automaton::NondeterministicZAutomaton < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > {
420public:
430 for ( const std::pair < const ext::pair < ext::variant < SymbolType, StateType >, ext::vector < ext::variant < SymbolType, StateType > > >, StateType > & t : automaton.getTransitions ( ) )
431 if ( t.first.first == symbol || ext::contains ( t.first.second.begin ( ), t.first.second.end ( ), symbol ) )
432 return true;
433
434 return false;
435 }
436
446 return true;
447 }
448
456 if ( automaton.template accessComponent < automaton::States > ( ).get ( ).count ( ext::poly_comp ( symbol ) ) )
457 throw automaton::AutomatonException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the input alphabet since it is already in the states set." );
458 }
459};
460
467template<class SymbolType, class StateType >
468class SetConstraint< automaton::NondeterministicZAutomaton < SymbolType, StateType >, StateType, automaton::States > {
469public:
479 if ( automaton.getFinalStates ( ).count ( state ) )
480 return true;
481
482 for ( const std::pair < const ext::pair < ext::variant < SymbolType, StateType >, ext::vector < ext::variant < SymbolType, StateType > > >, StateType > & t : automaton.getTransitions ( ) )
483 if ( t.first.first == state || ext::contains ( t.first.second.begin ( ), t.first.second.end ( ), state ) || t.second == state )
484 return true;
485
486 return false;
487 }
488
498 return true;
499 }
500
508 if ( automaton.template accessComponent < automaton::InputAlphabet > ( ).get ( ).count ( ext::poly_comp ( state ) ) )
509 throw automaton::AutomatonException ( "State " + ext::to_string ( state ) + " cannot be in the states set since it is already in the input alphabet." );
510 }
511};
512
519template<class SymbolType, class StateType >
520class SetConstraint< automaton::NondeterministicZAutomaton < SymbolType, StateType >, StateType, automaton::FinalStates > {
521public:
531 return false;
532 }
533
543 return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
544 }
545
553 }
554};
555
561template < class SymbolType, class StateType >
562struct normalize < automaton::NondeterministicZAutomaton < SymbolType, StateType > > {
564 ext::set < DefaultSymbolType > alphabet = alphabet::SymbolNormalize::normalizeAlphabet ( std::move ( value ).getInputAlphabet ( ) );
565 ext::set < DefaultStateType > states = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getStates ( ) );
566 ext::set < DefaultStateType > finalStates = automaton::AutomatonNormalize::normalizeStates ( std::move ( value ).getFinalStates ( ) );
567
568 automaton::NondeterministicZAutomaton < > res ( std::move ( states ), std::move ( alphabet ), std::move ( finalStates ) );
569
570 for ( std::pair < ext::pair < ext::variant < SymbolType, StateType >, ext::vector < ext::variant < SymbolType, StateType > > >, StateType > && transition : ext::make_mover ( std::move ( value ).getTransitions ( ) ) ) {
573 DefaultStateType to = automaton::AutomatonNormalize::normalizeState ( std::move ( transition.second ) );
574
575 res.addTransition ( std::move ( input ), std::move ( from ), std::move ( to ) );
576 }
577
578 return res;
579 }
580};
581
582} /* namespace core */
583
static ext::set< DefaultSymbolType > normalizeAlphabet(ext::set< SymbolType > &&symbols)
Definition: SymbolNormalize.h:50
static ext::vector< ext::variant< DefaultSymbolType, DefaultSymbolType > > normalizeVariantSymbols(ext::vector< ext::variant< FirstSymbolType, SecondSymbolType > > &&symbols)
Definition: SymbolNormalize.h:95
static ext::variant< DefaultSymbolType, DefaultSymbolType > normalizeVariantSymbol(ext::variant< FirstSymbolType, SecondSymbolType > &&symbol)
Definition: SymbolNormalize.h:73
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
Nondeterministic Z-Automaton. Computation model for unranked regular tree languages.
Definition: NondeterministicZAutomaton.h:68
bool addState(StateType state)
Definition: NondeterministicZAutomaton.h:119
void removeFinalState(const StateType &state)
Definition: NondeterministicZAutomaton.h:188
void removeState(const StateType &state)
Definition: NondeterministicZAutomaton.h:139
void setFinalStates(ext::set< StateType > states)
Definition: NondeterministicZAutomaton.h:177
void setInputAlphabet(ext::set< SymbolType > symbols)
Definition: NondeterministicZAutomaton.h:235
NondeterministicZAutomaton()
Creates a new instance of the automaton.
Definition: NondeterministicZAutomaton.h:369
auto operator<=>(const NondeterministicZAutomaton &other) const
Definition: NondeterministicZAutomaton.h:331
bool operator==(const NondeterministicZAutomaton &other) const
Definition: NondeterministicZAutomaton.h:342
ext::set< SymbolType > && getInputAlphabet() &&
Definition: NondeterministicZAutomaton.h:206
void removeInputSymbol(const SymbolType &symbol)
Definition: NondeterministicZAutomaton.h:246
ext::multimap< ext::pair< ext::variant< SymbolType, StateType >, ext::vector< ext::variant< SymbolType, StateType > > >, StateType > getTransitionsToState(const StateType &q) const
Definition: NondeterministicZAutomaton.h:299
void setStates(ext::set< StateType > states)
Definition: NondeterministicZAutomaton.h:128
ext::multimap< ext::pair< ext::variant< SymbolType, StateType >, ext::vector< ext::variant< SymbolType, StateType > > >, StateType > getTransitionsFromState(const StateType &q) const
Definition: NondeterministicZAutomaton.h:313
ext::set< StateType > && getFinalStates() &&
Definition: NondeterministicZAutomaton.h:157
SymbolTypeT SymbolType
Definition: NondeterministicZAutomaton.h:70
friend ext::ostream & operator<<(ext::ostream &out, const NondeterministicZAutomaton &instance)
Definition: NondeterministicZAutomaton.h:354
ext::set< StateType > && getStates() &&
Definition: NondeterministicZAutomaton.h:108
bool addInputSymbol(SymbolType symbol)
Definition: NondeterministicZAutomaton.h:217
const ext::multimap< ext::pair< ext::variant< SymbolType, StateType >, ext::vector< ext::variant< SymbolType, StateType > > >, StateType > & getTransitions() const &
Definition: NondeterministicZAutomaton.h:283
bool addFinalState(StateType state)
Definition: NondeterministicZAutomaton.h:168
const ext::set< StateType > & getStates() const &
Definition: NondeterministicZAutomaton.h:99
void addInputSymbols(ext::set< SymbolType > symbols)
Definition: NondeterministicZAutomaton.h:226
StateTypeT StateType
Definition: NondeterministicZAutomaton.h:71
ext::multimap< ext::pair< ext::variant< SymbolType, StateType >, ext::vector< ext::variant< SymbolType, StateType > > >, StateType > && getTransitions() &&
Definition: NondeterministicZAutomaton.h:292
bool addTransition(ext::variant< SymbolType, StateType > symbol, ext::vector< ext::variant< SymbolType, StateType > > prevStates, StateType next)
Add a transition to the automaton.
Definition: NondeterministicZAutomaton.h:373
const ext::set< StateType > & getFinalStates() const &
Definition: NondeterministicZAutomaton.h:148
bool removeTransition(const ext::variant< SymbolType, StateType > &symbol, const ext::vector< ext::variant< SymbolType, StateType > > &states, const StateType &next)
Removes a transition from the automaton.
Definition: NondeterministicZAutomaton.h:397
const ext::set< SymbolType > & getInputAlphabet() const &
Definition: NondeterministicZAutomaton.h:197
Definition: components.hpp:181
static bool available(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &automaton, const StateType &state)
Definition: NondeterministicZAutomaton.h:542
static bool used(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &, const StateType &)
Definition: NondeterministicZAutomaton.h:530
static void valid(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &, const StateType &)
Definition: NondeterministicZAutomaton.h:552
static bool used(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &automaton, const StateType &state)
Definition: NondeterministicZAutomaton.h:478
static void valid(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &automaton, const StateType &state)
Definition: NondeterministicZAutomaton.h:507
static bool available(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &, const StateType &)
Definition: NondeterministicZAutomaton.h:497
static bool used(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &automaton, const SymbolType &symbol)
Definition: NondeterministicZAutomaton.h:429
static bool available(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &, const SymbolType &)
Definition: NondeterministicZAutomaton.h:445
static void valid(const automaton::NondeterministicZAutomaton< SymbolType, StateType > &automaton, const SymbolType &symbol)
Definition: NondeterministicZAutomaton.h:455
Definition: setComponents.hpp:26
Class extending the multimap class from the standard library. Original reason is to allow printing of...
Definition: multimap.hpp:48
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
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
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
q
Definition: SingleInitialStateEpsilonTransition.h:85
Definition: ToGrammar.h:31
Definition: normalize.hpp:10
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
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
PolyComp< T > poly_comp(const T &inst)
Definition: functional.hpp:60
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::NondeterministicZAutomaton< > eval(automaton::NondeterministicZAutomaton< SymbolType, StateType > &&value)
Definition: NondeterministicZAutomaton.h:563
Definition: normalize.hpp:13