/**
 * Warranty & Liability
 * To the extent permitted by applicable law and unless explicitly
 * otherwise agreed upon, XLOG Technologies AG makes no warranties
 * regarding the provided information. XLOG Technologies AG assumes
 * no liability that any problems might be solved with the information
 * provided by XLOG Technologies AG.
 *
 * Rights & License
 * All industrial property rights regarding the information - copyright
 * and patent rights in particular - are the sole property of XLOG
 * Technologies AG. If the company was not the originator of some
 * excerpts, XLOG Technologies AG has at least obtained the right to
 * reproduce, change and translate the information.
 *
 * Reproduction is restricted to the whole unaltered document. Reproduction
 * of the information is only allowed for non-commercial uses. Selling,
 * giving away or letting of the execution of the library is prohibited.
 * The library can be distributed as part of your applications and libraries
 * for execution provided this comment remains unchanged.
 *
 * Restrictions
 * Only to be distributed with programs that add significant and primary
 * functionality to the library. Not to be distributed with additional
 * software intended to replace any components of the library.
 *
 * Trademarks
 * Jekejeke is a registered trademark of XLOG Technologies AG.
 */

/****************************************************************/
/* Random Numbers                                               */
/****************************************************************/

/**
 * random(M, N):
 * The predicate succeeds in N with a uniform random arbitrary
 * large integer value in the interval [0..M).
 */
% random(+Integer, -Integer)
random(M, _) :- M =< 0,
   throw(error(evaluation_error(undefined),_)).
random(M, N) :-
   L is msb(M)+1,
   repeat,
   sys_random_bits(L, H),
   H < M, !,
   H = N.

% sys_random_bits(+Integer, -Integer)
sys_random_bits(L, B) :-
   divmod(L, 32, X, Y),
   random(W), D is floor(W*(1<<Y)),
   sys_random_bits(X, D, B).

% sys_random_bits(+Integer, +Integer, -Integer)
sys_random_bits(0, A, A) :- !.
sys_random_bits(X, A, B) :-
   random(W), D is floor(W*(1<<32)),
   H is (A<<32)+D,
   Z is X-1,
   sys_random_bits(Z, H, B).

/*******************************************************************/
/* Foreign Predicates                                              */
/*******************************************************************/

% random(R):
% defined in foreign(bitlib)

% msb(X, Y):
% no good support in JavaScript, hopefully this will change
% defined in foreign(bitlib)

% lsb(X, Y):
% no good support in JavaScript and Python, hopefully this will change
% defined in foreign(bitlib)

% popcount(X, Y):
% no good support in JavaScript, hopefully this will change
% defined in foreign(bitlib)

% testbit(X, Y):
% no good support in JavaScript and Python, hopefully this will change
% defined in foreign(bitlib)

% sqrtrem(X, Y, Z):
% no good support in JavaScript, hopefully this will change
% defined in foreign(bitlib)

% isqrt(X, Y):
% no good support in JavaScript, hopefully this will change
% defined in foreign(bitlib)

:- ensure_loaded(foreign(bitlib)).

