{
  "chapter": {
    "id": "calculabilite",
    "level": "terminale",
    "theme": "Langages et 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).",
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "programme-donnee"
      ],
      "title": "Programme et donnée",
      "statement": "Pourquoi peut-on dire qu'**un programme est aussi une\ndonné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\nprogramme**, pas seulement chargé en mémoire.\n"
        },
        {
          "text": "Parce qu'un programme est stocké dans un fichier, manipulé, transmis et lu par d'autres programmes (compilateur, interpréteur, antivirus...) au même titre que n'importe quelle donnée",
          "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",
      "statement": "Lequel des exemples suivants illustre **un programme\nmanipulé 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",
      "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": "Il existe un algorithme qui, pour toute entrée valide, calcule $f$ en un nombre fini d'étapes",
          "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",
      "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",
      "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 peut être implémentée dans n'importe quel langage de programmation universel (Python, C, Java, OCaml...)",
          "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",
      "statement": "Qu'appelle-t-on un **problème décidable** ?",
      "options": [
        {
          "text": "Un problème pour lequel il existe un algorithme qui répond toujours « oui » ou « non » en un nombre fini d'étapes, pour toute instance",
          "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",
      "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",
      "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": "Un problème de décision pour lequel il n'existe aucun algorithme qui, pour toute entrée, donne une réponse correcte en temps fini",
          "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\nthé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",
      "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 ?",
          "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": "Existe-t-il un algorithme qui, pour tout couple (programme, entrée), répond « oui » si le programme s'arrête sur cette entrée, « non » s'il boucle indéfiniment ?",
          "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",
      "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",
      "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 » lui-même en utilisant le décideur sur sa propre entrée",
          "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",
      "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 écrire un programme qui détecte toutes les boucles infinies dans n'importe quel autre programme",
          "correct": true,
          "feedback": "Bonne réponse : aucune analyse statique ne\npourra repérer toutes les boucles infinies\nou tous les bugs de terminaison. C'est\npourquoi les tests, les revues de code et les\nassertions 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\nnombreuses autres propriétés : équivalence de\ndeux programmes, absence de bugs, terminaison sur\ntoutes les entrées, etc. Les outils d'analyse\nstatique sont donc nécessairement **incomplets**."
    },
    {
      "id": "q13",
      "difficulty": 2,
      "skills": [
        "calculable-vs-decidable"
      ],
      "title": "Calculable ou décidable",
      "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 » s'applique aux fonctions, « décidable » aux problèmes de décision (à réponse 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",
      "statement": "Pour **certains** programmes, on peut savoir\nfacilement s'ils s'arrêtent. Ce qui est\nindécidable, c'est :",
      "options": [
        {
          "text": "De le faire pour tous les programmes possibles, avec un seul algorithme 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",
      "statement": "L'idée d'**ordinateur universel** repose sur\nlaquelle des affirmations suivantes ?",
      "options": [
        {
          "text": "Un même dispositif peut exécuter n'importe quel programme, à condition de lui fournir le code de ce programme 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",
      "statement": "On peut écrire un interpréteur Python en Python\n(par exemple via la fonction `exec`). Que\nmontre 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 `exec` rend Python incalculable",
          "correct": false,
          "feedback": "Erreur : `exec` ne change rien aux capacités\nde calcul du langage ; il en illustre simplement\nl'aspect réflexif.\n"
        },
        {
          "text": "Que `exec` est une fonction obsolète",
          "correct": false,
          "feedback": "Erreur : `exec` est une fonction standard de\nPython, à utiliser avec précaution mais\ntoujours valide.\n"
        },
        {
          "text": "Qu'un programme peut prendre un autre programme comme donnée et l'exécuter, illustrant la dualité programme/donnée",
          "correct": true,
          "feedback": "Bonne réponse : la fonction `exec` traite le\ntexte d'un programme comme une donnée\nd'entrée et l'exécute. C'est l'expression\nconcrète de la dualité programme/donnée.\n"
        }
      ],
      "explanation": "Cette propriété, dite « réflexivité », existe dans\nla plupart des langages modernes (`eval` en\nJavaScript, en Lisp, etc.). Elle est cohérente\navec l'idée que les programmes sont des données."
    },
    {
      "id": "q17",
      "difficulty": 2,
      "skills": [
        "antivirus",
        "illustration"
      ],
      "title": "Détection de logiciels malveillants",
      "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": "Parce que reconnaître précisément le comportement d'un programme arbitraire est lié au problème de l'arrêt, qui est 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",
      "statement": "Parmi les problèmes suivants, lesquels sont\n**décidables** ? Sélectionnez la proposition\ncorrecte.",
      "options": [
        {
          "text": "Les trois sont décidables",
          "correct": false,
          "feedback": "Erreur : le problème de l'arrêt est\nindécidable.\n"
        },
        {
          "text": "« Cet entier est-il premier ? » et « cette chaîne contient-elle un point d'interrogation ? » sont décidables ; « ce programme s'arrête-t-il ? » ne l'est pas",
          "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"
      ],
      "title": "Programme à terminaison non triviale",
      "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\nQue peut-on dire de sa **terminaison** ?",
      "options": [
        {
          "text": "Personne ne sait, à ce jour, démontrer qu'il termine pour tout $n$ positif (conjecture de Syracuse)",
          "correct": true,
          "feedback": "Bonne réponse : c'est la suite de Syracuse\n(ou « 3$n$+1 »). Pour tous les entiers\ntestés, le programme termine, mais une\ndémonstration générale reste un problème\nmathématique ouvert.\n"
        },
        {
          "text": "Il termine en au plus $100$ étapes",
          "correct": false,
          "feedback": "Erreur : pour certains $n$ assez petits, le\nnombre d'étapes peut dépasser plusieurs\ncentaines.\n"
        },
        {
          "text": "Il termine si et seulement si $n$ est pair",
          "correct": false,
          "feedback": "Erreur : il termine aussi pour beaucoup\nd'entiers impairs (par exemple $n = 7$).\n"
        },
        {
          "text": "On a démontré qu'il ne termine jamais",
          "correct": false,
          "feedback": "Erreur : pour tous les entiers testés\nnumériquement, il termine.\n"
        }
      ],
      "explanation": "Cet exemple montre que prédire la terminaison\nd'un programme, même très court, peut être\nextrêmement difficile. Ce n'est pas surprenant :\nle problème général de l'arrêt est indécidable."
    },
    {
      "id": "q20",
      "difficulty": 2,
      "skills": [
        "calculable-non-decidable"
      ],
      "title": "Une fonction non calculable",
      "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": "Parce que la calculer reviendrait à décider le problème de l'arrêt, ce qui est impossible en général",
          "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",
      "statement": "Quelle contribution majeure Alan Turing a-t-il\napportée en $1936$ ?",
      "options": [
        {
          "text": "Il a posé les fondements de la calculabilité moderne et démontré l'indécidabilité du problème de l'arrêt",
          "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 inventé 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é",
      "statement": "Un problème **décidable** mais qui demande un\ntemps astronomique en pratique :",
      "options": [
        {
          "text": "Disparaît automatiquement après quelques années",
          "correct": false,
          "feedback": "L'indécidabilité est un\nrésultat mathématique\nintemporel, prouvé une fois\npour toutes. Elle ne dépend\nni du temps qui passe, ni\ndes progrès matériels.\n"
        },
        {
          "text": "Reste décidable. La calculabilité ne dit rien sur le temps d'exécution",
          "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": "Un problème indécidable\nreste un problème, même\nsi on en connaît une partie\ndu domaine. L'indécidabilité\nest un résultat mathématique\npermanent.\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": "q23",
      "difficulty": 3,
      "skills": [
        "auto-reference"
      ],
      "title": "Programme qui lit son propre code",
      "statement": "Pourquoi est-il important, en théorie de la\ncalculabilité, qu'un programme **puisse lire ou\nmanipuler son propre code source** ?",
      "options": [
        {
          "text": "Parce que c'est l'auto-référence qui rend possible l'argument d'indécidabilité du problème de l'arrêt",
          "correct": true,
          "feedback": "Bonne réponse : l'argument de Turing\nconstruit un programme qui interroge le\ndécideur d'arrêt à propos de **lui-même**.\nSans auto-référence, le raisonnement par\nl'absurde ne fonctionnerait pas.\n"
        },
        {
          "text": "Parce que cela permet d'écrire des programmes plus rapides",
          "correct": false,
          "feedback": "Erreur : aucun rapport direct avec la\nperformance.\n"
        },
        {
          "text": "Parce que cela rend les programmes immortels",
          "correct": false,
          "feedback": "La durée de vie d'un\nprogramme dépend de\nl'environnement d'exécution\net de la maintenance, pas\nde sa capacité à manipuler\nson propre code source.\n"
        },
        {
          "text": "Parce que cela évite les bugs",
          "correct": false,
          "feedback": "Manipuler son propre code\nn'évite pas les bugs : c'est\nun mécanisme théorique\nd'auto-référence, sans lien\navec la qualité logicielle.\n"
        }
      ],
      "explanation": "L'auto-référence est un thème récurrent en\nmathématiques (paradoxe du menteur, théorème de\nGödel) et en informatique théorique. Elle est\nau cœur des grandes limitations de la\ncalculabilité."
    },
    {
      "id": "q24",
      "difficulty": 3,
      "skills": [
        "equivalence-langages"
      ],
      "title": "Langages équivalents",
      "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": "Toute fonction calculable dans $A$ l'est aussi dans $B$, et réciproquement",
          "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é",
      "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, démontrées dès $1936$, à ce qu'un ordinateur peut décider, indépendamment de sa puissance ou du langage utilisé",
          "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",
      "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",
          "correct": false,
          "feedback": "Erreur : (c) est indécidable, (b) n'a pas de\nsolution efficace connue (NP-complet). Seule\n(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) décidable et facile, (b) décidable mais\npotentiellement coûteux à résoudre, (c)\nindécidable\n",
          "correct": true,
          "feedback": "Bonne réponse : (a) est résolu en $O(1)$ avec\nun test de parité. (b) est le problème de la\nsomme partielle, NP-complet : décidable\n(existence d'un algorithme qui termine\ntoujours), mais sans algorithme polynomial\nconnu, donc lourd en pratique pour de grandes\nlistes. (c) est l'arrêt, démontré indécidable.\nCette graduation montre que « décidable » ne\nsignifie pas « facile ».\n"
        }
      ],
      "explanation": "Trois niveaux à distinguer : **décidable et\nfaisable** (parité, primalité, tri) ; **décidable\nmais coûteux** (sac à dos, voyageur de\ncommerce) ; **indécidable** (arrêt, équivalence\nsémantique de programmes). La calculabilité\ntranche le binaire « algorithme existe ou\npas » ; la complexité affine selon le coût."
    },
    {
      "id": "q27",
      "difficulty": 3,
      "skills": [
        "auto-reference-detail"
      ],
      "title": "L'argument d'auto-référence en pratique",
      "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```\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": "Si `arrete?(D, D)` renvoie `True`, alors `D(D)`\ndevrait s'arrêter selon la prédiction, mais le\ncode entre dans la boucle infinie : contradiction.\nSi `arrete?(D, D)` renvoie `False`, alors\n`D(D)` ne devrait pas s'arrêter, mais le code\nrenvoie immédiatement : contradiction. La\ndouble contradiction prouve que `arrete?` ne\npeut exister\n",
          "correct": true,
          "feedback": "Bonne réponse : c'est le cœur de la preuve de\nTuring. Quel que soit ce que `arrete?` répond\nsur `(D, D)`, le programme `D` fait\nprécisément l'inverse de ce qui est prédit.\nAucune valeur de retour ne peut donc être\ncorrecte. La supposition initiale (existence\nd'`arrete?`) est donc fausse. C'est un\nraisonnement par l'absurde fondé sur l'auto-\nréférence (`D` reç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."
    }
  ]
}