Théorème de Rice

From Wikipedia, the free encyclopedia

En informatique théorique, plus précisément en théorie de la calculabilité, le théorème de Rice énonce que toute propriété sémantique non triviale d'un programme est indécidable[1],[2],[3]. Le théorème de Rice généralise l'indécidabilité du problème de l'arrêt. Le théorème est devenu un classique[4],[5],[6],[7],[8],[9] et fait l'objet d'exercices dans certains ouvrages de théorie de la calculabilité[10]. Il a une certaine portée philosophique vis-à-vis de la calculabilité et est dû au logicien Henry Gordon Rice.

L'animation montre une machine impossible : d'après le théorème de Rice, il n'existe pas de machine qui lit des codes sources de fonctions et qui prédit si la fonction ne renvoie jamais un entier non nul.

Les propriétés sémantiques concernent le comportement d'un programme et s'opposent aux propriétés syntaxiques sur le code source du programme. Une propriété est non triviale si elle n'est ni vraie pour toute fonction calculable, ni fausse pour toute fonction calculable. La table suivante donne des exemples de propriétés non triviales syntaxiques et des propriétés non triviales sémantiques. Le théorème de Rice ne s'applique qu'aux propriétés sémantiques.

Propriétés syntaxiques (attention, le théorème de Rice ne s'applique pas) Propriétés sémantiques (et donc indécidables par le théorème de Rice)
  • « le programme ne rend jamais de valeurs nulles[3] »
  • « le programme ne termine jamais par une erreur d'exécution »
  • « le programme calcule le même résultat qu'un programme donné », autrement dit « le programme calcule une fonction calculable donnée ».
  • « le programme calcule un résultat correct par rapport à sa spécification » autrement dit « la fonction calculée par le programme est bien celle définie par la spécification ». C'est une variante du précédent.
  • « le programme contient un virus »
  • « le programme accède à un site Web »

Impact en vérification de programmes

Pour vérifier qu'un programme est correct, on peut recourir au test, y compris à des batteries de tests avec couverture de code. Mais comme l'a souligné Edsger Dijkstra « Le test de programmes peut être une façon très efficace de montrer la présence de bugs, mais est désespérément inadéquat pour prouver leur absence »[11].

La formulation pragmatique du théorème de Rice est qu'aucune méthode automatique d'analyse statique de programmes ne permet de décider, à partir du code source d'un programme, si la fonction qui associe les entrées à la sortie de ce programme satisfait ou non une propriété intéressante (non triviale) donnée.

En pratique, on adopte des stratégies pour contourner les limitations du théorème de Rice[12],[13] :

  1. Vérification de programmes avec seulement un nombre fini d'états.
  2. Méthode de vérification partiellement automatisée.
  3. Méthodes à base d'approximations.
  4. Méthodes restreignant l'ensemble des programmes sur lesquels on veut démontrer la propriété.
  5. Restrictions raisonnables de l'ensemble des fonctions calculables[14].

Ces stratégies ont donné lieu à différentes approches pour vérifier des programmes : l'interprétation abstraite, la vérification de modèles (model checking[15]) et la preuve semi-automatisée de programmes par assistant de preuve. Aucune de ces méthodes n'a une portée universelle. Des recherches en cours visent à étendre les domaines d'application des vérificateurs, donc à diminuer les restrictions citées ci-dessus, mais le théorème de Rice dit que le vérificateur absolu n'existe pas ou comme disait Frederick Brooks « il n'y a pas de balle en argent »[16].

Un cas particulier introductif : la fonction réalisée par un programme

Comme introduction au théorème de Rice, considérons le cas spécifique où la propriété du programme soumise à décision est le fait que le programme calcule une fonction donnée  ; on dit aussi que le programme « réalise » la fonction . Par rapport à ce que nous avons dit dans l'introduction et le premier paragraphe, la propriété à décider sur la fonction associée au programme est l'égalité à . Autrement dit, on veut savoir si la fonction calculée par le programme est la fonction ou non. Nous allons considérer trois cas de généralité croissante.

La fonction est la fonction nulle part définie

Si la fonction calculée par le programme est celle qui n'est pas définie, cela signifie que le programme ne se termine jamais, quelle que soit la valeur en entrée. Décider cette propriété n'est pas possible en application du théorème de l'indécidabilité de l'arrêt qui peut se formuler en disant qu'il n'y a pas d'algorithme pour décider si un programme réalise la fonction nulle part définie.

La fonction est la fonction carré

Supposons que nous souhaitions décider si un programme réalise la fonction carré, autrement dit, réalise la fonction . Il faut que nous puissions décider si le programme

programmeCarré_p (x) =
(x);
x * x

est un programme quelconque, calcule effectivement la fonction pour une valeur , sans être non défini sur . Pour décider si le programme programmeCarré_p calcule la fonction carré, il faut décider si se termine sur . Il faut donc décider l'arrêt de sur . C'est ni plus ni moins le problème de l'arrêt, qui, comme l'on sait, est indécidable. Donc décider si un programme calcule le carré de la valeur qu'on lui donne en entrée est indécidable.

La fonction est une fonction quelconque

On peut dans ce cas aussi ramener la décision de la fonction calculée par un programme pour une fonction quelconque au problème de l'arrêt, il suffit de remplacer x * x par (x), à savoir décider si le programme

truc_p (x) =
(x);
(x)

calcule la fonction . On en conclut donc qu'étant donnée une fonction , décider si un programme calcule la fonction est indécidable.

Différentes présentations

Démonstration du théorème de Rice

Notes et références

Related Articles

Wikiwand AI