如何处理core.logic中的目标列表

时间:2013-10-14 10:43:01

标签: clojure clojure-core.logic

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

(run* [g]
   (f))

(defn f[]
  '(succeed succeed)) 

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

解决方案是什么?我觉得我在这里错过了一些显而易见的事情......

阿德里安。

3 个答案:

答案 0 :(得分:1)

这似乎有效:

(everyg succeed (f))

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

答案 1 :(得分:1)

如果您的目标只使用一个参数,那么您可以按照另一个答案中的建议使用everyg。基本上(everyg g 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还很陌生,所以欢迎提出意见。

答案 2 :(得分:0)

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

(def f (all
         succeed
         succeed))