1

我确定这一定是一个愚蠢的问题,但我该如何处理 core.logic 中的目标列表?

(run* [g]
   (f))

(defn f[]
  '(succeed succeed)) 

将抛出异常,因为run*不需要列表。我觉得我需要做(apply all (f)),但all它是一个宏,所以这不起作用。

解决方案是什么?我觉得我在这里遗漏了一些微不足道的东西......

阿德里安。

4

3 回答 3

1

这似乎有效:

(everyg succeed (f))

如果有更好或至少更惯用的解决方案,我仍然感兴趣。

于 2013-10-14T12:19:54.840 回答
1

如果您的目标仅采用一个参数,那么您可以按照另一个答案中的建议使用everyg 。基本上 (everygg coll) 是当目标 g 在 coll 的每个元素上成功时成功的目标。因此 coll 不是目标的集合,而是 g 的单个参数的集合。这仍然有帮助,因为与project结合使用,可以编写:

(defn applyg
  [g v]
  "Goal that succeeds when the goal g applied to v succeeds.
  Non-relational as g must be ground."
  (project [g] (everyg g [v])))

当有一系列目标要应用时:

(defna apply-collg
  [gcoll v]
  ([() _])
  ([[gh . gt] _] (applyg gh v) (apply-collg gt v)))

使用pred从 clojure 谓词中生成目标,测试变得很容易:

(run* [q] (apply-collg [#(pred % pos?) #(pred % odd?)] 1))
=> (_0)
(run* [q] (apply-collg [#(pred % pos?) #(pred % odd?)] 2))
=> ()

如果要应用的目标采用 2 个或更多参数,则只需将它们转换为采用单个参数集合的目标。

我对 core.logic 还是很陌生,所以欢迎发表评论。

于 2014-07-23T11:35:18.817 回答
0

我还没有尝试过,但是查看http://www.clojure.net/2012/10/02/More-core.logic/似乎有类似的事情使用这个结构:

(def f (all
         succeed
         succeed))
于 2013-10-14T11:54:49.160 回答