Lecture 20: How to Design Eurekas





  1. interesting readings:


  2. Newton's method is a great example of generative recursion and of program editing:
    a neat graph with tangent at some guess R0 => better guess R1

    Here is the math:

    Given:
      f: R -> R
      r: R
    
    Tangent at r:
    
      t(x) - f(r)
      -----------  = f'(r)
        x  -   r 
    
    Therefore the root s of the tangent at r is
    
               f(r)
      s = r - -----
              f'(r)
    

    Okay, so now define a function that does all that:

    #|
       find-root-newton : (number -> number) number number -> number
    
       the result r is such that (abs (f r)) <= TOLERANCE
       
       ASSUMPTION: f is continuous
    |#
    (define (find-root-newton f r0)
      (cond
        ((<= (abs (f r0)) tolerance)
         r)
        (else (find-root-newton f (root-of-tangent f r0)))))
    
    (define (root-of-tangent f r0)
      (- r0 (/ (f r0)
    	   ((d/dx f) r0))))
    

  3. Let's do some EDITING:

    (define (find-root-newton f r0)
      (local ((define (find-root-newton f r0)
    	    (cond
    	      ((<= (abs (f r0)) tolerance)
    	       r)
    	      (else (find-root-newton f (root-of-tangent f r0)))))
    
    	  (define (root-of-tangent f r0)
    	    (- r0 (/ (f r0)
    		     ((d/dx f) r0)))))
        (find-root-newton f r0)))
    
    = ; no need to pass around f when it's all inside
    
    (define (find-root-newton f r0)
      (local ((define (find-root-newton r0)
    	    (cond
    	      ((<= (abs (f r0)) tolerance)
    	       r)
    	      (else (find-root-newton (root-of-tangent r0)))))
    
    	  (define (root-of-tangent f r0)
    	    (- r0 (/ (f r0)
    		     ((d/dx f) r0)))))
        (find-root-newton r0)))
    
    = ; no need to recompute the derivative all the time
    
    (define (find-root-newton f r0)
      (local ((define (find-root-newton r0)
    	    (cond
    	      ((<= (abs (f r)) tolerance)
    	       r)
    	      (else (find-root-newton (root-of-tangent r0)))))
    
    	  (define (root-of-tangent f r0)
    	    (- r0 (/ (f r0)
    		     (fprime r0))))
    	  
    	  (define fprime (d/dx f)))
        (find-root-newton r0)))
    


  4. What's the receipe? The same old steps as before:
    1. data analysis
    2. contract, header, purpose
    3. program examples -- emphasis on "eureka"
    4. template -- reflects "eureka", not data structure
      (define (generative-recursive-fun problem-data)
        (cond
          ((trivially-solvable_1? problem-data)
           (determine-solution_1 problem-data))
          ...
          ((trivially-solvable_N? problem-data)
           (determine-solution_N problem-data))
          (else
            (combine-solutions
      	problem-data
      	(generative-recursive-fun (generate-problem_1 problem-data))
      	...
      	(generative-recursive-fun (generate-problem_N problem-data))))))
      
    5. definition -- template, each "function" needs to be defined/filled in
    6. test -- examples
    7. termination: why do these algorithms terminate?

    Termination argument:

    NEWTON when it doesn't terminate: If f'(guess) = 0, the algorithm does not terminate; it loops for ever.

    QUICK-SORT: if we use

    (quick-sort (filter (lambda (x) (>= x pivot)) alon))
    we never terminate -- because there will always be at least one item in this list.





Matthias Felleisen This page was generated on Fri Apr 9 09:17:38 CDT 1999.