Beispiel #1
0
 /// <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);
     }
 }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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)));
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
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);
            }
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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;
        }