1/************************************************************************* 2* * 3* YAP Prolog * 4* * 5* Yap Prolog was developed at NCCUP - Universidade do Porto * 6* * 7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * 8* * 9************************************************************************** 10* * 11* File: random.yap * 12* Last rev: 5/12/99 * 13* mods: * 14* comments: Random operations * 15* * 16*************************************************************************/ 17 18% original code from RA O'Keefe. 19 20% This is algorithm AS 183 from Applied Statistics. I also have a C 21% version. It is really very good. It is straightforward to make a 22% version which yields 15-bit random integers using only integer 23% arithmetic. 24 25:- module(random, [ 26 random/1, 27 random/3, 28 randseq/3, 29 randset/3, 30 getrand/1, 31 setrand/1 32 ]). 33 34:- load_foreign_files([yap_random], [], init_random). 35 36 37% random(R) binds R to a new random number in [0.0,1.0) 38 39% random(L, U, R) binds R to a random integer in [L,U) 40% when L and U are integers (note that U will NEVER be generated), 41% or to a random floating number in [L,U) otherwise. 42 43random(L, U, R) :- integer(L), integer(U), !, 44 random(X), 45 R is L+integer((U-L)*X). 46random(L, U, R) :- 47 number(L), number(U), !, 48 random(X), 49 R is L+((U-L)*X). 50 51/* There are two versions of this operation. 52 53 randset(K, N, S) 54 55 generates a random set of K integers in the range 1..N. 56 The result is an ordered list, such as setof might produce. 57 58 randseq(K, N, L) 59 60 generates a random sequence of K integers, the order is as 61 random as we can make it. 62*/ 63 64 65randset(K, N, S) :- 66 K >= 0, 67 K =< N, 68 randset(K, N, [], S). 69 70 71randset(0, _, S, S) :- !. 72randset(K, N, Si, So) :- 73 random(X), 74 X * N < K, !, 75 J is K-1, 76 M is N-1, 77 randset(J, M, [N|Si], So). 78randset(K, N, Si, So) :- 79 M is N-1, 80 randset(K, M, Si, So). 81 82 83randseq(K, N, S) :- 84 randseq(K, N, L, []), 85 keysort(L, R), 86 strip_keys(R, S). 87 88randseq(0, _, S, S) :- !. 89randseq(K, N, [Y-N|Si], So) :- 90 random(X), 91 X * N < K, !, 92 random(Y), 93 J is K-1, 94 M is N-1, 95 randseq(J, M, Si, So). 96randseq(K, N, Si, So) :- 97 M is N-1, 98 randseq(K, M, Si, So). 99 100 101strip_keys([], []) :- !. 102strip_keys([_-K|L], [K|S]) :- 103 strip_keys(L, S). 104 105setrand(rand(X,Y,Z)) :- 106 integer(X), 107 integer(Y), 108 integer(Z), 109 X > 0, 110 X < 30269, 111 Y > 0, 112 Y < 30307, 113 Z > 0, 114 Z < 30323, 115 setrand(X,Y,Z). 116 117getrand(rand(X,Y,Z)) :- 118 getrand(X,Y,Z). 119 120 121 122 123