/// <summary> /// If no need update para, return null /// </summary> /// <returns></returns> private Expression GetUpdatePara() { bool needUpdates = false; for (int i = 0; i < Args.Length; i++) { if (Args[i].ToString() != Def.Parameters[i]) { needUpdates = true; } } if (needUpdates) { Expression updatePara = new Assignment(Def.Parameters[0], Args[0]); for (int i = 1; i < Args.Length; i++) { updatePara = new SequenceExpression(updatePara, new Assignment(Def.Parameters[0], Args[0])); } return(updatePara); } return(null); }
/// <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 guard, update of channel output /// guard: buffer not full /// update: buffer = sender and update size of message and update length of buffer and update top of buffer /// Does not include update Model.Event_Name /// </summary> /// <param name="channelName"></param> /// <param name="exps"></param> /// <param name="assignmentExp">null if not exist</param> /// <param name="model"></param> /// <returns></returns> private static List<Expression> GetGuardUpdateOfChannelOutput(string channelName, List<Expression> exps, Expression assignmentExp, Model model) { string topChannelVariable = Model.GetTopVarChannel(channelName); string countChannelVariable = Model.GetCountVarChannel(channelName); string sizeElementArray = Model.GetArrayOfSizeElementChannel(channelName); //count_a < L Expression guardOfChannel = Expression.LT(new Variable(countChannelVariable), new IntConstant(model.mapChannelToSize[channelName])); Expression updateOfChannel = new BoolConstant(true); //Update buffer channel //a[top_a] [ i] = exps[i] for (int i = 0; i < exps.Count; i++) { updateOfChannel = new Sequence(updateOfChannel, new PropertyAssignment(new Variable(channelName), Expression.PLUS( Expression.TIMES(new Variable(topChannelVariable), new IntConstant(Model.MAX_MESSAGE_LENGTH)), new IntConstant(i)), exps[i])); } //Set size of the new element //size_a[top_a] = exps.count updateOfChannel = new Sequence(updateOfChannel, new PropertyAssignment(new Variable(sizeElementArray), new Variable(topChannelVariable), new IntConstant(exps.Count))); //Update size: count_a = count_a + 1 updateOfChannel = new Sequence(updateOfChannel, new Assignment(countChannelVariable, Expression.PLUS( new Variable(countChannelVariable), new IntConstant(1)))); //Update top position: top_a = (top_a + 1) %L updateOfChannel = new Sequence(updateOfChannel, new Assignment(topChannelVariable, Expression.MOD( Expression.PLUS(new Variable(topChannelVariable), new IntConstant(1)), new IntConstant(model.mapChannelToSize[channelName])))); if(assignmentExp != null) { updateOfChannel = new Sequence(updateOfChannel, assignmentExp); } return new List<Expression>() { guardOfChannel, updateOfChannel }; }
/// <summary> /// /// </summary> /// <param name="channelEventIndex"></param> /// <param name="exps">List of expressions of channel in</param> /// <param name="P1">Process after channel in</param> /// <param name="model">Process after channel in</param> /// <param name="result"></param> private static void SyncChannelOutputEncodeTransition(int channelEventIndex, List<Expression> exps, AutomataBDD P1, Model model, AutomataBDD result) { Expression guard = Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(0)); Expression update = new Assignment(Model.EVENT_NAME, new IntConstant(channelEventIndex)); for (int i = 0; i < exps.Count; i++) { //Update eventParameterVariables[i] = exps[i] //Don't need to update exps because later after synchronization, not updated variable keeps the same value update = new Sequence(update, new Assignment(model.eventParameterVariables[i], exps[i])); } update = new Sequence(update, new Assignment(result.newLocalVarName, new IntConstant(1))); List<CUDDNode> transition = model.EncodeTransition(guard, update, new List<int>()); transition = CUDD.Function.And(transition, P1.GetInitInColumn(model)); transition = model.AddVarUnchangedConstraint(transition, model.GlobalVarIndex); result.channelOutTransitionBDD.AddRange(transition); // CopyTransitionAfterEventChannel(P1, model, result); }
/// <summary> /// (!temp ∧ guard∧ ∧ update ∧ temp ' ∧ P1.init) /// </summary> private static void EventPrefixTransitition(Expression guardOfTrans, Expression updateOfTrans, AutomataBDD P1, Model model, AutomataBDD result) { Expression guard = Expression.AND(Expression.EQ(new Variable(result.newLocalVarName), new IntConstant(0)), guardOfTrans); Expression update = new Sequence(updateOfTrans, new Assignment(result.newLocalVarName, new IntConstant(1))); List<CUDDNode> transition = model.EncodeTransition(guard, update, new List<int>()); transition = CUDD.Function.And(transition, P1.GetInitInColumn(model)); transition = model.AddVarUnchangedConstraint(transition, model.GlobalVarIndex); result.transitionBDD.AddRange(transition); }
/// <summary> /// Encode transition, if it is synchronized, then we don't add constraint of unchanged global variables /// Parallel process only synchorinize event which does not change global variable or each transition changes same to global variables /// 3 kinds of transition: normal event, async channel input and async channel output /// </summary> /// <param name="encoder"></param> /// <param name="processVariableName"></param> /// <param name="localVars">Local of the current SymbolicLTS is unchanged</param> /// <param name="isSynchronized"></param> /// <returns></returns> public List<CUDDNode> Encode(BDDEncoder encoder, string processVariableName, List<int> localVars, bool isSynchronized) { Expression guardExpressions = Expression.EQ( new Variable(processVariableName), new IntConstant(encoder.stateIndexOfCurrentProcess[this.FromState.ID])); guardExpressions = Expression.CombineGuard(guardExpressions, GuardCondition); Expression eventUpdateExpression; if (this.Event is BDDEncoder.EventChannelInfo) { int channelIndex = encoder.GetChannelIndex(this.Event.BaseName, (this.Event as BDDEncoder.EventChannelInfo).type); eventUpdateExpression = new Assignment(Model.EVENT_NAME, new IntConstant(channelIndex)); } else { eventUpdateExpression = encoder.GetEventExpression(this.Event); } Assignment stateUpdateExpression = new Assignment(processVariableName, new IntConstant(encoder.stateIndexOfCurrentProcess[this.ToState.ID])); Sequence updateExpressions = new Sequence(eventUpdateExpression, stateUpdateExpression); if (this.ProgramBlock != null) { updateExpressions = new Sequence(updateExpressions, this.ProgramBlock); } List<int> unchangedVars = new List<int>(localVars); if (!isSynchronized) { unchangedVars.AddRange(encoder.model.GlobalVarIndex); } return encoder.model.EncodeTransition(guardExpressions, updateExpressions, unchangedVars); }
/// <summary> /// Return the event update expression when the event is a string like "event.0" /// </summary> /// <param name="eventName"></param> /// <returns></returns> private Expression GetEventExpression(string eventName) { string[] eventsTemp = eventName.Split('.', '[', ']'); List<string> events = new List<string>(); for (int i = 0; i < eventsTemp.Length; i++) { if (!string.IsNullOrEmpty(eventsTemp[i])) { events.Add(eventsTemp[i]); } } Expression eventExpression = new Assignment(Model.EVENT_NAME, new IntConstant(this.GetEventIndex(events[0], events.Count - 1))); for (int i = 1; i < events.Count; i++) { eventExpression = new Sequence(eventExpression, new Assignment(this.model.eventParameterVariables[i - 1], new IntConstant(int.Parse(events[i])))); } return eventExpression; }
/// <summary> /// Return the update event expression when the Event is an Event object /// </summary> /// <param name="Event"></param> /// <returns></returns> public Expression GetEventExpression(Event Event) { List<Expression> parameters = this.GetParaExpInEvent(Event); int eventIndex = this.GetEventIndex(Event.BaseName, parameters.Count); Expression eventUpdateExpression = new Assignment(Model.EVENT_NAME, new IntConstant(eventIndex)); if (parameters.Count > 0) { for (int i = 0; i < parameters.Count; i++) { eventUpdateExpression = new Sequence(eventUpdateExpression, new Assignment(this.model.eventParameterVariables[i], parameters[i])); } } return eventUpdateExpression; }