|
|
|
|
||
|
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.
|
||
|
|
|