miércoles, 2 de mayo de 2012

PROLOG en Java

PROLOG proveniente del francés PROgrammation en LOGique, es un lenguaje de programación lógico e interpretado, bastante conocido en el medio de investigación en Inteligencia Artificial.A diferencia de los lenguajes tradicionales su uso se basa en la definición de reglas y predicados que nos permitirán llegar a una determinada conclusión. Para más información sobre este lenguaje podéis bajaros este libro en el que a parte de las bases sobre el lenguaje encontrareis ejemplos, proyectos, etc. 

Antes de comenzar para poder trabajar en PROLOG desde Java vamos a utilizar la librería GNU Prolog for Java aunque también os recomiendo descargaros SWI-Prolog para probar los scripts que utilicéis y que también se puede linkar desde Java.

En primer lugar vamos a definir un sencillo script en PROLOG que determina si alguien es descendiente de otro alguien para lo que definimos los siguientes predicados:

% definiciones de padres
padre(tito, pepe).
padre(pepe, paco).
padre(pepe, ana).
% definiciones de madres
madre(maria, pepe).
madre(pepa, paco).
madre(pepa, lope).
madre(pepa, kique).

%Y es padre de alguien cuyo hijo es X
%o Y es madre de alguien cuyo hijo es X
es_descendiente(X, Y) :- padre(Y, _) , padre(_, X);
                         madre(Y, _) , madre(_, X).


Para probar este código en SWI-Prolog en primer lugar creamos el fichero desde cualquier editor de textos o desde el entorno escribiendo (acordaros de poner siempre .(punto) al final de cada linea/frase/predicado en Prolog):

?- edit(file('C:/tudir/tuprolog.pl')).

Lo completamos con el script de antes y para cargarlo y poder trabajar con las reglas que se definen tendremos que escribir:

? consult('C:/tudir/tuprolog.pl').

Y por ultimo para comprobar que funciona correctamente podemos probar con las siguientes consultas:

?- es_descendiente(paco, tito). %Paco es descendiente de Tito.
    true.
?- es_descendiente(tito, kique).
    false.
?- es_descendiente(X, tito). %Quien es descendiente de tito
X = pepe ;
X = paco ;
X = ana .

Ahora la idea es poder hacer uso de las características de PROLOG desde Java por lo que deberemos al igual que se ha hecho en SWI-Prolog en primer lugar cargar el fichero y después ejecutar las consultas que queramos verificar. Para ello en primer lugar necesitamos referenciar la librería e importar las siguientes clases:

import gnu.prolog.term.AtomTerm;
import gnu.prolog.term.CompoundTerm;
import gnu.prolog.term.Term;
import gnu.prolog.term.VariableTerm;
import gnu.prolog.vm.Environment;
import gnu.prolog.vm.Interpreter;
import gnu.prolog.vm.PrologCode;
import gnu.prolog.vm.PrologException;

Lo siguiente es inicilizar el interprete para lo que deberemos escribir el siguiente código:

    /**
     * Entorno que usara el interprete.
     */
    Environment env;
    /**
     * Interprete de PROLOG.
     */
    Interpreter interpreter;

    env = new Environment();
    // Cargamos el fichero en el entorno.
    env.ensureLoaded(AtomTerm.get("C:\\tudir\\tuprolog.pl"));
    // Obtenemos el interprete
    interpreter = env.createInterpreter();
    // Y lo inicializamos
    env.runInitialization(interpreter);

Y por ultimo realizar las consultas  :

    // Argumentos para la consulta en este caso constantes.
    Term[] args = { AtomTerm.get("paco"), AtomTerm.get("tito") };
    // Construimos la consulta Paco es desdenciente de Tito?
    CompoundTerm goalTerm =
        new CompoundTerm(AtomTerm.get("es_descendiente"), args);

       
    try {
        if (interpreter.runOnce(goalTerm) == 
            PrologCode.SUCCESS)
        {               
            System.out.println("Pepe es descendiente de Tito.");
        } else {
            System.out.println("Pepe NO es descendiente de Tito.");
        }
    } catch (PrologException e) {
        System.out.println("Error." + e.getMessage());           
   
    // Fin. 
    env.closeStreams();       



Para más información podéis consultar la API de la librería o el ejemplo que viene con ella donde se realiza lo mismo pero con variables y mostrando las respuestas obtenidas.

No hay comentarios:

Publicar un comentario