• 검색 결과가 없습니다.

재귀 혹은 귀납Recursive or Inductive Definition집합을 정의하는 방법

N/A
N/A
Protected

Academic year: 2021

Share "재귀 혹은 귀납Recursive or Inductive Definition집합을 정의하는 방법"

Copied!
18
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

재귀 혹은 귀납

Recursive or Inductive Definition

집합을 정의하는 방법

집합 S 를 정의하는 방법 :

• 0 은 S 의 원소이다 .

• n 이 S 의 원소라면 n+1 도 S 의 원소이다 . 집합 S 는 위의 두가지 방법으로만 만들어진다 . 계산식들의 집합을 정의하는 방법 :

• primitive constants are expressions

• names are expressions

• ( followed by two expressions and ) are expressions

계산식들의 집합 <expr> 은 위의 세가지 방법으로만 만들어진다 . A 라는 자연수 짝들의 집합을 정의하는 방법 :

• (0,1) 은 A 의 원소

• (n,m) 이 A 의 원소라면 (n+1,(n+1)*m) 도 A 의 원소 집합 A 는 위의 두가지 방법으로만 만들어진다 .

S ::= 0 | S+1

A(0) = 1

A(n+1) = (n+1)*A(n)

<expr> ::= <cont>

| <name>

| (<expr> <expr>)

(2)

재귀 혹은 귀납

Recursive or Inductive Definition

반복되는 계산을 정의하는 방법

A

0

= 1 S

0

= 0

A

n

= n*A

n-1

S

n

= n+S

n-1

재귀함수 = 반복되는 계산을 하는 함수

(3)

재귀함수의 정의

(define (<name> <name>*) <expr>) (define (fac n)

(cond ((= n 0) 1)

((> n 0) (* n (fac (- n 1)))) ))

The type of fac fac: nat -> nat

0! = 1

(n+1)! = (n+1)*n!

(4)

재귀함수의 실행

(fac 4)

(* 4 (fac 3))

(* 4 (* 3 (fac 2)))

(* 4 (* 3 (* 2 (fac 1))))

(* 4 (* 3 (* 2 (* 1 (fac 0)))))

(* 4 (* 3 (* 2 (* 1 1))))

(* 4 (* 3 (* 2 1)))

(* 4 (* 3 2))

(* 4 6)

24

(define (fac n)

(cond ((= n 0) 1)

((> n 0) (* n (fac (- n 1)))) ))

(5)

재귀함수가 모든 입력에 대해서 정 의되었는가 ? 확인 방법

• 모든 입력에 대해서 정의되었는가 ?

– 모든 가능한 입력값들은 대게 무한히 많다 – 그렇다면 어떻게 “확인”할 수 있는가 ?

• Use the power of induction

– 입력값들의 집합이 귀납적으로 정의된 경우 : 대부분 – 귀납적인 정의에서는 , 집합의 모든 원소를 만들 수 있

는 방법은 유한가지가 있다 .

– 함수는 각각의 귀납규칙으로 만들어지는 입력에 대해 서 하나의 경우씩 정의하면 된다 .

(cond ((= n 0) 1) nat ::= 0

((> n 0) (* n (fac (- n 1)))) | nat+1

(6)

(define (fac n)

(cond ((= n 0) 1)

((> n 0) (* n (fac (- n 1)))) (else 1)))

자연수가 아닌 수가 입력으로 올 수 있으면 .

(7)

재귀함수의 계산이 항상 끝나는가 ? 확인 방법

• 함수가 자기자신 안에서 다시 불려질 때 , 원래의 인자보다 항상 더 작은 인자로 불리 는가 ?

• 그리고 그 인자들이 작아지면서 항상 끝장 이 나는가 ?

(define (fac n)

(cond ((= n 0) 1)

((> n 0) (* n (fac (- n 1))))

(else 1)))

(8)

끝나는 재귀함수인지 확인하는 일반적인 방법

• Given (define (f x) … (f x’) … )

where x and x’ in X

• How to prove that (f x) terminates for any input x:

– Find an order x > x’ such that the order in X is “not infinitely descending.”( 가다보면 끝이있는 )

– And show that the argument to every recursive call follows that > order.

• (define (fac n) (if (= n 0) 1 … (fac (- n 1)) …))

• (define (bar a b c)

(if (= b 0) c … (bar (+ a 1) (- b 1) (* a b)) ))

(9)

왜 함수값만

재귀적인 정의를 허용하는가 ?

다음과 같은 정의가 불가능 할 이유가 뭐람 ? (define x (+ x 1))

(define I-love-u (more-than I-love-u)) 그 x 와 I-love-u 는 무슨 값인가 ?

무한수와 무한사랑 .

컴퓨터에 표현할 방안이 있다면 OK. ( 어떻게 ?)

Scheme 에서는 허용안한다 . 허용하는 언어도 있다 . ( 왜 ?)

한편 , 재귀적인 함수는 무슨 값인가 ?

일반 함수값과 같다 .

그 함수가 적용될 때 , 할 일 안에 자기 함수가 있는것 뿐 .

(10)

재귀함수의 정의는 letrec 의 설탕이란다 , 거의

(define (fac n) …fac… ) <expr’>

=

(letrec ((fac (lambda (n) … fac …))) <expr’>)

서로가 서로를 부르는 재귀 함수들의 정의 : (letrec ( (even (lambda (n) ... odd …)) (odd (lambda (n) … even …)) )

<expr>)

(11)

자기자신을 부르는 일이 하는 일의 맨 마지막인 경우

tail-recursive call

(define (fac n)

(cond ((= n 0) 1)

((> n 0) (* n (fac (- n 1)))) (else 1)))

(define (fac n)

(define (fac-aux n r) (cond ((= n 0) r)

((> n 0) (fac-aux (- n 1) (* n r))) (else 1)))

(fac-aux n 1) )

(12)

tail-recursive call 의 실행

(fac 4)

 (fac-aux 4 1)

 (fac-aux 3 (* 4 1))

 (fac-aux 3 4)

 (fac-aux 2 (* 3 4))

 (fac-aux 2 12)

 (fac-aux 1 (* 2 12))

 (fac-aux 1 24)

 (fac-aux 0 (* 1 24))

 (fac-aux 0 24)

 24

(13)

함수가 함수의 인자로

• 함수 / 프로시져는 값

• integer, boolean 등의 값과 다르지 않다 .

• 함수 / 프로시져는 함수 / 프로시져의 인자로 보낼 수 있다 .

• 그래왔었었다 :



010x2 for 02 + 12 + … + 102 (define (sum lower upper f) (if (> lower upper) 0

(+ (f lower) (sum (+ lower 1) upper f)))) The type of sigma is

sigma: num * num * (num -> num) -> num

(14)

덕택에 일반화된 프로시져 / 함수를 정의할 수 있다

(define (sum lower upper f) (if (> lower upper) 0

(+ (f lower) (sum (+ lower 1) upper f))

))

(define (sigma l u f op) (if (> l u) 0

(op (f l) (sigma (+ l 1) u f op)) ))

(define (sigma l u f op comp) (if (comp l u) 0

(op (f l) (sigma (+ l 1) u f op comp)) ))

(define (sigma l u f op comp) (define (iter n)

(if (comp n u) 0 (op (f n) (iter (+ n 1))) ))

(iter l))

(15)

함수가 함수의 결과로

• 함수 / 프로시져는 값

• integer, boolean 등의 값과 다르지 않다 .

• 함수 / 프로시져는 함수 / 프로서져의 결과가 될 수 있다 .

• 그래왔었었다 :

(define delta 0.0001) (define (deriv f)

(lambda (x) (/ (- (f (+ x delta)) (f x)) delta) ))

Type of deriv is

deriv: (num -> num) -> (num -> num)

(16)

덕택에 일반화된 프로시져 / 함수를 정의할 수 있다

(define (sum lower upper f) (if (> lower upper) 0

(+ (f lower) (sum (+ lower 1) upper f))

))

(define (sigma lower upper) (lambda (f)

(define (iter n) (if (> n upper) 0

(+ (f n) (iter (+ n 1))))) (iter lower)

))

(define one-to-ten (sigma 1 10)) (one-to-ten (lambda (n) (* n n))) (one-to-ten (lambda (n) (* n 2)))

(17)

덕택에 다양한 정도로 요약된 것들 이름붙일 수 있다 에

give-fn-bounds give-bounds-fn

(define (give-fn-bounds lower upper) …)

(define (give-bounds-fn f)

…)

(18)

고차함수 / 프로시져 higher-order

function/procedure

• 함수 / 프로시져를 인자로 받거나 함수 / 프 로시져를 결과로 내놓는 함수 / 프로시져

• Type of such higher-order functions:

(int -> int) -> int

int * int -> (int -> int)

(int -> bool) -> (num -> num)

money -> (year -> car list)

참조

관련 문서

전국에서 모인 축하사절과 함께 축제의 막을 여는 &lt;춤추는 도시들&gt;은 인천 문화예술계 뿐 아니라 공연예술계 전체의 경사인 인천시립무용단 창단 40주년을

또한 JEUSMain.xml의 &lt;application&gt; 설정을 통해서 각 컨테이너에 대한 Auto Deploy 디렉터리 설정을 할 수 있다.. AutoDeploy

* 주어진 문제 해결을 위하여 실행되는 명령어들의 유한 집합 -&gt; 데이터 변환을 위해서 적용 되는 잘

&lt;참고&gt; WTO설립을 위한 마라케쉬 협정

사이보그에서 심보그로, &lt;스파이더 맨&gt; 시리즈가 보여주는 사이보그 진화론(계속).. 하나는 유기적 신체에 무기적 기계를 결합시키는 방법, 다른 하나는

즉, &lt;FRAME&gt; 태그의 name 속성을 이용하여 프레임의 이름을 지정하고, &lt;A&gt; 태그의 target 속성에 그 이름을 지정하면 지정된

&lt;충무공 이순신 리더십 함양과정&gt; 운영 사후협의회 연산중학교. &lt;미래를 준비하는

또한 백업 소프트웨어에서 소산 백업만을 위해 별도 백업을 수행하기도 하지만 정기 백업 시 두벌씩 데이터를 백업하거나, 백업 완료 후 매체 복사를 통해 한 벌을