Пример #1
0
 public void Announce(PrtValue ev, PrtValue payload, PrtMachine parent)
 {
     foreach (var spec in specObservers[ev])
     {
         spec.PrtEnqueueEvent(ev, payload, parent);
     }
 }
Пример #2
0
        public void Announce(PrtEventValue ev, PrtValue payload, PrtMachine parent)
        {
            if (ev.Equals(PrtValue.@null))
            {
                throw new PrtIllegalEnqueueException("Enqueued event must not be null");
            }

            PrtType prtType = ev.evt.payloadType;

            //assertion to check if argument passed inhabits the payload type.
            if (prtType is PrtNullType)
            {
                if (!payload.Equals(PrtValue.@null))
                {
                    throw new PrtIllegalEnqueueException("Did not expect a payload value");
                }
            }
            else if (!PrtValue.PrtInhabitsType(payload, prtType))
            {
                throw new PrtInhabitsTypeException(String.Format("Payload <{0}> does not match the expected type <{1}> with event <{2}>", payload.ToString(), prtType.ToString(), ev.evt.name));
            }

            var allSpecMachines = GetSpecMachines(parent.renamedName);

            foreach (var mon in allSpecMachines)
            {
                if (mon.observes.Contains(ev))
                {
                    TraceLine("<AnnounceLog> Enqueued Event <{0}, {1}> to Spec Machine {2}", ev, payload, mon.Name);
                    mon.PrtEnqueueEvent(ev, payload, parent);
                }
            }
        }
Пример #3
0
        public PrtInterfaceValue CreateInterface(PrtMachine currMach, string interfaceOrMachineName, PrtValue payload)
        {
            //add visible action to trace
            if (visibleInterfaces.Contains(interfaceOrMachineName))
            {
                currentVisibleTrace.AddAction(interfaceOrMachineName, payload.ToString());
            }

            var renamedImpMachine = linkMap[currMach.renamedName][interfaceOrMachineName];
            var impMachineName    = machineDefMap[renamedImpMachine];
            var machine           = createMachineMap[impMachineName](this, payload);

            machine.isSafe      = isSafeMap[renamedImpMachine];
            machine.renamedName = renamedImpMachine;
            AddImplMachineToStateImpl(machine);

            CreateMachineCallback?.Invoke(machine);

            //TraceLine("<CreateLog> Machine {0}-{1} was created by machine {2}-{3}", currMach.renamedName, currMach.instanceNumber, machine.renamedName, machine.instanceNumber);
            TraceLine("<CreateLog> Machine {0}-{1} was created by machine {2}-{3}", machine.renamedName, machine.instanceNumber, currMach.renamedName, currMach.instanceNumber);

            if (interfaceMap.ContainsKey(interfaceOrMachineName))
            {
                return(new PrtInterfaceValue(machine, interfaceMap[interfaceOrMachineName]));
            }
            else
            {
                return(new PrtInterfaceValue(machine, machine.self.permissions));
            }
        }
Пример #4
0
        public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source)
        {
            if (e is PrtNullValue)
            {
                throw new PrtIllegalEnqueueException("Enqueued event must be non-null");
            }
            PrtType       prtType;
            PrtEventValue ev = e as PrtEventValue;


            //assertion to check if argument passed inhabits the payload type.
            prtType = ev.evt.payloadType;

            if (!(prtType is PrtNullType) && !PrtValue.PrtInhabitsType(arg, prtType))
            {
                throw new PrtInhabitsTypeException(String.Format("Payload <{0}> does not match the expected type <{1}> with event <{2}>", arg.GetString(), prtType.GetString(), ev.evt.name));
            }
            else if (prtType is PrtNullType && !(arg is PrtNullValue))
            {
                throw new PrtIllegalEnqueueException("Did not expect a payload value");
            }

            if (currentStatus == PrtMachineStatus.Halted)
            {
                stateImpl.Trace(
                    @"<EnqueueLog> {0}-{1} Machine has been halted and Event {2} is dropped",
                    this.Name, this.instanceNumber, ev.evt.name);
            }
            else
            {
                stateImpl.Trace(
                    @"<EnqueueLog> Enqueued Event <{0}, {1}> in {2}-{3} by {4}-{5}",
                    ev.evt.name, arg.GetString(), this.Name, this.instanceNumber, source.Name, source.instanceNumber);

                this.eventQueue.EnqueueEvent(e, arg);
                if (this.maxBufferSize != -1 && this.eventQueue.Size() > this.maxBufferSize)
                {
                    if (this.doAssume)
                    {
                        throw new PrtAssumeFailureException();
                    }
                    else
                    {
                        throw new PrtMaxBufferSizeExceededException(
                                  String.Format(@"<EXCEPTION> Event Buffer Size Exceeded {0} in Machine {1}-{2}",
                                                this.maxBufferSize, this.Name, this.instanceNumber));
                    }
                }
                if (currentStatus == PrtMachineStatus.Blocked && this.eventQueue.IsEnabled(this))
                {
                    currentStatus = PrtMachineStatus.Enabled;
                }
            }

            //Announce it to all the monitors
            stateImpl.Announce(e, arg, source);
        }
Пример #5
0
 public PrtValue ExecuteToCompletion(StateImpl application, PrtMachine parent, params PrtValue[] args)
 {
     parent.PrtPushFunStackFrame(this, CreateLocals(args));
     Execute(application, parent);
     if (parent.continuation.reason != PrtContinuationReason.Return)
     {
         throw new PrtInternalException("Unexpected continuation reason");
     }
     return(parent.continuation.retVal.Clone());
 }
Пример #6
0
        public void Announce(PrtEventValue ev, PrtValue payload, PrtMachine parent)
        {
            var allSpecMachines = GetSpecMachines(parent.renamedName);

            foreach (var mon in allSpecMachines)
            {
                if (mon.observes.Contains(ev))
                {
                    Trace("<AnnounceLog> Enqueued Event <{0}, {1}> to Spec Machine {2}", ev, payload, mon.Name);
                    mon.PrtEnqueueEvent(ev, payload, parent);
                }
            }
        }
Пример #7
0
 public virtual void DbgCompare(PrtMachine machine)
 {
     Debug.Assert(renamedName == machine.renamedName);
     Debug.Assert(isSafe == machine.isSafe);
     Debug.Assert(instanceNumber == machine.instanceNumber);
     Debug.Assert(fields.Count == machine.fields.Count);
     for (int i = 0; i < fields.Count; i++)
     {
         Debug.Assert(fields[i].GetHashCode() == machine.fields[i].GetHashCode());
     }
     Debug.Assert(eventValue.GetHashCode() == machine.eventValue.GetHashCode());
     Debug.Assert(stateStack.GetHashCode() == machine.stateStack.GetHashCode());
     Debug.Assert(invertedFunStack.GetHashCode() == machine.invertedFunStack.GetHashCode());
     Debug.Assert(continuation.GetHashCode() == machine.continuation.GetHashCode());
     Debug.Assert(currentStatus == machine.currentStatus);
     Debug.Assert(nextSMOperation == machine.nextSMOperation);
     Debug.Assert(stateExitReason == machine.stateExitReason);
     Debug.Assert(currentTrigger.GetHashCode() == machine.currentTrigger.GetHashCode());
     Debug.Assert(currentPayload.GetHashCode() == machine.currentPayload.GetHashCode());
     Debug.Assert((destOfGoto == null && machine.destOfGoto == null) ||
                  (destOfGoto != null && machine.destOfGoto != null && destOfGoto.GetHashCode() == machine.destOfGoto.GetHashCode()));
 }
Пример #8
0
        public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source, PrtMachineValue target = null)
        {
            PrtEventValue ev = e as PrtEventValue;

            if (ev.evt.name == "null")
            {
                throw new PrtIllegalEnqueueException("Enqueued event must not be null");
            }

            //check if the sent event is in source send set
            if (!source.sends.Contains(e as PrtEventValue))
            {
                throw new PrtIllegalEnqueueException(String.Format("Machine <0> cannot send event {1}", source.Name, e.ToString()));
            }

            //check if the sent event is in target permissions
            if (target is PrtInterfaceValue)
            {
                if (!(target as PrtInterfaceValue).permissions.Contains(e as PrtEventValue))
                {
                    throw new PrtIllegalEnqueueException(String.Format("Event {1} is not in the permission set of the target", e.ToString()));
                }
            }

            PrtType prtType = ev.evt.payloadType;

            //assertion to check if argument passed inhabits the payload type.
            if (prtType is PrtNullType)
            {
                if (!arg.Equals(PrtValue.@null))
                {
                    throw new PrtIllegalEnqueueException("Did not expect a payload value");
                }
            }
            else if (!PrtValue.PrtInhabitsType(arg, prtType))
            {
                throw new PrtInhabitsTypeException(String.Format("Payload <{0}> does not match the expected type <{1}> with event <{2}>", arg.ToString(), prtType.ToString(), ev.evt.name));
            }

            //check if the event sent is in the permissions

            if (currentStatus == PrtMachineStatus.Halted)
            {
                stateImpl.Trace(
                    @"<EnqueueLog> {0}-{1} Machine has been halted and Event {2} is dropped",
                    this.Name, this.instanceNumber, ev.evt.name);
            }
            else
            {
                stateImpl.Trace(
                    @"<EnqueueLog> Enqueued Event <{0}, {1}> in {2}-{3} by {4}-{5}",
                    ev.evt.name, arg.ToString(), this.Name, this.instanceNumber, source.Name, source.instanceNumber);
                this.eventQueue.EnqueueEvent(e, arg);
                if (this.maxBufferSize != DefaultMaxBufferSize && this.eventQueue.Size() > this.maxBufferSize)
                {
                    if (this.doAssume)
                    {
                        throw new PrtAssumeFailureException();
                    }
                    else
                    {
                        throw new PrtMaxBufferSizeExceededException(
                                  String.Format(@"<EXCEPTION> Event Buffer Size Exceeded {0} in Machine {1}-{2}",
                                                this.maxBufferSize, this.Name, this.instanceNumber));
                    }
                }
                if (currentStatus == PrtMachineStatus.Blocked && this.eventQueue.IsEnabled(this))
                {
                    currentStatus = PrtMachineStatus.Enabled;
                }
            }

            //Announce it to all the spec machines
            stateImpl.Announce(e as PrtEventValue, arg, source);
        }
Пример #9
0
 public abstract void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source);
Пример #10
0
 public abstract void Execute(StateImpl application, PrtMachine parent);
Пример #11
0
 public override void Execute(StateImpl application, PrtMachine parent)
 {
     throw new NotImplementedException();
 }
Пример #12
0
        public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source, PrtMachineValue target = null)
        {
            int numOfStepsTaken = 0;

            // set the currentTrigger and currentPayload fields
            // so that we can reuse the common functions
            currentPayload = arg.Clone();
            currentTrigger = e;

            PrtValue currEventValue;
            PrtFun   currAction;
            bool     hasMoreWork = false;

            try
            {
Start:
                switch (nextSMOperation)
                {
                case PrtNextStatemachineOperation.ExecuteFunctionOperation:
                    goto DoExecuteFunction;

                case PrtNextStatemachineOperation.HandleEventOperation:
                    goto DoHandleEvent;
                }

DoExecuteFunction:
                if (invertedFunStack.TopOfStack == null)
                {
                    //Trace: entered state
                    PrtFun entryFun = CurrentState.entryFun;
                    if (entryFun.IsAnonFun)
                    {
                        PrtPushFunStackFrame(entryFun, entryFun.CreateLocals(currentPayload));
                    }
                    else
                    {
                        PrtPushFunStackFrame(entryFun, entryFun.CreateLocals());
                    }
                }
                //invoke the function
                invertedFunStack.TopOfStack.fun.Execute(stateImpl, this);
                goto CheckFunLastOperation;

DoAction:
                currAction = PrtFindActionHandler(eventValue);
                if (currAction == PrtFun.IgnoreFun)
                {
                    //Trace: Performed ignore action for the event
                    currentTrigger = PrtValue.@null;
                    currentPayload = PrtValue.@null;
                }
                else
                {
                    if (invertedFunStack.TopOfStack == null)
                    {
                        //Trace: executed the action handler for event
                        if (currAction.IsAnonFun)
                        {
                            PrtPushFunStackFrame(currAction, currAction.CreateLocals(currentPayload));
                        }
                        else
                        {
                            PrtPushFunStackFrame(currAction, currAction.CreateLocals());
                        }
                    }
                    //invoke the action handler
                    invertedFunStack.TopOfStack.fun.Execute(stateImpl, this);
                }
                goto CheckFunLastOperation;

CheckFunLastOperation:
                switch (continuation.reason)
                {
                case PrtContinuationReason.Goto:
                {
                    stateExitReason = PrtStateExitReason.OnGotoStatement;
                    nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation;
                    PrtPushExitFunction();
                    goto DoExecuteFunction;
                }

                case PrtContinuationReason.Raise:
                {
                    nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                    hasMoreWork     = true;
                    goto Finish;
                }

                case PrtContinuationReason.Return:
                {
                    switch (stateExitReason)
                    {
                    case PrtStateExitReason.NotExit:
                    {
                        nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                        hasMoreWork     = false;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnGotoStatement:
                    {
                        PrtChangeState(destOfGoto);
                        currentTemperature = destOfGoto.temperature;
                        nextSMOperation    = PrtNextStatemachineOperation.ExecuteFunctionOperation;
                        stateExitReason    = PrtStateExitReason.NotExit;
                        hasMoreWork        = true;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnUnhandledEvent:
                    {
                        hasMoreWork     = !PrtPopState(false);
                        nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnTransition:
                    {
                        stateExitReason = PrtStateExitReason.OnTransitionAfterExit;
                        nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation;
                        PrtPushTransitionFun(eventValue);
                        goto DoExecuteFunction;
                    }

                    case PrtStateExitReason.OnTransitionAfterExit:
                    {
                        // The parameter to an anonymous transition function is always passed as swap.
                        // Update currentPayload to the latest value of the parameter so that the correct
                        // value gets passed to the entry function of the target state.
                        PrtTransition transition    = CurrentState.transitions[eventValue];
                        PrtFun        transitionFun = transition.transitionFun;
                        if (transitionFun.IsAnonFun)
                        {
                            currentPayload = continuation.retLocals[0];
                        }
                        PrtChangeState(transition.gotoState);
                        currentTemperature = transition.gotoState.temperature;
                        hasMoreWork        = true;
                        nextSMOperation    = PrtNextStatemachineOperation.ExecuteFunctionOperation;
                        stateExitReason    = PrtStateExitReason.NotExit;
                        goto Finish;
                    }

                    default:
                    {
                        Debug.Assert(false, "Unexpected value for exit reason");
                        goto Finish;
                    }
                    }
                }

                default:
                {
                    Debug.Assert(false, "Unexpected value for continuation reason");
                    goto Finish;
                }
                }

DoHandleEvent:
                if (!currentTrigger.Equals(PrtValue.@null))
                {
                    currEventValue = currentTrigger;
                    currentTrigger = PrtValue.@null;
                }
                else
                {
                    currEventValue = eventValue;
                }

                if (PrtIsTransitionPresent(currEventValue))
                {
                    stateExitReason = PrtStateExitReason.OnTransition;
                    nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation;
                    eventValue      = currEventValue;
                    PrtPushExitFunction();
                    goto DoExecuteFunction;
                }
                else if (PrtIsActionInstalled(currEventValue))
                {
                    eventValue = currEventValue;
                    goto DoAction;
                }
                else
                {
                    stateExitReason = PrtStateExitReason.OnUnhandledEvent;
                    nextSMOperation = PrtNextStatemachineOperation.ExecuteFunctionOperation;
                    eventValue      = currEventValue;
                    PrtPushExitFunction();
                    goto DoExecuteFunction;
                }

Finish:
                if (hasMoreWork)
                {
                    if (numOfStepsTaken > 100000)
                    {
                        throw new PrtInfiniteRaiseLoop("Infinite loop in spec machine");
                    }
                    else
                    {
                        numOfStepsTaken++;
                        goto Start;
                    }
                }
                else
                {
                    return;
                }
            }
            catch (PrtException ex)
            {
                stateImpl.Exception = ex;
            }
        }
Пример #13
0
 public abstract void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source, PrtMachineValue target = null);
Пример #14
0
 public override void DbgCompare(PrtMachine machine)
 {
     base.DbgCompare(machine);
     Debug.Assert(currentTemperature.GetHashCode() == (machine as PrtSpecMachine).currentTemperature.GetHashCode());
     Debug.Assert(GetHashCode() == machine.GetHashCode());
 }
Пример #15
0
        public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source)
        {
            int numOfStepsTaken = 0;

            // set the currentTrigger and currentPayload fields
            // so that we can reuse the common functions
            currentPayload = arg.Clone();
            currentTrigger = e;

            PrtValue currEventValue;
            PrtFun   currAction;
            bool     hasMoreWork = false;

            try
            {
Start:
                switch (nextSMOperation)
                {
                case PrtNextStatemachineOperation.EntryOperation:
                    goto DoEntry;

                case PrtNextStatemachineOperation.HandleEventOperation:
                    goto DoHandleEvent;
                }

DoEntry:
                if (invertedFunStack.TopOfStack == null)
                {
                    //Trace: entered state
                    if (CurrentState.entryFun.IsAnonFun)
                    {
                        PrtPushFunStackFrame(CurrentState.entryFun, CurrentState.entryFun.CreateLocals(currentPayload));
                    }
                    else
                    {
                        PrtPushFunStackFrame(CurrentState.entryFun, CurrentState.entryFun.CreateLocals());
                    }
                }
                //invoke the function
                invertedFunStack.TopOfStack.fun.Execute(stateImpl, this);
                goto CheckFunLastOperation;

DoAction:
                currAction = PrtFindActionHandler(eventValue);
                if (currAction == PrtCommonFunctions.IgnoreFun)
                {
                    //Trace: Performed ignore action for the event
                    currentTrigger = PrtValue.NullValue;
                    currentPayload = PrtValue.NullValue;
                }
                else
                {
                    if (invertedFunStack.TopOfStack == null)
                    {
                        //Trace: executed the action handler for event
                        PrtPushFunStackFrame(currAction, currAction.CreateLocals(currentPayload));
                    }
                    //invoke the action handler
                    invertedFunStack.TopOfStack.fun.Execute(stateImpl, this);
                }
                goto CheckFunLastOperation;

CheckFunLastOperation:
                switch (continuation.reason)
                {
                case PrtContinuationReason.Goto:
                {
                    stateExitReason = PrtStateExitReason.OnGotoStatement;
                    PrtExecuteExitFunction();
                    goto CheckFunLastOperation;
                }

                case PrtContinuationReason.Raise:
                {
                    nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                    hasMoreWork     = true;
                    goto Finish;
                }

                case PrtContinuationReason.Return:
                {
                    switch (stateExitReason)
                    {
                    case PrtStateExitReason.NotExit:
                    {
                        nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                        hasMoreWork     = false;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnGotoStatement:
                    {
                        PrtChangeState(destOfGoto);
                        nextSMOperation = PrtNextStatemachineOperation.EntryOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        hasMoreWork     = true;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnUnhandledEvent:
                    {
                        hasMoreWork     = !PrtPopState(false);
                        nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnTransition:
                    {
                        stateExitReason = PrtStateExitReason.OnTransitionAfterExit;
                        PrtExecuteTransitionFun(eventValue);
                        goto CheckFunLastOperation;
                    }

                    case PrtStateExitReason.OnTransitionAfterExit:
                    {
                        PrtChangeState(CurrentState.transitions[eventValue].gotoState);
                        hasMoreWork     = true;
                        nextSMOperation = PrtNextStatemachineOperation.EntryOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        goto Finish;
                    }

                    default:
                    {
                        Debug.Assert(false, "Unexpected value for exit reason");
                        goto Finish;
                    }
                    }
                }

                default:
                {
                    Debug.Assert(false, "Unexpected value for continuation reason");
                    goto Finish;
                }
                }

DoHandleEvent:
                if (!currentTrigger.IsEqual(PrtValue.NullValue))
                {
                    currEventValue = currentTrigger;
                    currentTrigger = PrtValue.NullValue;
                }
                else
                {
                    currEventValue = eventValue;
                }

                if (PrtIsTransitionPresent(currEventValue))
                {
                    stateExitReason = PrtStateExitReason.OnTransition;
                    eventValue      = currEventValue;
                    PrtExecuteExitFunction();
                    goto CheckFunLastOperation;
                }
                else if (PrtIsActionInstalled(currEventValue))
                {
                    goto DoAction;
                }
                else
                {
                    stateExitReason = PrtStateExitReason.OnUnhandledEvent;
                    eventValue      = currEventValue;
                    PrtExecuteExitFunction();
                    goto CheckFunLastOperation;
                }

Finish:
                if (hasMoreWork)
                {
                    if (numOfStepsTaken > 100000)
                    {
                        throw new PrtInfiniteRaiseLoop("Infinite loop in monitor");
                    }
                    else
                    {
                        numOfStepsTaken++;
                        goto Start;
                    }
                }
                else
                {
                    return;
                }
            }
            catch (PrtException ex)
            {
                stateImpl.Exception = ex;
            }
        }