;; lib/minikanren/nafc.sx — Phase 5 piece C: negation as finite failure. ;; ;; (nafc g) ;; succeeds (yields the input substitution) if g has zero answers ;; against that substitution; fails (mzero) if g has at least one. ;; ;; Caveat: `nafc` is unsound under the open-world assumption. It only ;; makes sense for goals over fully-ground terms, or with the explicit ;; understanding that adding more facts could flip the answer. Use ;; `(project (...) ...)` to ensure the relevant vars are ground first. ;; ;; Caveat 2: stream-take forces g for at least one answer; if g is ;; infinitely-ground (say, a divergent search over an unbound list), ;; nafc itself will diverge. Standard miniKanren limitation. (define nafc (fn (g) (fn (s) (let ((peek (stream-take 1 (g s)))) (if (empty? peek) (unit s) mzero)))))