Surface §5 geometry operators to compiled El

Register the six engram_geo_*_json operators in the compiler builtin_arity
table (bare heavy-runtime names + __ seed names, mirroring engram_activate_json)
and add the engram.el module wrappers, so a compiled El (CGI) program can call
them by name. The heavy-runtime C functions already existed (el_runtime.c:12287+,
declared el_runtime.h:627-632); this completes the EL call surface.

The shipped elc already emits a direct C call for these builtins (unknown
ident-calls pass through), so no self-host compiler fold — the memory-heavy,
drift-prone step — was required. Demonstrated end-to-end: a compiled geo_ops_demo.el
booted a copy of the store (13,036 nodes) and produced real subtract/distance JSON
on two real neighborhoods; test_geo_ops.c stays 20/20, ASan/UBSan clean.

Also brace the centroid_unit normalization if/else in engram_geometry.c to clear
the misleading-indentation warning (behavior-neutral).
This commit is contained in:
2026-08-13 00:50:56 -05:00
parent 5336cfe0a6
commit 85eee42106
4 changed files with 81 additions and 1 deletions
+12
View File
@@ -2633,6 +2633,12 @@ fn builtin_arity(name: String) -> Int {
if str_eq(name, "__engram_neighbors_filtered") { return 3 }
if str_eq(name, "__engram_activate") { return 2 }
if str_eq(name, "__engram_activate_json") { return 2 }
if str_eq(name, "__engram_geo_descriptor_json") { return 1 }
if str_eq(name, "__engram_geo_overlap_json") { return 2 }
if str_eq(name, "__engram_geo_subtract_json") { return 3 }
if str_eq(name, "__engram_geo_combine_json") { return 2 }
if str_eq(name, "__engram_geo_distance_json") { return 2 }
if str_eq(name, "__engram_geo_analogy_json") { return 2 }
if str_eq(name, "__engram_scan_nodes_json") { return 2 }
if str_eq(name, "__generate") { return 1 }
// Filesystem
@@ -2732,6 +2738,12 @@ fn builtin_arity(name: String) -> Int {
if str_eq(name, "engram_scan_nodes_json") { return 2 }
if str_eq(name, "engram_neighbors_json") { return 3 }
if str_eq(name, "engram_activate_json") { return 2 }
if str_eq(name, "engram_geo_descriptor_json") { return 1 }
if str_eq(name, "engram_geo_overlap_json") { return 2 }
if str_eq(name, "engram_geo_subtract_json") { return 3 }
if str_eq(name, "engram_geo_combine_json") { return 2 }
if str_eq(name, "engram_geo_distance_json") { return 2 }
if str_eq(name, "engram_geo_analogy_json") { return 2 }
if str_eq(name, "engram_stats_json") { return 0 }
// LLM
if str_eq(name, "llm_call") { return 2 }
+36
View File
@@ -6748,6 +6748,24 @@ el_val_t builtin_arity(el_val_t name) {
if (str_eq(name, EL_STR("__engram_activate_json"))) {
return 2;
}
if (str_eq(name, EL_STR("__engram_geo_descriptor_json"))) {
return 1;
}
if (str_eq(name, EL_STR("__engram_geo_overlap_json"))) {
return 2;
}
if (str_eq(name, EL_STR("__engram_geo_subtract_json"))) {
return 3;
}
if (str_eq(name, EL_STR("__engram_geo_combine_json"))) {
return 2;
}
if (str_eq(name, EL_STR("__engram_geo_distance_json"))) {
return 2;
}
if (str_eq(name, EL_STR("__engram_geo_analogy_json"))) {
return 2;
}
if (str_eq(name, EL_STR("__engram_scan_nodes_json"))) {
return 2;
}
@@ -6991,6 +7009,24 @@ el_val_t builtin_arity(el_val_t name) {
if (str_eq(name, EL_STR("engram_activate_json"))) {
return 2;
}
if (str_eq(name, EL_STR("engram_geo_descriptor_json"))) {
return 1;
}
if (str_eq(name, EL_STR("engram_geo_overlap_json"))) {
return 2;
}
if (str_eq(name, EL_STR("engram_geo_subtract_json"))) {
return 3;
}
if (str_eq(name, EL_STR("engram_geo_combine_json"))) {
return 2;
}
if (str_eq(name, EL_STR("engram_geo_distance_json"))) {
return 2;
}
if (str_eq(name, EL_STR("engram_geo_analogy_json"))) {
return 2;
}
if (str_eq(name, EL_STR("engram_stats_json"))) {
return 0;
}
+31
View File
@@ -119,6 +119,37 @@ fn engram_activate_json(query: String, limit: Int) -> String {
return __engram_activate_json(query, limit)
}
// --- Geometry operators (§5) ---
// Relational-neighborhood algebra over centered engram descriptors. Each takes
// comma-separated seed-id set(s); a centered neighborhood is grown from those
// seeds (ad-hoc NOCACHE path) and the operator's JSON result is returned.
// Delegates to the native __engram_geo_*_json seeds (el_seed.c); in the heavy
// engram runtime the same bare names resolve directly to el_runtime.c symbols.
fn engram_geo_descriptor_json(seeds: String) -> String {
return __engram_geo_descriptor_json(seeds)
}
fn engram_geo_overlap_json(a_seeds: String, b_seeds: String) -> String {
return __engram_geo_overlap_json(a_seeds, b_seeds)
}
fn engram_geo_subtract_json(a_seeds: String, b_seeds: String, mode: String) -> String {
return __engram_geo_subtract_json(a_seeds, b_seeds, mode)
}
fn engram_geo_combine_json(a_seeds: String, b_seeds: String) -> String {
return __engram_geo_combine_json(a_seeds, b_seeds)
}
fn engram_geo_distance_json(a_seeds: String, b_seeds: String) -> String {
return __engram_geo_distance_json(a_seeds, b_seeds)
}
fn engram_geo_analogy_json(a_seeds: String, b_seeds: String) -> String {
return __engram_geo_analogy_json(a_seeds, b_seeds)
}
// --- Generation ---
fn generate(form: String) -> String {
+2 -1
View File
@@ -1415,7 +1415,8 @@ int engram_geo_reify_index_finalize(GeoReifyIndex* ix){
r->centroid_unit=malloc((size_t)r->dim*sizeof(float));
if(r->centroid_unit){
double nrm=0; for(int d=0;d<r->dim;d++){ double v=(double)r->centroid_raw[d]-ix->mean[d]; r->centroid_unit[d]=(float)v; nrm+=v*v; }
nrm=sqrt(nrm); if(nrm>1e-12) for(int d=0;d<r->dim;d++) r->centroid_unit[d]=(float)(r->centroid_unit[d]/nrm);
nrm=sqrt(nrm);
if(nrm>1e-12){ for(int d=0;d<r->dim;d++) r->centroid_unit[d]=(float)(r->centroid_unit[d]/nrm); }
else { free(r->centroid_unit); r->centroid_unit=NULL; }
}
}