Scheme如何评估男人或男孩的测试?

时间:2015-06-26 02:20:29

标签: lambda functional-programming scheme lisp interpreter

这是Man or boy测试方案代码:

(define (A k x1 x2 x3 x4 x5)
  (define (B)
    (set! k (- k 1))
    (A k B x1 x2 x3 x4))
  (if (<= k 0)
      (+ (x4) (x5))
      (B)))

为了简化评估过程,我将其重写为:

(define (A k x1 x2)
  (define (B)
    (set! k (+ k -1))
    (A k B x1))
  (if (> 1 k)
      (x2)
      (B)))

我无法理解为什么(A 2 (lambda () 1) (lambda () -1))会返回1。

任何人都可以解释Scheme解释器如何逐步评估此表达式。如果您可以附加环境图表,那就更好了:)

2 个答案:

答案 0 :(得分:8)

The question is very subtle, and in the first moment I thought that the call would cause an infinte loop. But the real affair is the following:

Let's start calling F1 and F2 the two functions passed to A the first time, that is

F1 = (lambda() 1)
F2 = (lambda() -1)

So, after the first call of (A 2 F1 F2), A establishes the following environment, that we will name E1:

Environment E1

The test is now false, so A calls B1. B1 first decrements k in E1, then calls again A, passing 1, itself, and x1, which is F1. So this is the call with parameters substituted with their values: (A 1 B1 F1). And the new environment established by this call (E2) is shown in the following picture:

enter image description here

The test is still false, so A calls B2, which first modifies k in E2, then calls A with 0, itself, and x1 (which now is B1). So the call is (A 0 B2 B1), and the new set of environments is now:

enter image description here

The test is now true, so A call x2, which is B1. Now B1 modifies k in its environment (which is E1), and then calls A with 0, itself, and the value of x1, which, in E1, is F1. So the call is (A 0 B1 F1) and the environment established by this call is depicted in the next figure:

enter image description here

And finally, after checking that the test is true, A calls x2, that is F1, which returns 1. At last!

答案 1 :(得分:2)

我建议在DrRacket的Stepper中检查程序。 Stepper允许您检查计算中的各个步骤。 你甚至可以回去。

唯一的问题是程序原样不能在步进器中运行。 因此我做了一些细微的修改,我希望它足够接近。

(define (A k x1 x2)
  (local [(define (B _) (A (- k 1) B x1))]
    (if (< k 2) (x2 '_) (B '_))))

(A 2 (lambda (_) 1) (lambda (_) -1))

该计划将在正常计划中:

(define (A k x1 x2)
  (define (B _) (A (- k 1) B x1))
  (if (< k 2) (x2 '_) (B '_)))

但教学语言要求您使用local来进行本地定义。 此外,我已将参数_添加到B。它永远不会被使用。教学语言至少需要一个参数,所以我添加一个参数,然后忽略它。

以下是如何计算一步的屏幕截图:

enter image description here