;; lib/minikanren/tests/cyclic-graph.sx — demonstrates the naive-patho ;; behaviour on a cyclic graph. Without Phase-7 tabling/SLG, the search ;; produces ever-longer paths revisiting the cycle. `run n` truncates; ;; `run*` would diverge. (define cyclic-edges (list (list :a :b) (list :b :a) (list :b :c))) (define cyclic-edgeo (fn (x y) (membero (list x y) cyclic-edges))) (define cyclic-patho (fn (x y path) (conde ((cyclic-edgeo x y) (== path (list x y))) ((fresh (z mid) (cyclic-edgeo x z) (cyclic-patho z y mid) (conso x mid path)))))) ;; --- direct edge --- (mk-test "cyclic-direct" (run 1 q (cyclic-patho :a :b q)) (list (list :a :b))) ;; --- runs first 5 paths from a to b: bare edge, then increasing ;; numbers of cycle traversals (a->b->a->b, etc.) --- (mk-test "cyclic-enumerates-prefix-via-run-n" (let ((paths (run 5 q (cyclic-patho :a :b q)))) (and (= (len paths) 5) (and (every? (fn (p) (= (first p) :a)) paths) (every? (fn (p) (= (last p) :b)) paths)))) true) (mk-test "cyclic-finds-c-via-cycle-or-direct" (let ((paths (run 3 q (cyclic-patho :a :c q)))) (and (>= (len paths) 1) (some (fn (p) (= p (list :a :b :c))) paths))) true) (mk-tests-run!)