Exercice 1 Asie – Bac NSI 2025 – Jour 1
On y aborde le problème de l'arrêt (halting problem) formalisé par Turing.
La question 5 évoque l’algorithme de Boyer-Moore (recherche textuelle). Un sujet original.
mots clés: décidabilité, algorithmique, programmation
🔎 Voir les exercices similaires ↓
Asie – Bac NSI 2025 – Jour 1 Énoncé de l'exercice 1
Cet exercice porte sur la décidabilité, l’algorithmique et la programmation en Python.
En Python, on peut utiliser le triple guillemet pour écrire une chaîne de caractères sur plusieurs lignes. Par exemple, on peut définir une variable programme1 qui contient la chaîne de caractères correspondant à un petit programme Python de la manière suivante :
programme1 = """
x = 10
y = 10
while x > 0:
x = x - 1
y = y + 1
"""
De même, on peut définir la variable programme2 :
programme2 = """
def boucle_infinie():
while True:
pass # Ne rien faire
boucle_infinie()
"""
On suppose que l’on exécute le programme contenu dans la variable programme1. Donner les valeurs de x et de y après exécution de ce programme.
Expliquer pourquoi tout programme Python peut être vu comme une chaîne de caractères.
En Python, la fonction exec permet d’exécuter le programme correspondant à une chaîne de caractères passée en paramètre.
>>> exec("r = 42")
>>> r
42
>>> exec(programme1)
>>> x + y
20
>>> exec(programme2)
[ne termine pas]
On considère les quatre variables programme3, programme4, programme5, programme6 suivants :
programme3 = """
x = 10
while x != 0:
x = x - 2
"""
programme4 = """
x = 10
while x > 0:
x = x + 2
"""
programme5 = """
x = 10
while x < 0:
x = x + 4
"""
programme6 = """
x = 10
while x != 0:
x = x - 4
"""
On exécute les variables programme3, programme4, programme5, programme6 avec la fonction exec. Déterminer lesquelles terminent et lesquelles ne terminent pas.
On cherche à écrire une fonction arret telle que arret(programme) renvoie True si exec(programme) termine et False si exec(programme) ne termine pas. Cette fonction arret doit donc s’arrêter dans tous les cas.
Indiquer ce que réalise le programme suivant et s’il permet de répondre au problème posé ci-dessus.
def arret_essai1(programme):
exec(programme)
return True
On suppose disposer d’une fonction recherche(mot, texte) qui renvoie True si une chaîne de caractères mot est présente dans une chaîne de caractères texte et False sinon.
Expliquer succinctement le principe de l’algorithme de Boyer-Moore qui permet d’implémenter cette fonction recherche.
Une idée est d’écrire une fonction qui décrète qu’un programme s’arrête s’il ne contient pas de while et ne s’arrête pas s’il en contient un.
Écrire une fonction arret_essai2(programme) qui renvoie True si la chaîne de caractères "while" n’est pas utilisée dans la chaîne de caractères programme et False sinon.
Montrer qu’il est possible que :
arret_essai2(programme) renvoie True alors que le programme ne s’arrête pas;
arret_essai2(programme) renvoie False alors que le programme s’arrête.
Indication : il n’y a pas que les boucles while qui peuvent poser des problèmes de non terminaison.
Nos tentatives pour écrire une telle fonction arret sont restées vaines. Nous allons montrer qu’il est en réalité impossible d’écrire une telle fonction. On va supposer qu’une telle fonction arret existe. On va montrer que cette supposition aboutit à un paradoxe ce qui prouvera que la supposition est fausse.
Écrire une fonction terminaison_inverse telle que l’appel terminaison_inverse(programme) termine si la chaîne de caractères programme représente un programme qui ne termine pas et ne termine pas si la chaîne de caractères programme représente un programme qui termine. On pourra utiliser la fonction boucle_infinie de programme2 ainsi bien sûr que la fonction arret dont on a supposé l’existence.
On considère "terminaison_inverse(programme_paradoxal)" qui n’est rien d’autre qu’une chaîne de caractères, et on définit une variable que l’on appelle programme_paradoxal à laquelle on affecte cette chaîne de caractères :
programme_paradoxal = "terminaison_inverse(programme_paradoxal)"
Étudier si le programme paradoxal termine ou non, c’est-à-dire si exec(programme_paradoxal) termine ou non.
Indiquer ce que l’on peut conclure sur la fonction arret.
Expliquer si l’impossibilité d’écrire une telle fonction arret est due aux limitations du langage Python.
Asie – Bac NSI 2025 – Jour 1 Correction de l'exercice 1
1) Valeurs de x et y après exécution de programme1
Programme :
x = 10
y = 10
while x > 0:
x = x - 1
y = y + 1
Analyse :
x diminue de 1 à chaque tour.
y augmente de 1 à chaque tour.
La boucle s’exécute tant que x > 0.
Il y a donc 10 itérations.
Valeurs finales :
x = 0
y = 20
2) Pourquoi tout programme Python peut être vu comme une chaîne de caractères ?
Un programme Python est un texte écrit dans un fichier.
Or un texte est une suite de caractères.
Ainsi, tout programme peut être représenté comme une chaîne de caractères, puis interprété ou exécuté par Python (via exec).
3) Terminaison des programmes 3, 4, 5 et 6
programme3 : x prend les valeurs 10, 8, 6, 4, 2, 0 ; la condition x != 0 devient fausse : programme3 termine.
programme4 : x vaut 10, 12, 14… et reste toujours strictement positif : programme4 ne termine pas.
programme5 : x = 10 n’est pas strictement négatif, la boucle n’est jamais exécutée : programme5 termine.
programme6 : x prend les valeurs 10, 6, 2, −2, −6… et ne vaut jamais 0 : programme6 ne termine pas.
4) Analyse de arret_essai1
def arret_essai1(programme):
exec(programme)
return True
Ce programme :
exécute le programme donné
renvoie True si exec se termine
Problème :
Si le programme ne termine pas, alors arret_essai1 ne termine pas non plus.
Donc cette fonction ne résout pas le problème demandé car elle ne s’arrête pas dans tous les cas.
5) Principe de l’algorithme de Boyer-Moore
L’algorithme de Boyer-Moore est un algorithme efficace de recherche de motif dans une chaîne.
Principe :
Il compare le motif au texte de droite à gauche.
En cas de désaccord, il saute plusieurs caractères grâce à des tables de décalage.
Cela permet souvent d’éviter de comparer tous les caractères.
Il est plus efficace qu’une recherche naïve.
6) Fonction arret_essai2
def arret_essai2(programme):
return not recherche('while',programme)
7) Montrer les limites de arret_essai2
Cas 1 : renvoie True mais le programme ne termine pas
Exemple :
l = [1]
for x in l:
l.append(x)
Il n’y a pas de "while" mais la boucle for ne termine pas : à chaque tour on ajoute un élément à la liste parcourue, qui n’est donc jamais épuisée.
Donc arret_essai2 renvoie True alors que le programme ne termine pas.
Cas 2 : renvoie False mais le programme termine
Exemple :
x=1
while x!=1:
print("NSI for ever!")
Le mot "while" est présent, donc arret_essai2 renvoie False.
Mais la boucle ne s’exécute jamais, donc le programme termine. C’est aussi le cas du programme5.
8) Fonction terminaison_inverse
On suppose que la fonction arret existe.
def terminaison_inverse(programme):
if arret(programme): # programme termine
boucle_infinie() # alors on ne termine pas
# sinon on termine aussitôt
Comportement :
Si programme termine → terminaison_inverse boucle infiniment.
Si programme ne termine pas → terminaison_inverse termine.
9) Étude du programme paradoxal
On définit :
programme_paradoxal = "terminaison_inverse(programme_paradoxal)"
On analyse :
Si programme_paradoxal termine,
alors arret renvoie True,
donc terminaison_inverse boucle infiniment,
donc programme_paradoxal ne termine pas.
Contradiction.
Si programme_paradoxal ne termine pas,
alors arret renvoie False,
donc terminaison_inverse termine,
donc programme_paradoxal termine.
Nouvelle contradiction.
Conclusion : On obtient un paradoxe !
10) Conclusion sur la fonction arret
La fonction arret ne peut pas exister.
Il est impossible d’écrire un programme qui détermine pour tout programme s’il termine ou non.
C’est le problème de l’arrêt (Halting Problem), démontré indécidable par Alan Turing.
11) Cette impossibilité est-elle due à Python ?
Non.
Ce résultat est indépendant du langage.
Tout langage de programmation suffisamment expressif (Turing-complet) possède cette limitation.
Ce n’est pas une limite technique de Python, mais une limite fondamentale de l’informatique théorique.
Une erreur, un oubli ? Écrivez-moi : frederic.peuriere@lfcl.pt
🔎 Exercices sur des thèmes similaires
-
Asie 2024 – jour 1 – exercice 1
programmation, POO, algorithmique — Difficulté : 🔥🔥🔥🔥🔥 -
Polynésie 2025 – jour 2 – exercice 1
POO, algorithmique , programmation — Difficulté : 🔥🔥🔥🔥🔥 -
Asie 2024 – jour 1 – exercice 2
algorithmique des graphes, programmation, pile — Difficulté : 🔥🔥🔥🔥🔥 -
Nouvelle Caldédonie 2023 – jour 2 – exercice 2
programmation Python, récursivité — Difficulté : 🔥🔥🔥🔥🔥 -
Métropole 2025 – jour 1 – exercice 3
réseau, routage, arbres binaires de recherche, programmation — Difficulté : 🔥🔥🔥🔥🔥 -
Nouvelle Caldédonie 2023 – jour 1 – exercice 2
programmation, codage binaire — Difficulté : 🔥🔥🔥🔥🔥