생각해 볼 질문
데이터 생성자는 대수 단순화와 미분 규칙을 어떻게 나눌까요?
- 숫자와 변수와 합과 곱을 표현식 데이터로 구분하기
- 합과 곱의 미분 규칙을 재귀적으로 적용하기
- 생성자에서 0과 1과 숫자 사례 단순화하기
- 반환된 도함수를 새 표현식 트리로 읽기
deriv는 표현식 데이터의 모양에 따라 동작합니다. 숫자는 0이 되고 선택한 변수는 1이 되며 합이나 곱 리스트는 피연산자를 재귀적으로 미분합니다.
make-sum과 make-product가 표현 정리를 맡습니다. 0을 더하는 경우와 0 또는 1을 곱하는 경우를 없애고 숫자끼리는 계산하므로 미분 분기에서는 수학 규칙을 단순화 세부 사항과 섞지 않아도 됩니다.
SICP 코드UTF-8 1,188 / 1,048,576바이트
(begin
(define (=number? expression number)
(and (number? expression) (= expression number)))
(define (make-sum left right)
(cond ((=number? left 0) right)
((=number? right 0) left)
((and (number? left) (number? right)) (+ left right))
(else (list '+ left right))))
(define (make-product left right)
(cond ((or (=number? left 0) (=number? right 0)) 0)
((=number? left 1) right)
((=number? right 1) left)
((and (number? left) (number? right)) (* left right))
(else (list '* left right))))
(define (deriv expression variable)
(cond ((number? expression) 0)
((symbol? expression)
(if (eq? expression variable) 1 0))
((eq? (car expression) '+)
(make-sum (deriv (cadr expression) variable)
(deriv (caddr expression) variable)))
((eq? (car expression) '*)
(make-sum
(make-product (cadr expression)
(deriv (caddr expression) variable))
(make-product (deriv (cadr expression) variable)
(caddr expression))))))
(deriv '(* x (+ x 3)) 'x))
예제
예상 결과첫 프로그램은 (+ x (+ x 3))을 반환합니다. 두 번째 프로그램은 (+ 3 (+ x x))을 반환합니다.
실행 추적에서 볼 점deriv가 인용된 트리를 내려가는 과정을 따라간 뒤 make-sum과 make-product가 결과를 다시 만들며 0과 1 사례를 없애는 모습을 보세요. 반환된 리스트는 표현식 데이터입니다. 고정 한도의 실행 흐름은 선택한 식의 전체 기호 미분 과정을 기록합니다.
직접 해보기프로그램을 수정하고 결과를 비교해 보세요.
'(* x (* x x))를 x에 대해 미분하세요. 이 생성자들이 남길 단순화 전 반복 항을 먼저 예상해 보세요.
힌트 보기
곱 노드 두 곳에서 모두 곱의 미분 법칙을 적용하세요. 이 생성자는 0과 1과 숫자 둘의 계산만 단순화합니다.