Компьютерная алгебра для Clojure

Короткая версия: меня интересует некоторый код Clojure, который позволит мне указать преобразования x (например, перестановки, вращения), при которых значение функции f (x) является инвариантным, так что я могу эффективно генерировать последовательность из x которые удовлетворяют r = f (x). Есть ли какое-то развитие в компьютерной алгебре для Clojure? Для (тривиального) примера

(defn #^{:domain #{3 4 7} 
         :range #{0,1,2}
         :invariance-group :full} 
          f [x]  (- x x))

Я мог бы позвонить (preimage f # {0}), и он бы эффективно вернул # {3 4 7}. Естественно, он также сможет правильно комментировать кодомен. Какие-либо предложения?

Более длинная версия: у меня есть конкретная проблема, которая заставляет меня интересоваться разработкой компьютерной алгебры для Clojure. Кто-нибудь может указать мне на такой проект? Моя конкретная проблема заключается в поиске всех комбинаций слов, которые удовлетворяют F (x) = r, где F - функция ранжирования, а r - положительное целое число. В моем конкретном случае f может быть вычислено как сумма

F (x) = f (x [0]) + f (x [1]) + ... f (x [N-1])

Кроме того, у меня есть набор непересекающихся множеств S = {s_i}, таких что f (a) = f (b) для a, b в s, s в S. Таким образом, стратегия для генерации всех x таких, что F (x) = r должен полагаться на эту факторизацию F и инвариантность f при каждом s_i. Словом, я вычисляю все перестановки сайтов, содержащих элементы S, которые суммируются с r, и составляю их со всеми комбинациями элементов в каждом s_i. Это сделано довольно небрежно в следующем:

(use 'clojure.contrib.combinatorics)
(use 'clojure.contrib.seq-utils)


(defn expand-counter [c]
 (flatten (for [m c] (let [x (m 0) y (m 1)] (repeat y x)))))

(defn partition-by-rank-sum [A N f r]
  (let [M (group-by f A)
    image-A (set (keys M))
    ;integer-partition computes restricted integer partitions,
    ;returning a multiset as key value pairs
    rank-partitions (integer-partition r (disj image-A 0))
    ]
    (apply concat (for [part rank-partitions]
        (let [k (- N (reduce + (vals part)))
          rank-map (if (pos? k) (assoc part 0 k) part) 
          all-buckets (lex-permutations (expand-counter rank-map))
          ]
          (apply concat (for [bucket all-buckets]
        (let [val-bucket (map M bucket)
              filled-buckets (apply cartesian-product val-bucket)]
          (map vec filled-buckets)))))))))

Это делает работу, но не соответствует основной картине. Например, если бы ассоциативная операция была произведением, а не суммой, мне пришлось бы переписать порции.

Ответы на вопрос(1)

Ваш ответ на вопрос