Next: , Previous: , Up: Top   [Contents]


53 random

%--------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
%--------------------------------------------------%
% Copyright (C) 1994-1998,2001-2006, 2011 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%--------------------------------------------------%
% 
% File: random.m
% Main author: conway
% Stability: low
% 
% Define a set of random number generator predicates. This implementation
% uses a threaded random-number supply.  The supply can be used in a
% non-unique way, which means that each thread returns the same list of
% random numbers.  However, this may not be desired so in the interests
% of safety it is also declared with (backtrackable) unique modes.
%
% The coefficients used in the implementation were taken from Numerical
% Recipes in C (Press et al), and are originally due to Knuth.  These
% coefficients are described as producing a "Quick and Dirty" random number
% generator, which generates the numbers very quickly but not necessarily
% with a high degree of quality.  As with all random number generators,
% the user is advised to consider carefully whether this generator meets
% their requirements in terms of "randomness".  For applications which have
% special needs (e.g. cryptographic key generation), a generator such as
% this is unlikely to be suitable.
%
% Note that random number generators of this type have several known
% pitfalls which the user may need to avoid:
%
%	1) The high bits tend to be more random than the low bits.  If
%	you wish to generate a random integer within a given range, you
%	should something like 'div' to reduce the random numbers to the
%	required range rather than something like 'mod' (or just use
%	random.random/5).
%
%	2) Similarly, you should not try to break a random number up into
%	components.  Instead, you should generate each number with a
%	separate call to this module.
%
%	3) There can be sequential correlation between successive calls,
%	so you shouldn't try to generate tuples of random numbers, for
%	example, by generating each component of the tuple in sequential
%	order.  If you do, it is likely that the resulting sequence will
%	not cover the full range of possible tuples.
% 
%--------------------------------------------------%
%--------------------------------------------------%

:- module random.
:- interface.

:- import_module list.

%--------------------------------------------------%

	% The type `random.supply' represents a supply of random numbers.
    %
:- type random.supply.

	% random.init(Seed, RS): creates a supply of random numbers RS
	% using the specified Seed.
	%
:- pred random.init(int::in, random.supply::uo) is det.

	% random.random(Num, RS0, RS): extracts a number Num in the
	% range 0 .. RandMax from the random number supply RS0, and
	% binds RS to the new state of the random number supply.
    %
:- pred random.random(int, random.supply, random.supply).
:- mode random.random(out, mdi, muo) is det.
:- mode random.random(out, in, out) is det.

	% random.random(Low, Range, Num, RS0, RS): extracts a number Num
	% in the range Low .. (Low + Range - 1) from the random number
	% supply RS0, and binds RS to the new state of the random number
	% supply.  For best results, the value of Range should be no greater
	% than about 100.
	%
:- pred random.random(int, int, int, random.supply, random.supply).
:- mode random.random(in, in, out, mdi, muo) is det.
:- mode random.random(in, in, out, in, out) is det.

	% random.randmax(RandMax, RS0, RS): binds RandMax to the maximum
	% random number that can be returned from the random number
	% supply RS0, and returns RS = RS0.
	%
:- pred random.randmax(int, random.supply, random.supply).
:- mode random.randmax(out, mdi, muo) is det.
:- mode random.randmax(out, in, out) is det.

	% random.randcount(RandCount, RS0, RS): binds RandCount to the
	% number of distinct random numbers that can be returned from the
	% random number supply RS0, and returns RS = RS0.  This will be one
	% more than the number returned by randmax/3.
	%
:- pred random.randcount(int, random.supply, random.supply).
:- mode random.randcount(out, mdi, muo) is det.
:- mode random.randcount(out, in, out) is det.

	% random.permutation(List0, List, RS0, RS):
	% binds List to a random permutation of List0,
	% and binds RS to the new state of the random number supply.
	%
:- pred random.permutation(list(T), list(T), random.supply, random.supply).
:- mode random.permutation(in, out, mdi, muo) is det.
:- mode random.permutation(in, out, in, out) is det.

%--------------------------------------------------%
%--------------------------------------------------%


Next: , Previous: , Up: Top   [Contents]