Programación lógica

PrologEdit

Artículo principal: Prolog

El lenguaje de programación Prolog fue desarrollado en 1972 por Alain Colmerauer. Surgió de una colaboración entre Colmerauer en Marsella y Robert Kowalski en Edimburgo. Colmerauer estaba trabajando en la comprensión del lenguaje natural, usando la lógica para representar la semántica y usando la resolución para responder preguntas. Durante el verano de 1971, Colmerauer y Kowalski descubrieron que la forma clausal de la lógica podía usarse para representar gramáticas formales y que los probadores de teoremas de resolución podían usarse para analizar. Observaron que algunos probadores de teoremas, como la hiperresolución, se comportan como analizadores de abajo hacia arriba y otros, como SL-resolution (1971), se comportan como analizadores de arriba hacia abajo.

Fue en el verano siguiente de 1972, cuando Kowalski, de nuevo trabajando con Colmerauer, desarrolló la interpretación procedimental de las implicaciones. Esta interpretación declarativa/procedimental dual se formalizó más tarde en la notación Prolog

H :- B1, …, Bn.

que se puede leer (y usar) tanto de forma declarativa como de procedimiento. También quedó claro que tales cláusulas podían restringirse a cláusulas definidas o cláusulas Horn, donde H, B1,…, Bn son todas fórmulas lógicas de predicados atómicos, y que la resolución SL podría restringirse (y generalizarse) a resolución LUSH o SLD. La interpretación procedimental de Kowalski y LUSH se describieron en un memo de 1973, publicado en 1974.

Colmerauer, con Philippe Roussel, utilizó esta doble interpretación de cláusulas como base de Prolog, que se implementó en el verano y el otoño de 1972. El primer programa Prolog, también escrito en 1972 e implementado en Marsella, fue un sistema francés de respuesta de preguntas. El uso de Prolog como lenguaje de programación práctico recibió un gran impulso por el desarrollo de un compilador por David Warren en Edimburgo en 1977. Los experimentos demostraron que Edinburgh Prolog podía competir con la velocidad de procesamiento de otros lenguajes de programación simbólicos como Lisp. El Prolog de Edimburgo se convirtió en el estándar de facto e influyó fuertemente en la definición del Prolog estándar ISO.

Programación lógica abductivaedItar

La programación lógica abductiva es una extensión de la Programación Lógica normal que permite que algunos predicados, declarados como predicados abducibles, sean «abiertos» o indefinidos. Una cláusula en un programa de lógica abductiva tiene la forma:

H :- B1, …, Bn, A1, An, An.

donde H es una fórmula atómica que no es abducible, todos los Bi son literales cuyos predicados no son abducibles, y los Ai son fórmulas atómicas cuyos predicados son abducibles. Los predicados abducibles pueden estar limitados por restricciones de integridad, que pueden tener la forma:

false: – L1,…, Ln.

donde las Li son literales arbitrarias (definidas o abducibles, y atómicas o negadas). Por ejemplo:

canfly(X) :- bird(X), normal(X).false :- normal(X), wounded(X).bird(john).bird(mary).wounded(john).

donde el predicado normal es abducible.

La resolución de problemas se logra derivando hipótesis expresadas en términos de predicados abductibles como soluciones de problemas a resolver. Estos problemas pueden ser observaciones que necesitan ser explicadas (como en el razonamiento abductivo clásico) o metas que deben ser resueltas (como en la programación lógica normal). Por ejemplo, la hipótesis normal (maría) explica la observación de la mosca (maría). Además, la misma hipótesis implica la única solución X = mary del objetivo de encontrar algo que pueda volar:

:- canfly(X).

La programación lógica abductiva se ha utilizado para el diagnóstico de fallas, la planificación, el procesamiento del lenguaje natural y el aprendizaje automático. También se ha utilizado para interpretar la Negación como Fracaso como una forma de razonamiento abductivo.

Programación metalógicaeditar

Debido a que la lógica matemática tiene una larga tradición de distinguir entre lenguaje de objetos y metalenguaje, la programación lógica también permite la programación a nivel de metal. El programa metalogic más simple es el llamado meta-intérprete «vainilla»:

 solve(true). solve((A,B)):- solve(A),solve(B). solve(A):- clause(A,B),solve(B).

donde true representa una conjunción vacía,y la cláusula(A, B) significa que hay una cláusula a nivel de objeto de la formA:-B.

La programación Metalogic permite combinar representaciones a nivel de objeto y a nivel de metal, como en lenguaje natural. También se puede usar para implementar cualquier lógica que se especifique como reglas de inferencia. Metalogic se utiliza en la programación lógica para implementar metaprogramas, que manipulan otros programas, bases de datos, bases de conocimiento o teorías axiomáticas como datos.

Programación de lógica de restricciones Edit

Artículo principal: Programación de lógica de restricciones

La programación de lógica de restricciones combina la programación de lógica de cláusulas Horn con la resolución de restricciones. Extiende las cláusulas Horn al permitir que algunos predicados, declarados como predicados de restricción, ocurran como literales en el cuerpo de las cláusulas. Un programa de lógica de restricciones es un conjunto de cláusulas de la forma:

H :- C1, Cn, Cn B B1, Bn.

donde H y todos los Bi son fórmulas atómicas, y los Ci son restricciones. Declarativamente, tales cláusulas se leen como implicaciones lógicas ordinarias:

H si C1 y Cn y Cn y B1 y … y Bn.

Sin embargo, mientras que los predicados en las cabezas de las cláusulas están definidos por el programa de lógica de restricciones, los predicados en las restricciones están predefinidos por alguna estructura teórica de modelo específica de dominio o teoría.

Procedimentalmente, los subobjetivos cuyos predicados están definidos por el programa se resuelven mediante reducción de objetivos, como en la programación lógica ordinaria, pero las restricciones se comprueban para verificar su satisfabilidad mediante un solucionador de restricciones específico del dominio, que implementa la semántica de los predicados de restricciones. Un problema inicial se resuelve reduciéndolo a una conjunción de restricciones que se pueda satisfacer.

El siguiente programa de lógica de restricciones representa una base de datos temporal de juguete de la historia de john como profesor:

teaches(john, hardware, T) :- 1990 ≤ T, T < 1999.teaches(john, software, T) :- 1999 ≤ T, T < 2005.teaches(john, logic, T) :- 2005 ≤ T, T ≤ 2012.rank(john, instructor, T) :- 1990 ≤ T, T < 2010.rank(john, professor, T) :- 2010 ≤ T, T < 2014.

Aquí ≤ y < son predicados de restricción, con su semántica habitual. La siguiente cláusula de objetivo consulta la base de datos para averiguar cuándo john enseñó lógica y fue profesor:

:- enseña(john, lógica, T), rango(john, profesor, T).

La solución es 2010 ≤ T, T ≤ 2012.

La programación lógica de restricciones se ha utilizado para resolver problemas en campos como la ingeniería civil, la ingeniería mecánica, la verificación de circuitos digitales, la programación automatizada de horarios, el control del tráfico aéreo y las finanzas. Está estrechamente relacionado con la programación lógica abductiva.

Programación lógica concurrenteditar

Artículo principal: Programación lógica concurrente

La programación lógica concurrente integra conceptos de programación lógica con programación concurrente. Su desarrollo recibió un gran impulso en la década de 1980 por su elección para el lenguaje de programación de sistemas del Proyecto Japonés de Quinta Generación (FGCS).

Un programa de lógica concurrente es un conjunto de cláusulas de Cuerno guardadas de la forma:

H :- G1, G, Gn / B1,…, Bn.

La conjunción G1, … , Gn se llama la guardia de la cláusula, y / es el operador de compromiso. Declarativamente, las cláusulas de Cuerno guardadas se leen como implicaciones lógicas ordinarias:

H si G1 y G y Gn y B1 y … y Bn.

Sin embargo, procedimentalmente, cuando hay varias cláusulas cuyas cabezas H coinciden con un objetivo determinado, entonces todas las cláusulas se ejecutan en paralelo, verificando si sus guardias G1, … , Espera. Si las guardas de más de una cláusula se mantienen, entonces se hace una elección confirmada a una de las cláusulas, y la ejecución procede con los subobjetivos B1, … Bn de la cláusula. Estos subobjetivos también se pueden ejecutar en paralelo. Por lo tanto, la programación lógica concurrente implementa una forma de «no me importa el no determinismo», en lugar de «no sé el no determinismo».

Por ejemplo, el siguiente programa de lógica concurrente define un barajamiento de predicados (Izquierda, Derecha, Fusión), que se puede usar para barajar dos listas Izquierda y Derecha, combinándolas en una sola combinación de listas que conserva el orden de las dos listas Izquierda y Derecha:

shuffle(, , ).shuffle(Left, Right, Merge) :- Left = | Merge = , shuffle(Rest, Right, ShortMerge).shuffle(Left, Right, Merge) :- Right = | Merge = , shuffle(Left, Rest, ShortMerge).

Aquí, representa la lista vacía, y representa una lista con la cabeza del primer elemento seguida de Cola de lista, como en Prolog. (Observe que la primera aparición de | en la segunda y tercera cláusulas es el constructor de lista, mientras que la segunda aparición de | es el operador de compromiso.) El programa se puede utilizar, por ejemplo, para barajar las listas e invocar la cláusula goal:

shuffle(, , Merge).

El programa generará de forma no determinista una solución única, por ejemplo Merge = .

Podría decirse que la programación lógica concurrente se basa en el paso de mensajes, por lo que está sujeta a la misma indeterminación que otros sistemas de paso de mensajes concurrentes, como los Actores (véase Indeterminación en computación concurrente). Carl Hewitt ha argumentado que la programación lógica concurrente no se basa en la lógica en su sentido de que los pasos computacionales no se pueden deducir lógicamente. Sin embargo, en la programación lógica concurrente, cualquier resultado de un cálculo de terminación es una consecuencia lógica del programa, y cualquier resultado parcial de un cálculo parcial es una consecuencia lógica del programa y el objetivo residual (red de procesos). Por lo tanto, la indeterminación de los cálculos implica que no se pueden deducir todas las consecuencias lógicas del programa.

Programación de lógica de restricciones concurrenteseditar

Artículo principal: Programación de lógica de restricciones concurrentes

La programación de lógica de restricciones concurrentes combina la programación de lógica concurrente y la programación de lógica de restricciones, utilizando restricciones para controlar la concurrencia. Una cláusula puede contener una guardia, que es un conjunto de restricciones que pueden bloquear la aplicabilidad de la cláusula. Cuando se cumplen las guardas de varias cláusulas, la programación de lógica de restricción concurrente hace una elección confirmada de usar solo una.

Programación lógica inductivaedItar

Artículo principal: Programación lógica inductiva

La programación lógica inductiva se ocupa de generalizar ejemplos positivos y negativos en el contexto del conocimiento de fondo: aprendizaje automático de programas lógicos. El trabajo reciente en esta área, que combina programación lógica, aprendizaje y probabilidad, ha dado lugar al nuevo campo del aprendizaje relacional estadístico y la programación lógica inductiva probabilística.

Programación lógica de orden superioreditar

Varios investigadores han extendido la programación lógica con características de programación de orden superior derivadas de lógica de orden superior, como variables predicadas. Estos idiomas incluyen las extensiones Prolog HiLog y λProlog.

Programación lógica lineareditar

Basar la programación lógica dentro de la lógica lineal ha dado lugar al diseño de lenguajes de programación lógicos que son considerablemente más expresivos que los basados en la lógica clásica. Los programas de cláusulas Horn solo pueden representar el cambio de estado por el cambio de argumentos a predicados. En la programación de lógica lineal, se puede usar la lógica lineal ambiental para soportar el cambio de estado. Algunos de los primeros diseños de lenguajes de programación lógica basados en lógica lineal incluyen LO, Lolli, ACL y Forum . El Foro proporciona una interpretación dirigida a objetivos de toda la lógica lineal.

Programación lógica orientada a objetivosedItar

F-logic extiende la programación lógica con objetos y la sintaxis de marco.

Logtalk amplía el lenguaje de programación Prolog con soporte para objetos, protocolos y otros conceptos de POO. Es compatible con la mayoría de los sistemas Prolog que cumplen con los estándares como compiladores de back-end.

Programacióneditar

La lógica de transacciones es una extensión de la programación lógica con una teoría lógica de actualizaciones de modificación de estado. Tiene una semántica modelo-teórica y una semántica procedimental. Una implementación de un subconjunto de lógica de transacciones está disponible en el sistema Flora-2. Otros prototipos también están disponibles.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.