@@ -410,6 +410,26 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
410
410
/// Flattens out trees of `And`s and `Or`s; eliminate `Trivial` and
411
411
/// `Unsatisfiable`s. Does not reorder any branches; use `.sort`.
412
412
pub fn normalized ( self ) -> Policy < Pk > {
413
+ // Returns (m, n)-thresh values for the normalized (k, subs.len())-thresh.
414
+ fn normalized_threshold_values < Pk : MiniscriptKey > (
415
+ k : usize ,
416
+ subs : & [ Arc < Policy < Pk > > ] ,
417
+ ) -> ( usize , usize ) {
418
+ let trivial_count = subs
419
+ . iter ( )
420
+ . filter ( |& pol| * pol. as_ref ( ) == Policy :: Trivial )
421
+ . count ( ) ;
422
+ let unsatisfied_count = subs
423
+ . iter ( )
424
+ . filter ( |& pol| * pol. as_ref ( ) == Policy :: Unsatisfiable )
425
+ . count ( ) ;
426
+
427
+ let n = subs. len ( ) - unsatisfied_count - trivial_count; // remove all true/false
428
+ let m = k. checked_sub ( trivial_count) . unwrap_or ( 0 ) ; // satisfy all trivial
429
+
430
+ ( m, n)
431
+ }
432
+
413
433
match self {
414
434
Policy :: Threshold ( k, subs) => {
415
435
let mut ret_subs = Vec :: with_capacity ( subs. len ( ) ) ;
@@ -418,21 +438,12 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
418
438
. into_iter ( )
419
439
. map ( |sub| Arc :: new ( sub. as_ref ( ) . clone ( ) . normalized ( ) ) )
420
440
. collect ( ) ;
421
- let trivial_count = subs
422
- . iter ( )
423
- . filter ( |& pol| * pol. as_ref ( ) == Policy :: Trivial )
424
- . count ( ) ;
425
- let unsatisfied_count = subs
426
- . iter ( )
427
- . filter ( |& pol| * pol. as_ref ( ) == Policy :: Unsatisfiable )
428
- . count ( ) ;
429
-
430
- let n = subs. len ( ) - unsatisfied_count - trivial_count; // remove all true/false
431
- let m = k. checked_sub ( trivial_count) . unwrap_or ( 0 ) ; // satisfy all trivial
441
+
442
+ let ( m, n) = normalized_threshold_values ( k, & subs) ;
432
443
433
444
// Call the current threshold "parent" to differentiate it from its "child" threshold below.
434
445
let parent_is_and = m == n; // (n, n)-thresh is an AND
435
- let parent_is_or = m == 1 ; // (1, n)-thresh is an OR
446
+ let parent_is_or = m == 1 ; // (1, n)-thresh is an OR
436
447
437
448
for sub in subs {
438
449
match sub. as_ref ( ) {
@@ -447,7 +458,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
447
458
} else if parent_is_and && child_is_and {
448
459
// If both parent and child are ANDs we can flatten them.
449
460
subs. iter ( ) . for_each ( |sub| ret_subs. push ( Arc :: clone ( sub) ) ) ;
450
- } else if parent_is_or && child_is_or {
461
+ } else if parent_is_or && child_is_or {
451
462
// If both parent and child are ORs we can flatten them.
452
463
subs. iter ( ) . for_each ( |sub| ret_subs. push ( Arc :: clone ( sub) ) ) ;
453
464
} else {
0 commit comments