My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Commands14  
Commands(Modeling Guide)
Updated Mar 20, 2012 by benoit.g...@gmail.com

Table of Contents



General syntax

A command is a keyword, followed by specific attributes, some of them mandatory (in bold), some of them optional. One of the attribute names can be ommitted (the one that is omissible in the sequel). It has to be the first one.

command_keyword expression1 attribute2: expression2 ... ;
or
command_keyword attribute1: expression1 attribute2: expression2 ...; 

If the command encloses other commands, they are declared between curly brakets, as in:

command_keyword1 expression1 attribute2: expression2... {
     command_keyword2 expression1 attribute2: expression2...;  
     command_keyword3 expression1 attribute2: expression2...;
}

add

Attributes

  • item (omissible): any expression
  • to: an expression that evaluates to a container
  • at: any expression

Definition

Allows the agent to add, i.e. to insert, a new element in a container (a list, matrix, map, ...).

The new element can be added either at the end of the container or at a particular position.

Incorrect use: The addition of a new element at a position out of the bounds of the container will produce a warning and let the container unmodified.

  add expr to: expr_container;    // Add at the end
  add expr at: expr to: expr_container;   // Add at position expr

Note that the behavior and the type of the attributes depends on the specific kind of container.

  • Case of a list

In the case of list, the expression in the attribute at: should be an integer.

let emptyList type: list value: [];
add 0 at: 0 to: emptyList ;   // emptyList now equals [0]
add 10 at: 0 to: emptyList ;   // emptyList now equals [10,0]
add 25 at: 2 to: emptyList ;   // emptyList now equals [10,0,20]
add 50 to: emptyList;    // emptyList now equals [10,0,20,50]
  • Case of a matrix

This command can not be used on matrix. Please refer to the command `put`.

  • Case of a map

As a map is basically a list of pairs key::value, we can also use the add command on it. It is important to note that the behavior of the command is slightly different, in particular in the use of the at attribute.

let emptyMap type: map value: [];
add "val1" at: "x" to: emptyMap;   // emptyList now equals [x::val1]

If the at: attribute is ommitted, a pair null::expr_item will be added to the map. An important exception is the case where the is a pair expression: in this case the pair is added.

add "val2" to: emptyMap;   // emptyList now equals [null::val2, x::val1]
add 5::"val4" to: emptyMap;   // emptyList now equals [null::val2, 5::val4, x::val1]

Notice that, as the key should be unique, the addition of an item at an existing position (i.e. existing key) will only modify the value associated with the given key.

add "val3" at: "x" to: emptyMap;   // emptyList now equals [null::value2, 5::val4, x::val3]

Top of the page

ask

Attributes

  • target (omissible): an expression that evaluates to an agent or a list of agents
  • as: an expression that evaluates to a species

Definition

Allows an agent, the sender agent, to ask another (or other) agent(s) to perform a set of commands. It obeys the following syntax, where the target attribute denotes the receiver agent(s):

ask receiver_agent(s) {
     [commands]
}
Or
ask target: receiver_agent(s) {
     [commands]
}

If the value of the target attribute is nil or empty, the command is ignored. The species of the receiver agents must be known in advance for this command to compile. If not, it is possible to cast them using the as attribute, like :

ask receiver_agent(s) as: a_species_expression {
     [command_set]
}

Alternative forms for this casting are :

  • if there is only a single receiver agent:

ask species_name (receiver_agent) {
     [command_set]
}
  • if receiver_agent(s) is a list of agents:
ask receiver_agents of_species species_name {
     [commands]
}

Any command can be declared in the block commands. All the commands will be evaluated in the context of the receiver agent(s), as if they were defined in their species, which means that an expression like *self* will represent the receiver agent and not the sender. If the sender needs to refer to itself, some of its own attributes (or temporary variables) within the block commands, it has to use the keyword *myself*.

species animal {
    var energy type: float init: rnd (1000) min: 0.0 {
    reflex when: energy > 500 { // executed when the energy is above the given threshold
         let others type: list of: animal value: (self neighbours_at 5) of_species animal; // find all the neighbouring animals in a radius of 5 meters
         let shared_energy type: float  value: (energy - 500) / length (others); // compute the amount of energy to share with each of them
         ask others { // no need to cast, since others has already been filtered to only include animals
              if (energy < 500) { // refers to the energy of each animal in others
                   set energy value: energy + myself.shared_energy; // increases the energy of each animal
                   set myself.energy value: myself.energy - myself.shared_energy; // decreases the energy of the sender
              }
         }
    }
}

Notice

If the target is an addition of list like "target = (list speciesA) + (list speciesB)", the temporary built list will use the default cast from the first list and won't add the second list as the elements are from a different type.

Top of the page

capture

Attributes

  • target (omissible): an expression that is evaluated as an agent or a list of the agent to be captured.
  • as: the species that the captured agent(s) will become, this is a micro-species of the calling agent's species.
  • returns: a list of the newly captured agent(s).

Definition

Allows an agent to capture other agent(s) as its micro-agent(s). The preliminary for an agent A to capture an agent B as its micro-agent is that the A's species must defined a micro-species which is a sub-species of B's species (cf. Nesting species).

species B {
...
}

species A {
...
   species C parent: B {
   ...
   }
...
}

  • To capture all "B" agents as "C" agents, we can ask an "A" agent to execute the following command:
  • capture list(A) as: C;
    or
    capture target: list (A) as: C;

Top of the page

create

Attributes

  • species (omissible): an expression that evaluates to a species
  • number: an expression that evaluates to an int
  • from: an expression that evaluates to a localized entity, a list of localized entities or a string
  • with: an expression that evaluates to a map
  • type: an expression that evaluates to a string
  • size: an expression that evaluates to a float
  • return: a temporary variable name

Definition

Allows an agent to create *number* agents of species *species*, to create agents of species *species* from a shapefile or to create agents of species *species* from one or several localized entities (discretization of the localized entity geometries). Its simple syntax is:

  • To create *an_int* agents of species *a_species*:

create a_species number: an_int;
or
create species: a_species number: an_int;

If *number* equals 0 or species is not a species, the command is ignored.

  • To create agents of species *a_species* (with two attributes type and nature) from a shapefile *the_shapefile* while reading attributes 'TYPE_OCC' and 'NATURE' of the shapefile:

create a_species from: the_shapefile with: [type:: 'TYPE_OCC', nature::'NATURE'];

One agent will be created by object contained in the shapefile. In this example, we assume that for the species *a_species*, two variables *type* and *nature* are declared and that their type corresponds to the types of the shapefile attributes.

  • To create agents of species *a_species* by discretizing the geometry of one or several localized entities:

create a_species from: [agentA, agentB, agentC];

Two types of discretization exist:

  • 'Triangles' : default discretization. The agent geometries are decomposed into triangles; for each triangle, an agent is created. If a size is declared by attribute *size*, the geometries are first decomposed into squares of size *size*, then each square is decomposed into triangles.
  • create a_species from: [agentA, agentB, agentC] type: 'Triangles' size: 10.0;
  • 'Squares' : agent geometries are decomposed into squares of size *size*; for each square, an agent is created:
create a_species from: [agentA, agentB, agentC] type: 'Squares' size: 10.0;

The agents created are initialized following the rules of their species. If one wants to refer to them after the command is executed, the returns keyword has to be defined: the agents created will then be referred to by the temporary variable it declares. For instance, the following command creates 0 to 4 agents of the same species as the sender, and puts them in the temporary variable children for later use.

create species (self) number: rnd (4) returns: children;
ask children {
	...
}

If one wants to specify a special initialization sequence for the agents created, create provides the same possibilities as ask. This extended syntax is:

create a_species number: an_int {
     [commands]
}

The same rules as in ask apply. The only difference is that, for the agents created, the assignments of variables will bypass the initialization defined in species. For instance:

create species(self) number: rnd (4) returns: children {
     set location value: myself.location + {rnd (2), rnd (2)}; // tells the children to be initially located close to me
     set parent value: myself; // tells the children that their parent is me (provided the variable parent is declared in this species) 
}

Top of the page

do

Attributes

  • action (omissible): the name of an action or a primitive
  • with: a map expression

Enclosed tags

  • arg name : specify the arguments expected by the action/primitive to execute.

Definition

Allows the agent to execute an action or a primitive. For a list of primitives available in every species, see this page; for the list of primitives defined by the different skills, see this page. Finally, see this page to know how to declare custom actions. The simple syntax (when the action does not expect any argument and the result is not to be kept) is:

do name_of_action_or_primitive;
or
do action: name_of_action_or_primitive;

In case the result of the action needs to be made available to the agent, the returns keyword has to be defined; the result will then be referred to by the temporary variable declared in this attribute:

let result value: self name_of_action_or_primitive [];
or
let result value: name_of_action_or_primitive(self, []);

In case the action expects one or more arguments to be passed, they are defined by using facets, enclosed tags or a map. We can have the three following notations:

do name_of_action_or_primitive arg1: expression1 arg2: expression2;

which is equivalent to:

do name_of_action_or_primitive {
     arg arg1 value: expression1;
     arg arg2 value: expression2;
     ...
}

or to:

do name_of_action_or_primitive with: [arg1::expression1, arg2::expression2];

In the case of an action returning a value, we can only use facets or a map as follows:

do name_of_action_or_primitive arg1: expression1 arg2: expression2 returns: result;
or
let result value: self name_of_action_or_primitive [arg1::expression1, arg2::expression2];
or
let result value: name_of_action_or_primitive(self, [arg1::expression1, arg2::expression2]);

Top of the page

if

Attributes

  • condition (omissilbe): a boolean expression

Following tags

  • else : encloses alternative commands

Definition

Allows the agent to execute a sequence of commands if and only if the condition evaluates to true. The generic syntax is:

if bool_expr {
    [commands]
}
or
if condition: bool_expr {
    [commands]
}

Optionally, the commands to execute when the condition evaluates to false can be defined in a following command else. The syntax then becomes:

if bool_expr {
    [commands]
}
else {
    [commands]
}

ifs and elses can be imbricated as needed. For instance:

if bool_expr {
    [commands]
}
else if bool_expr2 {
	[commands]
}
else {
		[commands]
	}

Top of the page

let

Attributes

  • name (omissible): the name of the temporary variable
  • type: the datatype of the temporary variable
  • value: an expression

Definition

Allows the agent to declare a temporary variable, local to the scope in which it is defined. The naming rules follow those of the variable declarations. In addition, a temporary variable cannot be declared twice in the same scope. The generic syntax is:

let temp_var1 type: a_datatype value: an_expression;

If the datatype of the variable is not specified, it is inferred from that of the expression (which can be enforced using casting operators if necessary). After it has been declared this way, a temporary variable can be used like regular variables (for instance, the set command should be used to assign it a new value within the same scope).

Top of the page

loop

Attributes

  • var (omissible): a temporary variable name
  • times: an int expression
  • while: a boolean expression
  • over: a list, point, matrix or map expression
  • from: an int expression
  • to: an int expression
  • step: an int expression

Definition

Allows the agent to perform the same set of commands either a fixed number of times, or while a condition is true, or by progressing in a collection of elements or along an interval of integers. The basic syntax for each of these usages are:

loop times: an_int_expression {
     [commands]
}

Or:

loop while: a_bool_expression {
     [commands]
}

Or:

loop a_temp_var over: a_list_expression {
     [commands]
}

Or:

loop a_temp_var from: int_expression_1 to: int_expression_2 {
     [commands]
}
loop a_temp_var from: int_expression_1 to: int_expression_2 step: int_expression3{
     [commands]
}

In these latter two cases, the var attribute designates the name of a temporary variable, whose scope is the loop, and that takes, in turn, the value of each of the element of the list (or each value in the interval). For example, in the first instance of the "loop over" syntax :

let a type: int value: 0;
loop i over: [10, 20, 30] {
     set a value: a + i;
} // a now equals 60

The second (quite common) case of the loop syntax allows one to use an interval of integers. The from and to attributes take a a integer expression as arguments, with the first (resp. the last) specifying the beginning (resp. end) of the interval. The step is assumed equal to 1.

let the_list value:list (species_of (self)) {
loop i from: 0 to: length (the_list){
     ask target: the_list at i {
        ...
     }
} // every  agent of the list is asked to do something

Be aware that there are no prevention of infinite loops. As a consequence, open loops should be used with caution, as one agent may block the execution of the whole model.

Top of the page

put

Attributes

  • in: an expression that evaluates to a container
  • item (omissible): any expression
  • at: any expression
  • key: any expression
  • all: any expression

Definition

Allows the agent to replace a value in a container at a given position (in a list or a map) or for a given key (in a map).

The allowed parameters configurations are the following:

  put expr at: expr in: expr_container;   
  put all: expr in: expr_container;   

Note that the behavior and the type of the attributes depends on the specific kind of container:

  • In the case of a list, the position should an integer in the bound of the list. The attribute all is used to replace all the elements of the list by the given value.
  • let testList type: list value: [1,2,3,4,5];   // testList now contains [1,2,3,4,5]
    put -10 at: 1 in: testList;    // testList now contains [1,-10,3,4,5]	
    put all: 10 in: testList;	// testList now contains [10,10,10,10,10]	 
  • In the case of a matrix, the position should be a point in the bound of the matrix. The attribute all is used to replace all the elements of the matrix by the given value.
  • let testMat type: matrix value: [[0,1],[2,3]];  //testMat now contains [[0,1],[2,3]]
    put -10 at: {1,1} in: testMat;  //testMat now contains [[-10,1],[2,3]]
    put all: 10 in: testMat;  //testMat now contains [[10,10],[10,10]]
  • In the case of a map, the position should be one of the key values of the map. Notice that if the given key value does not exist in the map, the given pair key::value will be added to the map. The attribute all is used to replace the value of all the pairs of the map.
  • let testMap type: map value: ["x"::4,"y"::7]; //testMap now contains ["x"::4,"y"::7]
    put -10 key: "y" in: testMap;	//testMap now contains ["x"::4,"y"::10]
    put -20 key: "z" in: testMap;	//testMap now contains ["x"::4,"y"::7, "z"::-20]
    put all: -30 in: testMap;	//testMap now contains ["x"::-30,"y"::-30, "z"::-30]

Top of the page

release

Attributes

  • target (omissible): an expression that is evaluated as an agent or a list of the agent to be released.
  • returns: a list of the newly released agent(s).

Definition

Allows an agent to release its micro-agent(s). The preliminary for an agent to release its micro-agents is that species of these micro-agents are sub-species of other species (cf. Nesting species). The released won't be micro-agents of the calling agent anymore. Being released from a macro-agent, the micro-agents will change their species and host (macro-agent) .

species A {
}

species B {
   species C parent: A {
   }

   species D {
   }
}

Agents of "C" species can be released from a "B" agent to become agents of A species. Agents of "D" species cannot be released from the "A" agent because species "D" has no parent species.

  • To release all "C" agents from a "B" agent, we can ask the "C" agent to execute the following command:
  • release target: list (C);

The "C" agent will change to "A" agent. The won't consider "B" agent as their macro-agent (host) anymore. Their host (macro-agent) will the be the host (macro-agent) of the "B" agent.

Top of the page

remove

Attributes

  • from: an expression that evaluates to a container
  • item (omissible): any expression
  • index: any expression
  • key: any expression
  • all: any expression

Definition

Allows the agent to remove an element from a container (a list, matrix, map...).

This command should be used in the following ways, depending on the kind of container used and the expected action on it:

remove expr from: expr_container
remove index: expr from: expr_container
remove key: expr from: expr_container
remove all: expr from: expr_container
  • Case of list.

In the case of list, the attribut item: is used to remove the first occurence of a given expression, whereas all is used to remove all the occurences of the given expression.

let testList type: list value: [3,2,1,2,3];  //testList now contains [3,2,1,2,3]
remove 2 from: listTest;  // testList now contains [3,1,2,3]
remove all: 3 from: listTest;  // testList now contains [1,2]
remove index: 1 from: listTest;
  • Case of matrix

This command can not be used on matrix.

  • In the case of map

In the case of map, the attribute key: is used to remove the pair identified by the given key.

let mapTest type: map value: ["x"::5, "y"::7];	// mapTest now contains ["x"::5, "y"::7]
remove key: "x" from: mapTest;   // mapTest now contains ["y"::7]

Top of the page

return

Attributes

  • value (omissible): an expression

Definition

Allows to specify which value to return from the evaluation of the surrounding command. Usually used within the declaration of an action. Contrary to other languages, using return does not stop the evaluation of the surrounding command (for instance, a loop). It simply indicates what value to return: if it is inside a loop, then, only the last evaluation of return will be returned. Example:

action foo {
     return 'foo';
}
...
reflex {
    let foo_result type: string value: self.foo [];
    do write {
         arg message value: foo_result;
    }
}
// the agent will print  foo  on the console at each step

In the specific case one wants an agent to ask another agent to execute a command with a return, it can be done similarly to:

Species A:
action foo_different {
     return 'foo_not_same';
}
---
Species B
reflex
    let temp type: string value: some_agent_A.foo_different [];
    do write {
         arg message value: temp;
    }
}
 // the agent will print  foo_not_same  on the console at each step

Top of the page

save

Attributes

  • to: an expression that evaluates to an string
  • species: an expression that evaluates to a species
  • type: an expression that evaluates to an string

Definition

Allows to save the localized entities of species *species* into a particular kind of file (shapefile, text or csv...). The type can be "shp", "text" or "csv". Its simple syntax is:

save species: a_species to: the_shapefile type: a_type_file;

Top of the page

set

Attributes

  • an expression that either returns a variable or an element of a composite type
  • value: an expression

Definition

Allows the agent to assign a value to a variable. See this section to know how to access variables. Examples:

set my_var value: expression;
set temp_var value:expression;
set global_var value:expression;

The variable assigned can be accessed in the value atribute. In that case, it represents the value of the variable before it has been modified. Examples (with temporary variables):

let my_int type: int value: 1000;
set my_int value: my_int + 1; // my_int now equals 1001

Top of the page

switch

Attributes

  • value (omissible): an expression

Embedded tags

  • match value {...}
  • match_one list_values {... }
  • match_between [value1, value2] {...}
  • desfault {...}

Definition

The "switch... match" statement is a powerful replacement for imbricated "if ... else ..." constructs. All the blocks that match are executed in the order they are defined. The block prefixed by default is executed only if none have matched (otherwise it is not).

Examples:

switch an_expression {
	match value1 {...}
	match_one [value1, value2, value3] {...}
	match_between [value1, value2] {...}
	default {...}
}

Example:

switch 3 {
   match 1 {do write with: [message::"Match 1"]; }
   match 2 {do write with: [message::"Match 2"];}
   match 3 {do write with: [message::"Match 3"]; }
   match_one [4,4,6,3,7] {do write with: [message::"Match one_of"];}
   match_between [2, 4] {do write with: [message::"Match between"];}
   default {do write with: [message::"Match Default"];}
}

Top of the page


Sign in to add a comment
Powered by Google Project Hosting