Linguaggi di Programmazione Linguaggi Speciali & Tecnologie dei Linguaggi di Programmazione: Scritto del 30 Giugno 2006 Java Nome e Cognome: Matricola: Corso di Laurea: Date le classi seguenti: class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; public static Point[] makearray(int n, Point p1, Point p2) { Point[] res = new Point[n]; boolean flag = true; for (int i = 0; i < n; i++) { res[i] = flag? p1 : p2; flag =!flag; return res; public static Point sum(point[] a) { Point res = a[0]; for(int i = 1; i < a.length; i++) { res.x = res.x + a[i].y; res.x = res.x + a[i].x; return res; Dopo l esecuzione di: Point pt1 = new Point(1,2); Point pt2 = new Point(2,4); Point pt3 = Point.sum(Point.makeArray(3, pt1, pt2)); 1. Quanto vale pt1.x? 2. Quanto vale pt1.y? 3. Quanto vale pt2.x? 4. Quanto vale pt2.y? 5. Quanto vale pt3.x? 6. Quanto vale pt3.y? Date le classi seguenti: 1
class A { String method(b a, A b) { return "a"; class B extends A { String method(a a, B b) { return "b"; String method(b a, B b) { return "c"; e gli oggetti seguenti: A a = new A(); B b = new B(); A c = new B(); 7. Quanto vale a.method(a, a)? (a) "a" (b) "b" (c) "c" (d) Errore NoSuchMethod (e) Errore Ambiguous 8. Quanto vale b.method(b, b)? (a) "a" (b) "b" (c) "c" (d) Errore NoSuchMethod (e) Errore Ambiguous 9. Quanto vale c.method(c, c)? (a) "a" (b) "b" (c) "c" (d) Errore NoSuchMethod (e) Errore Ambiguous 10. Quanto vale b.method(b, c)? (a) (b) (c) (d) (e) "a" "b" "c" Errore NoSuchMethod Errore Ambiguous 2
11. Dato un array bidimensionale a di stringhe, il suo contorno è composto dalle caselle a[i][j] dove il valore di i o j è quello minimo o quello massimo rispetto alla loro dimensione. Una copertura di a è un array monodimensionale b di stringhe tale che il contorno di a è contenuto in b, ovvero ogni elemento del contorno di a compare in b. Definire un metodo pubblico statico unique che verifica che un array monodimensionale di stringhe è composto di valori unici, ovvero ogni valore compare una volta sola nell array. Definire un metodo minimalcover che prende un array bidimensionale a di stringhe e un array monodimensionale b di stringhe e verifica che b è una copertura di lunghezza minima di a. Per esempio, minimalcover(new String[][] { {"verde", "verde", "verde", "verde", {"bianco", "blue", "bianco", { "rosso", new String[] {"verde", "bianco", "rosso") restituisce true. 3
12. Sia Combinator la rappresentazione di un piccolo linguaggio di combinatori Turing completo. Questo linguaggio è composto di due combinatori S e K e dell applicazione di una funzione a un argomento. abstract class Combinator { class S extends Combinator { S () { class K extends Combinator { K () { 4
class Apply extends Combinator { Combinator fun; Combinator arg; Apply (Combinator fun, Combinator arg) { this.fun = fun; this.arg = arg; Per simulare l applicazione con più di un argomento si combina l applicazione. Per esempio, il termine S K (K S) K che rappresenta l applicazione di S ai tre argomenti K, (K S) e K, ed il termine K S S che rappresenta l applicazione di K ai due argomenti S e S si definiscono come: Combinator c1 = new Apply(new Apply(new Apply(new S(), new K()), new Apply(new K(), new S())), new K()); Combinator c2 = new Apply(new Apply(new K(), new S()), new S()); Ci sono due regole di riduzione, una per ogni combinatore. Dati due termini x e y qualsiasi, K x y si riduce in x. Dati tre termini x, y e z qualsiasi, S x y z si riduce in x z (y z). La valutazione si effettua in modo non deterministico iterando l applicazione delle regole di riduzione all interno del termine. Per esempio, c1 si valuta in K. Una possibile sequenza di riduzioni è la seguente: S K (K S) K K K (K S K) K K S K. Aggiungere in Combinator: - un metodo pubblico iss che indica se un oggetto di tipo Combinator è un S. Per esempio, new S().isS() restituisce true. - un metodo pubblico isk che indica se un oggetto di tipo Combinator è un K. Per esempio, new K().isK() restituisce true. - un metodo pubblico isapp che indica se un oggetto di tipo Combinator è un Apply. Per esempio, c1.isapp() restituisce true. - un metodo pubblico numberofs che ritorna il numero di combinatori S dentro un termine. Per esempio, c1.numberofs() restituisce 2. - un metodo pubblico equals che fa un test di uguaglianza strutturale con un oggetto o di tipo Object. Per esempio, c1.equals("true") restituisce false, invece new S().equals(new S()) restituisce true. - un metodo pubblico gethead che ritorna il combinatore di testa di un applicazione con argomenti multipli. Per esempio, c1.gethead().iss() restituisce true. - un metodo pubblico numberofargs che ritorna il numero di argomenti di un applicazione. Per esempio, c1.numberofargs() restituisce 3 e c2.numberofargs() restituisce 2. - un metodo pubblico isreds che indica se la regola di riduzione per S è applicabile sulla radice di un termine. Per esempio, c1.isreds() restituisce true. - un metodo pubblico isredk che indica se la regola di riduzione per K è applicabile sulla radice di un termine. Per esempio, c2.isredk() restituisce true. - un metodo pubblico reduce che prova ad applicare una riduzione all interno di un termine. Se tale riduzione non è possibile solleva l eccezione NothingToDoException. Per esempio, c2.reduce().iss() restituisce true. 5
- un metodo pubblico eval che itera la riduzione all interno di un termine fino ad esaurimento. Per esempio, c1.eval().isk() restituisce true. 6
7
Esterel 13. Scrivere un programma che gestisce il centralino delle docce di una piscina comunale. Il centralino gestisce l apertura e la chiusura di due docce (OPEN1, OPEN2 e CLOSE1, CLOSE2). All inizio, le due docce non sono in funzione. Sul centralino ci sono due pulsanti con una lampadina che indicano lo stato delle docce. Il programma può accendere la lampadina (LIGHT1_ON o LIGHT2_ON) o spengerla (LIGHT1_OFF o LIGHT1_OFF). Per mettere in funzione una doccia, l utente deve introdurre una carta magnetica (ENTER) e premere sul pulsante corrispondente (BUTTON1 o BUTTON1). Quando la doccia è libera, il centralino carica il costo della doccia sulla carta (DEBIT) e mette in funzione la doccia corrispondente (OPEN1 o OPEN2) e accende la lampadina corrispondente (LIGHT1_ON o LIGHT2_ON). La doccia funziona per 3 minuti (SECOND) prima di fermarsi (CLOSE1 e LIGHT1_OFF o CLOSE2 e LIGHT2_OFF). Premere su una doccia già occupata fa emettere un segnale sonoro (BEEP). Lasciare una carta inserita per più di un minuto (SECOND) fa emettere un segnale sonoro (BEEP) ogni due secondi (SECOND) fino a quando la carta è ritirata (EXIT). Le dichiarazioni dei segnali sono le seguenti: module SHOWER: input SECOND, ENTER, EXIT, BUTTON1, BUTTON2; relation SECOND # ENTER # EXIT # BUTTON1 # BUTTON2; output BEEP, DEBIT, OPEN1, OPEN2, CLOSE1, CLOSE2, LIGHT1_ON, LIGHT2_ON, LIGHT1_OFF, LIGHT2_OFF;... end module 8
Risposte dello scritto del 30 Giugno 2006 Java Date le classi seguenti: class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; public static Point[] makearray(int n, Point p1, Point p2) { Point[] res = new Point[n]; boolean flag = true; for (int i = 0; i < n; i++) { res[i] = flag? p1 : p2; flag =!flag; return res; public static Point sum(point[] a) { Point res = a[0]; for(int i = 1; i < a.length; i++) { res.x = res.x + a[i].y; res.x = res.x + a[i].x; return res; Dopo l esecuzione di: Point pt1 = new Point(1,2); Point pt2 = new Point(2,4); Point pt3 = Point.sum(Point.makeArray(3, pt1, pt2)); 1. Quanto vale pt1.x? 18 2. Quanto vale pt1.y? 2 3. Quanto vale pt2.x? 2 4. Quanto vale pt2.y? 4 5. Quanto vale pt3.x? 18 1
6. Quanto vale pt3.y? 2 Date le classi seguenti: class A { String method(b a, A b) { return "a"; class B extends A { String method(a a, B b) { return "b"; String method(b a, B b) { return "c"; e gli oggetti seguenti: A a = new A(); B b = new B(); A c = new B(); 7. Quanto vale a.method(a, a)? (a) "a" (b) "b" (c) "c" (d) Errore NoSuchMethod (e) Errore Ambiguous 8. Quanto vale b.method(b, b)? (a) "a" (b) "b" (c) "c" (d) Errore NoSuchMethod (e) Errore Ambiguous 9. Quanto vale c.method(c, c)? (a) (b) (c) (d) (e) "a" "b" "c" Errore NoSuchMethod Errore Ambiguous 2
10. Quanto vale b.method(b, c)? (a) (b) (c) (d) (e) "a" "b" "c" Errore NoSuchMethod Errore Ambiguous 11. Dato un array bidimensionale a di stringhe, il suo contorno è composto dalle caselle a[i][j] dove il valore di i o j è quello minimo o quello massimo rispetto alla loro dimensione. Una copertura di a è un array monodimensionale b di stringhe tale che il contorno di a è contenuto in b, ovvero ogni elemento del contorno di a compare in b. Definire un metodo pubblico statico unique che verifica che un array monodimensionale di stringhe è composto di valori unici, ovvero ogni valore compare una volta sola nell array. Definire un metodo minimalcover che prende un array bidimensionale a di stringhe e un array monodimensionale b di stringhe e verifica che b è una copertura di lunghezza minima di a. Per esempio, minimalcover(new String[][] { {"verde", "verde", "verde", "verde", {"bianco", "blue", "bianco", { "rosso", new String[] {"verde", "bianco", "rosso") restituisce true. public static boolean in(string s, int n, String[] a) { for(int i = n; i < a.length; i++) { if (s.equals(a[i])) { public static boolean in(string s, String[] a) { return in(s, 0, a); public static boolean in(string[] a, String[] b) { for (int i = 0; i < a.length; i++) { if (!in(a[i], b)) { public static boolean unique(string[] a) { for(int i = 0; i < a.length - 1; i++) { if (in(a[i], i + 1, a)) { 3
public static boolean inborder(string s, String[][] a) { if (a.length == 0) { if (in(s, a[0]) in(s, a[a.length -1])) { for(int i = 1; i < a.length - 1; i++) { if (a[i].length!=0 && (s.equals(a[i][0]) s.equals(a[i][a[i].length -1]))) { public static boolean inborder(string a[], String[][] b) { for(int i = 0; i < a.length; i++) { if (!(inborder(a[i], b))) { public static boolean cover(string[] c, String[][] a) { if (a.length == 0) { if (!(in(a[0], c) && in(a[a.length -1], c))) { for(int i = 1; i < a.length - 1; i++) { if (a[i].length!= 0 &&!(in(a[i][0], c) && in(a[i][a[i].length -1], c))){ public static boolean minimalcover(string[][] a, String[] c) { return (unique(c) && inborder(c,a) && cover(c,a)); 12. Sia Combinator la rappresentazione di un piccolo linguaggio di combinatori Turing completo. Questo linguaggio è composto di due combinatori S e K e dell applicazione di una funzione a un argomento. abstract class Combinator { 4
class S extends Combinator { S () { class K extends Combinator { K () { class Apply extends Combinator { Combinator fun; Combinator arg; Apply (Combinator fun, Combinator arg) { this.fun = fun; this.arg = arg; Per simulare l applicazione con più di un argomento si combina l applicazione. Per esempio, il termine S K (K S) K che rappresenta l applicazione di S ai tre argomenti K, (K S) e K, ed il termine K S S che rappresenta l applicazione di K ai due argomenti S e S si definiscono come: Combinator c1 = new Apply(new Apply(new Apply(new S(), new K()), new Apply(new K(), new S())), new K()); Combinator c2 = new Apply(new Apply(new K(), new S()), new S()); Ci sono due regole di riduzione, una per ogni combinatore. Dati due termini x e y qualsiasi, K x y si riduce in x. Dati tre termini x, y e z qualsiasi, S x y z si riduce in x z (y z). La valutazione si effettua in modo non deterministico iterando l applicazione delle regole di riduzione all interno del termine. Per esempio, c1 si valuta in K. Una possibile sequenza di riduzioni è la seguente: S K (K S) K K K (K S K) K K S K. Aggiungere in Combinator: - un metodo pubblico iss che indica se un oggetto di tipo Combinator è un S. Per esempio, new S().isS() restituisce true. - un metodo pubblico isk che indica se un oggetto di tipo Combinator è un K. Per esempio, new K().isK() restituisce true. - un metodo pubblico isapp che indica se un oggetto di tipo Combinator è un Apply. Per esempio, c1.isapp() restituisce true. - un metodo pubblico numberofs che ritorna il numero di combinatori S dentro un termine. Per esempio, c1.numberofs() restituisce 2. - un metodo pubblico equals che fa un test di uguaglianza strutturale con un oggetto o di tipo Object. Per esempio, c1.equals("true") restituisce false, invece new S().equals(new S()) restituisce true. - un metodo pubblico gethead che ritorna il combinatore di testa di un applicazione con argomenti multipli. Per esempio, c1.gethead().iss() restituisce true. - un metodo pubblico numberofargs che ritorna il numero di argomenti di un applicazione. Per esempio, c1.numberofargs() restituisce 3 e c2.numberofargs() restituisce 2. 5
- un metodo pubblico isreds che indica se la regola di riduzione per S è applicabile sulla radice di un termine. Per esempio, c1.isreds() restituisce true. - un metodo pubblico isredk che indica se la regola di riduzione per K è applicabile sulla radice di un termine. Per esempio, c2.isredk() restituisce true. - un metodo pubblico reduce che prova ad applicare una riduzione all interno di un termine. Se tale riduzione non è possibile solleva l eccezione NothingToDoException. Per esempio, c2.reduce().iss() restituisce true. - un metodo pubblico eval che itera la riduzione all interno di un termine fino ad esaurimento. Per esempio, c1.eval().isk() restituisce true. class NothingToDoException extends Exception { abstract class Combinator { public boolean iss() { public boolean isk() { public boolean isapp() { public abstract int numberofs(); public abstract boolean equals(object o); public Combinator gethead() { return this; public int numberofargs() { return 0; public boolean isredk() { return (gethead().isk() && numberofargs() == 2); public boolean isreds() { return (gethead().iss() && numberofargs() == 3); public Combinator reducetop() { return this; public Combinator reduce() throws NothingToDoException { Combinator res = reducetop(); if (this.equals(res)) { throw new NothingToDoException(); return res; public Combinator eval() { Combinator res = this, next; while (true) { System.out.println(res); 6
next = res.reducetop(); if (next.equals(res)) { return res; res = next; class S extends Combinator { S() { public boolean iss() { public int numberofs() { return 1; public boolean equals(object o) { return (o instanceof S); class K extends Combinator { K() { public boolean isk() { public int numberofs() { return 0; public boolean equals(object o) { return (o instanceof K); class Apply extends Combinator { Combinator fun; Combinator arg; Apply(Combinator fun, Combinator arg) { this.fun = fun; this.arg = arg; public boolean isapp() { public int numberofs() { return fun.numberofs() + arg.numberofs(); public boolean equals(object o) { if (!(o instanceof S)) { 7
Apply app = (Apply) o; return (fun.equals(app.fun) && arg.equals(app.arg)); public Combinator gethead() { return fun.gethead(); public int numberofargs() { return fun.numberofargs() + 1; public Combinator reducetop() { if (isredk()) { return ((Apply) fun).arg; if (isreds()) { Apply app1 = (Apply) fun; Apply app2 = (Apply) app1.fun; return new Apply(new Apply(app2.arg, arg), new Apply(app1.arg, arg)); Combinator res1 = fun.reducetop(); if (fun.equals(res1)) { return (new Apply(fun, arg.reducetop())); return new Apply(res1, arg); Esterel 13. Scrivere un programma che gestisce il centralino delle docce di una piscina comunale. Il centralino gestisce l apertura e la chiusura di due docce (OPEN1, OPEN2 e CLOSE1, CLOSE2). All inizio, le due docce non sono in funzione. Sul centralino ci sono due pulsanti con una lampadina che indicano lo stato delle docce. Il programma può accendere la lampadina (LIGHT1_ON o LIGHT2_ON) o spengerla (LIGHT1_OFF o LIGHT1_OFF). Per mettere in funzione una doccia, l utente deve introdurre una carta magnetica (ENTER) e premere sul pulsante corrispondente (BUTTON1 o BUTTON1). Quando la doccia è libera, il centralino carica il costo della doccia sulla carta (DEBIT) e mette in funzione la doccia corrispondente (OPEN1 o OPEN2) e accende la lampadina corrispondente (LIGHT1_ON o LIGHT2_ON). La doccia funziona per 3 minuti (SECOND) prima di fermarsi (CLOSE1 e LIGHT1_OFF o CLOSE2 e LIGHT2_OFF). Premere su una doccia già occupata fa emettere un segnale sonoro (BEEP). Lasciare una carta inserita per più di un minuto (SECOND) fa emettere un segnale sonoro (BEEP) ogni due secondi (SECOND) fino a quando la carta è ritirata (EXIT). Le dichiarazioni dei segnali sono le seguenti: module SHOWER: input SECOND, ENTER, EXIT, BUTTON1, BUTTON2; relation SECOND # ENTER # EXIT # BUTTON1 # BUTTON2; 8
output BEEP, DEBIT, OPEN1, OPEN2, CLOSE1, CLOSE2, LIGHT1_ON, LIGHT2_ON, LIGHT1_OFF, LIGHT2_OFF;... end module module SHOWER: input SECOND, ENTER, EXIT, BUTTON1, BUTTON2; relation SECOND # ENTER # EXIT # BUTTON1 # BUTTON2; output BEEP, DEBIT, OPEN1, OPEN2, CLOSE1, CLOSE2, LIGHT1_ON, LIGHT2_ON, LIGHT1_OFF, LIGHT2_OFF; signal SHOW1, SHOW2, RUN1, RUN2 in loop await RUN1; emit OPEN1; emit LIGHT1_ON; emit DEBIT; await SECOND; abort sustain SHOW1; when 179 SECOND; emit LIGHT2_ON; emit CLOSE2; end loop loop await RUN2; emit OPEN2; emit LIGHT2_ON; emit DEBIT; await SECOND; abort sustain SHOW2; when 179 SECOND; emit LIGHT2_ON; emit CLOSE2; end loop loop await ENTER; abort every BUTTON1 do present SHOW1 then emit BEEP else emit RUN1 end present end every every BUTTON2 do present SHOW2 then emit BEEP else emit RUN2 end present end every 9
await 60 SECOND; every 2 SECOND do emit BEEP end every when EXIT end loop end signal end module 10