Programación lógica

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
paradigma de programación basado en la lógica formal

La programación lógica es un paradigma de programación que se basa en gran medida en la lógica formal. Cualquier programa escrito en un lenguaje de programación lógico es un conjunto de oraciones en forma lógica, que expresan hechos y reglas sobre el dominio de algún problema. Las principales familias de lenguajes de programación lógica incluyen Prolog, programación de conjunto de respuestas (ASP) y Datalog. En todos estos idiomas, las reglas se escriben en forma de cláusulas:

H:- B1,..., Bn.

y se leen declarativamente como implicaciones lógicas:

H si B1 y Bn.

H se denomina cabeza de la regla y B1,..., Bn se llama el cuerpo. Los hechos son reglas que no tienen cuerpo, y se escriben en forma simplificada:

H.

En el caso más simple en el que H, B1,..., Bn son todas fórmulas atómicas, estas cláusulas se denominan cláusulas definidas o cláusulas Horn. Sin embargo, hay muchas extensiones de este caso simple, siendo la más importante el caso en el que las condiciones en el cuerpo de una cláusula también pueden ser negaciones de fórmulas atómicas. Los lenguajes de programación lógica que incluyen esta extensión tienen las capacidades de representación del conocimiento de una lógica no monótona.

En ASP y Datalog, los programas lógicos tienen solo una lectura declarativa, y su ejecución se realiza mediante un procedimiento de prueba o generador de modelos cuyo comportamiento no está destinado a ser controlado por el programador. Sin embargo, en la familia de lenguajes Prolog, los programas lógicos también tienen una interpretación procedimental como procedimientos de reducción de objetivos:

para resolver H, resolver B1, y... y resolver Bn.

Considere la siguiente cláusula como ejemplo:

fallible(X):- humano(X).

basado en un ejemplo utilizado por Terry Winograd para ilustrar el lenguaje de programación Planner. Como cláusula en un programa lógico, se puede usar tanto como un procedimiento para probar si X es falible como para probar si X es humano, y como un procedimiento para encontrar un X que sea falible al encontrar un X que sea humano. Incluso los hechos tienen una interpretación procesal. Por ejemplo, la cláusula:

humanos.

puede usarse como un procedimiento para mostrar que sócrates es humano y como un procedimiento para encontrar una X que es humano "asignando" sócrates a X.

La lectura declarativa de programas lógicos puede ser utilizada por un programador para verificar su corrección. Además, las técnicas de transformación de programas basadas en lógica también se pueden utilizar para transformar programas lógicos en programas lógicamente equivalentes que sean más eficientes. En la familia Prolog de lenguajes de programación lógicos, el programador también puede utilizar el conocido comportamiento de resolución de problemas del mecanismo de ejecución para mejorar la eficiencia de los programas.

Historia

El uso de la lógica matemática para representar y ejecutar programas informáticos también es una característica del cálculo lambda, desarrollado por Alonzo Church en la década de 1930. Sin embargo, la primera propuesta para utilizar la forma lógica de cláusulas para representar programas de computadora fue hecha por Cordell Green. Este utilizó una axiomatización de un subconjunto de LISP, junto con una representación de una relación de entrada-salida, para calcular la relación simulando la ejecución del programa en LISP. Absys de Foster y Elcock, por otro lado, empleó una combinación de ecuaciones y cálculo lambda en un lenguaje de programación asertivo que no impone restricciones en el orden en que se realizan las operaciones.

La programación lógica en su forma actual se remonta a los debates de finales de la década de 1960 y principios de la de 1970 sobre las representaciones declarativas versus procedimentales del conocimiento en inteligencia artificial. Los defensores de las representaciones declarativas trabajaban notablemente en Stanford, asociados con John McCarthy, Bertram Raphael y Cordell Green, y en Edimburgo, con John Alan Robinson (un visitante académico de la Universidad de Syracuse), Pat Hayes y Robert Kowalski. Los defensores de las representaciones procesales se centraron principalmente en el MIT, bajo el liderazgo de Marvin Minsky y Seymour Papert.

Aunque se basó en los métodos de prueba de la lógica, Planner, desarrollado en el MIT, fue el primer lenguaje que surgió dentro de este paradigma procedimental. Planner presentaba una invocación dirigida por patrones de planes procedimentales a partir de objetivos (es decir, reducción de objetivos o encadenamiento hacia atrás) y de afirmaciones (es decir, encadenamiento hacia adelante). La implementación más influyente de Planner fue el subconjunto de Planner, llamado Micro-Planner, implementado por Gerry Sussman, Eugene Charniak y Terry Winograd. Se utilizó para implementar el programa de comprensión del lenguaje natural SHRDLU de Winograd, que fue un hito en ese momento. Para hacer frente a los sistemas de memoria muy limitados en ese momento, Planner utilizó una estructura de control de retroceso para que solo se tuviera que almacenar una ruta de cálculo posible a la vez. Planner dio lugar a los lenguajes de programación QA-4, Popler, Conniver, QLISP y el lenguaje concurrente Ether.

Hayes y Kowalski en Edimburgo intentaron reconciliar el enfoque declarativo basado en la lógica para la representación del conocimiento con el enfoque procedimental de Planner. Hayes (1973) desarrolló un lenguaje ecuacional, Golux, en el que se podían obtener diferentes procedimientos alterando el comportamiento del probador de teoremas. Kowalski, por otro lado, desarrolló la resolución SLD, una variante de la resolución SL, y mostró cómo trata las implicaciones como procedimientos de reducción de objetivos. Kowalski colaboró con Colmerauer en Marsella, quien desarrolló estas ideas en el diseño e implementación del lenguaje de programación Prolog.

La Asociación de Programación Lógica se fundó para promover la Programación Lógica en 1986.

Prolog dio lugar a los lenguajes de programación ALF, Fril, Gödel, Mercury, Oz, Ciao, Visual Prolog, XSB y λProlog, así como a una variedad de lenguajes de programación de lógica concurrente, lenguajes de programación de lógica de restricción y Datalog.

Conceptos

Semántica

Maarten van Emden y Robert Kowalski definieron tres semánticas para los programas lógicos de cláusulas de Horn, teoría de modelos, punto fijo y teoría de prueba, y demostraron que son equivalentes.

Lógica y control

La programación lógica puede verse como una deducción controlada. Un concepto importante en la programación lógica es la separación de programas en su componente lógico y su componente de control. Con los lenguajes de programación de lógica pura, el componente lógico por sí solo determina las soluciones producidas. El componente de control se puede variar para proporcionar formas alternativas de ejecutar un programa lógico. Esta noción es capturada por el eslogan

Algoritm = Logic + Control

donde "Lógica" representa un programa lógico y "Control" representa diferentes estrategias de demostración de teoremas.

Resolución de problemas

En el caso proposicional simplificado en el que un programa lógico y un objetivo atómico de nivel superior no contienen variables, el razonamiento hacia atrás determina un árbol and-or, que constituye el espacio de búsqueda para resolver el objetivo. El objetivo de nivel superior es la raíz del árbol. Dado cualquier nodo en el árbol y cualquier cláusula cuyo encabezado coincida con el nodo, existe un conjunto de nodos secundarios correspondientes a los subobjetivos en el cuerpo de la cláusula. Estos nodos secundarios se agrupan mediante una "y". Los conjuntos alternativos de hijos correspondientes a formas alternativas de resolver el nodo se agrupan con un 'o'.

Se puede utilizar cualquier estrategia de búsqueda para buscar en este espacio. Prolog utiliza una estrategia de retroceso secuencial, de último en entrar, primero en salir, en la que solo se considera una alternativa y un subobjetivo a la vez. También son posibles otras estrategias de búsqueda, como la búsqueda paralela, el retroceso inteligente o la búsqueda del mejor primero para encontrar una solución óptima.

En el caso más general, donde los subobjetivos comparten variables, se pueden usar otras estrategias, como elegir el subobjetivo que se ejemplifica más o que se ejemplifica lo suficiente como para que solo se aplique un procedimiento. Tales estrategias se utilizan, por ejemplo, en la programación lógica concurrente.

La negación como fracaso

Para la mayoría de las aplicaciones prácticas, así como para las aplicaciones que requieren un razonamiento no monótono en inteligencia artificial, los programas lógicos con cláusulas de Horn deben extenderse a programas lógicos normales con condiciones negativas. Una cláusula en un programa de lógica normal tiene la forma:

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

y se lee declarativamente como una implicación lógica:

H si A1 y An y no B1 y no Bn.

donde H y todos los Ai y Bi son atómicos fórmulas La negación en los literales negativos no Bi se conoce comúnmente como "negación como falla", porque en la mayoría de las implementaciones, una condición negativa Se demuestra que no Bi se cumple mostrando que la condición positiva Bi no se cumple. Por ejemplo:

Canfly()X) :- pájaro()X), no anormal()X).anormal()X) :- heridos()X).pájaro()John.).pájaro()Mary).heridos()John.).

Dado el objetivo de encontrar algo que pueda volar:

:- Canfly()X).

hay dos soluciones candidatas, que resuelven el primer subobjetivo bird(X), a saber, X = john y X = mary. El segundo subobjetivo no anormal(juan) de la primera solución candidata falla, porque herido(juan) tiene éxito y, por lo tanto, anormal(juan) tiene éxito. Sin embargo, el segundo subobjetivo no anormal(maria) de la segunda solución candidata tiene éxito, porque herida(maria) falla y por lo tanto anormal(maria) falla Por lo tanto, X = mary es la única solución de la meta.

Micro-Planner tenía una construcción, llamada "thnot", que cuando se aplica a una expresión devuelve el valor verdadero si (y solo si) falla la evaluación de la expresión. Normalmente existe un operador equivalente en las implementaciones modernas de Prolog. Normalmente se escribe como not(Objetivo) o + Objetivo, donde Objetivo es algún objetivo (proposición) que el programa debe demostrar. Este operador difiere de la negación en la lógica de primer orden: una negación como + X == 1 falla cuando la variable X se ha vinculado al átomo 1 , pero tiene éxito en todos los demás casos, incluso cuando X no está vinculado. Esto hace que el razonamiento de Prolog no sea monótono: X = 1, + X == 1 siempre falla, mientras que + X == 1, X = 1 puede tener éxito, vinculando X a 1, dependiendo de si X se vinculó inicialmente (tenga en cuenta que Prolog estándar ejecuta objetivos en orden de izquierda a derecha).

El estatus lógico de la negación como falla no se resolvió hasta que Keith Clark [1978] demostró que, bajo ciertas condiciones naturales, es una implementación correcta (ya veces completa) de la negación clásica con respecto a la finalización del programa. La finalización equivale aproximadamente a considerar el conjunto de todas las cláusulas del programa con el mismo predicado en el lado izquierdo, digamos

H:- Cuerpo1.
...
H:- Cuerpok.

como una definición del predicado

H iff (Body1 o... o Cuerpok)

donde "iff" significa "si y solo si". Escribir la terminación también requiere el uso explícito del predicado de igualdad y la inclusión de un conjunto de axiomas apropiados para la igualdad. Sin embargo, la implementación de la negación como falla necesita solo las mitades si de las definiciones sin los axiomas de igualdad.

Por ejemplo, la finalización del programa anterior es:

canfly(X) iff bird(X), no anormal(X).
anormal(X) iff wounded(X).
pájaro(X) iff X = John o X = mary.
X = X.
No John = Mary.
no Mary = John.

La noción de finalización está estrechamente relacionada con la semántica de circunscripción de McCarthy para el razonamiento predeterminado y con la suposición de mundo cerrado.

Como alternativa a la semántica de finalización, la negación como falla también puede interpretarse epistémicamente, como en la semántica de modelo estable de la programación de conjuntos de respuestas. En esta interpretación not(Bi) significa literalmente que Bi no se conoce o no se cree. La interpretación epistémica tiene la ventaja de que puede combinarse de manera muy simple con la negación clásica, como en la "programación lógica extendida", para formalizar frases como "no se puede demostrar lo contrario", donde "contrario" es la negación clásica y "no se puede mostrar" es la interpretación epistémica de la negación como fracaso.

Representación del conocimiento

El hecho de que a las cláusulas de Horn se les pueda dar una interpretación procedimental y, viceversa, que los procedimientos de reducción de objetivos puedan entenderse como cláusulas de Horn + razonamiento hacia atrás significa que los programas lógicos combinan representaciones declarativas y procedimentales del conocimiento. La inclusión de la negación como falla significa que la programación lógica es un tipo de lógica no monótona.

A pesar de su simplicidad en comparación con la lógica clásica, esta combinación de cláusulas de Horn y negación como fracaso ha demostrado ser sorprendentemente expresiva. Por ejemplo, proporciona una representación natural de las leyes de causa y efecto del sentido común, formalizadas tanto por el cálculo de situación como por el cálculo de eventos. También se ha demostrado que se corresponde con bastante naturalidad con el lenguaje semiformal de la legislación. En particular, Prakken y Sartor dan crédito a la representación de la Ley de Nacionalidad Británica como un programa lógico por ser "enormemente influyente para el desarrollo de representaciones computacionales de la legislación, mostrando cómo la programación lógica permite representaciones intuitivamente atractivas que se pueden implementar directamente para generar inferencias automáticas".

Variantes y extensiones

Prólogo

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 sintácticamente. Observaron que algunos probadores de teoremas, como la hiperresolución, se comportan como analizadores sintácticos ascendentes y otros, como la resolución SL (1971), se comportan como analizadores sintácticos descendentes.

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

H:- B1,..., Bn.

que se puede leer (y usar) tanto de forma declarativa como procesal. También quedó claro que tales cláusulas podrí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 esa resolución SL podría restringirse (y generalizarse) a resolución LUSH o SLD. La interpretación procesal de Kowalski y LUSH se describieron en un memorando de 1973, publicado en 1974.

Colmerauer, con Philippe Roussel, utilizó esta interpretación dual de las 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 una pregunta francesa. -sistema de contestador. El uso de Prolog como lenguaje de programación práctico recibió un gran impulso con el desarrollo de un compilador por parte de 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. Edinburgh Prolog se convirtió en el estándar de facto e influyó fuertemente en la definición del estándar ISO Prolog.

Programación lógica abductiva

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

H:- B1,..., Bn, A1,..., 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 restringidos por restricciones de integridad, que pueden tener la forma:

false:- L1,..., Ln.

donde Li son literales arbitrarios (definidos o abducibles, y atómicos o negados). Por ejemplo:

Canfly()X) :- pájaro()X), normal()X).falso :- normal()X), heridos()X).pájaro()John.).pájaro()Mary).heridos()John.).

donde el predicado normal es abducible.

La resolución de problemas se logra derivando hipótesis expresadas en términos de predicados abducibles como soluciones a los problemas a resolver. Estos problemas pueden ser observaciones que necesitan ser explicadas (como en el razonamiento abductivo clásico) o metas a resolver (como en la programación lógica normal). Por ejemplo, la hipótesis normal(mary) explica la observación canfly(mary). 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ógica

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

 resolver()verdadero). resolver()A,B) resolver()A),resolver()B). resolver()A): cláusula()A,B),resolver()B).

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

La programación metalógica permite combinar representaciones a nivel de objeto y metanivel, como en el lenguaje natural. También se puede utilizar 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 lógica de restricciones

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

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

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

H si C1 y Cn y B1 y Bn.

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

Desde el punto de vista del procedimiento, los subobjetivos cuyos predicados están definidos por el programa se resuelven mediante la reducción de objetivos, como en la programación lógica ordinaria, pero las restricciones se verifican para determinar si son satisfactorias mediante un solucionador de restricciones específico del dominio, que implementa la semántica de los predicados de restricción. Un problema inicial se resuelve reduciéndolo a una conjunción de restricciones satisfacible.

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

enseña()John., hardware, T) :- 1990  T, T . 1999.enseña()John., software, T) :- 1999  T, T . 2005.enseña()John., lógica, T) :- 2005  T, T  2012.rango()John., instructor, T) :- 1990  T, T . 2010.rango()John., Profesor, T) :- 2010  T, T . 2014.

Aquí y < son predicados de restricción, con su semántica prevista 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 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 como lenguaje de programación de sistemas del Proyecto Japonés de Quinta Generación (FGCS).

Un programa lógico concurrente es un conjunto de cláusulas Horn protegidas de la forma:

H:- G1,..., Gn Silencio1,..., Bn.

La conjunción G1,... Gn se llama guarda de la cláusula, y | es el operador de compromiso. Declarativamente, las cláusulas de Horn protegidas se leen como implicaciones lógicas ordinarias:

H si G1 y Gn y B1 y Bn.

Sin embargo, procedimentalmente, cuando hay varias cláusulas cuyos encabezados H coinciden con un objetivo dado, entonces todas las cláusulas se ejecutan en paralelo, verificando si sus guardias G1,... Gn espera. Si las protecciones de más de una cláusula se mantienen, entonces se realiza una elección comprometida con una de las cláusulas y la ejecución continúa con los subobjetivos B1,..., Bn de la cláusula elegida. 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 predicado shuffle(Left, Right, Merge) , que se puede usar para mezclar dos listas Left y Derecha, combinándolas en una sola lista Combinar que conserva el orden de las dos listas Izquierda y Derecha:

shuffle([], [], []).shuffle()Izquierda, Bien., Merge) :- Izquierda = [Primera Silencio Descanso] Silencio Merge = [Primera Silencio ShortMerge] shuffle()Descanso, Bien., ShortMerge).shuffle()Izquierda, Bien., Merge) :- Bien. = [Primera Silencio Descanso] Silencio Merge = [Primera Silencio ShortMerge] shuffle()Izquierda, Descanso, ShortMerge).

Aquí, [] representa la lista vacía, y [Head | Tail] representa una lista con el primer elemento Head seguido de la lista Tail, como en Prolog. (Observe que la primera aparición de | en la segunda y tercera cláusulas es el constructor de listas, mientras que la segunda aparición de | es el operador de compromiso). El programa se puede utilizar, por ejemplo, para barajar las listas [as, queen, king] y [1, 4, 2] invocando la cláusula de objetivo:

shuffle[ace, queen, rey] [1, 4, 2] Merge).

El programa generará de forma no determinista una única solución, por ejemplo Merge = [as, queen, 1, king, 4, 2].

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 (consulte Indeterminación en el cálculo concurrente). Carl Hewitt ha argumentado que la programación lógica concurrente no se basa en la lógica en el 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ómputo final es una consecuencia lógica del programa, y cualquier resultado parcial de un cómputo parcial es una consecuencia lógica del programa y el objetivo residual (red de procesos). Así, la indeterminación de los cálculos implica que no se pueden deducir todas las consecuencias lógicas del programa.

Programación lógica de restricciones concurrentes

La programación lógica de restricciones concurrentes combina la programación lógica concurrente y la programación lógica de restricciones, usando restricciones para controlar la concurrencia. Una cláusula puede contener una protección, que es un conjunto de restricciones que pueden bloquear la aplicabilidad de la cláusula. Cuando se satisfacen las protecciones de varias cláusulas, la programación lógica de restricciones concurrentes toma una decisión comprometida de usar solo una.

Programación lógica inductiva

La programación lógica inductiva se ocupa de generalizar ejemplos positivos y negativos en el contexto del conocimiento previo: aprendizaje automático de programas lógicos. El trabajo reciente en esta área, que combina la programación lógica, el aprendizaje y la 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 superior

Varios investigadores han ampliado la programación lógica con funciones de programación de orden superior derivadas de la lógica de orden superior, como las variables de predicado. Dichos lenguajes incluyen las extensiones de Prolog HiLog y λProlog.

Programación lógica lineal

Basar la programación lógica en la lógica lineal ha dado como resultado el diseño de lenguajes de programación lógica 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 mediante el cambio de argumentos a predicados. En la programación de lógica lineal, se puede utilizar la lógica lineal ambiental para admitir el cambio de estado. Algunos de los primeros diseños de lenguajes de programación lógicos basados en lógica lineal incluyen LO, Lolli, ACL y Forum. Forum proporciona una interpretación dirigida a objetivos de toda la lógica lineal.

Programación lógica orientada a objetos

F-logic amplía la programación lógica con objetos y la sintaxis de marcos.

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

Programación de lógica de transacciones

La lógica de transacciones es una extensión de la programación lógica con una teoría lógica de actualizaciones que modifican el estado. Tiene tanto una semántica de teoría de modelos como una de procedimiento. Una implementación de un subconjunto de la lógica de transacción está disponible en el sistema Flora-2. Otros prototipos también están disponibles.

Contenido relacionado

Falacias de definición

Ethernet

Modelo de objeto de documento

Más resultados...
Tamaño del texto: