Linguaggi di Programmazione (21 Giugno 2013)
Esercizio 1
Fornire la definizione formale di sostituzione per il lambda-calcolo.
Trovare poi tre termini M,P e Q, tali che M contenga x e y tra le sue variabili
libere e tali che M[P/x,Q/y] sia diverso da M[P/x][Q/y]
Esercizio 2
Inserire le premesse (dandone giustificazione) della seguente regola (T-invk)
utilizzata dal type system di FJ per tipare l'invocazione di metodo.
???
------------------------------------
Γ |- e0.m(e) ∈ C
In cosa si discosta il type system di FJ rispetto a quello di Java
(tenuto conto ovviamente che FJ e' un frammento di Java)?
Esercizio 3
Si consideri il seguente insieme di fatti e le seguenti clausole
Prolog che definiscono le relazioni di genitore, nonno, fratello e cugino
genitore(roberto,gianni).
genitore(paola,gianni).
genitore(gianni,melo).
genitore(francesco,melo).
genitore(luigi,melo).
genitore(meloJun,roberto).
genitore(giacomo,francesco).
genitore(mario,francesco).
genitore(anna,paola).
genitore(foleman,luigi).
nonno(X,Y):-genitore(Z,X),genitore(Y,Z).
fratello(X,Y):- genitore(X,Z),genitore(Y,Z),X\==Y.
cugino(X,Y):- nonno(Z,X),nonno(Z,Y),not(fratello(X,Y)),X\==Y.
Alla query
?- cugino(roberto,Y).
l'interprete Prolog risponde, correttamente:
Y = giacomo ;
Y = mario ;
Y = foleman ;
false.
Se invece cambiamo la clausola che definisce la relazione cugino,
semplicemente permutando i suoi subgoal nel modo seguente
cugino(X,Y):- not(fratello(X,Y)),X\==Y,nonno(Z,X),nonno(Z,Y).
alla stessa query
?- cugino(roberto,Y).
l'interprete Prolog risponde invece solo:
false.
Perche'?
Esercizio 4
Definire i concetti di covarianza e controvarianza di una relazione
rispetto ad un operatore e giustificare informalmente la controvarianza della relazione
di sottotipo per il costruttore
di tipo Ref. Giustificare quindi perche' non e' possibile modificare
il tipo delle instance variables in una sottoclasse.
Esercizio 5
Descrivere il modello di concorrenza ad attori (Actors Model of Concurrency).
Esercizio 6
Nel seguente codice PICT il def increment rappresenta un server che incrementa numeri
e che invia il risultato su un canale pubblico result.
Due clienti utilizzano il server increment in mutua esclusione, utilizzando il canale
lock.
Tali clienti hanno un comportamento finito (utilizzano il numero incrementato con la parte USE(-), non meglio specificata)
e terminano.
Modificare il sistema in modo da avere i due client che,
partendo rispettivamente da 3 e da 4,
una volta utilizzato il risultato incrementato,
lo rimandano nuovamente al server per un nuovo
incremento ed un nuovo utilizzo, all'infinito.
new lock:^[]
new result:^Int
def increment n:Int =
result!(+ 1 n)
run ( lock![]
| lock?[] = ( increment!3
| result?m = ( USE(m)
| lock![]
) )
| lock?[] = ( increment!5
| result?m = ( USE(m)
| lock![]
) ) )