DEFINITION MODULE SimEvents;
(*******************************************************************
Module SimEvents (MW_V3.0)
Copyright (c) 1993-2006 by Andreas Fischlin and ETH Zurich.
Purpose Support for discrete event simulations (DEVS)
according to the event scheduling approach.
Remarks This module is part of the optional client interface of
'ModelWorks', an interactive Modula-2 modelling and
simulation environment.
Programming
o Design
Andreas Fischlin 07/03/1993
o Implementation
Andreas Fischlin 07/03/1993
ETH Zurich
Systems Ecology
CHN E 35.1
Universitaetstrasse 16
8092 Zurich
SWITZERLAND
URLs:
<mailto:RAMSES@env.ethz.ch>
<http://www.sysecol.ethz.ch>
<http://www.sysecol.ethz.ch/SimSoftware/RAMSES>
Last revision of definition: 17/10/2004 AF
*******************************************************************)
FROM SYSTEM IMPORT ADDRESS, BYTE;
FROM SimBase IMPORT Model;
(****************************************)
(*##### Discrete event classes #####*)
(****************************************)
CONST
minEventClass = 0;
maxEventClass = 3000;
unknownEventClass = maxEventClass;
timeAdvanceEventClass = maxEventClass - 7;
TYPE
EventClass = [minEventClass..maxEventClass];
(*
Each state transition of a DEVS is characterized by a
particular discrete event class. A DEVS owns a finite
set of event classes. Each event class must be positive
and unique within the simulation environment and must be
declared and associated with a given state transition
function via a data structure of type StateTransition.
The set of event classes respectively state transition
functions belonging to a DEVS are declared when calling
procedure DeclDiscEvtM. Event classes are mainly useful
if another model wishes to produce an event output. Such
a model, e.g. a continuous time (DESS) or discrete time
model (SQM), may do so by scheduling the event output
together with the appropriate event class (using
procedure ScheduleEvent). If the simulation time is
advanced to the time the event is due, ModelWorks will
then dispatch the event to the appropriate state
transition function. NOTE: timeAdvanceEventClass is an
event class reserved for internal use.
*)
Transaction = ADDRESS;
(*
Every discrete event may be associated with a particular set
of data, the transaction. E.g. arriving customers may be
described by several attributes such as sex, age, demand
etc. Use nilTransaction to schedule or handle data-less
events.
*)
TYPE
StateTransitionFunction = PROCEDURE (Transaction);
StateTransition = RECORD
ec: EventClass;
fct: StateTransitionFunction;
END;
(*
Associates state transition function fct with the event class
cl. Typically a state transition function changes
instantaneously the state of a DEVS if a corresponding event
is encountered.
*)
VAR
nilTransaction: Transaction; (* read only! *)
noStateTransition: ARRAY [0..0] OF StateTransition; (* read only! *)
PROCEDURE AsTransaction(VAR d: ARRAY OF BYTE): Transaction;
(*
Converts any data structure into a Transaction.
Example:
ScheduleEvent(ec,tau,AsTransaction(myGlobOjbect));
schedules an event of class ec operating on the transaction
myGlobOjbect. myGlobOjbect has been declared as a global
variable and is of type ObjectDescriptor, the latter having
been declared similar to this:
TYPE ObjectDescriptor = RECORD
x,y: INTEGER;
r: REAL;
...
END;
Fields of the transaction may then be accessed from within the
state transition function associated with the event class ec as
follows:
PROCEDURE MyStatetransFct (alfa: Transaction);
VAR theObj: ObjectDescriptor;
BEGIN
theObj := alfa;
WITH theObj^ DO
IF x=y THEN r := ...
...
END(*WITH*);
END MyStatetransFct;
Make sure that the transaction exists not only during scheduling,
but also when it is becomes due; otherwise the state transition
function is likely to corrupt your program.
*)
PROCEDURE EventClassExists(ec: EventClass): BOOLEAN;
(*
Tests whether any DEVS has been declared to ModelWorks which does
provide state transitions for the event class ec.
*)
(*************************************************************)
(*##### Declaration of discrete event models (DEVS) #####*)
(*************************************************************)
VAR
dummyDEVChg: REAL;
(*
Use this dummy variable instead of the formal parameter ds
(Derivative or NewState) tau declaring state variables
belonging to a discrete event model (see procedure DeclSV
from module SimBase.
*)
PROCEDURE DeclDEVM(VAR m: Model; initialize, input, output: PROC;
statetransfct: ARRAY OF StateTransition; terminate,
declModelObjects: PROC; descriptor, identifier: ARRAY OF CHAR;
about: PROC);
(*
Declares a discrete event model (DEVS). The array
statetransfct contains for every event class the corresponding
state transition function. For all other formal parameters see
DeclM from module SimBase. The integration method will appear
as discreteEvent (see IntegrationMethod from module SimBase).
StateTransitions remain known to ModelWorks as long as owner
model remains declared.
IMPLEMENTATION RESTRICTION: During simulations event classes can't be
reused, e.g. by removing a model (using SimBase.RemoveM) and
immediately reusing the same event classes for another model by calling
DeclDEVM. This implies that every event class has to be uniquely
associated with a single model during the entire course of a simulation
run.
*)
PROCEDURE GetDefltDEVM(VAR m: Model; VAR initialize, input, output: PROC;
VAR statetransfct: ARRAY OF StateTransition; VAR terminate: PROC;
VAR descriptor, identifier: ARRAY OF CHAR; VAR about: PROC);
PROCEDURE SetDefltDEVM(VAR m: Model; initialize, input, output: PROC;
statetransfct: ARRAY OF StateTransition; terminate: PROC;
descriptor, identifier: ARRAY OF CHAR; about: PROC);
(**********************************)
(*##### Event scheduling #####*)
(**********************************)
CONST
always = MIN(REAL);
never = MAX(REAL);
VAR
schedulingDone: BOOLEAN;
PROCEDURE InitEventScheduler;
(*
Clears the event scheduling mechanism, i.e. the event
scheduling queue, of the simulation environment. Any
eventually still pending events will be discarded. Then it
makes the scheduling mechanism ready to accept events always by
calling SchedulingOnlyAfter(always).
*)
PROCEDURE ScheduleEvent(ec: EventClass; tau: REAL; alfa: Transaction);
PROCEDURE ScheduleEventAt(ec: EventClass; t: REAL; alfa: Transaction);
(*
Schedule the event of class ec for transaction alfa. Use
nilTransaction to schedule an event without a transaction,
i.e. without any data and attributes. The event will be
due after time tau has elapsed (routine ScheduleEvent) or
at the specified time t (routine ScheduleEventAt). The
event can only be successfully scheduled if the following
condition is satisfied (t+tau) >= tmin or t >= tmin,
respectively. If the scheduling was successful =>
schedulingDone = TRUE.
*)
PROCEDURE NextEventAt(): REAL;
(* Returns the time (ts+tau) at which the next pending event is due. *)
PROCEDURE ProbeNextPendingEvent(VAR ec: EventClass; VAR when: REAL;
VAR alfa: Transaction);
(*
Retrieves the characteristics of the next pending event. The
time when (ts+tau) is the due time.
*)
PROCEDURE GetNextPendingEvent (VAR ec: EventClass; VAR when: REAL;
VAR alfa: Transaction);
(*
Retrieves the characteristics and removes the next pending
event from the event scheduling queue.
*)
PROCEDURE PendingEvents(): INTEGER;
(* Returns the total number of currently pending events *)
PROCEDURE SchedulingOnlyAfter(tmin: REAL);
(*
Disallows the scheduling of any events with a due time <
tmin. Once this routine has been called, ScheduleEvent is
only succesful, if it schedules events with a due time >=
tmin. Note, ModelWorks' run time systems automatically
updates the scheduling time tmin in order to disallow
scheduling of events in the past and hereby enforcing a
monotonely advancing time.
*)
PROCEDURE EarliestSchedulingPossibleAt(): REAL;
(*
Returns the time at which the next possible scheduling can
take place. For instance used after calling
SchedulingOnlyAfter to learn about the earliest possible
next time point at which you can successfully schedule an
event.
*)
PROCEDURE DiscardEventsAfter(ec: EventClass; aftert: REAL; alfa: Transaction);
(*
Discards from the event scheduling queue all events for event
class ec, due after the time aftert, and which operate on the
transaction alfa. Note: events with a due time = aftert are
also discarded. (event is only really discarded if alfa is
the same as the scheduled transaction!)
*)
PROCEDURE DiscardEventsBefore(beforet: REAL);
(*
discards from the event scheduling queue all events for which
the due time < beforet. Note: events with a due time = beforet
are not discarded)
*)
END SimEvents.