Scheme中的一般记忆

时间:2016-04-19 09:52:26

标签: scheme memoization

我已被分配作业在计划中制作一般记忆程序,到目前为止,它适用于采用一个参数的程序,但是当提供超过1时它似乎是最后一个参数失败。它也未能记住不带参数的程序。

非常感谢任何帮助。

(define mem
  (lambda (mem-it func)
    (let ((table (make-table) )(func-store func))
      (cond
        ((equal? mem-it 'memoize)         
         (lambda args
           (if (null? args)
               func
               (let ((prev (lookup args table)))
                 (or prev
                     (let ((result (apply func args)))
                       (insert! args result table)
                       result))))))

        ((equal? mem-it 'unmemoize)
         (func-store))

        (else (display "No Such command"))))))

这是我到目前为止所拥有的

(define (test-proc . args)
  (display "computing test-proc of ")
  (display args)
  (newline)
  (if (null? args)
      0
      (+ (expt (- 42 (car args)) 2)
         (apply test-proc (cdr args)))))

这是提供的测试程序

当我尝试运行以下测试时发生错误

(set! test-proc (mem 'memoize  test-proc))
(test-proc 40 41 42 43 44)

以下是使用的其他程序

  (define (make-table)
    (list '*table*))

  (define (lookup key table)
    (let ((record (assoc key (cdr table))))
      (and record (cdr record))))

 (define (insert! key value table)
   (let ((record (assoc key (cdr table))))
     (if record
        (set-cdr! record value)
         (set-cdr! table 
                   (cons (cons key value) (cdr table))))))

1 个答案:

答案 0 :(得分:1)

您的memoizarion过程有一个功能,它在没有传递参数时返回实现过程:

((mem 'memoize test-proc)) ; ==> test-proc

由于此功能,测试程序的基本情况永远不会发生,因此(test-proc 1)您可以用表达式(+ 1681 test-proc)替换它,这将表示错误,因为test-proc不是号。

最好使用独特的魔术值:

(define +GET-PROC+ (list "get-proc"))
(test-proc +GET-PROC+) ; ==> original-test-proc

由于我们正在制作一个列表,因此eq?只有数据。在R6RS中,您可以避免导出,以便使用memoization的代码实际上无法访问它。所有看起来像("get-proc")的列表都不会是eq?,因此可以在不获取原始过程的情况下将其用作参数。

由于您没有使用(rnrs hashtables)SRFI-69中的标准哈希过程,因此我无法对其进行检查,但由于您使用列表作为密钥,因此哈希表必须使用equal?作为测试。在大多数lisps中使用哈希表时,这通常是令人沮丧的原因。