Specifying an object's attributes

To choose the object template click on Special/Instantiate. A window with the objects appears. Choose Obj_Template.sym and click on the interface. The object template is shown in Figure [*].

Figure: Template to define a new object type.
\includegraphics[width=4in]{figuras/template.eps}

As shown in Figure [*], there are six attributes that describe the object: Declaration, Watches, Initialization, Events, Messages, and Rewards.

is used to specify the pre-: state variables, constants and parameters. Constants can be of type Integer, , Object or Port; parameters can be of type Integer or .
  1. State variables can be of type Integer or Float. In each case, the following ``flavors'' are allowed:
    1. Scalar. For example if we have a state variable named Status, it will be able to have the value 10 if its type is Integer, or 3.6 if its type is Float. Scalar state variables can only have non-negative values. (For the use of Float state variables see §[*].)
    2. Vector. The variable is represented by an array of Integer or Float values. NOTE: if we have a Integer vector, the maximum size allowed is 255. A Float vector has a maximum size of 127.
    3. Queue. This type is similar to the Vector type, but the user can specify the desired size. There is no maximum size.
  2. Constants and parameters can be of type Integer or Float. NOTE: We can represent the Integer and Float types in . E.g. Integer: 1e+10, 1E+05; Float: 1.0e+10, 1.0e-10, 1.0E+10, 1.0E-10.
  3. Object: used to make references to others objects in the model;
  4. Port: used to define between objects. Objects can only communicate (via the message mechanism) if they have ports that are intered. NOTE: port is a reserved word, so an object's port cannot be simply named ``port''.
is used to initialize constants and state variables to numerical values.
is used to specify all the events in an object. An event is defined by a name, a distribution type, and its parameters. An event must also have a condition, and at least one action associated with it. Note that one or more messages can be sent during the execution of an action.
lists all declared state variables. If we simulate the model interactively (see §[*]), the value of each watched variable is displayed at each step.
is used to declare the messages that can be received. When a specific message is received, an action associated with that message is taken. NOTE: Messages arriving at a port are always received. There are no conditions associated with messages.
is used to specify rate or s. Rewards are used in the simulation and in the analytical transient solution.

We start by creating the packet_source object type. Recall that the behavior of an object is represented by events, and messages and their associated actions.

The syntax of an event is as follows:

event     = event_name(distribution, parameters of distribution);
condition =
action    = {
       ...
     };
IMPORTANT: conditions are over state variables only. (The user can specify the condition to be always true. In this case, the reserved word TRUE is used).

The single event of the packet_source object is Packet_Generation. The distribution of the event is defined by the reserved word EXP which indicates an exponential distribution. The rate at which this event occurs is defined by the constant pkt_rate. In this case, there are no conditions for this event to occur, and this is specified by the keyword TRUE. Each time this event triggers, the action specified is executed. In this case, a message is sent. The message sent has the following syntax: msg(name_of_port, object, data).

To edit an attribute, in this case the Events attribute, you must right-click exactly on the object, select Edit Attribute in Editor and then select the attribute you want to edit. In our case, we will edit the Events attribute. (You can also change the default editor, setting your preferred one in your .Xdefaults file, adding the command Tgif*Editor: YOUR_EDITOR_HERE.) The syntax of this event is as follows:

Events    =
event     = Packet_Generation (EXP, pkt_rate)
condition =  (TRUE)
action  = {
            msg(port_out,all,0);
          };
There is another way to edit object attributes in Tgif. It is possible to edit more than one attribute in the editor window. To access this feature you should use the right mouse button over the Tangram-II object and choose the Edit Attribute Group In Editor option. The available groups will be presented in the sub-menu.

Users can create their own attribute groups by editing the .Xdefaults file. For instance, to create an attribute group called TANGRAM-II to edit all Tangram-II attributes at once, do the following:

  1. Add the following lines to the .Xdefaults file:
        Tgif.MaxAttributeGroups: 1
        Tgif.AttributeGroup0: TANGRAM-II:Declaration:Events:Messages
        :Rewards:Initialization:Watches (in the same line)
    
  2. Reload your X configuration with the command xrdb /.Xdefaults.
  3. Restart Tgif.
The option Tgif.MaxAttributeGroups configures the number of attribute groups available. The option Tgif.AttributeGroupX is used to define the attribute group X. An attribute must be defined as:
 Attribute_Name:<Attribute1:Attribute2:...:AttributeN>
IMPORTANT: all is a reserved word that indicates the message is sent to all objects ed to the the port. The is empty because no messages are received by a packet_source object.

The next step is to declarate the state variables and constants. This object type does not have state variables. It is a Poisson source that generates packets continuously. NOTE that at least one object must have a state variable in the model. Otherwise, the model can not be solved.

We must declare the variables used in the object. The for the packet_source is:

Declaration=
Const
Float: PKT_RATE;
Port: PORT_OUT;
Now, we must include all constants in the .

Our first object type is ready! Figure [*] shows the complete packet_source object type specification.

Figure: The packet_source object type.
\includegraphics[width=4in]{figuras/packet.eps}

After specifying the packet_source object type, now we will describe the server object type (queue plus server). We must follow the same steps. First, we will choose the as before.

The next step is to define the state variable of the server (this should be the first step because the condition of the single event is based on the state variable). For this object type, the state is the queue. We can declare this state variable using the .

The single event of the server object is named Packet_Service. Each time this event triggers, the action specified is executed. In this case a packet is removed from the queue. The mean rate at which this event occurs is defined by the constant service_rate. The Packet_Service event can only occur if the queue is not empty $(queue>0)$ . The distribution of the event is exponential. When the event Packet_Service fires, a packet is removed from the queue. An action is specified using C-like constructs (see §[*] in the appendix for the syntax).

Events =
event = Packet_Service (EXP, SERVICE_RATE)
condition =  (Queue > 0)
action = {
  int q;
  q = Queue -1;
  set_st ("Queue",q);
};
IMPORTANT: In an action , state variables can be used in the right-hand side of assignment expressions, but they cannot be modified except using the set_ st() (set state) function. This function assigns the value of a float or an integer constant to the specified state variable, and should be used only at the end of an action. This indicates that all state variables remain at the same value throughout the execution of an action. Their values are changed at once after the execution of the user code. The syntax is set_st (``state variable'', integer variable). If the action is empty, it is necessary to put a ; before the set_st statement.

A server object type receives messages from other objects. The message represents the arrival of a packet to the server. In this model, the message is received from port port_in If the queue is not full, the packet is stored in the queue. Otherwise the packet is dropped (no action is taken).

Messages =
msg_rec = PORT_IN
action = {
  int q;
  q = Queue;
  if (Queue < queue_size)
    q = Queue +1;
    set_st("Queue", q);
};
In this object type, the constant PORT_IN is used to receive messages. The constant queue_size is used to represent the maximum queue size. The constant SERVICE_RATE is used to represent the mean service rate.

We must declare the constants using the and then, all constants and state variables should be included in the .

Declaration=
State Var
Integer: Queue;
Const
Float: SERVICE_RATE;
Integer: QUEUE_SIZE;
Port: PORT_IN;
Our second object type is ready! With the two object types defined above we are able to create an M/M/1/k model. There is one instance of each object type in this model. When a new object is instantiated, an unique name must be given together with initial values for all state variables and constants. In this example, the objects are named Poisson_Source and Server_Queue. NOTE: the Tgif tool has a maximum length of 255 for names of objects and variables. The other limit is the total number of bytes in each line in Tgif editor: 512 bytes.

For the constants and the Server_Queue state variable, we use the following values:

Poisson_Source:
* Initialization
       PKT_RATE= 80
       PORT_OUT= wire

Server_Queue:
* Initialization
      Queue = 0
      SERVICE_RATE = 100
      QUEUE_SIZE = 100
      PORT_IN = wire
* Watches   
     Queue
Note that the port variable of each object receives the same name wire. This indicates that the two ports are ed.

The complete behavior of the model is as follows: with rate 80 packets per time unit, the source sends a message to the defined port (wire). All objects that are listening on this port receive this message. When received by the Server_Queue, this message increments the queue size, if and only if its queue is less that the maximum specified value (100 in this example). With rate 100 packets per time unit, the queue is served if and only if it is not empty.

Guilherme Dutra Gonzaga Jaime 2010-10-27