web-dev-qa-db-fra.com

Qu'est-ce qui rend un langage Turing-complet?

Quel est l'ensemble minimal de fonctionnalités/structures de langage qui le rendent Turing-complet?

83
Curious Cat

A Turing tarpit est une sorte de langage de programmation ésotérique qui s'efforce d'être complet à Turing tout en utilisant le moins d'éléments possible. Brainfuck est peut-être le tarpit le plus connu, mais il y en a beaucoup.

  • Iota et Jot sont des langages fonctionnels avec deux et trois symboles, respectivement, basés sur le SK (I) combinator calculus .

  • OISC ( One Instruction Set Computer ) désigne un type de calcul impératif qui ne nécessite qu'une seule instruction d'un ou plusieurs arguments, généralement " soustraire et ramifier si inférieur ou égal à zéro "ou" inverser soustraire et sauter si emprunter ". Le x86 MM implémente l'ancienne instruction et est donc Turing-complete.

En général, pour qu'un langage impératif soit Turing-complet, il faut:

  1. Une forme de répétition conditionnelle ou de saut conditionnel (par exemple, while, if + goto)

  2. Un moyen de lire et d'écrire une forme de stockage (par exemple, des variables, une bande)

Pour qu'un langage fonctionnel basé sur lambda-calcul soit TC, il faut:

  1. La capacité d'abstraire des fonctions sur des arguments (par exemple, abstraction lambda, citation)

  2. La possibilité d'appliquer des fonctions aux arguments (par exemple, la réduction)

Il existe bien sûr d'autres façons de voir le calcul, mais ce sont des modèles courants pour les tarpits de Turing. Notez que les vrais ordinateurs ne sont pas pas machines de Turing universelles car ils n'ont pas de stockage illimité. À proprement parler, ce sont des "machines de stockage délimitées". Si vous continuiez à leur ajouter de la mémoire, ils approcheraient asymptotiquement les machines Turing au pouvoir. Cependant, même les machines de stockage bornées et machines à états finis sont utiles pour le calcul; ils ne sont tout simplement pas universels .

À strictement parler, les E/S ne sont pas nécessaires pour que Turing soit complet; TC affirme seulement qu'un langage peut calculer la fonction que vous voulez, pas qu'il puisse afficher vous le résultat. Dans la pratique, chaque langue utile a une façon d'interagir avec le monde.

74
Jon Purdy

D'un point de vue plus pratique: si vous pouvez traduire tous les programmes dans une langue Turing-complete dans votre langue, alors (pour autant que je sache), votre langue doit être Turing-complete. Par conséquent, si vous voulez vérifier si un langage que vous avez conçu est complet pour Turing, vous pouvez simplement écrire un Brainf *** dans le compilateur YourLanguage et prouver/démontrer qu'il peut compiler tous les programmes BF légaux.

Pour clarifier, je veux dire qu'en plus d'un interpréteur pour YourLanguage, vous écrivez un compilateur (dans n'importe quelle langue) qui peut compiler n'importe quel programme BF dans YourLanguage (en gardant la même sémantique, bien sûr).

15
Anton Golov

Un système ne peut être considéré comme Turing complet que s'il peut faire tout ce que peut faire une machine de Turing universelle. Étant donné que la machine universelle de Turing est censée être capable de résoudre n'importe quelle fonction calculable dans le temps, les systèmes complets de Turing peuvent, par extension, également le faire.

Pour vérifier si quelque chose est Turing complet, voyez si vous pouvez implémenter une machine Turing à l'intérieur. En d'autres termes, vérifiez s'il peut simuler les éléments suivants:

  1. La capacité de lire et d'écrire des "variables" (ou des données arbitraires): Assez explicite.
  2. La possibilité de simuler le déplacement de la tête de lecture/écriture: Il ne suffit pas de pouvoir simplement récupérer et stocker des variables. Il doit également être possible de simuler la possibilité de déplacer la tête de bande afin de référencer d'autres variables. Cela peut souvent être simulé dans les langages de programmation avec l'utilisation de structures de données de tableau (ou équivalent) ou, dans le cas de certains langages tels que le code machine, la possibilité de référencer d'autres variables grâce à l'utilisation de "pointeurs" (ou équivalent).
  3. La capacité de simuler une machine à états finis: Bien que cela ne soit pas souvent mentionné, les machines de Turing sont en fait une variation des machines à états finis souvent utilisées dans le développement de l'IA. Alan Turing a déclaré que le but des États est de simuler les "différents modes de résolution de problèmes" d'une personne.
  4. n état "arrêt": Bien qu'il soit souvent mentionné qu'un ensemble de règles doit pouvoir se répéter pour être considéré comme Turing complet, ce n'est pas vraiment un bon critère depuis la définition formelle de ce un algorithme est un état que les algorithmes doivent toujours finir par conclure. S'ils ne peuvent pas conclure d'une manière ou d'une autre, ce n'est pas Turing complet ou ledit algorithme n'est pas une fonction calculable. Turing des systèmes complets qui ne peuvent techniquement pas se conclure en raison de leur façon de travailler (comme les consoles de jeux, par exemple) contournent cette limitation en étant capables de "simuler" un état d'arrêt d'une manière ou d'une autre. À ne pas confondre avec le "problème d'arrêt", une fonction indécidable qui prouve qu'il est impossible de construire un système qui pourrait détecter avec une fiabilité à 100% si une entrée donnée entraînerait la non-conclusion d'un autre système.

Ce sont les véritables exigences minimales pour qu'un système soit considéré comme Turing complet. Ni plus ni moins. S'il ne peut simuler aucun de ces éléments d'une certaine manière, ce n'est pas Turing complet. Les méthodes proposées par d'autres personnes ne sont que des moyens pour la fin car il existe plusieurs systèmes complets Turing qui n'ont pas ces fonctionnalités.

Notez qu'il n'y a aucun moyen connu de construire un véritable système complet de Turing. En effet, il n'existe aucun moyen connu de simuler véritablement l'infinité de la bande de la machine de Turing dans l'espace physique.

8
user3067516

Une condition nécessaire est une boucle avec un nombre d'itérations maximum qui n'est pas déterminé avant l'itération, ou une récursion où la profondeur de récursivité maximum n'est pas déterminée avant. Par exemple, pour les boucles ... in ... telles que vous les trouvez dans de nombreuses langues plus récentes, elles sont pas suffisantes pour rendre la langue complète (mais elles auront d'autres moyens). Notez que cela ne signifie pas un nombre limité d'itérations ou une profondeur de récursivité limitée, mais que les itérations et la profondeur de récursivité maximales doivent être calculées à l'avance.

Par exemple, la fonction Ackermann ne peut pas être calculée dans un langage sans ces fonctionnalités. D'un autre côté, de nombreux logiciels très complexes et très utiles peuvent être écrits sans nécessiter ces fonctionnalités.

D'un autre côté, avec chaque nombre d'itérations et chaque profondeur de récursion calculés à l'avance, non seulement on peut décider si un programme va s'arrêter ou non, mais il va s'arrêter.

4
gnasher729

Un langage de programmation est complet si vous pouvez faire n'importe quel calcul avec lui. Il n'y a pas qu'un seul ensemble de fonctionnalités qui rend une turing de langue complète, donc les réponses disant que vous avez besoin de boucles ou que vous avez besoin de variables sont fausses car il y a des langues qui n'a ni mais sont turing complètes.

Alan Turing a fait la machine de turing universelle et si vous pouvez traduire n'importe quel programme conçu pour fonctionner sur la machine universelle pour fonctionner sur votre langue, c'est aussi Turing complet. Cela fonctionne également indirectement pour que vous puissiez dire que la langue X est complète si tous les programmes pour la langue complète T peuvent être traduits pour X car tous les programmes de machine de turing universels peuvent être traduits en un programme Y.

La complexité temporelle, la complexité de l'espace, la facilité de format d'entrée/sortie et la facilité d'écriture de tout programme ne sont pas incluses dans l'équation, de sorte que cette machine peut théoriquement faire tous les calculs si les calculs ne sont pas interrompus par une perte de puissance ou la Terre avalée par le Soleil.

Habituellement, pour prouver l'intégralité de turing, ils font un interprète pour toute langue éprouvée comme turing complète, mais pour que cela fonctionne, vous avez besoin de moyens d'entrée et de sortie, deux choses qui ne sont vraiment pas nécessaires pour qu'une langue soit complète. Il suffit que votre programme puisse modifier son état au démarrage et que vous puissiez inspecter la mémoire une fois le programme arrêté.

Pour réussir un langage, il faut bien plus que l'exhaustivité de turing et cela est vrai même pour les bâches de turing. Je ne pense pas que BrainFuck aurait été populaire sans , et ..

4
Sylwester

Vous ne pouvez pas dire s'il va boucler indéfiniment ou s'arrêter.

-------------

Explication: Compte tenu de certaines entrées, il est impossible de dire dans tous les cas (en utilisant une autre machine Turing) si la chose va boucler à l'infini ou va finalement s'arrêter, sauf en l'exécutant (ce qui vous donne une réponse si elle s'arrête, mais pas s'il boucle!).

Cela signifie que vous devez être en mesure de stocker une quantité de données potentiellement illimitée d'une manière ou d'une autre - il doit y avoir un équivalent à la bande infinie, quelle que soit la complexité! (Sinon, il n'y a qu'un nombre fini d'états et vous pouvez ensuite vérifier si vous avez déjà traversé cet état et éventuellement vous arrêter). Généralement, les machines Turing peuvent augmenter ou réduire la taille de leur état par certains moyens contrôlables.

Étant donné que la machine Turing universelle originale de Turing a un problème d'arrêt insoluble, votre propre machine complète Turing doit également avoir un problème d'arrêt insoluble.

Les systèmes complets Turing peuvent émuler n'importe quel autre système complet Turing, donc si vous pouvez construire un émulateur pour un système complet Turing bien connu dans votre système, cela prouve que votre système est également Turing complet.

Par exemple, supposons que vous vouliez prouver que Snakes & Ladders est Turing complet, étant donné un tableau avec un motif de grille répété à l'infini (avec une version différente en haut et à gauche). Sachant que la machine Minsky à 2 compteurs est Turing complète (qui a 2 compteurs illimités et 1 état sur un nombre fini), vous pouvez construire une carte équivalente où la position X et Y sur la grille est la valeur actuelle des 2 compteurs et le chemin actuel est l'état actuel. Coup! Vous venez de prouver que Snakes & Ladders sont Turing complet.

4
Hubert Lamontagne