From fc14a8063b41eaef642d2ee43b12af05323b3747 Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 8 May 2026 11:40:28 +0000 Subject: [PATCH] =?UTF-8?q?mk:=20prefixo=20+=20suffixo=20=E2=80=94=20appen?= =?UTF-8?q?do-derived=20sublist=20relations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two-line definitions over appendo: (prefixo p l) ≡ ∃rest. (appendo p rest l) (suffixo s l) ≡ ∃front. (appendo front s l) Both enumerate all prefixes/suffixes when called with a fresh first arg, and serve as decision relations when called with both grounded. 9 new tests, 398/398 cumulative. --- lib/minikanren/relations.sx | 6 ++- lib/minikanren/tests/prefix-suffix.sx | 76 +++++++++++++++++++++++++++ plans/minikanren-on-sx.md | 1 + 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 lib/minikanren/tests/prefix-suffix.sx diff --git a/lib/minikanren/relations.sx b/lib/minikanren/relations.sx index 2475125a..b86b5e3b 100644 --- a/lib/minikanren/relations.sx +++ b/lib/minikanren/relations.sx @@ -68,6 +68,11 @@ (define palindromeo (fn (l) (fresh (rev) (reverseo l rev) (== l rev)))) +(define prefixo (fn (p l) (fresh (rest) (appendo p rest l)))) + +(define suffixo (fn (s l) (fresh (front) (appendo front s l)))) + + (define lengtho (fn @@ -84,7 +89,6 @@ ((conso a l p)) ((fresh (h t pt) (conso h t l) (conso h pt p) (inserto a t pt)))))) - (define permuteo (fn diff --git a/lib/minikanren/tests/prefix-suffix.sx b/lib/minikanren/tests/prefix-suffix.sx new file mode 100644 index 00000000..7237ef1d --- /dev/null +++ b/lib/minikanren/tests/prefix-suffix.sx @@ -0,0 +1,76 @@ +;; lib/minikanren/tests/prefix-suffix.sx — appendo-derived sublist relations. + +(mk-test + "prefixo-empty" + (run* q (prefixo (list) (list 1 2 3))) + (list (make-symbol "_.0"))) + +(mk-test + "prefixo-full" + (run* + q + (prefixo + (list 1 2 3) + (list 1 2 3))) + (list (make-symbol "_.0"))) + +(mk-test + "prefixo-partial" + (run* + q + (prefixo + (list 1 2) + (list 1 2 3 4))) + (list (make-symbol "_.0"))) + +(mk-test + "prefixo-mismatch-fails" + (run* + q + (prefixo + (list 1 3) + (list 1 2 3))) + (list)) + +(mk-test + "prefixo-enumerates-all" + (run* q (prefixo q (list 1 2 3))) + (list + (list) + (list 1) + (list 1 2) + (list 1 2 3))) + +(mk-test + "suffixo-empty" + (run* q (suffixo (list) (list 1 2 3))) + (list (make-symbol "_.0"))) + +(mk-test + "suffixo-full" + (run* + q + (suffixo + (list 1 2 3) + (list 1 2 3))) + (list (make-symbol "_.0"))) + +(mk-test + "suffixo-partial" + (run* + q + (suffixo + (list 2 3) + (list 1 2 3))) + (list (make-symbol "_.0"))) + +(mk-test + "suffixo-enumerates-all" + (run* q (suffixo q (list 1 2 3))) + (list + (list 1 2 3) + (list 2 3) + (list 3) + (list))) + +(mk-tests-run!) diff --git a/plans/minikanren-on-sx.md b/plans/minikanren-on-sx.md index cb59ed9b..a12b67b3 100644 --- a/plans/minikanren-on-sx.md +++ b/plans/minikanren-on-sx.md @@ -173,6 +173,7 @@ _(none yet)_ _Newest first._ +- **2026-05-08** — **prefixo + suffixo**: classic appendo-derived sublist relations. (prefixo p l) ≡ p ⊕ ? = l; (suffixo s l) ≡ ? ⊕ s = l. Both enumerate all prefixes/suffixes when given a fresh first arg. 9 new tests, 398/398 cumulative. - **2026-05-08** — **palindromeo**: 2-line definition (reverseo + ==). Succeeds when a list reads the same forwards and backwards. 7 new tests, 389/389 cumulative. - **2026-05-08** — **not-membero**: relational "x is not a member of l". Uses `nafc + ==` per element (the same skeleton all-distincto uses).