While converting very old models, I found an interesting problem related to turtle buttons.
The model (created with NetLogo 4.1) contains several turtle buttons (not “forever”).
Then for structured experimentation, the model logs the actions (at button level) in a list.
For testing variations, there is an observer procedure that executes the actions from the list.
In the old model, the observer procedure uses ask-concurrent to simulate the turtle button.
This works well in NetLogo 4.1 through 4.1.3, but breaks in any newer version.
The documentation of the operation of turtle buttons is still essentially the same is before.
However, the documentation of ask-concurrent says that new models should not use it, and that newer versions might break code that relies on it.
Now my question is: How can I simulate the turtle buttons in a context of the observer?
As an illustration, I include a reduced (abstracted) version of the model (in NetLogo 7.0.3). Next to each turtle button, I added an “equivalent” observer button. They do work as intended!
But the run-codes-x button gives a (very cryptic) error messages.
An alternative run-codes button, not using foreach, does work still…
As far as I know, there is no way to simulate the behavior of a turtle button in observer code, since observer code always runs serially. If I’m understanding your issue correctly, you might be able to get the desired behavior with something like this:
; this could also be a chooser widget
globals [ variation ]
; this is called by a button widget
to var-1
set variation "one"
end
; this is called by a button widget
to var-2
set variation "two"
end
; this is called by the turtle button
to update-turtle
if-else variation = "one" [
; do variation one
] [
; do variation two
]
end
Let me know if I misunderstood the problem or if this pattern doesn’t achieve the behavior you want.
Thank you for your answer. So, I gather that it is not intended that ask-concurrent emulates a turtle button.
As I read your code, it does not actually replace a turtle button. It only encapsulates multiple behaviors in one turtle button. In fact, I think it makes automating the process only harder, because now the replacement code not only must control replacement code for the turtle buttons but also control the chooser/global.
In the NetLogo 4.1 model, I had something similar to the turtle buttons and run-codes-x button of the example I posted earlier.
The info tab of the posted model says:
So, if I avoid contexts that break ask-concurrent, it seems that a turtle button and an observer button using ask-concurrent on the same code do exactly the same. (Still in NetLogo 7.0.3)
Or is this just a coincidence?
It seems like there might be some confusion about the behavior of turtle buttons and ask-concurrent. In contrast to the ask* primitives, turtle buttons do not wait for the code to be executed by all turtles before continuing; each turtle runs the code over and over without regard to the progress of other turtles. Technically, you might consider this a “concurrent ask”, however this is not the behavior of ask-concurrent. With ask, each turtle runs the provided code in its entirety before moving on to the next turtle. But with ask-concurrent, the turtles instead take turns running the provided instructions (the details of this can be found here). Both ask and ask-concurrent do not return until the code has been run for all turtles; the only difference is in the order of execution of the provided instructions. Hopefully this clears things up, but let me know if I need to clarify anything further.
Regarding the code I provided: I think I may have misunderstood the behavior you were asking for. My goal was not to replace a turtle button, but rather to allow observer code to control the behavior within a turtle button, because I thought your problem was that you couldn’t “call” a turtle button’s code as the observer. If that’s not the issue you encountered, could you clarify what exactly the problem was or what your goal was with the relevant model?
Thank you. This is the answer to my question, if not the answer I hoped for…
So, it is a coincidence that the turtle buttons and “equivalent” observer buttons using ask-concurrent do exactly the same in my example model.
In the next message, I will explain the context for this question a bit further.
In the old (NetLogo 4.1) model, I had started with turtle buttons. It is essential that the turtles do their actions at the same time and not in turns. All turtles move and change the patches they visit, which again influences what other turtles do – in a sense this happens in the Termites example model as well.
The model had no real research goal. It was the spin-off of a graphical puzzle I had set myself.
By a small trick, an identification of the button was recorded (once for the button, not for all turtles) for further analysis.
Later, I wanted to investigate slightly different histories. Of course, I started clicking the buttons, but at some moment I wanted to automate that as well. That was when I introduced ask-concurrent in observer context. It did work well, and I have not noticed any problems.
Now, while updating my old models, the code of this particular model did not work anymore.
I found that ask-concurrent is the culprit, but also that I shouldn’t use it anymore.
However, rewriting the turtle behavior to take small steps in turn (for using non-concurrent ask) is quite complicated.
I have checked the State Machine Example model for the changes made to the Termites model, but I’m afraid the actions taken by my turtles are so much more complicated that the same approach would become unwieldy and error-prone.
For now, I will settle with still using ask-concurrent, but replacing the turtle buttons by the “equivalent” observer buttons. At least, this makes behavior reproducible, at the risk of breaking the model again with a newer NetLogo version.