public override void SetChoiceResolver(ChoiceResolver choiceResolver) { foreach (var choice in Objects.OfType <Choice>()) { choice.Resolver = choiceResolver; } }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="serializedData">The serialized data describing the model.</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 RuntimeModel(SerializedRuntimeModel serializedData, int stateHeaderBytes = 0) { Requires.That(serializedData.Model != null, "Expected a valid model instance."); var buffer = serializedData.Buffer; var rootComponents = serializedData.Model.Roots; var objectTable = serializedData.ObjectTable; var formulas = serializedData.Formulas; Requires.NotNull(buffer, nameof(buffer)); Requires.NotNull(rootComponents, nameof(rootComponents)); Requires.NotNull(objectTable, nameof(objectTable)); Requires.NotNull(formulas, nameof(formulas)); Requires.That(stateHeaderBytes % 4 == 0, nameof(stateHeaderBytes), "Expected a multiple of 4."); Model = serializedData.Model; SerializedModel = buffer; RootComponents = rootComponents.Cast <Component>().ToArray(); Faults = objectTable.OfType <Fault>().Where(fault => fault.Activation == Activation.Nondeterministic && fault.IsUsed).ToArray(); ActivationSensitiveFaults = Faults.Where(fault => fault.RequiresActivationNotification).ToArray(); StateFormulas = objectTable.OfType <StateFormula>().ToArray(); Formulas = formulas; // Create a local object table just for the objects referenced by the model; only these objects // have to be serialized and deserialized. The local object table does not contain, for instance, // the closure types of the state formulas var objects = Model.ReferencedObjects; var deterministicFaults = objectTable.OfType <Fault>().Where(fault => fault.Activation != Activation.Nondeterministic); _serializedObjects = new ObjectTable(objects.Except(deterministicFaults, ReferenceEqualityComparer <object> .Default)); Objects = objectTable; StateVectorLayout = SerializationRegistry.Default.GetStateVectorLayout(Model, _serializedObjects, SerializationMode.Optimized); _deserialize = StateVectorLayout.CreateDeserializer(_serializedObjects); _serialize = StateVectorLayout.CreateSerializer(_serializedObjects); _restrictRanges = StateVectorLayout.CreateRangeRestrictor(_serializedObjects); _stateHeaderBytes = stateHeaderBytes; PortBinding.BindAll(objectTable); _choiceResolver = new ChoiceResolver(objectTable); ConstructionState = new byte[StateVectorSize]; fixed(byte *state = ConstructionState) { Serialize(state); _restrictRanges(); } FaultSet.CheckFaultCount(Faults.Length); StateFormulaSet.CheckFormulaCount(StateFormulas.Length); }
/// <summary> /// Generates the replay information for the <paramref name="trace" />. /// </summary> /// <param name="choiceResolver">The choice resolver that should be used to resolve nondeterministic choices.</param> /// <param name="trace">The trace the replay information should be generated for.</param> /// <param name="endsWithException">Indicates whether the trace ends with an exception being thrown.</param> private int[][] GenerateReplayInformation(ChoiceResolver choiceResolver, byte[][] trace, bool endsWithException) { var info = new int[trace.Length - 1][]; var targetState = stackalloc byte[StateVectorSize]; // We have to generate the replay info for all transitions for (var i = 0; i < trace.Length - 1; ++i) { choiceResolver.Clear(); choiceResolver.PrepareNextState(); // Try all transitions until we find the one that leads to the desired state while (true) { try { if (!choiceResolver.PrepareNextPath()) break; fixed (byte* sourceState = trace[i]) Deserialize(sourceState); if (i == 0) ExecuteInitialStep(); else ExecuteStep(); if (endsWithException && i == trace.Length - 2) continue; } catch (Exception) { Requires.That(endsWithException, "Unexpected exception."); Requires.That(i == trace.Length - 2, "Unexpected exception."); info[i] = choiceResolver.GetChoices().ToArray(); break; } NotifyFaultActivations(); Serialize(targetState); // Compare the target states; if they match, we've found the correct transition var areEqual = true; for (var j = _stateHeaderBytes; j < StateVectorSize; ++j) areEqual &= targetState[j] == trace[i + 1][j]; if (!areEqual) continue; info[i] = choiceResolver.GetChoices().ToArray(); break; } Requires.That(info[i] != null, $"Unable to generate replay information for step {i + 1} of {trace.Length}."); } return info; }
/// <summary> /// Creates a counter example from the <paramref name="path" />. /// </summary> /// <param name="createModel">The factory function that can be used to create new instances of this model.</param> /// <param name="path"> /// The path the counter example should be generated from. A value of <c>null</c> indicates that no /// transitions could be generated for the model. /// </param> /// <param name="endsWithException">Indicates whether the counter example ends with an exception.</param> public CounterExample CreateCounterExample(Func<RuntimeModel> createModel, byte[][] path,bool endsWithException) { Requires.NotNull(createModel, nameof(createModel)); // We have to create new model instances to generate and initialize the counter example, otherwise hidden // state variables might prevent us from doing so if they somehow influence the state var replayModel = createModel(); var counterExampleModel = createModel(); var choiceResolver = new ChoiceResolver(replayModel.Objects.OfType<Choice>()); CopyFaultActivationStates(replayModel); CopyFaultActivationStates(counterExampleModel); // Prepend the construction state to the path; if the path is null, at least one further state must be added // to enable counter example debugging. // Also, get the replay information, i.e., the nondeterministic choices that were made on the path; if the path is null, // we still have to get the choices that caused the problem. if (path == null) path = new[] { new byte[StateVectorSize] }; path = new[] { ConstructionState }.Concat(path).ToArray(); var replayInfo = replayModel.GenerateReplayInformation(choiceResolver, path, endsWithException); return new CounterExample(counterExampleModel, path, replayInfo, endsWithException); }