Recursively flatten a level into canonical form, accumulating into `acc`. `path` tracks the imax-conditioning chain, `k` is the accumulated succ offset.
( l: &KUniv<M>, path: &[u64], k: u64, acc: &mut NormLevel, )
| 365 | Err(pos) => { |
| 366 | let mut result = list.to_vec(); |
| 367 | result.insert(pos, a); |
| 368 | Some(result) |
| 369 | }, |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | /// Recursively flatten a level into canonical form, accumulating into `acc`. |
| 374 | /// `path` tracks the imax-conditioning chain, `k` is the accumulated succ offset. |
| 375 | fn normalize_aux<M: KernelMode>( |
| 376 | l: &KUniv<M>, |
| 377 | path: &[u64], |
| 378 | k: u64, |
| 379 | acc: &mut NormLevel, |
| 380 | ) { |
| 381 | match l.data() { |
| 382 | UnivData::Zero(_) => { |
| 383 | norm_add_const(acc, k, path); |
| 384 | }, |
| 385 | UnivData::Succ(inner, _) => { |
| 386 | normalize_aux(inner, path, k + 1, acc); |
| 387 | }, |
| 388 | UnivData::Max(a, b, _) => { |
| 389 | normalize_aux(a, path, k, acc); |
| 390 | normalize_aux(b, path, k, acc); |
| 391 | }, |
| 392 | UnivData::IMax(_, b, _) if b.is_zero() => { |
| 393 | norm_add_const(acc, k, path); |
| 394 | }, |
| 395 | UnivData::IMax(u, b, _) if matches!(b.data(), UnivData::Succ(..)) => { |
| 396 | if let UnivData::Succ(v, _) = b.data() { |
| 397 | normalize_aux(u, path, k, acc); |
| 398 | normalize_aux(v, path, k + 1, acc); |
| 399 | } |
| 400 | }, |
| 401 | UnivData::IMax(u, b, _) if matches!(b.data(), UnivData::Max(..)) => { |
| 402 | if let UnivData::Max(v, w, _) = b.data() { |
| 403 | normalize_imax_max(u, v, w, path, k, acc); |
| 404 | } |
| 405 | }, |
| 406 | UnivData::IMax(u, b, _) if matches!(b.data(), UnivData::IMax(..)) => { |
| 407 | if let UnivData::IMax(v, w, _) = b.data() { |
| 408 | normalize_imax_imax(u, v, w, path, k, acc); |
| 409 | } |
| 410 | }, |
| 411 | UnivData::IMax(u, b, _) if matches!(b.data(), UnivData::Param(..)) => { |
| 412 | if let UnivData::Param(idx, _, _) = b.data() { |
| 413 | let idx = *idx; |
| 414 | if let Some(new_path) = ordered_insert(idx, path) { |
| 415 | // When param(idx) = 0, imax(u, 0) = 0, contributing k from outer succs. |
| 416 | norm_add_const(acc, k, path); |
| 417 | norm_add_node(acc, idx, k, &new_path); |
| 418 | normalize_aux(u, &new_path, k, acc); |
| 419 | } else { |
| 420 | // Param(idx) is already in path (so we're in an `imax(u, v)` where |
| 421 | // v = Param(idx) and idx is fixed > 0 by the enclosing chain). |
| 422 | // The outer k Succ's still contribute when idx > 0, which it is |
| 423 | // along this path. Matches Lean4Lean's `acc.addVar v k path`. |
| 424 | if k != 0 { |
no test coverage detected