Currently, library(iso_ext) provides set_random/1 and maybe/0 for rudimentary probabilistic reasoning. In statistical applications of Scryer Prolog, more predicates would be very useful to reason about random numbers.
For example:
random(+Lower, +Upper, -Number) Number is unified with a random integer in the interval [Lower,Upper), where Lower and Upper are integers.
This would align nicely with the interface provided in https://docs.rs/rand/0.7.3/rand/trait.Rng.html#method.gen_range .
random/1 would also be useful:
random(-Number) Number is unified with a random float in the interval [0.0, 1.0).
All these predicates (set_random/1, maybe/0, random/3 and random/1) would make very nice contributions in a new library(random), either using these or better names.
To preserve declarative properties, Prolog predicates that internally generate random numbers should always be equipped with a seed, and use set_random/1 to set the seed to ensure reproducible results. See for example generate/4 in markov.pl.
It seems like it's possible to do this in Prolog only (maybe painfully). For example:
:- use_module(library(iso_ext)).
rnd(N, R) :-
random_(N, 0.0, R).
random_(0, R, R) :- !.
random_(M, R0, R) :-
zero_one(V),
R1 is R0 + (1.0 / 2.0 ^ M) * V,
M1 is M - 1,
random_(M1, R1, R).
zero_one(0) :- maybe, !.
zero_one(1).
The first argument of rnd/2 is the precision and the second argument is a random number in [0;1[, so:
?- rnd(100, R).
And the predicate random/1 could be defined as random(R) :- rnd(100, R)..
This way there isn't the need to add the crate rand and it would work with the current implementation of scryer-prolog.
Very nice! Yes, absolutely, much of it can certainly be done in Prolog.
Currently, we are already using the rand crate for maybe/0 and set_random/1, which are provided in system_calls.rs via internal functions.
If the dependency on this crate can be eliminated and the engine simplified, it would certainly be a very welcome contribution to move more of the implementation to Prolog! The seed could also be stored in a global variable, using bb_put/2 from library(iso_ext), thus putting more stress on Prolog and testing the engine itself (as opposed to an external crate), which is nice!
Of course, in the future, we will need more involved functionality, for example cryptographically secure random numbers in a future library(crypto). But for such basic use cases as the Markov chain example, a Prolog-based library(random) would be very nice!
Hi, this is something that I would be interested in contributing! Do you think it's a good first issue?
Yes, this is a good first issue in Prolog only.
@matt2xu: Thank you for your interest! @notoria has now brilliantly solved this issue in #406.
However, #388 (for example) is still open and seems like a very nice first issue, and I hope it interests you.
In scryer-prolog, the rand crate isn't part of it directly since it isn't imported with Cargo.toml. If the rand crate is part of scryer-prolog then it must be as a dependency of dependency ... and it isn't possible to remove it (unless the dependency is removed, not really an option).
The randomness scryer-prolog use is due to the rug crate like this line, this line and with doc, doc.
Moving the current random system to Prolog is really hard, it's more of an issue for Prolog programmer.
Yes, for cryptography it is required to use a dedicated crate.
@matt2xu: Thank you for your interest! @notoria has now brilliantly solved this issue in #406.
That was fast :)
However, #388 (for example) is still open and seems like a very nice first issue, and I hope it interests you.
Why not! I'll start to look into it tonight.
@notoria: Thank you a lot for library(random)!
@matt2xu: Another interesting issue may be #397. It includes two test cases that should be equivalent, but yield different results.
Thank you for all contributions! I am closing this issue.
Most helpful comment
Yes, this is a good first issue in Prolog only.