Prólogo - Prolog

Prólogo
Paradigma Lógica
Diseñada por Alain Colmerauer , Robert Kowalski
Apareció por primera vez 1972 ; Hace 49 años ( 1972 )
Lanzamiento estable
Parte 1: Núcleo general-Edición 1 (junio de 1995 ; hace 26 años ) Parte 2: Módulos-Edición 1 (junio de 2000 ; hace 21 años )  ( 1995-06 )
 ( 2000-06 )
Disciplina de mecanografía Sin tipo (su tipo de datos único es "término")
Extensiones de nombre de archivo .pl, .pro,.P
Sitio web Parte 1: www .iso .org / standard / 21413 .html
Parte 2: www .iso .org / standard / 20775 .html
Implementaciones importantes
B-Prolog , Ciao , ECLiPSe , GNU Prolog , Poplog Prolog, P # , Quintus Prolog , SICStus , Strawberry , SWI-Prolog , Tau Prolog , tuProlog, WIN-PROLOG , XSB , YAP .
Dialectos
Prólogo ISO, Prólogo de Edimburgo
Influenciado por
Planificador
Influenciado
CHR , Clojure , Registro de datos , Erlang , KL0 , KL1 , Mercury , Oz , Strand , Visual Prolog , XSB

Prolog es un lenguaje de programación lógica 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 Robert Kowalski de las cláusulas de Horn .

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 comerciales y gratuitas 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 original previsto, 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 en red.

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

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 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 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 análisis de lenguaje, matemáticas simbólicas y bases de datos . 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 tipo de datos único de Prolog es el término . Los términos son átomos , números , variables o términos compuestos .

  • Un átomo es un nombre de uso general sin un significado inherente. Ejemplos de átomos incluyen x, red, 'Taco', y 'some atom'.
  • Los números pueden ser flotantes o enteros . Los sistemas Prolog compatibles con la norma ISO pueden comprobar el indicador Prolog "acotado". La mayoría de los principales sistemas Prolog admiten números enteros de longitud arbitraria.
  • Las variables se indican mediante una cadena que consta de letras, números y caracteres de subrayado, y comienza con una letra mayúscula o un subrayado. Las variables se parecen mucho a las variables en lógica, ya que son marcadores de posición para términos arbitrarios.
  • Un término compuesto se compone de un átomo llamado "funtor" y una serie de "argumentos", que también son términos. Los términos compuestos se escriben normalmente como un funtor seguido de una lista de términos de argumentos separados por comas, que se incluye entre paréntesis. El número de argumentos se denomina aridad del término . Un átomo se puede considerar como un término compuesto con aridad cero. Un ejemplo de término compuesto es person_friends(zelda,[tom,jim]).

Casos especiales de términos compuestos:

  • Una lista es una colección ordenada de términos. Se indica mediante corchetes con los términos separados por comas o, en el caso de la lista vacía, por []. Por ejemplo, [1,2,3]o [red,green,blue].
  • Cadenas : una secuencia de caracteres rodeada de comillas equivale a una lista de códigos de caracteres (numéricos), una lista de caracteres (átomos de longitud 1) o un átomo, según el valor del indicador Prolog double_quotes. Por ejemplo "to be, or not to be",.

ISO Prolog proporciona los atom/1, number/1, integer/1, y float/1predicados para tipo de comprobación .

Reglas y hechos

Los programas de 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 tiene la forma

Head :- Body.

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(es decir, un operador arity 2 con nombre ,) denota conjunción de objetivos y ;/2denota 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:

cat(crookshanks).

que es equivalente a la regla:

cat(crookshanks) :- true.

El predicado incorporado true/0siempre es verdadero.

Dado el hecho anterior, uno puede preguntar:

¿Crookshanks es un gato?

 ?- cat(crookshanks).
 Yes

que cosas son los gatos?

 ?- cat(X).
 X = crookshanks

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

animal(X) :- cat(X).

Si agregamos esa regla y preguntamos ¿qué cosas son los animales?

 ?- animal(X).
 X = crookshanks

Debido a la naturaleza relacional de muchos predicados integrados, normalmente se pueden usar en varias direcciones. Por ejemplo, length/2se puede utilizar 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/3se puede usar tanto para agregar dos listas (listas append(ListA, ListB, X)dadas ListAy ListB) como para dividir una lista dada en partes ( append(X, Y, List), dada una lista List). Por esta razón, un conjunto relativamente 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 de rutina como entrada / salida , usar gráficos y comunicarse 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/1muestra un término en la pantalla.

Ejecución

La ejecución de un programa Prolog se inicia mediante la publicación del usuario de un único objetivo, llamado consulta. Lógicamente, el motor de Prolog intenta encontrar una refutación de resolución de la consulta negada. El método de resolución utilizado por Prolog se llama 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, una diferencia es que varios encabezados de cláusula 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, todos los enlaces de variables que se hicieron 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).
 
sibling(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:

 ?- sibling(sally, erica).
 Yes

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 variable apropiados en su lugar, es decir, la conjunción (parent_child(Z,sally), parent_child(Z,erica)). El siguiente objetivo a ser probado 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 demostrar utilizando el hecho de father_child(tom, sally), por lo que la unión Z = tomse genera, y el siguiente objetivo a ser probada es la segunda parte de la conjunción arriba: parent_child(tom, erica). Nuevamente, esto puede probarse con el hecho correspondiente. Dado que se pudieron probar todos los objetivos, la consulta se realiza correctamente. Dado que la consulta no contenía variables, no se informa al usuario de enlaces. Una consulta con variables, como:

?- father_child(Father, Child).

enumera todas las respuestas válidas sobre la marcha atrás.

Tenga en cuenta que con el código como se indicó anteriormente, la consulta ?- sibling(sally, sally).también se realiza correctamente. Se insertarían objetivos adicionales para describir las restricciones relevantes, si se desea.

Bucles y recursividad

Los algoritmos iterativos se pueden implementar mediante predicados recursivos.

Negación

El predicado Prolog integrado \+/1proporciona la negación como falla , lo que permite un razonamiento no monótono . El gol \+ illegal(X)en la regla

legal(X) :- \+ illegal(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 puede encontrar ninguna prueba, el objetivo original tiene éxito. Por lo tanto, el \+/1operador de prefijo se denomina operador "no demostrable", ya que la consulta se realiza ?- \+ Goal.correctamente si el objetivo 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 utilizar para enumerar todas las cosas que son legales.

Programación en Prolog

En Prolog, el código de carga se denomina consulta . Prolog se puede utilizar de forma interactiva introduciendo 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, estas 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.

A continuación, se muestran algunos programas de ejemplo escritos en Prolog.

Hola Mundo

Un ejemplo de consulta:

?- write('Hello World!'), nl.
Hello World!
true.

?-

Optimización del compilador

Cualquier cálculo puede expresarse declarativamente como una secuencia de transiciones de estado. Como ejemplo, un compilador de optimización con tres pasadas 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 de ordenación rápida , que relaciona una lista con su versión ordenada:

partition([], _, [], []).
partition([X|Xs], Pivot, Smalls, Bigs) :-
    (   X @< Pivot ->
        Smalls = [X|Rest],
        partition(Xs, Pivot, Rest, Bigs)
    ;   Bigs = [X|Rest],
        partition(Xs, Pivot, Smalls, Rest)
    ).
 
quicksort([])     --> [].
quicksort([X|Xs]) -->
    { partition(Xs, X, Smaller, Bigger) },
    quicksort(Smaller), [X], quicksort(Bigger).

Patrones de diseño de Prolog

Un patrón de diseño es una solución reutilizable general 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 programa, 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 el apoyo para la programación de orden superior toma Prolog fuera del dominio de la lógica de primer orden, que no permite la cuantificación sobre los predicados, ISO Prolog tiene ahora algunos incorporado predicados de orden superior, tales como call/1, call/2, call/3, findall/3, setof/3, y bagof/3. Además, dado que los objetivos de Prolog arbitrarios se pueden construir y evaluar 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/3que filtra elementos que satisfacen un predicado dado. , permitiendo también el curry .

Para convertir soluciones de representación temporal (sustituciones de respuesta en retroceso) 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:

 perfect(N) :-
     between(1, inf, N), U is N // 2,
     findall(D, (between(1,U,D), N mod D =:= 0), Ds),
     sumlist(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 maplistaplica un predicado Pa todas las posiciones correspondientes en un par de listas:

maplist(_, [], []).
maplist(P, [X|Xs], [Y|Ys]) :-
   call(P, X, Y),
   maplist(P, Xs, Ys).

Cuando Pes un predicado que para todos X, se P(X,Y)unifica Ycon un único 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 .

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.

Analizando

Existe una notación especial llamada gramáticas de cláusulas definidas (DCG). El preprocesador expande una regla definida mediante en -->/2lugar de :-/2( expand_term/2una función análoga a las macros en otros idiomas) de acuerdo con unas pocas reglas de reescritura sencillas, lo que da como resultado cláusulas Prolog ordinarias. Más notablemente, la reescritura equipa el predicado con dos argumentos adicionales, que se pueden usar para enhebrar implícitamente el estado, de forma análoga a las mónadas en otros lenguajes. Los DCG se utilizan a menudo para escribir analizadores sintácticos 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 ofrece muchas facilidades para la reflexión . Su estrategia de ejecución implícita hace posible escribir un evaluador meta-circular conciso (también llamado meta-intérprete ) para código Prolog puro:

solve(true).
solve((Subgoal1,Subgoal2)) :- 
    solve(Subgoal1),
    solve(Subgoal2).
solve(Head) :- 
    clause(Head, Body),
    solve(Body).

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

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

solve(true, 1) :- !.
solve((Subgoal1,Subgoal2), Certainty) :-
    !,
    solve(Subgoal1, Certainty1),
    solve(Subgoal2, Certainty2),
    Certainty is min(Certainty1, Certainty2).
solve(Goal, 1) :-
    builtin(Goal), !, 
    Goal.
solve(Head, Certainty) :-
    clause_cf(Head, Body, Certainty1),
    solve(Body, Certainty2),
    Certainty is Certainty1 * Certainty2.

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

builtin(A is B).
builtin(read(X)).
% etc.

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

Completitud de Turing

Pure Prolog se basa en un subconjunto de la lógica de predicados de primer orden , cláusulas Horn , que es Turing-complete . 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),
    reverse(Ls, Ls1),
    append(Ls1, Rs, Tape).
 
perform(qf, Ls, Ls, Rs, Rs) :- !.
perform(Q0, Ls0, Ls, Rs0, Rs) :-
    symbol(Rs0, Sym, RsRest),
    once(rule(Q0, Sym, Q1, NewSym, Action)),
    action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
    perform(Q1, Ls1, Ls, Rs1, Rs).
 
symbol([], b, []).
symbol([Sym|Rs], Sym, Rs).
 
action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).
action(stay, Ls, Ls, Rs, Rs).
action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).
 
left([], [], Rs0, [b|Rs0]).
left([L|Ls], Ls, Rs, [L|Rs]).

Los hechos especifican un ejemplo simple de la máquina de Turing:

rule(q0, 1, q0, 1, right).
rule(q0, b, qf, 1, stay).

Esta máquina realiza un incremento en uno de un número en la codificación unaria: recorre cualquier número de celdas "1" y agrega un "1" adicional 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, implementada 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.

Compilacion

Para mayor eficiencia, el código de Prolog se compila típicamente en 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 compilar 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 otros métodos de ejecución. Estos incluyen binarización de cláusulas y máquinas virtuales basadas en pilas .

Recursión de cola

Los sistemas Prolog generalmente 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 recursivos de cola deterministas se ejecutan con un espacio de pila constante, como los bucles en otros lenguajes.

Indexación de términos

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 sub-lineal . La indexación solo afecta el rendimiento del programa, no afecta la semántica. La mayoría de los Prologs solo usan la indexación en el primer término, ya que indexar en todos los términos es costoso, pero las técnicas basadas en palabras codificadas en el campo o palabras de código superpuestas proporcionan una indexación rápida en toda la consulta y el encabezado.

Hashing

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 grandes corpora como WordNet .

Presentación

Algunos sistemas Prolog, ( B-Prolog , XSB , SWI-Prolog , YAP , y Ciao ), implementan una memoization método llamado presentación , que libera al usuario de almacenar manualmente los resultados intermedios. La presentación es una compensación entre el espacio y el tiempo ; El tiempo de ejecución se puede reducir utilizando más memoria para almacenar resultados intermedios:

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 contra las cláusulas del programa.

La presentación de tablas puede extenderse 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 la tabulación pueden mantenerse privados para un hilo o compartidos entre todos los hilos. Y en la tabulación incremental, la tabulación puede reaccionar a los cambios.

Implementación en hardware

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. Además, Prolog tiene una serie de propiedades que pueden permitir la aceleración mediante 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 sistemáticamente a las arquitecturas más especializadas.

Limitaciones

Aunque Prolog se usa ampliamente en investigación y educación, Prolog y otros lenguajes de programación lógica 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 Edimburgo / Quintus es lo suficientemente buena como para permitir el mantenimiento de aplicaciones portátiles del mundo real".

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 utilizar cortes y otras construcciones del lenguaje para lograr un rendimiento deseable, destruyendo una de las principales atracciones de Prolog, la capacidad de ejecutar programas "hacia atrás y hacia adelante".

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 significativo, 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 ser programas de lógica puramente declarativa.

Extensiones

Se han desarrollado varias implementaciones de Prolog para ampliar las capacidades de programación lógica en numerosas 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 :

Tipos

Prolog es un lenguaje sin mecanografiar. 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

Especificador de modo Interpretación
+ nonvar en la entrada
- var en 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 significativa y se recomienda que se incluya en los comentarios. Los modos proporcionan información valiosa al razonar sobre los programas de Prolog y también se pueden utilizar para acelerar la ejecución.

Restricciones

La programación de lógica de restricciones extiende 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, tales 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 planificación automatizada de tiempos y la programación de producción . La mayoría de los sistemas Prolog se envían 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 de 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 de back-end. Como lenguaje de múltiples paradigmas, 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 multi-paradigma 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 la programación web del lado del servidor con soporte para protocolos web, HTML y XML . También hay extensiones para admitir formatos web semánticos como RDF y OWL . Prolog también se ha sugerido como 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 compatibilidad con FCA (Flash Cedar App). Esto proporciona una nueva plataforma para programar en Prolog a través de ActionScript .

Otro

Interfaces a otros idiomas

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

  • El LPA Server Intelligence permite la incorporación de LPA Prolog para Windows en C, C #, C ++, Java, Visual Basic, Delphi, .Net, Lua, Python y otros lenguajes. Explota el tipo de datos de cadena dedicada que proporciona LPA Prolog
  • La API de Logic Server permite tanto la extensión como la incrustación de Prolog en C, C ++, Java, VB, Delphi, .NET y cualquier lenguaje / entorno que pueda llamar a .dll o .so. ¡Está implementado para Amzi! Prolog Amzi! Prolog + Logic Server, pero la especificación API puede estar disponible para cualquier implementación.
  • JPL es un puente Java Prolog bidireccional que se envía con SWI-Prolog de forma predeterminada, lo que permite que Java y Prolog se llamen entre sí (recursivamente). Se sabe que tiene un buen soporte de concurrencia y está en desarrollo activo.
  • InterProlog , un puente de biblioteca de programación entre Java y Prolog, que implementa llamadas bidireccionales de predicado / método entre ambos lenguajes. Los objetos Java se pueden asignar a términos de Prolog y viceversa. Permite el desarrollo de GUI y otras funcionalidades en Java mientras deja el procesamiento lógico en la capa Prolog. Soporta XSB , con soporte para SWI-Prolog y YAP planeado para 2013.
  • Prova proporciona integración de sintaxis nativa con Java, mensajería de agentes y reglas de reacción. Prova se posiciona como un sistema de scripting basado en reglas (RBS) para middleware. El lenguaje abre nuevos caminos al combinar programación imperativa y declarativa .
  • PROL Un motor Prolog integrable para Java. Incluye un pequeño IDE y algunas bibliotecas.
  • GNU Prolog para Java es una implementación de ISO Prolog como una biblioteca Java (gnu.prolog)
  • Ciao proporciona interfaces para C, C ++, Java y bases de datos relacionales.
  • C # -Prolog es un intérprete de Prolog escrito en C # (administrado). Se puede integrar fácilmente en programas de C #. Características: intérprete confiable y bastante rápido, interfaz de línea de comandos, interfaz de Windows, DCG incorporado, predicados XML, predicados SQL, ampliable. El código fuente completo está disponible, incluido un generador de analizador que se puede usar para agregar extensiones de propósito especial.
  • Una máquina abstracta de Warren para PHP Un compilador e intérprete de Prolog en PHP 5.3. Una biblioteca que se puede usar de forma independiente o dentro del marco Symfony2.1 que se tradujo del trabajo de Stephan Buettcher en Java que se puede encontrar [aquí stefan .buettcher .org / cs / wam / index .html ]
  • tuProlog es un sistema Prolog liviano para aplicaciones e infraestructuras distribuidas, diseñado intencionalmente alrededor de un núcleo mínimo, para configurarse estática o dinámicamente cargando / descargando bibliotecas de predicados. tuProlog es compatible de forma nativa con la programación de múltiples paradigmas, proporcionando un modelo de integración limpio y sin problemas entre Prolog y los lenguajes orientados a objetos convencionales, a saber, Java, para la versión de Java tuProlog, y cualquier lenguaje basado en .NET (C #, F # ..), para tuProlog. NET.

Historia

El nombre Prolog fue elegido por Philippe Roussel como abreviatura de programmation en logique ( francés para programar 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 un lenguaje declarativo de representación del conocimiento con la representación procedimental del conocimiento que era popular en América del Norte a fines de la década de 1960 y principios de la de 1970. 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 HD Warren llevó a este intérprete a Edimburgo y allí implementó un front-end alternativo, que llegó a definir la sintaxis de "Edinburgh Prolog" utilizada por la mayoría de las implementaciones modernas. Warren también implementó el primer compilador para Prolog, creando el influyente DEC-10 Prolog en colaboración con Fernando Pereira. Más tarde, Warren generalizó las ideas detrás de DEC-10 Prolog, para crear la Warren Abstract Machine .

Los investigadores europeos de inteligencia artificial 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 impulso del proyecto Fifth Generation Computer Systems (FGCS), que desarrolló una variante de Prolog llamada Kernel Language para su primer sistema operativo .

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

H :- B1, ..., Bn.

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

to show/solve H, show/solve B1 and ... and Bn.

Sin embargo, pronto se extendió Pure Prolog para incluir la negación como falla , en la que las condiciones negativas de la forma no (B i ) se muestran al intentar y no resolver las condiciones positivas correspondientes B i .

Las posteriores extensiones de Prolog por parte del equipo original introdujeron habilidades de programación lógica de restricciones 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 sobre á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 los 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 idioma por su sencillez y expresividad ". Prolog se está utilizando en la plataforma de desarrollo Low-Code GeneXus , que se centra en la IA. La base de datos gráfica de código abierto TerminusDB se implementa en prolog. TerminusDB está diseñado para crear y curar gráficos de conocimiento de forma colaborativa .

Ver también

Idiomas relacionados

  • El lenguaje de Gödel es una implementación fuertemente tipada de programación lógica de restricción concurrente . Está construido sobre SICStus Prolog.
  • Visual Prolog , anteriormente conocido como PDC Prolog y Turbo Prolog, es un dialecto de Prolog orientado a objetos fuertemente tipado , que es muy diferente del Prolog estándar. Como Turbo Prolog, fue comercializado por Borland, pero ahora es desarrollado y comercializado por la firma danesa PDC (Prolog Development Center) que lo produjo originalmente.
  • Datalog es un subconjunto de Prolog. Se limita a las relaciones que pueden estar estratificadas y no permite términos compuestos. A diferencia de Prolog, Datalog no es Turing completo .
  • Mercury es una rama de Prolog orientada a la ingeniería de software en general con un sistema de tipo polimórfico estático, así como un sistema de modo y determinismo.
  • GraphTalk es una implementación patentada de la máquina abstracta de Warren, con propiedades adicionales orientadas a objetos.
  • En cierto modo, Prolog es un subconjunto de Planner . Las ideas de Planner se desarrollaron más tarde en la metáfora de la comunidad científica .
  • AgentSpeak es una variante de Prolog para programar el comportamiento del agente en sistemas multiagente .
  • Erlang comenzó su vida con una implementación basada en Prolog y mantiene gran parte de la sintaxis basada en unificación de Prolog.
  • Pilog es un lenguaje declarativo construido sobre PicoLisp , que tiene la semántica de Prolog, pero usa la sintaxis de Lisp.

Referencias

Otras lecturas