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) ;; 作为一个序列是可接受的
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
...