private bool CanTransitionsBeMerged(LtmcTransition *a, LtmcTransition *b)
        {
            var aToStuttering = TransitionFlags.IsToStutteringState(a->Flags);
            var bToStuttering = TransitionFlags.IsToStutteringState(b->Flags);

            if (aToStuttering != bToStuttering)
            {
                // Target states do not match
                return(false);
            }
            if (!aToStuttering)
            {
                // both target states are not the stuttering state. So check if the states match
                if (!MemoryBuffer.AreEqual(a->TargetStatePointer, b->TargetStatePointer, RelevantStateVectorSize))
                {
                    return(false);
                }
            }
            if (a->Flags != b->Flags)
            {
                return(false);
            }
            if (a->Formulas != b->Formulas)
            {
                return(false);
            }
            return(true);
        }
Exemple #2
0
 /// <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 <TExecutableModel> context, Worker <TExecutableModel> worker, TransitionCollection transitions, byte *sourceState,
                               int sourceStateIndex, bool isInitial)
 {
     foreach (CandidateTransition *transition in transitions)
     {
         transition->Flags = TransitionFlags.SetIsValidIffCondition(transition->Flags, transition->ActivatedFaults.GetIntersection(_suppressedFaults).IsEmpty);
     }
 }
 /// <summary>
 ///   Returns the target state if the transition has been transformed by Worker::HandleTransitions.
 /// </summary>
 public int GetTargetStateIndex()
 {
     Assert.That(TransitionFlags.IsStateTransformedToIndex(Flags), "Transition must be transformed first");
     fixed(byte **addr = &TargetStatePointer)
     {
         return(*((int *)addr + 1));               //second four bytes of FieldOffset(0)
     }
 }
 /// <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);
                }
            }
        }
Exemple #10
0
        /// <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;
            }
        }
Exemple #11
0
        /// <summary>
        ///   Removes all transitions that are no longer activation minimal due to the current transition.
        /// </summary>
        private void CleanupTransitions(FaultSet activatedFaults, int faultIndex, long stateHash)
        {
            var current     = faultIndex;
            var nextPointer = &_lookup[stateHash];

            while (current != -1)
            {
                var faultSet = &_faults[current];

                // Remove the fault set and the corresponding transition if it is a proper subset of the activated faults
                if (activatedFaults.IsSubsetOf(faultSet->Transition->ActivatedFaults) && activatedFaults != faultSet->Transition->ActivatedFaults)
                {
                    faultSet->Transition->Flags = TransitionFlags.RemoveValid(faultSet->Transition->Flags);
                    *nextPointer = faultSet->NextSet;
                }

                if (nextPointer != &_lookup[stateHash])
                {
                    nextPointer = &faultSet->NextSet;
                }

                current = faultSet->NextSet;
            }
        }
Exemple #12
0
        /// <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 <TExecutableModel> context, Worker <TExecutableModel> worker, TransitionCollection transitions, byte *sourceState,
                                      int sourceStateIndex, bool isInitial)
        {
            // The fault order state is encoded into the first four bytes of the state vector (must be four bytes as required by
            // RuntimeModel's state header field)
            var state = isInitial ? State.NeitherFaultActivated : *(State *)sourceState;

            foreach (CandidateTransition *transition in transitions)
            {
                var activatedFaults = transition->ActivatedFaults;
                var isValid         = true;
                var nextState       = state;

                switch (state)
                {
                case State.NeitherFaultActivated:
                    if (activatedFaults.Contains(_firstFault) && activatedFaults.Contains(_secondFault))
                    {
                        if (_forceSimultaneous)
                        {
                            nextState = State.BothFaultsActivated;
                        }
                        else
                        {
                            isValid = false;
                        }
                    }
                    else if (activatedFaults.Contains(_firstFault))
                    {
                        if (_forceSimultaneous)
                        {
                            isValid = false;
                        }
                        else
                        {
                            nextState = State.FirstFaultActivated;
                        }
                    }
                    else if (activatedFaults.Contains(_secondFault))
                    {
                        isValid = false;
                    }
                    break;

                case State.FirstFaultActivated:
                    if (activatedFaults.Contains(_secondFault))
                    {
                        nextState = State.BothFaultsActivated;
                    }
                    break;

                case State.BothFaultsActivated:
                    break;

                default:
                    Assert.NotReached("Unexpected state value.");
                    break;
                }

                transition->Flags = TransitionFlags.SetIsValidIffCondition(transition->Flags, isValid);
                *(State *)transition->TargetStatePointer = nextState;
            }
        }
Exemple #13
0
        /// <summary>
        ///   Handles the <paramref name="transitions" />, adding newly discovered states so that they are not visited again.
        /// </summary>
        private void HandleTransitions(TransitionCollection transitions, int sourceState, bool isInitial)
        {
            try
            {
                var transitionCount = 0;
                var stateCount      = 0;

                foreach (var modifier in _transitionModifiers)
                {
                    modifier.ModifyTransitions(_context, this, transitions, _context.States[sourceState], sourceState, isInitial);
                }

                _stateStack.PushFrame();

                foreach (var transition in transitions)
                {
                    int  targetState;
                    bool isNewState;

                    if (TransitionFlags.IsToStutteringState(((CandidateTransition *)transition)->Flags))
                    {
                        isNewState  = false;
                        targetState = _context.StutteringStateIndex;
                    }
                    else
                    {
                        isNewState = _context.States.AddState(((CandidateTransition *)transition)->TargetStatePointer, out targetState);
                    }

                    // Replace the CandidateTransition.TargetState pointer with the unique indexes of the transition's source and target states
                    transition->TargetStateIndex = targetState;
                    transition->SourceStateIndex = sourceState;
                    transition->Flags            = TransitionFlags.SetIsStateTransformedToIndexFlag(transition->Flags);

                    if (isNewState)
                    {
                        ++stateCount;
                        _stateStack.PushState(targetState);

                        foreach (var action in _stateActions)
                        {
                            action.ProcessState(_context, this, _context.States[targetState], targetState, isInitial);
                        }
                    }

                    foreach (var action in _transitionActions)
                    {
                        action.ProcessTransition(_context, this, transition, isInitial);
                    }

                    ++transitionCount;
                }

                Interlocked.Add(ref _context.StateCount, stateCount);
                Interlocked.Add(ref _context.TransitionCount, transitionCount);
                Interlocked.Add(ref _context.ComputedTransitionCount, transitions.TotalCount);

                foreach (var action in _batchedTransitionActions)
                {
                    action.ProcessTransitions(_context, this, sourceState, transitions, transitionCount, isInitial);
                }
            }
            catch (Exception e)
            {
                _context.LoadBalancer.Terminate();
                _context.Exception = e;

                if (!(e is OutOfMemoryException))
                {
                    CreateCounterExample(endsWithException: true, addAdditionalState: false);
                }
            }
        }
 private void MergeTransitions(LtmcTransition *mergeInCandidate, LtmcTransition *toMergeCandidate)
 {
     mergeInCandidate->Probability += toMergeCandidate->Probability;
     toMergeCandidate->Flags        = TransitionFlags.RemoveValid(toMergeCandidate->Flags);
 }
Exemple #15
0
 private void CheckIfTransitionIsValid(LtmcTransition *transition)
 {
     Assert.That(TransitionFlags.IsValid(transition->Flags), "Attempted to add an invalid transition.");
 }