Partiel POBJ (LI314)

Emmanuel Chailloux

07 novembre 2012


1  Conditions générales

A lire complètement avant de commencer l'épreuve !!!

Cet examen est formé d'un unique problème en plusieurs questions auxquelles vous pouvez répondre dans l'ordre qui vous plait, néanmoins certaines questions sont dépendantes de réponses précédentes.

Tous les documents sont autorisés et notamment ceux du cours ( site du cours).

Votre copie de l'examen sera formée de fichiers textuels qui se trouveront dans votre espace de travail (workspace) Eclipse PARTIEL dans lequel vous créerez le paquetage pobj/partiel2012nov, c'est-à-dire le répertoire $HOME/workspace/PARTIEL/src/pobj/partiel2012nov qui contiendra les programmes que vous aurez écrits. Des consignes plus précises seront énoncées pour chaque question.

Si vous utilisez directement les commandes javac et java, vous ferez particulièrement attention à respecter la hiérarchie de fichiers demandée, c'est-à-dire de placer tous les fichiers demandés dans le catalogue $HOME/workspace/PARTIEL/src/pobj/partiel2012nov.

À l'exception des clés USB en lecture seule, tous les appareils électroniques sont prohibés (y compris les téléphones portables, les assistants numériques personnels et les agendas électroniques).

Le partiel sera corrigé automatiquement. Pour cela nous vous imposons de n'écrire aucune classe dont le nom débute par Test, ces noms sont réservés aux classes que nous utiliserons pour tester vos programmes. Pour la même raison, nous vous imposons de n'écrire aucune méthode dont le nom débute par test. Vos classes seront compilées par la commande javac et les programmes exécutés par la commande java.
L'épreuve dure deux heures.

Le total du barème indicatif de ce partiel est de 24 points.
Souvenez-vous qu'un fichier qui ne peut être compilé vaut zéro! Il vaut mieux un fichier qui peut se compiler et qui implante une partie seulement des spécifications qu'un fichier qui implante presque tout et qui ne peut être compilé! Cela milite pour une résolution incrémentielle des problèmes.

Il est tout à fait licite et même louable de réutiliser les classes que vous avez précédemment écrites. Toutefois si vous modifiez une classe demandée afin qu'elle en fasse plus, assurez-vous qu'elle répond toujours aux questions précédentes.

Vous devez répondre en Java 1.7, aucune caractéristique en voie d'obsolescence (deprecated feature) n'est autorisée. Toutes les classes demandées doivent appartenir au paquetage pobj.partiel2012nov.
Cela indique que tous les fichiers que vous écrirez seront placés dans le catalogue $HOME/workspace/PARTIEL/src/pobj/partiel2012nov et nulle part ailleurs. Le notateur automatique n'étudiera que les fichiers de ce catalogue.

Vous aurez probablement besoin de la documentation sur Java.

2  Enoncé

On cherche à se doter de traitements extensibles sur les expressions arithmétiques en utilisant le modèle de conception << Visiteur >>. Un visiteur correspond à un traitement spécifique, ici sur les expressions arithmétiques. Ce modèle est présenté à la question 2 en fournissant un exemple d'un visiteur d'affichage d'expressions arithmétiques.

Pour cela on demande d'implanter plusieurs visiteurs de calcul sur les expressions : un visiteur d'évaluation des expressions sans variable, un visiteur d'évaluation d'expressions avec variables, si besoin un visiteur de test de constante, un visiteur de simplification d'expressions et un visiteur de dérivation symbolique.

Remarque
: toutes les classes données et demandées sont dans le paquetage suivant : pobj.partiel2012nov.

On se donne tout d'abord les classes suivantes pour la description des expressions. Chaque classe concrète possèdera une méthode accepte prenant comme argument un visiteur qui visitera l'instance de la classe pour effectuer son calcul qui correspondra au résultat de la méthode accepte. Le type de résultat de la méthode accepte est paramétré par le type T et dépendra donc du type de retour du calcul d'un tel visiteur.

Voici l'interface IVisiteur<T> que devra respecter tout futur visiteur d'expressions arithmétiques : et voici la hiérarchie de classes des expressions arithmétiques utilisées : Code source de départ : L'archive partiel2012nov-java.jar contient toutes ces classes. Vous pouvez soit l'importer directement dans votre projet, soit le décompresser (avec la commande jar -xf partiel2012nov-java.jar) puis copier les classes extraites dans dans le répertoire de travail : $HOME/workspace/PARTIEL/src/pobj/partiel2012nov.

Remarque
: Vous aurez à les recompiler, mais il faut savoir que la notation les utilisera comme elles sont fournies dans l'énoncé et ne tiendra pas compte de vos modifications sur ces fichiers.

Question 1

Pour se mettre en route dans cette épreuve, il vous est demandé de construire trois expressions simples :
  1. e1 = ( 2 + 3 ) * 4
  2. e2 = ( x + 3 ) * (x + 4)
  3. e3 = ( x + 10 ) * ( y + (-8) )
Les constantes entières seront représentées par des instances de la classe Constante; les opérateurs +, et * correspondront à des instances des classes Add et Mul; une variable est représentée par une instance de la classe Var dont un attribut ( variable d'instance) contient la chaîne de caractère correspondant à son nom.

Pour pouvoir tester vos constructions, écrivez une classe Question1 du paquetage pobj.partiel2012nov dont le squelette suit : Les méthodes statiques e1, e2 et e3 retournent respectivement les expressions e1, e2 et e3 décrites ci-dessus. Ne cherchez pas à simplifier les expressions demandées.

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/Question1.java

Notation sur 2 point(s)

Question 2

Pour vous familiariser avec l'écriture de visiteurs, voici un exemple d'un visiteur de conversion en chaînes de caractères appelé VisiteurTS. Le résultat de ce visiteur est une chaîne de caractères, pour cela la classe visiteurTS implante l'interface IVisiteur<String>. La méthode visite est surchargée permettant d'effectuer un travail spécifique pour chaque classe concrète sous-classe d'Expression. Si nécessaire pour le calcul, le visiteur peut parcourir les sous-expressions qui composent l'expression (comme pour Add ou Mul). Dans ce cas le visiteur doit être accepté par la sous-expression.
package pobj.partiel2012nov;

class VisiteurTS implements IVisiteur<String> {
    public String visite(Constante c){return ( ""+c.getValue());}
    public String visite(Var v){return v.getNom();}
    public String visite(Add a){
        String s1 = a.getFg().accepte(this);
        String s2 = a.getFd().accepte(this);
        return "( "+ s1 + " + " + s2 + " )";
    }
    public String visite(Mul a){
        String s1 = a.getFg().accepte(this);
        String s2 = a.getFd().accepte(this);
        return "( "+ s1 + " * " + s2 + " )";
    }

}
Et voici le programme de test pobj/partiel2012nov/Exemple.java qui l'utilise :
package pobj.partiel2012nov;

class Exemple {
  public static void main(String[] args) {
    VisiteurTS v1 = new VisiteurTS();
    VisiteurTS v2 = new VisiteurTS();
    Expression e1 = Question1.e1();
    Expression e2 = Question1.e2();
    Expression e3 = Question1.e3();
    String s1 = e1.accepte(v1);
    String s2 = e2.accepte(v2);
    String s3 = e3.accepte(v1);
    System.out.println(s1 + "\n" + s2 + "\n" + s3);
  }
}
Il vous est demandé d'écrire une classe VisiteurEval qui implante l'interface IVisiteur<Integer> qui calcule la valeur d'une expression sans variable.

Si un tel visiteur rencontre une instance de Var il déclenche l'exception InvalidArgument déclarée de la manière suivante :
package pobj.partiel2012nov;

class InvalidArgument extends RuntimeException {}
N'oubliez pas de tester votre classe au moins sur les exemples de la question 1.

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/VisiteurEval.java

Notation sur 4 point(s)

Question 3

Pour les formules contenant des variables, il est nécessaire de pouvoir les calculer dans un certain environnement. Un environnement est formé de couples liant une variable à une valeur booléenne.

On se donne la classe VarNotFound et on réutilise la classe InvalidArguement toutes deux sous-classes de RuntimeException et la classe Env pour les environnements :
package pobj.partiel2012nov;

class VarNotFound extends RuntimeException {}
package pobj.partiel2012nov;
 

class Env { 
  String[] vars;
  int[] values;
  int size;
  Env(int size, String[] vars, int[] values){
    this.size=size;
    this.vars =vars; this.values= values;
    if ( (size != 0) && ((size != vars.length) || (size != values.length)))
      throw new InvalidArgument();
  }

  String[] getVars(){return vars;}
  int[] getValues(){return values;}
  int getSize(){return size;}

  int get(String s){
    for (int i=0; i<size; i++) {
      if (vars[i].equals(s)) return values[i];
    }
    throw new VarNotFound();
  } 

  public String toString(){
    String res = "";
    for (int i = 0; i<size; i++) {
      res = res + "(" + vars[i] + "," + values[i] + ")";
    }
    return res;
  }
}

Un environnement vide retournera 0 à l'appel de la méthode getSize.

On cherche à construire les environnements suivants :
  1. env1 est l'environnement vide;
  2. env2 est l'environnement qui associe 10 à la variable "x" et 20 à "y"; l'ordre importe peu;
  3. env3 est l'environnement qui associe 9 à la variable "z".
Pour cela il vous est demandé d'écrire une classe Question3.java du paquetage pobj.partiel2012nov dont le squelette suit :
package pobj.partiel2010nov;

class Question3 {
  static Env env1() { /* A COMPLETER */ }
  static Env env2() { /* A COMPLETER */}
  static Env env3() { /* A COMPLETER */}
}
Les méthodes statiques env1, env2 et env3 retournent respectivement les environnements env1, env2 et env3 décrits ci-dessus.

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/Question3.java

Notation sur 2 point(s)

Question 4

Il vous est demandé d'écrire une classe VisiteurEvalVar, sous-classe de VisiteurEval, permettant l'évaluation d'une formule dans un environnement donné. La classe VisiteurEvalVar possède un constructeur prenant un environnement comme paramètre. On pourra ainsi construire de tels visiteurs de la manière suivante :
  VisiteurEvalVar vev1 = new VisiteurEvalVar(Question3.env2());
  Integer resultat = Question1.e2().accepte(vev1);
N'oubliez pas de tester votre classe au moins sur les expressions de la question 1 associés aux environnements de la question 3.

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/VisiteurEvalVar.java.

Notation sur 3 point(s)

Question 5

Pour la question suivante on a besoin de pouvoir vérifier si une expression est une constante. De même dans le cas où c'est bien une constante on peut avoir besoin de savoir si la constante vaut 0 ou 1. Pour cela il suffit de l'évaluer pour savoir si elle vaut 0 ou 1.

Pour cela on vous demande de compléter la classe Question5 suivante :

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/Question5.java

Notation sur 2 point(s)

Question 6

On cherche à simplifier les expressions arithmétiques que l'on construit selon les règles suivantes : Si les deux membres d'une expression d'un opérateur binaire (+ ou *) sont des constantes, on peut alors évaluer l'opérateur avec un visiteur d'évaluation (VisiteurEval) pour construire une nouvelle expression Constante symbolique valant la somme des deux constantes.

Chaque opération (Add et Mul) possède un élément neutre (0 pour l'addition, et 1 pour la multiplication). De plus la multiplication possède un élément absorbant, 0.

Il vous est demandé d'écrire une classe VisiteurSimplifie qui implante l'interface IVisiteur<Expression> permettant de calculer une expression simplifiée en fonction des règles de simplification proposées. Un tel visiteur retourne une nouvelle expression correspondant à la simplification de l'expression qu'il visite.
  VisiteurSimplifie vs = new VisiteurSimplifie();
  Expression resultat1 = Question1.e1().accepte(vs);
  Expression resultat2 = Question1.e2().accepte(vs);
  Expression resultat3 = Question1.e3().accepte(vs);
N'oubliez pas de tester votre classe au moins sur les expressions de la question 1.

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/VisiteurSimplifie.java.

Notation sur 5 point(s)

Question 7

On cherche maintenant à effectuer une dérivée symbolique des expressions par rapport à une variable. On rappelle les formules pour les une dérivée par rapport à la variable x en notant (e)' la dérivée de e par rapport à x. Il vous est demandé d'écrire une classe VisiteurDerive qui implante l'interface IVisiteur<Expression> permettant le calcul symbolique de la dérivée d'une expression par rapport à une variable. Un tel visiteur retourne une nouvelle expression correspond à la dérivée de l'expression qu'il visite. Il est nécessaire à la construction d'indiquer par rapport à quelle variable s'effectue la dérivée comme dans l'exemple suivant :
  VisiteurDerive vd = new VisiteurDerive(new Var("x"));
  Expression resultat = Question1.e3().accepte(vd);
A cette question, on ne cherche pas à simplifier l'expression ainsi obtenue.

N'oubliez pas de tester votre classe au moins sur les expressions de la question 1.

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/VisiteurDerive.java.

Notation sur 5 point(s)

Question 8

Comme le calcul de la dérivée symbolique construit de grosses expressions peu lisibles, il est nécessaire de les simplifier. Pour cela on demande de définir une fonction compose qui prend deux visiteurs f et g, et une expression e et qui retourne le résultat de la composition des deux visiteurs en appliquant d'abord g puis f sur le résultat de g.

Pour cela on vous demande de compléter la classe Question8 suivante :

Livraison

Un fichier $HOME/workspace/PARTIEL/src/pobj/partiel2012nov/Question8.java.

Notation sur 1 point(s)


Ce document a été traduit de LATEX par HEVEA