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