root/tags/lgt2210/library/random.lgt

Revision 1143, 3.6 KB (checked in by pmoura, 5 years ago)

Added spaces around */2 operator to workaround some operator bugs on XSB.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1
2:- object(random,
3    implements(randomp)).
4
5
6    :- info([
7        version is 1.1,
8        author is 'Paulo Moura',
9        date is 2002/8/7,
10        comment is 'Random number generator predicates.']).
11
12
13    :- initialization(::reset_seed).
14
15
16    :- private(seed_/3).
17    :- dynamic(seed_/3).
18
19    :- mode(seed_(-integer, -integer, -integer), one).
20
21    :- info(seed_/3, [
22        comment is 'Stores the current random generator seed values.',
23        argnames is ['S0', 'S1', 'S2']]).
24
25
26    random(Random) :-
27        ::retract(seed_(A0, A1, A2)),
28        random(A0, A1, A2, B0, B1, B2, Random),
29        ::asserta(seed_(B0, B1, B2)).
30
31
32    random(A0, A1, A2, B0, B1, B2, Random) :-
33        B0 is (A0*171) mod 30269,
34        B1 is (A1*172) mod 30307,
35        B2 is (A2*170) mod 30323,
36        Float is A0/30269 + A1/30307 + A2/30323,
37        Random is Float - truncate(Float).
38
39
40    random(Lower, Upper, Random) :-
41        integer(Lower),
42        integer(Upper),
43        Upper >= Lower,
44        !,
45        random(Float),
46        Random is truncate((Float * (Upper-Lower)+Lower)).
47
48
49    random(Lower, Upper, Random) :-
50        float(Lower),
51        float(Upper),
52        Upper >= Lower,
53        random(Float),
54        Random is Float * (Upper-Lower)+Lower.
55
56
57    randseq(Length, Lower, Upper, Sequence) :-
58        integer(Length),
59        Length >= 0,
60        integer(Lower),
61        integer(Upper),
62        Upper >= Lower,
63        !,
64        ::retract(seed_(A0, A1, A2)),
65        randseq(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], List),
66        ::asserta(seed_(B0, B1, B2)),
67        map_truncate(List, Sequence).
68
69    randseq(Length, Lower, Upper, Sequence) :-
70        integer(Length),
71        Length >= 0,
72        float(Lower),
73        float(Upper),
74        Upper >= Lower,
75        ::retract(seed_(A0, A1, A2)),
76        randseq(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], Sequence),
77        ::asserta(seed_(B0, B1, B2)).
78
79
80    randseq(0, _, _, Seed, Seed, List, List) :-
81        !.
82
83    randseq(N, Lower, Upper, (A0, A1, A2), (C0, C1, C2), Acc, List) :-
84        N2 is N - 1,
85        random(A0, A1, A2, B0, B1, B2, R),
86        Random is R * (Upper-Lower)+Lower,
87        randseq(N2, Lower, Upper, (B0, B1, B2), (C0, C1, C2), [Random| Acc], List).
88
89
90    map_truncate([], []).
91
92    map_truncate([Float| Floats], [Integer| Integers]) :-
93        Integer is truncate(Float),
94        map_truncate(Floats, Integers).
95
96
97    randset(Length, Lower, Upper, Set) :-
98        integer(Length),
99        Length >= 0,
100        integer(Lower),
101        integer(Upper),
102        Upper >= Lower,
103        Length =< Upper - Lower,
104        !,
105        ::retract(seed_(A0, A1, A2)),
106        randset(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], Set),
107        ::asserta(seed_(B0, B1, B2)).
108
109    randset(Length, Lower, Upper, Set) :-
110        integer(Length),
111        Length >= 0,
112        float(Lower),
113        float(Upper),
114        Upper >= Lower,
115        ::retract(seed_(A0, A1, A2)),
116        randset(Length, Lower, Upper, (A0, A1, A2), (B0, B1, B2), [], Set),
117        ::asserta(seed_(B0, B1, B2)).
118
119
120    randset(0, _, _, Seed, Seed, List, List) :-
121        !.
122
123    randset(N, Lower, Upper, (A0, A1, A2), (C0, C1, C2), Acc, List) :-
124        N2 is N - 1,
125        random(A0, A1, A2, B0, B1, B2, Float),
126        Float2 is Float * (Upper-Lower)+Lower,
127        (integer(Lower) ->
128            Random is truncate(Float2)
129            ;
130            Random is Float2),
131        (not_member(Acc, Random) ->
132            add_ordered(Acc, Random, Acc2),
133            randset(N2, Lower, Upper, (B0, B1, B2), (C0, C1, C2), Acc2, List)
134            ;
135            randset(N, Lower, Upper, (B0, B1, B2), (C0, C1, C2), Acc, List)).
136
137
138    not_member([], _).
139
140    not_member([H| T], R) :-
141        H =\= R,
142        not_member(T, R).
143
144
145    add_ordered([], R, [R]).
146
147    add_ordered([H| T], R, L) :-
148        H > R ->
149            L = [R, H| T]
150            ;
151            L = [H| T2],
152            add_ordered(T, R, T2).
153
154
155    reset_seed :-
156        ::retractall(seed_(_, _, _)),
157        ::asserta(seed_(3172, 9814, 20125)).
158
159
160    set_seed(Seed) :-
161        integer(Seed),
162        Seed > 0,
163        ::retractall(seed_(_, _, _)),
164        S0 is Seed mod 30269,
165        S1 is Seed mod 30307,
166        S2 is Seed mod 30323,
167        ::asserta(seed_(S0, S1, S2)).
168
169
170:- end_object.
Note: See TracBrowser for help on using the browser.