SRFI 27

Source of Random Bits

  1. SRFI 27
  2. Documentation
    1. SRFI 27
      1. Usage
      2. current-random-source
      3. registered-random-sources
      4. registered-random-source
      5. random-source?
      6. make-random-source
      7. new-random-source
      8. random-source-name
      9. random-source-documentation
      10. random-source-log2-period
      11. random-source-maximum-range
      12. random-source-entropy-source
      13. random-source-entropy-source-set!
      14. random-source-state-ref
      15. random-source-state-set!
      16. random-source-randomize!
      17. random-source-pseudo-randomize!
      18. random-source-make-integers
      19. random-source-make-reals
      20. random-source-make-u8vectors
      21. random-source-make-f64vectors
      22. current-entropy-source
      23. registered-entropy-sources
      24. registered-entropy-source
      25. entropy-source?
      26. make-entropy-source
      27. new-entropy-source
      28. entropy-source-name
      29. entropy-source-documentation
      30. entropy-source-u8
      31. entropy-source-f64
      32. entropy-source-u8vector
      33. entropy-source-f64vector
    2. Random Sources
      1. Pierre L'Ecuyer's Multiple Recursive Generator 32k3a random number generator
        1. Usage
        2. make-random-source-mrg32k3a
      2. George Marsaglia's Multiply With Carry random number generator
        1. Usage
        2. make-random-source-mwc
      3. George Marsaglia's Mother Of All random number generator
        1. Usage
        2. make-random-source-moa
    3. Composite Random Source
      1. Usage
      2. composite-random-source
    4. Entropy Sources
      1. System Clock
        1. Usage
        2. make-entropy-source-system-clock
      2. Windows Crypt Device
        1. Usage
        2. make-entropy-source-crypt
      3. Unix Random Device
        1. Usage
        2. make-entropy-source-urandom-device
        3. make-entropy-source-random-device
    5. Procedure Entropy Source
      1. Usage
      2. make-entropy-source/procedures
      3. make-entropy-source/f64procedure
    6. Port Entropy Source
      1. Usage
      2. entropy-port-lifetime
      3. make-entropy-source/port
      4. make-entropy-source/port-open
      5. make-entropy-source/port-open-timed
      6. make-entropy-source/file
    7. Simple Distributions
      1. Usage
      2. make-uniform-random-integers
      3. make-uniform-random-reals
    8. Vector Distributions
      1. Usage
      2. make-random-permutations
      3. random-permutation!
      4. make-random-vector
      5. random-vector!
      6. make-random-hollow-sphere
      7. random-hollow-sphere!
      8. make-random-solid-sphere
      9. random-solid-sphere!
    9. Other Distributions
      1. Usage
      2. make-random-normals
      3. make-random-exponentials
      4. make-random-triangles
      5. make-random-poissons
      6. make-random-bernoullis
      7. make-random-binomials
      8. make-random-geometrics
      9. make-random-lognormals
      10. make-random-cauchys
      11. make-random-gammas
      12. make-random-erlangs
      13. make-random-paretos
      14. make-random-levys
      15. make-random-weibulls
  3. Examples
  4. Notes
  5. Bugs and Limitations
  6. Requirements
  7. Author
  8. Version history
  9. License

Documentation

A Chicken implementation of SRFI 27.

SRFI 27

Most procedures are per the SRFI 27 specification document. Only the extensions are documented here.

The most obvious extensions are support for multiple random number generators and multiple entropy sources.

Usage

(use srfi-27)

current-random-source

[procedure] (current-random-source) => random-source
[procedure] (current-random-source RANDOM-SOURCE)

Parameter for the default random-source.

The variable default-random-source is the initial (current-random-source).

The initial random-source is an instace of 'mrg32k3a, per SRFI 27.

registered-random-sources

[procedure] (registered-random-sources) => (list-of symbol)

Returns a list of the registered random-source names.

registered-random-source

[procedure] (registered-random-source NAME) => (disjoint #f (procedure () random-source))

Returns the random-source creator for the specified NAME or #f if not registered.

random-source?

[procedure] (random-source? OBJ) => boolean
[procedure] (check-random-source LOC OBJ [NAM])
[procedure] (error-random-source LOC OBJ [NAM])

make-random-source

[procedure] (make-random-source [SOURCE (current-random-source)]) => random-source

SOURCE is either a random-source or the symbol of a registered random-source, the name.

new-random-source

[procedure] (new-random-source RANDOM-SOURCE) => random-source

Returns a new random-source from RANDOM-SOURCE.

Same as (make-random-source RANDOM-SOURCE).

random-source-name

[procedure] (random-source-name RANDOM-SOURCE) => symbol

The symbolic name of the RANDOM-SOURCE.

random-source-documentation

[procedure] (random-source-documentation RANDOM-SOURCE) => string

Some more information for the RANDOM-SOURCE.

random-source-log2-period

[procedure] (random-source-log2-period RANDOM-SOURCE) => integer

The period of the RANDOM-SOURCE as a power of 2. A fixnum.

random-source-maximum-range

[procedure] (random-source-maximum-range RANDOM-SOURCE) => inexact-integer

The largest integer the RANDOM-SOURCE can produce without resort to a bignum representation. An inexact-integer flonum, even for 64-bit CPUs.

random-source-entropy-source

[procedure] (random-source-entropy-source RANDOM-SOURCE) => entropy-source

The current entropy-source for the RANDOM-SOURCE.

random-source-entropy-source-set!

[procedure] (random-source-entropy-source-set! RANDOM-SOURCE ENTROPY-SOURCE)

Changes the current entropy-source for the RANDOM-SOURCE.

random-source-state-ref

[procedure] (random-source-state-ref RANDOM-SOURCE) => random-state

Per the SRFI 27 specification the random-state is a valid external representation.

random-source-state-set!

[procedure] (random-source-state-set! RANDOM-SOURCE RANDOM-STATE)

Only a RANDOM-STATE produced by a random-source-state-ref of the same random-source-name is acceptable.

random-source-randomize!

[procedure] (random-source-randomize! RANDOM-SOURCE [ENTROPY-SOURCE])

random-source-pseudo-randomize!

[procedure] (random-source-pseudo-randomize! RANDOM-SOURCE I J)

random-source-make-integers

[procedure] (random-source-make-integers RANDOM-SOURCE) => (procedure (integer) integer)

The variable random-integer is a procedure: (random-source-make-integers default-random-source)

random-source-make-reals

[procedure] (random-source-make-reals RANDOM-SOURCE [PRECISION]) => (procedure () real)

The variable random-real is a procedure: (random-source-make-reals default-random-source)

PRECISION maybe #f, in which case the value is flonum-epsilon.

random-source-make-u8vectors

[procedure] (random-source-make-u8vectors RANDOM-SOURCE) => (procedure (integer) u8vector)

Returns a procedure of one argument, the length of the generated vector, the returns a vector of random 8-bit unsigned values, a SRFI 4 u8vector.

The variable random-u8vector is a procedure: (random-source-make-u8vectors default-random-source)

random-source-make-f64vectors

[procedure] (random-source-make-f64vectors RANDOM-SOURCE [PRECISION]) => (procedure (integer) f64vector)

Returns a procedure of one argument, the length of the generated vector, the returns a vector of random 64-bit floatingpoint values, a SRFI 4 f64vector.

The variable random-f64vector is a procedure: (random-source-make-f64vectors default-random-source)

current-entropy-source

[procedure] (current-entropy-source) => entropy-source
[procedure] (current-entropy-source ENTROPY-SOURCE)

Parameter for the default entropy-source.

default-entropy-source is the initial (current-entropy-source).

The initial entropy-source is an instace of 'system-clock.

registered-entropy-sources

[procedure] (registered-entropy-sources) => (list-of symbol)

Returns a list of the registered entropy-source names.

registered-entropy-source

[procedure] (registered-entropy-source NAME) => (disjoint #f (procedure () entropy-source))

Returns the entropy-source creator for the specified NAME or #f if not registered.

entropy-source?

[procedure] (entropy-source? OBJ) => boolean
[procedure] (check-entropy-source LOC OBJ [NAM])
[procedure] (error-entropy-source LOC OBJ [NAM])

make-entropy-source

[procedure] (make-entropy-source [SOURCE (current-entropy-source)]) => entropy-source

SOURCE is either a entropy-source or the symbol of a registered entropy-source, the name.

new-entropy-source

[procedure] (new-entropy-source ENTROPY-SOURCE) => entropy-source

Returns a new entropy-source from ENTROPY-SOURCE.

Same as (make-random-entropy ENTROPY-SOURCE).

entropy-source-name

[procedure] (entropy-source-name ENTROPY-SOURCE) => symbol

The symbolic name of the ENTROPY-SOURCE.

entropy-source-documentation

[procedure] (entropy-source-documentation ENTROPY-SOURCE) => string

Some more information for the ENTROPY-SOURCE.

entropy-source-u8

[procedure] (entropy-source-u8 ENTROPY-SOURCE) => fixnum

Returns a non-negative fixnum from the ENTROPY-SOURCE.

entropy-source-f64

[procedure] (entropy-source-f64 ENTROPY-SOURCE) => flonum

Returns a flonum from the ENTROPY-SOURCE.

entropy-source-u8vector

[procedure] (entropy-source-u8vector ENTROPY-SOURCE LENGTH [U8VECTOR]) => u8vector

Returns a u8vector with the 0 thru LENGTH-1 elements filled with non-negative fixnums from the ENTROPY-SOURCE. If U8VECTOR is supplied then this is used otherwise a new vector is returned.

entropy-source-f64vector

[procedure] (entropy-source-f64vector ENTROPY-SOURCE LENGTH [F64VECTOR]) => f64vector

Returns a f64vector with the 0 thru LENGTH-1 elements filled with flonums from the ENTROPY-SOURCE. If F64VECTOR is supplied then this is used otherwise a new vector is returned.

Random Sources

A random source module must be loaded before it can be used. This maybe obvious but a call of (make-random-source 'moa) will fail unless the extension "moa" is loaded.

See make-random-source for use of the NAME.

Pierre L'Ecuyer's Multiple Recursive Generator 32k3a random number generator

Usage
(use mrg32k3a)
make-random-source-mrg32k3a
[procedure] (make-random-source-mrg32k3a) => random-source

Registered NAME is 'mrg32k3a

George Marsaglia's Multiply With Carry random number generator

Usage
(use mwc)
make-random-source-mwc
[procedure] (make-random-source-mwc) => random-source

Registered NAME is 'mwc

George Marsaglia's Mother Of All random number generator

Usage
(use moa)
make-random-source-moa
[procedure] (make-random-source-moa) => random-source

Registered NAME is 'moa

Composite Random Source

Usage

(use composite-random-source)

composite-random-source

[procedure] (composite-random-source [RANDOM-SOURCE ...] [#:comb-int INTEGER-COMBINE] [#:comb-real REAL-COMBINE]) => random-source

Returns a new random-source that combines the behaviors of the supplied RANDOM-SOURCE ....

INTEGER-COMBINE default is (lambda (ints bnd) (modulo (apply + ints) bnd)).

REAL-COMBINE default is (lambda (reals prec) (apply * reals)).

Does not register the constructed random-source.

Experimental at best.

Entropy Sources

An entropy source module must be loaded before it can be used.

System Clock

Usage
(use entropy-clock)
make-entropy-source-system-clock
[procedure] (make-entropy-source-system-clock) => entropy-source

Registered NAME is 'system-clock

Windows Crypt Device

Usage
(use entropy-windows)
make-entropy-source-crypt
[procedure] (make-entropy-source-crypt [BUFFER-LENGTH]) => entropy-source

Registered NAME is 'crypt

Unix Random Device

Usage
(use entropy-unix)
make-entropy-source-urandom-device
[procedure] (make-entropy-source-urandom-device) => entropy-source

Registered NAME is 'random-device

make-entropy-source-random-device
[procedure] (make-entropy-source-random-device) => entropy-source

Registered NAME is 'urandom-device

Procedure Entropy Source

U8PROC is a procedure of no arguments returning a fixnum in the range 0 .. 255.

F64PROC is a procedure of no arguments returning a finite flonum.

Usage

(use entropy-procedure)

make-entropy-source/procedures

[procedure] (make-entropy-source/procedures U8PROC F64PROC [#:name (gensym 'procedures-)] [#:docu "Entropy from procedures"]) => entropy-source

Returns an unregistered entropy-source built from the supplied U8PROC and F64PROC procedures.

make-entropy-source/f64procedure

[procedure] (make-entropy-source/f64procedure F64PROC [#:name (gensym 'procedures-)] [#:docu "Entropy from procedures"]) => entropy-source

Returns an unregistered entropy-source built from the supplied F64PROC procedure.

Port Entropy Source

Usage

(use entropy-port)

entropy-port-lifetime

[procedure] (entropy-port-lifetime) => flonum
[procedure] (entropy-port-lifetime SECONDS)

Gets and sets the number of SECONDS an entropy port is kept open without any activity.

SECONDS maybe #f, in which case the lifetime determined by GC finalizstion.

This is not a parameter!

make-entropy-source/port

[procedure] (make-entropy-source/port PORT [#:name (gensym 'port-)] [#:docu "Entropy from an open port"]) => entropy-source

Returns an unregistered entropy-source built from the supplied PORT, which is treated as a binary stream.

The PORT is kept open and must be closed by the caller, if at all.

make-entropy-source/port-open

[procedure] (make-entropy-source/port-open OPENER [#:name (gensym 'port-)] [#:docu "Entropy from port"]) => entropy-source

Returns an unregistered entropy-source built from the supplied OPENER.

OPENER is a (procedure () port), returning an opened port.

The returned port has an (entropy-port-lifetime) so the port may be closed and OPENER called more than once.

make-entropy-source/port-open-timed

[procedure] (make-entropy-source/port-open-timed OPENER SECONDS [#:name (gensym 'timed-port-)] [#:docu "Entropy from timed open port"]) => entropy-source

Returns an unregistered entropy-source built from the supplied OPENER & SECONDS.

SECONDS is interpreted as with entropy-port-lifetime.

OPENER is interpreted as with make-entropy-source/port-open.

make-entropy-source/file

[procedure] (make-entropy-source/file NAMSTR [#:name (gensym 'file-)] [#:docu (string-append "Entropy from file \"" namstr "\"")]) => entropy-source

Returns an unregistered entropy-source using the file named by the pathname NAMSTR.

The opened port for the file NAMSTR is interpreted as with make-entropy-source/port-open.

Simple Distributions

Provides exact-real and inexact-real generators.

All return 2 values: the generator itself and a procedure returning the argument values used to parameterize the generator. The second return value can be safely ignored, as it is below.

Usage

(use srfi-27-uniform-random)

make-uniform-random-integers

[procedure] (make-uniform-random-integers [#:high #f] [#:low 0] [#:precision 1] [#:source (current-random-source)]) => (procedure () integer)

low, high and precision are integers.

source is a random-source.

high, if not supplied, is the (random-source-maximum-range source).

The generator returns integers in the range low .. high with an index of precision. Unlike a (random-integer) result negative integers are possible.

The range of the generator is checked for logical soundness.

make-uniform-random-reals

[procedure] (make-uniform-random-reals [#:precision #f] [#:source (current-random-source)]) => (procedure () real)

The generator is as (random-source-make-reals source precision).

Vector Distributions

The procedures named as per make-random-... return a procedure of one argument N, the length of vector to be created.

The procedures named random-...! side-effect the supplied vector.

The nomenclature vector% is used to indicate a disjoint type union of vector, f32vector, f64vector. If the user is really keen to access the API for this type it is available in the, undocumented, "srfi-27-vector-support" module.

Usage

(use srfi-27-vector)

make-random-permutations

random-permutation!

[procedure] (make-random-permutations [#:randoms (make-uniform-random-integers)]) => (procedure (integer) vector)
[procedure] (random-permutation! VECTOR [#:randoms (make-uniform-random-integers)]) => vector

Performs the "Knuth shuffle" (or "Fisher-Yates shuffle").

Fills VECTOR with a random permutation of the finite set {0 ... N-1}, where N = (vector-length VECTOR).

make-random-vector

random-vector!

[procedure] (make-random-vector [#:randoms (make-uniform-random-reals)]) => (procedure (integer) vector)
[procedure] (random-vector! VECTOR% [#:randoms (make-uniform-random-reals)]) => vector%

Fills VECTOR with inexact real random numbers from the random distribution generator randoms.

make-random-hollow-sphere

random-hollow-sphere!

[procedure] (make-random-hollow-sphere [#:mu 0.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure (integer) vector)
[procedure] (random-hollow-sphere! VECTOR% [#:mu 0.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => vector%

Fills VECTOR% with inexact real random numbers the sum of whose squares is equal to 1.0. Thinking of VECTOR% as coordinates in space of dimension N = (vector%-length VECTOR%), the coordinates are uniformly distributed over the surface of the unit n-sphere.

make-random-solid-sphere

random-solid-sphere!

[procedure] (make-random-solid-sphere [#:mu 0.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure (integer) vector)
[procedure] (random-solid-sphere! VECTOR% [#:mu 0.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => vector%

Fills VECTOR% with inexact real random numbers the sum of whose squares is less than 1.0. Thinking of VECTOR% as coordinates in space of dimension N = (vector%-length VECTOR%), the coordinates are uniformly distributed within the unit n-sphere.

Other Distributions

Provides generators for some common distributions ranging over some subset of the inexact-reals. The domain of the generators depends, of course, on the specific distribution.

All return 2 values: the generator itself and a procedure returning the argument values used to parameterize the generator. The second return value can be safely ignored, as it is below.

Usage

(use srfi-27-distributions)

make-random-normals

[procedure] (make-random-normals [#:mu 0.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-exponentials

[procedure] (make-random-exponentials [#:mu 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-triangles

[procedure] (make-random-triangles [#:s 0.0] [#:m 0.5] [#:l 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-poissons

[procedure] (make-random-poissons [#:mu 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () integer)

make-random-bernoullis

[procedure] (make-random-bernoullis [#:p 0.5] [#:randoms (make-uniform-random-reals)]) => (procedure () boolean)

make-random-binomials

[procedure] (make-random-binomials [#:t 1] [#:p 0.5] [#:randoms (make-uniform-random-reals)]) => (procedure () integer)

make-random-geometrics

[procedure] (make-random-geometrics [#:p 0.5] [#:randoms (make-uniform-random-reals)])) => (procedure () integer)

make-random-lognormals

[procedure] (make-random-lognormals [#:mu 1.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-cauchys

[procedure] (make-random-cauchys [#:median 0.0] [#:sigma 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-gammas

[procedure] (make-random-gammas [#:alpha 1.0] [#:theta 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-erlangs

[procedure] (make-random-erlangs [#:alpha 1] [#:theta 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-paretos

[procedure] (make-random-paretos [#:alpha 1.0] [#:xmin 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-levys

[procedure] (make-random-levys [#:gamma 1.0] [#:delta 0.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

make-random-weibulls

[procedure] (make-random-weibulls [#:shape 1.0] [#:scale 1.0] [#:randoms (make-uniform-random-reals)]) => (procedure () real)

Examples

(use srfi-27 mwc srfi-27-uniform-random srfi-27-vector entropy-unix entropy-port)

(define (make-random-k-vector #!optional (k 1024))
  (let ((rs1 (make-random-source 'mwc)) ; or (make-random-source-mwc)
        (org (entropy-port-lifetime)) ) ; 'entropy-port-lifetime' is not a parameter!
    (entropy-port-lifetime 30) ; don't keep open port around too much
    (random-source-entropy-source-set! rs1 (make-entropy-source-random-device))
    (entropy-port-lifetime org)
    (make-random-vector #:randoms (make-uniform-random-integers #:high k #:low (- k) #:precision 2 #:source rs1))))
(use data-structures entropy-procedure)

(define (make-entropy-constant n)
  (make-entropy-source/f64procedure
    (constantly (exact->inexact n))
    #:name (string->uninterned-symbol (conc "entropy-constant-" n))
    #:docu (conc "Entropy constant " n)) )
(use srfi-1 srfi-13 coops)

;; Named (has a name) "concept"

(define-generic (name obj))
(define-class <named> () (
  (namsym #:reader name) ) )

;; Moves forward thru a set of values "concept"

(define-generic (step-function obj))
(define-class <stepper> () (
  (nxtval #:reader step-function) ) )
(define-generic (next-value obj))
(define-method (next-value (obj <stepper>)) ((step-function obj)))

;; Parameterized extension "concept"

(define-generic (parameters obj))
(define-generic (basis obj))
(define-class <parameterized> () (
  (parms #:reader parameters)
  (src #:reader basis) ) )

;; Parameterized generative set of random values "concept"

(define-class <random-distribution> (<named> <parameterized> <stepper>) (
  temp ) )

;; Create an instance of <random-distribution> where the arguments are
;; the same as the documented procedural distribution API.
;;
;; SRFI 27 API: ({some distribution constructor} arg...)
;;      OO API: (make-random-distribution {some distribution constructor} arg...)

(define-syntax make-random-distribution
  (syntax-rules ()
    ((_ ?ctor ?arg0 ...)
      (make <random-distribution> 'temp (?ctor ?arg0 ...)) ) ) )

(define-method (initialize-instance (obj <random-distribution>))
  ; The 'ctor' should be a globally defined procedure compiled
  ; with procedure-information. So if following nomenclature then the last
  ; procedure name element will be the kind of distribution.
  (let* ((temp (slot-value obj 'temp))
         (ctor (car temp))
         (procinfo (procedure-information ctor))
         (name (and procinfo (pair? procinfo) (symbol->string (car procinfo))))
         (name (and name
                    (and-let* ((kndpos (string-index-right name #\-)))
                      (substring/shared name (fx+ kndpos 1)) ) ) )
         (dstr-vals (receive (apply ctor (cdr temp))))
         (parms (and (fx<= 2 (length dstr-vals)) (receive ((second dstr-vals))))) )
    (set! (slot-value obj 'temp) #f) ;"free" the "any" slot
    (set! (slot-value obj 'namsym) (string->symbol name))
    (set! (slot-value obj 'nxtval) (first dstr-vals))
    (set! (slot-value obj 'parms) (and parms (drop-right parms 1)))
    (set! (slot-value obj 'src) (and parms (last parms))) ) )

; Use it

(use srfi-27-distributions)

(make-random-distribution make-random-exponentials #:mu 0.5)
;=> <random-distribution> with
; name          'exponentials
; step-function <procedure>
; parameters    '(0,5)
; basis         <procedure>

Notes

Bugs and Limitations

Currently 64-bit fixnum bounds are processed as if using a 32-bit platform. However, due to the bignum implementation results in the 64-bit fixnum range are coerced to fixnum.

Requirements

miscmacros numbers check-errors synch vector-lib thread-utils timed-resource

Author

Kon Lovett

Version history

3.1.8
Fix for ticket #630.
3.1.7
Fix for unsigned integer from entropic f64.
3.1.6
Fix for composite-random-source missing argument.
3.1.5
Fix for mrg32k3a bad state values.
3.1.4
Fix for mrg32k3a-pack-state bad index.
3.1.3
Fix for 64-bit fixnums and random integers.
3.1.2
Fix for "entropy-windows" make-entropy-source-crypt.
3.1.1
Moved thread stuff to own extensions.
3.1.0
Changed all random-source-name to lowercase symbols. Changed random-state tags to same as random-source-name. Added new-(random|entroppy)-source, @(random|entroppy)-source-constructor & (random|entroppy)-source-name. Exported registered-(random|entroppy)-sources & registered-(random|entroppy)-source.
3.0.1
Bug fix for bad external state symbol. Use of 64-bit arithmetic instead of double in C code.
3.0.0
Initial release for Chicken 4

License

Copyright (C) 2010 Kon Lovett. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Does not supercede any restrictions found in the source code.