Los términos básicos son las constantes y las variables. Una constante representa a un objeto o individuo determinado, y una variable representa a uno genérico. Sintácticamente, ambos son cadenas formadas con letras (mayúsculas o minúsculas), el símbolo de subrayado, «_» , y dígitos, y se diferencian porque las variables deben empezar con una letra mayúscula o con el símbolo «_» , mientras que las constantes pueden ser:
Con este convenio sintáctico (diferente al que hemos seguido en la lógica de predicados, Capítulo 4), «x» es una constante; para que fuese una variable debería escribirse «X» . De igual modo, «pepe» es una constante, pero «Pepe» es una variable.
Las constantes y las variables son términos simples (o átomos). Hay dos tipos de términos estructurados (o estructuras): las funciones y las listas.
Las funciones constan de un nombre de función y de uno o varios argumentos. El número de argumentos es el grado de la función. El nombre de función es una cadena alfanumérica con el mismo convenio que las constantes (empezar por letra minúscula). A continuación se escriben los argumentos, separados por comas y entre paréntesis. Por ejemplo:
padre_de(pepe)
|
puede representar al individuo que es el padre de Pepe, pero
padre_de(Pepe)
|
no representaría a un individuo concreto (porque «Pepe» es una variable, ya que empieza por mayúscula); para un valor determinado de «Pepe» (un «ejemplar» ) la función tendría un valor también determinado (supuesto que es una «función total» , es decir, con esta interpretación, todo individuo tiene un padre).
Hay que advertir que, a diferencia de los lenguajes funcionales, que se basan en la evaluación de funciones, en los lenguajes lógicos las funciones, en principio, no se evalúan1; simplemente pueden usarse para representar objetos, y su uso más frecuente es para la representación de objetos estructurados. La estructura más simple es la que corresponde a un objeto del que se deban destacar ciertos atributos. Por ejemplo, si el objeto «ordenador» tiene que ir acompañado de informaciones como su marca, modelo, sistema operativo y año de fabricación, podríamos representarlo mediante la función:
ordenador(Marca, Modelo, Sistema_Operativo, Año)
|
Un ordenador concreto podría ser:
ordenador(superclon, ’i686-600’, ’Linux’, 2000)
|
Obsérvese que aún no hemos entrado en las características esenciales y diferenciadoras de Prolog. Lo que en este último ejemplo hemos hecho no es más que expresar una estructura de representación, y es totalmente análogo a declarar, por ejemplo, en Pascal:
type ordenador = record
Marca: string; Modelo: string; Sistema_Operativo: string; Año: integer end; |
Si escribimos la función de esta otra manera:
ordenador(
Marca, Modelo, Sistema_Operativo, Año) |
la analogía es aún más patente.
En los anteriores ejemplos, los argumentos de las funciones son átomos (constantes o variables). Pero lo interesante es que esos argumentos son, en general, términos, con lo que se pueden representar estructuras complejas (del mismo modo que se hace en los lenguajes tradicionales, declarando tipos estructurados cuyos componentes son a su vez estructurados). Por ejemplo, podría interesarnos destacar las partes del modelo estructural del ordenador, y definir la función:
ordenador_estr
(procesador (ucp(Micro, Reloj, Contr_interrupc), mp(Capacidad, Ciclo)), perifericos(Monitor, Teclado, Impr, Disco), software(SO, BD, Paquetes)) |
Las listas son otro recurso sintáctico para representar objetos estructurados. Una lista es una secuencia ordenada de términos (que pueden, a su vez, ser listas). Por ejemplo, [A1, A2, A3] es una lista de variables, y [a1, a2, a3] una lista de constantes. Obsérvese que una función se define siempre con un grado asociado, pero una lista puede tener cualquier número de elementos. La lista puede ser vacía: []. Si no es vacía, se puede considerar formada por una cabeza (primer o primeros elementos de la lista) y una cola (lista formada por el resto de los elementos) unidas por la función de construcción de listas, «cons» . Así, la lista del caso anterior puede escribirse de las siguientes maneras:
[a1, a2, a3] = cons(a1, [a2, a3]) = cons(a1, cons(a2,[a3]))
= cons(a1, cons(a2, cons(a3, []))) |
o, en forma gráfica, según el árbol de la Figura A.2
En lugar de «cons» (denominación típica no de Prolog, sino de LISP) se suele utilizar (como se ha hecho en la figura) un punto:
[a1,a2,a3] = .(a1,.(a2,.(a3,[])))
|
Aún más utilizado es el símbolo «|» con notación infija, es decir, una lista, en general, es o bien [] (lista vacía) o bien [C|L], donde C es la cabeza (un elemento o una lista de elementos) y L la cola (otra lista):
[a1,a2,a3] = [a1|L], con L = [a2,a3], o bien:
[a1,a2,a3] = [a1,a2|L], con L = [a3], o bien:
[a1,a2,a3] = [a1,a2,a3|L], con L = []
Para terminar con la representación de objetos o individuos mediante términos haremos dos observaciones: