dave@quintus.UUCP (David Bowen) (01/28/91)
In article <27A20DBF.15393@ics.uci.edu> cain@ics.uci.edu (Timothy Cain) writes: >Does anyone have a random number generator written in Prolog, or know >how I can get a random number using Quintus Prolog 2.4 (UNIX)? I'd >rather not have to write a C routine just to produce a few different >numbers for every run of my Prolog code. Use library(random). It defines a number of different routines for random number generation.
ken@aiai.ed.ac.uk (Ken Johnson) (01/29/91)
In article <27A20DBF.15393@ics.uci.edu> cain@ics.uci.edu (Timothy Cain) writes: >Does anyone have a random number generator written in Prolog, or know >how I can get a random number using Quintus Prolog 2.4 (UNIX)? I'd >rather not have to write a C routine just to produce a few different >numbers for every run of my Prolog code. The following is in the Prolog Library and (as far as I know!!) is public domain. Please aknowledge ROK's authorship. The algorithm is very clever. ---------------------------------------- Cut Here 8< ------------------------- % 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). -- My father always wanted me % Ken Johnson, AIAI To be a buccaneer; % 80 South Bridge, Edinburgh So when I fixed his lawnmower % E-mail ken@aiai.ed.ac.uk He gave a hearty cheer. -- me % 031-650 2756 direct line
ken@aiai.ed.ac.uk (Ken Johnson) (01/30/91)
In article <4024@skye.ed.ac.uk> I gave a random number generator which I
attributed to Richard O'Keefe. I have since received the following
letter about its authorship:
$ From baw@uk.co.npl.seg Wed Jan 30 12:01:01 1991
$ Received: from uk.ac.ukc by aiai.ed.ac.uk; Wed, 30 Jan 91 12:00:55 GMT
$ Received: from psg.npl.co.uk by kestrel.Ukc.AC.UK with UUCP id aa19671;
$ 30 Jan 91 11:50 GMT
$ Received: from guava.seg.npl.co.uk by snow.psg.npl.co.uk; Wed, 30 Jan 91 10:53:1
$ 5 GMT
$ Date: Wed, 30 Jan 91 10:53:12 GMT
$ From: Brian A Wichmann <baw@uk.co.npl.seg>
$ Message-Id: <25478.9101301053@guava.seg.npl.co.uk>
$ To: ken@ed.aiai
$ Subject: Clever random numbers
$ Status: R
$
$ Dear Ken,
$ The `clever' random number generator you have in Prolog using
$ three primes is due to ID Hill (david) and myself. See
$ An efficient and portable pseudo-random number generator.
$ Applied Stats. AS183. 1982. Also Byte March 1987.
$
$ Please add this reference to the documentation, otherwise people
$ will be confused by the `cleverness' !!!
$ Brian Wichmann.
--
My father always wanted me % Ken Johnson, AIAI
To be a buccaneer; % 80 South Bridge, Edinburgh
So when I fixed his lawnmower % E-mail ken@aiai.ed.ac.uk
He gave a hearty cheer. -- me % 031-650 2756 direct line
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (01/31/91)
In article <27A20DBF.15393@ics.uci.edu>, cain@ics.uci.edu (Timothy Cain) writes: > Does anyone have a random number generator written in Prolog, or know > how I can get a random number using Quintus Prolog 2.4 (UNIX)? LOOK IN THE LIBRARY! It's even mentioned in the manual. ?- use_module(library(random))). ?- random(X). % uniform [0,1) random float There are lots of other routines in that file. -- The Marxists have merely _interpreted_ Marxism in various ways; the point, however, is to _change_ it. -- R. Hochhuth.
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (01/31/91)
In article <4024@skye.ed.ac.uk>, ken@aiai.ed.ac.uk (Ken Johnson) writes: > The following is in the Prolog Library and (as far as I know!!) is > public domain. Please acknowledge ROK's authorship. The algorithm is > very clever. Oh dear. Did the version of RANDOM.PL I left at Edinburgh *really* omit the attribution? The algorithm used there for generating uniform random floats is algorithm AS 163 from the journal Applied Statistics. (In effect it is a 48-bit linear congruential method.) > random(N, I) :- > ( recorded(seed,[A0,A1,A2],Key) > -> erase(Key) > ; > A0 = 3172, A1 = 9814, A2 = 20125 > ), > ... > record(seed,[B0,B1,B2],_), > ... I'm quite sure *I* didn't leave it like that. The third argument of recorded/1 is NOT a "key". It's a "data base reference", "dbref" or "ref" for short. The FIRST argument is the "key". Further, the thing that is recorded is not a seed, it is a random state, and it always contains precisely three numbers, so a list is not appropriate. What's more, if you haven't modules, it's a good idea to choose key names that are unlikely to picked by users. Hence recorded('random state', 'random state'(A0,A1,A2), Ref) ... recorda('random state', 'random state'(B1,B1,B3), _) > % 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). I'm sure that comment can't be mine. There are *much* more efficient ways of doing it, and the Quintus library uses one of them. What's more, the operation is there because it is extremely useful; I found that most of the time that I was generating random numbers was to shuffle lists (generate random permuations), so it seemed as well to do it directly. (Think about generating test data.) -- The Marxists have merely _interpreted_ Marxism in various ways; the point, however, is to _change_ it. -- R. Hochhuth.
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (01/31/91)
In article <4682@goanna.cs.rmit.oz.au>, ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: > Oh dear. Did the version of RANDOM.PL I left at Edinburgh *really* omit > the attribution? The algorithm used there for generating uniform random > floats is algorithm AS 163 from the journal Applied Statistics. *** Oops. That should have been "183". I'm quite sure that the attribution was included in at least one of the versions of random.pl that I wrote at Edinburgh. There's a hardcover book of algorithms from Applied Statistics and I think the algorithm was reprinted in that. -- The Marxists have merely _interpreted_ Marxism in various ways; the point, however, is to _change_ it. -- R. Hochhuth.