Re: [m-users.] Random Number Generator
Mark Brown <[email protected]>
| Newsgroups | gmane.comp.lang.mercury.general |
|---|---|
| Message-ID | <CAM4AczC6F0cnBATMgm1YO0wtVpwQB5sPk57K8u+gdhQQXWXsaA@mail.gmail.com> |
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. > > 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. 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. > > I hope I've made sense. You didn;t ask a specific question, but I hope I have been able to provide some clarification. Cheers, Mark > > > Cheers, > Volker > _______________________________________________ > users mailing list > [email protected] > https://lists.mercurylang.org/listinfo/users _______________________________________________ users mailing list [email protected] https://lists.mercurylang.org/listinfo/users