Automágica: durante 2017 estoy trabajando bastante en Automágica, mi software para editar libros: Más información - Posts relacionados

Entorno de desarrollo SWI-Prolog

Uso SWI-Prolog, una de las implementaciones más potentes y populares del lenguaje. Para Windows, está disponible un entorno de desarrollo compuesto básicamente por:

    <li>Un panel dónde escribir código con resaltado de sintáxis.</li>
    
    <li>Botones para hacer cosas como consultar el archivo que estamos editando (esto es compilarlo y cargarlo en memoria para poder hacer consultas sobre él).</li>
    
    <li>Un panel dónde realizar consultas.</li>
    

    En los sistemas operativos basados en Linux (como Ubuntu) no existe un entorno similar. Los programadores full-time Prolog deben tener su forma de solucionarlo. Yo encontré la mía. Puede no ser la mejor, pero es más cómoda que tipear por un lado, tener el intérprete abierto por otro e ir consultando luego de cada modificación.

    De hecho, la misma implementación trae algunas primitivas útiles que se pueden usar desde el lenguaje. Por ejemplo:

    ?- consult('cats.pdb').
    
    % cats.pdb compiled 0.01 sec, 1,664 bytes
    
    true.

    compilará el archivo cats.pdb y los hechos y reglas definidos en él estarán disponibles para nuestras consultas. Si modificamos el archivo fuente, luego debemos hacer:

    ?- reconsult('cats.pdb').
    
    % cats.pdb compiled 0.00 sec, 0 bytes
    
    true.

    para que las modificaciones tengan efecto. Encontré otro predicamo muy útil:

    ?- edit('cats.pdb').
    
    % Waiting for editor ...
    
    % Running make to reload modified files
    
    % /home/juanjo/prolog/cats.pdb compiled 0.00 sec, 124 bytes
    
    % Scanning references for 1 possibly undefined predicates
    
    true.

    Abrirá el editor por defecto configurado en la computadora, nos permitirá editar el archivo y cuando lo guardemos retorna true al intérprete. Ahora lo que antes hacíamos a mano, podemos hacerlo desde el intérprete. Un avance, pero se pone mejor: podemos usar estos predicados Prolog para escribir una regla que haga todo por nosotros. Yo uso:

    myedit(File) :-
    
    edit(File), reconsult(File).
    
    myedit(File) :-
    
    edit(file(File)), reconsult(File).

    ¿Cómo funciona? Primero notemos que son dos reglas. La primera recibe un nombre de archivo e intenta editarlo, si el archivo existe se abre el editor, editamos, cuando lo guardamos edit(File) evalúa true y se pasa al siguiente hecho que reconsulta el archivo y listo.

    Si el archivo no existe, la primer regla no termina y se pasa a la segunda. file(File) se encarga de crearlo y edit podrá editarlo, trabajamos y todo termina como en el caso anterior.

    Podemos escribir este código en el archivo .plrc de nuestra home para que sea cargado al iniciar el intérprete. Finalmente si utilizamos la extensión .pdb, vim se encarga de cargar el resaltado correspondiente a la sintácis de Prolog.


    Prolog, un lenguaje realmente diferente

    Hace unos años escuché una charla de Pupeno titulada "Lips, un lenguaje diferente". Fue una charla muy interesante y realmente logró sorprender a muchos de la audiencia con distintas características de Lisp.

    Sin embargo, creo que Lisp no es tan diferente a otros lenguajes. Ok, se basa en un paradigma (el funcional) distinto al que se basa la mayoría (lideran los rankings el paradigma procedural y el paradigma orientado a objetos). Pero aún así, no está tan lejos. De hecho, muchos lenguajes de programación tienden a Lisp.

    Prolog es el lenguaje más conocido, y otros prácticamente no se mencionan, del paradigma lógico. No es un paradigma imperativo (como los anteriormente mencionados) en el cual debemos decirle a la computadora cómo resolver un problema (poné en esta variable este valor multiplicado por dos, iterá hasta que n sea igual a 10, etc...) sino que es un paradigma declarativo: simplemente se plantean afirmaciones sobre los objetos y sus relaciones.

    Un programa Prolog está compuesto de dos partes: una base de conocimiento + consultas contra esta. Ambas partes se escriben utilizando la misma sintaxis. Una vez que se tiene escrita la base de conocimientos, esta es compilada o interpretada y ya está lista para qué se realicen consultas contra ella.

    Los siguientes son 3 ejemplos básicos de programas Prolog.

    Base de conocimiento familiar

    Vamos a utilizar Prolog para armar una base de conocimiento con relaciones familiares. Empezamos con hechos; se expresan las relaciones padre y madre:

    padre(raul, juanjo).
    
    padre(raul, marisu).
    
    madre(susana, juanjo).
    
    madre(susana, marisu).
    
    madre(nieve, raul).

    Y una regla, que se lee: X es abuela de Y si X es madre de Z y Z es madre de Y ó X es padre de Y.

    abuela(X, Y) :- madre(X, Z), madre(Z, Y).
    
    abuela(X, Y) :- madre(X, Z), padre(Z, Y).

    Con esta base definida, podemos compilarla y hacerle consultas. ¿De quiénes es padre raul?

    ?- padre(raul, X).
    
    X = juanjo ;
    
    X = marisu.

    ¿Quién es abuela de quién?

    ?- abuela(X,Y).
    
    X = nieve,
    
    Y = juanjo ;
    
    X = nieve,
    
    Y = marisu.

    nota: por lo general, la interfaz de Prolog nos da la primer respuesta que encuentra y con ; le pedimos la siguiente.

    Factorial

    Definir un predicado que calcule el factorial de un número es bastante directo en Prolog. Si tenés que explicar la función factorial a alguien le decís: el factorial de 0 es 1. El factorial de N es N por el factorial de N - 1. Escribimos eso en Prolog:

    factorial(0, 1) :- !.
    
    factorial(N, F) :- N1 is N - 1, factorial(N1, F1), F is N*F1.

    Con este programa compilado, podemos hacer las siguientes consultas:

    ?- factorial(0, N).
    
    N = 1.
    
    ?- factorial(6, N).
    
    N = 720.
    
    ?- factorial(6, 555).
    
    false.

    Podemos pedir el factorial de un número e indicar la variable dónde obtener la respuesta o consultar con un predicado sin variables (ground) y obtener como respuesta el valor de verdad de la misma.

    Concatenar listas

    Un tipo de dato poderoso que incorpora Prolog son las listas. Podemos definir un predicado que concatene listas. Lo vamos a llamar concatenar y tendrá 3 argumentos: las dos listas a concatenar y el resultado de la operación. Luego podremos usar el predicado de esta forma:

    ?- concatenar([1,2], [4,5,6], L).
    
    L = [1, 2, 4, 5, 6].
    
    
    
    ?- concatenar(X, Y, [4,5,6]).
    
    X = [],
    
    Y = [4, 5, 6] ;
    
    X = [4],
    
    Y = [5, 6] ;
    
    X = [4, 5],
    
    Y = [6] ;
    
    X = [4, 5, 6],
    
    Y = [] ;
    
    false.

    Definir este predicado en Prolog es muy sencillo:

    concatenar([],L,L).
    
    concatenar([X|L1],L2,[X|L3]):-concatenar(L1,L2,L3).

    Tiene dos partes y se lee así:

    Concatenar la lista vacía con L, da como resultado L.

    Concatenar una lista cuya cabeza es X y cola L1 con L2, da como resultado la lista de cabeza X y cola L3 SI el resultado de concatenar L1 con L2 es L3.

    Fin del tour

    Este fue un tour acelerado por Prolog, tuvo como objetivo mostrárselo a quienes no lo conocen, dejarles el gusto en la boca y ganas de mas. ¿Lo logré? ¿No conocías Prolog? ¿Qué pensás ahora?

    Tutoriales y otros enlaces

    Notas


    If you don't... you SHOULD: 3 Lecturas Recomendadas

    1) Nanni Search: aprenda prolog programando un juego: http://www.amzi.com/AdventureInProlog/a1start.htm.

    2) Beating de Avegarages: la historia de dos nerds que triunfan en los negocios en internet programando en Lisp, un lenguaje de programación desconocido en la industria pero estrella los laboratorios de IA: http://www.paulgraham.com/avg.html.

    3) SQL for web nerds: aprenda SQL de la mano del delirante Philip Greenspun del MIT: http://philip.greenspun.com/sql/.


    El Capitán Julio César

    Estos días me estuvo visitando mi amigo Joel Lorenzatti, estudia filosofía en la Universidad Nacional de Rosario y vino a exponer un trabajo en unas jornadas que ser realizaron aca en Santa Fe.

    Le interesa la lógica, así que le estuve mostrando el lenguaje de programación Prolog, y escarbando entre algunos códigos que escribí, encontré uno muy lindo llamado El Capitán Julio César y es un ejercicio del tipo de encontrar múltiples caminos dadas algunas condiciones.

    Dejo el código fuente para que quien quiera lo pruebe.