Cette leçon expérimentale a pour but d'enseigner aux étudiants le principe du "backtracking". Ce n'est pas encore prêt à être utilisé, ne serait-ce que les premiers exercices. Cette leçon contiendra plusieurs exercices sur le sujet permettant d'introduire pas à pas les notions nécessaires et de construire une représentation mentale dans l'esprit de l'étudiant.
A l'heure actuelle, cela contient un exercice sur le Backtracking qui a besoin d'une représentation graphique pour être utilisable. Cet exercice est base sur une entité KnapsackSolver qui travaille sur une KnapsackPartialSolution. Ce dernier n'est pas un World, mais un composant passif du monde. Il est utilisé par le solveur pour sauvegarder la meilleure solution actuelle et la solution courante. Le design devrait être assez générique et d'autres problèmes de backtracking, tels que ceux utilisés dans mes enseignements de TOP (pyramides, récipients ) devraient être implémentables en copiant ce design. C'est pourquoi les classes Backtracking dérivent d'une classe générique: BacktrackingEntity et BacktrackingPartialSolution. Il y a aussi un BacktrackingWorld; que les univers spécifiques ne doivent en aucun cas surchargé; et BacktrackingExercise, gérant cette spécificité où le monde ne contient pas seulement des entités solutions, mais aussi deux solutions partielles (meilleur connue et actuelle).
Cet exercice devrait être introduit par une activité de découverte interactive comme celle qui est utilisée ici : http://interstices.info/jcms/c_19213/le-probleme-du-sac-a-dos
Même si cet exercice semble presque utilisable, il y a une difficulté fondamentale à résoudre dans la visualisation. Il a été imaginé que le graphe des appels est utilisé ici pour aider les étudiants à construire leur propre représentation mentale de la récursion. La représentation actuelle du graphe devrait être assez simple, grâce à la bibliothèque JUNG. Mais j'ai échoué jusqu'à présent à trouver comment obtenir les informations nécessaires. Ajouter des capteurs à la méthode stepUI() est probablement la meilleur façon de procéder, mais j'aurai besoin d'inspecter la pile d'appel en entier alors que Thread.currentThread().getStack() ne fournit que la pile statique (méthodes appelées, locations des fichiers, etc). Je pense que j'ai besoin d'inspecter les paramètres passés à chaque appel de méthode pour reconstruire le bon arbre d'appel.
La première chose que j'ai essayé d'utiliser fut dtrace, mais il semble non portable et en quelque sorte lié à solaris donc je n'ai pas plus creusé dans cette direction.
Ensuite, j'ai essayé d'utiliser l'infrastructure de débuggage (JPDA), mais je ne suis jamais parvenu à la faire fonctionner. J'ai l'impression que le package com.sun.jdi original est en quelque sorte déprécié puisque com.sun.jdi.BootStrap.virtualMachineManager() renvoie null tandis que org.eclipse.jdi.Bootstrap.virtualMachineManager() ne le fait pas. Mais quand j'utilise la version d'eclipse, il semble nécessiter un nombre infini de dépendances, que je ne suis pas enclin à installer. La cause de mon problème pourrait être que j'utilisais un jdr.jar venant d'eclipse, mais je n'en ai pas trouvé d'autres. Je viens juste de réaliser que le package com.sun.jdi est aussi disponible dans /usr/lib/jvm/java-6-sun-1.6.0.26/lib/tools.jar sur mon disque. Il a l'air fonctionnel, je devrais essayer à nouveau.
Après cela, j'ai réessayé d'utiliser l'infrastructure de débuggage de DrJava. Cela semble être une bonne idée parce qu'il dispose de plusieurs interfaces d'aide pour le débuggage et la compilation. Il y a aussi un bon éditeur que l'on pourrait réutiliser. Finalement, ils ont un infrastructure solide de tests avec junit assurant que leur outil fonctionne toujours après modifications ( c'est quelque chose qui manque sérieusement dans la PLM). Je pense vraiment que les deux outils devraient fusionner en quelque chose de plus fort. Le seul argument pour ne pas le faire ( en plus de la quantité de travail nécessaire ) est que chacun d'entre nous reçoit les honneurs pour son outil alors que les choses seraient plus ambiguës sur un outil fusionné. Mais ce n'est pas important, l'outil fusionné serait bien plus cool que j'aimerai trouver le temps pour m'assurer que cela converge.
Mais la fonction de débuggage de DrJava semble souffrir d'un problème : http://sourceforge.net/tracker/index.php?func=detail&aid=3004294&group_id=44253&atid=438935 je suspectais une erreur de permission (quelque chose lié com.sun.jdi.JDIPermission ), mais même avec un java.security.AllPermission comme fichier des permissions, j'ai encore ce problème.
Un autre moyen pour le faire fonctionner est d'utiliser la bibliothèque ASM pour modifier le code de l'étudiant afin que leur méthode récursive soit tracée. Avec le backtrace statique et l'information de traçage, je pense que je pourrais reconstruire l'arbre d'appels. Cela semble possible: deux secondes sur Google m'ont donné quelque chose comme http://rejeev.blogspot.com/2009/04/method-tracing.html
Donc, j'en suis là. La leçon serait très intéressante pour les étudiants, et assez facile à terminer une fois que j'aurais réussi à obtenir les informations dont j'ai besoin, mais je n'y suis pas parvenu jusqu'à présent, malgré mes efforts. Si vous avez un conseil ( ou un patch! ), merci d'envoyer un email à martin.quinson#loria.fr.
Cela me donne les actions à faire suivantes: * Vérifier quel tools.jar donne un package com.sun.jdi qui fonctionne * Trouver le bug de DrJava au niveau du débuggage pour les aider, et ainsi je pourrai réutiliser des parties de leur code à ce propos dans la PLM ( c'est un projet BSD tandis que ja PLM est majoritairement GPL jusqu'à présent -- il faudra que je leur demande de faire une exception). Cela serait mieux puisque leur interface d'aide semble être capable de travailler avec différents débuggers (eclipse, sun ou openjdk). C'est une quantité importante de travail que j'aimerai éviter d'avoir à dupliquer. * Trouver comment je peux obtenir les informations de traçage d'ASM. Cela semble être plus robuste aux variations de la JVM que l'approche via débuggage. D'un autre côté, le débuggage est une fonctionnalité bien tenue dans la PLM.* Travailler sur la fusion entre PLM et DrJava. En plus du problème de licence, cela compliquera l'intégration actuelle de PLM dans Debian puisque DrJava est composé de [[5 modules séparés|http://drjava.org/docs/developer/ch02s03.html]] qui peuvent seulement être intégré en tant que source package distincts. Comme tout package java, aucune source n'est distribuée et ils doivent les récupérer directement du svn. Enfin, ils sont très gros, d'après sloccount.