Evaluating Call-by-need on the Control Stack Stephen Chang, David - - PowerPoint PPT Presentation

evaluating call by need on the control stack
SMART_READER_LITE
LIVE PREVIEW

Evaluating Call-by-need on the Control Stack Stephen Chang, David - - PowerPoint PPT Presentation

Evaluating Call-by-need on the Control Stack Stephen Chang, David Van Horn, Matthias Felleisen Northeastern University Lazy Abstract Machines Sharing implemented with: heap Lazy Abstract Machines Sharing implemented with: heap


slide-1
SLIDE 1

Evaluating Call-by-need on the Control Stack

Stephen Chang, David Van Horn, Matthias Felleisen Northeastern University

slide-2
SLIDE 2

Lazy Abstract Machines Sharing implemented with: heap

slide-3
SLIDE 3

Lazy Abstract Machines Sharing implemented with: heap stack operations

(alternative approach)

slide-4
SLIDE 4

Lazy Abstract Machines Sharing implemented with: heap stack operations

(alternative approach) [Garcia et al. 2009]

slide-5
SLIDE 5

Our Paper

  • New way to resolve variable references in the stack
slide-6
SLIDE 6

Our Paper

  • New way to resolve variable references in the stack
  • Reorganize stack structure to allow indexing
slide-7
SLIDE 7

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

slide-8
SLIDE 8

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
slide-9
SLIDE 9

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once
slide-10
SLIDE 10

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M

slide-11
SLIDE 11

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M | (λx.E) M | (λx.E[x]) E

slide-12
SLIDE 12

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M [ ] | E M [ ] | E M [ ] | E M | (λx.E) M | (λx.E[x]) E

slide-13
SLIDE 13

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M | (λx.E) M (λx.E) M (λx.E) M (λx.E) M | (λx.E[x]) E

slide-14
SLIDE 14

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M | (λx.E) M | (λx.E[x]) E (λx.E[x]) E (λx.E[x]) E (λx.E[x]) E

slide-15
SLIDE 15

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M | (λx.E) M | (λx.E[x]) E

deref (β alternative):

(λx.E[x]) V

(λx.E[V

V V V]) V

slide-16
SLIDE 16

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M | (λx.E) M | (λx.E[x]) E

deref (β alternative):

(λx.E[x]) V

(λx.E[V

V V V]) V

  • One-at-a-time substitution (only when needed)
slide-17
SLIDE 17

Call-by-need λ-Calculus

[Ariola et al. 1995] [Ariola and Felleisen 1997]

  • Delay evaluation of argument until needed
  • Evaluate each argument only once

M = x | M M | λx.M E = [ ] | E M | (λx.E) M | (λx.E[x]) E

deref (β alternative):

(λx.E[x]) V

(λx.E[V

V V V]) V

  • One-at-a-time substitution (only when needed)
  • Argument not removed (may need it again)
slide-18
SLIDE 18

An Initial Abstract Machine

slide-19
SLIDE 19

An Initial Abstract Machine Standard Reduction = abstract machine

E[M]

SR

E[N] if M N

slide-20
SLIDE 20

An Initial Abstract Machine Standard Reduction = abstract machine

E[M]

SR

E[N] if M N

  • Re-partition into E and M after every reduction
slide-21
SLIDE 21

CK Machine

[Felleisen 1986] (For by-value λ calculus)

  • Separate program into two registers:

C C C C = Current subterm being evaluated K K K K = Continuation (equiv. to eval. context)

slide-22
SLIDE 22

CK Machine

[Felleisen 1986] (For by-value λ calculus)

  • Separate program into two registers:

C C C C = Current subterm being evaluated K K K K = Continuation (equiv. to eval. context)

Don't need to re-partition program after every reduction

slide-23
SLIDE 23

CK Machine

[Felleisen 1986] (For by-value λ calculus)

  • Separate program into two registers:

C C C C = Current subterm being evaluated K K K K = Continuation (equiv. to eval. context)

Don't need to re-partition program after every reduction

[Garcia et al. 2009]: lazy CK machine

slide-24
SLIDE 24

Evaluation Contexts (E) vs Continuations (K)

[ ] ~ mt E[[ ] M] ~ (arg M K) E ~ K E[(λx.[ ]) M] ~ (bind x M K) E ~ K E[(λx.E'[x]) [ ]] ~ (op x K' K) K' ~ E', K ~ E

slide-25
SLIDE 25

Evaluation Contexts (E) vs Continuations (K)

[ ] ~ mt [ ] ~ mt [ ] ~ mt [ ] ~ mt E[[ ] M] ~ (arg M K) E ~ K E[(λx.[ ]) M] ~ (bind x M K) E ~ K E[(λx.E'[x]) [ ]] ~ (op x K' K) K' ~ E', K ~ E

slide-26
SLIDE 26

Evaluation Contexts (E) vs Continuations (K)

[ ] ~ mt E[[ ] M] ~ (arg M K) E[[ ] M] ~ (arg M K) E[[ ] M] ~ (arg M K) E[[ ] M] ~ (arg M K) E ~ K E[(λx.[ ]) M] ~ (bind x M K) E ~ K E[(λx.E'[x]) [ ]] ~ (op x K' K) K' ~ E', K ~ E

slide-27
SLIDE 27

Evaluation Contexts (E) vs Continuations (K)

[ ] ~ mt E[[ ] M] ~ (arg M K) E ~ K E[(λx.[ ]) M] ~ (bind x M K) E[(λx.[ ]) M] ~ (bind x M K) E[(λx.[ ]) M] ~ (bind x M K) E[(λx.[ ]) M] ~ (bind x M K) E ~ K E[(λx.E'[x]) [ ]] ~ (op x K' K) K' ~ E', K ~ E

slide-28
SLIDE 28

Evaluation Contexts (E) vs Continuations (K)

[ ] ~ mt E[[ ] M] ~ (arg M K) E ~ K E[(λx.[ ]) M] ~ (bind x M K) E ~ K E[(λx.E'[x]) [ ]] ~ (op x K' K) E[(λx.E'[x]) [ ]] ~ (op x K' K) E[(λx.E'[x]) [ ]] ~ (op x K' K) E[(λx.E'[x]) [ ]] ~ (op x K' K) K' ~ E', K ~ E

slide-29
SLIDE 29

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5

slide-30
SLIDE 30

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5

slide-31
SLIDE 31

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 K K K K = mt

slide-32
SLIDE 32

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) K K K K = (arg M5)

mt

slide-33
SLIDE 33

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λy.(λz.(y M)) M0 M1 M2) M3 M4 K K K K = (bind x M5)

mt

slide-34
SLIDE 34

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λy.(λz.(y M)) M0 M1 M2) M3 K K K K = (arg M4)

(bind x M5) mt

slide-35
SLIDE 35

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λy.(λz.(y M)) M0 M1 M2) K K K K = (arg M3)

(arg M4) (bind x M5) mt

slide-36
SLIDE 36

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λz.(y M)) M0 M1 M2 K K K K = (bind y M3)

(arg M4) (bind x M5) mt

slide-37
SLIDE 37

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λz.(y M)) M0 M1 K K K K = (arg M2)

(bind y M3) (arg M4) (bind x M5) mt

slide-38
SLIDE 38

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λz.(y M)) M0 K K K K = (arg M1)

(arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-39
SLIDE 39

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (λz.(y M)) K K K K = (arg M0)

(arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-40
SLIDE 40

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = (y M) K K K K = (bind z M0)

(arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-41
SLIDE 41

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-42
SLIDE 42

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(arg M) (arg M) (arg M) (bind z M0) (arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-43
SLIDE 43

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (bind z M0) (bind z M0) (bind z M0) (arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-44
SLIDE 44

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M1) (arg M1) (arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-45
SLIDE 45

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (arg M2) (arg M2) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-46
SLIDE 46

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) mt

slide-47
SLIDE 47

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) mt

slide-48
SLIDE 48

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) mt

slide-49
SLIDE 49

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) mt

slide-50
SLIDE 50

Example (Garcia Machine)

(λx.(λy.(λz.(y M)) M0 M1 M2) M3 M4) M5 C C C C = y K K K K = (arg M)

(bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) mt

  • Linear search to find argument
slide-51
SLIDE 51

CK+ Machine: Stack Structure

  • Reorganize stack to be stack of stacks

bind continuations on top

slide-52
SLIDE 52

CK+ Machine: Stack Structure

  • Reorganize stack to be stack of stacks

bind continuations on top

(arg M) (bind z M0) (arg M1) (arg M2) (bind y M3) (arg M4) (bind x M5) mt

slide-53
SLIDE 53

CK+ Machine: Stack Structure

  • Reorganize stack to be stack of stacks

bind continuations on top

(arg M) (bind z M0) (bind z M0) (bind z M0) (bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) (bind x M5) (bind x M5) (bind x M5) mt

slide-54
SLIDE 54

CK+ Machine: Stack Structure

  • Reorganize stack to be stack of stacks

bind continuations on top

(arg M) (bind z M0) (bind z M0) (bind z M0) (bind z M0) (arg M1) (arg M2) (bind y M3) (bind y M3) (bind y M3) (bind y M3) (arg M4) (bind x M5) (bind x M5) (bind x M5) (bind x M5) mt (arg M) mt (bind M0) (bind M0) (bind M0) (bind M0) (arg M1) (arg M2) mt (bind M3) (bind M3) (bind M3) (bind M3) (arg M4) mt (bind M5) (bind M5) (bind M5) (bind M5) mt

slide-55
SLIDE 55

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972]

slide-56
SLIDE 56

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M

slide-57
SLIDE 57

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M M = n | M M | λ.M

slide-58
SLIDE 58

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M M = n | M M | λ.M K = mt | (arg M K) | (bind x M K) | (op x K K)

slide-59
SLIDE 59

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M M = n | M M | λ.M K = mt | (arg M K) | (bind x M K) | (op x K K) K = mt | (arg M K) | (bind M K) | (op K K)

slide-60
SLIDE 60

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M M = n | M M | λ.M K = mt | (arg M K) | (bind x M K) | (op x K K) K = mt | (arg M K) | (bind M K) | (op K K) λx.(x λy.(x y))

slide-61
SLIDE 61

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M M = n | M M | λ.M K = mt | (arg M K) | (bind x M K) | (op x K K) K = mt | (arg M K) | (bind M K) | (op K K) λx.(x λy.(x y)) λ.(0 λ.(1 0))

slide-62
SLIDE 62

CK+ Machine: Lexical Addresses

  • Replace variables with lexical addresses

[De Bruijn 1972] M = x | M M | λx.M M = n | M M | λ.M K = mt | (arg M K) | (bind x M K) | (op x K K) K = mt | (arg M K) | (bind M K) | (op K K) λx.(x λy.(x y)) λ.(0 λ.(1 0))

slide-63
SLIDE 63

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5

slide-64
SLIDE 64

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5

slide-65
SLIDE 65

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 K K K K = mt

slide-66
SLIDE 66

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) K K K K = (arg M5)

mt

slide-67
SLIDE 67

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(λ.(1 M)) M0 M1 M2) M3 M4 K K K K = mt

(bind M5) mt

slide-68
SLIDE 68

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(λ.(1 M)) M0 M1 M2) M3 K K K K = (arg M4)

mt (bind M5) mt

slide-69
SLIDE 69

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(λ.(1 M)) M0 M1 M2) K K K K = (arg M3)

(arg M4) mt (bind M5) mt

slide-70
SLIDE 70

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(1 M)) M0 M1 M2 K K K K = mt

(bind M3) (arg M4) mt (bind M5) mt

slide-71
SLIDE 71

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(1 M)) M0 M1 K K K K = (arg M2)

mt (bind M3) (arg M4) mt (bind M5) mt

slide-72
SLIDE 72

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(1 M)) M0 K K K K = (arg M1)

(arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-73
SLIDE 73

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (λ.(1 M)) K K K K = (arg M0)

(arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-74
SLIDE 74

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = (1 M) K K K K = mt

(bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-75
SLIDE 75

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = 1 K K K K = (arg M)

mt (bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-76
SLIDE 76

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = 1 K K K K = (arg M)

mt (bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt

1

(bind M5) mt

2

slide-77
SLIDE 77

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = 1 K K K K = (arg M)

mt (bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt

1

(bind M5) mt

2

slide-78
SLIDE 78

CK+ Machine: Example

(λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 C C C C = 1 K K K K = (arg M)

mt (bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt

1

(bind M5) mt

2

  • Direct index instead of search
slide-79
SLIDE 79

Stack Compaction

slide-80
SLIDE 80

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M)

slide-81
SLIDE 81

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

slide-82
SLIDE 82

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

C C C C = 1 K K K K = (arg M)

mt (bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-83
SLIDE 83

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

C C C C = 1 K K K K = (arg M)

mt (bind M0) (bind M0) (bind M0) (bind M0) (arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-84
SLIDE 84

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

C C C C = 1 K K K K =

(arg M) (arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) mt

slide-85
SLIDE 85

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

C C C C = 1 K K K K =

(arg M) (arg M1) (arg M2) mt (bind M3) (bind M3) (bind M3) (bind M3) (arg M4) mt (bind M5) mt

slide-86
SLIDE 86

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

C C C C = 1 K K K K =

(arg M) (arg M1) (arg M2) mt (bind M3) (arg M4) mt (bind M5) (bind M5) (bind M5) (bind M5) mt

slide-87
SLIDE 87

Stack Compaction

((λx.M) N)

M

where x ∉ FV(M) (λ.(λ.(λ.(1 M)) M0 M1 M2) M3 M4) M5 where

No variables reference M0 or M5

C C C C = 1 K K K K =

(arg M) (arg M1) (arg M2) mt (bind M3) (arg M4) mt

slide-88
SLIDE 88

Thanks!