[m-users.] Random Number Generator

Volker Wysk post at volker-wysk.de
Mon Jul 31 22:20:38 AEST 2023


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 <post at volker-wysk.de> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mercurylang.org/archives/users/attachments/20230731/b6f21c6e/attachment.sig>


More information about the users mailing list