Categorías destacadas
programacion php    
Artículo
13
¡votar!

 Tutorial básico de programación en Prolog


Mi primer programa en Prolog

Los programas se escriben en ficheros de texto, generalmente con extension .pl y pueden contener comentarios y código. Para ello puede utilizar cualquier editor de texto. Le recomendamos que intente escribir el siguiente programa desde el principio para familiarizarse con la sintáxis.

 % Este es mi primer programa en Prolog 
 % 
 % Se trata de un arbol genealogico muy simple 
 % 
 % 
 % Primero defino los parentescos basicos 
 % de la familia. 
 % padre(A,B) significa que B es el padre de A... 
 
 padre(juan,alberto). 
 padre(luis,alberto). 
 padre(alberto,leoncio). 
 padre(geronimo,leoncio). 
 padre(luisa,geronimo). 
 
 % Ahora defino las condiciones para que 
 %  dos individuos sean hermanos 
 % hermano(A,B) significa que A es hermano de B... 
 
 hermano(A,B) :- 
   padre(A,P), 
   padre(B,P), 
   A \== B. 
 
 % Ahora defino el parentesco abuelo-nieto. 
 % nieto(A,B) significa que A es nieto de B... 
  
 nieto(A,B) :- 
   padre(A,P), 
   padre(P,B). 
 

. Cargando el código

Para compilar y cargar el código existe el predicado consult/1. Recuerde que puede ser necesario indicar la ruta completa del fichero fuente. En este ejemplo hemos usado el top-level shell de SWI-Prolog:

 Welcome to SWI-Prolog (Version 2.7.14) 
  Copyright (c) 1993-1996 University of Amsterdam.  All rights
  reserved. 
 
  For help, use ?- help(Topic). or ?- apropos(Word). 
 
 1 ?- consult('arbolgenealogico.pl'). 
 arbolgenealogico.pl compiled, 0.00 sec, 1,108 bytes. 
 
 Yes 
 2 ?- 
 

. Predicados reversibles

Una vez que hemos compilado y cargado nuestro programa vamos a estudiar sus características. Una de ellas es el backtracking, o la posibilidad de obtener varias soluciones, como ya hemos visto.

 2 ?- hermano(A,B). 
 
 A = juan 
 B = luis ; 
 
 A = luis 
 B = juan ; 
 
 A = alberto 
 B = geronimo ; 
 
 A = geronimo 
 B = alberto ; 
 
 No 
 3 ?- 
 

Ahora vamos a reparar en otra curiosa propiedad que no existe en otros lenguajes: la reversibilidad. Esto es la habilidad de los argumentos de los predicados para actuar indistintamente como argumentos de entrada y/o salida.Por ejemplo:

 3 ?- nieto(luis,X). 
 
 X = leoncio 
 
 No 
 4 ?- 
 

Aquí, el primer argumento es de entrada mientras que el segundo es de salida. El predicado nos dice de quién es nieto Luis. Pero ahora vamos a intercambiar los papeles:

 4 ?- nieto(X,leoncio). 
 
 X = juan ; 
 
 X = luis ; 
 
 X = luisa ; 
 
 No  
 5 ?-  
 

Obsérve cómo el mismo predicado que nos dice el abuelo de un nieto sirve para conocer los nietos de un abuelo. Estos predicados se dicen reversibles, o que sus argumentos son reversibles.

. Predicados no reversibles

No todos los predicados son reversibles. Por ejemplo, los de comparación aritmética. El predicado >/2 sirve para saber si un número es mayor que otro, pero no sirve para saber todos los números mayores que uno dado (puesto que son infinitos).

Otros predicados pueden perder la reversibilidad por deseo expreso de su programador, o solamente ser reversibles para ciertos argumentos pero no otros. Así podemos hablar de las posibles formas de invocar un predicado. Esto es lo que se denomina modos de uso.

. Modos de uso

Los modos de uso indican que combinacion de argumentos deben o no estar instanciados para que un objetivo tenga sentido. Se dice que un argumento está instanciado cuando no es una variable libre.

A efectos de documentación, los modos de uso se describen con un término anotado en sus argumentos con un símbolo. Los argumentos pueden ser:

  • De entrada y/o salida indistintamente. Estos argumentos se denotan con un símbolo de interrogación (?).
  • De solamente entrada. Estos se denotan con un símbolo de suma (+).
  • De solamente salida. Estos se denotan con un símbolo de resta (-).

El modo de uso que instancia todos los argumentos siempre es válido.

Por ejemplo, para el predicado hermano/2 su único modo de uso es hermano(?A,?B). Supongamos un predicado cuyos modos de uso son:

  • p(+A,+B,-C).
  • p(+A,-B,+C).

Entonces son objetivos válidos:

  • p(1,2,X).
  • p(1,X,3).
  • p(1,2,3).

Pero no son válidos:

  • p(X,Y,3).
  • p(X,2,3).
  • p(X,Y,Z).

Los modos de uso se suelen indicar a modo documentativo, pero actualmente los entornos de desarrollo más avanzados los pueden utilizar para detectar errores en tiempo de compilación.

. Culturilla

  • Un compilador que no utiliza los modos de uso no detecta objetivos inválidos. En ese caso, el programa se ejecuta sin más. Cuando le llega el turno al objetivo mal formado pueden ocurrir dos cosas: que el objetivo falle sin más, o que se lance una excepción. Cualquiera de ellas suele ir acompañada de un horrendo mensaje por pantalla.
  • La forma de describir los modos de uso "formalmente" varia de un entorno de desarrollo a otro. Si no es posible especificarlos "formalmente", entonces conviene escribir un comentario explicativo.
  • Si el compilador no detecta modos de uso, es responsabilidad del programador no invocar objetivos mal formados, tarea que no resulta nada trivial puesto que hay que saber que variables van a estar ligadas cuando el programa se ejecute.
  • Otra buena práctica es escribir predicados que siempre sean reversibles.
Publicado por:
manuel delgado
Recomendar
a un amigo
Compartir
en redes
 
Comentarios
 
BBDD
Entornos de desarrollo
Entretenimiento
Herramientas
Internet
Lenguajes de script
Lenguajes imperativos
Lenguajes orientados a objeto
Otros lenguajes
Plataformas
Teoría
Varios
Copyright © 1998-2011 Programación en Castellano. Todos los derechos reservados
Datos legales | Politica de privacidad | Contacte con nosotros | Publicidad

Diseño web y desarrollo web. Un proyecto de los hermanos Carrero.

Red internet:
Juegos gratis | Servidores dedicados
Más internet: Password | Directorio de weblogs | Favicon