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

Method try_eta_struct

crates/kernel/src/def_eq.rs:1101–1227  ·  view source on GitHub ↗

Struct eta (lean4lean style): if `s` is a fully-applied constructor of a struct-like type, check `proj(i, t) ≡ s.args[params+i]` for each field. Tries `tryEtaStructCore(t, s)` — caller should try both directions.

(
    &mut self,
    t: &KExpr<M>,
    s: &KExpr<M>,
  )

Source from the content-addressed store, hash-verified

1099 return Ok(*s_val == str_val);
1100 }
1101 let expanded = self.str_lit_to_ctor_app(&str_val)?;
1102 self.is_def_eq(&expanded, s)
1103 }
1104
1105 /// Convert a string literal to constructor form:
1106 /// `"abc"` → `String.ofList (List.cons (Char.ofNat 97) (List.cons (Char.ofNat 98) (... List.nil)))`
1107 ///
1108 /// Uses `Char.ofNat` (not `Char.mk`) matching lean4lean/C++ kernel.
1109 /// Uses `String.ofList` (= `String.mk` in our env) matching lean4lean/C++ kernel.
1110 pub(super) fn str_lit_to_constructor(&mut self, s: &str) -> KExpr<M> {
1111 let char_const =
1112 self.intern(KExpr::cnst(self.prims.char_type.clone(), Box::new([])));
1113 let char_of_nat =
1114 self.intern(KExpr::cnst(self.prims.char_of_nat.clone(), Box::new([])));
1115 let string_mk =
1116 self.intern(KExpr::cnst(self.prims.string_of_list.clone(), Box::new([])));
1117
1118 // List.nil.{0} Char
1119 let list_nil_z = self.intern(KExpr::cnst(
1120 self.prims.list_nil.clone(),
1121 Box::new([KUniv::zero()]),
1122 ));
1123 let nil = self.intern(KExpr::app(list_nil_z, char_const.clone()));
1124
1125 // List.cons.{0} Char
1126 let list_cons_z = self.intern(KExpr::cnst(
1127 self.prims.list_cons.clone(),
1128 Box::new([KUniv::zero()]),
1129 ));
1130 let cons = self.intern(KExpr::app(list_cons_z, char_const));
1131
1132 // Build list right-to-left: foldr
1133 let mut list = nil;
1134 for c in s.chars().rev() {
1135 let nat_val = bignat::Nat::from(c as u64);
1136 let nat_addr = ix_common::address::Address::hash(&nat_val.to_le_bytes());
1137 let nat_lit = self.intern(KExpr::nat(nat_val, nat_addr));
1138 let char_val = self.intern(KExpr::app(char_of_nat.clone(), nat_lit));
1139 let partial = self.intern(KExpr::app(cons.clone(), char_val));
1140 list = self.intern(KExpr::app(partial, list));
1141 }
1142
1143 // String.mk list
1144 self.intern(KExpr::app(string_mk, list))
1145 }
1146
1147 /// String literal → structure-constructor application.
1148 ///
1149 /// `str_lit_to_constructor` produces `String.ofList [Char.ofNat c…]`;
1150 /// with the native collapse rule in `try_reduce_string`, a whnf of
1151 /// that application folds straight back into the `Str` literal. So
1152 /// callers that need the actual constructor form — iota majors,
1153 /// projections, literal-vs-structural def-eq — take one delta step
1154 /// past `String.ofList` here: in the compiled environment that
1155 /// exposes `String.ofByteArray (List.utf8Encode [chars]) proof`
1156 /// (fields stay lazy). In environments where the `String.ofList`
1157 /// address IS the constructor (List-Char-model test envs), the delta
1158 /// step is a no-op and the expansion is already ctor-headed.

Callers 1

is_def_eq_whnfMethod · 0.80

Calls 12

collect_app_spineFunction · 0.85
whnf_no_deltaMethod · 0.80
dump_eta_traceMethod · 0.80
with_infer_onlyMethod · 0.80
inferMethod · 0.80
eta_expansion_baseMethod · 0.80
internMethod · 0.80
cloneMethod · 0.45
dataMethod · 0.45
try_get_constMethod · 0.45
lenMethod · 0.45
is_def_eqMethod · 0.45

Tested by

no test coverage detected