/// <summary> /// P.var : P1.var /// </summary> private static void GuardSetVariable(AutomataBDD P1, Model model, AutomataBDD result) { result.variableIndex.AddRange(P1.variableIndex); result.newLocalVarName = Model.GetNewTempVarName(); model.AddLocalVar(result.newLocalVarName, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); }
/// <summary> /// P.var : P1.var ∪ {temp} /// </summary> private static void EventPrefixSetVariable(AutomataBDD P1, Model model, AutomataBDD result) { result.variableIndex.AddRange(P1.variableIndex); result.newLocalVarName = Model.GetNewTempVarName(); model.AddLocalVar(result.newLocalVarName, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); }
/// <summary> /// P.var : [∪ {i = 1..n}Pi.var] ∪ {temp} /// </summary> private static void InternalChoiceSetVariable(List <AutomataBDD> choices, Model model, AutomataBDD result) { foreach (AutomataBDD choice in choices) { result.variableIndex.AddRange(choice.variableIndex); } result.newLocalVarName = Model.GetNewTempVarName(); model.AddLocalVar(result.newLocalVarName, -1, choices.Count - 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); }
private static void ChannelInputSetVariable(List<Expression> exps, AutomataBDD P1, Model model, AutomataBDD result) { //Add new variable used in channel input foreach (var expression in exps) { if (!(expression is IntConstant) && !model.ContainsVar(expression.ExpressionID)) { model.AddLocalVar(expression.ExpressionID, Model.MIN_ELEMENT_BUFFER, Model.MAX_ELEMENT_BUFFER); result.variableIndex.Add(model.GetNumberOfVars() - 1); } } EventPrefixSetVariable(P1, model, result); }
private static void ChannelInputSetVariable(List <Expression> exps, AutomataBDD P1, Model model, AutomataBDD result) { //Add new variable used in channel input foreach (var expression in exps) { if (!(expression is IntConstant) && !model.ContainsVar(expression.ExpressionID)) { model.AddLocalVar(expression.ExpressionID, Model.MIN_ELEMENT_BUFFER, Model.MAX_ELEMENT_BUFFER); result.variableIndex.Add(model.GetNumberOfVars() - 1); } } EventPrefixSetVariable(P1, model, result); }
/// <summary> /// P.var : P1.var ∪ P2.var ∪{isP1Terminate} /// </summary> public static List <string> SequenceSetVariable(AutomataBDD P1, AutomataBDD P2, Model model, AutomataBDD result) { // result.variableIndex.AddRange(P1.variableIndex); result.variableIndex.AddRange(P2.variableIndex); string isP1Terminate = Model.GetNewTempVarName(); model.AddLocalVar(isP1Terminate, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); return(new List <string>() { isP1Terminate }); }
/// <summary> /// Find the deadlock state. This state can be reached by a terminate event. /// Later termination transition is removed from the transition to finding path /// [ REFS: , DEREFS: ] /// </summary> /// <param name="transitions"></param> /// <param name="model"></param> /// <returns></returns> public static CUDDNode GetDeadlockDD(List<CUDDNode> transitions, Model model) { CUDDNode result = CUDD.Constant(1); //result contains state not having not tick outgoing transition foreach (CUDDNode transition in transitions) { CUDD.Ref(transition); CUDDNode notTickTrans = CUDD.Function.And(transition, CUDD.Function.Not(TimeBehaviors.GetTickTransEncoding(model))); //having not tick outgoing transition CUDDNode notDeadlockState = CUDD.Abstract.ThereExists(notTickTrans, model.AllColVars); CUDDNode deadlockState = CUDD.Function.Not(notDeadlockState); result = CUDD.Function.And(result, deadlockState); } CUDD.Ref(transitions); List<CUDDNode> tickTrans = CUDD.Function.And(transitions, TimeBehaviors.GetTickTransEncoding(model)); CUDD.Ref(tickTrans); CUDDNode stateHasTickTrans = CUDD.Function.Or(CUDD.Abstract.ThereExists(tickTrans, model.AllColVars)); List<int> eventIndex = model.GetEventIndex(); for (int i = 0; i < model.GetNumberOfVars(); i++) { if(!eventIndex.Contains(i)) { CUDD.Ref(model.varIdentities[i]); tickTrans = CUDD.Function.And(tickTrans, model.varIdentities[i]); } } CUDDNode stateHasLoopTick = CUDD.Function.Or(CUDD.Abstract.ThereExists(tickTrans, model.AllColVars)); //Deadlock state: not having not tick transition and if has tick, then it must loop tick CUDD.Ref(result); result = CUDD.Function.Or(CUDD.Function.And(result, CUDD.Function.Not(stateHasTickTrans)), CUDD.Function.And(result, stateHasLoopTick)); return result; }
/// <summary> /// General algorithm of the intersection of 2 automata /// Follow the algorithm in Linear Temporal Logic Symbolic Model Checking at http://ti.arc.nasa.gov/m/profile/kyrozier/papers/COSREV_62.pdf page 23 /// [ REFS: 'result', DEREFS:'automata1, automata2' ] /// </summary> /// <param name="automata1"></param> /// <param name="automata2"></param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD IntersectionGeneralAutomata(AutomataBDD automata1, AutomataBDD automata2, Model model) { //AddIdleTransAtDeadlockStates(automata1, model); AutomataBDD result = new AutomataBDD(); string newVarName = Model.GetNewTempVarName(); //Set var result.variableIndex.AddRange(automata1.variableIndex); result.variableIndex.AddRange(automata2.variableIndex); model.AddLocalVar(newVarName, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); //Set Init Expression initTemp = Expression.AND(automata1.initExpression, automata2.initExpression); Expression initValueOfT = Expression.EQ(new Variable(newVarName), new IntConstant(0)); result.initExpression = Expression.AND(initTemp, initValueOfT); //Set Acceptance State result.acceptanceExpression = Expression.AND(automata1.acceptanceExpression, initValueOfT); //Set Transition //(temp = 0 and automata1.accept) or (temp = 1 and buchi.accept) Expression guard = Expression.OR( Expression.AND( new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(0)), automata1.acceptanceExpression), Expression.AND( new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(1)), automata2.acceptanceExpression)); //guard and (temp' = 1 - temp) Expression transition1Exp = Expression.AND(guard, new Assignment(newVarName, new PrimitiveApplication( PrimitiveApplication.MINUS, new IntConstant(1), new Variable(newVarName)))); List <CUDDNode> transition1 = transition1Exp.TranslateBoolExpToBDD(model).GuardDDs; //!guard and (temp' = temp) Expression transition2Exp = Expression.AND( Expression.NOT(guard), new Assignment(newVarName, new Variable(newVarName))); List <CUDDNode> transition2 = transition2Exp.TranslateBoolExpToBDD(model).GuardDDs; //transition must happen at both automata1 + negation LTL List <CUDDNode> bothTransition = CUDD.Function.And(automata1.transitionBDD, automata2.transitionBDD); CUDD.Ref(bothTransition); transition1 = CUDD.Function.And(transition1, bothTransition); result.transitionBDD.AddRange(transition1); transition2 = CUDD.Function.And(transition2, bothTransition); result.transitionBDD.AddRange(transition2); // CUDD.Deref(automata1.channelInTransitionBDD, automata1.channelOutTransitionBDD, automata2.channelInTransitionBDD, automata2.channelOutTransitionBDD); return(result); }
/// <summary> /// P.var : m0 ∪ m1 ∪ {clk} /// </summary> private static List<string> TimeInterruptSetVariable(AutomataBDD m0, AutomataBDD m1, int t, Model model, AutomataBDD result) { result.variableIndex.AddRange(m0.variableIndex); result.variableIndex.AddRange(m1.variableIndex); // string clk = Model.GetNewTempVarName(); model.AddLocalVar(clk, -1, t + 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); return new List<string>() { clk }; }
/// <summary> /// P.var = {temp} /// </summary> private static void SkipSetVariable(Model model, AutomataBDD result) { result.newLocalVarName = Model.GetNewTempVarName(); model.AddLocalVar(result.newLocalVarName, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); }
/// <summary> /// General algorithm of the intersection of 2 automata /// Follow the algorithm in Linear Temporal Logic Symbolic Model Checking at http://ti.arc.nasa.gov/m/profile/kyrozier/papers/COSREV_62.pdf page 23 /// [ REFS: 'result', DEREFS:'automata1, automata2' ] /// </summary> /// <param name="automata1"></param> /// <param name="automata2"></param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD IntersectionGeneralAutomata(AutomataBDD automata1, AutomataBDD automata2, Model model) { //AddIdleTransAtDeadlockStates(automata1, model); AutomataBDD result = new AutomataBDD(); string newVarName = Model.GetNewTempVarName(); //Set var result.variableIndex.AddRange(automata1.variableIndex); result.variableIndex.AddRange(automata2.variableIndex); model.AddLocalVar(newVarName, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); //Set Init Expression initTemp = Expression.AND(automata1.initExpression, automata2.initExpression); Expression initValueOfT = Expression.EQ(new Variable(newVarName), new IntConstant(0)); result.initExpression = Expression.AND(initTemp, initValueOfT); //Set Acceptance State result.acceptanceExpression = Expression.AND(automata1.acceptanceExpression, initValueOfT); //Set Transition //(temp = 0 and automata1.accept) or (temp = 1 and buchi.accept) Expression guard = Expression.OR( Expression.AND( new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(0)), automata1.acceptanceExpression), Expression.AND( new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(1)), automata2.acceptanceExpression)); //guard and (temp' = 1 - temp) Expression transition1Exp = Expression.AND(guard, new Assignment(newVarName, new PrimitiveApplication( PrimitiveApplication.MINUS, new IntConstant(1), new Variable(newVarName)))); List<CUDDNode> transition1 = transition1Exp.TranslateBoolExpToBDD(model).GuardDDs; //!guard and (temp' = temp) Expression transition2Exp = Expression.AND( Expression.NOT(guard), new Assignment(newVarName, new Variable(newVarName))); List<CUDDNode> transition2 = transition2Exp.TranslateBoolExpToBDD(model).GuardDDs; //transition must happen at both automata1 + negation LTL List<CUDDNode> bothTransition = CUDD.Function.And(automata1.transitionBDD, automata2.transitionBDD); CUDD.Ref(bothTransition); transition1 = CUDD.Function.And(transition1, bothTransition); result.transitionBDD.AddRange(transition1); transition2 = CUDD.Function.And(transition2, bothTransition); result.transitionBDD.AddRange(transition2); // CUDD.Deref(automata1.channelInTransitionBDD, automata1.channelOutTransitionBDD, automata2.channelInTransitionBDD, automata2.channelOutTransitionBDD); return result; }
/// <summary> /// P.var : P1.var ∪ P2.var ∪{isP1Terminate} /// </summary> public static List<string> SequenceSetVariable(AutomataBDD P1, AutomataBDD P2, Model model, AutomataBDD result) { // result.variableIndex.AddRange(P1.variableIndex); result.variableIndex.AddRange(P2.variableIndex); string isP1Terminate = Model.GetNewTempVarName(); model.AddLocalVar(isP1Terminate, 0, 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); return new List<string>() { isP1Terminate }; }
/// <summary> /// P.var : [∪ {i = 1..n}Pi.var] ∪ {temp} /// </summary> private static void ExternalChoiceSetVariable(List<AutomataBDD> choices, Model model, AutomataBDD result) { foreach (AutomataBDD choice in choices) { result.variableIndex.AddRange(choice.variableIndex); } result.newLocalVarName = Model.GetNewTempVarName(); model.AddLocalVar(result.newLocalVarName, -1, choices.Count - 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); }
/// <summary> /// P.var : 0 <= state <= t + 1 /// </summary> /// <param name="t"></param> /// <param name="model"></param> /// <param name="result"></param> /// <returns></returns> private static List<string> WaitSetVariable(int t, Model model, AutomataBDD result) { string state = Model.GetNewTempVarName(); model.AddLocalVar(state, 0, t + 1); result.variableIndex.Add(model.GetNumberOfVars() - 1); return new List<string>() { state }; }