change library(random) to use O'Keefe code.
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@80 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
parent
96ae69e8d6
commit
90c92979c6
@ -451,6 +451,7 @@ install_unix:
|
|||||||
-(cd CHR ; make install)
|
-(cd CHR ; make install)
|
||||||
@INSTALL_DLLS@ (cd library/regex; make install)
|
@INSTALL_DLLS@ (cd library/regex; make install)
|
||||||
@INSTALL_DLLS@ (cd library/system; make install)
|
@INSTALL_DLLS@ (cd library/system; make install)
|
||||||
|
@INSTALL_DLLS@ (cd library/random; make install)
|
||||||
-mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
-mkdir -p $(DESTDIR)$(INCLUDEDIR)
|
||||||
for h in $(INTERFACE_HEADERS); do $(INSTALL) $$h $(DESTDIR)$(INCLUDEDIR); done
|
for h in $(INTERFACE_HEADERS); do $(INSTALL) $$h $(DESTDIR)$(INCLUDEDIR); done
|
||||||
|
|
||||||
@ -474,6 +475,7 @@ install_mingw32:
|
|||||||
(cd CHR ; make install)
|
(cd CHR ; make install)
|
||||||
(cd library/regex; make install_mingw32)
|
(cd library/regex; make install_mingw32)
|
||||||
(cd library/system; make install_mingw32)
|
(cd library/system; make install_mingw32)
|
||||||
|
(cd library/random; make install_mingw32)
|
||||||
|
|
||||||
install_library: libYap.a
|
install_library: libYap.a
|
||||||
$(INSTALL_DATA) -m 644 libYap.a $(DESTDIR)$(LIBDIR)/libYap.a
|
$(INSTALL_DATA) -m 644 libYap.a $(DESTDIR)$(LIBDIR)/libYap.a
|
||||||
|
4
TO_DO
4
TO_DO
@ -13,6 +13,10 @@ BEFORE 4.4:
|
|||||||
- document system(library)
|
- document system(library)
|
||||||
- document new interface functions.
|
- document new interface functions.
|
||||||
- ^C can break code.
|
- ^C can break code.
|
||||||
|
- check library(random)
|
||||||
|
- add more precision when outputting floats.
|
||||||
|
- make statistics/0 better looking.
|
||||||
|
- mask when installing.
|
||||||
|
|
||||||
TO CHECK:
|
TO CHECK:
|
||||||
- bad register allocation for a(X,Y) :- X is Y+2.3 ?
|
- bad register allocation for a(X,Y) :- X is Y+2.3 ?
|
||||||
|
@ -595,7 +595,7 @@ mkdir -p library/system
|
|||||||
mkdir -p CHR
|
mkdir -p CHR
|
||||||
mkdir -p CLPQR
|
mkdir -p CLPQR
|
||||||
|
|
||||||
AC_OUTPUT(Makefile library/regex/Makefile library/system/Makefile .depend library/Makefile CHR/Makefile CLPQR/Makefile)
|
AC_OUTPUT(Makefile library/regex/Makefile library/system/Makefile library/random/Makefile .depend library/Makefile CHR/Makefile CLPQR/Makefile)
|
||||||
|
|
||||||
make depend
|
make depend
|
||||||
|
|
||||||
|
10
docs/yap.tex
10
docs/yap.tex
@ -6889,9 +6889,9 @@ Creates a new list with the same elements as @var{Queue}.
|
|||||||
@cindex queue
|
@cindex queue
|
||||||
|
|
||||||
The following random number operations are included with the
|
The following random number operations are included with the
|
||||||
@code{use_module(library(random))} command. The random numbers packages
|
@code{use_module(library(random))} command. Since Yap-4.3.19 Yap uses
|
||||||
uses the Operating underlying random number generator, so random numbers
|
the O'Keefe public-domain algorithm, based on the "Applied Statistics"
|
||||||
are not necessarily repeatable.
|
algorithm AS183.
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
|
|
||||||
@ -6922,14 +6922,14 @@ integers then @var{NUMBER} will also be an integer, otherwise
|
|||||||
@syindex randseq/3
|
@syindex randseq/3
|
||||||
@cnindex randseq/3
|
@cnindex randseq/3
|
||||||
Unify @var{Numbers} with a list of @var{LENGTH} unique random integers
|
Unify @var{Numbers} with a list of @var{LENGTH} unique random integers
|
||||||
in the range @code{[1 ...@var{HIGH})}.
|
in the range @code{[1 ...@var{MAX})}.
|
||||||
|
|
||||||
@item randset(+@var{LENGTH}, +@var{MAX}, -@var{Numbers})
|
@item randset(+@var{LENGTH}, +@var{MAX}, -@var{Numbers})
|
||||||
@findex randset/3
|
@findex randset/3
|
||||||
@syindex randset/3
|
@syindex randset/3
|
||||||
@cnindex randset/3
|
@cnindex randset/3
|
||||||
Unify @var{Numbers} with an ordered list of @var{LENGTH} unique random
|
Unify @var{Numbers} with an ordered list of @var{LENGTH} unique random
|
||||||
integers in the range @code{[1 ...@var{HIGH})}.
|
integers in the range @code{[1 ...@var{MAX})}.
|
||||||
|
|
||||||
@item setrand(+@var{Key})
|
@item setrand(+@var{Key})
|
||||||
@findex setrand/1
|
@findex setrand/1
|
||||||
|
@ -15,6 +15,13 @@
|
|||||||
* *
|
* *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
|
% original code from RA O'Keefe.
|
||||||
|
|
||||||
|
% 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.
|
||||||
|
|
||||||
:- module(random, [
|
:- module(random, [
|
||||||
random/1,
|
random/1,
|
||||||
random/3,
|
random/3,
|
||||||
@ -24,79 +31,90 @@
|
|||||||
setrand/1
|
setrand/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
:- load_foreign_files([random], [], init_random).
|
||||||
|
|
||||||
random(X) :- X is random.
|
|
||||||
|
|
||||||
random(X, LOW, UPPER) :- integer(LOW), integer(UPPER), !,
|
% random(R) binds R to a new random number in [0.0,1.0)
|
||||||
X is integer(random*(UPPER-LOW))+LOW.
|
|
||||||
random(X, LOW, UPPER) :-
|
|
||||||
X is random*(UPPER-LOW)+LOW.
|
|
||||||
|
|
||||||
randseq(L, M, Rs) :-
|
% random(L, U, R) binds R to a random integer in [L,U)
|
||||||
integer(L),
|
% when L and U are integers (note that U will NEVER be generated),
|
||||||
L > 0,
|
% or to a random floating number in [L,U) otherwise.
|
||||||
integer(M),
|
|
||||||
M > 0,
|
|
||||||
M > L,
|
|
||||||
randseq(L, M, [], Rs).
|
|
||||||
|
|
||||||
randseq(0, _, Rs, Rs) :- !.
|
random(L, U, R) :- integer(L), integer(U), !,
|
||||||
randseq(K, N, Set, Rs) :-
|
random(X),
|
||||||
X is integer(random*N),
|
R is L+integer((U-L)*X).
|
||||||
not_in(Set, X), !,
|
random(L, U, R) :-
|
||||||
K1 is K-1,
|
number(L), number(U), !,
|
||||||
randseq(K1, N, [X|Set], Rs).
|
random(X),
|
||||||
randseq(K, N, Set, Rs) :-
|
R is L+((U-L)*X).
|
||||||
randseq(K, N, Set, Rs).
|
|
||||||
|
|
||||||
not_in([], _).
|
/* There are two versions of this operation.
|
||||||
not_in([X|L], Y) :- X \= Y,
|
|
||||||
not_in(L, Y).
|
randset(K, N, S)
|
||||||
|
|
||||||
randset(L, M, Rs) :-
|
generates a random set of K integers in the range 1..N.
|
||||||
integer(L),
|
The result is an ordered list, such as setof might produce.
|
||||||
L > 0,
|
|
||||||
integer(M),
|
randseq(K, N, L)
|
||||||
M > 0,
|
|
||||||
M > L,
|
generates a random sequence of K integers, the order is as
|
||||||
randset(L, M, [], Rs).
|
random as we can make it.
|
||||||
|
*/
|
||||||
randset(0, _, Rs, Rs) :- !.
|
|
||||||
randset(K, N, Set, Rs) :-
|
|
||||||
X is integer(random*N),
|
randset(K, N, S) :-
|
||||||
addnew(Set, X, NSet), !,
|
K >= 0,
|
||||||
K1 is K-1,
|
K =< N,
|
||||||
randset(K1, N, NSet, Rs).
|
randset(K, N, [], S).
|
||||||
randset(K, N, Set, Rs) :-
|
|
||||||
randset(K, N, Set, Rs).
|
|
||||||
|
randset(0, _, S, S) :- !.
|
||||||
addnew([], Y, [Y]).
|
randset(K, N, Si, So) :-
|
||||||
addnew([X|L], Y, [Y,X|L]) :- X > Y, !.
|
random(X),
|
||||||
addnew([X|L], Y, [X|NSet]) :-
|
X * N < K, !,
|
||||||
X < Y,
|
J is K-1,
|
||||||
addnew(L, Y, NSet).
|
M is N-1,
|
||||||
|
randset(J, M, [N|Si], So).
|
||||||
getrand(rand(X,Y,Z)) :-
|
randset(K, N, Si, So) :-
|
||||||
srandom(Seed0),
|
M is N-1,
|
||||||
Seed is abs(Seed0),
|
randset(K, M, Si, So).
|
||||||
X is Seed mod 30269,
|
|
||||||
Seed1 is Seed // 30269,
|
|
||||||
Y is Seed1 mod 30307,
|
randseq(K, N, S) :-
|
||||||
Seed2 is Seed1 // 30307,
|
randseq(K, N, L, []),
|
||||||
Z is Seed2 mod 30323.
|
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)) :-
|
setrand(rand(X,Y,Z)) :-
|
||||||
integer(X),
|
integer(X),
|
||||||
X > 1,
|
|
||||||
X < 30269,
|
|
||||||
integer(Y),
|
integer(Y),
|
||||||
Y > 1,
|
|
||||||
Y < 30307,
|
|
||||||
integer(Z),
|
integer(Z),
|
||||||
Z > 1,
|
X > 0,
|
||||||
Z < 30323,
|
X < 30269,
|
||||||
Seed is X + 30269*(Y + 30307*Z),
|
Y > 0,
|
||||||
srandom(Seed).
|
Y < 30307,
|
||||||
|
Z > 0,
|
||||||
|
Z < 30323,
|
||||||
|
setrand(X,Y,Z).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
88
library/random/Makefile.in
Normal file
88
library/random/Makefile.in
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#
|
||||||
|
# default base directory for YAP installation
|
||||||
|
#
|
||||||
|
ROOTDIR = @prefix@
|
||||||
|
#
|
||||||
|
# where the binary should be
|
||||||
|
#
|
||||||
|
BINDIR = $(ROOTDIR)/bin
|
||||||
|
#
|
||||||
|
# where YAP should look for libraries
|
||||||
|
#
|
||||||
|
LIBDIR=$(ROOTDIR)/lib/Yap
|
||||||
|
#
|
||||||
|
#
|
||||||
|
CC=@CC@
|
||||||
|
CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) -I$(srcdir) -I../.. -I$(srcdir)/../../include
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# You shouldn't need to change what follows.
|
||||||
|
#
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
INSTALL_DATA=@INSTALL_DATA@
|
||||||
|
INSTALL_PROGRAM=@INSTALL_PROGRAM@
|
||||||
|
SHELL=/bin/sh
|
||||||
|
RANLIB=@RANLIB@
|
||||||
|
srcdir=@srcdir@
|
||||||
|
SHLIB_CFLAGS=@SHLIB_CFLAGS@
|
||||||
|
SHLIB_SUFFIX=@SHLIB_SUFFIX@
|
||||||
|
#4.1VPATH=@srcdir@:@srcdir@/OPTYap
|
||||||
|
CWD=$(PWD)
|
||||||
|
#
|
||||||
|
|
||||||
|
OBJS=random.o
|
||||||
|
SOBJS=random@SHLIB_SUFFIX@
|
||||||
|
|
||||||
|
#in some systems we just create a single object, in others we need to
|
||||||
|
# create a libray
|
||||||
|
|
||||||
|
all: @NEWSHOBJ@
|
||||||
|
|
||||||
|
sobjs: $(SOBJS)
|
||||||
|
|
||||||
|
dll: random@SHLIB_SUFFIX@
|
||||||
|
|
||||||
|
random.o: $(srcdir)/random.c
|
||||||
|
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/random.c -o random.o
|
||||||
|
|
||||||
|
%.so: %.o
|
||||||
|
@SHLIB_LD@ -o $@ $<
|
||||||
|
|
||||||
|
random.so: random.o
|
||||||
|
@SHLIB_LD@ -o random.so random.o
|
||||||
|
|
||||||
|
#
|
||||||
|
# create a new DLL library on cygwin environments
|
||||||
|
#
|
||||||
|
# DLLNAME: name of the new dll
|
||||||
|
# OBJS: list of object files I want to put in
|
||||||
|
# LIBS: list of libraries to link with
|
||||||
|
# DEFFILE is the name of the definitions file.
|
||||||
|
# BASEFILE temporary
|
||||||
|
# EXPFILE temporary
|
||||||
|
# ENTRY is the entry point int WINAPI startup (HINSTANCE, DWORD, LPVOID)
|
||||||
|
#
|
||||||
|
DLLTOOL=dlltool
|
||||||
|
DLLNAME=random.dll
|
||||||
|
DLL_LIBS=-L /usr/lib/mingw -lmoldname -lcrtdll -lkernel32 -L../.. -lWYap
|
||||||
|
BASE_FILE=random.base
|
||||||
|
EXP_FILE=random.exp
|
||||||
|
DEF_FILE=$(srcdir)/random.def
|
||||||
|
ENTRY_FUNCTION=_win_random@12
|
||||||
|
#
|
||||||
|
random.dll: $(OBJS)
|
||||||
|
$(LD) -s --base-file $(BASE_FILE) --dll -o $(DLLNAME) $(OBJS) $(DLL_LIBS) -e $(ENTRY_FUNCTION)
|
||||||
|
$(DLLTOOL) --as=$(AS) --dllname $(DLLNAME) --def $(DEF_FILE) --base-file $(BASE_FILE) --output-exp $(EXP_FILE)
|
||||||
|
$(LD) -s --base-file $(BASE_FILE) $(EXP_FILE) -dll -o $(DLLNAME) $(OBJS) $(DLL_LIBS) -e $(ENTRY_FUNCTION)
|
||||||
|
$(DLLTOOL) --as=$(AS) --dllname $(DLLNAME) --def $(DEF_FILE) --base-file $(BASE_FILE) --output-exp $(EXP_FILE)
|
||||||
|
$(LD) $(EXP_FILE) --dll -o $(DLLNAME) $(OBJS) $(DLL_LIBS) -e $(ENTRY_FUNCTION)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
$(INSTALL_PROGRAM) $(SOBJS) $(DESTDIR)$(LIBDIR)
|
||||||
|
|
||||||
|
install_mingw32: dll
|
||||||
|
$(INSTALL_PROGRAM) -m 755 random.dll $(LIBDIR)/random.dll
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.so *~ $(OBJS) *.BAK
|
||||||
|
|
88
library/random/random.c
Normal file
88
library/random/random.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* YAP Prolog *
|
||||||
|
* *
|
||||||
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
||||||
|
* *
|
||||||
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
||||||
|
* *
|
||||||
|
**************************************************************************
|
||||||
|
* *
|
||||||
|
* File: regexp.c *
|
||||||
|
* Last rev: *
|
||||||
|
* mods: *
|
||||||
|
* comments: regular expression interpreter *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "c_interface.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void PROTO(init_random, (void));
|
||||||
|
|
||||||
|
static short a1 = 27314, b1 = 9213, c1 = 17773;
|
||||||
|
|
||||||
|
static int
|
||||||
|
p_random(void)
|
||||||
|
{
|
||||||
|
flt fli;
|
||||||
|
Int t1, t2, t3;
|
||||||
|
|
||||||
|
t1 = (a1 * 171) % 30269;
|
||||||
|
t2 = (b1 * 172) % 30307;
|
||||||
|
t3 = (c1 * 170) % 30323;
|
||||||
|
fli = (t1/30269.0) + (t2/30307.0) + (t3/30323.0);
|
||||||
|
a1 = t1;
|
||||||
|
b1 = t2;
|
||||||
|
c1 = t3;
|
||||||
|
return(unify(ARG1, MkFloatTerm(fli-(int)(fli))));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
p_setrand(void)
|
||||||
|
{
|
||||||
|
a1 = IntOfTerm(ARG1);
|
||||||
|
b1 = IntOfTerm(ARG2);
|
||||||
|
c1 = IntOfTerm(ARG3);
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
p_getrand(void)
|
||||||
|
{
|
||||||
|
return(unify(ARG1,MkIntTerm(a1)) &&
|
||||||
|
unify(ARG2,MkIntTerm(b1)) &&
|
||||||
|
unify(ARG3,MkIntTerm(c1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_random(void)
|
||||||
|
{
|
||||||
|
UserCPredicate("random", p_random, 1);
|
||||||
|
UserCPredicate("setrand", p_setrand, 3);
|
||||||
|
UserCPredicate("getrand", p_getrand, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
int WINAPI PROTO(win_random, (HANDLE, DWORD, LPVOID));
|
||||||
|
|
||||||
|
int WINAPI win_random(HANDLE hinst, DWORD reason, LPVOID reserved)
|
||||||
|
{
|
||||||
|
switch (reason)
|
||||||
|
{
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
2
library/random/random.def
Normal file
2
library/random/random.def
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
EXPORTS
|
||||||
|
init_random
|
Reference in New Issue
Block a user