scratch/multi/blog/2010-05-24-Trees--Pragmatism-and-Formalism.md

457 lines
16 KiB
Markdown
Raw Permalink Normal View History

-----
2010-06-07 09:30:20 +00:00
isHidden: false
menupriority: 1
kind: article
created_at: 2010-05-24T20:05:14+02:00
fr: title: Arbres ; Pragmatisme et Formalisme
2010-05-26 14:46:40 +00:00
fr: subtitle: Quand la théorie est plus pratique que la pratique
en: title: Trees; Pragmatism and Formalism
2010-05-26 14:46:40 +00:00
en: subtitle: When theory is more efficient than practice
author_name: Yann Esposito
author_uri: yannesposito.com
tags:
2011-12-07 15:40:03 +00:00
- XML
- Perl
en: - programming
2010-05-28 10:12:46 +00:00
en: - tree
en: - theory
en: - mathematics
en: - regexp
en: - script
2011-12-07 15:40:03 +00:00
fr: - programmation
2010-05-28 10:12:46 +00:00
fr: - arbre
fr: - théorie
fr: - mathématiques
fr: - regexp
fr: - script
-----
2010-05-26 21:49:51 +00:00
begindiv(intro)
2010-05-28 10:12:46 +00:00
en: %tldr:
2010-05-28 10:12:46 +00:00
en:
en: - I tried to program a simple filter
en: - Was blocked 2 days
en: - Then stopped working like an engineer monkey
en: - Used a pen and a sheet of paper
en: - Made some math.
en: - Crushed the problem in 10 minutes
en: - Conclusion: The pragmatism shouldn't mean "never use theory".
fr: %tlal :
2010-05-28 10:12:46 +00:00
fr:
fr: - J'ai essayé de programmer un simple filtre ;
fr: - J'ai été bloqué pendant deux jours ;
fr: - J'ai arrêté de penser comme un robot ;
fr: - J'ai utilisé un papier et un stylo ;
fr: - J'ai fait un peu de maths ;
fr: - J'ai résolu le problème en 10 minutes ;
fr: - Conclusion: Pragmatisme n'est pas : «n'utilisez jamais la théorie».
2010-05-26 21:49:51 +00:00
enddiv
en: ## Abstract (longer than %tldr)
fr: ## Résumé (plus long que le %tlal)
2010-05-28 10:12:46 +00:00
en: For my job, I needed to resolve a problem. It first seems not too hard.
en: Then I started working directly on my program.
en: I entered in the *infernal*: *try & repair loop*.
en: Each step was like:
fr: Je devais résoudre un problème à mon travail. Au début cela
fr: semblait assez facile. J'ai donc commencé à programmer
fr: tout de suite. Je suis alors entré dans un cercle infernal d'essais
fr: et de réparations. Voilà à quoi ressemblait cet étrange état
fr: de boucle infini :
en: > -- Just this thing to repair and that should be done.
en: > -- OK, now that should just work.
en: > -- Yeah!!!
en: > -- Oops! I forgotten that...
en: > `repeat until death`
fr: > -- Plus que ça a réparer et ça devrait être bon.
fr: > -- Très bien, maintenant ça doit marcher.
fr: > -- Oui !!
fr: > -- Ah mince! J'ai oublié ce détail...
fr: > `répéter jusqu'à la mort`
en: After two days of this [Sisyphus](http://fr.wikipedia.org/wiki/Sisyphe) work, I finally just stopped to rethink the problem.
en: I took a pen, a sheet of paper. I simplified the problem, reminded what I learned during my Ph.D. about trees.
en: Finally, the problem was crushed in less than 20 minutes.
fr: Après deux jours à me prendre pour [Sisyphe](http://fr.wikipedia.org/wiki/Sisyphe), je me suis arrêté pour repenser le problème.
fr: J'ai pris un stylo et une feuille de papier. Je me suis souvenu de de ce que j'avais appris sur les arbres pendant mon doctorat.
fr: Finalement, le problème fut résolu en moins de 20 minutes.
en: I believe the important lesson is to remember that the most efficient methodology to resolve this *pragmatic* problem was the *theoretical* one.
en: And therefore, argues opposing science, theory to pragmatism and efficiency are fallacies.
fr: Je pense que la leçon à retenir de cette expérience est de se souvenir que la méthodologie la plus efficace pour résoudre ce problème *pragamtique* était la méthode *théorique*.
2010-05-28 12:33:04 +00:00
fr: Ça ne signifie pas que la méthode théorique est toujours la meilleure, mais en tout cas, il ne faut pas l'écarter.
2010-05-26 21:49:51 +00:00
newcorps
2010-05-26 14:46:40 +00:00
en: # First: my experience
fr: # L'anecdote
2010-05-28 10:12:46 +00:00
en: Apparently 90% of programmer are unable to program a binary search without bug.
en: The algorithm is well known and easy to understand.
en: However it is difficult to program it without any flaw.
en: I participated to [this contest](http://reprog.wordpress.com/2010/04/19/are-you-one-of-the-10-percent/).
en: And you can see the [results here](http://reprog.wordpress.com/2010/04/21/binary-search-redux-part-1/)[^1].
en: I had to face a problem of the same kind at my job. The problem was simple to the start. Simply transform an <sc>xml</sc> from one format to another.
fr: Apparemment 90% des programmeurs sont incapable de programmer une recherche binaire sans faire de bug.
fr: L'algorithme est pourtant connu et facile à comprendre.
fr: Cependant, il est difficile à programmer sans bug.
fr: J'ai participé à [ce concours](http://reprog.wordpress.com/2010/04/19/are-you-one-of-the-10-percent/).
fr: Vous pouvez voir les [résultats ici](http://reprog.wordpress.com/2010/04/21/binary-search-redux-part-1/)[^1].
fr: J'ai dû faire face à un problème similaire à mon travail.
fr: Il paraissait simple au départ.
fr: Transformer un <sc>xml</sc> d'un format à un autre.
2010-05-28 10:12:46 +00:00
en: [^1]: Hopefully I am in the 10% who had given a bug free implementation.
fr: [^1]: Normalement, je fais parti des 10% qui ont fourni une implémentation sans bug.
2010-05-28 10:12:46 +00:00
en: The source <sc>xml</sc> was in the following general format:
fr: Voici le format général du <sc>xml</sc> source :
<code class="xml">
2010-05-27 14:57:29 +00:00
<rubrique>
<contenu>
<tag1>value1</tag1>
<tag2>value2</tag2>
...
2010-05-27 14:57:29 +00:00
</contenu>
<enfant>
2010-05-27 14:57:29 +00:00
<rubrique>
...
2010-05-27 14:57:29 +00:00
</rubrique>
...
2010-05-27 14:57:29 +00:00
<rubrique>
...
2010-05-27 14:57:29 +00:00
</rubrique>
</enfant>
</menu>
</code>
2010-05-28 10:12:46 +00:00
en: and the destination format was in the following general format:
fr: et le format d'arrivé est celui-ci :
<code class="xml">
2010-05-28 12:33:04 +00:00
<item name="Menu0">
<value>
<item name="menu">
2010-05-26 21:49:51 +00:00
<value>
2010-05-27 14:57:29 +00:00
<item name="tag1">
<value>value1</value>
</item>
<item name="tag2">
<value>value2</value>
</item>
...
<item name="menu">
<value>
...
</value>
<value>
...
</value>
</item>
2010-05-26 21:49:51 +00:00
</value>
2010-05-27 14:57:29 +00:00
</item>
</value>
2010-05-27 14:57:29 +00:00
</item>
</code>
2010-05-28 10:12:46 +00:00
en: At first sight I believed it will be easy. I was so certain it will be easy that I fixed to myself the following rules:
fr: À première vue, cela m'a paru simple. J'étais certain de pouvoir y arriver en me fixant les règles suivantes :
en: 1. do not use <sc>xslt</sc>
en: 2. avoid the use of an <sc>xml</sc> parser
en: 3. resolve the problem using a simple perl script[^2]
fr: 1. ne pas utiliser <sc>xslt</sc> ;
fr: 2. ne pas utiliser de parseur <sc>xml</sc> ;
fr: 3. résoudre le problème en utilisant un simple script perl
en: You can try if you want. If you attack the problem directly opening an editor, I assure you, it will certainly be not so simple.
en: I can tell that, because it's what I've done. And I must say I lost almost a complete day at work trying to resolve this. There was also, many small problems around that make me lose more than two days for this problem.
fr: Vous pouvez essayer si vous le souhaitez. Si vous attaquez ce problème directement en écrivant le programme, ce ne sera certainement pas si simple.
fr: Je peux le dire, parce que c'est ce que j'ai fait.
fr: Et je dois dire que j'ai perdu une journée de travail complète en m'y prenant de la sorte.
fr: En réalité, il y avait pas mal de petits détails dont je ne parle pas qui m'ont induis en erreur et qui m'ont fait perdre encore plus de temps.
en: Why after two days did I was unable to resolve this problem which seems so simple?
2010-05-31 19:30:23 +00:00
fr: Pourquoi étais-je incapable de résoudre ce problème si simple en aparence ?
2010-05-28 10:12:46 +00:00
en: What was my behaviour (workflow)?
2010-05-31 19:30:23 +00:00
fr: Voici comment je m'y suis pris :
2010-05-28 10:12:46 +00:00
en: 1. Think
en: 2. Write the program
en: 3. Try the program
en: 4. Verify the result
en: 5. Found a bug
en: 6. Resolve the bug
en: 7. Go to step 3.
fr: 1. Réfléchir
fr: 2. Écrire le programme
fr: 3. Essayer le programme
fr: 4. Vérifier les résultats
fr: 5. Trouver un bug
fr: 6. Résoudre le bug
fr: 7. Reprendre à l'étape 3
en: This was a *standard* workflow for computer engineer. The flaw came from the first step.
en: I thought about how to resolve the problem but with the eyes of a *pragmatic engineer*. I was saying:
fr: Il s'agissait d'une méthode de travail standard pour un ingénieur en informatique. L'erreur venait de la première étape.
fr: J'ai d'abord pensé à comment résoudre le problème mais avec des yeux d'*ingéinieur pragmatique*. Je me suis simplement dit :
en: > That should be a simple perl search and replace program.
en: > Let's begin to write code
fr: > Ça à l'air de pouvoir se résouvre avec un petit script de *search&amp;replace* en perl
fr: > Commençons à écrire le code maintenant.
en: This is the second sentence that was plainly wrong. I started in the wrong direction. And the workflow did not work from this entry point.
fr: C'est la deuxième phrase qui est complètement fausse. Parce que j'avais mal commencé et que cette méthodologie de travail ne fonctionne pas lorsque l'on part vraiment mal.
2010-05-28 12:33:04 +00:00
en: ## Think
fr: ## Réfléchir
2010-05-26 14:46:40 +00:00
2010-05-28 13:02:52 +00:00
en: After some times, I just stopped to work. Tell myself *"it is enough, now, I must finish it!"*.
en: I took a sheet of paper, a pen and began to draw some trees.
fr: Après un certain temps, j'ai arrêté de programmer et je me suis dit : &laquo;Maintenant, ça suffit !&raquo;.
fr: J'ai pris une feuille et un stylo et j'ai commencé à dessiner des arbres.
en: I began by make by removing most of the verbosity.
en: I first renamed `<item name="Menu">` by simpler name `M` for example.
en: I obtained something like:
fr: J'ai commencer par simplifier un peu en enlevant le maximum de verbiage.
fr: Tout d'abord en renommant `<item name="Menu">` par un simple `M` par exemple.
fr: J'ai obtenu quelque chose comme :
2010-05-28 12:33:04 +00:00
2010-05-31 19:30:23 +00:00
<graph title="The source tree">
subgraph cluster_x {
node [label="C"] C_x ;
node [label="E"] E_x ;
node [label="a1"] tag1_x ;
node [label="a2"] tag2_x ;
2011-12-07 15:40:03 +00:00
node [label="R", color="#333333", fillcolor="#333333", fontcolor="white"] R_x ;
2010-05-31 19:30:23 +00:00
R_x -> C_x;
C_x -> tag1_x ;
C_x -> tag2_x ;
R_x -> E_x ;
}
subgraph cluster_y {
node [label="C"] C_y ;
node [label="E"] E_y ;
node [label="a1"] tag1_y ;
node [label="a2"] tag2_y ;
2011-12-07 15:40:03 +00:00
node [label="R", color="#333333", fillcolor="#333333", fontcolor="white"] R_y ;
2010-05-31 19:30:23 +00:00
R_y -> C_y;
C_y -> tag1_y ;
C_y -> tag2_y ;
R_y -> E_y ;
}
subgraph cluster_z {
node [label="C"] C_z ;
node [label="E"] E_z ;
node [label="a1"] tag1_z ;
node [label="a2"] tag2_z ;
2011-12-07 15:40:03 +00:00
node [label="R", color="#333333", style="filled", fillcolor="#333333", fontcolor="white"] R_z ;
2010-05-31 19:30:23 +00:00
R_z -> C_z;
C_z -> tag1_z ;
C_z -> tag2_z ;
R_z -> E_z ;
}
E_x -> R_y ;
E_x -> R_z ;
</graph>
2010-05-28 12:33:04 +00:00
2010-05-28 13:02:52 +00:00
en: and
fr: et
2010-05-28 12:33:04 +00:00
2010-05-31 19:30:23 +00:00
<graph title="The destination tree">
subgraph cluster_x {
2010-05-31 19:46:16 +00:00
node [label="M"] E_x ;
2010-05-31 19:30:23 +00:00
node [label="a1"] tag1_x ;
node [label="V"] value_tag1_x ;
node [label="a2"] tag2_x ;
node [label="V"] value_tag2_x ;
2011-12-07 15:40:03 +00:00
node [label="V", color="#333333", fillcolor="#333333", fontcolor="white"] R_x ;
2010-05-31 19:30:23 +00:00
R_x -> value_tag1_x -> tag1_x ;
R_x -> value_tag2_x -> tag2_x ;
R_x -> E_x ;
}
subgraph cluster_y {
2010-05-31 19:46:16 +00:00
node [label="M"] E_y ;
2010-05-31 19:30:23 +00:00
node [label="a1"] tag1_y ;
node [label="V"] value_tag1_y ;
node [label="a2"] tag2_y ;
node [label="V"] value_tag2_y ;
2011-12-07 15:40:03 +00:00
node [label="V", color="#333333", fillcolor="#333333", fontcolor="white"] R_y ;
2010-05-31 19:30:23 +00:00
R_y -> value_tag1_y -> tag1_y ;
R_y -> value_tag2_y -> tag2_y ;
R_y -> E_y ;
}
subgraph cluster_z {
2010-05-31 19:46:16 +00:00
node [label="M"] E_z ;
2010-05-31 19:30:23 +00:00
node [label="a1"] tag1_z ;
node [label="V"] value_tag1_z ;
node [label="a2"] tag2_z ;
node [label="V"] value_tag2_z ;
2011-12-07 15:40:03 +00:00
node [label="V", color="#333333", fillcolor="#333333", fontcolor="white"] R_z ;
2010-05-31 19:30:23 +00:00
R_z -> value_tag1_z -> tag1_z ;
R_z -> value_tag2_z -> tag2_z ;
R_z -> E_z ;
}
E_x -> R_y ;
E_x -> R_z ;
</graph>
2010-05-28 12:33:04 +00:00
2010-05-28 13:02:52 +00:00
en: Then I made myself the following reflexion:
fr: Puis, je me suis fait la réflexion suivante :
en: Considering Tree Edit Distance, each unitary transformation of tree correspond to a simple search and replace on my <sc>xml</sc> source[^nb].
en: We consider three atomic transformations on trees:
fr: Dans les distances d'éditions sur les arbres, chaque opération atomique correspond à un simple *search and replace* sur mon fichier <sc>xml</sc> source[^nb].
fr: On considère trois opérations atomiques sur les arbres :
2010-05-28 12:33:04 +00:00
2010-05-28 13:02:52 +00:00
en: - *substitution*: renaming a node
en: - *insertion*: adding a node
en: - *deletion*: remove a node
fr: - *substitution*: renommer un nœud
fr: - *insertion*: ajouter un nœud
fr: - *délétion*: supprimer un nœud
2010-05-28 12:33:04 +00:00
2010-05-28 13:02:52 +00:00
en: [^nb]: I did a program which generate automatically the weight in a matrix of each edit distance from data.
fr: [^nb]: J'ai programmé un outil qui calcule automatiquement le poids de chaque élément des matrices d'édition à partir de données.
2010-05-28 12:33:04 +00:00
2010-05-28 13:02:52 +00:00
en: One of the particularity of atomic transformations on trees, is ; if you remove a node, all children of this node, became children of its father.
fr: Une des particularité avec les transformations sur les arbres est celle-ci :
fr: supprimer un nœud et tous ses enfants deviendront les enfants du père de ce nœud.
en: An example:
fr: Un exemple:
2010-05-28 12:33:04 +00:00
<pre class="twilight">
r - x - a
\ \
\ b
y - c
</pre>
2010-05-28 13:02:52 +00:00
en: If you delete the `x` node, you obtain
fr: Si vous supprimez le nœud `x`, vous obtenez
2010-05-28 12:33:04 +00:00
<pre class="twilight">
a
/
r - b
\
y - c
</pre>
2010-09-21 11:04:53 +00:00
en: And look at what it implies when you write it in <sc>xml</sc>:
fr: Et regardez ce que ça implique quand on l'écrit en <sc>xml</sc> :
2010-05-28 12:33:04 +00:00
<code class="xml">
<r>
<x>
<a>value for a</a>
2010-05-31 19:30:23 +00:00
<b>value for b</b>
2010-05-28 12:33:04 +00:00
</x>
<y>
<c>value for c</c>
</y>
</r>
</code>
2010-05-28 13:02:52 +00:00
en: Then deleting all `x` nodes is equivalent to pass the <sc>xml</sc> via the following search and replace script:
fr: Alors supprimer tous les nœuds `x` revient à faire passer le <sc>xml</sc> à travers le filtre suivant :
2010-05-26 14:46:40 +00:00
2010-05-27 14:57:29 +00:00
<code class="perl">
2010-05-28 12:33:04 +00:00
s/<\/?x>//g
2010-05-26 14:46:40 +00:00
</code>
2010-05-28 13:02:52 +00:00
en: Therefore, if there exists a one state deterministic transducer which transform my trees ;
en: I can transform the <sc>xml</sc> from one format to another with just a simple list of search and replace directives.
fr: Par conséquent, s'il existe un transducteur déterministe à un état qui permet de transformer mes arbres ;
fr: je suis capable de transformer le <sc>xml</sc> d'un format à l'autre en utilisant une simple liste de *search and replace*.
2010-05-27 14:57:29 +00:00
# Solution
2010-05-28 13:02:52 +00:00
en: Transform this tree:
fr: Transformer cet arbre :
2010-05-27 14:57:29 +00:00
2010-05-28 10:12:46 +00:00
<pre class="twilight">
2010-05-27 14:57:29 +00:00
R - C - tag1
2010-05-28 10:12:46 +00:00
\ \
\ tag2
E -- R - C - tag1
\ \ \
\ \ tag2
\ E ...
R - C - tag1
\ \
\ tag2
E ...
2010-05-27 14:57:29 +00:00
</pre>
2010-05-28 13:02:52 +00:00
en: to this tree:
fr: en celui-ci :
2010-05-27 14:57:29 +00:00
2010-05-28 10:12:46 +00:00
<pre class="twilight">
2010-05-27 14:57:29 +00:00
tag1
/
2010-05-28 10:12:46 +00:00
M - V - M - V - tag2 tag1
\ /
M --- V - tag2
\ \
\ M
2010-05-27 14:57:29 +00:00
\ tag1
\ /
V - tag2
\
M
2010-05-28 10:12:46 +00:00
</pre>
2010-05-27 14:57:29 +00:00
2010-05-28 13:02:52 +00:00
en: can be done using the following one state deterministic tree transducer:
fr: peut-être fait en utilisant le transducteur déterministe à un état suivant:
2010-05-27 14:57:29 +00:00
2010-05-28 10:12:46 +00:00
> C -> &epsilon;
2010-05-31 19:47:10 +00:00
> E -> M
2010-05-28 10:12:46 +00:00
> R -> V
2010-05-28 13:02:52 +00:00
en: Wich can be traduced by the following simple search and replace directives:
fr: Ce qui peut-être traduit par les simples directives Perl suivantes :
2010-05-28 10:12:46 +00:00
<code class="perl">
s/C//g
s/E/M/g
s/R/V/g
</code>
2010-05-28 13:02:52 +00:00
en: Once adapted to <sc>xml</sc> it becomes:
fr: Une fois adapté au <sc>xml</sc> cela devient :
2010-05-28 10:12:46 +00:00
<code class="perl">
2010-05-28 12:33:04 +00:00
s%</?contenu>%%g
s%<enfant>%<item name="menu">%g
2010-05-31 19:52:41 +00:00
s%</enfant>%</item>%g
2010-05-31 19:54:55 +00:00
s%<rubrique>%<value>%g
2010-05-28 12:33:04 +00:00
s%</rubrique>%</value>%g
2010-05-28 10:12:46 +00:00
</code>
2010-05-27 14:57:29 +00:00
2010-05-28 13:02:52 +00:00
en: That is all.
fr: Et c'est tout.
2010-05-27 14:57:29 +00:00
2010-05-28 13:02:52 +00:00
# Conclusion
2010-05-28 13:02:52 +00:00
en: It should seems a bit paradoxal, but sometimes the most efficient approach to a pragmatic problem is to use the theoretical methodology.
fr: Même si cela peut sembler paradoxal, parfois la solution la plus efficace à un problème pragmatique est d'utiliser une méthodologie théorique.