Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Papyrus for Real Time » guards & triggers(finding state of in-port)
guards & triggers [message #1792762] Mon, 23 July 2018 15:43 Go to next message
Sneha Sahu is currently offline Sneha SahuFriend
Messages: 20
Registered: June 2018
Junior Member
I have a protocol p with 3 msgs - in, out & inOut.

A capsule (with port p1 of type p) state has 2 transitions - t1 & t2.
t1 triggered with inOut
t2 triggered with in.

Now I want to put a check/guard on t1, such that the corresponding set of actions carried iff there is nothing received through 'in' .
Which means in case there is a scenario where port p1 recieves 2 messages 'in' & 'inOut', thereby triggering both t2 and t1 respectively, then this additional guard on t1 should prevent t1 from executing and only t2 must trigger.

I hope the scenario is not confusing.

Please let me know if something like this is possible.

Thanks,
Sneha Sahu
Re: guards & triggers [message #1792770 is a reply to message #1792762] Mon, 23 July 2018 16:50 Go to previous messageGo to next message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 438
Registered: March 2011
Senior Member
I'm not sure I understand you scenario: you want t1 (which has trigger inOut) to fire if and only if "there is nothing through 'in'"?

I think you might have some confusion about the semantics of UML-RT (and UML State Machines). In UML-RT, a capsule receives and handles only one message at a time. If the environment (other capsules) send messages to the capsule "at the same time", either to the same port or different ports, these messages are queued by the controller that runs the capsule. (There is one queue per controller, not one queue per port or per capsule). Then the capsule processes each such message fully and independently before processing the other message (this is called "run-to-completion semantics". If the messages arrived at the same time, they will be fed to the capsule according to their priority. If they have the same priority, they will be fed to it in order of arrival.

Now, whenever a capsule is in a state with several outgoing transitions and receives a message 'm', only a subset of those transitions will be *enabled*. Namely, those transitions which 1) have 'm' as its trigger and 2) its guard (if any) evaluates to 'true'. If a transition has no guard, you can think of it as having a guard that always evaluates to true. So only a (possibly empty) subset of the outgoing transitions of a state will satisfy these conditions. If there is more than one transition satisfying these, one of them will be selected arbitrarily (non-determinism), but it should always be the same one selected. Once the transition has been selected, its action is executed. If no transitions satisfy these conditions, there will be an "unexpected message" error and the capsule will remain in the same state.

So this means that if your capsule is an a state S with two outgoing transitions t1 and t2 with triggers 'inOut' and 'in' respectively, only one of them will be (potentially enabled) as only the message 'inOut' or 'in' will be processed by the capsule. Now, if the environment sends both messages at the "same time", assuming they have the same priority, they will be queued in any order, either [inOut,in] or [in,inOut]. In the first case, inOut is sent to the capsule, and only t1 will be enabled (assuming the guard is true) and therefore only t1 is executed, regardless of the fact that there is an 'in' message behind in the queue. Similarly, in the second case, 'in' is sent to the queue and so only t2 will be enabled.

I'm not sure what you mean by "there is nothing received through 'in'". 'in' is a message, so do you mean a message that carries no data? or perhaps you meant that there is another port and nothing arrives at the other port? If the former, whether a message carries some data or not depends on how the message is defined (does it have parameters, what type)? If the latter, this would require some operation that polls ports, but as explained above, ports in UML-RT don't have message queues, it's controllers who have those queues, so such an operation would need to check the controller queue to see if there is already a message directed to that port in the queue, but there is no such operation provided by the runtime. In other words, there is no way to poll a port in UML-RT. Ports in UML-RT are strictly reactive: a transition is enabled iff it's trigger message is the message it got from the controller, and if a transition is not enabled then, either its guard evaluates to false or its trigger is not the message currently being processed, but there is no relation between the 'enabledness' of a transition and whether its trigger is somewhere in the back of the queue, as it depends exclusively on what's in the front of the queue.






Re: guards & triggers [message #1792779 is a reply to message #1792770] Mon, 23 July 2018 22:00 Go to previous messageGo to next message
Sneha Sahu is currently offline Sneha SahuFriend
Messages: 20
Registered: June 2018
Junior Member
Thank you for explaining it so clearly.
I suppose I need to think of an alternative approach. Maybe you could suggest a better way out.

-------------------
I have 4 capsules(cap1,2,3,4) and 2 protocols(p,q) in my model.
[ protocol p :: out stop(), in Start(), inOut Run() ]
cap1 sends/multicasts Run() through p1(~p) to cap2(p2),3(p3),4(p4) .
cap3 and cap4 also communicate with q3 & q4 (not relevant here).

"what I want to achieve is, cap1 should continue to send Run() through p1 until it receives stop() from any of p2,p3,p4."

To get this loop, I was sending a reply from p2 for each incoming run().
But this is creating problem when stop() is sent by p3 or p4 instead of p2.
-------------------
I tried to make of a local flag attribute in cap1 that changes to true when stop() is received and use this as a guard for the transition being triggered from run().
But this still allows the 1 extra run() from p2 which is sent before p3 or p4 sends stop()
-------------------

I am not sure if the explanation is making any sense to you. In short I want to continuously send msg m1 through a port to 3 capsules and they would perform the defined course of action each time, until one of them decides to reply with msg m2. Post this the sending of m1 should stop for all 3.

Re: guards & triggers [message #1792781 is a reply to message #1792779] Mon, 23 July 2018 22:52 Go to previous messageGo to next message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 438
Registered: March 2011
Senior Member
Do you mean that you have a capsule that acts as a "director", sending a "run" message to a set of capsules, so that they all perform a "step" and then they all reply "run" as well to indicate they have finished the step, but it is possible that at some point one of those capsules replies "stop" telling the controller to stop all capsules?

Re: guards & triggers [message #1792797 is a reply to message #1792781] Tue, 24 July 2018 08:39 Go to previous messageGo to next message
Sneha Sahu is currently offline Sneha SahuFriend
Messages: 20
Registered: June 2018
Junior Member
yes exactly.
Re: guards & triggers [message #1792842 is a reply to message #1792781] Wed, 25 July 2018 02:38 Go to previous messageGo to next message
Sneha Sahu is currently offline Sneha SahuFriend
Messages: 20
Registered: June 2018
Junior Member
Ernesto Posse wrote on Mon, 23 July 2018 22:52
Do you mean that you have a capsule that acts as a "director", sending a "run" message to a set of capsules, so that they all perform a "step" and then they all reply "run" as well to indicate they have finished the step, but it is possible that at some point one of those capsules replies "stop" telling the controller to stop all capsules?



Thank you for the brief. It helped me figure out another approach.
I was able to achieve what I wanted using an integer counter for each run received and using the same as a guard before triggering the transaction.

However, I wanted to confirm if it is mandatory to have 1 outgoing transition for every possible incoming message over a port, for every state in the state diagram for a capsule. (something similar to finite state automatons, where we must have at least 1 out-going edge for every input symbol)
Re: guards & triggers [message #1792916 is a reply to message #1792842] Wed, 25 July 2018 17:30 Go to previous message
Ernesto Posse is currently offline Ernesto PosseFriend
Messages: 438
Registered: March 2011
Senior Member
Right. To achieve this sort of behaviour there are several different patterns that can be used. Generally they involve a "director" capsule and a set of "directed" capsules that communicate using some "Control" protocol. The director tells each of the directed to "go", or perform a "step" or "run", however you'd like to call it, and then waits for all to finish. This is essentially doing what in concurrent programming is called a "join" or "barrier". Thean, each of the directed sends a message saying "I finished my step", or "I'm ready", etc. When the director receives answers from all, it can decide whether to send a "go" message again (to repeat), or do something else, like stop. In your case, one of the directed capsules can tell the director to end, so when the director receives such message, it can send a "stop" message to each of the directed, to stop cleanly.

Usually, to ensure well-behaviour, the director should wait for each of the directed to be ready, again, by waiting for a "ready" message from each of them.

Waiting for a message from a set of capsule parts can be achieved in several ways, but perhaps the easiest is using a counter (which is probably what you did) that keeps track of how many messages you have received, and then using a choice point: if it has received less than the expected number, return to the listening/waiting state, otherwise, go to some other state. This approach is simple, and works in simple scenarios, but in some scenarios, there is the possibility of a race condition, e.g. if a capsule sends the message to the director twice as fast as another one, then the counter may be counting the wrong capsules, so you may need to keep track not only of how many messages you have received, but who exactly sent them, and make the decision when it is certain that the message has been received from each of the different capsules.

I'm attaching an example of the simple "Director-directed" pattern. It uses inheritance and hierarchical state machines (some states are refined in subclasses to specialize their behaviour) to capture the essence of the behaviour in this pattern. There is are several capsules: TopBase, Director, Directed, Capsule1, Capsule2 and Top. Top is a subclass of TopBase, simply redefining a state in its state machine. Capsule1 and Capsule2 are subclasses of Directed. Both redefine the "Running" state from the Directed capsule's state machine.

The Control protocol has the following messages:
* in ready: directed capsules use this to tell the director that they are ready to go
* out go: the director sends this to the directed capsules to run
* in end: one (or more) of the directed use this to tell the director that all should stop
* out stop: the director uses this to tell the directed to stop
* in stopped: the directed use this to tell the director that they have finally stopped.

The Top capsule first waits for a bit and then incarnates Capsule1 and Capsule2 into parts directed1 and directed2, which communicate with the Director via its 'control' port (which has replication 2, as there are two parts).

The Director first starts waiting for the directed capsules to be incarnated. This is done by listening to the 'rtBound' message on the control port (the 'control' port has to be declared as a 'notification' port, in its properties). This is to ensure that the parts exist and are ready, before the director starts sending them messages.

Once all directed parts are ready, the director sends them a 'go' message, and goes to its "Running" state where it waits for either a 'ready' message from each directed capsule or an 'end' message. If all capsules reply 'ready', it sends the 'go' message again and continues in "Running". If one capsule replies 'end', it goes to the "Stopping" state where it sends a 'stop' message to all, and waits for all to respond "stopped", after which it can safely call "exit(0)";

For their part, a directed capsule has three states: "WaitingForGoAhead", "Running" and "Stopped". In the first, it waits for the "go" signal from the director and then enters "Running". In "Running" it can receive a "stop" message and go to to "Stopped" where it sends "stopped" to the director. There is a transition from Running to WaitingForGoAhead which has an action (sends "ready" to the director) but no trigger. This is because the actual behaviour of "Running" is defined by subclasses of "Directed", by redefining this state. It is up to those subclasses to decide when to exit. Note that this uses explicit entry and exit points to make sure the right transition is taken to and from the Running state in the subclasses. Capsule1 and Capsule2 have their own internal behaviour that decides when to exit "Running" and go back to "WaitingForGoAhead". The transition from Running to Stopped triggered by "stop" is a group transition, so it will be enabled in all substates of Running.

Anyway, that is one way of doing this. There can be variations on this sort of pattern.

As for your question, no, it is *not* mandatory to have an outgoing transition for each possible incoming message (over any port) from a state. That would make the state machines very unwieldy. UMLRT State machines are not DFAs, although they look similar. If a capsule is in a state and an unexpected message arrives, then there will be a runtime error message shown, so you have to make the model deal with those cases. There are several ways of dealing with this: one is to create a transition that has "*" as trigger (you should see the * in the trigger selection dialog). The '*' means "any message". In this case, it is possible to defer the message (calling "msg.defer()" in the transition's action, and then calling one of the "recall" operations on a port, later on, i.e. "port.recall()", "port.recallAll()", "port.recallAt()", "port.recallFront()", "port.recallAllAt()" or "port.recallAllFront()"). Another possibility is override the 'void unexpectedMessage() const' method on the Capsule, by creating an Operation inside the capsule with that name and signature, and deciding what to do in its implementation. Finally, it may be that by construction it is impossible that a certain message arrives when the capsule is in some state, so it might not be necessary to do anything in that case. This is frequently what happens in practice.



Previous Topic:Requirement Specification
Next Topic:Unable to add log port in the middle of the capsule
Goto Forum:
  


Current Time: Thu Apr 18 20:22:33 GMT 2024

Powered by FUDForum. Page generated in 0.02981 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top