请在 2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!有关此工作的更多信息,请查看 关于 页面。

0
core.logic

目前我找不到一种方式来启用自定义数据类型以在两个方向上与序列对象进行统一。您可以使用 IUnifyTerms 在一个方向上使其工作,但不可能在另一个方向上使其工作(即序列对象首先是)。

问题似乎出在以下代码中

`
(defn unify-with-sequential* [u v s]
(cond

(sequential? v)
(if (and (counted? u) (counted? v)
      (not= (count u) (count v)))
  nil
  (loop [u u v v s s]
    (if (seq u)
      (if (seq v)
        (if-let [s (unify s (first u) (first v))]
          (recur (next u) (next v) s)
          nil)
        nil)
      (if (seq v) nil s))))

(lcons? v) (unify-terms v u s)
:else nil))

`

如果最后的 nil 可以用一个协议(IUnifyTermsReversed ???IUnifyWithSequential ???)调用代替,那么我相信这会使它更可扩展。

9 个答案

0

评论由:dnolen

我假设您不想您的数据类型实现 ISequential?

0

评论由:mikera

这是不希望的,因为一个表达式也可以是一个叶子节点

(+ 3 X) ;; 作为序列是OK的
7 ;; 绝对不是序列!

因此,使表达式实现 ISequential 是有问题的,并会破坏所有类型的协议.....

尝试将叶子节点与序列对象统一将当然失败,但这是我需要自己实现的逻辑(我想是吧?)

0

评论由:dnolen

我还是不明白,因为我缺少关于您用例的一些上下文。您有没有一个具体的 core.logic 示例,您认为应该可以工作呢?

0

评论由:mikera

当然,这里是我的测试用例

(let [ex1 (ex [+ 1 X])] ;; 包含 (+ 1 X) 的表达式 (is (= [(ex X)] (run* [q] (fresh [op p] (== [op p q] ex1))))) ;; 失败 (is (= [(ex X)] (run* [q] (fresh [op p] (== ex1 [op p q]))))) ;; 成功 )

第一种情况失败了(因为 unify-with-sequential* 返回 nil,如上所述)。第二种情况是好的,因为它通过了我自己的 IUnifyTerms 实现。我可能是错的,但我认为我无法在不改变 core.logic 本身的情况下使其工作。

0

评论由:dnolen

我们曾经支持双向统一,但这需要实现大量协议。最近我一直在考虑是否可能提供强制协议,就像 ICoerceToSequential 一样。

0

评论由:mikera

我认为如果自定义数据结构要成为 core.logic 中的第一类公民,则必须以某种方式支持双向统一。

我明白了如何通过 ICoerceToSequential 来实现这一点,这可能是一个不错的解决方案。我们在 core.matrix 中也做了类似的事情(处理不同后端矩阵实现之间的强制转换)。

0

评论由:dnolen

自定义数据结构已经是第一类的了。我们是否应该允许自定义类型使用 core Clojure 接口/协议/类型进行重载统一,完全是另一码事。

很抱歉造成混乱。我不清楚为什么您想使序列化工作,从您的例子来看,您已经有一个适当的表达式类型,您为什么要与序列化进行统一呢?

0

评论由:mikera

如果您的数据结构是“类序列”结构(并非严格按照顺序排列,但在概念上等同于序列),这可能非常重要。我的自定义表达式类型就是一个例子,例如,出于互操作性原因,java.util.ArrayList 等类似的事物也会让人想到。

实际上,我暂时回到了使用常规列表,所以这对我的问题并不是一个障碍。但这可能仍然值得考虑。

这种统一方法的几个优点似乎包括
a) 符号化 - 您可以使用常规的 Clojure 列表和向量来与类似序列的东西进行统一
b) 效率 - 当不需要时避免创建新的自定义对象(尽管在大多数情况下成本可能微不足道,无需考虑...)

当然,您可能会决定避免这些复杂的问题更简单、更纯净,这是可以理解的。但拥有所有这些很好的可扩展协议,却无法完全将这些功能扩展到自定义类型...这似乎不公平。

0
参考: https://clojure.atlassian.net/browse/LOGIC-123(由 mikera 报告)
...