#lang scribble/doc
@(require scribble/manual
scribblings/icons
(for-label scheme/base
plot/plot
"../simulation-with-graphics.ss"))
@title[#:tag "sets"]{Sets}
@local-table-of-contents[]
In the PLT Scheme Simulation Collection, a set is a general structure that maintains a doubly-linked list of its elements. The length of the list, i.e. the @schemefont{n} field, is implemented using a variable and, therefore, provide automatic data collection of its value.
@section{The @scheme[set-cell] Structure}
@schemeblock[
(struct set-cell (_next
_previous
_priority
_item))
_next : set-cell?
_previous : set-cell?
_priority : real?
_item : any?]
Represents an item in a set.
@section{The @scheme[set] Structure}
@schemeblock[
(struct set (_variable-n
_first-cell
_last-cell
_type))
_variable-n : variable?
_first-cell : (or/c set-cell? false/c)
_last-cell : (or/c set-cell? false/c)
_type : (one-of/c #:fifo #:lifo #:priority)]
Represents a collection of items whose length is implemented as a variable to facilitate automatic data collection.
@itemize{
@item{@schemefont{variable-n}---A variable that sores the number of elements in the set. This allows automatic data collection of the number of elements in the set. Bote that the actual number of elements is available (as an @scheme[exact-nonnegative-integer?]) using the pseudo-field @scheme[set-n].}
@item{@schemefont{first-cell}---The set cell representing the first item in the set ot @scheme[#f] if the set is empty.}
@item{@schemefont{last-cell}---The set cell representing the last item in the set ot @scheme[#f] if the set is empty.}
@item{@schemefont{type}---The type of the set. This is used for the generic set operations. Valid values are:
@itemize{
@item{@scheme[#:fifo]---a first-in-first-out set (i.e. a queue)}
@item{@scheme[#:lifo]---a last-in-first-out set (i.e. a stack)}
@item{@scheme[#:priority]---a priority set (i.e. a set whose elements are ordered by priority).}
}}
}
@defproc[(make-set (type (one-of/c #:fifo #:lifo #:priority) #:fifo)) set?]{
Returns a new, empty set of the specified @scheme[type]. If type is not specified, a first-in-first-out set is created (i.e. a queue).}
@defproc[(set-n (set set?)) exact-nonnegative-integer?]{
Returns the value of the @schemefont{n} field of the @schemefont{variable-n} field of @scheme[set]. This is the number of element in the set. Not that this is stored in a vriable to facilitate automatic data collection of the number of elements in a set.}
@section{Set Operations}
@defproc[(set-empty? (set set?)) boolean?]{
Returns true, @scheme[#t], if @scheme[set] is empty, that is if the number of elements in the set is @math{0}, and false, @scheme[#f], otherwise.}
@defproc[(set-first? (set set?)) any]{
Returns the first element of @scheme[set]. An error is signaled if @scheme[set] is empty.}
@defproc[(set-last? (set set?)) any]{
Returns the last element of @scheme[set]. An error is signaled if @scheme[set] is empty.}
@defproc[(set-for-each-cell (set set?) (proc (-> set-cell? any))) any]{
Iterates over the cells in @scheme[set] and applies the procedure @scheme[proc] to each cell in turn.}
@defproc[(set-for-each (set set?) (proc (-> any/c any))) any]{
Iterates over the elements in @scheme[set] and applied the procesure @scheme[proc] to each element in turn.}
@defproc[(set-find-cell (set set?) (item any/c)) (or/c set-cell? false/c)]{
Returns the first cell found in @scheme[set] that contains @scheme[item] or @scheme[#t] if it is not found.}
@defproc[(set-insert-cell-first! (set set?) (cell set-cell?)) any]{
Inserts @scheme[cell] as the first element of @scheme[set]. This is independent of the type of the set.}
@defproc[(set-insert-first! (set set?) (item any/c)) any]{
Creates a new cell containing @scheme[item] and inserts it as the first element of @scheme[set]. This is independent of the type of the set.}
@defproc[(set-insert-cell-last! (set set?) (cell set-cell?)) any]{
Inserts @scheme[cell] as the first element of @scheme[set]. This is independent of the type of the set.}
@defproc[(set-insert-last! (set set?) (item any/c)) any]{
Creates a new cell containing @scheme[item] and inserts it as the last element of @scheme[set]. This is independent of the type of the set.}
@defproc[(set-insert-cell-priority! (set set?) (cell set-cell?)) any]{
Inserts @scheme[cell] into @scheme[set] according to its priority. This is independent of the type of the set.}
@defproc[(set-insert-priority! (set set?) (item any/c) (priority real?)) any]{
Creates a new cell containing @scheme[item] with the specified @scheme[priority] and inserts it into @scheme[set] according to its priority. This is independent of the type of the set.}
@defproc[(set-remove-cell! (set set?) (cell set-cell?)) any]{
Removes @scheme[cell] from @scheme[set]. No error is raised if @scheme[cell] is not found.}
@defproc[(set-remove-item! (set set?) (item any/c)) (or/c set-cell? false/c)]{
Removes the cell containing @scheme[item] from @scheme[set]. If @scheme[item] is found, the cell containing it is returned, otherwise @scheme[#f] is returned.}
@defproc*[(((set-remove-first-cell! (set set?) (error-thunk (-> any))) any)
((set-remove-first-cell! (set set?)) set-cell?))]{
Removes the first cell from @scheme[set] and returns it. If @scheme[set] is empty and @scheme[error-think] is provided, it is evaluated and the result returned. Otherwise, if @scheme[set] is empty, an error is raised.}
@defproc*[(((set-remove-first! (set set?) (error-thunk (-> any))) any)
((set-remove-first! (set set?)) any))]{
Removes the first item from @scheme[set] and returns it. If @scheme[set] is empty and @scheme[error-think] is provided, it is evaluated and the result returned. Otherwise, if @scheme[set] is empty, an error is raised.}
@defproc*[(((set-remove-last-cell! (set set?) (error-thunk (-> any))) any)
((set-remove-last-cell! (set set?)) set-cell?))]{
Removes the last cell from @scheme[set] and returns it. If @scheme[set] is empty and @scheme[error-think] is provided, it is evaluated and the result returned. Otherwise, if @scheme[set] is empty, an error is raised.}
@defproc*[(((set-remove-last! (set set?) (error-thunk (-> any))) any)
((set-remove-last! (set set?)) any))]{
Removes the last item from @scheme[set] and returns it. If @scheme[set] is empty and @scheme[error-think] is provided, it is evaluated and the result returned. Otherwise, if @scheme[set] is empty, an error is raised.}
@section{Generic Set Routines}
@defproc[(set-insert! (set set?) (item any/c) (priotity real? 100)) any]{
Create a cell containing @scheme[item] and inserts it into @scheme[set] with the given @scheme[priority] according to the type of the set.}
@itemize{
@item{@scheme[#:fifo]---@scheme[item] is inserted at the end of @scheme[set]. The @scheme[priority], if provided, is ignored.}
@item{@scheme[#:lifo]---@scheme[item] is inserted at the beginning of @scheme[set]. The @scheme[priority], if provided, is ignored.}
@item{@scheme[#:priority]---@scheme[item] is inserted into @scheme[set] according to the @scheme[priority]. If @scheme[priority] is not provided, the default value of @math{100} is used.}
}
@defproc*[(((set-remove! (set set?) (item any/c)) any)
((set-remove! (set set?)) any))]{
If @scheme[item] is specified, the cell in @scheme[set] containing the element is removed and returned.
If @scheme[item] is not provided, removes the first element from @scheme[set] and returns it. An error is signaled if @scheme[set] is empty.}
@section{Example - Furnace Model 1}
The furnace model will be used in Chapter 10 Continuous Simulation Models to illustrate building a continuous model. This initial model is a purely discrete-event of the same system. The furnace itself is modeled by a set.
This simulation model is derived from an example in @italic{Introduction to Combined Discrete-Continuous Simulation Using SIMSCRIPT II.5} by Abdel-Moaty M Fayek @cite["Fayek02"].
@schememod[
scheme/base
(code:comment "Model 1 - Discrete Event Model")
(require (planet williams/simulation/simulation-with-graphics))
(require (planet williams/science/random-distributions))
(code:comment "Simulation Parameters")
(define end-time 720.0)
(define n-pits 7)
(code:comment "Data collection variables")
(define total-ingots 0)
(define wait-time (make-variable))
(coode:comment "Model Definition")
(define random-sources (make-random-source-vector 2))
(define furnace #f)
(define pit #f)
(define (scheduler)
(let loop ()
(schedule now (ingot))
(wait (random-exponential (vector-ref random-sources 0) 1.5))
(loop)))
(define-process (ingot)
(let ((arrive-time (current-simulation-time)))
(with-resource (pit)
(set-variable-value!
wait-time (- (current-simulation-time) arrive-time))
(set-insert! furnace self)
(work (random-flat (vector-ref random-sources 1) 4.0 8.0))
(set-remove! furnace self))
(set! total-ingots (+ total-ingots 1))))
(define (stop-sim)
(printf "Report after ~a Simulated Hours - ~a Ingots Processed~n"
(current-simulation-time) total-ingots)
(printf "~n-- Ingot Waiting Time Statistics --~n")
(printf "Mean Wait Time = ~a~n"
(variable-mean wait-time))
(printf "Variance = ~a~n"
(variable-variance wait-time))
(printf "Maximum Wait Time = ~a~n"
(variable-maximum wait-time))
(printf "~n-- Furnace Utilization Statistics --~n")
(printf "Mean No. of Ingots = ~a~n"
(variable-mean (set-variable-n furnace)))
(printf "Variance = ~a~n"
(variable-variance (set-variable-n furnace)))
(printf "Maximum No. of Ingots = ~a~n"
(variable-maximum (set-variable-n furnace)))
(printf "Minimum No. of Ingots = ~a~n"
(variable-minimum (set-variable-n furnace)))
(write-special
(history-plot (variable-history (set-variable-n furnace))
"Furnace Utilization History"))
(newline)
(stop-simulation))
(define (initialize)
(set! total-ingots 0)
(set! wait-time (make-variable))
(set! pit (make-resource n-pits))
(set! furnace (make-set))
(accumulate (variable-history (set-variable-n furnace)))
(tally (variable-statistics wait-time))
(schedule (at end-time) (stop-sim))
(schedule (at 0.0) (scheduler)))
(define (run-simulation)
(with-new-simulation-environment
(initialize)
(start-simulation)))
(run-simulation)]
The following is the resulting output.
@verbatim{
Report after 720.0 Simulated Hours - 479 Ingots Processed
-- Ingot Waiting Time Statistics --
Mean Wait Time = 0.1482393804317038
Variance = 0.24601817483957691
Maximum Wait Time = 3.593058032365832
-- Furnace Utilization Statistics --
Mean No. of Ingots = 4.0063959874393795
Variance = 3.2693449366238347
Maximum No. of Ingots = 7
Minimum No. of Ingots = 0}
@image["scribblings/images/model-1.gif"]