/// <summary>
		///   Initializes a new instance.
		/// </summary>
		/// <param name="counterExampleMetadata">The state vector layout expected by the counter example.</param>
		/// <param name="modelMetadata">The state vector layout expected by the model.</param>
		internal StateVectorMismatchException(StateVectorLayout counterExampleMetadata, StateVectorLayout modelMetadata)
			: base("Mismatch detected between the layout of the state vector as expected by the counter example and the " +
				   "actual layout of the state vector used by the instantiated model.")
		{
			CounterExampleMetadata = counterExampleMetadata;
			ModelMetadata = modelMetadata;
		}
示例#2
0
        /// <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);
        }
示例#3
0
        protected void GenerateCode(SerializationMode mode, params object[] objects)
        {
            objects = SerializationRegistry.Default.GetReferencedObjects(objects, mode).ToArray();
            var model = TestModel.InitializeModel(new DummyComponent(objects));

            _objectTable      = new ObjectTable(objects);
            StateVectorLayout = SerializationRegistry.Default.GetStateVectorLayout(model, _objectTable, mode);
            _serializer       = StateVectorLayout.CreateSerializer(_objectTable);
            _deserializer     = StateVectorLayout.CreateDeserializer(_objectTable);
            _rangeRestrictor  = StateVectorLayout.CreateRangeRestrictor(_objectTable);

            StateSlotCount  = StateVectorLayout.SizeInBytes / 4;
            StateVectorSize = StateVectorLayout.SizeInBytes;
            _buffer         = new MemoryBuffer();
            _buffer.Resize(StateVectorSize, zeroMemory: true);
            SerializedState = _buffer.Pointer;

            Output.Log("{0}", StateVectorLayout);
        }
		protected void GenerateCode(SerializationMode mode, params object[] objects)
		{
			objects = SerializationRegistry.Default.GetReferencedObjects(objects, mode).ToArray();
			var model = TestModel.InitializeModel(new DummyComponent(objects));

			_objectTable = new ObjectTable(objects);
			StateVectorLayout = SerializationRegistry.Default.GetStateVectorLayout(model, _objectTable, mode);
			_serializer = StateVectorLayout.CreateSerializer(_objectTable);
			_deserializer = StateVectorLayout.CreateDeserializer(_objectTable);
			_rangeRestrictor = StateVectorLayout.CreateRangeRestrictor(_objectTable);

			StateSlotCount = StateVectorLayout.SizeInBytes / 4;
			StateVectorSize = StateVectorLayout.SizeInBytes;
			_buffer = new MemoryBuffer();
			_buffer.Resize(StateVectorSize, zeroMemory: true);
			SerializedState = _buffer.Pointer;

			Output.Log("{0}", StateVectorLayout);
		}
示例#5
0
        /// <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 SafetySharpRuntimeModel(SerializedRuntimeModel serializedData, int stateHeaderBytes = 0) : base(stateHeaderBytes)
        {
            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();
            ExecutableStateFormulas = objectTable.OfType <ExecutableStateFormula>().ToArray();
            Formulas                = formulas;
            StateConstraints        = Model.Components.Cast <Component>().SelectMany(component => component.StateConstraints).ToArray();

            // 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.
            Faults             = objectTable.OfType <Fault>().Where(fault => fault.IsUsed).ToArray();
            _serializedObjects = new ObjectTable(Model.ReferencedObjects);

            Objects           = objectTable;
            StateVectorLayout = SerializationRegistry.Default.GetStateVectorLayout(Model, _serializedObjects, SerializationMode.Optimized);
            UpdateFaultSets();

            _deserialize    = StateVectorLayout.CreateDeserializer(_serializedObjects);
            _serialize      = StateVectorLayout.CreateSerializer(_serializedObjects);
            _restrictRanges = StateVectorLayout.CreateRangeRestrictor(_serializedObjects);

            PortBinding.BindAll(objectTable);

            InitializeConstructionState();
            CheckConsistencyAfterInitialization();
        }
示例#6
0
        /// <summary>
        ///   Initializes a new instance.
        /// </summary>
        /// <param name="layout">The layout of the state vector..</param>
        /// <param name="capacity">The capacity of the cache, i.e., the number of states that can be stored in the cache.</param>
        public StateStorage(StateVectorLayout layout, int capacity)
        {
            Requires.NotNull(layout, nameof(layout));
            Requires.InRange(capacity, nameof(capacity), 1024, Int32.MaxValue);

            _stateVectorSize = layout.SizeInBytes;
            _capacity        = capacity;

            _stateBuffer.Resize((long)_capacity * _stateVectorSize, zeroMemory: false);
            _stateMemory = _stateBuffer.Pointer;

            // We allocate enough space so that we can align the returned pointer such that index 0 is the start of a cache line
            _hashBuffer.Resize((long)_capacity * sizeof(int) + CacheLineSize, zeroMemory: true);
            _hashMemory = (int *)_hashBuffer.Pointer;

            if ((ulong)_hashMemory % CacheLineSize != 0)
            {
                _hashMemory = (int *)(_hashBuffer.Pointer + (CacheLineSize - (ulong)_hashBuffer.Pointer % CacheLineSize));
            }

            Assert.InRange((ulong)_hashMemory - (ulong)_hashBuffer.Pointer, 0ul, (ulong)CacheLineSize);
            Assert.That((ulong)_hashMemory % CacheLineSize == 0, "Invalid buffer alignment.");
        }
示例#7
0
		/// <summary>
		///   Loads a counter example from the <paramref name="file" />.
		/// </summary>
		/// <param name="file">The path to the file the counter example should be loaded from.</param>
		public static CounterExample Load(string file)
		{
			Requires.NotNullOrWhitespace(file, nameof(file));

			using (var reader = new BinaryReader(File.OpenRead(file), Encoding.UTF8))
			{
				if (reader.ReadInt32() != FileHeader)
					throw new InvalidOperationException("The file does not contain a counter example that is compatible with this version of S#.");

				var endsWithException = reader.ReadBoolean();
				var serializedRuntimeModel = reader.ReadBytes(reader.ReadInt32());
				var modelData = RuntimeModelSerializer.LoadSerializedData(serializedRuntimeModel);

				foreach (var fault in modelData.ObjectTable.OfType<Fault>())
					fault.Activation = (Activation)reader.ReadInt32();

				var runtimeModel = new RuntimeModel(modelData);
				runtimeModel.UpdateFaultSets();

				var metadataStream = new MemoryStream(reader.ReadBytes(reader.ReadInt32()));
				var formatter = new BinaryFormatter();
				var slotMetadata = new StateVectorLayout((StateSlotMetadata[])formatter.Deserialize(metadataStream));
				var modelMetadata = runtimeModel.StateVectorLayout;

				var counterExample = new byte[reader.ReadInt32()][];
				var slotCount = reader.ReadInt32();

				if (slotCount != runtimeModel.StateVectorSize)
				{
					throw new InvalidOperationException(
						$"State slot count mismatch; the instantiated model requires {runtimeModel.StateVectorSize} state slots, " +
						$"whereas the counter example uses {slotCount} state slots.");
				}

				if (slotMetadata.SlotCount != modelMetadata.SlotCount)
				{
					throw new InvalidOperationException(
						$"State slot metadata count mismatch; the instantiated model has {modelMetadata.SlotCount} state slot metadata entries, " +
						$"whereas the counter example has {slotMetadata.SlotCount} state slot entries.");
				}

				for (var i = 0; i < slotMetadata.SlotCount; ++i)
				{
					if (modelMetadata[i] != slotMetadata[i])
						throw new StateVectorMismatchException(slotMetadata, modelMetadata);
				}

				for (var i = 0; i < counterExample.Length; ++i)
				{
					counterExample[i] = new byte[runtimeModel.StateVectorSize];
					for (var j = 0; j < runtimeModel.StateVectorSize; ++j)
						counterExample[i][j] = reader.ReadByte();
				}

				var replayInfo = new int[reader.ReadInt32()][];
				for (var i = 0; i < replayInfo.Length; ++i)
				{
					replayInfo[i] = new int[reader.ReadInt32()];
					for (var j = 0; j < replayInfo[i].Length; ++j)
						replayInfo[i][j] = reader.ReadInt32();
				}

				return new CounterExample(runtimeModel, counterExample, replayInfo, endsWithException);
			}
		}
		/// <summary>
		///   Generates the <see cref="StateVectorLayout" /> for the <paramref name="objects" />.
		/// </summary>
		/// <param name="model">The model the state vector should be layouted for.</param>
		/// <param name="objects">The objects consisting of state values the state vector layout should be generated for.</param>
		/// <param name="mode">The serialization mode that should be used to generate the state vector layout.</param>
		internal StateVectorLayout GetStateVectorLayout(ModelBase model, ObjectTable objects, SerializationMode mode)
		{
			Requires.NotNull(model, nameof(model));
			Requires.NotNull(objects, nameof(objects));
			Requires.InRange(mode, nameof(mode));

			var layout = new StateVectorLayout();
			foreach (var slot in objects.SelectMany(obj => GetSerializer(obj).GetStateSlotMetadata(obj, objects.GetObjectIdentifier(obj), mode)))
				layout.Add(slot);

			layout.Compact(model, mode);
			return layout;
		}
		/// <summary>
		///   Serializes the <paramref name="model" />.
		/// </summary>
		private unsafe void SerializeModel(BinaryWriter writer, ModelBase model, Formula[] formulas)
		{
			// Collect all objects contained in the model
			var objectTable = CreateObjectTable(model, formulas);

			// Prepare the serialization of the model's initial state
			lock (_syncObject)
			{
				_stateVector = SerializationRegistry.Default.GetStateVectorLayout(model, objectTable, SerializationMode.Full);
				_deserializer = null;
			}

			var stateVectorSize = _stateVector.SizeInBytes;
			var serializer = _stateVector.CreateSerializer(objectTable);

			// Serialize the object table
			SerializeObjectTable(objectTable, writer);

			// Serialize the object identifier of the model itself and the formulas
			writer.Write(objectTable.GetObjectIdentifier(model));
			writer.Write(formulas.Length);
			foreach (var formula in formulas)
				writer.Write(objectTable.GetObjectIdentifier(formula));

			// Serialize the initial state
			var serializedState = stackalloc byte[stateVectorSize];
			serializer(serializedState);

			// Copy the serialized state to the stream
			writer.Write(stateVectorSize);
			for (var i = 0; i < stateVectorSize; ++i)
				writer.Write(serializedState[i]);
		}
		/// <summary>
		///   Deserializes a <see cref="RuntimeModel" /> from the <paramref name="reader" />.
		/// </summary>
		private unsafe SerializedRuntimeModel DeserializeModel(byte[] buffer, BinaryReader reader)
		{
			// Deserialize the object table
			var objectTable = DeserializeObjectTable(reader);

			// Deserialize the object identifiers of the model itself and the root formulas
			var model = (ModelBase)objectTable.GetObject(reader.ReadUInt16());
			var formulas = new Formula[reader.ReadInt32()];
			for (var i = 0; i < formulas.Length; ++i)
				formulas[i] = (Formula)objectTable.GetObject(reader.ReadUInt16());

			// Copy the serialized initial state from the stream
			var stateVectorSize = reader.ReadInt32();
			var serializedState = stackalloc byte[stateVectorSize];

			for (var i = 0; i < stateVectorSize; ++i)
				serializedState[i] = reader.ReadByte();

			// Deserialize the model's initial state
			OpenSerializationDelegate deserializer;
			lock (_syncObject)
			{
				if (_stateVector == null)
					_stateVector = SerializationRegistry.Default.GetStateVectorLayout(model, objectTable, SerializationMode.Full);

				if (_deserializer == null)
					_deserializer = _stateVector.CreateDeserializer();

				deserializer = _deserializer;
			}

			deserializer(objectTable, serializedState);

			// We instantiate the runtime type for each component and replace the original component
			// instance with the new runtime instance; we also replace all of the component's fault effects
			// with that instance and deserialize the initial state again. Afterwards, we have completely
			// replaced the original instance with its runtime instance, taking over all serialized data
			objectTable.SubstituteRuntimeInstances();
			deserializer(objectTable, serializedState);

			// We substitute the dummy delegate objects with the actual instances obtained from the DelegateMetadata instances
			objectTable.SubstituteDelegates();
			deserializer(objectTable, serializedState);

			// Return the serialized model data
			return new SerializedRuntimeModel(model, buffer, objectTable, formulas);
		}
示例#11
0
        /// <summary>
        ///   Loads a counter example from the <paramref name="file" />.
        /// </summary>
        /// <param name="file">The path to the file the counter example should be loaded from.</param>
        public static CounterExample Load(string file)
        {
            Requires.NotNullOrWhitespace(file, nameof(file));

            using (var reader = new BinaryReader(File.OpenRead(file), Encoding.UTF8))
            {
                if (reader.ReadInt32() != FileHeader)
                {
                    throw new InvalidOperationException("The file does not contain a counter example that is compatible with this version of S#.");
                }

                var endsWithException      = reader.ReadBoolean();
                var serializedRuntimeModel = reader.ReadBytes(reader.ReadInt32());
                var modelData = RuntimeModelSerializer.LoadSerializedData(serializedRuntimeModel);

                foreach (var fault in modelData.ObjectTable.OfType <Fault>())
                {
                    fault.Activation = (Activation)reader.ReadInt32();
                }

                var runtimeModel   = new RuntimeModel(modelData);
                var metadataStream = new MemoryStream(reader.ReadBytes(reader.ReadInt32()));
                var formatter      = new BinaryFormatter();
                var slotMetadata   = new StateVectorLayout((StateSlotMetadata[])formatter.Deserialize(metadataStream));
                var modelMetadata  = runtimeModel.StateVectorLayout;

                var counterExample = new byte[reader.ReadInt32()][];
                var slotCount      = reader.ReadInt32();

                if (slotCount != runtimeModel.StateVectorSize)
                {
                    throw new InvalidOperationException(
                              $"State slot count mismatch; the instantiated model requires {runtimeModel.StateVectorSize} state slots, " +
                              $"whereas the counter example uses {slotCount} state slots.");
                }

                if (slotMetadata.SlotCount != modelMetadata.SlotCount)
                {
                    throw new InvalidOperationException(
                              $"State slot metadata count mismatch; the instantiated model has {modelMetadata.SlotCount} state slot metadata entries, " +
                              $"whereas the counter example has {slotMetadata.SlotCount} state slot entries.");
                }

                for (var i = 0; i < slotMetadata.SlotCount; ++i)
                {
                    if (modelMetadata[i] != slotMetadata[i])
                    {
                        throw new StateVectorMismatchException(slotMetadata, modelMetadata);
                    }
                }

                for (var i = 0; i < counterExample.Length; ++i)
                {
                    counterExample[i] = new byte[runtimeModel.StateVectorSize];
                    for (var j = 0; j < runtimeModel.StateVectorSize; ++j)
                    {
                        counterExample[i][j] = reader.ReadByte();
                    }
                }

                var replayInfo = new int[reader.ReadInt32()][];
                for (var i = 0; i < replayInfo.Length; ++i)
                {
                    replayInfo[i] = new int[reader.ReadInt32()];
                    for (var j = 0; j < replayInfo[i].Length; ++j)
                    {
                        replayInfo[i][j] = reader.ReadInt32();
                    }
                }

                return(new CounterExample(runtimeModel, counterExample, replayInfo, endsWithException));
            }
        }