Как бороться со списком целей в core.logic

Я уверен, что это глупый вопрос, но как мне разобраться со списком целей в core.logic?

(run* [g]
   (f))

(defn f[]
  '(succeed succeed)) 

Выкину исключение, так как run* не ожидает список. Я чувствую, что мне нужно сделать (apply all (f)), но all это макрос, так что это не работает.

Какое решение? Я чувствую, что упускаю что-то тривиально очевидное здесь...

Адриан.

3 ответа

Решение

Если ваши цели принимают только один параметр, вы можете использовать EveryG, как это предлагается в другом ответе. По сути (каждый g g coll) - это цель, которая достигает успеха, когда цель g достигает успеха для каждого элемента coll. Следовательно, coll - это не набор целей, а набор параметров для g. Это все еще помогает, потому что в сочетании с проектом это позволяет написать:

(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, поэтому комментарии приветствуются.

Это похоже на работу:

(everyg succeed (f))

Мне все еще интересно, есть ли лучшее или хотя бы более идиоматическое решение.

Я не пробовал этого, но, глядя на http://www.clojure.net/2012/10/02/More-core.logic/ похоже, что с использованием этой конструкции есть нечто подобное:

(def f (all
         succeed
         succeed))
Другие вопросы по тегам