Skip to content

Commit beea8eb

Browse files
committed
Remove the default PositiveF64 constructor
It is now impossible to create an invalid PositiveF64. This eliminates any possibility of division by 0 in the compiler.
1 parent a29f8e3 commit beea8eb

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

src/policy/compiler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ where
12681268
.into_iter()
12691269
.filter(|&(key, _)| key.ty.corr.base == types::Base::B && key.dissat_prob == dissat_prob)
12701270
.map(|(_, val)| val)
1271-
.min_by_key(|ext| PositiveF64(ext.cost_1d(sat_prob, dissat_prob)))
1271+
.min_by_key(|ext| PositiveF64::new(ext.cost_1d(sat_prob, dissat_prob)))
12721272
.ok_or(CompilerError::LimitsExceeded)
12731273
}
12741274

@@ -1293,7 +1293,7 @@ where
12931293
&& key.dissat_prob == dissat_prob
12941294
})
12951295
.map(|(_, val)| val)
1296-
.min_by_key(|ext| PositiveF64(ext.cost_1d(sat_prob, dissat_prob)))
1296+
.min_by_key(|ext| PositiveF64::new(ext.cost_1d(sat_prob, dissat_prob)))
12971297
.ok_or(CompilerError::LimitsExceeded)
12981298
}
12991299

src/policy/concrete.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
618618
// Stopping condition: When NONE of the inputs can be further enumerated.
619619
'outer: loop {
620620
//--- FIND a plausible node ---
621-
let mut prob: Reverse<PositiveF64> = Reverse(PositiveF64(0.0));
621+
let mut prob: Reverse<PositiveF64> = Reverse(PositiveF64::EPSILON);
622622
let mut curr_policy: Arc<Self> = Arc::new(Self::Unsatisfiable);
623623
let mut curr_pol_replace_vec: Vec<(PositiveF64, Arc<Self>)> = vec![];
624624
let mut no_more_enum = false;
@@ -1155,9 +1155,9 @@ fn with_huffman_tree<Pk: MiniscriptKey>(
11551155
let (p1, s1) = node_weights.pop().expect("len must at least be two");
11561156
let (p2, s2) = node_weights.pop().expect("len must at least be two");
11571157

1158-
let p = (p1.0).0 + (p2.0).0;
1158+
let p = p1.0 + p2.0;
11591159
node_weights.push((
1160-
Reverse(PositiveF64(p)),
1160+
Reverse(p),
11611161
TapTree::combine(s1, s2)
11621162
.expect("huffman tree cannot produce depth > 128 given sane weights"),
11631163
));

src/primitives/positive_f64.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,28 @@ use crate::Threshold;
99

1010
/// Ordered f64 for comparison.
1111
#[derive(Copy, Clone, PartialEq, Debug)]
12-
pub struct PositiveF64(pub f64);
12+
pub struct PositiveF64(f64);
1313

1414
impl PositiveF64 {
15+
/// The smallest representable value of a [`PositiveF64`].
16+
pub const EPSILON: Self = Self(f64::EPSILON);
17+
1518
/// The constant one.
1619
pub const ONE: Self = Self(1.0);
1720

1821
/// Constant used in unit tsets
1922
#[cfg(test)]
2023
pub const ONE_QUARTER: Self = Self(0.25);
2124

25+
/// Attempts to create a [`PositiveF64`] from an ordinary `f64`.
26+
pub const fn new(f: f64) -> Option<Self> {
27+
if f > 0.0 {
28+
Some(Self(f))
29+
} else {
30+
None
31+
}
32+
}
33+
2234
/// Given an [`Option<PositiveF64>`], if it is `Some` then add it to the value.
2335
/// Otherwise return the unmodified value.
2436
///

0 commit comments

Comments
 (0)