Академический Документы
Профессиональный Документы
Культура Документы
ANTOLOGA DE
PROGRAMACIN
LGICA Y FUNCIONAL
en
Sistemas
Computacionales
contribuir,
aplicando
estos
CONTENIDO
UNIDAD 1.Conceptos Fundamentales..................................................................6
1.1. Estilos de programacin..............................................................................8
1.2. Evaluacin de expresiones....................................................................... 12
1.3. Definicin de funciones.............................................................................15
1.4. Disciplina de tipos......................................................................................17
1.5. Tipos de datos.............................................................................................18
UNIDAD 2. Programacin Funcional..................................................................22
2.1. El tipo de datos........................................................................................... 24
2.2. Funciones....................................................................................................34
2.3. Intervalos.....................................................................................................35
2.4. Operadores..................................................................................................36
2.5. Aplicaciones de las listas.......................................................................... 37
2.6. rboles.........................................................................................................40
UNIDAD 3. Evaluacin perezosa..........................................................................42
3.1. Estrategias de evaluacin perezosa.........................................................44
3.2. Tcnicas de programacin funcional perezosa...................................... 47
UNIDAD 4. Fundamentos de la programacin lgica.......................................50
4.1. Repaso de lgica de primer orden............................................................52
4.2. Unificacin y Resolucin...........................................................................55
4.3. Clusulas de Horn. Resolucin SLD........................................................ 56
4.4. Programacin lgica con clusulas de Horn.......................................... 62
4.5. Consulta de una base de clusulas..........................................................63
4.6. Representacin causada del conocimiento............................................ 63
4.7. Consulta de una base de clusulas..........................................................70
4.8. Espacios de bsqueda...............................................................................70
4.9. Programacin lgica con nmeros, listas y rboles.............................. 74
BIBLIOGRAFIA......................................................................................................91
Conceptos
Fundamentales
Programacin Funcional
Programacin Lgica y
Funcional
Evaluacin Perezosa
Estilos de Programacin
Evaluacin de Expresiones
Conceptos
fundamental
es
Definicin de
funciones
Disciplina de Tipos
Tipo de Datos
Estilo de identacin
Estilo de indentacin, en lenguajes de programacin que usan llaves para
identar o delimitar bloques lgicos de cdigo, como por ejemplo C, es tambin
un punto clave el buen estilo. Usando un estilo lgico y consistente hace el
cdigo de uno ms legible. Comprese:
if(horas < 24 && minutos < 60 && segundos < 60)
{ return true;
}else{
return false;
}
o bien:
return horas < 12 && minutos < 60 && segundos < 60;
La diferencia es, con frecuencia, puramente estilstica y sintctica, ya que los
compiladores modernos producirn cdigo objeto idntico en las dos formas.
Espaciado
Los lenguajes de formato libre ignoran frecuentemente los espacios en blanco.
El buen uso del espaciado en la disposicin del cdigo de uno es, por tanto,
considerado un buen estilo de programacin.
Comprese el siguiente extracto de cdigo C:
Ternarios: 3 operandos.
El orden en que se evalan los operandos viene dado por unas reglas:
Reglas de procedencia
Reglas de asociatividad
Uso de parntesis
EVALUACIN DE EXPRESIONES
Toda expresin regresa un valor. Si hay ms de un operador, se evalan primero operadores
mayor precedencia, en caso de empate, se aplica regla asociatividad
Para evaluar una expresin no hay que hacer nada del otro mundo, pues es bien
sencillo. Slo hay que saber sumar, restar, si un nmero es mayor que otro
Hay tres reglas de prioridad a seguir para evaluar una expresin:
Funcin F(X)
Inicio
F = X /(1 + X^2)
Fin
Inicio
Imprimir Este es el algoritmo principal
Leer N
R = F(N) llamado de la funcin
Imprimir El resultado de la funcin es:,R
Fin
Pascal
Ada
Tiene una funcin de biblioteca que permite extraer un valor de una variable de cualquier
tipo (como una cadena de bits) y usarlo como un tipo diferente (no es una conversin de
tipos) se trata de una suspensin temporal de la comprobacin de tipos
Java
ML y Haskell
Los tipos de los parmetros de las funciones (y de estas mismas) se conocen en tiempo
de compilacin (ya sea por declaracin del usuario o por inferencia de tipos)
Haskell y otros lenguajes funcionales utilizan el sistema de tipos de Milner, que tiene
dos caractersticas fundamentales:
Numricos
Simples Lgicos
Alfanumricos (string)
Tipos de datos Arreglos (Vectores, Matrices)
Estructurados Registros (Def. por el Archivos usuario) Apuntadores
hacer operaciones con ellos. Este tipo de datos se representan encerrados entre
comillas
Int
Integer
Char
Bool
Lgicamente podemos construir listas, tuplas y funciones con esos tipos de datos. Otro tipo
que tenemos presente en Haskell es el tipo polimrfico. As podemos construir estructuras y
funciones polimrficas.
Dentro de las caractersticas de los tipos de Haskell podemos deducir que cada expresin
tiene un nico tipo principal y que ese tipo principal se puede deducir automticamente.
Adems, Haskell incorpora las funciones sobrecargadas que se pueden aplicar sobre varios
tipos pero no sobre todos los tipos. Para ello se dispone de una jerarqua de clases de tipos
con operadores y funciones sobrecargadas como:
RESUMEN
El manejo de estndares y recomendaciones de programacin facilitaran al
programador la documentacin y seguimiento de sus proyectos an con el
paso del tiempo.
Mejorar el mantenimiento del software y permitir que el cdigo pueda ser ledo por
cualquier persona de la empresa que conozca los estndares de codificacin. Es
necesario indicar que las recomendaciones son exactamente mejores
El tipo de datos
Funciones
Intervalos
Programacin
Funcional
Operadores
rboles
= n+1
e1 => e2
Por ejemplo:
inc (inc 3)
=> 5
2.1.
Tipos Polimrficos
Esta definicin es auto-explicativa. Podemos leer las ecuaciones como sigue: "La
longitud de la lista vaca es 0, y la longitud de una lista cuyo primer elemento es x y su
resto es xs viene dada por 1 ms la longitud de xs." (Ntese el convenio en el nombrado:
xs es el plural de x, y x:xs debe leerse: "una x seguida de varias x).
Este ejemplo, adems de intuitivo, enfatiza un aspecto importante de Haskell que
debemos aclarar: la comparacin de patrones (pattern matching). Los miembros
izquierdos de las ecuaciones contienen patrones tales como [] y x:xs. En una aplicacin
o llamada a la funcin, estos patrones son comparados con los argumentos de la llamada
de forma intuitiva ([] solo "concuerda" (matches) o puede emparejarse con la lista vacia,
y x:xs se podr emparejar con una lista de al menos un elemento, instancindose x a este
primer elemento y xs al resto de la lista). Si la comparacin tiene xito, el miembro
izquierdo es evaluado y devuelto como resultado de la aplicacin. Si falla, se intenta la
siguiente ecuacin, y si todas fallan, el resultado es un error.
La definicin de funciones a travs de comparacin de patrones es usual en Haskell, y
el usuario deber familiarizarse con los distintos tipos de patrones que se permiten;
volveremos a esta cuestin en la Seccin 4.
La funcin length es tambin un ejemplo de funcin polimrfica. Puede aplicarse a
listas con elementos de cualquier tipo, por ejemplo [Integer], [Char], o [[Integer]].
=>
3
length ['a','b','c'] => 3
length [[1],[2],[3]] => 3
length
[1,2,3]
He aqu dos funciones polimrficas muy tiles sobre listas, que usaremos ms tarde. La
funcin head devuelve el primer elemento de una lista, y la funcin tail devuelve la lista
salvo el primero:
head
head (x:xs)
:: [a] -> a
= x
tail
tail (x:xs)
Al contrario que length, estas funciones no estan definidas para todos los posibles valores
de su argumento. Cuando las funciones son aplicadas a la lista vaca se produce un error
en tiempo de ejecucin.
Vemos que algunos tipos polimrficos son ms generales que otros en el sentido de que el
conjunto de valores que definen es ms grande. Por ejemplo, el tipo [a] es ms general que
[Char]. En otras palabras: el tipo [Char] puede ser derivado del tipo [a] a travs de una
sustitucin adecuada de a. Con respecto a este orden generalizado, el sistema de tipos de
Haskell tiene dos propiedades importantes: en primer lugar, se garantiza que toda expresin
bien tipificada tenga un nico tipo principal (descrito despus), y en segundo lugar, el tipo
principal puede ser inferido automticamente (4.1.4). En comparacin con un lenguaje con
tipos monomrficos como C, el lector encontrar que el polimrfismo enriquece la
expresividad, y que la inferencia de tipos reduce la cantidad de tipos usados por el
programador.
El tipo principal de una expresin o funcin es el tipo ms general que, intuitivamente,
"contiene todos los ejemplares de la expresin." Por ejemplo, el tipo principal de head es
[a]->a; los tipos [b]->a, a->a, o el propio a son demasiado generales, mientras que
algo como [Integer]->Integer es demasiado concreto. La existencia de un nico tipo
principal es la caracterstica esencial del sistema de tipos de Hindley-Milner, que es la base
del sistema de tipos de Haskell, ML, Miranda, ("Miranda" es marca registrada de Research
Software, Ltd.) y otros lenguajes (principalmente funcionales) .
2.2.
Podemos definir nuestros propios tipos en Haskell a travs de una declaracin data, que
introduciremos con una serie de ejemplos (4.2.1).
Un dato predefinido importante en Haskell corresponde a los valores de verdad:
data Bool
= False | True
El tipo definido con tal declaracin es Bool, y tiene exactamente dos valores: True y False.
Bool es un ejemplo de constructor de tipo (sin argumentos), mientras que True y
False son constructores de datos (o constructores, para abreviar).
Tanto Bool como Color son ejemplos de tipos enumerados, puesto que constan de un
nmero finito de constructores.
El siguiente es un ejemplo de tipo con un solo constructor de dato:
data Point a
= Pt a a
Al tener un solo constructor, un tipo como Point es llamado a menudo un tipo tupla, ya
que esencialmente es un producto cartesiano (en este caso binario) de otros tipos. (La tuplas
son conocidas en otros lenguajes como registros.) Por el contrario, un tipo multiconstructor, tal como Bool o Color, se llama una "suma de tipos" o tipo unin (disjunta).
Sin embargo, lo ms importante es que Point es un ejemplo de tipo polimrfico: para
cualquier tipo t, define el tipo de los puntos cartesianos que usan t como eje de
coordenadas. El tipo Point puede tambin verse como un constructor de tipos unario, ya
que a partir de un tipo t podemos obtener un nuevo tipo Point t. (En el mismo sentido,
usando el ejemplo de la listas, [] es tambin un constructor de tipos: podemos aplicar el
constructor [] a un tipo t para obtener un nuevo tipo [t]. La sintaxis de Haskell permite
escribir [t] en lugar de [] t. Similarmente, -> es otro constructor de tipos binario: dados
dos tipos "t" y "u", t->u es el tipo de las funciones que aplican datos de tipo "t" a
elementos de tipo "u".)
Ntese que el tipo del constructor de datos Pt es a -> a -> Point a, y las siguientes
asignaciones de tipos son vlidas:
Pt 2.0 3.0
Pt 'a' 'b'
Pt True False
:: Point Float
:: Point Char
:: Point Bool
Por otro lado, una expresin tal como Pt 'a' 1 est errneamente tipificada, ya que 'a' y
1 son de tipos diferentes.
Es importante distinguir entre la aplicacin de un constructor de datos para obtener un
valor, y la aplicacin de un constructor de tipos para obtener un tipo; el primero tiene lugar
durante el tiempo de ejecucin, que es cuando se computan cosas en Haskell, mientras que
el ltimo tiene lugar en tiempo de compilacin y forma parte del proceso de tipificado que
asegura un "tipo seguro".
[Constructores de tipo como Point y constructores de datos como Pt aparecen en niveles
distintos de la declaracin, lo que permite que el mismo nombre pueda usarse como
constructor de tipos y como constructor de datos, como vemos en:
data Point a = Point a a
Esto puede llevar a una pequea confusin al principio, pero sirve para crear un
enlace obvio entre el constructor de datos y el de tipo.]
2.2.1.
Tipos recursivos
Los tipos pueden ser recursivos, como el siguiente tipo para rboles binarios:
data Tree a
Con ello hemos definido un tipo polimrfico cuyos elementos son o bien hojas
conteniendo un valor de tipo a, o nodos internos ("ramas") conteniendo (en forma
recursiva) dos subrboles.
En la lectura de declaraciones de datos como la anterior, recordemos que Tree es un
constructor de tipos, mientras que Branch y Leaf son constructores de datos. La
declaracin anterior, adems de establecer una conexin entre estos constructores, define
esencialmente los tipos para los constructores Branch y Leaf:
Branch
Leaf
Con este ejemplo tenemos un tipo suficientemente rico que permite definir algunas
funciones (recursivas) interesantes que hagan uso de ste. Por ejemplo, supongamos que
queremos definir una funcin fringe que devuelva todos los elementos de las hojas de
un rbol de izquierda a derecha. En primer lugar es esencial escribir el tipo de la nueva
funcin; en este caso vemos que el tipo debe ser Tree a -> [a]. Es decir, fringe es una
funcin polimrfica que, para cualquier tipo a, aplica rboles de a sobre listas de a. Una
definicin adecuada es la siguiente:
fringe
:: Tree a -> [a]
fringe (Leaf x)
= [x]
fringe (Branch left right) = fringe left ++ fringe right
donde ++ es el operador infijo que concatena dos listas (su definicin completa se ver en
la Section 9.1). Al igual que la funcin length vista anteriormente, la funcin fringe est
definida mediante comparacin de patrones, salvo que los patrones implicados son los
constructores de la definicin dada por el usuario: Leaf y Branch. [Ntese que los
parmetros formales son fcilmente identificados ya que comienzan con letras minsculas.]
Por conveniencia, Haskell proporciona una forma para definir sinnimos de tipos; es decir,
nombres de tipos usados varias veces. Los sinnimos de tipo son creados a travs de una
declaracin type (4.2.2). He aqu algunos ejemplos:
type
type
type
data
String
Person
Name
Address
=
=
=
=
[Char]
(Name,Address)
String
None | Addr String
Los sinnimos no definen tipos nuevos, sino simplemente proporcionan nuevos nombres
a tipos ya existentes. Por ejemplo, el tipo Person -> Name es precisamente equivalente al
tipo (String,Address) -> String. Los nombres nuevos son a menudo ms cortos que
los tipos nombrados, pero ste no es el nico propsito de los sinnimos de tipos: stos
pueden mejorar la legibilidad de los programas a travs de nemotcnicos; en efecto, los
ejemplos anteriores enfatizan este hecho. Podemos dar nuevos nombres a tipos
polimrficos:
type AssocList a b
= [(a,b)]
Este es el tipo de las "listas de asociaciones" que asocian valores de tipo a con otros de tipo
b.
2.4.
Antes hemos introducido varios tipos "predefinidos" tales como listas, tuplas, enteros y
caracteres. Tambin mostramos como el programador puede definir nuevos tipos. Adems
de una sintaxis especial los tipos predefinidos tienen algo ms de especial? La respuesta
es no. La sintaxis especial es por conveniencia y consistencia, junto a algunas razones
histricas, pero no tiene ninguna consecuencia semntica.
Enfatizamos este punto diciendo que la apariencia de las declaraciones de stos tipos
predefinidos es especial. Por ejemplo, el tipo Char puede ser descrito en la forma:
data Char
Haskell
-- Esto no es cdigo
-- vlido!
Los nombres de los constructores no son vlidos sintcticamente; ello lo podramos arreglar
escribiendo algo como lo siguiente:
data Char
= Ca | Cb | Cc | ...
| CA | CB | CC | ...
| C1 | C2 | C3 | ...
...
Tales constructores son ms concisos, pero no son los habituales para representar
caracteres.
En cualquier caso, la escritura de cdigo "pseudo-Haskell" tal como la anterior ayuda a
aclarar la sintaxis especial. Vemos que Char es, en efecto, un tipo enumerado compuesto de
un gran nmero de constructores (constantes). Por ejemplo, visto Char de esta forma
aclaramos qu patrones pueden aparecer en las definiciones de funciones; es decir, qu
constructores de este tipo podemos encontrarnos.
Este ejemplo tambin muestra el uso de los comentarios en Haskell; los caracteres -- y
los sucesivos hasta el final de la lnea son ignorados. Haskell tambin permite comentarios
anidados que tienen las forma {-...-} y pueden aparecer en cualquier lugar (2.2).]
Similarmente, podemos definir Int (enteros de precisin limitada) y Integer en la forma:
data Int = -65532 | ... | -1 | 0 | 1 | ... | 65532 -- ms pseudocdigo
data Integer =
... -2 | -1 | 0 | 1 | 2 ...
donde -65532 y 65532, representan el mayor y el menor entero en precisin fija para una
implementacin concreta. Int es un tipo enumerado ms largo que Char, pero es finito! Por
el contrario, el pseudo-cdigo para Integer (el tipo de los enteros con precisin arbitraria)
debe verse como un tipo enumerado infinito.
Las tuplas tambin son fciles de definir en la misma forma:
data (a,b)
cdigo
data (a,b,c)
data (a,b,c,d)
.
.
.
= (a,b)
-- ms peudo-
= (a,b,c)
= (a,b,c,d)
.
.
.
Cada una de las declaraciones anteriores define una tupla de una longitud particular, donde
(...) juega distintos papeles: a la izquierda como constructor de tipo, y a la derecha
como constructor de dato. Los puntos verticales despus de la ltima declaracin indican
un nmero infinito de tales declaraciones, reflejando el hecho de que en Haskell estn
permitidas las tuplas de cualquier longitud.
La listas son manipulables fcilmente, y lo que es ms importante, son recursivas:
data [a]
cdigo
= [] | a : [a]
-- ms peudo-
Vemos que esto se ajusta a lo ya dicho sobre listas: [] es la lista vaca, y : es el constructor
infijo de listas; de esta forma [1,2,3] es equivalente a la lista 1:2:3:[]. (: es asociativo a
la derecha.) El tipo de [] es [a], y el tipo de : es a->[a]->[a].
[De esta forma ":" est definido con una sintaxis legal---los constructores infijos se
permiten en declaraciones data, y (para describir la comparacin de patrones) son
distinguidos de los operadores infijos ya que comienzan con el carcter ":" (una propiedad
satisfecha trivialmente por ":").]
En este punto, el lector deber notar con cuidado las diferencias entre tuplas y listas, ya
que las definiciones anteriores lo aclaran suficientemente. En particular, ntese la
naturaleza recursiva de las listas, con longitud arbitraria y cuyos elementos son
homogneos, y la naturaleza no recursiva de una tupla concreta, que tiene una longitud fija,
en la cual los elementos son heterogneos. Las reglas de tipificado para tuplas y listas
deberan quedar claras ahora:
Para (e1,e2,...,en), n>=2, si ti es el tipo de ei, entonces el tipo de la tupla es (t1,t2,...,tn).
Para [e1,e2,...,en], n>=0, cada ei debe tener el mismo tipo t, y el tipo de la lista es [t].
Intuitivamente, esta expresin puede leerse como "la lista de todos los f x tales que x
recorre xs." La similitud con la notacin de los conjuntos no es una coincidencia. La
frase x <- xs se llama un generador, y pueden utilizarse varios, como en :
[ (x,y) | x <- xs, y <- ys ]
Tal lista por comprensin determina el producto cartesiano de dos listas xs y ys. Los
elementos son seleccionados como si los generadores fueran anidados de izquierda a
derecha (con el de ms a la derecha variando el ltimo); es decir, si xs es [1,2] e ys es
[3,4], el resultado es [(1,3),(1,4),(2,3),(2,4)].
Adems de los generadores, se permiten expresiones booleanas llamadas guardas que
establecen restricciones sobre los elementos generados. Por ejemplo, he aqu una
definicin compacta del algoritmo de ordenacin favorito de todo el mundo:
quicksort
quicksort
[]
(x:xs)
=
=
++
++
[]
quicksort [y | y <- xs, y<x ]
[x]
quicksort [y | y <- xs, y>=x]
Como otra ayuda en la descripcin de listas, Haskell admite una sintaxis especial para
secuencias aritmticas, que mostramos con una serie de ejemplos:
[1..10] => [1,2,3,4,5,6,7,8,9,10]
[1,3..10] => [1,3,5,7,9]
[1,3..]
Como otro ejemplo de sintaxis especial para tipos predefinidos, hacemos notar que
la cadena de caracteres "hello" es una forma simplificada de la lista de caracteress
['h','e','l','l','o']. Adems, el tipo de "hello" es String, donde String es
un sinnimo de tipo predefinido:
type String
= [Char]
Esto significa que podemos usar las funciones polimrficas sobre listas para operar
con cadenas (strings). Por ejemplo:
"hello" ++ " world"
2.2. Funciones
2.3. Intervalos
2.4. Operadores
Here, we have a pair of integers, 5 and 3. In Haskell, the first element of a pairneed
not have the same type as the second element: that is, pairs are allowed to be
heterogeneous heterogeneous. For instance, you can have a pair of an integer
with a string. This contrasts with lists, which must be made up of elements of all the
same type (we will discuss lists further in Section 3.3).
There are two predefined functions that allow you to extract the first and
secondvelements of a pair. They are, respectively, fst and snd. You can see how
they workvbelow:
In addition to pairs, you can define triples, quadruples etc. To define a triple and a
quadruple, respectively, we write:
Exercise 3.2 Use a combination of fst and snd to extract the character out of the
tuple ((1,a),"foo").
Lists
The primary limitation of tuples is that they hold only a fixed number of elements:
pairs hold two, triples hold three, and so on. A data structure that can hold an
arbitrary number of elements is a list. Lists are assembled in a very similar fashion
to tuples, except that they use square brackets instead of parentheses. We can
define a list like:
Lists dont need to have any elements. The empty list is simply []. Unlike tuples, we
can very easily add an element on to the beginning of the list using the colon
operator. The colon is called the cons operator; the process of adding an element
is called consing. The etymology of this is that we are constructing a new list from
an element and an old list. We can see the cons operator in action in the following
examples:
We can actually build any list by using the cons operator (the colon) and the empty
list:
In fact, the [5,1,2,3,4] syntax is syntactic sugar for the expression using the
explicit cons operators and empty list. If we write something using the [5,1,2,3,4]
notation, the compiler simply translates it to the expression using (:) and [ ].
One further difference between lists and tuples is that, while tuples are
heterogeneous, lists must be homogenous. This means that you cannot have a list
that holds both integers and strings. If you try to, a type error will be reported. Of
course, lists dont have to just contain integers or strings; they can also contain
tuples or even other lists. Tuples, similarly, can contain lists and other tuples. Try
some of the following:
There are two basic list functions: head and tail. The head function returns the first
element of a (non-empty) list, and the tail function returns all but the first element of
a (non-empty) list. To get the length of a list, you use the length function:
2.6. rboles
La estrategia de evaluacin
perezosa
Evaluacin perezosa
Tcnicas de programacin
funcional
perezosa
Actividades de Aprendizaje
Identificar los conceptos bsicos de la evaluacin perezosa.
Describir las tcnicas de la programacin funcional perezosa.
BUSQUEDA NO DETERMINISTA
Un algoritmo no determinista
-Ofrece muchos posibles resultados
-Emplean modelos de computacin tales como la maquina de turing probabilstica, que no
son deterministas
-puede simularse utilizando la lista de xitos como por ejemplo x=x, x candidatos, validos
DATOS NO DETERMINISTAS
Requiere tipo de datos diferente como son
Data list m a= nil (cons (m a)(m(list a))
Puede representar lista perezosa no determinista.
Cons [2] [Nil, cons[1]]:: list{} int
Los argumentos de cons representan computacin no determinista, permute y lsSorted
se pueden adaptar a la lista de tipo permute y genera permutaciones perezosamente los
rendimientos isSorted [true, false]es aplicada por encima de la lista (s).
PROGRAMACION FUNCIONAL-LOGICA
La programacin lgica, junto con la funcional, forma parte de los que se conoce como
programacin declarativa. En los lenguajes tradicionales, la programacin consiste en como
RESUMEN
Las diversas tcnicas estudiadas en la unidad nos presentan las tcnicas
sobre programacin de funciones, y sobre su evaluacin.
Mientras se consideren estas recomendaciones se prev la obtencin de un
buen software que cumple su objetivo de forma correcta.
Unificacin y resolucin
Fundamentos
de la
programacin
lgica
Espacios de bsqueda
Programacin lgica con
nmeros, listas y
rboles
Control de bsqueda
en
programas
lgicos
Manipulacin de trminos.
Predicados
metalgicos
Actividades de Aprendizaje
Unificacin y Resolucin
La Deduccin Natural consiste en un sistema de reglas de inferencia, es decir, a
partir de "algo" podemos deducir o "llegar a" "otra cosa", hasta que encontramos
una conclusin
METODO DE RESOLUCION
El Mtodo de Resolucin, es un intento de mecanizar el proceso de
deduccin natura. Las demostraciones se consiguen utilizando el mtodo
refutativo (reduccin al absurdo), es decir lo que intentamos es encontrar
contradicciones.
El mtodo de resolucin es una regla de inferencia que toma dos clausulas
y produce una tercera que es consecuencia lgica de estas. El proceso
consiste en identificar y borrar parejas complementarias de dos clausulas,
una de cada clausula y luego, combinar las otras literales para formar una
clausula nueva.
METODO DE UNIFICACION
La Unificacin es un procedimiento de emparejamiento que compara dos
literales y descubre si existe un conjunto de sustituciones que los haga
idnticos.
La idea bsica de la unificacin es muy sencilla.
En primer lugar se comprueba si los predicados coinciden. Si es as,
seguimos adelante; si no es que no son unificables.
Si el predicado concuerda, comenzamos a comparar los argumentos. Si
el primero de ellos coincide en ambos literales, continuamos con el
siguiente... y as hasta completar todos los argumentos.
ie,
L1
L2
L3...
Una ligeramente forma de esta es una clusula Horn, donde la restriccin es que slo uno
de los literales es en negativo. Por ejemplo:
1.
L1
2.
L1
3. M
4.
L1
L2
L2
L3 ...
L3 ...
Son todas las clusulas de Horn. Es fcil demostrar que, por ejemplo, (2) es equivalente a
L1 L2 L3 ...=> M
or in goal-directed form:
M => L1 L2 L3...
Esta es la forma tpica de una declaracin en el lenguaje de programacin lgica Prolog.
Hay dos modos en Prolog. En el modo de consultar, uno suministra el sistema con
axiomas. (Tenga en cuenta que el `` '' se sustituye por '': - ', Que capitalizan smbolos
son variables, y que el ``. '' es importante)
Abuelos(X,Y):- hijo(X,Z),pariente(Y,Z).
Hijos(charles,elizabeth).
Parientes(george,elizabeth).
con prlog nos dice que no hay hechos de base de datos para verificar el comunicado. O
podramos preguntar
?- nieto(W,george).
A partir de esta consulta, Prolog trata de justificar cada literal en el lado derecho mediante la
bsqueda de una coincidencia literal en la LHS de otra clusula en la base de datos. En nuestro
ejemplo, se encontrara declaracin de dbase 1 y llevar a cabo la unificacin (W / X, George / Y).
De modo que el lado derecho se convierte en hijo (X, Z), el padre (George, Z). A continuacin,
utiliza la declaracin de dbase 2 para llevar a cabo la unificacin (X / charles, Z / Elizabeth),
dejando padre (George, Elizabeth) para ser verificada. Obviamente, dBase
statement 3 does this with no unification. The system returns the unification for W which is
(W/X/charles), ie charles.
?- grandson(W,george).
W = charles ?
yes
4.7. Consulta
clusulas
de
una
base
de
Operador
Operando 2
Resultado
+, -, *
entero
entero
real
+, -, *
entero
real
entero
+, -, *
real
real
real
+, -, *
real
real
entero real
entero real
real
entero
div
entero
entero
entero
mod
entero
entero
entero
Tabla 1
Orden de evaluacin
Si la expresin contiene subexpresiones entre parntesis, las subexpresiones se
evalan primero.
Si la expresin contiene multiplicacin o divisin, estas operaciones son
realizadas trabajando de izquierda a derecha a travs de la expresin.
Las operaciones de suma y resta son llevadas a cabo de izquierda a derecha tambin.
En el orden de evaluacin se tiene en cuenta, lgicamente, la precedencia de
los operadores.
Operador
Prioridad
+-
* / mod div
- + (unario
Tabla 2
Funciones y predicados
Visual Prolog posee una gran cantidad de funciones y predicados matemticos para realizar
las ms variadas operaciones. La lista completa se ofrece en la Tabla 3.
Nombre
Descripcin
X mod Y
X div Y
abs(X)
Valor absoluto de X.
cos(X)
Coseno de X.
sin(X)
Seno de X.
tan(X)
Tangente de X.
arctan(X)
Arcotangente de X.
exp(X)
ln(X)
Logaritmo neperiano de X.
log(X)
Logaritmo en base 10 de X.
sqrt(X)
Raz cuadrada de X.
random(X)
random(X, Y)
round(X)
trunc(X)
val(domain,X)
Comparaciones
En Visual Prolog podemos comparar expresiones aritmticas, caracteres, cadenas de
caracteres y smbolos.
Las comparaciones de este tipo se realizan a travs de operadores relacionales. Ver Tabla 4.
Smbolo
Relacin
<
menor que
<=
igual que
>
mayor que
>=
<> o ><
distinto
Tabla 4
RBOLES
Un rbol es una estructura con una definicin puramente recursiva, ya que se puede
considerar como el elemento raz cuyos hijos son, a su vez, rboles. Si el rbol tiene
nicamente dos hijos se denomina rbol binario. Este modelo especfico de rbol se
utiliza mucho para resolver gran cantidad de problemas en aspectos de programacin.
Un rbol se puede considerar, a su vez, un caso particular de grafo, donde todos los
caminos son acclicos.
La Figura 1 muestra un ejemplo de rbol.
Figura 1
Ejemplo de rbol
Figura 2
rbol de anlisis de una frase en espaol
Como se observa, el uso de un predicado con dos argumentos en el caso de rbol binario o
N argumentos en el caso de rbol N-ario es una forma sencilla de representar un rbol.
Mediante objetos compuestos recursivos del tipo arbol(nodo, hijoizq, hijoder), donde
hijoizq e hijoder son tambin rboles, podemos representar un rbol binario. El rbol
vaco se representa a travs del hecho vacio:
arbol(1,arbol(2,arbol(4,vacio,vacio),arbol(5,vacio,vacio)),arbol(3,vacio,vacio))
En la seccin DOMAINS podemos crear un tipo rbol de enteros del modo siguiente:
mi_arbol= arbol(INTEGER, mi_arbol, mi_arbol); vacio
Operaciones con rboles representados mediante objetos compuestos recursivos
domains
arbol= nodo(integer, arbol, arbol); vacio
lista= integer*
predicates
concatenar(lista, lista, lista)
preorden(arbol, lista)
inorden(arbol, lista)
postorden(arbol, lista)
clauses
concatenar([],[],[]):-!.
concatenar([],L2,L2):-!.
concatenar(L1,[],L1):-!.
concatenar([X|Y],L2,[X|Aux]):-concatenar(Y,L2,Aux).
preorden(vacio,[]):-!.
preorden(nodo(X,Izq,Der),[X|L]):-preorden(Izq,L1),
preorden(Der,L2),
concatenar(L1,L2,L).
inorden(vacio,[]):-!.
inorden(nodo(X,Izq,Der),L):-inorden(Izq,L1),
inorden(Der,L2),
concatenar(L1,[X|L2],L).
postorden(vacio,[]):-!.
postorden(nodo(X,Izq,Der),L):-postorden(Izq,L1),
postorden(Der,L2),
concatenar(L1,L2,L3),
concatenar(L3,[X],L).
goal
inorden(nodo(1,nodo(2,nodo(4,vacio,vacio),nodo(5,vacio,vacio)),nodo(3,vacio,vacio)), L1),
preorden(nodo(1,nodo(2,nodo(4,vacio,vacio),nodo(5,vacio,vacio)),nodo(3,vacio,vacio)), L2),
postorden(nodo(1,nodo(2,nodo(4,vacio,vacio),nodo(5,vacio,vacio)),nodo(3,vacio,vacio)), L3).
LISTAS
Una lista se puede considerar como un caso particular de rbol del modo que se muestra
en la Figura 3.
Figura 3
Lista implementada en forma de rbol
A su vez, una lista se puede considerar de forma recursiva. Es decir, siempre est formada
por un elemento seguido de otra lista (ver Figura 4). Cuando la lista tienen un slo
elemento podemos considerar que est formada por dicho elemento y la lista vaca. Esta
definicin es muy interesante, ya que su conocimiento nos permitir llevar a cabo todos
las operaciones que se pueden realizar sobre las listas con poco esfuerzo.
Figura 4
Definicin recursiva de una lista
Hemos de recordar que en Prolog no existen estructuras para realizar bucles luego todo
los algoritmos que representemos se definirn de forma recursiva. El hecho de que la
implementacin de la lista sea tambin recursiva facilita la construccin de operaciones
sobre la misma.
Es necesario comprender este tipo de estructura para construir algoritmos eficientes. La
mayor parte de las operaciones que se realizan sobre una lista implica un recorrido de
la misma, luego hemos de centrarnos en conocer cmo se lleva a cabo este algoritmo
utilizando tcnicas de recursividad.
Una lista se puede especificar en un predicado o en un objetivo a travs de:
Las listas pueden ser homogneas o heterogneas, es decir, almacenar elementos del mismo
tipo, o elementos de distinto tipo.
Para definir un tipo de lista en particular es necesario declararla en la seccin DOMAINS.
lista= elementos* (lista de una dimensin)
lista2= elementos** (lista de dos dimensiones)
lista3= elementos*** (lista de tres dimensiones)...
Es interesante observar la sintaxis de definicin de una lista: elementos representa el
dominio o tipo de los elementos que componen la lista.
El tipo elementos puede representar un dominio simple, es decir, slo un tipo de elementos
se corresponde con dicho dominio o un dominio complejo, donde varios tipos de elementos
se corresponden con dicho dominio.
Por ejemplo, una lista homognea de elementos simples estara definida como:
lista= integer*
Una lista heterognea de elementos estara definida como:
listaenteros=integer*
elementos= i(integer); s(symbol); c(char); le(listaenteros)
lista= elementos*
Ejemplo:
domains
listaenteros= integer*
elementos= i(integer); c(char); s(symbol); le(listaenteros)
lista= elementos*
predicates
recorrer(lista)
clauses
recorrer([]):-!.
recorrer([X|Y]):-write(X), nl, recorrer(Y).
goal
recorrer([i(1),c('a'),s(pepe),i(5),c('b'),le([1,2,3])]).
Se observa que la lista puede contener cuatro tipo de elementos distintos: enteros,
caracteres, smbolos y listas de enteros. En la seccin de declaracin del dominio o tipo
elementos no podemos escribir:
elementos= integer; char; symbol; listaenteros
para expresar que dicho dominio agrupa a cuatro tipos de elementos distintos sino que la
sintaxis a utilizar es aquella que representa que elementos agrupa a cuatro tipos de objetos
compuestos distintos.
El resultado de la ejecucin de la meta es el siguiente:
i(1)
c('a')
s("pepe")
i(5)
c('b')
le([1,2,3])
yes
Las operaciones tpicas que se pueden realizar sobre listas son: la insercin de elementos
al principio, al final, en orden; borrado, bsqueda de elementos, recorrido, eliminacin de
duplicados y, en general, todas las de las que se pueden realizar sobre conjuntos de
elementos tales como: interseccin, unin, diferencia, pertenencia, comprobacin de lista
vaca, concatenacin, etc.
Las listas se pueden utilizar para implementar otras estructuras tales como listas
circulares, vectores, pilas, colas, rboles, grafos y matrices.
De cada estructura nos interesa saber cules son los algoritmos para acceder a ellas. Una
vez que conocemos, perfectamente, el tipo de operaciones que las definen, cualquier tipo
de implementacin es vlida. Por ejemplo, es frecuente usar una implementacin mediante
listas para plasmar matrices.
Por otro lado, es fundamental aplicar tcnicas de diseo descendente para resolver todos
nuestros problemas e implementar las estructuras necesarias en nuestras aplicaciones.
MATRICES
Podemos definir matrices a partir de listas, primero de 2 dimensiones y, ms tarde,
generalizar matrices de dimensin N.
En un lenguaje imperativo, recorrer una matriz de dos dimensiones implica el uso de un par
de bucles anidados, que proporcionan una complejidad computacional O(n2). Sin embargo,
en Prolog, no disponemos de este tipo de estructuras de control, por tanto, cualquier
operacin debe ser resuelta de forma recursiva mediante la declaracin formal de su
enunciado.
Un tratamiento elemento a elemento de las matrices tal y como se realiza en un
lenguaje imperativo no es adecuado en Prolog, por tanto, conviene entender la
estructura matriz como una lista de listas, y aplicar los algoritmos diseados sobre listas
para resolver problemas matriciales.
Una matriz de cuatro dimensiones se puede ver como la secuencia de un conjunto de
matrices de tres dimensiones, una matriz de tres dimensiones como un conjunto de matrices
de dos dimensiones, una matriz de dos dimensiones como un conjunto o lista de matrices
de una dimensin (vector o lista), por ltimo, un vector o lista no es ms que una secuencia
de elementos simples.
BIBLIOGRAFIA
UNIDAD I
http://es.wikipedia.org/wiki/Estilo_de_programaci%C3%B3n
http://programacionlogicayfuncional.wordpress.com/2014/02/12/estilos-deprogramacion/
http://programacionlogicayfuncional.wordpress.com/2014/02/12/evaluacionde-expresiones/
http://programacionlogicayfuncional.wordpress.com/2014/02/13/definicionde-funciones/
http://users.dcc.uchile.cl/~lmateu/CC10A/Apuntes/deffun/index.html
UNIDAD II
http://sistemasumma.com/2011/09/04/tipos-de-datos-en-haskell/
Funciones http://www.cs.us.es/cursos/lp/practicas/tema-001.pdf
(Piensa en Haskell. JIMENEZ Jos A., Creative Commons. Sevilla 2012.)
(Yet Another Haskell Tutorial. Daume, Hal. 2006)
UNIDAD III
Evalacin perezosa. https://www.cs.us.es/~jalonso/cursos/pd09/temas/tema-10-1x2.pdf
Evaluacin perezosa. http://prezi.com/lhnyd5gqlj_-/unidad-3-evaliacionperezosa/
UNIDAD IV
Programacin Lgica. http://clubensayos.com/Tecnolog
%C3%ADa/Programacion-Logica/1777196.html
Repaso de Lgica de Primer Orden. http://web.ing.puc.cl/~marenas/iic326010/clases/repaso-lpo.pdf
http://es.scribd.com/doc/71607751/Metodos-de-Resolucion-y-Unificacion
http://gpd.sip.ucm.es/jaime/docencia/pl/sld.pdf
http://wwwg.eng.cam.ac.uk/mmg/teaching/artificialintelligence/nonflash/resolution6.htm
http://gpd.sip.ucm.es/jaime/docencia/pl/busqueda.pdf