/// <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> /// ∪ Pi.var /// </summary> private static void InterleaveSetVariable(List <AutomataBDD> processes, AutomataBDD result) { foreach (AutomataBDD process in processes) { result.variableIndex.AddRange(process.variableIndex); } }
/// <summary> /// P.init: m0.init ^ clk = 0 /// </summary> private static void DeadlineSetInit(string clk, AutomataBDD m0, AutomataBDD result) { result.initExpression = Expression.AND(m0.initExpression, Expression.EQ( new Variable(clk), new IntConstant(0))); }
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> /// Return AutomataBDD of the hiding process /// [ REFS: 'none', DEREFS: 'hidingEvent, tauEvent, P1' ] /// </summary> /// <param name="hidingEvent">CUDDNode of hiding events</param> /// <param name="tauEvent">CUDDNode of tau event</param> /// <param name="P1">AutomataBDD of the process P1</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Hiding(CUDDNode hidingEvent, CUDDNode tauEvent, AutomataBDD P1, Model model) { CUDD.Ref(P1.transitionBDD); CUDD.Ref(hidingEvent); List <CUDDNode> hidingTransition = CUDD.Function.And(P1.transitionBDD, hidingEvent); hidingTransition = CUDD.Abstract.ThereExists(hidingTransition, model.GetEventColVars()); CUDD.Ref(tauEvent); hidingTransition = CUDD.Function.And(hidingTransition, tauEvent); // CUDD.Ref(P1.transitionBDD); CUDD.Ref(hidingEvent); List <CUDDNode> notHidingTransition = CUDD.Function.And(P1.transitionBDD, CUDD.Function.Not(hidingEvent)); // CUDD.Deref(hidingEvent, tauEvent); CUDD.Deref(P1.transitionBDD); P1.transitionBDD.Clear(); P1.transitionBDD.AddRange(hidingTransition); P1.transitionBDD.AddRange(notHidingTransition); return(P1); }
/// <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> /// 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)); }
private void EncodeSimulationRel(BDDEncoder encoder, AutomataBDD processBDD, string stateVar) { int stateVarIndex = encoder.model.GetVarIndex(stateVar); CUDDVars rowStateVars = encoder.model.GetRowVars(stateVarIndex); CUDDVars colStateVars = encoder.model.GetColVars(stateVarIndex); CUDDNode result = CUDD.Constant(0); foreach (var pair in mapOldLoc2NewStates) { List <State> statesInLoc = pair.Value; for (int i = 0; i < statesInLoc.Count; i++) { for (int j = 0; j < statesInLoc.Count; j++) { if (ClockValuation.IsLUSimulated(mapNewState2Valuation[statesInLoc[i].ID], mapNewState2Valuation[statesInLoc[j].ID], pair.Key)) { CUDDNode simulated = CUDD.Matrix.SetVectorElement(CUDD.Constant(0), rowStateVars, encoder.stateIndexOfCurrentProcess[statesInLoc[i].ID], 1); CUDDNode simulating = CUDD.Matrix.SetVectorElement(CUDD.Constant(0), colStateVars, encoder.stateIndexOfCurrentProcess[statesInLoc[j].ID], 1); result = CUDD.Function.Or(result, CUDD.Function.And(simulated, simulating)); } } } } processBDD.SimulationRel = 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> /// Return AutomataBDD of Stop process /// </summary> /// <returns></returns> public static AutomataBDD Stop() { AutomataBDD result = new AutomataBDD(); // 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> /// 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> /// 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> /// 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> /// 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> /// ∧ Pi.init /// </summary> private static void InterleaveSetInit(List <AutomataBDD> processes, AutomataBDD result) { result.initExpression = processes[0].initExpression; for (int i = 1; i < processes.Count; i++) { result.initExpression = Expression.AND(result.initExpression, processes[i].initExpression); } }
/// <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> /// 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 : 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> /// 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> /// P.init : ∧{i = 1..n}Pi.init and temp = -1 /// </summary> private static void InternalChoiceSetInit(List<AutomataBDD> choices, AutomataBDD result) { result.initExpression = Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(-1)); for (int i = 0; i < choices.Count; i++) { result.initExpression = Expression.AND(result.initExpression, choices[i].initExpression); } }
/// <summary> /// P.init : ∧{i = 1..n}Pi.init and temp = -1 /// </summary> private static void InternalChoiceSetInit(List <AutomataBDD> choices, AutomataBDD result) { result.initExpression = Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(-1)); for (int i = 0; i < choices.Count; i++) { result.initExpression = Expression.AND(result.initExpression, choices[i].initExpression); } }
private void EncodeTransitions(BDDEncoder encoder, AutomataBDD processAutomataBDD, string processVariableName) { foreach (Transition transition in this.Transitions) { //Depend on what kind of transition to add the encoded transition to AutomataBDD if (transition.Event is ChannelInputEvent) { List <CUDDNode> transitionBDDs = transition.Encode(encoder, processVariableName, processAutomataBDD.variableIndex, true); if (transition.FromState.HavePriority) { processAutomataBDD.prioritychannelIns.AddRange(transitionBDDs); } else { processAutomataBDD.channelInTransitionBDD.AddRange(transitionBDDs); } } else if (transition.Event is ChannelOutputEvent) { List <CUDDNode> transitionBDDs = transition.Encode(encoder, processVariableName, processAutomataBDD.variableIndex, true); if (transition.FromState.HavePriority) { processAutomataBDD.prioritychannelOuts.AddRange(transitionBDDs); } else { processAutomataBDD.channelOutTransitionBDD.AddRange(transitionBDDs); } } else if (transition.Event is BDDEncoder.EventChannelInfo && (transition.Event as BDDEncoder.EventChannelInfo).type == BDDEncoder.EventChannelInfo.EventType.SYNC_CHANNEL_INPUT) { List <CUDDNode> transitionBDDs = transition.EncodeSyncChannelInTransition(encoder, processVariableName, processAutomataBDD.variableIndex); processAutomataBDD.channelInTransitionBDD.AddRange(transitionBDDs); } else if (transition.Event is BDDEncoder.EventChannelInfo && (transition.Event as BDDEncoder.EventChannelInfo).type == BDDEncoder.EventChannelInfo.EventType.SYNC_CHANNEL_OUTPUT) { List <CUDDNode> transitionBDDs = transition.EncodeSyncChannelOutTransition(encoder, processVariableName, processAutomataBDD.variableIndex); processAutomataBDD.channelOutTransitionBDD.AddRange(transitionBDDs); } else if (transition.IsTick()) { List <CUDDNode> transitionBDDs = transition.Encode(encoder, processVariableName, processAutomataBDD.variableIndex, false); processAutomataBDD.Ticks.AddRange(transitionBDDs); } else { List <CUDDNode> transitionBDDs = transition.Encode(encoder, processVariableName, processAutomataBDD.variableIndex, false); if (transition.FromState.HavePriority) { processAutomataBDD.priorityTransitionsBDD.AddRange(transitionBDDs); } else { processAutomataBDD.transitionBDD.AddRange(transitionBDDs); } } } }
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> /// /// </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> /// 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; }
/// <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> /// ∧ Pi.init /// </summary> private static void ParallelSetInit(List <AutomataBDD> processes, AutomataBDD result) { result.initExpression = processes[0].initExpression; //This loop and the implementation of AND of a list make sure that processes having the same event can run simultaneously for (int i = 1; i < processes.Count; i++) { result.initExpression = Expression.AND(result.initExpression, processes[i].initExpression); } }
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> /// 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 }; }
/// <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 AutomataBDD of the process which is composed of some choices /// Choice is not resolved until not tau transition happens /// </summary> /// <param name="choices">List of AutomataBDD of choices</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD ExternalChoice(List<AutomataBDD> choices, Model model) { AutomataBDD result = new AutomataBDD(); ExternalChoiceSetVariable(choices, model, result); ExternalChoiceSetInit(choices, result); ExternalChoiceEncodeTransition(choices, model, result); // return result; }
/// <summary> /// Return AutomataBDD of Stop process /// </summary> /// <returns></returns> public static AutomataBDD Stop(Model model) { AutomataBDD result = new AutomataBDD(); Expression guard = GetTickTransExpression(); List<CUDDNode> guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; guardDD = model.AddVarUnchangedConstraint(guardDD, model.GlobalVarIndex); result.Ticks.AddRange(guardDD); return result; }
/// <summary> /// Return AutomataBDD of the Skip process /// </summary> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Skip(Model model) { AutomataBDD result = new AutomataBDD(); SkipSetVariable(model, result); SkipSetInit(result); SkipEncodeTransition(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 = new AutomataBDD(); InterruptSetVariable(P1, P2, model, result); InterruptSetInit(P1, P2, result); InterruptEncodeTransition(P1, P2, model, result); // return result; }
/// <summary> /// Return AutomataBDD of the Skip process /// </summary> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Skip(Model model) { AutomataBDD result = new AutomataBDD(); SkipSetVariable(model, result); SkipSetInit(result); SkipEncodeTransition(model, result); // return result; }
/// <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 = new AutomataBDD(); GuardSetVariable(P1, model, result); GuardSetInit(P1, result); GuardEncodeTransition(guard, 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); }
/// <summary> /// Return the AutomataBDD of the Sync Channel Input. Encode this as event c?a.b.c and put it to ChannelInputTransition /// Currently Channel Input is translated as assginment, not guard. We don't support using channel input to expect a certain value /// </summary> /// <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="P1">AutomataBDD of process P1 after the channel input</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD SyncChannelInputPrefixing(int channelEventIndex, Expression guard, List <Expression> exps, AutomataBDD P1, Model model) { AutomataBDD result = new AutomataBDD(); ChannelInputSetVariable(exps, P1, model, result); EventPrefixSetInit(result); SyncChannelInputEncodeTransition(channelEventIndex, guard, exps, P1, model, result); // return(result); }
/// <summary> /// Return AutomataBDD of Sequence process /// </summary> /// <param name="P1">AutomataBDD of the first process</param> /// <param name="P2">AutomataBDD of the second process</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Sequence(AutomataBDD P1, AutomataBDD P2, Model model) { AutomataBDD result = new AutomataBDD(); List<string> varNames = AutomataBDD.SequenceSetVariable(P1, P2, model, result); SequenceSetInit(varNames[0], P1, P2, result); SequenceEncodeTransition(varNames[0], P1, P2, 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; }
/// <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 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="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, AutomataBDD P1, Model model) { AutomataBDD result = new AutomataBDD(); EventPrefixSetVariable(P1, model, result); EventPrefixSetInit(result); ChannelOutputEncodeTransition(channelName, channelEventIndex, exps, assignmentExp, P1, model, result); // return(result); }
/// <summary> /// Return AutomataBDD of the process which is composed of some choices /// Having tau transition to resolve the choice /// </summary> /// <param name="choices">List of AutomataBDD of choices</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD InternalChoice(List <AutomataBDD> choices, Model model) { AutomataBDD result = new AutomataBDD(); InternalChoiceSetVariable(choices, model, result); InternalChoiceSetInit(choices, result); InternalChoiceEncodeTransition(choices, model, result); // return(result); }
/// <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 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 = new AutomataBDD(); GuardSetVariable(P1, model, result); GuardSetInit(P1, result); GuardEncodeTransition(guard, P1, model, result); // return result; }
/// <summary> /// P.init : ∧{i = 1..n}Pi.init and temp = -1 /// </summary> private static void ExternalChoiceSetInit(List <AutomataBDD> choices, AutomataBDD result) { result.initExpression = choices[0].initExpression; for (int i = 1; i < choices.Count; i++) { result.initExpression = new PrimitiveApplication(PrimitiveApplication.AND, result.initExpression, choices[i].initExpression); } result.initExpression = new PrimitiveApplication(PrimitiveApplication.AND, result.initExpression, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(-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> /// 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 = new AutomataBDD(); InterruptSetVariable(P1, P2, model, result); InterruptSetInit(P1, P2, result); InterruptEncodeTransition(P1, P2, model, result); // return(result); }
/// <summary> /// Return AutomataBDD of Sequence process /// </summary> /// <param name="P1">AutomataBDD of the first process</param> /// <param name="P2">AutomataBDD of the second process</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Sequence(AutomataBDD P1, AutomataBDD P2, Model model) { AutomataBDD result = new AutomataBDD(); List <string> varNames = AutomataBDD.SequenceSetVariable(P1, P2, model, result); SequenceSetInit(varNames[0], P1, P2, result); SequenceEncodeTransition(varNames[0], P1, P2, model, result); // return(result); }
public static AutomataBDD TimeInterrupt(AutomataBDD m0, AutomataBDD m1, int t, Model model) { AutomataBDD result = new AutomataBDD(); List<string> varNames = TimeInterruptSetVariable(m0, m1, t, model, result); TimeInterruptSetInit(varNames[0], m0, m1, result); TimeInterruptEncodeTransitionChannel(varNames[0], m0, m1, t, model, result); TimeInterruptEncodeTick(varNames[0], m0, m1, t, model, result); // return result; }
/// <summary> /// Return AutomataBDD of Interleave process /// </summary> /// <param name="processes">List of AutomataBDD of interleaving processes</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Interleave(List <AutomataBDD> processes, Model model) { AutomataBDD result = new AutomataBDD(); InterleaveSetVariable(processes, result); InterleaveSetInit(processes, result); InterleaveEncodeTransition(processes, model, result); InterleaveEncodeChannel(processes, model, result); // return(result); }
/// <summary> /// Return AutomataBDD of Parallel process. /// Note: synchronized is created by AND of transition of 2 participant process a time. 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="alphabets">alphabet of each process if provided. Give True if not provided</param> /// <param name="model"></param> /// <returns></returns> public static AutomataBDD Parallel(List <AutomataBDD> processes, List <CUDDNode> alphabets, Model model) { AutomataBDD result = new AutomataBDD(); ParallelSetVariable(processes, result); ParallelSetInit(processes, result); ParallelEncodeTransition(processes, alphabets, model, result); InterleaveEncodeChannel(processes, model, result); // return(result); }
/// <summary> /// (!temp ∧ event ' = terminate ∧ temp ') /// </summary> private static void SkipEncodeTransition(Model model, AutomataBDD result) { Expression guard = Expression.AND( Expression.AND( new PrimitiveApplication( PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(0)), GetTerminateTransExpression()), new Assignment(result.newLocalVarName, new IntConstant(1))); result.transitionBDD.AddRange(model.AddVarUnchangedConstraint(guard.TranslateBoolExpToBDD(model).GuardDDs, model.GlobalVarIndex)); }
/// <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); }
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> /// tau transition in process 2 does not resolve /// [ REFS: '', DEREFS: 'P1, P2'] /// </summary> /// <param name="P1"></param> /// <param name="P2"></param> /// <param name="model"></param> /// <param name="result"></param> private static void InterruptEncodeTransition(AutomataBDD P1, AutomataBDD P2, Model model, AutomataBDD result) { //1. (isInterrupted < 2 ∧ P1.Trans/In/Out ∧ [(event' = termination and isInterrupted' = 1) or (event' != termination and isInterrupted' = isInterrupted)] P2.var = P2.var') Expression guard = Expression.AND( Expression.LT(new Variable(result.newLocalVarName), new IntConstant(2)), Expression.OR( Expression.AND( GetTerminateTransExpression(), new Assignment(result.newLocalVarName, new IntConstant(1))), Expression.AND( GetNotTerminateTransExpression(), new Assignment(result.newLocalVarName, new Variable(result.newLocalVarName)))) ); List <CUDDNode> transition = guard.TranslateBoolExpToBDD(model).GuardDDs; transition = model.AddVarUnchangedConstraint(transition, P2.variableIndex); // CUDD.Ref(transition); result.transitionBDD.AddRange(CUDD.Function.And(transition, P1.transitionBDD)); CUDD.Ref(transition); result.channelInTransitionBDD.AddRange(CUDD.Function.And(transition, P1.channelInTransitionBDD)); result.channelOutTransitionBDD.AddRange(CUDD.Function.And(transition, P1.channelOutTransitionBDD)); //2. (isInterrupted != 1 ∧ P2.Trans/In/Out ∧ [(event' = tau and isInterrupted' = isInterrupted) or (event' != tau and isInterrupted' = 2)]) guard = Expression.AND( Expression.NE(new Variable(result.newLocalVarName), new IntConstant(1)), Expression.OR( Expression.AND( GetTauTransExpression(), new Assignment(result.newLocalVarName, new Variable(result.newLocalVarName))), Expression.AND( GetNotTauTransExpression(), new Assignment(result.newLocalVarName, new IntConstant(2)))) ); transition = guard.TranslateBoolExpToBDD(model).GuardDDs; // CUDD.Ref(transition); result.transitionBDD.AddRange(CUDD.Function.And(transition, P2.transitionBDD)); CUDD.Ref(transition); result.channelInTransitionBDD.AddRange(CUDD.Function.And(transition, P2.channelInTransitionBDD)); //CUDD.Ref(transition); result.channelOutTransitionBDD.AddRange(CUDD.Function.And(transition, P2.channelOutTransitionBDD)); }
/// <summary> /// Encode the graph /// make sure that the local variables' names are unique. /// </summary> /// <param name="encoder"></param> /// <returns></returns> public AutomataBDD Encode(BDDEncoder encoder) { AutomataBDD processAutomataBDD = new AutomataBDD(); string processVariableName = this.AddLocalVariables(encoder); //Set local variables and initial condition SetLocalVarsAndInit(encoder, processAutomataBDD, processVariableName); //Encode transitions EncodeTransitions(encoder, processAutomataBDD, processVariableName); return(processAutomataBDD); }
/// <summary> /// (temp ∧ P1.Trans/In/Out ∧ temp') /// [ REFS: '', DEREFS: 'P1'] /// </summary> private static void CopyTransitionAfterEventChannel(AutomataBDD P1, Model model, AutomataBDD result) { Expression guard = new PrimitiveApplication(PrimitiveApplication.AND, new PrimitiveApplication(PrimitiveApplication.EQUAL, new Variable(result.newLocalVarName), new IntConstant(1)), new Assignment(result.newLocalVarName, new IntConstant(1))); List <CUDDNode> guardDD = guard.TranslateBoolExpToBDD(model).GuardDDs; // CUDD.Ref(guardDD); result.transitionBDD.AddRange(CUDD.Function.And(guardDD, P1.transitionBDD)); CUDD.Ref(guardDD); result.channelInTransitionBDD.AddRange(CUDD.Function.And(guardDD, P1.channelInTransitionBDD)); //CUDD.Ref(guardDD); result.channelOutTransitionBDD.AddRange(CUDD.Function.And(guardDD, P1.channelOutTransitionBDD)); }
/// <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 }); }