"Alan Turing a prouvé en 1936 qu'un algorithme général pour résoudre le problème d'arrêt pour toutes les paires d'entrée de programme possibles ne pouvait pas exister"
Puis-je trouver un algorithme général pour résoudre le problème d'arrêt pour certaines paires d'entrée de programme possibles?
Puis-je trouver un ou plusieurs langages de programmation, où pour chaque type de programme dans ce langage, il peut décider si le programme se termine ou s’exécute pour toujours?
Réponses:
Oui bien sûr. Par exemple, vous pouvez écrire un algorithme qui renvoie "Oui, il se termine" pour tout programme qui ne contient ni boucles ni récursivité et "Non, il ne se termine pas" pour tout programme qui contient une
while(true)
boucle qui sera certainement atteinte et ne contient pas une déclaration de pause et "Dunno" pour tout le reste.Pas si cette langue est Turing-complete, non.
Cependant, il existe des langages complets non Turing comme par exemple Coq , Agda ou Microsoft Dafny pour lesquels le problème d'arrêt est décidable (et en fait est décidé par leurs systèmes de types respectifs, ce qui en fait un total de langues (c'est-à-dire qu'un programme qui pourrait ne pas se terminer ne sera pas compiler)).
la source
Je pense que toutes les réponses ici manquent complètement et complètement le point. La réponse à la question est: en supposant que le programme est destiné à s'arrêter, alors oui, vous feriez mieux de pouvoir montrer qu'il s'arrête. Si vous ne pouvez pas montrer qu'il s'arrête facilement, le programme doit être considéré comme très mal écrit et rejeté par le contrôle qualité en tant que tel.
La possibilité d'écrire un algorithme machine approprié dépend du langage de programmation d'entrée et de votre ambition. C'est un objectif de conception raisonnable pour un langage de programmation de permettre facilement de prouver la terminaison.
Si le langage est C ++, vous ne pouvez probablement pas écrire l'outil, en effet, il est peu probable que vous lanciez l'analyseur, et encore moins prouviez la terminaison. Pour un langage mieux structuré, vous devriez au moins pouvoir générer une preuve, ou du moins le faire avec certaines hypothèses: dans ce dernier cas, l'outil devrait sortir ces hypothèses. Une approche similaire consisterait à inclure les assertions de terminaison dans la langue et à les utiliser dans des situations complexes où l'outil ferait confiance aux assertions.
L'essentiel est que personne ne semble comprendre que la preuve qu'un programme s'arrête est en effet possible parce que les (bons) programmeurs ayant l'intention d'écrire de tels programmes d'arrêt le font toujours intentionnellement et avec une image mentale des raisons pour lesquelles ils se terminent et agissent correctement: un tel code est délibérément écrit de sorte qu'il est clair qu'ils s'arrêtent et sont corrects et si un algorithme raisonnable ne peut pas le prouver, éventuellement avec quelques indices, alors le programme doit être rejeté.
Le point: les programmeurs n'écrivent pas de programmes arbitraires, donc la thèse du théorème d'arrêt n'est pas satisfaite et la conclusion ne s'applique pas.
la source
excellente et (probablement involontairement profonde) question. il existe en effet des programmes de détection d'arrêt qui peuvent réussir sur des ensembles limités d'entrées. c'est un domaine de recherche actif. il a des liens très forts avec les domaines de démonstration de théorèmes (automatisés).
cependant, l'informatique ne semble pas avoir de terme exact pour désigner les «programmes» qui réussissent «parfois». le mot "algorithme" est généralement réservé aux programmes qui s'arrêtent toujours.
le concept semble être nettement différent des algorithmes probabilistes où les théoriciens CS insistent sur le fait qu'il existe une probabilité connue ou calculable de leur réussite.
il existe un terme semi - algorithmes qui est parfois utilisé, mais c'est apparemment un synonyme de récursivement énumérable ou non calculable.
donc à des fins ici, appelez-les algorithmes quasi-aléatoires . le concept est différent de décidable vs indécidable.
dans CS, cette "quasi-hiérarchie d'algorithmes" semble être étudiée jusqu'à présent uniquement de manière informelle.
il apparaît dans la recherche sur les castors occupés [1] et le problème PCP [2]. en fait, une attaque informatique basée sur l'ADN sur PCP peut être considérée comme un algorithme quasi-complet [3]. et son vu dans d'autres domaines déjà notés tels que la preuve de théorème [4].
[1] Nouvelle attaque du millénaire contre le problème du castor occupé
[2] Tackling Posts correspondance problem by Zhao (v2?)
[3] Utiliser l'ADN pour résoudre le problème de la correspondance post-bornée par Kari et al
[4] prouver la fin du programme par Cook et al, Comm. de l'ACM
(donc c'est en fait une question très profonde qui mérite d'être sur TCS.SE à mon humble avis ... peut-être que quelqu'un peut la poser à nouveau de manière à ce qu'elle s'adapte et reste)
la source
Tant que le langage de programmation en question est suffisamment complexe (c'est-à-dire s'il est Turing complet), alors il y a toujours des programmes dans le langage qu'aucun programme ne peut prouver pour terminer.
Étant donné que tous les langages, sauf les plus primitifs, sont Turing complet (cela ne prend que des variables et des conditions), vous ne pouvez vraiment créer que de très petits langages jouets pour lesquels vous pouvez résoudre le problème d'arrêt.Edit: À la lumière des commentaires, permettez-moi d'être plus explicite: Toute langue que vous pourriez concevoir pour laquelle vous pourriez résoudre le problème d'arrêt devrait nécessairement être Turing-incomplète. Cela exclut tout langage contenant un ensemble approprié d'ingrédients de base (par exemple, "variables, conditions et sauts", ou, comme le dit @ sepp2k, une boucle "while" générique).
Apparemment, il existe plusieurs langages pratiques "simples" comme celui-ci (par exemple les solveurs de théorèmes tels que Coq et Agda). Si ceux-ci satisfont à votre notion de "langage de programmation", vous pouvez rechercher s'ils satisfont à une sorte d'exhaustivité, ou si le problème d'arrêt est résoluble pour eux.
la source
C'est assez banal. Si nous prenons l'union de n'importe quel sous-ensemble ce de TM en arrêt et tout sous-ensemble ce de TM sans arrêt, le résultat sera un ensemble de MT pour lesquelles le problème d'arrêt est décidable (exécutez les deux machines en parallèle, si le premier accepte le TM s'arrête, si le second accepte alors la machine ne s'arrête pas). Cependant, cela ne conduira pas à des langues très intéressantes.
la source
Oui, vous pouvez, mais je doute que ce sera utile. Vous devrez probablement le faire par analyse de cas et vous ne pourrez alors rechercher que les cas les plus évidents. Par exemple, vous pouvez grep un fichier pour le code
while(true){}
. Si le fichier contient ce code, il ne se terminera jamais ^. Plus généralement, vous pourriez dire qu'un programme sans boucle ni récursivité se terminera toujours et il y a plusieurs cas que vous pourriez faire qui pourraient garantir qu'un programme se terminera ou ne se terminera pas, mais même pour un programme de taille moyenne, ce serait très difficile et dans de nombreux cas, ne serait pas en mesure de vous donner une réponse.tl; dr: Oui, mais vous ne pourrez pas l'utiliser pour la plupart des programmes utiles.
^ Oui, techniquement, si ce code n'est pas sur le chemin de code ou s'il y a d'autres threads, il pourrait toujours se terminer, mais je fais une remarque générale ici.
la source