|
|
|
@ -4,7 +4,8 @@ using System.Text;
@@ -4,7 +4,8 @@ using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace CppSharp.Utils.FSM |
|
|
|
|
{ |
|
|
|
|
public class DFSM{ |
|
|
|
|
public class DFSM |
|
|
|
|
{ |
|
|
|
|
public readonly List<string> Q = new List<string>(); |
|
|
|
|
public readonly List<char> Sigma = new List<char>(); |
|
|
|
|
public readonly List<Transition> Delta = new List<Transition>(); |
|
|
|
@ -12,7 +13,8 @@ namespace CppSharp.Utils.FSM
@@ -12,7 +13,8 @@ namespace CppSharp.Utils.FSM
|
|
|
|
|
public List<string> F = new List<string>(); |
|
|
|
|
|
|
|
|
|
public DFSM(IEnumerable<string> q, IEnumerable<char> sigma, IEnumerable<Transition> delta, |
|
|
|
|
IEnumerable<string> q0, IEnumerable<string> f){ |
|
|
|
|
IEnumerable<string> q0, IEnumerable<string> f) |
|
|
|
|
{ |
|
|
|
|
Q = q.ToList(); |
|
|
|
|
Sigma = sigma.ToList(); |
|
|
|
|
AddTransitions(delta); |
|
|
|
@ -20,48 +22,61 @@ namespace CppSharp.Utils.FSM
@@ -20,48 +22,61 @@ namespace CppSharp.Utils.FSM
|
|
|
|
|
AddFinalStates(f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void AddTransitions(IEnumerable<Transition> transitions){ |
|
|
|
|
foreach (var transition in transitions.Where(ValidTransition)){ |
|
|
|
|
private void AddTransitions(IEnumerable<Transition> transitions) |
|
|
|
|
{ |
|
|
|
|
foreach (var transition in transitions.Where(ValidTransition)) |
|
|
|
|
{ |
|
|
|
|
Delta.Add(transition); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool ValidTransition(Transition transition){ |
|
|
|
|
private bool ValidTransition(Transition transition) |
|
|
|
|
{ |
|
|
|
|
return Q.Contains(transition.StartState) && |
|
|
|
|
Q.Contains(transition.EndState) && |
|
|
|
|
Sigma.Contains(transition.Symbol) && |
|
|
|
|
!TransitionAlreadyDefined(transition); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool TransitionAlreadyDefined(Transition transition){ |
|
|
|
|
private bool TransitionAlreadyDefined(Transition transition) |
|
|
|
|
{ |
|
|
|
|
return Delta.Any(t => t.StartState == transition.StartState && |
|
|
|
|
t.Symbol == transition.Symbol); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void AddInitialStates(IEnumerable<string> q0){ |
|
|
|
|
foreach (var startingState in q0.Where(q => q != null && Q.Contains(q))){ |
|
|
|
|
private void AddInitialStates(IEnumerable<string> q0) |
|
|
|
|
{ |
|
|
|
|
foreach (var startingState in q0.Where(q => q != null && Q.Contains(q))) |
|
|
|
|
{ |
|
|
|
|
Q0.Add(startingState); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void AddFinalStates(IEnumerable<string> finalStates){ |
|
|
|
|
foreach (var finalState in finalStates.Where(finalState => Q.Contains(finalState))){ |
|
|
|
|
private void AddFinalStates(IEnumerable<string> finalStates) |
|
|
|
|
{ |
|
|
|
|
foreach (var finalState in finalStates.Where(finalState => Q.Contains(finalState))) |
|
|
|
|
{ |
|
|
|
|
F.Add(finalState); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void Accepts(string input){ |
|
|
|
|
public void Accepts(string input) |
|
|
|
|
{ |
|
|
|
|
ConsoleWriter.Success("Trying to parse: " + input); |
|
|
|
|
if (InvalidInputOrFSM(input)){ |
|
|
|
|
if (InvalidInputOrFSM(input)) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
foreach (var q0 in Q0){ |
|
|
|
|
foreach (var q0 in Q0) |
|
|
|
|
{ |
|
|
|
|
var currentState = q0; |
|
|
|
|
var steps = new StringBuilder(); |
|
|
|
|
foreach (var symbol in input.ToCharArray()){ |
|
|
|
|
foreach (var symbol in input.ToCharArray()) |
|
|
|
|
{ |
|
|
|
|
var transition = Delta.Find(t => t.StartState == currentState && |
|
|
|
|
t.Symbol == symbol); |
|
|
|
|
if (transition == null){ |
|
|
|
|
if (transition == null) |
|
|
|
|
{ |
|
|
|
|
ConsoleWriter.Failure("No transitions for current state and symbol"); |
|
|
|
|
ConsoleWriter.Failure(steps.ToString()); |
|
|
|
|
continue; |
|
|
|
@ -69,7 +84,8 @@ namespace CppSharp.Utils.FSM
@@ -69,7 +84,8 @@ namespace CppSharp.Utils.FSM
|
|
|
|
|
currentState = transition.EndState; |
|
|
|
|
steps.Append(transition + "\n"); |
|
|
|
|
} |
|
|
|
|
if (F.Contains(currentState)){ |
|
|
|
|
if (F.Contains(currentState)) |
|
|
|
|
{ |
|
|
|
|
ConsoleWriter.Success("Accepted the input with steps:\n" + steps); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -79,43 +95,54 @@ namespace CppSharp.Utils.FSM
@@ -79,43 +95,54 @@ namespace CppSharp.Utils.FSM
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool InvalidInputOrFSM(string input){ |
|
|
|
|
if (InputContainsNotDefinedSymbols(input)){ |
|
|
|
|
private bool InvalidInputOrFSM(string input) |
|
|
|
|
{ |
|
|
|
|
if (InputContainsNotDefinedSymbols(input)) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
if (InitialStateNotSet()){ |
|
|
|
|
if (InitialStateNotSet()) |
|
|
|
|
{ |
|
|
|
|
ConsoleWriter.Failure("No initial state has been set"); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
if (NoFinalStates()){ |
|
|
|
|
if (NoFinalStates()) |
|
|
|
|
{ |
|
|
|
|
ConsoleWriter.Failure("No final states have been set"); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool InputContainsNotDefinedSymbols(string input){ |
|
|
|
|
foreach (var symbol in input.ToCharArray().Where(symbol => !Sigma.Contains(symbol))){ |
|
|
|
|
private bool InputContainsNotDefinedSymbols(string input) |
|
|
|
|
{ |
|
|
|
|
foreach (var symbol in input.ToCharArray().Where(symbol => !Sigma.Contains(symbol))) |
|
|
|
|
{ |
|
|
|
|
ConsoleWriter.Failure("Could not accept the input since the symbol " + symbol + " is not part of the alphabet"); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool InitialStateNotSet(){ |
|
|
|
|
private bool InitialStateNotSet() |
|
|
|
|
{ |
|
|
|
|
return Q0.Count == 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private bool NoFinalStates(){ |
|
|
|
|
private bool NoFinalStates() |
|
|
|
|
{ |
|
|
|
|
return F.Count == 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void RemoveUnreachableStates(){ |
|
|
|
|
public void RemoveUnreachableStates() |
|
|
|
|
{ |
|
|
|
|
var reachableStates = new HashSet<string>(Q0); |
|
|
|
|
var newStates = new HashSet<string>(Q0); |
|
|
|
|
do{ |
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
var temp = new HashSet<string>(); |
|
|
|
|
foreach (var q in newStates){ |
|
|
|
|
foreach (var q in newStates) |
|
|
|
|
{ |
|
|
|
|
var reachableFromQ = Delta.FindAll(t => t.StartState == q).Select(t => t.EndState); |
|
|
|
|
temp.UnionWith(reachableFromQ); |
|
|
|
|
} |
|
|
|
@ -124,14 +151,17 @@ namespace CppSharp.Utils.FSM
@@ -124,14 +151,17 @@ namespace CppSharp.Utils.FSM
|
|
|
|
|
reachableStates.UnionWith(newStates); |
|
|
|
|
} while (newStates.Count > 0); |
|
|
|
|
var unreachableStates = Q.Where(q => !reachableStates.Contains(q)); |
|
|
|
|
for (int i = Delta.Count - 1; i > 0; i--){ |
|
|
|
|
for (int i = Delta.Count - 1; i > 0; i--) |
|
|
|
|
{ |
|
|
|
|
var transition = Delta[i]; |
|
|
|
|
if (unreachableStates.Contains(transition.EndState) || |
|
|
|
|
unreachableStates.Contains(transition.StartState)){ |
|
|
|
|
unreachableStates.Contains(transition.StartState)) |
|
|
|
|
{ |
|
|
|
|
Delta.Remove(transition); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
foreach (var unrechableState in unreachableStates){ |
|
|
|
|
foreach (var unrechableState in unreachableStates) |
|
|
|
|
{ |
|
|
|
|
Q.Remove(unrechableState); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|