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

欢迎!请参阅 关于 页面获取更多此功能的信息。

0 投票
core.logic

conda 和 condu 的语义特别重视每个子句的头部,但是建立在它们之上的 core.logic 的模式匹配宏将主体合并到头部中。这意味着在决定选择哪一行时,考虑的是主体位置中的每个表达式,而不仅仅是头部位置中的表达式。这是因为在整个子句都被一个新的表达式包裹起来以绑定在模式中出现的隐式指定的 lvars。

为了说明:

`
(matcha ['a]

[['a] u#]
[['a] s#])

;; 展开为

(conda
[(fresh [] (== 'a 'a) u#)]
[(fresh [] (== 'a 'a) s#)])

;; 这与

(conda
[(== 'a 'a) u#]
[(== 'a 'a) s#])

`

理论上,我们可以设计一个新的系统来结合 conda 的语义与模式匹配。至少,我认为这些有问题的宏应该在它们的文档字符串中带有警告,说明这种语义差异。

我怀疑这也会使“第三条诫命”警告适用于整个行,而不仅仅是头部/问题,但我还没有调查这个问题。

以下是一个展示意义差异的示例:

`
;; 这不会成功,因为我们承诺了第一行,
;; 因为问题成功,但在主体中失败。

(run* [q]
(conda
[(== 'a 'a) u#]
[(== 'a 'a) s#]))

;; => ()

;; 这会成功,因为整个行被用来确定要承诺哪一行,
;; 而不仅仅是头部模式匹配子句。所以当第一行失败时,
;; 会尝试第二行。

(run* [q]
(matcha ['a]
[['a] u#]
[['a] s#]))

;; => (_0)
`

4 个答案

0 投票

评论由:austinhaas 发布

仅供参考

{quote}

第三条诫命

如果在确定 conda(或 condu)线路的问题之前,一个变量是新的,那么它必须在该线路的提问中保持新鲜。
{quote}

来自《逻辑方案师》。

0 投票
回答:[链接](../../index.php/7241/matcha-matchu-are-not-faithful-to-the-semantics-conda-condu?show=7328#a7328) 由 jira 回答

评论者:dnolen

很好,我需要思考一下这个问题。

0 投票
回答:[链接](../../index.php/7241/matcha-matchu-are-not-faithful-to-the-semantics-conda-condu?show=7326#a7326) 由 jira 回答

评论者:dnolen

问题在于我们依赖于 conde 宏,它并不很灵活。我们可能应该在更低一级做些什么,所以可以包装每个 conde 行在一个 let 中,该 let 构建逻辑变量,然后确保所有头部统一都在一个 fresh 中包装,以便保留 conda/u 的语义。

0 投票
回答:[链接](../../index.php/7241/matcha-matchu-are-not-faithful-to-the-semantics-conda-condu?show=7325#a7325) 由 jira 回答
参考:https://clojure.atlassian.net/browse/LOGIC-129(由 austinhaas 报告)
...