Dureté de calcul des programmes informatiques "réels"

10

J'ai souvent entendu dire que vous ne pouvez pas écrire un programme pour détecter les bogues dans un navigateur Web, un traitement de texte ou un système d'exploitation, à cause du théorème de Rice: toute propriété sémantique pour un langage complet de Turing est indécidable.

Cependant, je ne sais pas dans quelle mesure cela s'applique aux programmes du monde réel comme les systèmes d'exploitation. Ces types de programmes ont-ils besoin de toute la force de l'exhaustivité de Turing? Existe-t-il des modèles de calcul plus simples (tels que PR) dans lesquels ces applications pourraient être écrites? Si oui, dans quelle mesure cela permet-il de déterminer la justesse du programme?

David Harris
la source
vous ne pouvez pas vérifier les propriétés universelles non triviales (par exemple, quelque chose est valable pour toutes les entrées) de modèles beaucoup plus faibles, par exemple, vous ne pouvez pas vérifier si deux MT calculables polytime calculent la même fonction (bien que l'arrêt soit décidable pour elles car un TM polytime s'arrête toujours). D'un autre côté, si le domaine des entrées est borné, vous pouvez vérifier certaines propriétés dans certains modèles, par exemple le programme ne plante pas sur les entrées de taille inférieure à 1000, au moins en théorie (en pratique, il pourrait être intraitable).
Kaveh
question
Artem Kaznatcheev

Réponses:

14

Vous pouvez certainement écrire des programmes qui détectent des bogues - il existe une communauté importante et active de personnes qui écrivent des programmes pour faire exactement cela. Cependant, ce que le théorème de Rice vous empêche de faire est d'écrire des capteurs de bogues à la fois solides et complets (c'est-à-dire, attraper tous les bogues d'une certaine classe sans faux positifs).

Cela dit, les restrictions naïves sur le modèle de calcul ne vous aident pas vraiment beaucoup à améliorer le caractère pratique de l'analyse de programme. La raison en est que vous pouvez obtenir des programmes qui font "presque la même chose" en tournant les boucles while

while P do 
   C

en boucles for avec une grande constante d'itération:

for i = 0 to BIGNUM do 
  if P then 
    C
  else
    break

Maintenant, ce programme n'a même pas besoin de toute la puissance de la récursivité primitive (puisque la boucle for peut être macro-développée en une énorme instruction imbriquée if-then-else), mais dans la plupart des cas pratiques, elle se comportera de la même manière qu'auparavant. Notez que cela aide à la décidabilité en théorie - le programme est total, vous pouvez donc répondre aux questions en exécutant le programme et en voyant ce qui se passe. Ce n'est pas ce que nous voulons réellement, c'est d'obtenir des réponses plus rapidement que d'exécuter le programme - la terminaison artificielle introduite n'aide pas réellement l'analyse du programme dans la pratique, car les bogues se produisent en raison d'erreurs dans la logique réelle du programme, et nous n'avons pas '' t touché à tout cela.

De plus, l'ajout de fonctions d'abstraction à un langage de programmation peut radicalement aggraver la complexité du problème d'analyse, tout en facilitant la vérification des programmes dans la pratique. Par exemple, prouver la terminaison du calcul lambda simplement tapé avec des nombres naturels nécessite une induction jusqu'à , mais en ajoutant le polymorphisme de type, vous obtenez le système F, dont la preuve de terminaison est aussi forte que la cohérence de l'arithmétique de second ordre. Pourtant, dans la pratique, les programmes écrits en F sont beaucoup plus faciles à vérifier, car les propriétés de modularité de la quantification de second ordre facilitent l'écriture de programmes structurés et de preuves d'exactitude.ϵ0

Neel Krishnaswami
la source
Que voulez-vous dire par "ce programme n'est même pas récursif primitif"?
Ryan Williams
@RyanWilliams probablement juste qu'il peut être écrit dans un système qui autorise moins que le tableau complet des fonctions récursives primitives, par exemple des programmes qui ont besoin de limites explicites (temps de compilation) sur les boucles.
cody
Vous pouvez macro-étendre les boucles, vous laissant avec un programme de branchement (c'est-à-dire avec seulement si-alors-sinon et une composition séquentielle).
Neel Krishnaswami
Il serait peut-être plus clair de dire quelque chose comme "ce programme n'a même pas besoin de toute la force de la récursion primitive".
Max
@Max: suggestion acceptée!
Neel Krishnaswami
5

Puisque vous avez posé des questions sur l'exactitude des programmes des programmes du monde réel comme les systèmes d'exploitation, vous pourriez être intéressé par le projet seL4 ( journal , pdf , conférence ).

L'équipe NICTA a pris un micro-noyau de troisième génération de 8700 lignes de C et 600 lignes d'assembleur implémentées selon une spécification abstraite à Haskell. Ils ont fourni une preuve formelle et vérifiée par machine (dans Isabelle / HOL) que la mise en œuvre suit strictement les spécifications. Prouvant ainsi que leur programme est sans bug.

Donc, tout comme le problème d'arrêt, bien qu'il ne puisse pas être résolu en général, il peut être résolu pour certaines instances spécifiques. Dans ce cas, bien que vous ne puissiez pas prouver que le code C arbitraire est exempt de bogues, ils pourraient le faire dans le cas du micro-noyau seL4.

Artem Kaznatcheev
la source
Notez que le code certifié est toujours vulnérable aux erreurs dans ses spécifications, vous pouvez donc seulement dire que le code est exempt de bogues par rapport à la spécification.
nponeccop
@nponeccop est tout à fait vrai, mais lorsque vous commencez à douter de la spécification, vous commencez également à vraiment brouiller la fameuse ligne de fonctionnalités de bogues. Pour appeler quelque chose un `` bug '', vous devez avoir une spécification implicite à l'esprit, capturer l'intuition derrière une telle spécification implicite commence à creuser très profondément jusqu'à ce que vous posiez des questions sur les fondements de la philosophie des mathématiques (dans le style de Brouwer contre Hilbert) .
Artem Kaznatcheev
Par «spécification», j'entendais la spécification formelle, c'est-à-dire les théorèmes formels que vous prouvez. Vous pouvez toujours faire des erreurs en transformant vos exigences textuelles en théorèmes. Les seules choses que vous obtenez avec la certification sont la réduction de votre base de code de confiance (vous ne devez faire confiance qu'à vos théorèmes et non à votre code ou aux preuves) et la cohérence de votre code avec vos théorèmes.
nponeccop
Voici une citation du site Web seL4: «Le code C du micro-noyau seL4 implémente correctement le comportement décrit dans sa spécification abstraite et rien de plus.
nponeccop
2

Les questions que vous posez sont en fait assez différentes.

Cependant, je ne sais pas dans quelle mesure cela s'applique aux programmes du monde réel comme les systèmes d'exploitation. Ces types de programmes ont-ils besoin de toute la force de l'exhaustivité de Turing?

Il faut extrêmement peu de temps pour qu'un modèle de calcul soit complet. Par exemple, différents modèles avec compteurs peuvent simuler des machines de Turing. Si vous pensez que votre logiciel nécessite plus de deux compteurs que vous pouvez manipuler arbitrairement, vous utilisez un langage complet de Turing. Bien que les entiers machine soient bornés a priori, les structures de données allouées en tas ne le sont généralement pas. Si votre logiciel a besoin de listes, d'arbres et d'autres données allouées dynamiquement, vous utilisez un langage complet de Turing.

Existe-t-il des modèles de calcul plus simples (tels que PR) dans lesquels ces applications pourraient être écrites? Si oui, dans quelle mesure cela permet-il de déterminer la justesse du programme?

Il est important de reconnaître que nous ne voulons pas vérifier les propriétés arbitraires de notre logiciel. La vérification de propriétés très spécifiques et étroites (pas de débordements de tampon, pas de déréférences de pointeur nul, pas de boucles infinies, etc.) améliore énormément la qualité et l'utilisabilité du logiciel. En théorie, de tels problèmes sont encore indécidables. En pratique, se concentrer sur des propriétés spécifiques nous permet de découvrir dans nos programmes une structure que nous pouvons souvent exploiter pour résoudre le problème.

En particulier, vous pouvez modifier votre question d'origine en

Existe-t-il une abstraction de mon logiciel que je peux analyser efficacement dans un modèle complet non Turing?

Une abstraction est un modèle qui inclut le comportement du logiciel d'origine et éventuellement de nombreux comportements supplémentaires. Il existe des modèles tels que les machines à guichet unique ou les systèmes de refoulement qui ne sont pas complets et que nous pouvons analyser. L'approche standard de la vérification de programme avec des outils automatisés consiste à construire une abstraction dans un tel modèle et à la vérifier algorithmiquement.

Il existe des applications où les gens se soucient des propriétés sophistiquées de leur matériel ou de leurs logiciels. Les entreprises de matériel informatique souhaitent que leurs puces implémentent correctement des algorithmes arithmétiques, les entreprises automobiles et avioniques souhaitent des logiciels certes corrects. Si c'est si important, il vaut mieux utiliser un être humain (formé).

Vijay D
la source
Je pense que vous avez répondu à la question opposée, à savoir est-il possible qu'un traitement de texte soit Turing complet? Avec une gestion appropriée des registres, c'est le cas. Néanmoins, il est possible d'imposer des règles de manipulation des registres pour annuler l'exhaustivité de Turing. Ma question est de savoir combien vous pouvez programmer pratiquement dans ces contraintes étroites.
David Harris
Je répondais à la question de savoir si l'écriture de systèmes d'exploitation et d'autres logiciels d'application nécessite un langage de programmation complet Turing. Si vous avez besoin de plusieurs compteurs ou de structures de données illimitées, vous aurez besoin d'un langage de programmation complet Turing.
Vijay D
@Vijay: non, ce n'est pas vrai. Il existe de nombreuses théories de type (par exemple, Agda et Coq) qui sont toutes deux extrêmement expressives et ne permettent pas une récursion illimitée.
Neel Krishnaswami
@Neel: Pour clarifier, je ne parle que de l'exhaustivité de Turing. N'est-il pas possible de simuler une machine de Turing dans ces théories?
Vijay D
C'est vrai - ils ne sont pas Turing complets. Dans la logique constructive, la complétude de Turing permet de programmer un analogue du paradoxe de Russell.
Neel Krishnaswami