:- use_module(library(atts)).
:- use_module(library(lists)).
:- use_module(library(iso_ext)).
+:- use_module(library(random)).
:- use_module(library(pairs)).
:- use_module(library(dcgs)).
:- use_module(library(error), []).
-:- module(random, [maybe/0, set_random/1]).
+:- module(random, [maybe/0, random/1, random_integer/3, set_random/1]).
% succeeds with probability 0.5.
maybe :- '$maybe'.
+% The higher the precision, the slower it gets.
+random_number_precision(64).
+
+random(R) :-
+ var(R),
+ random_number_precision(N),
+ rnd(N, R).
+
+random_integer(Lower, Upper, R) :-
+ var(R),
+ ( (var(Lower) ; var(Upper)) ->
+ throw(error(instantiation_error, random_integer/3))
+ ; \+ integer(Lower) ->
+ throw(error(domain_error(integer, Lower), random_integer/3))
+ ; \+ integer(Upper) ->
+ throw(error(domain_error(integer, Upper), random_integer/3))
+ ; Upper > Lower,
+ random(R0),
+ R is floor((Upper - Lower) * R0 + Lower)
+ ).
+
+rnd(N, R) :-
+ rnd_(N, 0, R).
+
+rnd_(0, R, R) :- !.
+rnd_(N, R0, R) :-
+ maybe,
+ !,
+ N1 is N - 1,
+ rnd_(N1, R0, R).
+rnd_(N, R0, R) :-
+ N1 is N - 1,
+ R1 is R0 + 1.0 / 2.0 ^ N,
+ rnd_(N1, R1, R).
+
set_random(Seed) :-
( nonvar(Seed) ->
( Seed = seed(S) ->