root/tags/lgt2311/library/random.lgt

Revision 3875, 3.6 KB (checked in by pmoura, 15 months ago)

Updated the library object "random" by replacing the synchronized/0 directive by a synchronized/1 directive listing only the predicates that modify the random number seed.

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