Skip to content
Snippets Groups Projects
Commit c11318cb authored by Romain Vuillemot's avatar Romain Vuillemot
Browse files

updates

parent 54a2dc60
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id:013ab73d tags:
%% Cell type:markdown id:fe61912a tags:
NAME:
%% Cell type:markdown id:6d71a1d5-6589-4320-900f-b07f08df01f4 tags:
# INF TC1 - TD6 (2h) - Automates
%% Cell type:markdown id:54c3bdf8-4ded-45da-a79a-6530af149f51 tags:
---
%% Cell type:markdown id:33320365-404e-4424-96d1-6e6b742c8f44 tags:
## Objectif du TD
Dans ce TD nous allons introduire les automates, qui sont (en informatique) un modèle de calcul permettant de déterminer si une séquence d'information est valide ou non, selon une règle déterminée. Dans un premier temps nous allons définir des automates simples, et ensuite les implémenter en Python et résoudre des problèmes de complexité croissante.
%% Cell type:markdown id:02ba4e95-34be-41b9-b36c-255b5af6b3de tags:
## Qu'est-ce qu'un automate ?
Un automate est un outil de calcul permettant la validation de séquences d'instructions, à base d'états et de transitions. Un exemple d'automate est un feu tricolore, où :
- les **états** sont la couleur du feu (rouge, vert ou orange)
- les **transitions** les changements possibles de couleurs (du rouge au vert, du vert au orange, et du orange au rouge).
Les automates permettent donc de formaliser le fonctionnement d'un système et de détecter des erreurs éventuelles qui ne respectent pas les changements pré-définis (en reprenant l'exemple du feu tricolore, passer du vert au rouge directement est une erreur). Les applications des automates sont nombreuses et offrent souvent un code plus facile à écire et lire.
%% Cell type:code id:ca93dafe-32d7-4332-9d26-c57c928805ee tags:
``` python
from IPython.core.display import HTML
HTML('<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 7.1.0 (20230121.1956) --><!-- Pages: 1 --><svg width="131pt" height="52pt" viewBox="0.00 0.00 131.00 52.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 48)"><polygon fill="white" stroke="none" points="-4,4 -4,-48 127,-48 127,4 -4,4"/><g id="node1" class="node"><title>0</title><ellipse fill="none" stroke="black" stroke-width="2" cx="18" cy="-22" rx="18" ry="18"/><text text-anchor="middle" x="18" y="-18.3" font-family="Times,serif" font-size="14.00">0</text></g><g id="node2" class="node"><title>1</title><ellipse fill="none" stroke="black" cx="101" cy="-22" rx="18" ry="18"/><ellipse fill="none" stroke="black" cx="101" cy="-22" rx="22" ry="22"/><text text-anchor="middle" x="101" y="-18.3" font-family="Times,serif" font-size="14.00">1</text></g><g id="edge1" class="edge"><title>0→1</title><path fill="none" stroke="black" d="M36.18,-22C45.15,-22 56.45,-22 67.03,-22"/><polygon fill="black" stroke="black" points="67,-25.5 77,-22 67,-18.5 67,-25.5"/><text text-anchor="middle" x="57.5" y="-25.8" font-family="Times,serif" font-size="14.00">a</text></g></g></svg>')
```
%% Cell type:markdown id:07c95f05-1782-4f25-80fe-9dcf93bdedc6 tags:
## Définitions
Un automate possède une structure de données similaire à un graphe orienté, où **chaque nœud représente un état** et un **arc représente une transition possible d'un état à un autre**. Ce graphe est ensuite parcouru à partir de `mots` (par exemple : `aba`), qui sont une suite de symboles (comme les lettres `a` et `b`) permettant de passer d'un état à un autre. L'état initial (unique) est représenté visuellement par un cercle en gras, et le dernier état (il peut y en avoir plusieurs) par un double cercle. Les symboles `a` et `b` constituent l'alphabet de l'automate (il est possible d'utiliser tout type d'alphabet, comme les transitions d'un feu tricolore).
Dans l'exemple ci-dessus, si le mot à lire est `a`, l'automate commence à lire le mot depuis l'état `0` et réalise ensuite une transition vers l'état `1` et s'arrête. Comme l'état `1` est un état final le mot `a` est validé. On parlera de motif pour indiquer les familles de mots validés par un automate, comme par exemple les mots qui commencent par `a` nous notons `a*` (l'astérisque indiquant que tout symbole peut être utilisé).
De manière générale, un automate est défini comme $A = (\Sigma, S, s_{0}, \delta, F)$, avec :
- $\Sigma$, un ensemble fini, non vide de symboles qui est l'alphabet d'entrée
- $S$, un ensemble fini, non vide d'états
- $s_{0}$, l'état initial, élément de $S$
- $\delta$, la fonction de transition d'états: $\delta : S \times \Sigma \rightarrow S$
- $F$ est l'ensemble des états terminaux, un sous-ensemble (éventuellement vide) de $S$
%% Cell type:markdown id:15b6ca9c-be1c-4757-b02c-1511fed5df68 tags:
## Dessin d'automates
Pour dessiner des automates, nous utiliserons [Graphviz](https://graphviz.org/), un outil en ligne de commande qui permet de dessiner des graphes basé sur le langage [DOT](https://graphviz.org/doc/info/lang.html). Un exemple d'automate est donné ci-dessous :
```python
from graphviz import Digraph
dot = Digraph()
dot.graph_attr['rankdir'] = 'LR'
dot.node('A', shape='circle', style='bold', label='0')
dot.node('B', shape='doublecircle', label='1')
dot.edge('A', 'B', label='a')
dot.edge('B', 'A', label='a')
dot
``````
%% Cell type:markdown id:07d1cd6d-1845-4707-b126-fbe219408a92 tags:
**IMPORTANT :** vérifier que le code ci-dessus s'exécute bien (dans la cellule ci-dessous). Si cela n'est pas le cas alors suivez ces [instructions d'installation de la bibliothèque Graphviz](../graphviz.ipynb).
**IMPORTANT :** vérifier que le code ci-dessus s'exécute bien (dans la cellule ci-dessous). Si cela n'est pas le cas alors suivez ces [instructions d'installation de la bibliothèque Graphviz](https://gitlab.ec-lyon.fr/rvuillem/inf-tc1/-/blob/master/graphviz.ipynb).
%% Cell type:code id:bff8d514-4ab5-4a24-81c2-ecd7ef39aa9e tags:
``` python
from graphviz import Digraph
dot = Digraph()
dot.graph_attr['rankdir'] = 'LR'
dot.node('0', shape='circle', style='bold', label='0')
dot.node('1', shape='doublecircle', label='1')
dot.edge('0', '1', label='a')
dot
```
%% Cell type:markdown id:ad7810cc-eefc-4733-993e-50c131c3e514 tags:
## Exercice 1 : Automates simples
Dans cette section, nous vous demandons de proposer un automate qui valide un motif donné. Pour les questions 1.1, 1.2 et 1.3, nous considérons un alphabet contenant les lettres `a` et `b` seulement. Vous pouvez répondre aux questions sur papier de préférence, ou utiliser le code ci-dessus du module `graphviz` pour dessiner l'automate.
**Question 1.1 -** Proposer un automate qui contient un nombre paire de fois la lettre `a`.
%% Cell type:code id:d33a29aa-5e07-476d-bfa9-4ef7454bc6f4 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:87566002-5968-4b5f-aa05-c108bfe1cf33 tags:
**Question 1.2 -** Proposer un automate qui valide le motif `a*a` (les mots qui commencent et finissent par `a`, de taille > 2).
%% Cell type:code id:a8a32710-840f-4385-a85f-670c992ddca7 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:70c4a996-c123-49c9-b771-b58046b6bb97 tags:
penser à proposer une liste de mots à valider et à ne pas valider afin de guider les étudiants.
%% Cell type:markdown id:14d7d169-fa9b-4c90-87d9-b07cfb1cc323 tags:
**Question 1.3 -** Quel langage valide l'automate ci-dessous ? Donnez un exemple de mots validés et le langage.
%% Cell type:code id:b83f2bad-2864-4eeb-9851-510c7d5dd273 tags:
``` python
from IPython.core.display import HTML
HTML('<?xml version="1.0" encoding="UTF-8" standalone="no"?><!-- Generated by graphviz version 7.1.0 (20230121.1956) --><!-- Pages: 1 --><svg width="409pt" height="118pt" viewBox="0.00 0.00 408.60 118.00" version="1.1" id="svg487" sodipodi:docname="a.svg" inkscape:version="1.2.2 (b0a8486, 2022-12-01)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <defs id="defs491" /> <sodipodi:namedview id="namedview489" pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="pt" showgrid="false" inkscape:zoom="1.5" inkscape:cx="273" inkscape:cy="78.666667" inkscape:window-width="1309" inkscape:window-height="456" inkscape:window-x="403" inkscape:window-y="317" inkscape:window-maximized="0" inkscape:current-layer="svg487" /> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 114)"> <polygon fill="white" stroke="none" points="-4,4 -4,-114 404.6,-114 404.6,4 -4,4" id="polygon345" /> <!-- init --> <g id="node1" class="node"> <title id="title347">init</title> <ellipse fill="black" stroke="black" cx="1.8" cy="-39" rx="1.8" ry="1.8" id="ellipse349" /> </g> <!-- Q_0 --> <g id="node2" class="node"> <title id="title352">Q_0</title> <ellipse fill="none" stroke="black" cx="58.6" cy="-39" rx="18" ry="18" id="ellipse354" /> <text text-anchor="middle" x="58.6" y="-35.3" font-family="Times,serif" font-size="14.00" id="text356">0</text> </g> <!-- init&#45;&gt;Q_0 --> <g id="edge1" class="edge"> <title id="title359">init-&gt;Q_0</title> <path fill="none" stroke="black" d="M3.75,-39C6.96,-39 17.8,-39 28.92,-39" id="path361" /> <polygon fill="black" stroke="black" points="28.79,-42.5 38.79,-39 28.78,-35.5 28.79,-42.5" id="polygon363" /> </g> <!-- Q_0&#45;&gt;Q_0 --> <g id="edge3" class="edge"> <title id="title366">Q_0-&gt;Q_0</title> <path fill="none" stroke="black" d="M52.13,-56.04C50.81,-65.86 52.97,-75 58.6,-75 61.86,-75 63.95,-71.94 64.88,-67.47" id="path368" /> <polygon fill="black" stroke="black" points="68.38,-67.61 65.04,-57.55 61.38,-67.49 68.38,-67.61" id="polygon370" /> <text text-anchor="middle" x="58.6" y="-78.8" font-family="Times,serif" font-size="14.00" id="text372">b</text> </g> <!-- Q_1 --> <g id="node3" class="node"> <title id="title375">Q_1</title> <ellipse fill="none" stroke="black" cx="137.6" cy="-52" rx="18" ry="18" id="ellipse377" /> <text text-anchor="middle" x="137.6" y="-48.3" font-family="Times,serif" font-size="14.00" id="text379">1</text> </g> <!-- Q_0&#45;&gt;Q_1 --> <g id="edge2" class="edge"> <title id="title382">Q_0-&gt;Q_1</title> <path fill="none" stroke="black" d="M74.78,-47.66C80.76,-50.6 87.81,-53.52 94.6,-55 99.05,-55.97 103.83,-56.29 108.5,-56.22" id="path384" /> <polygon fill="black" stroke="black" points="108.46,-59.73 118.18,-55.49 107.94,-52.75 108.46,-59.73" id="polygon386" /> <text text-anchor="middle" x="98.1" y="-58.8" font-family="Times,serif" font-size="14.00" id="text388">a</text> </g> <!-- Q_1&#45;&gt;Q_0 --> <g id="edge5" class="edge"> <title id="title391">Q_1-&gt;Q_0</title> <path fill="none" stroke="black" d="M121.42,-43.34C115.44,-40.4 108.39,-37.48 101.6,-36 97.15,-35.03 92.37,-34.71 87.7,-34.78" id="path393" /> <polygon fill="black" stroke="black" points="87.74,-31.27 78.02,-35.51 88.26,-38.25 87.74,-31.27" id="polygon395" /> <text text-anchor="middle" x="98.1" y="-39.8" font-family="Times,serif" font-size="14.00" id="text397">b</text> </g> <!-- Q_2 --> <g id="node4" class="node"> <title id="title400">Q_2</title> <ellipse fill="none" stroke="black" cx="216.6" cy="-52" rx="18" ry="18" id="ellipse402" /> <text text-anchor="middle" x="216.6" y="-48.3" font-family="Times,serif" font-size="14.00" id="text404">2</text> </g> <!-- Q_1&#45;&gt;Q_2 --> <g id="edge4" class="edge"> <title id="title407">Q_1-&gt;Q_2</title> <path fill="none" stroke="black" d="M156.07,-52C165.13,-52 176.43,-52 186.74,-52" id="path409" /> <polygon fill="black" stroke="black" points="186.68,-55.5 196.68,-52 186.68,-48.5 186.68,-55.5" id="polygon411" /> <text text-anchor="middle" x="177.1" y="-55.8" font-family="Times,serif" font-size="14.00" id="text413">a</text> </g> <!-- Q_2&#45;&gt;Q_2 --> <g id="edge7" class="edge"> <title id="title416">Q_2-&gt;Q_2</title> <path fill="none" stroke="black" d="M209.6,-69.04C208.17,-78.86 210.51,-88 216.6,-88 220.12,-88 222.39,-84.94 223.4,-80.47" id="path418" /> <polygon fill="black" stroke="black" points="226.9,-80.61 223.57,-70.55 219.9,-80.49 226.9,-80.61" id="polygon420" /> <text text-anchor="middle" x="216.6" y="-91.8" font-family="Times,serif" font-size="14.00" id="text422">a</text> </g> <!-- Q_3 --> <g id="node5" class="node"> <title id="title425">Q_3</title> <ellipse fill="none" stroke="black" cx="295.6" cy="-22" rx="18" ry="18" id="ellipse427" /> <text text-anchor="middle" x="295.6" y="-18.3" font-family="Times,serif" font-size="14.00" id="text429">3</text> </g> <!-- Q_2&#45;&gt;Q_3 --> <g id="edge6" class="edge"> <title id="title432">Q_2-&gt;Q_3</title> <path fill="none" stroke="black" d="M233.93,-45.64C243.73,-41.82 256.44,-36.87 267.69,-32.48" id="path434" /> <polygon fill="black" stroke="black" points="268.84,-35.79 276.88,-28.9 266.3,-29.27 268.84,-35.79" id="polygon436" /> <text text-anchor="middle" x="256.1" y="-40.8" font-family="Times,serif" font-size="14.00" id="text438">b</text> </g> <!-- Q_3&#45;&gt;Q_0 --> <g id="edge9" class="edge"> <title id="title441">Q_3-&gt;Q_0</title> <path fill="none" stroke="black" d="M277.13,-21.08C245.54,-19.69 176.9,-17.91 119.6,-25 108.92,-26.32 97.36,-28.77 87.27,-31.25" id="path443" /> <polygon fill="black" stroke="black" points="86.5,-27.83 77.7,-33.73 88.26,-34.61 86.5,-27.83" id="polygon445" /> <text text-anchor="middle" x="177.1" y="-23.8" font-family="Times,serif" font-size="14.00" id="text447">b</text> </g> <!-- Q_4 --> <g id="node6" class="node"> <title id="title450">Q_4</title> <ellipse fill="none" stroke="black" cx="378.6" cy="-22" rx="18" ry="18" id="ellipse452" /> <ellipse fill="none" stroke="black" cx="378.6" cy="-22" rx="22" ry="22" id="ellipse454" /> <text text-anchor="middle" x="378.6" y="-18.3" font-family="Times,serif" font-size="14.00" id="text456">4</text> </g> <!-- Q_3&#45;&gt;Q_4 --> <g id="edge8" class="edge"> <title id="title459">Q_3-&gt;Q_4</title> <path fill="none" stroke="black" d="M313.78,-22C322.75,-22 334.05,-22 344.63,-22" id="path461" /> <polygon fill="black" stroke="black" points="344.6,-25.5 354.6,-22 344.6,-18.5 344.6,-25.5" id="polygon463" /> <text text-anchor="middle" x="335.1" y="-25.8" font-family="Times,serif" font-size="14.00" id="text465">a</text> </g> <!-- Q_4&#45;&gt;Q_4 --> <g id="edge10" class="edge"> <title id="title468">Q_4-&gt;Q_4</title> <path fill="none" stroke="black" d="M374.59,-43.81C374.2,-53.56 375.54,-62 378.6,-62 380.32,-62 381.5,-59.33 382.13,-55.26" id="path470" /> <polygon fill="black" stroke="black" points="385.62,-55.46 382.55,-45.32 378.63,-55.16 385.62,-55.46" id="polygon472" /> <text text-anchor="middle" x="378.6" y="-65.8" font-family="Times,serif" font-size="14.00" id="text474">a</text> </g> <!-- Q_4&#45;&gt;Q_4 --> <g id="edge11" class="edge"> <title id="title477">Q_4-&gt;Q_4</title> <path fill="none" stroke="black" d="M371.74,-43.11C368.71,-61.1 371,-80 378.6,-80 384.6,-80 387.29,-68.23 386.67,-54.43" id="path479" /> <polygon fill="black" stroke="black" points="390.16,-54.19 385.62,-44.62 383.2,-54.93 390.16,-54.19" id="polygon481" /> <text text-anchor="middle" x="378.6" y="-83.8" font-family="Times,serif" font-size="14.00" id="text483">b</text> </g> </g></svg>')
```
%% Cell type:code id:7aae22c9 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:b1c8a625-b2e5-4958-b49f-009c7bcdb038 tags:
**Question 1.4 -** Proposer un automate qui valide la propriété suivante : une chaîne de caractères est une adresse email. Les adresses email peuvent être définies comme suit (de manière simplifiée) :
- le premier caractère ne peut pas être un chiffre
- ensuite tous les caractères de `a` à `z` (majuscules et minuscules) et chiffres sont acceptés
- un `@` doit être présent
- ensuite un nom de domaine qui lui aussi ne peut commencer par un chiffre (et doit faire + de 1 caractère)
- un "."
- une extension parmis une liste autorisée (`fr`, `com`, etc)
Un exemple de chaîne qui n'est pas validée est `3toto@a.fr2` car la première partie commence par un chiffre, le nom de domaine est trop court et enfin l'extension n'est pas valide. Pour la partie de validation de l'extension (`.fr`, etc.), vous pouvez simplifier en proposant une reconnaissance de motifs pré-définis (`.fr`, `.com`, etc.). Vous pouvez vous référer à la page Wikipedia [ici](https://fr.wikipedia.org/wiki/Adresse_\%C3\%A9lectronique) ou à la RFC 8222 [ici](https://www.w3.org/Protocols/rfc822/) pour une définition plus précise.
%% Cell type:code id:2ee41daa-5611-433d-862a-f098127cad73 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:6655a83e tags:
## Exercice 2 : Structure de données d'automate en Python
%% Cell type:markdown id:bd6c2f5f-a14a-4a72-bbbe-ad7ec0406dad tags:
**Question 2.1 -** Nous allons désormais implémenter en Python une structure de données d'automate. Celle-ci doit être en mesure de stocker toutes les informations relatives à la définition d'un automate (symboles reconnu, états, états initiaux/finaux) et valider un mot donné. Votre structure de données peut être composée comme suit :
1. Un constructeur `__init__` qui initialise l'automate avec les symboles du motif (ici `a` et `b`) et les variables d'état interne. En particulier l'état initial.
2. Une méthode `ajout_etat` qui rajoute un nouvel état et s'assure que l'état n'existe pas déjà; un paramètre additionnel `final` indiquera si il s'agit d'un état finaal
3. Une méthode `ajout_transition` qui rajoute un nouvel état et s'assure que l'état n'existe pas déjà.
4. Une méthode `recherche_etat` qui étant donné un état source et un symbole, renvoie l'état correspondant (via la transition correspondant au symbole donné).
5. Une fonction `run` qui valide un mot donné, et renvoie `True` si l'état final est atteint et `False`.
%% Cell type:code id:445d2964 tags:
``` python
class automate:
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:dd5fe66b-8232-4ab6-94d7-0e49ca591f26 tags:
Voici un exemple attendu d'utilisation de votre structure de données :
%% Cell type:code id:51a7c400 tags:
``` python
a = automate("ab")
a.ajout_etat("0")
a.ajout_etat("1", True)
a.ajout_transition("0", "b", "0")
a.ajout_transition("0", "a", "1")
a.ajout_transition("1", "a", "1")
a.ajout_transition("1", "b", "1")
assert a.run("abaaaaa") == True
assert a.run("bbb") == False
```
%% Cell type:markdown id:d16f624a-7810-489c-9b6a-f0bba5eb25f2 tags:
**Question 2.2 -** Utilisez votre structure de données pour implémenter les automates de la partie précédente.
%% Cell type:markdown id:244afe6c-a606-4e1f-b09b-f9dd59882135 tags:
Question 1.1 (solution) :
%% Cell type:code id:428cf819-3d60-4776-ba94-3e8733eeadea tags:
``` python
# automate qui valide un nombre pair de fois la lettre "a" avec langage a, b
# YOUR CODE HERE
raise NotImplementedError()
# tests valides
assert a.run("") == True
assert a.run("aa") == True
assert a.run("aaaa") == True
assert a.run(''.join("a" for i in range(100))) == True
# tests non-valides
assert a.run("a") == False
assert a.run(''.join("a" for i in range(100 + 1))) == False
```
%% Cell type:markdown id:64e021b0-4613-444d-87d8-b0abeed5aef2 tags:
Question 1.2 (solution) :
%% Cell type:code id:f51ce343-fcdb-49c0-a126-4ffeaf4e1920 tags:
``` python
# automate qui valide a*a
# YOUR CODE HERE
raise NotImplementedError()
# tests valides
assert a.run("aa") == True
assert a.run("aaaa") == True
assert a.run(''.join("a" for i in range(100))) == True
# tests non-valides
assert a.run("") == False
assert a.run("a") == False
assert a.run("aabb") == False
assert a.run("b") == False
```
%% Cell type:markdown id:9b44355d-e2a6-4ef2-b427-d5c39cc72662 tags:
Question 1.3 (solution) :
%% Cell type:code id:6c1a0049-03c3-47b1-adf7-35a59d8c78f7 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:34eb2bb6-aba0-4263-9702-761694af7348 tags:
**Question 2.3 (bonus) -** Implémentez une méthode `visualize(self)` afin d'afficher votre automate en utilisant le code `graphviz` fourni dans les questions précédentes. En voici les principales étapes (il s'agit de construire un graphe..) :
1. Initialiser les sommes
2. Rajouter les arrêtes
3. Inclure les propriétés et labels
%% Cell type:markdown id:954a7d30-9e8a-4269-aee4-e36924da2e86 tags:
**Question 2.4 (bonus) -** Implémentez une méthode `__str__` afin que la commande `print(a)` affiche les états internes à l'automate comme ci-dessous :
%% Cell type:markdown id:0a4548cc-197f-4c70-a4f9-e3c5c706d378 tags:
```
automate :
- alphabet : 'ab'
- init : 0
- final : ['1']
- etats (2) :
- (0)automate :
- alphabet : 'ab'
- init : 0
- final : ['1']
- etats (2) :
- (0):
--(b)--> (0)
--(a)--> (1)
- (1):
--(a)--> (1)
--(b)--> (1)
```
%% Cell type:markdown id:6764667b-ab2b-46c1-a5bb-2a12bb670afd tags:
## Exercice 3 : Analyse de texte avec un automate
%% Cell type:markdown id:b13e013c-8c73-4008-ac92-cf981b2a5cb0 tags:
Nous allons maintenant développer un programme qui utilise votre structure de données d'automate implémentée en Python dans la section précédente. L'objectif de ce programme sera le suivant : proposer de compléter un mot, à partir d'une séquence de lettres partielle donnée. Par exemple si votre programme prend en entrée la séquence `bon`, en retour vous devez proposer une séquence de lettres pertinentes afin de compléter ce mot comme `bonjour` ou `bonsoir`.
Vous êtes libres de proposer la stratégie de recommandation de lettres que vous souhaitez. Nous vous proposons de vous baser sur es listes de mots les plus fréquents en Français [ce lien](http://www.pallier.org/extra/liste.de.mots.francais.frgut.txt) (fourni dans le fichier `mots.txt`). Ces mots permettent de réaliser des statistiques de co-occurences. Par exemple, étant donné les mots suivants :
```
abaissa
abaissable
abaissables
abaissai
abaissaient
abaissais
abaissait
abaissâmes
```
Si le mot d'entrée est `abaissa` alors votre programme suggère les lettres suivantes ordonnées par ordre de probabilité de transition pour compléter le mot (basé sur l'analyse du fichier `code/mots-10.txt` qui contient les mots ci-dessus):
```
i (4)
b (2)
m (1)
```
Conseils :
1. Utiliser les fichiers de listes de mots (`mots.txt`, ..) en analysant la fréquence de co-occurrences de lettres (autrement dit calculer probabilité d'être l'une après l'autre)
2. Construire un automate dont les transitions sont les probabilités de co-occurence entre les lettres
3. Proposer une méthode de recommandation de transition à partir de quelques lettres fournies en entrée
%% Cell type:code id:b5309ac0 tags:
``` python
# lecture du fichier de mots
data = []
with open("mots-10.txt") as f:
keys = None
for line in f:
l = [w.strip() for w in line.split(';')]
if keys is None:
keys = l
else:
data.append(l)
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:77408003 tags:
## Pour aller plus loin
- Vérifier si les automates sont [déterministes](https://fr.wikipedia.org/wiki/Automate_fini_d%C3%A9terministe)
- Comparer vos résultats avec une implémentation [Python d'Automate](https://pypi.org/project/python-automaton/) :
- Enregistrer les automates en utilisant la commande
`dot.render('graph', format='svg', view=True)`
%% Cell type:code id:30734c6a-eb05-4830-95b5-669cc417c4ee tags:
``` python
```
......
%% Cell type:markdown id:cd27fe91 tags:
## Graphviz
---
Graphviz une biobliothèque open-source de dessin de graphes (ce qui inclue les arbres et automates).
### Installation
#### Mac
Exécuter la commande "brew install graphviz" dans une fenêtre "terminal" (console).
Exécuter la commande suivante" dans une fenêtre "terminal" (console).
#### Windows
Le site https://graphviz.org/download/ vous indique comment procéder
Avec Conda :
> conda install -c anaconda graphviz
%% Cell type:code id:29fbc946 tags:
Une alternative consiste à installer le module Python à partir de `pip``:
https://pypi.org/project/graphviz/
### Alternatives
Vous pouvez créer vos proprez diagrammes en ligne en utilisant le format `dot`. Un exemple en ligne :
https://dreampuf.github.io/GraphvizOnline/#digraph%20auto%20%7B%0A%20%20%20%20rankdir%3D%22LR%22%3B%0A%0A%20%20%20%20%2F%2F%20Etats%20(12)%0A%20%20%20%20node%20%5Bshape%20%3D%20point%20%5D%3B%20%20%20%20%20__Qi__%20%2F%2F%20Etat%20initial%0A%20%20%20%20node%20%5Bshape%3Dcircle%5D%3B%20Q_0%20%5Blabel%3D0%5D%3B%0A%20%20%20%20node%20%5Bshape%3Ddoublecircle%5D%3B%20Q_1%20%5Blabel%3D1%5D%3B%0A%0A%20%20%20%20%2F%2F%20Transitions%0A%20%20%20%20__Qi__%20-%3E%20Q_0%3B%20%2F%2F%20Etat%20initial%20fleche%0A%20%20%20%20Q_0%20-%3E%20Q_0%20%5Blabel%3Db%5D%3B%0A%20%20%20%20Q_0%20-%3E%20Q_1%20%5Blabel%3Da%5D%3B%0A%20%20%20%20Q_1%20-%3E%20Q_1%20%5Blabel%3Da%5D%3B%0A%20%20%20%20Q_1%20-%3E%20Q_1%20%5Blabel%3Db%5D%3B%0A%7D
```
digraph auto {
rankdir="LR";
// Etats (12)
node [shape = point ]; __Qi__ // Etat initial inivisble
node [shape=circle]; Q_0 [label=0];
node [shape=doublecircle]; Q_1 [label=1]; // Etat final
// Transitions
__Qi__ -> Q_0; // Etat initial fleche
Q_0 -> Q_0 [label=b];
Q_0 -> Q_1 [label=a];
Q_1 -> Q_1 [label=a];
Q_1 -> Q_1 [label=b];
}
```
D'autres modules de dessins de graphes existent comme NetworkX https://networkx.org/
%% Cell type:code id:c76ec3e2 tags:
``` python
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment