private void InitializeFromSerializedModel()
        {
            var modelWithFormula = LustreModelSerializer.DeserializeFromByteArray(SerializedModel);

            Model    = modelWithFormula.Item1;
            Faults   = Model.Faults.Values.OrderBy(fault => fault.Identifier).ToArray();
            Formulas = modelWithFormula.Item2;

            var atomarPropositionVisitor = new CollectAtomarPropositionFormulasVisitor();

            _atomarPropositionFormulas = atomarPropositionVisitor.AtomarPropositionFormulas.ToArray();
            foreach (var stateFormula in Formulas)
            {
                atomarPropositionVisitor.Visit(stateFormula);
            }

            StateConstraints = new Func <bool> [0];

            UpdateFaultSets();

            _deserialize    = LustreModelSerializer.CreateFastInPlaceDeserializer(Model);
            _serialize      = LustreModelSerializer.CreateFastInPlaceSerializer(Model);
            _restrictRanges = () => { };

            InitializeConstructionState();
            CheckConsistencyAfterInitialization();
        }
        public static Tuple <LustreModelBase, Formula[]> DeserializeFromByteArray(byte[] serializedModel)
        {
            Requires.NotNull(serializedModel, nameof(serializedModel));

            using (var buffer = new MemoryStream(serializedModel))
                using (var reader = new BinaryReader(buffer, Encoding.UTF8, leaveOpen: true))
                {
                    // read ocFileName
                    var ocFileName = reader.ReadString();

                    // read mainNode
                    var mainNode = reader.ReadString();

                    // read faults
                    var faultNumber  = reader.ReadUInt32();
                    var faults       = new List <Fault>();
                    var indexToFault = new Dictionary <int, Fault>();
                    for (var i = 0; i < faultNumber; ++i)
                    {
                        var fault = ReadFault(reader);
                        faults.Add(fault);
                        indexToFault.Add(i, fault);
                    }

                    // read state and instantiate model
                    var deserializedModel = new LustreModelBase(ocFileName, mainNode, faults);

                    // read formulas
                    var formulaNumber = reader.ReadUInt32();
                    var formulas      = new Formula[formulaNumber];
                    for (var i = 0; i < formulaNumber; ++i)
                    {
                        formulas[i] = ReadFormula(reader, indexToFault);
                    }

                    //return tuple of model and formulas
                    return(new Tuple <LustreModelBase, Formula[]>(deserializedModel, formulas));
                }
        }
 public override bool Evaluate(LustreModelBase model)
 {
     return((int)model.Outputs.FirstOrDefault() < threshold);
 }
 public override bool Evaluate(LustreModelBase model)
 {
     return((bool)model.Outputs.FirstOrDefault());;
 }
 public abstract bool Evaluate(LustreModelBase model);
        public static SerializationDelegate CreateFastInPlaceSerializer(LustreModelBase model)
        {
            var permanentFaults = model.Faults.Values.OrderBy(fault => fault.Identifier).OfType <PermanentFault>().ToArray();

            var isActiveField = typeof(PermanentFault).GetField("_isActive", BindingFlags.NonPublic | BindingFlags.Instance);

            return(state =>
            {
                // Bools
                var boolPtr = (bool *)state;
                foreach (var b in model.Runner.Oc5ModelState.Bools)
                {
                    *(boolPtr++) = b;
                }


                // Ints
                var intPtr = (int *)boolPtr;
                foreach (var i in model.Runner.Oc5ModelState.Ints)
                {
                    *(intPtr++) = i > LustreQualitativeChecker.maxValue ? LustreQualitativeChecker.maxValue : i;
                }

                // Strings
                var charPtr = (char *)intPtr;
                foreach (var s in model.Runner.Oc5ModelState.Strings)
                {
                    var length = Math.Max(29, s.Length);
                    foreach (var c in s.ToCharArray(0, length))
                    {
                        *(charPtr++) = c;
                    }
                    charPtr += 30 - length;
                    *(charPtr++) = '\0';
                }

                // Floats
                var floatPtr = (float *)charPtr;
                foreach (var f in model.Runner.Oc5ModelState.Floats)
                {
                    *(floatPtr++) = f > LustreQualitativeChecker.maxValue ? LustreQualitativeChecker.maxValue : f;
                }

                // Double
                var doublePtr = (double *)floatPtr;
                foreach (var d in model.Runner.Oc5ModelState.Doubles)
                {
                    *(doublePtr++) = d > LustreQualitativeChecker.maxValue ? LustreQualitativeChecker.maxValue : d;
                }

                // Mappings
                var mappingsPtr = (PositionInOc5State *)doublePtr;
                foreach (var m in model.Runner.Oc5ModelState.Mappings)
                {
                    *(mappingsPtr++) = m;
                }

                // InputMappings
                foreach (var im in model.Runner.Oc5ModelState.InputMappings)
                {
                    *(mappingsPtr++) = im;
                }

                // OutputMappings
                foreach (var om in model.Runner.Oc5ModelState.OutputMappings)
                {
                    *(mappingsPtr++) = om;
                }

                // CurrentState
                var currentStatePtr = (int *)mappingsPtr;
                *(currentStatePtr++) = model.Runner.Oc5ModelState.CurrentState;

                // Faults
                var faultPtr = (long *)currentStatePtr;
                var faultsSerialized = 0L;
                for (var i = 0; i < permanentFaults.Length; ++i)
                {
                    var fault = permanentFaults[i];
                    var isActive = (bool)isActiveField.GetValue(fault);
                    if (isActive)
                    {
                        faultsSerialized |= 1L << i;
                    }
                }
                *(faultPtr) = faultsSerialized;
            });
        }
        public static SerializationDelegate CreateFastInPlaceDeserializer(LustreModelBase model)
        {
            var permanentFaults = model.Faults.Values.OrderBy(fault => fault.Identifier).OfType <PermanentFault>().ToArray();

            var isActiveField = typeof(PermanentFault).GetField("_isActive", BindingFlags.NonPublic | BindingFlags.Instance);

            return(state =>
            {
                // Bools
                var boolPtr = (bool *)state;
                for (int i = 0; i < model.Runner.Oc5ModelState.Bools.Count; i++)
                {
                    model.Runner.Oc5ModelState.Bools[i] = *(boolPtr++);
                }


                // Ints
                var intPtr = (int *)boolPtr;
                for (int i = 0; i < model.Runner.Oc5ModelState.Ints.Count; i++)
                {
                    model.Runner.Oc5ModelState.Ints[i] = *(intPtr++);
                }

                // Strings
                var charPtr = (char *)intPtr;
                for (int i = 0; i < model.Runner.Oc5ModelState.Strings.Count; i++)
                {
                    string str = string.Empty;

                    while (*charPtr != '\0')
                    {
                        str += *(charPtr++);
                    }

                    charPtr++; // skip '\0'

                    model.Runner.Oc5ModelState.Strings[i] = str;
                }

                // Floats
                var floatPtr = (float *)charPtr;
                for (int i = 0; i < model.Runner.Oc5ModelState.Floats.Count; i++)
                {
                    model.Runner.Oc5ModelState.Floats[i] = *(floatPtr++);
                }

                // Double
                var doublePtr = (double *)floatPtr;
                for (int i = 0; i < model.Runner.Oc5ModelState.Doubles.Count; i++)
                {
                    model.Runner.Oc5ModelState.Doubles[i] = *(doublePtr++);
                }

                // Mappings
                var mappingsPtr = (PositionInOc5State *)doublePtr;
                for (int i = 0; i < model.Runner.Oc5ModelState.Mappings.Count; i++)
                {
                    model.Runner.Oc5ModelState.Mappings[i] = *(mappingsPtr++);
                }

                // InputMappings
                for (int i = 0; i < model.Runner.Oc5ModelState.InputMappings.Count; i++)
                {
                    model.Runner.Oc5ModelState.InputMappings[i] = *(mappingsPtr++);
                }

                // OutputMappings
                for (int i = 0; i < model.Runner.Oc5ModelState.OutputMappings.Count; i++)
                {
                    model.Runner.Oc5ModelState.OutputMappings[i] = *(mappingsPtr++);
                }

                // CurrentState
                var currentStatePtr = (int *)mappingsPtr;
                model.Runner.Oc5ModelState.CurrentState = *(currentStatePtr++);

                // Faults
                var faultPtr = (long *)currentStatePtr;
                var faultsSerialized = *faultPtr;
                for (var i = 0; i < permanentFaults.Length; ++i)
                {
                    var fault = permanentFaults[i];
                    if ((faultsSerialized & (1L << i)) != 0)
                    {
                        isActiveField.SetValue(fault, true);
                    }
                    else
                    {
                        isActiveField.SetValue(fault, false);
                    }
                }

                var lastPosition = (byte *)(faultPtr + 1);
                var length = lastPosition - state;
                Requires.That(model.StateVectorSize == length, "model.StateVectorSize does not match");
            });
        }