From 2d51a8c4eaa3b9856d04493407066fd3a6d8de6b Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 8 May 2026 11:17:27 +0000 Subject: [PATCH] mk: numbero / stringo / symbolo type predicates Ground-only type tests via project. Each succeeds iff its argument walks to the corresponding host value type. Composes with membero for type-filtered enumeration: (fresh (x) (membero x (list 1 "a" 2 "b" 3)) (numbero x) (== q x)) -> (1 2 3) 12 new tests, 328/328 cumulative. Caveat: SX keywords are strings, so (stringo :k) succeeds. --- lib/minikanren/intarith.sx | 6 ++++ lib/minikanren/tests/types.sx | 52 +++++++++++++++++++++++++++++++++++ plans/minikanren-on-sx.md | 5 ++++ 3 files changed, 63 insertions(+) create mode 100644 lib/minikanren/tests/types.sx diff --git a/lib/minikanren/intarith.sx b/lib/minikanren/intarith.sx index 7f16a36b..1ca9aee2 100644 --- a/lib/minikanren/intarith.sx +++ b/lib/minikanren/intarith.sx @@ -54,3 +54,9 @@ (project (a b) (if (and (number? a) (and (number? b) (not (= a b)))) succeed fail)))) + +(define numbero (fn (x) (project (x) (if (number? x) succeed fail)))) + +(define stringo (fn (x) (project (x) (if (string? x) succeed fail)))) + +(define symbolo (fn (x) (project (x) (if (symbol? x) succeed fail)))) diff --git a/lib/minikanren/tests/types.sx b/lib/minikanren/tests/types.sx new file mode 100644 index 00000000..5eb50e6f --- /dev/null +++ b/lib/minikanren/tests/types.sx @@ -0,0 +1,52 @@ +;; lib/minikanren/tests/types.sx — type-predicate goals. + +(mk-test + "numbero-on-int" + (run* q (numbero 5)) + (list (make-symbol "_.0"))) +(mk-test "numbero-on-string" (run* q (numbero "5")) (list)) +(mk-test "numbero-on-symbol" (run* q (numbero (quote x))) (list)) +(mk-test "numbero-on-list" (run* q (numbero (list 1))) (list)) + +(mk-test + "stringo-on-string" + (run* q (stringo "hi")) + (list (make-symbol "_.0"))) +(mk-test "stringo-on-int" (run* q (stringo 5)) (list)) +(mk-test + "stringo-on-keyword" + (run* q (stringo :k)) + (list (make-symbol "_.0"))) ;; SX keywords ARE strings + +(mk-test + "symbolo-on-symbol" + (run* q (symbolo (quote x))) + (list (make-symbol "_.0"))) +(mk-test "symbolo-on-string" (run* q (symbolo "x")) (list)) +(mk-test "symbolo-on-int" (run* q (symbolo 5)) (list)) + +;; --- combine with membero for type-filtered enumeration --- + +(mk-test + "membero-numbero-filter" + (run* + q + (fresh + (x) + (membero x (list 1 "a" 2 "b" 3)) + (numbero x) + (== q x))) + (list 1 2 3)) + +(mk-test + "membero-stringo-filter" + (run* + q + (fresh + (x) + (membero x (list 1 "a" 2 "b" 3)) + (stringo x) + (== q x))) + (list "a" "b")) + +(mk-tests-run!) diff --git a/plans/minikanren-on-sx.md b/plans/minikanren-on-sx.md index dbce01e9..d40a86c9 100644 --- a/plans/minikanren-on-sx.md +++ b/plans/minikanren-on-sx.md @@ -173,6 +173,11 @@ _(none yet)_ _Newest first._ +- **2026-05-08** — **numbero / stringo / symbolo (type predicates)**: ground-only + type tests via project. Compose with `membero` for type-filtered enumeration: + `(fresh (x) (membero x (1 "a" 2 "b" 3)) (numbero x) (== q x))` → `(1 2 3)`. + Note: SX keywords are strings, so `(stringo :k)` succeeds. 12 new tests, + 328/328 cumulative. - **2026-05-08** — **Graph reachability via patho**: classic miniKanren graph search. `edgeo` looks up edges in a fact list via `membero`; `patho` recursively builds paths via direct-edge OR (one edge + recurse + cons).