1 (* Copyright (C
) 2009,2017 Matthew Fluet
.
2 * Copyright (C
) 1999-2006 Henry Cejtin
, Matthew Fluet
, Suresh
3 * Jagannathan
, and Stephen Weeks
.
5 * MLton is released under a BSD
-style license
.
6 * See the file MLton
-LICENSE for details
.
9 structure Random
: RANDOM
=
15 val alphaNumString
= alphaNumString
22 val word = Trace
.trace ("Random.word", Unit
.layout
, Word.layout
) word
23 val srand
= Trace
.trace ("Random.srand", Word.layout
, Unit
.layout
) srand
26 val ri
: int ref
= ref
0
27 val rw
= ref (word ())
28 val max
= Word.wordSize
- 1
33 val b
= 0w1
= Word.andb (0wx1
, Word.>> (!rw
, Word.fromInt i
))
43 fun int () = Word.toIntX (word ())
45 val int = Trace
.trace ("Random.int", Unit
.layout
, Int.layout
) int
50 val shft
= Option
.fold (Int.precision
, Word.wordSize
, Int.min
)
51 val shft
= Word.fromInt (shft
- 1)
53 Word.toInt (Word.notb (Word.<< (Word.notb
0w0
, shft
)))
56 val maxNatW
= Word.fromInt maxNat
58 fun nat () = Word.toInt (Word.andb (word (), maxNatW
))
60 val nat
= Trace
.trace ("Random.nat", Unit
.layout
, Int.layout
) nat
62 val maxNatR
= Real.fromInt maxNat
64 fun scale r
= r
/ maxNatR
66 val natReal
= Real.fromInt
o nat
68 val natReal
= Trace
.trace0 ("Random.natReal", Real.layout
) natReal
70 fun real () = scale (natReal () + scale (natReal ()))
72 val real = Trace
.trace0 ("Random.real", Real.layout
) real
76 val r
: word ref
= ref
0w0
77 val max
: word ref
= ref
0w0
79 fun wordLessThan (w
: word): word =
81 then Error
.bug
"Random.wordLessThan"
88 ; max
:= Word.notb
0wx0
)
90 val () = r
:= Word.div (w
', w
)
91 val () = max
:= Word.div (!max
, w
)
97 fun natLessThan (n
: int): int =
99 then Error
.bug
"Random.natLessThan"
100 else Word.toInt (wordLessThan (Word.fromInt n
))
102 fun charFrom (s
: string): char
=
103 Pervasive
.String.sub (s
, natLessThan (Pervasive
.String.size s
))
105 fun nRandom
{list
, length
, n
} =
107 fun loop (need
: int, length
: int, xs
: 'a list
, ac
: 'a list
): 'a list
=
108 (Assert
.assert ("Random.nRandom", fn () => need
<= length
)
112 [] => Error
.bug
"nRandom"
114 if natLessThan length
< need
115 then loop (need
- 1, length
- 1, xs
, x
:: ac
)
116 else loop (need
, length
- 1, xs
, ac
)))
117 in loop (n
, length
, list
, [])
120 val nRandom
= fn x
=>
123 fn {list
, length
, n
} => (length
= List.length list
126 fn l
=> n
= List.length l
))
131 val n
= List.length l
135 else SOME (List.nth (l
, natLessThan n
))