SIMSCRIPT II.5 Simplified - Department of Computer Science
SIMSCRIPT II.5 Simplified - Department of Computer Science
SIMSCRIPT II.5 Simplified - Department of Computer Science
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
process AIRPLANE<br />
call TOWER giving GATE yielding RUNWAY<br />
work TAXI.TIME (GATE, RUNWAY) minutes<br />
request 1 RUNWAY<br />
work TAKEOFF.TIME (AIRPLANE) minutes<br />
relinquish 1 RUNWAY<br />
end " process AIRPLANE<br />
Since<br />
S1962<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> ®<br />
<strong>Simplified</strong>
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
This document was produced by<br />
Pr<strong>of</strong>essor Tony Vignaux<br />
Victoria University<br />
New Zealand<br />
Tony.Vignaux@mcs.vuw.ac.nz<br />
Updated November 2002 by CACI<br />
If there are questions regarding the use or availability <strong>of</strong> <strong>SIMSCRIPT</strong> <strong>II.5</strong> product, please contact CACI at any <strong>of</strong> the<br />
following addresses:<br />
For product Information contact:<br />
CACI Products Company<br />
CACI Worldwide Headquarters<br />
1011 Camino Del Rio South, suite 230 1100 North Glebe Road<br />
San Diego, California 92108 Arlington, Virginia 22201<br />
Telephone: (619) 542-5224 Telephone (703) 841-7800<br />
www.caciasl.com<br />
www.caci.com<br />
For technical support contact:<br />
Manager <strong>of</strong> Technical Support<br />
CACI Products Company<br />
1011 Camino Del Rio South #230<br />
San Diego, CA 92108<br />
Telephone: (619) 542-5224<br />
simscript@caci.com<br />
The information in this publication is believed to be accurate in all respects. However, CACI cannot assume the responsibility<br />
for any consequences resulting from the use there<strong>of</strong>. The information contained herein is subject to change. Revisions to this<br />
publication or new editions <strong>of</strong> it may be issued to incorporate such change.<br />
<strong>SIMSCRIPT</strong> 11.5 is a registered trademark and service mark <strong>of</strong> CACI Products Company.<br />
2
TABLE OF CONTENTS<br />
1. Introduction................................................................................................ 1<br />
2. Simscript <strong>II.5</strong> Language Elements ......................................... 3<br />
2.1 Program Structure............................................................................................ 3<br />
2.2 The Main Program ........................................................................................... 3<br />
2.3 Variables ............................................................................................................ 4<br />
2.3.1 Modes........................................................................................................ 4<br />
2.3.2 Local and Global Variables................................................................. 5<br />
2.3.3 Arrays........................................................................................................ 5<br />
2.4 The Preamble .................................................................................................... 5<br />
2.5 The Assignment Statement............................................................................... 6<br />
2.6 Input and Output .............................................................................................. 6<br />
2.6.1 Free-form Input (read).......................................................................... 6<br />
2.6.2 Quick-and-dirty output (list)................................................................. 6<br />
2.6.3 Output with a Template (print) ........................................................... 7<br />
2.7 Program Flow.................................................................................................... 8<br />
2.7.1 Selector Phrases.................................................................................... 8<br />
2.8 Routines ............................................................................................................. 9<br />
2.8.1 Arguments................................................................................................ 9<br />
2.8.2 Functions................................................................................................ 10<br />
2.9 Predefined Elements ....................................................................................... 11<br />
3. Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong> ........................................ 13<br />
3.1 Simulation Time.............................................................................................. 13<br />
3.2 Entities ............................................................................................................. 14<br />
3.2.1 Creating and using Temporary Entities......................................... 14<br />
3.2.2 Attributes <strong>of</strong> Entities ............................................................................ 15<br />
3.3 Sets.................................................................................................................... 16<br />
3.4 Processes .......................................................................................................... 17<br />
3.4.1 Defining a Process .............................................................................. 17<br />
3.4.2 Process Routine................................................................................... 18<br />
3.4.3 Creating a Process Entity.................................................................. 18<br />
3.4.4 Activating a Process with Attributes and Arguments ................ 19<br />
3.4.5 Elapsing Time in a Process .............................................................. 20<br />
3.4.6 A Complete Program Using wait Commands.............................. 20<br />
3.4.7 Interactions <strong>of</strong> Processes.................................................................. 21
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
3.4.8 Interruptions .......................................................................................... 21<br />
3.5 Resources ......................................................................................................... 23<br />
3.5.1 Using Resources.................................................................................. 25<br />
3.6 Standard Attributes........................................................................................ 25<br />
4. Statistical Aspects <strong>of</strong> Simulation............................................ 27<br />
4.1 Random Number Generation ........................................................................ 27<br />
4.2 Statistical Monitoring ..................................................................................... 28<br />
4.2.1 Tally ......................................................................................................... 28<br />
4.2.2 Accumulate............................................................................................ 29<br />
5. Acknowledgments................................................................................ 31<br />
5.1 References........................................................................................................ 31<br />
5.1.1 Footnotes ............................................................................................... 31<br />
ii
Abstract<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> is a powerful simulation language in active use for major simulations,<br />
particularly in engineering applications. These notes illustrate just enough <strong>of</strong> the features<br />
so that simple simulations programs can be written.
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
b
1. Introduction<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> is a powerful, free form, English-like, general-purpose simulation<br />
programming language. It supports the application <strong>of</strong> s<strong>of</strong>tware engineering principles,<br />
such as structured programming and modularity, which impart orderliness and<br />
manageability to simulation models.'' [(Russell)(1983)] is available for a range <strong>of</strong><br />
computers including PCs running Windows and NT and also Unix workstations.<br />
These notes introduce only a few features <strong>of</strong> , enough for simple simulations. Many<br />
features <strong>of</strong> the language are left out. You are strongly urged to refer to the more<br />
comprehensive information found in the manuals such as [(CACI83)(1997)], and<br />
[(CACI89)(1989)], and other books such as [(CACI97)(1997)] and [(Russell)(1983)].<br />
Nor do the notes show how to compile and run programs.<br />
The first section is treated as a general-purpose computer language. It has all the<br />
programming structures that we are used to seeing in computer languages and it can be<br />
used for normal calculations just like Pascal, Java, or Python.<br />
The second section describes the special additions that make into a simulation language.<br />
These include simulation time, processes, and resources.<br />
In the third section the statistical routines used for generating random numbers and for<br />
monitoring simulations are described briefly.
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
2
2. Simscript <strong>II.5</strong> Language Elements<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> is a computer language with all the usual elements.<br />
2.1 Program Structure<br />
Every program must have a main program. In addition, it may contain a preamble and a<br />
number <strong>of</strong> routines.<br />
main program<br />
Every program must contain one main program which is the main processing<br />
part.<br />
preamble<br />
This contains all global declarations. It is not always required. If it is included it<br />
must be listed before the main program.<br />
routines<br />
Such as Functions, Subroutines, Events, and Processes. These are not always<br />
required but will be needed in simulation programs.<br />
2.2 The Main Program<br />
The main program starts with the word main. All blocks finish with end<br />
Example 2.1. From time immemorial, the first program that learners write is the one that prints out<br />
``Hello World!''. Here it is in <strong>SIMSCRIPT</strong> <strong>II.5</strong>. It consists <strong>of</strong> just one main block.<br />
main<br />
print 1 line<br />
thus<br />
Hello World!<br />
end '' main<br />
Comments begin with two, single quotes. The rest <strong>of</strong> the line is treated as a comment and<br />
ignored by the compiler.<br />
Convention: The comment attached to the end (though it is not needed) indicates the<br />
name <strong>of</strong> the block or routine that is terminating. It used to be the convention that basic<br />
words are in lower case and identifiers are in upper case. You will find this in much <strong>of</strong><br />
the documentation. It is not required.<br />
Example 2.2 This is an illustration <strong>of</strong> a main program. It contains variable declarations, creation<br />
<strong>of</strong> resources, input, process activation, starting a simulation and calling a routine. Don't worry<br />
about the details now - they will be explained later. (This would not run by itself)<br />
main<br />
define title as a text variable<br />
define no.<strong>of</strong>.tellers as an integer variable<br />
define lambda and mu as double variables
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
create every teller(1)<br />
read no.<strong>of</strong>.tellers, lambda, and mu<br />
let u.teller(1) = no.<strong>of</strong>.tellers<br />
activate a customer now<br />
start simulation<br />
call report '' calling a subroutine<br />
end ''main<br />
2.3 Variables<br />
Variable names can be any combination <strong>of</strong> letters, digits, and periods that contains at<br />
least one letter or two or more nonterminal periods 1 . Variables should be explicitly<br />
declared with a define variable-list statement which specifies a list <strong>of</strong> variables as being<br />
<strong>of</strong> a given mode 2 .<br />
Example 2.3 Here we define one variable <strong>of</strong> integer mode, two <strong>of</strong> double mode and one <strong>of</strong> text<br />
mode.<br />
define Next.Customer as an integer variable<br />
define Weight, Length, and Height<br />
as double variables<br />
define my.title as a text variable<br />
The variable-list can take a number <strong>of</strong> alternative forms. The variable names can be<br />
separated by any <strong>of</strong> the following: ``,'' or ``and'' or ``, and''. The choice is up to you and is<br />
intended to make the program more readable. See [(CACI83)(1997)]. Similarly, the word<br />
an (which could be a) in the first definition, above, is optional and is there for<br />
readability 3 .<br />
Convention: All variable names must be defined explicitly.<br />
2.3.1 Modes<br />
Variables can be <strong>of</strong> a number <strong>of</strong> modes (called types in other languages):<br />
• integer<br />
• real<br />
• double (increased precision reals)<br />
• text (for strings <strong>of</strong> text)<br />
• pointer<br />
integer, real, and double modes are intended for numerical calculations, text for string<br />
handling, and pointer for handling temporary entities and processes (to be considered in<br />
Section 3.2.1). At the start <strong>of</strong> a program all variables are initialized to zero or a blank<br />
value.<br />
4
<strong>SIMSCRIPT</strong> <strong>II.5</strong> Language Elements<br />
2.3.2 Local and Global Variables<br />
A variable is only known within the routine it is defined in. It is a local variable.<br />
Variables declared in the preamble (Section 2.4) are global and are know and can be<br />
used throughout the program.<br />
2.3.3 Arrays<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> does have arrays. They are defined as follows:<br />
Example 2.4 Defining 1- and 2-dimensional arrays.<br />
define Vector as a 1-dimensional integer array<br />
define Matrix as a 2-dimensional, real array<br />
Before an array can be used its dimensions must be reserved (in the main block or a<br />
subprogram, not in the preamble). This allows one to have arrays where the number <strong>of</strong><br />
elements is not known until the program is running 4 .<br />
Example 2.5 Reserving dimensions for the arrays defined in Example 2.4. The first line provides<br />
a 10-element vector <strong>of</strong> integers, referred to as Vector(1) to Vector(10). The second a 5 by 7 matrix<br />
<strong>of</strong> real numbers whose elements are referred to as Matrix(i,j), for example.<br />
reserve Vector as 10<br />
reserve Matrix as 5 by 7<br />
2.4 The Preamble<br />
The preamble is the section where global variables are defined. It must precede the main<br />
program and other routines and contain no executable statements.<br />
To ensures that any variables not declared are flagged by the compiler the preamble<br />
must contain the line<br />
normally, mode is undefined<br />
Example 2.6 A preamble showing declarations <strong>of</strong> two processes, some resources and a number <strong>of</strong><br />
global variables. The tally and accumulate statements set up statistical monitoring routines. Don't<br />
worry about the details at the moment. The idea is to see the sorts <strong>of</strong> declarations that occur in a<br />
preamble. It has no executable statements.<br />
preamble<br />
normally, mode is undefined<br />
processes<br />
every customer has an Arrival.time<br />
define Arrival.time as a real variable<br />
resources include Teller<br />
define no.<strong>of</strong>.tellers, and no.<strong>of</strong>.customers<br />
5
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
as integer variables<br />
define Time.in.bank and Waiting.time<br />
as real variables<br />
tally Avg.Wait as the average <strong>of</strong> Waiting.time<br />
accumulate Avg.Line as the average <strong>of</strong> N.Q.Teller<br />
end '' preamble<br />
2.5 The Assignment Statement<br />
All statements start with a key word such as let, add, subtract (though the let can be<br />
eliminated if preferred).<br />
Example 2.7 The first two lines show assignments with the let key word; The next shows an<br />
assignment without let. The next is an arithmetic assignment and the last two show what are<br />
effectively assignments using add and subtract.<br />
let Teller = 1<br />
let closing.time = closing.time/hours.v<br />
Number.<strong>of</strong>.Tellers = 10 '' key word 'let' is omitted here<br />
let no.<strong>of</strong>.customers = no.<strong>of</strong>.customers + 1<br />
add 1 to no.<strong>of</strong>.customers<br />
subtract 1 from no.<strong>of</strong>.customers<br />
2.6 Input and Output<br />
In this introduction we will use only a simple free-format read statement and one simple<br />
and one formatted print statement. More complicated ones are available.<br />
2.6.1 Free-form Input (read)<br />
The free-form read variable-list statement is the simplest form <strong>of</strong> input. The variable-list<br />
can have variables <strong>of</strong> any mode. Data can be entered from the terminal (i.e. the system<br />
input file) or read from a file 5 . Be careful with variables <strong>of</strong> mode text as the value entered<br />
cannot contain blanks.<br />
Example 2.8 This read statement assigns values to the 4 variables. Note that in , statements are<br />
not limited to a single line.<br />
read no.<strong>of</strong>.tellers, lambda, title<br />
and closing.time<br />
Since the list <strong>of</strong> variables 6 can use both commas and the word and we could also write the above<br />
read statement like this:<br />
read no.<strong>of</strong>.tellers, and lambda,<br />
and title, and closing.time<br />
2.6.2 Quick-and-dirty output (list)<br />
6
<strong>SIMSCRIPT</strong> <strong>II.5</strong> Language Elements<br />
This is used to help in debugging but should not be used in the final forms <strong>of</strong> programs in<br />
assignments. The list variable-list displays the values <strong>of</strong> the variables in the variable-list<br />
on the screen.<br />
Example 2.9 This list statement prints the values <strong>of</strong> variable x, lambda and no.<strong>of</strong>.tellers:<br />
list x, lambda, and no.<strong>of</strong>.tellers<br />
This results in the following output.<br />
X = 2.0000000000<br />
LAMBDA = 5.3300000000<br />
NO.OF.TELLERS = 4.0000000000<br />
2.6.3 Output with a Template (print)<br />
The print variable-list thus statement, introduced here, is the main form <strong>of</strong> output we will<br />
use in the course 7 . It prints the values <strong>of</strong> every variable in the variable-list in a form<br />
specified by a template.<br />
The template is a pattern showing how the values are to be presented. It can contain<br />
words other than the data being printed. Every variable in the variable-list will have a<br />
corresponding asterisk (*) pattern. Integer and text mode variables should be printed with<br />
the form *** (the number <strong>of</strong> * indicating how many digits or characters to print). Real and<br />
double mode variables will have a pattern including a decimal point somewhere (such as<br />
***.** for a value with 3 digits or spaces before the decimal point and 2 after it).<br />
Example 2.10 The general form is<br />
print N lines with {variable-list}<br />
thus<br />
{N lines <strong>of</strong> template<br />
with one group <strong>of</strong> *** or ***.**<br />
for every variable}<br />
However you must be careful to count the exact number <strong>of</strong> lines used. One common error<br />
is to use too few lines and try and print from the next line which may be part <strong>of</strong> the<br />
program.<br />
Convention: Leave an extra blank line after a print statement.<br />
Example 2.11 This print statement prints 5 lines with values <strong>of</strong> the 7 variables or arithmetic<br />
expressions.<br />
print 5 lines with<br />
no.<strong>of</strong>.tellers, lambda, mu, and closing.time*hours.v,<br />
Avg.Line, Avg.no.<strong>of</strong>.Custs, and<br />
Avg.Wait*Minutes.per.day<br />
thus<br />
N= ** lambda= **.** mu= **.**<br />
closing time = **<br />
Avge line = *.**<br />
Avge customers = *.**<br />
Avge wait = ***.**<br />
'' next program line here, thus leaving a blank<br />
7
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
'' after the print statement for safety.<br />
2.7 Program Flow<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> has all the usual program structures, such as if-then-else (or if-elseendif),<br />
for-do-loop, until and while loops, etc 8 .<br />
The if structure has no then, and the statement is terminated by endif 9 . The else part can<br />
be omitted but the endif must be retained.<br />
Example 2.12 An example <strong>of</strong> the if structure:<br />
if A > B<br />
let Maxvalue = A<br />
read C<br />
else<br />
let Maxvalue = B<br />
read D<br />
endif<br />
while loops are similar to until loops. For all the iterative structures, the group <strong>of</strong><br />
statements to be executed must be surrounded by a do-loop pair.<br />
Example 2.13 Some examples <strong>of</strong> looping program structures. Here, in each case, 100 values are<br />
read sequentially into the vector x()<br />
for i = 1 to 100<br />
do<br />
read x(i)<br />
loop<br />
let i = 1<br />
until i > 100<br />
do<br />
read x(i)<br />
add 1 to i<br />
loop<br />
let i = 1<br />
while i
<strong>SIMSCRIPT</strong> <strong>II.5</strong> Language Elements<br />
for count = 1 to No.<strong>of</strong>.seats<br />
when Baggage(count) > 1<br />
unless Owner(count) = "Vignaux"<br />
do<br />
add Baggage(count) to Total<br />
loop<br />
2.8 Routines<br />
Routines in <strong>SIMSCRIPT</strong> <strong>II.5</strong> are like subroutines or procedures in other programming<br />
languages. They are declared after the main block and not inside it. They are called from<br />
other subprograms ( not the preamble). Of course, they may define local variables and<br />
use global variables.<br />
Example 2.15 Here a routine is defined. It has a local variable, i and refers to Num.Ambulances<br />
which, we assume, is global and defined in the preamble.<br />
routine Initialise<br />
define i as an integer variable<br />
read Num.Ambulances<br />
let i = 0<br />
until i eq Num.Ambulances<br />
do<br />
let i = i + 1<br />
create an Ambulance<br />
activate this Ambulance now<br />
loop<br />
end '' routine Initialise<br />
Routines are executed using the call statement. For example:<br />
Example 2.16 Executing a routine using a call statement:<br />
call Initialise<br />
2.8.1 Arguments<br />
Routines can be given arguments and return results. The arguments supplying data are<br />
separated from those returning the result. This is done using the keywords given and<br />
yielding.<br />
Arguments behave like local variables and their mode must be declared immediately after<br />
the routine heading. As they are local to the routine, they can be given any names you<br />
like.<br />
Example 2.17 This routine calculates the value <strong>of</strong> Pr<strong>of</strong>it given the amount <strong>of</strong> Production.<br />
routine Pr<strong>of</strong>it.Calc given Production yielding Pr<strong>of</strong>it<br />
define Production, Pr<strong>of</strong>it as double variables '' arguments<br />
define Fixed, Contribution as double variables '' local<br />
9
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
let Fixed = 10000.0<br />
let Contribution = 20.0<br />
let Pr<strong>of</strong>it = - Fixed + Contribution*Production<br />
end '' Pr<strong>of</strong>it.Calc<br />
Example 2.18 The above routine would be called like this:<br />
call Pr<strong>of</strong>it.Calc given 50000.0 yielding The.Pr<strong>of</strong>it<br />
Instead <strong>of</strong> given you can enclose the given arguments in parentheses, ( ). Convention We<br />
usually declare and call routines with a list <strong>of</strong> given arguments enclosed in parentheses.<br />
You don't need the word given then.<br />
Example 2.19 For example, the above definition could be written:<br />
routine Pr<strong>of</strong>it.Calc(Production) yielding Pr<strong>of</strong>it<br />
define Production, Pr<strong>of</strong>it as double variables<br />
'' ..... lots <strong>of</strong> calculations ....<br />
end '' Pr<strong>of</strong>it.Calc<br />
Example 2.20 We could call the routine like this:<br />
call Pr<strong>of</strong>it.Calc(50000.0) yielding the.Pr<strong>of</strong>it<br />
A routine finishes when the program ``drops <strong>of</strong>f the end'' <strong>of</strong> the routine. You can finish at<br />
another part by the return statement.<br />
WARNING: does not automatically convert integer mode arguments to real or double.<br />
So don't forget to put the decimal point in real or double arguments when you call a<br />
routine!<br />
2.8.2 Functions<br />
Functions are routines that return a value and can be called as part <strong>of</strong> an arithmetic<br />
expression. The value is returned by using the return with or the return() statement. They<br />
are not executed using the call statement like routines but are used within expressions to<br />
return a value. They must be defined as functions in the preamble. In this definition you<br />
can set the mode and you can (and should) state the number <strong>of</strong> given arguments.<br />
Remember that the arguments and any other local variables are not recognized outside<br />
the function. The only communication with the main and other routines is via the<br />
arguments in the call command and the return value 10 .<br />
Of course there are also many pre-defined functions, which you do not have to define<br />
yourself.<br />
Example 2.21 We define a Normal.fn. In the preamble we define it as a double function and<br />
specify the number <strong>of</strong> arguments:<br />
preamble<br />
normally, mode is undefined<br />
define Normal.fn as a double function<br />
given 2 arguments<br />
end '' preamble<br />
10
<strong>SIMSCRIPT</strong> <strong>II.5</strong> Language Elements<br />
Example 2.22 The function code would appear after the main block and would look something<br />
like this:<br />
function Normal.fn (Mean, Std.Dev)<br />
define Mean and Std.Dev as double variables<br />
...<br />
return(XXX) '' some arithmetic result<br />
end '' Normal.fn<br />
Example 2.23 It would then be called like this:<br />
let x = Normal.fn(10.0,2.1)<br />
'' note the decimal points for doubles !<br />
Here is an example <strong>of</strong> a complete<br />
multiplies two variables.<br />
program with a preamble and a function that<br />
Example 2.24 The multiply function is declared in the preamble and defined later. It is called in<br />
the main block.<br />
preamble<br />
normally, mode is undefined<br />
define x,y, and z as double variables<br />
define multiply as a double function given 2 arguments<br />
end ''preamble<br />
main<br />
read x,y<br />
let z = multiply(x,y)<br />
print 1 line with x,y,z thus<br />
****.** times ****.** is *******.**<br />
end '' main<br />
function multiply(a,b) '' Definition <strong>of</strong> the function<br />
define a,b as double variables<br />
return (a*b)<br />
end '' multiply<br />
2.9 Predefined Elements<br />
There are many pre-defined functions, routines, variables and constants 11 . You do not<br />
have to define these. Pre-defined elements have special suffices, for example: .f for<br />
functions, .r, for routines, .v for variables, and .c for constants. Some examples are:<br />
Function abs.f(arg)<br />
Routine date.r<br />
Variable hours.v<br />
Constant pi.c<br />
value <strong>of</strong> <br />
absolute value <strong>of</strong> arg<br />
the current date<br />
hours per day<br />
11
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
12
3. Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
We now look at some <strong>of</strong> the special facilities provides for the simulation programmer.<br />
They include entities, sets, processes, resources, and, importantly, ways <strong>of</strong> recording and<br />
elapsing simulation time.<br />
3.1 Simulation Time<br />
All discrete-event simulation programs have the simulation time maintained in a s<strong>of</strong>tware<br />
clock. In this is called<br />
time.v<br />
time.v is a double variable. It is sed to record and print out the current simulation time<br />
particularly in controlling the simulation and in producing traces <strong>of</strong> its operation 12 . Do<br />
not attempt to alter time.v yourself.<br />
Time is measured in units 13<br />
During the running <strong>of</strong> a simulation program, time steps forward from one event to the<br />
next. An event occurs whenever the state <strong>of</strong> the simulated system changes. For example,<br />
an arrival <strong>of</strong> a customer is an event. So is a departure.<br />
Execution <strong>of</strong> this timing mechanism does not start until the following statement appears<br />
in the main block <strong>of</strong> the program:<br />
start simulation<br />
The simulation then starts, the timer routine seeking the first scheduled event 14 . It<br />
continues to run until there are no further events to execute. This is the usual method <strong>of</strong><br />
ending a simulation.<br />
More statements can be executed after the simulation (like the call Report in Example<br />
3.1).<br />
The program can be terminated using the stop statement.<br />
Example 3.1 This shows only the main block in a simulation program. Activating the<br />
PoissonProcess has the effect <strong>of</strong> scheduling at least one event 15 . The start simulation will make<br />
the programme jump to that event When the simulation ends the Report routine is called.<br />
main<br />
call Initialise<br />
activate a PoissonProcess now<br />
start simulation<br />
call Report<br />
end '' main
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
3.2 Entities<br />
Before we look at processes we must look briefly at entities. An entity is an element <strong>of</strong><br />
the system being simulated that can be individually identified and processed 16 . In they<br />
can be either permanent or temporary. They are defined in the preamble using either an<br />
include or an every declaration statement (every statements will be dealt with in Section<br />
3.2.2.)<br />
Example 3.2 Defining some entities.<br />
preamble<br />
normally, mode is undefined<br />
permanent entities<br />
include Teller, <strong>Computer</strong><br />
temporary entities<br />
include customer, Task<br />
....<br />
end '' preamble<br />
We will not say much about permanent entities in this simplified version <strong>of</strong> the language<br />
though they will be used, in the form <strong>of</strong> resources (see Section 3.5).<br />
3.2.1 Creating and using Temporary Entities<br />
Temporary entities must not only be defined in the preamble, they must be created before<br />
they can be used.<br />
Example 3.3 Assuming that the customer has been defined as a temporary entity we can create it<br />
as follows 17 :<br />
create a customer<br />
When a temporary entity, say customer, is created:<br />
• a section <strong>of</strong> memory is allocated to hold its attribute values (see section 3.2.2 to<br />
find out what attributes are) and<br />
• a single global variable customer points to this memory space.<br />
When we create another customer, the same global integer variable customer then points<br />
to the location <strong>of</strong> the new entity. (c.f. the new statement in many modern languages). We<br />
would not use that global value but define and use a pointer variable to refer to the new<br />
entity. So it is better (and our convention) to create temporary entities in the following<br />
form (where PV is previously defined as a pointer variable). PV can then be used to refer<br />
to the new entity.<br />
Example 3.4 Creating a customer with a pointer that can be used to refer to it.<br />
create a customer called PV<br />
An entity can later be destroyed. It is best to do this by way <strong>of</strong> the pointer variable. Just<br />
as the create statement needed the entity as well as the pointer, so does the destroy<br />
statement.<br />
14
Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
There is an important difference between the create and destroy statements. We create a<br />
customer called PV but destroy the customer called PV.<br />
Example 3.5 Here we define pointer variables Fred and Valerie which are used to access the two<br />
different temporary customer entities. We then get rid <strong>of</strong> Fred using the destroy the command.<br />
Note the different usage <strong>of</strong> a and the in the two statements.<br />
define Fred, Valerie as pointer variables<br />
...<br />
create a customer called Fred<br />
create a customer called Valerie<br />
...<br />
destroy the customer called Fred<br />
3.2.2 Attributes <strong>of</strong> Entities<br />
An attribute is a property <strong>of</strong> an entity that conveys extra information about it. Attributes<br />
can be used to identify a sub-class <strong>of</strong> entities (e.g. red cars) or values for an individual<br />
entity (a customer number) or to control its behavior. The programmer can define<br />
attributes for the entities in the program.<br />
We define an entity with attributes by the every statement in the temporary entities<br />
section <strong>of</strong> the preamble, instead <strong>of</strong> the include statement. You state what attributes the<br />
entity has and define their modes.<br />
Convention: The modes <strong>of</strong> attributes <strong>of</strong> entities are defined immediately they are specified<br />
and are given names that start with a prefix indicating the entity that they belong to.<br />
Example 3.6 Here we define temporary entities without (Task) and with (customer) attributes:<br />
preamble<br />
normally, mode is undefined<br />
temporary entities<br />
include Task<br />
''(no attributes)<br />
every customer has a cu.Arrival.time<br />
define cu.Arrival.time as a double variable<br />
...<br />
end '' preamble<br />
Later in the program you can use the attribute, indexed by the global entity name or a<br />
pointer variable<br />
Example 3.7 Using the Fred pointer variable to set the Arrival.time for that particular customer.<br />
main<br />
define Fred as a pointer variable<br />
...<br />
create a customer called Fred<br />
let cu.Arrival.time(Fred) = 11.4<br />
...<br />
end '' main<br />
15
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
3.3 Sets<br />
A set is an ordered list <strong>of</strong> entities, like a queue. Sets must be defined in the preamble and<br />
must have an owner. The owner is <strong>of</strong>ten another entity. In some cases this is not<br />
appropriate so we can specify that a general-purpose owner, the system, can own a set.<br />
When you define an entity in the preamble, you must specify what sets it can belong to<br />
and what sets it owns.<br />
Example 3.8 Here, each <strong>of</strong> the Job entities has its own list <strong>of</strong> Tasks to be done, the Task.list held<br />
as a set. The Job can be put on (it belongs to) 18 the single Job.queue which is owned by the<br />
system.<br />
preamble<br />
temporary entities<br />
every Task<br />
has a Tk.duration,<br />
and belongs to a Task.list<br />
define Tk.duration as a double variable<br />
every Job<br />
has an Jb.arrival.time,<br />
owns a Task.list, and<br />
belongs to a Job.queue<br />
the system owns the Job.queue<br />
...<br />
end '' preamble<br />
Sets (queues), if not further defined, are assumed to have a normal FIFO (First-in, firstout<br />
or First-come, first served). Otherwise they can be defined as being a LIFO set.<br />
Alternatively a set can be ranked by combinations <strong>of</strong> attributes <strong>of</strong> the entities that can<br />
belong to it. This is specified when the belongs phrase is used (See the define .. as a set ...<br />
in Example 3.9).<br />
Example 3.9 Here the Task.list contains Tasks filed in order <strong>of</strong> low values (ascending order) <strong>of</strong><br />
Tk.duration.<br />
temporary entities<br />
every Task<br />
has a Tk.duration,<br />
and belongs to a Task.list<br />
define Tk.duration as a double variable<br />
define Task.list as a set<br />
ranked by low Tk.duration<br />
Entities are put into and removed from sets by statements in the routines <strong>of</strong> the program.<br />
They are added to a set using the file statement (See line 5 in Example 3.10), and taken<br />
out using the remove statement (Line 7 in Example 3.10). The entities are filed in the<br />
appropriate order automatically.<br />
Sets have a number <strong>of</strong> standard attributes, automatically defined and updated for you (see<br />
Section 3.6). A most useful one is the number <strong>of</strong> entities in the set. For a set called Q, the<br />
16
Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
number <strong>of</strong> entities it holds is N.Q. This is automatically updated whenever entities are<br />
added to or removed from the set.<br />
You can test if a set is empty or not using the forms Q is empty or Q is not empty. You<br />
can also ask if a particular entity, say E, is in the set using: E is in Q or E is not in Q.<br />
Example 3.10 (following on from Problem 3.8) Here we create a Job100 and a Task which is put<br />
onto Job100s Task.list. The print statement (6) outputs the number in the Task.list. We can remove<br />
the task from the set (7). The particular statement used does not destroy the task and it can be<br />
accessed using tt.<br />
1) define Job100, and tt as pointer variables<br />
...<br />
2) create a Job called Job100<br />
3) create a Task called tt<br />
4) let Tk.durationn(tt) = 100.0<br />
5) file tt in the Task.list(Job100)<br />
...<br />
6) print 1 line with N.Task.list(Job100) thus<br />
Number in task list is ****<br />
....<br />
7) remove the first tt from the Task.list(Job100)<br />
...<br />
8) if the Task.list(Job100) is empty<br />
9) print 1 line thus<br />
10) Set is empty<br />
11)<br />
12)endif<br />
3.4 Processes<br />
We now come to the main tool for discrete-event simulation. A process is a sequence <strong>of</strong><br />
events that describes the experience <strong>of</strong> an entity as it lives its lifetime. For example, a<br />
message turns up in a computing network; it makes transitions between nodes, waits for<br />
service at each one, and eventually leaves the system. All these are events.<br />
In a process is represented as an entity associated with a process routine that describes<br />
the life-cycle. This entity is a temporary entity (but is defined in a separate section <strong>of</strong> the<br />
preamble as a process). A process can have attributes. Different individual processes<br />
(e.g. individual customers) are created as the program runs. The routine, which describes<br />
the sequence <strong>of</strong> events, is called the process routine and is written in the program as a<br />
routine with the same name as the entity.<br />
3.4.1 Defining a Process<br />
A process entity is defined with or without attributes in a processes section <strong>of</strong> the<br />
preamble. Processes can own and belong to sets.<br />
17
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
Example 3.11 Here we define a message process (with no attributes), a clock, and a customer<br />
process (with attributes).<br />
preamble<br />
normally, mode is undefined<br />
processes<br />
include message '' a process with no attributes<br />
every clock has a cl.int<br />
define cl.int as a real variable<br />
every customer has an cu.Arrival.time<br />
define cu.Arrival.time as a real variable<br />
end '' preamble<br />
3.4.2 Process Routine<br />
The process routine is, like other routines, declared after the main block but uses the<br />
keyword process. Its name must be that <strong>of</strong> the process defined in the preamble. The<br />
process starts executing the routine when it is activated.<br />
Example 3.12 A process routine for a ticking clock. int is the time interval between ticks. It<br />
would be defined as an attribute <strong>of</strong> the process entity and an argument <strong>of</strong> the process routine.<br />
process clock(int)<br />
define int as a double variable<br />
define i as an integer variable<br />
for i = 1 to 10<br />
do<br />
print 1 line with time.v<br />
thus<br />
***.*** tick<br />
wait int units<br />
loop<br />
end '' clock<br />
3.4.3 Creating a Process Entity<br />
A new process entity appears when the process is created or activated. To create and start<br />
a new process in one step, use the activate statement. Pointer variables can be used to<br />
reference such new processes.<br />
Example 3.13 We activate two messages immediately. the word a indicates that we are both<br />
creating and activating new messages (they have no attributes). The word now implies no<br />
simulation delay before the process starts.<br />
activate a message now<br />
activate a message called mmm now<br />
18
Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
It is also possible to give values to the attributes <strong>of</strong> the process before it is activated. This<br />
is done by first creating it, setting the attribute values and then activating it.<br />
Example 3.14 Here the customer is created first, given an attribute value, then activated. The<br />
word the is used to indicate we are not creating a new customer when we activate. The attribute<br />
cu.Arrival.time here records the time the customer is created.<br />
create a customer called Fred<br />
let cu.Arrival.time(Fred) = time.v<br />
activate the customer called Fred now<br />
Processes do not have to be activated immediately.<br />
Example 3.15 Here we activate a Job to start at some (random) time in the future and activate a<br />
customer (to be called Fred) immediately, and a bus when time.v becomes 120.0 time units. The<br />
word a indicates that these processes are being created.<br />
activate a Job in exponential.f(13.33, 2) hours<br />
activate a customer called Fred now<br />
activate a Bus called b at 120.0 units<br />
3.4.4 Activating a Process with Attributes and Arguments<br />
A process with attributes may have a corresponding routine with arguments that<br />
correspond in mode but not name to the attributes <strong>of</strong> the process entity.<br />
Example 3.16 For the customer process definition shown in Example 3.11, a corresponding<br />
process routine fragment might be:<br />
process customer(ArrTime)<br />
define ArrTime as a real variable<br />
...<br />
end '' customer<br />
We can then activate the process and at the same time assign a value <strong>of</strong> 13.3 to the<br />
attribute cu.Arrival.time by either <strong>of</strong> the following methods:<br />
1. Assign an cu.Arrival.time with the value <strong>of</strong> the process argument, ArrTime, when<br />
the routine starts.<br />
Example 3.17 Process argument used 19 :<br />
activate a customer called Fred given 13.3 now<br />
2. Set the value <strong>of</strong> the attribute and then activate the process. This ignores the<br />
process argument:<br />
Example 3.18 3-step process:<br />
create a customer called Fred<br />
let cu.Arrival.time(Fred) = 13.3<br />
activate the customer called Fred now<br />
However, a process attribute, such as cu.Arrival.time, and a process routine argument,<br />
such as ArrTime, cannot have the same name 20 .<br />
19
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
3.4.5 Elapsing Time in a Process<br />
Within a process routine the process can wait or work for some time interval measured in<br />
units. (It can also request and relinquish resources as described later in Section 3.5). In<br />
this way it can simulate the elapsing <strong>of</strong> time.<br />
Example 3.19 The process will hold for a random time with mean 10.0 units.<br />
work exponential.f(10.0, 3) units<br />
wait and work are effectively synonymous but work is more appropriate if a resource is<br />
being used.<br />
A process disappears when it is destroyed or when it runs <strong>of</strong>f the end <strong>of</strong> its routine.<br />
Convention: we do not usually destroy processes. instead, allow them to run <strong>of</strong>f the end<br />
<strong>of</strong> the routine.<br />
3.4.6 A Complete Program Using wait Commands<br />
Example 3.20 This program simulates a firework with a time fuse. It contains a preamble to<br />
define the firework process. I have put in a few extra wait commands<br />
preamble<br />
normally mode is undefined<br />
processes<br />
include firework<br />
end '' preamble<br />
main<br />
activate a firework in 20.0 units<br />
start simulation<br />
end ''main<br />
process firework<br />
define i as an integer variable<br />
print 1 line with time.v thus<br />
*****.** firework activated<br />
wait 10.0 units<br />
for i = 1 to 10<br />
do<br />
wait 1.0 unit<br />
print 1 line with time.v, and i thus<br />
*****.** tick **<br />
loop<br />
wait 10.0 units<br />
print 1 line with time.v thus<br />
*****.** Boom!!<br />
end '' process firework<br />
The output from the program in Example<br />
20.00 firework activated<br />
31.00 tick 1<br />
3.20 is :<br />
20
Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
32.00 tick 2<br />
33.00 tick 3<br />
34.00 tick 4<br />
35.00 tick 5<br />
36.00 tick 6<br />
37.00 tick 7<br />
38.00 tick 8<br />
39.00 tick 9<br />
40.00 tick 10<br />
50.00 Boom!!<br />
One useful program pattern is the generator (See Example 3.21). This is a process that<br />
generated events or activates a number <strong>of</strong> other processes as a sequence - it is a source or<br />
generator <strong>of</strong> other processes. Random arrivals are generated using such a process.<br />
Example 3.21 The generator pattern. A process to generate a series <strong>of</strong> customers to arrive at<br />
intervals <strong>of</strong> 10.0 units <strong>of</strong> time. To achieve ``random'' arrivals <strong>of</strong> customers the wait statement<br />
should use an exponential random variate instead <strong>of</strong>, as here, a constant 10.0 value.<br />
process Generator<br />
while time.v < Finish.time<br />
do<br />
activate a customer now<br />
wait 10.0 units<br />
loop<br />
end '' Generator<br />
3.4.7 Interactions <strong>of</strong> Processes<br />
The various states that a process can exist in are shown in this diagram:<br />
An executing process can suspend itself and can be sent a reactivate command by<br />
another process.<br />
Example 3.22 The process itself would say<br />
suspend<br />
and (some other process) would reactivate using the form:<br />
Example 3.23 reactivation by a second process.<br />
reactivate the customer called Fred now<br />
3.4.8 Interruptions<br />
A pending process (one that is waiting for an event to occur) can be interrupted and later<br />
resumed by another routine.<br />
Example 3.24 Here we are in some routine (not the customer routine. The customer called Fred<br />
is interrupted, filed in a set. It is held there for 20.0 units and then resumed.<br />
interrupt the customer called Fred now<br />
21
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
file Fred in Interrupted.Set<br />
wait 20.0 units<br />
remove the first customer called Fred<br />
from the Interrupted.Set<br />
resume the customer called Fred<br />
Example 3.25 In this program example the Arrival.Generator is interrupted by the terminating<br />
process Close.Doors. This routine prints out a report and then stops the program, even though<br />
some processes have not yet finished. First we look at the preamble and main blocks.<br />
preamble<br />
normally mode is undefined<br />
processes<br />
include Arrival.Generator,and Close.Doors<br />
every customer has a cu.number<br />
define cu.number as an integer variable<br />
define Day.Length, Mean, sojourn<br />
as real variables<br />
define count.departs, and count.arrivals<br />
as integer variables<br />
end '' preamble<br />
main<br />
call Read.Data ''reads 3 global variables<br />
count.departs = 0<br />
count.arrivals = 0<br />
activate an Arrival.Generator now<br />
activate a Close.Doors in Day.Length units<br />
start simulation '' it starts operating here<br />
call Report<br />
end '' main<br />
Example 3.26 Following on from Example (3.25) we list the processes and routines.<br />
process Arrival.Generator<br />
define i as an integer variable<br />
for i = 1 to 1000000<br />
do<br />
wait exponential.f(Mean,1) units<br />
activate a customer(i) now<br />
add 1 to count.arrivals<br />
loop<br />
end '' Arrival.Generator<br />
process customer(id)<br />
define id as an integer variable<br />
print 1 line with time.v, and id thus<br />
***.*** customer *** arrives<br />
wait exponential.f(sojourn,2) units<br />
print 1 line with time.v, and id thus<br />
***.*** customer *** departs<br />
add 1 to count.departs<br />
end ''customer<br />
process Close.Doors<br />
interrupt Arrival.Generator<br />
22
Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
call Report<br />
stop<br />
end ''Close.Doors<br />
routine Read.Data<br />
read Day.Length, Mean, and sojourn<br />
end '' Read.Data<br />
routine Report<br />
print 2 line with count.arrivals<br />
and count.departs thus<br />
***** customers arrived<br />
***** customers departed<br />
end '' Report<br />
Example 3.27 An example <strong>of</strong> the trace output from a run <strong>of</strong> this program is as follows:<br />
.078 customer 1 arrives<br />
1.803 customer 2 arrives<br />
3.219 customer 3 arrives<br />
3.242 customer 4 arrives<br />
3.619 customer 3 departs<br />
4.643 customer 5 arrives<br />
4.803 customer 6 arrives<br />
5.146 customer 1 departs<br />
5.222 customer 7 arrives<br />
5.404 customer 8 arrives<br />
5.654 customer 8 departs<br />
5.847 customer 7 departs<br />
6.315 customer 9 arrives<br />
6.860 customer 2 departs<br />
7.285 customer 6 departs<br />
7.765 customer 10 arrives<br />
7.882 customer 9 departs<br />
10 customers arrived<br />
7 customers departed<br />
3.5 Resources<br />
A resource models a congestion point where there may be queuing. For example in a<br />
manufacturing plant, a Task (modeled as a process) needs work done at a particular sort<br />
<strong>of</strong> Machine (modeled as a resource). If not enough Machines are available; the Task will<br />
have to wait until one becomes free. The Task will then have the use <strong>of</strong> a Machine for<br />
however long it needs. It is not available for other Tasks until it is released. These actions<br />
are all automatically taken care <strong>of</strong> by the resource.<br />
A resource can have a number <strong>of</strong> different types. There may be three types <strong>of</strong> Machine<br />
resource, perhaps, lathe, cutter, and polisher. A Ship may be a tanker, a general cargo<br />
ship, or a ferry. Each different type <strong>of</strong> a resource has a number <strong>of</strong> units. This records how<br />
many <strong>of</strong> that type there are initially.<br />
23
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
In a resource is modeled as a special kind <strong>of</strong> permanent entity. A process gets service by<br />
requesting and, when it is finished, by relinquishing the resource. A resource maintains a<br />
set (a queue or list) <strong>of</strong> processes using units <strong>of</strong> each type the resource and another set <strong>of</strong><br />
processes waiting for units <strong>of</strong> it. These sets are defined and updated automatically.<br />
Resources are defined in the preamble in a special section labelled resources. A resource<br />
can have user-defined attributes.<br />
Example 3.28 Here Teller is defined as a resource without user-defined attributes. Ma.name is a<br />
user-defined attribute for the resource Machine.<br />
resources<br />
include Teller<br />
every Machine has a Ma.name<br />
define Ma.name as a text variable<br />
A resource also has standard attributes defined automatically (See Section 3.6). These<br />
record how many units <strong>of</strong> each type <strong>of</strong> the resource are free, how many processes are<br />
waiting for it, etc. For example, the number <strong>of</strong> types <strong>of</strong> a resource R is held in the<br />
variable N.R. Type i is referred to as R(i) where i = 1 to N.R. Each type has a number <strong>of</strong><br />
units. The number <strong>of</strong> units <strong>of</strong> type i is referred to as U.R(i).<br />
Once a resource has been defined in the preamble it must have storage allocated for its<br />
attributes in the main block 21 . First you must specify the number <strong>of</strong> types (N.R); then you<br />
create all the types (create every R), then you specify how many units <strong>of</strong> each type<br />
(U.R(i)).<br />
Example 3.29 A group <strong>of</strong> Machines (a resource) might have 2 different types (N.Machines =<br />
2).There can be different numbers <strong>of</strong> units <strong>of</strong> each type:<br />
let N.Machines = 2 '' the number <strong>of</strong> TYPES<br />
create every Machine ''creates storage<br />
let U.Machine(1) = 4 '' the number <strong>of</strong> UNITS <strong>of</strong> type 1<br />
let U.Machine(2) = 1 '' the number <strong>of</strong> UNITS <strong>of</strong> type 2<br />
You can get information about the set <strong>of</strong> processes that are using units <strong>of</strong> the<br />
resource and those <strong>of</strong> processes that are waiting. For resource R the set using units <strong>of</strong><br />
type i is known as X.R(i); the set waiting for it as Q.R(i). Then, <strong>of</strong> course, since Q.R(i) is<br />
a set, we can find out how many processes are waiting from the set attribute N.Q.R(i).<br />
Example 3.30 for the Machines, in Example3.29, look at type 1 Machines only (there are 4 <strong>of</strong><br />
them)<br />
Q.Machine(1) '' the set <strong>of</strong> processes waiting for a<br />
'' type 1 Machine<br />
N.Q.Machine(1) '' the number <strong>of</strong> processes waiting<br />
X.Machine(1) '' the set containing resources using<br />
'' units <strong>of</strong> a type 1 Machine<br />
N.X.Machine(1) '' the number <strong>of</strong> processes using units<br />
24
Simulation with <strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
3.5.1 Using Resources<br />
The process routines will contain statements to interact with the resource. These are the<br />
request and the relinquish statements. To use a resource for a time a process will request<br />
a number <strong>of</strong> units <strong>of</strong> the particular type. If they are available they are allocated to the<br />
process, which then holds them until releasing them. If they are not available, the<br />
processes will he held on the waiting queue until some come free. The process will<br />
suspend its operation until it receives its request. See Example (3.31).<br />
On finishing with the resource the process must release it using the relinquish statement,<br />
saying how many units <strong>of</strong> what type are to be released 22 .<br />
Example 3.31 Here the Job requests, and if necessary waits for, one unit <strong>of</strong> a Machine <strong>of</strong> type 2.<br />
On acquisition it then holds it while it works for a random time (exponentially distributed, mean<br />
20.0) units and then relinquishes it again.<br />
process Job<br />
request 1 Machine(2)<br />
work exponential.f(20.0,3) units<br />
relinquish 1 Machine(2)<br />
end '' Job<br />
3.6 Standard Attributes<br />
Entities, sets, processes and resources have predefined standard attributes in addition to<br />
those defined by the user. These are listed in the manuals. Only a few are tabulated here:<br />
Some automatically generated attributes<br />
routines and variables<br />
Entities variable entity global variable<br />
variable<br />
Processes attribute<br />
Resources set<br />
set<br />
attribute<br />
N.entity<br />
time.a<br />
Q.resource<br />
X.resource<br />
no <strong>of</strong> entities in class (only<br />
permanent entities)<br />
next scheduled entry time for<br />
the process<br />
set <strong>of</strong> processes waiting for this<br />
resource<br />
set <strong>of</strong> processes using this<br />
resource<br />
U.resource number <strong>of</strong> idle units<br />
Sets attributes F.set first entity in set<br />
<strong>of</strong> owner L.set last entity in set<br />
entities N.set number <strong>of</strong> entities in set<br />
Sets attributes P.set pointer to predecessor in set<br />
25
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
<strong>of</strong> member S.set<br />
entities<br />
M.set<br />
pointer to successor in set<br />
equals 1 if entity is in the set, 0<br />
otherwise<br />
Thus the processes waiting for a resource R are listed in the set Q.R and the variable<br />
N.Q.R tells you how many there are.<br />
To list them, you would start at F.Q.R which is the first one waiting. If First.one =<br />
F.Q.R, the next one waiting is S.First.one (the successor to the first one).<br />
26
4. Statistical Aspects <strong>of</strong> Simulation<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong> provides a number <strong>of</strong> statistical facilities. These include random variate<br />
generation with different seed streams and statistical monitoring methods. See<br />
[(CACI)(1997)][Section 5.3].<br />
4.1 Random Number Generation<br />
There are 10 random number streams, numbered S = 1 ... 10. At any instant each stream<br />
has an integer seed value, which is updated every time the stream is called on for a<br />
random number. All the seed values are different. A stream's seed value can be found<br />
from the variable seed.v(S).<br />
The stream is updated using one <strong>of</strong> the random variable functions. All these have the<br />
stream as a parameter and update that stream one or more times whenever they are called.<br />
Example 4.1 Generating a random variable from stream 3.<br />
let S = 3<br />
let X = random.f(S)<br />
In this example, the seed value for stream 3 is updated to the next ``random'' integer and<br />
the real value X = seed.v(3)/(2 31 1) is returned as a real random variable 23 . Thus 0 < X < 1.<br />
Thus random.f(S) generates apparently uniform random deviates between 0 and 1. It uses<br />
one <strong>of</strong> the 10 random number seed variables. Each seed sequence <strong>of</strong> random integers is<br />
supposedly independent <strong>of</strong> <strong>of</strong> the others.<br />
The initial values <strong>of</strong> the seed integers (the starting seeds) from each <strong>of</strong> the STREAMs are<br />
initialized by at the start <strong>of</strong> a run. They are listed at the start <strong>of</strong> Appendix C <strong>of</strong><br />
[(Russell)(1983)]. For example, seed.v(1)=2116429302. You can supply your own initial<br />
integer values if you want:<br />
Example 4.2 Set the initial seed value for stream 3 to 2345.<br />
let seed.v(3) = 2345<br />
Pseudo-random variables can be generated from a number <strong>of</strong> distributions 24 :<br />
• binomial.f(N,P,STREAM)<br />
• erlang.f(Mean,K,STREAM)<br />
• exponential.f(Mean,STREAM)<br />
• gamma.f(Mean,K,STREAM)<br />
• log.normal.f(Mean,StdDev,STREAM)
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
• normal.f(Mean,StdDev,STREAM)<br />
• randi.f(Start,Finish,STREAM)<br />
• uniform.f(Start,Finish,STREAM)<br />
These routines contain calls to random.f(STREAM) and use the corresponding seed<br />
stream.<br />
Example 4.3 To generate a sample, x, from an exponential distribution with mean 20.0, using<br />
STREAM 1, one would use the following call. Notice that I have been careful to put in a decimal<br />
point into the first argument which must be real.<br />
x = exponential.f(20.0,1)<br />
NOTE: You must use real values if a routine requires a real argument. For example<br />
exponential.f(3, 1) will not give you a sample from an exponential with mean 3. Instead,<br />
you must use the call exponential.f(3.0, 1). does NOT automatically convert<br />
arguments from integer to real.<br />
4.2 Statistical Monitoring<br />
Any global variable can be automatically monitored by the system to calculate statistics.<br />
Little change has to be done to the program except by the addition <strong>of</strong> a special statement<br />
in the preamble. The two types <strong>of</strong> monitoring are tally and accumulate.<br />
4.2.1 Tally<br />
tally takes a sample every time the variable is changed. It is intended to monitor a number<br />
<strong>of</strong> individual observations, such as waiting times.<br />
Example 4.4 here in the preamble we define two global variables 25 and then indicate that they<br />
are to be monitored using the tally statement. The tally statement specifies that we want to find<br />
both the mean and standard deviation <strong>of</strong> the values <strong>of</strong> the waiting.time.<br />
preamble<br />
...<br />
define Waiting.time and Time.in.bank as real variables<br />
...<br />
tally Avg.Wait as the mean ,<br />
and Sd.Wait as the std.dev <strong>of</strong> Waiting.time<br />
...<br />
end ''preamble<br />
Later in the main part <strong>of</strong> the program the mean and standard deviation <strong>of</strong> the Waiting.time can be<br />
used:<br />
print 1 line with Avg.Wait and Sd.Wait thus<br />
Waiting time: mean = ****.***, sd = ****.***<br />
28
Statistical Aspects <strong>of</strong> Simulation<br />
4.2.2 Accumulate<br />
accumulate is intended to monitor variables that are continuous in time such as the length<br />
<strong>of</strong> a queue. Although it changes discretely, there is always a queue length existing 26 .<br />
accumulate calculates the time-integrals <strong>of</strong> the value such as the average queue length.<br />
Example 4.5 Here the queue at the Teller is to be monitored to determine the average <strong>of</strong> the<br />
number waiting for the Teller (held in N.Q.Teller).<br />
preamble<br />
...<br />
resources include Teller<br />
..<br />
accumulate Avg.Line<br />
as the mean <strong>of</strong> N.Q.Teller<br />
...<br />
end '' preamble<br />
Then in the main part <strong>of</strong> the program we could find out the average length <strong>of</strong> the line so far:<br />
print 1 line with Avg.Line thus<br />
The average number waiting so far is ****.***<br />
tally and accumulate can calculate a number <strong>of</strong> different statistics: number, sum, mean,<br />
sum.<strong>of</strong>.squares, mean.square, variance, std.dev, maximum, minimum.<br />
29
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
30
5. Acknowledgments<br />
Students in OPRE352 and COMP349 classes have, year by year, improved these notes by<br />
their comments and questions. I am also particularly grateful to Jay Braun, the author <strong>of</strong><br />
the Reference Handbook, [(CACI83)(1997)], and now with JPL, who kindly corrected a<br />
number <strong>of</strong> mistakes and suggested changes.<br />
I will be grateful for any corrections or suggestions for improvements to the document<br />
from students, experts, or anyone accessing it over the Web. My email address is<br />
Tony.Vignaux@vuw.ac.nz.<br />
5.1 References<br />
[(CACI83)(1997)]<br />
CACI83 (1997). <strong>SIMSCRIPT</strong> <strong>II.5</strong> Reference Handbook. C.A.C.I, 2nd edition.<br />
[(CACI89)(1989)]<br />
CACI89 (1989). UNIX <strong>SIMSCRIPT</strong> <strong>II.5</strong> User's Manual. C.A.C.I.<br />
[(Law and Larmey)(1984)]<br />
Law, A. M. and Larmey, C. S. (1984). An Introduction to Simulation using<br />
<strong>SIMSCRIPT</strong> <strong>II.5</strong>. C.A.C.I.<br />
[(CACI97)(1997)]<br />
CACI97 (1997). <strong>SIMSCRIPT</strong> <strong>II.5</strong> Programming Language. C.A.C.I.<br />
[(Pidd)(1992)]<br />
Pidd, M., editor (1992). <strong>Computer</strong> Simulation in Management <strong>Science</strong>. Wiley, 3rd<br />
edition.<br />
[(Russell)(1983)]<br />
Russell, E. C. (1983). Building Models with <strong>SIMSCRIPT</strong> <strong>II.5</strong>. C.A.C.I.<br />
5.1.1 Footnotes<br />
1 <strong>II.5</strong> disregards all periods written at the end <strong>of</strong> names and numbers. Thus the names<br />
flight...and flight.. become flight when the program is compiled. (<strong>SIMSCRIPT</strong> <strong>II.5</strong><br />
Reference Manual) You can have periods within an identifier.<br />
2 In the word ``mode'' is used instead <strong>of</strong> ``type''<br />
3 Don't read this! If a name is not explicitly declared, will declare it implicitly with<br />
double mode. Implicit declaration is strongly discouraged because it can lead to errors<br />
that are hard detect. We forbid this using a command in the preamble (see the beginning<br />
<strong>of</strong> Section 2.4).
<strong>SIMSCRIPT</strong> <strong>II.5</strong> <strong>Simplified</strong><br />
4 Arrays can be multiply-dimensioned and can even be ``ragged'' where the rows are not<br />
all <strong>of</strong> the same length<br />
5 In Unix systems, such a file can be read by redirection. For example, when running<br />
program harbour that is written to read from the terminal and write to the terminal,<br />
without changing the program we can make it read from datafile and write the results to<br />
file results. using: harbour < datafile > results<br />
6 See the definition <strong>of</strong> variable list in the Reference handbook<br />
7 See the documentation for others<br />
8 it also has a case statement<br />
9 Or always, otherwise<br />
10 Or in Global variables<br />
11 See the Reference Handbook<br />
12 A trace is an output record that lists every event and the simulation time it occurred. It<br />
is essential for debugging simulation code and can also be analyzed after a run to produce<br />
statistical results. We will be using traces frequently.<br />
13 Other time units are days. hours and minutes. Convention: unless the simulation is<br />
actually operating in days, hours and minutes, the term units will be used to measure<br />
time.<br />
14 At least one process must be activated before the simulation is started otherwise no<br />
simulation will occur<br />
15 See section 3.4 to find out more about processes<br />
16 [(Pidd)(1992)] treats entities more fully.<br />
17 The a is important<br />
18 You can use may belong to or can belong to instead <strong>of</strong> belongs to<br />
19 I get an error if the bracketed method is used though it is documented in the Reference<br />
handbook<br />
20 If this sounds a bit complicated, that is because it is. For comments on this, see [(Law<br />
and Larmey)(1984)].<br />
21 or in another routine<br />
32
Acknowledgements<br />
22 If you do not balance the request and relinquish pair your program may grind to a halt<br />
23 Because the largest integer that the seeds can take is (2 31 1)<br />
24 Yes, Valerie, there is a poisson distribution [poisson.f(Mean,STREAM)] but it is never<br />
used in simulations. Understand? Never!<br />
25 Remember you can only tally global variables<br />
26 though it may sometimes be zero<br />
33