/// <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 : [∪ {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); }
public AutomataBDD EncodeBA(BuchiAutomata buchi) { // string processVariableName = Model.GetNewTempVarName(); this.model.AddLocalVar(processVariableName, 0, buchi.States.Length - 1); // this.stateIndexOfCurrentProcess = new Dictionary <string, int>(); //collect the state index foreach (string state in buchi.States) { this.stateIndexOfCurrentProcess.Add(state, this.stateIndexOfCurrentProcess.Count); } AutomataBDD processAutomataBDD = new AutomataBDD(); //Set variable processAutomataBDD.variableIndex.Add(this.model.GetVarIndex(processVariableName)); //Set initial expression processAutomataBDD.initExpression = new BoolConstant(false); foreach (string initState in buchi.InitialStates) { processAutomataBDD.initExpression = Expression.OR(processAutomataBDD.initExpression, Expression.EQ(new Variable(processVariableName), new IntConstant(this.stateIndexOfCurrentProcess[initState]))); } //set acceptance expression processAutomataBDD.acceptanceExpression = new BoolConstant(false); foreach (string state in buchi.States) { if (state.EndsWith(Constants.ACCEPT_STATE)) { processAutomataBDD.acceptanceExpression = Expression.OR(processAutomataBDD.acceptanceExpression, Expression.EQ(new Variable(processVariableName), new IntConstant(this.stateIndexOfCurrentProcess[state]))); } } //Encode transition foreach (BA.Transition transition in buchi.Transitions) { List <CUDDNode> transitionBDDs = this.EncodeTransitionBA(transition, buchi.DeclarationDatabase, processVariableName); processAutomataBDD.transitionBDD.AddRange(transitionBDDs); } // return(processAutomataBDD); }
/// <summary> /// Add local variable including state, and parameters /// Return the variable name encoding states /// </summary> /// <param name="encoder"></param> public string AddLocalVariables(BDDEncoder encoder) { RenameLocalVars(); for (int i = 0; i < this.Parameters.Count; i++) { string parameter = this.Parameters[i]; int min = 0; int max = 0; if (ParameterUpperBound.ContainsKey(parameter) && ParameterLowerBound.ContainsKey(parameter)) { min = ParameterLowerBound[parameter]; max = ParameterUpperBound[parameter]; } else { if (this.Arguments[i] is IntConstant) { IntConstant tempExp = (IntConstant)this.Arguments[i]; min = tempExp.Value; max = tempExp.Value; } else { throw new Exception("Symbolic Model Checking only support constant parameters!"); } } //In its old transition encoding, we don't make sure this variable must be unchanged. //We also need to add this variable to VaribleIndex of the AutomataBDD because previous process does not know this variable //if global then later processes will set this variable as unchange. encoder.model.AddLocalVar(parameter, min, max); } const string STATE = "state"; // string processVariableName = Name + Model.NAME_SEPERATOR + STATE + Model.GetNewTempVarName(); encoder.model.AddLocalVar(processVariableName, 0, this.States.Count - 1); // encoder.stateIndexOfCurrentProcess = new Dictionary <string, int>(); //collect the state index foreach (State state in this.States) { encoder.stateIndexOfCurrentProcess.Add(state.ID, encoder.stateIndexOfCurrentProcess.Count); } return(processVariableName); }
/// <summary> /// Return the AutomataBDD of the Sync Channel Input. Encode this as event c!a.b.c and put it to ChannelIOutTransition /// </summary> /// <param name="channelEventIndex"></param> /// <param name="exps">List of output expressions of the channel</param> /// <param name="P1">AutomataBDD of process P1 after the channel input</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD SyncChannelOutputPrefixing(int channelEventIndex, List <Expression> exps, AutomataBDD P1, Model model) { AutomataBDD result = new AutomataBDD(); result.newLocalVarName = Model.GetNewTempVarName(); EventPrefixSetVariable(P1, model, result); EventPrefixSetInit(result); SyncChannelOutputEncodeTransition(channelEventIndex, exps, P1, model, result); // return(result); }
/// <summary> /// Rename local variable to be unique /// </summary> /// <returns></returns> private void RenameLocalVars() { if (Parameters.Count == 0) { return; } //Rename parameter to be unique Dictionary <string, Expression> newLocalVariableNameMapping = new Dictionary <string, Expression>(); List <string> parameters = new List <string>(); Dictionary <string, int> parameterUpper = new Dictionary <string, int>(this.ParameterUpperBound); Dictionary <string, int> parameterLower = new Dictionary <string, int>(this.ParameterLowerBound); // foreach (string para in this.Parameters) { //Just build the unique name string newName = para + Model.GetNewTempVarName(); //Update ParameterLowerBound, ParameterUpperBound if (parameterUpper.ContainsKey(para)) { parameterUpper.Add(newName, ParameterUpperBound[para]); } if (parameterLower.ContainsKey(para)) { parameterLower.Add(newName, ParameterLowerBound[para]); } // newLocalVariableNameMapping.Add(para, new Variable(newName)); parameters.Add(newName); } List <Transition> newTransition = new List <Transition>(); for (int i = 0; i < Transitions.Count; i++) { newTransition.AddRange(Transitions[i].ClearConstantExtended(States, newLocalVariableNameMapping)); } this.Parameters = parameters; this.ParameterUpperBound = parameterUpper; this.ParameterLowerBound = parameterLower; this.SetTransitions(newTransition); }
/// <summary> /// Add local variable including state, and parameters /// Return the variable name encoding states /// </summary> /// <param name="encoder"></param> public string AddLocalVariables(BDDEncoder encoder) { RenameLocalVars(); for (int i = 0; i < this.Parameters.Count; i++) { string parameter = this.Parameters[i]; int min = Model.BDD_INT_UPPER_BOUND; int max = Model.BDD_INT_LOWER_BOUND; if (ParameterUpperBound.ContainsKey(parameter) && ParameterLowerBound.ContainsKey(parameter)) { min = ParameterLowerBound[parameter]; max = ParameterUpperBound[parameter]; } else { ExpressionBDDEncoding argumentBDD = this.Arguments[i].TranslateIntExpToBDD(encoder.model); foreach (CUDDNode argExp in argumentBDD.ExpressionDDs) { min = Math.Min(min, (int)CUDD.FindMinThreshold(argExp, Model.BDD_INT_LOWER_BOUND)); max = Math.Max(max, (int)CUDD.FindMaxThreshold(argExp, Model.BDD_INT_UPPER_BOUND)); } } //In its old transition encoding, we don't make sure this variable must be unchanged. //We also need to add this variable to VaribleIndex of the AutomataBDD because previous process does not know this variable //if global then later processes will set this variable as unchange. encoder.model.AddLocalVar(parameter, min, max); } const string STATE = "state"; // string processVariableName = Name + Model.NAME_SEPERATOR + STATE + Model.GetNewTempVarName(); encoder.model.AddLocalVar(processVariableName, 0, this.States.Count - 1); // encoder.stateIndexOfCurrentProcess = new Dictionary <string, int>(); //collect the state index foreach (State state in this.States) { encoder.stateIndexOfCurrentProcess.Add(state.Name, encoder.stateIndexOfCurrentProcess.Count); } return(processVariableName); }
/// <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> /// 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 = {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); }