Skip to content

Commit

Permalink
New DrawRandomBool operation (#1645)
Browse files Browse the repository at this point in the history
Adds new `DrawRandomBool` operation that was inspired by
[this](https://learn.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.random.drawrandombool)
page on the deprecated QDK. This change has the same documentation and
functionality as the linked version.

Fixes #1170.
  • Loading branch information
nirajvenkat authored Jun 24, 2024
1 parent 6fb306b commit be3181b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 1 deletion.
4 changes: 4 additions & 0 deletions compiler/qsc_eval/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ pub(crate) fn call(
Ok(Value::Double(rng.gen_range(lo..=hi)))
}
}
"DrawRandomBool" => {
let p = arg.unwrap_double();
Ok(Value::Bool(rng.gen_bool(p)))
}
#[allow(clippy::cast_possible_truncation)]
"Truncate" => Ok(Value::Int(arg.unwrap_double() as i64)),
"__quantum__rt__qubit_allocate" => Ok(Value::Qubit(Qubit(sim.qubit_allocate()))),
Expand Down
14 changes: 14 additions & 0 deletions compiler/qsc_eval/src/intrinsic/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,20 @@ fn draw_random_double() {
);
}

#[test]
fn draw_random_bool() {
check_intrinsic_value(
"",
"Microsoft.Quantum.Random.DrawRandomBool(0.0)",
&Value::Bool(false),
);
check_intrinsic_value(
"",
"Microsoft.Quantum.Random.DrawRandomBool(1.0)",
&Value::Bool(true),
);
}

#[test]
fn truncate() {
check_intrinsic_value("", "Microsoft.Quantum.Math.Truncate(3.1)", &Value::Int(3));
Expand Down
2 changes: 1 addition & 1 deletion compiler/qsc_partial_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ impl<'a> PartialEvaluator<'a> {
| "GlobalPhase" => Ok(Value::unit()),
// The following intrinsic functions and operations should never make it past conditional compilation and
// the capabilities check pass.
"CheckZero" | "DrawRandomInt" | "DrawRandomDouble" | "Length" => {
"CheckZero" | "DrawRandomInt" | "DrawRandomDouble" | "DrawRandomBool" | "Length" => {
Err(Error::Unexpected(
format!(
"`{}` is not a supported by partial evaluation",
Expand Down
16 changes: 16 additions & 0 deletions compiler/qsc_partial_eval/tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,22 @@ fn call_to_draw_random_double_panics() {
});
}

#[test]
#[should_panic(expected = "`DrawRandomBool` is not a supported by partial evaluation")]
fn call_to_draw_random_bool_panics() {
_ = get_rir_program(indoc! {
r#"
namespace Test {
open Microsoft.Quantum.Random;
@EntryPoint()
operation Main() : Unit {
let _ = DrawRandomBool(0.0);
}
}
"#,
});
}

#[test]
fn call_to_length_in_inner_function_succeeds() {
let program = get_rir_program(indoc! {
Expand Down
25 changes: 25 additions & 0 deletions compiler/qsc_rca/tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,31 @@ fn check_rca_for_draw_random_double() {
);
}

#[test]
fn check_rca_for_draw_random_bool() {
let compilation_context = CompilationContext::default();
check_callable_compute_properties(
&compilation_context.fir_store,
compilation_context.get_compute_properties(),
"DrawRandomBool",
&expect![
r#"
Callable: CallableComputeProperties:
body: ApplicationsGeneratorSet:
inherent: Quantum: QuantumProperties:
runtime_features: RuntimeFeatureFlags(0x0)
value_kind: Element(Dynamic)
dynamic_param_applications:
[0]: [Parameter Type Element] Quantum: QuantumProperties:
runtime_features: RuntimeFeatureFlags(UseOfDynamicDouble)
value_kind: Element(Dynamic)
adj: <none>
ctl: <none>
ctl-adj: <none>"#
],
);
}

#[test]
fn check_rca_for_begin_estimate_caching() {
let compilation_context = CompilationContext::default();
Expand Down
21 changes: 21 additions & 0 deletions library/std/random.qs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,25 @@ namespace Microsoft.Quantum.Random {
body intrinsic;
}

/// # Summary
/// Given a success probability, returns a single Bernoulli trial
/// that is true with the given probability.
///
/// # Input
/// ## successProbability
/// The probability with which true should be returned.
///
/// # Output
/// `true` with probability `successProbability`
/// and `false` with probability `1.0 - successProbability`.
///
/// # Example
/// The following Q# snippet samples flips from a biased coin:
/// ```qsharp
/// let flips = DrawMany(DrawRandomBool, 10, 0.6);
/// ```
@Config(Unrestricted)
operation DrawRandomBool(successProbability : Double) : Bool {
body intrinsic;
}
}

0 comments on commit be3181b

Please sign in to comment.