@@ -698,20 +698,34 @@ fn verify_rule_fixtures_match_computed() {
698698 loaded_rule. source. problem,
699699 loaded_rule. target. problem
700700 ) ;
701- let loaded_solutions: BTreeSet < _ > = loaded_rule
702- . solutions
703- . iter ( )
704- . map ( |pair| ( pair. source_config . clone ( ) , pair. target_config . clone ( ) ) )
705- . collect ( ) ;
706- let computed_solutions: BTreeSet < _ > = computed_rule
707- . solutions
708- . iter ( )
709- . map ( |pair| ( pair. source_config . clone ( ) , pair. target_config . clone ( ) ) )
710- . collect ( ) ;
701+ // Solution witnesses may differ across platforms (ILP solver
702+ // nondeterminism), so compare energy (objective value) rather than
703+ // exact configs — both must be optimal.
711704 assert_eq ! (
712- loaded_solutions, computed_solutions,
713- "solution set mismatch for {} -> {} — regenerate fixtures" ,
705+ loaded_rule. solutions. len( ) ,
706+ computed_rule. solutions. len( ) ,
707+ "solution count mismatch for {} -> {} — regenerate fixtures" ,
714708 loaded_rule. source. problem, loaded_rule. target. problem
715709 ) ;
710+ let label =
711+ format ! ( "{} -> {}" , loaded_rule. source. problem, loaded_rule. target. problem) ;
712+ for ( loaded_pair, computed_pair) in
713+ loaded_rule. solutions . iter ( ) . zip ( computed_rule. solutions . iter ( ) )
714+ {
715+ let loaded_target_problem = load_dyn (
716+ & loaded_rule. target . problem ,
717+ & loaded_rule. target . variant ,
718+ loaded_rule. target . instance . clone ( ) ,
719+ )
720+ . unwrap_or_else ( |e| panic ! ( "{label}: load target: {e}" ) ) ;
721+ let loaded_energy =
722+ loaded_target_problem. evaluate_dyn ( & loaded_pair. target_config ) ;
723+ let computed_energy =
724+ loaded_target_problem. evaluate_dyn ( & computed_pair. target_config ) ;
725+ assert_eq ! (
726+ loaded_energy, computed_energy,
727+ "{label}: target energy mismatch — regenerate fixtures"
728+ ) ;
729+ }
716730 }
717731}
0 commit comments