Prólogo

Compartir Imprimir Citar
Lenguaje de programación que utiliza la lógica de primer orden

Prolog es un lenguaje de programación lógico asociado con la inteligencia artificial y la lingüística computacional.

Prolog tiene sus raíces en la lógica de primer orden, una lógica formal y, a diferencia de muchos otros lenguajes de programación, Prolog está pensado principalmente como un lenguaje de programación declarativo: la lógica del programa se expresa en términos de relaciones, representadas como hechos y reglas. Se inicia un cálculo ejecutando una consulta sobre estas relaciones.

El lenguaje fue desarrollado e implementado en Marsella, Francia, en 1972 por Alain Colmerauer con Philippe Roussel, basado en la interpretación procedimental de las cláusulas Horn de Robert Kowalski en la Universidad de Edimburgo.

Prolog fue uno de los primeros lenguajes de programación lógica y sigue siendo el lenguaje de este tipo más popular en la actualidad, con varias implementaciones gratuitas y comerciales disponibles. El lenguaje se ha utilizado para la demostración de teoremas, sistemas expertos, reescritura de términos, sistemas de tipos y planificación automatizada, así como su campo de uso previsto original, el procesamiento del lenguaje natural. Los entornos modernos de Prolog admiten la creación de interfaces gráficas de usuario, así como aplicaciones administrativas y de red.

Prolog es ideal para tareas específicas que se benefician de las consultas lógicas basadas en reglas, como la búsqueda de bases de datos, los sistemas de control de voz y el llenado de plantillas.

Sintaxis y semántica

En Prolog, la lógica del programa se expresa en términos de relaciones y se inicia un cálculo ejecutando una consulta sobre estas relaciones. Las relaciones y las consultas se construyen utilizando el tipo de datos único de Prolog, el término. Las relaciones se definen mediante cláusulas. Dada una consulta, el motor de Prolog intenta encontrar una refutación de resolución de la consulta negada. Si la consulta negada se puede refutar, es decir, se encuentra una instanciación para todas las variables libres que hace que la unión de las cláusulas y el conjunto único que consta de la consulta negada sean falsos, se sigue que la consulta original, con la instanciación encontrada aplicada, es una consecuencia lógica del programa. Esto hace que Prolog (y otros lenguajes de programación lógica) sean particularmente útiles para aplicaciones de base de datos, matemáticas simbólicas y análisis de lenguaje. Debido a que Prolog permite predicados impuros, verificar el valor de verdad de ciertos predicados especiales puede tener algún efecto secundario deliberado, como imprimir un valor en la pantalla. Debido a esto, al programador se le permite usar cierta cantidad de programación imperativa convencional cuando el paradigma lógico es inconveniente. Tiene un subconjunto puramente lógico, llamado "prólogo puro", así como una serie de características extralógicas.

Tipos de datos

El único tipo de datos de Prolog es el término. Los términos son átomos, números, variables o términos compuestos.

Casos especiales de términos compuestos:

ISO Prolog proporciona el atom/1, number/1, integer/1 y float/1 predicados para verificación de tipos.

Reglas y hechos

Los programas Prolog describen relaciones, definidas por medio de cláusulas. Pure Prolog está restringido a las cláusulas Horn. Hay dos tipos de cláusulas: hechos y reglas. Una regla es de la forma

Head :- Cuerpo.

y se lee como "La cabeza es verdadera si el cuerpo es verdadero". El cuerpo de una regla consta de llamadas a predicados, que se denominan objetivos de la regla. El operador lógico incorporado ,/2 (lo que significa un operador de aridad 2 con el nombre ,) denota la conjunción de objetivos, y ;/2 denota disyunción. Las conjunciones y disyunciones solo pueden aparecer en el cuerpo, no en la cabeza de una regla.

Las cláusulas con cuerpos vacíos se denominan hechos. Un ejemplo de un hecho es:

gato()tom).

que es equivalente a la regla:

gato()tom) :- verdadero.

El predicado incorporado true/0 siempre es verdadero.

Dado el hecho anterior, uno puede preguntarse:

¿Tom es un gato?

 ? - gato()tom). Sí.

¿Qué cosas son los gatos?

 ? - gato()X). X = tom

Las cláusulas con cuerpos se denominan reglas. Un ejemplo de regla es:

animal()X) :- gato()X).

Si añadimos esa regla y preguntamos ¿qué cosas son animales?

 ? - animal()X). X = tom

Debido a la naturaleza relacional de muchos predicados integrados, normalmente se pueden usar en varias direcciones. Por ejemplo, length/2 puede usarse para determinar la longitud de una lista (length(List, L), dada una lista List) así como para generar un esqueleto de lista de una longitud determinada (length(X, 5)), y también para generar ambos esqueletos de lista y sus longitudes juntos (length(X, L)). De manera similar, append/3 se puede usar para agregar dos listas (append(ListA, ListB, X) listas dadas ListA y ListB), así como para dividir una lista dada en partes (append(X, Y, List), dada una lista List). Por esta razón, un conjunto comparativamente pequeño de predicados de biblioteca es suficiente para muchos programas de Prolog.

Como lenguaje de propósito general, Prolog también proporciona varios predicados integrados para realizar actividades rutinarias como entrada/salida, uso de gráficos y comunicación con el sistema operativo. A estos predicados no se les da un significado relacional y solo son útiles por los efectos secundarios que exhiben en el sistema. Por ejemplo, el predicado write/1 muestra un término en la pantalla.

Ejecución

La ejecución de un programa Prolog se inicia cuando el usuario publica un único objetivo, denominado consulta. Lógicamente, el motor Prolog intenta encontrar una refutación de resolución de la consulta negada. El método de resolución utilizado por Prolog se denomina resolución SLD. Si la consulta negada se puede refutar, se deduce que la consulta, con los enlaces de variables apropiados en su lugar, es una consecuencia lógica del programa. En ese caso, todos los enlaces de variables generados se informan al usuario y se dice que la consulta se ha realizado correctamente. Desde el punto de vista operativo, la estrategia de ejecución de Prolog se puede considerar como una generalización de las llamadas a funciones en otros lenguajes, con la diferencia de que varios encabezados de cláusulas pueden coincidir con una llamada determinada. En ese caso, el sistema crea un punto de elección, unifica el objetivo con el encabezado de la cláusula de la primera alternativa y continúa con los objetivos de esa primera alternativa. Si algún objetivo falla en el curso de la ejecución del programa, todas las vinculaciones de variables que se realizaron desde que se creó el punto de elección más reciente se deshacen y la ejecución continúa con la siguiente alternativa de ese punto de elección. Esta estrategia de ejecución se denomina retroceso cronológico. Por ejemplo:

mother_child()trude, sally).father_child()tom, sally).father_child()tom, erica).father_child()Mike, tom).hermano()X, Y) :- parent_child()Z, X), parent_child()Z, Y).parent_child()X, Y) :- father_child()X, Y).parent_child()X, Y) :- mother_child()X, Y).

Esto da como resultado que la siguiente consulta se evalúe como verdadera:

 ? - hermano()sally, erica). Sí.

Esto se obtiene de la siguiente manera: Inicialmente, el único encabezado de cláusula coincidente para la consulta sibling(sally, erica) es el primero, por lo que probar la consulta es equivalente a probar el cuerpo de esa cláusula con los enlaces de variables apropiados en su lugar, es decir, la conjunción (parent_child(Z,sally), parent_child(Z,erica)). El próximo objetivo a probar es el más a la izquierda de esta conjunción, es decir, parent_child(Z, sally). Dos cabezas de cláusula coinciden con este gol. El sistema crea un punto de elección y prueba la primera alternativa, cuyo cuerpo es father_child(Z, sally). Este objetivo se puede probar usando el hecho padre_hijo(tom, sally), por lo que se genera el enlace Z = tom, y el siguiente objetivo que se probará es la segunda parte de la conjunción anterior: parent_child(tom, erica). Nuevamente, esto puede ser probado por el hecho correspondiente. Dado que se pudieron probar todos los objetivos, la consulta tiene éxito. Dado que la consulta no contenía variables, no se notifican enlaces al usuario. Una consulta con variables, como:

? - father_child()Padre, Niño).

enumera todas las respuestas válidas al retroceder.

Observe que con el código como se indica arriba, la consulta ?- sibling(sally, sally). también tiene éxito. Si se desea, se insertarían metas adicionales para describir las restricciones relevantes.

Bucles y recursividad

Los algoritmos iterativos se pueden implementar mediante predicados recursivos.

Negación

El predicado incorporado de Prolog +/1 proporciona negación como falla, lo que permite un razonamiento no monótono. El objetivo + ilegal(X) en la regla

legales()X) :- + ilegales()X).

se evalúa de la siguiente manera: Prolog intenta probar ilegal(X). Si se puede encontrar una prueba para ese objetivo, el objetivo original (es decir, + ilegal(X)) falla. Si no se puede encontrar ninguna prueba, el objetivo original tiene éxito. Por lo tanto, el operador de prefijo +/1 se denomina "no demostrable" operador, ya que la consulta ?- + Goal. tiene éxito si Goal no es demostrable. Este tipo de negación es sólida si su argumento es "base" (es decir, no contiene variables). La solidez se pierde si el argumento contiene variables y el procedimiento de prueba está completo. En particular, la consulta ?- legal(X). ahora no se puede usar para enumerar todas las cosas que son legales.

Programación en Prolog

En Prolog, cargar código se conoce como consultoría. Prolog se puede usar de forma interactiva ingresando consultas en el indicador de Prolog ?-. Si no hay solución, Prolog escribe no. Si existe una solución, se imprime. Si hay varias soluciones para la consulta, se pueden solicitar introduciendo un punto y coma ;. Hay pautas sobre buenas prácticas de programación para mejorar la eficiencia, la legibilidad y el mantenimiento del código.

Aquí siguen algunos programas de ejemplo escritos en Prolog.

Hola Mundo

Un ejemplo de una consulta:

? - escribir()¡Hola Mundo! '), #.Hola. Mundo!verdadero.? -

Optimización del compilador

Cualquier cálculo se puede expresar declarativamente como una secuencia de transiciones de estado. Como ejemplo, un compilador de optimización con tres pases de optimización podría implementarse como una relación entre un programa inicial y su forma optimizada:

program_optimized()Prog0, Prog) :- optimization_pass_1()Prog0, Prog1), optimization_pass_2()Prog1, Prog2), optimization_pass_3()Prog2, Prog).

o de manera equivalente usando la notación DCG:

program_optimized -- optimization_pass_1, optimization_pass_2, optimization_pass_3.

Ordenación rápida

El algoritmo de clasificación quicksort, que relaciona una lista con su versión ordenada:

partición([], ¿Qué?, [], []).partición[XSilencioXs] Pivot, Pequeñas, Grandes) :- () X @. Pivot - Pequeñas = [XSilencioDescanso] partición()Xs, Pivot, Descanso, Grandes) ; Grandes = [XSilencioDescanso] partición()Xs, Pivot, Pequeñas, Descanso) ).rápido([]) -- [].rápido[XSilencioXs]) -- {} partición()Xs, X, Más pequeña, Más grande) } rápido()Más pequeña), [X] rápido()Más grande).

Patrones de diseño de Prolog

Un patrón de diseño es una solución general reutilizable para un problema común en el diseño de software. Algunos patrones de diseño en Prolog son esqueletos, técnicas, clichés, esquemas de programas, esquemas de descripción lógica y programación de orden superior.

Programación de orden superior

Un predicado de orden superior es un predicado que toma uno o más predicados como argumentos. Aunque la compatibilidad con la programación de orden superior saca a Prolog del dominio de la lógica de primer orden, que no permite la cuantificación sobre predicados, ISO Prolog ahora tiene algunos predicados de orden superior integrados, como call/1, call/2, call/3, findall/3, setof/3 y bagof /3. Además, dado que se pueden construir y evaluar objetivos arbitrarios de Prolog en tiempo de ejecución, es fácil escribir predicados de orden superior como maplist/2, que aplica un predicado arbitrario a cada miembro de una lista dada, y sublist/3, que filtra elementos que satisfacen un predicado dado, y también permite curry.

Para convertir soluciones de representación temporal (sustituciones de respuesta al retroceder) a representación espacial (términos), Prolog tiene varios predicados de todas las soluciones que recopilan todas las sustituciones de respuesta de una consulta determinada en una lista. Esto se puede utilizar para la comprensión de listas. Por ejemplo, los números perfectos son iguales a la suma de sus divisores propios:

 perfecto()N) :- entre()1, inf, N), U es N // 2, encontrarlo()D, ()entre()1,U,D), N mod D == 0), Ds), Total()Ds, N).

Esto se puede usar para enumerar números perfectos y también para verificar si un número es perfecto.

Como otro ejemplo, el predicado maplist aplica un predicado P a todas las posiciones correspondientes en un par de listas:

lista()¿Qué?, [], []).lista()P, [XSilencioXs] [YSilencioYs]) :- llamada()P, X, Y), lista()P, Xs, Ys).

Cuando P es un predicado que para todo X, P(X,Y) unifica Y con un único valor único, maplist(P, Xs, Ys) es equivalente a aplicar la función map en programación funcional como Ys = map(Function, Xs).

El estilo de programación de orden superior en Prolog fue pionero en HiLog y λProlog.

Módulos

Para la programación en grande, Prolog proporciona un sistema de módulos. El sistema de módulos está estandarizado por ISO. Sin embargo, no todos los compiladores de Prolog admiten módulos y existen problemas de compatibilidad entre los sistemas de módulos de los principales compiladores de Prolog. En consecuencia, los módulos escritos en un compilador de Prolog no necesariamente funcionarán en otros.

Análisis

Hay una notación especial llamada gramáticas de cláusulas definidas (DCG). Una regla definida a través de -->/2 en lugar de :-/2 es expandida por el preprocesador (expand_term/2, una instalación análoga a macros en otros idiomas) de acuerdo con unas pocas reglas de reescritura sencillas, lo que da como resultado cláusulas ordinarias de Prolog. En particular, la reescritura equipa el predicado con dos argumentos adicionales, que se pueden usar para enhebrar implícitamente el estado, de manera análoga a las mónadas en otros idiomas. Los DCG se utilizan a menudo para escribir analizadores o generadores de listas, ya que también proporcionan una interfaz conveniente para las listas de diferencias.

Meta-intérpretes y reflexión

Prolog es un lenguaje homoicónico y proporciona muchas facilidades para la reflexión. Su estrategia de ejecución implícita hace posible escribir un evaluador metacircular conciso (también llamado meta-intérprete) para código Prolog puro:

resolver()verdadero).resolver()Subgoal1,Subgoal2) :- resolver()Subgoal1), resolver()Subgoal2).resolver()Head) :- cláusula()Head, Cuerpo), resolver()Cuerpo).

donde true representa una conjunción vacía, y clause(Head, Body) se unifica con cláusulas en la base de datos de la forma Head:- Body.

Dado que los programas de Prolog son en sí mismos secuencias de términos de Prolog (:-/2 es un operador infijo) que se pueden leer e inspeccionar fácilmente usando mecanismos integrados (como read/1), es posible escribir intérpretes personalizados que mejoren Prolog con características específicas del dominio. Por ejemplo, Sterling y Shapiro presentan un meta-intérprete que razona con incertidumbre, reproducido aquí con ligeras modificaciones:

resolver()verdadero, 1) :- !resolver()Subgoal1,Subgoal2), Determinación) :- ! resolver()Subgoal1, Determinación1), resolver()Subgoal2, Determinación2), Determinación es min()Determinación1, Determinación2).resolver()Objetivo, 1) :- construida()Objetivo), ! Objetivo.resolver()Head, Determinación) :- cláusula_cf()Head, Cuerpo, Determinación1), resolver()Cuerpo, Determinación2), Determinación es Determinación1 * Determinación2.

Este intérprete utiliza una tabla de predicados Prolog integrados de la forma

construida()A es B).construida()leído()X)).%, etc.

y cláusulas representadas como clause_cf(Head, Body, Certainty). Dados estos, se puede llamar como solve(Objetivo, Certeza) para ejecutar Objetivo y obtener una medida de certeza sobre el resultado.

Integridad de Turing

Pure Prolog se basa en un subconjunto de la lógica de predicados de primer orden, las cláusulas de Horn, que es completa de Turing. La integridad de Turing de Prolog se puede mostrar usándolo para simular una máquina de Turing:

Turing()Tape0, Tape) :- perform()q0, [], Ls, Tape0, Rs), inversión()Ls, Ls1), apéndice()Ls1, Rs, Tape).perform()qf, Ls, Ls, Rs, Rs) :- !perform()Q0, Ls0, Ls, Rs0, Rs) :- símbolo()Rs0, Sym, RsRest), una vez()Regla()Q0, Sym, Q1, NewSym, Medida)), acción()Medida, Ls0, Ls1, [NewSymSilencioRsRest] Rs1), perform()Q1, Ls1, Ls, Rs1, Rs).símbolo([], b, []).símbolo[SymSilencioRs] Sym, Rs).acción()izquierda, Ls0, Ls, Rs0, Rs) :- izquierda()Ls0, Ls, Rs0, Rs).acción()estancia, Ls, Ls, Rs, Rs).acción()derecho, Ls0, [SymSilencioLs0] [SymSilencioRs] Rs).izquierda([], [], Rs0, [bSilencioRs0]).izquierda[LSilencioLs] Ls, Rs, [LSilencioRs]).

Un ejemplo simple de máquina de Turing se especifica por los hechos:

Regla()q0, 1, q0, 1, derecho).Regla()q0, b, qf, 1, estancia).

Esta máquina realiza incrementos por uno de un número en codificación unaria: Recorre cualquier número de "1" celdas y añade un "1" al final. Ejemplo de consulta y resultado:

? - Turing[1,1,1] Ts).Ts = [1, 1, 1, 1] ;

Esto ilustra cómo cualquier cálculo puede expresarse declarativamente como una secuencia de transiciones de estado, implementado en Prolog como una relación entre estados de interés sucesivos.

Implementación

Prólogo ISO

El estándar ISO Prolog consta de dos partes. ISO/IEC 13211-1, publicado en 1995, tiene como objetivo estandarizar las prácticas existentes de las muchas implementaciones de los elementos centrales de Prolog. Ha aclarado aspectos del lenguaje que antes eran ambiguos y conduce a programas portátiles. Hay tres correcciones: Cor.1:2007, Cor.2:2012 y Cor.3:2017. ISO/IEC 13211-2, publicado en 2000, agrega soporte para módulos al estándar. El estándar es mantenido por el grupo de trabajo ISO/IEC JTC1/SC22/WG17. ANSI X3J17 es el Grupo Asesor Técnico de EE. UU. para el estándar.

Compilación

Para mayor eficiencia, el código de Prolog generalmente se compila en un código de máquina abstracto, a menudo influenciado por el conjunto de instrucciones Warren Abstract Machine (WAM) basado en registros. Algunas implementaciones emplean interpretación abstracta para derivar información de tipo y modo de predicados en tiempo de compilación, o compilan en código de máquina real para un alto rendimiento. El diseño de métodos de implementación eficientes para el código Prolog es un campo de investigación activa en la comunidad de programación lógica, y en algunas implementaciones se emplean varios otros métodos de ejecución. Estos incluyen binarización de cláusulas y máquinas virtuales basadas en pilas.

Recurrencia de cola

Los sistemas Prolog normalmente implementan un método de optimización bien conocido llamado optimización de llamada de cola (TCO) para predicados deterministas que exhiben recurrencia de cola o, más generalmente, llamadas de cola: el marco de pila de una cláusula se descarta antes de realizar una llamada en un posición de la cola. Por lo tanto, los predicados recursivos de cola deterministas se ejecutan con un espacio de pila constante, como los bucles en otros lenguajes.

Indización de términos

La búsqueda de cláusulas que son unificables con un término en una consulta es lineal en el número de cláusulas. La indexación de términos utiliza una estructura de datos que permite realizar búsquedas en tiempo sublineal. La indexación solo afecta el rendimiento del programa, no afecta la semántica. La mayoría de los Prologs solo utilizan la indexación en el primer término, ya que la indexación en todos los términos es costosa, pero las técnicas basadas en palabras codificadas en campos o palabras en código superpuestas brindan una indexación rápida en toda la consulta. y cabeza

Hashing

Algunos sistemas Prolog, como WIN-PROLOG y SWI-Prolog, ahora implementan hashing para ayudar a manejar grandes conjuntos de datos de manera más eficiente. Esto tiende a generar ganancias de rendimiento muy grandes cuando se trabaja con corporaciones grandes como WordNet.

Presentación

Algunos sistemas Prolog (B-Prolog, XSB, SWI-Prolog, YAP y Ciao) implementan un método de memorización llamado tabling, que libera al usuario del almacenamiento manual de resultados intermedios. La presentación es una compensación de espacio-tiempo; el tiempo de ejecución se puede reducir usando más memoria para almacenar resultados intermedios:

Los subgoales encontrados en una evaluación de la consulta se mantienen en un cuadro, junto con las respuestas a estos subgoales. Si se vuelve a contabilizar un subgoal, la evaluación reutiliza la información del cuadro en lugar de volver a aplicar la resolución contra las cláusulas del programa.

La presentación se puede extender en varias direcciones. Puede admitir predicados recursivos mediante resolución SLG o tabulación lineal. En un sistema Prolog de subprocesos múltiples, los resultados de las tablas podrían mantenerse privados para un subproceso o compartirse entre todos los subprocesos. Y en la presentación incremental, la presentación podría reaccionar a los cambios.

Implementación en hardware

Durante el proyecto de sistemas informáticos de quinta generación, hubo intentos de implementar Prolog en hardware con el objetivo de lograr una ejecución más rápida con arquitecturas dedicadas. Además, Prolog tiene una serie de propiedades que pueden permitir acelerar la ejecución en paralelo. Un enfoque más reciente ha sido compilar programas Prolog restringidos en una matriz de puertas programables en campo. Sin embargo, el rápido progreso en el hardware de uso general ha superado constantemente a las arquitecturas más especializadas.

Sega implementó Prolog para usar con Sega AI Computer, lanzado para el mercado japonés en 1986. Prolog se usó para leer entradas de lenguaje natural, en japonés, a través de un panel táctil.

Limitaciones

Aunque Prolog se usa ampliamente en investigación y educación, Prolog y otros lenguajes de programación lógicos no han tenido un impacto significativo en la industria informática en general. La mayoría de las aplicaciones son pequeñas según los estándares industriales, y pocas superan las 100 000 líneas de código. La programación en general se considera complicada porque no todos los compiladores de Prolog admiten módulos y existen problemas de compatibilidad entre los sistemas de módulos de los principales compiladores de Prolog. La portabilidad del código de Prolog entre implementaciones también ha sido un problema, pero los desarrollos desde 2007 han significado: "la portabilidad dentro de la familia de implementaciones de Prolog derivadas de Edinburgh/Quintus es lo suficientemente buena como para permitir el mantenimiento de aplicaciones portátiles del mundo real". 34;

El software desarrollado en Prolog ha sido criticado por tener una penalización de alto rendimiento en comparación con los lenguajes de programación convencionales. En particular, la estrategia de evaluación no determinista de Prolog puede ser problemática cuando se programan cálculos deterministas, o incluso cuando se usa "no importa el no determinismo" (donde se hace una sola elección en lugar de retroceder sobre todas las posibilidades). Es posible que se deban usar cortes y otras construcciones del lenguaje para lograr el rendimiento deseado, destruyendo una de las principales atracciones de Prolog, la capacidad de ejecutar programas 'hacia adelante y hacia atrás'.

Prolog no es puramente declarativo: debido a construcciones como el operador de corte, se necesita una lectura de procedimiento de un programa Prolog para comprenderlo. El orden de las cláusulas en un programa Prolog es importante, ya que de él depende la estrategia de ejecución del lenguaje. Otros lenguajes de programación lógica, como Datalog, son verdaderamente declarativos pero restringen el lenguaje. Como resultado, muchos programas prácticos de Prolog están escritos para ajustarse al orden de búsqueda en profundidad de Prolog, en lugar de programas lógicos puramente declarativos.

Extensiones

Se han desarrollado varias implementaciones a partir de Prolog para ampliar las capacidades de programación lógica en numerosas direcciones. Estos incluyen tipos, modos, programación lógica de restricción (CLP), programación lógica orientada a objetos (OOLP), concurrencia, lógica lineal (LLP), capacidades de programación lógica funcional y de orden superior, además de interoperabilidad con bases de conocimiento:

Tipos

Prolog es un lenguaje sin tipos. Los intentos de introducir tipos se remontan a la década de 1980 y, a partir de 2008, todavía hay intentos de ampliar Prolog con tipos. La información de tipos es útil no solo para la seguridad de tipos sino también para razonar sobre los programas Prolog.

Modos

Modo especificador Interpretación
+nonvar a la entrada
-var a la entrada
?No especificado

La sintaxis de Prolog no especifica qué argumentos de un predicado son entradas y cuáles son salidas. Sin embargo, esta información es importante y se recomienda incluirla en los comentarios. Los modos brindan información valiosa al razonar sobre los programas de Prolog y también se pueden usar para acelerar la ejecución.

Restricciones

La programación lógica de restricciones amplía Prolog para incluir conceptos de satisfacción de restricciones. Un programa de lógica de restricciones permite restricciones en el cuerpo de las cláusulas, como: A(X,Y):- X+Y>0. Es adecuado para problemas de optimización combinatoria a gran escala y, por lo tanto, es útil para aplicaciones en entornos industriales, como la programación automatizada de horarios y la producción. La mayoría de los sistemas Prolog vienen con al menos un solucionador de restricciones para dominios finitos y, a menudo, también con solucionadores para otros dominios, como números racionales.

Orientación a objetos

Flora-2 es un sistema de razonamiento y representación del conocimiento orientado a objetos basado en lógica F e incorpora HiLog, lógica de transacciones y razonamiento anulable.

Logtalk es un lenguaje de programación lógica orientado a objetos que puede usar la mayoría de las implementaciones de Prolog como un compilador de back-end. Como lenguaje multiparadigma, incluye soporte tanto para prototipos como para clases.

Oblog es una extensión pequeña, portátil y orientada a objetos de Prolog de Margaret McDougall de EdCAAD, Universidad de Edimburgo.

Objlog era un lenguaje basado en marcos que combinaba objetos y Prolog II de CNRS, Marsella, Francia.

Prolog++ fue desarrollado por Logic Programming Associates y lanzado por primera vez en 1989 para PC con MS-DOS. Se agregó soporte para otras plataformas y se lanzó una segunda versión en 1995. Addison-Wesley publicó un libro sobre Prolog ++ de Chris Moss en 1994.

Visual Prolog es un lenguaje multiparadigma con interfaces, clases, implementaciones y expresiones de objetos.

Gráficos

Los sistemas Prolog que proporcionan una biblioteca de gráficos son SWI-Prolog, Visual Prolog, WIN-PROLOG y B-Prolog.

Concurrencia

Prolog-MPI es una extensión SWI-Prolog de código abierto para computación distribuida a través de la interfaz de paso de mensajes. También hay varios lenguajes de programación Prolog concurrentes.

Programación web

Algunas implementaciones de Prolog, en particular Visual Prolog, SWI-Prolog y Ciao, admiten programación web del lado del servidor con soporte para protocolos web, HTML y XML. También hay extensiones para admitir formatos de web semántica como RDF y OWL. Prolog también se ha sugerido como un lenguaje del lado del cliente. Además, Visual Prolog es compatible con JSON-RPC y Websockets.

Adobe Flash

Cedar es un intérprete de Prolog básico y gratuito. A partir de la versión 4, Cedar tiene soporte FCA (Flash Cedar App). Esto proporciona una nueva plataforma para la programación en Prolog a través de ActionScript.

Otro

Interfaces a otros idiomas

Existen marcos que pueden servir de puente entre Prolog y otros lenguajes:

Historia

El nombre Prolog fue elegido por Philippe Roussel como abreviatura de programmation en logique (en francés, programación en lógica). Fue creado alrededor de 1972 por Alain Colmerauer con Philippe Roussel, basado en la interpretación procedimental de Robert Kowalski de las cláusulas de Horn. Fue motivado en parte por el deseo de reconciliar el uso de la lógica como lenguaje declarativo de representación del conocimiento con la representación procedimental del conocimiento que fue popular en Norteamérica a finales de los años sesenta y principios de los setenta. Según Robert Kowalski, el primer sistema Prolog fue desarrollado en 1972 por Colmerauer y Phillipe Roussel. La primera implementación de Prolog fue un intérprete escrito en Fortran por Gerard Battani y Henri Meloni. David H. D. Warren llevó este intérprete a la Universidad de Edimburgo y allí implementó un front-end alternativo, que llegó a definir la sintaxis "Edinburgh Prolog" utilizada por la mayoría de las implementaciones modernas. Warren también implementó el primer compilador de Prolog, creando el influyente DEC-10 Prolog en colaboración con Fernando Pereira. Warren luego generalizó las ideas detrás de DEC-10 Prolog, para crear Warren Abstract Machine.

Los investigadores europeos de IA favorecieron a Prolog, mientras que los estadounidenses favorecieron a Lisp, lo que supuestamente provocó muchos debates nacionalistas sobre los méritos de los idiomas. Gran parte del desarrollo moderno de Prolog provino del ímpetu del proyecto Fifth Generation Computer Systems (FGCS), que desarrolló una variante de Prolog llamada Kernel Language para su primer sistema operativo.

Pure Prolog originalmente estaba restringido al uso de un probador de teoremas de resolución con cláusulas Horn de la forma:

H:- B1,...n.

La aplicación del probador de teoremas trata tales cláusulas como procedimientos:

para mostrar/solver H, show/solve B1 y Bn.

Pure Prolog pronto se amplió, sin embargo, para incluir la negación como falla, en la que las condiciones negativas de la forma not(Bi) se muestran al intentar y fallar en resolver las condiciones positivas correspondientes Bi.

Las extensiones posteriores de Prolog por parte del equipo original introdujeron capacidades de programación de lógica de restricción en las implementaciones.

Uso en la industria

Prolog se ha utilizado en Watson. Watson utiliza el software DeepQA de IBM y el marco Apache UIMA (Arquitectura de gestión de información no estructurada). El sistema se escribió en varios lenguajes, incluidos Java, C++ y Prolog, y se ejecuta en el sistema operativo SUSE Linux Enterprise Server 11 utilizando el marco Apache Hadoop para proporcionar computación distribuida. Prolog se utiliza para la coincidencia de patrones en árboles de análisis de lenguaje natural. Los desarrolladores han declarado: "Necesitábamos un lenguaje en el que pudiéramos expresar convenientemente las reglas de coincidencia de patrones sobre los árboles de análisis y otras anotaciones (como los resultados del reconocimiento de entidades nombradas), y una tecnología que pudiera ejecutar estas reglas de manera muy eficiente. Descubrimos que Prolog era la opción ideal para el lenguaje debido a su simplicidad y expresividad." Prolog se está utilizando en la plataforma de desarrollo Low-Code GeneXus, que se centra en la IA. La base de datos de gráficos de código abierto TerminusDB se implementa en prolog. TerminusDB está diseñado para construir y seleccionar gráficos de conocimiento de forma colaborativa.