Deux questions qu’un ordinateur ne règle pas
Le problème de l’arrêt demande si un programme finira un jour ou tournera sans fin. Aucun programme ne peut répondre juste pour tous les programmes : c’est une limite prouvée du calcul.
D’autres problèmes ont une réponse, mais elle devient trop lente à trouver quand les données grandissent. Vous allez voir ces deux limites, puis compter les essais d’une recherche par force brute.
À la fin de cette leçon
Remarque
Je peux expliquer pourquoi aucun programme ne décide toutes les questions, et ce que veut dire « trop lent ».
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Problème décidable | un problème qu’un programme résout toujours, en un temps fini | ce nombre est-il premier ? |
| Problème indécidable | un problème qu’aucun programme ne résout pour tous les cas | |
| Problème de l’arrêt | savoir si un programme finit ou tourne sans fin | |
| Force brute | essayer toutes les possibilités, l’une après l’autre | |
| Sous-ensemble | un choix de certains éléments d’une liste | [12, 5] |
| Croissance exponentielle | un travail qui double chaque fois que la taille augmente de 1 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Peut-on écrire un programme qui prédit l’arrêt ?
Supposons qu’un programme arrete(programme, entree) existe. Il reçoit le texte d’un programme et une entrée. Il répond toujours True si ce programme finit sur cette entrée, et False sinon, en un temps fini.
Ce serait très utile : aucune boucle sans fin ne passerait plus. Pour montrer que c’est impossible, on construit un second programme, contraire, qui fait l’inverse de ce que arrete prédit.
Le programme contraire
def arrete(programme, entree):
# Hypothèse : cette fonction existe. Elle rend toujours
# True ou False, en un temps fini, et elle a toujours raison.
...
def contraire(programme):
if arrete(programme, programme):
while True:
pass # boucle sans fin
else:
return "fini"
Exemple travaillé : contraire appliqué à lui-même
| arrete(contraire, contraire) répond | contraire(contraire) fait | Conclusion |
|---|---|---|
| True : il finit | Il boucle sans fin | arrete s’est trompé |
| False : il ne finit pas | Il se termine | arrete s’est trompé |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Certains problèmes sont décidables, d’autres non
Dans les deux cas, arrete se trompe. L’hypothèse était donc fausse : le problème de l’arrêt est indécidable.
Beaucoup de problèmes sont au contraire décidables. Un automate fini, une grammaire ou un compilateur donnent toujours une réponse juste. Le tableau range quelques questions dans l’un ou l’autre groupe.
Quelques questions et leur statut
| Question | Statut | Pourquoi |
|---|---|---|
| Cette ligne est-elle une plaque correcte ? | Décidable | Un automate fini suffit |
| Ces parenthèses sont-elles équilibrées ? | Décidable | Une grammaire suffit |
| Ce nombre est-il premier ? | Décidable | On teste les diviseurs un à un |
| Ce programme s’arrête-t-il ? | Indécidable | La preuve avec contraire |
| Ce programme affichera-t-il un jour le mot erreur ? | Indécidable | Il faudrait savoir s’il arrive jusque-là |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Décidable ne veut pas dire rapide
Un magasin vend cinq articles. Un client veut en choisir quelques-uns pour dépenser exactement sa carte cadeau. Ce problème, la somme d’un sous-ensemble, est décidable.
Une méthode sûre existe : essayer tous les sous-ensembles, c’est la force brute. Avec n articles, chacun est pris ou pas : cela fait 2 puissance n choix. Le tableau compte ces essais, sans aucun chronomètre.
Exemple travaillé : le nombre d’essais selon n
| Articles n | Sous-ensembles à essayer (2 puissance n) | Pour comparer : n fois n |
|---|---|---|
| 5 | 32 | 25 |
| 10 | 1 024 | 100 |
| 20 | 1 048 576 | 400 |
| 30 | 1 073 741 824 | 900 |
| 40 | 1 099 511 627 776 | 1 600 |
| 60 | 1 152 921 504 606 846 976 | 3 600 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
La force brute, essai par essai
# Force brute : tous les sous-ensembles de prix qui font 25 euros.
prix = [12, 7, 5, 20, 8]
cible = 25
n = len(prix)
essais = 0
for masque in range(2 ** n):
essais = essais + 1
total = 0
for i in range(n):
# Le bit i du masque dit si l'on prend le prix i.
if masque // 2 ** i % 2 == 1:
total = total + prix[i]
if total == cible:
print("trouvé avec le masque", masque)
print("essais :", essais)
# Ajoutez un prix à la liste : le nombre d'essais double.
Vérifier est facile, trouver est dur
Si quelqu’un vous donne un choix d’articles, vérifier son total demande quelques additions seulement. Trouver un bon choix, en revanche, demande de chercher parmi 2 puissance n possibilités.
On ne connaît aucune méthode rapide qui marche pour toutes les listes. On ne sait pas non plus prouver qu’il n’y en a pas : c’est la question ouverte « P contre NP ».
Le labo sert de calculette exacte
Le labo ne mesure aucun temps ici : seul le nombre d’essais compte, et il est exact. Les Runs affichent de grandes puissances de 2 avec Python.
Le dernier montre à quel point la vérification est simple : une seule addition en shell, là où la recherche en demande des milliards.
Essais pour 30 articles
python3 -c "print(2 ** 30)"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Essais pour 60 articles
python3 -c "print(2 ** 60)"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les chiffres de 2 puissance 1000
python3 -c "print(len(str(2 ** 1000)))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Vérifier un choix en une addition
echo $((12 + 5 + 8))Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce que sait faire chaque modèle
| Modèle | Ce qu’il sait faire | Ce qu’il ne sait pas faire |
|---|---|---|
| Automate fini, motif | Reconnaître une forme fixe, comme une plaque | Compter sans limite |
| Grammaire | Gérer l’emboîtement des parenthèses | Tout ce qui demande de calculer |
| Machine de Turing | Tout ce qui est calculable | Décider l’arrêt de tout programme |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Erreur fréquente
Attention
Beaucoup de gens pensent qu’« indécidable » veut dire « trop difficile pour l’instant », et qu’une machine plus puissante y arrivera. C’est faux : la preuve vaut pour toute machine. « Trop lent » est un autre cas : la réponse existe, mais le travail explose.
Pour aller plus loin
Dans la table des essais, comparez la colonne 2 puissance n et la colonne n fois n quand n passe de 30 à 60. Laquelle a été multipliée par plus de mille ?
Dites ensuite, en une phrase, pourquoi un compilateur peut signaler une erreur de syntaxe, mais pas toutes les boucles sans fin.