コード例 #1
0
        private SystemDDs EncodeSingleModule(SingleModuleSystem system, List <int> currentAvailStartBits)
        {
            int    moduleIndex = modules.GetModuleIndex(system.moduleName);
            Module module      = modules.GetModule(moduleIndex);

            SystemDDs result = new SystemDDs();

            //encode not sync command
            result.ind = EncodeModule(moduleIndex, module, string.Empty, 0);

            // build mtbdd for each synchronising action
            for (int i = 0; i < synchs.Count; i++)
            {
                result.synchs.Add(EncodeModule(moduleIndex, module, synchs.ElementAt(i), currentAvailStartBits[i]));
            }

            // store identity matrix
            CUDD.Ref(moduleIdentities[moduleIndex]);
            result.id = moduleIdentities[moduleIndex];

            // store synchs used
            result.allSynchs.UnionWith(module.GetAllSynchs());

            return(result);
        }
コード例 #2
0
        private SystemDDs EncodeFullParallelSystem(FullParallelSystem sys, List <int> currentAvailStartBits)
        {
            SystemDDs  sysDDs1, sysDDs2, sysDDs;
            List <int> newCurrentAvailStartBits = new List <int>();
            int        i, j;

            // construct mtbdds for first operand
            sysDDs = EncodeSystemDefRec(sys.GetSystem(0), currentAvailStartBits);

            // loop through all other operands in the parallel operator
            for (i = 1; i < sys.NumberSystem; i++)
            {
                // change min to max for potentially synchronising actions
                // store this in new array - old one may still be used elsewhere
                for (j = 0; j < synchs.Count; j++)
                {
                    int newValue = (sysDDs.allSynchs.Contains(synchs[j])) ? sysDDs.synchs[j].max : currentAvailStartBits[j];
                    newCurrentAvailStartBits.Add(newValue);
                }

                // construct mtbdds for next operand
                sysDDs2 = EncodeSystemDefRec(sys.GetSystem(i), newCurrentAvailStartBits);

                // move sysDDs (operands composed so far) into sysDDs1
                sysDDs1 = sysDDs;
                // we are going to combine sysDDs1 and sysDDs2 and put the result into sysDDs
                sysDDs = new SystemDDs();

                // combine mtbdds for independent bit
                sysDDs.ind = CombineNonSynchronising(sysDDs1.ind, sysDDs2.ind, sysDDs1.id, sysDDs2.id);

                // combine mtbdds for each synchronising action
                for (j = 0; j < synchs.Count; j++)
                {
                    // do asynchronous parallel composition
                    if ((sysDDs1.allSynchs.Contains(synchs.ElementAt(j)) ? 1 : 0) + (sysDDs2.allSynchs.Contains(synchs.ElementAt(j)) ? 1 : 0) == 1)
                    {
                        sysDDs.synchs.Add(CombineNonSynchronising(sysDDs1.synchs[j], sysDDs2.synchs[j], sysDDs1.id, sysDDs2.id));
                    }
                    else
                    {
                        sysDDs.synchs.Add(CombineSynchronising(sysDDs1.synchs[j], sysDDs2.synchs[j]));
                    }
                }

                // compute identity
                sysDDs.id = CUDD.Function.Times(sysDDs1.id, sysDDs2.id);

                // combine lists of synchs
                sysDDs.allSynchs.UnionWith(sysDDs1.allSynchs);
                sysDDs.allSynchs.UnionWith(sysDDs2.allSynchs);
            }

            return(sysDDs);
        }
コード例 #3
0
        private SystemDDs EncodeParallel(ParallelSystem sys, List <int> currentAvailStartBits)
        {
            SystemDDs   sysDDs1, sysDDs2, sysDDs;
            List <bool> synchBool = new List <bool>();

            for (int i = 0; i < synchs.Count; i++)
            {
                synchBool[i] = sys.ContainsAction(synchs[i]);
            }

            // construct mtbdds for first operand
            sysDDs1 = EncodeSystemDefRec(sys.system1, currentAvailStartBits);

            List <int> newCurrentAvailStartBits = new List <int>();

            for (int i = 0; i < synchs.Count; i++)
            {
                newCurrentAvailStartBits[i] = synchBool[i] ? sysDDs1.synchs[i].max : currentAvailStartBits[i];
            }

            // construct mtbdds for second operand
            sysDDs2 = EncodeSystemDefRec(sys.system2, newCurrentAvailStartBits);

            // create object to store mtbdds
            sysDDs = new SystemDDs();

            // combine mtbdds for independent bit
            sysDDs.ind = CombineNonSynchronising(sysDDs1.ind, sysDDs2.ind, sysDDs1.id, sysDDs2.id);

            // combine mtbdds for each synchronising action
            for (int i = 0; i < synchs.Count; i++)
            {
                if (synchBool[i])
                {
                    sysDDs.synchs.Add(CombineSynchronising(sysDDs1.synchs[i], sysDDs2.synchs[i]));
                }
                else
                {
                    sysDDs.synchs.Add(CombineNonSynchronising(sysDDs1.synchs[i], sysDDs2.synchs[i], sysDDs1.id, sysDDs2.id));
                }
            }

            // combine mtbdds for identity matrices
            sysDDs.id = CUDD.Function.Times(sysDDs1.id, sysDDs2.id);

            // combine lists of synchs
            sysDDs.allSynchs.UnionWith(sysDDs1.allSynchs);
            sysDDs.allSynchs.UnionWith(sysDDs2.allSynchs);

            return(sysDDs);
        }
コード例 #4
0
        private SystemDDs EncodeInterelave(InterleaveSystem system, List <int> currentAvailStartBits)
        {
            SystemDDs sysDDs1, sysDDs2, sysDDs;
            int       i, j;

            // construct mtbdds for first operand
            sysDDs = EncodeSystemDefRec(system.GetSystem(0), currentAvailStartBits);

            // loop through all other operands in the parallel operator
            for (i = 1; i < system.NumberSystem; i++)
            {
                // construct mtbdds for next operand
                sysDDs2 = EncodeSystemDefRec(system.GetSystem(i), currentAvailStartBits);

                // move sysDDs (operands composed so far) into sysDDs1
                sysDDs1 = sysDDs;
                // we are going to combine sysDDs1 and sysDDs2 and put the result into sysDDs
                sysDDs = new SystemDDs();

                // combine mtbdds for independent bit
                sysDDs.ind = CombineNonSynchronising(sysDDs1.ind, sysDDs2.ind, sysDDs1.id, sysDDs2.id);

                // combine mtbdds for each synchronising action
                for (j = 0; j < synchs.Count; j++)
                {
                    sysDDs.synchs.Add(CombineNonSynchronising(sysDDs1.synchs[j], sysDDs2.synchs[j], sysDDs1.id, sysDDs2.id));
                }

                // compute identity
                sysDDs.id = CUDD.Function.Times(sysDDs1.id, sysDDs2.id);

                // combine lists of synchs
                sysDDs.allSynchs.UnionWith(sysDDs1.allSynchs);
                sysDDs.allSynchs.UnionWith(sysDDs2.allSynchs);
            }

            return(sysDDs);
        }
コード例 #5
0
        private void EncodeSystemDef(SystemDef system)
        {
            List <int> currentAvailStartBits = new List <int>();

            for (int i = 0; i < synchs.Count; i++)
            {
                currentAvailStartBits.Add(0);
            }

            SystemDDs sysDDs = EncodeSystemDefRec(system, currentAvailStartBits);


            // for the nondeterministic case, add extra mtbdd variables to encode nondeterminism
            if (modules.modelType == ModelType.MDP)
            {
                int max = sysDDs.ind.max;
                for (int i = 0; i < synchs.Count; i++)
                {
                    if (sysDDs.synchs[i].max > max)
                    {
                        max = sysDDs.synchs[i].max;
                    }
                }

                //update max
                sysDDs.ind.max = max;
                for (int i = 0; i < synchs.Count; i++)
                {
                    sysDDs.synchs[i].max = max;
                }

                //TODO Different from Prism
                // now add in new mtbdd variables to distinguish between actions
                //index 0 for empty label
                CUDDNode tmp = CUDD.Matrix.SetVectorElement(CUDD.Constant(0), allSynchVars, 0, 1);
                sysDDs.ind.trans = CUDD.Function.Times(tmp, sysDDs.ind.trans);

                // synchronous bits
                //1... for other labels
                for (int i = 0; i < synchs.Count; i++)
                {
                    tmp = CUDD.Matrix.SetVectorElement(CUDD.Constant(0), allSynchVars, i + 1, 1);
                    sysDDs.synchs[i].trans = CUDD.Function.Times(tmp, sysDDs.synchs[i].trans);
                }
            }

            ComputeRewards(sysDDs);

            // now, for all model types, transition matrix can be built by summing over all actions
            // also build transition rewards at the same time
            CUDD.Ref(sysDDs.ind.trans);
            trans = sysDDs.ind.trans;

            int numRewardStructs = modules.rewardStructs.Count;

            for (int j = 0; j < numRewardStructs; j++)
            {
                CUDD.Ref(sysDDs.ind.rewards[j]);
                transRewards.Add(sysDDs.ind.rewards[j]);
            }

            for (int i = 0; i < synchs.Count; i++)
            {
                CUDD.Ref(sysDDs.synchs[i].trans);
                trans = CUDD.Function.Plus(trans, sysDDs.synchs[i].trans);

                for (int j = 0; j < numRewardStructs; j++)
                {
                    CUDD.Ref(sysDDs.synchs[i].rewards[j]);
                    transRewards[j] = CUDD.Function.Plus(transRewards[j], sysDDs.synchs[i].rewards[j]);
                }
            }

            // For D/CTMCs, final rewards are scaled by dividing by total prob/rate for each transition
            // (when individual transition rewards are computed, they are multiplied by individual probs/rates).
            // Need to do this (for D/CTMCs) because transition prob/rate can be the sum of values from
            // several different actions; this gives us the "expected" reward for each transition.
            // (Note, for MDPs, nondeterministic choices are always kept separate so this never occurs.)
            if (modules.modelType != ModelType.MDP)
            {
                int numberOfRewardStructs = modules.rewardStructs.Count;
                for (int j = 0; j < numberOfRewardStructs; j++)
                {
                    CUDD.Ref(trans);
                    transRewards[j] = CUDD.Function.Divide(transRewards[j], trans);
                }
            }

            //
            sysDDs.Deref();
        }
コード例 #6
0
        /// <summary>
        /// Calculate state rewards and store in stateRewards
        /// Transition rewards are prepared and stored in sysDDs
        /// </summary>
        /// <param name="sysDDs"></param>
        private void ComputeRewards(SystemDDs sysDDs)
        {
            int numRewardStructs = modules.rewardStructs.Count;

            //Initialize reward of State and the resulted SystemDDs sysDDs
            for (int j = 0; j < numRewardStructs; j++)
            {
                stateRewards.Add(CUDD.Constant(0));

                sysDDs.ind.rewards.Add(CUDD.Constant(0));

                for (int i = 0; i < synchs.Count; i++)
                {
                    sysDDs.synchs[i].rewards.Add(CUDD.Constant(0));
                }
            }

            // for each reward structure...
            for (int j = 0; j < numRewardStructs; j++)
            {
                // get reward struct
                RewardStruct rs = modules.rewardStructs[j];

                // work through list of items in reward struct
                foreach (var rewardItem in rs.items)
                {
                    // translate states predicate and reward expression
                    CUDDNode guard   = EncodeExpression(rewardItem.guard);
                    CUDDNode rewards = EncodeExpression(rewardItem.reward);

                    CUDDNode rewardDD;
                    string   synch = rewardItem.synch;
                    if (synch == null)
                    {
                        // first case: item corresponds to state rewards

                        // restrict rewards to relevant states
                        rewardDD = CUDD.Function.Times(guard, rewards);

                        // check for negative rewards
                        if (CUDD.FindMin(rewardDD) < 0)
                        {
                            throw new Exception("Reward structure item with guard " + rewardItem.guard + " contains negative rewards");
                        }
                        // add to state rewards
                        stateRewards[j] = CUDD.Function.Plus(stateRewards[j], rewardDD);
                    }
                    else
                    {
                        // second case: item corresponds to transition rewards

                        //find the corresponding component to update the reward
                        ComponentDDs compDDs;

                        // work out which (if any) action this is for
                        if (synch == string.Empty)
                        {
                            compDDs = sysDDs.ind;
                        }
                        else if (synchs.Contains(synch))
                        {
                            int k = synchs.IndexOf(synch);
                            compDDs = sysDDs.synchs[k];
                        }
                        else
                        {
                            throw new Exception("Invalid action name \"" + synch + "\" in reward structure item");
                        }


                        // identify corresponding transitions
                        // (for dtmcs/ctmcs, keep actual values - need to weight rewards; for mdps just store 0/1)
                        CUDD.Ref(compDDs.trans);
                        rewardDD = (modules.modelType == ModelType.MDP)? (CUDD.Convert.GreaterThan(compDDs.trans, 0)): compDDs.trans;

                        // restrict to relevant states
                        rewardDD = CUDD.Function.Times(rewardDD, guard);
                        // multiply by reward values
                        rewardDD = CUDD.Function.Times(rewardDD, rewards);

                        // check for negative rewards
                        if (CUDD.FindMin(rewardDD) < 0)
                        {
                            throw new Exception("Reward structure item with guard " + rewardItem.guard + " contains negative rewards");
                        }
                        // add result to rewards
                        compDDs.rewards[j] = CUDD.Function.Plus(compDDs.rewards[j], rewardDD);
                    }
                }
            }
        }