ESHLL - An Event Scheduling High Level Language

ESHLL is a high level language that will compile a high level event scheduling model into python code that can then be runned within our framework.

The language and the compiler are rough prototypes. The compiler may allow some invalid model to compile. Also, not all features of our framework can be described in ESHLL.

A First Example - The Cashier Model

The code written by hand and described in the Using the ESAS Frameworks section.
#
# Cashier example
#
#

# location of simulator
import sys, os
sys.path.append(os.pardir + os.sep + 'es')

# frame work modules
from sim import *
from model import *
from event import *

from rng import *

# constants
IDLE = Utilization.IDLE
BUSY = Utilization.BUSY
end_time = 100

# priorities
LOW  = 1
HIGH = 2

# Random Number Generator
rng_10_2 = IntUniform(mean = 10, spread = 2)


# a flag to make it run with or without priorities
priorityOn = 0

#
# This is a start event.  It will be the first
# event scheduled.
#
class MyStartEvent(StartEvent):

    # handler routine
    def execute(self, sched, state):
        # create state variables and add then to
        # the state set
        state.add(QueueVar("queue_length"))
        state.add(Utilization("cashier_state", IDLE))

        # schedule the first arrival at time 0
        sched.schedule(ArrivalEvent(0))
        # schedule the end event at time end_time
        sched.schedule(StatsEndEvent(end_time))



# represents the arrival of a customer
class ArrivalEvent(Event):

    def __init__(self, time):
        Event.__init__(self, time)
        if priorityOn:
            self.setPriority(LOW)


    # handler routine
    def execute(self, sched, state):
        # current time
        time = self.getTime()

        # get variables needed
        queue = state.getStateVar("queue_length")
        cashier_state = state.getStateVar("cashier_state")
        
        sched.schedule(ArrivalEvent(time + rng_10_2.next()))
        if (queue.isEmpty()):
            if (cashier_state.isIdle()):
                cashier_state.setValue(BUSY)
                sched.schedule(DepartureEvent(time + 25))
            else:
                # note:
                # This simply increases the queue length by 1.
                # No object is actually enqueued.
                # It is equivalent to:
                #   queue.setValue(queue.getValue() + 1)
                queue.enqueue()
        else:
            queue.enqueue()
            

class DepartureEvent(Event):

    def __init__(self, time):
        Event.__init__(self, time)
        if priorityOn:
            self.setPriority(HIGH)


    def execute(self, sched, state):
        time = self.getTime()
        queue = state.getStateVar("queue_length")
        cashier_state = state.getStateVar("cashier_state")

        if (queue.isEmpty()):
            # note: equivalent to: cashier_state.setValue(IDLE)
            cashier_state.releaseFacility()
        else:
            queue.dequeue()
            sched.schedule(DepartureEvent(time + 25))


#
# Construct a model object.
# An instance of our start event is required.
# An optional name may be given.
#
# This model is passed on to the simulator.
#
mymodel = Model(MyStartEvent(), "Super Market")
simulator = Simulator(mymodel)


if __name__ == "__main__":
    if len(sys.argv) > 1:
        if sys.argv[1] == 'p':
            print "Using priorities"
            priorityOn = 1
    simulator.setTrace()  # turn on trace mode, default output file
    simulator.run()       # simulates

The same model written in ESHLL (file):

# ES simulator path
simpath: "../es"


# Section declaring and initializing all the state variables.
vars:
QueueVar queue_length          # default is 0 for a QueueVar
Utilization cashier_state = 0  # 0 - Idle, 1 - Busy


# Section declaring all events and handler routines
events:

MyStart start event {
  # schedule first arrival and EndEvent
  #  using 'abs' is optional, by default the time
  #  expression is taken to be absolute
  # End or StatsEnd can be used, or any user-defined
  # end event.
  schedule Arrival 0
  schedule StatsEnd abs 100
}

Arrival event {
  schedule Arrival rel randomInt(10, 2) 

  if queue_length == 0 {
    if cashier_state == 0 {
      cashier_state = 1
      schedule Departure rel 25
    } else {
      queue_length = queue_length + 1
    }  
  } else {  # queue_length != 0
    queue_length = queue_length + 1
  }
}

Departure event {
  if queue_length == 0 {
    cashier_state = 0
  } else {
    queue_length = queue_length - 1
    schedule Departure current_time + 25
  }
}

### end-of-file ###

This model description can then be compiled with the ESHLL compiler.

[lab105n-2] [/net/fs1/u18/ugrad/dbelan2/work/cs522_project/src/examples] python ../eshllc/compiler.py es_cashier.model

The following python code is generated by the compiler:

#
# Code generated by the eshll compiler
#

# set simulator path
import sys
sys.path.append('../es')

from sim import *
from model import *
from event import *
from rng import *

# random number generators
randomInt__10_2__ = IntUniform(mean = 10, spread = 2)

class MyStartEvent(StartEvent):

    # Handler routine
    def execute(self, sched, state):
        # Create and initialize state variables
        state.add(Utilization('cashier_state', 0))
        state.add(QueueVar('queue_length'))

        sched.schedule(ArrivalEvent(0))
        sched.schedule(StatsEndEvent(100))


class ArrivalEvent(Event):

    # Handler routine
    def execute(self, sched, state):
        sched.schedule(ArrivalEvent(state.getValue('current_time') + randomInt__10_2__.next()))
        if state.getValue('queue_length') == 0:
            if state.getValue('cashier_state') == 0:
                state.setValue('cashier_state', 1)
                sched.schedule(DepartureEvent(state.getValue('current_time') + 25))
            else:
                state.setValue('queue_length', state.getValue('queue_length') + 1)
        else:
            state.setValue('queue_length', state.getValue('queue_length') + 1)


class DepartureEvent(Event):

    # Handler routine
    def execute(self, sched, state):
        if state.getValue('queue_length') == 0:
            state.setValue('cashier_state', 0)
        else:
            state.setValue('queue_length', state.getValue('queue_length') - 1)
            sched.schedule(DepartureEvent(state.getValue('current_time') + 25))


mymodel = Model(MyStartEvent(), 'model_name')
simulator = Simulator(mymodel)

if __name__ == '__main__':
    simulator.setTrace()
    simulator.run()

# end-of-code generated

We obtained the same simulation results by running the generated code.

A Second Example

This examples uses parametrized event. We modeled a super market with 2 cashiers. One is an express cashier (4 items or less / 8 items or less) and the other a regular cashier. See the model source code for a more complete model description.

We have plotted the data from the trace files. The blue curve is the express cashier queue, the red is the regular cashier queue.


Case: 4 items or less for express cashier


Case: 8 items or less for express cashier


Back

$Id: eshll.html,v 1.1.1.1 2003/03/22 05:15:49 dbelan2 Exp $