/// <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]); } }
/// <summary> /// [ REFS: traces, DEREFS: ] /// </summary> /// <param name="automataBDD"></param> /// <param name="model"></param> public void MC(AutomataBDD automataBDD, Model model) { //Clear the old data this.traces.Clear(); List<CUDDNode> allTransitions = new List<CUDDNode>(automataBDD.transitionBDD); CUDDNode deadlockGoadDD = GetDeadlockDD(allTransitions, model); ExpressionBDDEncoding initEncoding = automataBDD.initExpression.TranslateBoolExpToBDD(model); if (initEncoding.GuardDDs.Count == 0) { this.VerificationOutput.VerificationResult = VerificationResultType.VALID; } else { CUDD.Ref(automataBDD.transitionBDD); List<CUDDNode> notTerminateNoEventTrans = CUDD.Function.And(automataBDD.transitionBDD, CUDD.Function.Not(AutomataBDD.GetTerminationTransEncoding(model))); notTerminateNoEventTrans = CUDD.Abstract.ThereExists(notTerminateNoEventTrans, model.GetAllEventVars()); bool reachable = model.Path(CUDD.Function.Or(initEncoding.GuardDDs), deadlockGoadDD, notTerminateNoEventTrans, traces, SelectedEngineName, VerificationOutput.GenerateCounterExample); CUDD.Deref(notTerminateNoEventTrans); this.VerificationOutput.VerificationResult = (reachable) ? VerificationResultType.INVALID : VerificationResultType.VALID; } }
/// <summary> /// Check whethere the goal can be reachable from the initial state of automataBDD /// [ REFS: traces, DEREFS: ] /// </summary> /// <param name="automataBDD"></param> /// <param name="goal"></param> /// <param name="model"></param> public void MC(AutomataBDD automataBDD, Expression goal, Model model) { //Clear the old data this.traces.Clear(); ExpressionBDDEncoding goalBddEncoding = goal.TranslateBoolExpToBDD(model); ExpressionBDDEncoding initEncoding = automataBDD.initExpression.TranslateBoolExpToBDD(model); if (initEncoding.GuardDDs.Count == 0) { VerificationOutput.VerificationResult = VerificationResultType.INVALID; } else { CUDDNode initDD = CUDD.Function.Or(initEncoding.GuardDDs); CUDDNode goalDD = CUDD.Function.Or(goalBddEncoding.GuardDDs); CUDD.Ref(automataBDD.transitionBDD); List<CUDDNode> noEventTrans = CUDD.Abstract.ThereExists(automataBDD.transitionBDD, model.GetAllEventVars()); bool reachable = model.Path(initDD, goalDD, noEventTrans, traces, SelectedEngineName, VerificationOutput.GenerateCounterExample); CUDD.Deref(noEventTrans); // CUDD.Deref(initDD, goalDD); VerificationOutput.VerificationResult = (reachable) ? VerificationResultType.VALID : VerificationResultType.INVALID; } }