Le trente-sixième chapitre de Madame Bovary |
Votre programme est à rendre par courier électronique à Luc.Maranget@inria.fr avant le 11 janvier 2008, 23h59.Trop tard : Solution.Questions posées avant le 11 janvier et mes réponses disponibles ici.
Suivre la technique « chaîne de Markov » décrite lors de l’amphi 04 pour faire écrire par un ordinateur un chapitre plausible de Madame Bovary de Gustave Flaubert (qu’il nous pardonne, notre œuvre n’arrivera pas à la cheville de la sienne).
Écrire le programme Markov
qui produit, à la demande,
des chapitres dans le style de Madame Bovary.
Pour un entier n ≥ 1 donné, le texte produit est tel que :
L’entier n est donné en argument de la ligne de commande. Ainsi, la commande
% java Markov 3
produit un texte plutôt étrange, par exemple1 :
[…]
– Oui, du capharnaüm ! La clef qui enferme les acides avec les alcalis caustiques ! Avoir été prendre une bassine de réserve ! Une bassine à couvercle ! et dont jamais peut-être je ne me sens pas en mon assiette ; il faudra même un de ces hommes d’ardeurs taciturnes qui travaillent la nuit dans les livres, et portent enfin, à soixante ans, quand vient l’âge des rhumatismes, une brochette de croix, sur leur habit noir, mal fait. Elle aurait voulu ne rien entendre, ne rien voir, afin de ne pas payer, d’emprunter, de souscrire des billets, puis de renouveler ces billets, qui s’enflaient à chaque échéance nouvelle, elle avait fini par préparer au sieur Lheureux était encore si longue, qu’il n’y fallait pas songer. D’ailleurs, imaginant qu’elle y mettait de la délicatesse, Charles insista davantage ; si bien qu’elle demeurait fort embarrassée dans sa velléité de sacrifice, lorsque l’apothicaire vint à propos lui fournir une occasion.
Le texte ci-dessus est de toute évidence dérivé de l’œuvre de Flaubert. Dérivé est d’ailleurs le mot juste, on perçoit un certain flottement dans l’écriture.
Plus sérieusement, on notera par exemple, que le chapitre numéro 28 commence par « Un soir que [Charles l’écoutait,…] ». La jolie sentence « Emma, tout exprès, avait retiré la clef de sol, […] » n’est pas de Flaubert, mais Flaubert a écrit :
Il est donc établi que « retiré la clef de » et « la clef de sol, » sont deux suites de n+1 = 4 mots qui permettent de relier la clef de la barrière à la clef de sol.
Ce qu’est exactement un mot est expliqué (si on peut dire)
plus loin comme étant
défini par la classe des lecteurs de mots fournie.
Disons pour le moment qu’il existe, dans les textes fournis, un mot un
peu spécial <PAR>
qui indique les sauts de paragraphes.
Il est également commode de considérer deux mots supplémentaires
<START>
et <END>
qui marquent le début et la fin d’un chapitre.
Notez que ces mots ne sont pas présents dans les textes fournis,
et n’ont pas besoin de l’être.
L’algorithme emploie une table de hachage dont les clés sont des suites de n mots et les valeurs des multi-ensembles (ensembles avec répétitions possibles des éléments) de mots. Il se décompose en deux phases, construction de la table et production du texte.
<START>
, <START>
, …,
<START>
, <START>
.
<END>
aux mots associés à P.
<START>
, <START>
, …,
<START>
, <START>
.
<END>
, alors terminer.
Sans chercher à produire une présentation parfaite,
l’affichage devra être lisible
(espaces entre les mots, sauts de lignes avant et après
le mot <PAR>
).
Un « multi-ensemble » de mots est facilement représenté soit comme une liste soit comme un tableau. Sans que cela soit un jugement définitif, on peut dire que la liste est plus appropriée dans la phase de construction, tandis que le tableau est plus approprié dans la phase de production du texte (pour choisir le n+1-ième mot, cf. le cours.) Une solution simple est de convertir les listes en tableaux entre les deux phases de l’algorithme.
On peut iterer sur les associations d’une HashMap<K,V>
de la bibliothèque
de la manière suivante :
Le code ci-dessus exécute I[k,v] pour toutes les associations (k → v) contenues dans la table t. Les derniers transparents de l’amphi 04 donnent quelques explications.
Enfin, souvenez-vous qu’une fois qu’une clé est rangée dans la table, cette clé ne doit pas changer.
Le texte de Madame Bovary est donné sous la forme de 35 fichiers (un par chapitre de 01.txt à 35.txt) dans l’archive bovary.tar.gz à désarchiver ainsi :
% tar zxf bovary.tar.gz
Vous disposez maintenant d’un sous-répertoire bovary qui contient les 35 chapitres. Le texte est soumis à cette licence.
Récupérez la classe des lecteurs des
mots WordReader
qui est conforme à
la description donnée en cours.
et compilez la.
Cette classe comprend entre autres, un
constructeur new WordReader (String filename)
qui prend un nom de fichier en argument ; ainsi qu’une
méthode main d’essai :
% java WordReader bovary/01.txt [Nous] [étions] [à] [l'Etude,] [quand] [le] [Proviseur] [entra] [suivi] [d'un] ... [<PAR>] ...
Outre les mots du premier chapitre écrit par Flaubert, vous voyez
apparaître des mots <PAR>
qui indiquent simplement les
paragraphes. Ces mots <PAR>
sont
à traiter comme des mots ordinaires.
Votre programme Markov
doit obligatoirement se comporter ainsi.
System.out
)
et seulement son résultat.
Args
fournie.
% java Markov 4ou encore
% java Markov 4 bovary/01.txtAlors
a.prefixLength
vaut la valeur de l’argument numérique.
Sinon a.prefixLength
a la valeur par défaut 2.a.files
.
Par exemple avec :
% java Markov petit.txtle tableau
a.files
est
{ "petit.txt", }
(tableau à un élément).
Cette disposition vous permet de tester votre programme sur de petits
exemples, si petit.txt est le fichier suivant.
a b c a b c a b cAlors le programme doit afficher « a b c » un certain nombre de fois.
% java Markov petit.txt a b c a b c a b c a b c
Si il n’y pas d’arguments autres qu’un éventuel premier argument numérique,
alors a.files
a une valeur par défaut qui correspond aux 35
chapitres contenus dans le sous-répertoire bovary.
Ce document a été traduit de LATEX par HEVEA