martes, 12 de marzo de 2013

Operadores-aritmetica







LISTAS, OPERADORES Y ARITMETICA
Representación de listas.

La "lista" es una estructura de datos ampliamente utilizada en la programación no  numérica. Una lista es una secuencia de cualquier número de elementos, tales como los objetos ana, tenis, tomás, eskí. Esta lista se puede escribir en Prolog como:
[ ana, tenis, tomás, eskí ]
Sin embargo ésta es solamente la apariencia externa de las listas. En Prolog todos los objetos estructurados son árboles y las listas no son una excepción.

¿Cómo puede una lista representarse como un objeto Prolog? Tenemos que considerar dos casos: si la lista está ó no vacía. En el primer caso la lista se escribe como un átomo
Prolog : []. En el segundo caso la lista puede verse como formada por dos cosas:
(1). el primer elemento, llamado "cabeza" de la lista.
(2). los elementos restantes, llamados en conjunto: "cola" de la lista.
Para el ejemplo anterior : [ ana, tenis, tomás, eskí ]
la cabeza es : ana la cola es : [ tenis, tomás, eskí ].
En general, la cabeza puede ser cualquier cosa (cualquier objeto Prolog, por ejemplo, un árbol ó una variable); la cola tiene forzosamente que ser una lista. La cabeza y la cola se combinan en una estructura con un functor especial. El símbolo para este functor depende de la implementación de Prolog. Asumiremos que se trata del punto [.].

.( Cabeza, Cola)

Operaciones sobre listas.

Las listas se pueden utilizar para representar conjuntos aunque se debe tomar en cuenta
que existen diferencias: el orden de los elementos en un conjunto no interesa mientras
que en una lista sí, además los objetos se pueden repetir en una lista y en un conjunto no.
Aún con estas diferencias, las operaciones más frecuentes sobre listas son semejantes a
las operaciones sobre conjuntos:
Pertenencia a una lista.

Implementaremos la relación miembro como:
miembro( X, L)
donde X es un objeto y L es una lista. La meta miembro( X, L) es cierta si X es
miembro de la lista L




Adicionar un elemento.

Para adicionar un elemento a una lista, se puede colocar este nuevo elemento al frente de
la lista de tal modo que sea la nueva cabeza de la lista :
aumentar( X, L, [X|L]).

Eliminar un elemento.

Para eliminar un elemento X de una lista L se puede programar la relación:
eliminar( X, L, L1) donde L1 es igual a la lista L con el elemento X removido. Esta relación se puede definir de manera similar a la relación de pertenencia, tendremos nuevamente dos casosposibles :
(1). Si X es la cabeza de la lista, entonces el resultado después de la eliminación es la cola de la lista.
(2). Si X está en la cola entonces deberá eliminarse de la cola.
En Prolog:
eliminar( X, [X|Cola], Cola).
eliminar( X, [Y|Cola], [Y|Cola1]) :-
eliminar(X, Cola, Cola1).

Notación de los operadores.

En matemáticas estamos acostumbrados a escribir expresiones como:
2 * a + b * c
donde + y * son operadores, 2,a,b y c son argumentos. Decimos que estos operadores son infijos porque aparecen entre dos argumentos. Estas expresiones se pueden representar como árboles y se pueden escribir como términos de Prolog con los símbolos
+ y * como functores: +( *( 2, a), *( b, c))
Prolog acepta también la notación infija pero recuerde que ésta es solamente su representación externa y será automáticamente convertida a la forma normal anterior de Prolog (árbol). Es decir, si escribimos en la forma a + b, Prolog lo manejará exactamente igual que si hubiésemos escrito +( a, b).

El principal functor será siempre el operador con la más alta precedencia.

Un programador puede definir además sus propios operadores. Por ejemplo podemos definir los operadores tiene y soporta como operadores infijos y poder escribir después en nuestros programas hechos como:

pedro tiene informacion.
el_piso soporta la_mesa.
estos hechos resultan exactamente equivalentes a :
tiene( pedro, informacion)
soporta( el_piso, la_mesa)

La manera en cómo definimos operadores nuevos es insertando en el programa tipos especiales de cláusulas conocidas como directivas que actúan para definir operadores.
La definición de un operador debe aparecer en el programa antes de cualquier expresión que lo contenga. Por ejemplo, el operador 'tiene' se puede definir con la siguiente directiva:


:- op( 600, xfx, tiene).
esto le dice a Prolog que queremos utilizar 'tiene' como operador y cuyo valor de
precedencia es 600 y su tipo es 'xfx' que indica que se trata de un operador infijo.

Nótese que la definición del operador no especifica ninguna operación ó acción. En principio, no se asocia ninguna operación ni dato alguno con el operador definido (excepto en casos muy especiales). Los operadores se usan normalmente como functores para combinar objetos con estructuras y no invocan acciones o datos aunque la palabra operador lo sugiera.
Los nombres de los operadores deben ser átomos y su precedencia debe estar en un rango que dependa del sistema usado. Asumiremos un rango de 1 a 1200.
Existen tres tipos de grupos de operadores:

(1). Operadores infijos de tres tipos:
xfx xfy yfx
(2). Operadores prefijos de dos tipos:
fx  fy

(3). Operadores postfijos de dos tipos:
xf  yf

Explicaremos ahora la diferencia entre 'x' y 'y' pero antes debemos introducir la noción de precedencia del argumento. Si un argumento se encierra entre paréntesis ó se trata de un objeto no estructurado, entonces su valor de precedencia es 0. Si un argumento es una estructura entonces su valor de precedencia es igual a la precedencia de su functor principal. 'x' representa un argumento cuyo valor de precedencia debe ser estrictamente menor que el del operador. 'y' representa un argumento cuyo valor de precedencia es menor ó igual al del operador.
Estas reglas ayudan a reconocer expresiones ambiguas con varios operadores de la misma precedencia.
Prolog contiene operadores predefinidos listos para usarse y que no necesitan definirse:

:- op( 1200, xfx, ':-').
:- op( 1200, fx, [:-,?-]).
:- op( 1100, xfy, ';').
:- op( 1000, xfy, ',').
:- op( 700, xfx, [=,is,<,>,=<,>=,==,=\=,\==,=:=]).
:- op( 500, yfx, [+,-]).
:- op( 500, fx, [+,-,not]).
:- op( 400, yfx, [*,/,div]).
:- op( 300, xfx, mod).
Aritmética.

Los operadores predefinidos que se pueden utilizar para las operaciones aritméticas son :
+ adición
* multiplicación
- sustracción
/ división
mod módulo (residuo de la división entera).

Observe lo siguiente: Si preguntamos
?- X = 1 + 2.
Prolog contestará : X = 1 + 2

Y no X = 3 como podriamos esperar. La razón es simple: la expresión 1+2 solamente denota un término de Prolog donde el símbolo + es el functor y 1 y 2 son sus argumentos. No existe nada en la pregunta anterior que force a Prolog para activar la operación de la adición. Sin embargo existe un operador predefinido de Prolog “is” para resolver este problema. El operador is forza la evaluación. La manera correcta de invocar
a la operación aritmética es:

?- X is 1 + 2.
X = 3


Los operadores de comparación son los siguientes:

X > Y X es mayor que Y
X < Y X es menor que Y
X >= Y X es mayor o igual que Y
X =< Y X es menor o igual que Y
X =:= Y los valores de X y Y son iguales
X =\= Y los valores de X y Y no son iguales              

Ejemplos 1.
?- 1 + 2 =:= 2 + 1.
Yes
?- 1 + 2 = 2 + 1.
No

 Ejemplo2.



Ejemplo3. Dados dos enteros positivos, X y Y, encontrar el máximo común divisor D.
Por ejemplo, para X=20 y Y=25 el máximo común divisor es D=5.
El máximo común divisor puede encontrarse de acuerdo a tres casos:
(1). Si X y Y son iguales, entonces D es igual a X.
(2). Si X < Y entonces D es igual al máximo común divisor de X y la diferencia Y – X.
(3). Si Y < X entonces D es igual al máximo común divisor de X y Y intercambiados.

En Prolog:
mcd(X,X,X).
mcd(X,Y,D) :-
X < Y,
Y1 is Y – X,
mcd(X,Y1,D).
mcd(X,Y,D) :-
Y < X,
mcd(Y,X,D).

PLUS
Plus sirve para sumar los argumentos recibidos, ejemplo:

 







BETWEEN
Encuentra un número en un rango, ejemplo:
                                                  
 











SUCC
Devuelve verdadero si el 2º argumento es= 1º + 1 y si el 1º >= 0, ejemplo:









IS
Es un predicado que define una expresión, ejemplo:

 













FUNCIONES

Función





Descripción
Abs
Valor absoluto
sign
Signo de un numero
Min
Valor minimo
Max
Valor maximo
Random
Numero aleatorio.
round
Redondeo
Floor
Redondeo hacia arria
ceiling
Redondeo hacia abajo
sqrt
Raiz
powm
Potencia
pi
Valor de pi


Ejercicios.
1. Defina la relación max(X,Y,Max) de tal modo que Max sea el mayor valor de los
dos números X y Y.
2. Defina el predicado maxlist(List, Max) de tal manera que Max sea el mayor
número de la lista List de números.
3. Defina el predicado sumlist(List, Sum) donde Sum es la suma de una lista de
números dada en List.
4. Defina el predicado ordenada(List) el cual es cierto (devolverá yes) si List es una
lista ordenada de números en forma ascendente o descendente, por ejemplo,
?- ordenada(1,5,6,6,9,12).
Yes
5. Defina el predicado subsum(Set, Sum, Subset) donde Set es una lista de números,
Subset es un subconjunto de esta lista y Sum es la suma de los números en
Subset. Por ejemplo,
?- subsum([1,2,5,3,2], 5, Sub).
Sub = [1,2,2];
Sub = [2,3];
Sub = [5];



jueves, 7 de marzo de 2013

PROG.LOGICA


REFLEXION

PROGRAMACION LOGICA

La programación lógica es un tipo de paradigmas de programación dentro del paradigma de programación declarativa. El resto de los subparadigmas de programación dentro de la programación declarativa son: programación funcional, programación con restricciones, programas DSL (de dominio específico) e híbridos. La programación funcional se basa en el concepto de función (que no es más que una evolución de los predicados), de corte más matemático. La programación lógica gira en torno al concepto de predicado, o relación entre elementos.
Históricamente, los ordenadores se han programado utilizando lenguajes muy cercanos a las peculiaridades de la propia máquina: operaciones aritméticas simples, instrucciones de acceso a memoria, etc. Un programa escrito de esta manera puede ocultar totalmente su propósito a la comprensión de un ser humano, incluso uno entrenado. Hoy día, estos lenguajes pertenecientes al paradigma de la Programación imperativa han evolucionado de manera que ya no son tan crípticos.
En cambio, la lógica matemática es la manera más sencilla, para el intelecto humano, de expresar formalmente problemas complejos y de resolverlos mediante la aplicación de reglas, hipótesis y teoremas. De ahí que el concepto de "programación lógica" resulte atractivo en diversos campos donde la programación tradicional es un fracaso.

Campos de aplicación
La programación lógica encuentra su hábitat natural en aplicaciones de inteligencia artificial o relacionada: Sistemas expertos, donde un sistema de información imita las recomendaciones de un experto sobre algún dominio de conocimiento.
·         Demostración automática de teoremas, donde un programa genera nuevos teoremas sobre una teoría existente.
·         Reconocimiento de lenguaje natural, donde un programa es capaz de comprender (con limitaciones) la información contenida en una expresión lingüística humana.
La programación lógica también se utiliza en aplicaciones más "mundanas" pero de manera muy limitada, ya que la programación tradicional es más adecuada a tareas de propósito general.

Fundamentos
La mayoría de los lenguajes de programación lógica se basan en la teoría lógica de primer orden, aunque también incorporan algunos comportamientos de orden superior como la lógica difusa. En este sentido, destacan los lenguajes funcionales, ya que se basan en el cálculo lambda, que es la única teoría lógica de orden superior que es demostradamente computable (hasta el momento).

En qué consiste (ejemplo)
La programación lógica permite formalizar hechos del mundo real, por ejemplo:
·         las aves vuelan
·         los pingüinos no vuelan
·         "pichurri" es un ave
·         "sandokan" es un perro
·         "alegría" es un ave

y también reglas o restricciones:  una mascota vuela si es un ave y no es un pingüino
 
Ante dicho "programa" es posible establecer hipótesis que no son más que preguntas o incógnitas, por ejemplo:
¿ "pichurri" vuela ?
   ¿ qué mascotas vuelan ?....

Gracias a que la lógica de primer orden es computable, el ordenador será capaz de verificar la hipótesis, es decir, responder a las incógnitas:

Es cierto que "pichurri" vuela.
   "pichurri" y "alegría" vuelan.

Obsérvese que el programa lógico no solamente es capaz de responder si una determinada hipótesis es verdadera o falsa. También es capaz de determinar que valores de la incógnita hacen cierta la hipótesis.

Este ejemplo es claramente académico. Sin embargo, consideremos el siguiente ejemplo: el sistema de control de semáforos de una ciudad.
El estado de cada uno de los semáforos (verde, rojo o ámbar) constituye los hechos del mundo real. El programa en sí consiste en unas pocas reglas de sentido común: determinados semáforos no pueden permanecer simultáneamente en verde, un semáforo solamente puede transitar de verde a ámbar y de ámbar a rojo, etc. La hipótesis es el estado en el que deberían estar cada uno de los semáforos en el siguiente instante de tiempo.
Éste es un ejemplo imposible de resolver mediante programación tradicional, ya que la lógica subyacente al comportamiento de los semáforos en su conjunto queda enmascarada por simples órdenes imperativas del tipo "cambiar color de tal o cual semáforo".

Lenguajes

El lenguaje de programación lógica por excelencia es Prolog, que cuenta con diversas variantes. La más importante es la programación lógica con restricciones.


Otras consultas

Un paradigma de programación es una propuesta tecnológica que es adoptada por una comunidad de programadores cuyo núcleo central es incuestionable en cuanto a que unívocamente trata de resolver uno o varios problemas claramente delimitados. La resolución de estos problemas debe suponer consecuentemente un avance significativo en al menos un parámetro que afecte a la ingeniería de software. Tiene una estrecha relación con la formalización de determinados lenguajes en su momento de definición. Un paradigma de programación está delimitado en el tiempo en cuanto a aceptación y uso ya que nuevos paradigmas aportan nuevas o mejores soluciones que la sustituyen parcial o totalmente.

Tipos de paradigmas de programación más comunes:

·         Imperativo o por procedimientos: es considerado el más común y está representado, por ejemplo, por CBASIC o Pascal
·         Funcional: está representado por Scheme o Haskell. Este es un caso del paradigma declarativo.
·         Lógico: está representado por Prolog. Este es otro caso del paradigma declarativo.
·         Declarativo: por ejemplo la programación funcional, la programación lógica, o la combinación lógico-funcional.
·         Orientado a objetos: está representado por Smalltalk, un lenguaje completamente orientado a objetos.
Si bien puede seleccionarse la forma pura de estos paradigmas al momento de programar, en la práctica es habitual que se mezclen, dando lugar a la programación multiparadigma.
Actualmente el paradigma de programación más usado es el de la programación orientada a objetos.


REFERENCIAS:
http://es.wikipedia.org/wiki/Programaci%C3%B3n_l%C3%B3gica
http://es.wikipedia.org/wiki/Paradigma_de_programaci%C3%B3n

domingo, 3 de marzo de 2013

SINTAXIS

Sintaxis y significado de los programas

Prolog reconoce el tipo de un objeto por su sintaxis.

Al igual que en Logica de Primer Orden, los terminos en Prolog se clasifican en tres categorias: constantes, variables y terminos compuestos.

Constantes

Prolog distingue dos tipos de constantes:

Números. Este tipo de constantes se utilizan para representar tanto números  enteros como

números  reales y poder realizar con ellos operaciones aritmeticas.

- La representación mas corriente de los números  enteros es la notación decimal habitual

(por ejemplo 0, 1, -320, 539, etc) aunque también se pueden representar en otras

bases no decimales.

- Los números  reales se pueden representar tanto en notación decimal (por ejemplo

1.0, -3.14) como en notación exponencial (por ejemplo 4.5E6, -0.12e+3, 12.0e-2). En ambos casos deberá haber siempre por lo menos un digito a cada lado del punto.

Átomos. Los átomos (no confundir con las formulas atómicas de la LPO) se utilizan para

dar nombre a objetos especificos, es decir, representan individuos concretos. Existen tres

clases principales de atomos:

- cadenas formadas por letras, digitos y el simbolo de subrayado, que deben empezar necesariamente por una letra minuscula.

Cadenas validas
: f, pepe1, libro33a, libro_blanco.

Cadenas no validas: 1libro, libro-blanco, _hola, Libro.

- cualquier cadena de caracteres encerrada entre comillas simples.

Ejemplos: 'Tomas' 'Juan_Hernandez' 'Jose Lopez Lopez'.

Estos atomos son utiles cuando se necesita trabajar con constantes que empiecen por una letra mayuscula  o por un digito.

- existe además otro tipo de átomos, compuestos por combinaciones especiales de signos, de uso menos común.

Variables

Las variables en Prolog se representan mediante cadenas formadas por letras, dígitos y el símbolo de subrayado, pero deben necesariamente empezar por una letra mayúscula o por un símbolo de subrayado.
Ejemplos: X, Resultado_1, Entrada, _total3, _3bis, _
Las variables que empiezan con un símbolo de subrayado, _, se denominan variables anónimas, y se usan cuando se necesita trabajar con variables cuyos posibles valores no interesan. Su utilidad se describirá mas adelante al analizar la construcción de programas y consultas.

Términos Compuestos
Los términos compuestos, o estructuras, se construyen mediante un símbolo de función, denominado functor, que se denota mediante un átomo, seguido, entre paréntesis, por una serie de términos separados por comas, denominados argumentos.
Ejemplos: fecha(1,mayo,2001), punto(X,Y), recta(punto(1,2), punto(3,5))
Nota: al escribir un término compuesto, no puede haber ningún espacio entre el functor  y el paréntesis abierto previo a los argumentos. Por ejemplo, \punto (X,Y)" no es un termino compuesto correcto y producirá un error de compilación.
Prolog también permite escribir ciertos términos compuestos en forma de operadores, generalmente en notación infija en el caso de functores de aridad 2 y en notacion prefija o postfija enel caso de functores de aridad 1. Este es el caso de los operadores aritméticos predefinidos de
Prolog, que se mencionaran mas adelante, y que permiten escribir terminos compuestos de la forma X+Y o -X en lugar de +(X,Y) o -(X). El programador tambien puede definir sus propios operadores.
Uno de los terminos compuestos mas importantes y utiles  que ofrece Prolog son las listas,secuencias ordenadas de cero o mas elementos, donde los elementos pueden ser cualquier tipode termino. Prolog representa las listas teniendo en cuenta su estructura recursiva:
- la lista vacia se representa mediante el atomo [].
- toda lista no vacia tiene una cabeza (que seria cualquier termino) y un resto (que seria una lista), y se representa mediante un termino compuesto de aridad 2, cuyo functor es unpunto ¢ y cuyos argumentos son, respectivamente, la cabeza y el resto de la lista.
Ejemplos: la lista compuesta por un unico  elemento, la constante a, se representa como “(a;[])".
La lista compuesta por los elementos a; b y c se corresponde con la estructura \¢(a;¢(b;¢(c;[])))".
Dado que la notación anterior puede resultar incomoda a la hora de escribir listas complicadas, Prolog admite también una notación más sencilla que consiste en enumerar entre corchetes todos los elementos de la lista, separados por comas. Con esta notación, las dos listas del ejemplo anterior se representaran, respectivamente, como [a] y [a; b; c]. Prolog también dispone de otra notación para las listas, que consiste en representar la lista con cabeza X y resto Y mediante el termino [X Y ]. Esta última  notación es fundamental para poder separar la cabeza del resto de una lista. Su utilidad en la practica se vera en las clases de problemas.

Estructuras.
Son objetos que tienen varios componentes.
Ejemplo: fecha( 20, agosto, 1992)

fecha recibe el nombre de functor; En este caso todos sus componentes son constantes
pero pueden ser variables ó incluso estructuras. Aunque las estructuras tienen varios
componentes, en los programas Prolog se tratan como objetos únicos. Es decir, en
Prolog, todos los objetos son términos.
Ejemplo: agosto y fecha( 20, agosto, 1992)
son ambos términos.
Todos los objetos estructurados se pueden interpretar como árboles donde el functor es la
raíz del árbol y sus componentes son las hojas del árbol. Si un componente es a su vez
una estructura, entonces será un subárbol del árbol inicial.

Ejemplo. Representación de objetos geométricos simples mediante objetos
estructurados en Prolog:
a). Un punto en un espacio de dos dimensiones se puede definir con dos coordenadas.
b). Un segmento de línea con dos puntos.
c). Un triángulo con tres puntos.
si escogemos como functores a : punto, línea y triángulo; la figura siguiente:

se puede representar con los siguientes términos de Prolog :
P1 = punto(1,1)
P2 = punto(2,3)
S = línea( P1, P2) = línea( punto(1,1), punto(2,3) )
T = triangulo( punto(4,2), punto(6,4), punto(7,1) )


Un functor se define con dos cosas :
1). El nombre.
2). Su aridad (número de argumentos).

Ejercicio. Sugiera una representación para rectángulos, cuadrados y círculos como
objetos Prolog estructurados. Escriba algunos ejemplos que representen objetos físicos
concretos utilizando la representación que sugirió.


referencias
http://arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf
http://www.slideshare.net/njrr/el-lenguaje-de-programacin-prolog-jaume-i-castelln