• Aucun résultat trouvé

Composition d’Informatique Les Principes des Langages de Programmation (INF 321) Promotion 2011

N/A
N/A
Protected

Academic year: 2022

Partager "Composition d’Informatique Les Principes des Langages de Programmation (INF 321) Promotion 2011"

Copied!
10
0
0

Texte intégral

(1)

Composition d’Informatique

Les Principes des Langages de Programmation (INF 321) Promotion 2011

Corrig´ e propos´ e par Eric Goubault et Xavier Rival 12 juillet 2012

1 Types de donn´ ees et constructeurs

1.a) D´efinir une classe Javaconcr`ete AExpr qui impl´emente le type correspondant aux expres- sions arithm´etiques.

public enum o p e r a t o r { Plus , Times , Div }

public enum k i n d { Bot ,

Cst , C e l l , Neg , Bin }

c l a s s AExpr { k i n d k ; f l o a t v a l ; i n t i ; i n t j ; o p e r a t o r op ;

AExpr l ; // s t o r e s t h e o n l y sub−e x p r o f ”−e ” AExpr r ; // s h o u l d b e n u l l f o r Neg

}

Barˆeme: 2 points

1.b) D´efinir les constructeurs:

AExpr ( )

AExpr (f l o a t n ) AExpr (i n t i , i n t j )

AExpr ( o p e r a t o r op , l e x p r , r e x p r ) AExpr ( e x p r )

qui rendent respectivement ⊥, un AExpr repr´esentant le flottant n, ci,j, l’op´eration binaire op appliqu´e `a une sous-expression gauchelexpr et `a une sous-expression droiterexpr, et le moins appliqu´e `a la sous-expressionexpr.

(2)

AExpr ( ) { k = k i n d . Bot ; }

AExpr (f l o a t f ) { k = k i n d . Cst ; v = f ;

}

AExpr (i n t i , i n t j ) { k = k i n d . C e l l ;

t h i s. i = i ; t h i s. j = j ; }

AExpr ( o p e r a t o r op , AExpr l e x p r , AExpr r e x p r ) { k = k i n d . Bin ;

o = op ; l = l e x p r ; r = r e x p r ; }

AExpr ( AExpr e x p r ){ k = k i n d . Neg ;

l = e x p r ; }

Barˆeme: .5 point par constructeur (2.5 points en tout)

1.c) D´efinir une classe permettant de stocker une feuille de calcul. On l’appelleraFeuille.

c l a s s F e u i l l e{ AExpr [ ] [ ] c e l l s ; }

Barˆeme: 1 point

2 S´ emantique et ´ evaluation

2.a) On consid`ere dans cette question la feuille:

D= c1,1+c0,1 3∗c1,0 2 c0,0+c0,1

Quelles en sont les cellules d´efinies ? (On donnera pour ce faire le grapheGρD).

Les arˆetes du graphe sont:

c0,0 → c0,1

c0,0 → c1,1

c0,1 → c1,0

c1,1 → c0,0

c1,1 → c0,1

Les cellules d´efinies sont doncc1,0et c0,1. Barˆeme: 2 points.

(3)

2.b) Ecrire la s´´ emantique d´enotationnelle [[expr]] des expressions arithm´etiquesa∈AExpr, par r´ecurrence structurelle sur AExpr. Expliquer bri`evement pourquoi cette r´ecurrence structurelle est bien d´efinie.

• si e n’est pas d´efinie, [[e]](p) =⊥

• [[⊥]](p) =⊥

• [[f]](p) =f

• [[ci,j]](p) = [[p(i, j)]](p)

• [[−e]](p) =−[[e]](p)

• [[e0 o e1]](p) = [[e0]](p)◦[[e1]](p) sio∈ {+,−,∗}

La s´emantique des expressions non d´efinies est bien d´efinie. Si e est une expression d´efinie, le sous-graphe de d´ependance obtenu en ne consid´erant que les noeuds atteignables `a partir des cellules apparaissant dans l’expression est un arbre ; de plus, le sous-graphe d´efini de la mˆeme mani`ere pour chacun des appels r´ecursifs dans l’´evaluation deecorrespond `a un sous arbre strict de l’arbre initial. La r´ecurrence est donc bien fond´ee.

Barˆeme: 2 points pour la s´emantique, 1 point pour l’explication de la correction de cette d´efinition.

2.c) Ecrire le code de la m´´ ethode dynamique et r´ecursive Eval de la classe AExpr prenant en argument une feuillep, et permettant d’´evaluer l’expression sur laquelle elle s’applique.

AExpr Eval ( F e u i l l e p ) { i f ( D e f i n e d (t h i s) ) {

switch( k ) { case Bot :

return t h i s; case Cst :

return t h i s; case C e l l :

return p . c e l l s [ i ] [ j ] . e v a l ( p ) ; case Neg :

return new AExpr(−l . e v a l ( p ) . v ) ; case Bin :

switch( o ) { case P l u s :

return new AExpr ( l . e v a l ( p ) . v+r . e v a l ( p ) . v ) ; case Times :

return new AExpr ( l . e v a l ( p ) . v∗r . e v a l ( p ) . v ) ; case Div :

f l o a t den = r . e v a l ( p ) . v ; i f ( den != 0 )

return new AExpr ( l . e v a l ( p ) . v / den ) ; e l s e

return new AExpr ( ) ; }

} } e l s e {

return new AExpr ( ) ; }

}

Barˆeme: 2.5 points.

(4)

2.d) optionnel Comment faire pour se passer de la m´ethodeDefinedpour programmerEval?

AExpr Eval (boolean [ ] [ ] d e j a v u , F e u i l l e p ){ switch( k ) {

case Bot : return t h i s; case Cst :

return t h i s; case C e l l :

i f ( d e j a v u [ i ] [ j ] ) return new AExpr ( ) ; e l s e {

d e j a v u [ i ] [ j ] = true;

return p . c e l l s [ i ] [ j ] . e v a l ( p ) ; }

case Neg :

return new AExpr(−l . e v a l ( p ) . v ) ; case Bin :

switch( o ) { case P l u s :

return new AExpr ( l . e v a l ( p ) . v+r . e v a l ( p ) . v ) ; case Times :

return new AExpr ( l . e v a l ( p ) . v∗r . e v a l ( p ) . v ) ; case Div :

f l o a t den = r . e v a l ( p ) . v ; i f ( den != 0 )

return new AExpr ( l . e v a l ( p ) . v / den ) ; e l s e

return new AExpr ( ) ; }

} }

AExpr Eval ( F e u i l l e p ) {

boolean[ ] [ ] d e j a v u = new boolean[ p . c e l l s . l e n g t h ] [ ] ; f o r (i n t i = 0 ; i < p . c e l l s . l e n g t h ; i ++) {

d e j a v u [ i ] = new boolean[ p . c e l l s [ i ] . l e n g t h ] ; }

return e v a l ( d e j a v u , p ) ; }

Barˆeme: 2 points.

3 Gestion de la feuille de calcul

3.a) Ecrire une m´´ ethode dynamiqueCompute, de la classeFeuille, qui ´evalue chaque cellule de la feuille courante.

Compute ( ) {

f o r ( i =0; i < c e l l s . l e n g t h ; i ++)

f o r ( j =0; j < c e l l s [ i ] . l e n g t h ; j ++) { c e l l s [ i ] [ j ] = c e l l s [ i ] [ j ] . e v a l (t h i s) ; }

}

Barˆeme: 2 points.

(5)

3.b) Que doit donnerComputesurC? et surD?

Sur C, seulc0,0est d´efini ´egal `a 1, les trois autres cellules sont `a bottom.

Sur D, on a vu que seules c0,1 et c1,0 sont d´efinis, respectivement `a 6 et `a 2, les deux autres cellules sont `a bottom.

Barˆeme: 1 point pour chaque cas (2 points en tout).

3.c) Par quel m´ecanisme peut-on traiter simplement ces cas de division par z´ero ? Par le m´ecanisme d’exception, disponible en Java.

Barˆeme: 1 point.

3.d) Dire comment modifier le code d’Eval(sans tout r´e´ecrire) de la question (2.c) et le code de Computede la question (3.a) afin d’impl´ementer ce m´ecanisme.

Par exemple, on peut se souvenir de l’expression de la feuille responsable de la division par z´ero (indicatif, non n´ecessaire pour avoir les points de cette question):

c l a s s A r i t h E x c e p t i o n extends E x c e p t i o n { AExpr d ;

. . . }

AExpr Eval ( F e u i l l e p ) throws A r i t h E x c e p t i o n { i f ( D e f i n e d (t h i s) ) {

switch( k ) { case Bot :

return t h i s; case Cst :

return t h i s; case C e l l :

return p . c e l l s [ i ] [ j ] . e v a l ( p ) ; case Neg :

return new AExpr(−l . e v a l ( p ) . v ) ; case Bin :

switch( o ) { case P l u s :

return new AExpr ( l . e v a l ( p ) . v+r . e v a l ( p ) . v ) ; case Times :

return new AExpr ( l . e v a l ( p ) . v∗r . e v a l ( p ) . v ) ; case Div :

AExpr e x p r d e n = r . e v a l ( p ) ; f l o a t den = e x p r d e n . v ; i f ( den != 0 )

return new AExpr ( l . e v a l ( p ) . v / den ) ; e l s e

throw new A r i t h E x c e p t i o n ( e x p r d e n ) ; return new AExpr ( ) ;

} } } e l s e {

return new AExpr ( ) ; }

}

Compute ( ) {

f o r ( i =0; i < c e l l s . l e n g t h ; i ++)

(6)

f o r ( j =0; j < c e l l s [ i ] . l e n g t h ; j ++) { try {

c e l l s [ i ] [ j ] = c e l l s [ i ] [ j ] . e v a l (t h i s) ; } catch ( A r i t h E x c e p t i o n e ) {

// I d e a l l y , s h o u l d p r e t t y p r i n t t h e e x p r e s s i o n e . d

System . o u t . p r i n l n ( ” E x p r e s s i o n au d e n o m i n a t e u r ”+e . d+” e s t n u l l e ! ” ) }

} }

Barˆeme: 2 points (1 pour la d´efinition d’une exception, mˆeme vide, et pour la modification dansEval, 1 pour letry/catchde la m´ethodeCompute).

4 M´ ethode alternative d’´ evaluation

4.a) Quels sont les points fixes du FC particulier d´efini ci-dessus ? De mˆeme pourFD la fonc- tionnelle induite par la feuilleDde la question 2.a.

On a

FC

 c0,0

c0,1 c1,0 c1,1

=

 1 c1,1

⊥ c0,0−c0,1

Les points fixes deFC sont donc tels que: c0,0= 1,c0,1=c1,1,c1,0=⊥etc1,1=c0,0−c0,1= 1−c1,1. Donc on a deux solutions:

• c0,1=c1,1=c1,0=⊥etc0,0= 1

• c0,1=c1,1=12,c0,0= 1 etc1,0=⊥ On a

FD

 c0,0 c0,1 c1,0 c1,1

=

c1,1+c0,1 3c1,0

2 c0,0+c0,1

Les points fixes deFDsont donc tels que: c0,0=c1,1+c0,1,c0,1= 3c1,0,c1,0= 2 etc1,1=c0,0+c0,1. Doncc0,0=c0,0+ 2c0,1=c0,0+ 6c1,0=c0,0+ 12,c0,1= 6,c1,0= 2 etc1,1=c0,0+ 6. Donc on n’a qu’une plus petite solution (plus petit point fixe): c0,1=⊥,c0,1= 6,c1,0= 2 etc1,1=⊥.

Barˆeme: 1 point par fonctionnelle (2 points en tout). Pour la fonctionnelle FC un demi-point par cas trouv´e (2 points fixes).

4.b) Quel est le plus petit point fixe deFC ? deFD ?

Pour FC: c0,1=c1,1=c1,0=⊥et c0,0= 1. PourFD: c0,1=⊥,c0,1= 6, c1,0= 2 etc1,1=⊥.

Barˆeme: .5 point par plus petit point fixe (1 point en tout).

4.c) Donner les it´er´ees successives du calcul de plus petit point fixe de FC et de FD par le th´eor`eme de Kleene.

(7)

On calcule:

FC1(⊥) =

 1

FC2(⊥) =

 1

Donc le plus petit point fixe deFC est (1,⊥,⊥,⊥).

Maintenant pour FD:

FD1(⊥) =

⊥ 2

FD2(⊥) =

⊥ 6 2

FD3(⊥) =

⊥ 6 2

et on atteint le plus petit (et unique) point fixe.

Barˆeme: 1 point par fonctionnelle (2 points en tout).

4.d) Prouver que sici,j n’est pas d´efini dans la feuilleρ, alors pour toutk∈N, (Fk)i,j(⊥) =⊥, o`u (Fk)i,j est la composante (i, j) de l’it´er´eeki`eme deF.

Une celluleci,jn’est pas d´efinie si elle est dans un cycle de d´ependance, ou si elle d´epend d’une valeur⊥. Dans tous les cas, l’evaluation en ⊥de la fonctionnelle correspondant au calcul deci,j, Fi,j, et mˆeme de la fonctionnelle it´er´ee kfois, utilise au moins une valeur `a ⊥(ci,j mˆeme, si dans un cycle de d´ependance, sinon une cellule `a⊥), or les fonctions arithm´etiques sont toutes strictes, donc par induction structurelle simple, le r´esultat est toujours⊥.

Barˆeme: 1 point.

4.e) Prouver maintenant que si tous lesci,j sont d´efinis dans la feuilleρ,Fk(⊥),k≥1, donne la valeur num´erique (donc diff´erente de⊥, au sens de la s´emantique d´enotationnelle de la question (2.a)) de l’ensembleCk des cellules ci,j telles quek > kic0i,j,j0 pour toutes cellulesci0,j0 ∈C1.

Soit donc C1 l’ensemble des cellules ci,j telles queρ(ci,j) est une constante num´erique, et de fa¸con g´en´eraleCk l’ensemble des cellulesci,jde profondeur inf´erieure strictement `akpar rapport aux cellules deC1. On effectue une r´ecurrence surk.

Le cas de base estk= 1: l’ensemble des cellules deC1est pr´ecis´ement celui calcul´e parF1(⊥).

On suppose que l’ensemble des cellules deCk est calcul´e parFk(⊥), et on calculeFk+1(⊥) = F(Fk(⊥)). On voit ais´ement que les cellulesci,j deCk+1 sont `a profondeur inf´erieure ou ´egale `a 1 par rapport aux cellules deCk. Pour les cellules de profondeur 0, ce sont des cellules deCk donc sont d´ej`a calcul´ees par Fk(⊥), a fortiori par Fk+1(⊥) (pour s’en convaincre facilement, on peut utiliser la monotonie deF). Pour les cellules de profondeur 1 par rapport `a Ck, elles d´ependent directement de la valeur des cellules deCk, qui sont donn´ees parFk(⊥): ainsiFk+1(⊥) les calcule.

Barˆeme: 1 point.

(8)

4.f ) En d´eduire que le plus petit point fixe de la fonctionnelle F est ´egal `a la s´emantique d´enotationnelle donn´ee `a la question (2.a).

Pour les cellules ci,j non-d´efinies, par la question 4.d), on sait queFi,jk (⊥) est ⊥pour toutk, donc leur valeur dans la s´emantique de plus petit point fixe (deF) est⊥. Cela correspond `a la s´emantique d´enotationnelle de la question 2.a).

Pour les cellules ci,j d´efinies, par la question 4.e), on sait qu’il existe ktel queFi,jk (⊥) donne la valeur num´erique deci,j, car le graphe de d´ependance est fini, donc toutes les profondeurs sont finies. Donc leur valeur est calcul´ee (par la mˆeme s´emantique que la s´emantique d´enotationnelle de la question 2.a) par le plus petit point fixe deF.

Barˆeme: 1 point.

4.g) Ecrire une version it´´ erative de la m´ethodeEvalde la question (2.c), impl´ementant l’it´eration de Kleene, que l’on sait donner le mˆeme r´esultat que la m´ethode r´ecursive de la question (2.c), grˆace `a la question (4.f).

En fait, on doit d’abord ´ecrireCompute()avantEval.

AExpr EvalAExpr ( F e u i l l e p , F e u i l l e c u r ) {

// E v a l u a t i n g e x p r e s s i o n t h i s , w i t h f u n c t i o n a l p , under c o n t e x t c u r AExpr r e s l , r e s r ;

switch( k ) { case Bot :

return new AExpr ( ) ; case Cst :

return t h i s; case C e l l :

return EvalAExpr ( c u r . c e l l s [ i ] [ j ] , p ) ; case Neg :

r e s l = EvalAExpr ( l , p ) ;

i f ( r e s l . k == Bot ) return new AExpr ( ) ; e l s e return new AExpr(−r e s l . v ) ;

case Bin :

r e s l = EvalAExpr ( l , p ) ; r e l r = EvalAExpr ( r , p ) ;

i f ( r e s l . k == Bot ) return new AExpr ( ) ; i f ( r e s r . k == Bot ) return new AExpr ( ) ; switch( e . o ) {

case P l u s :

return new AExpr ( r e s l . v+r e s r . v ) ; case Times :

return new AExpr ( r e s l . v∗. r e s r . v ) ; case Div :

f l o a t den = r e s r . v ; i f ( den != 0 )

return new AExpr ( r e s l . v / den ) ; e l s e

return new AExpr ( ) ; }

} }

// A u x i l i a r y f u n c t i o n s

s t a t i c boolean equalAExpr ( AExpr e0 , AExpr e1 ) { // s u p p o s i n g a l l e x p r e s s i o n s a r e a l l o c a t e d

i f ( e0 . k != e1 . k ) return f a l s e;

(9)

switch( e0 . k ) { case Bot :

return true; case Cst :

return ( e0 . k == e1 . k ) ; case C e l l :

return ( ( e0 . i == e1 . i ) && ( e0 . j == e1 . j ) ) ; case Neg :

return equalAExpr ( e0 . l , e1 . l ) ; case Bin :

i f ( e0 . o != e1 . o ) return f a l s e;

return ( equalAExpr ( e0 . l , e1 . l ) && equalAExpr ( e0 . r , e1 . r ) ) ; }

}

s t a t i c boolean e q u a l F e u i l l e ( F e u i l l e cur , F e u i l l e n e x t ) { // s u p p o s i n g t h e y h a v e t h e same s i z e , and w e l l a l l o c a t e d

boolean r e s = true;

f o r (i n t i =0; i<c u r . c e l l s . l e n g t h ; i ++) f o r (i n t j =0; j<c u r . c e l l s [ i ] . l e n g t h ; j ++)

i f ( ! equalAExpr ( c u r . c e l l s [ i ] [ j ] , n e x t . c e l l s [ i ] [ j ] ) ) r e s = f a l s e;

return r e s ; }

s t a t i c c o p y c e l l s ( AExpr [ ] [ ] from , AExpr [ ] [ ] t o ) {

// s u p p o s i n g same s i z e and w e l l a l l o c a t e d s q u a r e c e l l a r r a y s f o r (i n t i =0; i<from . l e n g t h ; i ++)

f o r (i n t j =0; i<from [ i ] . l e n g t h ; j ++) t o . c e l l s [ i ] [ j ] = from . c e l l s [ i ] [ j ] ; }

Compute ( ) {

AExpr p r e v = new AExpr ( ) ; b o o l u n s t a b l e = true;

F e u i l l e c u r = new F e u i l l e ( ) ; F e u i l l e n e x t = new F e u i l l e ( ) ;

// s u p p o s e p . c e l l s c o n t a i n s a t l e a s t one c e l l , and t h a t t h e s h e e t i s s q u a r e c u r . c e l l s = new AExpr [ c e l l s . l e n g t h ] [ p . c e l l s [ 0 ] . l e n g t h ] ;

n e x t . c e l l s = new AExpr [ c e l l s . l e n g t h ] [ p . c e l l s [ 0 ] . l e n g t h ] ;

// i n i t i a l i z i n g c u r r e n t i t e r a t e t o b o t f o r (i n t i =0; i<c e l l s . l e n g t h ; i ++)

f o r (i n t j =0; i<c e l l s [ i ] . l e n g t h ; j ++) c u r . c e l l s [ i ] [ j ] = new AExpr ( ) ;

// K l e e n e i t e r a t e while ( u n s t a b l e ) {

f o r (i n t i =0; i<c e l l s . l e n g t h ; i ++) f o r (i n t j =0; i<c e l l s [ i ] . l e n g t h ; j ++)

n e x t . c e l l s [ i ] [ j ] = c e l l s [ i ] [ j ] . EvalAExpr (t h i s, c u r ) ;

// t e s t w h e t h e r f i x p o i n t

i f ( e q u a l F e u i l l e ( cur , n e x t ) ) u n s t a b l e = f a l s e; e l s e u n s t a b l e = true;

// c o p y i t e r a t e k+1 i n t o c u r

(10)

c o p y c e l l s ( n e x t . c e l l s , c u r . c e l l s ) ; }

// c o p y i n g r e s u l t i n t o t h i s c o p y c e l l s ( c u r . c e l l s , c e l l s ) ; }

AExpr Eval ( F e u i l l e p ) { p . Compute ( ) ;

return EvalAexpr ( p , p ) ; }

Barˆeme: 2 points d`es que la structure de l’it´er´ee de Kleene est correcte (mˆeme si le code des fonctions auxiliairesequalAExpr,copycellsetc. est absent). +1 point si plus complet.

4.h) optionnel SoitP le pr´edicat suivant sur lesa∈AExpr et les feuilles ρ: P(a, ρ) est vrai si aest d´efinie dansρ. Donner les assertions n´ecessaires `a la preuve `a la Hoare du code it´eratif d’Eval de la question (4.d), `a chaque ligne du code, permettant de prouver

{¬P(a, ρ)}x=a.Eval(ρ){x=⊥}

V´erifier les assertions de preuve en utilisant les r`egles de preuve `a la Hoare du cours.

Barˆeme: 2 points d`es que l’id´ee est l`a.

Références

Documents relatifs

Un tel entier sera donc repr´ esent´ e par une variable X de type List qui d´ ecrit dans l’ordre, les digits en base N.. Comment d´ eclarer la variable N dans la

• (2.c) ´ Ecrire le code de la m´ ethode dynamique et r´ ecursive Eval de la classe AExpr prenant en argument une feuille C, et permettant d’´ evaluer l’expression sur laquelle

Pour donner une partie de la s´ emantique de la calculatrice programmable, on doit changer un peu la repr´ esentation de l’´ etat courant de la calculatrice: c’est maintenant

Sujet propos´ e par Gilles Dowek 9 juillet 2007..

Une m´ ethode, parmi d’autres, consiste ` a remarquer que les L(p+1,m+1) listes croissantes de p+1 entiers compris entre 0 et m+1 se partitionnent entre celles qui commencent par 0

[r]

Sujet propos´e par Gilles Dowek 13 juillet 2010..

a l’affichage V , la valeur de la m´ emoire M , et l’op´ eration courante dans {p, m, t, n}; E est un bool´ een indiquant si l’on est dans le mode programme (apr` es avoir tap´