/// <summary> /// Optionally modifies the <paramref name="transitions" />, changing any of their values. However, no new transitions can be /// added; transitions can be removed by setting their <see cref="CandidateTransition.IsValid" /> flag to <c>false</c>. /// During subsequent traversal steps, only valid transitions and target states reached by at least one valid transition /// are considered. /// </summary> /// <param name="context">The context of the model traversal.</param> /// <param name="worker">The worker that found the transition.</param> /// <param name="transitions">The transitions that should be checked.</param> /// <param name="sourceState">The source state of the transitions.</param> /// <param name="sourceStateIndex">The unique index of the transition's source state.</param> /// <param name="isInitial">Indicates whether the transitions are initial transitions not starting in any valid source state.</param> public void ModifyTransitions(TraversalContext context, Worker worker, TransitionCollection transitions, byte *sourceState, int sourceStateIndex, bool isInitial) { foreach (CandidateTransition *transition in transitions) { if (TransitionFlags.IsValid(transition->Flags) && _terminateEarlyCondition(transition->Formulas)) { transition->Flags = TransitionFlags.SetToStutteringStateFlag(transition->Flags); } } }
private void IterateThroughAllTransitionsInSortedOrder() { var mergeInCandidateIndex = 0; while (mergeInCandidateIndex < _transitions.Count) { var mergeInCandidate = GetCandidateTransition(mergeInCandidateIndex); if (TransitionFlags.IsValid(mergeInCandidate->Flags)) { MergeCandidateWithAllApplicableTargets(mergeInCandidate, mergeInCandidateIndex); } mergeInCandidateIndex++; } }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> public bool MoveNext() { ++_current; while (_current < _count) { if (TransitionFlags.IsValid(Current->Flags)) { return(true); } ++_current; } return(false); }
private uint HashTransition(LtmcTransition *transition) { // hashing see FNV hash at http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx if (!TransitionFlags.IsValid(transition->Flags)) { return(0); } unchecked { uint hash = 0; if (!TransitionFlags.IsToStutteringState(transition->Flags)) { hash = MemoryBuffer.Hash(transition->TargetStatePointer, RelevantStateVectorSize, 0); } hash = hash * 397 ^ (uint)transition->Formulas.GetHashCode(); return(hash); } }
private void MergeCandidateWithAllApplicableTargets(LtmcTransition *mergeInCandidate, int mergeInCandidateIndex) { var mergeInCandidateHash = GetCandidateHash(mergeInCandidateIndex); var toMergeCandidateIndex = mergeInCandidateIndex + 1; while (!CandidateIsOutOfIndexOrHasDifferentHash(mergeInCandidateHash, toMergeCandidateIndex)) { var toMergeCandidate = GetCandidateTransition(toMergeCandidateIndex); if (TransitionFlags.IsValid(toMergeCandidate->Flags)) { if (CanTransitionsBeMerged(mergeInCandidate, toMergeCandidate)) { MergeTransitions(mergeInCandidate, toMergeCandidate); } } toMergeCandidateIndex++; } }
/// <summary> /// Adds the <paramref name="sourceState" /> and all of its <see cref="transitions" /> to the state graph. /// </summary> /// <param name="sourceState">The state that should be added.</param> /// <param name="isInitial">Indicates whether the state is an initial state.</param> /// <param name="transitions">The transitions leaving the state.</param> /// <param name="transitionCount">The number of valid transitions leaving the state.</param> internal void AddStateInfo(int sourceState, bool isInitial, TransitionCollection transitions, int transitionCount) { Assert.That(transitionCount > 0, "Cannot add deadlock state."); Dictionary <EnrichedTargetState, double> container; if (isInitial) { container = _initialStates; } else { if (_transitions.ContainsKey(sourceState)) { container = _transitions[sourceState]; } else { container = new Dictionary <EnrichedTargetState, double>(); _transitions[sourceState] = container; } } // Search for place to append is linear in number of existing transitions of state linearly => O(n^2) foreach (var transition in transitions) { var probTransition = (LtmcTransition *)transition; Assert.That(TransitionFlags.IsValid(probTransition->Flags), "Attempted to add an invalid transition."); var enrichedTargetState = new EnrichedTargetState(transition->TargetStateIndex, transition->Formulas); if (container.ContainsKey(enrichedTargetState)) { //Case 1: Merge var currentProbability = container[enrichedTargetState]; container[enrichedTargetState] = currentProbability + probTransition->Probability; } else { //Case 2: Append container.Add(enrichedTargetState, probTransition->Probability); } } }
/// <summary> /// Adds the <paramref name="state" /> and all of its <see cref="transitions" /> to the state graph. /// </summary> /// <param name="state">The state that should be added.</param> /// <param name="isInitial">Indicates whether the state is an initial state.</param> /// <param name="transitions">The transitions leaving the state.</param> /// <param name="transitionCount">The number of valid transitions leaving the state.</param> internal void AddStateInfo(int state, bool isInitial, TransitionCollection transitions, int transitionCount) { Assert.That(!isInitial || _initialTransitionCount == 0, "Initial transitions can only be added once."); if (isInitial) { _initialTransitionCount = transitionCount; } else { Interlocked.Increment(ref _stateCount); } Interlocked.Add(ref _transitionCount, transitionCount); // Transitions are synchronized by atomatically incrementing the offset counter var offset = InterlockedExtensions.AddFetch(ref _transitionOffset, transitionCount); if (offset + transitionCount > _transitionCapacity) { throw new OutOfMemoryException("Unable to store transitions. Try increasing the transition capacity."); } // No need to synchronize state addition, as all states are only discovered once if (!isInitial) { _stateMap[state] = new TransitionRange { StartIndex = offset, Count = transitionCount } } ; // Copy the transitions into the buffer foreach (var transition in transitions) { Assert.That(TransitionFlags.IsValid(transition->Flags), "Attempted to add an invalid transition."); MemoryBuffer.Copy((byte *)transition, _transitions + offset * TransitionSize, TransitionSize); ++offset; } }
private void CheckIfTransitionIsValid(LtmcTransition *transition) { Assert.That(TransitionFlags.IsValid(transition->Flags), "Attempted to add an invalid transition."); }