[mercury-users] The Mercury random module

Fergus Henderson fjh at cs.mu.oz.au
Fri Jul 4 14:15:45 AEST 1997

Lourens van der Meij, you wrote:
> In the following program I use random__test/4 that is part of the
> Mercury random module. Is it correct that random__random should generate
> negative integer values? I use mercury0.6, the binary distribution for 
> Solaris.

No, it is not correct.

The good news is that this bug has already been fixed in our
development sources.  Our latest development version also has better
documentation for the `random' module.

This bug was in fact caused by using `mod' on a negative number.  In
Mercury 0.6, the semantics of `mod' on negative numbers was not really
well defined.  In our current development version, we have cleaned up
the handling of integer division, modulus, and remainder for negative
numbers.  The semantics of `mod' have been tightened up (it always
returns a non-negative number), and there are new functions `div' and
`rem'.  With this change, you can now choose between `//' (round-to-zero)
and `div' (round-to-minus-infinity).  You call also choose between the
corresponding remainders: `rem' is remainder with respect to `//', and
`mod' is remainder with respect to `div'.

If you need a fix for this bug, you could try one of our development
snapshot beta-test releases.  (Email me for details.)
But as a workaround, I think something like

	my_random(R) -->
		( { R0 < 0 } ->
			{ R is R0 + M }
			{ R = R0 }

should probably work.  (That's just off the top of my head, untested.)
Or alternatively, you could easily just use Mercury's C interface to
access the rand() function in the C standard library.

P.S. I've appended the documentation changes for random.m.

Index: random.m
RCS file: /home/staff/zs/imp/mercury/library/random.m,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- random.m	1997/05/21 02:16:20	1.11
+++ random.m	1997/06/25 06:25:27	1.12
@@ -21,24 +21,43 @@
 :- 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, random__supply).
 :- mode random__init(in, 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.
+	% random__randmax(RandMax, RS0, RS): binds Randax 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.
+:- implementation.
+	% Everything after the first `:- implementation' does not appear
+	% in the Mercury Library Reference Manual.
+:- interface.
+	% The following predicate was just for test purposes.
+	% It should not be used by user programs.
+:- pragma obsolete(random__test/4).
 :- pred random__test(int, int, list(int), int).
 :- mode random__test(in, in, out, out) is det.
 :- implementation.
-:- import_module require, int.
+:- import_module int.
 :- type random__supply		==	int.	% I(j)
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at         |     -- the last words of T. S. Garp.

More information about the users mailing list