score_set/traits.rs
1use witnessed::Witnessed;
2
3/// Witness attached to values known to be valid for the normalized `[0, 1]`
4/// scoring boundary.
5pub struct V01;
6
7/// Error returned when a value cannot be proven to be in the normalized
8/// `[0, 1]` range.
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct V01Error;
11
12/// Proves that an `f32` value is in the normalized `[0, 1]` range.
13///
14/// This function is suitable for use with [`witnessed::Witnessing::by`]:
15///
16/// ```
17/// use score_set::traits::{prove_v01_f32, V01};
18/// use witnessed::{WitnessExt, Witnessed};
19///
20/// let score: Witnessed<f32, V01> = 0.75_f32.witness().by(prove_v01_f32).unwrap();
21/// assert_eq!(*score, 0.75);
22/// ```
23///
24/// Values such as `NaN` are rejected because neither range comparison
25/// succeeds for them.
26pub fn prove_v01_f32(value: &f32) -> Result<V01, V01Error> {
27 (0.0..=1.0).contains(value).then_some(V01).ok_or(V01Error)
28}
29
30/// Proves that an `f64` value is in the normalized `[0, 1]` range.
31///
32/// Values such as `NaN` are rejected because neither range comparison
33/// succeeds for them.
34pub fn prove_v01_f64(value: &f64) -> Result<V01, V01Error> {
35 (0.0..=1.0).contains(value).then_some(V01).ok_or(V01Error)
36}
37
38/// Measures a context and returns a value chosen by the implementation.
39///
40/// `Output` is the value consumed by a corresponding `Map01F32` or `Map01F64`
41/// implementation.
42pub trait Measure<Ctx: ?Sized>: Send + Sync {
43 /// The value produced by [`Measure::measure`].
44 type Output;
45
46 /// Extracts a measurable value from `ctx`.
47 fn measure(&self, ctx: &Ctx) -> Self::Output;
48}
49
50/// Maps a measurement into the `[0, 1]` range.
51///
52/// `Input` is associated with the mapper rather than fixed in the trait, so a
53/// mapper can consume any measurement type. The normalized result carries the
54/// [`V01`] witness.
55pub trait Map01F32: Send + Sync {
56 /// The value accepted by [`Map01F32::map`].
57 type Input;
58
59 /// Converts `value` into a normalized score.
60 fn map(&self, value: Self::Input) -> Witnessed<f32, V01>;
61}
62
63/// Maps a measurement into the `[0, 1]` range.
64///
65/// `Input` is associated with the mapper rather than fixed in the trait, so a
66/// mapper can consume any measurement type. The normalized result carries the
67/// [`V01`] witness.
68pub trait Map01F64: Send + Sync {
69 /// The value accepted by [`Map01F64::map`].
70 type Input;
71
72 /// Converts `value` into a normalized score.
73 fn map(&self, value: Self::Input) -> Witnessed<f64, V01>;
74}
75
76/// Evaluates a context into an `f64` score.
77pub trait EvalF64<Ctx: ?Sized>: Send + Sync {
78 /// Computes a score from `ctx`.
79 fn eval(&self, ctx: &Ctx) -> f64;
80}
81
82/// Evaluates a context into an `f32` score.
83pub trait EvalF32<Ctx: ?Sized>: Send + Sync {
84 /// Computes a score from `ctx`.
85 fn eval(&self, ctx: &Ctx) -> f32;
86}