Á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.