Recursion and Fixed-Point Theorem: Understanding Recursive Functions in Programming, Study notes of Computer Science

Recursion in programming, specifically the concept of recursive procedure definitions using the letrec construct. It also covers the concept of recursive functions as fixed points and the fixed-point theorem. Examples and explanations to help understand these concepts.

Typology: Study notes

Pre 2010

Uploaded on 09/02/2009

koofers-user-zbt
koofers-user-zbt 🇺🇸

10 documents

1 / 18

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Com S 342
Recursion
Most programming languages support the definition of recursive
abstractions:
Records (to construct linked lists)
Procedure (to implement inductively specified data types)
Mutual depended data structures like classes
Recursion is a challenging mechanism and may often lead to
complications in program understanding.
We will study only one form of recursive definition here:
letrec recursive procedure definition à la Scheme.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12

Partial preview of the text

Download Recursion and Fixed-Point Theorem: Understanding Recursive Functions in Programming and more Study notes Computer Science in PDF only on Docsity!

Com S 342

Recursion

„

Most programming languages support the definition of recursiveabstractions:

„

Records (to construct linked lists)

„

Procedure (to implement inductively specified data types)

„

Mutual depended data structures like classes

„

Recursion is a challenging mechanism and may often lead tocomplications in program understanding.

„

We will study only one form of recursive definition here:letrec – recursive procedure definition à la Scheme.

Com S 342

A Recursive Problem

„

Suppose we want to define the operation plus using only the operatorsincrement and decrement.We may write:$

let plus = proc (n, m) if n then (plus dec(n) inc(m)) else

m

in (plus 2 3)

Error reported by apply-envNo binding for plus

„

Unfortunately this is not a definition, since we are trying to use “plus” beforeit is defined.

„

Task: Although recursion is fundamental to programming, it is not yetprimitive in the our language, so we must find a way to “program” it!

Com S 342

Fixed Points

„

In general, a fixed point of a function is a value in the function’s domain,which is mapped to itself by the function. Therefore, a fixed point of afunction

f

is a value

p

such that

f

p) =

p.

„

Examples:

(factorial 1) = 1(factorial 2) = 2(fibonacci 0) = 0(fibonacci 1) = 1

„

However, not all functions have exactly one fixed point: “inc(n) = n + 1” hasnone.

Î

We need to represent the fixed-point operation in our language.

Com S 342

Fixed-Point Theorem

Fixed-point Theorem:

For every

F

there exists a fixed-point

X

such that

F X

X

Proof:

Let

Y

≡ λ

f. (

λ

x. f (x x)) (

λ

x. f (x x))

Now consider:

X

Y F

Æ

λ

x. F (x x)) (

λ

x. F (x x))

Æ

F ((

λ

x. F (x x)) (

λ

x. F (x x)))

Æ

F X

Therefore, the “Y combinator” can always be used to find a fixed-point ofan arbitrary lambda expression, if such a fixed-point exists.

Com S 342

Strict Fixed-Point Operator

The fixed-point operator Y is useless in a call-by-value setting, since theexpression Y g diverges for any g. In call-by-value settings we use,therefore, the operator fix:

fix

≡ λ

f. (

λ

x. f (

λ

y. x x y)) (

λ

x. f (

λ

y. x x y))

Com S 342

Unfolding Recursive Lambda Expressions IIrplus = proc (plus, n, m) if n then (plus dec(n) inc(m)) else

m

„

We can take: plus

fix rplus

plus 1 1

= (fix rplus) 1 1 Æ

(h h) 1 1

where h = (

λ

x. rplus (

λ

y. x x y))

Æ

rplus fct 1 1

where fct =

λ

y. h h y

Æ

if 1 then (fct 0 2) else 1

Æ

fct 0 2

Æ

h h 0 2

Æ

rplus fct 0 2

Æ

if 0 then (fct (pred 0) (succ 2)) else 2

Æ

call-by-value

Com S 342

Applications of a Recursive Definition

<reclet

<declarations

<declaration /><declaration /> /><invoke <arguments

odd

fv(even) and even

fv(odd)

Com S 342

Even & Odd<proc

<params /><if

<condition /><then <invoke <reference value =

odd

/>

<arguments <dec <arguments /> /> /> /> />

<else /> /> />

<proc

<params /><if

<condition /><then <invoke

<reference value =

even

/>

<arguments <dec <arguments /> /> /> /> />

<else /> /> />

Com S 342

Evaluation of reclet

… (reclet-exp (decls body)

(let* ((args (eval-rands (get-rands decls) env))

;; filter recursive procedure ids(rec-proc-ids (map car (filter (lambda (p) (procval? (cadr p)))

(zip (get-ids decls) args))))

;; now change closure to closure-rec(new-args (map (lambda (v)

(if (procval? v)

(build-rec-proc v rec-proc-ids)v)) args)))

(eval-expression body (extend-env (get-ids decls) new-args env))))

Com S 342

Filter

(define filter

(lambda (p lst)

(if (null? lst)

'() (if (p (car lst))

(cons (car lst) (filter p (cdr lst)))(filter p (cdr lst)))

> (filter odd? ‘(1 2 3 4 5 6 7 8))‘(1 3 5 7)

(define odd? (lambda (n) (= (modulo n 2) 1)))

Com S 342

New Approach to Call Procedures

(app-exp (rator rands)

(let ((proc (eval-expression rator env))

(args (eval-rands rands env)))

(if (procval? proc)

;; add calling-env to resolve occuring recursive procedures

(apply-procval proc args env) (eopl:error 'eval-expression

"Attempt to apply non-procedure ~s" proc))))

Com S 342

New apply-procval

(define apply-procval

(lambda (proc args calling-env)

(cases procval proc

(closure (ids body env)

(eval-expression

body(extend-env ids args env)))

(closure-rec (ids body rec-proc-ids env)

(eval-expression

body(extend-env ids args (extend-rec-env rec-proc-ids calling-env env))))