Álgebra computacional para Clojure

Versão curta: Estou interessado em algum código Clojure que me permita especificar as transformações de x (por exemplo, permutações, rotações) sob as quais o valor de uma função f (x) é invariável, para que eu possa gerar com eficiência uma sequência de x que satisfazem r = f (x). Existe algum desenvolvimento na álgebra computacional para Clojure? Para um exemplo (trivial)

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

Eu poderia ligar (pré-imagem f # {0}) e retornaria com eficiência # {3 4 7}. Naturalmente, também seria capaz de anotar o codomain corretamente. Alguma sugestão?

Versão mais longa: Eu tenho um problema específico que me interessa em descobrir sobre o desenvolvimento de álgebra computacional para Clojure. Alguém pode me apontar para esse projeto? Meu problema específico envolve encontrar todas as combinações de palavras que satisfaçam F (x) = r, onde F é uma função de classificação er um número inteiro positivo. No meu caso particular, f pode ser calculado como uma soma

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

Além disso, eu tenho um conjunto de conjuntos disjuntos S = {s_i}, de modo que f (a) = f (b) para a, b em s, s em S. Portanto, uma estratégia para gerar todos os x de modo que F (x) = r deve confiar nessa fatoração de F e na invariância de f sob cada s_i. Em palavras, calculo todas as permutações de sites que contêm elementos de S que somam r e os componho com todas as combinações dos elementos em cada s_i. Isso é feito de maneira desleixada no seguinte:

(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)))))))))

Isso faz o trabalho, mas perde a imagem subjacente. Por exemplo, se a operação associativa fosse um produto em vez de uma soma, eu teria que reescrever partes.

questionAnswers(3)

yourAnswerToTheQuestion