SUMMARY ID1218 Lecture 122009-12-07 Christian Schulte cschulte@kth.se Software and Computer Systems...

Preview:

Citation preview

SUMMARY

ID1218 Lecture 12 2009-12-07

Christian Schultecschulte@kth.se

Software and Computer SystemsSchool of Information and Communication

TechnologyKTH – Royal Institute of Technology

Stockholm, Sweden

Overview

Only functional programming summary C++ summary and example questions,

see Lecture 10

L12 2009-12-07ID1218, Christian Schulte

2

Functional Programming

L12 2009-12-07ID1218, Christian Schulte

3

Evaluate functions returning results executed by MiniErlang machine

Techniques recursion with last-call-optimization pattern matching list processing higher-order programming accumulators

MiniErlang Machine

L12 2009-12-07

4

ID1218, Christian Schulte

MiniErlang: Values, Expressions, Instructions

MiniErlang valuesV := int | [] | [ V1 | V2 ]

MiniErlang expressions E := int | [] | [ E1 | E2 ]

| X | F(E1,…, En) where X stands for a variable

MiniErlang instructionsCONS, CALL

L12 2009-12-07ID1218, Christian Schulte

5

MiniErlang Machine

MiniErlang machineEs ; Vs → Es’ ; Vs’

transforms a pair (separated by ;) of expression stack Es and value stack Vs

into a new pair of expression stack Es’ and value stack Vs’

according to topmost element of Es Initial configuration:

expression we want to evaluate on expression stack Final configuration:

single value as result on value stack

L12 2009-12-07ID1218, Christian Schulte

6

MiniErlang: Expressions

Evaluate valuesV Er ; Vs → Er ; V Vs

provided V is a value Evaluate list expression

[E1|E2]Er ; Vs

→ E1E2CONSEr ; Vs Evaluate function call

F(E1, …, En)Er ; Vs

→ E1…EnCALL(F/n)Er ; VsL12 2009-12-07ID1218, Christian Schulte

7

MiniErlang: Instructions

CONS instructionCONSEr ; V1V2Vs

→ Er ; [V2|V1]Vs CALL instruction

CALL(F/n)Er ; V1…VnVs

→ s(E)Er ; Vs F(P1, …, Pn) -> E first clause of F/n such that

[P1, …, Pn] matches [Vn, …,V1] with substitution s

L12 2009-12-07ID1218, Christian Schulte

8

MiniErlang Pattern Matching

PatternsP := int | [] | [ P1 | P2 ] | X

match(P,V)s:=try(P,V)if errors or XV1, XV2 s withV1≠V2 then no else s

wheretry(i,i) = try([],[]) = try([P1|P2],[V1|V2])= try(P1,V1)try(P2,V2)

try(X,V) = {XV}otherwise = {error}

L12 2009-12-07ID1218, Christian Schulte

9

Substitution

Defined over structure of expressionss(i) = is([]) = []s([E1|E2]) = [s(E1)|s(E2)]

s(F(E1, …, En)) = F(s(E1), …, s(En))

s(X) = if XV s then V else X

L12 2009-12-07ID1218, Christian Schulte

10

Iterative Computations

L12 2009-12-07ID1218, Christian Schulte

11

A Better Length?

L12 2009-12-07ID1218, Christian Schulte

l([]) -> 0;l([_|Xr]) -> 1+l(Xr).

l([],N) -> N;l([_|Xr],N) -> l(Xr,N+1).

Two different functions: l/1 and l/2 Which one is better?

12

Running l/1

l([1,2,3]) ; → [1,2,3]CALL(l/1) ; → CALL(l/1) ; [1,2,3]→ 1+l([2,3]) ; → 1l([2,3])ADD ; → l([2,3])ADD ; 1→ [2,3]CALL(l/1)ADD ; 1→ CALL(l/1)ADD ; [2,3]1→ 1+l([3])ADD ; 1→ 1l([3])ADDADD ; 1→ l([3])ADDADD ; 11→ …

requires stack space in the length of list

L12 2009-12-07ID1218, Christian Schulte

13

Running l/2

l([1,2,3],0) ; → [1,2,3]0 CALL(l/2) ; → 0 CALL(l/2) ; [1,2,3]→ CALL(l/2) ; 0[1,2,3]→ l([2,3],0+1) ; → [2,3]0+1 CALL(l/2) ; → 0+1 CALL(l/2) ; [2,3]→ 01ADDCALL(l/2) ; [2,3]→ 1ADDCALL(l/2) ; 0[2,3]→ ADDCALL(l/2) ; 10[2,3]→ CALL(l/2) ; 1[2,3]→ l([3],1+1) ; → …

requires constant stack space!

L12 2009-12-07ID1218, Christian Schulte

14

L12 2009-12-07ID1218, Christian Schulte

Iterative Computations

Iterative computations run with constant stack space

Make use of last optimization call correspond to loops essentially

Tail recursive functions computed by iterative computations

15

Accumulators

Making Computations Iterative

L12 2009-12-07

16

ID1218, Christian Schulte

L12 2009-12-07ID1218, Christian Schulte

Recursive Function

pow(_,0) -> 1;pow(X,N) -> X*pow(X,N-1).

Is not tail-recursive not an iterative function uses stack space in order of N

17

L12 2009-12-07ID1218, Christian Schulte

Using Accumulators

Accumulator stores intermediate result

Finding an accumulator amounts to finding an invariant

recursion maintains invariant invariant must hold initially result must be obtainable from invariant

18

L12 2009-12-07ID1218, Christian Schulte

State Invariant for pow/2

The invariant isXN = pow(X,N-i) * Xi

where i is the current iteration

Capture invariant with accumulator for Xi

initially (i=0) 1=X0

finally (i=N) XN

19

L12 2009-12-07ID1218, Christian Schulte

The pow/3 Function

pow(_,0,A) -> A;pow(X,N,A) -> pow(X,N-1,X*A).

pow(X,N) -> pow(X,N,1).

20

L12 2009-12-07ID1218, Christian Schulte

Naïve Reverse Function

rev([]) -> [];rev([X|Xr]) -> app(rev(Xr),[X]).

Some abbreviations r(Xs) for rev(Xs) Xs ++ Ys for app(Xs,Ys)

21

L12 2009-12-07ID1218, Christian Schulte

Invariant for rev

Now it is easy to see thatrev([x1, …, xn])

=rev([xi+1, …, xn]) ++ [xi, …, x1]

as we go along

22

L12 2009-12-07ID1218, Christian Schulte

rev Final

rev([],Ys) ->

Ys;

rev([X|Xr],Ys) ->

rev(Xr,[X|Ys]).

Is tail recursive now Cost: n+1 calls for list with n elements

23

Higher-Order Programming

L12 2009-12-07

24

ID1218, Christian Schulte

L12 2009-12-07ID1218, Christian Schulte

Generic Procedures

Sorting a list in increasing or decreasing order by number or phone book order (maybe even a

Swedish phone book!) sorting algorithm + order

Mapping a list of numbers to list of square numbers to list of inverted numbers to list of square roots …

25

L12 2009-12-07ID1218, Christian Schulte

Map

map(_,[]) -> [];map(F,[X|Xr]) -> [F(X)|map(F,Xr)].

msq(Xs) -> map(fun (X) -> X*X end, Xs).

Use map/2 for any mapping function! Syntax of fun like case

26

L12 2009-12-07ID1218, Christian Schulte

Using Map

Mapping to square numbersmap(fun (X) -> X*X end,[1,2,3])

Mapping to negative numbersmap(fun (X) -> -X end,[1,2,3])

27

L12 2009-12-07ID1218, Christian Schulte

Other Examples

filter(F,Xs)returns all elements of Xs for which F returns true

any(F,Xs)tests whether Xs has an element for which F returns true

all(F,Xs)tests whether F returns true for all elements of Xs

28

L12 2009-12-07ID1218, Christian Schulte

Folding Lists

Consider computing the sum of list elements

…or the product …or all elements appended to a list …or the maximum …

What do they have in common?

Consider example: sl

29

L12 2009-12-07ID1218, Christian Schulte

Left-Folding

Two values define “folding” initial value 0 for sl binary function + for sl

Left-folding foldl(F,[x1 , …, xn],S)

F(… F(F(S,x1),x2) …,xn) or

(…((S F x1) F x2) … F xn)

30

L12 2009-12-07ID1218, Christian Schulte

foldl

foldl(_,[],S) -> S;foldl(F,[X|Xr],S) -> foldl(F,Xr,F(S,X)).

31

L12 2009-12-07ID1218, Christian Schulte

32

Right-Folding

Two values define “folding” initial value binary function

Right-folding foldr(F,[x1 … xn],S)

F(x1,F(x2, … F(xn,S)…))

orx1F(x2 F( … (xn F S) … ))

L12 2009-12-07ID1218, Christian Schulte

33

foldr

foldr(_,[],S) -> S;foldr(F,[X|Xr],S) -> F(X,foldr(F,Xr,S)).

Concurrency

L12 2009-12-07

34

ID1218, Christian Schulte

Erlang Concurrency Primitives Creating processes

spawn(F) for function value F spawn(M,F,As) for function F in module M

with argument list As Sending messages

PID ! message Receiving messages

receive … end with clauses Who am I?

self() returns the PID of the current process

L12 2009-12-07ID1218, Christian Schulte

35

Processes

Each process has a mailbox incoming messages are stored in order of

arrival sending puts message in mailbox

Processes are executed fairly if a process can receive a message or

compute……eventually, it will

It will pretty soon… simple priorities available (low)

L12 2009-12-07ID1218, Christian Schulte

36

Message Sending

Message sending P ! M is asynchronous the sender does not wait until message has been

processed continues execution immediately evaluates to M

When a process sends messages M1 and M2 to same PID, they arrive in order in mailbox

FIFO ordering When a process sends messages M1 and M2

to different processes, order of arrival is undefined

L12 2009-12-07ID1218, Christian Schulte

37

Message Receipt

Only receive inspects mailbox all messages are put into the mailbox

Messages are processed in order of arrival that is, receive processes mailbox in order

If the receive statement has a matching clause for the first message

remove message and execute clause always choose the first matching clause

Otherwise, continue with next message Unmatched messages are kept in original

orderL12 2009-12-07ID1218, Christian Schulte

38

Communication Patterns

L12 2009-12-07

39

ID1218, Christian Schulte

Broadcast

foreach(_,[]) -> void;foreach(F,[X|Xr]) -> F(X),foreach(Xr).

broadcast(PIDs,M) -> foreach(fun(PID) -> PID ! M end,PIDs).

L12 2009-12-07ID1218, Christian Schulte

40

Broadcast With Ordered Replycollect(PIDs,M) -> map(fun (P) -> P ! {self(),M}, receive {P,Reply} -> Reply end end, PIDs). Collect a reply from all processes in

orderL12 2009-12-07ID1218, Christian Schulte

41

Low-latency Collect

collect(PIDs,M) -> foreach(fun (P) -> P ! M end, PIDs), map(fun (P) -> receive {P,R} -> R end end, PIDs). No order

L12 2009-12-07ID1218, Christian Schulte

42

Coordination

L12 2009-12-07

43

ID1218, Christian Schulte

L12 2009-12-07ID1218, Christian Schulte

44

Protocols

Protocol: rules for sending and receiving messages

programming with processes Examples

broadcasting messages to group of processes choosing a process

Important properties of protocols safety liveness

L12 2009-12-07ID1218, Christian Schulte

45

Choosing a Process

Example: choosing the best lift, connection, … More general: seeking agreement

coordinate execution

General idea: Master

send message to all slaves containing reply PID select one slave: accept all other slaves: reject

Slaves answer by replying to master PID wait for decision from master

Master: Blueprint

decide(SPs) -> Rs=collect(SPs,propose), {SP,SPr}=choose(SPs,Rs), SP ! {self(),accept}, broadcast(SPr,reject}. Generic:

collecting and broadcasting Specific:

choose single process from processes based on replies Rs

L12 2009-12-07ID1218, Christian Schulte

46

Slave: Blueprint

slave() -> receive {M,propose} -> R=…, M ! {self(),R}, receive {M,accept} -> …; {M,reject} -> … end end

L12 2009-12-07ID1218, Christian Schulte

47

L12 2009-12-07ID1218, Christian Schulte

48

Avoiding Deadlock

Master can only proceed, after all slaves answered

will not process any more messages until then receiving messages in collect

Slave can only proceed, after master answered

will not process any more messages until then What happens if multiple masters for

same slaves?

L12 2009-12-07ID1218, Christian Schulte

49

Avoiding Deadlock

Force all masters to send in order: First A, then B, then C, … Guarantee: If A available, all others will be available difficult: what if dynamic addition and removal of

lists does not work with low-latency collect

low-latency: messages can arrive in any order high-latency: receipt imposes strict order

Use an adaptor access to slaves through one single master slaves send message to single master problem: potential bottleneck

Liveness Properties

Important property of concurrent programsliveness

An event/activity might fail to be live other activities consume all CPU power message box is flooded (denial of services) activities have deadlocked …

Difficult: all possible interactions with other processes must guarantee liveness

reasoning of all possible interactions

L12 2009-12-07ID1218, Christian Schulte

50

Process State Reconsidered

L12 2009-12-07

51

ID1218, Christian Schulte

L12 2009-12-07ID1218, Christian Schulte

52

State and Concurrency

Difficult to guarantee that state is maintained consistently in a concurrent setting

Typically needed: atomic execution of several statements together

Processes guarantee atomic execution

Locking Processes

Idea that is used most often in languages which rely on state

Before state can be manipulated: lock must be acquired

for example, one lock per object If process has acquired lock: can perform

operations If process is done, lock is released

L12 2009-12-07ID1218, Christian Schulte

53

A Lockable Process

outside(F,InS) -> receive {acquire,PID} -> PID ! {ok,self()}, inside(F,InS,PID) end.inside(F,InS,PID) -> receive {release,PID} -> outside(F,InS) {PID,Msg} -> inside(F,F(Msg,InS)); end.

L12 2009-12-07ID1218, Christian Schulte

54

Safety Properties

Maintain state of processes in consistent fashion

do not violate invariants to not compute incorrect results

Guarantee safety by atomic execution exclusion of other processes ("mutual

exclusion")

L12 2009-12-07ID1218, Christian Schulte

55

Runtime Efficiency

L12 2009-12-07

56

ID1218, Christian Schulte

L12 2009-12-07ID1218, Christian Schulte

57

Approach

Take MiniErlang program Take execution time for each expression Give equations for runtime of functions Solve equations Determine asymptotic complexity

L12 2009-12-07ID1218, Christian Schulte

58

Execution Times for Expressions

Give inductive definition based on function definition and structure of expressions

Function definition pattern matching and guards

Simple expression values and list construction

More involved expression function call recursive function call leads to recursive

equation often called: recurrence equation

L12 2009-12-07ID1218, Christian Schulte

59

Execution Time: T(E)

ValueT(V) = cvalue

List constructionT([E1|E2]) = ccons + T(E1) + T(E2)

Time T(E) needed for executing expression E

how MiniErlang machine executes E

L12 2009-12-07ID1218, Christian Schulte

60

Function Call

For a function F define a functionTF(n) for its runtime

and determine size of input for call to F input for a function

L12 2009-12-07ID1218, Christian Schulte

61

Function Call

T(F(E1, ..., Ek)) = ccall + T(E1) + ... + T(Ek)

+ TF(size(IF({1, ..., k})))

input arguments IF({1, ..., k}) input arguments for F

size size(IF({1, ..., k}))size of input for F

Function Definition

Assume function F defined by clausesH1 -> B1; …; Hk -> Bk.

TF(n) = cselect + max { T(B1), …, T(Bk) }

L12 2009-12-07ID1218, Christian Schulte

62

L12 2009-12-07ID1218, Christian Schulte

63

Example: app/2

app([],Ys)

-> Ys;

app([X|Xr],Ys)

-> [X|app(Xr,Ys)].

What do we want to compute

Tapp(n) Knowledge needed

input argument first argument size function length of list

L12 2009-12-07ID1218, Christian Schulte

64

Append: Recurrence Equation Analysis yields

Tapp(0) = c1

Tapp(n) = c2 + Tapp(n-1) Solution to recurrence is

Tapp(n) = c1 + c2 n Asymptotic complexity

Tapp(n) is of O(n) “linear complexity”

L12 2009-12-07ID1218, Christian Schulte

65

Recurrence Equations

Analysis in general yields a system T(n) defined in terms of

T(m1), …, T(mk)

for m1, …, mk < n T(0), T(1), … values for certain n

Possibilities solve recurrence equation (difficult in general) lookup asymptotic complexity for common case

L12 2009-12-07 ID1218, Christian Schulte 66

Common Recurrence Equations

T(n) Asymptotic Complexity

c + T(n–1) O(n)

c1 + c2n + T(n–1) O(n2)

c + T(n/2) O(log n)

c1 + c2n + T(n/2) O(n)

c + 2T(n/2) O(n)

c + 2T(n-1) O(2n)

c1 + c2n + T(n/2) O(n log n)

That’s It!

L12 2009-12-07

67

ID1218, Christian Schulte

Recommended