使用 core.logic 列出唯一的 DAG 父级

Posted

技术标签:

【中文标题】使用 core.logic 列出唯一的 DAG 父级【英文标题】:Listing unique DAG parents with core.logic 【发布时间】:2012-09-15 19:31:38 【问题描述】:

这是一个(希望如此)简单的逻辑程序,我已经坚持了一段时间。

我有一个由 core.logic 中的边关系表示的 DAG,在生成父节点列表时,当我在图中有“菱形”时会得到重复(我不是在谈论循环)。

在这种情况下,有什么方法可以生成不同的父母列表(通过重写 parento 或类似方法)?

(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)

我想得到 (:b :c :a) 并且我想在 run* 语句中执行它(即将结果包装在一个集合中不是我的目标)。

此外,将“^:tabled”添加到 parento 似乎可以解决问题,但我不想要 tabled 引入的记忆。

【问题讨论】:

【参考方案1】:

如果您像之前那样为边定义单独的事实,那么在不离开关系编程的情况下就无法做到这一点。一种解决方案是简单地将整个结果列表传递给 Clojure 的 set 构造函数。另一种选择是在逻辑程序中一次处理所有节点。

查看针对此问题的现有 Prolog 解决方案并翻译您的发现可能会有所帮助。

【讨论】:

感谢您的回复,我一直在阅读 Bratko 并在谷歌上搜索了一下,但没有发现任何直接有用的东西。你能概述一下你提到的“一次性”解决方案吗?干杯...

以上是关于使用 core.logic 列出唯一的 DAG 父级的主要内容,如果未能解决你的问题,请参考以下文章

Clojure core.logic 中的阶乘

如何在 core.logic 中模拟“外部连接”?

在实践中,非关系对 core.logic 意味着啥?

Clojure core.logic 的简单 Prolog

使用 clojure 的 core.logic / minikanren 查找相似的集合

为啥 core.logic 的输出重复给出相同的值?