mk: foldl-o — relational left fold
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s

Complement to foldr-o. The combiner relation has signature
(acc head new-acc) — accumulator first.

Examples:
  (foldl-o pluso-i (list 1 2 3 4 5) 0 q)  -> (15)
  (foldl-o *o-i    (list 1 2 3 4)   1 q)  -> (24)
  (foldl-o (fn (acc x r) (conso x acc r))  ; flipped conso
           (list 1 2 3 4) (list) q)        -> ((4 3 2 1))   ; reverse

5 new tests, 510/510 cumulative.
This commit is contained in:
2026-05-08 12:23:40 +00:00
parent c51d52dae2
commit f5ab66e1a3
3 changed files with 58 additions and 1 deletions

View File

@@ -64,6 +64,14 @@
((nullo l) (== result acc))
((fresh (a d r-rest) (conso a d l) (foldr-o rel d acc r-rest) (rel a r-rest result))))))
(define
foldl-o
(fn
(rel l acc result)
(conde
((nullo l) (== result acc))
((fresh (a d new-acc) (conso a d l) (rel acc a new-acc) (foldl-o rel d new-acc result))))))
(define
membero
(fn
@@ -80,6 +88,7 @@
((nullo l))
((fresh (a d) (conso a d l) (nafc (== a x)) (not-membero x d))))))
(define
subseto
(fn
@@ -88,7 +97,6 @@
((nullo l1))
((fresh (a d) (conso a d l1) (membero a l2) (subseto d l2))))))
(define
reverseo
(fn

View File

@@ -0,0 +1,48 @@
;; lib/minikanren/tests/foldl-o.sx — relational left fold.
(mk-test
"foldl-o-empty"
(run* q (foldl-o pluso-i (list) 42 q))
(list 42))
(mk-test
"foldl-o-sum"
(run*
q
(foldl-o
pluso-i
(list 1 2 3 4 5)
0
q))
(list 15))
(mk-test
"foldl-o-product"
(run*
q
(foldl-o
*o-i
(list 1 2 3 4)
1
q))
(list 24))
(mk-test
"foldl-o-reverse-via-flip-conso"
(run*
q
(foldl-o
(fn (acc x r) (conso x acc r))
(list 1 2 3 4)
(list)
q))
(list (list 4 3 2 1)))
(mk-test
"foldl-o-with-init"
(run*
q
(foldl-o pluso-i (list 1 2 3) 100 q))
(list 106))
(mk-tests-run!)

View File

@@ -173,6 +173,7 @@ _(none yet)_
_Newest first._
- **2026-05-08** — **foldl-o (relational left fold)**: complement to foldr-o. Combiner has args (acc, head) -> new-acc. (foldl-o pluso-i (1 2 3 4 5) 0 q) -> 15; (foldl-o flipped-conso l () q) reverses l. 5 new tests, 510/510 cumulative.
- **2026-05-08** — **foldr-o (relational right fold)**: takes a 3-arg combiner relation rel, a list, an initial accumulator, produces the result. (foldr-o appendo lists () q) is a flatten; (foldr-o conso l () q) rebuilds l. 4 new tests, 505/505 cumulative.
- **2026-05-08** — **enumerate-i / enumerate-from-i — 500-test milestone**: index-each-element relations. (enumerate-i l result) -> result is l with each element paired with its 0-based index. (enumerate-from-i n l result) starts at n. 5 new tests, **501/501** cumulative.
- **2026-05-08** — **partitiono**: relational partition. (partitiono pred l yes no) splits l so yes contains elements where pred succeeds and no contains the rest. Composes with intarith for numeric predicates. 5 new tests, 496/496 cumulative.