Các StreamMemo thư viện cho Coq minh họa cách memoize một chức năng f : nat -> A
so với các số tự nhiên. Đặc biệt khi f (S n) = g (f n)
, các imemo_make
chia sẻ tính toán của các cuộc gọi đệ quy.
Giả sử thay vì số tự nhiên, chúng tôi muốn ghi nhớ các hàm đệ quy trên cây nhị phân:
Inductive binTree : Set :=
| Leaf : binTree
| Branch : binTree -> binTree -> binTree.
Giả sử chúng ta có một hàm f : binTree -> A
đệ quy có cấu trúc, nghĩa là có một hàm g : A -> A -> A
như vậy f (Branch x y) = g (f x) (f y)
. Làm thế nào để chúng tôi xây dựng một bảng ghi nhớ tương tự f
trong Coq sao cho các tính toán đệ quy được chia sẻ?
Trong Haskell, không quá khó để xây dựng một bảng ghi nhớ như vậy ( ví dụ như xem MemTrie ) và thắt nút. Rõ ràng bảng ghi nhớ như vậy là hiệu quả. Làm thế nào chúng ta có thể sắp xếp mọi thứ để thuyết phục một ngôn ngữ gõ phụ thuộc để chấp nhận việc thắt nút như vậy là hiệu quả?
Mặc dù tôi đã chỉ định vấn đề trong Coq, tôi cũng rất vui khi có câu trả lời bằng Agda hoặc bất kỳ ngôn ngữ phụ thuộc nào khác.
go
giá trị là một hàm của tham số Size. Nói chung, không có chia sẻ giữa các lệnh gọi hàm độc lập ở cùng một giá trị. Điều này có thể được khắc phục bằng cách thêm một câu lệnh let trong định nghĩa củah (Branch l r)
. Thứ hai, định nghĩa phân tầngBT
có nghĩa là hai cây, nếu không có hình dạng giống hệt nhau, sẽ có các giá trị khác nhau khi chúng xảy ra ở các cấp độ khác nhau. Những giá trị riêng biệt này sẽ không được chia sẻ trong Bản ghi nhớ.