Пример #1
0
        /// <summary>
        /// Return a computation of a buchi automata in form "prefix (period)*"
        /// [ REFS: 'prefix, period', DEREFS:]
        /// </summary>
        /// <param name="automataBDD"></param>
        /// <param name="model"></param>
        public void MC(AutomataBDD automataBDD, Model model)
        {
            //Clear the old data
            this.transitionsNoEvents.Clear();
            this.prefix.Clear();
            this.period.Clear();

            ExpressionBDDEncoding initEncoding = automataBDD.initExpression.TranslateBoolExpToBDD(model);

            if (initEncoding.GuardDDs.Count == 0)
            {
                return;
            }

            ExpressionBDDEncoding finalStateEncoding = automataBDD.acceptanceExpression.TranslateBoolExpToBDD(model);
            if (finalStateEncoding.GuardDDs.Count == 0)
            {
                return;
            }

            CUDDNode initState = CUDD.Function.Or(initEncoding.GuardDDs);
            CUDDNode finalState = CUDD.Function.Or(finalStateEncoding.GuardDDs);
            CUDDNode finalStateWithNoEvent = CUDD.Abstract.ThereExists(finalState, model.GetAllEventVars());

            CUDD.Ref(automataBDD.transitionBDD);
            this.transitionsNoEvents = CUDD.Abstract.ThereExists(automataBDD.transitionBDD, model.GetAllEventVars());

            CUDDNode allSCCs = SCCHull(model, initState, finalStateWithNoEvent);

            if (!allSCCs.Equals(CUDD.ZERO) && VerificationOutput.GenerateCounterExample)
            {
                this.VerificationOutput.VerificationResult = VerificationResultType.INVALID;

                //Transitions out from allSCCs
                CUDD.Ref(transitionsNoEvents);
                CUDD.Ref(allSCCs);
                List<CUDDNode> R = CUDD.Function.And(transitionsNoEvents, allSCCs);

                //pick one state from the set final
                CUDD.Ref(allSCCs);
                CUDDNode s = CUDD.RestrictToFirst(allSCCs, model.AllRowVars);

                //while the states from which we can reach s are not all states that can be reached from s
                CUDDNode scc;
                while (true)
                {
                    CUDD.Ref(s);
                    CUDDNode backwardOfS = model.PredecessorsStart(s, R);

                    CUDD.Ref(s);
                    CUDDNode forwardOfS = model.SuccessorsStart(s, R);

                    //
                    CUDD.Ref(backwardOfS, forwardOfS);
                    CUDDNode temp = CUDD.Function.Different(backwardOfS, forwardOfS);
                    if (temp.Equals(CUDD.ZERO))
                    {
                        scc = backwardOfS;
                        CUDD.Deref(forwardOfS, temp);
                        break;
                    }
                    else
                    {
                        CUDD.Deref(backwardOfS, forwardOfS, s);
                        s = CUDD.RestrictToFirst(temp, model.AllRowVars);
                    }
                }

                //R now contains only transitions within the SCC scc
                CUDD.Ref(scc, scc, scc, scc);
                R[0] = CUDD.Function.And(CUDD.Function.And(R[0], scc), model.SwapRowColVars(scc));
                R[1] = CUDD.Function.And(CUDD.Function.And(R[1], scc), model.SwapRowColVars(scc));

                CUDD.Ref(scc);
                CUDDNode notInSCC = CUDD.Function.Not(scc);

                List<CUDDNode> transitionNotInSCC = new List<CUDDNode>();

                CUDD.Ref(transitionsNoEvents, transitionsNoEvents);
                CUDD.Ref(notInSCC, notInSCC);
                transitionNotInSCC.AddRange(CUDD.Function.And(transitionsNoEvents, notInSCC));
                transitionNotInSCC.AddRange(CUDD.Function.And(transitionsNoEvents, model.SwapRowColVars(notInSCC)));

                //prefix is now a shortest path from an initial state to a state in final
                model.Path(initState, scc, transitionNotInSCC, prefix, true);
                CUDD.Deref(transitionNotInSCC[0], transitionNotInSCC[1]);

                //Dummy value
                period.Add((prefix.Count == 0) ? initState : prefix[prefix.Count - 1]);

                //cycle must pass final state
                CUDD.Ref(period);
                CUDD.Ref(finalStateWithNoEvent);
                CUDDNode temp1 = CUDD.Function.And(CUDD.Function.Or(period), finalStateWithNoEvent);
                if (temp1.Equals(CUDD.ZERO))
                {
                    CUDD.Ref(scc, finalStateWithNoEvent);
                    CUDDNode acceptanceStateInCyle = CUDD.Function.And(scc, finalStateWithNoEvent);
                    model.Path(period[period.Count - 1], acceptanceStateInCyle, R, period, true);

                    CUDD.Deref(acceptanceStateInCyle);
                }
                CUDD.Deref(temp1);

                //
                bool isEmptyPathAllowed = period.Count != 1;
                model.Path(period[period.Count - 1], period[0], R, period, isEmptyPathAllowed);

                //Remove dummy
                CUDD.Deref(period[0]); period.RemoveAt(0);

                //
                CUDD.Deref(initState, finalStateWithNoEvent, allSCCs, s, scc, notInSCC);
                CUDD.Deref(transitionsNoEvents[0], transitionsNoEvents[1]);
                CUDD.Deref(R[0], R[1]);

            }
            else
            {
                this.VerificationOutput.VerificationResult = VerificationResultType.VALID;
                CUDD.Deref(initState, finalStateWithNoEvent, allSCCs);
                CUDD.Deref(transitionsNoEvents[0], transitionsNoEvents[1]);
            }
        }