From 8ba00e19547b48a39afa449982850a1e66f058cc Mon Sep 17 00:00:00 2001 From: "David A. Madore" Date: Wed, 22 Jan 2025 19:27:43 +0100 Subject: Answer key (on the Kreisel-Lacombe-Shoenfield theorem). --- controle-20250129.tex | 518 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 449 insertions(+), 69 deletions(-) diff --git a/controle-20250129.tex b/controle-20250129.tex index 37001d5..e2a28c3 100644 --- a/controle-20250129.tex +++ b/controle-20250129.tex @@ -132,9 +132,9 @@ Git: \input{vcline.tex} \exercice[Problème] \textbf{Notations :} Dans tout cet exercice, on notera comme -d'habitude $\varphi_e\colon\mathbb{N}\dasharrow\mathbb{N}$ la $e$-ième -fonction générale récursive (i.e., calculable) partielle pour -$e\in\mathbb{N}$. On notera +d'habitude $\varphi_e\colon\mathbb{N}\dasharrow\mathbb{N}$ (pour +$e\in\mathbb{N}$) la $e$-ième fonction partielle calculable +(i.e. générale récursive). On notera \[ \mathsf{PartCalc} := \{\varphi_e \; : \; e\in\mathbb{N}\} = \{g\colon\mathbb{N}\dasharrow\mathbb{N} \; : \; @@ -143,7 +143,7 @@ $e\in\mathbb{N}$. On notera l'ensemble des fonctions \emph{partielles} calculables $\mathbb{N}\dasharrow\mathbb{N}$, ainsi que \[ -\mathsf{TotIdx} := \{e\in\mathbb{N} \; : \; +\mathsf{TotCode} := \{e\in\mathbb{N} \; : \; \varphi_e\hbox{~est totale}\} = \{e\in\mathbb{N} \; : \; \varphi_e\in\mathsf{TotCalc}\} \] @@ -151,11 +151,11 @@ l'ensemble des codes des programmes qui définissent une fonction \emph{totale} $\mathbb{N}\to\mathbb{N}$ (i.e., terminent et renvoient un entier quel que soit l'entier qu'on leur fournit en entrée), et \[ -\mathsf{TotCalc} := \{\varphi_e \; : \; e\in\mathsf{TotIdx}\} +\mathsf{TotCalc} := \{\varphi_e \; : \; e\in\mathsf{TotCode}\} = \{g\colon\mathbb{N}\to\mathbb{N} \; : \; \exists e\in\mathbb{N}.\,(g = \varphi_e)\} \] -l'ensemble des fonctions \emph{totales} calculables +l'ensemble correspondant des fonctions \emph{totales} calculables $\mathbb{N}\to\mathbb{N}$, i.e., celles calculées par les programmes qu'on vient de dire. @@ -165,9 +165,9 @@ On va s'intéresser à la notion (qu'on va définir) de fonction calculable $\mathsf{PartCalc} \to \mathbb{N}$ d'une part, et $\mathsf{TotCalc} \to \mathbb{N}$ d'autre part. (On parle parfois de « fonctionnelles » ou de « fonction de second ordre » pour ces -fonctions sur les fonctions.) On souligne qu'on parle bien de -fonction \emph{totales} $\mathsf{PartCalc} \to \mathbb{N}$ d'une part, -et $\mathsf{TotCalc} \to \mathbb{N}$ d'autre part. +fonctions sur les fonctions. On souligne qu'on parle bien ici de +fonction \emph{totales} $\mathsf{PartCalc} \to \mathbb{N}$ et +$\mathsf{TotCalc} \to \mathbb{N}$.) \medskip @@ -178,12 +178,12 @@ F(e) = F(\varphi_e)$ est calculable.\quad (B) De même, une fonction (totale) $F\colon \mathsf{TotCalc} \to \mathbb{N}$ est dite calculable lorsqu'il existe une fonction $\hat F\colon \mathbb{N} \dasharrow \mathbb{N}$ partielle calculable telle que telle que $\hat F(e) = -F(\varphi_e)$ pour tout $e \in \mathsf{TotIdx}$. +F(\varphi_e)$ pour tout $e \in \mathsf{TotCode}$. \smallskip En français : une fonctionnelle définie sur l'ensemble des fonctions -calculables partielles ou partielles est elle-même dite calculable +calculables partielles ou totales est elle-même dite calculable lorsqu'il existe un programme qui calcule $F(g)$ à partir du code $e$ d'un programme quelconque calculant $g$. @@ -191,25 +191,28 @@ d'un programme quelconque calculant $g$. {\footnotesize -Il est évident que la fonction $\hat F$ vérifie forcément -$(\varphi_{e_1} = \varphi_{e_2}) \; \Longrightarrow (\hat F(e_1) = -\hat F(e_2))$ ; c'est-à-dire qu'elle est « extensionnelle » : elle -doit renvoyer la même valeur sur deux programmes qui calculent la même -fonction (= ont la même « extension »). D'ailleurs (on ne demande pas -de justifier ce fait, qui est facile), se donner une fonction $F\colon -\mathsf{PartCalc} \to \mathbb{N}$ revient exactement à se donner une -fonction $\hat F\colon \mathbb{N} \to \mathbb{N}$ ayant cette -propriété d'« extensionnalité » ; et de même, se donner une fonction -$F\colon \mathsf{TotCalc} \to \mathbb{N}$ revient exactement à se -donner une fonction $\hat F\colon \mathsf{TotIdx} \dasharrow -\mathbb{N}$ qui soit extensionnelle. La définition ci-dessus dit donc -que $F$ est calculable lorsque la $\hat F$ qui lui correspond est -elle-même calculable dans le cas (A), ou la restriction à -$\mathsf{TotIdx}$ d'une fonction calculable dans le cas (B). +Il est évident dans le cas (A) que la fonction $\hat F$ vérifie +forcément $(\varphi_{e_1} = \varphi_{e_2}) \; \Longrightarrow (\hat +F(e_1) = \hat F(e_2))$ ; c'est-à-dire qu'elle est « extensionnelle » : +elle doit renvoyer la même valeur sur deux programmes qui calculent la +même fonction (= ont la même « extension »). D'ailleurs (on ne +demande pas de justifier ce fait, qui est facile), se donner une +fonction $F\colon \mathsf{PartCalc} \to \mathbb{N}$ revient exactement +à se donner une fonction $\hat F\colon \mathbb{N} \to \mathbb{N}$ +ayant cette propriété d'« extensionnalité ». De même, dans le +cas (B), se donner une fonction $F\colon \mathsf{TotCalc} \to +\mathbb{N}$ revient exactement à se donner une fonction $\hat F\colon +\mathsf{TotCode} \dasharrow \mathbb{N}$ qui soit extensionnelle sur +$\mathsf{TotCode}$. La définition ci-dessus dit donc que $F$ est +calculable lorsque la $\hat F$ qui lui correspond est elle-même +calculable dans le cas (A), ou, dans le cas (B) la restriction à +$\mathsf{TotCode}$ d'une fonction calculable partielle +sur $\mathbb{N}$ dont le domaine de définition contient au +moins $\mathsf{TotCode}$. \par} -\medskip +\bigskip \textbf{(1)} Montrer que toute fonction (totale !) calculable $F\colon \mathsf{PartCalc} \to \mathbb{N}$ est en fait constante. @@ -219,6 +222,23 @@ distinctes, disons $v_1$ et $v_2$, et considérer l'ensemble des $e$ tels que $F(\varphi_e) = v_1$ (i.e., tels que $\hat F(e) = v_1$). (Pourquoi est-il décidable ? Et pourquoi est-ce une contradiction ?) +\begin{corrige} +Si $F$ n'est pas constante, il existe $v_1\neq v_2$ tels que $F$ +prenne la valeur $v_1$ et la valeur $v_2$, disons $F(\varphi_{e_1}) = +v_1$ et $F(\varphi_{e_2}) = v_2$. Considérons l'ensemble $D_1$ des +$e$ tels que $F(\varphi_e) = v_1$, c'est-à-dire $\hat F(e) = v_1$ par +définition de $\hat F$. D'une part, cet ensemble $D_1$ est +décidable : pour décider si $e\in D_1$, il suffit de calculer $\hat +F(e)$ (ce qui est possible par l'hypothèse que $F$, i.e., que $\hat +F$, est calculable), et tester si sa valeur vaut $v_1$. D'autre part, +$D_1$ n'est ni vide (puisque $e_1 \in D_1$) et n'est pas plein +(puisque $e_2 \not\in D_1$). Or ceci contredit le théorème de Rice, +lequel affirme que si $E \subseteq \mathsf{PartCalc}$ est tel que +l'ensemble $\{e \in \mathbb{N} : \varphi_e \in E\}$ est décidable, +alors il est vide ou plein (ici, on prend $E = \{g\in\mathsf{PartCalc} +: F(g) = v_1\}$). +\end{corrige} + \medskip \textbf{(2)} Expliquer pourquoi il existe des fonctions calculables @@ -227,7 +247,28 @@ constantes. Donner un exemple explicite. Pour cela, on pourra penser évaluer en un point, c'est-à-dire exécuter, le programme dont on a reçu le code en argument (on -rappellera pourquoi on peut faire cela). +rappellera pourquoi on peut faire cela). Par ailleurs, on fera +clairement ressortir pourquoi le raisonnement tenu ici ne s'applique +pas à la question (1). + +\begin{corrige} +La fonction partielle $e\mapsto\varphi_e(0)$ (ou, plus généralement, +$(e,x) \mapsto \varphi_e(x)$) est calculable par l'existence d'un +programme universel. Ceci montre que la fonction $F\colon +\mathsf{TotCalc} \to \mathbb{N}$ donnée par $g \mapsto g(0)$ est +calculable (la fonction $\hat F$ qui lui correspond étant justement +$e\mapsto\varphi_e(0)$). Ce raisonnement n'était pas applicable à +$\mathsf{PartCalc}$ car on cherche à définir une fonction +\emph{totale}, or $g \mapsto g(0)$ n'est que partielle sur +$\mathsf{PartCalc}$ (tandis qu'elle est totale sur +$\mathsf{TotCalc}$). + +Plus généralement, on peut construire énormément de fonctions +calculables $\mathsf{TotCalc} \to \mathbb{N}$ en appliquant librement +l'évaluation de l'argument qu'on a reçu (qui, par hypothèse, est +toujours défini). Un autre exemple serait la fonction $g \mapsto g(0) ++ g(1)$ ou encore $g \mapsto g(g(0))$. +\end{corrige} \medskip @@ -238,9 +279,10 @@ définitions ci-dessus. Dans les questions (3) à (8) qui suivent, on cherche à démontrer que $F$ a la propriété\footnote{Si on sait ce que cela signifie, cette -propriété peut s'exprimer ainsi : $F$ est continue lorsque -$\mathsf{TotCalc}$ est muni de la topologie (héritée de la topologie) -produit sur $\mathbb{N}^{\mathbb{N}}$.} suivante (« théorème de +propriété peut s'exprimer ainsi : $F$ est continue (ou, ce qui revient +ici au même : localement constante) lorsque $\mathsf{TotCalc}$ est +muni de la topologie [héritée de la topologie] produit sur +$\mathbb{N}^{\mathbb{N}}$.} suivante (« théorème de Kreisel-Lacombe-Shoenfield ») : quelle que soit $g \in \mathsf{TotCalc}$, il existe $n$ telle que pour toute fonction $g' \in \mathsf{TotCalc}$ qui coïncide avec $g$ jusqu'au rang $n$ (i.e. : @@ -260,16 +302,45 @@ rang, c'est-à-dire telles que $\exists m. \forall i\geq m.\,(h(i) = $\mathbb{N}\to\mathbb{N}$ nulle à partir d'un certain rang est automatiquement calculable.\quad\textbf{(b)} Montrer, plus précisément, qu'il existe une fonction calculable $\Gamma\colon -\mathbb{N}\times\mathbb{N}\to\mathbb{N}$ telle que toute fonction $h -\in \mathsf{NulAPCR}$ soit de la forme $\Gamma(j,\emdash)$ -(c'est-à-dire $i \mapsto \Gamma(j,i)$) pour un certain $j$. -(\emph{Indication :} on pourra utiliser un codage de Gödel des suites -finies d'entiers naturels par des entiers -naturels $j$.)\quad\textbf{(c)} En déduire qu'il existe $\gamma\colon -\mathbb{N}\to\mathbb{N}$ calculable telle que toute fonction $h \in -\mathsf{NulAPCR}$ soit de la forme $\varphi_{\gamma(j)}$ pour un -certain $j$. (\emph{Indication :} on pourra utiliser le théorème -s-m-n.) +\mathbb{N}\times\mathbb{N}\to\mathbb{N}$ telle que les fonctions $h +\in \mathsf{NulAPCR}$ soient exactement celles de la forme +$\Gamma(j,\emdash)$ (c'est-à-dire $i \mapsto \Gamma(j,i)$) pour un +certain $j$. (\emph{Indication :} on pourra utiliser un codage de +Gödel des suites finies d'entiers naturels par des entiers +naturels $j$ ; on ne demande pas de justifier les détails de ce +codage.)\quad\textbf{(c)} En déduire qu'il existe $\gamma\colon +\mathbb{N}\to\mathbb{N}$ calculable telle que les fonctions de +$\mathsf{NulAPCR}$ soient exactement celles de la forme +$\varphi_{\gamma(j)}$ pour un certain $j$. (\emph{Indication :} on +pourra utiliser le théorème s-m-n.) + +\begin{corrige} +\textbf{(a)} Si on a $h(i) = 0$ pour $i\geq m$, alors $h$ est +trivialement calculable par le programme « si $i=0$, renvoyer $h(0)$, +si $i=1$ renvoyer $h(1)$, ..., si $i=m-1$ renvoyer $h(m-1)$, et si +$i\geq m$ renvoyer $0$ ». + +\textbf{(b)} On considère le programme qui, donné deux entiers $j,i$ +effectue les opérations suivantes : il décode $j$ comme le codage de +Gödel $\dbllangle a_0,\ldots,a_{m-1}\dblrangle$ d'un $m$-uplet +$(a_0,\ldots,a_{m-1})$ d'entiers naturels, puis, si $i0$ : ainsi, $F(g) = 0$, donc on devrait +avoir $F(g')$ pour tout $g'\in \mathcal{B}(g,n)$, c'est-à-dire tout +$g'$ tel que $g'(0)=n+1$ et $g'(1)=\cdots=g'(n)=0$. Or en prenant +$g'$ valant $42$ en $n+1$ et toujours $0$ ensuite, on a $F(g') = 42$, +donc $F(g') \neq F(g)$, ce qui contredit l'affirmation. +\end{corrige} + +\medskip + +\textbf{(11)} On a prouvé en (9) qu'un $n$ (tel que $\forall +g'\in\mathcal{B}(g,n).\; (F(g') = F(g))$) peut être calculé +algorithmiquement en fonction du code $r$ d'un programme qui +calcule $g$. En fait, on pourrait prouver un peu mieux (\emph{ceci +n'est pas demandé}) : il est possible de calculer un tel $n$ par un +algorithme qui a seulement le droit d'interroger les +valeurs\footnote{C'est-à-dire : un algorithme qui a accès à un oracle +calculant qui renvoie $g(i)$ quand on lui soumet la valeur $i$. +L'algorithme a le droit d'appeler librement l'oracle un nombre fini +quelconque de fois au cours de son exécution.} de la fonction $g$. En +\emph{admettant} ce fait, expliquer pourquoi la fonction $F$ elle-même +peut être calculée par un tel algorithme. + +\begin{corrige} +Pour la complétude de ce corrigé, et \emph{bien que ce ne soit pas +demandé par le sujet}, prouvons l'affirmation admise. Appelons $N(r)$ +la valeur calculée par l'algorithme B donné dans la question (9), +c'est-à-dire en supposant qu'on ait accès au code $r$ du programme qui +calcule $g$. On cherche maintenant à faire pareil sans avoir accès à +ce code. Pour cela, considérons l'algorithme C suivant : on recherche +un $r \in \mathbb{N}$ vérifiant les conditions : +\begin{itemize} +\item $N(r){\downarrow}$, +\item $\varphi_r(i) = g(i)$ pour tout $i \leq N(r)$, +\item $\hat F(\gamma(g,N(r),0)) = \hat F(r)$ ; +\end{itemize} +et une fois qu'il est trouvé, on renvoie $N(r)$. + +Un tel $r$ existe bien car si $r_0$ est tel que $\varphi_{r_0} = g$, +alors ce $r_0$ vérifie bien les trois conditions (la première vient de +$r_0 \in \mathsf{TotCode}$, la deuxième est une conséquence triviale +de $\varphi_{r_0} = g$, et la troisième découle du fait que tout $g' +\in \mathcal{B}(g,N(r_0))$ vérifie $F(g') = F(g)$, et que $g' := +\varphi_{\gamma(g,N(r_0),0)} \in \mathcal{B}_0(g,N(r_0))$ donc $\hat +F(\gamma(g,N(r),0)) = F(g') = F(g) = \hat F(r_0)$). + +La recherche d'un $r$ est possible algorithmiquement bien que les +trois contraintes ne soient que semi-décidables (le calcul de +$\varphi_r(i)$ pourrait ne pas terminer, comme celui de $N(r)$ ou de +$\hat F(r)$, puisque rien ne garantit que $r \in \mathsf{TotCode}$) : +en effet, on peut à lancer en parallèle toutes les recherches +(c'est-à-dire qu'on parcourt les couples $(r,M)$ et pour chacun on +fait $M$ étapes de la vérification que $r$ convient, jusqu'à trouver +un $r$ qui vérifie les contraintes). + +L'algorithme C qu'on vient de dire n'utilise que l'interrogation de +valeurs de $g$ (c'est trivial pour le premier point qui ne fait pas +intervenir $g$, pour le deuxième le test se fait en utilisant les +valeurs $g(0),\ldots,g(N(r))$, et pour le troisième, il est clair dans +la construction faite en (4) que pour déterminer $\gamma(g,n,j)$ on +n'a besoin que d'interroger les valeurs de $g$, pas d'avoir accès à +son code). + +Une fois qu'un tel $r$ est trouvé, même sans supposer que la fonction +$\varphi_r$ soit totale, l'argument donné en (7) montre qu'on ne peut +pas y avoir de $j$ tel que $\hat F(\gamma(g,N(r),j)) \neq \hat F(r)$, +donc comme en (8), on a $F(g') = \hat F(r)$ pour tout $g' \in +\mathcal{B}(g,N(r))$, et $N(r)$ vérifie bien la contrainte demandée. + +Ceci conclut la preuve du fait qui était admis. Passons maintenant à +la question proprement dite. + +Pour calculer $F(g)$ à partir de l'interrogation de valeurs de $g$, on +commence par calculer, en interrogeant les valeurs de $g$, un $n$ tel +que $\forall g'\in\mathcal{B}(g,n).\; (F(g') = F(g))$ (on vient +d'admettre ou d'expliquer qu'on peut le faire). Puis on calcule et +renvoie $\hat F(\gamma(g,n,0))$, ce qui peut se faire en +n'interrogeant qu'un nombre fini de valeurs de $g$ (à savoir +$g(0),\ldots,g(n)$) : comme $\gamma(g,n,0) \in \mathcal{B}(g,n)$ par +définition de $\gamma$, on a bien $\hat F(\gamma(g,n,0)) = F(g)$, et +on a calculé cette valeur en passant simplement par l'interrogation de +valeurs de $g$ et sans avoir besoin de connaître son code. +\end{corrige} + +\medskip + +\textbf{(12)} Quelle est la morale de l'ensemble de ce problème ? +Autrement dit, expliquer \emph{en français de façon informelle} le +sens du théorème de Kreisel-Lacombe-Shoenfield : on cherchera à dire +quelque chose de la forme « la seule manière de construire une +fonction totale calculable sur l'ensemble des fonctions est la +suivante ». On contrastera avec la situation des +questions (1) et (2). + +\begin{corrige} +On s'est interrogé dans ce problème sur ce que peuvent faire des +algorithmes qui prennent en entrée un autre programme et qui calculent +un entier. Dans la question (1), on a vu, comme variation sur le +théorème de Rice, que si le programme fourni en entrée de l'algorithme +n'est pas supposé terminer à coup sûr, alors on ne peut rien faire +d'intelligent : on ne peut que renvoyer toujours la même valeur. + +En revanche, lorsque l'algorithme fourni en entrée est supposé +toujours terminer, on peut au moins évaluer ses valeurs (c'est ce +qu'on a fait dans la question (2)), c'est-à-dire qu'on peut renvoyer +des expressions faisant intervenir les $g(i)$. Ce qu'affirme le +théorème de Kreisel-Lacombe-Shoenfield, c'est que toute valeur $F(g)$ +calculée ne dépend, en fait, que d'un nombre fini de telles valeurs +$g(0),\ldots,g(n)$, et, finalement (c'est la question (11)) peut être +calculé par un algorithme qui n'a le droit d'accéder qu'à une boîte +noire renvoyant la valeur de $g(i)$ en fonction de $i$. + +La question (10) montre que, si pour n'importe quel $g$ le nombre de +valeurs dont dépend $F(g)$ est borné, il n'est pas forcément +\emph{uniformément borné}, c'est-à-dire qu'on ne peut pas forcément +trouver un seul et même $n$ tel que la connaissance des $n$ premières +valeurs de $g$ suffise à calculer $F(g)$. +\end{corrige} + % -- cgit v1.2.3