In general, languages โโprovide you with a uniform distribution from 0 to 1. There are various algorithms for getting from this uniform distribution to another distribution, but this case is especially common, so there are several ways to do this.
If you need a small number of random values โโin a normal distribution, Box-Muller transform is a very simple algorithm, it is equal to a little math in several uniform random values:
random_normal(N) :- random(U1), random(U2), Z0 is sqrt(-2 * log(U1)) * cos(2*pi*U2), Z1 is sqrt(-2 * log(U1)) * sin(2*pi*U2), (N = Z0 ; N = Z1).
This algorithm uses two identical values โโand creates two normal values. I provide both solutions. Other ways to do this may be better for some applications. For example, you can use asserta/1 and retract/1 to cache the second value and use it without calculation, although the clutter in the dynamic storage can be about as bad as for other work (you would need to compare it). :
?- random_normal(Z). Z = -1.2418135230345024 ; Z = -1.1135242997982466. ?- random_normal(Z). Z = 0.6266801862581797 ; Z = -0.4934840828548163. ?- random_normal(Z). Z = 0.5525713772053663 ; Z = -0.7118660644436128.
I'm not very sure about this, but it can lead you to a hump.
source share