• Aucun résultat trouvé

Fonctions universelles

Résultats fondamentaux de calculabilité

2.2 Fonctions universelles

On pourrait très bien continuer à exploiter la proposition1.5.5, mais on obtient une forme un peu plus simple pour les fonctions calculables avec une démonstration alternative des résultats précédents qui fait intervenir le code de la suite des états de la machine, plutôt que le temps de calcul qui est la longueur de cette suite. C’est l’objet de la section suivante.

2.2.1 Forme normale de Kleene.

Proposition 2.2.1 Pour chaque entier n≥1il existe un prédicat récursif primitif noté Tn et une fonc-tion récursive primitive U :N→Ntels que pour toute machine de code m calculant une fonction à n arguments f :

1.s Tn[m,x1, . . . ,xn,s]f(x1, . . . ,xn)↓ 2. Tn[m,x1, . . . ,xn,s]U(s)=f(x1, . . . ,xn) 3. ¡

Tn[m,x1, . . . ,xn,s]etTn[m,x1, . . . ,xn,s0

s=s0

Démonstration. L’idée est quesdésigne le code (en commençant par la fin) d’une suite d’états correcte pourm, soit [en; . . . ;e0]. On commence par définir un prédicatPn qui indique que la suite d’états est bien correcte (sans que le calcul soit forcément fini), pour une machine de codemavecx1, . . . ,xn en entrées. Le prédicatPnest défini par sa fonction caractéristiquegn:

gn(m,x1, . . . ,xn, [])=1

gn(m,x1, . . . ,xn, [e])=χ=(initn(m,x1, . . . ,xn),e)

gn(m,x1, . . . ,xn,e::s)=gn(m,x1, . . . ,xn,s)·χ=(tr(m, hd(s)),e)

la fonctiongn est définie par récurrence structurelle sur les listes, à partir de fonctions récursives pri-mitives. on a vu qu’alorsgnest récursive primitive. Le prédicatPnest donc récursif primitif. On définit ensuite

T0n[m,x1, . . . ,xn,s]Pn(m,x1, . . . ,xn,s]etHalt[m, hd(s)]

Tn[m,x1, . . . ,xn,s]≡T0n[m,x1, . . . ,xn,s]ets0<s¬T0n[m,x1, . . . ,xn,s0]

Le prédicat récursif primitifT0n ne vérifie a priori que la première condition de la proposition (termi-naison). Le prédicatTn est récursif primitif et vérifie les deux premières conditions : terminaison et fonctionalité poursen sortie.

La fonctionUa besoin d’extraire la valeur deR0du code du premier état dessoit : U(s)=hd(π21(hd(s)))

fonction qui est bien récursive primitive.

Corollaire 2.2.2 (forme normale de Kleene) Les prédicats Tnet la fonction U sont ceux de la proposi-tion précédente. Pour toute foncproposi-tion partielle calculable f :Nn→N, il existe au moins un entier m tel que :

f(x1, . . . ,xn)=U(µs.Tn[m,x1, . . . ,xn,s]) . Démonstration. Il suffit de prendre le codemd’une machine qui calculef. Une expression de la fonctionf comme celle donnée dans le corollaire :

f(x1, . . . ,xn)=g(µs.P(x1, . . . ,xn,s))

g:N→Nest une fonction récursive primitive etPun prédicat récursif primitif est dite sousforme normale de Kleene.

Exercice 14 En utilisant les prédicatsTnet la fonctionU, démontrer la proposition1.2.8 page 17 (clô-ture par « si ... alors ... sinon ... » dans le cas des fonctions partielles calculables).

2.2. Fonctions universelles. (v. provisoire 28 octobre 2021 13: 33) 35

2.2.2 Propriété d’énumération.

Pour chaquen≥1 on définit la fonction d’aritén+1ϕn:

ϕn(m,x1, . . . ,xn)=U(µs.Tn[m,x1, . . . ,xn,s]) et on note simplementϕpourϕ1.

Cette fonction partielle calculable permet de calculer toutes les fonctions partielles calculables àn arguments. On dit que c’est unefonction universellepour les fonctions partielles calculables àn argu-ments. On peut réécrire ainsi le corollaire précédent :

Théorème 2.2.3 (Théorème d’énumération) la famille de fonctions(ϕn)n∈N, définie ci-dessus est telle que pour toute fonction partielle calculable f :Nn→Nil existe au moins un entier m tel que :

f(x1, . . . ,xn)=ϕn(m,x1, . . . ,xn)

Un tel entiermsera appelé unindice de f (rappelons que c’est essentiellement le code d’une ma-chine qui calculef). On noteraf =ϕnmsimest un code def.

En fait chacune des fonctions (ϕn)n∈Nest universelle en un sens un peu plus fort. Par exemple, la fonctionϕ=ϕ1énumère modulo codage toutes les fonctions partielles calculables :

Corollaire 2.2.4 Pour toute fonction partielle calculable f:Nn→N, il existe un entier i tel que : f(x1, . . . ,xn)=ϕ(i,〈x1, . . . ,xn〉)

Démonstration. On prend pouriun indice de la fonction :x7→f(πn1(x), . . . ,πnn(x)).

Il est intuitivement clair (voir exercice suivant) qu’une fonction partielle calculable possède une infinité d’indices : on peut toujours ajouter des détours inutiles dans le programme d’une machine. On montrera plus tard que c’est en un certain sens inévitable.

Exercice 15 (Lemme de bourrage)

1. étant donné une machineMàkregistres, construire une machineM0, avec autant de registres, qui calcule la même fonction, et dont le programme a un code strictement plus grand que celui deM.

2. Soitn∈N. Montrer qu’il existe une fonction récursive primitiveu:N→Ntelle que ϕnu(m)=ϕnmet pour toutm u(m)>m

(upeut dépendre den) ;

3. Montrer qu’il existe une fonction récursive primitivev:N2→Ntelle quevest strictement crois-sante en sur son second argument et pour tous entiersmetp,ϕnv(m,p)=ϕnm.

Une conséquence immédiate du théorème d’énumération est que la fonction partielleϕn, qui est cal-culable àn+1 arguments, a un indice : le code d’une machine qui la calcule, que l’on appellemachine universelle.

Corollaire 2.2.5 Pour tout n≥1il existe un entier mntel que :

ϕn(m,x1, . . . ,xn)=ϕn+1(mn,m,x1, . . . ,xn) .

2.2.3 Propriété de paramétrisation.

Une propriété en quelque sorte réciproque de celle que l’on vient d’énoncer, est aussi caractéris-tique des familles de fonctions universelle, la propriété deparamétrisation.

Théorème 2.2.6 (théorèmesnmou de paramétrisation) Pour tous entiers m,n≥1il existe une fonction totale calculablesnm:Nm+1→Ntelle que :

ϕm+n(i,x1, . . . ,xm,y1, . . . ,yn)=ϕm(snm(i,x1, . . . ,xm),y1, . . . ,yn) Pour la famille de fonctions universelle étudiée ici, la fonctionsnmest récursive primitive.

Si on on revient aux machines, la fonction snmpermet donc, à partir du codeid’une machineMàm+n entrées, et dementiersx1, . . . ,xm, de calculer le code d’une machineM0àn entrées, qui fonctionne commeM, après avoir fixé lesmpremières entrées àx1, . . . ,xm.

Démonstration. On va suivre la remarque précédente. Il s’agit d’abord d’indiquer comment construire M0, puis on montre que les constructions se codent de façon récursive primitive. Il faut veiller à ce que la fonction calculée soit bien celle cherchée même quand l’indicei= 〈k,l〉n’est pas un « vrai » code de machine (cf. paragraphe1.5.2). La machineM0 va avoir les mêmesk registres. On construit son programme à partir de celui deMen 3 étapes.

1. On ajoute en tête de programme des instructions qui essentiellement (c’est-à-dire quand il y a suffisamment de registres) recopient les registres d’entréesR1, . . .,Rnà partir deRm+1(registres de travail), et mettent à 0 lesn premiers registres d’entrées). il faut en fait discuter suivant le nombre de registresk. L’opération est donnée,

sikmpar la séquence

Rk:=0, . . . ,R1:=0 sim<k<m+npar la séquence

Rk:=Rkm, . . . ,Rm+1:=R1 et sikm+npar la séquence

Rm+n:=Rn, . . . ,Rm+1:=R1. Chacune des instructionsRm+i:=Ri, respectivementRi:=0, s’écrit

l ifRi=0gotol+4 l+1 Rm+i:=Rm+i+1 l+2 Ri:=Ri−1 l+3 gotol

l ifRi=0gotol+3 l+1 Ri:=Ri−1 l+2 gotol

avec, par exemple dans le dernier casl=4(n−i). On ajoute 3klignes dans le premier cas, 4(k−m) dans le second cas et 4nlignes dans le dernier.

2. On ajoute ensuite les instructions qui correspondent à : R1:=x1, . . . ,Rm:=xm

chaque opérationRi:=xis’écrit (le registreRiest à 0) : Ri:=Ri+1, . . . ,Ri:=Ri+1

| {z }

xi

on ajoute doncx1+ · · · +xmlignes.

3. On ajoute le programme deM modifié de façon à se comporter de la même façon que pour la machineM, c’est-à-dire que les instructionsgotodoivent pointer sur les numéros de lignes décalées du nombre d’instructions ajouté en tête de programme. Ce nombre est une fonction de (k,x1, . . . ,xm) (metnsont des constantes).

Il est à peu près clair qu’à chaque étape correspond une opération récursive primitive sur le code. Ceux qui n’en sont pas convaincus sont invités à le démontrer eux-mêmes, ou, en dernier ressort, à chercher de possibles erreurs dans les détails donnés ci-dessous.