1 implementation module randomstream
3 import StdEnv, StdEnvExt
8 randomStream :: !Int !([Int] -> a) !RandomSeed -> Stream a
9 randomStream nrInts transform seed
10 # (ints,seed) = randoms nrInts seed
11 = [transform ints : randomStream nrInts transform seed]
13 randoms :: !Int !RandomSeed -> (![Int],!RandomSeed)
14 randoms 0 seed = ([],seed)
16 # (r, seed) = random seed
17 # (rs,seed) = randoms (n-1) seed
20 intRandomStream :: !RandomSeed -> Stream Int
21 intRandomStream seed = randomStream 2 createInt seed
23 createInt :: ![Int] -> Int
24 createInt [a,b] = if (isOdd a) -1 1 * (abs b)
25 createInt _ = abort "Fatal error: intRandomStream applied to unexpected number of integers.\n"
27 realRandomStream :: !RandomSeed -> Stream Real
28 realRandomStream seed = randomStream 4 createReal seed
30 createReal :: ![Int] -> Real
31 createReal [s,a,b,c] = toReal (if (isOdd s) "-" "" <+++ abs a <+++ "." <+++ abs b <+++ "E" <+++ (c rem 100))
32 createReal _ = abort "Fatal error: realRandomStream applied to unexpected number of integers.\n"
34 boolRandomStream :: !RandomSeed -> Stream Bool
35 boolRandomStream seed = randomStream 1 createBool seed
37 createBool :: ![Int] -> Bool
38 createBool [i] = isEven i
39 createBool _ = abort "Fatal error: boolRandomStream applied to unexpected number of integers.\n"
41 probabilityRandomStream :: !RandomSeed -> Stream P
42 probabilityRandomStream seed = randomStream 2 createProbability seed
44 createProbability :: ![Int] -> P
45 createProbability [a,b]
47 | otherwise = (toReal a`) / (toReal b`)
49 [a`,b`:_] = sort [abs a,abs b]
50 createProbability _ = abort "Fatal error: probabilityRandomStream applied to unexpected number of integers.\n"
52 onesStream :: Stream P
53 onesStream = [one,one..]
55 nextRandomInt :: !RandomSeed -> .(!Int, !RandomSeed)
57 # (r1,seed) = random seed
58 # (r2,seed) = random seed
59 = (if (isOdd r1) -1 1 * (abs r2),seed)
61 nextRandomReal :: !RandomSeed -> .(!Real,!RandomSeed)
63 # (r1,seed) = random seed
64 # (r2,seed) = random seed
65 # (r3,seed) = random seed
66 # (r4,seed) = random seed
67 = (toReal (if (isOdd r1) "-" "" <+++ abs r2 <+++ "." <+++ abs r3 <+++ "E" <+++ (r4 rem 100)),seed)
69 nextRandomBool :: !RandomSeed -> .(!Bool,!RandomSeed)
71 # (r1,seed) = random seed
74 nextRandomP :: !RandomSeed -> .(!P, !RandomSeed)
76 # (r1,seed) = random seed
77 # (r2,seed) = random seed
78 # (a,b) = minmax (abs r1,abs r2)
79 = (if (r2==0) 1.0 ((toReal a)/(toReal b)),seed)
81 next1 :: !RandomSeed -> .(!P, !RandomSeed)
82 next1 seed = (1.0,seed)
84 /** make the random realistic, as in, small errors occur more often:
88 makeRandomRealistic :: !P -> P
89 makeRandomRealistic r = 1.0-r^4.0
91 makeRandomRealisticSkilled :: !P -> P
92 makeRandomRealisticSkilled r = 1.0-r^10.0
94 selectMostProbableAction :: ![(P,a)] !RandomSeed -> (!Maybe a,!RandomSeed)
95 selectMostProbableAction odds seed
96 = case sortBy (\(p1,_) (p2,_) -> p1 > p2) (filter (\(p,_) -> p > zero) odds) of
98 odds=:[(p,_):_] = let mostProbable = takeWhile ((==) p o fst) odds
99 nr = length mostProbable
100 (p1,seed1) = nextRandomP seed
101 in (Just (snd (odds !! (entier (p1 * toReal nr)))),seed1)