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

Function nat_env

crates/kernel/src/whnf.rs:3637–3803  ·  view source on GitHub ↗

Build a Nat env with Nat, Nat.zero, Nat.succ, Nat.rec, and Nat.sub. Nat.sub is defined as a primitive that the kernel's try_reduce_nat handles, but also has a delta-unfoldable body using Nat.rec (to test reduction order).

()

Source from the content-addressed store, hash-verified

3635 fn walk_literal_char_list(
3636 &mut self,
3637 list: &KExpr<M>,
3638 out: &mut String,
3639 ) -> Result<bool, TcError<M>> {
3640 let mut cur = list.clone();
3641 loop {
3642 let Some(w) = self.whnf_prim_arg(&cur)? else {
3643 return Ok(false);
3644 };
3645 let (head, args) = collect_app_spine(&w);
3646 let ExprData::Const(id, _, _) = head.data() else {
3647 return Ok(false);
3648 };
3649 // List.nil.{u} α
3650 if id.addr == self.prims.list_nil.addr {
3651 return Ok(args.len() == 1);
3652 }
3653 // List.cons.{u} α head tail
3654 if id.addr != self.prims.list_cons.addr || args.len() != 3 {
3655 return Ok(false);
3656 }
3657 let elem = match self.char_lit_value(&args[1]) {
3658 Some(c) => Some(c),
3659 None => match self.whnf_prim_arg(&args[1])? {
3660 Some(we) => self.char_lit_value(&we),
3661 None => None,
3662 },
3663 };
3664 let Some(c) = elem else {
3665 return Ok(false);
3666 };
3667 out.push(c);
3668 cur = args[2].clone();
3669 }
3670 }
3671
3672 /// Recognize the kernel's native char-value form: `Char.ofNat
3673 /// <Nat-lit>` where the literal is a valid Unicode scalar value.
3674 /// (`char::from_u32` rejects exactly the complement of
3675 /// `Nat.isValidChar`: surrogates and codepoints above `0x10FFFF`.)
3676 /// Purely syntactic — no reduction, and no spine allocation: this
3677 /// runs on every main-whnf-loop iteration.
3678 pub(super) fn char_lit_value(&self, e: &KExpr<M>) -> Option<char> {
3679 // Exactly `App(Const(Char.ofNat), Nat-lit)` — a nested App head
3680 // (over-application) or any other shape is not a char value.
3681 let ExprData::App(f, arg, _) = e.data() else {
3682 return None;
3683 };
3684 let ExprData::Const(id, _, _) = f.data() else {
3685 return None;
3686 };
3687 if id.addr != self.prims.char_of_nat.addr {
3688 return None;
3689 }
3690 let ExprData::Nat(n, _, _) = arg.data() else {
3691 return None;
3692 };
3693 let cp = n.to_u64()?;
3694 u32::try_from(cp).ok().and_then(char::from_u32)

Calls 13

sortFunction · 0.85
mk_idFunction · 0.70
sort1Function · 0.70
natFunction · 0.70
piFunction · 0.70
paramFunction · 0.70
appFunction · 0.70
varFunction · 0.70
cnstFunction · 0.70
lamFunction · 0.70
sort0Function · 0.70
insertMethod · 0.45