Esempio n. 1
0
        /// <summary>
        ///   Removes all invalid sets from <paramref name="sets" /> that conflict with either <paramref name="suppressedFaults" /> or
        ///   <paramref name="forcedFaults" />.
        /// </summary>
        private static HashSet <FaultSet> RemoveInvalidSets(HashSet <FaultSet> sets, FaultSet suppressedFaults, FaultSet forcedFaults,
                                                            HashSet <FaultSet> safeSets)
        {
            var validSets = new HashSet <FaultSet>();

            foreach (var set in sets)
            {
                // The set must contain all forced faults, hence it must be a superset of those
                if (!forcedFaults.IsSubsetOf(set))
                {
                    safeSets.Add(set);
                    continue;
                }

                // The set is not allowed to contain any suppressed faults, hence the intersection must be empty
                if (!suppressedFaults.GetIntersection(set).IsEmpty)
                {
                    safeSets.Add(set);
                    continue;
                }

                validSets.Add(set);
            }

            return(validSets);
        }
Esempio n. 2
0
        private void AddTransition(byte *stateToAdd, StateFormulaSet formulas, FaultSet activatedFaults, double probability)
        {
            if (_consolidateOnTheFly)
            {
                AddTransitionConsolidate(stateToAdd, formulas, activatedFaults, probability);
            }
            else
            {
                if (_count >= _capacity)
                {
                    throw new OutOfMemoryException("Unable to store an additional transition. Try increasing the successor state capacity.");
                }

                var successorState = _temporalStateStorage.GetFreeTemporalSpaceAddress();
                MemoryBuffer.Copy(stateToAdd, successorState, _temporalStateStorage.StateVectorSize);
                _transitions[_count] = new LtmcTransition
                {
                    TargetStatePointer = successorState,
                    Formulas           = formulas,
                    //ActivatedFaults = activatedFaults,
                    Flags       = TransitionFlags.IsValidFlag,
                    Probability = probability
                };
                ++_count;
            }
        }
Esempio n. 3
0
        /// <summary>
        ///   Adds a transition to the <paramref name="model" />'s current state.
        /// </summary>
        /// <param name="model">The model the transition should be added for.</param>
        /// <param name="continuationId">The id of the transition.</param>
        public void Add(ExecutableModel <TExecutableModel> model, int continuationId)
        {
            if (_transitionsWithContinuationIdCount >= _capacity)
            {
                throw new OutOfMemoryException("Unable to store an additional transition. Try increasing the successor state capacity.");
            }

            // 1. Notify all fault activations, so that the correct activation is set in the run time model
            //    (Needed to persist persistent faults)
            model.NotifyFaultActivations();

            // 2. Serialize the model's computed state; that is the successor state of the transition's source state
            //    _including_ any changes resulting from notifications of fault activations
            var successorState = _targetStateMemory + _stateVectorSize * _transitionsWithContinuationIdCount;

            model.Serialize(successorState);

            // 3. Store the transition
            var activatedFaults      = FaultSet.FromActivatedFaults(model.NondeterministicFaults);
            var positionOfTransition = _transitionsWithContinuationIdCount;

            _transitionsWithContinuationIdMemory[positionOfTransition] = new LtmdpTransition
            {
                TargetStatePointer = successorState,
                Formulas           = new StateFormulaSet(_formulas),
                ActivatedFaults    = activatedFaults,
                Flags = TransitionFlags.IsValidFlag,
                Index = positionOfTransition
            };
            ++_transitionsWithContinuationIdCount;
            LtmdpStepGraph.SetTargetOfFinalOrUnsplitChoice(continuationId, positionOfTransition);
        }
Esempio n. 4
0
        /// <summary>
        ///   Initializes a new instance.
        /// </summary>
        /// <param name="runtimeModelCreator">A factory function that creates the model instance that should be executed.</param>
        /// <param name="formulas">The formulas that should be evaluated for each state.</param>
        /// <param name="configuration">The analysis configuration that should be used.</param>
        /// <param name="stateHeaderBytes">
        ///   The number of bytes that should be reserved at the beginning of each state vector for the model checker tool.
        /// </param>
        internal ActivationMinimalExecutedModel(CoupledExecutableModelCreator <TExecutableModel> runtimeModelCreator, int stateHeaderBytes, Func <bool>[] formulas, AnalysisConfiguration configuration)
            : base(runtimeModelCreator, stateHeaderBytes, configuration)
        {
            formulas = formulas ?? RuntimeModel.Formulas.Select(formula => FormulaCompilationVisitor <TExecutableModel> .Compile(RuntimeModel, formula)).ToArray();

            _transitions      = new ActivationMinimalTransitionSetBuilder <TExecutableModel>(TemporaryStateStorage, configuration.SuccessorCapacity, formulas);
            _stateConstraints = RuntimeModel.StateConstraints;

            bool useForwardOptimization;

            switch (configuration.MomentOfIndependentFaultActivation)
            {
            case MomentOfIndependentFaultActivation.AtStepBeginning:
            case MomentOfIndependentFaultActivation.OnFirstMethodWithoutUndo:
                useForwardOptimization = false;
                break;

            case MomentOfIndependentFaultActivation.OnFirstMethodWithUndo:
                useForwardOptimization = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            ChoiceResolver = new NondeterministicChoiceResolver(useForwardOptimization);
            FaultSet.CheckFaultCount(RuntimeModel.Faults.Length);

            RuntimeModel.SetChoiceResolver(ChoiceResolver);

            _allowFaultsOnInitialTransitions = configuration.AllowFaultsOnInitialTransitions;
        }
		void IFaultSetHeuristic.Update(LinkedList<FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
		{
			if (!_subsumedSets.Contains(checkedSet))
				return;

			_successCounter += isSafe ? 1 : -1;
			if (_successCounter != 0)
				return;

			// if the subsumed sets are critical more often than they are not,
			// check the "normal" sets first.
			for (var node = setsToCheck.First; node != null; node = node.Next)
			{
				var set = node.Value;
				if (_subsumedSets.Contains(set))
				{
					if (isSafe && node.Previous != null) // move subsumed set before set
						SwitchValues(node, node.Previous);
					else if (!isSafe && node.Next != null) // move subsumed set after set
					{
						SwitchValues(node, node.Next);
						node = node.Next; // skip iteration for node.Next
					}
				}
			}
		}
Esempio n. 6
0
        /// <summary>
        ///   Adds the <paramref name="successorState" /> to the transition set if neccessary, reached using the
        ///   <paramref name="activatedFaults" />.
        /// </summary>
        /// <param name="successorState">The successor state that should be added.</param>
        /// <param name="activatedFaults">The faults activated by the transition to reach the state.</param>
        private bool Add(byte *successorState, FaultSet activatedFaults)
        {
            var hash = MemoryBuffer.Hash(successorState, _stateVectorSize, 0);

            for (var i = 1; i < ProbeThreshold; ++i)
            {
                var stateHash  = MemoryBuffer.Hash((byte *)&hash, sizeof(int), i * 8345723) % _capacity;
                var faultIndex = _lookup[stateHash];

                // If we don't know the state yet, set everything up and add the transition
                if (faultIndex == -1)
                {
                    _successors.Add((uint)stateHash);
                    AddFaultMetadata(stateHash, -1);
                    MemoryBuffer.Copy(successorState, _hashedStateMemory + stateHash * _stateVectorSize, _stateVectorSize);

                    return(true);
                }

                // If there is a hash conflict, try again
                if (!MemoryBuffer.AreEqual(successorState, _hashedStateMemory + stateHash * _stateVectorSize, _stateVectorSize))
                {
                    continue;
                }

                // The transition has an already-known target state; it might have to be added or invalidate previously found transitions
                return(UpdateTransitions(stateHash, activatedFaults, faultIndex));
            }

            throw new OutOfMemoryException(
                      "Failed to find an empty hash table slot within a reasonable amount of time. Try increasing the successor state capacity.");
        }
Esempio n. 7
0
        void IFaultSetHeuristic.Update(LinkedList <FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
        {
            if (!_subsumedSets.Contains(checkedSet))
            {
                return;
            }

            _successCounter += isSafe ? 1 : -1;
            if (_successCounter != 0)
            {
                return;
            }

            // if the subsumed sets are critical more often than they are not,
            // check the "normal" sets first.
            for (var node = setsToCheck.First; node != null; node = node.Next)
            {
                var set = node.Value;
                if (_subsumedSets.Contains(set))
                {
                    if (isSafe && node.Previous != null)                     // move subsumed set before set
                    {
                        SwitchValues(node, node.Previous);
                    }
                    else if (!isSafe && node.Next != null)                     // move subsumed set after set
                    {
                        SwitchValues(node, node.Next);
                        node = node.Next;                         // skip iteration for node.Next
                    }
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        ///   Gets the activation order relationships that exist for the faults contained in
        ///   <paramref name="minimalCriticalFaultSet" />, if any.
        /// </summary>
        /// <param name="minimalCriticalFaultSet">The minimal critical fault set the order should be returned for.</param>
        private IEnumerable <OrderRelationship <TExecutableModel> > GetOrderRelationships(ISet <Fault> minimalCriticalFaultSet)
        {
            var checkedSet    = new FaultSet(minimalCriticalFaultSet);
            var activation    = _results.FaultActivationBehavior == FaultActivationBehavior.ForceOnly ? Activation.Forced : Activation.Nondeterministic;
            var checkedFaults = minimalCriticalFaultSet.ToArray();

            // Create all pairs of faults contained in minimalCriticalFaultSet such that
            // we don't get pairs (f,f) and we don't generate duplicate pairs (f1,f2) and (f2,f1)
            for (var i = 0; i < checkedFaults.Length; ++i)
            {
                for (var j = i + 1; j < checkedFaults.Length; ++j)
                {
                    var fault1 = checkedFaults[i];
                    var fault2 = checkedFaults[j];

                    // Check if one can be activated strictly before the other
                    var fault1BeforeFault2 = _backend.CheckOrder(fault1, fault2, checkedSet, activation, forceSimultaneous: false);
                    var fault2BeforeFault1 = _backend.CheckOrder(fault2, fault1, checkedSet, activation, forceSimultaneous: false);

                    // If both can be activated stritly before the other, there is no ordering
                    if (!fault2BeforeFault1.FormulaHolds && !fault1BeforeFault2.FormulaHolds)
                    {
                        continue;
                    }

                    // Check for simultaneous activations
                    var simultaneous = _backend.CheckOrder(fault1, fault2, checkedSet, activation, forceSimultaneous: true);

                    // f1 == f2
                    if (!simultaneous.FormulaHolds && fault1BeforeFault2.FormulaHolds && fault2BeforeFault1.FormulaHolds)
                    {
                        yield return(new OrderRelationship <TExecutableModel>(simultaneous, fault1, fault2, OrderRelationshipKind.Simultaneously));
                    }

                    // f1 <= f2
                    else if (!fault1BeforeFault2.FormulaHolds && !simultaneous.FormulaHolds)
                    {
                        yield return(new OrderRelationship <TExecutableModel>(simultaneous, fault1, fault2, OrderRelationshipKind.Precedes));
                    }

                    // f1 < f2
                    else if (!fault1BeforeFault2.FormulaHolds && simultaneous.FormulaHolds)
                    {
                        yield return(new OrderRelationship <TExecutableModel>(simultaneous, fault1, fault2, OrderRelationshipKind.StrictlyPrecedes));
                    }

                    // f2 <= f1
                    else if (!fault2BeforeFault1.FormulaHolds && !simultaneous.FormulaHolds)
                    {
                        yield return(new OrderRelationship <TExecutableModel>(simultaneous, fault2, fault1, OrderRelationshipKind.Precedes));
                    }

                    // f2 < f1
                    else if (!fault2BeforeFault1.FormulaHolds && simultaneous.FormulaHolds)
                    {
                        yield return(new OrderRelationship <TExecutableModel>(simultaneous, fault2, fault1, OrderRelationshipKind.StrictlyPrecedes));
                    }
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        ///   Classifies how the transition set must be updated.
        /// </summary>
        private void ClassifyActivatedFaults(FaultSet activatedFaults, int faultIndex, out bool addTransition, out bool addFaults,
                                             out bool cleanupTransitions)
        {
            addFaults          = false;
            cleanupTransitions = false;

            // Basic invariant of the fault list: it contains only sets of activation-minimal faults
            while (faultIndex != -1)
            {
                var faultSet = &_faults[faultIndex];
                faultIndex = faultSet->NextSet;

                // If the fault set is a subset of the activated faults, the current transition is not activation-minimal;
                // we can therefore safely ignore the transition; due to the list invariant, none of the remaining
                // fault sets in the list can be a superset of the activated faults because then the current fault set
                // would also be a subset of that other fault set, violating the invariant
                if (faultSet->Transition->ActivatedFaults.IsSubsetOf(activatedFaults))
                {
                    addTransition = faultSet->Transition->ActivatedFaults == activatedFaults;
                    return;
                }

                // If at least one of the previously added transitions that we assumed to be activation-minimal is
                // in fact not activation-minimal, we have to clean up the transition set
                if (activatedFaults.IsSubsetOf(faultSet->Transition->ActivatedFaults))
                {
                    cleanupTransitions = true;
                }
            }

            // If we get here, we must add the faults and the transition
            addTransition = true;
            addFaults     = true;
        }
        void IFaultSetHeuristic.Update(LinkedList <FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
        {
            var isSuggestion = _currentSuggestions.Remove(checkedSet);

            if (!isSuggestion)
            {
                return;
            }

            // subsets of a safe set are safe - do not check them again
            if (isSafe)
            {
                _successCounter++;
                _nextSuggestions.ExceptWith(GetSubsets(new[] { checkedSet }));
            }
            else
            {
                _successCounter--;
            }

            var tolerance = _allFaults.Length / 4;

            if (_currentSuggestions.Count == 0 && checkedSet.Cardinality > _minSetSize)
            {
                if (_successCounter < -tolerance && isSafe)
                {
                    _subsetStepSize++;
                    _successCounter = 0;
                }

                _currentSuggestions = _nextSuggestions;
                _nextSuggestions    = GetSubsets(_currentSuggestions);
            }
        }
Esempio n. 11
0
 /// <summary>
 ///   Updates the activation modes of the faults contained in the model.
 /// </summary>
 private void ChangeFaultActivations(FaultSet faults, Activation activation)
 {
     foreach (var model in _invariantChecker.AnalyzedModels.Cast <ExecutedModel <TExecutableModel> >())
     {
         model.ChangeFaultActivations(GetUpdateFaultActivations(faults, activation));
     }
 }
        /// <summary>
        ///   Adds a transition to the <paramref name="model" />'s current state.
        /// </summary>
        /// <param name="model">The model the transition should be added for.</param>
        /// <param name="probability">The probability of the transition.</param>
        public void Add(ExecutableModel <TExecutableModel> model, double probability)
        {
            if (_count >= _capacity)
            {
                throw new OutOfMemoryException("Unable to store an additional transition. Try increasing the successor state capacity.");
            }

            // 1. Notify all fault activations, so that the correct activation is set in the run time model
            //    (Needed to persist persistent faults)
            model.NotifyFaultActivations();

            // 2. Serialize the model's computed state; that is the successor state of the transition's source state
            //    _including_ any changes resulting from notifications of fault activations
            var successorState = _targetStateMemory + _stateVectorSize * _count;

            model.Serialize(successorState);

            // 3. Store the transition
            var activatedFaults = FaultSet.FromActivatedFaults(model.NondeterministicFaults);

            _transitions[_count] = new LtmcTransition
            {
                TargetStatePointer = successorState,
                Formulas           = new StateFormulaSet(_formulas),
                ActivatedFaults    = activatedFaults,
                Flags       = TransitionFlags.IsValidFlag,
                Probability = probability
            };
            ++_count;
        }
Esempio n. 13
0
			public void Update(LinkedList<FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
			{
				if (updated)
					return;
				setsToCheck.AddFirst(new FaultSet(C.F2));
				updated = true;
			}
Esempio n. 14
0
		/// <summary>
		///   Initizializes the model that should be analyzed.
		/// </summary>
		/// <param name="configuration">The configuration that should be used for the analyses.</param>
		/// <param name="model">The model that should be analyzed.</param>
		/// <param name="hazard">The hazard that should be analyzed.</param>
		internal void InitializeModel(AnalysisConfiguration configuration, ModelBase model, Formula hazard)
		{
			Model = model;
			ForcedFaults = new FaultSet(Model.Faults.Where(fault => fault.Activation == Activation.Forced));
			SuppressedFaults = new FaultSet(Model.Faults.Where(fault => fault.Activation == Activation.Suppressed));

			InitializeModel(configuration, hazard);
		}
		/// <summary>
		///   Initializes a new instance.
		/// </summary>
		/// <param name="model">The model the heuristic is created for.</param>
		/// <param name="cardinalityLevel">The cardinality level where the first suggestions should be made.</param>
		public MaximalSafeSetHeuristic(ModelBase model, uint cardinalityLevel = 3)
		{
			Requires.NotNull(model, nameof(model));

			_model = model;
			_cardinalityLevel = cardinalityLevel;
			_allFaults = new FaultSet(model.Faults.Where(fault => fault.Activation != Activation.Suppressed).ToArray());
		}
Esempio n. 16
0
        /// <summary>
        ///   Initizializes the model that should be analyzed.
        /// </summary>
        /// <param name="configuration">The configuration that should be used for the analyses.</param>
        /// <param name="createFreshModel">The creator for the model that should be checked.</param>
        /// <param name="hazard">The hazard that should be analyzed.</param>
        internal void InitializeModel(AnalysisConfiguration configuration, CoupledExecutableModelCreator <TExecutableModel> createFreshModel, Formula hazard)
        {
            RuntimeModelCreator = createFreshModel;
            ForcedFaults        = new FaultSet(createFreshModel.FaultsInBaseModel.Where(fault => fault.Activation == Activation.Forced));
            SuppressedFaults    = new FaultSet(createFreshModel.FaultsInBaseModel.Where(fault => fault.Activation == Activation.Suppressed));

            InitializeModel(configuration, hazard);
        }
        /// <summary>
        ///   Finds all subsets of <paramref name="set" /> with the given <paramref name="size" />.
        /// </summary>
        private List <FaultSet> GetSubsets(FaultSet set, int size)
        {
            var subset  = new Fault[size];
            var results = new List <FaultSet>();

            GetSubsets(set, subset, 0, 0, results);
            return(results);
        }
Esempio n. 18
0
        /// <summary>
        ///   Initializes a new instance.
        /// </summary>
        /// <param name="modelFaults">All faults in the model the heuristic is created for.</param>
        /// <param name="cardinalityLevel">The cardinality level where the first suggestions should be made.</param>
        public MaximalSafeSetHeuristic(Fault[] modelFaults, uint cardinalityLevel = 3)
        {
            Requires.NotNull(modelFaults, nameof(modelFaults));

            _modelFaults      = modelFaults;
            _cardinalityLevel = cardinalityLevel;
            _allFaults        = new FaultSet(modelFaults.Where(fault => fault.Activation != Activation.Suppressed).ToArray());
        }
Esempio n. 19
0
        private bool CheckSet(FaultSet set, Fault[] allFaults, bool isHeuristicSuggestion, Activation activationMode)
        {
            try
            {
                var result = _backend.CheckCriticality(set, activationMode);

                if (Configuration.CollectFaultSets)
                {
                    if (!result.FormulaHolds)
                    {
                        if (!isHeuristicSuggestion)
                        {
                            ConsoleHelpers.WriteLine($"    critical:  {{ {set.ToString(allFaults)} }}", ConsoleColor.DarkRed);
                        }

                        _criticalSets.Add(set);
                    }
                    else if (isHeuristicSuggestion)
                    {
                        ConsoleHelpers.WriteLine($"    safe:      {{ {set.ToString(allFaults)} }}  [heuristic]", ConsoleColor.Blue);
                    }

                    _checkedSets.Add(set);
                }

                _checkedSetCount++;

                if (result.CounterExample != null)
                {
                    var executableCounterExample = new ExecutableCounterExample <TExecutableModel>(_backend.RuntimeModelCreator.Create(0), result.CounterExample);
                    _counterExamples.Add(set, executableCounterExample);
                }

                return(result.FormulaHolds);
            }
            catch (AnalysisException e)
            {
                var heuristic = isHeuristicSuggestion ? " [heuristic]" : string.Empty;
                ConsoleHelpers.WriteLine($"    critical:  {{ {set.ToString(allFaults)} }} {heuristic} [exception thrown]", ConsoleColor.DarkRed);
                Console.WriteLine(e.InnerException);

                if (Configuration.CollectFaultSets)
                {
                    _checkedSets.Add(set);
                }
                _checkedSetCount++;
                _criticalSets.Add(set);
                _exceptions.Add(set, e.InnerException);

                if (e.CounterExample != null)
                {
                    var executableCounterExample = new ExecutableCounterExample <TExecutableModel>(_backend.RuntimeModelCreator.Create(0), e.CounterExample);
                    _counterExamples.Add(set, executableCounterExample);
                }

                return(false);
            }
        }
Esempio n. 20
0
 public void Update(LinkedList <FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
 {
     if (updated)
     {
         return;
     }
     setsToCheck.AddFirst(new FaultSet(C.F2));
     updated = true;
 }
 private ISet <FaultSet> GetSubsets(IEnumerable <FaultSet> sets)
 {
     return(new HashSet <FaultSet>(
                from set in sets
                // get a subset of size subsetStepSize
                from subset in GetSubsets(set, _subsetStepSize)
                // remove all faults in the subset and their subsuming faults
                let suggestion = set.GetDifference(FaultSet.SubsumingFaults(subset, _allFaults))
                                 select suggestion
                ));
 }
Esempio n. 22
0
        /// <summary>
        ///   Informs the heuristic of the result of analyzing <paramref name="checkedSet" />
        ///   and allows it to adapt the sets to check next.
        /// </summary>
        public void Update(LinkedList <FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
        {
            // Ignore critical sets we've suggested ourself as these are likely not minimal and
            // would degrade the quality of our suggestions
            if (isSafe || _suggestedSets.Contains(checkedSet))
            {
                return;
            }

            _hasNewMinimalCriticalSets = true;
            _minimalCriticalSets.Add(checkedSet.ToFaultSequence(_modelFaults).ToArray());
        }
		/// <summary>
		///   Initializes a new instance.
		/// </summary>
		/// <param name="model">The model the heuristic is created for.</param>
		/// <param name="minimalCriticalFaultSets">The minimal critical fault sets known from a previous analysis.</param>
		public MaximalSafeSetHeuristic(ModelBase model, ISet<ISet<Fault>> minimalCriticalFaultSets)
		{
			Requires.NotNull(model, nameof(model));
			Requires.NotNull(minimalCriticalFaultSets, nameof(minimalCriticalFaultSets));

			_model = model;
			_hasNewMinimalCriticalSets = true;
			_allFaults = new FaultSet(model.Faults.Where(fault => fault.Activation != Activation.Suppressed).ToArray());

			foreach (var set in minimalCriticalFaultSets)
				_minimalCriticalSets.Add(set.Select(MapFault).ToArray());
		}
Esempio n. 24
0
 void IFaultSetHeuristic.Augment(uint cardinalityLevel, LinkedList <FaultSet> setsToCheck)
 {
     // for each set, check the set of subsumed faults first
     for (var node = setsToCheck.First; node != null; node = node.Next)
     {
         var subsumed = FaultSet.SubsumedFaults(node.Value, _allFaults);
         if (!node.Value.Equals(subsumed) && !_subsumedSets.Contains(subsumed))
         {
             setsToCheck.AddBefore(node, subsumed);
             _subsumedSets.Add(subsumed);
         }
     }
 }
        private void CollectSuggestions(IEnumerable <IEnumerable <Fault> > faultGroups)
        {
            var faults = new FaultSet(_allFaults);

            _currentSuggestions = new HashSet <FaultSet>(
                // one fault of each group is not activated (try all combinations)
                from excludedFaults in CartesianProduct(faultGroups)
                // also exclude subsuming faults
                let subsuming = FaultSet.SubsumingFaults(excludedFaults, _allFaults)
                                orderby subsuming.Cardinality ascending
                                select faults.GetDifference(subsuming)
                );
        }
Esempio n. 26
0
		/// <summary>
		///   Checks the <see cref="faults" /> for criticality using the <see cref="activation" /> mode.
		/// </summary>
		/// <param name="faults">The fault set that should be checked for criticality.</param>
		/// <param name="activation">The activation mode of the fault set.</param>
		internal override AnalysisResult CheckCriticality(FaultSet faults, Activation activation)
		{
			var suppressedFaults = new FaultSet();
			foreach (var fault in Model.Faults)
			{
				if (GetEffectiveActivation(fault, faults, activation) == Activation.Suppressed)
					suppressedFaults = suppressedFaults.Add(fault);
			}

			_checker.Context.TraversalParameters.TransitionModifiers.Clear();
			_checker.Context.TraversalParameters.TransitionModifiers.Add(() => new FaultSuppressionModifier(suppressedFaults));

			return _checker.Check();
		}
        /// <summary>
        ///   Converts the integer-based set to a set faults.
        /// </summary>
        private ISet <Fault> Convert(Dictionary <FaultSet, ISet <Fault> > knownSets, FaultSet set)
        {
            ISet <Fault> faultSet;

            if (knownSets.TryGetValue(set, out faultSet))
            {
                return(faultSet);
            }

            faultSet = new HashSet <Fault>(set.ToFaultSequence(RuntimeModelCreator.FaultsInBaseModel));
            knownSets.Add(set, faultSet);

            return(faultSet);
        }
Esempio n. 28
0
        /// <summary>
        ///   Initializes a new instance.
        /// </summary>
        /// <param name="modelFaults">All faults in the model the heuristic is created for.</param>
        /// <param name="minimalCriticalFaultSets">The minimal critical fault sets known from a previous analysis.</param>
        public MaximalSafeSetHeuristic(Fault[] modelFaults, ISet <ISet <Fault> > minimalCriticalFaultSets)
        {
            Requires.NotNull(modelFaults, nameof(modelFaults));
            Requires.NotNull(minimalCriticalFaultSets, nameof(minimalCriticalFaultSets));

            _modelFaults = modelFaults;
            _hasNewMinimalCriticalSets = true;
            _allFaults = new FaultSet(modelFaults.Where(fault => fault.Activation != Activation.Suppressed).ToArray());

            foreach (var set in minimalCriticalFaultSets)
            {
                _minimalCriticalSets.Add(set.Select(MapFault).ToArray());
            }
        }
Esempio n. 29
0
		/// <summary>
		///   Adds a transition to the <paramref name="successorState" /> to the set.
		/// </summary>
		/// <param name="successorState">The successor state of the transition that should be added.</param>
		/// <param name="activatedFaults">The faults activated by the transition that should be added.</param>
		/// <param name="formulas">The formulas holding in the successor state of the transition that should be added.</param>
		public void Add(byte* successorState, FaultSet activatedFaults, StateFormulaSet formulas)
		{
			var targetState = _targetStateMemory + _count * _stateVectorSize;
			MemoryBuffer.Copy(successorState, targetState, _stateVectorSize);

			_transitions[_count] = new CandidateTransition
			{
				TargetState = targetState,
				Formulas = formulas,
				ActivatedFaults = activatedFaults,
				IsValid = true,
			};

			++_count;
		}
Esempio n. 30
0
        internal void CreateTransition(bool[] isFormulaSatisfied, byte *targetState, double p)
        {
            var transition = _transitionCount;

            _transitionCount++;
            _transitions[transition] = new LtmcTransition {
                Probability = p
            };
            var t = _transitions + transition;

            t->TargetStatePointer = targetState;
            t->Formulas           = new StateFormulaSet(isFormulaSatisfied);
            t->Flags           = TransitionFlags.IsValidFlag | TransitionFlags.IsStateTransformedToIndexFlag;
            t->ActivatedFaults = new FaultSet();
        }
Esempio n. 31
0
        private void CreateTransition(bool isFormulaSatisfied, int targetStateIndex, int continuationId, double p)
        {
            var transition = _transitionCount;

            _transitionCount++;
            _transitions[transition] = new LtmdpTransition {
                Probability = p, ContinuationId = continuationId
            };
            var t = (Transition *)(_transitions + transition);

            t->SourceStateIndex = 0;
            t->TargetStateIndex = targetStateIndex;
            t->Formulas         = new StateFormulaSet(new Func <bool>[] { () => isFormulaSatisfied });
            t->Flags            = TransitionFlags.IsValidFlag | TransitionFlags.IsStateTransformedToIndexFlag;
            t->ActivatedFaults  = new FaultSet();
        }
Esempio n. 32
0
        private FaultSet CollectSubsumedFaultsTransitive()
        {
            IEnumerable <Fault> currentFaults = new[] { this };
            var subsumed = new FaultSet(this);

            uint oldCount;

            do             // fixed-point iteration
            {
                oldCount      = subsumed.Cardinality;
                currentFaults = currentFaults.SelectMany(fault => fault.SubsumedFaults);
                subsumed      = subsumed.GetUnion(new FaultSet(currentFaults));
            } while (oldCount < subsumed.Cardinality);

            return(subsumed);
        }
Esempio n. 33
0
        /// <summary>
        ///   Adds a transition to the <paramref name="successorState" /> to the set.
        /// </summary>
        /// <param name="successorState">The successor state of the transition that should be added.</param>
        /// <param name="activatedFaults">The faults activated by the transition that should be added.</param>
        /// <param name="formulas">The formulas holding in the successor state of the transition that should be added.</param>
        public void Add(byte *successorState, FaultSet activatedFaults, StateFormulaSet formulas)
        {
            var targetState = _targetStateMemory + _count * _stateVectorSize;

            MemoryBuffer.Copy(successorState, targetState, _stateVectorSize);

            _transitions[_count] = new CandidateTransition
            {
                TargetStatePointer = targetState,
                Formulas           = formulas,
                ActivatedFaults    = activatedFaults,
                Flags = TransitionFlags.IsValidFlag,
            };

            ++_count;
        }
Esempio n. 34
0
        /// <summary>
        ///   Initializes a new instance.
        /// </summary>
        /// <param name="runtimeModelCreator">A factory function that creates the model instance that should be executed.</param>
        /// <param name="formulas">The formulas that should be evaluated for each state.</param>
        /// <param name="configuration">The analysis configuration that should be used.</param>
        /// <param name="stateHeaderBytes">
        ///   The number of bytes that should be reserved at the beginning of each state vector for the model checker tool.
        /// </param>
        internal ActivationMinimalExecutedModel(CoupledExecutableModelCreator <TExecutableModel> runtimeModelCreator, int stateHeaderBytes, Func <bool>[] formulas, AnalysisConfiguration configuration)
            : base(runtimeModelCreator, stateHeaderBytes, configuration)
        {
            formulas = formulas ?? RuntimeModel.Formulas.Select(formula => FormulaCompilationVisitor <TExecutableModel> .Compile(RuntimeModel, formula)).ToArray();

            _transitions      = new ActivationMinimalTransitionSetBuilder <TExecutableModel>(TemporaryStateStorage, configuration.SuccessorCapacity, formulas);
            _stateConstraints = RuntimeModel.StateConstraints;

            var useForwardOptimization = configuration.EnableStaticPruningOptimization;

            ChoiceResolver = new NondeterministicChoiceResolver(useForwardOptimization);
            FaultSet.CheckFaultCount(RuntimeModel.Faults.Length);

            RuntimeModel.SetChoiceResolver(ChoiceResolver);

            _allowFaultsOnInitialTransitions = configuration.AllowFaultsOnInitialTransitions;
        }
Esempio n. 35
0
        /// <summary>
        ///   Checks the <see cref="faults" /> for criticality using the <see cref="activation" /> mode.
        /// </summary>
        /// <param name="faults">The fault set that should be checked for criticality.</param>
        /// <param name="activation">The activation mode of the fault set.</param>
        internal override InvariantAnalysisResult CheckCriticality(FaultSet faults, Activation activation)
        {
            var suppressedFaults = new FaultSet();

            foreach (var fault in RuntimeModelCreator.FaultsInBaseModel)
            {
                if (GetEffectiveActivation(fault, faults, activation) == Activation.Suppressed)
                {
                    suppressedFaults = suppressedFaults.Add(fault);
                }
            }

            _checker.ModelTraverser.Context.TraversalParameters.TransitionModifiers.Clear();
            _checker.ModelTraverser.Context.TraversalParameters.TransitionModifiers.Add(() => new FaultSuppressionModifier(suppressedFaults));

            return(_checker.Check());
        }
        /// <summary>
        ///   Helper function for recursively finding subsets.
        /// </summary>
        private void GetSubsets(FaultSet set, Fault[] subset, int index, int minFaultIndex, List <FaultSet> results)
        {
            if (index == subset.Length)
            {
                results.Add(new FaultSet(subset));
                return;
            }

            for (var i = minFaultIndex; i < _allFaults.Length - subset.Length + index; ++i)
            {
                if (set.Contains(_allFaults[i]))
                {
                    subset[index] = _allFaults[i];
                    GetSubsets(set, subset, index + 1, i + 1, results);
                }
            }
        }
Esempio n. 37
0
        internal void CreateTransition(bool[] isFormulaSatisfied, int targetStateIndex, int continuationId)
        {
            var transition = _transitionCount;

            _transitionCount++;
            _transitions[transition] = new LtmdpTransition {
                Index = transition
            };
            var t = (Transition *)(_transitions + transition);

            t->SourceStateIndex = 0;
            t->TargetStateIndex = targetStateIndex;
            t->Formulas         = new StateFormulaSet(isFormulaSatisfied);
            t->Flags            = TransitionFlags.IsValidFlag | TransitionFlags.IsStateTransformedToIndexFlag;
            t->ActivatedFaults  = new FaultSet();
            StepGraph.SetTargetOfFinalOrUnsplitChoice(continuationId, transition);
        }
Esempio n. 38
0
		private bool CheckSet(FaultSet set, Fault[] allFaults, bool isHeuristicSuggestion, Activation activationMode)
		{
			try
			{
				var result = _backend.CheckCriticality(set, activationMode);

				if (!result.FormulaHolds)
				{
					if (!isHeuristicSuggestion)
						ConsoleHelpers.WriteLine($"    critical:  {{ {set.ToString(allFaults)} }}", ConsoleColor.DarkRed);

					_criticalSets.Add(set);
				}
				else if (isHeuristicSuggestion)
				{
					ConsoleHelpers.WriteLine($"    safe:      {{ {set.ToString(allFaults)} }}  [heuristic]", ConsoleColor.Blue);
				}

				_checkedSets.Add(set);

				if (result.CounterExample != null)
					_counterExamples.Add(set, result.CounterExample);

				return result.FormulaHolds;
			}
			catch (AnalysisException e)
			{
				var heuristic = isHeuristicSuggestion ? " [heuristic]" : string.Empty;
				ConsoleHelpers.WriteLine($"    critical:  {{ {set.ToString(allFaults)} }} {heuristic} [exception thrown]", ConsoleColor.DarkRed);
				Console.WriteLine(e.InnerException);

				_checkedSets.Add(set);
				_criticalSets.Add(set);
				_exceptions.Add(set, e.InnerException);

				if (e.CounterExample != null)
					_counterExamples.Add(set, e.CounterExample);
				return false;
			}
		}
			public void Update(LinkedList<FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
			{
				setCounter++;
			}
		/// <summary>
		///   Converts the integer-based set to a set faults.
		/// </summary>
		private ISet<Fault> Convert(Dictionary<FaultSet, ISet<Fault>> knownSets, FaultSet set)
		{
			ISet<Fault> faultSet;
			if (knownSets.TryGetValue(set, out faultSet))
				return faultSet;

			faultSet = new HashSet<Fault>(set.ToFaultSequence(Model.Faults));
			knownSets.Add(set, faultSet);

			return faultSet;
		}
		/// <summary>
		///   Initializes a new instance.
		/// </summary>
		/// <param name="suppressedFaults">The suppressed faults that are removed by the modifier.</param>
		public FaultSuppressionModifier(FaultSet suppressedFaults)
		{
			_suppressedFaults = suppressedFaults;
		}
Esempio n. 42
0
		private bool IsTriviallySafe(FaultSet faultSet)
		{
			return _safeSets.ContainsSupersetOf(faultSet);
		}
Esempio n. 43
0
		private bool IsTriviallyCritical(FaultSet faultSet)
		{
			return _criticalSets.ContainsSubsetOf(faultSet);
		}
Esempio n. 44
0
		private bool CheckSet(FaultSet set, Fault[] allFaults, bool isHeuristicSuggestion)
		{
			if (isHeuristicSuggestion)
				_results.HeuristicSuggestionCount++;

			var isSafe = true;

			// check if set is trivially safe or critical
			// (do not add to safeSets / criticalSets if so, in order to keep them small)
			if (IsTriviallySafe(set))
			{
				_results.TrivialChecksCount++;
				if (isHeuristicSuggestion)
					_results.HeuristicTrivialCount++;

				// do not add to safeSets: all subsets are subsets of safeSet as well
				return true;
			}

			// trivially critical sets are not generated in GeneratePowerSetLevel, thus only check if set suggested by heuristic
			if (isHeuristicSuggestion && IsTriviallyCritical(set))
			{
				_results.TrivialChecksCount++;
				_results.HeuristicTrivialCount++;

				// do not add to criticalSets: non-minimal, and all supersets are supersets of criticalSet as well
				return false;
			}

			// if configured to do so, check with forced fault activation
			if (FaultActivationBehavior == FaultActivationBehavior.ForceOnly || FaultActivationBehavior == FaultActivationBehavior.ForceThenFallback)
				isSafe = CheckSet(set, allFaults, isHeuristicSuggestion, Activation.Forced);

			if (isSafe && FaultActivationBehavior == FaultActivationBehavior.ForceThenFallback)
				ConsoleHelpers.WriteLine("    Checking again with nondeterministic activation...");

			// check with nondeterministic fault activation
			if (isSafe && FaultActivationBehavior != FaultActivationBehavior.ForceOnly)
				isSafe = CheckSet(set, allFaults, isHeuristicSuggestion, Activation.Nondeterministic);

			if (isSafe) // remember non-trivially safe sets to avoid checking their subsets
			{
				_safeSets.Add(set);

				if (isHeuristicSuggestion)
					_results.HeuristicNonTrivialSafeCount++;
			}

			return isSafe;
		}
Esempio n. 45
0
		/// <summary>
		///   Generates a level of the power set.
		/// </summary>
		/// <param name="cardinality">The cardinality of the sets that should be generated.</param>
		/// <param name="faults">The fault set the power set is generated for.</param>
		/// <param name="previousSafe">The set of safe sets generated at the previous level.</param>
		private HashSet<FaultSet> GeneratePowerSetLevel(int cardinality, Fault[] faults, HashSet<FaultSet> previousSafe)
		{
			var result = new HashSet<FaultSet>();

			switch (cardinality)
			{
				case 0:
					// There is only the empty set with a cardinality of 0
					result.Add(new FaultSet());
					break;
				case 1:
					// We have to kick things off by explicitly generating the singleton sets; at this point,
					// we know that there are no further minimal critical sets if the empty set is already critical.
					if (previousSafe.Count > 0)
					{
						foreach (var fault in faults)
						{
							var set = new FaultSet(fault);
							if (!_criticalSets.Contains(set))
								result.Add(set);
						}
					}
					break;
				default:
					// We now generate the sets with the requested cardinality based on the sets from the previous level
					// which had a cardinality that is one less than the sets we're going to generate now. The basic
					// idea is that we create the union between all safe sets and all singleton sets and discard
					// the ones we don't want, while avoiding duplicate generation of sets.

					var setsToRemove = new HashSet<FaultSet>();
					for (var i = 0; i < faults.Length; ++i)
					{
						var fault = faults[i];
						setsToRemove.Clear();

						foreach (var safeSet in previousSafe)
						{
							// avoid duplicate set generation
							if (safeSet.Contains(fault))
							{
								setsToRemove.Add(safeSet);
								continue;
							}

							var set = safeSet.Add(fault);

							// set is trivially critical iff one of the direct subsets is not safe (i.e. critical)
							// * the faults faults[0], ..., faults[i-1] are not definitely not contained in set (see above)
							// * faults[i] is definitely in set, but set.Remove(faults[i]) == safeSet and is thus safe.
							var isTriviallyCritical = _criticalSets.Contains(set);
							for (var j = i + 1; j < faults.Length && !isTriviallyCritical; ++j)
							{
								var f = faults[j];
								if (set.Contains(f) && !previousSafe.Contains(set.Remove(f)))
									isTriviallyCritical = true;
							}

							// Check if the newly generated set is a super set of any critical sets;
							// if so, discard it
							if (!isTriviallyCritical)
								result.Add(set);
						}

						// all supersets of sets in setsToRemove have either
						// been previously generated or are critical
						previousSafe.ExceptWith(setsToRemove);

						// if no more sets in previousSafe, further iterations are pointless
						if (previousSafe.Count == 0)
							break;
					}
					break;
			}

			return result;
		}
Esempio n. 46
0
		/// <summary>
		///   Gets the activation order relationships that exist for the faults contained in
		///   <paramref name="minimalCriticalFaultSet" />, if any.
		/// </summary>
		/// <param name="minimalCriticalFaultSet">The minimal critical fault set the order should be returned for.</param>
		private IEnumerable<OrderRelationship> GetOrderRelationships(ISet<Fault> minimalCriticalFaultSet)
		{
			var checkedSet = new FaultSet(minimalCriticalFaultSet);
			var activation = _results.FaultActivationBehavior == FaultActivationBehavior.ForceOnly ? Activation.Forced : Activation.Nondeterministic;
			var checkedFaults = minimalCriticalFaultSet.ToArray();

			// Create all pairs of faults contained in minimalCriticalFaultSet such that
			// we don't get pairs (f,f) and we don't generate duplicate pairs (f1,f2) and (f2,f1)
			for (var i = 0; i < checkedFaults.Length; ++i)
			{
				for (var j = i + 1; j < checkedFaults.Length; ++j)
				{
					var fault1 = checkedFaults[i];
					var fault2 = checkedFaults[j];

					// Check if one can be activated strictly before the other
					var fault1BeforeFault2 = _backend.CheckOrder(fault1, fault2, checkedSet, activation, forceSimultaneous: false);
					var fault2BeforeFault1 = _backend.CheckOrder(fault2, fault1, checkedSet, activation, forceSimultaneous: false);

					// If both can be activated stritly before the other, there is no ordering
					if (!fault2BeforeFault1.FormulaHolds && !fault1BeforeFault2.FormulaHolds)
						continue;

					// Check for simultaneous activations
					var simultaneous = _backend.CheckOrder(fault1, fault2, checkedSet, activation, forceSimultaneous: true);

					// f1 == f2
					if (!simultaneous.FormulaHolds && fault1BeforeFault2.FormulaHolds && fault2BeforeFault1.FormulaHolds)
						yield return new OrderRelationship(simultaneous, fault1, fault2, OrderRelationshipKind.Simultaneously);

					// f1 <= f2
					else if (!fault1BeforeFault2.FormulaHolds && !simultaneous.FormulaHolds)
						yield return new OrderRelationship(simultaneous, fault1, fault2, OrderRelationshipKind.Precedes);

					// f1 < f2
					else if (!fault1BeforeFault2.FormulaHolds && simultaneous.FormulaHolds)
						yield return new OrderRelationship(simultaneous, fault1, fault2, OrderRelationshipKind.StrictlyPrecedes);

					// f2 <= f1
					else if (!fault2BeforeFault1.FormulaHolds && !simultaneous.FormulaHolds)
						yield return new OrderRelationship(simultaneous, fault2, fault1, OrderRelationshipKind.Precedes);

					// f2 < f1
					else if (!fault2BeforeFault1.FormulaHolds && simultaneous.FormulaHolds)
						yield return new OrderRelationship(simultaneous, fault2, fault1, OrderRelationshipKind.StrictlyPrecedes);
				}
			}
		}
		/// <summary>
		///   Gets all combinations of fault sets that have one fault of each minimal critical fault set removed.
		/// </summary>
		private IEnumerable<FaultSet> RemoveAllFaults(FaultSet removed, int setIndex)
		{
			if (setIndex >= _minimalCriticalSets.Count)
				yield return removed;
			else
			{
				foreach (var fault in _minimalCriticalSets[setIndex].Where(f => f.Activation != Activation.Forced))
				{
					var next = removed.Contains(fault) ? removed : removed.Add(fault);

					foreach (var set in RemoveAllFaults(next, setIndex + 1))
						yield return set;
				}
			}
		}
		/// <summary>
		///   Informs the heuristic of the result of analyzing <paramref name="checkedSet" />
		///   and allows it to adapt the sets to check next.
		/// </summary>
		public void Update(LinkedList<FaultSet> setsToCheck, FaultSet checkedSet, bool isSafe)
		{
			// Ignore critical sets we've suggested ourself as these are likely not minimal and
			// would degrade the quality of our suggestions
			if (isSafe || _suggestedSets.Contains(checkedSet))
				return;

			_hasNewMinimalCriticalSets = true;
			_minimalCriticalSets.Add(checkedSet.ToFaultSequence(_model.Faults).ToArray());
		}
Esempio n. 49
0
		/// <summary>
		///   Checks the order of <see cref="firstFault" /> and <see cref="secondFault" /> for the
		///   <see cref="minimalCriticalFaultSet" /> using the <see cref="activation" /> mode.
		/// </summary>
		/// <param name="firstFault">The first fault that should be checked.</param>
		/// <param name="secondFault">The second fault that should be checked.</param>
		/// <param name="minimalCriticalFaultSet">The minimal critical fault set that should be checked.</param>
		/// <param name="activation">The activation mode of the fault set.</param>
		/// <param name="forceSimultaneous">Indicates whether both faults must occur simultaneously.</param>
		internal override AnalysisResult CheckOrder(Fault firstFault, Fault secondFault, FaultSet minimalCriticalFaultSet,
													Activation activation, bool forceSimultaneous)
		{
			throw new NotImplementedException();
		}
		/// <summary>
		///   Adds the <paramref name="successorState" /> to the transition set if neccessary, reached using the
		///   <paramref name="activatedFaults" />.
		/// </summary>
		/// <param name="successorState">The successor state that should be added.</param>
		/// <param name="activatedFaults">The faults activated by the transition to reach the state.</param>
		private bool Add(byte* successorState, FaultSet activatedFaults)
		{
			var hash = MemoryBuffer.Hash(successorState, _stateVectorSize, 0);
			for (var i = 1; i < ProbeThreshold; ++i)
			{
				var stateHash = MemoryBuffer.Hash((byte*)&hash, sizeof(int), i * 8345723) % _capacity;
				var faultIndex = _lookup[stateHash];

				// If we don't know the state yet, set everything up and add the transition
				if (faultIndex == -1)
				{
					_successors.Add((uint)stateHash);
					AddFaultMetadata(stateHash, -1);
					MemoryBuffer.Copy(successorState, _hashedStateMemory + stateHash * _stateVectorSize, _stateVectorSize);

					return true;
				}

				// If there is a hash conflict, try again
				if (!MemoryBuffer.AreEqual(successorState, _hashedStateMemory + stateHash * _stateVectorSize, _stateVectorSize))
					continue;

				// The transition has an already-known target state; it might have to be added or invalidate previously found transitions
				return UpdateTransitions(stateHash, activatedFaults, faultIndex);
			}

			throw new OutOfMemoryException(
				"Failed to find an empty hash table slot within a reasonable amount of time. Try increasing the successor state capacity.");
		}
Esempio n. 51
0
		/// <summary>
		///   Checks the <see cref="faults" /> for criticality using the <see cref="activation" /> mode.
		/// </summary>
		/// <param name="faults">The fault set that should be checked for criticality.</param>
		/// <param name="activation">The activation mode of the fault set.</param>
		internal abstract AnalysisResult CheckCriticality(FaultSet faults, Activation activation);
		/// <summary>
		///   Adds the current transition if it is activation-minimal. Previously found transition might have to be removed if they are
		///   no longer activation-minimal.
		/// </summary>
		private bool UpdateTransitions(long stateHash, FaultSet activatedFaults, int faultIndex)
		{
			bool addTransition;
			bool addFaults;
			bool cleanupTransitions;

			ClassifyActivatedFaults(activatedFaults, faultIndex, out addTransition, out addFaults, out cleanupTransitions);

			if (cleanupTransitions)
				CleanupTransitions(activatedFaults, faultIndex, stateHash);

			if (addFaults)
				AddFaultMetadata(stateHash, _lookup[stateHash]);

			return addTransition;
		}
		/// <summary>
		///   Checks the <see cref="faults" /> for criticality using the <see cref="activation" /> mode.
		/// </summary>
		/// <param name="faults">The fault set that should be checked for criticality.</param>
		/// <param name="activation">The activation mode of the fault set.</param>
		internal override AnalysisResult CheckCriticality(FaultSet faults, Activation activation)
		{
			ChangeFaultActivations(faults, activation);
			return _invariantChecker.Check();
		}
		/// <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->IsValid = false;
					*nextPointer = faultSet->NextSet;
				}

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

				current = faultSet->NextSet;
			}
		}
		/// <summary>
		///   Creates a function that determines the activation state of a fault.
		/// </summary>
		private Func<Fault, Activation> GetUpdateFaultActivations(FaultSet faults, Activation activation)
		{
			return fault => GetEffectiveActivation(fault, faults, activation);
		}
		/// <summary>
		///   Classifies how the transition set must be updated.
		/// </summary>
		private void ClassifyActivatedFaults(FaultSet activatedFaults, int faultIndex, out bool addTransition, out bool addFaults,
											 out bool cleanupTransitions)
		{
			addFaults = false;
			cleanupTransitions = false;

			// Basic invariant of the fault list: it contains only sets of activation-minimal faults
			while (faultIndex != -1)
			{
				var faultSet = &_faults[faultIndex];
				faultIndex = faultSet->NextSet;

				// If the fault set is a subset of the activated faults, the current transition is not activation-minimal;
				// we can therefore safely ignore the transition; due to the list invariant, none of the remaining
				// fault sets in the list can be a superset of the activated faults because then the current fault set
				// would also be a subset of that other fault set, violating the invariant
				if (faultSet->Transition->ActivatedFaults.IsSubsetOf(activatedFaults))
				{
					addTransition = faultSet->Transition->ActivatedFaults == activatedFaults;
					return;
				}

				// If at least one of the previously added transitions that we assumed to be activation-minimal is 
				// in fact not activation-minimal, we have to clean up the transition set
				if (activatedFaults.IsSubsetOf(faultSet->Transition->ActivatedFaults))
					cleanupTransitions = true;
			}

			// If we get here, we must add the faults and the transition
			addTransition = true;
			addFaults = true;
		}
Esempio n. 57
0
		private bool IsValid(FaultSet set)
		{
			// The set must contain all forced faults, hence it must be a superset of those
			// The set is not allowed to contain any suppressed faults, hence the intersection must be empty
			return _forcedSet.IsSubsetOf(set) && _suppressedSet.GetIntersection(set).IsEmpty;
		}
Esempio n. 58
0
		/// <summary>
		///   Computes the minimal critical sets for the <paramref name="hazard" />.
		/// </summary>
		/// <param name="model">The model the safety analysis should be conducted for.</param>
		/// <param name="hazard">The hazard the minimal critical sets should be computed for.</param>
		/// <param name="maxCardinality">
		///   The maximum cardinality of the fault sets that should be checked. By default, all minimal
		///   critical fault sets are determined.
		/// </param>
		public SafetyAnalysisResults ComputeMinimalCriticalSets(ModelBase model, Formula hazard, int maxCardinality = Int32.MaxValue)
		{
			Requires.NotNull(model, nameof(model));
			Requires.NotNull(hazard, nameof(hazard));

			ConsoleHelpers.WriteLine("Running Deductive Cause Consequence Analysis.");

			var heuristicWatch = new Stopwatch();
			var stopwatch = new Stopwatch();
			stopwatch.Start();

			var allFaults = model.Faults;
			FaultSet.CheckFaultCount(allFaults.Length);

			var forcedFaults = allFaults.Where(fault => fault.Activation == Activation.Forced).ToArray();
			var suppressedFaults = allFaults.Where(fault => fault.Activation == Activation.Suppressed).ToArray();
			var nondeterministicFaults = allFaults.Where(fault => fault.Activation == Activation.Nondeterministic).ToArray();
			var nonSuppressedFaults = allFaults.Where(fault => fault.Activation != Activation.Suppressed).ToArray();

			ConsoleHelpers.WriteLine();
			ConsoleHelpers.WriteLine($"Of the {allFaults.Length} faults contained in the model,");
			ConsoleHelpers.WriteLine($"   {suppressedFaults.Length} faults are suppressed,");
			ConsoleHelpers.WriteLine($"   {forcedFaults.Length} faults are forced, and");
			ConsoleHelpers.WriteLine($"   {nondeterministicFaults.Length} faults are nondeterministically activated.");
			ConsoleHelpers.WriteLine();

			_suppressedSet = new FaultSet(suppressedFaults);
			_forcedSet = new FaultSet(forcedFaults);

			var isComplete = true;

			// Remove information from previous analyses
			Reset(model);

			// Initialize the backend, the model, and the analysis results
			switch (Backend)
			{
				case SafetyAnalysisBackend.FaultOptimizedOnTheFly:
					_backend = new FaultOptimizationBackend();
					break;
				case SafetyAnalysisBackend.FaultOptimizedStateGraph:
					_backend = new StateGraphBackend();
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}

			_backend.OutputWritten += output => OutputWritten?.Invoke(output);
			_backend.InitializeModel(Configuration, model, hazard);
			_results = new SafetyAnalysisResults(model, hazard, suppressedFaults, forcedFaults, Heuristics, FaultActivationBehavior);

			// Remember all safe sets of current cardinality - we need them to generate the next power set level
			var currentSafe = new HashSet<FaultSet>();

			// We check fault sets by increasing cardinality; this is, we check the empty set first, then
			// all singleton sets, then all sets with two elements, etc. We don't check sets that we
			// know are going to be critical sets due to monotonicity
			for (var cardinality = 0; cardinality <= nonSuppressedFaults.Length; ++cardinality)
			{
				// Generate the sets for the current level that we'll have to check
				var sets = GeneratePowerSetLevel(cardinality, nonSuppressedFaults, currentSafe);
				currentSafe.Clear();

				// Remove all sets that conflict with the forced or suppressed faults; these sets are considered to be safe.
				// If no sets remain, skip to the next level
				sets = RemoveInvalidSets(sets, currentSafe);
				if (sets.Count == 0)
					continue;

				// Abort if we've exceeded the maximum fault set cardinality; doing the check here allows us
				// to report the analysis as complete if the maximum cardinality is never reached
				if (cardinality > maxCardinality)
				{
					isComplete = false;
					break;
				}

				if (cardinality == 0)
					ConsoleHelpers.WriteLine("Checking the empty fault set...");
				else
					ConsoleHelpers.WriteLine($"Checking {sets.Count} sets of cardinality {cardinality}...");

				// use heuristics
				var setsToCheck = new LinkedList<FaultSet>(sets);
				foreach (var heuristic in Heuristics)
				{
					var count = setsToCheck.Count;

					heuristicWatch.Restart();
					heuristic.Augment((uint)cardinality, setsToCheck);

					count = setsToCheck.Count - count;
					if (count > 0)
						ConsoleHelpers.WriteLine($"    {heuristic.GetType().Name} made {count} suggestions in {heuristicWatch.Elapsed.TotalMilliseconds}ms.");
				}

				// We have to check each set - heuristics may add further during the loop
				while (setsToCheck.Count > 0)
				{
					var set = setsToCheck.First.Value;

					var isCurrentLevel = sets.Remove(set); // returns true if set was actually contained
					setsToCheck.RemoveFirst();

					// for current level, we already know the set is valid
					var isValid = isCurrentLevel || IsValid(set);

					// the set is invalid if it exceeds the maximum cardinality level
					isValid &= set.Cardinality <= maxCardinality;

					var isSafe = true;
					if (isValid)
						isSafe = CheckSet(set, allFaults, !isCurrentLevel);

					if (isSafe && isCurrentLevel)
						currentSafe.Add(set);

					// inform heuristics about result and give them the opportunity to add further sets
					foreach (var heuristic in Heuristics)
						heuristic.Update(setsToCheck, set, isSafe);
				}

				// in case heuristics removed a set (they shouldn't)
				foreach (var set in sets)
				{
					var isSafe = CheckSet(set, allFaults, false);
					if (isSafe)
						currentSafe.Add(set);
				}
			}

			// Reset the nondeterministic faults so as to not influence subsequent analyses
			foreach (var fault in nondeterministicFaults)
				fault.Activation = Activation.Nondeterministic;

			// due to heuristics usage, we may have informatiuon on non-minimal critical sets
			var minimalCritical = RemoveNonMinimalCriticalSets();

			_results.IsComplete = isComplete;
			_results.Time = stopwatch.Elapsed;
			_results.SetResult(minimalCritical, _checkedSets, _counterExamples, _exceptions);

			return _results;
		}
Esempio n. 59
0
		/// <summary>
		///   Checks the order of <see cref="firstFault" /> and <see cref="secondFault" /> for the
		///   <see cref="minimalCriticalFaultSet" /> using the <see cref="activation" /> mode.
		/// </summary>
		/// <param name="firstFault">The first fault that should be checked.</param>
		/// <param name="secondFault">The second fault that should be checked.</param>
		/// <param name="minimalCriticalFaultSet">The minimal critical fault set that should be checked.</param>
		/// <param name="activation">The activation mode of the fault set.</param>
		/// <param name="forceSimultaneous">Indicates whether both faults must occur simultaneously.</param>
		internal abstract AnalysisResult CheckOrder(Fault firstFault, Fault secondFault, FaultSet minimalCriticalFaultSet,
													Activation activation, bool forceSimultaneous);
Esempio n. 60
0
		/// <summary>
		///   Determines the effective <see cref="Activation" /> of the <paramref name="fault" /> when <paramref name="faults" /> should
		///   be checked for criticality.
		/// </summary>
		protected Activation GetEffectiveActivation(Fault fault, FaultSet faults, Activation activation)
		{
			Assert.That(fault != null && fault.IsUsed, "Invalid fault.");

			if (SuppressedFaults.Contains(fault))
				return Activation.Suppressed;

			if (ForcedFaults.Contains(fault))
				return Activation.Forced;

			if (faults.Contains(fault))
				return activation;

			return Activation.Suppressed;
		}