1+ using System . Collections . Generic ;
2+ using System . Linq ;
3+ using System . Text ;
4+
5+ namespace CppSharp . Utils . FSM
6+ {
7+ public class DFSM {
8+ public readonly List < string > Q = new List < string > ( ) ;
9+ public readonly List < char > Sigma = new List < char > ( ) ;
10+ public readonly List < Transition > Delta = new List < Transition > ( ) ;
11+ public List < string > Q0 = new List < string > ( ) ;
12+ public readonly List < string > F = new List < string > ( ) ;
13+
14+ public DFSM ( IEnumerable < string > q , IEnumerable < char > sigma , IEnumerable < Transition > delta ,
15+ IEnumerable < string > q0 , IEnumerable < string > f ) {
16+ Q = q . ToList ( ) ;
17+ Sigma = sigma . ToList ( ) ;
18+ AddTransitions ( delta ) ;
19+ AddInitialStates ( q0 ) ;
20+ AddFinalStates ( f ) ;
21+ }
22+
23+ private void AddTransitions ( IEnumerable < Transition > transitions ) {
24+ foreach ( var transition in transitions . Where ( ValidTransition ) ) {
25+ Delta . Add ( transition ) ;
26+ }
27+ }
28+
29+ private bool ValidTransition ( Transition transition ) {
30+ return Q . Contains ( transition . StartState ) &&
31+ Q . Contains ( transition . EndState ) &&
32+ Sigma . Contains ( transition . Symbol ) &&
33+ ! TransitionAlreadyDefined ( transition ) ;
34+ }
35+
36+ private bool TransitionAlreadyDefined ( Transition transition ) {
37+ return Delta . Any ( t => t . StartState == transition . StartState &&
38+ t . Symbol == transition . Symbol ) ;
39+ }
40+
41+ private void AddInitialStates ( IEnumerable < string > q0 ) {
42+ foreach ( var startingState in q0 . Where ( q => q != null && Q . Contains ( q ) ) ) {
43+ Q0 . Add ( startingState ) ;
44+ }
45+ }
46+
47+ private void AddFinalStates ( IEnumerable < string > finalStates ) {
48+ foreach ( var finalState in finalStates . Where ( finalState => Q . Contains ( finalState ) ) ) {
49+ F . Add ( finalState ) ;
50+ }
51+ }
52+
53+ public void Accepts ( string input ) {
54+ ConsoleWriter . Success ( "Trying to parse: " + input ) ;
55+ if ( InvalidInputOrFSM ( input ) ) {
56+ return ;
57+ }
58+ foreach ( var q0 in Q0 ) {
59+ var currentState = q0 ;
60+ var steps = new StringBuilder ( ) ;
61+ foreach ( var symbol in input . ToCharArray ( ) ) {
62+ var transition = Delta . Find ( t => t . StartState == currentState &&
63+ t . Symbol == symbol ) ;
64+ if ( transition == null ) {
65+ ConsoleWriter . Failure ( "No transitions for current state and symbol" ) ;
66+ ConsoleWriter . Failure ( steps . ToString ( ) ) ;
67+ continue ;
68+ }
69+ currentState = transition . EndState ;
70+ steps . Append ( transition + "\n " ) ;
71+ }
72+ if ( F . Contains ( currentState ) ) {
73+ ConsoleWriter . Success ( "Accepted the input with steps:\n " + steps ) ;
74+ return ;
75+ }
76+ ConsoleWriter . Failure ( "Stopped in state " + currentState +
77+ " which is not a final state." ) ;
78+ ConsoleWriter . Failure ( steps . ToString ( ) ) ;
79+ }
80+ }
81+
82+ private bool InvalidInputOrFSM ( string input ) {
83+ if ( InputContainsNotDefinedSymbols ( input ) ) {
84+ return true ;
85+ }
86+ if ( InitialStateNotSet ( ) ) {
87+ ConsoleWriter . Failure ( "No initial state has been set" ) ;
88+ return true ;
89+ }
90+ if ( NoFinalStates ( ) ) {
91+ ConsoleWriter . Failure ( "No final states have been set" ) ;
92+ return true ;
93+ }
94+ return false ;
95+ }
96+
97+ private bool InputContainsNotDefinedSymbols ( string input ) {
98+ foreach ( var symbol in input . ToCharArray ( ) . Where ( symbol => ! Sigma . Contains ( symbol ) ) ) {
99+ ConsoleWriter . Failure ( "Could not accept the input since the symbol " + symbol + " is not part of the alphabet" ) ;
100+ return true ;
101+ }
102+ return false ;
103+ }
104+
105+ private bool InitialStateNotSet ( ) {
106+ return Q0 . Count == 0 ;
107+ }
108+
109+ private bool NoFinalStates ( ) {
110+ return F . Count == 0 ;
111+ }
112+
113+ public void RemoveUnreachableStates ( ) {
114+ var reachableStates = new HashSet < string > ( Q0 ) ;
115+ var newStates = new HashSet < string > ( Q0 ) ;
116+ do {
117+ var temp = new HashSet < string > ( ) ;
118+ foreach ( var q in newStates ) {
119+ var reachableFromQ = Delta . FindAll ( t => t . StartState == q ) . Select ( t => t . EndState ) ;
120+ temp . UnionWith ( reachableFromQ ) ;
121+ }
122+ temp . ExceptWith ( reachableStates ) ;
123+ newStates = temp ;
124+ reachableStates . UnionWith ( newStates ) ;
125+ } while ( newStates . Count > 0 ) ;
126+ var unreachableStates = Q . Where ( q => ! reachableStates . Contains ( q ) ) ;
127+ for ( int i = Delta . Count - 1 ; i > 0 ; i -- ) {
128+ var transition = Delta [ i ] ;
129+ if ( unreachableStates . Contains ( transition . EndState ) ||
130+ unreachableStates . Contains ( transition . StartState ) ) {
131+ Delta . Remove ( transition ) ;
132+ }
133+ }
134+ foreach ( var unrechableState in unreachableStates ) {
135+ Q . Remove ( unrechableState ) ;
136+ }
137+ }
138+ }
139+ }
0 commit comments