Поиск дерева в Clojure core.logic
Я был озадачен проблемой моделирования в течение некоторого времени, и я должен признаться, что понятия не имею, как я мог бы "правильно" решить ее в core.logic
,
Это очень легко сформулировать: как вы используете дерево (ациклический однонаправленный ориентированный граф) и вершину в нем core.logic
определить цель, которая позволяет lvar быть любой достижимой вершиной из данной вершины?
Я начал с чего-то максимально простого:
(defrel vertex x)
(defrel child)
(def facts
(pldb/db
[vertex 'a]
[vertex 'b] [child 'a 'b]
[vertex 'c] [child 'b 'c]
[vertex 'd] [child 'c 'd]))
Учитывая эту конфигурацию, я стремлюсь определить цель, которая позволит lvar принимать значения в ['a 'b 'c 'd]. Получить вершины с помощью "1 прыжка" очень просто:
(defn reachableo
[a]
(fresh [q]
(child a q)))
и вы можете добавить переменные для 2 прыжков и так далее, но... это можно обобщить? Я думал, чтобы определить список lvar с чем-то вроде
(let [vars (repeatedly lvar)]
(map #(child (nth vars %) (nth vars (inc %)))
(-> vars count dec range))
(all
...))
но несколько попыток спустя, я должен признаться, я не уверен, что это правильный путь.
2 ответа
(pldb/db-rel vertex x)
(pldb/db-rel child parent child)
(def facts
(pldb/db
[vertex 'a]
[vertex 'b] [child 'a 'b]
[vertex 'c] [child 'b 'c]
[vertex 'd] [child 'c 'd]))
Рекурсивная цель:
(defn reachable° [from to]
(l/fresh [v]
(l/conde
[(child from to)]
[(child from v) (reachable° v to)])))
тестирование
=> (pldb/with-db facts
(vec (l/run* [to] (reachable° 'a to))))
[b c d]
Спасибо за вашу помощь!
На самом деле я получил
(defn order-relationo
"Abstract the general pattern of a order relation in a logic, relational way."
[relation x y]
(conde
[(relation x y)]
[(fresh [z]
(relation x z)
(order-relationo relation z y))]))
(def kino
"A goal where the two inputs x and y share kinship: x is an ancestor of y and
y a descandant of x."
(partial order-relationo child))
Я задал этот вопрос, потому что долгое время я не практиковал логическое программирование, но теперь я чувствую, что это снова придет ^^
В любом случае, большое спасибо за ваш ответ, который дает мне дополнительную точку зрения.