Ce devoir est à rendre sur le dépôt moodle avant le :
dimanche 9 novembre à 23h59
Vous rendrez un seul fichier appelé
DevoirOctobre.v et complèterez la
déclaration suivante ci-dessous :
NOM, prénom, numéro étudiant : Je déclare qu'il s'agit de mon propre
travail.
C'est un travail individuel. Vous pouvez vous aider les uns les autres mais
vous ne devez jamais vous montrer le code de votre solution. L'usage de
ChatGPT ou de toute autre intelligence artificielle pour résoudre les
exercices est interdit. N'hésitez pas à vous aider les uns les autres, mais
sans jamais vous montrer le code de la solution. Il est possible aussi
d'envoyer des mails à
rousselin@univ-paris13.fr.
Il y a 2 parties inégales et indépendentes.
<=. Cette partie est la plus
fournie. En partant de trois propriétés admise de
<=, vous aurez à
prouver les propriétés usuelles de
<=. Pour la traiter, il est nécessaire
d'avoir terminé le deuxième TP.
introsunfoldexactsplitdestruct pour : un
/\, un
\/, une preuve de
False, un
exists
ou un entier naturel (preuve par cas)
left/rightexfalsoreflexivityapply et
apply ... inapply <- et
apply -> avec ou sans
in pour appliquer des équivalences
(voir partie 2)
rewrite,
rewrite <-,
rewrite ... in et
rewrite <- ... indiscriminateinductionspecializeadd_0_l : ∀ n : nat, 0 + n = nadd_0_r : ∀ n : nat, n + 0 = nadd_1_l : ∀ n : nat, 1 + n = S nadd_1_r : ∀ n : nat, n + 1 = S nadd_succ_l : ∀ n m : nat, S n + m = S (n + m)add_succ_r : ∀ n m : nat, n + S m = S (n + m)add_comm : ∀ n m : nat, n + m = m + nadd_assoc : ∀ n m p : nat, n + (m + p) = (n + m) + pmul_0_l : ∀ n : nat, 0 * n = 0mul_0_r : ∀ n : nat, n * 0 = 0mul_1_l : ∀ n : nat, 1 * n = nmul_1_r : ∀ n : nat, n * 1 = nmul_succ_l : ∀ n m : nat, S n * m = n * m + mmul_succ_r : ∀ n m : nat, n * S m = n * m + nmul_comm : ∀ n m : nat, n * m = m * nmul_assoc : ∀ n m p : nat, n * (m * p) = (n * m) * pmul_add_distr_l : ∀ n m p : nat, n * (m + p) = n * m + n * pmul_add_distr_l : ∀ n m p : nat, (n + m) * p = n * p + m * piff_refl : ∀ A : Prop, A <-> Aiff_trans : ∀ A B C : Prop, A <-> B -> B <-> C -> A <-> Cf_equal : ∀ (A B : Type) (f : A -> B) (x y : A), x = y -> f x = f yeq_sym : ∀ (A : Type) (x y : A), x = y -> y = x
Partie 1 : entiers naturels et ordre
<=
L'ordre
<= sur les entiers naturels est défini sur les entiers naturels
d'une certaine façon, qui est hors du programme de ce cours. On peut
cependant prouver toutes ses propriétés en admettant les trois propriétés
suivantes, qu'on utilisera comme des axiomes.
Une remarque sur succ
le
mono : c'est une équivalence. Pour l'utiliser comme
une implication, utiliser
apply ->succ_le_mono ou
apply <-succ_le_mono,
suivant le sens que l'on veut.
Par exemple, on peut prouver les deux résultats suivants "à la main".
À partir de maintenant, on va établir les propriétés usuelles de
<= sur
les entiers naturels.
D'abord, on va prouver que c'est une relation d'ordre, c'est-à-dire que c'est une relation réflexive, transitive et antisymétrique.
Indice:
induction.
Indices : pas d'induction, faire une preuve
par cas
sur n. Penser
à
exfalso si c'est pertinent.
Pour faciliter la preuve de l'antisymétrie, on va avoir besoin du théorème
suivant, général et très utile.
Il dit que, quelle que soit la fonction
f, pour prouver que
f x = f y,
il suffit de prouver que
x est égal à
y.
Indication : ne pas changer la première ligne. Elle permet d'avoir une
hypothèse de récurrence universellement quantifiée et on en a besoin.
Dans la deuxième partie de la preuve, raisonner par cas sur
m de
façon à pouvoir utiliser
succ_le_mono.
Indication : ne pas changer la première ligne. Elle permet d'avoir une
hypothèse de récurrence universellement quantifiée et on en a besoin.
La preuve est dans la même veine que
le_antisym, il faudra raisonner
par cas sur
m et
p.
Maintenant, il faut montrer que l'ordre
<= est total, c'est-à-dire que
deux entiers naturels sont toujours comparables.
Maintenant, on va établir des propriétés de compatibilité entre l'addition et l'ordre.
Ne pas utiliser d'induction. Utiliser
add_comm et le théorème précédent.
Indice: la récurrence doit porter sur
p.
Il y a plusieurs façons de procéder. La plus rapide est sans doute
de raisonner directement par équivalence.
Dans ce cas, vous pouvez utiliser les théorèmes
iff_refl et
iff_trans.
Ne pas utiliser d'induction. Utiliser
add_comm et le théorème précédent.
Ne pas utiliser d'induction. Utiliser
le_trans et les résultats
précédents.
On passe à la compatibilité avec la multiplication.
Ne pas utiliser d'induction.
Ne pas utiliser d'induction.
Partie 2 : un autre ordre sur Nat, la relation de divisibilité.
On dit qu'un entier
xdivise
un entier
y (notation :
x | y)
lorsqu'il existe un entier
z tel que
y = z * x.
D'abord quelques propriétés simples :
Cette relation de divisibilité est réflexive.
Si vous avez besoin de vous rappeler de la définition de
divide,
n'hésitez pas à
unfold divide.
Rappelez-vous comment prouver un énoncé du type "il existe".
Cette relation est de plus transitive.
Rappelez-vous comment utiliser un énoncé du type "il existe".
Enfin, c'est une relation antisymétrique.
Vous pourrez utiliser les théorèmes suivants :
Ainsi que :
Mais elle n'est pas totale, par exemple on a :
Indice : on pourra raisonner par cas sur l'entier k tel que 2 = k * 3 et
utiliser
simpl et
discriminate pour demander à Coq de trouver une
contradiction "par calcul".
Enfin, quelques proporiétés faciles de la divisibilité en lien avec l'addition et la multiplication :