@@ -314,6 +314,29 @@ TEST_F(PerBlockGateCountTests, RecursionConstraintBasic)
314314 info (" N=1 vs N=2 real_variable_index diffs: " , n1_n2_diffs);
315315 EXPECT_EQ (n1_n2_diffs, 0 ) << " N=1 vs N=2 not bit-identical" ;
316316 }
317+
318+ // Quick Ultra check: does the same test fail with Ultra?
319+ {
320+ AcirFormat ultra_par_c = constraints;
321+ UltraCircuitBuilder ultra_par{ WitnessVector (witness), ultra_par_c.public_inputs , false };
322+ build_constraints_parallel (ultra_par, ultra_par_c, metadata, /* num_threads=*/ 1 );
323+
324+ AcirFormat ultra_seq_c = constraints;
325+ UltraCircuitBuilder ultra_seq{ WitnessVector (witness), ultra_seq_c.public_inputs , false };
326+ for (const auto & [val, _] : ultra_par.constant_variable_indices ) {
327+ ultra_seq.put_constant_variable (val);
328+ }
329+ for (const auto & [target, rl] : ultra_par.range_lists ) {
330+ if (ultra_seq.range_lists .count (target) == 0 ) {
331+ ultra_seq.range_lists .insert ({ target, ultra_seq.create_range_list (target) });
332+ }
333+ }
334+ build_constraints (ultra_seq, ultra_seq_c, metadata);
335+ info (" Ultra: par vars=" , ultra_par.get_num_variables (), " seq vars=" , ultra_seq.get_num_variables ());
336+
337+ size_t ultra_failures = check_semantic_equivalence (" recursion Ultra seq-vs-par" , ultra_seq, ultra_par);
338+ info (" Ultra seq-vs-par: " , ultra_failures, " failures" );
339+ }
317340}
318341
319342// Test recursion constraint alongside other constraint types in the parallel pipeline.
0 commit comments