Calcul des prédicats

Ce sujet contient trois parties :

  • La première reprend et approfondit le travail entamé sur le quantificateur universel forall.
  • La seconde introduit le quantificateur existentiel exists, ainsi que les tactiques nécessaires pour utiliser une hypothèse ainsi quantifiée ( destruct comme toujours...) et pour prouver ou introduire une formule du type « il existe ... ».
  • La troisième fait travailler sur les notions importantes de surjectivité et d'injectivité.

Prédicats et connecteur forall

Un prédicat sur un certain type X est une fonction de X vers Prop, donc une proposition qui dépend d'une variable à valeur dans un certain type. Par exemple, on peut définir le prédicat est_pair : nat -> Prop qui est satisfait uniquement par les entiers naturels pairs. On peut donc voir un prédicat comme une certaine propriété des éléments d'un type. Comme premier prédicat très simple, définissons est_nul sur nat.

Bien sûr on prouve facilement que 0 est nul :

On peut même aller plus loin :

Exercice : Prouver le théorème suivant.

N'oubliez pas discriminate H, si H est est une preuve d'un égalité fausse.

On se donne maintenant un type abstrait, noté X (penser, par exemple au type nat) et deux prédicats sur X.

Le quantificateur « pour tout » s'écrit forall ou forall en Coq : forall x : X, P x est la proposition qui dit que pour tout x de type X, la proposition P x est vraie. Avec le point de vue « prédicat », cela signifie qu'une certaine propriété est satisfaite par tous les habitants d'un type.

L'énoncé forall x : X, (P x) est encore une proposition.

La tactique specialize n'est jamais indispensable mais souvent pratique. L'idée est de fournir des arguments à une hypothèse universellement quantifiée de façon à en avoir une version spécialisée. On peut voir specialize comme la tactique qui "utilise le forall". Voyons tout de suite des exemples :

On peut utiliser des "intro patterns" dans la partie "as ..."

Un exemple de tautologie du calcul des prédicats est le suivant.

Exercice : Prouver le théorème suivant.

Il faudrait vraiment connaître et comprendre intuitivement le théorème précédent. En fait, on peut voir le quantificateur forall comme une généralisation du /\. Par exemple, pour un prédicat P : nat -> Prop, dire que forall n : nat, (P n) signifie qu'on a (P 0) /\ (P 1) /\ (P 2) /\ (P 3) /\ ...

Avec la disjonction, en revanche, les choses sont différentes.

Exercice : Prouver le théorème suivant.

Prenez bien le temps de comprendre l'énoncé de façon intuitive avant de commencer la preuve.

La réciproque est-elle vraie ? Non, et c'est très important que vous le compreniez. Dans un premier temps, on peut essayer de voir ce qui bloque dans la preuve.

Exercice : essayer d'avancer dans la preuve du théorème suivant.

Voir où vous êtes bloqué et pourquoi. Laisser Abort. (abandonner) à la fin, le théorème est faux de toute façon.

Dans un second temps, c'est important de se convaincre que c'est faux avec un contre-exemple. Pour le type X, on va prendre nat, pour P, notre prédicat est_nul et pour Q un nouveau prédicat est_non_nul.

La prémisse du faux théorème précédent est bien sûr satisfaite.

Exercice : Prouver le théorème suivant.

Mais sa conclusion est fausse.

Exercice : Prouver le théorème suivant.

Indices :

  • dans le premier cas, vous aurez à trouver une contradiction depuis une hypothèse du type H1 : forall (n : nat), n = 0. Vous pouvez spécialiser cette hypothèse avant d'utiliser discriminate.
  • dans l'autre cas, vous aurez à prouver False en utilisant une hypothèse du type H2 : forall (n : nat), n = 0 -> False. Encore une fois, vous pouvez spécialiser cette hypothèse.

Vous devriez vraiment vous arrêter deux minutes pour bien noter qu'en général il est FAUX que (forall x, (P x \/ Q x)) -> (forall x, P x) \/ (forall x, Q x). et noter le contre-exemple.

Le quantificateur exists

Le quantificateur « il existe » s'écrit exists ou exists dans des mathématiques en Coq. Il se lit « il existe » : exists x : X, P x est la proposition qui dit qu'il y a (au moins) un x de type X tel que la proposition P x est vraie.

Prouver un "il existe" : la tactique exists

En logique intuitionniste, pour prouver une proposition du type « il existe un élément ayant telle propriété », la seule possibilité est d'exhiber un tel élément (appelé témoin). La tactique exists, suivie de ce témoin pressenti permet d'éliminer le quantificateur exists.

Pour montrer qu'il existe n tel que n + 3 = 8, il suffit de montrer que 5 + 3 = 8 (c'est une intuition géniale qui m'a fait penser à 5).

Exercice : Prouver le théorème suivant.

Quelques tautologies (ou non) avec exists.

On se donne de nouveau un type X quelconque et deux prédicats sur X.

La formule exists x, P x est encore de type Prop.

Pour un type habité (c'est-à-dire ayant au moins un élément), on a le résultat très intuitif suivant.

Exercice : Prouver le théorème suivant.

Attention, une erreur très courante en mathématiques (ou même dans la logique de tous les jours) consiste à penser qu'avec un ou quelques exemples (donc des preuves de « il existe »), on montre « pour tout » :

  • Le polynôme X^2 - 4 a des racines réelles donc tous les polynômes en ont.
  • Les entiers impairs 3, 5 et 7 sont premiers donc tous les nombres impairs le sont.
  • Cet étudiant est nul en maths, la preuve, il a eu 3 au dernier contrôle.
  • Beaucoup d'autres exemples sortent constamment de la bouche des dirigeants politiques...

Utiliser un « il existe » : tactique destruct

Pour utiliser une proposition avec exists, on utilise de nouveau la tactique destruct. Noter la syntaxe as [y H], où y est la variable pour laquelle la propriété va être vraie, et H la preuve que cette propriété est vraie pour y.

On peut aussi destruct immédiatement une hypothèse avec un «  intro pattern  ». On remplace intros H2 par intros [y H'] directement.

Exercice : Prouver le théorème suivant.

Le théorème précédent est important et intéressant. Si on y réfléchit, le quantificateur exists est d'une certaine façon une généralisation de la disjonction \/. Par exemple, sur nat, on peut penser à la proposition exists (n : nat), P n comme (P 0) \/ (P 1) \/ (P 2) \/ (P 3) \/ ...

Exercice : Prouver le théorème suivant.

Exercice : essayer d'avancer dans la preuve du théorème suivant.

Voir où vous êtes bloqué et pourquoi. Laisser Abort. (abandonner) à la fin, le théorème est faux de toute façon.

Comme pour la propriété analogue avec forall et \/, nous allons construire un contre-exemple pour montrer qu'il est faux que (exists x : X, P x) /\ (exists y : X, Q y) -> (exists x, P x /\ Q x). On va encore prendre X = nat, P = est_nul et Q = est_non_nul.

La prémisse du faux théorème précédent est satisfaite par nat, est_nul et est_non_nul.

Exercice : Prouver le théorème suivant.

Mais la conclusion est évidemment fausse.

Exercice : Prouver le théorème suivant.

Négation et quantificateurs

Les deux résultats suivants ont une réciproque en logique classique (c'est-à-dire une fois qu'on a ajouté le tiers exclu).

Exercice : Prouver le théorème suivant.

Remarquer la similitude avec l'une des lois de de Morgan :

Le lemme suivant dit en substance qu'un contre-exemple permet de nier une formule universellement quantifiée.

Exercice : Prouver le théorème suivant.

Encore une fois, remarquer la similitude avec :

Fonctions injectives, surjectives, bijectives

On considère maintenant deux types quelconques X et Y.

Une fonction injective de X vers Y est telle que chaque élément y de Y a au plus un antécédent.

Une fonction surjective de X vers Y est telle que chaque élément y de Y a au moins un antécédent.

Voyons tout de suite des exemples :

On va commencer par la fonction S (successeur) et une nouvelle fonction appelée « prédécesseur ».

Cette fonction est définie par un petit programme qui raisonne par cas sur la nullité ou non de son argument.

Les valeurs sont bien celles qu'on attend :

Sauf que c'est une fonction totale, le prédécesseur de 0 est (de façon un peu arbitraire) 0.

Comme il se doit, on définit deux petits lemmes pour ne pas avoir à se reposer entièrement sur simpl.

En fait, le lemme pred_succ est assez fondamental : il dit que la composée des fonctions pred et S est l'identité, autrement dit, que pred est réciproque à gauche de S.

On va maintenant étudier l'injectivité et la surjectivité (ou non) des fonctions S et pred.

Exercice : Prouver le théorème suivant.

Indice : utiliser pred_succ pour réécrire dans le but.

Exercice : Prouver le théorème suivant.

Exercice : Prouver le théorème suivant.

En fait, on peut être plus précis:

Exercice : Prouver le théorème suivant.

Passons à des résultats généraux sur la composition des fonctions