summaryrefslogtreecommitdiffstats
path: root/controle-20250129.tex
diff options
context:
space:
mode:
authorDavid A. Madore <david+git@madore.org>2025-01-22 19:27:43 +0100
committerDavid A. Madore <david+git@madore.org>2025-01-22 19:27:43 +0100
commit8ba00e19547b48a39afa449982850a1e66f058cc (patch)
treece95ea147177bce73f066748f895f135d8090fc3 /controle-20250129.tex
parent7d1dd5fa98eb7c0ff8f3f557d08aaf9bd871bfaa (diff)
downloadinf110-lfi-8ba00e19547b48a39afa449982850a1e66f058cc.tar.gz
inf110-lfi-8ba00e19547b48a39afa449982850a1e66f058cc.tar.bz2
inf110-lfi-8ba00e19547b48a39afa449982850a1e66f058cc.zip
Answer key (on the Kreisel-Lacombe-Shoenfield theorem).
Diffstat (limited to 'controle-20250129.tex')
-rw-r--r--controle-20250129.tex518
1 files 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 $i<m$, renvoie
+$a_i$, et sinon, renvoie $0$. Ce programme calcule une fonction
+$\Gamma\colon \mathbb{N}\times\mathbb{N}\to\mathbb{N}$. Et par
+construction, chaque fonction $\Gamma(j,\emdash)$ est nulle à partir
+d'un certain rang, et chaque fonction $h$ qui est nulle à partir du
+rang $m$ est de la forme $\Gamma(j,\emdash)$, à savoir pour $j =
+\dbllangle h(0),\ldots,h(m-1)\dblrangle$.
+
+\textbf{(c)} Le théorème s-m-n assure qu'on peut calculer le code
+$\gamma(j)$ d'un programme calculant $\Gamma(j,\emdash)$ de manière
+calculable à partir de $j$. (De façon extrêmement précise : si $p$
+est un code tel que $\varphi^{(2)}_p(j,i) = \Gamma(j,i)$, alors
+$\varphi^{(1)}_{s_{1,1}(p,j)}(i) = \varphi^{(2)}_p(j,i) =
+\Gamma(j,i)$, donc $\gamma(j) := s_{1,1}(p,j)$ convient au sens où
+$\varphi_{\gamma(j)} = \Gamma(j,\emdash)$. La fonction $\gamma$ est
+bien calculable car $s_{1,1}$ l'est ; elle est même primitive
+récursive.)
+\end{corrige}
\medskip
@@ -278,27 +349,47 @@ on appellera $\mathcal{B}(g,n) := \{g' \in \mathsf{TotCalc} : \forall
i\leq n.\,(g'(i) = g(i))\}$ l'ensemble des $g'$ qui coïncident avec
$g$ jusqu'au rang $n$, et $\mathcal{B}_0(g,n) := \mathcal{B}(g,n) \cap
\mathsf{NulAPCR}$ celles qui, en outre, sont nulles à partir d'un
-certain rang (c'est-à-dire les fonctions prenant les valeurs
-$g(0),g(1),\ldots,g(n),?,?,\ldots,?,0,0,0,\ldots$).
+certain rang (c'est-à-dire les fonctions prenant des valeurs de la
+forme $g(0),g(1),\ldots,g(n),?,?,\ldots,?,0,0,0,\ldots$).
+
+\smallskip
+
+(On rappelle que notre but est de montrer qu'il existe $n$ tel que $F$
+soit constante sur $\mathcal{B}(g,n)$.)
\medskip
\textbf{(4)} Soit $g \in \mathsf{TotCalc}$ et $n\in\mathbb{N}$.
Expliquer \emph{brièvement} pourquoi les conclusions de la
question (3) valent encore en remplaçant $\mathsf{NulAPCR}$ par
-$\mathcal{B}_0(g,n)$ partout. On notera $\gamma(g,n,j)$ la conclusion
-de la dernière sous-question, c'est-à-dire que toute fonction $h \in
-\mathcal{B}_0(g,n)$ soit de la forme $h = \varphi_{\gamma(g,n,j)}$
-pour un certain $j$. On expliquera \emph{brièvement} pourquoi
-$\gamma(g,n,j)$ est calculable en fonction de $j$, de $n$ et du code
-(dans $\mathsf{TotIdx}$) d'un programme calculant $g$.
+$\mathcal{B}_0(g,n)$ partout. (\emph{Indication :} on peut par
+exemple fabriquer un élément de $\mathcal{B}_0(g,n)$ en insérant les
+valeurs $g(0),\ldots,g(n)$ avant un élément de $\mathsf{NulAPCR}$.)
+On notera $\gamma(g,n,j)$ la conclusion de la dernière sous-question,
+c'est-à-dire que les fonctions $h \in \mathcal{B}_0(g,n)$ soient
+exactement celles de la forme $h = \varphi_{\gamma(g,n,j)}$ pour un
+certain $j$. On expliquera \emph{brièvement} pourquoi $\gamma(g,n,j)$
+est calculable en fonction de $j$, de $n$ et du code (dans
+$\mathsf{TotCode}$) d'un programme calculant $g$.
+
+\begin{corrige}
+En (3)(b), on a vu qu'on pouvait fabriquer n'importe quel élément de
+$\mathsf{NulAPCR}$ en prenant le codage $j$ d'un $m$-uplet qu'on étend
+en la fonction qui commence par ces $m$ valeurs puis une infinité de
+zéros. Pour obtenir tous les éléments de $\mathcal{B}_0(g,n)$, il
+suffit par exemple d'insérer $g(0),\ldots,g(n)$ avant les valeurs
+codées par $j$. Il faut simplement justifier que le calcul des
+valeurs $g(0),\ldots,g(n)$ (ou du tuple de ces valeurs) est faisable
+en fonction de $n$ et du code d'un programme calculant $g$, or c'est
+clair (par l'existence d'un programme universel).
+\end{corrige}
\medskip
-Si on n'a pas su traiter la question (4), pour les questions
-suivantes, \textbf{on retiendra juste ceci :} $\gamma(g,n,j)$ est
-calculable, et toute fonction $\mathcal{B}_0(g,n)$ est de la forme
-$\varphi_{\gamma(g,n,j)}$ pour un certain $j$.
+Si on n'a pas su traiter les questions (3) et/ou (4), pour la suite,
+\textbf{on retiendra juste ceci :} $\gamma(g,n,j)$ est calculable, et
+on a $\mathcal{B}_0(g,n) = \{\varphi_{\gamma(g,n,j)} \,:\,
+j\in\mathbb{N}\}$.
\medskip
@@ -308,11 +399,11 @@ informellement ainsi :
\begin{itemize}
\item lancer l'exécution de $\varphi_d(0)$ pour au plus $\ell$
étapes\footnote{Si on préfère la notion d'arbre de calcul, remplacer
- par : « rechercher parmi les entiers $n\leq\ell$ un arbre de calcul
- de $\varphi_d(0)$ », et de même plus loin, remplacer « l'exécution
- s'est terminée en exactement $n\leq\ell$ étapes » par « $n$ est un
- arbre de calcul de $\varphi_d(0)$ ». Cela ne changera rien au
- problème.} ;
+ par : « rechercher parmi les entiers $n\leq\ell$ le code d'un arbre
+ de calcul de $\varphi_d(0)$ », et de même plus loin, remplacer
+ « l'exécution s'est terminée en exactement $n\leq\ell$ étapes » par
+ « $n$ est le code d'un arbre de calcul de $\varphi_d(0)$ ». Cela ne
+ changera rien au problème.} ;
\item si l'exécution ne s'est pas terminée dans le temps imparti,
terminer en renvoyant la valeur $g(\ell)$ ;
\item sinon, disons si l'exécution s'est terminée en exactement
@@ -340,12 +431,43 @@ qu'on a bien défini une fonction $\mathbb{N}\times\mathbb{N}
\dasharrow \mathbb{N}$ partielle calculable $(d,\ell) \mapsto
g_d(\ell)$).\quad\textbf{(b)} En déduire qu'il existe une fonction
calculable totale $e \mapsto e_d$ telle que $g_d = \varphi_{e_d}$ pour
-tout $d$. (\emph{Indication :} on pourra utiliser le théorème s-m-n.)
+tout $d$.
+
+\begin{corrige}
+\textbf{(a)} Parmi les points pouvant mériter d'être justifiés :
+\begin{itemize}
+\item il est bien possible de lancer l'exécution de $\varphi_d(0)$
+ pour au plus $\ell$ étapes (programme universel avec limite de temps
+ / théorème de la forme normale de Kleene) ;
+\item renvoyer $g(\ell)$ ne pose pas de problème car $g$ est
+ calculable ;
+\item calculer $\hat F(\gamma(g,n,j))$ est possible car $\gamma$ est
+ calculable (question (4)) et $\hat F$ l'est (par définition de la
+ calculabilité de $F$) ;
+\item calculer $F(g)$ est possible, là aussi car $F$ est calculable
+ (note : à la limite, ce point se passe de justification car $F(g)$
+ est de toute façon une constante dans notre programme, sauf si on
+ fait varier $g$, ce qui ne sera le cas qu'à la question (9)) ;
+\item on a bien le droit de faire une boucle non bornée sur $j$ par
+ l'opérateur $\mu$ de Kleene ;
+\item calculer $\varphi_{\gamma(g,n,j)}(\ell)$ est possible car
+ $\gamma$ est calculable (et en utilisant un programme universel pour
+ le $\varphi$) ; d'ailleurs, ce calcul termine forcément car
+ $\varphi_{\gamma(g,n,j)}$ est une fonction totale par définition
+ de $\gamma(g,n,j)$.
+\end{itemize}
+
+\textbf{(b)} On utilise le théorème s-m-n exactement comme en (3)(c) :
+dès lors que $(d,\ell) \mapsto g_d(\ell)$ est caclulable, on en déduit
+une fonction $d \mapsto e_d$ calculable (totale ! et même primitive
+récursive, à savoir $e_d = s_{1,1}(q,d)$ où $q$ est tel que $g_d(\ell)
+= \varphi^{(2)}_q(d,\ell)$) vérifiant $g_d = \varphi_{e_d}$.
+\end{corrige}
\medskip
\textbf{(6)} Soit $\mathscr{H} := \{d\in\mathbb{N} :
-\varphi_d(0)\downarrow\}$ l'ensemble des $d$ tels que l'exécution de
+\varphi_d(0){\downarrow}\}$ l'ensemble des $d$ tels que l'exécution de
$\varphi_d(0)$ termine.\quad\textbf{(a)} Lorsque
$d\not\in\mathscr{H}$, que vaut $g_d$ ? et du coup, que vaut $\hat
F(e_d)$ ?\quad\textbf{(b)} Montrer que $\{d\in\mathbb{N} : \hat F(e_d)
@@ -354,15 +476,74 @@ $\complement\mathscr{H} = \{d\in\mathbb{N} : \varphi_d(0)\uparrow\}$
de $\mathscr{H}$ est-il semi-décidable ?\quad\textbf{(d)} En déduire
qu'il existe $d\in\mathscr{H}$ tel que $\hat F(e_d) = F(g)$.
+\begin{corrige}
+\textbf{(a)} Si $d\not\in\mathscr{H}$, alors dans l'algorithme A, on
+est toujours dans le cas « l'exécution ne s'est pas terminée dans le
+temps imparti », donc $g_d(\ell)$ pour tout $\ell$, c'est-à-dire que
+$g_d = g$ (et notamment, $g_d$ est \emph{totale}). Par conséquent,
+$\hat F(e_d) = F(g_d) = F(g)$ (par extensionnalité).
+
+\textbf{(b)} Pour semi-décider si $\hat F(e_d) = F(g)$, il suffit de
+lancer le calcul de $\hat F(e_d)$ et, si celle-ci termine, comparer
+son résultat à $F(g)$ et renvoyer vrai si c'est le cas (et sinon,
+faire une boucle infinie).
+
+(On notera que le calcul de $\hat F(e_d)$ ne termine pas forcément,
+parce qu'on n'a pas la certitude que $e_d \in \mathsf{TotCode}$ vu
+qu'on ne sait pas si $g_d$ est totale.)
+
+\textbf{(c)} L'ensemble $\mathscr{H}$ n'est pas décidable (c'est une
+variante du problème de l'arrêt, ou bien on peut invoquer le théorème
+de Rice) ; or il est clairement semi-décidable. Donc
+$\complement\mathscr{H}$ n'est pas semi-décidable.
+
+\textbf{(d)} Supposons par l'absurde qu'on ait $\hat F(e_d) \neq F(g)$
+pour tout $d\in\mathscr{H}$ : comme on a vu en (a) que $\hat F(e_d) =
+F(g)$ pour tout $d\not\in\mathscr{H}$, on a alors $\{d\in\mathbb{N} :
+\hat F(e_d) \neq F(g)\} = \mathscr{H}$, autrement dit
+$\{d\in\mathbb{N} : \hat F(e_d) = F(g)\} = \complement\mathscr{H}$, or
+on a vu en (b) que $\{d\in\mathbb{N} : \hat F(e_d) = F(g)\}$ est
+semi-décidable et en (c) que $\complement\mathscr{H}$ ne l'est pas,
+une contradiction. Donc il doit exister $d\in\mathscr{H}$ tel que
+$\hat F(e_d) = F(g)$.
+\end{corrige}
+
\medskip
\textbf{(7)} On a montré en (6) qu'il existe $d$ tel que
-$\varphi_d(0)\downarrow$ et que $\hat F(e_d) = F(g)$. Soit $n$ le
-nombre d'étapes d'exécution\footnote{Ou si on préfère : l'arbre de
-calcul.} de $\varphi_d(0)$. Montrer que pour tout $g' \in
+$\varphi_d(0){\downarrow}$ et que $\hat F(e_d) = F(g)$. Soit $n$ le
+nombre d'étapes d'exécution\footnote{Ou si on préfère : le code de
+l'arbre de calcul.} de $\varphi_d(0)$. Montrer que pour tout $g' \in
\mathcal{B}_0(g,n)$ on a $F(g') = F(g)$. (\emph{Indication :} sinon,
-la recherche d'un $j$ dans l'algorithme A aurait trouvé un $j$ et on
-aurait $g_d = \varphi_{\gamma(g,n,j)}$.)
+la recherche d'un $j$ dans l'algorithme A aurait réussi à trouver
+un $j$ : on pourra montrer qu'on aurait $g_d =
+\varphi_{\gamma(g,n,j)}$ donc $F(g_d) \neq F(g)$ dans ce cas.)
+
+\begin{corrige}
+Supposons par l'absurde que $F(g') \neq F(g)$ pour un certain $g' \in
+\mathcal{B}_0(g,n)$. Comme on l'a vu dans la question (4), on a $g' =
+\varphi_{\gamma(g,n,j_0)}$ pour un certain $j_0$, et en particulier,
+$F(g') = F(\varphi_{\gamma(g,n,j_0)}) = \hat F(\gamma(g,n,j_0))$ donc
+$\hat F(\gamma(g,n,j_0)) \neq F(g)$. Dans l'exécution de
+l'algorithme A, si $\ell\geq n$, on est dans le cas où l'exécution de
+$\varphi_d(0)$ s'est terminée dans le temps imparti (par définition
+de $n$), et la seconde boucle va trouver un $j$ tel que $\hat
+F(\gamma(g,n,j)) \neq F(g)$ (puisqu'il en existe un), pas forcément
+$j_0$ mais toujours le même quel que soit $\ell$, appelons-le $j_1$,
+et l'algorithme va renvoyer $\varphi_{\gamma(g,n,j_1)}(\ell)$ ; tandis
+que si $\ell<n$, alors l'exécution de $\varphi_d(0)$ ne sera terminée
+dans le temps imparti et l'algorithme va renvoyer $g(\ell)$, qui est
+aussi $\varphi_{\gamma(g,n,j_1)}(\ell)$ puisque $\gamma(g,n,j_1) \in
+\mathcal{B}(g,n)$. Donc dans tous les cas, l'algorithme renvoie
+$\varphi_{\gamma(g,n,j_1)}(\ell)$, c'est-à-dire que $g_d =
+\varphi_{\gamma(g,n,j_1)}$. Or la définition de $j_1$ fait que $\hat
+F(\gamma(g,n,j_1)) \neq F(g)$, et on a $F(g_d) =
+F(\varphi_{\gamma(g,n,j_1)}) = \hat F(\gamma(g,n,j_1))$, ce qui mis
+ensemble montre que $F(g_d) \neq F(g)$. Mais ceci contredit le fait
+que $F(g_d) = \hat F(e_d) = F(g)$. On a bien abouti à une
+contradiction. C'est donc que $F(g') = F(g)$ pour tout $g' \in
+\mathcal{B}_0(g,n)$.
+\end{corrige}
\medskip
@@ -375,12 +556,211 @@ qu'on vient de dire, il existe $n'$ tel que pour tout $g'' \in
trouver $g'' \in \mathcal{B}_0(g,n) \cap \mathcal{B}_0(g',n')$,
montrer que $F(g') = F(g)$. Conclure.
+\begin{corrige}
+Renommons en $g''$ le $g'$ de la question (7) pour y voir plus clair :
+on a trouvé un $n$ tel que pour tout $g'' \in \mathcal{B}_0(g,n)$ on a
+$F(g'') = F(g)$. Si maintenant $g' \in \mathcal{B}(g,n)$, on trouve
+de la même manière $n'$ tel que pour tout $g'' \in
+\mathcal{B}_0(g',n')$ on a $F(g'') = F(g')$. Si $n'' = \max(n,n')$,
+alors n'importe quel $g'' \in \mathcal{B}_0(g',n'')$ coïncide avec
+$g'$ jusqu'au rang $n''$ donc jusqu'au rang $n'$, et par ailleurs avec
+$g'$ jusqu'au rang $n''$ donc jusqu'au rang $n$ donc aussi avec $g$
+jusqu'au rang $n$ : ceci montre $g'' \in \mathcal{B}_0(g,n) \cap
+\mathcal{B}_0(g',n')$ (en fait, $\mathcal{B}_0(g',n'') \subseteq
+\mathcal{B}_0(g,n) \cap \mathcal{B}_0(g',n')$), et on a $F(g'') =
+F(g)$ puisque $g'' \in \mathcal{B}_0(g,n)$ et $F(g'') = F(g')$ puisque
+$g'' \in \mathcal{B}_0(g',n')$, donc $F(g') = F(g'') = F(g)$.
+
+On a donc bien montré l'existence d'un certain $n$ tel que $F(g') =
+F(g)$ pour tout $g' \in \mathcal{B}(g,n)$.
+\end{corrige}
+
+\medskip
+
+\textbf{(9)} En observant que l'algorithme A peut s'écrire (à $g$
+variable) à partir du code d'un programme calculant $g$, justifier
+qu'un $n$ dont on a montré l'existence en (8) peut être obtenu de
+façon calculable en fonction du code d'un programme calculant $g$.
+(On esquissera un algorithme B qui calcule un $n$ en fonction d'un
+code $r$ d'un programme calculant $g$.)
+
+\begin{corrige}
+Observons d'abord que l'algorithme A peut s'écrire (i.e., « être rendu
+uniforme ») à partir du code $r$ d'un programme calculant $g =
+\varphi_r$ : on a déjà observé en (4) que c'est le cas
+de $\gamma(g,n,j)$, et dans l'algorithme A, on peut remplacer
+l'invocation de $g(\ell)$ par $\varphi_r(\ell)$ (calculable au moyen
+d'un programme universel), et celle de $F(g)$ par $\hat F(r)$. Au
+moyen du théorème s-m-n (comme on l'a déjà expliqué plusieurs fois
+ci-dessus), on en déduit une fonction calculable $(r,d) \mapsto
+e_{r,d}$ qui (si $r \in \mathsf{TotCode}$) renvoie le code d'un
+$e_{r,d}$ calculé par l'algorithme en question (i.e., un code pour
+$g_d$ si $g = \varphi_r$).
+
+Reste maintenant expliquer comment trouver $n$ en fonction de ce $r$.
+Pour cela, l'algorithme B sera le suivant. On parcourt tous les
+couples $(d,n)$ (disons, au moyen du code de Gödel $\langle
+d,n\rangle$ du couple), et, si $\varphi_d(0)$ termine en exactement
+$n$ étapes, on teste si $\hat F(e_{r,d}) = \hat F(r)$ (où $e_{r,d}$
+est, comme on vient de le dire, essentiellement la curryfication de
+l'algorithme A, et $\hat F$ est donné). Lorsqu'un $(d,n)$ est trouvé,
+on renvoie le $n$ en question.
+
+D'après la question (6) (et le fait que $\hat F(r) = F(g)$), il existe
+bien un tel $(d,n)$ comme recherché par l'algorithme B, donc celui-ci
+termine. D'après les question (7) et (8), le $n$ qu'il renvoie
+vérifie la propriété demandée.
+\end{corrige}
+
\medskip
-\textbf{(9)} En observant que l'algorithme A peut s'écrire à partir du
-code d'un programme calculant $g$, justifier que le $n$ dont on a
-montré l'existence en (8) peut être obtenu de façon calculable en
-fonction du code d'un programme calculant $g$.
+\textbf{(10)} On a montré en (3)–(8) le théorème de
+Kreisel-Lacombe-Shoenfield qui affirme que
+\[
+\forall F:\mathsf{TotCalc}\to\mathbb{N}\text{~calculable}.\;
+\forall g\in\mathsf{TotCalc}.\;
+\exists n\in\mathbb{N}.\;
+\forall g'\in\mathcal{B}(g,n).\;
+(F(g') = F(g))
+\]
+Montrer par un exemple simple que l'affirmation suivante\footnote{Ce
+serait une affirmation de continuité \emph{uniforme} de $F$.}
+\[
+\forall F:\mathsf{TotCalc}\to\mathbb{N}\text{~calculable}.\;
+\exists n\in\mathbb{N}.\;
+\forall g\in\mathsf{TotCalc}.\;
+\forall g'\in\mathcal{B}(g,n).\;
+(F(g') = F(g))
+\]
+n'est pas valable. (\emph{Indication :} proposer une fonction $F$ qui
+évalue un nombre de valeurs $g(i)$ de $g$ dépendant, disons,
+de $g(0)$.)
+
+\begin{corrige}
+On peut par exemple considérer la fonction(nelle) $F$ suivante :
+calculer $g(0) =: N$, puis calculer et renvoyer la somme des valeurs
+$g(1) + g(2) + \cdots + g(N)$. Manifestement, $F$ est bien
+calculable. Supposons par l'absurde qu'il existe $n$ tel que $\forall
+g\in\mathsf{TotCalc}.\; \forall g'\in\mathcal{B}(g,n).\; (F(g') =
+F(g))$. Considérons la fonction (évidemment calculable) qui vaut
+$n+1$ en $0$ et $0$ en tout $i>0$ : 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}
+
%