Presentation is loading. Please wait.

Presentation is loading. Please wait.

Seif Haridi and Peter Van Roy1 Explicit State Seif Haridi Peter Van Roy.

Similar presentations


Presentation on theme: "Seif Haridi and Peter Van Roy1 Explicit State Seif Haridi Peter Van Roy."— Presentation transcript:

1 Seif Haridi and Peter Van Roy1 Explicit State Seif Haridi Peter Van Roy

2 Seif Haridi and Peter Van Roy2 Explicit State I State as a group of memory cells The box O can remember information between independent invocations, it has a memory The basic elements of explicit state Index datatypes Basic techniques and ideas of using state in program design Group of functions and procedures that operate on the state An Interface that hides the state The box O

3 Seif Haridi and Peter Van Roy3 Explicit State II State as a group of memory cells What is the difference between implicit state and explicit state What is the difference between state in general and encapsulated state Component based programming and object- oriented programming Data abstractions using encapsulated state Group of functions and procedures that operate on the state An Interface that hides the state The box O

4 Seif Haridi and Peter Van Roy4 What is state? State is a sequence of values in time that contains the intermediate results of a desired computation Declarative programs can also have state according to this definition Consider the following program fun {Sum Xs A } case Xs of X|Xr then {Sum Xr A+X } [] nil then A end {Show {Sum [1 2 3 4] 0}}

5 Seif Haridi and Peter Van Roy5 What is implicit state? The two arguments Xs and A represent an implicit state XsA [1 2 3 4]0 [2 3 4]1 [3 4]3 [4]6 nil10 fun {Sum Xs A } case Xs of X|Xr then {Sum Xr A+X } [] nil then A end {Show {Sum [1 2 3 4] 0}}

6 Seif Haridi and Peter Van Roy6 What is explicit state: Example? X An unbound variable X A cell C is created with initial value 5 X is bound to C 5 X The cell C, which X is bound to, is assigned the value 6 6 C C

7 Seif Haridi and Peter Van Roy7 What is explicit state: Example? X An unbound variable X A cell C is created with initialvalue 5 X is bound to C 5 X The cell C, which X is bound to, is assigned the value 6 6 C C The cell is a value container with a unique identity X is really bound to the identity of the cell When the cell is assigned, X does not change

8 Seif Haridi and Peter Van Roy8 What is explicit state? X = {NewCell I} –Creates a cell with initial value I –Binds X to the identity of the cell Example: X = {NewCell 0} X:=J –Assumes X is bound to a cell C (otherwise exception) –Changes the content of C to become J Y = @X –Assumes X is bound to a cell C (otherwise exception) –Binds Y to the value contained in C

9 Seif Haridi and Peter Van Roy9 Examples X = {NewCell 0} X:=5 Y = X Y:=10 @X == 10 % returns true X == Y % returns true X 0 X 5 Y X 10 Y

10 Seif Haridi and Peter Van Roy10 Examples X = {NewCell 10} Y = {NewCell 10} X == Y % returns false Because X and Y refer to different cells, with different identities @X == @Y % returns true X 10 Y

11 Seif Haridi and Peter Van Roy11 Examples X = {NewCell 0} X:=5 Y = X Y:=10 @X == 10 returns true X 0 X 5 Y X 10 Y

12 Seif Haridi and Peter Van Roy12 The model extended with cells Semantic stack (Thread 1) Semantic stack (Thread n) w = f(x) z = person(a:y) y =  1 u =  2 x  1: w  2: x......... single assignment store mutable store

13 Seif Haridi and Peter Van Roy13 The stateful model  s  ::= skip empty statement |  s 1   s 2  statement sequence |... | thread  s 1  end thread creation | {NewCell  x   c  } cell creation |{Exchange  c   x   y  } cell exchange Exchange: bind  x  to the old content of  c  and set the content of the cell  c  to  y 

14 Seif Haridi and Peter Van Roy14 The stateful model | {NewCell  x   c  } cell creation |{Exchange  c   x   y  } cell exchange proc {Assign C X} {Exchange C _ X} end fun {Access C} X in{Exchange C X X}X end The ’@’ and ’:=’ syntaxes are syntactic sugar for Assign and Access Exchange: bind  x  to the old content of  c  and set the content of the cell  c  to  y 

15 Seif Haridi and Peter Van Roy15 Do we need explicit state? Up to now the computation model we introduced in the previous lectures did not have any notion of explicit state And important question is: do we need explicit state? There is a number of reasons for introducing state. We discuss them some of them here

16 Seif Haridi and Peter Van Roy16 Programs that change their behavior over time Declarative program: all information is in the arguments Stateful program: new information can be put inside a running program Program

17 Seif Haridi and Peter Van Roy17 Modular programs A system (program) is modular if changes (updates) in the program are confined to the components where the functionality are changed Here is an example where introduction of explicit state in a well confined way leads to program modularity compared to programs that are written using only the declarative model (where evey component is a function)

18 Seif Haridi and Peter Van Roy18 Encapsulated state I Assume we have three persons, P, U1, and U2 P is a programmer who developed a component M that provides two functions F and G U1 and U2 are system builders that use the component M fun {MF} fun {F...}  Definition of F  end fun {G...}  Definition of G  end in ’export’(f:F g:G) end M = {MF }

19 Seif Haridi and Peter Van Roy19 Encapsulated state I Assume we have three persons, P, U1, and U2 P is a programmer who developed a component M that provides two functions F and G U1 and U2 are system builders that use the component M functor MF export f:F g:G define fun {F...}  Definition of F  end fun {G...}  Definition of G  end

20 Seif Haridi and Peter Van Roy20 Encapsulated state II User U2 has a demanding application He wants to extend the module M to enable him to monitor how many times the function F is invoked in his application He goes to P, and asks him to do so without changing the interface to M fun {M} fun {F...}  Definition of F  end fun {G...}  Definition of G  end in ’export’(f:F g:G) end

21 Seif Haridi and Peter Van Roy21 Encapsulated state III This cannot be done in the declarative model because F cannot remember its previous invocations The only way is to change the interface to F by adding two extra arguments FIn and FOut: fun {F... +FIn ?FOut} FOut = FIn+1... end The rest of the program always remembers the previous number of invocations (FIn), and FOut returns the new number of invocations But this changes the interface!

22 Seif Haridi and Peter Van Roy22 fun {MF} X = {NewCell 0} fun {F...} X:=@X+1  Definition of F  end fun {G...}  Definition of G  end fun {Count} @X end in ’export’(f:F g:G c:Count) end M = {MF} Encapsulated state III A cell is created when MF is called Due to lexical scoping the cell is only visible to the created version of F and Count The M.f did not change New function M.c is available X is hidden: only visible inside M (encapsulated state)

23 Seif Haridi and Peter Van Roy23 Relationship between the declarative model and the stateful model Declarative programming guarantees by construction that each procedure computes a function This means each component (and subcomponent) is a function It is possible to use encapsulated state (cells) so that a component is declarative from outside, and stateful from the inside Considered as a black-box the program procedure is still a function

24 Seif Haridi and Peter Van Roy24 Programs with accumulators local fun {Sum1 Xs A } case Xs of X|Xr then {Sum1 Xr A+X } [] nil then A end end in fun {Sum Xs} {Sum1 Xs 0} end

25 Seif Haridi and Peter Van Roy25 Programs with accumulators fun {Sum Xs} fun {Sum1 Xs A } case Xs of X|Xr then {Sum1 Xr A+X } [] nil then A end end in {Sum1 Xs 0 } end fun {Sum Xs} fun {Sum1 Xs} case Xs of X|Xr then A:=X+@A {Sum1 Xr} [] nil then {Access A} end end A = {NewCell 0 } in {Sum1 Xs} end

26 Seif Haridi and Peter Van Roy26 Programs with accumulators fun {Sum Xs} fun {Sum1 Xs} case Xs of X|Xr then A:=X+@A {Sum1 Xr} [] nil then @A end end A = {NewCell 0} in {Sum1 Xs} end fun {Sum Xs} A = {NewCell 0} in {ForAll Xs proc {$ X} A:=X+@A end} @A end

27 Seif Haridi and Peter Van Roy27 Programs with accumulators fun {Sum Xs} A = {NewCell 0} in {ForAll Xs proc {$ X} A:=X+@A end} @A end fun {Sum Xs} A = {NewCell 0} in for X in Xs do A:=X+@A end @A end The state is encapsulated inside each procedure invocation

28 Seif Haridi and Peter Van Roy28 Data abstraction (revisited) With encapsulated state, we can complete the discussion started in Chapter 4 For a given functionality, there are many ways to package the data abstraction. We distinguish three axes. Open vs. secure: is the internal representation visible to the program or hidden? Declarative vs. stateful: does the data abstraction have encapsulated state or not? Bundled vs. unbundled: is the data kept together from the operations or is it separable? Let us see what our stack abstraction looks like with some of these possibilities

29 Seif Haridi and Peter Van Roy29 Stack: Open, declarative, and unbundled Here is the basic stack, as we saw it before: fun {NewStack} nil end fun {Push S E} E|S end fun {Pop S E} case S of X|S1 then E=X S1 end end fun {IsEmpty S} S==nil end This is completely unprotected. Where is it useful? Primarily, in small programs in which expressiveness is more important than security.

30 Seif Haridi and Peter Van Roy30 Stack: Secure, declarative, and unbundled We can make the declarative stack secure by using a wrapper: local Wrap Unwrap in {NewWrapper Wrap Unwrap} fun {NewStack} {Wrap nil} end fun {Push S E} {Wrap E|{Unwrap S}} end fun {Pop S E} case {Unwrap S} of X|S1 then E=X {Wrap S1} end end fun {IsEmpty S} {Unwrap S} ==nil end end Where is this useful? In large programs where we want to protect the implementation of a declarative component.

31 Seif Haridi and Peter Van Roy31 Stack: Secure, stateful, and bundled This is the simplest way to make a secure stateful stack: proc {NewStack Push Pop IsEmpty} C={NewCell nil} in proc {Push X} C:=X|@C end fun {Pop} case @C of X|S then C:=S X end end fun {IsEmpty C} @C==nil end end Compare the declarative with the stateful versions: the declarative version needs two arguments per operation, the stateful version uses higher-order programming (instantiation) With some syntactic support, this gives object-oriented programming

32 Seif Haridi and Peter Van Roy32 Stack: Secure, stateful, and unbundled Let us combine the wrapper with state: local Wrap Unwrap in {NewWrapper Wrap Unwrap} fun {NewStack} {Wrap {NewCell nil}} end proc {Push W X} C={Unwrap W} in C:=X|@C end fun {Pop W} C={Unwrap W} in case @C of X|S then C:=S X end end fun {IsEmpty S} @ {Unwrap W}==nil end end This version is stateful but lets us store the stack separate from the operations. The same operations work on all stacks.

33 Seif Haridi and Peter Van Roy33 Some ways to package a stack Open, declarative, and unbundled: the usual declarative style, e.g., as in Prolog and Scheme Secure, declarative, and unbundled: use wrappers to make the declarative style secure Secure, stateful, and bundled: the usual object-oriented style, e.g., as in Smalltalk and Java Secure, stateful, and unbundled: an interesting variation on the usual object-oriented style Other possibilities: there are four more possibilities! Try to write all of them.

34 Seif Haridi and Peter Van Roy34 Indexed Collections Indexed collections groups a set of (partial) values The individual elements are accessible through an index The declarative model provides: –tuples, e.g. date(17 december 2001) –records, e.g. date(day:17 month:decemeber year:2001) We can now add state to the fields –arrays –dictionaries

35 Seif Haridi and Peter Van Roy35 Arrays An array is a mapping from integers to (partial) values The domain is a set of consecutive integers, with a lower bound and an upper bound The range can be mutated (change) A good approximation is to thing of arrays as a tuple of cells

36 Seif Haridi and Peter Van Roy36 Operations on arrays A = {Array.new LB UB ?Value} –Creates an array A with lower bound LB and upper bound UB –All elements are initialized to Value There are other operations: –To access and update the elements of the array –Get the lower and upper bounds –Convert an array to tuple and vice versa –Check its type

37 Seif Haridi and Peter Van Roy37 Example 1 A = {MakeArray L H F} Creates an array A where for each index I is mapped to {F I} fun {MakeArray L H F} A = {Array.new L H unit} in for I in L..H do A.I := {F I} end A end

38 Seif Haridi and Peter Van Roy38 Array2Record R = {Array2Record L A} Define a function that takes a label L and an array A, it returns a record R whose label is L and whose features are from the lower bound of A to the upper bound of A We need to know how to make a record R = {Record.make L Fs} –creates a record R with label L and a list of features (selector names), returns a record with distict fresh variables as values L = {Array.low A} and H = {Array.high A} –Return lower bound and higher bound of array A

39 Seif Haridi and Peter Van Roy39 Array2Record fun {Array2Record LA A} L = {Array.low A} H = {Array.high A} R = {Record.make LA {From L H}} in for I in L..H do R.I = A.I end R end

40 Seif Haridi and Peter Van Roy40 Tuple to Array fun {Tuple2Array T} H = {Width T} in {MakeArray 1 H fun{$ I} T.I end} end

41 Seif Haridi and Peter Van Roy41 Dictionaries (Hash tables) A dictionary is a mapping from simple values or literals (integers, atoms, amd names) to (partial) values Both the domain and the range can be mutated (changed) The pair consisting of the literal and the value is called an item Items can be added, changed and removed in amortized constant time That is to say n operations takes on average O(n)

42 Seif Haridi and Peter Van Roy42 Operations on dictionaries D = {Dictionary.new} –Creates an empty dictionary There are other operations: –To access and update (and add) the elements of a dictionary using the ’.’ and ’:=’ notations –Remove an item, test the memership of a key –Convert a dictionary to a record and vice versa –Check its type

43 Seif Haridi and Peter Van Roy43 Indexed Collections Tuple Array Record Dictionary Add stateAdd atoms as indices Add state Add atoms as indices stateless collection stateful collection

44 Seif Haridi and Peter Van Roy44 Other collections lists streams stacks queues potentially infinite lists stateless ports generalizes streams to stateful mailboxes stateless collection stateful collection

45 Seif Haridi and Peter Van Roy45 Encapsulated stateful abstract datatypes These are stateful entities that can be access only by the external interface The implementation is not visible outside The are two method to build stateful abstract data types The functor based approach (record interface) The procedure dispatch approach

46 Seif Haridi and Peter Van Roy46 The functor-based approach fun {NewCounter I} S S = {Record.toDictionary state(v:I)} proc {Inc} S.v := S.v + 1 end proc {Dec} S.v := S.v – 1 end fun {Get} S.v end proc {Put I} S.v := I end proc {Display} {Show S.v} end in o(inc:Inc dec:Dec get:Get put:Put show:Display) end

47 Seif Haridi and Peter Van Roy47 The functor-based approach fun {NewCounter I} S S = {Record.toDictionary state(v:I)} proc {Inc} S.v := S.v + 1 end proc {Dec} S.v := S.v – 1 end fun {Get} S.v end proc {Put I} S.v := I end proc {Display} {Show S.v} end in o(inc:Inc dec:Dec get:Get put:Put show:Display) end The state is collected in dictionary S The state is completely encapsulated i.e. not visible out side

48 Seif Haridi and Peter Van Roy48 The functor-based approach fun {NewCounter I} S S = {Record.toDictionary state(v:I)} proc {Inc} S.v := S.v + 1 end proc {Dec} S.v := S.v – 1 end fun {Get} S.v end proc {Put I} S.v := I end proc {Display} {Show S.v} end in o(inc:Inc dec:Dec get:Get put:Put show:Display) end The interface is created for each instance Counter

49 Seif Haridi and Peter Van Roy49 fun {NewCounter I} S S = {Record.toDictionary state(v:I)} proc {Inc} S.v := S.v + 1 end proc {Dec} S.v := S.v – 1 end fun {Get} S.v end proc {Put I} S.v := I end proc {Display} {Show S.v} end in o(inc:Inc dec:Dec get:Get put:Put show:Display) end The functor-based approach function that access the state by lexical scope

50 Seif Haridi and Peter Van Roy50 Call pattern declare C1 C2 C1 = {NewCounter 0} C2 = {NewCounter 100} {C1.inc} {C1.show} {C2.dec} {C2.show}

51 Seif Haridi and Peter Van Roy51 Defined as a functor functor Counter export inc:Inc dec:Dec get:Get put:Put show:Display init:Init defineS S proc {Init init(I)} S = {Record.toDictionary state(v:I)} end proc {Inc} S.v := S.v + 1 end proc {Dec} S.v := S.v – 1 end fun {Get} S.v end proc {Put I} S.v := I end proc {Display} {Show S.v} end end

52 Seif Haridi and Peter Van Roy52 Functors Functors have been used as a specification of modules Also functors have been used as a specification of abstract datatypes How to create a stateful entity from a functor?

53 Seif Haridi and Peter Van Roy53 Explicit creation of objects from functors Given a variable F that is bound to a functor [O] = {Module.apply [F]} creates stateful ADT object O that is an instance of F Given the functor F is stored on a file ’f.ozf’ [O] = {Module.link [’f.ozf’]} creates stateful ADT object O that is an instance of F

54 Seif Haridi and Peter Van Roy54 Defined as a functor functor Counter export inc:Inc dec:Dec get:Get put:Put show:Display init:Init defineS S proc {Init init(I)} S = {Record.toDictionary state(v:I)} end proc {Inc} S.v := S.v + 1 end proc {Dec} S.v := S.v – 1 end fun {Get} S.v end proc {Put I} S.v := I end proc {Display} {Show S.v} end end

55 Seif Haridi and Peter Van Roy55 Pattern of use fun {New Functor Init} [M] = {Module.apply [Functor]} {M.init Init} M end declare C1 C2 C1 = {New Counter init(0)} {C1.inc} {C1.show} {C2.inc} {C2.show}

56 Seif Haridi and Peter Van Roy56 Example: memoization Stateful programming can be used to speed up declarative (functional) components by remembering previous results Consider Pascal’s triangle One way to make it faster between separate invocations is to remember previously computed rows Here follow our principle and change only the internals of a component

57 Seif Haridi and Peter Van Roy57 Functions over lists Compute the function {Pascal N} Takes an integer N, and returns the Nth row of a Pascal triangle as a list 1.For row 1, the result is [1] 2.For row N, shift to left row N-1 and shift to the right row N-1 3.Align and add the shifted rows element-wise to get row N 1 11 121 1331 14641 (0) [0 1 3 3 1] [1 3 3 1 0] Shift right Shift left

58 Seif Haridi and Peter Van Roy58 fun {FastPascal N} if N==1 then [1] else local L in L={FastPascal N-1} {AddList {ShiftLeft L} {ShiftRight L}} end Faster Pascal Introduce a local variable L Compute {FastPascal N-1} only once Try with 30 rows. FastPascal is called N times, each time a list on the average of size N/2 is processed The time complexity is proportional to N 2 (polynomial) Low order polynomial programs are practical.

59 Seif Haridi and Peter Van Roy59 Memoizing FastPascal {FastPascal N} New Version 1.Make a store S available to FastPascal 2.Let K be the number of the rows stored in S (i.e. max row is the K th row) 3.if N is less or equal K retrieve the N th row from S 4.Otherwise, compute the rows numbered K+1 to N, and store them in S 5.Return the N th row from S Viewed from outside (as a black box), this version behaves like the earlier one but faster declare [S] = {Module.apply [StoreFun]} {S.put 2 [1 1]} {Browse {Get S 2}} {Browse {Size S}} (see the program)

60 Seif Haridi and Peter Van Roy60 The store functor functor export put:Put get:Get size:Size define S = {NewDictionary} C = {NewCell 0} proc {Put K X} if {Not {Dictionary.member S K}} then C:=@C+1 end S.K := X end fun {Get K} S.K end fun {Size} @C end end

61 Seif Haridi and Peter Van Roy61 The Pascal functor functor PascalFun import S at 'Store.ozf’ System export pascal:FastPascal define fun {FastPascal N}  Definition of Pascal  end  Definition of help procedures for Pascal  {S.put 1 [1]} end

62 Seif Haridi and Peter Van Roy62 Memo Pascal (1) fun {FastPascal N} MaxRow in MaxRow = {S.size} if N =< MaxRow then {S.get N} else L in  Compute the next N-MaxRow rows stating from row the value of MaxRow, call this list of rows L  {PutList S MaxRow+1 L} {S.get N} end

63 Seif Haridi and Peter Van Roy63 Memo Pascal (2) fun {FastPascal N} MaxRow in MaxRow = {S.size} if N =< MaxRow then {S.get N} else L in L = {PascalListNext N-MaxRow {S.get MaxRow}} {PutList S MaxRow+1 L} {S.get N} end

64 Seif Haridi and Peter Van Roy64 The procedure dispatch approach Another method to realize stateful data abstractions is the procedure dispatch approach The instance of the data abstraction is a one argument procedure The procedure receives messages (when called) and dispatches to the right function according to the label of the message State is encapsulated The interface is defined as messages (implemented as records)

65 Seif Haridi and Peter Van Roy65 The procedure-based approach fun {NewCounter I} S S = {Record.toDictionary state(v:I)} proc {Inc inc} S.v := S.v + 1 end proc {Dec dec} S.v := S.v – 1 end proc{Get get(I)} I = S.v end proc {Put put(I)} S.v := I end proc {Display show} {Show S.v} end D = o(inc:Inc dec:Dec get:Get put:Put show:Display) in proc{$ M} {D.{Label M} M} end end

66 Seif Haridi and Peter Van Roy66 Call pattern declare C1 C2 C1 = {NewCounter 0} C2 = {NewCounter 100} {C1 put(10)} {C1 inc} declare X {C1 get(X)} {C1 show} {C2 dec} {C2 show}

67 Seif Haridi and Peter Van Roy67 Declarative vs. Stateful We are going to study two different implementations of an algorithm, one using a stateful data type representation and the other using a stateless representation The stateful representation will lead to a stateful (imperative) algorithm The stateless representation will lead to a declarative (functional) algorithm We start from the abstract description of the algorithm Which approach is better? We will see!

68 Seif Haridi and Peter Van Roy68 Transitive closure A directed graph consists of a set of vertices (nodes) V and a set of edges (represented as set of pairs of vertices) E (vi,vj)  E iff there is an edge from vi to vj 2 1 4 3 6 5 {1,2,3,4,5,6} {(1,2), (2,3), (3,4), (4,5), (5,6),(6,2) (1,2) } The vertices The edges

69 Seif Haridi and Peter Van Roy69 Transitive closure Calculate a new graph TG, from the original graph G such that TG is the transitive closure of G That is to say there is an edge between a pair of nodes (i,j) in TG iff there is a path from i to j in the graph G

70 Seif Haridi and Peter Van Roy70 Transitive closure 1 4 3 6 5 2 The set of immediate predecessors on node I, Pred(I) The set of immediate successors on node I, Suc(I) Pred(2) = {1 6 5} Suc(2) = {3}

71 Seif Haridi and Peter Van Roy71 The algorithm works by transforming the graph incrementally 1 4 3 6 5 2 1 4 3 6 5 2

72 Seif Haridi and Peter Van Roy72 The algorithm works by transforming the graph incrementally 1 4 3 6 5 2 1 4 3 6 5 2

73 Seif Haridi and Peter Van Roy73 The abstract algorithm For each node x in the graph G –For each node y in Pred(x) For each node z in Suc(x) add the edge (y,z) to G

74 Seif Haridi and Peter Van Roy74 The representation The representation determines very much the model of implementation List (tree) based representation is suitable for a declarative formulation Array (dictionary) based representation is suitable for a stateful formulation

75 Seif Haridi and Peter Van Roy75 Representation The adjacency list representation The graph is a list of elements of the form I#Ns I is the node identifier, Ns is the list of successor nodes The matrix representation The graph is a two dimensional array GM where GM.I.J is true iff there is an edge from node I to node J

76 Seif Haridi and Peter Van Roy76 Transitive closure The matrix representation M is the matrix K I J M.I.K = true L M.K.J = true M.L.K = false

77 Seif Haridi and Peter Van Roy77 From abstract to concrete Matrix representation For each node K in the graph G –For each node I in Pred(K) For each node J in Suc(K) add the edge (I,J) to G proc {StateTrans GM} L={Array.low GM} H={Array.high GM} in for K in L..H do  For each in I in Pred(K) For each J in Suc(K) add GM.I.J := true  end

78 Seif Haridi and Peter Van Roy78 From abstract to concrete Matrix representation For each node K in the graph G –For each node I in Pred(K) For each node J in Suc(K) add the edge (I,J) to G proc {StateTrans GM} L={Array.low GM} H={Array.high GM} in for K in L..H do for I in L..H do if GM.I.K then For each J in Suc(K) add GM.I.J := true  end

79 Seif Haridi and Peter Van Roy79 From abstract to concrete Matrix representation proc {StateTrans GM} L H... in for K in L..H do for I in L..H do if GM.I.K then for J in L..H do if GM.K.J then GM.I.J := true end end end % if end % for end proc {StateTrans GM} L={Array.low GM} H={Array.high GM} in for K in L..H do for I in L..H do if GM.I.K then For each J in Suc(K) add GM.I.J := true  end

80 Seif Haridi and Peter Van Roy80 From abstract to concrete Matrix representation proc {StateTrans GM} L H... in for K in L..H do for I in L..H do if GM.I.K then for J in L..H do if GM.K.J then GM.I.J := true end end end % if end % for end proc {StateTrans GM} L={Array.low GM} H={Array.high GM} in for K in L..H do for I in L..H do if GM.I.K then For each J in Suc(K) add GM.I.J := true  end

81 Seif Haridi and Peter Van Roy81 From abstract to concrete Matrix representation proc {StateTrans GM} L H... in for K in L..H do for I in L..H do if GM.I.K then for J in L..H do if GM.K.J then GM.I.J := true end end end % if end % for end proc {StateTrans GM} L H... in for K in L..H do for I in L..H do if GM.I.K then for J in L..H do GM.I.J := GM.I.J orelse GM.K.J end end % if end % for end

82 Seif Haridi and Peter Van Roy82 Transitive closure adjacency lists 1 4 3 6 5 2 [ 1 # [2] 2 # [1 3] 3 # [4] 4 # [5] 5 # [2] 6 # [2] ] The immediate successor list is sorted, e.g. 2 # [1 3]

83 Seif Haridi and Peter Van Roy83 From abstract to concrete Adjacency list representation For each node X in the graph G –For each node Y in Pred(X) For each node Z in Suc(X) add the edge (Y,Z) to G fun {DeclTrans G} Xs = {Nodes G} in {FoldL Xs fun {$ InG X} SX = {Suc X}  For each node Y in Pred(X) For each Z in SX add edge (Y,Z)  end G} end G0, {F G0 X0}, {F {F G0 X0} X1},... This is {FoldL Xs F G0}

84 Seif Haridi and Peter Van Roy84 From abstract to concrete Adjacency list representation fun {IncPath X SX InG} {Map InG fun{$ Y#SY} Y#If  Y in Pred(X)  then {Union SY SX} else SY end end} end fun {DeclTrans G} Xs = {Nodes G} in {FoldL Xs fun {$ InG X} SX = {Suc X}  For each node Y in Pred(X) For each Z in SX add edge (Y,Z) in GC  end G} end  For each node Y in PX For each Z in SX add edge (Y,Z) in GC 

85 Seif Haridi and Peter Van Roy85 From abstract to concrete Adjacency list representation fun {IncPath X SX InG} {Map InG fun{$ Y#SY} Y#If {Member X SY} then {Union SY SX} else SY end end} end fun {DeclTrans G} Xs = {Nodes G} in {FoldL Xs fun {$ InG X} SX = {Suc X}  For each node Y in Pred(X) For each Z in SX add edge (Y,Z) in GC  end G} end Y in Pred(X) if and only if X in Pred(Y)

86 Seif Haridi and Peter Van Roy86 Conclusion The stateful algorithm was straightforward in this case The declarative algorithm was a bit harder Both algorithms are of O(n 3 ) In the declarative algorithm we assume Successor list is sorted Union is just implemented by mergeing sorted lists O(n) We exploited the fact that Y in Pred(X) if and only if X in Pred(Y) The declarative one is better if the graph is sparse (many elements in the martix are ’false’)

87 Seif Haridi and Peter Van Roy87 System building Abstraction is the best tool to build complex system Complex systems are built by layers of abstractions Each layer have to parts: –Specification, and –Implementation Any layer uses the specification of the lower layer to implement its functionality

88 Seif Haridi and Peter Van Roy88 Properties needed to support the principle of abstraction Encapsulation –Hide internals from the interface Compositionality –Combine parts to make new parts Instantiation/invocation –Create new instances of parts

89 Seif Haridi and Peter Van Roy89 Component base programming Supports –Encapsulation –Compositionality –Instantiation

90 Seif Haridi and Peter Van Roy90 Object-oriented programming Supports –Encapsulation –Compositionality –Instantiation Plus –Inheritance

91 Seif Haridi and Peter Van Roy91 Component-based programming ”Good software is good in the large and in the small, in its high level architecture and in its low-level details”. In Object-oriented software construction by Bertrand Meyer What is the best way to build big applications? A large application is (almost) always built by a team How should the team members communicate? This depends on the application’s structure (architecture) One way is to structure the application as a hierarchical graph

92 Seif Haridi and Peter Van Roy92 Component-based programming Interface Component instance External world

93 Seif Haridi and Peter Van Roy93 Component based design Team members are assigned individual components Team members communicate at the interface A component, can be implemented as a record that has a name, and a list of other component instances it needs, and a higher-order procedure that returns a component instance with the component instances it needs A component instance has an interface and an internal entities that serves the interface

94 Seif Haridi and Peter Van Roy94 Model independence priciple As the system evolves, a component implementation might change or even the model changes –declarative (functional) –stateful sequential –concurrent, or –relational The interface of a component should be independent of the computation model used to implement the component The interface should depend only on the externally visible functionality of the component

95 Seif Haridi and Peter Van Roy95 Example:memoization Consider Pascal’s triangle One way to make it faster between separate invocations is to remember previously computed rows Here we follow our principle and change only the internals of a component

96 Seif Haridi and Peter Van Roy96 What happens at the interface? The power of the component based infrastructure depends on large extent on the expressiveness of the interface How does components communicate with each others? We have three possible case: –The components are written in the same language –The components are written in different languages –The components are written in different computation model

97 Seif Haridi and Peter Van Roy97 Components in the same language This is easy In Mozart/Oz component instances are modules (records whose fields contain the various services provided by the component-instance part In Java, interfaces are provided by objects (method invocations of objects) In Erlang, component instances are mainly concurrent processes (threads), communication is provided by sending asynchronous messages

98 Seif Haridi and Peter Van Roy98 Components in different languages An intermediate common language is defined to allow components to communicate given that the language provide the same computation model A common example is CORBA IDL (Interface Definition Language) which maps a language entity to a common format at the client component, and does the inverse mapping at the service-provider component The components are normally reside on different operating system processes (or even on different machines) This approach works if the components are relatively large and the interaction is relatively infrequent

99 Seif Haridi and Peter Van Roy99 Illustration (one way) A component C1 calling the function (method) f(x) in the Component C2 Translate f(x) from language L1 (structured data) to IDL (sequence of bytes) Translate f(x) from language IDL (sequence of bytes) to language L2 (structured data) A component C2 invoking the function (method) f(x)


Download ppt "Seif Haridi and Peter Van Roy1 Explicit State Seif Haridi Peter Van Roy."

Similar presentations


Ads by Google