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 提供

自定义数据结构已经是一等公民了。是否允许使用 core Clojure 的接口/协议/类型来重载自定义类型的统一,完全是另一回事。

对不起,造成了混乱。我不太清楚你为什么要使序列工作,从你的例子来看,你似乎已经有了适当的表达式类型,为什么要与序列统一呢?

0 投票

评论由:mikera 提供

如果你有“序列-like”但不是精确序列的数据结构,这可能很重要?但在概念上与序列相当。我的自定义表达式类型就是一个例子,还有出于互操性的原因,比如java.util.ArrayList。

事实上,我暂时又改回了使用常规列表,所以这个问题对我来说不是障碍。但它仍然值得思考。

这种统一方法的几个优点可能包括:
a) 符号标记 - 你可以使用常规的Clojure列表和向量与序列-like对象进行统一
b) 效率 - 当不需要时避免构造新的自定义对象(尽管在大多数情况下成本可能太微不足道,而不值得理会……)

当然,你可能会决定避免这些复杂性会更简单、更纯粹,这是完全可以的。但似乎有点浪费所有这些可扩展的协议,却不能完全将这些功能扩展到自定义类型……

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