Beispiel #1
0
 public void AddTransition(string condition, State nextState)
 {
     Transitions.Add(Transition.Parse(condition, this, nextState));
     if (AmountOfTapes == 0)
     {
         AmountOfTapes = Transitions.First().AmountOfTapes;
         return;
     }
     if (Transitions.Any(c => c.AmountOfTapes != AmountOfTapes))
     {
         throw new ArgumentException("The amounts of tapes required differs among the conditions.");
     }
 }
Beispiel #2
0
        public bool IsLoopFixedPoint()
        {
            if (Transitions == null || !Transitions.Any())
            {
                return(true);
            }

            var nextCondition = Transitions.First().Node.CurrentCondition;

            return(CurrentCondition.Count == nextCondition.Count &&
                   CurrentCondition.All(a => nextCondition.ContainsKey(a.Key) && nextCondition[a.Key] == a.Value) &&
                   Transitions.First().Node.IsLoopFixedPoint());
        }
        public void Transition(string token)
        {
            // First check that we have that token defined
            if (!Tokens.Contains(token))
            {
                throw new ArgumentOutOfRangeException(nameof(token), token, "Given token is not defined.");
            }

            // And that we have a transition for this token
            if (!Transitions.Any(t => t.Token == token && t.From == CurrentState))
            {
                throw new ArgumentOutOfRangeException(nameof(token), token, $"No transition exists for {CurrentState} + {token}.");
            }

            // Get list of possible transitions...
            var possible = Transitions.Where(t => t.From == CurrentState && t.Token == token).ToList();

            // Check validity of transition
            do
            {
                var transition = possible.MinBy(t =>
                {
                    if (t.TransitionMode != Mode.Pop)
                    {
                        return(0);
                    }
                    var distanceTo = Stack.IndexOf((T)t.To);
                    return(distanceTo == -1 ? int.MaxValue : distanceTo);
                });
                switch (transition.TransitionMode)
                {
                case Mode.Pop:
                    var pop = Stack.IndexOf((T)transition.To);
                    if (pop == -1)
                    {
                        possible.Remove(transition);
                        continue;
                    }
                    for (var i = 0; i < pop; i++)
                    {
                        Stack.RemoveAt(0);
                    }
                    break;

                case Mode.Push:
                    transition = Transitions.First(t => t.Token == token && t.From == CurrentState);
                    Stack.Insert(0, (T)transition.To);
                    break;

                case Mode.PushPop:
                    transition = Transitions.First(t => t.Token == token && t.From == CurrentState);
                    if (Stack.Count > 0)
                    {
                        Stack.RemoveAt(0);
                    }
                    Stack.Insert(0, (T)transition.To);
                    break;
                }

                CurrentState?.Enter();
                Transitioned?.Invoke(transition);
                return;
            } while (Transitions.Count > 0);
        }