Álgebra computacional para Clojure

Versión corta: estoy interesado en algún código Clojure que me permita especificar las transformaciones de x (por ejemplo, permutaciones, rotaciones) bajo las cuales el valor de una función f (x) es invariable, de modo que pueda generar eficientemente una secuencia de x que satisfacen r = f (x). ¿Hay algún desarrollo en álgebra informática para Clojure? Por ejemplo (trivial)

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

Podría llamar a (preimage f # {0}) y devolvería eficientemente # {3 4 7}. Naturalmente, también podría anotar el codominio correctamente. ¿Alguna sugerencia?

Versión más larga: tengo un problema específico que me interesa conocer el desarrollo del álgebra computacional para Clojure. ¿Alguien puede señalarme a tal proyecto? Mi problema específico consiste en encontrar todas las combinaciones de palabras que satisfacen F (x) = r, donde F es una función de clasificación yr un número entero positivo. En mi caso particular, f se puede calcular como una suma

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

Además, tengo un conjunto de conjuntos disjuntos S = {s_i}, de modo que f (a) = f (b) para a, b en s, s en S. Entonces, una estrategia para generar todo x tal que F (x) = r debería basarse en esta factorización de F y la invariancia de f debajo de cada s_i. En palabras, calculo todas las permutaciones de sitios que contienen elementos de S que suman r y las compongo con todas las combinaciones de los elementos en cada s_i. Esto se hace bastante descuidadamente en lo siguiente:

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

Esto hace el trabajo pero pierde la imagen subyacente. Por ejemplo, si la operación asociativa fuera un producto en lugar de una suma, tendría que volver a escribir porciones.

Respuestas a la pregunta(3)

Su respuesta a la pregunta