미분하는 프로그램 3 - Infix 로 입출력하기

semmal의 이미지

입출력을 infix로 하기 위해서는 각 selector에서 첫번째 심볼을 골라내는 car를 cadr로, 두번째 심볼을 골라내는 cadr을 car로 바꿔 처리합니다.

또한, constructor에서 연산자를 첫번재가 아닌 두번째 위치로 지정해주면 됩니다.

negative의 경우에는 연산자가 앞에 있기때문에 거의 그대로 처리해주면 됩니다.

하지만 아직까지 이 미분하는 프로그램은 여러가지면에서 부족합니다.

예를들면, 공식을 하나 추가할때마다 deriv같은 함수의 소스를 일일이 고쳐야하는 것은 큰 단점이라고 볼 수 있습니다.

Object-Oriented에서 주로 보이는 message passing 기법을 쓰면 위의 단점을 해결할 수 있습니다.

다음에는 공식 하나하나를 오브젝트로 보고, 오브젝트만 추가하면 미분하는 프로그램을 확장할 수 있도록 만들어보겠습니다.

(define (deriv exp var)
  (cond ((number? exp) 0)
        ((variable? exp)
         (if (same-variable? exp var) 1 0))
        ((negative? exp) (make-negative (deriv (negand exp) var)))
        ((sum? exp)
         (make-sum (deriv (addend exp) var)
                   (deriv (augend exp) var)))
        ((difference? exp)
         (make-difference (deriv (minuend exp) var)
                          (deriv (subtrahend exp) var)))
        ((product? exp)
         (make-sum
          (make-product (multiplier exp)
                        (deriv (multiplicand exp) var))
          (make-product (deriv (multiplier exp) var)
                        (multiplicand exp))))
        ((exponentiation? exp)
         (make-product
          (make-product (exponent exp) 
                        (make-exponentiation (base exp)
                                             (make-difference (exponent exp) 1)))
          (deriv (base exp) var)))
        (else
         (error "unknown expression type -- DERIV" exp))))
 
(define (variable? x) (symbol? x))
 
(define (same-variable? v1 v2)
  (and (variable? v1) (variable? v2) (eq? v1 v2)))
 
(define (=number? exp num)
  (and (number? exp) (= exp num)))
 
(define (make-sum a1 a2)
  (cond ((=number? a1 0) a2)
        ((=number? a2 0) a1)
        ((and (number? a1) (number? a2)) (+ a1 a2))
        (else (list a1 '+ a2))))
 
(define (make-product m1 m2)
  (cond ((or (=number? m1 0) (=number? m2 0)) 0)
        ((=number? m1 1) m2)
        ((=number? m2 1) m1)
        ((and (number? m1) (number? m2)) (* m1 m2))
        (else (list m1 '* m2))))
 
(define (sum? x)
  (and (pair? x) (eq? (cadr x) '+)))
 
(define (addend s) (car s))
 
(define (augend s) (caddr s))
 
(define (product? x)
  (and (pair? x) (eq? (cadr x) '*)))
 
(define (multiplier p) (car p))
 
(define (multiplicand p) (caddr p))
 
(define (make-negative n)
  (cond ((number? n) (- n))
        (else (list '- n))))
 
(define (negative? x)
  (and (pair? x) (eq? (car x) '-)))
 
(define (negand n) (cadr n))
 
(define (make-difference a1 a2)
  (cond ((=number? a1 0) (make-negative a2))
        ((=number? a2 0) a1)
        ((and (number? a1) (number? a2)) (- a1 a2))
        (else (list a1 '- a2))))
 
(define (difference? x)
  (and (pair? x) (eq? (cadr x) '-)))
 
(define (minuend d) (car d))
 
(define (subtrahend d) (caddr d))
 
(define (make-exponentiation e1 e2)
  (cond ((or (=number? e1 0) (=number? e1 1)) e1)
        ((=number? e2 0) 1)
        ((=number? e2 1) e1)
        ((and (number? e1) (number? e2)) (** e1 e2))
        (else (list e1 '** e2))))
 
(define (exponentiation? x)
  (and (pair? x) (eq? (cadr x) '**)))
 
(define (base e) (car e))
 
(define (exponent e) (caddr e))
 
;; 이전 문제와 답
;(deriv '(+ x 3) 'x)
;;1
;
;(deriv '(* x y) 'x)
;;y
;
;(deriv '(* (* x y) (+ x 3)) 'x)
;;(+ (* x y) (* y (+ x 3)))
;
;(deriv '(- x) 'x)
;;-1
;
;(deriv '(- (* x 3) 4) 'x)
;;3
;
;(deriv '(- (** x 2)) 'x)
;;(- (* 2 x))
 
; infix로 풀어본 문제
(deriv '(x + 3) 'x)
;1
 
(deriv '(x * y) 'x)
;y
 
(deriv '((x * y) * (x + 3)) 'x)
;((x * y) + (y * (x + 3)))
 
(deriv '(- x) 'x)
;-1
 
(deriv '((x * 3) - 4) 'x)
;3
 
(deriv '(- (x ** 2)) 'x)
;(- (2 * x))

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.