@@ -23,7 +23,15 @@ pub struct NodeRef {
23
23
24
24
impl std:: fmt:: Debug for NodeRef {
25
25
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
26
- f. debug_tuple ( "NodeRef::new" ) . field ( & self . index ( ) ) . finish ( )
26
+ if self . is_const ( ) {
27
+ if * self == Self :: TRUE {
28
+ f. debug_struct ( "NodeRef::TRUE" ) . finish ( )
29
+ } else {
30
+ f. debug_struct ( "NodeRef::FALSE" ) . finish ( )
31
+ }
32
+ } else {
33
+ f. debug_tuple ( "NodeRef::new" ) . field ( & self . index ( ) ) . finish ( )
34
+ }
27
35
}
28
36
}
29
37
@@ -48,6 +56,10 @@ impl NodeRef {
48
56
pub fn index ( self ) -> usize {
49
57
!( self . code . 0 . get ( ) ) as usize
50
58
}
59
+
60
+ pub fn is_const ( self ) -> bool {
61
+ self == Self :: TRUE || self == Self :: FALSE
62
+ }
51
63
}
52
64
53
65
#[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
@@ -348,7 +360,10 @@ impl AndOrGraph {
348
360
}
349
361
} ;
350
362
351
- if shuffle > 0 && output != NodeRef :: FALSE && output != NodeRef :: TRUE {
363
+ if ( shuffle > 0 || new_inputs != inputs)
364
+ && output != NodeRef :: FALSE
365
+ && output != NodeRef :: TRUE
366
+ {
352
367
if let Ok ( ( gate, inputs) ) = self . nodes [ output. index ( ) ] . def . as_gate ( ) {
353
368
let [ a, b] = inputs. map ( |input| self . nodes [ input. index ( ) ] . priority ) ;
354
369
@@ -438,6 +453,7 @@ pub enum Verification {
438
453
439
454
pub struct MinimizationOptions {
440
455
pub fixed_init : bool ,
456
+ pub satisfy_assumptions : bool ,
441
457
pub verify : Option < Verification > ,
442
458
}
443
459
@@ -509,6 +525,7 @@ pub fn minimize<L: Lit>(
509
525
) ;
510
526
511
527
let mut minimization_target = ' minimization_target: {
528
+ let mut invariant_failed = ( Some ( false ) , NodeRef :: TRUE ) ;
512
529
for ( t, inputs) in frame_inputs. iter ( ) . enumerate ( ) {
513
530
if t > 0 {
514
531
successor_frame (
@@ -527,18 +544,29 @@ pub fn minimize<L: Lit>(
527
544
& mut graph,
528
545
) ;
529
546
}
547
+
548
+ if options. satisfy_assumptions {
549
+ for invariant in aig. invariant_constraints . iter ( ) {
550
+ let ( var, polarity) = unpack_lit ( * invariant) ;
551
+ let inv_invariant = state[ var] . invert_if ( !polarity, & mut graph) ;
552
+
553
+ invariant_failed = invariant_failed. or ( inv_invariant, & mut graph) ;
554
+ }
555
+ }
556
+
530
557
let mut good_state = ( Some ( true ) , NodeRef :: TRUE ) ;
531
558
532
559
for ( i, bad) in aig. bad_state_properties . iter ( ) . enumerate ( ) {
533
560
let ( var, polarity) = unpack_lit ( * bad) ;
534
561
let inv_bad = state[ var] . invert_if ( !polarity, & mut graph) ;
535
562
536
- if inv_bad. 0 == Some ( false ) {
563
+ if inv_bad. 0 == Some ( false ) && invariant_failed . 0 == Some ( false ) {
537
564
println ! ( "bad state property {i} active in frame {t}" ) ;
538
565
}
539
566
540
567
good_state = good_state. and ( inv_bad, & mut graph) ;
541
568
}
569
+ good_state = good_state. or ( invariant_failed, & mut graph) ;
542
570
if good_state. 0 == Some ( false ) {
543
571
println ! ( "bad state found in frame {t}" ) ;
544
572
@@ -691,6 +719,16 @@ pub fn minimize<L: Lit>(
691
719
) ;
692
720
}
693
721
722
+ if options. satisfy_assumptions {
723
+ for invariant in aig. invariant_constraints . iter ( ) {
724
+ let ( var, polarity) = unpack_lit ( * invariant) ;
725
+ let invariant_output = check_state[ var] . invert_if ( polarity, & mut ( ) ) ;
726
+ if invariant_output != Some ( true ) {
727
+ break ' frame;
728
+ }
729
+ }
730
+ }
731
+
694
732
for bad in aig. bad_state_properties . iter ( ) {
695
733
let ( var, polarity) = unpack_lit ( * bad) ;
696
734
let bad_output = check_state[ var] . invert_if ( polarity, & mut ( ) ) ;
0 commit comments