Está en la página 1de 16

4.6 Programacion Logica Con Numeros, Listas Y Arboles.

PROLOG cuenta con operadores para la unificacion y comparacion, sea con


evaluacion o sea simbolica, como los siguientes:

X is Y%unificacion con evaluacion.

X = Y %unificacion. Simbolica

X=:=Y %comparacion con evaluacion

X == Y %comparacion simbolica.

Ejemplo:

 ?- X is 3+5.
 X=8
 ?- X = 3+5.
 X = 3+5
 ?-3 +5 =:= 2+6.
 Yes
 3+5== 2+6.
 No
 3+5 == 3+5
 Yes

Enunciado 1 (Números naturales) Una posible codificación de números naturales


en Prolog se basa en la siguiente definición:
El cero es un número natural

Si X es un numero natural, entonces s(X) (siguiente de X) también es un numero


natural

Las reglas anteriores se codificarían en Prolog como:

N a t u r a l (0 ).

n a t u r a l (s (X)) : − n a t u r a l (X ) .
Compilar el programa anterior y comprobar si el dos (s(s(0))) es un número
natural mediante la llamada natural(s(s(0)) Observar las respuestas del sistema
ante la pregunta natural(X)

Enunciado 2 (suma) La suma de números naturales puede definirse con las


siguientes reglas.

0+X=0

Si X + Y = Z entonces s(X) + Y = s(Z)

En Prolog, dichas reglas pueden expresarse como:

Suma (0, X, X).

Suma (s (X), Y, s (Z)): −suma (X,Y, Z ).

Enunciado 3 (producto) El producto de números naturales se define con las reglas:

0∗X=0

Si X ∗ Y = Z entonces s(X) ∗ Y = Z + Y

Dichas reglas pueden expresarse en Prolog como:

p r o d u c t o ( 0 ,X , 0 ) . p r o d u c t o ( s (X) ,Y,R):− p r o d u c t o (X,Y, Z ) ,


suma (Z ,Y,R ) .

Comprobar que realmente multiplica naturales

Enunciado 4 (otros (Opcional)) Intentar definir otros predicados aritméticos como:

 Potencia(X,Y,Z) se cumple si Z es igual a X elevado a Y

 Menor(X,Y) se cumple si X es menor que Y

 Mcd(X,Y,Z) se cumple si Z es el máximo común divisor de X e Y etc.


Enunciado 5 (Listas) En Prolog, existe una estructura recursiva que representa
listas de elementos. La definición podría ser:

[ ] (la lista vacía) es una lista

Si L es una lista, entonces [XL] — (el resultado de añadir un elemento X al


principio de L) también es una lista.

Las reglas anteriores se codificarían en Prolog como: l i s t a ( [ ] ) . l i s t a ( [X| L ]


) : − l i s t a (L ) .

Compilar el programa anterior y preguntar si [ ] es una lista Preguntar si [c [ ] ]— es


una lista Preguntar si [b [c — [] ] ]— es una lista

Preguntar si [a [b — [c — [] ] ] ]— es una lista

En realidad, Prolog utiliza una notación simplificada para representar listas de


forma que:

• [] = []

• [c [] ] = [c]—

• [b [c— [] ] ] = [b,c]—

• [a [b — [c —[] ] ] ] = [a, b, c]—

Preguntar si [c], [b,c] y [a,b,c] son listas.


Recorridos en un árbol binario

Un recorrido en un árbol binario es Una operación que consiste en visitar todos sus
vértices o nodos, de tal manera que cada vértice se visite una sola vez.
Se distinguen tres tipos de recorrido: INORDEN, POSORDEN Y PREORDEN.
En cada recorrido se tiene en cuenta la posición de la raíz (de ahí su nombre) y
que siempre se debe ejecutar primero el hijo izquierdo y luego el derecho.

Recorrido INORDEN. Este recorrido se realiza así: primero recorre el subárbol


izquierdo, segundo visita la raíz y por último, va al subárbol derecho. En síntesis:
hijo izquierdo — raíz — hijo derecho

Recorrido PREORDEN. Este recorrido se realiza así: primero visita la raíz;


segundo recorre el subárbol izquierdo y por último va a subárbol derecho. En
síntesis:
raíz — hijo izquierdo — hijo derecho

Recorrido POSORDEN. Primero recorre el subárbol izquierdo; segundo, recorre el


subárbol derecho y por último, visita la raíz. En síntesis:
hijo izquierdo– hijo derecho — raíz
Tipos de árboles binarios

Árboles de expresión
Son árboles binarios que se utilizan para almacenar en la memoria de una
computadora expresiones lógicas, aritméticas o algebraicas. Este proceso lo
realizan los compiladores de los lenguajes de programación. Los PC y las
calculadoras comunes utilizan el recorrido INORDEN usando la notación infija para
evaluar las expresiones, al igual que los seres humanos. El recorrido PREORDEN
utiliza la notación infija o polaca.
Algunos compiladores y algunas calculadoras como por ejemplo, la Hewlet Packard
evalúan las expresiones en POSORDEN usando la notación posfija (o notación
polaca inversa) donde el operador aparece después de sus operandos; por
ejemplo, AB/ indican que A debe dividirse por B. Observe que la notación posfija
tiene ventajas sobre la notación infija debido a que la notación posfija no necesita
paréntesis ni tiene que predeterminar un orden de prioridad para sus operadores
(lógicos o aritméticos); es por tal razón que una expresión se evaluará sin
ambigüedad.

Una expresión con recorrido INORDEN pueden seguirse los siguientes pasos:

1. Trascriba la expresión con recorrido INORDEN a POSORDEN (o a


PREORDEN). Para tal fin, debe parentizar completamente la expresión y
luego, cambie el paréntesis derecho (o izquierdo) por el operador más próximo
no utilizado.

2. Forme el árbol de expresión con recorrido POSORDEN (o PREORDEN) a


partir de la expresión dada. En efecto, el árbol se forma escribiendo como raíz
el operador principal de la expresión y se escriben los operandos como
subárboles izquierdo y derecho. Observe que las hojas del árbol
corresponderán a los operandos.

3. expresión utilizando el árbol, dándole valores aritméticos o lógicos a los


operandos.

R: la representación en un árbol binario de la expresión algebraica


Árbol binario de búsqueda
Un árbol binario de búsqueda es aquel que tiene sus nodos con un orden definido,
de tal manera que los datos del subárbol izquierdo son menores y los del subárbol
derecho son mayores. Estos árboles tienen como particularidad la permisión de
que se puedan realizar búsquedas de nodos o datos determinados, utilizando el
método de búsqueda binaria de manera similar al usado en arreglos.
Para crear un árbol binario de búsqueda a partir un listado de datos, asuma que el
primer dato es la raíz del árbol; los demás se ubican en el árbol así: los menores
como hijos izquierdos y los mayores como hijos derechos.
Numericos

En PROLOG los objetos numericos pueden corresponder a tipos integer o float


de C. para realizar operaciones numericas, se tiene el predicado is, que se
comporta como una asignacion en un lenguaje imperativo. Asi, el objetivo X is
<expresion> sera verdadero cuando X unifique con el resultado numerico de
evaluar <expresion>.

EJEMPLO:

 Si Denimos:
 Masuno(X,Y): - Y is X+1.
 Xmasuno(X,Y): - Y=+1.
 Obersvaremos el siguiente
 Comportamiento:
 ?-masuno (,5).
 Yes

En este tema veremos aspectos del control en PROLOG. En primer lugar, cómo
afecta el orden de los literales y de las sentencias en el funcionamiento del
programa. Ya hemos visto cómo crear el árbol de llamadas y cómo explorarlo
siguiendo una estrategia SLD. Sin embargo, muchas veces al programar y
conociendo las características del problema, se puede asegurar que cierta parte
del árbol no dará lugar a soluciones y por tanto no necesitaría ser explorada. Para
indicar a PROLOG cuestiones de este estilo y ganar en eficiencia, disponemos del
operador corte del que hablaremos en las dos siguientes secciones. Finalmente,
dedicamos la última sección a estudiar la negación como fallo finito y su relación
con la negación lógica.
4.7 Control de búsqueda en programas logicos

El orden en que aparecen los literales dentro de una sentencia (dentro del cuerpo)
o el orden en que se introducen las sentencias en el programa son importantes en
PROLOG. El orden afecta tanto al correcto funcionamiento del programa, como al
recorrido del árbol de llamadas, determinando, entre otras cosas, el orden en que
PROLOG devuelve las soluciones a una pregunta dada. El orden de las
sentencias determina el orden en que se obtienen las soluciones ya que varía el
orden en que se recorren las ramas del árbol de búsqueda de soluciones.
Ejemplo: A continuación se presentan dos versiones del programa "miembro de
una lista". Ambas versiones tienen las mismas sentencias pero escritas en distinto
orden. A ambas versiones les hacemos la misma pregunta ?miembro (X, [1,2,3]).

ELpredicado ! (leído corte) proporciona control sobre el mecanismo de


backtracking de programación lógica: siempre tiene éxito pero tiene el efecto
lateral de podar todas las elecciones alternativas en el nodo correspondiente en el
árbol de búsqueda.

Este es un predicado meta-logico o extra-logico: predicado que afecta al


comportamiento operacional de programación lógica. Es en cierto sentido un
predicado impuro (ajeno a la lógica) pero es un predicado muy útil… casi
fundamental para el programador de programación lógica

¿Cómo opera el corte?

Cuando se resuelve un objetivo p con una cláusula de la forma:

P: - q1,…,qn !, r1,…,rm

Programación logicia intenta resolver los objetivos q1,…qn normalmente


(haciendo backtracking sobre cada uno de ellos si es necesario);

Ejemplo

El corte en ejemplos (I)

En la pagina ?? de niamos un predicado para incrementar en 1 los enteros de una


lista (dejando intactos los no enteros).

Incl..st2([ ], [ ]).

Incl..st2([X|Xx]. [Y|Ys]):- integer (X) .!. Y is X+1 incl st2(Xs.Ys)

Incl.. st2 ([X|Xs]. [X|Ys]):- incl.st2 (Xs, Ys)


4.8 Manipulación De Términos

Es uno de los más útiles entre la biblioteca standard Prolog.

El Predicado Functor/3

Este predicado permite extraer el functor y la aridad de un término cualquiera.

Al ser reversible, también permite construir nuevos términos a partir del functor y la
aridad deseada

Los Modos De Uso Son:

 functor (+Termino,-Functor, Aridad).


 functor (-Termino,+Functor,+Aridad).
Ejemplo:
Crear un nuevo término, sus argumentos siempre serán nuevas variables
libres:

Ejemplo:

Extraer Factor y Aridad.

Manipulación de argumentos con "arg"

Ahora que podemos construir términos, sería deseable poder asignarles


argumentos. Uno de los predicados que permiten esto es arg/3. Para ello se indica
el número de índice del argumento deseado, empezando a numerar por el 1 de
izquierda a derecha. El modo de uso es:
 arg(+Indice,+Termino,-Argumento).

El primer uso de este predicado es extraer un argumento concreto de un término:

?- arg(2,termino(a,b,c,d),ARG).

ARG = b ?

yes
?-

Si el término tiene variables libres como argumento, se les puede asignar valor
mediante arg/3. Pero el resultado es el mismo que una simple unificación
mediante =/2. Esto se observa en el siguiente ejemplo:

?- Termino = p(X,b), arg(1,Termino,zzz).


Termino = p(zzz,b),
X = zzz ?
yes
?- Termino = p(X,b), Termino = p(zzz,_).
Termino = p(zzz,b),
X = zzz ?

yes
?-

El predicado arg/3 solamente es útil cuando se conoce a priori el número de


argumentos del término manipulado, pero en combinación con functor/3 resulta
muy eficaz.

Manipulación de argumentos con "univ"

En ocasiones resulta mucho más útil convertir los argumentos de un término en


una lista y viceversa. Esta es la función de "univ", nombre que recibe el operador
infijo =../2. Sus modos de uso son:
 +Termino =.. -Lista
 -Termino =.. +Lista

La lista contiene siempre el functor del término en la primera posición, y los


argumentos en el resto de la lista. El siguiente ejemplo desglosa los elementos de
un término:

?- p(a,b,c(i)) =.. X.

X = [p,a,b,c(i)] ?
yes
?-

Siguiente ejemplo construye un nuevo término a partir de la lista de sus


componentes...

?- Termino =.. [functor,arg1,arg2,arg3].

Termino = functor(arg1,arg2,arg3) ?

yes
?-

Llamadas de orden superior

Lo interesante ahora es convertir un término en un objetivo Prolog a ejecutar. Esto


se consigue con el predicado call/1. Naturalmente, el término debe corresponder
con algún predicado existente, de otra forma, se genera una excepción. Por
ejemplo:

% Un predicado
mipred(X) :-
display(X),
nl.

% Llamada de orden superior


ejemplo :-
X = mipred(5),
call(X).

Naturalmente, este ejemplo carece de utilidad puesto que se puede ejecutar la


llamada a mipred/1 directamente. Pero resulta muy útil en combinación con los
predicados anteriormente descritos.
Ejemplo:

sujeto(12).
sujeto(13).
sujeto(78).

aplicar(Predicado) :-
sujeto(X),
LLamada =.. [Predicado,X],
call(LLamada),
fail.
aplicar(_).

ejemplo :-
aplicar(display).

El resultado es el siguiente:

?- ejemplo.
12
13
78

yes
?-

Los predicados de este tipo, que reciben un argumento y lo convierten a un


objetivo ejecutable (sin saber lo que se ejecuta) se denominan metapredicados.
Dicho argumento se denomina meta-argumento.
Un ejemplo de metapredicado es la propia negación por fallo, que se implementa
de esta manera:

not(Objetivo) :-
call(Objetivo),
!,
fail.

not(_).

Predicados Meta lógicos:

Permiten controlar el Algoritmo de resolución facilitando la meta programación

Meta Programación: Consiste En Construir Programas proporcionando una mayor


expresividad al lenguaje.

Chequeo De Tipo:

 Predicado:

Var(x)

Condición Para Que Se Cumpla:

X es una variable no instancia


Ejemplo:

|?- var(x)

X=_

|?- X-1, var(x)

No.

 Predicado:

nonvar(x)

Condiciones para que se cumpla:

X no es una variable o es una variable instancia

Ejemplo:

|?- novar(x)

No

|?- X-1, novar(x)

X-1

La utilización de estos predicados permite al programador chequear si es una


variable esta instancia o no para proporcionar programas más flexibles

Abuelo(X,Y):-novar(X)

hombre(x), progenitor(x,z), progenitor (z,y).

abuelo(x,y):-novar(y)

progenitor(z,y), progenitor(x,z) hombre(x)

abuelo(x,y):- X es abuelo Y
Bibliografias

 https://prezi.com/wzpdx9r407pp/411-manipulacion-de-terminos-412-
predicados-metalogicos/

 https://programacion.nt/articulo/curso_avanzado_de_prolog_166/4

 http://eclipseclp.org/doc/bips/kernel/termmanip/functor-3.html

 https://diegoandrescalvolopez.blogspot.com/2019/

También podría gustarte