From ce72070d2ac874213e3410ed92862628232333b5 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 6 May 2026 19:24:46 +0000 Subject: [PATCH] =?UTF-8?q?apl:=20membership=20=E2=88=8A,=20dyadic=20?= =?UTF-8?q?=E2=8D=B3,=20without=20~=20(dyadic);=2094/94=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- lib/apl/runtime.sx | 42 +++++++++++++++++ lib/apl/tests/structural.sx | 93 ++++++++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/lib/apl/runtime.sx b/lib/apl/runtime.sx index ca6fa2c7..ec3e5e1e 100644 --- a/lib/apl/runtime.sx +++ b/lib/apl/runtime.sx @@ -753,3 +753,45 @@ ((inner-shape (rest shape)) (inner-size (reduce * 1 (rest shape)))) (make-array inner-shape (take ravel inner-size)))))))) + +(define + apl-member + (fn + (a b) + (let + ((a-ravel (if (scalar? a) (list (disclose a)) (get a :ravel))) + (b-ravel (if (scalar? b) (list (disclose b)) (get b :ravel))) + (a-shape (get a :shape))) + (make-array + a-shape + (map (fn (x) (if (index-of b-ravel x) 1 0)) a-ravel))))) + +(define + apl-index-of + (fn + (v w) + (let + ((v-ravel (if (scalar? v) (list (disclose v)) (get v :ravel))) + (w-ravel (if (scalar? w) (list (disclose w)) (get w :ravel))) + (w-shape (get w :shape)) + (n (len (if (scalar? v) (list (disclose v)) (get v :ravel))))) + (make-array + w-shape + (map + (fn + (x) + (let + ((i (index-of v-ravel x))) + (if i (+ i apl-io) (+ n apl-io)))) + w-ravel))))) + +(define + apl-without + (fn + (a b) + (let + ((a-ravel (if (scalar? a) (list (disclose a)) (get a :ravel))) + (b-ravel (if (scalar? b) (list (disclose b)) (get b :ravel)))) + (let + ((result (filter (fn (x) (not (index-of b-ravel x))) a-ravel))) + (make-array (list (len result)) result))))) diff --git a/lib/apl/tests/structural.sx b/lib/apl/tests/structural.sx index cfdf16cf..03c28a53 100644 --- a/lib/apl/tests/structural.sx +++ b/lib/apl/tests/structural.sx @@ -514,4 +514,95 @@ (apl-test "disclose matrix returns first row" (rv (apl-disclose (make-array (list 2 3) (list 1 2 3 4 5 6)))) - (list 1 2 3)) \ No newline at end of file + (list 1 2 3)) + +(apl-test + "member basic" + (rv + (apl-member + (make-array (list 3) (list 1 2 3)) + (make-array (list 2) (list 2 3)))) + (list 0 1 1)) + +(apl-test + "member all absent" + (rv + (apl-member + (make-array (list 3) (list 4 5 6)) + (make-array (list 3) (list 1 2 3)))) + (list 0 0 0)) + +(apl-test + "member scalar" + (rv (apl-member (apl-scalar 5) (make-array (list 3) (list 1 5 9)))) + (list 1)) + +(apl-test + "member shape preserved" + (sh + (apl-member + (make-array (list 2 3) (list 1 2 3 4 5 6)) + (make-array (list 3) (list 1 3 5)))) + (list 2 3)) + +(apl-test + "member matrix ravel" + (rv + (apl-member + (make-array (list 2 3) (list 1 2 3 4 5 6)) + (make-array (list 3) (list 1 3 5)))) + (list 1 0 1 0 1 0)) + +(apl-test + "index-of basic" + (rv + (apl-index-of + (make-array (list 4) (list 10 20 30 40)) + (make-array (list 3) (list 20 40 10)))) + (list 2 4 1)) + +(apl-test + "index-of not-found" + (rv + (apl-index-of + (make-array (list 3) (list 1 2 3)) + (make-array (list 2) (list 5 2)))) + (list 4 2)) + +(apl-test + "index-of scalar right" + (rv + (apl-index-of (make-array (list 3) (list 10 20 30)) (apl-scalar 20))) + (list 2)) + +(apl-test + "without basic" + (rv + (apl-without + (make-array (list 5) (list 1 2 3 4 5)) + (make-array (list 2) (list 2 4)))) + (list 1 3 5)) + +(apl-test + "without shape" + (sh + (apl-without + (make-array (list 5) (list 1 2 3 4 5)) + (make-array (list 2) (list 2 4)))) + (list 3)) + +(apl-test + "without nothing removed" + (rv + (apl-without + (make-array (list 3) (list 1 2 3)) + (make-array (list 3) (list 4 5 6)))) + (list 1 2 3)) + +(apl-test + "without all removed" + (rv + (apl-without + (make-array (list 3) (list 1 2 3)) + (make-array (list 3) (list 1 2 3)))) + (list)) \ No newline at end of file