```%   File   : RANDOM.PL
%   Author : R.A.O'Keefe
%   Updated: 1 October 1984
%   NIP version: 13 May 1987
%   Purpose: Random number generator.

%   given an integer N >= 1, random(N, I) unifies I with a random
%   integer between 0 and N - 1.

random(N, I) :-
(	recorded(seed,[A0,A1,A2],Key)
->	erase(Key)
;
A0 = 3172, A1 = 9814, A2 = 20125
),
B0 is (A0*171) mod 30269,
B1 is (A1*172) mod 30307,
B2 is (A2*170) mod 30323,
record(seed,[B0,B1,B2],_),
R is A0/30269 + A1/30307 + A2/30323,
I is trunc((R - trunc(R)) * N).

%	The next bit: K R Johnson, 13-5-87
%	Restart the random sequence from the beginning

randomise :-
(	recorded(seed,[_,_,_],Key)
->	erase(Key)
;	true
),
record(seed, [3172,9814,20125], _).

%	Instantiate the seeds to your own favourite value

randomise(Seed) :-
integer(Seed),
Seed > 0,
(	recorded(seed,[_,_,_], Key)
->	erase(Key)
;	true
),
S0 is Seed mod 30269,
S1 is Seed mod 30307,
S2 is Seed mod 30323,
record(seed,[S0,S1,S2],_).

%   given an non-empty List, random(List, Elem, Rest) unifies Elem with
%   a random element of List and Rest with the other elements.

random(List, Elem, Rest) :-
length(List, N),
N > 0,
random(N, I),
nth0(I, List, Elem, Rest).

%   rand_perm(List, Perm) unifies Perm with a random permutation
%   of List.  What good this may be I'm not sure, and there's bound
%   to be a more efficient way of doing it.  Oh well.

rand_perm([], []).
rand_perm([H1|T1], [H2|T2]) :-
random([H1|T1], H2, T3),
rand_perm(T3, T2).

```