En pocas palabras : un algoritmo es la parte constructiva de una prueba constructiva de que un problema dado tiene una solución. La motivación para esta definición es el isomorfismo de Curry-Howard entre programas y pruebas, considerando que un programa tiene un interés solo si resuelve un problema, pero probablemente así sea. Esta definición permite una mayor abstracción, y deja algunas puertas abiertas con respecto al tipo de dominios que pueden preocuparse, por ejemplo, con respecto a las propiedades de finitud.
Advertencia . Estoy tratando de encontrar un enfoque formal adecuado para responder la pregunta. Creo que es necesario, pero parece que ninguno de los usuarios que respondieron hasta ahora (incluido yo mismo, y algunos fueron más o menos explícitos al respecto en otras publicaciones) tiene los antecedentes adecuados para desarrollar adecuadamente los problemas, que están relacionados con Matemáticas constructivas, teoría de pruebas, teoría de tipos y resultados como el isomorfismo de Curry-Howard entre pruebas y programas. Estoy haciendo mi mejor esfuerzo aquí, con cualquier fragmento de conocimiento que tenga (creo), y soy muy consciente de las limitaciones de esta respuesta. Solo espero dar algunas pistas de cómo creo que debería ser la respuesta. Si ve algún punto que está claramente equivocado formalmente (probablemente), permítame ahora en un comentario, o por correo electrónico.
Identificando algunos problemas
Una forma estándar de considerar un algoritmo es establecer que un algoritmo es un programa arbitrariamente especificado para algunos dispositivos informáticos , incluidos aquellos que no tienen limitaciones en la memoria. El idioma también puede ser el lenguaje de la computadora. En realidad, es suficiente considerar todos los programas para un dispositivo informático completo de Turing (lo que implica no tener limitaciones de memoria). Es posible que no le proporcione todas las presentaciones de algoritmos, en el sentido de que los algoritmos deben expresarse de una forma que dependa en sus detalles del contexto de interpretación, incluso teórico, ya que todo está definido hasta cierta codificación. Pero, dado que calculará todo lo que hay que calcular, incluirá de alguna manera todos los algoritmos, hasta la codificación.
π
π, posiblemente en el sentido matemático de casi todos. Pero eso requeriría más precisión en las definiciones.
Entonces, la verdadera pregunta es saber cuáles son los algoritmos significativos. La respuesta es que los algoritmos significativos son aquellos que resuelven un problema, calculando paso a paso la "solución", la "respuesta" a ese problema. Un algoritmo es interesante si está asociado con un problema que resuelve.
Entonces, dado un problema formal, ¿cómo obtenemos un algoritmo que resuelva el problema? Ya sea explícita o implícitamente, los algoritmos están asociados con la idea de que existe una solución al problema, que puede probarse que es correcta. Si nuestras técnicas de prueba son precisas es otra cuestión, pero al menos tratamos de convencernos. Si se limita a las matemáticas constructivas, que en realidad es lo que tenemos que hacer (y es una restricción axiomática muy aceptable para la mayoría de las matemáticas), la forma de demostrar la existencia de una solución es pasar por los pasos de prueba que realmente muestran una construcción eso representa la solución, incluidos posiblemente otros pasos que establecen su corrección.
Todos los programadores piensan algo así: si jugueteo con los datos de tal o cual manera, obtengo este widget que tiene las propiedades correctas debido al teorema de Sesame, y al ejecutar esta transformación de preservación de foo obtengo la respuesta deseada . Pero la prueba suele ser informal, y no elaboramos todos los detalles, lo que explica por qué un satélite intentó orbitar Marte bajo tierra (entre otras cosas). Hacemos gran parte del razonamiento, pero en realidad solo conservamos la parte constructiva que construye la solución, y la describimos en un lenguaje de computadora como el algoritmo que resuelve el problema.
Algoritmos (o programas) interesantes
Todo esto fue para introducir las siguientes ideas, que son objeto de mucha investigación actual (de las cuales no soy especialista). La noción de " algoritmo interesante " utilizada aquí es mía, introducida como un lugar informal para obtener definiciones más precisas.
Un algoritmo interesante es la parte constructiva de una prueba constructiva de que un problema dado tiene una solución . Eso significa que la prueba realmente debe exhibir la solución en lugar de simplemente demostrar su existencia, por ejemplo, por contradicción. Para más detalles, ver Lógica intuitiva y constructivismo en matemáticas.
Por supuesto, esta es una definición muy restrictiva, que considera solo lo que llamé algoritmos interesantes. Entonces los ignora a casi todos. Pero también lo hacen todos nuestros libros de texto sobre algoritmos. Intentan enseñar solo algunos de los interesantes.
Dados todos los parámetros del problema (datos de entrada), le indica cómo obtener un resultado específico paso a paso. Un ejemplo típico es la resolución de ecuaciones (el algoritmo de nombre se deriva realmente del nombre de un matemático persa, Muḥammad ibn Mūsā al-Khwārizmī , que estudió la resolución de algunas ecuaciones). Partes de la prueba se utilizan para establecer que algunos valores calculados en el algoritmo tienen algunas propiedades, pero estas partes no necesitan mantenerse en el algoritmo mismo.
Por supuesto, esto debe tener lugar dentro de un marco lógico formalizado que establezca con qué se computan los datos, cuáles son los pasos computacionales elementales permitidos y cuáles son los axiomas utilizados.
Volviendo a su ejemplo factorial, puede interpretarse como un algoritmo, aunque sea trivial. La función factorial normal corresponde a una prueba de que, dado un marco aritmético, y dado un número entero n, hay un número que es el producto de los primeros n números enteros. Esto es bastante sencillo, como lo es el cálculo factorial. Podría ser más complejo para otras funciones.
Ahora, si decide tabular factorial, suponiendo que puede, lo cual no es cierto para todos los enteros (pero podría ser cierto para algunos dominios finitos de valores), todo lo que está haciendo es incluir en sus axiomas la existencia de factorial definiendo con un nuevo axioma su valor para cada número entero, por lo que ya no necesita probar (por lo tanto, calcular) nada.
Pero se supone que un sistema de axiomas es finito (o al menos finitamente definido). Y hay una infinidad de valores para factorial, uno por entero. Por lo tanto, tiene problemas para su sistema finito de axiomas si axiomatiza una función infinita, es decir, definida en un dominio infinito. Eso se traduce computacionalmente en el hecho de que su posible búsqueda de tabla no se puede implementar para todos los enteros. Eso eliminaría el requisito habitual de finitud para los algoritmos (pero ¿será tan estricto como se presenta a menudo?).
Podría decidir tener un generador de axiomas definido de forma finita para manejar todos los casos. Esto equivaldría, más o menos, a incluir el programa factorial estándar en su algoritmo para inicializar la matriz según sea necesario. Eso se llama memorización por parte de los programadores. Esto es en realidad lo más cerca que está del equivalente de una tabla calculada previamente. Se puede entender que tiene una tabla precalculada, excepto por el hecho de que la tabla se crea realmente en modo de evaluación diferida , siempre que sea necesario. Esta discusión probablemente necesitaría un poco más de atención formal.
Puede definir sus operaciones primitivas como lo desee (de acuerdo con su sistema formal) y asignarles el costo que elija cuando lo utilice en un algoritmo, para realizar análisis de complejidad o rendimiento. Pero, si los sistemas concretos que realmente implementan su algoritmo (una computadora o un cerebro, por ejemplo) no pueden respetar estas especificaciones de costos, su análisis puede ser intelectualmente interesante, pero no tiene valor para el uso real en el mundo real.
21000
¿Qué programas son interesantes?
Esta discusión debería estar más correctamente vinculada a resultados como el
isomorfismo de Curry-Howard entre programas y pruebas. Si algún programa es en realidad una prueba de algo, cualquier programa puede interpretarse como un programa interesante en el sentido de la definición anterior.
Sin embargo, a mi entender (limitado), este isomorfismo se limita a programas que se pueden escribir bien en algún sistema de escritura apropiado, donde los tipos corresponden a proposiciones de la teoría axiomática. Por lo tanto, no todos los programas pueden calificar como programas interesantes. Supongo que es en ese sentido que se supone que un algoritmo resuelve un problema.
Esto probablemente excluye la mayoría de los programas "generados aleatoriamente".
También es una definición algo abierta de lo que es un "algoritmo interesante". Cualquier programa que pueda verse como interesante definitivamente lo es, ya que hay un sistema de tipos identificado que lo hace interesante. Pero un programa que no se podía escribir hasta ahora, podría convertirse en un sistema de escritura más avanzado y, por lo tanto, volverse interesante. Más precisamente, siempre fue interesante, pero por falta de conocimiento del sistema de tipos adecuado, no pudimos saberlo.
Sin embargo, se sabe que no todos los programas se pueden escribir, ya que se sabe que algunas expresiones lambda, como la implementación del combinador Y , no se pueden escribir en un sistema de tipo de sonido .
Esta vista solo se aplica a formalismos de programación que pueden asociarse directamente a algún sistema de prueba axiomático. No sé cómo se puede extender a formalismos computacionales de bajo nivel como la Máquina de Turing. Sin embargo, dado que la algorítmica y la computabilidad son a menudo un juego de codificación de problemas y soluciones (piense en la aritmética codificada en cálculo lambda ), se puede considerar que cualquier computación formalmente definida que pueda mostrarse como una codificación de un algoritmo también es un algoritmo. Tales codificaciones probablemente usan solo una parte muy pequeña de lo que se puede expresar en un formalismo de bajo nivel, como las Máquinas de Turing.
Un interés de este enfoque es que da una noción de algoritmo que es más abstracta e independiente de los problemas de codificación real, de "representabilidad física" del dominio de cómputo. Entonces, por ejemplo, uno puede considerar dominios con objetos infinitos siempre que haya una forma computacionalmente sólida de usarlos.