/// <summary> /// Runs a step of the simulation. Returns <c>false</c> to indicate that the simulation is completed. /// </summary> public void SimulateStep() { Prune(); var state = stackalloc byte[_runtimeModel.StateVectorSize]; if (_counterExample == null) { _runtimeModel.ExecuteStep(); _runtimeModel.Serialize(state); AddState(state); } else { if (_stateIndex + 1 >= _counterExample.StepCount) { return; } _counterExample.DeserializeState(_stateIndex + 1); _runtimeModel.Serialize(state); EnsureStatesMatch(state, _counterExample.GetState(_stateIndex + 1)); AddState(state); Replay(); } }
/// <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> public void Add(RuntimeModel model) { if (_count >= _capacity) throw new OutOfMemoryException("Unable to store an additional transition. Try increasing the successor state capacity."); ++_computedCount; // 1. Serialize the model's computed state; that is the successor state of the transition's source state // modulo any changes resulting from notifications of fault activations var successorState = _targetStateMemory + _stateVectorSize * _count; var activatedFaults = FaultSet.FromActivatedFaults(model.NondeterministicFaults); model.Serialize(successorState); // 2. Make sure the transition we're about to add is activation-minimal if (!Add(successorState, activatedFaults)) return; // 3. Execute fault activation notifications and serialize the updated state if necessary if (model.NotifyFaultActivations()) model.Serialize(successorState); // 4. Store the transition _transitions[_count] = new CandidateTransition { TargetState = successorState, Formulas = new StateFormulaSet(_formulas), ActivatedFaults = activatedFaults, IsValid = true, }; ++_count; }