ingest: name the inversion, and correct the worked example to decomposition
El SDK CI - dev / build-and-test (pull_request) Failing after 11m43s
El SDK CI - dev / build-and-test (pull_request) Failing after 11m43s
ingest.el's transduce() was renamed to transduce_manifold() earlier the same day on the reasoning that it 'was never signal->geometry -- it chunks already-extracted content and PACKS it into a node+edge manifold, one layer up, and it had taken the name that belongs to the primitive underneath it.' That reasoning was backwards. Producing a node+edge manifold is not a layer above transduction, it IS transduction. Signal -> one vector is the operation underneath, and its name is geometry. The layer doing it right was renamed out of the way so the layer doing it wrong could have the name. With the primitive corrected to return a Manifold, the two layers do the same kind of thing and the inversion dissolves. What is left is a real distinction about MODALITY, not layering: transduce() dispatches to a realizer that knows its modality and can name its components; transduce_bytes() is the opaque-bytes realizer, the decomposition available to a reader that knows nothing about what it is reading. It still yields components and relations, which is why it is transduction and not packing -- it just cuts on byte boundaries, so its components are positional rather than meaningful. That is a limitation of this realizer, not the definition of the operation. Renamed by modality rather than demoted by layer. A distinct symbol is still mechanically required: reusing transduce here is a conflicting-types error the moment ingest.c links el_runtime.c. lang/examples/transduce.el asserted #144's contract and would now fail, so it is replaced by the decomposition worked example: transduce a chord, persist the five components and six relations as real nodes and edges, read each part's geometry back off its own node, and ground one part while its sibling is demonstrably untouched.
This commit is contained in:
+54
-25
@@ -13,7 +13,7 @@
|
|||||||
// relations add edges. Every node enters with PROVENANCE + grounding-level
|
// relations add edges. Every node enters with PROVENANCE + grounding-level
|
||||||
// + stewardship class from the moment of entry.
|
// + stewardship class from the moment of entry.
|
||||||
//
|
//
|
||||||
// transduce_manifold() is THE single mechanism — one function, polymorphic, with no
|
// transduce_bytes() is THE single mechanism — one function, polymorphic, with no
|
||||||
// content-type branch inside it. It does not ask whether a payload is
|
// content-type branch inside it. It does not ask whether a payload is
|
||||||
// prose, structured data, or raw/opaque bytes (audio, or anything else);
|
// prose, structured data, or raw/opaque bytes (audio, or anything else);
|
||||||
// it runs one boundary-scan-with-fixed-window-fallback chunking algorithm
|
// it runs one boundary-scan-with-fixed-window-fallback chunking algorithm
|
||||||
@@ -401,25 +401,54 @@ fn head80(s: String) -> String {
|
|||||||
// truncates at the first embedded NUL, which is routine in real binary
|
// truncates at the first embedded NUL, which is routine in real binary
|
||||||
// bytes) is a MECHANICAL fidelity concern that belongs to whatever produced
|
// bytes) is a MECHANICAL fidelity concern that belongs to whatever produced
|
||||||
// `source` (see ingest_file's file_source_string below) — not a
|
// `source` (see ingest_file's file_source_string below) — not a
|
||||||
// content-type judgment made in here. transduce_manifold() never learns whether a
|
// content-type judgment made in here. transduce_bytes() never learns whether a
|
||||||
// chunk is plain text or a base64-encoded raw-byte window; every chunk is
|
// chunk is plain text or a base64-encoded raw-byte window; every chunk is
|
||||||
// handled identically either way.
|
// handled identically either way.
|
||||||
// RENAMED transduce -> transduce_manifold (2026-08-16). Two reasons, and the
|
// NAMING, CORRECTED 2026-08-16 (second pass). This function was renamed
|
||||||
// first is not the interesting one:
|
// `transduce` -> `transduce_bytes` earlier the same day, on the reasoning
|
||||||
|
// that it "was never signal->geometry — it chunks already-extracted content
|
||||||
|
// and PACKS it into a node+edge manifold, one layer up, and it had taken the
|
||||||
|
// name that belongs to the primitive underneath it."
|
||||||
//
|
//
|
||||||
// 1. Mechanical: `transduce` is now a LANGUAGE primitive in el_runtime.h
|
// THAT REASONING WAS BACKWARDS, and it is worth recording why rather than
|
||||||
// (transduce(signal, modality) -> Geometry). Every El `fn name(...)`
|
// quietly re-renaming. Producing a node+edge manifold is not a layer above
|
||||||
// compiles to a global C symbol with that exact name, so keeping this
|
// transduction — it IS transduction. Transduction is not conversion. When you
|
||||||
// name here is a hard `conflicting types for 'transduce'` compile error
|
// take in music you do not store the song as one discrete geometry; you break
|
||||||
// the moment ingest.c links el_runtime.c. Measured, not anticipated.
|
// it into its component parts and store the geometry of each along with the
|
||||||
|
// relations between them. The song is the structure of those relations.
|
||||||
|
// Signal -> one vector is the operation UNDERNEATH transduction, and its name
|
||||||
|
// is encoding, or geometry. So the layer that was doing it right got renamed
|
||||||
|
// out of the way so the layer doing it wrong could have the name.
|
||||||
//
|
//
|
||||||
// 2. Actual: this function was never signal->geometry. It chunks already-
|
// The primitive has since been corrected: `transduce(signal, modality)` now
|
||||||
// extracted content and PACKS it into a node+edge manifold — a real
|
// returns a Manifold — components plus relations — not a Geometry
|
||||||
// operation, but one layer up, and it had taken the name that belongs to
|
// (el_runtime.c, "Manifold"). The two layers are therefore doing the SAME KIND
|
||||||
// the primitive underneath it. `transduce` is where a signal becomes
|
// of thing, and the inversion dissolves rather than needing to be re-argued.
|
||||||
// geometry; `transduce_manifold` is where extracted content becomes
|
//
|
||||||
// structure. Nothing about this function's behaviour changed.
|
// What is left is a real distinction, and it is about MODALITY, not layering:
|
||||||
fn transduce_manifold(nodes: [String], edges: [String], source: String,
|
//
|
||||||
|
// * `transduce(signal, modality)` dispatches to a realizer that KNOWS the
|
||||||
|
// modality and can name its components — for audio: pitch, interval,
|
||||||
|
// rhythm, harmonic function.
|
||||||
|
// * `transduce_bytes` below is the OPAQUE-BYTES realizer: the decomposition
|
||||||
|
// available to a reader that knows nothing about what it is reading. It
|
||||||
|
// still yields components and relations (chunk nodes; contains / precedes
|
||||||
|
// / section_of edges), which is why it is transduction and not packing. It
|
||||||
|
// just cuts on the only structure visible without understanding — byte
|
||||||
|
// boundaries — so its components are positional rather than meaningful.
|
||||||
|
// That is a LIMITATION of this realizer, not the definition of the
|
||||||
|
// operation.
|
||||||
|
//
|
||||||
|
// The name is suffixed by its modality, not demoted to a lesser layer. Keeping
|
||||||
|
// a distinct symbol is also still mechanically required: every El `fn name`
|
||||||
|
// compiles to a global C symbol, so reusing `transduce` here is a hard
|
||||||
|
// `conflicting types` error the moment ingest.c links el_runtime.c.
|
||||||
|
//
|
||||||
|
// WHERE THIS SHOULD GO: this function should become a registered realizer
|
||||||
|
// returning a real Manifold, so ingest rides the same primitive as every other
|
||||||
|
// modality instead of carrying a parallel implementation. Not done here.
|
||||||
|
// Nothing about this function's behaviour changed in this pass.
|
||||||
|
fn transduce_bytes(nodes: [String], edges: [String], source: String,
|
||||||
prov: String, ground: String, steward: String,
|
prov: String, ground: String, steward: String,
|
||||||
root_lid: String, root_title: String) -> [String] {
|
root_lid: String, root_title: String) -> [String] {
|
||||||
let tagbase: String = "prov:" + prov + " ground:" + ground + " steward:" + steward
|
let tagbase: String = "prov:" + prov + " ground:" + ground + " steward:" + steward
|
||||||
@@ -546,8 +575,8 @@ fn default_steward() -> String {
|
|||||||
// trustworthy verbatim. When they don't (silent truncation happened),
|
// trustworthy verbatim. When they don't (silent truncation happened),
|
||||||
// rebuild the payload as base64-encoded fixed-size windows read directly
|
// rebuild the payload as base64-encoded fixed-size windows read directly
|
||||||
// off disk (fs_read_b64_chunk — binary-safe in C), joined with the same
|
// off disk (fs_read_b64_chunk — binary-safe in C), joined with the same
|
||||||
// "\n\n" boundary marker transduce_manifold()'s generic scan already looks for, so
|
// "\n\n" boundary marker transduce_bytes()'s generic scan already looks for, so
|
||||||
// transduce_manifold() sees one ordinary boundary-delimited payload and runs its one
|
// transduce_bytes() sees one ordinary boundary-delimited payload and runs its one
|
||||||
// algorithm on it exactly as it would on prose — it never learns that a
|
// algorithm on it exactly as it would on prose — it never learns that a
|
||||||
// fidelity problem occurred upstream, let alone why.
|
// fidelity problem occurred upstream, let alone why.
|
||||||
fn file_source_string(path: String, text: String, real_size: Int) -> String {
|
fn file_source_string(path: String, text: String, real_size: Int) -> String {
|
||||||
@@ -556,7 +585,7 @@ fn file_source_string(path: String, text: String, real_size: Int) -> String {
|
|||||||
// 3072 raw bytes -> 4096 base64 chars (3 divides evenly into base64's
|
// 3072 raw bytes -> 4096 base64 chars (3 divides evenly into base64's
|
||||||
// 3-byte/4-char ratio); keeps each resulting node's content a clean,
|
// 3-byte/4-char ratio); keeps each resulting node's content a clean,
|
||||||
// bounded, low-kilobytes unit, same order of magnitude as the fixed
|
// bounded, low-kilobytes unit, same order of magnitude as the fixed
|
||||||
// fallback window in transduce_manifold() itself.
|
// fallback window in transduce_bytes() itself.
|
||||||
let win: Int = 3072
|
let win: Int = 3072
|
||||||
let out: String = ""
|
let out: String = ""
|
||||||
let off: Int = 0
|
let off: Int = 0
|
||||||
@@ -576,7 +605,7 @@ fn file_source_string(path: String, text: String, real_size: Int) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ingest one file -> report JSON. Uniform for every file regardless of
|
// ingest one file -> report JSON. Uniform for every file regardless of
|
||||||
// extension or content — transduce_manifold() decides nothing about content-type, so
|
// extension or content — transduce_bytes() decides nothing about content-type, so
|
||||||
// neither does this function; it only decides whether the raw bytes made it
|
// neither does this function; it only decides whether the raw bytes made it
|
||||||
// through the read intact (file_source_string), which is a fidelity
|
// through the read intact (file_source_string), which is a fidelity
|
||||||
// question, not a format one.
|
// question, not a format one.
|
||||||
@@ -588,14 +617,14 @@ fn ingest_file(path: String) -> String {
|
|||||||
return "{\"error\":\"empty or unreadable\",\"path\":" + j_q(path) + "}"
|
return "{\"error\":\"empty or unreadable\",\"path\":" + j_q(path) + "}"
|
||||||
}
|
}
|
||||||
let prov: String = "file:" + path
|
let prov: String = "file:" + path
|
||||||
let packed: [String] = transduce_manifold(el_list_empty(), el_list_empty(),
|
let packed: [String] = transduce_bytes(el_list_empty(), el_list_empty(),
|
||||||
source, prov, default_ground(), default_steward(),
|
source, prov, default_ground(), default_steward(),
|
||||||
"doc:" + basename(path), basename(path))
|
"doc:" + basename(path), basename(path))
|
||||||
return merge_packed(packed)
|
return merge_packed(packed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ingest a directory: walk one level, ingest every file found, aggregate.
|
// ingest a directory: walk one level, ingest every file found, aggregate.
|
||||||
// No extension filter — transduce_manifold() handles any payload uniformly now, so
|
// No extension filter — transduce_bytes() handles any payload uniformly now, so
|
||||||
// there is no content-type gate at the directory boundary either.
|
// there is no content-type gate at the directory boundary either.
|
||||||
fn ingest_dir(path: String) -> String {
|
fn ingest_dir(path: String) -> String {
|
||||||
let entries: [String] = fs_list(path)
|
let entries: [String] = fs_list(path)
|
||||||
@@ -630,7 +659,7 @@ fn ingest_dir(path: String) -> String {
|
|||||||
fn ingest_url(url: String) -> String {
|
fn ingest_url(url: String) -> String {
|
||||||
let body: String = http_get(url)
|
let body: String = http_get(url)
|
||||||
if str_eq(body, "") { return "{\"error\":\"empty fetch\",\"url\":" + j_q(url) + "}" }
|
if str_eq(body, "") { return "{\"error\":\"empty fetch\",\"url\":" + j_q(url) + "}" }
|
||||||
let packed: [String] = transduce_manifold(el_list_empty(), el_list_empty(),
|
let packed: [String] = transduce_bytes(el_list_empty(), el_list_empty(),
|
||||||
body, "url:" + url, "extracted", "public-web",
|
body, "url:" + url, "extracted", "public-web",
|
||||||
"url:" + url, url)
|
"url:" + url, url)
|
||||||
return merge_packed(packed)
|
return merge_packed(packed)
|
||||||
@@ -645,7 +674,7 @@ fn ingest_llm(query: String) -> String {
|
|||||||
let resp: String = http_post_json("http://127.0.0.1:11434/api/generate", body)
|
let resp: String = http_post_json("http://127.0.0.1:11434/api/generate", body)
|
||||||
let answer: String = json_get_string(resp, "response")
|
let answer: String = json_get_string(resp, "response")
|
||||||
if str_eq(answer, "") { return "{\"error\":\"no model response\"}" }
|
if str_eq(answer, "") { return "{\"error\":\"no model response\"}" }
|
||||||
let packed: [String] = transduce_manifold(el_list_empty(), el_list_empty(),
|
let packed: [String] = transduce_bytes(el_list_empty(), el_list_empty(),
|
||||||
answer, "llm:" + model + ":" + query, "candidate-provisional", "guide-provisional",
|
answer, "llm:" + model + ":" + query, "candidate-provisional", "guide-provisional",
|
||||||
"llm:" + query, "guide answer: " + query)
|
"llm:" + query, "guide answer: " + query)
|
||||||
return merge_packed(packed)
|
return merge_packed(packed)
|
||||||
@@ -697,7 +726,7 @@ fn ingest_stream(path: String) -> String {
|
|||||||
// It is NOT a content-type flag: it says nothing about what's inside the
|
// It is NOT a content-type flag: it says nothing about what's inside the
|
||||||
// bytes once fetched, and none of the five ingest_* functions it selects
|
// bytes once fetched, and none of the five ingest_* functions it selects
|
||||||
// among interpret their payload differently by content shape anymore —
|
// among interpret their payload differently by content shape anymore —
|
||||||
// they all hand off to the single, format-agnostic transduce_manifold(). The old
|
// they all hand off to the single, format-agnostic transduce_bytes(). The old
|
||||||
// "structured" value (a caller-declared alias for "file", used only to hint
|
// "structured" value (a caller-declared alias for "file", used only to hint
|
||||||
// the now-removed JSON-vs-prose branch) is gone along with that branch.
|
// the now-removed JSON-vs-prose branch) is gone along with that branch.
|
||||||
let kind: String = env("INGEST_KIND")
|
let kind: String = env("INGEST_KIND")
|
||||||
|
|||||||
+182
-167
@@ -1,67 +1,33 @@
|
|||||||
// transduce.el — geometry as a first-class El value, and a realizer written
|
// transduce.el — transduction decomposes a signal into components and the
|
||||||
// in El. Runnable: this is the worked example for the transduce surface, and
|
// relations between them. Runnable: this is the worked example for the
|
||||||
// it doubles as an executable proof because it checks every claim it makes.
|
// transduce surface, and it exits non-zero if any claim in it stops being true.
|
||||||
//
|
//
|
||||||
// elc lang/examples/transduce.el > transduce.c
|
// elc lang/examples/transduce.el > transduce.c
|
||||||
// cc -std=c11 -O2 -I lang/runtime -o transduce transduce.c \
|
// cc -std=c11 -O2 -I lang/runtime -o transduce transduce.c \
|
||||||
// lang/runtime/el_runtime.c lang/runtime/el_seed.c \
|
// lang/runtime/el_runtime.c lang/runtime/el_seed.c \
|
||||||
// lang/runtime/engram_*.c -lcurl -lpthread -lm
|
// lang/runtime/engram_store.c lang/runtime/engram_vindex.c \
|
||||||
|
// lang/runtime/engram_cognition.c lang/runtime/engram_geometry.c \
|
||||||
|
// lang/runtime/engram_reason.c lang/runtime/engram_verify.c \
|
||||||
|
// -lcurl -lpthread -lm
|
||||||
// ./transduce # exits 0 only if every check passes
|
// ./transduce # exits 0 only if every check passes
|
||||||
//
|
//
|
||||||
// (A `test "..."` form of the same checks lives in
|
// It writes to an IN-MEMORY engram (leave ENGRAM_STORE unset) and contacts no
|
||||||
// lang/tests/native/test_transduce.el, for when the native harness is
|
// server. The same claims are asserted by the native harness in
|
||||||
// repaired — the shipped elc currently emits calls to __el_reg_count and
|
// lang/tests/native/test_transduce.el.
|
||||||
// friends without emitting their definitions, which breaks every native test
|
|
||||||
// equally, test_math.el included. Verified 2026-08-16, unrelated to this work.)
|
|
||||||
//
|
//
|
||||||
// WHY THIS EXISTS. Until 2026-08-16 no El ingest path could carry a vector:
|
// WHAT CHANGED, AND WHY IT MATTERS. #144 shipped
|
||||||
// nodes took text, and geometry was DERIVED from that text. Text was the
|
// `transduce(signal, modality) -> Geometry`: one vector per signal. That made
|
||||||
// mandatory entry medium, so any non-text modality had to be DESCRIBED in
|
// transduction a CONVERSION — take a thing, encode it, store a position — and
|
||||||
// prose first and the geometry we reasoned over was the geometry OF THE
|
// what a conversion returns is a fingerprint. A fingerprint can be matched and
|
||||||
// DESCRIPTION, not of the signal. Two things fix that, and both are shown
|
// ranked, and that is all it can ever do. It cannot be decomposed, cannot have
|
||||||
// below: geometry is a VALUE that carries its own width, and a REALIZER is an
|
// one part grounded while another is not, and cannot be contradicted in one
|
||||||
// ordinary El function — so admitting a new modality never requires a runtime
|
// part while holding in another, because it has no parts.
|
||||||
// patch.
|
|
||||||
//
|
//
|
||||||
// COMPARISON DISCIPLINE (measured, not stylistic): elc lowers `a == b`
|
// A song is not a point. It decomposes into pitch, interval, rhythm, harmonic
|
||||||
// numerically only when both operand NAMES are in the per-function int-name
|
// function — components, each with its own geometry, plus the relations among
|
||||||
// set that `let x: Int` populates. A bare `f(x) == 0` is not a registered
|
// them. THE SONG IS THE STRUCTURE OF THE RELATIONS. transduce now returns a
|
||||||
// name and lowers to str_eq — strcmp on two integers as pointers. `<` and `>`
|
// Manifold, and a realizer's job is to say what its modality's components ARE.
|
||||||
// lower directly with no inference, so truthiness is written `> 0` / `< 1`.
|
|
||||||
|
|
||||||
// ── A realizer, written entirely in El ──────────────────────────────────────
|
|
||||||
// Not in the runtime. Not known to the compiler. Registered by NAME and
|
|
||||||
// dispatched to through transduce(). That is the whole claim.
|
|
||||||
fn tone_realizer(signal: String) -> Geometry {
|
|
||||||
let g: Geometry = geometry_new(4)
|
|
||||||
let n: Int = str_len(signal)
|
|
||||||
let a: Int = geometry_set(g, 0, int_to_float(n))
|
|
||||||
let b: Int = geometry_set(g, 1, int_to_float(n * 2))
|
|
||||||
let c: Int = geometry_set(g, 2, int_to_float(n * 3))
|
|
||||||
let d: Int = geometry_set(g, 3, int_to_float(n * 4))
|
|
||||||
g
|
|
||||||
}
|
|
||||||
|
|
||||||
// A second modality, to show the registry keys on modality rather than just
|
|
||||||
// returning whatever was registered last.
|
|
||||||
fn pulse_realizer(signal: String) -> Geometry {
|
|
||||||
let g: Geometry = geometry_new(2)
|
|
||||||
let a: Int = geometry_set(g, 0, 1.0)
|
|
||||||
let b: Int = geometry_set(g, 1, 0.0)
|
|
||||||
g
|
|
||||||
}
|
|
||||||
|
|
||||||
// A deliberately BROKEN realizer: returns something that is not a Geometry.
|
|
||||||
fn bogus_realizer(signal: String) -> Geometry {
|
|
||||||
return 12345
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fails FAST rather than accumulating a count, for a measured reason: a first
|
|
||||||
// cut wrote `let fails: Int = fails + check(...)` and `+` lowered to STRING
|
|
||||||
// CONCAT, because elc dispatches `+` on whether both operands are known-Int and
|
|
||||||
// a user-defined fn call is not — so the counter printed 4343632752, a pointer.
|
|
||||||
// Nothing was wrong with the checks; the tally was lying. Exiting at the first
|
|
||||||
// failure needs no arithmetic at all, so there is nothing left to get wrong.
|
|
||||||
fn check(ok: Int, label: String) -> Int {
|
fn check(ok: Int, label: String) -> Int {
|
||||||
if ok > 0 {
|
if ok > 0 {
|
||||||
println(" ok " + label)
|
println(" ok " + label)
|
||||||
@@ -84,128 +50,177 @@ fn eq_int(a: Int, b: Int) -> Int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── A DECOMPOSING realizer, written entirely in El ──────────────────────────
|
||||||
|
// "tone" signals are note letters, e.g. "CEG". This does NOT return one vector
|
||||||
|
// for the chord. It returns the PARTS — one component per note, one per
|
||||||
|
// interval between adjacent notes — and the relations that make those parts a
|
||||||
|
// chord rather than an unordered bag of pitches.
|
||||||
|
//
|
||||||
|
// The interval is deliberately a COMPONENT, not a field on a note. An interval
|
||||||
|
// is a thing with its own geometry belonging to neither endpoint; modelling it
|
||||||
|
// as an attribute of one of them is the same collapse, one level down.
|
||||||
|
fn tone_realizer(signal: String) -> Manifold {
|
||||||
|
let m: Manifold = manifold_new()
|
||||||
|
let n: Int = str_len(signal)
|
||||||
|
let i: Int = 0
|
||||||
|
while i < n {
|
||||||
|
let code: Int = str_char_code(signal, i)
|
||||||
|
let g: Geometry = geometry_new(2)
|
||||||
|
let s0: Int = geometry_set(g, 0, int_to_float(code))
|
||||||
|
let s1: Int = geometry_set(g, 1, int_to_float(i))
|
||||||
|
let idx: Int = manifold_add(m, "note:" + int_to_str(i), "pitch", g)
|
||||||
|
let f: Int = geometry_free(g)
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
|
let j: Int = 1
|
||||||
|
while j < n {
|
||||||
|
let a: Int = str_char_code(signal, j - 1)
|
||||||
|
let b: Int = str_char_code(signal, j)
|
||||||
|
let lo: String = "note:" + int_to_str(j - 1)
|
||||||
|
let hi: String = "note:" + int_to_str(j)
|
||||||
|
let key: String = "interval:" + int_to_str(j - 1) + "-" + int_to_str(j)
|
||||||
|
let g: Geometry = geometry_new(1)
|
||||||
|
let s: Int = geometry_set(g, 0, int_to_float(b - a))
|
||||||
|
let idx: Int = manifold_add(m, key, "interval", g)
|
||||||
|
let f: Int = geometry_free(g)
|
||||||
|
let e1: Int = manifold_relate(m, key, "spans", lo, 0.9)
|
||||||
|
let e2: Int = manifold_relate(m, key, "spans", hi, 0.9)
|
||||||
|
let e3: Int = manifold_relate(m, lo, "sounds_before", hi, 0.8)
|
||||||
|
j = j + 1
|
||||||
|
}
|
||||||
|
m
|
||||||
|
}
|
||||||
|
|
||||||
|
// #144's contract, kept as a control: one vector for the whole signal.
|
||||||
|
fn fingerprint_realizer(signal: String) -> Geometry {
|
||||||
|
let g: Geometry = geometry_new(4)
|
||||||
|
let n: Int = str_len(signal)
|
||||||
|
let a: Int = geometry_set(g, 0, int_to_float(n))
|
||||||
|
g
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> Void {
|
fn main() -> Void {
|
||||||
println("geometry is a value that carries its own width")
|
|
||||||
let g8: Geometry = geometry_new(8)
|
|
||||||
let _c: Int = check(geometry_is(g8), "geometry_new returns a live Geometry")
|
|
||||||
let d8: Int = geometry_dim(g8)
|
|
||||||
let _c: Int = check(eq_int(d8, 8), "a Geometry carries its own width (8)")
|
|
||||||
let _c: Int = check(geometry_free(g8), "geometry_free reports what it did")
|
|
||||||
|
|
||||||
println("nonsense is refused — with no arbitrary max-dim bound")
|
|
||||||
// #141 needed `dim <= 8192` only to bound an allocation sized from a
|
|
||||||
// caller's CLAIM about a string's length. A value that carries its own
|
|
||||||
// width has nothing left to validate.
|
|
||||||
let z: Geometry = geometry_new(0)
|
|
||||||
let zi: Int = geometry_is(z)
|
|
||||||
let _c: Int = check(1 - zi, "dim 0 is not a geometry")
|
|
||||||
let ng: Geometry = geometry_new(-4)
|
|
||||||
let ngi: Int = geometry_is(ng)
|
|
||||||
let _c: Int = check(1 - ngi, "negative dim is not a geometry")
|
|
||||||
let nd: Int = geometry_dim(0)
|
|
||||||
let _c: Int = check(1 - nd, "geometry_dim of a non-geometry is 0, not a crash")
|
|
||||||
let nf: Int = geometry_free(0)
|
|
||||||
let _c: Int = check(1 - nf, "geometry_free of a non-geometry is a no-op")
|
|
||||||
|
|
||||||
println("components round-trip, and out-of-range is refused")
|
|
||||||
let g3: Geometry = geometry_new(3)
|
|
||||||
let s0: Int = geometry_set(g3, 0, 1.5)
|
|
||||||
let s1: Int = geometry_set(g3, 1, -2.5)
|
|
||||||
let _c: Int = check(s0, "set in range succeeds")
|
|
||||||
let oob: Int = geometry_set(g3, 3, 9.0)
|
|
||||||
let _c: Int = check(1 - oob, "set out of range is refused, not silently dropped")
|
|
||||||
let _c: Int = check(near(geometry_get(g3, 0), 1.5), "component 0 round-trips")
|
|
||||||
let _c: Int = check(near(geometry_get(g3, 1), -2.5), "component 1 round-trips (negative)")
|
|
||||||
let ff3: Int = geometry_free(g3)
|
|
||||||
|
|
||||||
println("hex is an EDGE adapter, and derives its own width")
|
|
||||||
// little-endian float32: 1.0 = 0000803f, 2.0 = 00000040
|
|
||||||
let gh: Geometry = geometry_from_f32le_hex("0000803f00000040")
|
|
||||||
let _c: Int = check(geometry_is(gh), "valid hex decodes to a Geometry")
|
|
||||||
let dh: Int = geometry_dim(gh)
|
|
||||||
let _c: Int = check(eq_int(dh, 2), "width DERIVED from input, never supplied")
|
|
||||||
let _c: Int = check(near(geometry_get(gh, 0), 1.0), "first component decoded")
|
|
||||||
let _c: Int = check(near(geometry_get(gh, 1), 2.0), "second component decoded")
|
|
||||||
let back: String = geometry_to_f32le_hex(gh)
|
|
||||||
let _c: Int = check(str_eq(back, "0000803f00000040"), "hex round-trips exactly")
|
|
||||||
let ffh: Int = geometry_free(gh)
|
|
||||||
|
|
||||||
println("malformed hex is refused")
|
|
||||||
let he: Geometry = geometry_from_f32le_hex("")
|
|
||||||
let hei: Int = geometry_is(he)
|
|
||||||
let _c: Int = check(1 - hei, "empty hex is not a geometry")
|
|
||||||
let hr: Geometry = geometry_from_f32le_hex("0000803f0000")
|
|
||||||
let hri: Int = geometry_is(hr)
|
|
||||||
let _c: Int = check(1 - hri, "length not a multiple of 8 is refused")
|
|
||||||
let hn: Geometry = geometry_from_f32le_hex("zzzzzzzz")
|
|
||||||
let hni: Int = geometry_is(hn)
|
|
||||||
let _c: Int = check(1 - hni, "non-hex characters are refused")
|
|
||||||
|
|
||||||
println("a realizer declared in El is a first-class realizer")
|
println("a realizer declared in El is a first-class realizer")
|
||||||
let reg: Int = realizer_register("tone", "tone_realizer")
|
let reg: Int = realizer_register("tone", "tone_realizer")
|
||||||
let _c: Int = check(reg, "an El fn registers as a realizer BY NAME")
|
let _c: Int = check(reg, "an El fn registers as a realizer by name")
|
||||||
let _c: Int = check(realizer_has("tone"), "the modality now has an organ")
|
let _c: Int = check(realizer_has("tone"), "the modality now has an organ")
|
||||||
let gt: Geometry = transduce("aaa", "tone")
|
|
||||||
let _c: Int = check(geometry_is(gt), "transduce returns real geometry")
|
|
||||||
let dt: Int = geometry_dim(gt)
|
|
||||||
let _c: Int = check(eq_int(dt, 4), "the El realizer determined the width, not the runtime")
|
|
||||||
// str_len("aaa") == 3, so component 0 must be 3.0 — proof the signal
|
|
||||||
// actually reached the El function rather than a stub answering for it.
|
|
||||||
let _c: Int = check(near(geometry_get(gt, 0), 3.0), "the signal REACHED the El realizer")
|
|
||||||
let fft: Int = geometry_free(gt)
|
|
||||||
|
|
||||||
println("distinct signals transduce to distinct geometry")
|
println("transduction decomposes a signal into parts")
|
||||||
let g1: Geometry = transduce("aa", "tone")
|
let m: Manifold = transduce("CEG", "tone")
|
||||||
let g2: Geometry = transduce("aaaaa", "tone")
|
let _c: Int = check(manifold_is(m), "transduce returns a real Manifold")
|
||||||
let a1: Float = geometry_get(g1, 0)
|
let sz: Int = manifold_size(m)
|
||||||
let a2: Float = geometry_get(g2, 0)
|
let _c: Int = check(eq_int(sz, 5), "three notes and two intervals are five parts")
|
||||||
// 5 - 2 = 3. If transduction were a stub these would be equal.
|
let rc: Int = manifold_rel_count(m)
|
||||||
let _c: Int = check(near(a2 - a1, 3.0), "different signals produce different geometry")
|
let _c: Int = check(eq_int(rc, 6), "and they stand in six stated relations")
|
||||||
let ff1: Int = geometry_free(g1)
|
|
||||||
let ff2: Int = geometry_free(g2)
|
|
||||||
|
|
||||||
println("the registry keys on modality")
|
println("every part is addressable BY KEY, which is what survives persistence")
|
||||||
let r2: Int = realizer_register("pulse", "pulse_realizer")
|
let i_c: Int = manifold_index_of(m, "note:0")
|
||||||
let _c: Int = check(r2, "a second modality registers independently")
|
let _c: Int = check(1 - eq_int(i_c, -1), "the first note is addressable on its own")
|
||||||
let mt: Geometry = transduce("aaa", "tone")
|
let i_iv: Int = manifold_index_of(m, "interval:0-1")
|
||||||
let mp: Geometry = transduce("aaa", "pulse")
|
let _c: Int = check(1 - eq_int(i_iv, -1), "so is the interval between the first two")
|
||||||
let mdt: Int = geometry_dim(mt)
|
let miss: Int = manifold_index_of(m, "never_added")
|
||||||
let mdp: Int = geometry_dim(mp)
|
let _c: Int = check(eq_int(miss, -1), "an unknown key is -1, not component 0")
|
||||||
let _c: Int = check(eq_int(mdt, 4), "tone still routes to its own realizer")
|
|
||||||
let _c: Int = check(eq_int(mdp, 2), "pulse routes to a different realizer")
|
|
||||||
let ffm1: Int = geometry_free(mt)
|
|
||||||
let ffm2: Int = geometry_free(mp)
|
|
||||||
|
|
||||||
println("no organ is reported as no organ")
|
println("parts carry their own geometry, and may differ in width")
|
||||||
// A modality with no realizer must transduce to NOTHING. It must never
|
let gn: Geometry = manifold_geometry(m, i_c)
|
||||||
// fall back to embedding a description of the signal and calling that
|
let _c: Int = check(eq_int(geometry_dim(gn), 2), "a note component is 2 wide")
|
||||||
// perception — that silent substitution is the defect this all exists to end.
|
let _c: Int = check(near(geometry_get(gn, 0), 67.0), "and it is C — the signal reached the realizer")
|
||||||
let eh: Int = realizer_has("echolocation")
|
let gi: Geometry = manifold_geometry(m, i_iv)
|
||||||
let _c: Int = check(1 - eh, "unregistered modality has no organ")
|
let _c: Int = check(eq_int(geometry_dim(gi), 1), "an interval component is 1 wide")
|
||||||
let ge: Geometry = transduce("anything", "echolocation")
|
// A single vector per signal cannot represent parts of unequal width at all.
|
||||||
let gei: Int = geometry_is(ge)
|
let _c: Int = check(near(geometry_get(gi, 0), 2.0), "C to E is two semitones")
|
||||||
let _c: Int = check(1 - gei, "no realizer means NO geometry, not fake geometry")
|
let f1: Int = geometry_free(gn)
|
||||||
|
let f2: Int = geometry_free(gi)
|
||||||
|
|
||||||
println("an unresolvable realizer name fails at WIRING time")
|
println("the relations are content no single part carries")
|
||||||
let bad: Int = realizer_register("ghost", "no_such_function_anywhere")
|
// That "2" above is not a property of C and not a property of E. It exists
|
||||||
let _c: Int = check(1 - bad, "unresolvable realizer name is a registration failure")
|
// only BETWEEN them, so a representation with no relations cannot hold it.
|
||||||
let gh2: Int = realizer_has("ghost")
|
let spans: Int = 0
|
||||||
let _c: Int = check(1 - gh2, "and nothing gets registered")
|
let k: Int = 0
|
||||||
|
while k < rc {
|
||||||
|
if str_eq(manifold_rel_name(m, k), "spans") {
|
||||||
|
if str_eq(manifold_rel_from(m, k), "interval:0-1") { spans = spans + 1 }
|
||||||
|
}
|
||||||
|
k = k + 1
|
||||||
|
}
|
||||||
|
let _c: Int = check(eq_int(spans, 2), "the interval is wired to both notes it spans")
|
||||||
|
|
||||||
println("a realizer returning non-geometry transduces nothing")
|
println("relation weight IS the grounding (correspondence-and-censorship §1)")
|
||||||
let rb: Int = realizer_register("bogus", "bogus_realizer")
|
let wk: Int = 0
|
||||||
let _c: Int = check(rb, "the symbol resolves, so registration succeeds")
|
let found: Int = 0
|
||||||
let gb: Geometry = transduce("x", "bogus")
|
while wk < rc {
|
||||||
let gbi: Int = geometry_is(gb)
|
if str_eq(manifold_rel_name(m, wk), "sounds_before") {
|
||||||
let _c: Int = check(1 - gbi, "contract enforced at the boundary: nothing handed back")
|
if near(manifold_rel_weight(m, wk), 0.8) > 0 { found = 1 }
|
||||||
|
}
|
||||||
|
wk = wk + 1
|
||||||
|
}
|
||||||
|
let _c: Int = check(found, "the ordering relation carries the weight its realizer stated")
|
||||||
|
|
||||||
println("norm lets a caller check a realizer emitted signal, not zeros")
|
println("the decomposition persists as real, separately addressable nodes")
|
||||||
let gn: Geometry = geometry_new(2)
|
let ids: [String] = el_list_empty()
|
||||||
let _c: Int = check(near(geometry_norm(gn), 0.0), "a fresh geometry is zero — norm says so")
|
let n0: Int = engram_node_count()
|
||||||
let n0: Int = geometry_set(gn, 0, 3.0)
|
let e0: Int = engram_edge_count()
|
||||||
let n1: Int = geometry_set(gn, 1, 4.0)
|
let pi: Int = 0
|
||||||
let _c: Int = check(near(geometry_norm(gn), 5.0), "3-4-5: norm is 5")
|
while pi < sz {
|
||||||
let ffn: Int = geometry_free(gn)
|
let key: String = manifold_key(m, pi)
|
||||||
|
let g: Geometry = manifold_geometry(m, pi)
|
||||||
|
let id: String = engram_node("component " + key, "Concept", 0.6)
|
||||||
|
let att: Int = node_attach_geometry(id, g)
|
||||||
|
ids = el_list_append(ids, id)
|
||||||
|
let ff: Int = geometry_free(g)
|
||||||
|
pi = pi + 1
|
||||||
|
}
|
||||||
|
let ri: Int = 0
|
||||||
|
while ri < rc {
|
||||||
|
let fi: Int = manifold_index_of(m, manifold_rel_from(m, ri))
|
||||||
|
let ti: Int = manifold_index_of(m, manifold_rel_to(m, ri))
|
||||||
|
engram_connect(el_list_get(ids, fi), el_list_get(ids, ti),
|
||||||
|
manifold_rel_weight(m, ri), manifold_rel_name(m, ri))
|
||||||
|
ri = ri + 1
|
||||||
|
}
|
||||||
|
let _c: Int = check(eq_int(engram_node_count() - n0, 5), "one signal became five nodes")
|
||||||
|
let _c: Int = check(eq_int(engram_edge_count() - e0, 6), "and six edges between them")
|
||||||
|
|
||||||
|
println("each part's geometry is independently readable back off its node")
|
||||||
|
let id_c: String = el_list_get(ids, manifold_index_of(m, "note:0"))
|
||||||
|
let id_iv: String = el_list_get(ids, manifold_index_of(m, "interval:0-1"))
|
||||||
|
let _c: Int = check(eq_int(node_geometry_dim(id_c), 2), "note:0 node carries a 2-wide geometry")
|
||||||
|
let _c: Int = check(eq_int(node_geometry_dim(id_iv), 1), "interval:0-1 node carries a 1-wide one")
|
||||||
|
|
||||||
|
println("one part can be grounded without touching its siblings")
|
||||||
|
let ear: String = engram_node("evidence: heard a C in the recording", "Memory", 0.7)
|
||||||
|
engram_connect(ear, id_c, 0.95, "corroborates")
|
||||||
|
let _c: Int = check(engram_edge_between(ear, id_c), "evidence attaches to note:0 specifically")
|
||||||
|
let id_g: String = el_list_get(ids, manifold_index_of(m, "note:2"))
|
||||||
|
let _c: Int = check(1 - engram_edge_between(ear, id_g), "and NOT to note:2 — the sibling is untouched")
|
||||||
|
// This is the whole gain, and it is impossible with a fingerprint: with one
|
||||||
|
// node per signal, "the C is corroborated" and "the G is not" have the same
|
||||||
|
// grounding target and cannot both be recorded.
|
||||||
|
let _c: Int = check(eq_int(node_geometry_dim(id_g), 2), "note:2 geometry is intact regardless")
|
||||||
|
|
||||||
|
println("a fingerprint realizer transduces NOTHING")
|
||||||
|
// #144's contract exactly: signal in, one Geometry out. It resolves, so the
|
||||||
|
// organ is present — but it does not decompose, so it does not transduce.
|
||||||
|
// "No organ" and "an organ that only fingerprints" must not look alike.
|
||||||
|
let rf: Int = realizer_register("fingerprint", "fingerprint_realizer")
|
||||||
|
let _c: Int = check(rf, "the symbol resolves, so registration succeeds")
|
||||||
|
let mf: Manifold = transduce("x", "fingerprint")
|
||||||
|
let _c: Int = check(1 - manifold_is(mf), "a single vector is not a transduction")
|
||||||
|
|
||||||
|
println("the one-part case is a size-one manifold, not a bare vector")
|
||||||
|
let g1: Geometry = geometry_new(3)
|
||||||
|
let s1: Int = geometry_set(g1, 0, 5.0)
|
||||||
|
let ms: Manifold = manifold_single("level", "scalar", g1)
|
||||||
|
let _c: Int = check(manifold_is(ms), "manifold_single yields a real Manifold")
|
||||||
|
let _c: Int = check(eq_int(manifold_size(ms), 1), "of size one — visibly degenerate, not hidden")
|
||||||
|
let fg: Int = geometry_free(g1)
|
||||||
|
let fs: Int = manifold_free(ms)
|
||||||
|
|
||||||
|
println("no organ is still reported as no organ")
|
||||||
|
let me: Manifold = transduce("anything", "echolocation")
|
||||||
|
let _c: Int = check(1 - manifold_is(me), "no realizer means no manifold, not a fake one")
|
||||||
|
|
||||||
|
let fm: Int = manifold_free(m)
|
||||||
|
|
||||||
// Reaching here means nothing called exit(1) along the way.
|
// Reaching here means nothing called exit(1) along the way.
|
||||||
println("")
|
println("")
|
||||||
|
|||||||
Reference in New Issue
Block a user