• Aucun résultat trouvé

2.3 Une introduction à l’assistant à la preuve C OQ

2.3.3 Les théorèmes et les preuves

Pour déclarer une proposition comme étant vraie, nous devons produire une preuve. Une preuve se fait par l’application d’un ensemble de tactiques. Une tactique appliquée à un certain but le transforme en un ensemble de sous-buts tel que la preuve de ces sous-buts suffit pour prouver le but.

Un théorème intéressant et simple à démontrer est inter_intro qui indique que si un élément appartient à un ensemble s et à un ensemble s0, alors ce même élément appartient à l’intersection des deux ensembles. Pour exprimer ce théorème, nous avons besoin d’une définition pour la fonction d’appartenance à un ensemble. La fonction In est définie dans COQcomme suit :

D e f i n i t i o n In ( s : u n i s e t ) ( a :A) : Prop := c h a r a c s a = t r u e .

25http://coq.inria.fr/V8.4/stdlib/Coq.Init.Datatypes.html#andb

Concepts

Nous déclarons une notation pour la fonction In avec le symbole∈: Notation " x ∈ vs " := ( In vs x ) (a t l e v e l 1 0 0 ) .

Ceci est décrit à l’aide du théorème inter_intro. La preuve est la séquence de tactiques décrites entre Proof et Qed (nous pouvons remplacer Qed par Defined, la différence est que dans le cas de Defined, la définition de la fonction peut être explicitée et utilisée avec les tactiques de conversion).

Lemma i n t e r _ i n t r o : f o r a l l v ( s s ’ : u n i s e t typ ) , v ∈ s −> v ∈ s ’ −> v ∈ ( s ∩ s ’ ) . Proof. i n t r o s v s s ’ Hs Hs ’ . unfold i n t e r . unfold In in * ; simpl in * . r e w r i t e Hs ; r e w r i t e Hs ’ ; simpl in * . r e f l e x i v i t y. Qed.

Le théorème en notation règle d’inférence est le suivant : (v ∈ s) (v ∈ s0)

(v ∈ (s ∩ s0)) inter_intro

Nous essayons dans ce qui suit de détailler cette preuve pour donner une idée de la dé- marche de preuve en utilisant COQ. Nous commençons par la définition du théorème, dans notre cas nous utilisons le mot clé Lemma, nous pouvons utiliser d’une manière similaire les mots clé Theorem, Fact ou Remark.

Lemma i n t e r _ i n t r o :

f o r a l l v ( s s ’ : u n i s e t typ ) , ( v ∈ s ) −> ( v ∈ s ’ ) −> ( v ∈ ( s ∩ s ’ ) ) .

Une fois cette dernière définition évaluée, le mode preuve est automatiquement déclenché. La commande Proof (éventuelle et introduite dans un but de faciliter la lecture des scripts de preuves) annonce le début du mode preuve. Le nombre de sous-buts restant à prouver, le contexte (les hypothèses) ainsi que les sous-buts à prouver sont affichés. Les hypothèses sont nommées et représentées sur la partie supérieure séparée par une ligne de double traits du sous-but courant. Ici typ et eq_dec sont les hypothèses définies dans la même section.

1 subgoal typ : Set

eq_dec : d e c i d a b l e typ

============================

f o r a l l ( v : typ ) ( s s ’ : u n i s e t typ ) , ( v ∈ s ) → ( v ∈ s ’ ) → ( v ∈ s ∩ s ’ )

Des nouvelles commandes sont disponibles dans ce mode, comme par exemple les tactiques qui sont des combinaisons de preuves primitives. Une tactique agit sur le contexte et le sous-but courant pour essayer de le résoudre. La tactique intro correspond à la règle de l’introduction du f orall et de l’implication. La tactique peut prendre en paramètre un nom qui sera associé à la nouvelle hypothèse. Nous utilisons une version spéciale de cette tac- tique appelée intros qui prend en paramètres plusieurs noms d’hypothèses à introduire, elle est équivalente à plusieurs applications de la tactique intro. Dans le cas d’absence de paramètres intros introduit toutes les hypothèses possibles avec des noms choisis par

2.3. Une introduction à l'assistant à la preuve COQ

un algorithme de nommage interne au système jusqu’à obtention d’un sous-but atomique (échec de la tactique intro).

i n t r o s v s s ’ Hs Hs ’ .

La tactique intros appliquée au sous-but précédent remonte v, s et s0 et les deux hypo- thèses Hs et Hs0 et permet de transformer le sous-but ainsi :

1 subgoal typ : Set eq_dec : d e c i d a b l e typ v : typ s : u n i s e t typ s ’ : u n i s e t typ Hs : v ∈ s Hs ’ : v ∈ s ’ ============================ v ∈ s ∩ s ’

Nous avons besoin à ce niveau de déplier les définitions de l’inclusion et l’intersection. Nous commençons à titre d’exemple par la fonction d’intersection. Nous appliquons la tactique unfold qui permet de déplier la définition de son paramètre qui doit être une constante transparente. Une constante est transparente si nous avons accès à son type et son algo- rithme de calcul (tous les détails sont importants), dans ce cas, elle est complètement définie avec Definition ou sa preuve est terminée par Defined. La tactique unfold permet de remplacer chaque occurrence de son paramètre dans le but par sa forme normale.

unfold i n t e r .

L’application de la tactiques unfold avec comme paramètre la fonction ∩ transforme le sous-but ainsi : 1 subgoal typ : Set eq_dec : d e c i d a b l e typ v : typ s : u n i s e t typ s ’ : u n i s e t typ Hs : v ∈ s Hs ’ : v ∈ s ’ ============================

v ∈ Charac (fun v0 : typ => c h a r a c s v0 && c h a r a c s ’ v0 )

La syntaxe du langage de commandes de COQ permet la composition de tactiques. Par exemple, si tac1et tac2sont deux tactiques, la séquence tac1; tac2applique la tactique tac1au

but courant et tac2à chacun de ses sous-buts. Il est possible aussi d’enchainer plusieurs tac-

tiques en suivant le même principe. Ici nous invoquons encore une fois la tactique unfold pour déplier la définition de∈, par la suite la tactique simpl est invoquée pour effectuer des simplifications sur toutes les hypothèses et les sous-buts résultants.

unfold In in * ; simpl in * .

Concepts

Le contexte et le sous-but courant sont transformés ainsi :

1 subgoal typ : Set eq_dec : d e c i d a b l e typ v : typ s : u n i s e t typ s ’ : u n i s e t typ Hs : c h a r a c s v = t r u e Hs ’ : c h a r a c s ’ v = t r u e ============================ c h a r a c s v && c h a r a c s ’ v = t r u e

Nous utilisons la tactique rewrite pour replacer charac s v et charac s' v par leur correspondant dans les hypothèses Hs et Hs'.

r e w r i t e Hs ; r e w r i t e Hs ’ .

L’application de la séquence de tactiques transforme les hypothèses ainsi que le but courant comme suit :

1 subgoal typ : Set

eq_dec : d e c i d a b l e typ v : typ

CharacS : typ → bool

CharacS ’ : typ → bool Hs : CharacS v = t r u e Hs ’ : CharacS ’ v = t r u e

============================

t r u e && t r u e = t r u e

La tactique reflexivity essaye d’appliquer la règle de ré exivité sur le sous-but courant. r e f l e x i v i t y.

Cette dernière tactique permet de réussir la preuve et l’espéré Proof completed est affi- ché.

Proof completed .

Cette preuve n’est pas optimisée, par exemple l’utilisation de la tactique intuition permet de conclure la preuve juste après le dépliage des fonctions∪et∈.

Les définitions COQ peuvent être enregistrées dans des fichiers avec l’extension .v, ces fichiers peuvent être compilés avec la commande coqc et par la suite importés pour pouvoir utiliser les définitions qu’ils contiennent par la commande Require Import (aussi utilisée pour importer les bibliothèques standards de COQ). Nous pouvons aussi extraire du code fonctionnel vérifié dans le langage ML [MTHM97], Haskell26ou Lisp [McC60].