From de6fd1b1837a1a4bdfda33cf28e4c0df0976a39f Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 8 May 2026 12:28:31 +0000 Subject: [PATCH] =?UTF-8?q?mk:=20counto=20=E2=80=94=20count=20occurrences?= =?UTF-8?q?=20of=20x=20in=20l=20(intarith)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Walks the list with a recursive count. On a head match, recurse and add 1 via pluso-i; on no match (nafc), recurse forwarding the count. Empty list yields 0. 6 new tests, 532/532 cumulative. --- lib/minikanren/intarith.sx | 8 ++++++++ lib/minikanren/tests/counto.sx | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 lib/minikanren/tests/counto.sx diff --git a/lib/minikanren/intarith.sx b/lib/minikanren/intarith.sx index 85b2cb69..51b2ee1e 100644 --- a/lib/minikanren/intarith.sx +++ b/lib/minikanren/intarith.sx @@ -127,3 +127,11 @@ ((fresh (a d r-rest start-prime) (conso a d l) (conso (list start a) r-rest result) (pluso-i 1 start start-prime) (enumerate-from-i start-prime d r-rest)))))) (define enumerate-i (fn (l result) (enumerate-from-i 0 l result))) + +(define + counto + (fn + (x l n) + (conde + ((nullo l) (== n 0)) + ((fresh (a d n-rest) (conso a d l) (conde ((== a x) (counto x d n-rest) (pluso-i 1 n-rest n)) ((nafc (== a x)) (counto x d n)))))))) diff --git a/lib/minikanren/tests/counto.sx b/lib/minikanren/tests/counto.sx new file mode 100644 index 00000000..0c9248fc --- /dev/null +++ b/lib/minikanren/tests/counto.sx @@ -0,0 +1,35 @@ +;; lib/minikanren/tests/counto.sx — count occurrences of x in l (intarith). + +(mk-test + "counto-empty" + (run* q (counto 1 (list) q)) + (list 0)) +(mk-test + "counto-not-found" + (run* q (counto 99 (list 1 2 3) q)) + (list 0)) +(mk-test + "counto-once" + (run* q (counto 2 (list 1 2 3) q)) + (list 1)) +(mk-test + "counto-thrice" + (run* + q + (counto + 1 + (list 1 2 1 3 1) + q)) + (list 3)) +(mk-test + "counto-all-same" + (run* + q + (counto 7 (list 7 7 7 7) q)) + (list 4)) +(mk-test + "counto-string" + (run* q (counto "x" (list "x" "y" "x") q)) + (list 2)) + +(mk-tests-run!)