ESERCIZI Actors Model and ERLANG
Esercizio 1
Il seguente modulo Erlang permette di calcolare una funzione map che restituisce lo stesso valore della funzione Haskell
map f [] = []
map f (x:xs) = (f x):(map f xs)
ma in modo tale che ogni valore della lista di output viene calcolato da un processo (Actor) differente
-module(mapfun).
-export([map/2,compute/3]).
collectRes([]) -> [];
collectRes([ID|IDs]) -> receive
{ID,Res} -> [Res|collectRes(IDs)]
end.
map(_,[]) -> [];
map(F,List) ->
ComputingActors = [spawn(mapfun,compute,[F,X,self()]) || X <- List ],
collectRes(ComputingActors).
compute(F,X,Collector) -> Res = F(X),
Collector!{self(),Res}.
Ricopiare e commentare il codice descrivendo sinteticamente il suo funzionamento.
Esercizio 2
Si consideri la seguente funzione Haskell
factg g 0 = g 1
factg g n = (g n)*(factg g (n-1))
Poiche' il calcolo di (g n) potrebbe richiedere tempo,
vogliamo definire la stessa funzione in Erlang in modo
che il calcolo di (g n) venga eseguito da un processo, mentre altri
processi si occupano del calcolo di (factg g (n-1)).
Possibile soluzione.
Esercizio 3
Calcolare la funzione factg dell'esercizio 2 in modo da poter parallelizzare al massimo il calcolo.
Esercizio 4
Scrivere un predicato in Erlang che controlli se tue dipi PICT (opportunamente rappresentati)sono uno un sottotipo dell'altro. Lo si faccia cercando di far eseguire il controllo da
piu' processi. Si renda inoltre la funzione parametrica, in modo da poter fornire come
parametro i tipi base che si intendono utilizzare e quale relazione di sottotipaggio
c'e' tra di loro.
Possibile soluzione. (by rondey)
Esercizio 5
Esercizio 6
Esercizio 7
Esercizio 8
Esercizio 9
Esercizio 10
Esercizio 11
Descrivere il modello di concorrenza ad attori (Actors Model of Concurrency).
Esercizio 12
Esercizio 13
Definire una funzione map in Erlang che restituisca lo stesso valore della seguente funzione Haskell
map f [] = []
map f (x:xs) = (f x):(map f xs)
ma in cui ogni valore della lista di output venga calcolato da un processo (Actor) differente
Possibile soluzione.
Esercizio 14 (non banale)
Modificare il programma in [AAVV] Erlang Examples relativo alle espressioni regolari, in modo che la funzione create prenda un argomento
che rappresenta la funzione di transizione di un automa a stati finiti, crei l'automa
corrispondente e restituisca il PID del manager. Assumiamo che gli automi generati da create
siano dei riconoscitori di linguaggi regolari su {a,b,c}. La funzione di transizione si puo'
rappresentare come lista di quadruple (i primi tre elementi di una quadrupla corrispondono ad una riga della tabella
associata alla funzione di transizione, mentre il quarto elemento descrive se lo stato e' o meno dfinale).
Possibile soluzione.
Esercizio 15
Il seguente modulo Erlang permette di calcolare una funzione map che restituisce lo stesso valore della funzione Haskell
map f [] = []
map f (x:xs) = (f x):(map f xs)
ma in modo tale che ogni valore della lista di output viene calcolato da un processo (Actor) differente.
-module(mapfun).
-export([map/2,compute/3]).
collectRes([]) -> [];
collectRes([ID|IDs]) -> receive
{ID,Res} -> [Res|collectRes(IDs)]
end.
map(_,[]) -> [];
map(F,List) ->
ComputingActors = [spawn(mapfun,compute,[F,X,self()]) || X <- List ],
collectRes(ComputingActors).
compute(F,X,Collector) -> Res = F(X),
Collector!{self(),Res}.
Modificare il modulo Erlang in modo che i risultati vengano ricevuti
dalla funzione collectRes
in qualsiasi ordine e poi riordinati correttamente.
Possibile soluzione.
Esercizio 17
Si consideri la seguente estensione del programma usable dell'esercizio 12 di Haskell
usable Yor pred = False
usable (Frunz n m y1 y2) pred = (pred n)||(pred m)||(usable y1)||(usable y2)
In considerazione del fatto che il predicato pred in input possa essere
molto pesante dal punto di vista computazionale, si scriva un programma Erlang
in modo che il calcolo dei valori booleani (pred n) venga eseguito da processi
indipendenti.
Supporre che elementi del tipo di dato Yunz vengano rappresentati da liste
con le seguenti forme: [yor] per rappresentare uno Yor, e [frunz,N,M,Y1,Y2] per rappresentare
Yunz che non sono Yor (ovviamente N ed M saranno numeri e Y1 ed Y2 due liste che rappresentano
due Yunz).
Possibile soluzione.
Esercizio 18
Esercizio 19
Scrivere il corrispettivo Erlang della funzione Haskell treeapply
definita da
data BT a = Leaf a | Node a (BT a) (BT a)
treeapply f (Leaf x) = x
treeappply f (Node n t1 t2) = f n (treeapply f t1) (treeapply f t2)
Il programma Erlang deve far si
che la computazione sia parallelizzabile il piu' possibile.
Supporre di aver definito in Erlang un modulo
-module(bt)
-export(leaf/1, nodeLabel/3, getRoot/1, subtreeL/1, subtreeR/1, isLeaf/1)
Possibile soluzione.
Esercizio 20
Scrivere un modulo Erlang contenente una funzione (insieme ad altre)
che permetta di creare attori che corrispondano ad oggetti
appartenenti alle seguente classe OCaml:
class cell =
object (self:'self)
val mutable contents = 0
method read = contents
method write new_cont = contents <- new_cont
method eq (c:`self) = (self#read=c#read)
end;;
Commentare il codice.
Possibile soluzione.
Esercizio 21
Si consideri il sistema degli N filosofi a cena, con N forchette sul tavolo,
parzialmente implementato nel seguente codice Erlang.
-module(diningPhil).
-export([create/1,looptable/1,loopphil/1]).
% Funzione ausiliaria che restituisce la coppia degli indici delle forchette
% associate al filosofo M-esimo (N èl numero totale di filosofi)
forks(M, N) ->
if
(M =:= 1) -> {N, 1};
true -> {M - 1, M}
end.
create(N) ->
Table = spawn(diningPhil,looptable,[[true| | X<- lists:seq(1,N)]]),
Phils = [spawn(diningPhil,loopphil,[forks(X,N),X,Table]) || X <- lists:seq(1,N)]
true.
loopphil({L,R},NumPhil,Table) -> think(),
......
eat(),
......
looptable(ListForksAvailable) -> ...
Si completi il codice solamente della funzione loopphil.
Si assuma che le funzioni think()
e eat() siano gia' implementate e
che il comportamento
di ogni filosofo sia: pensare, mandare richiesta di acquisizione
prima forchetta al tavolo, ricevere concessione forchetta,
mandare richiesta di acquisizione
seconda forchetta al tavolo, ricevere concessione forchetta, mangiare, rilasciare le forchette,
e di nuovo cosi', all'infinito.
Si assuma che nel sistema non ci sia alcuna politica per evitare uno stallo.
Possibile soluzione.
Esercizio 22
Implementare in Erlang la funzione che, presa una funzione F ed un numero N,
restituisca la somma degli F(i) con i che va da 1 ad N.
Poiche' il calcolo di F(i) potrebbe risultare pesante dal punto di vista
computazionale, si faccia in modo che ogni singolo valore F(i) venga calcolato
da un processo apposito.
Possibile soluzione.
Esercizio XX
Possibile soluzione.