• Aucun résultat trouvé

Langage de haut niveau

Dans le document COMPLEXITÉ ALGORITHMIQUE (Page 47-51)

Le modèle de calcul

1.2 La machine de Turing

1.2.4 Langage de haut niveau

Un peu de recul

Les exemples et résultats qui précèdent illustrent la grande difficulté de définir des ma-chines de Turing pour des opérations pourtant très simples. Pour la suite, la machine de Turing nous servira pour définir proprement les concepts mais nous utiliserons plutôt un langage bien plus compréhensible pour décrire nos algorithmes. Ce chapitre doit nous convaincre que ce langage peut être exécuté par des machines de Turing. Il s’agit d’une

28 Chapitre 1. Le modèle de calcul

des particularités de la complexité (et de la calculabilité) : définir un modèle de calcul basique pour l’oublier ensuite au profit d’un langage plus commode.

Pour décrire un algorithme nous utiliserons dorénavant un langage de haut niveau comme on en a l’habitude, avec des instructions conditionnelles, des boucles, des variables, etc.

Il faut donc montrer que ces instructions sont réalisables par une machine de Turing. La proposition suivante est informelle et la preuve est à peine esquissée : nous invitons le lecteur à se convaincre par lui-même qu’une machine de Turing est capable de simuler tout programme qu’on pourrait écrire sur un ordinateur.

1-U Proposition (informelle)

Tout programme écrit dans un langage composé de variables entièresxi (en nombre non borné), d’opérations d’affectation, d’addition+et de multiplication×, de tests d’éga-lité=et d’inégalité, d’instructions conditionnellessi...alors...sinonet de boucles tant que, peut être simulé par une machine de Turing.

Idée de la démonstration On associe à chaque ligne du programme un certain nombre d’états qui permettront de réaliser l’instruction correspondante. Un ruban de travail sera consacré au stockage des variables : ce ruban contiendrax1#x2# . . . #xm, c’est-à-dire les valeurs des variables codées en binaire et séparées par des symboles#.

L’affectation d’une valeur dans une variable consiste en la recopie au bon endroit de la valeur sur le ruban stockant les variables. Pour cela, il peut être nécessaire de décaler une partie du ruban vers la gauche ou vers la droite pour libérer des cases, ce qui se fait en décalant les cases une par une.

Pour réaliser une addition, il s’agit d’abord d’amener la tête sur la première variable à ajouter, de copier la valeur sur un ruban de travail auxiliaire, de se positionner sur la seconde variable et d’effectuer l’addition comme expliqué à l’exemple1-J. On réalise une multiplication de manière similaire.

Décider l’égalité de deux valeurs revient à les comparer chiffre à chiffre en effectuant des allers-retours entre elles. Pour un test d’inégalité, il suffit d’abord de comparer le nombre de chiffres des valeurs puis, en cas d’égalité, de comparer les valeurs chiffre à chiffre en partant des bits de poids forts.

Une instruction conditionnelle revient simplement à évaluer un test puis à changer d’état en fonction du résultat pour exécuter la bonne instruction. De même, une bouclewhile n’est rien de plus qu’un test suivi d’un changement d’état, soit pour

revenir au début de la boucle, soit pour en sortir. ⊓⊔

1-V Remarque Lors de la traduction de ce langage de haut niveau vers une ma-chine de Turing, il faut garder à l’esprit que les opérations d’affectation, d’addition et de comparaison prendront sur la machine de Turing un temps linéaire en la taille binaire des

1.2. La machine de Turing 29 entiers manipulés, et que la multiplication prendra un temps quadratique : contrairement à ce que laisse penser le langage de haut niveau, ce ne sont pas des opérations unitaires.

Nous utiliserons les mots-clésaccepteretrejeterpour signifier que la machine entre dans un état acceptant ou rejetant respectivement. Une telle instruction termine donc le calcul (même s’il reste des instructions à exécuter dans le programme). Par exemple, pour décider si un nombrenest premier, on pourra écrire

pouri de2àn1faire

sii divisen,rejeter; – accepter.

Un peu de recul

Le modèle des machines de Turing est si général qu’il semble être universel. Il s’agit de la thèse de Church-Turing : tout ce qui est « calculable par un système physique » est calculable par machine de Turing.

Attention, ce n’est pas un théorème mais seulement une profession de foi, partagée par la plupart des scientifiques et jamais remise en cause à ce jour depuis sa formulation par Church dans les années 1930. Remarquons qu’on ne peut démontrer un tel énoncé sans définir formellement ce qu’on entend par « calculable par un système physique »…

1.2.5 Indécidabilité

Avant d’aller plus loin, et bien que ceci sorte du cadre de ce livre, il n’est pas inutile de rappeler que certains problèmes ne peuvent pas être résolus par un algorithme, quel que soit le temps dont il dispose. Ce résultat fondamentald’indécidabilité remonte aux débuts des machines de Turing (années 1930) et la théorie qui en découle, la calculabilité, a donné ensuite naissance à la complexité algorithmique. Nous suggérons au lecteur de se reporter aux ouvrages cités en introduction, par exemple au livre de Wolper [Wol06], pour approfondir le passionnant sujet de la calculabilité.

La démonstration du résultat suivant utilise le « procédé diagonal », oudiagonalisation, inventé par Cantor et que nous étudierons plus en détail par la suite.

30 Chapitre 1. Le modèle de calcul 1-W Théorème

Il n’existe pas de machine de Turing reconnaissant le langage

H={〈M〉 |M est une machine de Turing etM(〈M〉)rejette}.

Démonstration Par l’absurde, supposons qu’une machineMreconnaisseH. Alors, par définition deM,〈M〉 ∈H ssiM(〈M〉)accepte. Mais d’autre part, par définition deH,

〈M〉 ∈HssiM(〈M〉)rejette. Ainsi,M(〈M〉)accepte ssiM(〈M〉)rejette : une

contradic-tion. ⊓⊔

Un peu de recul

Il existe quantité d’autres problèmes indécidables très naturels. Le théorème que nous venons de voir montre qu’il n’existe pas de programme d’ordinateur capable de décider si un code source quelconque (par exemple un code de programme Java), lors de son exécution sur son propre code, va renvoyer0ou1ou s’il va boucler indéfiniment.

Plus généralement, on peut montrer (théorème de Rice) qu’aucune propriété non triviale d’un programme ne peut être décidée par algorithme. Pour résumer grossièrement, cela signifie qu’il n’existe pas de méthode automatique pour détecter un bug dans un pro-gramme ou pour certifier qu’il exécute bien la tâche voulue.

En calculabilité, les ressources de la machine ne sont pas limitées : elle peut prendre autant de temps et d’espace qu’elle veut. En revanche, les questions que nous nous poserons dans le reste de cet ouvrage concerneront la quantité de ressources nécessaires pour résoudre un problème : ce seront des questions de la forme « quels langages peuvent être reconnus efficacement ? ».

2

Considérations de base

Dans le document COMPLEXITÉ ALGORITHMIQUE (Page 47-51)