Funções recursivas primitivas e função Ackerman

A função de Ackerman é uma das características mais famosas da Ciência da Computação. Está associado a pelo menos um resultado fundamental e pelo menos um simplesmente importante. O resultado fundamental, para colocá-lo de maneira clara e incompreensível, é o seguinte: existe uma função computável definida em todos os lugares que não é recursiva primitiva. Um resultado importante é que a floresta de conjuntos disjuntos (também conhecida como união de conjuntos disjuntos) é muito rápida .


Eu realmente gosto de estudar a função de Ackerman, como tudo relacionado a ela é muito bonito e elegante. Portanto, o resultado fundamental registrado acima é muito mais fácil de entender do que parece.


No texto abaixo, você aprenderá o que são funções recursivas primitivas e como descobrir que a função Akkerman não se aplica a elas. E, é claro, este texto o convencerá de que é um design incrivelmente bonito e um raciocínio incrivelmente bonito!


1. Por que pode ser interessante


A discussão da relação entre funções recursivas primitivas e a função Ackerman é um exemplo de solução de um problema padrão na teoria da computabilidade: um determinado modelo de cálculo, uma determinada função é fornecida e é necessário determinar se essa função é computável nesse modelo.


Outros exemplos semelhantes estão associados, por exemplo, à decidibilidade algorítmica , à equivalência de vários modelos computacionais (máquinas de Turing, funções parcialmente recursivas, algoritmos normais de Markov e assim por diante). E através deles já estamos conectados a uma área de definição completamente prática para a integridade de Turing das linguagens de programação, transformações equivalentes dos textos dos programas e outras coisas interessantes.


A função de Ackerman parece ter sido criada especialmente para ser um exemplo elegante de solução de tais problemas. Você verá isso em breve.


2. função Ackerman


, « ». , , , .


a0,a1,...,an,... . :


a0(x)=x+1


ai+1(x)=ai[x+2](x)


f[n](x)=f(f(...(f(x))...))n, n . , : , x+2 xx.


, — , .


:


def Foo(number, argument):
    if number == 0:
        return argument + 1

    result = argument
    for i in range(argument + 2):
        result = Foo(number - 1, result)

    return result

ai(x) Foo(i, x).


. -, : ai(x)>x i x. , , a0(x)=x+1>x, a0 .


-, : ai+1(x)>ai(x) i x. , — , . :


ai+1(x)=ai[x+2](x)ai[2](x)=ai(ai(x))>ai(x)


,


ai+1(x)ai(ai(x))


3. - ()


« ». — . : , , , .


- ? «». - :


  1. , : Null(x1,x2,...,xk)=0
  2. : S(x)=x+1
  3. -: Pik(x1,x2,...,xk)=xi

. « »:


  • . fk , g1,g2,...,gkn , n F: n , k g1,...,gk, f. !

F(x1,...,xn)=f(g1(x1,...,xn),...,gk(x1,...,xn))


  • . fk , gk+2 , , :

F(x1,...,xk,0)=f(x1,...,xk)


F(x1,...,xk,y+1)=g(x1,...,xk,y,F(x1,...,xk,y))


, . : , . : , , . , .. , .


, — , , .


.


, . , . , :


Sum(x,0)=P11(x)


Sum(x,y+1)=S(P33(x,y,Sum(x,y)))


— , . , . Sum(x,0)=x, , .. x . P11. , : x,y,Sum(x,y). , P33, .


:


Mult(x,0)=Null(x)


Mult(x,y+1)=Sum(P13(x,y,Mult(x,y)),P33(x,y,Mult(x,y)))


- . , ! , :


Fib0=0
Fib1=1
Fibn+2=Fibn+Fibn+1


, ; , !


, . , F, . , G, , :


F(n)=Fibn
G(n)=Fibn+1


F 0, 1, 1, 2, 3, 5; G, , 1, 1, 2, 3, 5, 8. :
G(n+1)=G(n)+F(n)
F(n+1)=G(n)


:


F(0)=Null()


G(0)=S(Null())


F(y+1)=P12(G(y),F(y))


G(y+1)=Sum(F(y),G(y))


:


def G(x):
    if x == 0:
        return 1
    return G(x - 1) + F(x - 1)

def F(x):
    if x == 0:
        return 0
    return G(x - 1)

, , , , n- - !


4. ,


, - « » . : - k f n, :


f(x1,...,xk)<an(max(x1,...,xk))


— . , , .


, :


Null(x1,...,xk)=0<max(x1,...,xk)+1=a0(max(x1,...,xk))


S(x)=x+1=a0(x)<a1(x)


Pik(x1,...,xk)=ximax(x1,...,xk)<a0(max(x1,...,xk))


, , a0 (: , , ). — a0, a1. - , , , .


. : , , , , .


F f,g1,...,gk, aM. , F . :


F(x1,...,xn)=f(g1(x1,...,xn),...,gk(x1,...,xn))<


<aM(max(g1(x1,...,xn),...,gk(x1,...,xn)))<


<aM[max(aM(max(x1,...,xn)),...,aM(max(x1,...,xn)))]


<aM(aM(max(x1,...,xn)))aM+1(max(x1,...,xn))


f, gi, k , . aM , aM+1.


F f g, aM.


, , . : f:


F(x1,...,xk,0)=f(x1,...,xk)<aM(max(x1,...,xk))


, , :


F(x1,...,xk,1)=g(x1,...,xk,0,F(x1,...,xk,0))<


<aM(max(x1,...,xk,0,aM(max(x1,...,xk)))<


<aM(aM(max(x1,...,xk))=aM[2](max(x1,...,xk))


F, g. aM: ,


aM(max(x1,...,xk))>max(x1,...,xk,0)


, ,


F(x1,...,xk,y)<aM[y+1](max(x1,...,xk))


E as propriedades da sequência introduzida de funções garantem que


aM[y+1 1](mumax(x1 1,...,xk))<umaM+1 1(mumax(x1 1,...,xk,y))


Finalmente:


F(x1 1,...,xk,y)<umaM+1 1(mumax(x1 1,...,xk,y))


E é aqui que a nossa prova termina. O engraçado é que, cada aplicação de composição ou recursão primitiva aumenta em um o número da função necessária pelas condições da instrução.


5. Função Ackerman e PRF, parte dois


Portanto, sabemos que, para qualquer função recursiva primitiva, existe uma função umaMque crescerá mais rápido. Agora você pode definir a seguinte função:


UMA(n)=uman(n)


De fato, introduzindo a sequência de funções de um argumento, introduzimos a função de dois argumentos: o primeiro deles define o número da função na sequência, o segundo - o próprio argumento. Igualando o número e o argumento, obtemos a função de um argumento.


: A -.


, , -. 4 M, A(x)<aM(x) x. , :


A(M+1)=aM+1(M+1)>aM(M+1)


, -. - , ! .


6. ?


, , - , . , . nn. Além disso, qualquer função da forma


nn...nn


com um número predeterminado de expoentes, é recursivo primitivo. Eu não vou ser preguiçoso e provar isso. Para começar, eu construirei uma funçãony:


PoW(n,0 0)=S(Nvocêeueu())


PoW(n,y+1 1)=Mvocêeut(P1 13(n,y,PoW(n,y)),P33(n,y,PoW(n,y)))


Agora eu uso para definir uma função nn:


SPoW(n)=PoW(P1 11 1(n),P1 11 1(n))


Como você pode ver, isso é feito por simples substituição. Agora não há dificuldade em definir uma funçãonnn:


SSPoW(n)=PoW(P1 11 1(n),SPoW(n))


Por analogia, podemos construir uma função na qual n elevado ao poder ncinco vezes, dez vezes, cem vezes, um milhão de vezes. A função de Ackerman cresce mais rapidamente do que qualquer uma dessas funções. É assim que cresce rápido!

Source: https://habr.com/ru/post/undefined/


All Articles