ajouts dossier Processus, Calculabilité, Recherche textuelle. Avec images et exercices.

This commit is contained in:
2025-04-24 11:55:58 +02:00
parent f043365aac
commit ed6f9ebd47
16 changed files with 928 additions and 0 deletions

293
Calculabilité/README.md Normal file
View File

@@ -0,0 +1,293 @@
## Calculabilité et décidabilité en informatique ##
> A chaque problème sa non solution !
<img src="assets/bo.png" alt="bo" style="zoom:50%;" />
## Logique
#### Introduction à la décidabilité
Il vous est deja arrivé de prendre des décisions en suivant une logique. Dans la vie vous suivez la votre, en prenant des conseils, ou de par ce que vous avez appris à l'école. C'est donc quelque chose général.
Cela vous semble simple de définir la logique, mais en réalité, mise en pratique, cela devient plus complexe à commenter :
mathématiquement, la logique n'a pas grand chose à voir avec celle dont on use au quotidien.
En informatique, une chose primordiale est l'utilisation et la mise au point d'algorithme, et donc de prise de décision.
Ces décisions sont prises par le programme informatique via un shcéma de pensée que l'on peut représenter comme ceci :
<img src="assets/diagramme.png" alt="Diagramme" style="zoom:50%;" />
D'un point de vue mathématique ou informatique, ces paramètres et prises de décision sont de type booléen, (vrai ou faux)
On peut par exemple prendre des problèmes assez élémentaires :
- X est il un nombre pair ?
- Y est il une puissance de 3 ?
- Dans un graphe, quel est le chemin le plus court passant par tous les sommets ?
Dans notre premier cas, nous avons en **instance de départ :** un entier naturel, qui, après être traité via le **paramètre** choisi (Si reste = 0 après une division par 2, alors nombre est pair) dans **l'algorithme**, ressortira en une réponse simple : *Oui* ou *Non* selon la **décision** prise.
### Définition
En informatique ou mathématiques, on peut parler d'une **fonction algorithmique**. Quand le résultat de celle ci, c'est à dire ce qu'elle *renvoit*, est un boléen, on parle de ***prédicat***
Un ***prédicat*** est une fonction qui ne prendra que des valeurs booléennes:
<p>
La réponse à un problème de décision est donc soit un booléen ou alors une valeur qui permet de répondre à un prédicat
Exemple : Dans un graphe, connaitre le nombre de sommets permet de répondre à la question : le chemin que j'ai choisi est il le plus court passant par tous les sommets de ce graphe ?
Question dont la réponse est bel et bien un prédicat.
### Définition
Si, pour réponse à un problème, on peut en écrire un algorithme permettant la prise de décision et donc amenant à la résolution du dit problème, on parlera de problème ***décidable*** ou de <u>**décidabilité**</u>
Et donc, par extension, si un problème n'est pas soluble, on utilisera le terme ***Indécidabilité***
-------
## ~~La calcul habilité~~ La calculabilité
En informatique, plus précisemment dans la branche dite de programmation, nous utilisons un langage qui nous est propre afin de mettre en place nos idées dans un algorithme.
### Vocabulaire
Cela ne signifie pas pour autant que cet algorithme fonctionne : pour cela il faut vérifier que la propriété qu'on appelle ***Terminaison*** est bien respectée, et que l'algorithme nous mène bien à la réponse souhaitée.
On parlera également d'algorithme de ***haut niveau***: l'algorithme doit pouvoir être traduit en n'importe quel langage de programmation, il ne doit donc pas faire appel à des notions techniques relatives à un programme particulier ou bien à un système d'exploitation donné.
Quel rapport avec la calculabilité ? Et bien une fonction mathématique, que l'on peut retranscrire sous forme d'algorithme afin de la programmer dans un langage informatique utilisé, est dite ***Calculable***
### Un peu d'histoire
En 1943, un mathématicien américain, du nom d'Alonzo Church définit une thèse dite "thèse de Church" qui affirme la notion de calculabilité : Tout traitement d'un système réalisable par un processus quel qu'il soit, peut être exprimé par un ensemble de règles de calcul.
Cet ensemble est défini lui même par les règles de calcul dont on prouve mathématiquement l'équivalence.
Cette thèse propose les règles suivante en matière d'algorithme :
1. L'algorithme consiste en un ensemble fini d'instructions simples et précises
qui sont décrites avec un nombre limité de symboles.
2. L'algorithme doit toujours produire le résultat en un nombre fini d'étapes.
3. L'algorithme peut être suivi par un humain avec seulement du papier et un crayon.
4. L'exécution de l'algorithme ne requiert pas d'intelligence de l'humain
sauf celle qui est nécessaire pour comprendre et exécuter les instructions.
### Trop long, j'ai pas lu !
Pour résumer : une fonction mathématique qui fonctionne selon un modèle existant fonctionnera dans n'importe quel modèle.
Si vous décidez de programmer une fonction qui vous dit si un nombre est pair en python, votre fonction devrait fonctionner dans un autre langage, pourvu que vous utilisiez les "codes" de ce langage.
Ici, en NSI, nous utilisons le langage Python, mais nous pourrions parfaitement transposer nos codes en C++, Java ou autre.
### Et la calculabilité dans tout ça ?
Revenons au prédicat : si une fonction renvoie un prédicat, et que celui là est dit calculable, alors la prise de décision est possible. Une fonction calculable permet donc l'emergence de décisions décidables.
Ce qui signifie qu'il existe un algorithme permettant la résolution de cette fonction, ou d'un problème ammené par la fonction, et si un algorithme existe, alors nous sommes en mesure de programmer la fonction dans n'importe quel langage.
--------
## La décidabilité
### Vocabulaire
Une propriété est dite décidable si l'on peut déterminer son résultat (vrai ou faux) en un nombre fini d'étapes
C'est le principe même d'un algorithme, ou d'une recette de cuisine par exemple : on indique un nombre d'étapes qui doit mener, à terme, à un résultat.
Pour un problème, c'est la même chose : si l'on peut écrire un programme qui renvoit un prédicat permettant de calculer la réponse au problème de départ, alors on parlera de ***problème décidable***.
### Pourquoi est ce important ?
Imaginez, si votre programme, logiciel ou jeu vidéo favori rencontrait un problème d'execution et tournait en boucle quand vous l'utilisez. <br> Frustrant n'est ce pas ? Une personne qui souhaite développer des programmes doit s'assurer de la décidabilité de son travail.
### Et maintenant, des exemples !
Exercice : Prouver qu'un nombre est pair :
Nous allons définir une fonction \\(f : N --> {Vrai, Faux} \\) telle que f(n) est vraie si et seulement si \\(n\\)%2 == 0
Nous savons que ce problème est résoluble et donc ***décidable***
Son algorithme est très simple : il suffit de diviser par 2 et d'observer le reste de la division : si celui ci est égal à 0, alors il s'agit d'un nombre pair. Sinon, ce nombre est impair.
On peut maintenant écrire notre algorithme sous forme de langage python :
```python
def est_pair(n):
''' Renvoie un prédicat exprimant le résultat de n modulo 2
Si le reste est nul, alors le prédicat est vrai et le nombre n est pair, sinon, il est impair.
'''
return n % 2 == 0
```
```python
>>>est_pair(42)
>>>True
>>>est_pair(113)
>>>False
```
Si ce code fonctionne, il ne faut pas oublier une chose : ça n'est pas la seule solution existante au problème : puisque ce problème est décidable, vous pouvez écrire votre propre algorithme qui fera tout aussi bien !
Par exemple :
```python
def est_pair2(n):
if (n % 2) == 0:
return("{0} est Pair".format(n))
else:
return("{0} est Impair".format(n))
```
```python
>>>est_pair2(113)
>>>'113 est Impair'
>>>est_pair2(42)
>>>'42 est Pair'
```
Nous avons bien la preuve que le problème " Peut-on prouver qu'un nombre est pair" est bel et bien décidable.
### Tous les problèmes sont ils décidables?
Et bien non ! Disons le tout de suite, il existe un nombre de problèmes que l'ont ne peut résoudre par un simple algorithme. On parlera de ***Problèmes Indécidables*** !
La question qui se pose à nous est de savoir comment reconnaitre un problème indécidable.
Et à l'heure actuelle, nous ne disposons pas de machine magique permettant de nous donner cette information.
Pour déduire l'indécidabilité d'un programme, il faut un algorithme répondant à ce problème et également la preuve qu'il se termine.
En mathématiques, on utilise le ***problème de l'arrêt***
### Un peu plus d'histoire...
En 1931, Kurt Gödel, mathématicien et logicien autrichien, énonce son théorème d'incomplétude.
Il y établit qu'une théorie suffisante pour y démontrer les théorèmes de base de l'arithmétique -la partie des mathématiques qui s'occupe des nombres, en opposition à la géométrie - est nécessairement incomplète, au sens où il existe des énoncés qui n'y sont ni démontrables, ni réfutables . On parle alors d'énoncés indécidables dans la théorie.
Note : Il s'agit de la définition Wikipédia
Il parle également d'***Axiomes***
Un axiome est une proposition non démontrée que l'on va utiliser pour tenter de résoudre un problème.
C'est à dire qu'on va partir d'une hypothèse qu'on supposera vraie, pour essayer d'aller au bout du raisonnement.
Cela nous ramènera donc à des décisions logiques qui en découleront.
### Mais si le postulat de base est éronné ?
C'est tout le principe : s'il est éronné, alors il faut tester son exact opposé : celà prend du temps.
Et enfin, en testant l'opposé, on pourra savoir si notre problème est décidable ou pas !
Revenons à notre problème d'arrêt : Il s'agit d'un problème de décision qui determine si le programme s'arrête ou non. Pratique ? C'est exactement ce que l'on cherche justement.
Oui mais :En 1936, Alan Turing démontre son indécidabilité.
#### Attendez, le programme qui determine l'indécidabilité est lui même indécidable ??
Eeh oui, c'est incroyable mais juste : ironique n'est ce pas ? On peut même dire *absurde*
En effet, on va user d'un raisonnement par l'absurde pour montrer que ce qu'on pense vrai est en réalité faux.
En supposant que ce que l'on veut vrai, soit faux, avec une pensée logique, on peut et doit, aboutir à une contradiction qui établira que ce que l'on pense donc vrai, est faux.
#### Vous suivez toujours ?
Supposons que l'on puisse écrire une fonction arret, capable de dire si une fonction programme va s'arrêter dans tous les cas ou s'il existe des cas où elle ne s'arrête pas.
Il n'est, dans notre exemple, absolument pas certain qu'une telle fonction existe.
Nous allons dans un premier temps, créer une fonction qui nous servira de cobaye dans notre fonction absurbe de programme d'arrêt.
```python
def arret_programme(programme, x):
'''retourne vrai si le programme s'arrête ou non selon le paramètre x
'''
predicat = ...
if predicat:
return True
else:
return False
```
Dans le code ci dessus, si notre condition est vraie, alors le programme renverra True.
Sinon, il renverra False.
Jusqu'ici, tout est logique, et c'est comme cela que la plupart des programmes fonctionne.
Maintenant, définissons notre fonction absurde
```python
def absurde(programme):
if arret_programme(programme,x):
while True:
continue
else:
return True
```
Si on analyse ce que l'on vient d'écrire : Quand la fonction arret_programme peut s'arrêter, la fonction absurde va lui permettre de boucler à l'infini !
Mais si le test se révèle négatif, on renvoit True et arretons donc la fonction!
Nous venons donc de prouver l'impossible. Pas mal non ?
#### Quand le possible et l'impossible se mélangent...Possimpible ?
Turing prouve donc qu'il n'est pas possible d'inventer une fonction prouvant qu'une autre donnée se termine.
Si la machine ne peut nous aider, il vous faudra donc, en tant qu'humain, toujours assurer le contrôle de votre code.
### Question : Que peut-on en déduire ?
On peut retenir deux choses de notre exemple : Le fameux théorème de Kurt Gödel, qui traite de l'indécidabilité, n'est pas vérifiable puisque qu'on ne peut vérifier la décidabilité de tous les sytèmes, dès lors que la fonction qui doit nous y aider n'est elle même pas décidable !
Pour comprendre la démonstration de tout cela, il nous aura fallu analyser la démonstration en elle même, et non pas essayer de démontrer ce qu'elle prouve. Ce qui laisse perplexe quant à la veracité de certaines affirmations.
Enfin, on peut se demander une chose. Puisque nous avons une donnée en entrée d'une fonction, et une donnée en sortie...Une fonction ne serait-elle pas uniquement que données ?
Finalement, quand on regarde un programme, qu'est ce que c'est ? Exemple en python : un fichier texte avec une extension.
Sous un système unix, absolument tous les fichiers ne sont que du texte ! Pire : dans notre exemple, nous utilisons un programme comme donnée d'un autre programme !
Et si tout est donnée, alors cela expliquerait pourquoi la logique tient une si grande importance dans notre environnement.
--------
Auteur : Florian Mathieu
Licence CC BY NC
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas dUtilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.

57
Calculabilité/TURING.md Normal file
View File

@@ -0,0 +1,57 @@
## Machine de Turing
Cette machine est constituée :
- D' un **ruban infini** divisé en cases consécutives. Chaque case contient un symbole d'un *alphabet*. L'alphabet contient un symbole spécial appelé « symbole blanc », et un ou plusieurs autres symboles. Le ruban est supposé être de longueur infinie vers la gauche ou vers la droite, en d'autres termes la machine doit toujours avoir assez de longueur de ruban pour son exécution. On considère que les cases du ruban contiennent par défaut le « symbole blanc » .
- Une **tête de lecture/écriture** (ci-dessous le **`V`**) qui peut lire et écrire les symboles sur le ruban, et se déplacer vers la gauche ou vers la droite du ruban
- Un **registre d'état** qui mémorise l'état courant de la machine de Turing. Le nombre d'états possibles est toujours fini, et il existe un état spécial appelé « état de départ » qui est l'état initial de la machine avant son exécution.
- Une **table d'actions** qui indique à la machine quel symbole écrire sur le ruban, comment déplacer la tête de lecture (vers la droite ou la gauche), et quel est le nouvel état, en fonction du symbole lu sur le ruban et de l'état courant de la machine. Si aucune action n'existe pour une combinaison donnée d'un symbole lu et d'un état courant, la machine s'arrête.
**Exemple : voici l'algorithme permettant d'ajouter 1 à un nombre binaire.**
Choisissez un nombre binaire et écrivez le à droite de la tête de lecture (par exemple 101).
| | | | | | | | | | | V | | | | | | | | | |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| | | | | | | | | | | | 1 | 0 | 1 | | | | | | |
Réalisez pas à pas l'algorithme ci-dessous :
- la machine lit chaque case de gauche à droite jusqu'à tomber sur une case vide. Il y a alors deux cas possibles:
- Si la dernière case mémorisée dans le registre d'état est un 0 alors la machine se décale d'une case à gauche et écrit 1 puis retourne dans sa position initiale. .
- Si la dernière case est un 1, la machine se décale d'une case à gauche et :
- si cette case vaut 1, elle écrit 0 puis se décale à gauche et recommence le point précédent.
- si cette case vaut 0 ou est vide, elle écrit 1 puis retourne à sa position initiale.
*Etape 1* : la machine va à droite jusqu'à la première case vide.
| | | | | | | | | | | | | | | V | | | | | |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| | | | | | | | | | | | 1 | 0 | 1 | | | | | | |
*Etape 2* : la dernière case lue est ... donc ...
| | | | | | | | | | | | | | V | | | | | | |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| | | | | | | | | | | | 1 | 0 | 0 | | | | | | |
*Etape 4* : ...
| | | | | | | | | | | | | V | | | | | | | |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| | | | | | | | | | | | 1 | 1 | 0 | | | | | | |
*Etape 5* : ...
| | | | | | | | | | | V | | | | | | | | | |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| | | | | | | | | | | | 1 | 1 | 0 | | | | | | |
Vous trouverez [sur ce site](http://zanotti.univ-tln.fr/turing/turing.php) un simulateur d'une machin de de Turing si vous souhaitez aller plus loin.
ll faut garder à l'esprit que la machine de Turing est un modèle universel de calcul et qu'elle peut calculer tout ce que n'importe quel ordinateur physique peut calculer (aussi puissant soit-il). In­ver­sement, ce qu'elle ne peut pas calculer ne peut l'être non plus par un ordinateur. Elle résume donc de manière saisissante le concept d'*ordinateur* et constitue un support idéal pour raisonner autour de la notion d'*algorithme* de *calcul* ou de *démonstration*. En terminale, nous étudierons plus en détail le concept de calculabilité.

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.