mk: phase 4B — reverseo + lengtho, 10 new tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
reverseo: standard recursive definition via appendo. Forward works in run*; backward (input fresh, output ground) works in run 1 but run* diverges trying to enumerate the unique answer (canonical TRS issue with naive reverseo). lengtho: Peano encoding (:z / (:s :z) / (:s (:s :z)) ...) so it works relationally in both directions without arithmetic-as-relation. Forward returns the Peano length; backward enumerates lists of a given length. 162/162 cumulative.
This commit is contained in:
@@ -49,3 +49,19 @@
|
||||
(conde
|
||||
((fresh (d) (conso x d l)))
|
||||
((fresh (a d) (conso a d l) (membero x d))))))
|
||||
|
||||
(define
|
||||
reverseo
|
||||
(fn
|
||||
(l r)
|
||||
(conde
|
||||
((nullo l) (nullo r))
|
||||
((fresh (a d res-rev) (conso a d l) (reverseo d res-rev) (appendo res-rev (list a) r))))))
|
||||
|
||||
(define
|
||||
lengtho
|
||||
(fn
|
||||
(l n)
|
||||
(conde
|
||||
((nullo l) (== n :z))
|
||||
((fresh (a d n-1) (conso a d l) (== n (list :s n-1)) (lengtho d n-1))))))
|
||||
|
||||
@@ -172,4 +172,56 @@
|
||||
(run* q (membero q (list "a" "b" "c")))
|
||||
(list "a" "b" "c"))
|
||||
|
||||
;; --- reverseo ---
|
||||
|
||||
(mk-test
|
||||
"reverseo-forward"
|
||||
(run* q (reverseo (list 1 2 3) q))
|
||||
(list (list 3 2 1)))
|
||||
|
||||
(mk-test "reverseo-empty" (run* q (reverseo (list) q)) (list (list)))
|
||||
|
||||
(mk-test
|
||||
"reverseo-singleton"
|
||||
(run* q (reverseo (list 42) q))
|
||||
(list (list 42)))
|
||||
|
||||
(mk-test
|
||||
"reverseo-five"
|
||||
(run*
|
||||
q
|
||||
(reverseo (list 1 2 3 4 5) q))
|
||||
(list (list 5 4 3 2 1)))
|
||||
|
||||
(mk-test
|
||||
"reverseo-backward-one"
|
||||
(run 1 q (reverseo q (list 1 2 3)))
|
||||
(list (list 3 2 1)))
|
||||
|
||||
(mk-test
|
||||
"reverseo-round-trip"
|
||||
(run*
|
||||
q
|
||||
(fresh (mid) (reverseo (list "a" "b" "c") mid) (reverseo mid q)))
|
||||
(list (list "a" "b" "c")))
|
||||
|
||||
;; --- lengtho (Peano-style) ---
|
||||
|
||||
(mk-test "lengtho-empty-is-z" (run* q (lengtho (list) q)) (list :z))
|
||||
|
||||
(mk-test
|
||||
"lengtho-of-3"
|
||||
(run* q (lengtho (list "a" "b" "c") q))
|
||||
(list (list :s (list :s (list :s :z)))))
|
||||
|
||||
(mk-test
|
||||
"lengtho-empty-from-zero"
|
||||
(run 1 q (lengtho q :z))
|
||||
(list (list)))
|
||||
|
||||
(mk-test
|
||||
"lengtho-enumerates-of-length-2"
|
||||
(run 1 q (lengtho q (list :s (list :s :z))))
|
||||
(list (list (make-symbol "_.0") (make-symbol "_.1"))))
|
||||
|
||||
(mk-tests-run!)
|
||||
|
||||
@@ -109,10 +109,13 @@ Key semantic mappings:
|
||||
- [x] `nullo` `l` — l is empty
|
||||
- [x] `pairo` `p` — p is a (non-empty) cons-cell / list
|
||||
- [x] `caro` / `cdro` / `conso` / `firsto` / `resto`
|
||||
- [ ] `reverseo` `l` `r` — reverse of list
|
||||
- [ ] `flatteno` `l` `f` — flatten nested lists
|
||||
- [ ] `permuteo` `l` `p` — permutation of list
|
||||
- [ ] `lengtho` `l` `n` — length as a relation (Peano or integer)
|
||||
- [x] `reverseo` `l` `r` — reverse of list. Forward is fast; backward is `run 1`-clean,
|
||||
`run*` diverges due to interleaved unbounded list search (canonical TRS issue).
|
||||
- [ ] `flatteno` `l` `f` — flatten nested lists (deferred — needs atom predicate)
|
||||
- [ ] `permuteo` `l` `p` — permutation of list (deferred to Phase 5 with `matche`)
|
||||
- [x] `lengtho` `l` `n` — length as a relation, Peano-encoded:
|
||||
`:z` / `(:s :z)` / `(:s (:s :z))` ... matches TRS. Forward is direct;
|
||||
backward enumerates lists of a given length.
|
||||
- [x] Tests: run each relation forwards and backwards (so far 25 in
|
||||
`tests/relations.sx`; reverseo/flatteno/permuteo/lengtho deferred)
|
||||
|
||||
@@ -152,6 +155,10 @@ _(none yet)_
|
||||
|
||||
_Newest first._
|
||||
|
||||
- **2026-05-07** — **Phase 4 piece B — reverseo + lengtho**: reverseo runs forward
|
||||
cleanly and `run 1`-cleanly backward; lengtho uses Peano-encoded lengths so it
|
||||
works as a true relation in both directions (tests use the encoding directly).
|
||||
10 new tests, 162/162 cumulative.
|
||||
- **2026-05-07** — **Phase 4 piece A — appendo canary green**: cons-cell support
|
||||
in `unify.sx` + `(:s head tail)` lazy stream refactor in `stream.sx` + hygienic
|
||||
`Zzz` (gensym'd subst-name) wrapping each `conde` clause + `lib/minikanren/
|
||||
|
||||
Reference in New Issue
Block a user