Example #1
0
        /// <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));
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <summary>
        /// Encode this assignment in a sequence of statements. Return variable values after this assignment based on the current value in resultBefore
        /// [ REFS: 'result', DEREFS: 'resultBefore' ]
        /// </summary>
        public override ExpressionBDDEncoding TranslateStatementToBDD(ExpressionBDDEncoding resultBefore, Model model)
        {
            ExpressionBDDEncoding newUpdate = this.TranslateBoolExpToBDD(model);

            ExpressionBDDEncoding tempResult = new ExpressionBDDEncoding();

            List<List<int>> updatedVariablesInNewUpdate = new List<List<int>>();
            for (int index = 0; index < newUpdate.Count(); index++)
            {
                updatedVariablesInNewUpdate.Add(model.GetColSupportedVars(newUpdate.GuardDDs[index]));
            }

            List<List<int>> usedVariableInNewUpdate = new List<List<int>>();
            for (int index = 0; index < newUpdate.Count(); index++)
            {
                usedVariableInNewUpdate.Add(model.GetRowSupportedVars(newUpdate.GuardDDs[index]));
            }

            List<List<int>> updatedVariablesBefore = new List<List<int>>();
            for (int index = 0; index < resultBefore.Count(); index++)
            {
                updatedVariablesBefore.Add(model.GetColSupportedVars(resultBefore.GuardDDs[index]));
            }

            for (int j1 = 0; j1 < resultBefore.Count(); j1++)
            {
                for (int j2 = 0; j2 < newUpdate.Count(); j2++)
                {
                    //a variable is already updated, now is updated again and it also apprears in the value expression
                    if (Assignment.IsComplexUpdate(updatedVariablesBefore[j1], updatedVariablesInNewUpdate[j2], usedVariableInNewUpdate[j2]))
                    {
                        model.CreateTemporaryVar();
                        Expression newUpdate1;
                        Expression newUpdate2;

                        PropertyAssignment assignment = this as PropertyAssignment;
                        newUpdate1 = new Assignment(Model.TEMPORARY_VARIABLE, this.RightHandExpression);
                        newUpdate2 = new PropertyAssignment(this.RecordExpression, this.PropertyExpression, new Variable(Model.TEMPORARY_VARIABLE));

                        resultBefore.Ref();
                        ExpressionBDDEncoding tempResult1 = newUpdate1.TranslateStatementToBDD(resultBefore, model);
                        ExpressionBDDEncoding tempResult2 = newUpdate2.TranslateStatementToBDD(tempResult1, model);

                        //Remove the temporary variable from transition
                        for (int i = 0; i < tempResult2.Count(); i++)
                        {
                            tempResult2.GuardDDs[i] = CUDD.Abstract.ThereExists(tempResult2.GuardDDs[i], model.GetRowVars(Model.TEMPORARY_VARIABLE));
                            tempResult2.GuardDDs[i] = CUDD.Abstract.ThereExists(tempResult2.GuardDDs[i], model.GetColVars(Model.TEMPORARY_VARIABLE));

                            tempResult.AddNodeToGuard(tempResult2.GuardDDs[i]);
                        }
                    }
                    else
                    {
                        //swap row, col updated variable in result in the new update command expression
                        CUDDNode update2 = newUpdate.GuardDDs[j2];
                        CUDD.Ref(update2);
                        foreach (int index in updatedVariablesBefore[j1])
                        {
                            if (usedVariableInNewUpdate[j2].Contains(index))
                            {
                                update2 = CUDD.Variable.SwapVariables(update2, model.GetColVars(index), model.GetRowVars(index));
                            }
                        }

                        //Restrict updated variable in new update of the old update
                        CUDDNode update1 = resultBefore.GuardDDs[j1];
                        CUDD.Ref(update1);
                        foreach (int index in updatedVariablesInNewUpdate[j2])
                        {
                            if (updatedVariablesBefore[j1].Contains(index))
                            {
                                update1 = CUDD.Abstract.ThereExists(update1, model.GetColVars(index));
                            }
                        }

                        CUDDNode transition = CUDD.Function.And(update1, update2);
                        tempResult.AddNodeToGuard(transition);
                    }
                }
            }

            resultBefore.DeRef();
            newUpdate.DeRef();

            return tempResult;
        }
Example #4
0
        /// <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);
        }
Example #5
0
        /// <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;
        }
Example #6
0
        /// <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;
        }
Example #7
0
        /// <summary>
        /// Encode this assignment in a sequence of statements. Return variable values after this assignment based on the current value in resultBefore
        /// [ REFS: 'result', DEREFS: 'resultBefore' ]
        /// </summary>
        public override ExpressionBDDEncoding TranslateStatementToBDD(ExpressionBDDEncoding resultBefore, Model model)
        {
            ExpressionBDDEncoding newUpdate = this.TranslateBoolExpToBDD(model);

            ExpressionBDDEncoding tempResult = new ExpressionBDDEncoding();

            List <List <int> > updatedVariablesInNewUpdate = new List <List <int> >();

            for (int index = 0; index < newUpdate.Count(); index++)
            {
                updatedVariablesInNewUpdate.Add(model.GetColSupportedVars(newUpdate.GuardDDs[index]));
            }

            List <List <int> > usedVariableInNewUpdate = new List <List <int> >();

            for (int index = 0; index < newUpdate.Count(); index++)
            {
                usedVariableInNewUpdate.Add(model.GetRowSupportedVars(newUpdate.GuardDDs[index]));
            }

            List <List <int> > updatedVariablesBefore = new List <List <int> >();

            for (int index = 0; index < resultBefore.Count(); index++)
            {
                updatedVariablesBefore.Add(model.GetColSupportedVars(resultBefore.GuardDDs[index]));
            }

            for (int j1 = 0; j1 < resultBefore.Count(); j1++)
            {
                for (int j2 = 0; j2 < newUpdate.Count(); j2++)
                {
                    //a variable is already updated, now is updated again and it also apprears in the value expression
                    if (Assignment.IsComplexUpdate(updatedVariablesBefore[j1], updatedVariablesInNewUpdate[j2], usedVariableInNewUpdate[j2]))
                    {
                        model.CreateTemporaryVar();
                        Expression newUpdate1;
                        Expression newUpdate2;

                        PropertyAssignment assignment = this as PropertyAssignment;
                        newUpdate1 = new Assignment(Model.TEMPORARY_VARIABLE, this.RightHandExpression);
                        newUpdate2 = new PropertyAssignment(this.RecordExpression, this.PropertyExpression, new Variable(Model.TEMPORARY_VARIABLE));

                        resultBefore.Ref();
                        ExpressionBDDEncoding tempResult1 = newUpdate1.TranslateStatementToBDD(resultBefore, model);
                        ExpressionBDDEncoding tempResult2 = newUpdate2.TranslateStatementToBDD(tempResult1, model);

                        //Remove the temporary variable from transition
                        for (int i = 0; i < tempResult2.Count(); i++)
                        {
                            tempResult2.GuardDDs[i] = CUDD.Abstract.ThereExists(tempResult2.GuardDDs[i], model.GetRowVars(model.GetVarIndex(Model.TEMPORARY_VARIABLE)));
                            tempResult2.GuardDDs[i] = CUDD.Abstract.ThereExists(tempResult2.GuardDDs[i], model.GetColVars(model.GetVarIndex(Model.TEMPORARY_VARIABLE)));

                            tempResult.AddNodeToGuard(tempResult2.GuardDDs[i]);
                        }
                    }
                    else
                    {
                        //swap row, col updated variable in result in the new update command expression
                        CUDDNode update2 = newUpdate.GuardDDs[j2];
                        CUDD.Ref(update2);
                        foreach (int index in updatedVariablesBefore[j1])
                        {
                            if (usedVariableInNewUpdate[j2].Contains(index))
                            {
                                update2 = CUDD.Variable.SwapVariables(update2, model.GetColVars(index), model.GetRowVars(index));
                            }
                        }

                        //Restrict updated variable in new update of the old update
                        CUDDNode update1 = resultBefore.GuardDDs[j1];
                        CUDD.Ref(update1);
                        foreach (int index in updatedVariablesInNewUpdate[j2])
                        {
                            if (updatedVariablesBefore[j1].Contains(index))
                            {
                                update1 = CUDD.Abstract.ThereExists(update1, model.GetColVars(index));
                            }
                        }

                        CUDDNode transition = CUDD.Function.And(update1, update2);
                        tempResult.AddNodeToGuard(transition);
                    }
                }
            }

            resultBefore.DeRef();
            newUpdate.DeRef();

            return(tempResult);
        }