sicp 2.2 계층 구조 데이터와 닫힘 성질

32
2.2 계층 구조 데이터와 닫힘 성질 Structure and Interpretation of Computer Programs [email protected] 2014.10.18

Upload: aceigy6322

Post on 19-Jul-2015

140 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Sicp 2.2 계층 구조 데이터와 닫힘 성질

2.2 계층 구조 데이터와닫힘 성질

Structure and Interpretation of Computer Programs

[email protected] 2014.10.18

Page 2: Sicp 2.2 계층 구조 데이터와 닫힘 성질

상자와 화살표 쌍을 나타내기

닫힘 성질로 계층 구조표현 가능

- 차례열(Sequence)

- 나무(Tree)

- 그림 언어(Graphic)

Page 3: Sicp 2.2 계층 구조 데이터와 닫힘 성질

2.2.1 차례열(Sequence) 표현 방법

(cons ⟨a1⟩

(cons ⟨a2⟩

(cons : : :

(cons ⟨an⟩

nil): : :)))

(list ⟨a1⟩ ⟨a2⟩ : : : ⟨an⟩)

리스트 - Cons를 겹쳐 만든 쌍의 차례열

(define one-through-four (list 1 2 3 4))

• one-through-four

- (1 2 3 4)

• (car one-through-four)

- 1

• (cdr one-through-four)

- (2 3 4)

• (car (cdr one-through-four))

- 2

• (cons 10 one-through-four)

- (10 1 2 3 4)

Page 4: Sicp 2.2 계층 구조 데이터와 닫힘 성질

리스트 연산

• ‘cdr연산을 가지고 흝어 내려가는’ 프로그램 기법으로 리스트 연산을 만듬.

• List-ref 프로시져 - 리스트와 수 N을 인자로 받아서, 그 리스트의 n번째 원소를 내놓음.

• List-ref 규칙

– N = 0이면, list-ref의 값은 리스트의car 이다.

– 그렇지 않으면, list-ref는 리스트의cdr에서 n-1번째 원소다.

(define (list-ref items n)

(if (= n 0)

(car items)

(list-ref (cdr items) (- n 1))))

(define squares (list 1 4 9 16 25))

(list-ref squares 3)

16

Page 5: Sicp 2.2 계층 구조 데이터와 닫힘 성질

리스트 연산

• length 프로시져 - 리스트를 인자로받아 리스트의 원소가 몇 개인지 찾음.

• length 규칙– 리스트의 length는 그 리스트의 cdr

의 length에 1을 더한 값이다.

– 빈 리스트의 length는 0이다.

• Null? – 인자가 빈인자인지 판단.

(define (length items)

(if (null? items)

0

(+ 1 (length (cdr items)))))

(define odds (list 1 3 5 7))

(length odds)

4-----------------------------------------------(define (length items)

(define (length-iter a count)

(if (null? a)

count

(length-iter (cdr a) (+ 1 count))))

(length-iter items 0))

(define odds (list 1 3 5 7))

(length odds)

Page 6: Sicp 2.2 계층 구조 데이터와 닫힘 성질

리스트 연산

• ‘리스트 구조를 cdr로 풀어 헤치면서, 이를 cons로 되묶어서 새로운 리스트를 만드는 방법’

• Append 프로시져 – 두 리스트를 인자로 받아 모든 원소를 한데 엮어 새 리스트를 만듬.

• Append 규칙

– List1이 빈 리스트면, 결과는 list2임.

– 그렇지 않으면, list1의 cdr와 list2를append한 다음 , 그 결과에 list1의car를 cons 한 리스트를 만듬.

(define squares (list 1 2 3 4))

(define odds (list 6 7 8 9))

(define (append list1 list2)

(if (null? list1)

list2

(cons (car list1)

(append (cdr list1) list2))))

(append squares odds)

- 1 2 3 4 6 7 8 9

Page 7: Sicp 2.2 계층 구조 데이터와 닫힘 성질

리스트 매핑(Mapping)

• 리스트 연산에서 계산 방법을 요약해서 차수높은 프로시져(Higher-Order Procedure )를만든것이 Map.

• Map – 프로시져 하나와 리스트를인자로 받아, 리스트 원소마다 똑같은 프로시져를적용한 결과를 묶은리스트를 반환.

(define (scale-list items factor)(if (null? items)

null(cons (* (car items) factor)

(scale-list (cdr items)factor))))

(scale-list (list 1 2 3 4 5) 10)

(10 20 30 40 50)

---------------------------------(define items1 (list 1 2 3 4 5))(define factor1 10)

(define (scale-list1 items factor)(map (lambda (x) (* x factor))items))

(scale-list1 items1 factor1)

Page 8: Sicp 2.2 계층 구조 데이터와 닫힘 성질

2.2.2 계층 구조

• 차례열을 원소로하는 차례열을나타낼수 있음.

(cons (list 1 2) (list 3 4))

• 차례열을 원소로 가지는 차례열을 나무(Tree) 꼴로 펼쳐 나타낼수있음.

Page 9: Sicp 2.2 계층 구조 데이터와 닫힘 성질

Count-leaves 프로시져

• Count-leaves 프로시져 - 재귀 처리로 나무 가지를 순회하여 나뭇잎의카운터를 계산.

• Count-leaves 규칙

– 리스트 x의 length는 x의 cdr의length에 1을 더한 값이다.

– 빈 리스트의 length는 0이다.

• Pair 프로시져 – 인자로 받은 값이 쌍인지판단.

#lang scheme ;added

(define x (cons (list 1 2) (list 3 4)))

(length (list x x))

- 2

(count-leaves x)

- 4

;---------------------------------------------

(define (count-leaves x)

(cond ((null? x) 0)

((not (pair? x)) 1)

(else (+ (count-leaves (car x))

(count-leaves (cdr x))))))

Page 10: Sicp 2.2 계층 구조 데이터와 닫힘 성질

나무 매핑

• Map과 재귀 처리 방식을 한데 엮어 나무꼴 데이터를 효과적으로다룰 수 있음.

• scale-tree 프로시져 – 곱할 수와나무를 인자로 받아, 모든 나뭇잎에 곱수가 곱해진 나무를 반환.

• 다른 방법은 나무를 부분 나무의차례열로 보고, map을 사용.

(define (scale-tree tree factor)(cond ((null? tree) null)

((not (pair? tree)) (* tree factor))(else (cons (scale-tree (car tree) factor)

(scale-tree (cdr tree) factor)))))(scale-tree (list 1 (list 2 (list 3 4) 5) (list 6 7)) 10)

-------------------------------------------------------

(define tempTree (list 1 (list 2 (list 3 4) 5) (list 6 7)))

(define (scale-tree tree factor)(map (lambda (sub-tree1)

(if (pair? sub-tree1)(scale-tree sub-tree1 factor)(* sub-tree1 factor)))

tree))

(scale-tree tempTree 10);(10 (20 (30 40) 50) (60 70))

Page 11: Sicp 2.2 계층 구조 데이터와 닫힘 성질

2.2.3 공통 인터페이스로써 차례열의 쓰임새

• 나무꼴 데이터를 인자로

받아서 잎사귀 가운데 홀수인

것만 제곱한 다음에 이것을 모두

더한 값을 반환

------------------------------------

• N보다 작거나 N과 같은

정수 K에 대하여 피보나치 수열

Fib(k) 값을 구한 후 짝수만

모아서 리스트로 묶어내는

프로시져

(define (square x) (* x x))(define (sum-odd-squares tree)(cond ((null? tree) 0)

((not (pair? tree))(if (odd? tree) (square tree) 0))(else (+ (sum-odd-squares (car tree))

(sum-odd-squares (cdr tree))))))

----------------------------------------------------

(define (even-fibs n)(define (next k)(if (> k n)

null(let ((f (fib (k))))(if (even? f)

(cons f (next (+ k 1)))(next (+ k 1))))))

(next 0))

Page 12: Sicp 2.2 계층 구조 데이터와 닫힘 성질

• 처리 과정이 비슷함.

• 그러나 두 프로시져는 신호가 흘러가는 구조를 갖추지 못하였음.

• 따라서 두 프로시저 정의에서는 신호 흐름 방식의 단계별 처리 과정이 확실히 대응하는 부분을 찾기 힘듬.

Page 13: Sicp 2.2 계층 구조 데이터와 닫힘 성질

차례열 연산

• 계산 단계에서 다음 계산 단계로 흘러가는신호를 리스트로 나타내면, 모든 단계별처리 과정을 리스트 연산이 가능함.

• 모듈 방식으로 독립된 부품을 짜 맞추듯이프로그램을 설계

Page 14: Sicp 2.2 계층 구조 데이터와 닫힘 성질

Map

• (map square (list 1 2 3 4 5))

• (1 4 9 16 25)

Page 15: Sicp 2.2 계층 구조 데이터와 닫힘 성질

Filter

(define (filter predicate sequence)(cond ((null? sequence) nil)

((predicate (car sequence))(cons (car sequence)

(filter predicate (cdr sequence))))(else (filter predicate (cdr sequence)))))

(filter odd? (list 1 2 3 4 5))

(1 3 5)

Page 16: Sicp 2.2 계층 구조 데이터와 닫힘 성질

Accumulate

(define (accumulate op initial sequence)(if (null? sequence)

initial(op (car sequence)

(accumulate op initial (cdr sequence)))))

(accumulate + 0 (list 1 2 3 4 5))15

(accumulate * 1 (list 1 2 3 4 5))120

Page 17: Sicp 2.2 계층 구조 데이터와 닫힘 성질

Enumerate

(define (enumerate-tree tree)

(cond ((null? tree) nil)

((not (pair? tree)) (list tree))

(else (append (enumerate-tree (car tree))

(enumerate-tree (cdr tree))))))

(enumerate-tree (list 1 (list 2 (list 3 4)) 5))

(1 2 3 4 5)

(define (enumerate-interval low high)

(if (> low high)

nil

(cons low (enumerate-interval (+ low 1) high))))

(enumerate-interval 2 7)

(2 3 4 5 6 7)

Page 18: Sicp 2.2 계층 구조 데이터와 닫힘 성질

모듈 조합

(define (sum-odd-squares tree)

(accumulate +

0

(map square

(filter odd?

(enumerate-tree tree)))))

----------------------------------------------------------------------------

(define (even-fibs n)

(accumulate cons

nil

(filter even?

(map fib

(enumerate-interval 0 n)))))

Page 19: Sicp 2.2 계층 구조 데이터와 닫힘 성질

겹친 매핑

• 차례열 패러다임의 쓰임새를 넓혀서, 겹친 루프를 써서 나타낼 수있는 계산 문제를 표현

• 양의 정수 n, I, j가 있을때, 1 <= j < I <= n 만족하고 I + j 의 값이소수가 되는 i와 j의 모든 순서 쌍을 구하는 문제

• N = 6 일 경우.

Page 20: Sicp 2.2 계층 구조 데이터와 닫힘 성질

• Enumerate– n보다 작거나 같은 양의

정수로 이루어진 모든 순서쌍을 차례열로 묶어냄

• Filter– 그 가운데 그 합이 소수인

쌍들만 거르개로 고름.

• Map– 골라낸 쌍(I,j)에 대해 트리

플(I,j, i+j)를 만듬.

• Accumulate

(accumulate append

nil

(map (lambda (i)

(map (lambda ( j) (list i j))

(enumerate-interval 1 (- i 1))))

(enumerate-interval 1 n)))

(define (flatmap proc seq)

(accumulate append nil (map proc seq)))

----------------------------------------------------------

(define (prime-sum? pair)

(prime? (+ (car pair) (cadr pair))))

----------------------------------------------------------

(define (make-pair-sum pair)

(list (car pair) (cadr pair)

(+ (car pair) (cadr pair))))

Page 21: Sicp 2.2 계층 구조 데이터와 닫힘 성질

(define (prime-sum-pairs n)

(map make-pair-sum

(filter prime-sum?

(flatmap

(lambda (i)

(map (lambda ( j) (list i j))

(enumerate-interval 1 (- i 1))))

(enumerate-interval 1 n)))))

Page 22: Sicp 2.2 계층 구조 데이터와 닫힘 성질

(define (enumerate-interval low high)(if (> low high)

null(cons low (enumerate-interval (+ low 1) high))));------------------------------------------------

(define (accumulate append null)((map (lambda (i)

(map (lambda (j) (list i j))(enumerate-interval 1 (- i 1))))

(enumerate-interval 1 n))))

(define (flatmap proc seq)(accumulate append null (map proc seq)))

;----------------------------------------------------------(define (square x) (* x x))

(define (find-divisor n test-divisor)(cond ((> (square test-divisor) n) n)

((divides? test-divisor n) test-divisor)(else (find-divisor n (+ test-divisor 1)))))

(define (divides? a b) (= (remainder b a) 0))

(define (smallest-divisor n) (find-divisor n 2))

(define (prime? n)(= n (smallest-divisor n)))

(define (prime-sum? pair)(prime? (+ (car pair) (cadr pair))))

;----------------------------------------------------------(define (make-pair-sum pair)

(list (car pair) (cadr pair) (+ (car pair) (cadr pair))))

;----------------------------------------------------------

(define (prime-sum-pairs n)(map make-pair-sum

(filter prime-sum? (flatmap (lambda (i)

(map (lambda (j) (list i j))

(enumerate-interval 1 (- i 1))))(enumerate-interval 1 n)))))

Page 23: Sicp 2.2 계층 구조 데이터와 닫힘 성질

2.2.4 그림 언어

• 데이터 요약과 닫힘 성질, 아울러 차수 높은

프로시저가 프로그램 설계에 미치는 힘을

살펴보기 위해 그림을 그리는데 쓰는 간단한

그림 언어를 만들어 보자.

• 그림언어는 페인터라는 한가지 요소만 갖춤.

Page 24: Sicp 2.2 계층 구조 데이터와 닫힘 성질

• Wave 라는 기본 페인터를 써서 그린 그림.

Page 25: Sicp 2.2 계층 구조 데이터와 닫힘 성질

• Rogers 페인터 사용.

Page 26: Sicp 2.2 계층 구조 데이터와 닫힘 성질

(define wave2 (beside wave (flip-vert wave)))

(define wave4 (below wave2 wave2))

Page 27: Sicp 2.2 계층 구조 데이터와 닫힘 성질

(define (flipped-pairs painter)(let ((painter2 (beside painter (flip-vert painter))))(below painter2 painter2)))

(define wave4 (flipped-pairs wave))

Page 28: Sicp 2.2 계층 구조 데이터와 닫힘 성질

(define (right-split painter n)(if (= n 0)

painter(let ((smaller (right-split painter (- n 1))))

(beside painter (below smaller smaller)))))

-------------------------------------------------(define (corner-split painter n)

(if (= n 0)painter(let ((up (up-split painter (- n 1)))

(right (right-split painter (- n 1))))(let ((top-left (beside up up))

(bottom-right (below right right))(corner (corner-split painter (- n

1))))(beside (below painter top-left)

(below bottom-right corner))))))

Page 29: Sicp 2.2 계층 구조 데이터와 닫힘 성질

그림틀

Origin(Frame) + x Edge1(Frame) + y Edge2(Frame)

(define (frame-coord-map frame)

(lambda (v)

(add-vect

(origin-frame frame)

(add-vect (scale-vect (xcor-vect v) (edge1-frame frame))

(scale-vect (ycor-vect v) (edge2-frame

frame))))))

((frame-coord-map a-frame) (make-vect 0 0))

(origin-frame a-frame)

Page 30: Sicp 2.2 계층 구조 데이터와 닫힘 성질

페인터

• 페인터 프로시져는 그림틀을 인자로 받아서, 그 틀에 맞춘 그림을 그림.

(define (segments->painter segment-list)

(lambda (frame)

(for-each

(lambda (segment)

(draw-line

((frame-coord-map frame) (start-segment segment))

((frame-coord-map frame) (end-segment segment))))

segment-list)))

Page 31: Sicp 2.2 계층 구조 데이터와 닫힘 성질

단단하게 설계할 때 쓰는 언어

• 다층 설계 – 단계별로 여러 언어를 쌓아올려 복잡한 시스템을 층층이 짜맞추어 가는방법

• 다층 설계 방식은 프로그램을 “튼튼하게” 짜는데 큰 도움을 줌.

Page 32: Sicp 2.2 계층 구조 데이터와 닫힘 성질

Referance

• 컴퓨터 프로그램의 구조와 해석 2/E – 헤럴드에빌슨, 제럴드 제이 서스먼, 줄리 서스먼 지음. 인사이트.