├── .gitignore ├── README.md ├── invariant_programming_and_lists ├── naive_fib.oz ├── sum.oz ├── append.oz ├── mirror.oz ├── tail_fib.oz ├── list_factorial.oz ├── flatten_list.oz ├── prime.oz ├── find_in_list.oz └── factorial.py ├── state_data_abstraction_and_oop ├── reverse_list.oz ├── shuffle_list.oz ├── collection.oz ├── eval.oz ├── palindrome.oz └── expressions.oz ├── java_and_dataflow ├── reverse.oz ├── stream.oz ├── counter.oz ├── produce_consume_filter.oz ├── stack.oz └── queue.oz ├── multiagent_dataflow ├── port_example.oz ├── Lifts │ ├── Agent.oz │ ├── Floor.oz │ ├── Main.oz │ ├── Cabin.oz │ └── Lift.oz ├── port_eval.oz └── broadcast.oz ├── deterministic_dataflow ├── forcollect.oz ├── not_prime.oz └── n_full_adder.oz ├── semantics └── tail_recur_proc_fact.oz ├── high_order_programming_records_and_trees ├── build.oz ├── infix_traverse_btree.oz ├── tree_to_list.oz ├── is_balanced.oz ├── transform.oz └── list_to_tree.oz ├── final ├── shared_stream.oz └── object_consumer.oz ├── paradigms_redux ├── exceptions.oz └── tree_oop.oz └── midterm └── midterm.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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /state_data_abstraction_and_oop/reverse_list.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Reverse L} 3 | local X in 4 | {NewCell nil X} 5 | for Elt in L do 6 | X:=Elt|@X 7 | end 8 | @X 9 | end 10 | end 11 | 12 | {Browse {Reverse [1 2 3 4]}} 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /java_and_dataflow/reverse.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Reverse S} 3 | local I={NewCell S} in 4 | local Temp={NewCell nil} in 5 | for C in @I do 6 | Temp:=C|@Temp 7 | end 8 | @Temp 9 | end 10 | end 11 | end 12 | 13 | {Browse {Reverse [1 2 3 4]}} 14 | {Browse {Reverse nil}} 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /multiagent_dataflow/port_example.oz: -------------------------------------------------------------------------------- 1 | declare P S 2 | P={NewPort S} 3 | {Browse S} 4 | for E in S do 5 | {Browse E} 6 | case E of pair(r X) then X=ok 7 | else skip end 8 | end 9 | 10 | {Send P 1} 11 | {Send P 2} 12 | 13 | 14 | declare X 15 | {Browse X} 16 | {Send P pair(r X)} 17 | {Send P pair(r _)} 18 | {Send P notpair(r _)} 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /semantics/tail_recur_proc_fact.oz: -------------------------------------------------------------------------------- 1 | declare 2 | proc {Fact N A R} 3 | local B in 4 | B=(N==0) 5 | if B then R=A 6 | else local N1 A1 in 7 | N1=N-1 8 | A1=A*N 9 | {Fact N1 A1 R} 10 | end 11 | end 12 | end 13 | end 14 | 15 | local R in 16 | {Fact 4 1 R} 17 | {Browse R} 18 | end 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /multiagent_dataflow/Lifts/Agent.oz: -------------------------------------------------------------------------------- 1 | 2 | declare 3 | 4 | fun {NewAgent Process InitState} 5 | Port Stream 6 | proc {Serve Messages State} 7 | case Messages of Message|Next then 8 | {Serve Next {Process State Message}} 9 | end 10 | end 11 | in 12 | 13 | Port={NewPort Stream} 14 | thread {Serve Stream InitState} end 15 | proc {$ M} {Send Port M} end 16 | end 17 | 18 | /* 19 | 20 | 21 | */ 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /java_and_dataflow/stream.oz: -------------------------------------------------------------------------------- 1 | declare 2 | proc {Disp S} 3 | case S of H|T then {Browse H} {Disp T} end 4 | end 5 | 6 | fun {Prod N} 7 | {Delay 1000} 8 | N|{Prod N+1} 9 | end 10 | 11 | fun {Trans S} 12 | case S of N|T then 13 | N*N|{Trans T} 14 | end 15 | end 16 | 17 | 18 | declare S S2 19 | thread S={Prod 1} end 20 | thread S2={Trans S} end 21 | thread {Disp S2} end 22 | 23 | %declare S2 in S=a|b|c|S2 24 | %declare S3 in S2=d|e|f|s3 25 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /multiagent_dataflow/port_eval.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Eval Port} 3 | proc {Process Stream} 4 | case Stream of Func#Input|Tail then 5 | {Send Port {Func Input}} 6 | {Process Tail} 7 | end 8 | end 9 | in 10 | local P S in 11 | P={NewPort S} 12 | thread {Process S} end 13 | P 14 | end 15 | end 16 | 17 | fun {Triple X} 18 | X*3 19 | end 20 | 21 | fun {PlusTwo X} 22 | X+2 23 | end 24 | 25 | % test 26 | local A B C in 27 | A={NewPort B} 28 | C={Eval A} 29 | {Browse B} 30 | {Send C Triple#4} 31 | {Send C PlusTwo#6} 32 | {Send C Triple#3} 33 | end 34 | 35 | -------------------------------------------------------------------------------- /state_data_abstraction_and_oop/shuffle_list.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {Shuffle L} 3 | local Array Len Cell in 4 | Cell={NewCell nil} 5 | Len={Length L} 6 | Array={NewArray 1 Len 0} 7 | for I in 1..Len do 8 | Array.I:={Nth L I} 9 | end 10 | for J in Len..1;~1 do 11 | local R Swap in 12 | R={OS.rand} mod J + 1 13 | Swap=Array.R 14 | Array.R:=Array.J 15 | Array.J:=Swap 16 | end 17 | Cell:=Array.J|@Cell 18 | end 19 | @Cell 20 | end 21 | end 22 | 23 | {Browse {Shuffle [1 2 3 4]}} 24 | {Browse {Shuffle [1 4]}} 25 | -------------------------------------------------------------------------------- /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 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 | -------------------------------------------------------------------------------- /multiagent_dataflow/broadcast.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {NewAgent Process InitState} 3 | Port Stream 4 | in 5 | Port={NewPort Stream} 6 | thread 7 | {FoldL Stream Process InitState _} 8 | end 9 | proc {$ M} {Send Port M} end 10 | end 11 | 12 | % broadcast function 13 | % needs to be a function so that FoldL can update state 14 | fun {BF State Msg} 15 | case Msg of init(As) then state(agents:As) 16 | [] broadcast(M1) then 17 | for A in State.agents do 18 | {A M1} 19 | end 20 | State 21 | else State end 22 | end 23 | 24 | % brodcaster function 25 | % needs to be a function (not a proc) for FoldL to work 26 | fun {BrowseF S M} 27 | {Browse (S.name)#M} 28 | _ % return anything will do 29 | end 30 | 31 | % Broadcaster is a port, BF is the process function 32 | % state is the initial state 33 | Broadcaster={NewAgent BF state} 34 | As=for I in 1..10 collect:C do 35 | {C {NewAgent BrowseF state(name:I)}} 36 | end 37 | {Broadcaster init(As)} 38 | {Broadcaster broadcast(a)} 39 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /paradigms_redux/exceptions.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {DivIfNot5 N T} 3 | if (T mod 5)==0 then error5 4 | else N div T end 5 | end 6 | 7 | fun {DivIfNot4 N T} 8 | X in 9 | X={DivIfNot5 N T-1} 10 | if (T mod 4)==0 then error4 11 | else if X==error5 then 12 | X 13 | else X div T end 14 | end 15 | end 16 | 17 | fun {DivIfNot3 N T} 18 | X in 19 | X={DivIfNot4 N T-1} 20 | if (T mod 3)==0 then error3 21 | else if X==error4 then 22 | X 23 | else X div T end 24 | end 25 | end 26 | 27 | fun {DivIfNot5E N T} 28 | if (T mod 5)==0 then raise mod0By5(error5) end 29 | else N div T end 30 | end 31 | 32 | fun {DivIfNot4E N T} 33 | X in 34 | X={DivIfNot5E N T-1} 35 | if (T mod 4)==0 then raise mod0By4(error4) end 36 | else X div T end 37 | end 38 | 39 | fun {DivIfNot3E N T} 40 | X in 41 | X={DivIfNot4E N T-1} 42 | if (T mod 3)==0 then raise mod0By3(error3) end 43 | else X div T end 44 | end 45 | 46 | 47 | {Browse {DivIfNot4E 60 3}} 48 | 49 | -------------------------------------------------------------------------------- /java_and_dataflow/stack.oz: -------------------------------------------------------------------------------- 1 | declare 2 | class Stack 3 | attr cell 4 | 5 | meth init 6 | cell:=nil 7 | end 8 | 9 | meth size($) 10 | {Length @cell} 11 | end 12 | 13 | meth isEmpty($) 14 | @cell==nil 15 | end 16 | 17 | meth top($) 18 | if @cell==nil then 19 | raise topEmptyStack end 20 | else @cell.1 end 21 | end 22 | 23 | meth push(X) 24 | cell:=X|@cell 25 | end 26 | 27 | meth pop($) 28 | if @cell==nil then 29 | raise popEmptyStack end 30 | else local H in 31 | H = @cell.1 32 | cell:=@cell.2 33 | H 34 | end 35 | end 36 | end 37 | end 38 | 39 | local S={New Stack init} in 40 | {Browse {S size($)}} 41 | {Browse {S isEmpty($)}} 42 | %{Browse {S top($)}} 43 | {S push(8)} 44 | {Browse {S size($)}} 45 | {Browse {S isEmpty($)}} 46 | {Browse {S top($)}} 47 | {Browse {S pop($)}} 48 | %{Browse {S pop($)}} 49 | end 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /state_data_abstraction_and_oop/eval.oz: -------------------------------------------------------------------------------- 1 | declare 2 | fun {NewStack} {NewCell nil} end 3 | fun {IsEmpty S} @S==nil end 4 | proc {Push S X} S:=X|@S end 5 | fun {Pop S} 6 | local Out=@S.1 in 7 | S:=@S.2 8 | Out 9 | end 10 | end 11 | 12 | 13 | fun {Eval L} 14 | local Stack Result in 15 | Stack={NewStack} 16 | Result={NewStack} 17 | for I in {Length L}..1;~1 do 18 | {Push Stack {Nth L I}} 19 | end 20 | for while:{Not {IsEmpty Stack}} do 21 | local Elt in 22 | Elt={Pop Stack} 23 | case Elt of 24 | '+' then {Push Result {Pop Result}+{Pop Result}} 25 | [] '*' then {Push Result {Pop Result}*{Pop Result}} 26 | [] '-' then {Push Result ~{Pop Result}+{Pop Result}} 27 | [] '/' then 28 | local X Y in 29 | X={Pop Result} 30 | Y={Pop Result} 31 | {Push Result Y div X} 32 | end 33 | else {Push Result Elt} end 34 | end 35 | end 36 | {Pop Result} 37 | end 38 | end 39 | 40 | {Browse {Eval [2 3 '+' 4 '*' 10 '/']}} 41 | -------------------------------------------------------------------------------- /paradigms_redux/tree_oop.oz: -------------------------------------------------------------------------------- 1 | declare 2 | class Tree 3 | attr 4 | value 5 | left 6 | right 7 | 8 | meth init(V) 9 | value:=V 10 | left:=leaf 11 | right:=leaf 12 | end 13 | 14 | meth setLeft(T) 15 | left:=T 16 | end 17 | 18 | meth setRight(T) 19 | right:=T 20 | end 21 | 22 | meth setValue(V) 23 | value:=V 24 | end 25 | 26 | meth getLeft($) 27 | @left 28 | end 29 | 30 | meth getRight($) 31 | @right 32 | end 33 | 34 | meth getValue($) 35 | @value 36 | end 37 | 38 | meth isBalanced($) 39 | fun {NumOfLeaves T} 40 | case T of leaf then 1 41 | else {NumOfLeaves {T getLeft($)}}+{NumOfLeaves {T getRight($)}} end 42 | end 43 | in 44 | {Number.abs {NumOfLeaves @left}-{NumOfLeaves @right}}<2 45 | end 46 | 47 | end 48 | 49 | local A B C in 50 | A={New Tree init(4)} 51 | B={New Tree init(5)} 52 | C={New Tree init(6)} 53 | {B setLeft(C)} 54 | {A setLeft(B)} 55 | %{Browse {A getValue($)}} 56 | {Browse {A isBalanced($)}} 57 | {Browse {B isBalanced($)}} 58 | {Browse {C isBalanced($)}} 59 | end 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /java_and_dataflow/queue.oz: -------------------------------------------------------------------------------- 1 | declare 2 | class Queue 3 | attr cell 4 | 5 | meth init 6 | cell:=nil 7 | end 8 | 9 | meth size($) 10 | {Length @cell} 11 | end 12 | 13 | meth isEmpty($) 14 | @cell==nil 15 | end 16 | 17 | meth front($) 18 | if @cell==nil then 19 | raise frontEmptyQueue end 20 | else {Nth @cell {Length @cell}} end 21 | end 22 | 23 | meth enqueue(X) 24 | cell:=X|@cell 25 | end 26 | 27 | meth dequeue($) 28 | if @cell==nil then 29 | raise dequeueEmptyQueue end 30 | else local Len={Length @cell} H List in 31 | H = {Nth @cell Len} 32 | List=@cell 33 | cell:=nil 34 | for I in Len-1..1;~1 do 35 | cell:={Nth List I}|@cell 36 | end 37 | H 38 | end 39 | end 40 | end 41 | end 42 | 43 | local S={New Queue init} in 44 | {Browse {S size($)}} 45 | {Browse {S isEmpty($)}} 46 | %{Browse {S top($)}} 47 | {S enqueue(8)} 48 | {S enqueue(7)} 49 | {Browse {S size($)}} 50 | {Browse {S isEmpty($)}} 51 | {Browse {S front($)}} 52 | {Browse {S dequeue($)}} 53 | {Browse {S size($)}} 54 | {Browse {S front($)}} 55 | %{Browse {S pop($)}} 56 | end 57 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /midterm/midterm.oz: -------------------------------------------------------------------------------- 1 | declare 2 | proc {Split L L1 L2} 3 | case L of 4 | nil then L1=nil L2=nil 5 | [] H|nil then L1=[H] L2=nil 6 | [] H1|H2|T then 7 | local M1 M2 in 8 | L1=H1|M1 9 | L2=H2|M2 10 | {Split T M1 M2} 11 | end 12 | end 13 | end 14 | 15 | fun {Reduction L A B C D} 16 | local L1 L2 La Lb Lc Ld 17 | fun {LstSum Lst} 18 | fun {Sum Lst Acc} 19 | case Lst of 20 | nil then Acc 21 | [] H|T then {Sum T H+Acc} 22 | end 23 | end 24 | in 25 | case Lst of 26 | nil then nil 27 | [] H|T then {Sum H 0}|{LstSum T} 28 | end 29 | end 30 | fun {LstDotLst Lx Ly} 31 | case Lx of 32 | nil then 0 33 | [] H|T then H*Ly.1 + {LstDotLst T Ly.2} 34 | end 35 | end 36 | in 37 | {Split L L1 L2} 38 | {Split L1 La Lc} 39 | {Split L2 Lb Ld} 40 | {LstDotLst {LstSum [La Lb Lc Ld]} [A B C D]} 41 | end 42 | end 43 | 44 | 45 | 46 | 47 | proc {TestSplit} 48 | proc {Test L} 49 | local L1 L2 in 50 | {Split L L1 L2} 51 | {Browse L1} 52 | {Browse L2} 53 | end 54 | end 55 | in 56 | {Test nil} 57 | {Test [a0]} 58 | {Test [a0 a1]} 59 | {Test [a0 a1 a2]} 60 | {Test [a0 a1 a2 a3]} 61 | end 62 | 63 | {TestSplit} 64 | {Browse {Reduction [1 1 1 1 1] 1 2 3 4}} 65 | -------------------------------------------------------------------------------- /state_data_abstraction_and_oop/palindrome.oz: -------------------------------------------------------------------------------- 1 | declare 2 | class Sequence 3 | attr l 4 | 5 | meth init 6 | l:=nil 7 | end 8 | 9 | meth isEmpty($) 10 | @l==nil 11 | end 12 | 13 | meth first($) 14 | @l.1 15 | end 16 | 17 | meth last($) 18 | local Len={Length @l} in 19 | {Nth @l Len} 20 | end 21 | end 22 | 23 | meth insertFirst(X) 24 | l:=X|@l 25 | end 26 | 27 | meth insertLast(X) 28 | local L Len={Length @l} in 29 | L=@l 30 | l:=X|nil 31 | for I in Len..1;~1 do 32 | l:={Nth L I}|@l 33 | end 34 | end 35 | end 36 | 37 | meth removeFirst 38 | l:=@l.2 39 | end 40 | 41 | meth removeLast 42 | local L=@l Len={Length @l}-1 in 43 | l:=nil 44 | for I in Len..1;~1 do 45 | l:={Nth L I}|@l 46 | end 47 | end 48 | end 49 | end 50 | 51 | fun {Palindrome Xs} 52 | S={New Sequence init} 53 | fun {Check} 54 | if {S isEmpty($)} then true 55 | else 56 | if {S first($)}=={S last($)} then 57 | {S removeFirst} 58 | {S removeLast} 59 | {Check} 60 | else false end 61 | end 62 | end 63 | in 64 | for I in Xs do 65 | {S insertFirst(I)} 66 | end 67 | {Check} 68 | end 69 | 70 | {Browse {Palindrome ['s' 'd' 'a']}} 71 | {Browse {Palindrome ['s' 'd' 'a' 'd' 's']}} 72 | {Browse {Palindrome [1 2 3 3 2 1]}} 73 | {Browse {Palindrome [1 2 3 2 1]}} 74 | {Browse {Palindrome nil}} 75 | {Browse {Palindrome ['s']}} 76 | 77 | -------------------------------------------------------------------------------- /multiagent_dataflow/Lifts/Floor.oz: -------------------------------------------------------------------------------- 1 | %%% Author: 2 | %%% Seif Haridi 3 | %%% 4 | %%% The Floor agent 5 | %%% Types: 6 | %%% ::= 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 | -------------------------------------------------------------------------------- /state_data_abstraction_and_oop/expressions.oz: -------------------------------------------------------------------------------- 1 | declare 2 | class Addition 3 | attr x y 4 | meth init(X Y) 5 | x:=X 6 | y:=Y 7 | end 8 | meth evaluate(Result) 9 | local Xresult Yresult in 10 | {@x evaluate(Xresult)} 11 | {@y evaluate(Yresult)} 12 | Result=Xresult+Yresult 13 | end 14 | end 15 | end 16 | 17 | class Subtraction 18 | attr x y 19 | meth init(X Y) 20 | x:=X 21 | y:=Y 22 | end 23 | meth evaluate(Result) 24 | local Xresult Yresult in 25 | {@x evaluate(Xresult)} 26 | {@y evaluate(Yresult)} 27 | Result=Xresult-Yresult 28 | end 29 | end 30 | end 31 | 32 | class Multiplication 33 | attr x y 34 | meth init(X Y) 35 | x:=X 36 | y:=Y 37 | end 38 | meth evaluate(Result) 39 | local Xresult Yresult in 40 | {@x evaluate(Xresult)} 41 | {@y evaluate(Yresult)} 42 | Result=Xresult*Yresult 43 | end 44 | end 45 | end 46 | 47 | class Division 48 | attr x y 49 | meth init(X Y) 50 | x:=X 51 | y:=Y 52 | end 53 | meth evaluate(Result) 54 | local Xresult Yresult in 55 | {@x evaluate(Xresult)} 56 | {@y evaluate(Yresult)} 57 | Result=Xresult div Yresult 58 | end 59 | end 60 | end 61 | 62 | class Constant 63 | attr v 64 | meth init(Value) 65 | v:=Value 66 | end 67 | meth evaluate(Result) 68 | Result=@v 69 | end 70 | end 71 | 72 | class Variable 73 | attr v 74 | meth init(Value) 75 | v:=Value 76 | end 77 | meth set(NewValue) 78 | v:=NewValue 79 | end 80 | meth evaluate(Result) 81 | Result=@v 82 | end 83 | end 84 | 85 | VarX = {New Variable init(0)} 86 | VarY = {New Variable init(0)} 87 | local 88 | Result 89 | C = {New Constant init(6)} 90 | Expr1 = {New Addition init(VarX VarY)} 91 | Expr2 = {New Division init(Expr1 C)} 92 | in 93 | {VarX set(3)} 94 | {VarX set(4)} 95 | {Expr2 evaluate(Result)} 96 | {Browse Result} 97 | end 98 | 99 | -------------------------------------------------------------------------------- /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= ::= 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 | --------------------------------------------------------------------------------