file exists system predicate $source_file -> $user source hide and make system preds fix check_head_and_body user_expansion never fails goal expansion is controlled b dynamic procedure add must_be_of_type predicate_indicator fix neat_call, debug flag is user controlled use simplecudd, not ptoblogbdd compile all of myddas fx junk in file_name fix warnings use common file opening struct and funds avoid pairs module fix db queues
		
			
				
	
	
		
			221 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
| /*************************************************************************
 | |
| *									 *
 | |
| *	 YAP Prolog 							 *
 | |
| *									 *
 | |
| *	Yap Prolog was developed at NCCUP - Universidade do Porto	 *
 | |
| *									 *
 | |
| * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 *
 | |
| *									 *
 | |
| **************************************************************************
 | |
| *									 *
 | |
| * File:		random.yap						 *
 | |
| * Last rev:	5/12/99							 *
 | |
| * mods:									 *
 | |
| * comments:	Random operations					 *
 | |
| *									 *
 | |
| *************************************************************************/
 | |
| 
 | |
| /**
 | |
|  * @file   random.yap
 | |
|  * @author original code from RA O'Keefe.
 | |
|  * @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
 | |
|  * @date   Wed Nov 18 00:05:21 2015
 | |
|  *
 | |
|  * @brief Integer Random Number Generator
 | |
|  *
 | |
|  *
 | |
| */
 | |
| 
 | |
| :- module(random, [
 | |
| 	random/1,
 | |
| 	random/3,
 | |
| 	randseq/3,
 | |
| 	randset/3,
 | |
| 	getrand/1,
 | |
| 	setrand/1
 | |
|     ]).
 | |
| 
 | |
| /** @defgroup random Random Number Generator
 | |
| @ingroup library
 | |
| @{
 | |
| 
 | |
|  Since YAP-4.3.19 YAP uses
 | |
| the O'Keefe public-domain algorithm, based on the "Applied Statistics"
 | |
| algorithm AS183.
 | |
| 
 | |
| The following random number operations are included with the
 | |
| `use_module(library(random))` command.
 | |
| 
 | |
| In ROK's words: ``This is algorithm AS 183 from Applied Statistics.  I also have a C
 | |
|    version.  It is really very good.  It is straightforward to make a
 | |
|    version which yields 15-bit random integers using only integer
 | |
|    arithmetic.''
 | |
| 
 | |
| 
 | |
| */
 | |
| 
 | |
| /** @pred getrand(- _Key_)
 | |
| 
 | |
| 
 | |
| Unify  _Key_ with a term of the form `rand(X,Y,Z)` describing the
 | |
| current state of the random number generator.
 | |
| 
 | |
| 
 | |
| */
 | |
| 
 | |
| 
 | |
| /** @pred random(+ _LOW_, + _HIGH_, - _NUMBER_)
 | |
| 
 | |
| Unify  _Number_ with a number in the range
 | |
| `[LOW...HIGH)`. If both  _LOW_ and  _HIGH_ are
 | |
| integers then  _NUMBER_ will also be an integer, otherwise
 | |
|  _NUMBER_ will be a floating-point number.
 | |
| 
 | |
| 
 | |
| */
 | |
| 
 | |
| 
 | |
| /** @defgroup Pseudo_Random Pseudo Random Number Integer Generator
 | |
| @ingroup library
 | |
| @{
 | |
| 
 | |
| The following routines produce random non-negative integers in the range
 | |
| 0 .. 2^(w-1) -1, where w is the word size available for integers, e.g.
 | |
| 32 for Intel machines and 64 for Alpha machines. Note that the numbers
 | |
| generated by this random number generator are repeatable. This generator
 | |
| was originally written by Allen Van Gelder and is based on Knuth Vol 2.
 | |
| 
 | |
| 
 | |
| */
 | |
| 
 | |
| 
 | |
| /** @pred random(- _Number_)
 | |
| 
 | |
| 
 | |
| Unify  _Number_ with a floating-point number in the range `[0...1)`.
 | |
| 
 | |
| 
 | |
| */
 | |
| /** @pred randseq(+ _LENGTH_, + _MAX_, - _Numbers_)
 | |
| 
 | |
| 
 | |
| Unify  _Numbers_ with a list of  _LENGTH_ unique random integers
 | |
| in the range `[1... _MAX_)`.
 | |
| 
 | |
| 
 | |
| */
 | |
| /** @pred randset(+ _LENGTH_, + _MAX_, - _Numbers_)
 | |
| 
 | |
| 
 | |
| Unify  _Numbers_ with an ordered list of  _LENGTH_ unique random
 | |
| integers in the range `[1... _MAX_)`.
 | |
| 
 | |
| 
 | |
| */
 | |
| /** @pred setrand(+ _Key_)
 | |
| 
 | |
| 
 | |
| Use a term of the form `rand(X,Y,Z)` to set a new state for the
 | |
| random number generator. The integer `X` must be in the range
 | |
| `[1...30269)`, the integer `Y` must be in the range
 | |
| `[1...30307)`, and the integer `Z` must be in the range
 | |
| `[1...30323)`.
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|  */
 | |
| %:- use_module(library(pairs)).
 | |
| :- use_module(library(lists)).
 | |
| 
 | |
| 
 | |
| :- load_foreign_files([yap_random], [], init_random).
 | |
| 
 | |
| 
 | |
| %   random(R) binds R to a new random number in [0.0,1.0)
 | |
| 
 | |
| %   random(L, U, R) binds R to a random integer in [L,U)
 | |
| %   when L and U are integers (note that U will NEVER be generated),
 | |
| %   or to a random floating number in [L,U) otherwise.
 | |
| 
 | |
| random(L, U, R) :-
 | |
| 	( integer(L), integer(U) ->
 | |
| 	    U > L,
 | |
| 	    random(X),
 | |
| 	    R is L+integer((U-L)*X)
 | |
|         ;
 | |
| 	    number(L), number(U),
 | |
| 	    U > L,
 | |
| 	    random(X),
 | |
| 	    R is L+((U-L)*X)
 | |
| 	).
 | |
| 
 | |
| /*  There are two versions of this operation.
 | |
| 
 | |
| 	randset(K, N, S)
 | |
| 
 | |
|     generates a random set of K integers in the range 1..N.
 | |
|     The result is an ordered list, such as setof might produce.
 | |
| 
 | |
| 	randseq(K, N, L)
 | |
| 
 | |
|     generates a random sequence of K integers, the order is as
 | |
|     random as we can make it.
 | |
| */
 | |
| 
 | |
| 
 | |
| randset(K, N, S) :-
 | |
| 	K >= 0,
 | |
| 	K =< N,
 | |
| 	randset(K, N, [], S).
 | |
| 
 | |
| 
 | |
| randset(0, _, S, S) :- !.
 | |
| randset(K, N, Si, So) :-
 | |
| 	random(X),
 | |
| 	X * N < K, !,
 | |
| 	J is K-1,
 | |
| 	M is N-1,
 | |
| 	randset(J, M, [N|Si], So).
 | |
| randset(K, N, Si, So) :-
 | |
| 	M is N-1,
 | |
| 	randset(K, M, Si, So).
 | |
| 
 | |
| 
 | |
| randseq(K, N, S) :-
 | |
| 	randseq(K, N, L, []),
 | |
| 	keysort(L, R),
 | |
| 	strip_keys(R, S).
 | |
| 
 | |
| randseq(0, _, S, S) :- !.
 | |
| randseq(K, N, [Y-N|Si], So) :-
 | |
| 	random(X),
 | |
| 	X * N < K, !,
 | |
| 	random(Y),
 | |
| 	J is K-1,
 | |
| 	M is N-1,
 | |
| 	randseq(J, M, Si, So).
 | |
| randseq(K, N, Si, So) :-
 | |
| 	M is N-1,
 | |
| 	randseq(K, M, Si, So).
 | |
| 
 | |
| 
 | |
| strip_keys([], []) :- !.
 | |
| strip_keys([_-K|L], [K|S]) :-
 | |
| 	strip_keys(L, S).
 | |
| 
 | |
| setrand(rand(X,Y,Z)) :-
 | |
| 	integer(X),
 | |
| 	integer(Y),
 | |
| 	integer(Z),
 | |
| 	X > 0,
 | |
| 	X < 30269,
 | |
| 	Y > 0,
 | |
| 	Y < 30307,
 | |
| 	Z > 0,
 | |
| 	Z < 30323,
 | |
| 	setrand(X,Y,Z).
 | |
| 
 | |
| getrand(rand(X,Y,Z)) :-
 | |
| 	getrand(X,Y,Z).
 |