Exemplo n.º 1
0
        public static Machine GetFromOptions(SMOptions options)
        {
            Machine stateMachine;

            if (options.Transitions.Any(tr => tr.IsEpsilon) ||
                options.Transitions
                .GroupBy(tr => tr.StartState + tr.Token)
                .Any(gr => gr.Count() > 1))
            {
                stateMachine = new MachineNonDetermined();
            }
            else
            {
                stateMachine = new MachineDetermined();
            }

            var statesNames = options.GetStates();
            var statesDict  = new Dictionary <string, State>();

            foreach (var stateName in statesNames)
            {
                var state = new State(stateName, options.FinalStates.Contains(stateName));
                statesDict.Add(stateName, state);
                stateMachine.AddState(state);
            }

            foreach (var transitionOptions in options.Transitions)
            {
                if (transitionOptions.IsEpsilon)
                {
                    stateMachine.AddTransition(new Transition(
                                                   statesDict[transitionOptions.StartState],
                                                   statesDict[transitionOptions.EndState]
                                                   ));
                }

                else
                {
                    stateMachine.AddTransition(new Transition(
                                                   statesDict[transitionOptions.StartState],
                                                   transitionOptions.Token,
                                                   statesDict[transitionOptions.EndState]
                                                   ));
                }
            }

            stateMachine.Init(options.InitialState);

            return(stateMachine);
        }
Exemplo n.º 2
0
        public new MachineDetermined RenameToNormalNames(string startsWith)
        {
            startsWith ??= "q";

            var renameDict = new Dictionary <State, State>();

            var buffer = new List <State> {
                InitialState
            };

            var n = 1;

            while (buffer.Any())
            {
                var currentNode = buffer[0];

                var nextStops = Transitions.Where(tr => Equals(tr.StartState, currentNode) && !buffer.Contains(tr.EndState) && !renameDict.Keys.Contains(tr.EndState)).Select(tr => tr.EndState).Distinct(new StatesComparer()).ToList();

                if (nextStops.Any())
                {
                    buffer.AddRange(nextStops);
                }

                buffer.Remove(currentNode);
                renameDict.Add(currentNode, new State($"{startsWith}{n}", currentNode.IsFinal));
                n++;
            }

            var renamedMachine = new MachineDetermined();

            renamedMachine.AddStateRange(renameDict.Values);
            renamedMachine.AddTransitionRange(Transitions.Select(transition => new Transition(renameDict[transition.StartState], transition.Token, renameDict[transition.EndState])));
            renamedMachine.Init(renameDict[InitialState].Id);

            return(renamedMachine);
        }
Exemplo n.º 3
0
        public override Machine Minimize()
        {
            var tokens = Transitions.Select(transition => transition.Token).Distinct().ToList();

            tokens.Sort();

            var currentSplitting = States.GroupBy(state => state.IsFinal ? "A0" : "B0").ToList();

            for (int k = 1; k <= States.Count; ++k)
            {
                var newSplitting = new List <IGrouping <string, State> >();

                foreach (var currentCategory in currentSplitting)
                {
                    var subSplittingIntoCurrentCategory = currentCategory.GroupBy(checkedStartState => {
                        var kLocal = k;
                        var currentSplittingLocal = currentSplitting;

                        var movementCategories = tokens.Select(checkedToken =>
                        {
                            var endState = Transitions.Find(transition =>
                                                            Equals(transition.StartState, checkedStartState) &&
                                                            transition.Token == checkedToken)
                                           ?.EndState;

                            if (endState == null)
                            {
                                return("");
                            }

                            var endCategory = currentSplittingLocal.Find(suspectedCategory =>
                                                                         suspectedCategory.Contains(endState));

                            var nameOfEndCategory = "{" + string.Join(",", endCategory) + "}" /* + "[" + kLocal + "]"*/;
                            return(nameOfEndCategory);
                        });

                        var movementsRow = string.Join("|", movementCategories);

                        return(movementsRow);
                    }).ToList();

                    newSplitting.AddRange(subSplittingIntoCurrentCategory);
                }

                currentSplitting = newSplitting;

                // If current splitting ans new splitting are equal
                // Then break; here [todo]
            }

            var minimizedStateMachine = new MachineDetermined();

            var newStates = currentSplitting.Select(category => new { State = new State("{" + string.Join(",", category.Select(state => state.Id)) + "}", category.Any(state => state.IsFinal)), Category = category }).ToList();

            minimizedStateMachine.AddStateRange(newStates.Select(state => state.State));

            foreach (var startPoint in newStates)
            {
                var ways = startPoint.Category.Key.Split("|")
                           .Zip(tokens, (endPoint, token) => new { Token = token, EndPoint = endPoint })
                           .Where(x => !string.IsNullOrEmpty(x.EndPoint))
                           .Select(x =>
                {
                    var endPointState = newStates.Find(state => state.State.Id == x.EndPoint);

                    return(new Transition(startPoint.State, x.Token, endPointState.State));    // Null check??
                });

                minimizedStateMachine.AddTransitionRange(ways);
            }

            minimizedStateMachine.Init(newStates.Find(x => x.Category.Contains(InitialState))?.State.Id ?? throw new InitialStateIsNullException("null", minimizedStateMachine));

            return(minimizedStateMachine);
        }
Exemplo n.º 4
0
        public override MachineDetermined Determine(bool verbose = false)
        {
            var determined = new MachineDetermined();

            if (IsThereAnyEpsilonTransition || IsThereAnyMultiVariantTokenTransition)
            {
                var tokens = Transitions.Select(tr => tr.Token).Distinct().ToList();
                tokens.Remove(null);
                tokens.Sort();

                var initialClosure = EpsilonClosure(new List <State> {
                    InitialState
                });
                var buffer = new List <List <State> > {
                    initialClosure
                };
                var newStates     = new List <List <State> >();
                var tempMovements = new List <TempTransition>();

                if (verbose)
                {
                    Console.WriteLine("ε-closure({" + InitialState.Id + "}) = " + GetClosureName(initialClosure) + "\n");
                }

                while (buffer.Any())
                {
                    var currentClosure = buffer[0];
                    buffer.Remove(currentClosure);

                    newStates.Add(currentClosure);

                    foreach (var token in tokens)
                    {
                        var nextStops = Transitions.Where(tr =>
                                                          !tr.IsEpsilon && currentClosure.Contains(tr.StartState) && tr.Token == token)
                                        .Select(tr => tr.EndState)
                                        .ToList();

                        var newClosure = EpsilonClosure(nextStops);

                        if (verbose)
                        {
                            Console.Write($"Move({GetClosureName(currentClosure)}, {token}) =  {GetClosureName(nextStops)};");
                        }

                        if (newClosure.Any())
                        {
                            tempMovements.Add(new TempTransition(GetClosureName(currentClosure), token, GetClosureName(newClosure)));
                        }

                        if (!newClosure.Any() ||
                            newStates.Select(GetClosureName).Contains(GetClosureName(newClosure)) ||
                            buffer.Select(GetClosureName).Contains(GetClosureName(newClosure)))
                        {
                            if (verbose)
                            {
                                Console.WriteLine();
                            }
                            continue;
                        }

                        if (verbose)
                        {
                            Console.WriteLine($"     ε-closure({GetClosureName(nextStops)}) = {GetClosureName(newClosure)}");
                        }

                        buffer.Add(newClosure);
                    }

                    if (verbose)
                    {
                        Console.WriteLine();
                    }
                }

                var determinedStates = newStates.Select(state => new State(GetClosureName(state), state.Any(x => x.IsFinal))).ToList();
                determined.AddStateRange(determinedStates);

                foreach (var startNewState in determinedStates)
                {
                    foreach (var token in tokens)
                    {
                        var way = tempMovements.Find(mv => mv.Q0 == startNewState.Id && mv.Token == token);

                        if (way == null)
                        {
                            continue;
                        }

                        var nextStop = determinedStates.Find(st => st.Id == way.Q1);

                        determined.AddTransition(new Transition(startNewState, token, nextStop));
                    }
                }

                determined.Init(GetClosureName(initialClosure));
            }

            else
            {
                determined.AddStateRange(States);
                determined.AddTransitionRange(Transitions);
                determined.Init(InitialState.Id);
            }

            return(determined);
        }