Is there a workaround for using the > operator on more than one turtle breed? - operators

My model has a a number of turtle breeds and I want them to avoid each other according to size. So turtle 1 with size = 1 will avoid turtle 2 with size = 2 and so on.
The code that generates the error is:
ask turtles with [color = green]
[if not any? turtles in-radius vision with [size > self][avoid]
And the error I get is
"The > operator can only be used on two numbers, two strings, or two agents of the same type, but not on a number and a turtle."
I think I understand the error but my question is is there a workaround for this problem?
Thanks

This has nothing to do with breeds. The problem is the one described by the error: you can't compare size directly with self (which is a turtle, not a number).
You need to do:
with [ size > [ size ] of myself ]
(And note that inside the with block, you need to use myself instead of self.)

Related

Is it possible to create LOCAL variable dynamically in rebol / red?

It is easy to create GLOBAL variables dynamically in rebol / red with set like
i: 1
myvarname: rejoin ["var" i]
set to-word myvarname 10
var1
but then var1 is global. What if I want to create var1 dynamically inside a function and make it LOCAL so as to avoid collision with some global variables of same name ?
In javascript it is possible:
How to declare a dynamic local variable in Javascript
Not sure it is possible in rebol/red ?
In Red you have function, in Rebol2 you have funct. Both create local variable words automatically. Here an example for Rebol2
>> for num 1 100 1 [
[ set to-word rejoin ["f" num] funct [] compose/deep [
[ print [ "n =" n: (num) ]
[ ]
[ ]
>> f1
n = 1
>> f2
n = 2
>> n
** Script Error: n has no value
** Near: n
How it is done, you can see with source funct
In Rebol, there is USE:
x: 10
word: use [x] [
x: 20
print ["Inside the use, x is" x]
'x ;-- leak the word with binding to the USE as evaluative result
]
print ["Outside the use, plain x is" x]
print ["The leaked x from the use is" get word]
That will give you:
Inside the use, x is 20
Outside the use, x is 10
The leaked x from the use is 20
One should be forewarned that the way this works is it effectively does a creation like make object! [x: none]. Then it does a deep walk of the body of the USE, looking for ANY-WORD! that are named x (or X, case doesn't matter)...and binds them to that OBJECT!.
This has several annoying properties:
The enumeration and update of bindings takes time. If you're in a loop it will take this time each visit through the loop.
The creation of the OBJECT! makes two series nodes, one for tracking keys (x) and one for tracking vars (20). Again if you are in a loop, the two series nodes will be created each time through that loop. As the GET outside the loop shows, these nodes will linger until the garbage collector decides they're not needed anymore.
You might want to say use [x] code and not disrupt the bindings in code, hence the body would need to be deep copied before changing it.
The undesirable properties of deep binding led Red to change the language semantics of constructs like FOR-EACH. It currently has no USE construct either, perhaps considered best to avoid for some of the same reasoning.
(Note: New approaches are being investigated on the Rebol side for making the performance "acceptable cost", which might be good enough to use in the future. It would be an evolution of the technique used for specific binding).

netlogo: Check whether a certain turtle is ahead of current moving turtle

A. In NetLogo, I want to check which type of turtle is ahead of the current moving turtle. I try to do this through looking at the shape or color of the turtle ahead. Context: i want the moving turtle to check whether it meets a moving enemy, if so, the moving turtle should avoid the moving enemy
I tried this line as condition:
if [color] of turtles-on patch-ahead 0 = yellow [do this]
B. And I would like to check whether a certain turtle is overlapping the current moving turtle with this code as condition.
if [color] of turtles-here = yellow [do this]
It doesn't give an error, but it doesn't do as intended.
[color] of turtles-here
returns a list of colors. yellow returns a number. So you're comparing a list with a number rather than a number with a number.
I think you'd like:
if any? turtles-here with [color = yellow] [do something]

Is it possible to implement DO + function in pure REBOL?

When DO is followed by a function, that function is executed and the remaining values are consumed as arguments according to the arity of the given function, e.g.,
do :multiply 3 4
multiply 3 4
These two statements are identical in their effects. But I think DO + function receives special treatment by the REBOL interpreter, because I don't believe it's possible to implement your own DO (with the exact same syntax) in pure REBOL, e.g.,
perform: func [f [any-function!]] [
; What goes here?
]
Is this correct?
Clarification
I am not asking about the DO dialect. This is not a "beginner" question. I understand REBOL's general syntax very, very well: Bindology (an old blog post I did on it), the implications of its homoiconicity, the various flavors of words, and all the rest. (For example, here is my implementation of Logo's cascade in REBOL. While I'm at it, why not plug my Vim syntax plug-in for REBOL.)
I'm asking something more subtle. I'm not sure how I can phrase it more clearly than I already have, so I'll ask you to read my original question more carefully. I want to achieve a function that, like DO, has the following capability:
do :multiply 3 4
double: func [n] [n * 2]
do :double 5
Notice how the syntax do :double or do :multiply consumes the appropriate number of REBOL values after it. This is the key to understanding what I'm asking. As far as I can tell, it is not possible to write your own REBOL function that can DO this.
You'll have answered this question when you can write your own function in pure REBOL that can be substituted for DO in the examples above—without dialects, blocks, or any other modifications—or explain why it can't be done.
The cause of the behavior you are seeing is specifically this line of code for the Rebol native DO.
/***********************************************************************
**
*/ REBNATIVE(do)
/*
***********************************************************************/
{
REBVAL *value = D_ARG(1);
switch (VAL_TYPE(value)) {
/* ... */
case REB_NATIVE:
case REB_ACTION:
case REB_COMMAND:
case REB_REBCODE:
case REB_OP:
case REB_CLOSURE:
case REB_FUNCTION:
VAL_SET_OPT(value, OPTS_REVAL); /* <-- that */
return R_ARG1;
This OPTS_REVAL can be found in sys-value.h, where you'll find some other special control bits...like the hidden "line break" flag:
// Value option flags:
enum {
OPTS_LINE = 0, // Line break occurs before this value
OPTS_LOCK, // Lock word from modification
OPTS_REVAL, // Reevaluate result value
OPTS_UNWORD, // Not a normal word
OPTS_TEMP, // Temporary flag - variety of uses
OPTS_HIDE, // Hide the word
};
So the way the DO native handles a function is to return a kind of "activated" function value. But you cannot make your own values with this flag set in user code. The only place in the entire codebase that sets the flag is this snippet in the DO native.
It looks like something that could be given the axe, as APPLY does this more cleanly and within the definitions of the system.
Yes, in Rebol 3:
>> perform: func [f [any-function!]] [return/redo :f]
>> perform :multiply 3 4
== 12
>> double: func [n] [n * 2]
>> perform :double 5
== 10
You might find it interesting to read: Why does return/redo evaluate result functions in the calling context, but block results are not evaluated?
This is a good question, and I will try to explain it to the best of my understanding.
The two statements above are identical in effect, but it is worth diving deeper into what is happening.
The :word syntax is known as a get-word! and is equivalent to writing get 'word. So another way of writing this would be
do get 'multiply 3 4
multiply is just another word! to Rebol.
The do dialect is the default dialect used by the Rebol interpreter.
If you want to implement your own version of do you need to be evaluating your code/data yourself, not using do. Here is a trivial example:
perform: func [ code [block!]] [ if equal? code [ 1 ] [ print "Hello" ] ]
This defines perform as a function which takes a block of code. The "language" or dialect it is expecting is trivial in that the syntax is just perform an action (print "hello") if the code passed is the integer 1.
If this was called as
perform [ multiply 3 4 ]
nothing would happen as code is not equal to 1.
The only way it would do something is if it was passed a block! containing 1.
>> perform [ 1 ]
Hello
Expanding on this slightly:
perform: func [ code [block!]] [ if equal? code [ multiply 3 4 ] [ 42 ] ]
would give us a perform which behaves very differently.
>> perform [ multiply 3 4 ]
== 42
You can easily write your own do to evaluate your dialect, but if you run it directly then you are already running within the do dialect so you need to call a function of some kind to bootstrap your own dialect.
This jumping between dialects is a normal way to write Rebol code, a good example of this being the parse dialect
parse [ 1 2.4 3 ] [ some number! ]
which has it's own syntax and even reuses existing do dialect words such as skip but with a different meaning.

Turtles dying according to slider

I want to make a certain number of turtles (controlled by a slider) die every year. So far I got this, it is probably very straightforward but I can't seem to make it work.
Thanks a lot!
to hunting
let huntedturtles (count turtles = hunted-turtles) ; Hunted-turtles is the slider.
if ticks mod 365 = 0
[ask huntedturtles [die]]
set hunted hunted + hunted-monkeys
end
You're getting an error like ERROR: ASK expected this input to be an agent or agentset, but got a TRUE/FALSE instead, correct?
count turtles = hunted-turtles is checking whether or not the total number of turtles is equal to hunted-turtles. I don't think that's what you want. Instead, you probably want something like
let huntedturtles n-of hunted-turtles turtles
That's going to randomly choose hunted-turtles turtles.
Side note: huntedturtles and hunted-turtles are easily confusable variable names. Consider making the slider num-hunted-turtles or something similar, and the set of hunted turtles themselves hunted-turtles.

How to create dynamic links in Netlogo? - Global variables change values for agents, agents interact and then change their type accordingly

I have a system where the two global/systemic variables economic-output-x and environmental-damage-y depend on the distribution of four types of worldviews (utility-assumptions) of the agents in the model. These two state variables get distributed as internal values among all agents as income and exposure. These two marginal or individual distributed valus determine power to persuade (P2P) and susceptibility for persuasion (S4P). Each agent therefore has P2P-x and P2P-y as well as S4P-x and S4P-y.
When two agents meet (Compare former related question) they exchange their internal values of P2P and S4P, which could be conceptualised as a debate, a discussion or a clash of opinions. If the substraction of these values results in a number above a particular threshold, i.e. the range between the two values is high, the 'losing' agent changes his worldview to the other one's worldview (transition), which in turn has an impact on the global variables.
Therefore we have quite a nested network of interrelationships and feedback loops. I am having problems putting this into practice. I have also looked at quite some opinion-influence-models but none quite grasps it the way I am approaching it.
My first attempt looked like this:
ask turtles [ ; Agents are doing their thing
[if occupied = "yes" [
ifelse count-down > 0
[set count-down (count-down - 1)]
[; get the hell out of here
rt 180
fd 2
set occupied "no"
set count-down 3]
]
if occupied = "no" [ ; Wandering around, ignoring occupied agents
set neighbourhood other turtles in-radius 2]
; If someone interesting and unoccupied is near, communicate!
set nearest-neighbour one-of neighbourhood with-min [distance myself]
ifelse nearest-neighbour != nobody [ ; In case someone has been set as nearest-neighbour, encounter is set in motion
if ([ occupied ] of nearest-neighbour = "no") [
face nearest-neighbour
set occupied "yes"
[if ([ S4P-x ] of self < [ P2P-x ] of nearest-neighbour) [
set worldview [ worldview ] of nearest-neighbour ]
ask nearest-neighbour [
face myself
set occupied "yes"
if ([ S4P-x ] of self < [ P2P-x ] of myself) [set worldview [
worldview ] of myself ]
]
But that did not really work out. Plus, I am not quite sure whether this is the most elegant way. I doubt it.
Is there maybe an entry on this topic on Stackoverflow which I overlooked, which is a little easier to grasp? Or another functionality in NETLOGO, which might fit my needs more appropriately?
Thanks in advance.
I think you probably mean just P2P-x instead of [P2P-x] of myself, and I think you mean set worldview [worldview] of myself instead of set worldview [worldview of myself]. Does that fix it?
You probably don't need to use links unless you want to represent a relationship between turtles that persists over time. If the encounters between turtles are fleeting, involving links doesn't buy you anything.
I'd suggest you look at Communication T-T Example in the Code Examples section of the Models Library, and at other models where pairs of turtles meet and interact, such as PD N-Person Iterated.