lumbda/examples/proof-netspace-client.lsp
russell@unturf.com f7352b51b0 rename: uncommonlisp -> lumbda throughout the repo
Historical internal name "uncommonlisp" retired in favor of the
public name "lumbda" ahead of lumbda.com going live. Scope of
this commit:

Source files renamed:
  uncommonlisp.py                     -> lumbda.py
  asm/uncommonlisp.s                  -> asm/lumbda.s
  c/uncommonlisp.h                    -> c/lumbda.h
  whitepaper/uncommonlisp-whitepaper  -> whitepaper/lumbda-whitepaper (.rst + .pdf)

Binaries renamed (tracked ones; c/ was always gitignored):
  asm/uncommonlisp, asm/uncommonlisp-gc, asm/uncommonlisp.o,
  asm/uncommonlisp-gc.o                -> asm/lumbda(-gc)(.o)
  c/.gitignore                          -> ignores lumbda

Internal string updates (sed pass ordered longest-first):
  asm/uncommonlisp -> asm/lumbda
  c/uncommonlisp   -> c/lumbda
  uncommonlisp.py  -> lumbda.py
  UNCOMMONLISP_BIN -> LUMBDA_BIN (asm/test.sh env var)
  "uncommonlisp> " -> "lumbda> " (asm REPL prompt baked into binary)
  UNCOMMONLISP     -> LUMBDA (macros, comments)
  uncommonlisp     -> lumbda (prose)

Binary portal magic updated:
  "ULPORTAL" -> "LUMBDAB1"   # "Lumbda Binary v1"
Old portal files are not backward-compatible — this is a deliberate
break since it's the rename moment. S-expression portals already
carry their own ";; lumbda-portal v1" header and remain cleanly
versioned.

WHITEPAPER.pdf / WHITEPAPER.rst symlinks repointed to the renamed
files. Makefile's whitepaper target targets lumbda-whitepaper.pdf.

Not changed (intentional, separate phases):
  - Filesystem directory /home/fox/git/uncommonlisp itself
    (fox renames locally and the gitlab repo URL in a follow-up)
  - tests.py hardcoded cwd=/home/fox/git/uncommonlisp
    (matches the current on-disk location; will flip when the
    directory rename ships)
  - Git history (immutable; old commits still say uncommonlisp,
    which is correct — that's what they were)

Verified:
  137 asm no-GC + 137 asm GC + 571 Python + 83 C + 189 shared
  functional tests all pass under the new names.
  bench-gc-http (2000 req): all 4 cells behave as expected
  (cells 1/2 flat, 3 leaks, 4 bounded at 1 chunk).
  Python REPL, C REPL, asm REPL all start cleanly.
2026-04-19 10:20:11 -04:00

123 lines
4.5 KiB
Text

;;; proof-netspace-client.lsp — query the proof netspace server.
;;;
;;; Three passes:
;;;
;;; 1. Verify each of five EML theorems per-proof (PROVEN / UNKNOWN).
;;; 2. Fetch the whole envelope — the server's full solution space
;;; ships back in one round-trip as (envelope (h1 h2 ...)).
;;; 3. Merge our own envelope back + one synthetic hash. Server
;;; reports (merged 1) proving the synthetic was the only new
;;; entry and the rest were already known.
;;;
;;; Two nodes can chain (envelope) + (merge ...) in either direction
;;; until both hold the union of what either knew.
;;;
;;; Usage (start the server first):
;;; python3 lumbda.py --fast examples/proof-netspace-client.lsp
;;; ./c/lumbda examples/proof-netspace-client.lsp
;;; ./asm/lumbda < examples/proof-netspace-client.lsp
(define *host* "127.0.0.1")
(define *port* 9086)
;;; ─── Canonical serializer (matches server) ─────────────────
(define (atom->string v)
(cond
((number? v) (number->string v))
((symbol? v) (symbol->string v))
((null? v) "()")
((pair? v) (string-append "(" (list->str v) ")"))
(else "?")))
(define (list->str lst)
(cond
((null? lst) "")
((null? (cdr lst)) (atom->string (car lst)))
(else (string-append (atom->string (car lst)) " "
(list->str (cdr lst))))))
;;; ─── One-shot TCP round-trip ───────────────────────────────
(define (request str)
(let ((sock (tcp-connect *host* *port*)))
(if sock
(begin
(tcp-send sock str)
(let ((resp (tcp-recv sock 65536)))
(tcp-close sock)
(if resp resp "NO-RESPONSE")))
"NO-CONNECT")))
;;; ─── Per-proof verification ────────────────────────────────
(define (ask lhs rhs)
(request (string-append "(" (atom->string lhs) " "
(atom->string rhs) ")")))
(define (probe name lhs rhs)
(let ((t0 (current-time-ms)))
(let ((resp (ask lhs rhs)))
(let ((t1 (current-time-ms)))
(display name) (display ": ")
(display (- t1 t0)) (display " ms ")
(display resp)))))
;;; ─── Envelope teleport ─────────────────────────────────────
(define (count-items form n)
;; Return length of a list form; used to count hashes in envelope.
(if (pair? form) (count-items (cdr form) (+ n 1)) n))
(define (parse-envelope resp)
;; resp = "(envelope (h1 h2 ...))\n" — return the inner list.
(let ((form (read-from-string resp)))
(if (and (pair? form) (eqv? (car form) 'envelope) (pair? (cdr form)))
(car (cdr form))
'())))
(define (hashes->string lst acc)
(if (null? lst) acc
(hashes->string (cdr lst)
(string-append acc (number->string (car lst)) " "))))
(define (fetch-envelope)
(let ((t0 (current-time-ms)))
(let ((resp (request "(envelope)")))
(let ((t1 (current-time-ms)))
(display "envelope : ") (display (- t1 t0)) (display " ms ")
(let ((hashes (parse-envelope resp)))
(display (count-items hashes 0))
(display " hashes teleported") (newline)
hashes)))))
(define (merge-envelope hashes synthetic)
;; Send the server its own envelope back plus one synthetic hash.
;; Expected reply: (merged 1) — only the synthetic was new.
(let ((t0 (current-time-ms)))
(let ((payload (string-append "(merge ("
(hashes->string hashes "")
(number->string synthetic) "))")))
(let ((resp (request payload)))
(let ((t1 (current-time-ms)))
(display "merge : ") (display (- t1 t0)) (display " ms ")
(display resp))))))
;;; ─── Run ───────────────────────────────────────────────────
(display "querying proof netspace at ") (display *host*) (display ":")
(display *port*) (newline)
(newline)
(probe "eml_is_exp " '(eml ?x 1) '(exp ?x))
(probe "eml_is_e " '(eml 1 1) '(exp 1))
(probe "eml_is_ln " '(eml 1 (eml (eml 1 ?x) 1)) '(ln ?x))
(probe "eml_is_zero " '(eml 1 (eml (eml 1 1) 1)) 0)
(probe "eml_is_sub " '(eml (ln ?a) (exp ?b)) '(- ?a ?b))
(newline)
(define env (fetch-envelope))
(merge-envelope env 999999999)
(newline)
(display "done") (newline)