La biblioteca StreamMemo para Coq ilustra cómo memorizar una función f : nat -> A
sobre los números naturales. En particular cuando f (S n) = g (f n)
, imemo_make
comparte el cálculo de llamadas recursivas.
Supongamos que, en lugar de números naturales, queremos memorizar funciones recursivas sobre árboles binarios:
Inductive binTree : Set :=
| Leaf : binTree
| Branch : binTree -> binTree -> binTree.
Supongamos que tenemos una función f : binTree -> A
que es estructuralmente recursiva, lo que significa que hay una función g : A -> A -> A
tal que f (Branch x y) = g (f x) (f y)
. ¿Cómo construimos una tabla de notas similar para f
Coq de modo que se compartan los cálculos recursivos?
En Haskell, no es demasiado difícil construir una tabla de notas (ver MemoTrie por ejemplo) y atar el nudo. Claramente, tales tablas de notas son productivas. ¿Cómo podemos organizar las cosas para convencer a un lenguaje mecanografiado de manera dependiente de que acepte que este nudo sea productivo?
Aunque especifiqué el problema en Coq, me encantaría recibir una respuesta en Agda o en cualquier otro lenguaje de tipo dependiente.
go
valor es una función de un parámetro Tamaño. En general, no se comparte entre llamadas a funciones independientes con el mismo valor. Esto probablemente se puede solucionar agregando una declaración let en la definición deh (Branch l r)
. En segundo lugar, la definición estratificada deBT
significa que dos, de otro modo árboles idénticos, tendrán valores diferentes cuando ocurran en niveles diferentes. Estos valores distintos no se compartirán en el MemoTrie.