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."); } }
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); }