private static void TimeInterruptEncodeTick(string clk, AutomataBDD m0, AutomataBDD m1, int t, Model model, AutomataBDD result) { Expression guard; List <CUDDNode> guardDD; //1. m0.Tick and [(clk >= 0 and clk < t and clk' = clk + 1) or (clk = -1 and clk' = -1)] guard = new PrimitiveApplication(PrimitiveApplication.OR, new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication(PrimitiveApplication.GREATER_EQUAL, new Variable(clk), new IntConstant(0)), new PrimitiveApplication(PrimitiveApplication.LESS, new Variable(clk), new IntConstant(t))), new Assignment(clk, new PrimitiveApplication(PrimitiveApplication.PLUS, new Variable(clk), new IntConstant(1)))), new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(clk), new IntConstant(-1)), new Assignment(clk, new IntConstant(-1)))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = CUDD.Function.And(m0.Ticks, guardDD); result.Ticks.AddRange(guardDD); //2. clk = t + 1 and m1.Tick and clk' = t + 1 guard = new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(clk), new IntConstant(t + 1)), new Assignment(clk, new IntConstant(t + 1))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = CUDD.Function.And(m1.Ticks, guardDD); result.Ticks.AddRange(guardDD); }
/// <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 = new PrimitiveApplication(PrimitiveApplication.AND, automata1.initExpression, automata2.initExpression); Expression initValueOfT = new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(0)); result.initExpression = new PrimitiveApplication(PrimitiveApplication.AND, initTemp, initValueOfT); //Set Acceptance State result.acceptanceExpression = new PrimitiveApplication(PrimitiveApplication.AND, automata1.acceptanceExpression, initValueOfT); //Set Transition //(temp = 0 and automata1.accept) or (temp = 1 and buchi.accept) Expression guard = new PrimitiveApplication(PrimitiveApplication.OR, new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(0)), automata1.acceptanceExpression), new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(newVarName), new IntConstant(1)), automata2.acceptanceExpression)); //guard and (temp' = 1 - temp) Expression transition1Exp = new PrimitiveApplication(PrimitiveApplication.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 = new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication(PrimitiveApplication.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> /// Tau transition ∧ ((temp = -1 and temp' = -1 and other unchanged) or (temp = i and temp' = i) /// (temp = i or temp = -1) and Not Tau Transition ∧ temp' = i; /// If Tau transitions happens first then temp still not initialized. /// After Not Tau Transition happen, then temp is initialize. Later although Tau transition can happen, this selection is not changed. /// [ REFS: 'none', DEREFS: 'choices, tauEvent' ] /// </summary> /// <param name="choices"></param> /// <param name="model"></param> /// <param name="result"></param> private static void ExternalChoiceEncodeTransition(List <AutomataBDD> choices, Model model, AutomataBDD result) { for (int i = 0; i < choices.Count; i++) { //2. (temp = i or temp = -1) and Not Tau Transition ∧ temp' = i Expression guard = new PrimitiveApplication(PrimitiveApplication.OR, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(-1)), new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(i))); guard = new PrimitiveApplication(PrimitiveApplication.AND, guard, new Assignment(result.newLocalVarName, new IntConstant(i))); List <CUDDNode> transition = guard.TranslateBoolExpToBDD(model).GuardDDs; CUDD.Ref(transition); List <CUDDNode> notTauTransition = CUDD.Function.And(transition, CUDD.Function.Not(GetTauTransEncoding(model))); // CUDD.Ref(choices[i].transitionBDD); result.transitionBDD.AddRange(CUDD.Function.And(choices[i].transitionBDD, notTauTransition)); //Channel communication vacuously is not tau transition CUDD.Ref(transition); result.channelInTransitionBDD.AddRange(CUDD.Function.And(choices[i].channelInTransitionBDD, transition)); result.channelOutTransitionBDD.AddRange(CUDD.Function.And(choices[i].channelOutTransitionBDD, transition)); //1. Tau transition ∧ ((temp = -1 and temp' = -1 and other unchanged) or (temp = i and temp' = i) guard = new PrimitiveApplication(PrimitiveApplication.OR, new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(-1)), new Assignment(result.newLocalVarName, new IntConstant(-1))), new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(i)), new Assignment(result.newLocalVarName, new IntConstant(-1)))); transition = guard.TranslateBoolExpToBDD(model).GuardDDs; List <CUDDNode> tauTransition = CUDD.Function.And(choices[i].transitionBDD, GetTauTransEncoding(model)); transition = CUDD.Function.And(transition, tauTransition); //already includes temp List <int> unchangedVariableIndex = new List <int>(result.variableIndex); foreach (int index in choices[i].variableIndex) { unchangedVariableIndex.Remove(index); } model.AddVarUnchangedConstraint(transition, unchangedVariableIndex); result.transitionBDD.AddRange(transition); } }
public void Test1Test() { var sb = new StringBuilder(); string varX = "x"; string varY = "y"; //Set number of action names, 2 for a, b Model.NUMBER_OF_EVENT = 3; Model.MAX_NUMBER_EVENT_PARAMETERS = 0; BDDEncoder encoder = new BDDEncoder(); encoder.model.AddGlobalVar(varX, 0, 10); encoder.model.AddGlobalVar(varY, 0, 10); SymbolicLTS lts = new SymbolicLTS(); State state1 = lts.AddState(); State state2 = lts.AddState(); State state3 = lts.AddState(); State state4 = lts.AddState(); lts.InitialState = state1; var primitiveApplication1 = new Assignment(varX, new PrimitiveApplication(PrimitiveApplication.PLUS, new Variable(varX), new IntConstant(1))); var primitiveApplication2 = new Assignment(varY, new PrimitiveApplication(PrimitiveApplication.PLUS, new Variable(varY), new IntConstant(4))); /* * * for (int i = 0; i < exps.Count; i++) * { * //Update eventParameterVariables[i] = exps[i] * //Don't need to update exps because later after synchronization, not updated variable keeps the same value * update = new Sequence(update, new Assignment(model.eventParameterVariables[i], exps[i])); * } */ var primitiveApplication = new Sequence(primitiveApplication1, primitiveApplication2); /*PrimitiveApplication.CombineProgramBlock( * primitiveApplication1, * primitiveApplication2);*/ logger.Info(primitiveApplication); Transition trans1 = new Transition(new Event("a"), null, primitiveApplication, state1, state2); Expression assignment = new Assignment(varX, new PrimitiveApplication(PrimitiveApplication.PLUS, new Variable(varX), new IntConstant(2))); logger.Info("Assignments: " + assignment); var secAssignment = new Assignment(varY, new PrimitiveApplication(PrimitiveApplication.PLUS, new Variable(varY), new WildConstant())); Transition trans2 = new Transition(new Event("b"), null, primitiveApplication, state2, state3); Transition trans3 = new Transition(new Event("c"), null, primitiveApplication, state3, state4); lts.AddTransition(trans1); lts.AddTransition(trans2); lts.AddTransition(trans3); AutomataBDD systemBDD = lts.Encode(encoder); //Variable x is initialised to 1 systemBDD.initExpression = new PrimitiveApplication(PrimitiveApplication.AND, systemBDD.initExpression, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(varX), new IntConstant(1))); systemBDD.initExpression = new PrimitiveApplication(PrimitiveApplication.AND, systemBDD.initExpression, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(varY), new IntConstant(1))); CUDDNode initDD = CUDD.Function.Or(systemBDD.initExpression.TranslateBoolExpToBDD(encoder.model).GuardDDs); logger.Info("init: " + systemBDD.initExpression); var u = 1; for (; u < 2; u++) { logger.Info($"U is {u}"); //Define 2 goals Expression goal1 = new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(varX), new IntConstant(3)); goal1 = new PrimitiveApplication(PrimitiveApplication.AND, goal1, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(varY), new IntConstant(9))); //Encode 2 goals to BDD CUDDNode goal1DD = CUDD.Function.Or(goal1.TranslateBoolExpToBDD(encoder.model).GuardDDs); logger.Info("Goal: " + goal1); List <CUDDNode> path = new List <CUDDNode>(); bool reach1 = encoder.model.PathForward(initDD, goal1DD, new List <List <CUDDNode> >() { systemBDD.transitionBDD }, path, true); if (reach1) { sb.AppendLine("goal1 is reachable"); foreach (var cuddNode in path) { encoder.model.PrintAllVariableValue(cuddNode); logger.Info("after"); CUDD.Print.PrintMinterm(cuddNode); // CUDD.Print.PrintBDDTree(path); int valueOfX = encoder.model.GetRowVarValue(cuddNode, varX); sb.AppendLine(varX + " = " + valueOfX); int valueOfY = encoder.model.GetRowVarValue(cuddNode, varY); sb.AppendLine(varY + " = " + valueOfY); } } else { sb.AppendLine("goal1 is unreachable"); } path.Clear(); } /* * bool reach2 = encoder.model.PathForward(initDD, goal2DD, new List<List<CUDDNode>>() { systemBDD.transitionBDD }, path, true); * if (reach2) * { * sb.AppendLine("goal2 is reachable"); * foreach (var cuddNode in path) * { * int valueOfX = encoder.model.GetRowVarValue(cuddNode, varX); * sb.AppendLine(varX + " = " + valueOfX); * } * } * else * { * sb.AppendLine("goal2 is unreachable"); * } */ logger.Info(sb); encoder.model.Close(); }