| 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. |
|---|