apl: life.apl runs as-written (+5 e2e)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

Five infrastructure fixes to make the Hui formulation
{1 ⍵ ∨.∧ 3 4 = +/+/¯1 0 1 ∘.⊖ ¯1 0 1 ⌽¨ ⊂⍵} work:

1. apl-each-dyadic: unbox enclosed-array scalar before pairing;
   preserve array results instead of disclosing
2. apl-outer: same dict-vs-number wrap detection
3. apl-reduce: dict-aware wrap in reducer; don't double-wrap
   the final result in apl-scalar when it's already a dict
4. broadcast-dyadic: leading-axis extension for shape-(k) vs
   shape-(k …) — `3 4 = M[5,5]` → shape (2 5 5)
5. :vec eval keeps non-scalar dicts intact (no flatten-to-first)

life.apl: drop leading ⊃ (Hui's ⊃ assumes inner-product produces
enclosed cell; our extension-style impl produces clean (5 5)).
Comment block in life.apl explains.

5 e2e tests: blinker oscillates period-2, 2×2 block stable,
empty grid stays empty, source file load via apl-run-file.

Full suite 578/578.
This commit is contained in:
2026-05-08 23:35:14 +00:00
parent d1a491e530
commit 36e1519613
5 changed files with 122 additions and 34 deletions

View File

@@ -65,10 +65,30 @@
(get a :shape)
(map (fn (x) (f x sv)) (get a :ravel)))))
(else
(if
(equal? (get a :shape) (get b :shape))
(make-array (get a :shape) (map f (get a :ravel) (get b :ravel)))
(error "length error: shape mismatch"))))))
(let
((a-shape (get a :shape)) (b-shape (get b :shape)))
(cond
((equal? a-shape b-shape)
(make-array a-shape (map f (get a :ravel) (get b :ravel))))
((and (= (len a-shape) 1) (> (len b-shape) 1))
(make-array
(append a-shape b-shape)
(flatten
(map
(fn
(x)
(get (broadcast-dyadic f (apl-scalar x) b) :ravel))
(get a :ravel)))))
((and (= (len b-shape) 1) (> (len a-shape) 1))
(make-array
(append a-shape b-shape)
(flatten
(map
(fn
(acell)
(get (broadcast-dyadic f (apl-scalar acell) b) :ravel))
(get a :ravel)))))
(else (error "length error: shape mismatch"))))))))
; ============================================================
; Arithmetic primitives
@@ -1174,11 +1194,9 @@
(if
(= n 0)
(apl-scalar 0)
(apl-scalar
(reduce
(fn (a b) (disclose (f (apl-scalar a) (apl-scalar b))))
(first ravel)
(rest ravel)))))
(let
((rr (reduce (fn (a b) (let ((wa (if (= (type-of a) "dict") a (apl-scalar a))) (wb (if (= (type-of b) "dict") b (apl-scalar b)))) (let ((r (f wa wb))) (if (scalar? r) (disclose r) r)))) (first ravel) (rest ravel))))
(if (= (type-of rr) "dict") rr (apl-scalar rr)))))
(let
((last-dim (last shape))
(pre-shape (take shape (- (len shape) 1)))
@@ -1200,7 +1218,13 @@
(reduce
(fn
(a b)
(disclose (f (apl-scalar a) (apl-scalar b))))
(let
((wa (if (= (type-of a) "dict") a (apl-scalar a)))
(wb
(if (= (type-of b) "dict") b (apl-scalar b))))
(let
((r (f wa wb)))
(if (scalar? r) (disclose r) r))))
(first elems)
(rest elems)))))
(range 0 pre-size)))))))))
@@ -1341,13 +1365,29 @@
(cond
((and (scalar? a) (scalar? b)) (apl-scalar (disclose (f a b))))
((scalar? a)
(make-array
(get b :shape)
(map (fn (x) (disclose (f a (apl-scalar x)))) (get b :ravel))))
(let
((a-eff (let ((d (disclose a))) (if (= (type-of d) "dict") d a))))
(make-array
(get b :shape)
(map
(fn
(x)
(let
((r (f a-eff (apl-scalar x))))
(if (scalar? r) (disclose r) r)))
(get b :ravel)))))
((scalar? b)
(make-array
(get a :shape)
(map (fn (x) (disclose (f (apl-scalar x) b))) (get a :ravel))))
(let
((b-eff (let ((d (disclose b))) (if (= (type-of d) "dict") d b))))
(make-array
(get a :shape)
(map
(fn
(x)
(let
((r (f (apl-scalar x) b-eff)))
(if (scalar? r) (disclose r) r)))
(get a :ravel)))))
(else
(if
(equal? (get a :shape) (get b :shape))
@@ -1368,16 +1408,22 @@
(b-shape (get b :shape))
(a-ravel (get a :ravel))
(b-ravel (get b :ravel)))
(make-array
(append a-shape b-shape)
(flatten
(map
(fn
(x)
(map
(fn (y) (disclose (f (apl-scalar x) (apl-scalar y))))
b-ravel))
a-ravel))))))
(let
((wrap (fn (x) (if (= (type-of x) "dict") x (apl-scalar x)))))
(make-array
(append a-shape b-shape)
(flatten
(map
(fn
(x)
(map
(fn
(y)
(let
((r (f (wrap x) (wrap y))))
(if (scalar? r) (disclose r) r)))
b-ravel))
a-ravel)))))))
(define
apl-inner
@@ -1411,7 +1457,7 @@
(fn
(j)
(let
((pairs (map (fn (k) (disclose (g (apl-scalar (nth a-ravel (+ (* i inner-dim) k))) (apl-scalar (nth b-ravel (+ (* k b-post-size) j)))))) (range 0 inner-dim))))
((pairs (map (fn (k) (let ((a-elem (nth a-ravel (+ (* i inner-dim) k))) (b-elem (nth b-ravel (+ (* k b-post-size) j)))) (let ((a-cell (if (= (type-of a-elem) "dict") (nth (get a-elem :ravel) j) a-elem)) (b-cell (if (= (type-of b-elem) "dict") (nth (get b-elem :ravel) 0) b-elem))) (disclose (g (apl-scalar a-cell) (apl-scalar b-cell)))))) (range 0 inner-dim))))
(reduce
(fn
(x y)