Prolog es un lenguaje de programación lógica que tiene su origen en la inteligencia artificial , la demostración automatizada de teoremas y la lingüística computacional . [1] [2] [3]
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 : el programa es un conjunto de hechos y reglas que definen relaciones . Un cálculo se inicia ejecutando una consulta sobre el programa. [4]
Prolog fue uno de los primeros lenguajes de programación lógica [5] y sigue siendo el lenguaje de este tipo más popular en la actualidad, con varias implementaciones comerciales y gratuitas disponibles. El lenguaje se ha utilizado para la demostración de teoremas , [6] sistemas expertos , [7] reescritura de términos , [8] sistemas de tipos , [9] y planificación automatizada , [10] así como su campo de uso original previsto, el procesamiento del lenguaje natural . . [11] [12]
Prolog es un lenguaje de programación de propósito general completo de Turing, muy adecuado para aplicaciones inteligentes de procesamiento de conocimiento.
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 consultas se construyen utilizando el tipo de datos único de Prolog, el término . [4] Las relaciones se definen mediante cláusulas . Dada una consulta, el motor Prolog intenta encontrar una resolución que refute la consulta negada. Si la consulta negada puede ser refutada, es decir, se encuentra una instanciación para todas las variables libres que hace que la unión de cláusulas y el conjunto singleton que consiste en la consulta negada sea falsa, se deduce 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 bases de datos, matemáticas simbólicas y análisis de lenguajes. 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 utilizar 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.
El único tipo de datos de Prolog es el término . Los términos son átomos , números , variables o términos compuestos . [nota 1]
x
, red
, 'Taco'
, 'some atom'
y 'p(a)'
.person_friends(zelda,[tom,jim])
.Casos especiales de términos compuestos:
[]
. Por ejemplo, [1,2,3,4]
o [red,green,blue]
.double_quotes
. Por ejemplo, "to be, or not to be"
. [13]Los programas Prolog describen relaciones, definidas mediante cláusulas. Pure Prolog está restringido a cláusulas Horn . Se utilizan dos tipos de cláusulas Horn para definir programas Prolog: reglas y hechos. Una regla es de la forma
Cabeza : -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 (es decir, un operador,/2
de aridad 2 con nombre ) denota conjunción de objetivos y denota disyunción . Las conjunciones y disyunciones sólo pueden aparecer en el cuerpo, no en el encabezamiento de una regla.,
;/2
Las cláusulas con cuerpo vacío se llaman hechos . Un ejemplo de un hecho es:
humano ( sócrates ).
que es equivalente a la regla:
humano ( sócrates ) :- verdadero .
El predicado incorporado true/0
siempre es verdadero.
Teniendo en cuenta el hecho anterior, cabe preguntarse:
¿Es Sócrates un ser humano?
?- humano ( sócrates ). Sí
¿Qué cosas son los humanos?
?- humano ( X ). X = sócrates
Las cláusulas con cuerpo se llaman reglas . Un ejemplo de regla es:
mortal ( X ) :- humano ( X ).
¿Si sumamos esa regla y preguntamos qué cosas son los mortales?
?-mortal ( X ) . X = sócrates
Un predicado (o definición de procedimiento ) es una colección de cláusulas cuyos encabezados tienen el mismo nombre y aridad. Usamos la notación nombre/aridad para referirnos a predicados. Un programa lógico es un conjunto de predicados. Por ejemplo, el siguiente programa Prolog, que define algunas relaciones familiares, tiene cuatro predicados:
madre_niño ( truda , sally ).padre_hijo ( tom , sally ). padre_hijo ( tom , erica ). padre_hijo ( mike , tom ).hermano ( X , Y ) : - padre_hijo ( Z , X ), padre_hijo ( Z , Y ).padre_hijo ( X , Y ) : - padre_hijo ( X , Y ). padre_hijo ( X , Y ) : - madre_hijo ( X , Y ).
El predicado father_child/2
tiene tres cláusulas, todas las cuales son hechos, y el predicado parent_child/2
tiene dos cláusulas, ambas son reglas.
Debido a la naturaleza relacional de muchos predicados integrados, normalmente se pueden utilizar en varias direcciones. Por ejemplo, length/2
se puede utilizar para determinar la longitud de una lista ( length(List, L)
, dada una lista List
), y para generar un esqueleto de lista de una longitud determinada ( length(X, 5)
), y para generar ambos esqueletos de lista y sus longitudes juntos ( length(X, L)
). De manera similar, append/3
se puede usar tanto para agregar dos listas ( append(ListA, ListB, X)
listas dadas ListA
y ListB
) como para dividir una lista determinada 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 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 sólo son útiles por los efectos secundarios que presentan en el sistema. Por ejemplo, el predicado write/1
muestra un término en la pantalla.
Los algoritmos iterativos se pueden implementar mediante predicados recursivos. [14]
Considere el parent_child/2
predicado definido en el programa de relaciones familiares anterior. El siguiente programa Prolog define la relación de ancestro :
antepasado ( X , Y ) : - padre_hijo ( X , Y ). antepasado ( X , Y ) : - padre_hijo ( X , Z ), antepasado ( Z , Y ).
Expresa que X es un antepasado de Y si X es padre de Y o X es padre de un antepasado de Y. Es recursivo porque se define en términos de sí mismo (hay un llamado a predicar ancestor/2
en el cuerpo de la segunda cláusula ).
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 resolución que refute la consulta negada. El método de resolución utilizado por Prolog se llama resolución SLD . Si la consulta negada puede ser refutada, se deduce que la consulta, con las vinculaciones de variables apropiadas implementadas, es una consecuencia lógica del programa. En ese caso, todas las vinculaciones de variables generadas se informan al usuario y se dice que la consulta se realizó correctamente. Operacionalmente, la estrategia de ejecución de Prolog puede considerarse como una generalización de llamadas a funciones en otros lenguajes, con una diferencia que varios encabezados de cláusulas pueden coincidir con una llamada determinada. En ese caso, el sistema crea un punto de elección, unifica la meta con la cláusula principal de la primera alternativa y continúa con las metas de esa primera alternativa. Si algún objetivo falla durante 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 llama retroceso cronológico . Por ejemplo, dado el programa de relación familiar definido anteriormente, la siguiente consulta se evaluará 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 equivale a probar el cuerpo de esa cláusula con las vinculaciones de variables apropiadas en su lugar, es decir, la conjunción (parent_child(Z,sally), parent_child(Z,erica))
. El próximo objetivo a demostrar 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 objetivo. 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 utilizando el hecho father_child(tom, sally)
, por lo que se genera la vinculación Z = tom
y el siguiente objetivo a demostrar es la segunda parte de la conjunción anterior parent_child(tom, erica)
:. Una vez más, esto puede demostrarse mediante el hecho correspondiente. Como se pudieron probar todos los objetivos, la consulta tiene éxito. Dado que la consulta no contenía variables, no se informa ningún enlace al usuario. Una consulta con variables, como:
?- padre_hijo ( Padre , Hijo ).
enumera todas las respuestas válidas sobre el retroceso.
Tenga en cuenta que con el código indicado anteriormente, la consulta ?- sibling(sally, sally).
también se realiza correctamente. Si se desea, se insertarían objetivos adicionales para describir las restricciones relevantes.
El predicado Prolog incorporado \+/1
proporciona negación como fracaso , lo que permite un razonamiento no monótono . El objetivo \+ illegal(X)
en la regla.
legal ( X ) :- \+ ilegal ( X ).
se evalúa de la siguiente manera: Prolog intenta probar illegal(X)
. Si se puede encontrar una prueba para ese objetivo, el objetivo original (es decir, \+ illegal(X)
) falla. Si no se pueden encontrar pruebas, el objetivo original tiene éxito. Por lo tanto, el \+/1
operador de prefijo se denomina operador "no demostrable", ya que la consulta ?- \+ Goal.
tiene éxito si el objetivo no es demostrable. Este tipo de negación es válida si su argumento es "fundamental" (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 utilizar para enumerar todas las cosas que son legales.
En Prolog, la carga de código se denomina consulta . Prolog se puede utilizar de forma interactiva ingresando consultas en el indicador de Prolog ?-
. Si no hay solución, escribe Prolog no
. Si existe una solución, se imprime. Si hay varias soluciones para la consulta, se pueden solicitar ingresando un punto y coma ;
. Existen directrices sobre buenas prácticas de programación para mejorar la eficiencia, la legibilidad y el mantenimiento del código. [15]
A continuación se muestran algunos programas de ejemplo escritos en Prolog.
Ejemplo de una consulta básica en un par de dialectos populares de Prolog:
Esta comparación muestra que el mensaje ("?-" frente a "| ?-") y el estado de resolución ("verdadero" frente a "sí", "falso" frente a "no") pueden diferir de una implementación de Prolog a otra.
Cualquier cálculo puede expresarse declarativamente como una secuencia de transiciones de estado. Como ejemplo, se podría implementar un compilador de optimización con tres pasos de optimización como una relación entre un programa inicial y su forma optimizada:
programa_optimizado ( Prog0 , Prog ) : - optimización_pass_1 ( Prog0 , Prog1 ), optimización_pass_2 ( Prog1 , Prog2 ), optimización_pass_3 ( Prog2 , Prog ).
o de manera equivalente usando la notación DCG :
program_optimized --> optimización_pass_1 , optimización_pass_2 , optimización_pass_3 .
El algoritmo de clasificación Quicksort , que relaciona una lista con su versión ordenada:
partición ([], _ , [], []). partición ([ X | Xs ], Pivote , Pequeños , Grandes ) :- ( X @< Pivote -> Pequeños = [ X | Resto ], partición ( Xs , Pivote , Resto , Grandes ) ; Grandes = [ X | Resto ], partición ( Xs , Pivote , Smalls , Rest ) ).clasificación rápida ([]) --> []. clasificación rápida ([ X | Xs ]) --> { partición ( Xs , X , Más pequeña , Más grande ) }, clasificación rápida ( Más pequeña ), [ X ], clasificación rápida ( Más grande ).
Un patrón de diseño es una solución general reutilizable a un problema que ocurre comúnmente en el diseño de software . Algunos patrones de diseño en Prolog son esqueletos, técnicas, [16] [17] clichés, [18] esquemas de programa, [19] esquemas de descripción lógica, [20] y programación de orden superior . [21]
Un predicado de orden superior es un predicado que toma uno o más predicados como argumentos. Aunque el soporte para la programación de orden superior lleva a Prolog fuera del dominio de la lógica de primer orden, que no permite la cuantificación de predicados, [22] ISO Prolog ahora tiene algunos predicados de orden superior integrados como call/1
,,,,, y . [23] 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 , que aplica un predicado arbitrario a cada miembro de una lista determinada, y , que filtra elementos que satisfacen un predicado dado, permitiendo también el curry . [21]call/2
call/3
findall/3
setof/3
bagof/3
maplist/2
sublist/3
Para convertir soluciones de representación temporal (sustituciones de respuestas al retroceder) a representación espacial (términos), Prolog tiene varios predicados de todas las soluciones que recopilan todas las sustituciones de respuestas 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 , findall ( D , ( entre ( 1 , U , D ), N mod D =:= 0 ), Ds ), lista de sumas ( Ds , N ).
Esto se puede utilizar para enumerar números perfectos y comprobar 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 de mapas ( _ , [], []). lista de mapas ( P , [ X | Xs ], [ Y | Ys ]) : - llamar ( P , X , Y ), lista de mapas ( P , Xs , Ys ).
Cuando P
es un predicado que para todos X
, P(X,Y)
se unifica Y
con un solo valor único, maplist(P, Xs, Ys)
equivale 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 .
Para la programación a gran escala , Prolog proporciona un sistema de módulos , que se encuentra en el estándar ISO. [24] Sin embargo, si bien la mayoría de los sistemas Prolog admiten la estructuración del código en módulos, prácticamente ninguna implementación se adhiere a los módulos que forman parte del estándar ISO. En cambio, la mayoría de los sistemas Prolog han decidido admitir como módulo estándar de facto el sistema de módulos Quintus / SICStus . Sin embargo, solo algunas implementaciones proporcionan predicados de conveniencia adicionales relacionados con los módulos y, a menudo, tienen diferencias sutiles en su semántica. [25]
Algunos sistemas optaron por implementar conceptos de módulo como compilación de fuente a fuente en ISO Prolog base, como es el caso de Logtalk . [26] GNU Prolog inicialmente se desvió de los módulos ISO, optando en su lugar por la programación lógica contextual, en la que la carga y descarga de unidades (módulos) se puede realizar dinámicamente. [27] Ciao diseñó un estricto sistema de módulos que, si bien es básicamente compatible con el estándar de facto utilizado por otros sistemas Prolog, es susceptible de análisis estáticos precisos, admite la ocultación de términos y facilita la programación a gran escala. [28] XSB adopta un enfoque diferente y ofrece un sistema de módulos basado en átomos . [29] Los dos últimos sistemas Prolog permiten controlar la visibilidad de los términos además de la de los predicados. [25]
Existe una notación especial llamada gramáticas de cláusulas definidas (DCG). El preprocesador expande una regla definida vía -->/2
en lugar de ( , una función análoga a las macros en otros lenguajes) de acuerdo con unas pocas reglas de reescritura sencillas, lo que da como resultado cláusulas Prolog ordinarias. En particular, la reescritura equipa al predicado con dos argumentos adicionales, que pueden usarse para enhebrar implícitamente el estado, [ se necesita aclaración ] de manera análoga a las mónadas en otros lenguajes. Los DCG se utilizan a menudo para escribir analizadores o generadores de listas, ya que también proporcionan una interfaz conveniente para diferenciar listas.:-/2
expand_term/2
Prolog es un lenguaje homoicónico y proporciona muchas facilidades para la programación reflexiva (reflexión). Su estrategia de ejecución implícita permite escribir un evaluador metacircular conciso (también llamado metaintérprete ) para código Prolog puro:
resolver ( verdadero ). resolver (( Subobjetivo1 , Subobjetivo2 )) : - resolver ( Subobjetivo1 ), resolver ( Subobjetivo2 ). resolver ( Cabeza ) : - cláusula ( Cabeza , 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 del formulario Head :- Body
.
Dado que los programas Prolog son en sí mismos secuencias de términos de Prolog ( es un operador:-/2
infijo ) que se leen e inspeccionan fácilmente utilizando mecanismos integrados (como ), es posible escribir intérpretes personalizados que aumenten Prolog con características específicas de dominio. Por ejemplo, Sterling y Shapiro presentan un metaintérprete que razona con incertidumbre, reproducido aquí con ligeras modificaciones: [30] : 330 read/1
resolver ( verdadero , 1 ) : - !. resolver (( Subobjetivo1 , Subobjetivo2 ), Certeza ) :- !, resolver ( Subobjetivo1 , Certeza1 ), resolver ( Subobjetivo2 , Certeza2 ), La certeza es mínima ( Certeza1 , Certeza2 ). resolver ( Objetivo , 1 ) : - incorporado ( Objetivo ), !, Objetivo . resolver ( Cabeza , Certeza ) : - cláusula_cf ( Cabeza , Cuerpo , Certeza1 ), resolver ( Cuerpo , Certeza2 ), Certeza es Certeza1 * Certeza2 .
Este intérprete utiliza una tabla de predicados Prolog integrados de la forma [30] : 327
incorporado ( A es B ). incorporado ( leer ( X )). % etc.
y cláusulas representadas como clause_cf(Head, Body, Certainty)
. Teniendo en cuenta eso, se le puede llamar para solve(Goal, Certainty)
ejecutar Goal
y obtener una medida de certeza sobre el resultado.
Pure Prolog se basa en un subconjunto de lógica de predicados de primer orden , las cláusulas de Horn , que es Turing-completa . La integridad de Turing de Prolog se puede demostrar usándolo para simular una máquina de Turing:
turing ( Tape0 , Tape ) : - realizar ( q0 , [], Ls , Tape0 , Rs ), invertir ( Ls , Ls1 ), agregar ( Ls1 , Rs , Tape ).realizar ( qf , Ls , Ls , Rs , Rs ) :- !. realizar ( Q0 , Ls0 , Ls , Rs0 , Rs ) : - símbolo ( Rs0 , Sym , RsRest ), una vez ( regla ( Q0 , Sym , Q1 , NewSym , Action )), acción ( Action , Ls0 , Ls1 , [ NewSym | RsRest ], Rs1 ), realizar ( Q1 , Ls1 , Ls , Rs1 , Rs ).símbolo ([], b , []). símbolo ([ Sym | Rs ], Sym , Rs ).acción ( izquierda , Ls0 , Ls , Rs0 , Rs ) : - izquierda ( Ls0 , Ls , Rs0 , Rs ). acción ( quedarse , Ls , Ls , Rs , Rs ). acción ( derecha , Ls0 , [ Sym | Ls0 ], [ Sym | Rs ], Rs ).izquierda ([], [], Rs0 , [ b | Rs0 ]). izquierda ([ L | Ls ], Ls , Rs , [ L | Rs ]).
Un ejemplo sencillo de máquina de Turing se concreta en los hechos:
regla ( q0 , 1 , q0 , 1 , derecha ). regla ( q0 , b , qf , 1 , permanecer ).
Esta máquina realiza un incremento en uno de un número en codificación unaria: recorre cualquier número de celdas "1" y agrega un "1" adicional al final. Consulta de ejemplo 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, implementadas en Prolog como una relación entre sucesivos estados de interés.
La norma técnica Prolog de la Organización Internacional de Normalización (ISO) consta de dos partes. ISO/IEC 13211-1, [23] [31] publicada 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 corrigenda: Cor.1:2007, [32] Cor.2:2012, [33] y Cor.3:2017. [34] ISO/IEC 13211-2, [23] publicada 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 [35] . ANSI X3J17 es el grupo asesor técnico de EE. UU. para el estándar. [36]
Para mayor eficiencia, el código Prolog generalmente se compila en código de máquina abstracto, a menudo influenciado por el conjunto de instrucciones Warren Abstract Machine (WAM) basado en registros. [37] Algunas implementaciones emplean interpretación abstracta para derivar información de tipo y modo de predicados en tiempo de compilación, o compilar en código de máquina real para un alto rendimiento. [38] 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 pila . [ cita necesaria ]
Los sistemas Prolog normalmente implementan un método de optimización conocido llamado optimización de llamadas de cola (TCO) para predicados deterministas que exhiben recursividad 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 una posición de cola. Por lo tanto, los predicados deterministas recursivos de cola se ejecutan con un espacio de pila constante, como los bucles en otros lenguajes.
Encontrar cláusulas que sean 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 búsquedas en tiempo sublineal . [39] La indexación solo afecta el rendimiento del programa, no afecta la semántica. La mayoría de los prólogos solo usan indexación en el primer término, ya que la indexación de todos los términos es costosa, pero las técnicas basadas en palabras codificadas por campos o palabras en código superpuestas brindan una indexación rápida en toda la consulta y el encabezado. [40] [41]
Algunos sistemas Prolog, como WIN-PROLOG y SWI-Prolog, ahora implementan hash para ayudar a manejar grandes conjuntos de datos de manera más eficiente. Esto tiende a producir ganancias de rendimiento muy grandes cuando se trabaja con corpus grandes como WordNet .
Algunos sistemas Prolog ( B-Prolog , XSB , SWI-Prolog , YAP y Ciao ) implementan un método de memorización llamado tabulación , que libera al usuario de almacenar manualmente resultados intermedios. La presentación es una compensación espacio-temporal ; El tiempo de ejecución se puede reducir utilizando más memoria para almacenar resultados intermedios: [42] [43]
Los subobjetivos encontrados en la evaluación de una consulta se mantienen en una tabla, junto con las respuestas a estos subobjetivos. Si se vuelve a encontrar un subobjetivo, la evaluación reutiliza la información de la tabla en lugar de volver a realizar la resolución según las cláusulas del programa. [44]
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, la presentación de resultados podría mantenerse privada para un subproceso o compartirse entre todos los subprocesos. Y en la presentación incremental, la presentación puede reaccionar a los cambios.
Durante el proyecto de Sistemas Informáticos de Quinta Generación , se intentó implementar Prolog en hardware con el objetivo de lograr una ejecución más rápida con arquitecturas dedicadas. [45] [46] [47] Además, Prolog tiene una serie de propiedades que pueden permitir la aceleración mediante la ejecución paralela. [48] Un enfoque más reciente ha sido compilar programas Prolog restringidos en una matriz de puertas programables en campo . [49] 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 idioma japonés , a través de un panel táctil . [50]
Aunque Prolog se usa ampliamente en investigación y educación, [51] Prolog y otros lenguajes de programación lógica no han tenido un impacto significativo en la industria informática en general. [52] 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. [52] [53] La programación en general se considera compleja 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. [26] La portabilidad del código Prolog entre implementaciones también ha sido un problema, pero los desarrollos desde 2007 han significado: "la portabilidad dentro de la familia de implementaciones Prolog derivadas de Edimburgo/Quintus es lo suficientemente buena como para permitir el mantenimiento de aplicaciones portátiles del mundo real". [54]
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 al programar cálculos deterministas, o incluso cuando se utiliza "no me importa el no determinismo" (donde se hace una única elección en lugar de retroceder sobre todas las posibilidades). Es posible que sea necesario utilizar cortes y otras construcciones del lenguaje para lograr el rendimiento deseable, destruyendo uno de los principales atractivos de Prolog, la capacidad de ejecutar programas "hacia adelante y hacia atrás". [55]
Prolog no es puramente declarativo: debido a construcciones como el operador de corte , se necesita una lectura procesal de un programa Prolog para comprenderlo. [56] El orden de las cláusulas en un programa Prolog es importante, ya que de él depende la estrategia de ejecución del lenguaje. [57] 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 ser programas de lógica puramente declarativa. [55]
Se han desarrollado varias implementaciones desde Prolog para ampliar las capacidades de programación lógica en muchas direcciones. Estos incluyen tipos , modos, programación lógica de restricciones (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 :
Prolog es un lenguaje sin escribir. Los intentos de introducir y ampliar Prolog con tipos comenzaron en la década de 1980, [58] [59] y continúan a partir de 2008 [actualizar]. [60] La información de tipos es útil no sólo para la seguridad de tipos sino también para razonar sobre los programas Prolog. [61]
La sintaxis de Prolog no especifica qué argumentos de un predicado son entradas y cuáles son salidas. [62] Sin embargo, esta información es significativa y se recomienda que se incluya en los comentarios. [63] Los modos proporcionan información valiosa al razonar sobre programas Prolog [61] y también se pueden utilizar para acelerar la ejecución. [64]
La programación lógica de restricciones extiende Prolog para incluir conceptos de satisfacción de restricciones . [65] [66] Un programa de lógica de restricciones permite restricciones en el cuerpo de cláusulas, tales como: A(X,Y) :- X+Y>0.
Es adecuado para problemas de optimización combinatoria a gran escala [67] y, por lo tanto, es útil para aplicaciones en entornos industriales, como la programación automatizada de horarios. y programación de la producción . La mayoría de los sistemas Prolog se entregan con al menos un solucionador de restricciones para dominios finitos y, a menudo, también con solucionadores para otros dominios, como números racionales .
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 utilizar la mayoría de las implementaciones de Prolog como compilador 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 creada por Margaret McDougall de EdCAAD, Universidad de Edimburgo.
Objlog era un lenguaje basado en marcos que combinaba objetos y Prolog II del 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.
Los sistemas Prolog que proporcionan una biblioteca de gráficos son SWI-Prolog , [68] Visual Prolog , WIN-PROLOG y B-Prolog .
Prolog-MPI es una extensión SWI-Prolog de código abierto para informática distribuida a través de la interfaz de paso de mensajes . [69] También hay varios lenguajes de programación Prolog concurrentes. [70]
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 . [71] También existen extensiones para admitir formatos web semánticos , como el Marco de descripción de recursos (RDF) y el Lenguaje de ontología web (OWL). [72] [73] Prolog también se ha sugerido como lenguaje del lado del cliente . [74] Además, Visual Prolog admite JSON-RPC y Websockets .
Cedar Archivado el 19 de octubre de 2010 en Wayback Machine es un intérprete de Prolog básico y gratuito. A partir de la versión 4 y superiores, Cedar tiene soporte FCA (Flash Cedar App). Esto proporciona una nueva plataforma para programar en Prolog a través de ActionScript .
Existen marcos que pueden servir de puente entre Prolog y otros lenguajes:
El nombre Prolog fue elegido por Philippe Roussel, a sugerencia de su esposa, como abreviatura de programmation en logique ( programación en lógica en francés ). [76] Fue creado alrededor de 1972 por Alain Colmerauer con Philippe Roussel, basado en la interpretación procesal 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 de representación del conocimiento declarativo con la representación procedimental del conocimiento que fue popular en América del Norte 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. [77] [78] [79] La primera implementación de Prolog fue un intérprete escrito en Fortran por Gerard Battani y Henri Meloni. David HD Warren llevó este intérprete a la Universidad de Edimburgo , y allí implementó una interfaz alternativa, 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 la 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. [80] Gran parte del desarrollo moderno de Prolog provino del impulso del proyecto de sistemas informáticos de quinta generación (FGCS), que desarrolló una variante de Prolog llamada Kernel Language para su primer sistema operativo .
Pure Prolog se restringió originalmente al uso de un demostrador de teoremas de resolución con cláusulas de Horn de la forma:
H :- B 1 , ..., B n .
La aplicación del demostrador de teoremas trata dichas cláusulas como procedimientos:
para mostrar/resolver H, mostrar/resolver B 1 y ... y B n .
Sin embargo, pronto se amplió Pure Prolog para incluir la negación como fracaso , en la que condiciones negativas de la forma not(B i ) se muestran al intentar resolver sin éxito las correspondientes condiciones positivas B i .
Las extensiones posteriores de Prolog realizadas por el equipo original introdujeron capacidades de programación lógica de restricciones en las implementaciones.
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 fue escrito 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 reglas de coincidencia de patrones sobre los árboles de análisis y otras anotaciones (como resultados de reconocimiento de entidades con nombre), y una tecnología que pudiera ejecutar estas reglas de manera muy eficiente. Descubrimos que Prolog Fue la elección ideal para el lenguaje por su sencillez y expresividad ." [12] Prolog se está utilizando en la plataforma de desarrollo Low-Code GeneXus , que se centra en la IA. [ cita necesaria ] La base de datos de gráficos de código abierto TerminusDB está implementada en Prolog. [81] TerminusDB está diseñado para construir y curar de forma colaborativa gráficos de conocimiento .