Mr *_*per 6 clojure logic-programming minikanren clojure-core.logic
这是一个(希望)简单的逻辑程序,我已经坚持了一段时间.
我在core.logic中有一个由边缘关系表示的DAG,当生成父节点列表时,当我在图中有"菱形"时,我得到重复(我不是在讨论这里的循环).
在这种情况下,有没有办法生成一个明确的父母列表(通过重写父母或类似的东西)?
(defrel edge a b)
(fact edge :a :b)
(fact edge :a :c)
(fact edge :b :d)
(fact edge :c :d)
(defne parento [x y]
([x y] (edge y x))
([x y] (fresh [z]
(edge z x)
(parento z y))))
(run* [q] (parento :d q))
;; => (:b :c :a :a)
Run Code Online (Sandbox Code Playgroud)
我想得到(:b:c:a)并且我想在run*语句中执行它(即将结果包装在一个集合中并不是我的目标).
此外,将"^:tabled"添加到parento似乎可以解决问题,但我不想要tabled介绍的memoization.
如果您像以前那样为边定义了单独的事实,则在不离开关系编程的情况下就无法做到这一点。一种解决方案是简单地将整个结果列表传递给 Clojure 的 set 构造函数。另一种选择是在逻辑程序中一次处理所有节点。
查看此问题的现有 Prolog 解决方案并翻译您找到的内容可能会有所帮助。