Replies: 5 comments 1 reply
-
OK, I threw together a custom Agent class and added a brf like this:
and used this class for agent2 only. In synchronous mode, nothing happened with any agent until agent2 made it out of that. That seems reasonable and I think this is becoming a little bit clearer... but Using the same setup, I turned off Synchronous mode[1] and I still saw the exact same behavior. So now I'm really confused. [1]: I see in the PMASIAUJ book that Asynchronous mode is the default, so I assume that you get Asynchronous mode when you don't have an executionControl keyword in your .mas2j file at all? And that you get Synchronous mode when you use:
Or maybe there's something else going on that I am missing here? Am I not getting Asynchronous mode when I think I am for some reason? |
Beta Was this translation helpful? Give feedback.
-
Thinking out loud here... I did try something that does reveal a very subtle difference in the behavior between the two modes finally. I still don't fully grok the deep details of what's going on, but I think if I keep adding enough print statements and running enough experiments it will eventually all make sense. Here's what I did.
Comparing the outputs, this doesn't necessarily behave exactly the way I naively expected, but I can see that there is a difference in behavior. The change appears to be very subtle though: synchronous mode output
asynchronous mode output
Most notably I see that in synchronous mode, agent1 and agent3 respectively do their first action in cycle 0 and we don't see the "executing: slow action" line (triggered by agent 2) until later in the process. In synchronous mode, agents 1 and 3 do their first action in cycle number 1 and we see the action triggered by agent 2 earlier. This is actually backwards to my intuition, so clearly I still don't get exactly what's going on under the hood. Of course, some of the variance in these outputs could be noise, just random side effects of the vagaries of the underlying JVM thread scheduler, load on my CPU, etc. I guess I need to run each scenario a few dozen more times to see how reproducible all of this even is. :-) |
Beta Was this translation helpful? Give feedback.
-
Hi Philip,
Many thanks for the interesting question. You are right that using .wait or
long action is not a good way of noticing the difference of behaviour
because the agent might have other intentions to use their cycle turn.
Although we may discuss together that maybe this shouldn't be so and hence
improving the synchronous mode. One of the reasons this was created was to
allow simulation of reactive agents like many agent-based simulation
platforms had. If all plans are like
+b <- a. % where a is an action
You'll get a behaviour where each agent gets to execute one action in every
step of the simulation. Although not for your tests, using synchronous mode
changes EVERYTHING in the system. In fact it's very annoying that most bugs
that exist in asynchronous mode, if you just change to synchronous they
disappear, because they only happen in specific interleavings of the agents
threads that do not occur in "fair" executions (when an agent can only
execute one reasoning cycle and must immediately pass control to another
agent). And our debugger (the mind inspector) requires synchronization for
it to run. We always hoped for someone to come up with a mind inspector
that worked asynchronously exactly for that reason
…On Fri, 18 Oct 2024, 19:04 Phillip Rhodes, ***@***.***> wrote:
Hi Jason team, I'm back with another question. Sorry for the deluge of
these. I hope you'll be patient and bear with me. There's a lot to absorb
here!
So there's the question (apologies for it being so long winded. I'm still
trying to figure out what it even is that I'm missing!)
I am reading the PMASIAUJ book and am in Chapter 4, and reading the bit
about ExecutionControl. I see this paragraph:
All agents perform one reasoning cycle at every global 'execution step'. When an agent finishes its reasoning cycle, it informs Jason's controller and waits for a 'carry on' signal. The Jason controller waits until all agents have finished their reasoning and then sends the 'carry on' signal.
OK, so that makes perfect sense - conceptually. But in terms of
understanding the practical significance, I've been having a bit of a
struggle. This may be in part because of my background as (mostly) a Java
programmer and my instinct to see things in terms of normal Java program
flow control. But in either case...
I read this and immediately find myself wanting to understand what kind of
situation would result in the difference between asynchronous mode and
synchronous mode actually changing the program behavior. I have tried to
intentionally construct such a situation and have failed so far. I think
I'm starting to understand why that is, but that still leaves me with some
doubts.
So... to the end of trying to see some behavior change, I implemented a
simple MAS with 3 agents - agent1, agent2, and agent3. In agent1 and agent3
I put some simple plan that triggers on +started, with a few actions in the
body of the plan, including some .print() actions. In agent2 I did more or
less the same thing except I put a .wait() as the first action. I had
initially though that that .wait() would cause agent2 to take longer to get
through it's reasoning loop, and would hold up some of the actions in
agent1 and agent3. I did not observe that however.
Then I read more of the docs and see that .wait() suspends the current
intention while it waits. I assume that means the agent is free to continue
through its reasoning loop while that intention is suspended?
As my next experiment I wrote a custom action to spit out the cycle
number, and made that the first action in the plan in each agent, to verify
that all of the agents truly start at "time step 0" (aka cycle number 0).
That did indeed turn out to be the case.
Having verified that, I tried putting a long running external action in
agent2 instead of a .wait(). And again, this does not prevent any of the
agents from proceeding. I finally did custom subclass of ExecutionControl
and added some extra logging statements just so I could confirm that agent2
is happily sending a message to *receiveFinishedCycle()* even while the
external action is sitting in a long Thread.sleep() section.
Upon further examination I found in the PMASIAUJ book (pg 82) that
So it sounds like .wait() and external actions both have the same effect in this regard and neither will affect how the agent cycles through the reasoning loop? **Is this a correct understanding?**
And, if the above understanding is correct, **can anybody share an example of the kind of situation where something would affect the ability of the agent to traverse through the reasoning loop, and would result in a difference in behavior between asynchronous mode and synchronous mode?** Maybe a call to perceive() or buf() that takes a longer time?
Finally, FWIW, I found one example in the jason_examples dir that ships with the Jason distribution that uses the executionControl flag in its .mas2j file. That being the "room" example. It's set to run in synchronous mode by default. So I ran that, then commented out the executionControl flag to let it default back to asynchronous mode. And I didn't see any apparent change in the output behavior of that system either. Should I have, or is that an unreasonable expectation?
Thanks in advance for any and all advice on this!
—
Reply to this email directly, view it on GitHub
<#114>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACMU7UDMWEIUMHA4GY63S3DZ4GAWBAVCNFSM6AAAAABQGYYDU2VHI2DSMVQWIX3LMV43ERDJONRXK43TNFXW4OZXGMZTSMJXGY>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Following up on my own question. I now see that there is a doc in the Jason docs area that deals specifically with concurrency. I guess I should spend more time looking at the online docs and not just limit myself to reading the "Programming Multiagent Systems in AgentSpeak Using Jason" book. :-) https://github.com/jason-lang/jason/blob/master/doc/tech/concurrency.adoc |
Beta Was this translation helpful? Give feedback.
-
Yes, these things in this doc were created after the book, mostly by a
student of Jomi. Note that the synchronous/ asynchronous concepts there are
not the same as execution modes you were referring to earlier
…On Tue, 22 Oct 2024, 15:24 Phillip Rhodes, ***@***.***> wrote:
Following up on my own question. I now see that there is a doc in the
Jason docs area that deals specifically with concurrency. I guess I should
spend more time looking at the online docs and not just limit myself to
reading the "Programming Multiagent Systems in AgentSpeak Using Jason"
book. :-)
https://github.com/jason-lang/jason/blob/master/doc/tech/concurrency.adoc
—
Reply to this email directly, view it on GitHub
<#114 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACMU7UA3QTA77646L24GBHTZ42J5RAVCNFSM6AAAAABQGYYDU2VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTCMBSGA3DENI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Hi Jason team, I'm back with another question. Sorry for the deluge of these. I hope you'll be patient and bear with me. There's a lot to absorb here!
So here's the question (apologies for it being so long winded. I'm still trying to figure out what it even is that I'm missing!)
I am reading the PMASIAUJ book and am in Chapter 4, and reading the bit about ExecutionControl. I see this paragraph:
OK, so that makes perfect sense - conceptually. But in terms of understanding the practical significance, I've been having a bit of a struggle. This may be in part because of my background as (mostly) a Java programmer and my instinct to see things in terms of normal Java program flow control. But in either case...
I read this and immediately find myself wanting to understand what kind of situation would result in the difference between asynchronous mode and synchronous mode actually changing the program behavior. I have tried to intentionally construct such a situation and have failed so far. I think I'm starting to understand why that is, but that still leaves me with some doubts.
So... to the end of trying to see some behavior change, I implemented a simple MAS with 3 agents - agent1, agent2, and agent3. In agent1 and agent3 I put some simple plan that triggers on +started, with a few actions in the body of the plan, including some .print() actions. In agent2 I did more or less the same thing except I put a .wait() as the first action. I had initially thought that the .wait() would cause agent2 to take longer to get through it's reasoning loop, and would hold up some of the actions in agent1 and agent3. I did not observe that however.
Then I read more of the docs and see that .wait() suspends the current intention while it waits. I assume that means the agent is free to continue through its reasoning loop while that intention is suspended?
As my next experiment I wrote a custom action to spit out the cycle number, and made that the first action in the plan in each agent, to verify that all of the agents truly start at "time step 0" (aka cycle number 0). That did indeed turn out to be the case.
Having verified that, I tried putting a long running external action in agent2 instead of a .wait(). And again, this does not prevent any of the agents from proceeding. I finally did custom subclass of ExecutionControl and added some extra logging statements just so I could confirm that agent2 is happily sending a message to receiveFinishedCycle() even while the external action is sitting in a long Thread.sleep() section.
Upon further examination I found in the PMASIAUJ book (pg 82) that
So it sounds like .wait() and external actions both have the same effect in this regard and neither will affect how the agent cycles through the reasoning loop? Is this a correct understanding?
And, if the above understanding is correct, can anybody share an example of the kind of situation where something would affect the ability of the agent to traverse through the reasoning loop, and would result in a difference in behavior between asynchronous mode and synchronous mode? Maybe a call to brf() or buf() that takes a longer time?
Finally, FWIW, I found one example in the jason_examples dir that ships with the Jason distribution that uses the executionControl flag in its .mas2j file. That being the "room" example. It's set to run in synchronous mode by default. So I ran that, then commented out the executionControl flag to let it default back to asynchronous mode. And I didn't see any apparent change in the output behavior of that system either. Should I have, or is that an unreasonable expectation?
Thanks in advance for any and all advice on this!
Beta Was this translation helpful? Give feedback.
All reactions