{
  "chapter": {
    "id": "calculabilite",
    "level": "terminale",
    "theme": "Programmation",
    "title": "Calculabilité et décidabilité",
    "description": "Notion de programme en tant que donnée, calculabilité,\ndécidabilité, indépendance de la calculabilité vis-à-vis\ndu langage de programmation, problème de l'arrêt et son\nindécidabilité (présentés sans formalisme théorique).",
    "parties": [
      {
        "id": "notions",
        "title": "Calculable et décidable"
      },
      {
        "id": "arret",
        "title": "Problème de l'arrêt et ses conséquences"
      }
    ],
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "programme-donnee"
      ],
      "title": "Programme et donnée",
      "partie": "notions",
      "statement": "Pourquoi peut-on dire qu'**un programme est aussi une donnée** ?",
      "options": [
        {
          "text": "Cette affirmation est fausse",
          "correct": false,
          "feedback": "Erreur : c'est au contraire l'un des principes\nfondamentaux de l'informatique.\n"
        },
        {
          "text": "Parce qu'un programme contient toujours des données en entrée",
          "correct": false,
          "feedback": "Erreur : on parle ici du programme lui-même\nconsidéré comme donnée, pas de ses entrées.\n"
        },
        {
          "text": "Parce qu'il occupe de la mémoire vive",
          "correct": false,
          "feedback": "C'est vrai mais incomplet : la phrase clé est\nque le programme peut être **lu par un autre programme**, pas seulement chargé en mémoire.\n"
        },
        {
          "text": "Un fichier d'octets, lu par d'autres programmes",
          "correct": true,
          "feedback": "Bonne réponse : sur un disque, un fichier `.py`\nest une suite d'octets exactement comme une\nimage ou un texte. C'est cette idée qui rend\npossibles les compilateurs, les interpréteurs\nou la mise à jour automatique des logiciels.\n"
        }
      ],
      "explanation": "Un compilateur prend en entrée un programme (donnée\ntexte) et en produit un autre (programme exécutable).\nUn interpréteur Python lit un programme et l'exécute\nligne par ligne. Cette dualité programme/donnée\nouvre la voie à toute la métacomputation."
    },
    {
      "id": "q02",
      "difficulty": 1,
      "skills": [
        "interpreteur",
        "exemple-programme-donnee"
      ],
      "title": "Programme manipulé par un autre",
      "partie": "notions",
      "statement": "Lequel des exemples suivants illustre **un programme manipulé comme une donnée** ?",
      "options": [
        {
          "text": "Un compilateur qui lit un fichier `.c` et produit un fichier exécutable",
          "correct": true,
          "feedback": "Bonne réponse : pour le compilateur, le fichier\n`.c` est une donnée d'entrée comme une autre.\nSa sortie est elle-même un programme.\n"
        },
        {
          "text": "Un programme qui calcule un déterminant de matrice",
          "correct": false,
          "feedback": "Erreur : la donnée traitée est une matrice\nde nombres, pas un programme.\n"
        },
        {
          "text": "Un programme qui affiche « Bonjour »",
          "correct": false,
          "feedback": "Erreur : aucun programme n'est manipulé comme\ndonnée dans cet exemple.\n"
        },
        {
          "text": "Un programme qui calcule la somme de deux nombres saisis par l'utilisateur",
          "correct": false,
          "feedback": "Erreur : ici, les données sont des nombres,\npas un programme.\n"
        }
      ],
      "explanation": "Les compilateurs, les interpréteurs, les\ndébogueurs, les antivirus ou encore les\ntranspileurs sont autant de programmes dont\nl'entrée est elle-même un programme."
    },
    {
      "id": "q03",
      "difficulty": 1,
      "skills": [
        "calculabilite",
        "definition"
      ],
      "title": "Fonction calculable",
      "partie": "notions",
      "statement": "Que signifie qu'une fonction $f$ est **calculable**\nau sens informatique ?",
      "options": [
        {
          "text": "La fonction est continue",
          "correct": false,
          "feedback": "Erreur : la continuité est une notion\nmathématique sans rapport avec la\ncalculabilité informatique.\n"
        },
        {
          "text": "La fonction s'exécute en moins d'une seconde",
          "correct": false,
          "feedback": "Erreur : la calculabilité n'impose aucune\ncontrainte de temps. Seule l'existence d'un\nalgorithme fini est requise.\n"
        },
        {
          "text": "La fonction renvoie toujours un entier",
          "correct": false,
          "feedback": "Erreur : aucune contrainte sur le type de\nsortie. Une fonction calculable peut renvoyer\ndes chaînes, des listes, des booléens, etc.\n"
        },
        {
          "text": "Un algorithme calcule $f$ en temps fini",
          "correct": true,
          "feedback": "Bonne réponse : la calculabilité dit qu'on\ndispose d'un procédé algorithmique fini pour\nobtenir le résultat. Le temps d'exécution\npeut être très long, mais doit rester fini.\n"
        }
      ],
      "explanation": "La calculabilité capture l'idée de\n« ce qu'on peut résoudre par algorithme ». Elle\nne dit rien sur la rapidité (cette question relève\nde la complexité) ni sur la facilité d'écriture\n(qui dépend du langage et du programmeur)."
    },
    {
      "id": "q04",
      "difficulty": 1,
      "skills": [
        "calculabilite",
        "exemple"
      ],
      "title": "Exemple de fonction calculable",
      "partie": "notions",
      "statement": "Lequel des éléments suivants définit une fonction\n**calculable** ?",
      "options": [
        {
          "text": "Une fonction qui prend en entrée un programme et renvoie « oui » s'il s'arrête, « non » sinon",
          "correct": false,
          "feedback": "Erreur : c'est précisément le problème de\nl'arrêt, qui est **indécidable**, donc non\ncalculable.\n"
        },
        {
          "text": "Une fonction qui à un texte associe « oui » s'il représente un programme correct",
          "correct": false,
          "feedback": "Erreur : si « correct » signifie « sans bug\nlogique », ce problème est lié à\nl'indécidabilité de l'arrêt et n'est pas\ncalculable en général.\n"
        },
        {
          "text": "La fonction qui à un programme associe le nombre exact d'instructions qu'il exécutera dans tous les cas",
          "correct": false,
          "feedback": "Erreur : pour certaines entrées, le programme\npeut ne jamais s'arrêter ; on ne peut donc pas\ntoujours répondre.\n"
        },
        {
          "text": "La fonction qui à un entier $n$ associe son carré $n^2$",
          "correct": true,
          "feedback": "Bonne réponse : un algorithme trivial\n(`return n * n`) calcule cette fonction en\ntemps fini pour tout entier $n$.\n"
        }
      ],
      "explanation": "Les fonctions arithmétiques usuelles, les\nfonctions sur les chaînes, le tri d'une liste,\nl'évaluation d'une expression : toutes sont\ncalculables. L'indécidabilité concerne au contraire\nles questions portant sur le **comportement** des\nprogrammes."
    },
    {
      "id": "q05",
      "difficulty": 1,
      "skills": [
        "independance-langage"
      ],
      "title": "Indépendance du langage",
      "partie": "notions",
      "statement": "Une fonction est calculable. Que peut-on en\ndéduire sur les langages de programmation ?",
      "options": [
        {
          "text": "Le résultat de la fonction varie selon le langage utilisé",
          "correct": false,
          "feedback": "Erreur : la fonction (au sens mathématique) est\nla même quel que soit le langage qui\nl'implémente.\n"
        },
        {
          "text": "Elle ne peut être écrite qu'en Python",
          "correct": false,
          "feedback": "Erreur : Python n'a aucune capacité\nalgorithmique particulière. Les autres\nlangages universels font tout aussi bien.\n"
        },
        {
          "text": "Elle s'implémente dans tout langage universel",
          "correct": true,
          "feedback": "Bonne réponse : la calculabilité ne dépend\npas du langage utilisé. Tout langage assez\nexpressif (autorisant boucles ou récursivité,\nconditions, mémoire) peut implémenter\nn'importe quelle fonction calculable.\n"
        },
        {
          "text": "Elle nécessite obligatoirement un langage récursif",
          "correct": false,
          "feedback": "Erreur : on peut tout calculer avec des\nboucles itératives, sans récursion explicite.\n"
        }
      ],
      "explanation": "Tous les langages de programmation usuels sont\n« équivalents » en pouvoir calculatoire : ce qu'on\npeut programmer dans l'un, on peut le programmer\ndans les autres. Les différences se situent au\nniveau de la lisibilité, de la performance ou de\nl'écosystème, pas de la calculabilité."
    },
    {
      "id": "q06",
      "difficulty": 1,
      "skills": [
        "decidable",
        "definition"
      ],
      "title": "Problème décidable",
      "partie": "notions",
      "statement": "Qu'appelle-t-on un **problème décidable** ?",
      "options": [
        {
          "text": "Un algorithme répond oui/non en temps fini",
          "correct": true,
          "feedback": "Bonne réponse : un problème décidable est un\nproblème de décision (« oui »/« non ») dont\nla réponse est **calculable** pour toutes les\nentrées. L'algorithme doit toujours\nterminer.\n"
        },
        {
          "text": "Un problème dont la réponse est connue par avance",
          "correct": false,
          "feedback": "Erreur : la décidabilité concerne l'existence\nd'un algorithme général, pas la connaissance\na priori.\n"
        },
        {
          "text": "Un problème qui n'a pas de solution",
          "correct": false,
          "feedback": "Erreur : c'est exactement l'inverse. Un\nproblème décidable a une solution\nalgorithmique systématique.\n"
        },
        {
          "text": "Un problème facile à résoudre",
          "correct": false,
          "feedback": "Erreur : la décidabilité ne dit rien sur la\ndifficulté. Beaucoup de problèmes décidables\nsont très coûteux à résoudre.\n"
        }
      ],
      "explanation": "Exemples décidables : « cet entier est-il pair ? »,\n« ce mot est-il dans le dictionnaire ? », « ce\nnombre est-il premier ? ». Pour chacun, on dispose\nd'un algorithme qui répond toujours en temps fini."
    },
    {
      "id": "q07",
      "difficulty": 1,
      "skills": [
        "decidable",
        "exemple"
      ],
      "title": "Exemple de problème décidable",
      "partie": "notions",
      "statement": "Lequel de ces problèmes est clairement **décidable** ?",
      "options": [
        {
          "text": "Étant donné un programme, dire s'il contient un bug logique",
          "correct": false,
          "feedback": "Erreur : ce problème est indécidable au sens\ngénéral (lié au problème de l'arrêt).\n"
        },
        {
          "text": "Étant donné un programme Python, dire s'il s'arrêtera sur l'entrée $0$",
          "correct": false,
          "feedback": "Erreur : c'est une instance du problème de\nl'arrêt, qui est indécidable en général.\n"
        },
        {
          "text": "Étant donné un entier $n$, déterminer s'il est divisible par $7$",
          "correct": true,
          "feedback": "Bonne réponse : un simple test `n % 7 == 0`\nrépond toujours en temps fini, pour tout\nentier $n$.\n"
        },
        {
          "text": "Étant donné deux programmes, dire s'ils calculent la même fonction sur toute entrée",
          "correct": false,
          "feedback": "Erreur : c'est aussi un problème indécidable\nen général.\n"
        }
      ],
      "explanation": "Beaucoup de propriétés **syntaxiques** sur les\nprogrammes (longueur du code, présence d'un\nmot-clé...) sont décidables, mais les propriétés\n**sémantiques** (comportement, terminaison,\nrésultat) sont rarement décidables."
    },
    {
      "id": "q08",
      "difficulty": 2,
      "skills": [
        "indecidable",
        "definition"
      ],
      "title": "Problème indécidable",
      "partie": "arret",
      "statement": "Qu'est-ce qu'un **problème indécidable** ?",
      "options": [
        {
          "text": "Un problème qui demande beaucoup de mémoire",
          "correct": false,
          "feedback": "Erreur : la consommation mémoire n'a aucun\nrapport avec la décidabilité.\n"
        },
        {
          "text": "Un problème dont la réponse change selon la machine utilisée",
          "correct": false,
          "feedback": "Erreur : la décidabilité est indépendante de\nla machine.\n"
        },
        {
          "text": "Un problème difficile, qu'on n'a pas encore résolu",
          "correct": false,
          "feedback": "Erreur : « indécidable » est un résultat\nmathématique d'**inexistence**, pas d'attente.\n"
        },
        {
          "text": "Aucun algorithme ne peut répondre pour toute entrée",
          "correct": true,
          "feedback": "Bonne réponse : il ne s'agit pas de dire\nqu'on n'a pas trouvé d'algorithme : on a\ndémontré qu'il n'en existe pas, et n'en\nexistera jamais.\n"
        }
      ],
      "explanation": "Un problème indécidable est une **limite théorique** de l'informatique : il existe des\nquestions qu'aucun ordinateur, présent ou futur,\nne pourra résoudre dans le cas général."
    },
    {
      "id": "q09",
      "difficulty": 2,
      "skills": [
        "arret",
        "enonce"
      ],
      "title": "Énoncé du problème de l'arrêt",
      "partie": "arret",
      "statement": "Comment énonce-t-on le **problème de l'arrêt** ?",
      "options": [
        {
          "text": "Comment savoir combien de temps un programme va s'exécuter ?",
          "correct": false,
          "feedback": "Erreur : c'est une question de complexité,\npas de calculabilité.\n"
        },
        {
          "text": "Comment arrêter un programme qui boucle sans fin du tout ?",
          "correct": false,
          "feedback": "Erreur : la question pratique « arrêter un\nprogramme » (avec Ctrl-C par exemple) n'a\nrien à voir avec le problème théorique.\n"
        },
        {
          "text": "À quel moment faut-il interrompre une compilation ?",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la calculabilité.\n"
        },
        {
          "text": "Un algorithme peut-il prédire l'arrêt de tout programme ?",
          "correct": true,
          "feedback": "Bonne réponse : c'est l'énoncé classique. La\nréponse, démontrée par Turing en 1936, est\n**non**.\n"
        }
      ],
      "explanation": "L'enjeu : disposer d'un programme universel\n`arrete?(P, e)` qui, donné un programme $P$ et\nune entrée $e$, répondrait toujours « oui » si\n$P$ termine sur $e$, « non » sinon. Ce programme\nn'existe pas."
    },
    {
      "id": "q10",
      "difficulty": 2,
      "skills": [
        "arret",
        "indecidable"
      ],
      "title": "Statut du problème de l'arrêt",
      "partie": "arret",
      "statement": "Le problème de l'arrêt est :",
      "options": [
        {
          "text": "Décidable, mais coûteux",
          "correct": false,
          "feedback": "Erreur : il est mathématiquement démontré\nqu'aucun algorithme ne peut le résoudre.\n"
        },
        {
          "text": "Indécidable",
          "correct": true,
          "feedback": "Bonne réponse : aucun algorithme ne peut\ndécider, dans le cas général, si un\nprogramme arbitraire s'arrête sur une entrée\ndonnée. C'est un théorème dû à Alan Turing\n(1936).\n"
        },
        {
          "text": "Décidable, et résolu par les antivirus",
          "correct": false,
          "feedback": "Erreur : les antivirus utilisent des\nheuristiques (signatures, comportements\nsuspects), pas une décision exacte. Une\ndétection parfaite reviendrait à résoudre\nl'arrêt.\n"
        },
        {
          "text": "Inconnu de la communauté scientifique",
          "correct": false,
          "feedback": "Erreur : le résultat est connu et démontré\ndepuis 1936.\n"
        }
      ],
      "explanation": "Démontrer l'indécidabilité de l'arrêt est l'un\ndes grands résultats fondateurs de l'informatique\nthéorique. Il pose une limite **absolue** à ce\nque les ordinateurs peuvent décider."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "arret",
        "idee-preuve"
      ],
      "title": "Idée de la démonstration",
      "partie": "arret",
      "statement": "L'argument classique de Turing pour montrer que\nl'arrêt est indécidable consiste à supposer qu'on\npossède un tel décideur, puis à :",
      "options": [
        {
          "text": "Mesurer le temps d'exécution de tous les programmes possibles",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la démonstration\nd'indécidabilité.\n"
        },
        {
          "text": "Programmer le décideur en plusieurs langages et comparer",
          "correct": false,
          "feedback": "Erreur : la démonstration ne dépend pas du\nlangage utilisé.\n"
        },
        {
          "text": "Construire un programme qui se contredit via le décideur",
          "correct": true,
          "feedback": "Bonne réponse : à partir du décideur supposé\n`arrete?`, on fabrique un programme `D` qui\nfait l'inverse de ce que prédit `arrete?` sur\nson propre code. On obtient alors une\ncontradiction.\n"
        },
        {
          "text": "Réécrire les programmes en machine de Turing",
          "correct": false,
          "feedback": "Erreur : la machine de Turing est un cadre\nformel possible, mais ce n'est pas l'idée\ncentrale de la preuve.\n"
        }
      ],
      "explanation": "L'idée force est l'**auto-référence** : on\nconstruit un programme qui interroge le décideur\nà propos de lui-même puis fait le contraire de la\nprédiction. Le décideur ne peut donc pas exister."
    },
    {
      "id": "q12",
      "difficulty": 2,
      "skills": [
        "consequence",
        "debogage"
      ],
      "title": "Conséquence pratique",
      "partie": "arret",
      "statement": "Quelle conséquence pratique l'indécidabilité du\nproblème de l'arrêt a-t-elle sur le développement\nlogiciel ?",
      "options": [
        {
          "text": "Plus aucun nouveau bug ne peut être trouvé",
          "correct": false,
          "feedback": "Erreur : c'est l'inverse, on continue à\ntrouver des bugs régulièrement.\n"
        },
        {
          "text": "On ne peut pas détecter toutes les boucles infinies",
          "correct": true,
          "feedback": "Bonne réponse : aucun programme ne pourra repérer toutes les boucles infinies ou tous les bugs de terminaison. C'est pourquoi les tests, les revues de code et les assertions restent indispensables.\n"
        },
        {
          "text": "Les ordinateurs ne peuvent pas exécuter de programmes",
          "correct": false,
          "feedback": "Erreur : aucun rapport. L'indécidabilité ne\nconcerne que la **prédiction** du\ncomportement des programmes.\n"
        },
        {
          "text": "Les langages modernes ne contiennent plus jamais de boucles infinies",
          "correct": false,
          "feedback": "Erreur : on peut tout à fait écrire des\nboucles infinies dans tous les langages,\nvolontairement ou non.\n"
        }
      ],
      "explanation": "L'indécidabilité de l'arrêt entraîne celle de nombreuses autres propriétés : équivalence de deux programmes, absence de bugs, terminaison sur toutes les entrées, etc. Les outils d'analyse de code sont donc nécessairement **incomplets**."
    },
    {
      "id": "q13",
      "difficulty": 2,
      "skills": [
        "calculable-vs-decidable"
      ],
      "title": "Calculable ou décidable",
      "partie": "notions",
      "statement": "Quelle est la différence entre **calculable** et\n**décidable** ?",
      "options": [
        {
          "text": "« Calculable » signifie « facile », « décidable » signifie « difficile »",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la difficulté.\n"
        },
        {
          "text": "« Calculable » concerne les nombres, « décidable » concerne les chaînes",
          "correct": false,
          "feedback": "Erreur : aucune contrainte sur le type des\ndonnées.\n"
        },
        {
          "text": "Calculable pour les fonctions, décidable pour les problèmes oui/non",
          "correct": true,
          "feedback": "Bonne réponse : un problème de décision est\ndécidable lorsque la fonction associée\n(« oui » ou « non ») est calculable et que\nl'algorithme termine toujours. Les deux\nnotions sont étroitement liées.\n"
        },
        {
          "text": "Aucune différence, ce sont des synonymes",
          "correct": false,
          "feedback": "Erreur : « calculable » est plus général ;\n« décidable » est réservé aux problèmes à\nréponse binaire.\n"
        }
      ],
      "explanation": "Tout problème décidable correspond à une fonction\nindicatrice calculable. La réciproque est vraie :\npour qu'un problème de décision soit décidable,\nil faut et il suffit que sa fonction indicatrice\nsoit calculable."
    },
    {
      "id": "q14",
      "difficulty": 2,
      "skills": [
        "arret",
        "exemple-cas-particulier"
      ],
      "title": "Cas particuliers",
      "partie": "arret",
      "statement": "Pour **certains** programmes, on peut savoir\nfacilement s'ils s'arrêtent. Ce qui est\nindécidable, c'est :",
      "options": [
        {
          "text": "Le faire pour tout programme, en général",
          "correct": true,
          "feedback": "Bonne réponse : un humain peut analyser un\npetit programme et raisonner sur sa\nterminaison. Ce qui est impossible, c'est de\nconstruire un algorithme qui réussisse pour\n**n'importe quel** programme et n'importe\nquelle entrée.\n"
        },
        {
          "text": "De le faire pour les programmes écrits en Python",
          "correct": false,
          "feedback": "Erreur : la limite ne dépend pas du langage.\n"
        },
        {
          "text": "De le faire en moins d'une heure",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la durée\nd'analyse.\n"
        },
        {
          "text": "De le faire pour les programmes courts",
          "correct": false,
          "feedback": "Erreur : pour les programmes courts, l'analyse\nhumaine ou des outils dédiés peuvent souvent\nrépondre. C'est le cas général qui est\nindécidable.\n"
        }
      ],
      "explanation": "L'indécidabilité concerne l'existence d'un\nalgorithme **général**. Cas par cas, beaucoup\nde programmes peuvent être analysés, parfois\nautomatiquement. Mais il existera toujours des\ncas où aucun algorithme général ne peut conclure."
    },
    {
      "id": "q15",
      "difficulty": 2,
      "skills": [
        "universalite-machine"
      ],
      "title": "Machine universelle",
      "partie": "notions",
      "statement": "L'idée d'**ordinateur universel** repose sur\nlaquelle des affirmations suivantes ?",
      "options": [
        {
          "text": "Un seul appareil exécute tout programme fourni en entrée",
          "correct": true,
          "feedback": "Bonne réponse : c'est exactement le concept\nde machine universelle de Turing (1936) et,\nen pratique, de tout ordinateur moderne.\n"
        },
        {
          "text": "Tous les programmes peuvent s'écrire sans boucles",
          "correct": false,
          "feedback": "Erreur : sans rapport avec l'universalité.\n"
        },
        {
          "text": "Tous les ordinateurs ont le même processeur",
          "correct": false,
          "feedback": "Erreur : il existe de nombreux processeurs\ndifférents (x86, ARM, RISC-V…). L'universalité\nest une propriété logique, pas matérielle.\n"
        },
        {
          "text": "Tout calcul peut s'effectuer instantanément",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la vitesse.\n"
        }
      ],
      "explanation": "C'est cette universalité qui rend possibles les\nordinateurs polyvalents : un seul appareil\nexécute traitement de texte, jeux, navigateur,\ncompilateurs, etc., simplement en chargeant des\nprogrammes différents."
    },
    {
      "id": "q16",
      "difficulty": 2,
      "skills": [
        "interpreteur-self"
      ],
      "title": "Interpréteur écrit dans son langage",
      "partie": "notions",
      "statement": "On peut écrire en Python un interpréteur de Python, c'est-à-dire un programme qui lit le texte d'un autre programme Python et l'exécute. Que montre cet exemple ?",
      "options": [
        {
          "text": "Que Python est plus rapide que les autres langages",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la performance.\n"
        },
        {
          "text": "Que Python calcule plus de fonctions que les autres langages",
          "correct": false,
          "feedback": "Erreur : tous les langages de programmation usuels calculent les mêmes fonctions. Écrire un interpréteur ne change rien aux capacités de calcul du langage.\n"
        },
        {
          "text": "Que le problème de l'arrêt devient décidable pour Python",
          "correct": false,
          "feedback": "Erreur : l'interpréteur exécute le programme qu'il reçoit, il ne prédit pas s'il s'arrêtera. Le problème de l'arrêt reste indécidable, quel que soit le langage.\n"
        },
        {
          "text": "Un programme peut exécuter un autre programme",
          "correct": true,
          "feedback": "Bonne réponse : l'interpréteur traite le texte d'un programme comme une donnée d'entrée et l'exécute. C'est l'expression concrète de la dualité programme/donnée.\n"
        }
      ],
      "explanation": "Interpréteurs, compilateurs et systèmes d'exploitation manipulent tous des programmes comme des données. C'est aussi ce qui permet de télécharger un logiciel, de le stocker, puis de l'exécuter."
    },
    {
      "id": "q17",
      "difficulty": 2,
      "skills": [
        "antivirus",
        "illustration"
      ],
      "title": "Détection de logiciels malveillants",
      "partie": "arret",
      "statement": "Pourquoi est-il **impossible** d'écrire un\nantivirus parfait qui détecterait tous les\nlogiciels malveillants sans aucune erreur ?",
      "options": [
        {
          "text": "Parce que les antivirus sont mal programmés",
          "correct": false,
          "feedback": "Erreur : la limite est théorique, elle ne\ndépend pas de la qualité de l'implémentation.\n"
        },
        {
          "text": "Cela rejoint le problème de l'arrêt, indécidable",
          "correct": true,
          "feedback": "Bonne réponse : décider si un programme aura\nun certain comportement (lire un fichier\nsensible, par exemple) est en général\nindécidable. Les antivirus s'appuient donc\nsur des **heuristiques** (signatures,\ncomportements suspects), jamais sur une\ndécision exacte.\n"
        },
        {
          "text": "Parce que les antivirus sont trop lents",
          "correct": false,
          "feedback": "Erreur : la lenteur n'est pas la cause de\nl'imperfection. Même avec un temps infini,\naucun algorithme ne peut décider tous les\ncas.\n"
        },
        {
          "text": "Parce que les antivirus ne peuvent pas analyser un fichier",
          "correct": false,
          "feedback": "Erreur : ils peuvent l'analyser, mais ne\npeuvent pas en déduire avec certitude tout\nson comportement.\n"
        }
      ],
      "explanation": "Cet exemple est souvent cité pour illustrer les\n**conséquences pratiques** de l'indécidabilité.\nLes antivirus bons en pratique combinent\ndétection par signature, analyse comportementale\net apprentissage statistique, toujours sans\ngarantie absolue."
    },
    {
      "id": "q18",
      "difficulty": 2,
      "skills": [
        "exemple-decidable"
      ],
      "title": "Identifier des problèmes décidables",
      "partie": "notions",
      "statement": "On considère trois problèmes : (1) déterminer si un\nentier est premier ; (2) chercher si un caractère\napparaît dans une chaîne ; (3) déterminer si un programme\nquelconque finit par s'arrêter. Lesquels sont\n**décidables** ? Sélectionnez la proposition correcte.",
      "options": [
        {
          "text": "Les trois sont décidables",
          "correct": false,
          "feedback": "Erreur : le problème de l'arrêt est\nindécidable.\n"
        },
        {
          "text": "Les deux premières oui, le problème de l'arrêt non",
          "correct": true,
          "feedback": "Bonne réponse : les deux premières questions\nse résolvent par un algorithme simple et\nterminant ; la dernière est l'archétype du\nproblème indécidable.\n"
        },
        {
          "text": "Aucun de ces problèmes n'est décidable",
          "correct": false,
          "feedback": "Erreur : la primalité et la recherche d'un\ncaractère sont décidables.\n"
        },
        {
          "text": "Tous les problèmes énoncés en français sont décidables",
          "correct": false,
          "feedback": "Erreur : le langage de l'énoncé n'a aucun\nrapport avec la décidabilité.\n"
        }
      ],
      "explanation": "La frontière passe entre les questions\n**syntaxiques** ou portant sur des données\nfinies (souvent décidables) et les questions\nportant sur le **comportement** d'un programme\n(souvent indécidables)."
    },
    {
      "id": "q19",
      "difficulty": 3,
      "skills": [
        "terminaison-difficulte",
        "tests"
      ],
      "title": "Programme à terminaison non triviale",
      "partie": "arret",
      "statement": "Considérons le programme suivant qui prend en\nentrée un entier $n > 0$ :\n\n```python\nwhile n != 1:\n    if n % 2 == 0:\n        n = n // 2\n    else:\n        n = 3 * n + 1\n```\n\nNour l'exécute pour $n = 27$ : le programme s'arrête après $111$ passages dans la boucle. Laquelle des affirmations suivantes cet unique essai permet-il de **réfuter** ?",
      "options": [
        {
          "text": "Le programme ne s'arrête pour aucun entier impair",
          "correct": true,
          "feedback": "Bonne réponse : $27$ est impair et le programme s'arrête pour lui. Un seul contre-exemple suffit à réfuter une affirmation qui porte sur tous les entiers impairs.\n"
        },
        {
          "text": "Le programme s'arrête pour tout entier $n > 0$",
          "correct": false,
          "feedback": "Erreur : l'essai est compatible avec cette affirmation, mais ne la démontre pas. Aucun nombre fini d'essais réussis ne prouve qu'un programme s'arrête pour une infinité d'entrées.\n"
        },
        {
          "text": "Il existe un entier $n > 0$ pour lequel le programme ne s'arrête pas",
          "correct": false,
          "feedback": "Erreur : l'essai montre que $27$ n'est pas un tel entier, mais un autre entier pourrait l'être. Pour réfuter cette affirmation, il faudrait vérifier tous les entiers, ce qu'aucun test ne permet.\n"
        },
        {
          "text": "Le programme s'arrête pour tout entier pair",
          "correct": false,
          "feedback": "Erreur : l'essai porte sur $27$, un entier impair, et ne dit rien des entiers pairs. Cette affirmation n'est ni confirmée ni réfutée par cet essai.\n"
        }
      ],
      "explanation": "Un test peut réfuter une affirmation générale en exhibant un contre-exemple, mais il ne peut pas prouver qu'un programme s'arrête pour toutes les entrées. Même pour un programme de cinq lignes, prouver la terminaison peut être très difficile, et aucune méthode automatique ne s'applique à tous les programmes, puisque le problème de l'arrêt est indécidable."
    },
    {
      "id": "q20",
      "difficulty": 2,
      "skills": [
        "calculable-non-decidable"
      ],
      "title": "Une fonction non calculable",
      "partie": "notions",
      "statement": "Pourquoi la fonction « $f(P)$ vaut $1$ si le\nprogramme $P$ s'arrête sur l'entrée vide, $0$\nsinon » n'est-elle **pas calculable** ?",
      "options": [
        {
          "text": "Parce que les programmes ne sont pas tous écrits en Python",
          "correct": false,
          "feedback": "Erreur : la calculabilité est indépendante\ndu langage de programmation.\n"
        },
        {
          "text": "Parce qu'on ne sait pas représenter un programme comme une donnée",
          "correct": false,
          "feedback": "Erreur : on sait parfaitement représenter un\nprogramme comme une donnée (texte, octets...).\nC'est précisément le concept clé de la\ncalculabilité.\n"
        },
        {
          "text": "Parce que la fonction renvoie un entier",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec le type de\nsortie.\n"
        },
        {
          "text": "La calculer reviendrait à décider l'arrêt, impossible",
          "correct": true,
          "feedback": "Bonne réponse : tout algorithme calculant\n$f$ serait un décideur du problème de\nl'arrêt. Comme ce dernier est indécidable,\n$f$ n'est pas calculable.\n"
        }
      ],
      "explanation": "Toutes les fonctions « qui s'amusent à prédire\nle comportement » d'un programme arbitraire\ntendent à être non calculables. C'est l'écho\ndirect du théorème de Turing."
    },
    {
      "id": "q21",
      "difficulty": 2,
      "skills": [
        "histoire",
        "turing"
      ],
      "title": "Histoire : Alan Turing",
      "partie": "notions",
      "statement": "Quelle contribution majeure Alan Turing a-t-il\napportée en $1936$ ?",
      "options": [
        {
          "text": "Fonder la calculabilité, prouver l'arrêt indécidable",
          "correct": true,
          "feedback": "Bonne réponse : son article « On Computable\nNumbers » introduit la machine universelle\n(notion d'ordinateur programmable) et\ndémontre l'indécidabilité de l'arrêt.\n"
        },
        {
          "text": "Il a personnellement inventé tout le réseau Internet",
          "correct": false,
          "feedback": "Erreur : Internet est apparu dans les années\n1960-70 (ARPANET), bien après Turing.\n"
        },
        {
          "text": "Il a écrit le premier compilateur",
          "correct": false,
          "feedback": "Erreur : le premier compilateur est\ngénéralement attribué à Grace Hopper ($1952$).\n"
        },
        {
          "text": "Il a inventé le langage Python",
          "correct": false,
          "feedback": "Erreur : Python a été créé par Guido van\nRossum en $1991$, des décennies après\nTuring.\n"
        }
      ],
      "explanation": "Turing ($1912$-$1954$) est l'un des fondateurs\nde l'informatique théorique. Son article de 1936\nprécède même l'apparition des premiers\nordinateurs physiques."
    },
    {
      "id": "q22",
      "difficulty": 2,
      "skills": [
        "calculabilite-vs-complexite"
      ],
      "title": "Calculabilité et complexité",
      "partie": "notions",
      "statement": "Un problème **décidable** mais qui demande un\ntemps astronomique en pratique :",
      "options": [
        {
          "text": "Disparaît complètement automatiquement après quelques années",
          "correct": false,
          "feedback": "Erreur : la décidabilité et la\ncomplexité d'un problème sont des\npropriétés mathématiques. Elles ne\ndisparaissent ni avec le temps qui\npasse, ni avec les progrès matériels.\n"
        },
        {
          "text": "Il reste décidable, le temps n'entre pas en compte",
          "correct": true,
          "feedback": "Bonne réponse : un problème peut être\ndécidable et avoir une complexité telle que\nl'algorithme reste inutilisable en pratique.\nLa distinction calculable / décidable est\nséparée de la question de l'efficacité.\n"
        },
        {
          "text": "N'est plus un problème",
          "correct": false,
          "feedback": "Erreur : un problème difficile reste\nun problème. Sa décidabilité et sa\ncomplexité sont des résultats\nmathématiques permanents, qu'on sache\nou non le résoudre rapidement.\n"
        },
        {
          "text": "Devient indécidable",
          "correct": false,
          "feedback": "Erreur : l'indécidabilité signifie qu'aucun\nalgorithme **n'existe**, pas qu'il existe\nmais soit lent.\n"
        }
      ],
      "explanation": "Décidabilité et complexité sont deux questions\ndistinctes : la décidabilité demande s'il existe\nun algorithme ; la complexité demande à quel\ncoût (temps, mémoire). Un problème peut être\n« décidable mais inutilisable en pratique »."
    },
    {
      "id": "q24",
      "difficulty": 3,
      "skills": [
        "equivalence-langages"
      ],
      "title": "Langages équivalents",
      "partie": "notions",
      "statement": "Deux langages de programmation $A$ et $B$ sont\ndits **équivalents en calculabilité** si :",
      "options": [
        {
          "text": "Ils s'exécutent à la même vitesse",
          "correct": false,
          "feedback": "Erreur : la vitesse est une question de\ncomplexité, pas de calculabilité.\n"
        },
        {
          "text": "Ils sont compilés par le même compilateur",
          "correct": false,
          "feedback": "Erreur : le compilateur ne change pas la\npuissance du langage.\n"
        },
        {
          "text": "Les mêmes fonctions y sont calculables",
          "correct": true,
          "feedback": "Bonne réponse : tous les langages usuels\n(Python, C, Java, OCaml, Haskell…) sont\néquivalents en ce sens. C'est précisément\nce qui justifie qu'on parle de\n« calculabilité » sans préciser le langage.\n"
        },
        {
          "text": "Ils ont la même syntaxe",
          "correct": false,
          "feedback": "Erreur : la syntaxe peut être très\ndifférente entre deux langages équivalents.\n"
        }
      ],
      "explanation": "L'équivalence en calculabilité justifie\nl'expression « tout langage de programmation\nuniversel ». Quel que soit le langage choisi,\nles questions calculables et décidables sont\nles mêmes."
    },
    {
      "id": "q25",
      "difficulty": 3,
      "skills": [
        "synthese",
        "limites"
      ],
      "title": "Synthèse : Limites de la calculabilité",
      "partie": "arret",
      "statement": "Laquelle des affirmations suivantes résume le\nmieux l'apport de la calculabilité à\nl'informatique ?",
      "options": [
        {
          "text": "La calculabilité dépend du processeur utilisé",
          "correct": false,
          "feedback": "Erreur : elle est indépendante du matériel.\n"
        },
        {
          "text": "La calculabilité ne sert à rien dans la pratique",
          "correct": false,
          "feedback": "Erreur : elle éclaire la conception des\noutils d'analyse statique, des antivirus,\ndes compilateurs, etc.\n"
        },
        {
          "text": "Il existe des limites théoriques (1936) à ce qu'un ordinateur décide",
          "correct": true,
          "feedback": "Bonne réponse : la calculabilité fixe des\nfrontières que la technologie ne peut\nfranchir. Elle invite à concevoir des\nanalyses **incomplètes mais utiles**, et à\ncombiner outils automatiques, tests et\nrevues humaines.\n"
        },
        {
          "text": "Tout problème pourra finir par être résolu avec des ordinateurs assez puissants",
          "correct": false,
          "feedback": "Erreur : c'est précisément ce que l'indé-\ncidabilité réfute. Aucune puissance de\ncalcul ne suffit à résoudre un problème\nindécidable.\n"
        }
      ],
      "explanation": "La calculabilité est une boussole : elle dit ce\nqui est faisable algorithmiquement, ce qui ne\nl'est pas, et invite donc à choisir des\nstratégies pragmatiques (heuristiques, tests,\npreuves partielles) lorsqu'on touche aux\nlimites."
    },
    {
      "id": "q26",
      "difficulty": 2,
      "skills": [
        "exemple-frontiere"
      ],
      "title": "Frontière calculable / décidable / faisable",
      "partie": "notions",
      "statement": "Considérons les trois questions suivantes :\n(a) « Cet entier est-il pair ? », (b) « Existe-t-il\nun sous-ensemble d'une liste de cent entiers dont\nla somme vaut zéro ? », (c) « Ce programme\narbitraire s'arrête-t-il sur une entrée donnée ? ».\nComment se classent-elles ?",
      "options": [
        {
          "text": "Les trois sont indécidables",
          "correct": false,
          "feedback": "Erreur : (a) et (b) sont parfaitement\ndécidables. Pour (b), un algorithme de force\nbrute énumère tous les sous-ensembles, ce qui\ntermine toujours en temps fini.\n"
        },
        {
          "text": "Les trois sont décidables et faciles à résoudre",
          "correct": false,
          "feedback": "Erreur : (c) est indécidable, et (b), bien que décidable, demande par la méthode directe d'examiner jusqu'à $2^{100}$ sous-ensembles. Seule (a) est à la fois décidable et facile.\n"
        },
        {
          "text": "(a) facile, (b) indécidable, (c) décidable\n",
          "correct": false,
          "feedback": "Erreur : c'est exactement l'inverse pour (b)\net (c). (b) est décidable mais coûteux ; (c)\nest l'archétype de l'indécidable.\n"
        },
        {
          "text": "(a) facile, (b) décidable mais coûteux, (c) indécidable",
          "correct": true,
          "feedback": "Bonne réponse : (a) se résout par un simple test de parité. (b) est décidable : un algorithme qui énumère les $2^{100}$ sous-ensembles termine toujours, mais leur nombre rend ce calcul irréalisable en pratique. (c) est l'arrêt, démontré indécidable. Cette graduation montre que « décidable » ne signifie pas « facile ».\n"
        }
      ],
      "explanation": "Trois niveaux à distinguer : **décidable et faisable** (parité, tri) ; **décidable mais coûteux** (essayer tous les sous-ensembles d'une grande liste) ; **indécidable** (arrêt). La calculabilité dit si un algorithme existe ; le coût d'exécution dit ensuite s'il est utilisable en pratique."
    },
    {
      "id": "q27",
      "difficulty": 3,
      "skills": [
        "auto-reference-detail"
      ],
      "title": "L'argument d'auto-référence en pratique",
      "partie": "arret",
      "statement": "Supposons qu'on dispose d'un programme `arrete?(P, e)`\nqui répondrait toujours `True` ou `False`. Pour\nconstruire la contradiction, on définit :\n```python\ndef D(P):\n    if arrete?(P, P):\n        while True: pass\n    return\n```\nQue se passe-t-il quand on appelle `D(D)` ?",
      "options": [
        {
          "text": "Quelle que soit la réponse de `arrete?(D, D)`,\nle comportement réel de `D(D)` la contredit :\n`arrete?` ne peut donc pas exister\n",
          "correct": true,
          "feedback": "Bonne réponse : c'est le cœur de la preuve de\nTuring. Si `arrete?(D, D)` renvoie `True`,\n`D(D)` entre dans la boucle infinie au lieu de\ns'arrêter ; s'il renvoie `False`, `D(D)`\nrenvoie immédiatement au lieu de boucler. Dans\nles deux cas, la prédiction est démentie :\naucune valeur de retour ne peut être correcte,\ndonc la supposition initiale (existence\nd'`arrete?`) est fausse. C'est un raisonnement\npar l'absurde fondé sur l'auto-référence (`D`\nreçoit son propre code).\n"
        },
        {
          "text": "Le programme `arrete?` retournerait simplement\nune erreur, ce qui résoudrait la situation\n",
          "correct": false,
          "feedback": "Erreur : on suppose au départ que `arrete?`\nrépond **toujours** par `True` ou `False`,\njamais par une erreur. C'est précisément ce\nque la preuve montre impossible : un tel\noracle parfait ne peut exister.\n"
        },
        {
          "text": "Le programme `D(D)` ne pose aucun problème :\n`arrete?` répond simplement par défaut\n",
          "correct": false,
          "feedback": "Erreur : c'est précisément le piège. La\ncontradiction ne disparaît pas en choisissant\nune réponse par défaut. Quelle que soit la\nréponse de `arrete?(D, D)`, on construit un\nprogramme qui fait l'inverse, donc la\nprédiction est fausse.\n"
        },
        {
          "text": "La contradiction n'apparaît que si Python est\ncompilé, pas interprété\n",
          "correct": false,
          "feedback": "Erreur : le langage ou son mode d'exécution\nn'a aucun rôle. La preuve est mathématique et\nse transpose à n'importe quel langage de\nprogrammation universel.\n"
        }
      ],
      "explanation": "L'argument est un parent direct du paradoxe du\nmenteur (« cette phrase est fausse ») et du\nthéorème d'incomplétude de Gödel. L'auto-\nréférence permet de fabriquer un objet\ncontradictoire à partir de tout candidat\n« décideur universel », rendant son existence\nimpossible."
    },
    {
      "id": "q28",
      "difficulty": 2,
      "skills": [
        "arret",
        "cas-particulier",
        "indecidabilite"
      ],
      "title": "L'arrêt d'un programme donné",
      "partie": "arret",
      "statement": "Le problème de l'arrêt est indécidable. Peut-on malgré tout savoir\nsi ce programme s'arrête ?\n```python\ni = 0\nwhile i < 10:\n    i = i + 1\n```",
      "options": [
        {
          "text": "Oui, en dix tours ; l'indécidabilité vise le cas général",
          "correct": true,
          "feedback": "Bonne réponse : `i` augmente de un à chaque tour et atteint\n$10$. L'indécidabilité affirme qu'aucun procédé unique ne\ntranche pour tous les programmes, pas qu'aucun programme ne\npeut être jugé.\n"
        },
        {
          "text": "Non, aucun programme ne peut être jugé, le problème étant indécidable",
          "correct": false,
          "feedback": "Erreur : l'indécidabilité porte sur l'existence d'une méthode\ngénérale, pas sur chaque programme pris isolément.\n"
        },
        {
          "text": "Oui, mais seulement en l'exécutant, sans pouvoir le prouver",
          "correct": false,
          "feedback": "Erreur : un raisonnement sur la variable `i` prouve l'arrêt\nsans exécution.\n"
        },
        {
          "text": "Non, car la boucle `while` interdit toute conclusion",
          "correct": false,
          "feedback": "Erreur : une boucle `while` dont le compteur progresse vers la\nborne se termine, et on peut le démontrer.\n"
        }
      ],
      "explanation": "L'indécidabilité est une impossibilité générale : pour un programme\nparticulier, un raisonnement peut très bien établir l'arrêt."
    },
    {
      "id": "q29",
      "difficulty": 2,
      "skills": [
        "arret",
        "execution",
        "limite-de-temps"
      ],
      "title": "Exécuter pour savoir",
      "partie": "arret",
      "statement": "Pour savoir si un programme s'arrête, on l'exécute pendant une\nheure. Au bout de l'heure, il tourne encore. Qu'a-t-on appris ?",
      "options": [
        {
          "text": "Rien de certain, il peut s'arrêter plus tard ou jamais",
          "correct": true,
          "feedback": "Bonne réponse : l'exécution ne tranche que si le programme\ns'arrête. Tant qu'il tourne, les deux issues restent possibles,\net aucune durée d'attente ne lève le doute.\n"
        },
        {
          "text": "Qu'il ne s'arrêtera jamais, une heure étant largement suffisante",
          "correct": false,
          "feedback": "Erreur : certains programmes s'arrêtent après des jours ou des\nsiècles de calcul.\n"
        },
        {
          "text": "Qu'il s'arrêtera, tout programme finissant par terminer",
          "correct": false,
          "feedback": "Erreur : `while True: pass` ne termine jamais.\n"
        },
        {
          "text": "Qu'il contient une erreur de syntaxe non détectée",
          "correct": false,
          "feedback": "Erreur : une erreur de syntaxe empêche le lancement, elle ne\nfait pas tourner le programme.\n"
        }
      ],
      "explanation": "Simuler un programme permet de confirmer un arrêt, jamais d'établir\nun non-arrêt : c'est une des raisons de l'indécidabilité."
    },
    {
      "id": "q30",
      "difficulty": 2,
      "skills": [
        "arret",
        "equivalence",
        "indecidabilite"
      ],
      "title": "Deux programmes équivalents",
      "partie": "arret",
      "statement": "Existe-t-il un algorithme qui, pour deux programmes quelconques,\ndécide s'ils renvoient toujours le même résultat pour les mêmes\nentrées ?",
      "options": [
        {
          "text": "Non, ce problème est indécidable, comme celui de l'arrêt",
          "correct": true,
          "feedback": "Bonne réponse : s'il existait, on comparerait un programme\nquelconque à un programme qui ne s'arrête jamais, et l'on\nsaurait s'il s'arrête sur au moins une entrée, ce qui est\nimpossible. L'équivalence de programmes est indécidable.\n"
        },
        {
          "text": "Oui, en comparant les deux codes source ligne à ligne",
          "correct": false,
          "feedback": "Erreur : deux textes différents peuvent calculer la même\nchose, une boucle et une formule par exemple.\n"
        },
        {
          "text": "Oui, en les exécutant sur toutes les entrées possibles",
          "correct": false,
          "feedback": "Erreur : les entrées sont en nombre infini, l'exécution ne\nfinirait jamais.\n"
        },
        {
          "text": "Non, sauf si les deux programmes sont écrits dans le même langage",
          "correct": false,
          "feedback": "Erreur : le langage ne change rien, le problème reste\nindécidable.\n"
        }
      ],
      "explanation": "Beaucoup de questions sur le comportement des programmes se\nramènent au problème de l'arrêt et héritent de son indécidabilité."
    },
    {
      "id": "q31",
      "difficulty": 3,
      "skills": [
        "arret",
        "toutes-entrees",
        "reduction"
      ],
      "title": "S'arrêter sur toutes les entrées",
      "partie": "arret",
      "statement": "Le problème de l'arrêt porte sur un programme et une entrée\ndonnée. Le problème « ce programme s'arrête-t-il sur toutes les\nentrées ? » est-il décidable ?",
      "options": [
        {
          "text": "Non, il est indécidable lui aussi, sans algorithme général",
          "correct": true,
          "feedback": "Bonne réponse : pour un programme `p` et une entrée `x`, on\nconstruit un programme qui ignore son entrée et exécute `p`\nsur `x` ; il s'arrête sur toutes les entrées exactement quand\n`p` s'arrête sur `x`. Décider l'un déciderait l'autre.\n"
        },
        {
          "text": "Oui, il suffit de tester chaque entrée l'une après l'autre",
          "correct": false,
          "feedback": "Erreur : les entrées sont infinies, et une seule exécution qui\nne finit pas bloque le test.\n"
        },
        {
          "text": "Oui, car il est plus simple que le problème de l'arrêt",
          "correct": false,
          "feedback": "Erreur : il est au moins aussi difficile, puisqu'il permettrait\nde résoudre le problème de l'arrêt.\n"
        },
        {
          "text": "Non, mais il devient décidable pour les entrées entières",
          "correct": false,
          "feedback": "Erreur : la nature des entrées ne change rien, les entiers\nsuffisent à coder n'importe quelle donnée.\n"
        }
      ],
      "explanation": "La technique de réduction transfère l'indécidabilité : si résoudre\nun problème B permettait de résoudre le problème de l'arrêt, B\nest indécidable."
    },
    {
      "id": "q32",
      "difficulty": 2,
      "skills": [
        "arret",
        "langage-restreint",
        "boucles-bornees"
      ],
      "title": "Un langage sans boucle `while`",
      "partie": "arret",
      "statement": "Dans un langage sans récursivité, dont les seules boucles sont des\n`for` parcourant un `range` fixé avant la boucle, tout programme\ns'arrête. Le problème de l'arrêt y est-il décidable ?",
      "options": [
        {
          "text": "Oui, trivialement, mais ce langage ne peut pas tout calculer",
          "correct": true,
          "feedback": "Bonne réponse : la réponse est toujours « oui ». Le prix à payer\nest que ce langage ne peut pas exprimer toutes les fonctions\ncalculables, par exemple une recherche dont on ignore la durée.\n"
        },
        {
          "text": "Non, le problème de l'arrêt est indécidable dans tout langage",
          "correct": false,
          "feedback": "Erreur : l'indécidabilité vaut pour les langages capables de\ntout calculer, ce qui n'est pas le cas ici.\n"
        },
        {
          "text": "Oui, et ce langage est aussi puissant que Python",
          "correct": false,
          "feedback": "Erreur : s'il l'était, le problème de l'arrêt y serait\nindécidable.\n"
        },
        {
          "text": "Non, car les boucles `for` peuvent aussi être infinies",
          "correct": false,
          "feedback": "Erreur : un `for` sur un `range` fixé fait un nombre de tours\nconnu d'avance.\n"
        }
      ],
      "explanation": "Décidabilité de l'arrêt et puissance du langage vont en sens\ninverse : garantir la terminaison coûte des fonctions calculables."
    },
    {
      "id": "q33",
      "difficulty": 1,
      "skills": [
        "arret",
        "materiel",
        "limite-theorique"
      ],
      "title": "Un ordinateur plus puissant",
      "partie": "arret",
      "statement": "Un ordinateur mille fois plus rapide permettrait-il de résoudre\nle problème de l'arrêt ?",
      "options": [
        {
          "text": "Non, la limite est mathématique et non matérielle",
          "correct": true,
          "feedback": "Bonne réponse : la démonstration ne suppose rien sur la vitesse\nou la mémoire de la machine. Aucun progrès technique ne lève\nune impossibilité logique.\n"
        },
        {
          "text": "Oui, la vitesse permettant d'explorer tous les cas",
          "correct": false,
          "feedback": "Erreur : les cas sont en nombre infini, aucune vitesse finie ne\nles épuise.\n"
        },
        {
          "text": "Oui, à condition d'y ajouter assez de mémoire",
          "correct": false,
          "feedback": "Erreur : la mémoire n'intervient pas davantage dans\nl'impossibilité.\n"
        },
        {
          "text": "Non, mais un ordinateur quantique le résoudrait",
          "correct": false,
          "feedback": "Erreur : un ordinateur quantique calcule les mêmes fonctions,\nparfois plus vite ; il ne franchit pas la limite.\n"
        }
      ],
      "explanation": "Calculabilité et vitesse sont deux questions distinctes : la\npremière dit ce qui est possible, la seconde en combien de temps."
    },
    {
      "id": "q34",
      "difficulty": 1,
      "skills": [
        "notions",
        "decidable",
        "syntaxe"
      ],
      "title": "Une propriété du texte d'un programme",
      "partie": "notions",
      "statement": "Le problème « le texte de ce programme contient-il le mot-clé\n`while` ? » est-il décidable ?",
      "options": [
        {
          "text": "Oui, un parcours du texte source suffit à répondre",
          "correct": true,
          "feedback": "Bonne réponse : la question porte sur le texte, pas sur le\ncomportement. Une lecture du fichier répond en temps fini, pour\ntout programme.\n"
        },
        {
          "text": "Non, toute question sur un programme est indécidable",
          "correct": false,
          "feedback": "Erreur : seules certaines questions sur le comportement le\nsont ; les propriétés du texte se vérifient.\n"
        },
        {
          "text": "Oui, mais seulement en exécutant le programme",
          "correct": false,
          "feedback": "Erreur : nul besoin d'exécuter, il suffit de lire.\n"
        },
        {
          "text": "Non, sauf si le programme s'arrête sur toute entrée",
          "correct": false,
          "feedback": "Erreur : l'arrêt du programme n'a aucun rapport avec la\nprésence d'un mot dans son texte.\n"
        }
      ],
      "explanation": "Distinguer les propriétés syntaxiques, toujours décidables, des\npropriétés du comportement, souvent indécidables."
    },
    {
      "id": "q35",
      "difficulty": 2,
      "skills": [
        "notions",
        "enumeration",
        "programme-donnee"
      ],
      "title": "Lister tous les programmes",
      "partie": "notions",
      "statement": "Peut-on écrire un programme qui énumère, un par un, tous les\nprogrammes Python possibles ?",
      "options": [
        {
          "text": "Oui, ce sont des textes finis, énumérables par longueur",
          "correct": true,
          "feedback": "Bonne réponse : un programme est une suite finie de caractères\npris dans un alphabet fini. En engendrant les textes par\nlongueur croissante et en gardant ceux qui sont des programmes\nvalides, chacun finit par apparaître.\n"
        },
        {
          "text": "Non, car ils sont en nombre infini et ne peuvent être listés",
          "correct": false,
          "feedback": "Erreur : les entiers aussi sont infinis, et on sait les\nénumérer sans jamais finir.\n"
        },
        {
          "text": "Non, car un programme ne peut pas manipuler un programme",
          "correct": false,
          "feedback": "Erreur : un programme est une donnée comme une autre, un\ninterpréteur en manipule en permanence.\n"
        },
        {
          "text": "Oui, mais uniquement ceux dont on sait qu'ils s'arrêtent",
          "correct": false,
          "feedback": "Erreur : l'énumération porte sur les textes, sans rien\ndécider de leur comportement.\n"
        }
      ],
      "explanation": "Les programmes forment un ensemble dénombrable : cette remarque\nest au départ de la preuve qu'il existe des fonctions non\ncalculables."
    },
    {
      "id": "q36",
      "difficulty": 2,
      "skills": [
        "notions",
        "decidable",
        "nombre-fini"
      ],
      "title": "Un problème à un nombre fini de cas",
      "partie": "notions",
      "statement": "Un problème n'a que mille instances possibles. Est-il décidable ?",
      "options": [
        {
          "text": "Oui, une table des mille réponses constitue un algorithme",
          "correct": true,
          "feedback": "Bonne réponse : un algorithme qui cherche l'instance dans la\ntable et renvoie la réponse associée termine toujours. Il\nexiste, même si personne ne connaît encore son contenu.\n"
        },
        {
          "text": "Non, s'il faut une infinité d'étapes pour chaque cas",
          "correct": false,
          "feedback": "Erreur : la table répond en un nombre fini d'étapes, quel que\nsoit le cas.\n"
        },
        {
          "text": "Non, il peut être indécidable comme le problème de l'arrêt",
          "correct": false,
          "feedback": "Erreur : l'indécidabilité exige une infinité d'instances ; avec\nmille cas, la table existe.\n"
        },
        {
          "text": "Oui, seulement si les mille réponses sont connues aujourd'hui",
          "correct": false,
          "feedback": "Erreur : la décidabilité est l'existence d'un algorithme, pas\nle fait de le connaître.\n"
        }
      ],
      "explanation": "La décidabilité ne parle que d'existence : un problème fini est\ntoujours décidable, même quand on ignore quel algorithme le\nrésout."
    },
    {
      "id": "q37",
      "difficulty": 3,
      "skills": [
        "notions",
        "denombrable",
        "fonctions-non-calculables"
      ],
      "title": "Plus de fonctions que de programmes",
      "partie": "notions",
      "statement": "Les programmes forment un ensemble dénombrable, mais l'ensemble des\nfonctions des entiers vers les entiers ne l'est pas. Qu'en\ndéduit-on ?",
      "options": [
        {
          "text": "Qu'il existe des fonctions qu'aucun programme ne calcule",
          "correct": true,
          "feedback": "Bonne réponse : chaque programme calcule au plus une fonction.\nAvec moins de programmes que de fonctions, certaines fonctions\nne sont calculées par aucun programme.\n"
        },
        {
          "text": "Que chaque programme calcule plusieurs fonctions à la fois",
          "correct": false,
          "feedback": "Erreur : un programme calcule une seule fonction ; le\nraisonnement va dans l'autre sens.\n"
        },
        {
          "text": "Que les fonctions non calculables sont en nombre fini",
          "correct": false,
          "feedback": "Erreur : elles sont au contraire infiniment plus nombreuses que\nles calculables.\n"
        },
        {
          "text": "Rien, deux ensembles infinis ayant toujours la même taille",
          "correct": false,
          "feedback": "Erreur : il existe des infinis de tailles différentes, c'est\nprécisément le point.\n"
        }
      ],
      "explanation": "L'argument de dénombrement prouve l'existence de fonctions non\ncalculables sans en exhiber une ; le problème de l'arrêt en donne\nun exemple explicite."
    }
  ]
}