Build the "flat" block for recursor generation, detecting nested occurrences. Mirrors lean4lean's `ElimNestedInductive.run`: walks constructor fields, detects `ExtInd(block_member_ref)` patterns, and adds auxiliary entries for each nested external inductive. Queue-based for transitive nesting.
(
&mut self,
block_inds: &[KId<M>],
n_rec_params: u64,
univ_offset: u64,
)
| 489 | match w.data() { |
| 490 | ExprData::All(_, _, dom, body, _) => { |
| 491 | if expr_mentions_any_addr(dom, block_addrs) { |
| 492 | return Ok(true); |
| 493 | } |
| 494 | ty = body.clone(); |
| 495 | }, |
| 496 | _ => break, |
| 497 | } |
| 498 | } |
| 499 | } |
| 500 | Ok(false) |
| 501 | } |
| 502 | |
| 503 | /// Build the "flat" block for recursor generation, detecting nested occurrences. |
| 504 | /// |
| 505 | /// Mirrors lean4lean's `ElimNestedInductive.run`: walks constructor fields, |
| 506 | /// detects `ExtInd(block_member_ref)` patterns, and adds auxiliary entries |
| 507 | /// for each nested external inductive. Queue-based for transitive nesting. |
| 508 | fn build_flat_block( |
| 509 | &mut self, |
| 510 | block_inds: &[KId<M>], |
| 511 | n_rec_params: u64, |
| 512 | univ_offset: u64, |
| 513 | ) -> Result<Vec<FlatBlockMember<M>>, TcError<M>> { |
| 514 | let anon = || M::meta_field(ix_common::env::Name::anon()); |
| 515 | let all_block_addrs: Vec<Address> = |
| 516 | block_inds.iter().map(|id| id.addr.clone()).collect(); |
| 517 | |
| 518 | let mut flat: Vec<FlatBlockMember<M>> = Vec::new(); |
| 519 | // (ext_ind_addr, spec_params content hashes) for dedup. |
| 520 | // Uses [u8; 32] blake3 digest for structural equality. |
| 521 | let mut aux_seen: Vec<(Address, Vec<KExpr<M>>)> = Vec::new(); |
| 522 | |
| 523 | // Seed with original block inductives. |
| 524 | for ind_id in block_inds { |
| 525 | let (own_params, n_indices, ctors, lvls) = match self.get_const(ind_id)? { |
| 526 | KConst::Indc { params, indices, ctors, lvls, .. } => { |
| 527 | (params, indices, ctors.clone(), lvls) |
| 528 | }, |
| 529 | _ => continue, |
| 530 | }; |
| 531 | let ind_us = self.mk_ind_univs(lvls, univ_offset); |
| 532 | let spec_params: Vec<KExpr<M>> = (0..n_rec_params) |
| 533 | .map(|j| KExpr::var(n_rec_params - 1 - j, anon())) |
| 534 | .collect(); |
| 535 | flat.push(FlatBlockMember { |
| 536 | id: ind_id.clone(), |
| 537 | is_aux: false, |
| 538 | spec_params, |
| 539 | own_params, |
| 540 | n_indices, |
| 541 | ctors, |
| 542 | lvls, |
| 543 | ind_us: ind_us.clone(), |
| 544 | occurrence_us: ind_us, |
| 545 | }); |
| 546 | } |
| 547 | |
| 548 | // Queue-based processing: scan each member's ctors for nested occurrences. |
no test coverage detected