Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2017-01-03T18:27:38+01:00Les derniers messages parus sur le forum de Zeste de Savoir.Problème avec un dependent pattern matching, message #1373502017-01-03T18:27:38+01:00lthms/@lthmshttps://zestedesavoir.com/forums/sujet/7694/probleme-avec-un-dependent-pattern-matching/?page=1#p137350<p>Bonjour à tous !</p>
<p>Il y a un petit moment déjà, j’avais écrit un article sur <a href="http://leth.io/blog/strongly-specified-functions">le typage fort de Coq</a>. Ayant depuis pris un peu de bouteille, je me suis dis que j’allais faire une nouvelle version un peu plus poussée en utilisant notamment le <code>Program</code> des dernières versions de Coq, comme on me l’avait conseillé à l’époque.</p>
<div class="warning ico-after">
<p>Le gist fonctionne avec coq 8.6, sa première révision avec coq 8.5</p>
</div>
<p>J’ai presque réussi à faire tout ce que je voulais et le code complet peut être trouvé dans <a href="https://gist.github.com/lethom/8d76dddecb8b343a9e7592764d42fa87">le gist suivant</a>.</p>
<p>En gros, je reprends l’exemple mille fois cité des vecteurs normés, mais j’essaie d’aller plus loin que les exemples que je peux trouver sur Internet en ce qui concerne le type de retour des fonctions.</p>
<p>J’arrive à faire des choses plutôt cools (de mon point de vue), pour des fonctions comme <code>take</code>, <code>drop</code>, etc. :</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="c">(* un exemple au hasard *)</span>
<span class="n">Program</span> <span class="kn">Fixpoint</span> <span class="n">drop</span>
<span class="o">{</span><span class="n">A</span><span class="o">:</span> <span class="kt">Type</span><span class="o">}</span>
<span class="o">{</span><span class="n">n</span><span class="o">:</span> <span class="kt">nat</span><span class="o">}</span>
<span class="o">(</span><span class="n">v</span><span class="o">:</span> <span class="n">vector</span> <span class="n">A</span> <span class="n">n</span><span class="o">)</span>
<span class="o">(</span><span class="n">b</span><span class="o">:</span> <span class="kt">nat</span><span class="o">)</span>
<span class="o">(</span><span class="n">Hbound</span><span class="o">:</span> <span class="n">b</span> <span class="o"><=</span> <span class="n">n</span><span class="o">)</span>
<span class="o">:</span> <span class="o">{</span> <span class="n">v'</span><span class="o">:</span> <span class="n">vector</span> <span class="n">A</span> <span class="o">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">b</span><span class="o">)</span> <span class="o">|</span> <span class="k">forall</span> <span class="n">i</span><span class="o">,</span> <span class="n">i</span> <span class="o"><</span> <span class="n">n</span> <span class="o">-</span> <span class="n">b</span> <span class="o">-></span> <span class="n">nth</span> <span class="n">v'</span> <span class="n">i</span> <span class="o">=</span> <span class="n">nth</span> <span class="n">v</span> <span class="o">(</span><span class="n">b</span> <span class="o">+</span> <span class="n">i</span><span class="o">)</span> <span class="o">}</span>
</pre></div>
</td></tr></table></div>
<p>Avec <code>extract</code>, j’arrive à peu près à tirer parti de la composition de ces fonctions, c’est encore mieux !</p>
<p>Par contre, pour une fonction de type <code>zip</code>, je bloque… je suis obligé de passer par une définition <em>via</em> des tactics, ce qui donne une extraction dégueulasse !</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="c">(* TODO: do not rely on tactics for this *)</span>
<span class="n">Program</span> <span class="kn">Fixpoint</span> <span class="n">zip</span>
<span class="o">{</span><span class="n">A</span> <span class="n">B</span> <span class="n">C</span><span class="o">:</span> <span class="kt">Type</span><span class="o">}</span>
<span class="o">{</span><span class="n">n</span><span class="o">:</span> <span class="kt">nat</span><span class="o">}</span>
<span class="o">(</span><span class="n">v</span><span class="o">:</span> <span class="n">vector</span> <span class="n">A</span> <span class="n">n</span><span class="o">)</span>
<span class="o">(</span><span class="n">v'</span><span class="o">:</span> <span class="n">vector</span> <span class="n">B</span> <span class="n">n</span><span class="o">)</span>
<span class="o">(</span><span class="n">f</span><span class="o">:</span> <span class="n">A</span> <span class="o">-></span> <span class="n">B</span> <span class="o">-></span> <span class="n">C</span><span class="o">)</span>
<span class="o">:</span> <span class="o">{</span> <span class="n">v''</span><span class="o">:</span> <span class="n">vector</span> <span class="n">C</span> <span class="n">n</span> <span class="o">|</span> <span class="k">forall</span> <span class="n">i</span><span class="o">,</span> <span class="n">nth</span> <span class="n">v''</span> <span class="n">i</span> <span class="o">=</span> <span class="n">option_app</span> <span class="o">(</span><span class="n">option_map</span> <span class="n">f</span> <span class="o">(</span><span class="n">nth</span> <span class="n">v</span> <span class="n">i</span><span class="o">))</span> <span class="o">(</span><span class="n">nth</span> <span class="n">v'</span> <span class="n">i</span><span class="o">)</span> <span class="o">}</span> <span class="o">:=</span> <span class="o">_.</span>
<span class="n">Next</span> <span class="n">Obligation</span><span class="o">.</span>
<span class="n">dependent</span> <span class="k">induction</span> <span class="n">v</span><span class="o">;</span> <span class="n">dependent</span> <span class="k">induction</span> <span class="n">v'</span><span class="o">.</span>
<span class="o">+</span> <span class="n">remember</span> <span class="o">(</span><span class="n">IHv</span> <span class="n">v'</span> <span class="n">f</span><span class="o">)</span> <span class="k">as</span> <span class="n">v''</span><span class="o">.</span>
<span class="k">inversion</span> <span class="n">v''</span><span class="o">.</span>
<span class="k">refine</span> <span class="o">(</span><span class="n">exist</span> <span class="o">_</span> <span class="o">(</span><span class="n">vcons</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span> <span class="n">a0</span><span class="o">)</span> <span class="n">x</span><span class="o">)</span> <span class="o">_).</span>
<span class="k">intros</span> <span class="n">i</span><span class="o">.</span>
<span class="k">induction</span> <span class="n">i</span><span class="o">.</span>
<span class="o">*</span> <span class="k">cbv</span><span class="o">.</span>
<span class="kp">reflexivity</span><span class="o">.</span>
<span class="o">*</span> <span class="k">simpl</span><span class="o">.</span>
<span class="k">apply</span> <span class="o">(</span><span class="n">H</span> <span class="n">i</span><span class="o">).</span>
<span class="o">+</span> <span class="k">refine</span> <span class="o">(</span><span class="n">exist</span> <span class="o">_</span> <span class="n">vnil</span> <span class="o">_).</span>
<span class="k">cbv</span><span class="o">.</span>
<span class="kp">reflexivity</span><span class="o">.</span>
<span class="kn">Qed</span><span class="o">.</span>
</pre></div>
</td></tr></table></div>
<p>À l’origine, l’implémentation promettait pourtant d’être simple, quelque chose du genre :</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">match</span> <span class="n">v</span><span class="o">,</span> <span class="n">v'</span> <span class="k">with</span>
<span class="o">|</span> <span class="n">vcons</span> <span class="n">a</span> <span class="n">v</span><span class="o">,</span> <span class="n">vcons</span> <span class="n">b</span> <span class="n">v'</span> <span class="o">=></span> <span class="n">vcons</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">zip</span> <span class="n">v</span> <span class="n">v'</span> <span class="n">f</span><span class="o">)</span>
<span class="o">|</span> <span class="o">_,</span> <span class="o">_</span> <span class="o">=></span> <span class="n">vnil</span>
<span class="k">end</span><span class="o">.</span>
</pre></div>
</td></tr></table></div>
<p>Mais ça ne marche pas du tout ! Avec <code>Program</code>, je tombe sur une erreur très étrange qui parle de <code>@eq</code>. Sans <code>Program</code>, coq oublie que v et v’ ont la même taille…</p>
<p>Des idées ? Moi, je sèche complètement.</p>
<p>Merci d’avance !</p>