@@ -295,7 +295,8 @@ impl SolvedMultiPod {
295295 added_statements_by_content. insert ( original_stmt, stmt) ;
296296 }
297297
298- // For the output pod, make statements public in the original order
298+ // For the output pod, make statements public in the original order.
299+ // Intermediate pods use the solver-selected public set.
299300 if pod_idx == solution. pod_count - 1 {
300301 for idx in & self . output_public_indices {
301302 let stmt = added_statements_by_content
@@ -312,6 +313,13 @@ impl SolvedMultiPod {
312313 }
313314 }
314315
316+ // Forward external premises only when the solver selected them as public
317+ // for this POD. These do not require local proving in this POD.
318+ for ext_premise_idx in & solution. pod_public_external_premises [ pod_idx] {
319+ let ext_premise = & solution. external_premises [ * ext_premise_idx] ;
320+ builder. reveal ( & ext_premise. statement ) ;
321+ }
322+
315323 // Step 4: Prove the POD
316324 let pod = builder. prove ( prover) ?;
317325
@@ -323,36 +331,17 @@ impl SolvedMultiPod {
323331 /// Returns (internal_pod_indices, external_pod_indices).
324332 fn compute_pod_inputs ( & self , pod_idx : usize ) -> ( BTreeSet < usize > , BTreeSet < usize > ) {
325333 let solution = & self . solution ;
326- let statements_in_pod = & solution. pod_statements [ pod_idx] ;
327-
328- let mut internal_pods: BTreeSet < usize > = BTreeSet :: new ( ) ;
334+ let internal_pods = solution. pod_internal_inputs [ pod_idx] . clone ( ) ;
329335 let mut external_pods: BTreeSet < usize > = BTreeSet :: new ( ) ;
330336
331- for & stmt_idx in statements_in_pod {
332- for dep in & self . deps . statement_deps [ stmt_idx] {
333- match dep {
334- StatementSource :: Internal ( dep_idx) => {
335- // Check if dependency is in an earlier POD (not local)
336- if !statements_in_pod. contains ( dep_idx) {
337- let earlier_pod_idx = ( 0 ..pod_idx)
338- . find ( |earlier_pod_idx| {
339- solution. pod_public_statements [ * earlier_pod_idx]
340- . contains ( dep_idx)
341- } )
342- . expect ( "internal pod with dependency statement" ) ;
343- internal_pods. insert ( earlier_pod_idx) ;
344- }
345- }
346- StatementSource :: External ( pod_hash) => {
347- let idx = self
348- . input_pods
349- . iter ( )
350- . position ( |p| p. statements_hash ( ) == * pod_hash)
351- . expect ( "external pod with dependency statement" ) ;
352- external_pods. insert ( idx) ;
353- }
354- }
355- }
337+ for external_idx in & solution. pod_external_inputs [ pod_idx] {
338+ let pod_hash = solution. external_pod_hashes [ * external_idx] ;
339+ let idx = self
340+ . input_pods
341+ . iter ( )
342+ . position ( |p| p. statements_hash ( ) == pod_hash)
343+ . expect ( "external pod hash from solver solution" ) ;
344+ external_pods. insert ( idx) ;
356345 }
357346
358347 assert ! ( internal_pods. len( ) + external_pods. len( ) <= self . params. max_input_pods) ;
@@ -1196,16 +1185,16 @@ mod tests {
11961185
11971186 #[ test]
11981187 fn test_external_pods_counted_in_input_limit ( ) -> Result < ( ) > {
1199- // Verifies that external input PODs are counted toward max_input_pods.
1188+ // Verifies that external input PODs are counted toward max_input_pods while
1189+ // still allowing the solver to route external premises through intermediate PODs.
12001190 //
12011191 // Setup:
12021192 // - max_input_pods = 2
12031193 // - 3 external PODs (A, B, C), each with a public statement
12041194 // - 3 public operations, each copying from a different external POD
12051195 //
1206- // Since all 3 must be public in POD 0 (the output POD), and POD 0 would need
1207- // all 3 external PODs as inputs (3 > max_input_pods), this is infeasible.
1208- // The solver should correctly detect and report this.
1196+ // A direct 1-POD layout would need 3 external inputs in the output POD (infeasible),
1197+ // so the solver should split the work and keep each generated POD within input limits.
12091198
12101199 let params = Params {
12111200 max_statements : 10 ,
@@ -1256,26 +1245,24 @@ mod tests {
12561245 multi_builder. add_pod ( ext_pod_b) ?;
12571246 multi_builder. add_pod ( ext_pod_c) ?;
12581247
1259- // Add public operations that each depend on a different external POD
1260- // All 3 must be public in POD 0, requiring 3 external inputs > max_input_pods
1248+ // Add public operations that each depend on a different external POD.
12611249 multi_builder. pub_op ( FrontendOp :: copy ( stmt_a) ) ?;
12621250 multi_builder. pub_op ( FrontendOp :: copy ( stmt_b) ) ?;
12631251 multi_builder. pub_op ( FrontendOp :: copy ( stmt_c) ) ?;
12641252
1265- // Solver should correctly detect infeasibility and return an error
1266- let result = multi_builder. solve ( ) ;
1253+ // Solver should find a feasible multi-POD layout that respects input limits.
1254+ let solved = multi_builder. solve ( ) ? ;
12671255 assert ! (
1268- result. is_err( ) ,
1269- "Expected solver to report infeasibility, but got: {:?}" ,
1270- result
1256+ solved. solution( ) . pod_count >= 2 ,
1257+ "Expected at least 2 PODs to satisfy max_input_pods=2 with 3 external sources"
12711258 ) ;
12721259
1273- let err_msg = result . unwrap_err ( ) . to_string ( ) ;
1274- assert ! (
1275- err_msg . contains ( "No feasible solution" ) ,
1276- "Expected 'No feasible solution' error, got: {}" ,
1277- err_msg
1278- ) ;
1260+ let result = solved . prove ( & prover ) ? ;
1261+ for ( i , pod ) in result . pods . iter ( ) . enumerate ( ) {
1262+ pod . pod
1263+ . verify ( )
1264+ . unwrap_or_else ( |_| panic ! ( "POD {} verification failed" , i ) ) ;
1265+ }
12791266
12801267 Ok ( ( ) )
12811268 }
0 commit comments