3 puntos por GN⁺ 2023-09-14 | 1 comentarios | Compartir por WhatsApp
  • Prolog construye programas con una sola cláusula (clause) y un modelo de datos centrado en términos, por lo que puede expresar relaciones computables incluso con una gramática pequeña
  • El enfoque declarativo escribe qué es cierto más que el procedimiento de ejecución, así que la misma relación puede usarse para calcular, generar y consultar
  • Prolog puro se basa en Horn clause y resolution, y el efecto de agregar restricciones o cláusulas sobre el conjunto de soluciones puede predecirse lógicamente
  • El programa en sí mismo es un term de Prolog, por lo que es fácil leer, analizar y transformar otros programas, y también crear lenguajes específicos de dominio con reescritura en tiempo de compilación
  • Gracias a su dinamismo en tiempo de ejecución y a mecanismos implícitos como búsqueda, unificación y propagación de restricciones, se usa ampliamente en procesamiento de lenguaje, bases de datos, verificación y optimización

Un lenguaje pequeño hecho de cláusulas y términos

  • Todos los datos en Prolog se expresan como term de Prolog
  • El elemento central del lenguaje es una sola clause, cuyo formato básico es Head :- Body.
    • Su significado es que si Body se cumple, entonces Head se cumple
    • El operador infijo (:-)/2 representa una flecha que apunta de derecha a izquierda
    • Si Head siempre se cumple, puede omitirse :- Body
  • Esta estructura por sí sola basta para escribir un primer programa útil en Prolog
  • Todo cálculo conocido puede describirse con estas cláusulas, por lo que Prolog es un lenguaje Turing completo
    • Una máquina de Turing puede implementarse describiendo con cláusulas la relación que lleva al siguiente estado a partir del estado actual y del símbolo bajo el cabezal de la cinta
    • Puede verse un ejemplo en turing.pl

Programación declarativa y pensamiento orientado a relaciones

  • Prolog es un lenguaje declarativo que expresa qué es cierto sobre las soluciones de interés, en lugar de cómo encontrarlas
  • Esta naturaleza permite especificaciones concisas, claras y generales
  • La relación entre una lista y su longitud puede describirse así
list_length([], 0).
list_length([_|Ls], N) :-
        N #> 0,
        N #= N0 + 1,
        list_length(Ls, N0).
  • En algunos sistemas Prolog hay que incluir una biblioteca aparte para usar aritmética entera declarativa
  • Esta definición puede leerse declarativamente así
    • La longitud de la lista vacía [] es 0
    • Si la longitud de Ls es N0 y N es N0 + 1, entonces la longitud de [_|Ls] es N, y esta relación solo se cumple cuando N es mayor que 0
  • La misma relación puede usarse en varios modos
    • list_length("abc", L) devuelve L = 3
    • list_length(Ls, 3) encuentra una lista de longitud 3 con la forma Ls = [_A,_B,_C]
    • list_length(Ls, L) enumera respuestas generales, desde la lista vacía hasta listas de longitud creciente
  • Prolog normalmente reporta todas las respuestas mediante backtracking
  • length/2 está incluido en el borrador de Prologue for Prolog y se ofrece como predicado integrado con el mismo significado en casi todas las implementaciones de Prolog

Prolog como programación lógica

  • Dentro de los lenguajes declarativos están los lenguajes de programación funcional y los de programación lógica
  • Una función es un caso especial de una relación, y la programación funcional puede verse como una forma restringida de programación lógica
  • Prolog tiene sus raíces en la logic
  • Un programa Prolog puro está compuesto por un conjunto de Horn clause
  • La ejecución puede verse como un caso especial de resolution
  • Gracias a su conexión con la lógica formal, es posible aplicar depuración declarativa basada en las propiedades lógicas del programa
    • Si se agregan restricciones, el conjunto de soluciones como máximo se reduce
    • Si se agregan cláusulas, el conjunto de soluciones como máximo se amplía
    • Esta propiedad de los programas Prolog puros se llama monotonicidad
  • El GUPU system de Ulrich Neumerkel es un ejemplo de aplicación de estas ideas

La propiedad homoicónica de tratar programas como datos

  • Un programa Prolog también es un term válido de Prolog
  • Gracias a esta propiedad, es fácil para un programa Prolog analizar, transformar e interpretar otros programas Prolog
  • El predicado integrado read/1 puede leer términos Prolog, y por tanto también cláusulas Prolog
  • Prolog tiene un potente mecanismo de macros para reescribir programas en tiempo de compilación
    • Esto permite implementar lenguajes específicos de dominio que hacen más natural resolver ciertas tareas
  • list_length(Ls,N) y N#>0 se ven distintos en la notación, pero son formas más legibles gracias a los operadores prefix, infix y postfix de Prolog
    • Por ejemplo, el término Prolog +(a,b) puede escribirse con notación de operador como a+b
    • Como la sintaxis abstracta es uniforme, todos los términos Prolog pueden leerse y procesarse sin importar cómo se escriban
  • Es posible definir dinámicamente operadores personalizados adaptados a usos concretos

Dinamismo en tiempo de ejecución y extensibilidad

  • Los programas Prolog pueden crearse, llamarse y modificarse fácilmente en tiempo de ejecución
  • Estas características aumentan la expresividad y permiten implementar predicados de orden superior que reciben otros predicados como argumento
  • También pueden implementarse técnicas muy dinámicas como adaptive parsing
  • Prolog es adecuado para escribir programas que se extienden con reglas definidas por otros programadores o por usuarios finales
  • Un intérprete para Prolog puro puede definirse en dos líneas de código Prolog
  • Este tema se trata en A Couple of Meta-interpreters in Prolog

Amplitud de usos y mecanismos implícitos

  • La naturaleza relacional de Prolog hace que los programas sean flexibles y generales
  • Esta característica cumple un papel importante en la representación de conocimiento para procesamiento de lenguaje y bases de datos
  • Los sistemas Prolog modernos ofrecen lo necesario para todo, desde logic puzzles simples hasta aplicaciones de gran escala
  • La versatilidad y el poder de Prolog tienen sus raíces en mecanismos implícitos como búsqueda, unificación, indexación de argumentos y propagación de restricciones
  • El desarrollador puede aprovechar estos mecanismos y delegar gran parte del trabajo al motor de Prolog

1 comentarios

 
GN⁺ 2023-09-14
Opiniones de Hacker News
  • Estoy casi totalmente de acuerdo con este sentimiento. Usé Prolog en tres cursos universitarios de IA, y cubrimos casi todo "AI: A Modern Approach" junto con programación en Prolog; fue una experiencia que realmente te retuerce la forma de pensar
    Siempre necesitaba calentar para volver a pensar al estilo Prolog, y durante ese semestre solía escribir código espagueti horriblemente prologuiano incluso en otros lenguajes. En ese momento, la mayor desventaja era que la interoperabilidad con otras cosas era complicada, y había que meter Prolog dentro de la JVM, usar implementaciones con pocas funciones o apoyarse en bindings de C. Es excelente para ciertas tareas, especialmente problemas de satisfacción de restricciones, pero me parecía que no encajaba cuando se mezclaban cosas como interfaces de usuario o acceso al sistema de archivos. En esa época SWI también estaba atrasado y usábamos soluciones propietarias como Sicstus, pero la última vez que revisé, SWI ya había alcanzado a las implementaciones propietarias, así que hoy probablemente elegiría SWI. El examen de Prolog fue de lo más aterrador que tuve en la universidad: tres problemas de live coding en 60 minutos seguidos de un examen oral, pero lo superé bien; gasté 40 minutos en el problema fácil y resolví los otros dos en unos minutos. En el curso posterior, fue divertido tener una tarea donde implementábamos agentes de juego para competir en un torneo, y "The Art of Prolog" y "The Craft of Prolog" siguen estando entre los mejores libros de programación que he leído

    • Considero que The Art of Prolog es parte del canon de la programación con tipado dinámico, junto con Concepts, Techniques, and Models of Computer Programming, Paradigms of AI Programming y Structure and Interpretation of Computer Programs
      The Craft of Prolog también es excelente, pero está tan especializado en programación de sistemas Prolog antiguos que algunos capítulos ya se sienten obsoletos. Muchas ideas de Prolog siguen vivas en la programación con conjuntos de respuestas y en Datalog, y Datalog es excelente para crear analizadores estáticos modernos: https://arxiv.org/abs/2012.10086
    • Todavía recuerdo las caras de los estudiantes de licenciatura al salir de su primera clase de Prolog. Mitad conmoción, mitad preocupación
      De pronto me pregunto cómo les irá a los chatbots con Prolog. ¿Habrán visto suficiente? ¿Podrán razonar de esa manera?
    • Me pregunto por qué resulta tan difícil. ¿No es simplemente búsqueda en profundidad convertida en lenguaje?
  • Prolog es genial, y vale la pena aprenderlo aunque sea solo por la diversión de experimentar un paradigma de programación poco familiar. Muchos conceptos se expresan de una forma completamente distinta y, cuando el paradigma hace clic, se vuelve mucho más simple
    Por ejemplo, en Prolog normalmente no manipulas colecciones directamente; proporcionas información sobre cuáles son los elementos de la colección y dejas que la implementación lo resuelva. Incluso dibujar un árbol de dependencias puede hacerse con tres reglas: qué son las entidades, cómo determinar la relación entre las entidades X e Y, y cómo representarla. Pero como es difícil, cuesta convencer a otros de aprenderlo o usarlo, y todavía no he encontrado una forma de integrarlo de manera fluida en otras apps. Sé que FFI es una opción, pero no me convence que esté listo para producción. En los últimos meses busqué alternativas a Prolog más cercanas a “producción”, pero LispWorks y Franz Allegro CL son demasiado caros y no muy amigables para integrar. Me encantaría conocer casos donde Prolog esté bien integrado en software moderno. Como XPCE no funciona en Mac, también estoy buscando una solución de GUI. Swish también vale la pena como notebook en línea: https://swish.swi-prolog.org

    • No es una respuesta directa, pero David Hovell usó Prolog para imponer la consistencia de la configuración de red de Windows NT
      Tengo entendido que ya fue eliminado, así que no es un caso “moderno”, pero es un ejemplo realmente hermoso de aplicación de Prolog. Vale mucho la pena leer el hilo que va de https://news.ycombinator.com/item?id=36821871 a https://web.archive.org/web/20030218034509/http://www.resear.... Enlace relacionado: https://news.ycombinator.com/item?id=14046420
    • No sé si esto cuenta, pero los predicados de envío de Gerrit se configuraban en Prolog y ahora están previstos para deprecación. Un producto interno con el que trabajé en Google estaba construido alrededor de una base de conocimiento Datalog generada por código, y se podía consultar directamente o generar consultas desde la UI
      Ambos funcionaban bastante bien, pero los casos de uso eran limitados. Mi experiencia usando Prolog en la universidad fue divertida, pero no querría usarlo salvo que el problema tenga esencialmente forma de Prolog. En cuanto empiezas a implementar algo apenas complejo, las abstracciones empiezan a hacer agua por todos lados, y se siente más como pelear contra el algoritmo de backtracking que como aprovechar las ventajas del lenguaje
    • Racket tiene Racklog
      Racklog es una incrustación de programación lógica al estilo Prolog en Racket, y “incrustación” significa que no pierdes Racket. Puedes escribir fragmentos de código estilo Prolog junto a código Racket normal. Incluye la mayoría de las funciones de Prolog, incluida la metalógica y los predicados de “conjuntos” de segundo orden, y solo omite las funciones que pueden hacerse de forma más fácil y eficiente con subexpresiones de Racket. https://docs.racket-lang.org/racklog/index.html Racket también tiene GUI y, en la práctica, casi todo lo que podrías necesitar
    • Hoy en día digo lo mismo de CUE. Es una herramienta que también te sacude la forma de pensar, pero ofrece una nueva manera de controlar la complejidad de la configuración y los esquemas
      CUE se puede incorporar mucho más fácilmente a los flujos de trabajo existentes, así que es una buena forma de volver prácticas las ventajas de la programación lógica. https://cuelang.org | https://cuetorials.com
  • Durante varios años desarrollé software de optimización de cadenas de suministro en C++ y usé el software de propagación de restricciones de ILOG, Solver, que ahora pertenece a IBM. En ese entonces también evaluamos BinProlog: tenía propagación de rangos incorporada, compilaba a x86 nativo y su interoperabilidad FFI era bastante buena.
    Aun así, parece que al final quedó desplazado por SWI Prolog y la toolchain de GNU. Creo que la GUI debería verse como un área de especialización completamente distinta; nosotros usábamos nuestro propio motor de renderizado de canvas en C++ y una horrible herramienta integrada de desarrollo 4GL llamada “4D” o “Fourth Dimension”. https://www.tomshw.it/data/images/2/0/4/3/infor-advanced-sch...

  • El lenguaje Shen de Mark Tarver incluye una implementación completa de Prolog: https://shenlanguage.org/SD/Prolog.html
    También está el capítulo correspondiente de The Book of Shen: https://shenlanguage.org/TBoS/tbos_359.html Tarver también escribió dos libros sobre programación lógica que vienen con software. Logic, Proof and Computation: https://shenlanguage.org/lpc.html Programming the Logic Lab: https://shenlanguage.org/logiclab.html

    • Me gusta Shen, pero nunca logré profundizar bien en él. Estuve suscrito medio año a la versión profesional, y me gustaban las implementaciones de Shen construidas sobre varios lenguajes de programación.
      El pattern matching, la verificación de tipos opcional y el Prolog incorporado son sorprendentes. Su creador quedó en parte marginado de la comunidad más amplia por su falta de diplomacia, pero es brillante, y la adopción se mantuvo de nicho y de punta. Si una organización como Mozilla lo hubiera respaldado, creo que habría tenido un atractivo mucho más masivo. Las charlas de @deech ya tienen sus años, pero siguen siendo excelentes y relevantes: https://www.youtube.com/watch?v=lMcRBdSdO_U, https://www.youtube.com/watch?v=BUJNyHAeAc8 Aunque hay que tomarlo con pinzas: soy fanático de APL/J/BQN
  • Recuerdo haber aprendido Prolog hace unos 25 años en una carrera de IA + ciencias de la computación. Lo usamos mucho en el módulo de procesamiento de lenguaje natural.
    Al principio era frustrante e irritante, pero cuando uno se acostumbra resulta sorprendentemente divertido; y como la recursión era la única forma de iterar, también era una excelente introducción a la recursión.

    • Una de las cosas que Prolog me enseñó fue lo importante que es tener docentes capaces de ponerse en el lugar del estudiante.
      En la universidad aprendimos Prolog sobre todo de matemáticos que usaban principalmente ese tipo de lenguajes, y para ellos Prolog era una forma de pensar muy natural. En cambio, para estudiantes que venían usando sobre todo lenguajes procedurales, era confuso y frustrante, y todos intentaban usar Prolog como si fuera otro lenguaje y terminaban enredados. Recién en la tercera o cuarta materia donde usamos Prolog, después de estudiar los algoritmos que había detrás, me entró en la cabeza cómo usarlo bien. Más adelante ayudé a un estudiante de grado que estaba sufriendo con Prolog, y la clave era no intentar hacer que Prolog se comportara como los lenguajes que ya conocía, sino cambiar la forma de pensar la resolución de problemas para ajustarla al mundo de Prolog. Después de una charla bastante larga llegó el verdadero momento de iluminación, y terminó el trabajo de manera excelente.
    • A mí me pasó algo parecido. Al principio intentaba escribir código imperativo con sintaxis de Prolog, y eso era frustrante e irritante.
      Pero cuando el nuevo paradigma finalmente hizo clic en mi cabeza, terminó encantándome. Solo por ese momento de revelación ya valió la pena tomar esa clase.
    • Sería más correcto decir: “también es excelente como introducción a la recursión, porque es la única forma de hacer recursión”.
    • Hace algunos años también vimos Prolog en la licenciatura en ciencias de la computación. No fue una parte grande, apenas un componente pequeño de una materia de IA, pero aun así fue divertido.
  • Otros comentarios hablan de Prolog en general, pero quiero decir que The Power of Prolog es una serie de tutoriales bastante excelente.
    Los videos también valen la pena, y Markus sabe mantener el interés de espectadores y lectores.

    • Como alguien que primero se frustró con Prolog y luego tuvo una “revelación”, recomiendo empezar por el video de Markus Preparing Prolog: https://www.metalevel.at/prolog/videos/preparing_prolog
      Gracias a ese video empecé a ver Prolog como un movimiento actual y progresivo dentro de la programación.
  • Prolog es un lenguaje hermoso. Escribí decenas de miles de líneas para razonamiento matemático, razonamiento basado en reglas y cosas por el estilo; para esos dominios encaja perfectamente y el trabajo es tremendamente divertido.
    Para otros tipos de aplicaciones hay dos problemas. Primero, el paradigma es tan distinto que no encaja bien con librerías y otros lenguajes. Segundo, crear una GUI decente es casi imposible, también porque no encaja con el paradigma.

    • Participé en la escritura de la parte de interoperabilidad con Go de GoLog, y hacer interfaces con otros lenguajes no es particularmente difícil.
      Normalmente, del lado de Prolog, la interfaz externa se ve como un predicado en el que todos los argumentos están instanciados; y del lado externo, se interactúa con Prolog como si fuera una base de datos SQL. Se envía una consulta, se descompone la consulta y se piden más soluciones o se impulsa el backtracking. Se podría decir que este tipo de interacción no es “interesante”, pero funciona así porque las librerías no aprovechan realmente las funciones útiles de Prolog. Si uno quiere, puede construir una capa de interoperabilidad más gruesa y agrupar varias funciones de una librería en una única interfaz de predicado del lado de Prolog, haciendo que llame a una subrutina específica según el modo de instanciación de los argumentos. Pero eso no es muy distinto de exponer una librería en C a un lenguaje orientado a objetos como Python agrupando varias funciones de C como accesores de propiedades o métodos de una estructura de datos.
  • Estoy usando Prolog activamente para análisis de datos. Al principio hace falta una etapa en la que uno se obliga a hacer todo lo posible en Prolog para entender cómo convertir las preguntas en problemas simbólicos.

Es porque Prolog tiene un soporte pésimo para cálculo científico y manipulación de cadenas. Una vez superada esa etapa, las soluciones en Prolog suelen ser más elegantes que la siguiente mejor alternativa. Además, como es un paradigma lógico, vale la pena dedicar tiempo a entender cómo prueba por negación + unificación = programación lógica. De los lenguajes de programación que aprendí, es por lejos el que más me amplió la perspectiva.

  • El soporte de Prolog para manipulación de cadenas es bastante bueno. Casi ningún lenguaje moderno y popular trae de base algo como las DCG.
    El Prolog estándar no incluye expresiones regulares de fábrica, pero las implementaciones populares suelen ofrecer bibliotecas para eso. Si tuviera que hacer mucho trabajo con cadenas y elegir entre C y Prolog, definitivamente elegiría Prolog. Entre Python y Prolog, dependería de la tarea.
  • Interesante; ¿podrías dar un ejemplo de cómo se usa para análisis de datos?
  • También se discutió hace un año: https://news.ycombinator.com/item?id=31641014
    En cualquier caso, es un sitio excelente y me alegra que este tema vuelva a aparecer.
  • Las 10 líneas con las que implementé búsqueda de grafos A* en Prolog fueron las 10 líneas de código más difíciles de mi vida.
  • En la universidad tomé una clase de Prolog. Tenía que implementar un solucionador de Sudoku y en cierto momento me quedé trabado.
    Como ya había escrito antes un solucionador en Java, intenté trasladar ese código a Prolog, pero no funcionó para nada. Al final empecé de cero y escribí código Prolog simple que verificaba si un Sudoku era válido, y me di cuenta de que, al ejecutar esos predicados, también podía resolver el Sudoku. Así terminé un solucionador en menos de 10 líneas. Fue un verdadero momento eureka, y Prolog es muy potente, pero en la práctica se usa injustamente poco. Por suerte, tuve la oportunidad de trabajar con Datalog y OWL.