Tuesday, February 3, 2009

Ch5, Ex1

Interleaving is in lockstep.

Message sequence sent is
ping(0) pong(100000) pong(1) ping(100001) ping(2) pong(100002)...

because we first send ping(0) and then immediately pong(100000),
processing of first msg sends pong(1) and processing of second msg
sends ping(100001) and this goes on....

its possible to see by running following code:
declare [QTk]={Module.link [ 'x-oz://system/wp/QTk.ozf']}
declare
proc {NewPortObjects ?AddPortObject ?Call}
Sin P={NewPort Sin}
proc {MsgLoop S1 Procs}
case S1
of msg(I M)|S2 then
try {Procs.I M} catch _ then skip end
{MsgLoop S2 Procs}
[] add(I Proc Sync)|S2 then Procs2 in
Procs2={AdjoinAt Procs I Proc}
Sync=unit
{MsgLoop S2 Procs2}
[] nil then skip end
end
in
proc {AddPortObject I Proc}
Sync in
{Send P add(I Proc Sync)}
{Wait Sync}
end
proc {Call I M}
{Send P msg(I M)}
end
thread {MsgLoop Sin procs} end
end
fun {NewProgWindow CheckMsg}
InfoHdl See={NewCell true}
H D=td(label(text:nil handle:InfoHdl)
checkbutton(
text:CheckMsg handle:H init:true
action:proc {$} See:={H get($)} end))
in
{{QTk.build D} show}
proc {$ Msg}
if @See then {Delay 50} {InfoHdl set(text:Msg)} end
end
end

declare AddPortObject Call
{NewPortObjects AddPortObject Call}
InfoMsg={NewProgWindow "See ping-pong"}
fun {PingPongProc Other}
proc {$ Msg}
case Msg
of ping(N) then
{InfoMsg "ping("#N#")"}
{Delay 1000}
{Call Other pong(N+1)}
[] pong(N) then
{InfoMsg "pong("#N#")"}
{Delay 1000}
{Call Other ping(N+1)}
end
end
end
{AddPortObject pingobj {PingPongProc pongobj}}
{AddPortObject pongobj {PingPongProc pingobj}}
{Call pingobj ping(0)}
{Call pongobj pong(100000)}

Sunday, February 1, 2009

Ch4, Ex22 (todo)

tbd

Ch4, Ex21 (todo)

tbd

Ch4, Ex20 (tbd)

tbd

Ch4, Ex19

In case of Merge, recise order of reading is clear. So result is always deterministic while in client/server example we can have observable nondeterminism due to no restrictions on the order of read of various client streams.

Ch4, Ex18

Results Possible:
1.
bing
bong
2.
bong
bing

Multiple executions are possible.

Ch4, Ex17

% First generate primes then solve hamming problem
declare
proc {Touch L N}
if N > 0 then
{Touch L.2 N-1}
else skip
end
end
fun lazy {Filter Xs F}
case Xs of nil then nil
[] X|Xr andthen {F X} then X|{Filter Xr F}
[] X|Xr then {Filter Xr F}
end
end
fun lazy {Integers N}
N|{Integers N+1}
end
fun lazy {Sieve Xs}
case Xs
of nil then nil
[] X|Xr then Ys in
thread Ys={Filter Xr fun {$ Y} Y mod X \= 0 end} end
X|{Sieve Ys}
end
end
% Generate list of first k primes; k >=1
fun {GeneratePrimes K}
Ps = {Sieve {Integers 2}}
fun {Iter K Ps}
if K==0 then nil
else
case Ps of P|Pr then P|{Iter K-1 Pr} end
end
end
in
{Iter K Ps}
end

% Test, Generating first 10 primes
{Browse {GeneratePrimes 10}}

% Generalized Hamming Problem
declare
fun lazy {Times N H}
case H of X|H2 then N*X|{Times N H2} end
end
fun lazy {Merge Xs Ys}
case Xs#Ys of (X|Xr)#(Y|Yr) then
if X<Y then X|{Merge Xr Ys}
elseif X>Y then Y|{Merge Xs Yr}
else X|{Merge Xr Yr}
end
end
end
fun {Hamming K}
fun {Recur Ps H}
case Ps of P|nil then {Times P H}
[] P|Pr then
{Merge {Times P H} {Recur Pr H}}
end
end
H
in
H = 1|{Recur {GeneratePrimes K} H}
H
end

% Test, Compare results from both, they should be equal
local X in
X = {Hamming 3}
{Touch X 10}
{Browse X}
end

local H in
H=1|{Merge {Times 2 H}
{Merge {Times 3 H}
{Times 5 H}}}
{Browse H}
{Touch H 10}
end