/// <summary> /// Adds an outgoing transition to the place. This is usually called when you add a <see cref="Transition"/> to the net. /// </summary> /// <param Name="transition">The outgoing transition.</param> public void AppendOutgoingTransition(Transition transition) { if (!OutgoingTransitions.Contains(transition)) { OutgoingTransitions.Add(transition); } }
public void RemoveTransition(Transition transition, StateOptimizer optimizer = null) { Requires.NotNull(transition, nameof(transition)); Requires.Argument(transition.SourceState == this, nameof(transition), "The transition source state must be the current instance."); Verify.Operation(OutgoingTransitions.Contains(transition), "Expected the state to contain the transition."); RemoveTransitionInternal(transition, optimizer); }
public void AddTransition(Transition transition, StateOptimizer optimizer = null) { Contract.Requires <ArgumentNullException>(transition != null, "transition"); Contract.Requires <InvalidOperationException>(transition.SourceState == null); Contract.Requires <InvalidOperationException>(!OutgoingTransitions.Contains(transition)); Contract.Requires <InvalidOperationException>(!transition.TargetState.IncomingTransitions.Contains(transition)); AddTransitionInternal(transition, optimizer); }
public void AddTransition(Transition transition, StateOptimizer optimizer = null) { Requires.NotNull(transition, nameof(transition)); Verify.Operation(transition.SourceState == null, "Expected the transition to not be associated with a source state."); Verify.Operation(!OutgoingTransitions.Contains(transition), "Expected the state to not already contain the transition."); Verify.Operation(!transition.TargetState.IncomingTransitions.Contains(transition), "Expected the target state to not already contain the incoming transition."); AddTransitionInternal(transition, optimizer); }
public void RemoveTransition(Transition transition, StateOptimizer optimizer = null) { Contract.Requires <ArgumentNullException>(transition != null, "transition"); Contract.Requires <ArgumentException>(transition.SourceState == this); Contract.Requires <InvalidOperationException>(OutgoingTransitions.Contains(transition)); Contract.Ensures(transition.SourceState == null); Contract.Ensures(!Contract.OldValue(transition.SourceState).OutgoingTransitions.Contains(transition)); Contract.Ensures(!transition.TargetState.IncomingTransitions.Contains(transition)); RemoveTransitionInternal(transition, optimizer); }
internal void RemoveTransitionInternal(Transition transition, StateOptimizer optimizer) { Contract.Requires(transition != null, "transition"); Contract.Requires(transition.SourceState == this); #if ALL_CHECKS Contract.Requires(OutgoingTransitions.Contains(transition)); #endif Contract.Ensures(transition.SourceState == null); #if ALL_CHECKS Contract.Ensures(!Contract.OldValue(transition.SourceState).OutgoingTransitions.Contains(transition)); Contract.Ensures(!transition.TargetState.IncomingTransitions.Contains(transition)); Contract.Assert(transition.TargetState.IncomingTransitions.Contains(transition)); #endif //PopContextTransition popContextTransition = transition as PopContextTransition; //if (popContextTransition != null) //{ // foreach (var pushTransition in popContextTransition.PushTransitions) // { // Contract.Assert(pushTransition.PopTransitions.Contains(transition)); // pushTransition.PopTransitions.Remove(popContextTransition); // } //} //PushContextTransition pushContextTransition = transition as PushContextTransition; //if (pushContextTransition != null) //{ // foreach (var popTransition in pushContextTransition.PopTransitions) // { // Contract.Assert(popTransition.PushTransitions.Contains(transition)); // popTransition.PushTransitions.Remove(pushContextTransition); // } //} if (optimizer != null) { optimizer.RemoveTransition(transition); } OutgoingTransitions.Remove(transition); transition.TargetState.IncomingTransitions.Remove(transition); _followSet = null; _isForwardRecursive = null; transition.TargetState._sourceSet = null; transition.TargetState._isBackwardRecursive = null; transition.SourceState = null; }
internal IEnumerable <Transition> GetOptimizedTransitions() { if (IsOptimized) { return(OutgoingTransitions); } HashSet <State> visited = new HashSet <State>(ObjectReferenceEqualityComparer <State> .Default); if (HasRecursiveTransitions ?? true) { visited.Add(this); } return(OutgoingTransitions.SelectMany(i => FollowOptimizedTransitions(visited, i))); }
public virtual TransitionImpl CreateOutgoingTransition(string transitionId) { var transition = new TransitionImpl(transitionId, processDefinition); transition.Source = this; OutgoingTransitions.Add(transition); if (!ReferenceEquals(transitionId, null)) { if (NamedOutgoingTransitions.ContainsKey(transitionId)) { throw new PvmException("activity '" + id + " has duplicate transition '" + transitionId + "'"); } NamedOutgoingTransitions[transitionId] = transition; } return(transition); }
private void OptimizeOutgoingTransitions(StateOptimizer optimizer) { List <Transition> oldTransitions = new List <Transition>(OutgoingTransitions.Where(i => !i.IsRecursive)); foreach (var transition in oldTransitions) { RemoveTransitionInternal(transition, optimizer); } Contract.Assert(Contract.ForAll(OutgoingTransitions, i => i.IsRecursive)); foreach (var transition in oldTransitions) { HashSet <Transition> visited = new HashSet <Transition>(ObjectReferenceEqualityComparer <Transition> .Default); visited.Add(transition); AddOptimizedTransitions(optimizer, visited, transition, PreventContextType.None); } Contract.Assert(oldTransitions.Count == 0 || OutgoingTransitions.Count > 0); }
public void RemoveExtraEpsilonTransitions(StateOptimizer optimizer, bool isStartState) { if (OutgoingTransitions.Count == 1 && OutgoingTransitions.First().IsEpsilon) { Transition epsilon = OutgoingTransitions.First(); foreach (var incoming in IncomingTransitions.ToArray()) { State sourceState = incoming.SourceState; sourceState.RemoveTransitionInternal(incoming, optimizer); sourceState.AddTransitionInternal(MergeTransitions(incoming, epsilon), optimizer); } if (!isStartState) { RemoveTransitionInternal(epsilon, optimizer); } } if (IncomingTransitions.Count == 1 && IncomingTransitions.First().IsEpsilon) { Transition epsilon = IncomingTransitions.First(); State sourceState = epsilon.SourceState; foreach (var outgoing in OutgoingTransitions.ToArray()) { if (!isStartState) { this.RemoveTransitionInternal(outgoing, optimizer); } sourceState.AddTransitionInternal(MergeTransitions(epsilon, outgoing), optimizer); } epsilon.SourceState.RemoveTransitionInternal(epsilon, optimizer); } }
public IntervalSet GetFollowSet(PreventContextType preventContextType) { if (_followSet != null && _followSet[(int)preventContextType] != null) { return(_followSet[(int)preventContextType]); } IntervalSet[] sets = _followSet ?? new IntervalSet[Enum.GetValues(typeof(PreventContextType)).Cast <int>().Max() + 1]; IntervalSet set = new IntervalSet(); var queue = new Queue <Tuple <Transition, PreventContextType> >(OutgoingTransitions.Select(i => Tuple.Create(i, preventContextType))); var comparer = new TupleEqualityComparer <Transition, PreventContextType>(ObjectReferenceEqualityComparer <Transition> .Default, null); var visited = new HashSet <Tuple <Transition, PreventContextType> >(queue, comparer); while (queue.Count > 0) { var pair = queue.Dequeue(); Transition transition = pair.Item1; PreventContextType nextPreventContextType = pair.Item2; if (transition.IsContext) { switch (nextPreventContextType) { case PreventContextType.Pop: if (!transition.IsRecursive && transition is PopContextTransition) { continue; } break; case PreventContextType.PopRecursive: if (transition.IsRecursive && (transition is PopContextTransition)) { continue; } break; case PreventContextType.Push: if (!transition.IsRecursive && transition is PushContextTransition) { continue; } break; case PreventContextType.PushRecursive: if (transition.IsRecursive && (transition is PushContextTransition)) { continue; } break; default: break; } } if (transition.IsEpsilon || transition.IsContext) { // the preventContextType can only change if we're following a another context transition if (transition.IsContext) { nextPreventContextType = PreventContextType.None; if (transition.SourceState.IsOptimized) { if (transition is PushContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PushRecursive : PreventContextType.Push; } else if (transition is PopContextTransition) { nextPreventContextType = transition.IsRecursive ? PreventContextType.PopRecursive : PreventContextType.Pop; } } } if (transition.TargetState._followSet != null && transition.TargetState._followSet[(int)nextPreventContextType] != null) { set.UnionWith(transition.TargetState._followSet[(int)nextPreventContextType]); } else { foreach (var outgoing in transition.TargetState.OutgoingTransitions) { var nextPair = Tuple.Create(outgoing, nextPreventContextType); if (visited.Add(nextPair)) { queue.Enqueue(Tuple.Create(outgoing, nextPreventContextType)); } } } } else { set.UnionWith(transition.MatchSet); } } _followSet = sets; _followSet[(int)preventContextType] = set; return(set); }
internal void AddTransitionInternal(Transition transition, StateOptimizer optimizer) { Contract.Requires(transition != null); Contract.Requires(transition.SourceState == null); #if ALL_CHECKS Contract.Requires(!OutgoingTransitions.Contains(transition)); Contract.Requires(!transition.TargetState.IncomingTransitions.Contains(transition)); #endif if (IsRecursiveAnalysisComplete && !transition.IsMatch && transition.TargetState == this && !transition.IsRecursive) { throw new InvalidOperationException(); } PopContextTransition popContextTransition = transition as PopContextTransition; PushContextTransition pushContextTransition = transition as PushContextTransition; #if false if (popContextTransition != null && !transition.IsRecursive) { foreach (var recursive in OutgoingTransitions.OfType <PopContextTransition>().Where(i => i.IsRecursive)) { if (popContextTransition.ContextIdentifiers.Take(recursive.ContextIdentifiers.Count).SequenceEqual(recursive.ContextIdentifiers)) { if (popContextTransition.ContextIdentifiers.Count > recursive.ContextIdentifiers.Count) { throw new InvalidOperationException(); } } } } #endif if (_outgoingTransitions.Count > 10 && !(_outgoingTransitions is ISet <Transition>)) { _outgoingTransitions = new HashSet <Transition>(_outgoingTransitions, ObjectReferenceEqualityComparer <Transition> .Default); } #if false if (transition.IsContext && transition.IsRecursive) { PopContextTransition first = transition as PopContextTransition; if (first != null) { foreach (var existing in OutgoingTransitions.OfType <PopContextTransition>().ToArray()) { if (existing.TargetState != transition.TargetState) { continue; } if (first.ContextIdentifiers.Take(existing.ContextIdentifiers.Count).SequenceEqual(existing.ContextIdentifiers)) { RemoveTransitionInternal(existing, optimizer); } } } PushContextTransition second = transition as PushContextTransition; if (second != null) { foreach (var existing in OutgoingTransitions.OfType <PushContextTransition>().ToArray()) { if (existing.TargetState != transition.TargetState) { continue; } if (second.ContextIdentifiers.Take(existing.ContextIdentifiers.Count).SequenceEqual(existing.ContextIdentifiers)) { RemoveTransitionInternal(existing, optimizer); } } } } #endif OutgoingTransitions.Add(transition); if (transition.TargetState.IncomingTransitions.Count > 10 && !(transition.TargetState.IncomingTransitions is ISet <Transition>)) { transition.TargetState._incomingTransitions = new HashSet <Transition>(transition.TargetState._incomingTransitions, ObjectReferenceEqualityComparer <Transition> .Default); } transition.TargetState.IncomingTransitions.Add(transition); transition.SourceState = this; if (optimizer != null) { optimizer.AddTransition(transition); } if (popContextTransition != null) { //if (optimizer != null) // popContextTransition.PushTransitions.UnionWith(optimizer.GetPushContextTransitions(popContextTransition.ContextIdentifiers.Last())); //foreach (var pushTransition in popContextTransition.PushTransitions) //{ // Contract.Assert(pushTransition.ContextIdentifiers.First() == popContextTransition.ContextIdentifiers.Last()); // Contract.Assert(pushTransition.SourceState != null); // pushTransition.PopTransitions.Add(popContextTransition); //} #if ALL_CHECKS Contract.Assert(Contract.ForAll(OutgoingTransitions.OfType <PushContextTransition>(), i => i.ContextIdentifiers.Last() != popContextTransition.ContextIdentifiers.First() || popContextTransition.PushTransitions.Contains(i))); #endif } else if (pushContextTransition != null) { //if (optimizer != null) // pushContextTransition.PopTransitions.UnionWith(optimizer.GetPopContextTransitions(pushContextTransition.ContextIdentifiers[0])); //foreach (var popTransition in pushContextTransition.PopTransitions) //{ // Contract.Assert(popTransition.ContextIdentifiers.Last() == pushContextTransition.ContextIdentifiers.First()); // Contract.Assert(popTransition.SourceState != null); // popTransition.PushTransitions.Add(pushContextTransition); //} #if ALL_CHECKS Contract.Assert(Contract.ForAll(OutgoingTransitions.OfType <PopContextTransition>(), i => i.ContextIdentifiers.Last() != pushContextTransition.ContextIdentifiers.First() || pushContextTransition.PopTransitions.Contains(i))); #endif } _followSet = null; _isForwardRecursive = null; transition.TargetState._sourceSet = null; transition.TargetState._isBackwardRecursive = null; }