Re: [m-users.] Random Number Generator

Volker Wysk <[email protected]>
Newsgroups gmane.comp.lang.mercury.general
Message-ID <[email protected]>
Am Montag, dem 31.07.2023 um 09:46 +1000 schrieb Mark Brown:
> Hi Volker,
> 
> On Sun, Jul 30, 2023 at 9:17 PM Volker Wysk <[email protected]> wrote:
> > 
> > Hi
> > 
> > I find the documentation of the random* modules a litte confusing. I got
> > this far (this works):
> > 
> > main(!IO) :-
> >     open_system_rng(MaybeHandle, !IO),
> >     (
> >         MaybeHandle = maybe.ok(Handle),
> > 
> >         random.system_rng.generate_uint64(Handle, First, !IO),
> >         random.system_rng.generate_uint64(Handle, Second, !IO),
> >         random.system_rng.generate_uint64(Handle, Third, !IO),
> > 
> >         random.sfc64.seed(First, Second, Third, P, State),
> >         make_io_urandom(P, State, M, !IO),
> > 
> >         generate_uint64(M, R, !IO),
> >         io.format("R=%s\n", [s(string.string(R))], !IO)
> >     ;
> >         MaybeHandle = maybe.error(Msg),
> >         io.format("Error opening system random number generator:\n%s\n",
> >                   [s(Msg)], !IO)
> >     ).
> > 
> > 
> > I don't like the argument M of make_io_random/5 and generate_uint64/4, which
> > needs to be passed around when using the random number generator. The RNG is
> > attached to the IO state only half-way, the M arument still needs to be
> > passed around. I'd like to have some predicate "generate_uint64(uint64::out,
> > io::di, io::uo)", which doesn't need the M argument, because all is stored
> > in the IO state.
> 
> In C terms, this is akin to having access to a global resource (e,g,,
> /dev/urandom), but having your code pass around the file handle with
> which the process accesses it. You could avoid passing around the
> handle by using a global static variable if you wanted.
> 
> Similarly, in Mercury you could use a module-local mutable variable to
> store the system_rng handle, once initialized.

I'm using system_rng for creating a random seed only. It's the "M" variable
of type io_urandom(P, S), the result of make_io_urandom, which I don't want
to carry around.

I've looked for info on mutable variables and found the modules thread.mvar,
store and mutvar (which is undocumented). It's confusing. It uses impurity
and I can't see how to make and initialize a handle to a mutable variable
local to a module, such that nothing needs to be carried around. It looks to
me like some use of promise_pure is needed - but would that be safe?

> 
> > 
> > Actually, that M argument is of type params and this is a dummy type (from
> > the source code of random.sfc64):
> > 
> > :- type params
> >     --->    params.
> > 
> > It's the same for random.sfc32, but not for random.sfc16. And the module
> > random.sfc64 defines this:
> > 
> > :- pred generate_uint64(uint64::out, ustate::di, ustate::uo) is det.
> > 
> > That's looks like what I need, but there isn't such a member of the urandom
> > type class, which I need to use when I want it to be attached to the IO
> > state.
> 
> Since you're digging into the implementation, you could look at the
> source code of make_io_urandom to see what's going on. It wraps the
> ustate, which is destructively updatable because it is unique (it's an
> array), in a mutvar, which is destructively updatable because it is
> attached to the I/O state.
> 
> By "destructively updatable" I mean that there is some way for the
> compiler to verify that such an update is safe. The two interfaces
> provide two such options, though the actual update that is happening
> is the same either way.

Sorry, but this makes me even more confused. I think, I'll bite the bullet
and pass around that dummy variable. 

> The random interface is designed to be general enough to allow for
> different types of RNGs, since its purpose is to allow users to write
> polymorphic code that is decoupled from the choice of RNG. It aims to
> do this with a minimal amount of overhead, but we still end up with
> some dummy types being passed around in some cases.

So it's for the sake of possible further random generators which might need
that "M" variable. 

> 
> > 
> > I hope I've made sense.
> 
> You didn;t ask a specific question, but I hope I have been able to
> provide some clarification.

You made it clear that it's confusing.  :-)

Thanks,
Volker

_______________________________________________
users mailing list
[email protected]
https://lists.mercurylang.org/listinfo/users
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEE6QXGh82Ov3+2nrxp+K4ydFOsHoUFAmTHpxYACgkQ+K4ydFOs
HoU2pA//cUeZxVoLSArxrqmvZHT9xXzdLBExqi5Svv7MFC+be8z5bJ5rvonKtSQ8
T1AWF/nZprGGnTv9yM0SQXQhbplBTmc0+beh9a0zzl9GNYHqzd/RQ/Hregk4zlY5
PSZXqfmNTs9TJd64Wv5xqI1rroDUfJBcWgE/Vlc6+cu979u+1ikmLxZt/dLfeB1n
eAI9txUrK/gQK2uzYaILz+XZreTEDci3AT1rwtYFJ1BMuQE5nK1UO584iq5MBVp2
R7VkRYq46Qb80m33DLcOSI/9wbbhywxwJWeCMHyH7tfnEJGYgvTWhyiR1BtzDsGI
hnvbs8cNz0/k2zLurBZ5ZJ5RQblYdaYgyO+1W7VkNK+QvshXomCp9Ee/WAvaEnDx
6LO6nwORd81bIfSbAGp0xqWJVjx+bq7h9tocAcU5imdXVb/kbkRr5P6Eb4qrYgpZ
lvFPZk1ZfyCek8TJ5mJFcFKnsmrtz91J2gNp0HIkAgXHXWebVGMjA35H7P+0U0mr
5T01D+LxENA7n6SVq4Y/4jQRGTcQX3jCLCcwPz7+sWXh2VTR4gYIkPO4FI+S2Fm1
j3WSZKtgtiV7R1j5FDZjTJei+zzv2/6Dpz/dqtfC9bkmOj6x9R/G52yLrN2AmGyD
3/qTpKjYZYMVX2izWEf0ECTFqCyR/r+8VfLXPApb+9ul7mcGCbw=
=lOwZ
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.