请在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 ;; 完全不是顺序!

因此,使 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

自定义数据结构已经是第一等的。是否应该允许在核心 Clojure 接口/协议/类型中重载自定义类型的统一,完全是另一回事。

很抱歉造成混淆。我不清楚您为什么想让序列工作,从您的示例来看,您似乎有一个合适的表达式类型,您为什么要与序列统一?

0 投票

发表评论的人:mikera

如果您拥有“类似序列”的数据结构,但这些数据结构并不完全按顺序排列,而是从概念上等同于序列,这也许很重要?但如果实际上不完全按顺序排列,这样可能也足够了。我的自定义表达式类型就是一个例子,为了互操作性,我想到java.util.ArrayList等。

碰巧,我已经暂时切换回使用常规列表,因此这个问题对我来说并不是一个阻止因素。但这依然值得思考。

这种统一方法的一些潜在优势包括
a) 符号表示法 - 您可以使用常规的Clojure列表和向量来统一类似序列的数据结构
b) 效率 - 避免在不需要时构建新的自定义对象(尽管大多数情况下这种成本可能是微乎其微的……)

当然,您可能会觉得避免这些复杂性会更简单、更纯粹,这完全可以。但似乎很遗憾不能充分利用所有这些可扩展的协议,而不能完全扩展到自定义类型……

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