3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -631,6 +631,7 @@ dependencies = [
|
|||||||
"dashu-int",
|
"dashu-int",
|
||||||
"num-modular",
|
"num-modular",
|
||||||
"num-order",
|
"num-order",
|
||||||
|
"rand",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
@@ -645,6 +646,7 @@ dependencies = [
|
|||||||
"dashu-base",
|
"dashu-base",
|
||||||
"num-modular",
|
"num-modular",
|
||||||
"num-order",
|
"num-order",
|
||||||
|
"rand",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
@@ -676,6 +678,7 @@ dependencies = [
|
|||||||
"dashu-int",
|
"dashu-int",
|
||||||
"num-modular",
|
"num-modular",
|
||||||
"num-order",
|
"num-order",
|
||||||
|
"rand",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ bytes = "1"
|
|||||||
chrono = "0.4.38"
|
chrono = "0.4.38"
|
||||||
cpu-time = "1.0.0"
|
cpu-time = "1.0.0"
|
||||||
crrl = "0.9.0"
|
crrl = "0.9.0"
|
||||||
dashu = "0.4.2"
|
dashu = { version = "0.4.2", features = ["rand"] }
|
||||||
derive_more = "0.99.18"
|
derive_more = "0.99.18"
|
||||||
dirs-next = "2.0.0"
|
dirs-next = "2.0.0"
|
||||||
divrem = "1.0.0"
|
divrem = "1.0.0"
|
||||||
|
|||||||
@@ -419,6 +419,8 @@ enum SystemClauseType {
|
|||||||
GetUnknown,
|
GetUnknown,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$install_new_block")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$install_new_block")))]
|
||||||
InstallNewBlock,
|
InstallNewBlock,
|
||||||
|
#[strum_discriminants(strum(props(Arity = "3", Name = "$random_integer")))]
|
||||||
|
RandomInteger,
|
||||||
#[strum_discriminants(strum(props(Arity = "0", Name = "$maybe")))]
|
#[strum_discriminants(strum(props(Arity = "0", Name = "$maybe")))]
|
||||||
Maybe,
|
Maybe,
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$current_time")))]
|
#[strum_discriminants(strum(props(Arity = "1", Name = "$current_time")))]
|
||||||
@@ -1805,6 +1807,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::CallGetDoubleQuotes |
|
&Instruction::CallGetDoubleQuotes |
|
||||||
&Instruction::CallGetUnknown |
|
&Instruction::CallGetUnknown |
|
||||||
&Instruction::CallInstallNewBlock |
|
&Instruction::CallInstallNewBlock |
|
||||||
|
&Instruction::CallRandomInteger |
|
||||||
&Instruction::CallMaybe |
|
&Instruction::CallMaybe |
|
||||||
&Instruction::CallCpuNow |
|
&Instruction::CallCpuNow |
|
||||||
&Instruction::CallDeterministicLengthRundown |
|
&Instruction::CallDeterministicLengthRundown |
|
||||||
@@ -2042,6 +2045,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ExecuteGetDoubleQuotes |
|
&Instruction::ExecuteGetDoubleQuotes |
|
||||||
&Instruction::ExecuteGetUnknown |
|
&Instruction::ExecuteGetUnknown |
|
||||||
&Instruction::ExecuteInstallNewBlock |
|
&Instruction::ExecuteInstallNewBlock |
|
||||||
|
&Instruction::ExecuteRandomInteger |
|
||||||
&Instruction::ExecuteMaybe |
|
&Instruction::ExecuteMaybe |
|
||||||
&Instruction::ExecuteCpuNow |
|
&Instruction::ExecuteCpuNow |
|
||||||
&Instruction::ExecuteDeterministicLengthRundown |
|
&Instruction::ExecuteDeterministicLengthRundown |
|
||||||
|
|||||||
@@ -15,16 +15,14 @@ the random seed. This makes everything completely reproducible.
|
|||||||
% Succeeds with probability 0.5.
|
% Succeeds with probability 0.5.
|
||||||
maybe :- '$maybe'.
|
maybe :- '$maybe'.
|
||||||
|
|
||||||
% The higher the precision, the slower it gets.
|
|
||||||
random_number_precision(64).
|
|
||||||
|
|
||||||
%% random(-R).
|
%% random(-R).
|
||||||
%
|
%
|
||||||
% Generates a random floating number between 0 (inclusive) and 1 (exclusive).
|
% Generates a random floating number between 0 (inclusive) and 1 (exclusive).
|
||||||
random(R) :-
|
random(R) :-
|
||||||
var(R),
|
var(R),
|
||||||
random_number_precision(N),
|
N is 2^50,
|
||||||
rnd(N, R).
|
'$random_integer'(0, N, K),
|
||||||
|
R is K/N.
|
||||||
|
|
||||||
%% random_integer(+Lower, +Upper, -R).
|
%% random_integer(+Lower, +Upper, -R).
|
||||||
%
|
%
|
||||||
@@ -41,25 +39,10 @@ random_integer(Lower, Upper, R) :-
|
|||||||
type_error(integer, Lower, random_integer/3)
|
type_error(integer, Lower, random_integer/3)
|
||||||
; \+ integer(Upper) ->
|
; \+ integer(Upper) ->
|
||||||
type_error(integer, Upper, random_integer/3)
|
type_error(integer, Upper, random_integer/3)
|
||||||
; Upper > Lower,
|
; Lower < Upper,
|
||||||
random(R0),
|
'$random_integer'(Lower, Upper, R)
|
||||||
R is floor((Upper - Lower) * R0 + Lower)
|
|
||||||
).
|
).
|
||||||
|
|
||||||
rnd(N, R) :-
|
|
||||||
rnd_(N, 0, R).
|
|
||||||
|
|
||||||
rnd_(0, R, R) :- !.
|
|
||||||
rnd_(N, R0, R) :-
|
|
||||||
maybe,
|
|
||||||
!,
|
|
||||||
N1 is N - 1,
|
|
||||||
rnd_(N1, R0, R).
|
|
||||||
rnd_(N, R0, R) :-
|
|
||||||
N1 is N - 1,
|
|
||||||
R1 is R0 + 1.0 / 2.0 ^ N,
|
|
||||||
rnd_(N1, R1, R).
|
|
||||||
|
|
||||||
%% set_random(+Seed).
|
%% set_random(+Seed).
|
||||||
%
|
%
|
||||||
% Sets a seed that will be used for subsequent random generations in this library.
|
% Sets a seed that will be used for subsequent random generations in this library.
|
||||||
|
|||||||
@@ -4061,6 +4061,14 @@ impl Machine {
|
|||||||
.install_new_block(self.machine_st.registers[1]);
|
.install_new_block(self.machine_st.registers[1]);
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
|
&Instruction::CallRandomInteger => {
|
||||||
|
self.random_integer();
|
||||||
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
|
}
|
||||||
|
&Instruction::ExecuteRandomInteger => {
|
||||||
|
self.random_integer();
|
||||||
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
|
}
|
||||||
&Instruction::CallMaybe => {
|
&Instruction::CallMaybe => {
|
||||||
self.maybe();
|
self.maybe();
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
|
|||||||
@@ -4157,6 +4157,63 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn random_integer(&mut self) {
|
||||||
|
let a1 = self.deref_register(1);
|
||||||
|
let a2 = self.deref_register(2);
|
||||||
|
let value = match (Number::try_from(a1), Number::try_from(a2)) {
|
||||||
|
(Ok(Number::Fixnum(lower)), Ok(Number::Fixnum(upper))) => {
|
||||||
|
let (lower, upper) = (lower.get_num(), upper.get_num());
|
||||||
|
if lower >= upper {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let value = self.rng.gen_range(lower..upper);
|
||||||
|
Number::Fixnum(Fixnum::build_with(value))
|
||||||
|
}
|
||||||
|
(Ok(Number::Fixnum(lower)), Ok(Number::Integer(upper))) => {
|
||||||
|
let lower = Integer::from(lower);
|
||||||
|
if &lower >= &*upper {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let value = self.rng.gen_range(lower..(&*upper).clone());
|
||||||
|
Number::arena_from(value, &mut self.machine_st.arena)
|
||||||
|
}
|
||||||
|
(Ok(Number::Integer(lower)), Ok(Number::Fixnum(upper))) => {
|
||||||
|
let upper = Integer::from(upper);
|
||||||
|
if &*lower >= &upper {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let value = self.rng.gen_range((&*lower).clone()..upper);
|
||||||
|
Number::arena_from(value, &mut self.machine_st.arena)
|
||||||
|
}
|
||||||
|
(Ok(Number::Integer(lower)), Ok(Number::Integer(upper))) => {
|
||||||
|
if &*lower >= &*upper {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let value = self.rng.gen_range((&*lower).clone()..(&*upper).clone());
|
||||||
|
Number::arena_from(value, &mut self.machine_st.arena)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let a3 = self.deref_register(3);
|
||||||
|
match value {
|
||||||
|
Number::Fixnum(n) => {
|
||||||
|
self.machine_st.unify_fixnum(n, a3);
|
||||||
|
}
|
||||||
|
Number::Integer(n) => {
|
||||||
|
self.machine_st.unify_big_int(n, a3);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn maybe(&mut self) {
|
pub(crate) fn maybe(&mut self) {
|
||||||
self.machine_st.fail = self.rng.gen();
|
self.machine_st.fail = self.rng.gen();
|
||||||
|
|||||||
Reference in New Issue
Block a user