rand-nth follows the reference shape; refresh doc counts and the corpus floor

rand-nth vec'd its argument, so (rand-nth nil) hit index-out-of-bounds
through the empty vector where the reference's (nth coll (rand-int (count
coll))) returns nil (and a set throws) — the last genuinely-fixable row in
the suite baseline; rand-nth is fully clean now. Corpus/README counts
updated to the current ~3570 rows, the run-corpus regression floor raised
from 2730 to 3390 to match current parity, and the stale traceability line
dropped.
This commit is contained in:
Yogthos 2026-07-02 14:32:53 -04:00
parent ab10e68218
commit a67dbdb93d
7 changed files with 3578 additions and 3578 deletions

View file

@ -11,7 +11,7 @@
;; reset between cases so there is no leakage — same isolation a fresh process gives. ;; reset between cases so there is no leakage — same isolation a fresh process gives.
;; ;;
;; chez --script host/chez/run-corpus.ss ;; chez --script host/chez/run-corpus.ss
;; JOLT_CHEZ_ZJ_FLOOR=N override the regression floor (default 2730) ;; JOLT_CHEZ_ZJ_FLOOR=N override the regression floor (default 3390)
;; JOLT_CORPUS_LIMIT=N every-Nth stride (fast iteration; floor drops to 0) ;; JOLT_CORPUS_LIMIT=N every-Nth stride (fast iteration; floor drops to 0)
;; JOLT_DUMP_CRASH_LABELS=1 list crash + allowlisted labels ;; JOLT_DUMP_CRASH_LABELS=1 list crash + allowlisted labels
(import (chezscheme)) (import (chezscheme))
@ -196,7 +196,7 @@
;; Regression floor: fail on any NEW divergence or if pass drops below the floor. ;; Regression floor: fail on any NEW divergence or if pass drops below the floor.
(define base-floor (let ((s (getenv "JOLT_CHEZ_ZJ_FLOOR"))) (define base-floor (let ((s (getenv "JOLT_CHEZ_ZJ_FLOOR")))
(if s (string->number s) 2730))) (if s (string->number s) 3390)))
(define floor (if limit 0 base-floor)) (define floor (if limit 0 base-floor))
(when (or (> (length diverged) 0) (< pass floor)) (when (or (> (length diverged) 0) (< pass floor))
(printf "REGRESSION: pass ~a < floor ~a or ~a new divergence(s)\n" (printf "REGRESSION: pass ~a < floor ~a or ~a new divergence(s)\n"

View file

@ -361,7 +361,7 @@
(guard (e (#t #f)) (guard (e (#t #f))
(def-var! "clojure.core" "char-name-string" (letrec ((char-name-string (lambda (c) (let fnrec4381 ((c c)) (jolt-get (var-deref "clojure.core" "char-name-strings") c))))) char-name-string))) (def-var! "clojure.core" "char-name-string" (letrec ((char-name-string (lambda (c) (let fnrec4381 ((c c)) (jolt-get (var-deref "clojure.core" "char-name-strings") c))))) char-name-string)))
(guard (e (#t #f)) (guard (e (#t #f))
(def-var! "clojure.core" "rand-nth" (letrec ((rand-nth (lambda (coll) (let fnrec4382 ((coll coll)) (let* ((v (jolt-invoke (var-deref "clojure.core" "vec") coll))) (jolt-nth v (jolt-invoke (var-deref "clojure.core" "rand-int") (jolt-count v)))))))) rand-nth))) (def-var! "clojure.core" "rand-nth" (letrec ((rand-nth (lambda (coll) (let fnrec4382 ((coll coll)) (jolt-nth coll (jolt-invoke (var-deref "clojure.core" "rand-int") (jolt-count coll))))))) rand-nth)))
(guard (e (#t #f)) (guard (e (#t #f))
(def-var! "clojure.core" "random-sample" (letrec ((random-sample (case-lambda ((prob) (let fnrec4383 ((prob prob)) (jolt-invoke jolt-filter (lambda (_) (let fnrec4384 ((_ _)) (jolt-n< (jolt-invoke (var-deref "clojure.core" "rand")) prob)))))) ((prob coll) (let fnrec4385 ((prob prob) (coll coll)) (jolt-filter (lambda (_) (let fnrec4386 ((_ _)) (jolt-n< (jolt-invoke (var-deref "clojure.core" "rand")) prob))) coll)))))) random-sample))) (def-var! "clojure.core" "random-sample" (letrec ((random-sample (case-lambda ((prob) (let fnrec4383 ((prob prob)) (jolt-invoke jolt-filter (lambda (_) (let fnrec4384 ((_ _)) (jolt-n< (jolt-invoke (var-deref "clojure.core" "rand")) prob)))))) ((prob coll) (let fnrec4385 ((prob prob) (coll coll)) (jolt-filter (lambda (_) (let fnrec4386 ((_ _)) (jolt-n< (jolt-invoke (var-deref "clojure.core" "rand")) prob))) coll)))))) random-sample)))
(guard (e (#t #f)) (guard (e (#t #f))

View file

@ -66,9 +66,10 @@
\backspace "backspace" \space "space"}) \backspace "backspace" \space "space"})
(defn char-name-string [c] (get char-name-strings c)) (defn char-name-string [c] (get char-name-strings c))
;; Random selection over the host rand primitives. ;; Random selection over the host rand primitives — the reference shape:
;; nth directly (nil returns nil via RT.nth; a set throws like the JVM).
(defn rand-nth [coll] (defn rand-nth [coll]
(let [v (vec coll)] (nth v (rand-int (count v))))) (nth coll (rand-int (count coll))))
(defn random-sample (defn random-sample
([prob] (filter (fn [_] (< (rand) prob)))) ([prob] (filter (fn [_] (< (rand) prob))))

View file

@ -7,7 +7,7 @@ test` from the repo root.
## The spec corpus ## The spec corpus
`corpus.edn` is the contract: ~2920 rows `{:suite :label :expected :actual}`, with `corpus.edn` is the contract: ~3570 rows `{:suite :label :expected :actual :portability}`, with
`:expected` sourced from reference JVM Clojure by `test/conformance/regen-corpus.clj`. `:expected` sourced from reference JVM Clojure by `test/conformance/regen-corpus.clj`.
It is frozen (the canonical source) — add or change cases here, then re-source the It is frozen (the canonical source) — add or change cases here, then re-source the
answers with `regen-corpus.clj` and re-certify with `test/conformance/certify.clj`. answers with `regen-corpus.clj` and re-certify with `test/conformance/certify.clj`.
@ -22,7 +22,7 @@ answers with `regen-corpus.clj` and re-certify with `test/conformance/certify.cl
chez --script host/chez/run-corpus.ss chez --script host/chez/run-corpus.ss
JOLT_CORPUS_LIMIT=200 … # every-Nth stride, fast iteration JOLT_CORPUS_LIMIT=200 … # every-Nth stride, fast iteration
JOLT_CHEZ_ZJ_FLOOR=N … # override the floor (default 2678) JOLT_CHEZ_ZJ_FLOOR=N … # override the floor (see run-corpus.ss)
- `run-unit.ss` — host-specific unit cases (`test/chez/unit.edn`) that aren't in the - `run-unit.ss` — host-specific unit cases (`test/chez/unit.edn`) that aren't in the
JVM-portable corpus: dot-forms, java statics, io, reader, walk, vars/namespaces, JVM-portable corpus: dot-forms, java statics, io, reader, walk, vars/namespaces,

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,6 @@ clojure.core-test.plus 11 0
clojure.core-test.plus-squote 11 0 clojure.core-test.plus-squote 11 0
clojure.core-test.pos-int-qmark 1 0 clojure.core-test.pos-int-qmark 1 0
clojure.core-test.quot 25 0 clojure.core-test.quot 25 0
clojure.core-test.rand-nth 0 1
clojure.core-test.realized-qmark 1 0 clojure.core-test.realized-qmark 1 0
clojure.core-test.rem 16 0 clojure.core-test.rem 16 0
clojure.core-test.remove-watch 0 1 clojure.core-test.remove-watch 0 1

View file

@ -10,7 +10,7 @@ read one data file, run each case, compare, report.
| File | Role | Generated by | | File | Role | Generated by |
|------|------|--------------| |------|------|--------------|
| `test/chez/corpus.edn` | **The spec.** ~2900 cases of `{:suite :label :expected :actual}`, `:expected` **sourced from reference JVM Clojure**. | `test/conformance/regen-corpus.clj` | | `test/chez/corpus.edn` | **The spec.** ~3570 cases of `{:suite :label :expected :actual :portability}`, `:expected` **sourced from reference JVM Clojure**. | `test/conformance/regen-corpus.clj` |
| `test/conformance/profile.edn` | Per-case **feature classification** — which non-portable cases need which host capability. | `certify.clj --profile` | | `test/conformance/profile.edn` | Per-case **feature classification** — which non-portable cases need which host capability. | `certify.clj --profile` |
| `test/conformance/known-divergences.edn` | The few rows whose JVM value is an opaque host object that can't round-trip to readable source (Java arrays/transients/atoms/beans/proxies print as `#object[..@addr]`), so the corpus keeps jolt's value. | `regen-corpus.clj` leftovers, hand-checked | | `test/conformance/known-divergences.edn` | The few rows whose JVM value is an opaque host object that can't round-trip to readable source (Java arrays/transients/atoms/beans/proxies print as `#object[..@addr]`), so the corpus keeps jolt's value. | `regen-corpus.clj` leftovers, hand-checked |
| `test/conformance/regen-corpus.clj` | Sources every `:expected` from reference **JVM Clojure** in one process. | — | | `test/conformance/regen-corpus.clj` | Sources every `:expected` from reference **JVM Clojure** in one process. | — |
@ -54,8 +54,8 @@ the canonical, frozen contract**: it is what every runtime consumes, what
Historically every `:expected` was hand-written. `certify.clj` removes that Historically every `:expected` was hand-written. `certify.clj` removes that
weakness: it evaluates every `:actual` (and `:expected`) on **JVM Clojure** in a weakness: it evaluates every `:actual` (and `:expected`) on **JVM Clojure** in a
fresh `user` namespace and checks jolt's `:expected` against what real Clojure fresh `user` namespace and checks jolt's `:expected` against what real Clojure
produces. Of ~2740 vanilla-certifiable rows, **>2730 match reference Clojure produces. Of ~3400 vanilla-certifiable rows, **all but ~26 allowlisted rows
exactly**. The rest are classified (see below) — none are silently wrong. match reference Clojure exactly**. The rest are classified (see below) — none are silently wrong.
```sh ```sh
clojure -M test/conformance/certify.clj # gate clojure -M test/conformance/certify.clj # gate
@ -243,8 +243,7 @@ documented model divergence — nothing in the baseline is an unexplained bug:
- **vec of an array copies**: the reference ADOPTS an Object array (mutating - **vec of an array copies**: the reference ADOPTS an Object array (mutating
the array mutates the vector); jolt copies — immutable semantics win over the array mutates the vector); jolt copies — immutable semantics win over
the implementation leak (`vec` namespace, one row). the implementation leak (`vec` namespace, one row).
- **eval of JVM shapes** (`rand-nth`/`eval` residue): rows needing JVM-only
evaluation shapes (e.g. evaluating a Java array literal).
A future change that makes any of these rows pass will fail the cts gate as A future change that makes any of these rows pass will fail the cts gate as
STALE, forcing this section and the baseline to be updated together. STALE, forcing this section and the baseline to be updated together.