MCPcopy Create free account
hub / github.com/argumentcomputer/ix / try_proj_reduce

Method try_proj_reduce

crates/kernel/src/whnf.rs:1390–1443  ·  view source on GitHub ↗
(
    &mut self,
    id: &KId<M>,
    field: u64,
    wval: &KExpr<M>,
  )

Source from the content-addressed store, hash-verified

1388 log::info!(
1389 "[nat_iota_trace] rec={} major_bits={} spine={} major_idx={}",
1390 rec_id,
1391 val.0.bits(),
1392 spine.len(),
1393 recr.major_idx
1394 );
1395 }
1396 }
1397 major_was_nat_lit = true;
1398 major_whnf = self.nat_to_constructor(&val.clone());
1399 }
1400 if let Some(cleaned) = self.cleanup_nat_offset_major(&major_whnf)? {
1401 major_whnf = cleaned;
1402 }
1403 // String literal → constructor form (matching lean4lean
1404 // Reduce.lean:71 / C++ inductive.h:95). The expansion takes one
1405 // delta step past `String.ofList` (see `str_lit_to_ctor_app`) so the
1406 // native collapse rule in `try_reduce_string` can't fold it straight
1407 // back into the literal; constructor fields stay lazy.
1408 if let ExprData::Str(val, _, _) = major_whnf.data() {
1409 let val = val.clone();
1410 major_whnf = self.str_lit_to_ctor_app(&val)?;
1411 }
1412 // Native char values are kept stuck by whnf (they never unfold to
1413 // their `dite`-validity body on their own). A recursor that
1414 // genuinely scrutinizes a char pays for the structural expansion
1415 // here, once — exactly what pre-native reduction did on every whnf.
1416 // Cheap mode leaves the major stuck, as it did before the fast path
1417 // (`Char.ofNat` is a Defn head that cheap whnf never delta-unfolds).
1418 if !flags.cheap_rec
1419 && self.char_lit_value(&major_whnf).is_some()
1420 && let Some(unfolded) = self.delta_unfold_one(&major_whnf)?
1421 {
1422 major_whnf = self.whnf(&unfolded)?;
1423 }
1424
1425 // Check if major is a constructor application
1426 let (ctor_head, ctor_args) = collect_app_spine(&major_whnf);
1427 let is_ctor = match ctor_head.data() {
1428 ExprData::Const(id, _, _) => {
1429 matches!(self.try_get_const(id)?, Some(KConst::Ctor { .. }))
1430 },
1431 _ => false,
1432 };
1433
1434 // Diagnostic: when the major doesn't reduce to a ctor, iota is stuck.
1435 // Surface which recursor + major shape we got \u2014 the major's head
1436 // tells us which downstream reduction (delta, iota, nat, int) failed
1437 // to complete.
1438 if !is_ctor && let Some(filter) = IX_IOTA_STUCK.as_ref() {
1439 let rec_name = format!("{rec_id}");
1440 if filter.is_empty() || rec_name.contains(filter) {
1441 log::info!("[iota stuck] rec={rec_name}");
1442 log::info!("[iota stuck] major: {major}");
1443 log::info!("[iota stuck] major whnf: {major_whnf}");
1444 }
1445 }
1446

Callers 3

try_project_coreMethod · 0.80
try_proj_app_reduceMethod · 0.80

Calls 9

collect_app_spineFunction · 0.85
whnfMethod · 0.80
dump_proj_traceMethod · 0.80
dataMethod · 0.45
cloneMethod · 0.45
try_get_constMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected