• Aucun résultat trouvé

Un exemple de preuve de simulation : l’addition

4.4 Preuves de simulation

4.4.4 Un exemple de preuve de simulation : l’addition

Nous allons illustrer toutes nos tactiques sur un exemple : la preuve de simulation pour l’addition. Rappelons tout d’abord sa définition :

Version Coq : plus Version mini-ML : plus__extr

(fix plus (n m : nat) : nat := match n with

| 0 => m

| S p => S (plus p m) end)

(TFix (TFun (TMatch (TVar 1) (Patc 0 (TVar 0)

:: Patc 1 (TConstr 1

(TVar 3 @ TVar 0 @ TVar 1 :: nil))

:: nil))))

Compte-tenu de toute l’infrastructure mise en place, voici l’énoncé et la preuve com- plète de simulation :

Lemma plus__simul : simul plus plus__extr. Proof.

unfold plus, plus__extr. ie_hnf. fix IHn 3. intros n n’ Hnn’. ie_simpl. ie_hnf. intros m m’ Hmm’. ie_simpl. pattern n at 1, n’ at 1. ie_destruct_nat Hnn’; ie_simpl. (* O *) ie_easy. (* S *) apply S__simul. ie_apply; ie_easy. Qed.

La preuve commence par déplier les définitions de plus et de plus__extr. Face à une conclusion de la forme simul f f’, où f est une fonction, on utilise la tactique ie_hnf qui se charge de transformer la conclusion afin de la faire commencer par des quanti- fications par variables hermétiques (c’est-à-dire de la forme forall x x’, ie_pred x x’ -> ...), puis on introduit ces variables avec intros, et on réduit autant que pos- sible le terme mini-ML avec ie_simpl (voir section 4.4.2). L’introduction des variables

hermétiques correspondant à l’argument décroissant de plus est précédée d’un appel à la tactique fix, qui indique la construction d’un point fixe dans le terme de preuve. Lorsque le filtrage sur l’argument décroissant arrive en tête de réduction, on procède à une analyse par cas avec pattern et ie_destruct_nat (voir section 4.4.3), puis on réduit le terme mini-ML dans chaque sous-but. Le terme Coq est également réduit en parallèle, implicitement. Le cas O du filtrage revient à prouver simul m m’ en ayant ie_pred m m’ en hypothèse, ce qui se résout en utilisant le lemme ie_compat via la tactique ie_easy. Le cas S revient à prouver (on a replié les définitions de plus et de plus__extr par souci de clarté) :

simul (S (plus n m)) (TConstr 1 (plus__extr @ n’ @ m’ :: nil))

On fait alors disparaître le constructeur de tête avec le lemme S__simul (un lemme similaire est créé au préalable pour chaque constructeur), puis le but est décomposé en deux sous-buts avec ie_apply, un dont la conclusion est :

simul (plus n) (plus__extr @ n’)

qui se résout par un appel (récursif) à l’hypothèse introduite par fix, et un autre dont la conclusion est la même que dans le cas O, et se résout de la même manière.

Ces techniques de preuve fonctionnent au moins pour la fonction d’Ackermann (points fixes imbriqués), la multiplication (utilisant une définition préalable, l’addition), les fonc- tions length et map sur les listes polymorphes, la fonction test1 de la page 86, et même la fonction double de la page 81, qui manipule des sous-termes logiques. Elles ne fonc- tionnent pas avec le pred de la page 81 : plus précisément, la tactique pattern échoue, probablement à cause des types dépendants. Il est néanmoins possible d’achever la preuve manuellement.

4.5 Bilan

4.5.1 Contributions

Dans ce chapitre, nous avons exposé le principe d’une extraction directe à partir de Coq visant un langage entièrement formalisé. Notre langage source est le CIC implanté dans Coq, sans modification ni modélisation. Nous avons réalisé sous la forme d’un greffon une nouvelle commande vernaculaire d’extraction qui génère des termes sous une forme exploitable au niveau logique. Bien que cette extraction ne soit pas elle-même prouvée, nous avons présenté un cadre de certification des programmes extraits au sein du système Coq.

Le travail présenté ici est le résultat de très longues expérimentations. Il s’inspire à l’origine de l’étude sémantique de [33]. Toutefois, P. Letouzey avait réalisé cette étude en faisant notamment les deux hypothèses simplificatrices suivantes concernant CIC : les

4.5 Bilan

promotions entre sortes sont explicites et deux termes mini-ML convertibles sont égaux. Ces deux hypothèses changent significativement CIC. Nous pensons que la première pourrait être implantée au sein de Coq et passer inaperçue pour l’utilisateur en ajoutant une phase d’insertion automatique de transtypages (casts) lors du pré-typage. Nous avons déjà mentionné cette idée comme aide possible pour la résolution du problème du polymorphisme de sortes mentionné à la section 3.4. La seconde hypothèse est encore plus envahissante et revient à intégrer une partie de la sémantique de mini-ML à CIC. Nous avons plutôt choisi de travailler avec Coq sans chercher à changer la théorie sous-jacente. Nous avons proposé une notion de correction des termes extraits à travers une relation de simulation entre des termes Coq et des termes mini-ML. Cette relation repose sur des prédicats dits d’extractibilité reliant les termes Coq à des valeurs mini-ML, prédicats eux-mêmes combinés à une sémantique opérationnelle de mini-ML pour donner une notion s’appliquant à tous les termes mini-ML. Seuls les prédicats d’extractibilité sont spécifiques à chaque type et nécessitent des définitions dédiées. Nous pensons qu’ils peuvent être automatiquement générés pour tous les types ML.

Nous avons également exposé notre approche pour prouver la simulation entre un terme Coq et son extrait. Pour cela, nous reposons sur le système de tactiques. Nous avons présenté une démarche générale pour mener ces preuves, et nous avons défini de nouvelles tactiques pour manipuler les termes mini-ML, et en particulier les réduire. Nous avons cherché à simplifier au maximum ces preuves, dans un but d’automatisation.

Le développement concret fait environ 2 000 lignes de Coq et 300 lignes d’OCaml.