/// <summary> /// Return AutomataBDD of the guard process /// </summary> /// <param name="guard">The guard expression of the process P1</param> /// <param name="P1">AutomataBDD of the process P1</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Guard(Expression guard, AutomataBDD P1, Model model) { AutomataBDD result = AutomataBDD.Guard(guard, P1, model); GuardEncodeTick(guard, P1, model, result); // return result; }
/// <summary> /// Return the intersection of model and negation of LTL /// Note that all of the state of model are the accepting state /// [ REFS: 'result', DEREFS:'automata1, automata2' ] /// </summary> /// <param name="system"></param> /// <param name="negationLTL"></param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Intersection(AutomataBDD system, AutomataBDD negationLTL, Model model) { //AddIdleTransAtDeadlockStates(system, model); AutomataBDD result = new AutomataBDD(); //Set var result.variableIndex.AddRange(system.variableIndex); result.variableIndex.AddRange(negationLTL.variableIndex); //Set Init result.initExpression = Expression.AND(system.initExpression, negationLTL.initExpression); //Set Acceptance State result.acceptanceExpression = negationLTL.acceptanceExpression; //Set Transition //transition must happen at both automata1 + negation LTL result.transitionBDD = CUDD.Function.And(system.transitionBDD, negationLTL.transitionBDD); // CUDD.Deref(system.channelInTransitionBDD, system.channelOutTransitionBDD, negationLTL.channelInTransitionBDD, negationLTL.channelOutTransitionBDD); return result; }
/// <summary> /// Tick transition if done is false, don't need to add unchanged condition of other local variables. /// They will be updated after the event becomes true /// use the tick transition of P1 if done is true /// </summary> /// <param name="P1"></param> /// <param name="model"></param> /// <param name="result"></param> private static void EventPrefixEncodeTick(Expression guardOfTick, AutomataBDD P1, Model model, AutomataBDD result) { Expression guard; List<CUDDNode> guardDD; //1. !done and guardOfTick and event = tick and !done' if (!(guardOfTick is BoolConstant && !(guardOfTick as BoolConstant).Value)) { guard = Expression.AND( Expression.EQ( new Variable(result.newLocalVarName), new IntConstant(0)), Expression.AND( guardOfTick, new PrimitiveApplication( PrimitiveApplication.AND, AutomataBDD. GetTerminateTransExpression (), new Assignment( result.newLocalVarName, new IntConstant(0))))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = model.AddVarUnchangedConstraint(guardDD, model.GlobalVarIndex); result.Ticks.AddRange(guardDD); } //2. done and p1.Tick and done' guard = Expression.AND(Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(1)), new Assignment(result.newLocalVarName, new IntConstant(0))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = CUDD.Function.And(guardDD, P1.Ticks); result.Ticks.AddRange(guardDD); }
/// <summary> /// Return AutomataBDD of the Skip process /// </summary> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Skip(Model model) { AutomataBDD result = AutomataBDD.Skip(model); SkipEncodeTick(model, result); // return result; }
//public override string GetID() //{ // return Value.ToString(); //} /// <summary> /// Return the encoding of the integer value /// </summary> public override ExpressionBDDEncoding TranslateIntExpToBDD(Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); result.GuardDDs.Add(CUDD.Constant(1)); result.ExpressionDDs.Add(CUDD.Constant(Value)); return result; }
private static void WithinEncodeTransitionChannel(string clk, AutomataBDD m0, int t, Model model, AutomataBDD result) { Expression guard; List<CUDDNode> guardDD, transTemp; //1. (clk <= t) and m0.Trans/In/Out and [(event' = tau and clk' = clk) or (event' != tau and clk' = -1)] guard = Expression.AND(Expression.LE(new Variable(clk), new IntConstant(t)), Expression.OR(Expression.AND( AutomataBDD.GetTauTransExpression(), new Assignment(clk, new Variable(clk))), Expression.AND( AutomataBDD.GetNotTauTransExpression(), new Assignment(clk, new IntConstant(-1))))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m0.transitionBDD, guardDD); result.transitionBDD.AddRange(transTemp); // CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m0.channelInTransitionBDD, guardDD); result.channelInTransitionBDD.AddRange(transTemp); // //CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m0.channelOutTransitionBDD, guardDD); result.channelOutTransitionBDD.AddRange(transTemp); }
/// <summary> /// [ REFS: 'result', DEREFS: 'resultBefore' ] /// </summary> public override ExpressionBDDEncoding TranslateStatementToBDD(ExpressionBDDEncoding resultBefore, Model model) { resultBefore = this.FirstPart.TranslateStatementToBDD(resultBefore, model); resultBefore = this.SecondPart.TranslateStatementToBDD(resultBefore, model); return resultBefore; }
/// <summary> /// 1. Interrupt is not resolved, time evolution is synchronized /// 2. P1 terminate, or P2 interrupt, not need synchronization /// </summary> /// <param name="P1"></param> /// <param name="P2"></param> /// <param name="model"></param> /// <param name="result"></param> private static void InterruptEncodeTick(AutomataBDD P1, AutomataBDD P2, Model model, AutomataBDD result) { //1. (isInterrupted = 0 ∧ P1.Tick ∧ P2.Tick ∧ isInterrupted' = 0) Expression guard = Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(0)); Expression update = new Assignment(result.newLocalVarName, new IntConstant(0)); List<CUDDNode> transition = model.EncodeTransition(guard, update, new List<int>()); CUDD.Ref(P2.Ticks); transition = CUDD.Function.And(CUDD.Function.And(transition, P1.Ticks), P2.Ticks); result.Ticks.AddRange(CUDD.Function.And(transition, P1.Ticks)); //2. (isInterrupted = 1 and P1.tick ∧ isInterrupted' = 1) guard = Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(1)); update = new Assignment(result.newLocalVarName, new IntConstant(1)); transition = model.EncodeTransition(guard, update, new List<int>()); result.Ticks.AddRange(CUDD.Function.And(transition, P1.Ticks)); //3. (isInterrupted = 2 and P2.tick ∧ isInterrupted' = 2) guard = Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(2)); update = new Assignment(result.newLocalVarName, new IntConstant(2)); transition = model.EncodeTransition(guard, update, new List<int>()); result.Ticks.AddRange(CUDD.Function.And(transition, P2.Ticks)); }
/// <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; } }
/// <summary> /// Create a new variable which know whether event is tick or not /// Later all event information is removed from the transition /// Return the justice based on that new varaible /// justice: event = tick, event != tick /// </summary> /// <param name="modelBDD"></param> /// <param name="model"></param> /// <returns></returns> public List<CUDDNode> GetJustices(AutomataBDD modelBDD, Model model) { model.AddLocalVar(EVENT_DUMMY, 0, 1); //Because later event variables are removed, add new variable to check whether it is tick or not Expression guard = Expression.OR( Expression.AND( TimeBehaviors.GetTickTransExpression(), new Assignment(EVENT_DUMMY, new IntConstant(1))), Expression.AND( TimeBehaviors.GetNotTickTransExpression(), new Assignment(EVENT_DUMMY, new IntConstant(0)))); modelBDD.transitionBDD = CUDD.Function.And(modelBDD.transitionBDD, guard.TranslateBoolExpToBDD(model).GuardDDs); //the cycle must contain tick transition (zeno) and other transitions (progress) List<CUDDNode> justices = new List<CUDDNode>(); guard = Expression.EQ(new Variable(EVENT_DUMMY), new IntConstant(0)); justices.Add(CUDD.Function.Or(guard.TranslateBoolExpToBDD(model).GuardDDs)); guard = Expression.EQ(new Variable(EVENT_DUMMY), new IntConstant(1)); justices.Add(CUDD.Function.Or(guard.TranslateBoolExpToBDD(model).GuardDDs)); return justices; }
/// <summary> /// Encode this assignment as a single statement /// </summary> /// <param name="model"></param> /// <returns></returns> public override ExpressionBDDEncoding TranslateBoolExpToBDD(Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); ExpressionBDDEncoding variableBddEncoding = new PrimitiveApplication(PrimitiveApplication.ARRAYPRIME, this.RecordExpression, this.PropertyExpression).TranslateIntExpToBDD(model); ExpressionBDDEncoding valueBddEncoding = this.RightHandExpression.TranslateIntExpToBDD(model); for (int i = 0; i < variableBddEncoding.Count(); i++) { for (int j = 0; j < valueBddEncoding.Count(); j++) { CUDD.Ref(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); CUDDNode guardDD = CUDD.Function.And(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); if (guardDD.Equals(CUDD.ZERO)) { CUDD.Deref(guardDD); continue; } CUDD.Ref(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); CUDDNode assignmentDD = CUDD.Function.Equal(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); guardDD = CUDD.Function.And(guardDD, assignmentDD); result.AddNodeToGuard(guardDD); } } //remove unused expression variableBddEncoding.DeRef(); valueBddEncoding.DeRef(); return result; }
/// <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> /// Return AutomataBDD of the process which is composed of some choices /// tick transition could not resolve the choice /// </summary> /// <param name="choices">List of AutomataBDD of choices</param> /// <param name="tauEvent">Event' = Tau Event Index</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD IndexChoice(List<AutomataBDD> choices, Model model) { AutomataBDD result = AutomataBDD.Choice(choices, model); IndexChoiceEncodeTick(choices, model, result); // return result; }
/// <summary> /// Return AutomataBDD of the not tau event prefix process with guard [b] e -> P1 /// </summary> /// <param name="guard"></param> /// <param name="updateOfEvent">Update command happening with the event</param> /// <param name="guardOfTick">Guard of the tick before engaging the event</param> /// <param name="P1">AutomataBDD of the process P1 engaging after the event</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD EventPrefix(Expression guard, Expression updateOfEvent, Expression guardOfTick, AutomataBDD P1, Model model) { AutomataBDD result = AutomataBDD.EventPrefix(guard, updateOfEvent, P1, model); EventPrefixEncodeTick(guardOfTick, P1, model, result); // return result; }
/// <summary> /// Return AutomataBDD of interrupt process /// </summary> /// <param name="P1">AutomataBDD of interrupted process</param> /// <param name="P2">AutomataBDD of interrupting process</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Interrupt(AutomataBDD P1, AutomataBDD P2, Model model) { AutomataBDD result = AutomataBDD.Interrupt(P1, P2, model); InterruptEncodeTick(P1, P2, model, result); // return result; }
/// <summary> /// Return AutomataBDD of the process which is composed of some choices /// tick transition could not resolve the choice /// </summary> /// <param name="choices">List of AutomataBDD of choices</param> /// <param name="tauEvent">Event' = Tau Event Index</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD ExternalChoice(List<AutomataBDD> choices, Model model) { AutomataBDD result = AutomataBDD.ExternalChoice(choices, model); ExternalChoiceEncodeTick(choices, model, result); // return result; }
/// <summary> /// Return the AutomataBDD of the Channel Output /// </summary> /// <param name="channelName">Channel's name</param> /// <param name="channelEventIndex"></param> /// <param name="exps">List of output expressions of the channel</param> /// <param name="guardOfTick"></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, Expression guardOfTick, AutomataBDD P1, Model model) { AutomataBDD result = AutomataBDD.SyncChannelOutputPrefixing(channelEventIndex, exps, P1, model); EventPrefixEncodeTick(guardOfTick, P1, model, result); // return result; }
/// <summary> /// Return AutomataBDD of Parallel process. /// Note: synchronized is created by AND of transition of participant process. Therefore this only happens when the transition does not change any global variable /// because when encoding transition, each transition will make variable unchanged if it is not updated in that transition. This synchronization is similar to /// Explicit model checking when does not allow synchronized transition having program block. /// </summary> /// <param name="processes">List of AutomataBDD of parallel processes</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Parallel(List<AutomataBDD> processes, List<CUDDNode> alphabets, Model model) { AutomataBDD result = AutomataBDD.Parallel(processes, alphabets, model); ParallelEncodeTick(processes, model, result); // return result; }
/// <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 }; }
/// <summary> /// Return the AutomataBDD of the Channel Output /// </summary> /// <param name="channelName">Channel's name</param> /// <param name="channelEventIndex"></param> /// <param name="exps">List of output expressions of the channel</param> /// <param name="assignmentExp"></param> /// <param name="guardOfTick"></param> /// <param name="P1"><AutomataBDD of process P1 after the channel input/param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD ChannelOutputPrefixing(string channelName, int channelEventIndex, List<Expression> exps, Expression assignmentExp, Expression guardOfTick, AutomataBDD P1, Model model) { AutomataBDD result = AutomataBDD.ChannelOutputPrefixing(channelName, channelEventIndex, exps, assignmentExp, P1, model); EventPrefixEncodeTick(guardOfTick, P1, model, result); // return result; }
private static void TimeInterruptEncodeTransitionChannel(string clk, AutomataBDD m0, AutomataBDD m1, int t, Model model, AutomataBDD result) { Expression guard; List<CUDDNode> guardDD, transTemp; //1. clk <= t and m0.Trans/In/Out and [(event' = termination & clk' = -1) or (event' != termination & clk' = clk)] guard = Expression.AND(Expression.LE(new Variable(clk), new IntConstant(t)), Expression.OR(Expression.AND( AutomataBDD.GetTerminateTransExpression(), new Assignment(clk, new IntConstant(-1))), Expression.AND( AutomataBDD.GetNotTerminateTransExpression(), new Assignment(clk, new Variable(clk))))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m0.transitionBDD, guardDD); result.transitionBDD.AddRange(transTemp); // CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m0.channelInTransitionBDD, guardDD); result.channelInTransitionBDD.AddRange(transTemp); // //CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m0.channelOutTransitionBDD, guardDD); result.channelOutTransitionBDD.AddRange(transTemp); //2. clk = t and event' = tau and clk' = t + 1 and m1.Init guard = Expression.AND(Expression.EQ(new Variable(clk), new IntConstant(t)), Expression.AND(AutomataBDD.GetTauTransExpression(), new Assignment(clk, new IntConstant(t + 1)))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = CUDD.Function.And(m1.GetInitInColumn(model), CUDD.Function.Or(guardDD)); guardDD = model.AddVarUnchangedConstraint(guardDD, model.GlobalVarIndex); result.transitionBDD.AddRange(guardDD); //3. clk = t + 1 and m1.Trans and clk' = t + 1 guard = Expression.AND(Expression.EQ(new Variable(clk), new IntConstant(t + 1)), new Assignment(clk, new IntConstant(t + 1))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; // CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m1.transitionBDD, guardDD); result.transitionBDD.AddRange(guardDD); // CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m1.channelInTransitionBDD, guardDD); result.channelInTransitionBDD.AddRange(guardDD); // //CUDD.Ref(guardDD); transTemp = CUDD.Function.And(m1.channelOutTransitionBDD, guardDD); result.channelOutTransitionBDD.AddRange(guardDD); }
/// <summary> /// A sequence, containing some statement, must be encoded in TranslateStatementToBDD mode /// </summary> /// <param name="model"></param> /// <returns></returns> public override ExpressionBDDEncoding TranslateBoolExpToBDD(Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); result.GuardDDs.Add(CUDD.Constant(1)); result = TranslateStatementToBDD(result, model); return result; }
/// <summary> /// /// </summary> /// <param name="channelName">The channel Name</param> /// <param name="channelEventIndex"></param> /// <param name="guard">If no guard, give BoolConstant(true)</param> /// <param name="exps">List of expressions of channel out</param> /// <param name="assignmentExp">If no guard, give BoolConstant(true)</param> /// <param name="P1">Process after channel in</param> /// <param name="model"></param> /// <param name="result"></param> private static void ChannelInputEncodeTransition(string channelName, int channelEventIndex, Expression guard, List<Expression> exps, Expression assignmentExp, AutomataBDD P1, Model model, AutomataBDD result) { List<Expression> guardUpdateChannel = GetGuardUpdateOfChannelInput(channelName, guard, exps, assignmentExp, model); //set update Model.Event_Name guardUpdateChannel[1] = new Sequence(guardUpdateChannel[1], new Assignment(Model.EVENT_NAME, new IntConstant(channelEventIndex))); EventPrefixEncodeTransition(guardUpdateChannel[0], guardUpdateChannel[1], P1, model, result); }
/// <summary> /// syncTransition = P1.transition ∧ P2.transition /// syncEvent: formula of synchronized events /// P.transition = syncTransition ∨ (Pi.transition ∧ !syncEvent ∧ unchanged.i) /// Applied this formula for each pair of process: P1 || P2 || P3 = (P1 || P2) || P3 /// [ REFS: '', DEREFS: 'processes[i].transitionBDD, alphabet'] /// </summary> /// <param name="processes"></param> /// <param name="alphabets">alphabet of each process if provided. Give True if not provided</param> /// <param name="model"></param> /// <param name="result"></param> private static void ParallelEncodeTransition(List<AutomataBDD> processes, List<CUDDNode> alphabets, Model model, AutomataBDD result) { List<CUDDNode> transition = processes[0].transitionBDD; CUDDNode lastAlphabet = alphabets[0]; //Do encoding at each step, 2 processes once for (int i = 1; i < processes.Count; i++) { //find sync transitions CUDD.Ref(transition); CUDD.Ref(processes[i].transitionBDD); List<CUDDNode> syncTransition = CUDD.Function.And(transition, processes[i].transitionBDD); //sync alphabet = (P0.alphabet and P1.alphabet) or termination event //We rename the event with assignment whose name may be also in the alphabet //After the rename, they do not belong to the alphabet CUDD.Ref(lastAlphabet, alphabets[i]); CUDDNode syncEvent = CUDD.Function.Or(CUDD.Function.And(lastAlphabet, alphabets[i]), GetTerminationTransEncoding(model)); //sync transition must have no program block which mean no global variable updated foreach (var globalVarIndex in model.GlobalVarIndex) { CUDD.Ref(model.varIdentities[globalVarIndex]); syncEvent = CUDD.Function.And(syncEvent, model.varIdentities[globalVarIndex]); } CUDD.Ref(syncEvent); syncTransition = CUDD.Function.And(syncTransition, syncEvent); //update current alphabet lastAlphabet = CUDD.Function.Or(lastAlphabet, alphabets[i]); CUDD.Ref(syncTransition); List<CUDDNode> tempTransition = new List<CUDDNode>(syncTransition); //find not sync event, we need to add global variable unchanged to syncEvent because for example process a -> a {x = 1} -> P; //a may be in the alphabet, and the first a can be synced, but the secondtion is not CUDDNode notSyncEvents = CUDD.Function.Not(syncEvent); CUDD.Ref(notSyncEvents); tempTransition.AddRange(CUDD.Function.And(transition, notSyncEvents)); tempTransition.AddRange(CUDD.Function.And(processes[i].transitionBDD, notSyncEvents)); transition = tempTransition; } // CUDD.Deref(lastAlphabet); transition = model.AddVarUnchangedConstraint(transition, result.variableIndex); // result.transitionBDD = transition; }
/// <summary> /// P.var : m0 ∪ {clk} /// </summary> private static List<string> WithinSetVariable(AutomataBDD m0, int t, Model model, AutomataBDD result) { result.variableIndex.AddRange(m0.variableIndex); // string clk = Model.GetNewTempVarName(); model.AddLocalVar(clk, -1, t); result.variableIndex.Add(model.GetNumberOfVars() - 1); return new List<string>() { clk }; }
private static void SkipEncodeTick(Model model, AutomataBDD result) { //2. state = 0 & event' = tick & state = 0 //3. state = 1 & event' = tick & state = 1 Expression guard = Expression.AND(GetTickTransExpression(), new Assignment(result.newLocalVarName, new Variable(result.newLocalVarName))); List<CUDDNode> guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = model.AddVarUnchangedConstraint(guardDD, model.GlobalVarIndex); result.Ticks.AddRange(guardDD); }
/// <summary> /// [ REFS: 'result', DEREFS: 'resultBefore' ] /// </summary> public override ExpressionBDDEncoding TranslateStatementToBDD(ExpressionBDDEncoding resultBefore, Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); CUDDNode conditionDD = CUDD.Function.Or(this.Test.TranslateBoolExpToBDD(model).GuardDDs); do { ExpressionBDDEncoding tempResult = new ExpressionBDDEncoding(); List<List<int>> updatedVariablesBefore = new List<List<int>>(); for (int index = 0; index < resultBefore.Count(); index++) { updatedVariablesBefore.Add(model.GetColSupportedVars(resultBefore.GuardDDs[index])); } List<int> usedVariablesInCondition = model.GetRowSupportedVars(conditionDD); for (int j1 = 0; j1 < resultBefore.Count(); j1++) { foreach (int index in usedVariablesInCondition) { if (updatedVariablesBefore[j1].Contains(index)) { conditionDD = CUDD.Variable.SwapVariables(conditionDD, model.GetRowVars(index), model.GetColVars(index)); } } //Add configuration making the While condition true CUDD.Ref(resultBefore.GuardDDs[j1], conditionDD); CUDDNode transition = CUDD.Function.And(resultBefore.GuardDDs[j1], conditionDD); tempResult.AddNodeToGuard(transition); //Add configuration making the While condition false CUDD.Ref(resultBefore.GuardDDs[j1], conditionDD); CUDDNode falseTransition = CUDD.Function.And(resultBefore.GuardDDs[j1], CUDD.Function.Not(conditionDD)); result.AddNodeToGuard(falseTransition); } //There is no any configuration making the While condition true if (tempResult.Count() > 0) { resultBefore.DeRef(); resultBefore = this.Body.TranslateStatementToBDD(tempResult, model); } else { break; } } while (true); resultBefore.DeRef(); return result; }
/// <summary> /// [ REFS: '', DEREFS: 'P1, P2'] /// </summary> /// <param name="isP1Terminate"></param> /// <param name="P1"></param> /// <param name="P2"></param> /// <param name="model"></param> /// <param name="result"></param> public static void SequenceEncodeTransition(string isP1Terminate, AutomataBDD P1, AutomataBDD P2, Model model, AutomataBDD result) { CUDDNode tauEvent = GetTauTransEncoding(model); CUDDNode terminateEvent = GetTerminationTransEncoding(model); CUDD.Ref(terminateEvent); CUDD.Ref(P1.transitionBDD); List<CUDDNode> notTerminateTransition = CUDD.Function.And(P1.transitionBDD, CUDD.Function.Not(terminateEvent)); //CUDD.Ref(terminateEvent); //CUDD.Ref(P1.transitionBDD); List<CUDDNode> terminateTransition = CUDD.Function.And(P1.transitionBDD, terminateEvent); //Convert terminate transition to tau transition terminateTransition = CUDD.Abstract.ThereExists(terminateTransition, model.GetAllEventVars()); terminateTransition = CUDD.Function.And(terminateTransition, tauEvent); //1. !isP1Terminate and not terminate transition, channel and !isP1Terminate Expression guard = Expression.AND(Expression.EQ(new Variable(isP1Terminate), new IntConstant(0)), new Assignment(isP1Terminate, new IntConstant(0))); List<CUDDNode> guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; // CUDD.Ref(guardDD); result.transitionBDD.AddRange(CUDD.Function.And(guardDD, notTerminateTransition)); CUDD.Ref(guardDD); result.channelInTransitionBDD.AddRange(CUDD.Function.And(guardDD, P1.channelInTransitionBDD)); // CUDD.Ref(guardDD); result.channelOutTransitionBDD.AddRange(CUDD.Function.And(guardDD, P1.channelOutTransitionBDD)); //2. (!isP1Terminate ∧ terminate P1.transition ∧ isP1Terminate' and P2.Init') guard = Expression.AND(Expression.EQ(new Variable(isP1Terminate), new IntConstant(0)), new Assignment(isP1Terminate, new IntConstant(1))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = CUDD.Function.And(guardDD, P2.GetInitInColumn(model)); result.transitionBDD.AddRange(CUDD.Function.And(guardDD, terminateTransition)); //3. (isP1Terminate ∧ P2.Trans/In/Out ∧ isP1Terminate') guard = Expression.AND(Expression.EQ(new Variable(isP1Terminate), new IntConstant(1)), new Assignment(isP1Terminate, new IntConstant(1))); guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; // CUDD.Ref(guardDD); result.transitionBDD.AddRange(CUDD.Function.And(guardDD, P2.transitionBDD)); CUDD.Ref(guardDD); result.channelInTransitionBDD.AddRange(CUDD.Function.And(guardDD, P2.channelInTransitionBDD)); //CUDD.Ref(guardDD); result.channelOutTransitionBDD.AddRange(CUDD.Function.And(guardDD, P2.channelOutTransitionBDD)); }
/// <summary> /// Return the AutomataBDD of the Channel Input /// Currently Channel Input is translated as assginment, not guard. We don't support using channel input to expect a certain value /// </summary> /// <param name="channelName">Channel's name</param> /// <param name="channelEventIndex"></param> /// <param name="guard">Guard expression of the channel input</param> /// <param name="exps">List of input expression to the channel</param> /// <param name="assignmetExp"></param> /// <param name="P1">AutomataBDD of process P1 after the channel input</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD ChannelInputPrefixing(string channelName, int channelEventIndex, Expression guard, List<Expression> exps, Expression assignmetExp, AutomataBDD P1, Model model) { AutomataBDD result = new AutomataBDD(); ChannelInputSetVariable(exps, P1, model, result); EventPrefixSetInit(result); ChannelInputEncodeTransition(channelName, channelEventIndex, guard, exps, assignmetExp, P1, model, result); // return result; }
/// <summary> /// Return AutomataBDD of the not tau event prefix process with guard [b] e -> P1 /// </summary> /// <param name="guard">Guard of this event to happen</param> /// <param name="updateOfEvent">Update command happening with the event</param> /// <param name="P1">AutomataBDD of the process P1 engaging after the event</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD EventPrefix(Expression guard, Expression updateOfEvent, AutomataBDD P1, Model model) { AutomataBDD result = new AutomataBDD(); EventPrefixSetVariable(P1, model, result); EventPrefixSetInit(result); EventPrefixEncodeTransition(guard, updateOfEvent, P1, model, result); // return result; }