Clojure core.logic порождающий родителей
У меня есть этот код, который делает, как я хочу, он рекурсивно тянет родителей данного человека:
(defn anc [child]
(run* [q]
(conde
[(fresh [?p]
(parento child ?p)
(?== q [child ?p]))]
[(fresh [?p ?gp]
(parento child ?p)
(parento ?p ?gp)
(?== q [ ?p ?gp]))]
[(fresh [?p ?gp ?ggp]
(parento child ?p)
(parento ?p ?gp)
(parento ?gp ?ggp)
(?== q [ ?gp ?ggp]))]
)))
Проблема в том, что для каждого поколения, которое я возвращаюсь, я должен добавить новый тест.
Есть ли способ обобщить это в core.logic?
1 ответ
Решение
Я попробовал что-то, и, надеюсь, это поможет вам:
user=> (defrel parent c p)
user=> (fact parent :b :a)
nil
user=> (fact parent :c :b)
nil
user=> (fact parent :d :c)
nil
user=> (defn anso [c a]
(conde
[(fresh [p x]
(parent c p)
(anso p x)
(appendo [p] x a))]
[(fresh [x]
(parent c x)
(== a [x]))]))
#'user/anso
user=> (last (run* [q] (anso :c q)))
(:b :a)
user=> (last (run* [q] (anso :b q)))
[:a]
user=> (last (run* [q] (anso :d q)))
(:c :b :a)