proof netspace: envelope teleport + portable hash-table on vectors

Extends proof-netspace RPC with two verbs that let peers exchange the
full solution space in one round-trip:

  (envelope)           → reply (envelope (h1 h2 ...))
  (merge (h1 h2 ...))  → fold hashes into local DB, reply (merged N)

Any node can now bootstrap from a peer's cache instead of re-verifying
every theorem locally. Two nodes that swap envelopes both become
supersets of what either knew — the primitive for mesh-wide spiral.

*proof-db* swapped from linear alist to a hash-set. O(N·M) merge drops
to O(M). The hash-table is a ~20-line pure-Lumbda library over
make-vector / vector-ref / vector-set! — runs unmodified in all three
tiers. No asm hash-table primitive needed.

Also fixes a pre-existing asm defect: bi_makevec clobbered %rax via
the GETARG macro's internal scratch use, causing SIGSEGV on every
(make-vector N fill) call. The bug shipped because asm/test.sh only
covered the variadic (vector ...) constructor; tests/functional.lsp
had one make-vector assert but was never wired into asm's harness.
Added five make-vector assertions to asm/test.sh (132 → 137).

Portal snapshot rewritten to emit (set! *proof-db* ...) so the
top-level binding is actually mutated on restart — previous
(define ...) form bound locally on some code paths, leaving the
in-memory DB empty after load.

Verified: make test-all green (137 asm + 189 functional + Python/C
tests), 3-tier matrix cold+warm+restart all clean.
This commit is contained in:
russell@unturf.com 2026-04-17 21:36:26 -04:00
parent 3463fadd3f
commit d88149a502
6 changed files with 489 additions and 10 deletions

View file

@ -160,6 +160,11 @@ check "vec-len" "(vector-length (vector 1 2 3))" "3"
check "vec?" "(vector? (vector 1))" "#t"
check "vec?-f" "(vector? 42)" "#f"
check "vec-set" "(let ((v (vector 1 2 3))) (vector-set! v 1 99) (vector-ref v 1))" "99"
check "makevec" "(vector-ref (make-vector 3 0) 1)" "0"
check "makevec-len" "(vector-length (make-vector 5 42))" "5"
check "makevec-fill" "(vector-ref (make-vector 4 7) 2)" "7"
check "makevec-mut" "(let ((v (make-vector 3 0))) (vector-set! v 1 99) (vector-ref v 1))" "99"
check "makevec-big" "(vector-length (make-vector 1021 0))" "1021"
# ─── FUNCTIONAL TESTS: real programs ─────────────────────

Binary file not shown.

Binary file not shown.

View file

@ -3738,15 +3738,18 @@ bi_vector:
RET_VAL
bi_makevec:
# (make-vector n fill) allocate n-slot vector filled with `fill`.
# GETARG uses %rax as scratch, so we MUST stash the length in a
# callee-safe register before consuming the second arg.
GETARG %rax
sarq $3, %rax # n
GETARG %rcx # fill value (or default 0)
movq %r15, %rdx # vector obj
movq %rax, (%r15) # length
leaq 8(%r15,%rax,8), %r15
# Fill
leaq 8(%rdx), %rdi
movq (%rdx), %rsi # count
sarq $3, %rax # n (untagged)
movq %rax, %rdx # save n in %rdx survives next GETARG
GETARG %rcx # fill value (tagged)
movq %r15, %rax # vector obj pointer
movq %rdx, (%r15) # store length
leaq 8(%r15,%rdx,8), %r15 # advance heap past length + n*8 bytes
leaq 8(%rax), %rdi # elements start
movq %rdx, %rsi # count = n
.bmv_fill:
testq %rsi, %rsi
jz .bmv_done
@ -3755,8 +3758,7 @@ bi_makevec:
decq %rsi
jmp .bmv_fill
.bmv_done:
movq %rdx, %rax
orq $7, %rax
orq $7, %rax # tag as vector
RET_VAL
bi_vecref: