Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Problème de l’arrêt et limites du calcul

Après cette leçon: Je peux expliquer pourquoi aucun programme ne décide toutes les questions, et ce que veut dire « trop lent ».

Leçon de 65 min4 commandesLab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

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

MotCe que ça veut direExemple
Problème décidableun problème qu’un programme résout toujours, en un temps finice nombre est-il premier ?
Problème indécidableun problème qu’aucun programme ne résout pour tous les cas
Problème de l’arrêtsavoir si un programme finit ou tourne sans fin
Force bruteessayer toutes les possibilités, l’une après l’autre
Sous-ensembleun choix de certains éléments d’une liste[12, 5]
Croissance exponentielleun 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

Code: python
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épondcontraire(contraire) faitConclusion
True : il finitIl boucle sans finarrete s’est trompé
False : il ne finit pasIl se terminearrete 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

QuestionStatutPourquoi
Cette ligne est-elle une plaque correcte ?DécidableUn automate fini suffit
Ces parenthèses sont-elles équilibrées ?DécidableUne grammaire suffit
Ce nombre est-il premier ?DécidableOn teste les diviseurs un à un
Ce programme s’arrête-t-il ?IndécidableLa preuve avec contraire
Ce programme affichera-t-il un jour le mot erreur ?IndécidableIl 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 nSous-ensembles à essayer (2 puissance n)Pour comparer : n fois n
53225
101 024100
201 048 576400
301 073 741 824900
401 099 511 627 7761 600
601 152 921 504 606 846 9763 600

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

La force brute, essai par essai

Code: python
# 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

Commande
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

Commande
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

Commande
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

Commande
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èleCe qu’il sait faireCe qu’il ne sait pas faire
Automate fini, motifReconnaître une forme fixe, comme une plaqueCompter sans limite
GrammaireGérer l’emboîtement des parenthèsesTout ce qui demande de calculer
Machine de TuringTout ce qui est calculableDé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.

À propos de ce labo et de sa source: Lab de compilation et d’architecture : gcc, flex, bison et RISC-V dans une VM

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.