scratch/output/Scratch/en/blog/2010-05-24-Trees--Pragmatism-and-Formalism/index.html

464 lines
26 KiB
HTML
Raw Normal View History

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="keywords" content="tree, theory, mathematics, regexp, script">
<link rel="shortcut icon" type="image/x-icon" href="/Scratch/img/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/Scratch/assets/css/main.css" />
<link rel="stylesheet" type="text/css" href="/Scratch/css/twilight.css" />
<link rel="stylesheet" type="text/css" href="/Scratch/css/idc.css" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://feeds.feedburner.com/yannespositocomen"/>
<link rel="alternate" lang="fr" xml:lang="fr" title="Arbres ; Pragmatisme et Formalisme" type="text/html" hreflang="fr" href="/Scratch/fr/blog/2010-05-24-Trees--Pragmatism-and-Formalism/" />
<link rel="alternate" lang="en" xml:lang="en" title="Trees; Pragmatism and Formalism" type="text/html" hreflang="en" href="/Scratch/en/blog/2010-05-24-Trees--Pragmatism-and-Formalism/" />
<script type="text/javascript" src="/Scratch/js/jquery-1.3.1.min.js"></script>
<script type="text/javascript" src="/Scratch/js/jquery.cookie.js"></script>
<script type="text/javascript" src="/Scratch/js/index.js"></script>
<title>Trees; Pragmatism and Formalism</title>
</head>
<body lang="en">
<script type="text/javascript">// <![CDATA[
document.write('<div id="blackpage"><img src="/Scratch/img/loading.gif" alt="loading..."/></div>');
// ]]>
</script>
<div id="content">
<div id="choix">
<div class="return"><a href="#entete">&darr; Menu &darr;</a></div>
<div id="choixlang">
2010-09-10 07:57:27 +00:00
<a href="/Scratch/fr/blog/2010-05-24-Trees--Pragmatism-and-Formalism/" onclick="setLanguage('fr')">en Français</a>
</div>
</div>
2010-09-27 18:49:15 +00:00
<img src="/Scratch/img/presentation.png" alt="Presentation drawing"/>
<div id="titre">
<h1>
Trees; Pragmatism and Formalism
</h1>
<h2>
When theory is more efficient than practice
</h2>
</div>
<div class="flush"></div>
<div class="flush"></div>
<div id="afterheader">
<div class="corps">
<div class="intro">
<p><abbr title="Too Long; Don't Read"><span class="sc">tl;dr</span></abbr>: </p>
<ul>
<li>I tried to program a simple filter</li>
<li>Was blocked 2 days</li>
<li>Then stopped working like an engineer monkey</li>
<li>Used a pen and a sheet of paper</li>
<li>Made some math.</li>
<li>Crushed the problem in 10 minutes</li>
<li>Conclusion: The pragmatism shouldn&rsquo;t mean &ldquo;never use theory&rdquo;.</li>
</ul>
</div>
<h2 id="abstract-longer-than-abbr-titletoo-long-dont-readsctldrscabbr">Abstract (longer than <abbr title="Too Long; Don't Read"><span class="sc">tl;dr</span></abbr>)</h2>
<p>For my job, I needed to resolve a problem. It first seems not too hard.
Then I started working directly on my program.
I entered in the <em>infernal</em>: <em>try &amp; repair loop</em>.
Each step was like:</p>
<blockquote>
<p>&ndash; Just this thing to repair and that should be done.<br />
&ndash; OK, now that should just work.<br />
&ndash; Yeah!!!<br />
&ndash; Oops! I forgotten that&hellip;<br />
<code>repeat until death</code></p>
</blockquote>
<p>After two days of this <a href="http://fr.wikipedia.org/wiki/Sisyphe">Sisyphus</a> work, I finally just stopped to rethink the problem.
I took a pen, a sheet of paper. I simplified the problem, reminded what I learned during my Ph.D. about trees.
Finally, the problem was crushed in less than 20 minutes.</p>
<p>I believe the important lesson is to remember that the most efficient methodology to resolve this <em>pragmatic</em> problem was the <em>theoretical</em> one.
And therefore, argues opposing science, theory to pragmatism and efficiency are fallacies.</p>
</div>
<div class="corps">
<h1 class="first" id="first-my-experience">First: my experience</h1>
<p>Apparently 90% of programmer are unable to program a binary search without bug.
The algorithm is well known and easy to understand.
However it is difficult to program it without any flaw.
I participated to <a href="http://reprog.wordpress.com/2010/04/19/are-you-one-of-the-10-percent/">this contest</a>.
And you can see the <a href="http://reprog.wordpress.com/2010/04/21/binary-search-redux-part-1/">results here</a><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.
I had to face a problem of the same kind at my job. The problem was simple to the start. Simply transform an <span class="sc">xml</span> from one format to another.</p>
<p>The source <span class="sc">xml</span> was in the following general format:</p>
<pre class="twilight">
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">rubrique</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">contenu</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">tag1</span><span class="MetaTagAll">&gt;</span></span>value1<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">tag1</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">tag2</span><span class="MetaTagAll">&gt;</span></span>value2<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">tag2</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">contenu</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">enfant</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">rubrique</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">rubrique</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">rubrique</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">rubrique</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">enfant</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">menu</span><span class="MetaTagAll">&gt;</span></span>
</pre>
<p>and the destination format was in the following general format:</p>
<pre class="twilight">
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">item</span> <span class="MetaTagAll">name</span>=<span class="String"><span class="String">&quot;</span>Menu0<span class="String">&quot;</span></span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">item</span> <span class="MetaTagAll">name</span>=<span class="String"><span class="String">&quot;</span>menu<span class="String">&quot;</span></span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">item</span> <span class="MetaTagAll">name</span>=<span class="String"><span class="String">&quot;</span>tag1<span class="String">&quot;</span></span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>value1<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">item</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">item</span> <span class="MetaTagAll">name</span>=<span class="String"><span class="String">&quot;</span>tag2<span class="String">&quot;</span></span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>value2<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">item</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">item</span> <span class="MetaTagAll">name</span>=<span class="String"><span class="String">&quot;</span>menu<span class="String">&quot;</span></span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
...
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">item</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">item</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">value</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">item</span><span class="MetaTagAll">&gt;</span></span>
</pre>
<p>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:</p>
<ol>
<li>do not use <span class="sc">xslt</span></li>
<li>avoid the use of an <span class="sc">xml</span> parser</li>
<li>resolve the problem using a simple perl script[^2]</li>
</ol>
<p>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.
I can tell that, because it&rsquo;s what I&rsquo;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.</p>
<p>Why after two days did I was unable to resolve this problem which seems so simple?</p>
<p>What was my behaviour (workflow)?</p>
<ol>
<li>Think</li>
<li>Write the program</li>
<li>Try the program </li>
<li>Verify the result</li>
<li>Found a bug</li>
<li>Resolve the bug</li>
<li>Go to step 3.</li>
</ol>
<p>This was a <em>standard</em> workflow for computer engineer. The flaw came from the first step.
I thought about how to resolve the problem but with the eyes of a <em>pragmatic engineer</em>. I was saying:</p>
<blockquote>
<p>That should be a simple perl search and replace program.<br />
Let&rsquo;s begin to write code</p>
</blockquote>
<p>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.</p>
<h2 id="think">Think</h2>
<p>After some times, I just stopped to work. Tell myself <em>&ldquo;it is enough, now, I must finish it!&rdquo;</em>.
I took a sheet of paper, a pen and began to draw some trees.</p>
<p>I began by make by removing most of the verbosity.
I first renamed <code>&lt;item name=&quot;Menu&quot;&gt;</code> by simpler name <code>M</code> for example.
I obtained something like:</p>
<p><img alt="The source tree" src="/Scratch/en/blog/2010-05-24-Trees--Pragmatism-and-Formalism/graph/The_source_tree.png" /></p>
<p>and</p>
<p><img alt="The destination tree" src="/Scratch/en/blog/2010-05-24-Trees--Pragmatism-and-Formalism/graph/The_destination_tree.png" /></p>
<p>Then I made myself the following reflexion:</p>
<p>Considering Tree Edit Distance, each unitary transformation of tree correspond to a simple search and replace on my <span class="sc">xml</span> source<sup id="fnref:nb"><a href="#fn:nb" rel="footnote">2</a></sup>.
We consider three atomic transformations on trees:</p>
<ul>
<li><em>substitution</em>: renaming a node</li>
<li><em>insertion</em>: adding a node</li>
<li><em>deletion</em>: remove a node</li>
</ul>
<p>One of the particularity of atomic transformations on trees, is&nbsp;; if you remove a node, all children of this node, became children of its father.</p>
<p>An example:</p>
<pre class="twilight">
r - x - a
\ \
\ b
y - c
</pre>
<p>If you delete the <code>x</code> node, you obtain</p>
<pre class="twilight">
a
/
r - b
\
y - c
</pre>
2010-09-21 20:27:27 +00:00
<p>And look at what it implies when you write it in <span class="sc">xml</span>:</p>
<pre class="twilight">
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">r</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">x</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">a</span><span class="MetaTagAll">&gt;</span></span>value for a<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">a</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">b</span><span class="MetaTagAll">&gt;</span></span>value for b<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">b</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">x</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">y</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;</span><span class="MetaTagAll">c</span><span class="MetaTagAll">&gt;</span></span>value for c<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">c</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">y</span><span class="MetaTagAll">&gt;</span></span>
<span class="MetaTagAll"><span class="MetaTagAll">&lt;/</span><span class="MetaTagAll">r</span><span class="MetaTagAll">&gt;</span></span>
</pre>
<p>Then deleting all <code>x</code> nodes is equivalent to pass the <span class="sc">xml</span> via the following search and replace script:</p>
<pre class="twilight">
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>/</span>&lt;<span class="StringRegexpSpecial">\/</span>?x&gt;</span><span class="StringRegexp"><span class="StringRegexp">/</span><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
</pre>
<p>Therefore, if there exists a one state deterministic transducer which transform my trees&nbsp;;
I can transform the <span class="sc">xml</span> from one format to another with just a simple list of search and replace directives.</p>
<h1 id="solution">Solution</h1>
<p>Transform this tree:</p>
<pre class="twilight">
R - C - tag1
\ \
\ tag2
E -- R - C - tag1
\ \ \
\ \ tag2
\ E ...
R - C - tag1
\ \
\ tag2
E ...
</pre>
<p>to this tree:</p>
<pre class="twilight">
tag1
/
M - V - M - V - tag2 tag1
\ /
M --- V - tag2
\ \
\ M
\ tag1
\ /
V - tag2
\
M
</pre>
<p>can be done using the following one state deterministic tree transducer:</p>
<blockquote>
<p>C &rarr; &epsilon;<br />
E &rarr; M<br />
R &rarr; V </p>
</blockquote>
<p>Wich can be traduced by the following simple search and replace directives: </p>
<pre class="twilight">
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>/</span>C</span><span class="StringRegexp"><span class="StringRegexp">/</span><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>/</span>E</span><span class="StringRegexp"><span class="StringRegexp">/</span>M<span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>/</span>R</span><span class="StringRegexp"><span class="StringRegexp">/</span>V<span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
</pre>
<p>Once adapted to <span class="sc">xml</span> it becomes:</p>
<pre class="twilight">
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>%</span>&lt;/?contenu&gt;</span><span class="StringRegexp"><span class="StringRegexp">%</span><span class="StringRegexp">%</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>%</span>&lt;enfant&gt;</span><span class="StringRegexp"><span class="StringRegexp">%</span>&lt;item name=&quot;menu&quot;&gt;<span class="StringRegexp">%</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>%</span>&lt;/enfant&gt;</span><span class="StringRegexp"><span class="StringRegexp">%</span>&lt;/item&gt;<span class="StringRegexp">%</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>%</span>&lt;rubrique&gt;</span><span class="StringRegexp"><span class="StringRegexp">%</span>&lt;value&gt;<span class="StringRegexp">%</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
<span class="StringRegexp"><span class="StringRegexp"><span class="SupportFunction">s</span>%</span>&lt;/rubrique&gt;</span><span class="StringRegexp"><span class="StringRegexp">%</span>&lt;/value&gt;<span class="StringRegexp">%</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="Keyword">g</span></span></span>
</pre>
<p>That is all.</p>
<h1 id="conclusion">Conclusion</h1>
<p>It should seems a bit paradoxal, but sometimes the most efficient approach to a pragmatic problem is to use the theoretical methodology.</p>
<hr/><div class="footnotes">
<ol>
<li id="fn:1">
<p>Hopefully I am in the 10% who had given a bug free implementation.<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>
<li id="fn:nb">
<p>I did a program which generate automatically the weight in a matrix of each edit distance from data.<a href="#fnref:nb" rev="footnote">&#8617;</a></p>
</li>
</ol>
</div>
</div>
<div id="choixrss">
<a id="rss" href="http://feeds.feedburner.com/yannespositocomen">
Subscribe
</a>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#comment').hide();
$('#clickcomment').click(showComments);
});
function showComments() {
$('#comment').show();
$('#clickcomment').fadeOut();
}
document.write('<div id="clickcomment">Comments</div>');
</script>
<div class="flush"></div>
<div class="corps" id="comment">
<h2 class="first">comments</h2>
<noscript>
Vous devez activer javascript pour commenter.
</noscript>
<script type="text/javascript">
var idcomments_acct = 'a307f0044511ff1b5cfca573fc0a52e7';
var idcomments_post_id = '/Scratch/en/blog/2010-05-24-Trees--Pragmatism-and-Formalism/';
var idcomments_post_url = 'http://yannesposito.com/Scratch/en/blog/2010-05-24-Trees--Pragmatism-and-Formalism/';
</script>
<span id="IDCommentsPostTitle" style="display:none"></span>
<script type='text/javascript' src='/Scratch/js/genericCommentWrapperV2.js'></script>
</div>
<div id="entete" class="corps_spaced">
<div id="liens">
<ul><li><a href="/Scratch/en/">Homepage</a></li>
<li><a href="/Scratch/en/blog/">Blog</a></li>
<li><a href="/Scratch/en/about/">About</a></li>
<li><a href="/Scratch/en/contact/">Contact</a></li></ul>
</div>
<div class="flush"></div>
<hr/>
<div id="next_before_articles">
<div id="previous_articles">
previous entries
<div class="previous_article">
<a href="/Scratch/en/blog/2010-05-19-How-to-cut-HTML-and-repair-it/">&larr; How to repair a cutted XML?</a>
</div>
<div class="previous_article">
<a href="/Scratch/en/blog/2010-05-17-at-least-this-blog-revive/">&larr; I live again!</a>
</div>
<div class="previous_article">
<a href="/Scratch/en/blog/2010-03-23-Encapsulate-git/">&larr; Encapsulate git</a>
</div>
</div>
<div id="next_articles">
next entries
<div class="next_article">
<a href="/Scratch/en/blog/2010-06-14-multi-language-choices/">multi language choices&rarr; </a>
</div>
<div class="next_article">
<a href="/Scratch/en/blog/2010-06-15-Get-my-blog-engine/">Get my blog engine&rarr; </a>
</div>
<div class="next_article">
<a href="/Scratch/en/blog/2010-06-17-track-events-with-google-analytics/">Track Events with Google Analytics&rarr; </a>
</div>
</div>
<div class="flush"></div>
</div>
</div>
<div id="bottom">
<div>
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Copyright ©, Yann Esposito</a>
</div>
<div id="lastmod">
2010-08-31 13:06:43 +00:00
Created: 05/24/2010
2010-09-23 10:17:16 +00:00
Modified: 09/21/2010
</div>
<div>
Entirely done with
<a href="http://www.vim.org">Vim</a>
and
<a href="http://nanoc.stoneship.org">nanoc</a>
</div>
<div>
<a href="/Scratch/en/validation/">Validation</a>
<a href="http://validator.w3.org/check?uri=referer"> [xhtml] </a>
.
<a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3"> [css] </a>
.
<a href="http://validator.w3.org/feed/check.cgi?url=http%3A//yannesposito.com/Scratch/en/blog/feed/feed.xml">[rss]</a>
</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>