Primeros pasos con Prolog Language
Programación de bases de datos
Prolog clasifica todo en:
- Átomos: cualquier secuencia de caracteres que no comience con un alfabeto en mayúsculas. Por ejemplo:
a
,b
,bien
- Números - No hay una sintaxis especial para números, no se requiere declaración. Por ejemplo,
1
,22
,35.8
- Variables - Una cadena que comienza con un carácter en mayúscula o guión bajo (
_
). Por ejemplo,X
,Y
,Abc
,AA
- Términos complejos - Están formados por un funtor y una secuencia de argumentos. El nombre de un término complejo es siempre un átomo, mientras que los argumentos pueden ser átomos o variables. Por ejemplo,
padre(john,doe)
,pariente(a)
,madre(X,Y)
.
Una base de datos lógica contiene un conjunto de hechos y reglas.
Un término complejo con solo átomos como argumentos se llama hecho, mientras que un término complejo con variables como argumentos se llama regla.
Ejemplo de hechos en Prolog:
father_child(fred, susan).
mother_child(hillary, joe).
Ejemplo de una regla en Prolog:
child_of(X,Y):-
father_child(Y,X)
;
mother_child(Y,X).
Tenga en cuenta que ;
aquí es como el operador o
en otros idiomas.
Prolog es un lenguaje declarativo y puede leer esta base de datos de la siguiente manera:
fred es el padre de susan
Hillary es la madre de Joe.
Para todo
X
eY
,X
es hijo deY
siY
es padre deX
oY
es madre deX
.
De hecho, un conjunto finito de hechos y/o reglas constituye un programa lógico.
El uso de dicho programa se demuestra haciendo consultas. Las consultas le permiten recuperar información de un programa lógico.
Para cargar la base de datos en el intérprete (suponiendo que haya guardado la base de datos en el directorio en el que está ejecutando el intérprete), simplemente ingrese:
?- [nameofdatabase].
reemplazando nameofdatabase
con el nombre real del archivo (tenga en cuenta que aquí excluimos la extensión .pl
del nombre de archivo).
Ejemplo de consultas en el intérprete para el programa anterior y los resultados:
?- child_of(susan,fred).
true
?- child_of(joe,hillary).
true
?- child_of(fred,susan).
false
?- child_of(susan,hillary).
false
?- child_of(susan,X).
X = fred
?- child_of(X,Y).
X = susan,
Y = fred ;
X = joe,
Y = hillary.
Las consultas anteriores y sus respuestas se pueden leer de la siguiente manera:
¿susan es hija de fred? - verdadero
es joe hijo de hillary? - verdadero
es fred un hijo de susan? - falso
¿susan es hija de hillary? - falso
¿De quién es hija Susan? - fred
Así es como programamos la lógica en Prolog. Un programa lógico es más formalmente: un conjunto de axiomas o reglas que definen relaciones (también conocidas como predicados) entre objetos. Una forma alternativa de interpretar la base de datos anterior de una manera lógica más formal es:
La relación
padre_hijo
se da entre fred y susan
La relación
madre_hijo
se da entre hillary y joe
Para todo
X
eY
, la relaciónhijo_de
se cumple entreX
eY
si la relaciónpadre_hijo
se cumple entreY
yX
, o la relaciónmadre_hijo
se cumple entreY
yX
.
Hola Mundo
Hello, World en el intérprete interactivo
Para imprimir “¡Hola, mundo!” en el intérprete de Prolog (aquí estamos usando swipl
, el shell para SWI Prolog):
$ swipl
<...banner...>
?- write('Hello, World!'), nl.
?-
es el indicador del sistema: indica que el sistema está listo para que el usuario ingrese una secuencia de objetivos (es decir, una consulta) que debe terminar con un .
(punto).
Aquí la consulta write('Hello World!'), nl
tiene dos objetivos:
write('Hello World!')
:'Hello World!'
tiene que mostrarse y (,
)- debe seguir una nueva línea (
nl
).
write/1
(el /1
se usa para indicar que el predicado toma un argumento) y nl/0
son predicados integrados (la definición la proporciona de antemano el sistema Prolog). Los predicados incorporados brindan funciones que no se pueden obtener mediante la definición pura de Prolog o para evitar que el programador tenga que definirlos.
La salida:
¡Hola, mundo!
si
termina con sí
, lo que significa que la consulta se ha realizado correctamente. En algunos sistemas se imprime verdadero
en lugar de sí
.
Hola, mundo de un archivo
Abra un nuevo archivo llamado hello_world.pl
e inserte el siguiente texto:
:- initialization hello_world, halt.
hello_world :-
write('Hello, World!'), nl.
La directiva de inicialización
especifica que se debe llamar al objetivo hello_world, halt
cuando se carga el archivo. halt
sale del programa.
Este archivo puede ser ejecutado por su ejecutable de Prolog. Las banderas exactas dependen del sistema Prolog. Si está utilizando SWI Prolog:
$ swipl -q -l hello_world.pl
Esto producirá la salida ¡Hola, Mundo!
. El indicador -q
suprime el banner que generalmente se muestra cuando llama a ejecutar swipl
. El -l
especifica un archivo para cargar.
Instalación o configuración
SWI-Prólogo
Windows y Mac:
- Descargue SWI-Prolog en el sitio web [oficial] (http://www.swi-prolog.org/download/stable)
- Simplemente instale siguiendo las instrucciones del instalador.
Linux (PPA):
-
Agregue el PPA
ppa:swi-prolog/stable
a las fuentes de software de su sistema (los desarrolladores pueden elegirppa:swi-prolog/devel
):-
Open a terminal (Ctrl+Alt+T) and type:
sudo add-apt-repository ppa:swi-prolog/stable
-
Afterwards, update the package information:
sudo apt-get update
-
-
Ahora instale SWI-Prolog a través del administrador de paquetes:
sudo apt-get install swi-prolog
-
Ahora puede iniciar SWI-Prolog a través de la línea de comandos con el comando
swipl
agregar/3
append([], Bs, Bs).
append([A|As], Bs, [A|Cs]) :-
append(As, Bs, Cs).
append/3
es una de las relaciones de Prolog más conocidas. Define una relación entre tres argumentos y es verdadera si el tercer argumento es una lista que denota la concatenación de las listas que se especifican en el primer y segundo argumento.
En particular, y como es típico del buen código de Prolog, append/3
se puede usar en varias direcciones: se puede usar para:
-
añadir dos listas instanciadas total o parcialmente:
?- A = [1, 2, 3], B=[4, 5, 6], append(A, B, Y) Output: A = [1, 2, 3], B = [4, 5, 6], Y = [1, 2, 3, 4, 5, 6].
-
comprobar si la relación es verdadera para tres listas completamente instanciadas:
?- A = [1, 2, 3], B = [4, 5], C = [1, 2, 3, 4, 5, 6], append(A, B, C) Output: false
-
generar todas las formas posibles de agregar dos listas a una lista dada:
?- append(A, B, [1, 2, 3, 4]). Output: A = [], B = [1, 2, 3, 4] ; A = [1], B = [2, 3, 4] ; A = [1, 2], B = [3, 4] ; A = [1, 2, 3], B = [4] ; A = [1, 2, 3, 4], B = [] ; false.
Restricciones CLP(FD)
Todas las implementaciones serias de Prolog proporcionan restricciones CLP(FD). Nos permiten razonar sobre enteros de forma pura.
?- X #= 1 + 2.
X = 3.
?- 5 #= Y + 2.
Y = 3.