Función recursiva primitiva

ImprimirCitar
Función computable con bucles atados

En la teoría de la computabilidad, una función recursiva primitiva es, en términos generales, una función que puede calcularse mediante un programa de computadora cuyos bucles son todos "for" bucles (es decir, se puede determinar un límite superior del número de iteraciones de cada bucle antes de entrar en el bucle). Las funciones recursivas primitivas forman un subconjunto estricto de aquellas funciones recursivas generales que también son funciones totales.

La importancia de las funciones recursivas primitivas radica en el hecho de que la mayoría de las funciones computables que se estudian en teoría de números (y más generalmente en matemáticas) son recursivas primitivas. Por ejemplo, la suma y la división, la función factorial y exponencial, y la función que devuelve el nésimo primo son todos recursivos primitivos. De hecho, para mostrar que una función computable es recursiva primitiva, basta con mostrar que su complejidad temporal está acotada superiormente por una función recursiva primitiva del tamaño de entrada. Por lo tanto, no es tan fácil diseñar una función computable que no sea recursiva primitiva; se muestran algunos ejemplos en la sección § Limitaciones a continuación.

El conjunto de funciones recursivas primitivas se conoce como PR en la teoría de la complejidad computacional.

Definición

Una función recursiva primitiva toma un número fijo de argumentos, cada uno de ellos un número natural (entero no negativo: {0, 1, 2,...}), y devuelve un número natural. Si toma n argumentos, se llama n-ario.

Las funciones recursivas primitivas básicas están dadas por estos axiomas:

  1. Funciones constantes Ck
    n
    : Para cada número natural n y todos k, el k- función constante, definida por Cnk()x1,...... ,xk)=defn{displaystyle ¿Qué? {fnK} {fnK}}} No., es recursivo primitivo.
  2. Función de éxito: Función sucesora 1-ary S, que devuelve al sucesor de su argumento (ver Peano postulates), es decir, S()x)=defx+1{displaystyle S(x) {fnMicrosoft} } {=} x+1}, es recursivo primitivo.
  3. Función de proyección Pik{displaystyle P_{i} {k}: Para todos los números naturales i,k{displaystyle i,k} tales que 1≤ ≤ i≤ ≤ k{displaystyle 1leq ileq k}, el k- Funciónaria definida Pik()x1,...... ,xk)=defxi{displaystyle P_{i} {k}(x_{1},ldotsx_{k}) {fnMicrosoft} } {=} x_{i}} es recursivo primitivo.

Se pueden obtener funciones recursivas primitivas más complejas aplicando las operaciones dadas por estos axiomas:

  1. Composition operator ∘ ∘ {displaystyle circ ,} (también llamado el substitution operator): Dado un m- Función diaria h()x1,...... ,xm){displaystyle h(x_{1},ldotsx_{m},} y m k- Funciones g1()x1,...... ,xk),...... ,gm()x1,...... ,xk){displaystyle g_{1}(x_{1},ldotsx_{k}),ldotsg_{m}(x_{1},ldotsx_{k})}:
    h∘ ∘ ()g1,...... ,gm)=deff,Dondef()x1,...... ,xk)=h()g1()x1,...... ,xk),...... ,gm()x1,...... ,xk)).{displaystyle hcirc (g_{1},ldotsg_{m}) {fnMicrosoft} }{=} f,quad {text{where}quad f(x_{1},ldotsx_{k})=h(g_{1}(x_{1},ldotsx_{k}),ldotsg_{m}(x_{1},ldotsx_{k})). }
  2. Operador de recursión primitiva ***: Dada la k- Función diaria g()x1,...... ,xk){displaystyle g(x_{1},ldotsx_{k},} y elk+ 2) función diaria h()Sí.,z,x1,...... ,xk){displaystyle h(y,z,x_{1},ldotsx_{k},}:
    *** *** ()g,h)=deff,Donde()k+1)- Función diariafse define porf()0,x1,...... ,xk)=g()x1,...... ,xk)f()S()Sí.),x1,...... ,xk)=h()Sí.,f()Sí.,x1,...... ,xk),x1,...... ,xk).{displaystyle {begin{aligned}rho (g,h) sentimiento {stackrel {mathrm {def} } {=} {cHFF} {cHFF}}f}f}f(0,x_{1},ldotsx_{_k})} {ccccH0}cH00}cH00}cH00}

    Interpretación:

    La funciónf actúa como un for-loop de 0 hasta el valor de su primer argumento. El resto de los argumentos paraf, denotado aquí con x1,...,xk, son un conjunto de condiciones iniciales para el bucle que puede ser utilizado por él durante cálculos pero que son inmutables por él. Funciones g y h en el lado derecho de las ecuaciones que definen f representan el cuerpo del bucle, que realiza cálculos. La funcióng se utiliza sólo una vez para realizar cálculos iniciales. Cálculos para los pasos posteriores del bucle se realizan porh. El primer parámetro deh es alimentado el valor "corriente" del índice de for-loop. El segundo parámetro deh es alimentado el resultado de los cálculos previos del circuito, de pasos anteriores. El resto de los parámetros parah son esas condiciones iniciales inmutables para el bucle mencionado anteriormente. Pueden ser utilizados porh para realizar cálculos pero ellos mismos no serán alterados porh.

Las funciones recursivas primitivas son las funciones básicas y las que se obtienen de las funciones básicas aplicando estas operaciones un número finito de veces.

Ejemplos

  • C01{displaystyle C_{0} {1} es una función 1-ary que devuelve 0{displaystyle 0} para cada entrada: C01()x)=0{displaystyle C_{0} {1}(x)=0}.
  • C11{displaystyle C_{1} {1} es una función 1-ary que devuelve 1{displaystyle 1} para cada entrada: C11()x)=1{displaystyle C_{1}{1}(x)=1}.
  • C30{displaystyle C_{3} {0} es una función 0-ary, es decir, una constante: C30=3{displaystyle C_{3} {0}=3}.
  • P11{displaystyle P_{1} {1} es la función de identidad en los números naturales: P11()x)=x{displaystyle P_{1} {1}(x)=x}.
  • P12{displaystyle P_{1} {2} y P22{displaystyle P_{2} {2}} es la proyección izquierda y derecha en pares de números naturales, respectivamente: P12()x,Sí.)=x{displaystyle P_{1} {2}(x,y)=x} y P22()x,Sí.)=Sí.{displaystyle P_{2} {2}(x,y)=y}.
  • S∘ ∘ S{displaystyle Scirc S} es una función 1-ary que añade 2 a su entrada, ()S∘ ∘ S)()x)=x+2{displaystyle (Scirc S)(x)=x+2}.
  • S∘ ∘ C01{displaystyle Scirc C_{0} {1} es una función 1-ary que devuelve 1 para cada entrada: ()S∘ ∘ C01)()x)=S()C01()x))=S()0)=1{displaystyle (Scirc C_{0}{1})(x)=S(C_{0}^{1}(x)=S(0)=1}. Eso es, S∘ ∘ C01{displaystyle Scirc C_{0} {1} y C11{displaystyle C_{1} {1} son la misma función: S∘ ∘ C01=C11{displaystyle Scirco ¿Qué?. De una manera similar, cada Cn1{displaystyle C_{n} {1} puede expresarse como una composición apropiada de muchos S{displaystyle S. y C01{displaystyle C_{0} {1}.

Adición

Una definición de la función 2-ary Add{displaystyle Add}, para calcular la suma de sus argumentos, se puede obtener utilizando el operador de recursión primitiva *** *** {displaystyle rho }. Para ello, las ecuaciones conocidas

0+Sí.=Sí.yS()x)+Sí.=S()x+Sí.).{displaystyle {begin{array}{rcll}0+y tendrían un aspecto {text{ y}}S(x)+y tendrían una relación.

son "refrasados en la terminología de función recursiva primitiva": En la definición *** *** ()g,h){displaystyle rho (g,h)}, la primera ecuación sugiere elegir g=P11{displaystyle G=P_{1} {1}} para obtener Add()0,Sí.)=g()Sí.)=Sí.{displaystyle Add(0,y)=g(y)=y}; la segunda ecuación sugiere elegir h=S∘ ∘ P23{displaystyle h=Scirco P_{2} {3} para obtener Add()S()x),Sí.)=h()x,Add()x,Sí.),Sí.)=()S∘ ∘ P23)()x,Add()x,Sí.),Sí.)=S()Add()x,Sí.)){displaystyle Add(S(x),y)=h(x,Add(x,y),y)=(Scirc P_{2}^{3})(x,Add(x,y),y)=S(Add(x,y)}. Por lo tanto, la función de adición se puede definir como Add=*** *** ()P11,S∘ ∘ P23){displaystyle Add=rho (P_{1}^{1},Scirc P_{2} {3}}. Como ejemplo de cálculo,

Add()1,7)=*** *** ()P11,S∘ ∘ P23)()S()0),7)por Def.Add,S=()S∘ ∘ P23)()0,Add()0,7),7)por caso*** *** ()g,h)()S()...),...)=S()Add()0,7))por Def.∘ ∘ ,P23=S()*** *** ()P11,S∘ ∘ P23)()0,7))por Def.Add=S()P11()7))por caso*** *** ()g,h)()0,...)=S()7)por Def.P11=8por Def.S.{0} {0}} {0}} {0}} {0}}} ¿Por qué? Sí.

Duplicación

Dado Add{displaystyle Add}, la función 1-ary Add∘ ∘ ()P11,P11){displaystyle Addcirc (P_{1}{1},P_{1}{1}}} duplica su argumento, ()Add∘ ∘ ()P11,P11))()x)=Add()x,x)=x+x{displaystyle (Addcirc (P_{1}^{1},P_{1})(x)=Add(x,x)=x+x}.

Multiplicación

De manera similar como adición, la multiplicación puede ser definida por Mul=*** *** ()C01,Add∘ ∘ ()P23,P33)){displaystyle Mul=rho (C_{0}{1},Addcirc (P_{2}{3},P_{3}^{3})}. Esto reproduce las ecuaciones de multiplicación conocidas:

Mul()0,Sí.)=*** *** ()C01,Add∘ ∘ ()P23,P33))()0,Sí.)por Def.Mul=C01()Sí.)por caso*** *** ()g,h)()0,...)=0por Def.C01.{} {} {f}cH00}\cH00}\cH00}\cH00}\cH0}cH0}cH00}cH0}cH0}cH0\cH0}cH0\cH00}cH0\cH00\cH0\\cH0}cH0cH00\cH00cH00cH00cH0}cH00cH00cH00cH00cH00cH00cH00cH00cH00\cH00cH00cH00\cH00} - ¿Qué?

y

Mul()S()x),Sí.)=*** *** ()C01,Add∘ ∘ ()P23,P33))()S()x),Sí.)por Def.Mul=()Add∘ ∘ ()P23,P33))()x,Mul()x,Sí.),Sí.)por caso*** *** ()g,h)()S()...),...)=Add()Mul()x,Sí.),Sí.)por Def.∘ ∘ ,P23,P33=Mul()x,Sí.)+Sí.por propiedad deAdd.{fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {f}} {f}} {cH0} {cH0} {cH0}cH0}cH0}cH00}cH00}cH00}cH00}cH00}

Predecesora

(feminine)

La función predecesora actúa como la "opposita" de la función sucesora y se define recursivamente por las reglas Pred()0)=0{displaystyle Pred(0)=0} y Pred()S()n))=n{displaystyle Pred(S(n)=n}. Una definición recursiva primitiva es Pred=*** *** ()C00,P12){displaystyle Pred=rho (C_{0} {0},P_{1}{2}}. Como ejemplo de cálculo,

Pred()8)=*** *** ()C00,P12)()S()7))por Def.Pred,S=P12()7,Pred()7))por caso*** *** ()g,h)()S()...),...)=7por Def.P12.{displaystyle {begin{lll} {cH00}\cH00}\\cH00\cH00\cH009} (C_{0}{0},P_{1}{2});(S(7)) limitada{text{ by Def. }}Pred,S= limitP_{1}^{2}(7,Pred(7))} {text{ by case }}rho (g,h);(S(...),...)={7}=cl] }P_{1} {2}

Resta truncada

La función restante limitada (también llamada "monus", y denotado "− − .{fnMicrosoft Sans Serif} {}}}") es definible de la función predecesora. Satisface las ecuaciones

Sí.− − .0=Sí.ySí.− − .S()x)=Pred()Sí.− − .x).{displaystyle {begin{rcll}y{stackrel {fnMicrosoft Sans Serif}y {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif}S(x) {fnMicrosoft Sans Serif}

Puesto que la recursión pasa por el segundo argumento, comenzamos con una definición recursiva primitiva de la resta inversa, RSub()Sí.,x)=x− − .Sí.{displaystyle RSub(y,x)=x{stackrel Sí.. Su recursión entonces se extiende sobre el primer argumento, por lo que se puede obtener su definición recursiva primitiva, similar a la adición, como RSub=*** *** ()P11,Pred∘ ∘ P23){displaystyle RSub=rho (P_{1}{1}Predcirc P_{2} {3}}. Para deshacerse de la orden de argumento inversa, luego definir Sub=RSub∘ ∘ ()P22,P12){displaystyle Sub=Rsubcirc (P_{2}{2},P_{1} {2}}. Como ejemplo de cálculo,

Sub()8,1)=()RSub∘ ∘ ()P22,P12))()8,1)por Def.Sub=RSub()1,8)por Def.∘ ∘ ,P22,P12=*** *** ()P11,Pred∘ ∘ P23)()S()0),8)por Def.RSub,S=()Pred∘ ∘ P23)()0,RSub()0,8),8)por caso*** *** ()g,h)()S()...),...)=Pred()RSub()0,8))por Def.∘ ∘ ,P23=Pred()*** *** ()P11,Pred∘ ∘ P23)()0,8))por Def.RSub=Pred()P11()8))por caso*** *** ()g,h)()0,...)=Pred()8)por Def.P11=7por propiedad dePred.{fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {f} {f}f}f}f}f} {cH0}f}cH0}cH0}cH0}cH0}cH00}cH0}cH0fnMicrob}cH0}cH0cH0cH0}cH00}cH0}cH00}cH00}cH00}cH0cH00cH00}cH00}cH00cH0}cH0}cH00cH00}cH00} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif} {f} {f}}f}f}}f}f}f}f}f}f}f}f}f}f}f}f}f}f}f}}f}}}f}}}}}f}f}}f}f}}}f}}}}}f}f}}f}f}f}f}f}f}f}f}}f}}}}}f}}}}}}}}}}}}f}}}}}}}}}}f}f}}f}f}f}f}}f}f}f}f}}f}f}f}f}}f}}}}}}f}} }RSub=ConsejoPred(P_{1} {1}(8)) Consiguiendo {text{ by case }rho (g,h);(0,...)=ConsejoPred(8) consiguiendo {text{ by Def. Pred.

Convertir predicados en funciones numéricas

En algunas configuraciones, es natural considerar funciones recursivas primitivas que toman como entrada tuplas que mezclan números con valores de verdad (es decir, t para verdadero y f para falso), o que producen valores de verdad como salidas. Esto se puede lograr identificando los valores de verdad con números de cualquier forma fija. Por ejemplo, es común identificar el valor de verdad t con el número 1 y el valor de verdad f con el número 0. Una vez realizada esta identificación, la función característica de un conjunto A, que siempre devuelve 1 o 0, puede verse como un predicado que indica si un número está en el conjunto A. Tal identificación de predicados con funciones numéricas se asumirá en el resto de este artículo.

Predicado "Es cero"

Como ejemplo para un predicado recursivo primitivo, la función 1-ary IsZero{displaystyle IsZero} será definido como IsZero()x)=1{displaystyle IsZero(x)=1} si x=0{displaystyle x=0}, y IsZero()x)=0{displaystyle IsZero(x)=0}De lo contrario. Esto puede lograrse definiendo IsZero=*** *** ()C10,C02){displaystyle IsZero=rho (C_{1} {0},C_{0} {2}}. Entonces, IsZero()0)=*** *** ()C10,C02)()0)=C10()0)=1{displaystyle IsZero(0)=rho (C_{1}{0},C_{0}{2}(0)=C_{1}{0}(0)=1} y por ejemplo. IsZero()8)=*** *** ()C10,C02)()S()7))=C02()7,IsZero()7))=0{displaystyle IsZero(8)=rho (C_{1}{0},C_{0}{2}(S(7)=C_{0}^{2}(7,IsZero(7))=0}.

Predicado "Menor o igual"

Utilizando la propiedad x≤ ≤ Sí.⟺ ⟺ x− − .Sí.=0{displaystyle xleq yiff x{stackrel Sí., la función 2-ary Leq{displaystyle Leq. puede definirse Leq=IsZero∘ ∘ Sub{displaystyle Leq=IsZerocirco Subir. Entonces... Leq()x,Sí.)=1{displaystyle Leq(x,y)=1} si x≤ ≤ Sí.{displaystyle xleq y}, y Leq()x,Sí.)=0{displaystyle Leq(x,y)=0}De lo contrario. Como ejemplo de cálculo,

Leq()8,3)=IsZero()Sub()8,3))por Def.Leq=IsZero()5)por propiedad deSub=0por propiedad deIsZero{displaystyle {begin{array}{lll} {c]\\\\\\=cH00\\\\\cH009\\\cH009\cH009}Sub==0}\cH009\cH00}\cH00}\cH009\cH00}\cH009cH00}\cH009cH00}\cH00}cH00}\cH009\\cH00}\\\\\\\\cH009}}}}}}}}}\\cH00}\cH009cH00}\\\\\\\cH00}}}\\\\\cH00}}}}}}}}

Predicado "Mayor o igual"

Una vez definida Leq{displaystyle Leq. se obtiene, el predicado transversal se puede definir como Geq=Leq∘ ∘ ()P22,P12){displaystyle Geq=Leqcirco (P_{2}{2},P_{1} {2}}. Entonces, Geq()x,Sí.)=Leq()Sí.,x){displaystyle Geq(x,y)=Leq(y,x)} es cierto (más precisamente: tiene valor 1) si, y sólo si, x≥ ≥ Sí.{displaystyle xgeq y}.

Si-entonces-otro

El operador 3-ary if-then-else conocido desde lenguajes de programación puede ser definido por Si=*** *** ()P22,P34){displaystyle {textit {}=rho} (P_{2}{2},P_{3} {4}}. Entonces, por arbitrariedad x{displaystyle x},

Si()S()x),Sí.,z)=*** *** ()P22,P34)()S()x),Sí.,z)por Def.Si=P34()x,Si()x,Sí.,z),Sí.,z)por caso*** *** ()S()...),...)=Sí.por Def.P34{displaystyle {begin{lll}{textit {If}(S(x),y,z)\\= limitrho (P_{2}^{2},P_{4});(S(x),y,z)} {text{ by Def. }{textit {Si}\\\cHFF} {fnMicrosoft Sans Serif} {fnMicrosoft Sans Serif}}rho (S(...),...)\=Condentro{text{ by Def. {fnMicrosoft Sans Serif}

y

Si()0,Sí.,z)=*** *** ()P22,P34)()0,Sí.,z)por Def.Si=P22()Sí.,z)por caso*** *** ()0,...)=zpor Def.P22.{displaystyle {begin{lll} {textit {If}(0,y,z)\\\\\\\\=rho (P_{2}^{2},P_{4});(0,y,z)}{text{ by Def. }{textit {Si}\= }\\cH00} {2} {y,z)}rho (0,...)\= }= }= }= }text{ by Def. - ¿Qué?.

Eso es, Si()x,Sí.,z){displaystyle {textit {}(x,y,z)} devuelve la parte posterior, Sí.{displaystyle y}Si la parte si, x{displaystyle x}, es verdad, y la otra parte, z{displaystyle z}De lo contrario.

Juntas

Basado en Si{displaystyle {textit {Si}} función, es fácil definir los junctores lógicos. Por ejemplo, definir And=Si∘ ∘ ()P12,P22,C02){displaystyle Y={textit [Si]circ (P_{1} {2},P_{2} {2},C_{0}^{2}}, uno obtiene And()x,Sí.)=Si()x,Sí.,0){displaystyle And(x,y)={textit {If}(x,y,0)}, es decir, And()x,Sí.){displaystyle And(x,y)} es verdad si, y sólo si, ambos x{displaystyle x} y Sí.{displaystyle y} son verdaderas (conjunción lógica de x{displaystyle x} y Sí.{displaystyle y}).

Análogamente, Or=Si∘ ∘ ()P12,C12,P22){displaystyle O={textit [Si]circ (P_{1} {2},C_{1}{2},P_{2}^{2}} y Not=Si∘ ∘ ()P11,C01,C11){displaystyle No. [Si]circ (P_{1} {1},C_{0}{1},C_{1}^{1}} dar lugar a definiciones apropiadas de desjunción y negación: Or()x,Sí.)=Si()x,1,Sí.){displaystyle Or(x,y)={textit {If}(x,1,y)} y Not()x)=Si()x,0,1){displaystyle Not(x)={textit {If}(x,0,1)}.

Predicado de igualdad

Utilizando las funciones anteriores Leq{displaystyle Leq., Geq{displaystyle Geq. y And{displaystyle Y..., la definición Eq=And∘ ∘ ()Leq,Geq){displaystyle Eq=Andcirc (Leq,Geq)} implementa la situación de igualdad. De hecho, Eq()x,Sí.)=And()Leq()x,Sí.),Geq()x,Sí.)){displaystyle Eq(x,y)=And(Leq(x,y),Geq(x,y)} es verdad si, y sólo si, x{displaystyle x} iguales Sí.{displaystyle y}.

Análogamente, la definición Lt=Not∘ ∘ Geq{displaystyle No. implementa el predicado "menos-que", y Gt=Not∘ ∘ Leq{displaystyle Gt=Notcirc Leq} implementa "greater-than".

Otras operaciones con números naturales

Las pruebas de exponenciación y primalidad son recursivas primitivas. Dadas las funciones recursivas primitivas e, f, g y h, una función que devuelve el valor de g cuando ef y el valor de h de lo contrario es recursivo primitivo.

Operaciones con números enteros y racionales

Al usar la numeración de Gödel, las funciones recursivas primitivas se pueden extender para operar en otros objetos, como números enteros y números racionales. Si los números enteros se codifican mediante números de Gödel de forma estándar, las operaciones aritméticas, incluidas la suma, la resta y la multiplicación, son recursivas primitivas. De manera similar, si los racionales están representados por números de Gödel, entonces las operaciones de campo son todas recursivas primitivas.

Algunas funciones recursivas primitivas comunes

Los siguientes ejemplos y definiciones son de Kleene (1952) pp. 223–231 — muchos aparecen con pruebas. La mayoría también aparecen con nombres similares, ya sea como pruebas o como ejemplos, en Boolos-Burgess-Jeffrey 2002 pp. 63–70; añaden el logarithm lo(x, y) o lg(x, y) dependiendo de la derivación exacta.

A continuación observamos que las funciones recursivas primitivas pueden ser de cuatro tipos:

  1. funciones para abreviar: "funciones teórico-número" de { 0, 1, 2,...} a { 0, 1, 2,...},
  2. predicados: de { 0, 1, 2,...} a los valores de verdad { t =true, f =false },
  3. conexiones proposicionesde los valores de la verdad a los valores de la verdad
  4. funciones: de los valores de la verdad { t, f } a { 0, 1, 2,... }. Muchas veces un predicado requiere una función representativa para convertir la salida del predicado { t, f } a { 0, 1 } (nota el orden "t" a "0" y "f" a "1" partidos con ~sg() definido abajo). Por definición una función φ(x) es una "función representativa" del predicado P(x) si φ toma sólo los valores 0 y 1 y produce 0 cuando P es verdad".

A continuación, la marca " ' ", p. a', es la marca primitiva que significa "el sucesor de", generalmente considerado como " +1", p. ej. a +1 =def a'. Las funciones 16-20 y #G son de particular interés con respecto a la conversión de predicados recursivos primitivos a sus funciones "aritméticas" forma expresada como números de Gödel.

  1. Adición: a+b
  2. Multiplicación: a×b
  3. Exposición: ab
  4. Factorial a!: 0! = 1, a' = a'! '
  5. pred(a): (Predecesador o decremento): Si un título 0 entonces a-1 0
  6. Sustracción adecuada a ∸ b: Si un ≥ b entonces a-b 0
  7. Mínimo(a)1,... an)
  8. Máximo(a)1,... an)
  9. Diferencia absoluta:def (a ∸ b) + (b ∸ a)
  10. ~sg(a): NOT[signum(a)]: Si a=0 entonces 1 más 0
  11. sg(a): signum(a): Si a=0 entonces 0 más 1
  12. a Silencio b: (una división b): Si b=k×a para algunos k entonces 0 más 1
  13. Restante(a, b): la sobra si b no divide un "evenalmente". También se llama MOD(a, b)
  14. a = b: sg Silencio a - b Silencio (La convención de Cleene era representar verdadero por 0 y falso por 1; actualmente, especialmente en las computadoras, la convención más común es la inversa, a saber, representar verdadero por 1 y falso por 0, lo que equivale a cambiar sg en ~sg aquí y en el siguiente artículo)
  15. a b: sg(a' ∸ b)
  16. Pr(a): a es un número primario Pr(a) =def a título personal1 < NO(Existe c)1 sec [ c sometidaa]
  17. pi: el número i+1-est
  18. a)i: exponente de pi en a: el único x tal que pixtención no(pix 'Silencio
  19. lh(a): la "longitud" o número de exponentes no-vanishing en un
  20. Lo(a, b): (logaritmo de a a base b): Si a, b > 1 entonces el mayor x tal que bx Silencio a otra 0
En lo siguiente, la abreviatura x =def x1, xn; los subscriptos pueden ser aplicados si el significado requiere.
  • #A: Una función φ definable explícitamente de funciones Ψ y constantes q1, qn es recursivo primitivo en Ψ.
  • #B: La suma finitayx, y) y el productoyx, y) son primitivas recursivas en .
  • #C: A predicar P obtenido por funciones de sustitución χ1, χm para las variables respectivas de un predicado Q es recursivo primitivo en la χ1, χm, Q.
  • #D: The following predicados son primitivos recursivos en Q y R:
  • NOT_Q(x).
  • Q OR R: Q(xV Rx),
  • Q AND R: Q(xRx),
  • Q IMPLIES R: Q(x) → R(x)
  • Q es equivalente a R: Q(x)x)
  • #E: The following predicados son primitivas recursivas en predicar R:
  • (Ey)y R(x, y) donde (Ey)y denota "hay al menos un y que es menos que z tal que"
  • (y)y R(x, y) donde (y)y denota "para todos y menos que z es verdad que"
  • μyy R(x, y). El operador μyy R(x, y) es un atado forma de la llamada minimización- o mu-operador: Definido como "el menor valor de y menos que z tal que R(x, y) es cierto; o z si no hay tal valor."
  • Definición por casos: La función se define así, donde Q1,...m son mutuamente excluyentes predicados (o "nuevo(x) tendrá el valor dado por la primera cláusula que aplica), es primitiva recursiva en φ1,...1,... Qm:
φ(x)
  • φ1()xSi Q1()x) es verdad,
  • ...............
  • φm()xSi Qm()x) es verdad
  • φm+1()xDe lo contrario
  • #G: Si φ satisface la ecuación:
φ(y,x) = χ(y, COURSE-φ(y; x2, xn), x2, xn entonces φ es recursivo primitivo en la χ. El valor COURSE-φ(y; x2 a n) de la función de curso de valores codifica la secuencia de valores φ(0,x2 a n, φ(y-1,x2 a n) de la función original.

Utilizar en aritmética de Peano de primer orden

En la aritmética de Peano de primer orden, hay un número infinito de variables (símbolos 0-arios), pero no hay símbolos no lógicos k-arios con k>0 que no sean S, +, * y ≤. Por lo tanto, para definir funciones recursivas primitivas, se debe usar el siguiente truco de Gödel.

Al usar una numeración de Gödel para secuencias, por ejemplo, la función β de Gödel, cualquier secuencia finita de números se puede codificar con un solo número. Por lo tanto, tal número puede representar la función recursiva primitiva hasta un n dado.

Sea h una función recursiva primitiva aria definida por:

h()0)=C{displaystyle h(0)=C}
h()n+1)=g()n,h()n)){displaystyle h(n+1)=g(n,h(n)}

donde C es una constante y g es una función ya definida.

Usando la función β de Gödel, para cualquier secuencia de números naturales (k0, k1,..., kn), existen números naturales b y c tales que, para todo i ≤ n, β(b, c, i) = ki. Por lo tanto, podemos usar la siguiente fórmula para definir h; más precisamente, m=h(n) es una forma abreviada de lo siguiente:

<math alttext="{displaystyle exists b:exists c:beta (b,c,0)=Cland forall i:(i∃ ∃ b:∃ ∃ c:β β ()b,c,0)=C∧ ∧ О О i:()i.n)→ → ()β β ()b,c,i+1)=g()i,β β ()b,c,i)))∧ ∧ ()m=β β ()b,c,n)){displaystyle exists b:exists c:beta (b,c,0)=Cland forall i:(i donen)rightarrow (beta (b,c,i+1)=g(i,beta (b,c,i))))land (m=beta (b,c,n)}<img alt="{displaystyle exists b:exists c:beta (b,c,0)=Cland forall i:(i

y la equiparación a g, ya definida, es de hecho una abreviatura de alguna otra fórmula ya definida (como lo es β, cuya fórmula se da aquí).

La generalización a cualquier función recursiva primitiva k-aria es trivial.

Relación con funciones recursivas

La clase más amplia de funciones recursivas parciales se define mediante la introducción de un operador de búsqueda ilimitado. El uso de este operador puede resultar en una función parcial, es decir, una relación con como máximo un valor para cada argumento, pero no necesariamente tiene ningún valor para ningún argumento (ver dominio). Una definición equivalente establece que una función recursiva parcial es aquella que puede calcularse mediante una máquina de Turing. Una función recursiva total es una función recursiva parcial que se define para cada entrada.

Toda función recursiva primitiva es recursiva total, pero no todas las funciones recursivas totales son recursivas primitivas. La función de Ackermann A(m,n) es un ejemplo bien conocido de una función recursiva total (de hecho, total demostrable), que no es recursivo primitivo. Se caracterizan las funciones recursivas primitivas como un subconjunto de las funciones recursivas totales utilizando la función de Ackermann. Esta caracterización establece que una función es recursiva primitiva si y solo si hay un número natural m tal que la función puede ser calculada por una máquina de Turing que siempre se detiene dentro de A(m,n) o menos pasos, donde n es la suma de los argumentos de la función recursiva primitiva.

Una propiedad importante de las funciones recursivas primitivas es que son un subconjunto recursivamente enumerable del conjunto de todas las funciones recursivas totales (que en sí mismo no es recursivamente enumerable). Esto significa que hay una única función computable f(m,n) que enumera las funciones recursivas primitivas, a saber:

  • Para cada función recursiva primitiva g, hay un m tales que g()n) f()m,n) para todos n, y
  • Por todos m, la función h()n) f()m,n) es primitiva recursiva.

f se puede construir explícitamente repitiendo iterativamente todas las formas posibles de crear funciones recursivas primitivas. Por lo tanto, es demostrablemente total. Se puede usar un argumento de diagonalización para mostrar que f no es un primitivo recursivo en sí mismo: si lo hubiera sido, también lo sería h(n) = f(n,n)+1. Pero si esto es igual a alguna función recursiva primitiva, existe una m tal que h(n) = f(m,n) para todo n, y luego h(m) = f(m,m), lo que lleva a la contradicción.

Sin embargo, el conjunto de funciones recursivas primitivas no es el subconjunto recursivamente enumerable más grande del conjunto de todas las funciones recursivas totales. Por ejemplo, el conjunto de funciones demostrablemente totales (en la aritmética de Peano) también es recursivamente enumerable, ya que uno puede enumerar todas las pruebas de la teoría. Si bien todas las funciones recursivas primitivas son demostrablemente totales, lo contrario no es cierto.

Limitaciones

Las funciones recursivas primitivas tienden a corresponder muy de cerca con nuestra intuición de lo que debe ser una función computable. Ciertamente, las funciones iniciales son intuitivamente computables (en su misma simplicidad), y las dos operaciones mediante las cuales se pueden crear nuevas funciones recursivas primitivas también son muy sencillas. Sin embargo, el conjunto de funciones recursivas primitivas no incluye todas las funciones computables totales posibles; esto se puede ver con una variante del argumento diagonal de Cantor. Este argumento proporciona una función computable total que no es recursiva primitiva. Un esquema de la demostración es el siguiente:

Las funciones recursivas primitivas de un argumento (es decir, funciones inadvertidas) pueden enumerarse computadamente. Esta enumeración utiliza las definiciones de las funciones recursivas primitivas (que son esencialmente sólo expresiones con la composición y las operaciones de recursión primitiva como operadores y las funciones recursivas primitivas básicas como átomos), y se puede suponer que contienen cada definición una vez, aunque una misma función ocurrirá muchas veces en la lista (ya que muchas definiciones definen la misma función; de hecho, simplemente componer por la función de identidad genera infinitamente muchas definiciones de cualquier función recursiva primitiva). Esto significa que n-la definición de una función recursiva primitiva en esta enumeración puede determinarse efectivamente a partir de n. De hecho, si uno utiliza algunos Gödel numeración para codificar definiciones como números, entonces esto n-la definición en la lista es calculada por una función recursiva primitiva n. Vamos fn denotar la función recursiva primitiva no original dada por esta definición.

Ahora definir la "función del evaluador" ev con dos argumentos, por ev()i,j) fi()j). Claramente ev es total y computable, ya que uno puede determinar eficazmente la definición fi, y ser una función recursiva primitiva fi es en sí mismo total y computable, así fi()j) es siempre definido y efectivamente computable. Sin embargo, un argumento diagonal mostrará que la función ev de dos argumentos no es recursivo primitivo.

Suppose ev eran primitivas recursivas, entonces la función no seria g definidas por g()i.ev()i,i) sería también recursivo primitivo, ya que se define por la composición de la función sucesora y ev. Pero entonces g ocurre en la enumeración, por lo que hay algún número n tales que g = fn. Pero ahora g()n.ev()n,n) = S(fn()n) = S(g()n) da una contradicción.

Este argumento se puede aplicar a cualquier clase de funciones computables (totales) que se pueden enumerar de esta manera, como se explica en el artículo Máquina que siempre se detiene. Sin embargo, tenga en cuenta que las funciones computables parciales (aquellas que no necesitan definirse para todos los argumentos) se pueden enumerar explícitamente, por ejemplo, enumerando las codificaciones de la máquina de Turing.

Se conocen otros ejemplos de funciones recursivas totales pero no recursivas primitivas:

  • La función que toma m a Ackermann(m,m) es una función recursiva total no original que no es recursiva primitiva.
  • El teorema de París-Harrington implica una función recursiva total que no es recursiva primitiva.
  • Función del Sudán
  • La función Goodstein

Variantes

Funciones constantes

En lugar de Cnk{displaystyle C_{n} {k}, definiciones alternativas utilizan sólo un 0-ary Función cero C00{displaystyle C_{0} {0} como una función primitiva que siempre devuelve cero, y construye las funciones constantes de la función cero, la función sucesora y el operador de composición.

Recursión primitiva débil

La función predecesora de 1 lugar es recursiva primitiva, consulte la sección #Predecesor. Fischer, Fischer &amperio; Beigel eliminó el predecesor implícito de la regla de recursión, reemplazándolo por la regla más débil

f()0,x1,...... ,xk)=g()x1,...... ,xk)yf()S()Sí.),x1,...... ,xk)=h()S()Sí.),f()Sí.,x1,...... ,xk),x1,...... ,xk){fnMicrosoft Sans Serif} {f} {cH00} {cH00} {cH00}} {cccH00}}cccH00}cH00}cH00}cH00} {cH00cH00}cH00} {cH00cH00cH00}cH00}cH00}cH00cH00cH00cH00}cH00}cH00cH00cH00cH00}cH00cH00}cH00cH00}cH00}cH00cH00cH00}cH00}cH00}cH00cH00cH00cH00cH00cH00}cH00}cH00}cH00cH00cH00cH00cH00}}cH00}

Probaron que la función predecesora aún se podía definir y, por lo tanto, que "débil" La recursividad primitiva también define las funciones recursivas primitivas.

Funciones iterativas

Debilitándolo aún más utilizando funciones h{displaystyle h} de la aridad k+1, eliminación Sí.{displaystyle y} y S()Sí.){displaystyle S(y)} de los argumentos de h{displaystyle h} completamente, tenemos el iteración regla:

f()0,x1,...... ,xk)=g()x1,...... ,xk)yf()S()Sí.),x1,...... ,xk)=h()f()Sí.,x1,...... ,xk),x1,...... ,xk){cH00} {cH00} {ccH00}cH00} {ccH00}cH00} {ccH00} {ccH00} {cH00}}cH00}cH00} {cH00}}ccH00} {cH00cH00}}}}}cH00cH00cH00cH00}}}cH00cH00}}}}}}}cH00cH00cccH00ccH00cH00cH00cH00cH00cH00cH00cH00cH00cH00}cH00}cH00}cH00cH00cH00cH00cH00}cH00}cH00cH00}cH00}}}cH00}}}}cH00

La clase de funciones iterativas se define de la misma manera que la clase de funciones recursivas primitivas excepto con esta regla más débil. Se conjetura que estas son un subconjunto propio de las funciones recursivas primitivas.

Formas recursivas primitivas adicionales

Algunas formas adicionales de recursividad también definen funciones que son de hecho recursivo primitivo. Las definiciones en estos formularios pueden ser más fáciles de encontrar o más natural para leer o escribir. La recursión de curso de valores define funciones recursivas primitivas. Algunas formas de recursividad mutua también definen funciones recursivas primitivas.

Las funciones que se pueden programar en el lenguaje de programación LOOP son exactamente las funciones recursivas primitivas. Esto da una caracterización diferente del poder de estas funciones. La principal limitación del lenguaje LOOP, en comparación con un lenguaje completo de Turing, es que en el lenguaje LOOP se especifica el número de veces que se ejecutará cada ciclo antes de que el ciclo comience a ejecutarse.

Definición de lenguaje informático

Un ejemplo de un lenguaje de programación recursivo primitivo es uno que contiene operadores aritméticos básicos (p. ej., + y -, o SUMA y RESTA), condicionales y comparación (SI-ENTONCES, IGUAL, MENOR-QUE) y bucles acotados, como como el bucle for básico, donde hay un límite superior conocido o calculable para todos los bucles (FOR i FROM 1 TO n, sin i ni n modificables por el cuerpo del bucle). No se admiten estructuras de control de mayor generalidad, como bucles while o IF-THEN más GOTO, en un lenguaje recursivo primitivo.

El lenguaje LOOP, introducido en un artículo de 1967 por Albert R. Meyer y Dennis M. Ritchie, es uno de esos lenguajes. Su poder de cómputo coincide con las funciones recursivas primitivas. Una variante del lenguaje LOOP es BlooP de Douglas Hofstadter en Gödel, Escher, Bach. Agregar bucles ilimitados (WHILE, GOTO) hace que el lenguaje sea recursivo en general y Turing completo, como lo son todos los lenguajes de programación de computadoras del mundo real.

La definición de funciones recursivas primitivas implica que su cálculo se detiene en cada entrada (después de un número finito de pasos). Por otro lado, el problema de la detención es indecidible para funciones recursivas generales, incluso si son totales. Es decir, hay programas que se detienen en cada entrada, pero para los cuales esto no puede ser verificado por un algoritmo.

Resultados de finitismo y consistencia

Las funciones recursivas primitivas están estrechamente relacionadas con el finitismo matemático y se utilizan en varios contextos de lógica matemática donde se desea un sistema particularmente constructivo. La aritmética recursiva primitiva (PRA), un sistema de axiomas formales para los números naturales y las funciones recursivas primitivas en ellos, se usa a menudo para este propósito.

PRA es mucho más débil que la aritmética de Peano, que no es un sistema finitista. Sin embargo, muchos resultados en la teoría de números y en la teoría de la demostración pueden probarse en PRA. Por ejemplo, el teorema de incompletitud de Gödel se puede formalizar en PRA, dando el siguiente teorema:

Si T es una teoría de aritmética satisfacer ciertas hipótesis, con la sentencia de Gödel GT, entonces PRA demuestra la implicación Con(T)→GT.

Del mismo modo, muchos de los resultados sintácticos de la teoría de las demostraciones pueden probarse en PRA, lo que implica que existen funciones recursivas primitivas que realizan las correspondientes transformaciones sintácticas de las demostraciones.

En la teoría de la prueba y la teoría de conjuntos, existe un interés en las pruebas de consistencia finitistas, es decir, las pruebas de consistencia que en sí mismas son finitísticamente aceptables. Tal prueba establece que la consistencia de una teoría T implica la consistencia de una teoría S al producir una función recursiva primitiva que puede transformar cualquier prueba de una inconsistencia de S en una prueba de una inconsistencia de T. Una condición suficiente para que una prueba de consistencia sea finitista es la capacidad de formalizarla en PRA. Por ejemplo, muchos resultados de consistencia en la teoría de conjuntos que se obtienen forzando pueden reformularse como pruebas sintácticas que pueden formalizarse en PRA.

Historia

Las definiciones recursivas se habían usado antes de manera más o menos formal en matemáticas, pero la construcción de la recursividad primitiva se remonta al teorema 126 de Richard Dedekind de su libro Was sind und was sollen die Zahlen? (1888). Este trabajo fue el primero en dar una prueba de que cierta construcción recursiva define una función única.

La aritmética recursiva primitiva fue propuesta por primera vez por Thoralf Skolem en 1923.

La terminología actual fue acuñada por Rózsa Péter (1934) después de que Ackermann demostrara en 1928 que la función que hoy lleva su nombre no era recursiva primitiva, hecho que motivó la necesidad de renombrar lo que hasta entonces se llamaba simplemente funciones recursivas.

Contenido relacionado

Thomas Bradwardine

Thomas Bradwardine fue un clérigo, erudito, matemático, físico, cortesano y, muy brevemente, arzobispo de Canterbury inglés. Como célebre filósofo...

Necesidad y suficiencia

En lógica y matemáticas, necesidad y suficiencia son términos utilizados para describir una relación condicional o implicativa entre dos enunciados. Por...

Computadora personal IBM

Más resultados...
Tamaño del texto:
Copiar