1(* Random -- Moscow ML library 1995-04-23, 1999-02-24 *)
2structure Random :> Random =
3struct
4
5type generator = {seedref : real ref}
6
7(* Generating random numbers.  Paulson, page 96 *)
8
9val a = 16807.0
10val m = 2147483647.0
11
12fun nextrand seed =
13   let
14      val t = a * seed
15   in
16      t - m * real (floor (t / m))
17   end
18
19fun newgenseed seed = {seedref = ref (nextrand seed)}
20
21fun getrealtime () =
22   let
23      val t = Time.now ()
24      val micro_s = Time.toMicroseconds t
25      val sec = micro_s div 1000000
26      val usec = micro_s mod 1000000
27   in
28      {sec = sec, usec = usec}
29   end
30
31fun newgen () =
32   let
33      val {sec, usec} = getrealtime ()
34   in
35      newgenseed (Real.fromLargeInt sec + Real.fromLargeInt usec)
36   end
37
38fun random {seedref} =
39  let
40    val seed = !seedref
41  in
42    (seedref := nextrand seed; seed / m)
43  end
44
45fun randomlist (n, {seedref}) =
46   let
47      val seed0 = !seedref
48      fun h 0 seed res = (seedref := seed; res)
49        | h i seed res = h (i - 1) (nextrand seed) (seed / m :: res)
50   in
51      h n seed0 []
52   end
53
54fun range (min, max) =
55   if min > max
56      then raise Fail "Random.range: empty range"
57   else fn {seedref} =>
58         let
59            val seed = !seedref
60         in
61           (seedref := nextrand seed
62            ; min + floor (real (max - min) * seed / m))
63         end
64
65fun rangelist (min, max) =
66   if min > max
67      then raise Fail "Random.rangelist: empty range"
68   else fn (n, {seedref}) =>
69           let
70              fun h 0 seed res = (seedref := seed; res)
71                | h i seed res =
72                    h (i - 1) (nextrand seed)
73                      (min + floor (real (max - min) * seed / m) :: res)
74           in
75              h n (!seedref) []
76           end
77
78end
79