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 ;; 绝对不是序列!

因此,使Expression实现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报告)
...