├── .gitignore ├── README.md ├── deterministic_dataflow ├── forcollect.oz ├── n_full_adder.oz └── not_prime.oz ├── final ├── object_consumer.oz └── shared_stream.oz ├── high_order_programming_records_and_trees ├── build.oz ├── infix_traverse_btree.oz ├── is_balanced.oz ├── list_to_tree.oz ├── transform.oz └── tree_to_list.oz ├── invariant_programming_and_lists ├── append.oz ├── factorial.py ├── find_in_list.oz ├── flatten_list.oz ├── list_factorial.oz ├── mirror.oz ├── naive_fib.oz ├── prime.oz ├── sum.oz └── tail_fib.oz ├── java_and_dataflow ├── counter.oz ├── produce_consume_filter.oz ├── queue.oz ├── reverse.oz ├── stack.oz └── stream.oz ├── midterm └── midterm.oz ├── multiagent_dataflow ├── Lifts │ ├── Agent.oz │ ├── Cabin.oz │ ├── Floor.oz │ ├── Lift.oz │ └── Main.oz ├── broadcast.oz ├── port_eval.oz └── port_example.oz ├── paradigms_redux ├── exceptions.oz └── tree_oop.oz ├── semantics └── tail_recur_proc_fact.oz └── state_data_abstraction_and_oop ├── collection.oz ├── eval.oz ├── expressions.oz ├── palindrome.oz ├── reverse_list.oz └── shuffle_list.oz /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *# 3 | .idea/ 4 | .swap 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##Paradigms of Computer Programming 2 | ------ 3 | Quizzes and homeworks for edX course **Paradigms of Computer Programming** 4 | 5 | -------------------------------------------------------------------------------- /deterministic_dataflow/forcollect.oz: -------------------------------------------------------------------------------- 1 | declare 2 | proc {ForCollect Xs P Ys} 3 | Acc={NewCell Ys} 4 | proc {C X} R2 in @Acc=X|R2 Acc:=R2 end 5 | in 6 | for X in Xs do {P C X} end 7 | @Acc=nil 8 | end 9 | 10 | local R in 11 | R={ForCollect [1 2 3 4 5] proc {$ C X} if X==1 then {C 2} else {C X*X} end end} 12 | {Browse R} 13 | end 14 | 15 | -------------------------------------------------------------------------------- /deterministic_dataflow/n_full_adder.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {AndG X Y} 3 | X*Y 4 | end 5 | 6 | fun {OrG X Y} 7 | X+Y-X*Y 8 | end 9 | 10 | fun {XorG X Y} 11 | X+Y-2*X*Y 12 | end 13 | 14 | proc {FullAdder X Y Z C S} 15 | A B D E F 16 | in 17 | A={AndG X Y} 18 | B={AndG Y Z} 19 | D={AndG X Z} 20 | F={OrG B D} 21 | C={OrG A F} 22 | E={XorG X Y} 23 | S={XorG Z E} 24 | end 25 | 26 | fun {ListAdder L1 L2} 27 | case L1#L2 of nil#nil then 28 | nil#0 29 | [] (H1|T1)#(H2|T2) then 30 | case {ListAdder T1 T2} of Lst#Cin then 31 | local Cout S in 32 | {FullAdder H1 H2 Cin Cout S} 33 | (S|Lst)#Cout 34 | end 35 | end 36 | end 37 | end 38 | 39 | %{Browse {ListAdder [0 1 0 1] [1 0 1 0]}} 40 | 41 | fun {NFullAdder S1 S2} 42 | case S1#S2 of (H1|T1)#(H2|T2) then 43 | {ListAdder H1 H2}|{NFullAdder T1 T2} 44 | else nil end 45 | end 46 | 47 | fun {RandList N} 48 | if N==0 then nil 49 | else ({OS.rand} mod 2)|{RandList N-1} end 50 | end 51 | 52 | %{Browse {RandList 3}} 53 | 54 | fun {Stream N} 55 | {RandList N}|{Stream N} 56 | end 57 | 58 | 59 | local S1 S2 S3 in 60 | S1=[1 1 1 1 1]|[0 0 0 0 0]|[1 1 1 1 0]|_ 61 | S2=[1 1 1 1 1]|[0 0 0 0 0]|[0 0 0 0 1]|_ 62 | %thread S1={Stream 4} end 63 | %thread S2={Stream 4} end 64 | thread S3={NFullAdder S1 S2} end 65 | {Delay 1000} 66 | {Browse S3} 67 | end 68 | 69 | -------------------------------------------------------------------------------- /deterministic_dataflow/not_prime.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Prod Start End} 3 | if Start > End then nil 4 | else Start|{Prod Start+1 End} end 5 | end 6 | 7 | fun {Stream Start} 8 | Start|{Stream Start+1} 9 | end 10 | 11 | fun {Filter Stream K} 12 | case Stream of H|T then 13 | if H mod K == 0 then {Filter T K} 14 | else H|{Filter T K} end 15 | else nil end 16 | end 17 | 18 | 19 | fun {Sieve S} 20 | case S of H|T then 21 | %{Delay 1000} 22 | %{Browse H} 23 | %because of thread it works when S is a stream 24 | H|{Sieve thread {Filter T H} end} 25 | %below works when S is a list, but not when S is a Stream 26 | %H|{Sieve {Filter T H}} 27 | else nil end 28 | end 29 | 30 | fun {NotPrime S1 S2} 31 | case S1 of H1|T1 then 32 | case S2 of H2|T2 then 33 | if H1==H2 then {NotPrime T1 T2} 34 | else H1|{NotPrime T1 S2} end 35 | else S1 end 36 | else nil end 37 | end 38 | 39 | local X Y Z in 40 | thread X={Prod 2 60} end 41 | %thread X={Stream 2} end 42 | thread Y={Sieve X} end 43 | Z={NotPrime X Y} 44 | {Browse Z} 45 | end 46 | -------------------------------------------------------------------------------- /final/object_consumer.oz: -------------------------------------------------------------------------------- 1 | declare 2 | class List 3 | attr list 4 | 5 | meth init(L) 6 | list:=L 7 | end 8 | 9 | meth isEven(I $) 10 | {Nth @list I+1} mod 2 == 0 11 | end 12 | 13 | meth get(I $) 14 | {Nth @list I+1} 15 | end 16 | 17 | meth getList($) 18 | @list 19 | end 20 | end 21 | 22 | 23 | fun {Producer M N} 24 | fun {Mrand X} 25 | if X == 0 then nil 26 | else {OS.rand}|{Mrand X-1} end 27 | end 28 | in 29 | if N == 0 then nil 30 | else {New List init({Mrand M})}|{Producer M N-1} end 31 | end 32 | 33 | fun {Filter S J} 34 | case S of H|T then 35 | if {H isEven(J $)} then H|{Filter T J} 36 | else {Filter T J} end 37 | else nil end 38 | end 39 | 40 | fun {Consumer P S1 S2} 41 | case S1#S2 of (H1|T1)#(H2|T2) then 42 | if {H1 get(P $)} < {H2 get(P $)} then H1|H2|{Consumer P T1 T2} 43 | else H2|H1|{Consumer P T1 T2} end 44 | else nil end 45 | end 46 | 47 | L1 = {New List init([1 2 3])} 48 | {Browse {L1 get(0 $)}} 49 | 50 | L2 = {Producer 3 3} 51 | {Browse {Filter L2 1}} 52 | 53 | -------------------------------------------------------------------------------- /final/shared_stream.oz: -------------------------------------------------------------------------------- 1 | declare 2 | proc {Add S} 3 | thread 4 | case S of r('add' A B R)|T then 5 | R=A+B 6 | {Add T} 7 | [] H|T then {Add T} 8 | else skip end 9 | end 10 | end 11 | 12 | proc {Sub S} 13 | thread 14 | case S of r('sub' A B R)|T then 15 | R=A-B 16 | {Sub T} 17 | [] H|T then {Sub T} 18 | else skip end 19 | end 20 | end 21 | 22 | proc {Mul S} 23 | thread 24 | case S of r('mul' A B R)|T then 25 | R=A*B 26 | {Mul T} 27 | [] H|T then {Mul T} 28 | else skip end 29 | end 30 | end 31 | 32 | proc {Divi S} 33 | thread 34 | case S of r('divi' A B R)|T then 35 | R=A div B 36 | {Divi T} 37 | [] H|T then {Divi T} 38 | else skip end 39 | end 40 | end 41 | 42 | local S in 43 | {Add S} 44 | {Sub S} 45 | {Mul S} 46 | {Divi S} 47 | S = r('add' 1 2 _)|r('sub' 10 5 _)|r('sub' 5 5 _)|_ 48 | {Browse S} % Displays: r('add' 1 2 3)|r('sub' 10 5 5)|r('sub' 5 5 0)|_ 49 | end 50 | -------------------------------------------------------------------------------- /high_order_programming_records_and_trees/build.oz: -------------------------------------------------------------------------------- 1 | local 2 | F 3 | fun {Build D C} 4 | fun {Out X D C} 5 | case D of 6 | H|T then if X==H then C.1 else {Out X T C.2} end 7 | else 'bottom' end 8 | end 9 | in 10 | fun {$ X} {Out X D C} end 11 | end 12 | in 13 | F = {Build [1 2 3] ['a' 'b' 'c']} 14 | {Browse {F 1}} 15 | {Browse {F 2}} 16 | {Browse {F 3}} 17 | end 18 | -------------------------------------------------------------------------------- /high_order_programming_records_and_trees/infix_traverse_btree.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Infix Tree} 3 | case Tree of 4 | btree(X left:Y right:Z) then {Append {Append {Infix Y} [X]} {Infix Z}} 5 | [] leaf then nil 6 | end 7 | end 8 | 9 | {Browse {Infix btree(4 left:btree(2 left:btree(1 left:leaf right:leaf) 10 | right:btree(3 left:leaf right:leaf)) 11 | right:btree(5 left:leaf right:leaf))}} 12 | -------------------------------------------------------------------------------- /high_order_programming_records_and_trees/is_balanced.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {IsBalanced Tree} 3 | fun{NumLeaves Tree} 4 | case Tree of 5 | leaf then 1 6 | [] btree(T left:L right:R) then {NumLeaves L} + {NumLeaves R} 7 | end 8 | end 9 | in 10 | case Tree of 11 | leaf then true 12 | [] btree(T left:L right:R) then {IsBalanced L} andthen {IsBalanced R} 13 | andthen {Number.abs {NumLeaves L}-{NumLeaves R}}<2 14 | end 15 | end 16 | 17 | {Browse {IsBalanced btree(a left:leaf 18 | right:btree(b left:leaf 19 | right:btree(c left:leaf right:leaf)))}} 20 | {Browse {IsBalanced btree(a left:leaf 21 | right:btree(b left:leaf 22 | right:leaf))}} 23 | -------------------------------------------------------------------------------- /high_order_programming_records_and_trees/list_to_tree.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {FromListToTree L} 3 | fun {Insert Tree Elt} 4 | case Tree of 5 | leaf then btree(Elt left:leaf right:leaf) 6 | [] btree(Root left:L right:R) then if Elt < Root 7 | then btree(Root left:{Insert L Elt} right:R) 8 | else if Elt > Root 9 | then btree(Root left:L right:{Insert R Elt}) 10 | else Tree end 11 | end 12 | end 13 | end 14 | 15 | fun {ListToTree Tree List} 16 | case List of 17 | nil then Tree 18 | [] H|T then {ListToTree {Insert Tree H} T} 19 | end 20 | end 21 | in 22 | {ListToTree leaf L} 23 | end 24 | 25 | 26 | {Browse {FromListToTree [42 42 24 12 28 51 49 77]}} 27 | -------------------------------------------------------------------------------- /high_order_programming_records_and_trees/transform.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Transform1 L} 3 | fun {Assign R Fields Values} 4 | case Fields of 5 | nil then R 6 | [] H|T then R.H = {Transform1 Values.1} {Assign R T Values.2} 7 | end 8 | end 9 | in 10 | case L of 11 | H|(Mh|Mt)|T|nil then 12 | {Assign {Record.make H Mh|Mt} Mh|Mt T} 13 | else L end 14 | end 15 | 16 | fun {Transform2 L} 17 | fun {Adjoin R Fields Values} 18 | case Fields of 19 | nil then R 20 | [] H|T then {Adjoin {AdjoinAt R H {Transform2 Values.1}} T Values.2} 21 | end 22 | end 23 | in 24 | case L of 25 | H|(Mh|Mt)|(Th|Tt)|nil then {Adjoin H(Mh:{Transform2 Th}) Mt Tt} 26 | else L end 27 | end 28 | 29 | 30 | 31 | {Browse {Transform1 [z [3 a] [b [y [4] [5]]]]}} 32 | {Browse {Transform2 [z [3 a] [b [y [4] [5]]]]}} 33 | 34 | -------------------------------------------------------------------------------- /high_order_programming_records_and_trees/tree_to_list.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {FromTreeToList T} 3 | case T of 4 | leaf then nil 5 | [] btree(Root left:L right:R) then 6 | {Append {Append {FromTreeToList L} [Root]} {FromTreeToList R}} 7 | end 8 | end 9 | 10 | {Browse {FromTreeToList btree(42 left:btree(24 left:btree(12 left:leaf right: leaf) 11 | right:leaf) 12 | right:leaf)}} 13 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/append.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {AppendLists L1 L2} 3 | case L1 of 4 | nil then L2 5 | [] H|T then H|{AppendLists T L2} 6 | end 7 | end 8 | 9 | {Browse {AppendLists [4] [1 2 3]}} 10 | {Browse {AppendLists [5 [6]] [1 2 3]}} 11 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/factorial.py: -------------------------------------------------------------------------------- 1 | """ 2 | The script below shows that Python does not support tail call optimization. 3 | """ 4 | from memory_profiler import profile 5 | 6 | 7 | def fact(n): 8 | if n == 0: 9 | return 1 10 | else: 11 | return n * fact(n - 1) 12 | 13 | 14 | def fact_tail(n, a=1): 15 | if n == 0: 16 | return a 17 | else: 18 | return fact_tail(n - 1, n * a) 19 | 20 | 21 | def fact_loop(n, a=1): 22 | while True: 23 | if n == 0: 24 | return a 25 | n, a = n - 1, n * a 26 | 27 | 28 | @profile 29 | def main(n): 30 | #a = [fact_tail(i) for i in xrange(n)] 31 | b = [fact(i) for i in xrange(n)] 32 | #c = [fact_loop(i) for i in xrange(n)] 33 | 34 | if __name__ == '__main__': 35 | main(500) 36 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/find_in_list.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Prefix L1 L2} 3 | case L1 of 4 | nil then true 5 | [] H|T then 6 | if L2 == nil then false 7 | else H==L2.1 andthen {Prefix T L2.2} end 8 | end 9 | end 10 | 11 | declare 12 | fun {FindString L1 L2} 13 | if L2 == nil then {Prefix L1 L2} 14 | else 15 | if {Prefix L1 L2} then true 16 | else {FindString L1 L2.2} end 17 | end 18 | end 19 | 20 | {Browse {Prefix [1 2] [1 2 3]}} 21 | {Browse {Prefix nil [1 2 3]}} 22 | {Browse {Prefix [1] nil}} 23 | {Browse {FindString [1 3] [1 2 3]}} 24 | {Browse {FindString nil nil}} 25 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/flatten_list.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {FlattenList L} 3 | case L of 4 | nil then L 5 | [] H|T then 6 | case H of 7 | HH|HT then {Append {FlattenList H} {FlattenList T}} 8 | else H|{FlattenList T} 9 | end 10 | end 11 | end 12 | 13 | {Browse {FlattenList [[1 2] [1 [2]]]}} 14 | {Browse {FlattenList [[1 2 [3 [4[5]]]] [1 [2]]]}} 15 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/list_factorial.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {ListFact L} 3 | fun {Fact N Acc} 4 | if N<2 then Acc 5 | else {Fact N-1 N*Acc} end 6 | end 7 | in 8 | case L of 9 | nil then nil 10 | [] H|T then {Fact H 1}|{ListFact T} 11 | end 12 | end 13 | 14 | {Browse {ListFact [1 2 3]}} 15 | {Browse {ListFact [7 6 15]}} 16 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/mirror.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {MainMirror N} 3 | fun {Mirror N Acc} 4 | if N==0 then Acc 5 | else {Mirror (N div 10) Acc*10+(N mod 10)} end 6 | end 7 | in 8 | {Mirror N 0} 9 | end 10 | 11 | {Browse {MainMirror 1234}} 12 | {Browse {MainMirror 876465}} 13 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/naive_fib.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {NaiveFib N} 3 | case N of 4 | 0 then 0 5 | [] 1 then 1 6 | else {NaiveFib N-1} + {NaiveFib N-2} 7 | end 8 | end 9 | 10 | {Browse {NaiveFib 32}} 11 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/prime.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Prime N} 3 | fun {IsPrime N Acc} 4 | if Acc==1 then true 5 | else 6 | if N mod Acc == 0 then false 7 | else {IsPrime N Acc-1} end 8 | end 9 | end 10 | in 11 | if N==1 then false 12 | else {IsPrime N N-1} end 13 | end 14 | 15 | 16 | {Browse {Prime 1}} 17 | {Browse {Prime 2}} 18 | {Browse {Prime 13}} 19 | {Browse {Prime 50}} 20 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/sum.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {MainSum N} 3 | fun {Sum N Acc} 4 | if N==0 then Acc 5 | else {Sum N-1 N+Acc} end 6 | end 7 | in 8 | {Sum N 0} 9 | end 10 | 11 | {Browse {MainSum 10}} 12 | {Browse {MainSum 5}} 13 | -------------------------------------------------------------------------------- /invariant_programming_and_lists/tail_fib.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {TailFib N} 3 | fun {Fib N Acc1 Acc2} 4 | case N of 5 | 0 then Acc1 6 | [] 1 then Acc2 7 | else {Fib N-1 Acc2 Acc1+Acc2} 8 | end 9 | end 10 | in 11 | {Fib N 0 1} 12 | end 13 | 14 | {Browse {TailFib 32}} 15 | {Browse {TailFib 42}} 16 | -------------------------------------------------------------------------------- /java_and_dataflow/counter.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Counter S} 3 | fun {Count Lst M} 4 | case Lst of 5 | nil then [M#1] 6 | [] X#Y|T then 7 | if X==M then X#(Y+1)|T 8 | else X#Y|{Count T M} end 9 | end 10 | end 11 | local Cell={NewCell nil} in 12 | fun {Consume Stream} 13 | case Stream of H|T then 14 | Cell:={Count @Cell H} 15 | @Cell|{Consume T} 16 | else _ end 17 | end 18 | end 19 | in 20 | thread {Consume S} end 21 | end 22 | 23 | local InS X in 24 | X={Counter InS} 25 | InS=a|b|a|c|_ 26 | {Delay 2000} 27 | {Browse X} 28 | end 29 | -------------------------------------------------------------------------------- /java_and_dataflow/produce_consume_filter.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Producer N} 3 | fun {Prod M} 4 | if M ::= up | down 7 | %%% ::= propose(time: status:) 8 | %%% ::= reserve | reject 9 | %%% 10 | %%% Request (received) messages: 11 | %%% press() 12 | %%% press(, ?Lift) 13 | %%% 14 | %%% Indication (sent) messages: 15 | %%% request(floor: dir: answer:?) 16 | %%% 17 | 18 | 19 | 20 | declare 21 | 22 | local 23 | 24 | proc {Select As B} 25 | case As 26 | of nil then 27 | B.status = reserve 28 | [] A|Ar then 29 | if A.time < B.time then 30 | B.status = reject {Select Ar A} 31 | else 32 | A.status = reject {Select Ar B} 33 | end 34 | end 35 | end 36 | local 37 | fun {In Xs P I} 38 | case Xs 39 | of nil then {Browse error(I)} I 40 | [] X|_ andthen {P X} then I 41 | [] _|Xr then {In Xr P I+1} 42 | end 43 | end 44 | in 45 | fun {Index Xs P} {In Xs P 1} end 46 | end 47 | 48 | fun {SelectLift As Ls} 49 | {Select As.2 As.1} 50 | {Nth Ls {Index As fun{$ A} A.status==reserve end}} 51 | end 52 | 53 | fun {FloorProcess S M} 54 | Floor = S.floor 55 | Lifts = S.lifts 56 | in 57 | case M 58 | of press(Dir) then 59 | As = {Map Lifts 60 | fun {$ L} 61 | A 62 | in 63 | {L request(floor:Floor dir:Dir answer:?A)} A 64 | end} 65 | in 66 | {Select As.2 As.1} S 67 | [] press(Dir Lift) then 68 | As = {Map Lifts 69 | fun {$ L} 70 | A 71 | in 72 | {L request(floor:Floor dir:Dir answer:?A)} A 73 | end} 74 | in 75 | Lift = {SelectLift As Lifts} S 76 | end 77 | end 78 | 79 | in 80 | 81 | fun {NewFloor N Lifts} 82 | {NewAgent FloorProcess 83 | state(floor:N lifts:Lifts id:floor(N))} 84 | end 85 | 86 | end 87 | -------------------------------------------------------------------------------- /multiagent_dataflow/Lifts/Lift.oz: -------------------------------------------------------------------------------- 1 | %%% Author: 2 | %%% Seif Haridi 3 | %%% 4 | %%% The lift Agent 5 | %%% Types: 6 | %%% ::= up | down 7 | %%% ::= propose(time: status:) 8 | %%% ::= reserve | reject 9 | %%% ::= wait | stop | down | up 10 | %%% 11 | %%% Request (received) messages: 12 | %%% request(floor: dir: answer:?) 13 | %%% stop(floor:) 14 | %%% arrived(floor: action:?) 15 | %%% 16 | %%% Indication (sent) messages: 17 | %%% propose(time: status:?) 18 | %%% 19 | 20 | /************** Messages accepted 21 | 22 | 23 | 24 | 25 | 26 | ****************/ 27 | 28 | declare 29 | 30 | local 31 | TimeMove = 1 32 | TimeStop = 5 33 | 34 | fun {Insert Dir Floor Now Stop} 35 | case Stop 36 | of nil then [Floor] 37 | [] Next|After then 38 | if Next==Floor then Stop 39 | elseif Floor==Now then Stop 40 | elseif Dir==up andthen Now < Floor andthen Floor < Next then 41 | Floor|Stop 42 | elseif Dir==down andthen Next < Floor andthen Floor Now then 74 | {Insert up Floor Now Stop} 75 | else 76 | {Insert down Floor Now Stop} 77 | end 78 | end 79 | 80 | fun {WaitTime Dir Floor Now Stop} 81 | case Stop 82 | of nil then {Abs Floor-Now}*TimeMove 83 | [] Next|After then 84 | if Next==Floor then 85 | {Abs Floor-Now}*TimeMove 86 | elseif Dir==up andthen Now==Floor andthen Floor>=Next then 89 | (Now-Floor)*TimeMove 90 | else 91 | {WaitTime Dir Floor Next After}+ 92 | {Abs Now-Next}*TimeMove+TimeStop 93 | end 94 | end 95 | end 96 | 97 | fun {LiftProcess S M} 98 | Stop = S.stop 99 | CurrentFloor = S.floor 100 | in 101 | case M 102 | of request(floor:Floor dir:Dir answer:?Answer) then 103 | Ack 104 | in 105 | Answer = propose(time:{WaitTime Dir Floor CurrentFloor Stop} status:Ack) 106 | case Ack 107 | of reserve then {AdjoinAt S stop {Insert Dir Floor CurrentFloor Stop}} 108 | [] reject then S 109 | end 110 | [] stop(floor:Floor) then S1 in 111 | {Browse stop(floor:Floor)} 112 | S1 = {AdjoinAt S stop {StopAt Floor CurrentFloor Stop}} 113 | {Browse S1.id#S.stop} 114 | S1 115 | [] arrived(floor:N action:?Continue) then 116 | case Stop 117 | of nil then 118 | Continue = wait 119 | {AdjoinAt S floor N} 120 | [] Next|After andthen Next==N then 121 | Continue = stop 122 | {AdjoinAt {AdjoinAt S stop After} floor N} 123 | [] Next|_ andthen NextN then 127 | Continue = up 128 | {AdjoinAt S floor N} 129 | end 130 | [] id(I) then I = S.id S 131 | end 132 | end 133 | in 134 | fun {NewLift N} 135 | {NewAgent LiftProcess state(floor:1 stop:nil id:lift(N))} 136 | end 137 | 138 | end 139 | 140 | -------------------------------------------------------------------------------- /multiagent_dataflow/Lifts/Main.oz: -------------------------------------------------------------------------------- 1 | %%% 2 | %%% Author: 3 | %%% Seif Haridi 4 | %%% 5 | %%% Copyright: 6 | %%% Seif Haridi, 2003 7 | %%% 8 | %%% Based on Erlang Lift control system in Concurrent Programming in Erlang 9 | %%% 10 | %%% 11 | %%% Main file for the lift simulation 12 | %%% 13 | 14 | \insert 'Agent.oz' 15 | \insert 'Cabin.oz' 16 | \insert 'Lift.oz' 17 | \insert 'Floor.oz' 18 | 19 | declare 20 | 21 | local 22 | 23 | proc {LinkLifts Ls I NewCabin} 24 | %% Link lifts to cabins 25 | case Ls 26 | of nil then skip 27 | [] L|Lr then {NewCabin L I} {LinkLifts Lr I+1 NewCabin} 28 | end 29 | end 30 | 31 | fun {ForCons I N F} 32 | %% Create a list with N elements by calling F 33 | if I=