Você está na página 1de 67

INSTITUTO TECNOLÓGICO DE NUEVO LAREDO

DEPARTAMENTO DE SISTEMAS Y COMPUTACIÓN


INGENIERÍA EN SISTEMAS COMPUTACIONALES

MANUAL DE PRÁCTICAS
de
PROGRAMACIÓN LÓGICA
Y FUNCIONAL

ING. SERGIO GARZA CARRANZA M.C.


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

Nuevo Laredo, Tamaulipas, México. 2014.

CONTENIDO

Objetivo General 3

Práctica 1.1 Mapa conceptual de los diferentes estilos de programación. 4

Práctica 1.2 Evaluación de expresiones. 7

Práctica 1.3 Mapa conceptual de los diferentes tipos de datos 11

Práctica 2.1 Investigación sobre las diferentes versiones del lenguaje LISP 15

Práctica 2.2 Funciones en LISP 18

Práctica 2.3 Predicados en LISP 22

Práctica 2.4 Manejo de listas en LISP 25

Práctica 2.5 Arreglos en LISP 30

Práctica 3.1 Mapa conceptual de la estrategia de evaluación perezosa 35

Práctica 4.1 Mapa conceptual sobre la lógica de primer orden 38

Práctica 4.2 Investigación sobre las diferentes versiones de PROLOG 43

Práctica 4.3 Cláusulas de Horn en PROLOG 48

Práctica 4.4 Consulta de una base de conocimientos 53

Práctica 4.5 Listas en PROLOG 57

Práctica 4.6 Árboles y grafos en PROLOG 61

Práctica 4.7 Predicados metalógicos 65

M.C. Sergio Garza Carranza 2


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

OBJETIVO GENERAL

Proporcionar al estudiante de la materia Programación Lógica y Funcional,


una guía completa para la elaboración de programas basados en lenguajes de
Inteligencia Artificial, como LISP y PROLOG, que complementen los
fundamentos teóricos de la materia; incluyendo la metodología y los
aspectos relativos a la codificación, con el fin de ampliar el conocimiento de
tecnologías alternativas para el desarrollo de sistemas automatizados y la
implementación de agentes inteligentes.

M.C. Sergio Garza Carranza 3


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 1.1

MAPA CONCEPTUAL DE LOS DIFERENTES ESTILOS DE PROGRAMACIÓN.

OBJETIVO.

El estudiante conocerá los principales estilos de programación, así como las ventajas y
desventajas de cada uno de ellos. A través de la elaboración de un mapa conceptual
realizado mediante la herramienta de diseño Cmap Tools.

INTRODUCCIÓN.

En esta práctica se aborda el tema 1.1 del programa de estudios denominado Estilos de
Programación. Además de reforzar los conceptos explicados en el aula, se busca
desarrollar las habilidades de análisis y síntesis así como el manejo de recursos de
cómputo como lo es la herramienta Cmap Tools para la elaboración de mapas
conceptuales.
Estilo de programación (también llamado estándares de código o convención de código)
es un término que describe convenciones para escribir código fuente en ciertos lenguajes
de programación.
El estilo de programación es frecuentemente dependiente del lenguaje de programación
que se haya elegido para escribir.
Los aspectos que normalmente se denominan "estilos de programación" son aspectos
relacionados a los lenguajes de programación como medio de comunicación entre
personas, y que usualmente no influyen en la comunicación humano-máquina. El problema
del estilo es muy recurrente en el desarrollo de software. Muchas veces se escribe el código
pensando que la única persona que lo modificará es el mismo programador; y cuando es
necesario que otra persona revise el código pueden surgir serios problemas.

Si bien es cierto que la meta final del programador es construir programas, el ideal es
construir "buenos" programas. No basta con escribir un programa que funcione. El
código tiene que estar bien escrito.

Las principales cualidades derivadas de un buen estilo de programación son:


● Extensibilidad: La facilidad con que se adapta el software a cambios de especificación.
● Verificabilidad: La facilidad con que pueden comprobarse las propiedades de un
sistema.
● Reparabilidad: la posibilidad de corregir errores sin demasiado esfuerzo.

M.C. Sergio Garza Carranza 4


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

● Capacidad de evolución: la posibilidad de adaptarse a nuevas necesidades.


● Comprensibilidad: la facilidad con que el programa puede ser comprendido.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software Cmap Tools (o similar).
3. Proyector.
4. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Leer los apuntes, identificar las ideas o conceptos principales y escribirlos en una
lista.
2. Ordenar los conceptos desde el más general al más específico en orden
descendiente.
3. Desglosar los conceptos para ver si la idea principal puede ser dividida en dos o
más conceptos.
4. Usar líneas que conecten los conceptos, y escribir sobre cada línea una palabra o
enunciado que aclare por qué los conceptos están conectados entre sí.

Consideraciones Importantes:

• Un mapa conceptual es una forma breve de representar información.


• Un mapa conceptual no tiene que ser simétrico.
• No existe un mapa correcto o perfecto para un grupo de conceptos, los errores
solo ocurren si las relaciones entre los conceptos son incorrectas.

SUGERENCIAS DIDÁCTICAS.

• Formar equipos de 2 o 3 alumnos.


• Mostrar un mapa conceptual de otro tema a manera de ejemplo.
• Explicar los aspectos generales del manejo de la herramienta Cmap Tools.
• Pedir a los alumnos que muestren y expliquen su diseño al resto del grupo

M.C. Sergio Garza Carranza 5


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Mapa conceptual.
5. Conclusiones

BIBLIOGRAFÍA
• NILSSON, N. J. Inteligencia Artificial. Una nueva síntesis. Mc Graw Hill. 2001.
• HRISTOV, ALEXANDER. Manual de Estilos de Programación. Planetalia. 2007

M.C. Sergio Garza Carranza 6


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 1.2

EVALUACIÓN DE EXPRESIONES

OBJETIVO.

El alumno identificará los diferentes tipos de expresiones y sus propiedades, así como los
fundamentos relacionados con la definición, construcción y evaluación de las mismas.

INTRODUCCIÓN.

En esta práctica se aborda el tema 1.2 denominado Evaluación de expresiones. Se busca


reforzar los conocimientos básicos de la carrera, practicar la búsqueda y el análisis de
información, así como la solución de problemas.

Una expresión es una combinación de operadores y operandos de cuya evaluación se


obtiene un valor. Los operandos pueden ser nombres que denoten objetos variables o
constantes, funciones, literales de cualquier tipo adecuado de acuerdo con los operadores
u otras expresiones más simples. La evaluación de una expresión da lugar a un valor de
algún tipo, una expresión se dice que es del tipo de su resultado. Las expresiones se
evalúan de acuerdo con la precedencia de los operadores. Ante una secuencia de
operadores de igual precedencia, la evaluación se realiza según el orden de escritura, de
izquierda a derecha. El orden de evaluación puede modificarse usando paréntesis.

Según sea el tipo de objetos que manipulan, las expresiones se pueden clasificar, en:
• Aritméticas
• Lógicas
• Relacionales
• De caracter.

Las expresiones aritméticas son análogas a las fórmulas matemáticas. Las variables y
constantes son numéricas (reales o enteras) y las operaciones son las aritméticas.

Para las expresiones que tienen dos o más operadores, existen reglas que determinan el
orden de las operaciones. Estas reglas se denominan reglas de prioridad o precedencia, y
son las siguientes:

M.C. Sergio Garza Carranza 7


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

1. Las operaciones encerradas entre paréntesis se evalúan primero. Si existen


paréntesis anidados, las expresiones más internas se realizan primero.
2. Las operaciones aritméticas en una expresión siguen el siguiente orden:
• Operador exponencial (^, ↑, **)
• Operadores * , /
• Operadores div y mod
• Operadores + , -.

3. En caso de coincidir varios operadores de igual prioridad en una expresión o


subexpresión, se aplica el orden de izquierda a derecha.

Las expresiones lógicas o booleanas son aquellas cuyo valor es siempre verdadero o falso.
Recuerde que existen dos constantes lógicas, verdadera (true) y falsa (false) y que las
variables lógicas pueden tomar sólo estos dos valores. Se denominan también expresiones
booleanas en honor del matemático británico George Boole, que desarrolló el álgebra
lógica de Boole.
Las expresiones lógicas se forman combinando constantes lógicas, variables lógicas y otras
expresiones lógicas, utilizando los operadores lógicos not, and y or, y los operadores
relacionales =, <, >, <=, >=, <>.
Los operadores relacionales o de relación, permiten realizar comparaciones de valores
tipo numérico o carácter., y permiten expresar las condiciones en los algoritmos.

Para las expresiones que utilizan caracteres o cadenas de caracteres, se debe tomar en
cuenta el valor numérico de cada caracter con respecto a un código, normalmente el
código ASCII (American Standard Code for Information Interchange) .
Aunque no todas las computadoras siguen el código normalizado en su juego completo de
caracteres, sí son prácticamente estándar los códigos de los caracteres alfanuméricos más
usuales. Estos códigos normalizados son:

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Pizarrón y marcadores
3. Proyector (opcional)
4. Material y apuntes vistos en clase.

M.C. Sergio Garza Carranza 8


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

METODOLOGÍA.

1. Evaluar las siguientes expresiones aritméticas, y explicar paso a paso su procedimiento.

• 3*4–2
• 3 +2*6
• 8+7*3–4*6
• -4 * 7 + 2^3 / 4 – 5

2. Evaluar las siguientes expresiones lógicas y relacionales, y explicar su procedimiento.

• (2<6) or (3>5)
• (6<=3) or (4<>4)
• not(8<3) and (7<9)
• not( (5=5) and (3>7) or not(4<8) )

3. Evaluar las siguientes expresiones lógicas que operan cadenas de caracteres y explique
su procedimiento.

• ‘Pérez’ > ‘Martínez’


• ‘Garza’ > ‘García’
• ‘casa’ = ‘CASA’
• ‘Vázquez’ > ‘Vazquez’
• ‘María de la Luz’ < ‘Ma. de la Luz’

SUGERENCIAS DIDÁCTICAS.

• Formar equipos de 2 o 3 alumnos.


• Pedir a los alumnos que muestren y expliquen sus resultados al resto del grupo
• Realizar pequeños cambios en las expresiones añadiendo o quitando paréntesis y
cambiando operadores para que los alumnos identifiquen el efecto que ocurre en
el resultado de las mismas.

M.C. Sergio Garza Carranza 9


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Ejercicios resueltos con procedimiento incluido
5. Conclusiones

BIBLIOGRAFÍA

• LUIS JOYANES AGUILAR, Fundamentos de Programación, Prentice Hall.


• JESÚS J. GARCÍA MOLINA, Introducción a la programación un Enfoque Algorítmico,
Paraninfo.
• LEOBARDO LÓPEZ ROMÁN, Metodología de la Programación Orientada a Objetos,
Alfaomega.
• CAIRO OSVALDO, Metodología de la Programación, Alfaomega.

M.C. Sergio Garza Carranza 10


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 1.3

MAPA CONCEPTUAL DE LOS DIFERENTES TIPOS DE DATOS

OBJETIVO.

El alumno conocerá y comprenderá la clasificación de los diferentes tipos de datos, así


como sus propiedades y aplicaciones. A través de la elaboración de un mapa conceptual
realizado mediante la herramienta de diseño Cmap Tools.

INTRODUCCIÓN.

En esta práctica se abordan los temas 1.4 y 1.5 del programa de estudio denominados
Disciplina de tipos y Tipos de Datos respectivamente. Además de reforzar los conceptos
explicados en el aula, y los aprendidos en materias anteriores, se busca desarrollar las
habilidades de análisis y síntesis, el trabajo en equipo, y el manejo de recursos de
cómputo.

Datos y Tipos de Datos. La palabra “dato” proviene del latín datum, que significa “lo que
se da”. Un dato es un documento, un evento o un testimonio que permite llegar al
conocimiento de algo o deducir las consecuencias legítimas de un hecho.
En informática, los datos son expresiones generales que describen características de las
entidades sobre las que operan los algoritmos. Estas expresiones deben representarse en
una forma que puedan ser tratadas por una computadora.
Los datos por sí solos no constituyen información, sino que ésta surge del adecuado
procesamiento de los datos.

La mayoría de las computadoras pueden trabajar con varios tipos de datos. Los datos de
entrada se transforman, por medio del programa, en datos de salida.

Existen dos clases de tipos de datos:

- Simples (sin estructura), estos son los siguientes:


• Numéricos (integer, real)
• Lógicos (boolean)
• Carácter (char, string)

- Compuestos (con estructura), por ejemplo:


• Arreglos

M.C. Sergio Garza Carranza 11


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

• Registros
• Listas

Una clasificación más general de los datos es la siguiente:

Datos numéricos.

Los datos numéricos pueden representarse en dos formas distintas:


- enteros (integer), es un subconjunto finito de los números enteros. Los enteros son
números completos, no tienen componentes fraccionarios o decimales y pueden ser
negativos o positivos.
- reales (real), el tipo real consiste en un subconjunto de los números reales. Los números
reales siempre tienen un punto decimal y pueden ser positivos o negativos. Un número
real consta de un entero y una parte decimal.

Datos lógicos (booleanos)


El tipo lógico, también denominado booleano, es aquel dato que sólo puede tomar uno de
los valores: Cierto o verdadero (TRUE) y falso (FALSE)
Este tipo de dato se utiliza para representar las alternativas de (SI/NO), a determinadas
condiciones.

Datos tipo caracter y tipo cadena


El tipo caracter es el conjunto finito y ordenado de caracteres que la computadora
reconoce.
Un dato tipo caracter contiene un solo caracter. La mayoría de las computadoras
reconocen los siguientes caracteres alfabéticos y numéricos:
• Caracteres alfabéticos: (A, B, C, ….., Z) (a, b, c, ….., z)

M.C. Sergio Garza Carranza 12


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

• Caracteres numéricos (1, 2, 3, 4, …, 9, …….)


• Caracteres especiales ( + , - , * , / , ^ , . , ; , < , > , etc)
Una cadena (string) de carateres es una sucesión de caracteres que se encuentran
delimitados por comillas (apóstrofes) o doble comillas, según sea el tipo de lenguaje que
utilicemos al programar.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software Cmap Tools (o similar).
3. Proyector.
4. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Leer los apuntes, identificar las ideas o conceptos principales y escribirlos en


una lista.
2. Ordenar los conceptos desde el más general al más específico en orden
descendiente.
3. Desglosar los conceptos para ver si la idea principal puede ser dividida en dos o
más conceptos.
4. Usar líneas que conecten los conceptos, y escribir sobre cada línea una palabra
o enunciado que aclare por qué los conceptos están conectados entre sí.

SUGERENCIAS DIDÁCTICAS.

• Formar equipos de 2 o 3 alumnos.


• Pedir a los alumnos que muestren y expliquen su diseño al resto del grupo

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Mapa conceptual.
5. Conclusiones

M.C. Sergio Garza Carranza 13


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

BIBLIOGRAFÍA

• LUIS JOYANES AGUILAR, Fundamentos de Programación, Prentice Hall.


• JESÚS J. GARCÍA MOLINA, Introducción a la programación un Enfoque Algorítmico,
Paraninfo.
• LEOBARDO LÓPEZ ROMÁN, Metodología de la Programación Orientada a Objetos,
Alfaomega.
• CAIRO OSVALDO, Metodología de la Programación, Alfaomega.

M.C. Sergio Garza Carranza 14


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 2.1

INVESTIGACIÓN SOBRE LAS DIFERENTES VERSIONES DEL LENGUAJE LISP.

OBJETIVO.

El alumno conocerá las principales versiones del lenguaje LISP, e identificará las ventajas y
desventajas de cada versión.
INTRODUCCIÓN.

Esta práctica corresponde a la unidad 2 del programa de estudio, denominada


Programación Funcional. Debido a que los temas siguientes se explicarán utilizando el
lenguaje de programación LISP, en esta práctica se investigan diferentes versiones del
lenguaje, para conocer las principales características de cada una y seleccionar la que
mejor se acomode a nuestras necesidades y recursos.

La programación funcional es un paradigma de programación declarativa basado en la


utilización de funciones aritméticas que no maneja datos mutables o de estado. Enfatiza la
aplicación de funciones, en contraste con el paradigma de programación imperativa, que
enfatiza los cambios de estado. La característica principal de la programación funcional es
que los cálculos se ven como una función matemática que hacen corresponder entradas y
salidas.

La programación funcional tiene sus raíces en el cálculo lambda, un sistema formal


desarrollado en los años 1930s para investigar la definición de función, la aplicación de las
funciones y la recursión. Muchos lenguajes de programación funcionales pueden ser vistos
como elaboraciones del cálculo lambda.

Características generales

• No hay noción de posición de memoria y por tanto, necesidad de una instrucción


de asignación.
• Los bucles se modelan a través de la recursividad ya que no hay manera de
incrementar o disminuir el valor de una variable.
• Como aspecto práctico casi todos los lenguajes funcionales soportan el concepto
de variable, asignación y bucle. Estos elementos no forman parte del modelo
funcional “puro”.

LISP es uno de los principales lenguajes de programación del paradigma funcional.

M.C. Sergio Garza Carranza 15


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

Fue desarrollado por John McCarthy, en 1958. LISP es un lenguaje maduro, aplicable a
diversos escenarios, tales como: Robótica, Inteligencia Artificial, Procesamiento de
lenguaje natural y Demostración automática de teoremas.

El nombre de LISP es un acrónimo de LISt Processing. Las características principales de


LISP son:
• Todo programa consiste en una función.
• No posee asignaciones.
• Su principal estructura de control es la recursión.
• Los programas y los datos son equivalentes.
• Su principal estructura de datos es la lista.
• La memoria es asignada por demanda.

Lisp es un lenguaje de notación prefija (polaca), es decir que los operadores van delante
de los operandos, por ejemplo:
• 2+3  (+ 2 3)
• 4*3*2  (* 4 3 2)
• 2+3*5  (+ 2 (* 3 5))

Cualquier sistema LISP, incluye una interfaz interactiva llamada top-level. Uno escribe
expresiones LISP en el top-level, y el sistema despliega sus valores. El sistema
normalmente despliega un indicador llamado prompt (>) señalando que está esperando
que una expresión sea escrita.

Por ejemplo, si escribimos el entero 1 después del prompt y tecleamos enter, tenemos:

El sistema despliega el valor de la expresión, seguida de un nuevo prompt, indicando que


está listo para evaluar una nueva expresión. En este caso, el sistema desplegó lo mismo
que tecleamos porque los números, como otras constantes, evalúan a sí mismos.

MATERIAL Y EQUIPO.

1. Computadora personal con acceso a internet.


2. Proyector.
3. Material y apuntes vistos en clase.

METODOLOGÍA.

M.C. Sergio Garza Carranza 16


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

1. Investigar la versión de LISP designada por el maestro.


2. Explicar y mostrar al grupo las características principales de la versión.
3. Explicar el entorno de desarrollo y la forma de escribir un programa.
4. Realizar un programa sencillo a manera de ejemplo.

SUGERENCIAS DIDÁCTICAS.

• Formar equipos de 2 o 3 alumnos.


• Realizar una lista de las versiones más comunes de LISP y sortearlas entre los
equipos.
• Hacer que los equipos expongan al grupo su investigación y proponer un debate en
el que “defiendan” su versión asignada.

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Características de la versión de LISP
5. Ventajas y desventajas.
6. Programa de ejemplo.
7. Conclusiones

BIBLIOGRAFÍA

• FOKKER, Jeroen. Programación Funcional. Universidad de Utrecht, Departamento


de Informática. 1995.
• MCCARTHY, J. LISP 1.5 Programmer’s Manual. The MIT Press. 1962
• SEIBEL, P. Practical Common Lisp. USA: Apress. 2005.
• GRAHAM, P. On Lisp: Advanced Techniques for Common Lisp. Prentice Hall. 1993.

M.C. Sergio Garza Carranza 17


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 2.2

FUNCIONES EN LISP

OBJETIVO.

El alumno comprenderá las características de las funciones en LISP. Implementará


funciones básicas y evaluará sus resultados.

INTRODUCCIÓN.

En esta práctica se abordan los temas 2.1 y 2.2 del programa de estudio, denominados El
tipo de datos y Funciones respectivamente. Se busca que el alumno comprenda la lógica
de LISP al realizar funciones sencillas y comprobar sus resultados.

Toda expresión LISP es un átomo, o bien es una lista que consiste de cero o más
expresiones delimitadas por paréntesis. La expresión (+ 2 3) es una lista, en la cual el
operador + es en realidad el nombre de una función, mientras que 2 y 3 son los
argumentos. La expresión (+ 2 3) es una llamada a la función suma.

Cuando LISP evalúa una llamada a alguna función, lo hace en dos pasos:

1. Los argumentos de la llamada son evaluados de izquierda a derecha. En este caso, los
valores de los argumentos son 2 y 3, respectivamente.

2. Los valores de los argumentos son pasados a la función nombrada por el operador. En
este caso la función + que regresa 5.

Si alguno de los argumentos es a su vez una llamada de función, será evaluado con las
mismas reglas. Por ejemplo, al evaluar la expresión (/ (- 7 1) (- 4 2)) pasa lo siguiente:

1. LISP evalúa el primer argumento de izquierda a derecha (- 7 1). Los valores 7 y 1


son pasados a la función - , que regresa 6.

2. El siguiente argumento (- 4 2) es evaluado. Los valores 4 y 2 son pasados a la


función - , que regresa 2.

M.C. Sergio Garza Carranza 18


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

3. Los valores 6 y 2 son pasados a la función /, que regresa 3.

No todos los operadores en LISP son funciones, pero la mayoría lo son. Todas las llamadas
a función son evaluadas de esta forma, que se conoce como regla de evaluación de LISP.
Los operadores que no siguen la regla de evaluación se conocen como operadores
especiales. Uno de estos operadores especiales es quote (’).
La regla de evaluación de quote es: No evalúes nada, despliega lo que el usuario escribió.
Por ejemplo:

LISP provee el operador quote como una forma de evitar que una expresión sea evaluada.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software XLISP-PLUS versión 3.05 o más nueva.
3. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Resolver los siguientes ejemplos en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejemplos.

1. Definir una función que devuelva la longitud de una circunferencia, dando como
parámetro el radio R de la misma siendo L = 2 π R
2. Definir una función que pase de grados Fahrenheit a grados centígrados, sabiendo
que: C = F -32 * 5/9
3. Definir una función que, dados tres argumentos numéricos, devuelva cuál es el
mediano, utilizando MAX y MIN.
4. Definir una función que devuelva el área de un triángulo, dando como parámetros
su base y su altura.
5. Definir una función GRADO que reciba una calificación C y devuelva un mensaje de
acuerdo a lo siguiente:
100 Excelente

M.C. Sergio Garza Carranza 19


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

90-99 Notable
80-89 Bien
70-79 Suficiente
<70 Deficiente

Soluciones.

1. (DEFUN long_circ (radio)


(* 2 3.1416 radio)
)

2. (DEFUN f-c (f)


(* (- f 32) (FLOAT (/ 5 9)))
)

3. (DEFUN mediano (a b c)
(- (+ a b c) (MAX a b c) (MIN a b c))
)

4. (DEFUN at (b h)
(/ (* b h) 2)
)

5. (DEFUN grado (c)


(COND
((= c 100) 'Excelente)
((> c 90) 'Notable)
((> c 80) 'Sobresaliente)
((>= c 70) 'Suficiente)
(T 'Deficiente)
)
)

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplos resueltos.
5. Conclusiones

M.C. Sergio Garza Carranza 20


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

BIBILOGRAFÍA

• TOURETZKY, DAVID S. Common Lisp: A Gentle Introduction to Symbolic


Computation. Carnegie Mellon University, 1990.
• MCCARTHY, J. LISP 1.5 Programmer’s Manual. The MIT Press. 1962
• SEIBEL, P. Practical Common Lisp. USA: Apress. 2005.
• GABRIEL, RICHARD P. Performance and Evaluation of LISP Systems. The MIT Press.
1985

M.C. Sergio Garza Carranza 21


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 2.3

PREDICADOS EN LISP

OBJETIVO.

El alumno comprenderá el concepto de predicado y su aplicación en LISP, e implementará


predicados básicos y evaluará sus resultados.

INTRODUCCIÓN.

En esta práctica se aborda un tipo especial de funciones del tema 2.1 del programa de
estudio, denominados Predicados. Se busca que el alumno practique la implementación
de predicados a través de ejemplos sencillos y que conozca los diferentes tipos de
predicados que incluye el propio lenguaje.

Un predicado puede representarse en LISP como una función que retorna un valor de
verdad. Se adopta la convención de que NIL denota falso, y que cualquier otra s-expresión
denota verdadero. Por ejemplo:

NIL equivale a falso.


T equivale a verdadero.
(+ 2 2) equivale a verdadero.

Además de los predicados lógicos tradicionales AND, OR y NOT, el lenguaje LISP cuenta
con algunos otros predicados, entre los más comunes tenemos:

(ATOM arg) Devuelve T si arg es un átomo


(NUMBERP arg) Devuelve T si arg es un número
(ZEROP arg) Devuelve T si arg es el número cero
(PLUSP arg) Devuelve T si arg es un número positivo
(MINUS arg) Devuelve T si arg es un número negativo
(SYMBOLP arg) Devuelve T si arg es un símbolo

También se tienen los predicados relacionales comunes >, <, >=, <=, =. Por ejemplo:

M.C. Sergio Garza Carranza 22


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

(< a1 a2….an) Devuelve T si a1 es menor que a2 y a2 es menor que an

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software XLISP-PLUS versión 3.05 o más nueva.
3. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Resolver los siguientes ejemplos en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejemplos.

1. Definir un predicado ADOLECENTE que devuelva T si el número recibido como


parámetro (edad) está entre 12 y 17.
2. Definir un predicado DOBLE que reciba dos números y devuelva T si el primero es
el doble del segundo.
3. Definir un predicado que dados A, B y C como argumentos devuelva T si B2 - 4AC es
menor que cero.
4. Definir un predicado que determine si un número es divisible por 3 utilizando la
función REM, que dados dos parámetros enteros, devuelve el residuo de la
división.
5. Definir un predicado que reciba los parámetros A, B y C y devuelva T si A2+B2>C2

Soluciones.

1. (DEFUN adolecente (edad)


(AND (<= edad 17) (>= edad 12))
)
2. (DEFUN doble (a b)
(= (* b 2) a)
)
3. (DEFUN cuadratica (a b c)
(< (- (* b b) (* 4 a c)) 0)
)
4. (DEFUN div3 (n)

M.C. Sergio Garza Carranza 23


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

(= (REM n 3) 0)
)
5. (DEFUN tr (a b c)
(> (+ (* a a) (* b b)) (* c c))
)

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplos resueltos.
5. Conclusiones

BIBILOGRAFÍA

• TOURETZKY, DAVID S. Common Lisp: A Gentle Introduction to Symbolic


Computation. Carnegie Mellon University, 1990.
• MCCARTHY, J. LISP 1.5 Programmer’s Manual. The MIT Press. 1962
• SEIBEL, P. Practical Common Lisp. USA: Apress. 2005.
• GABRIEL, RICHARD P. Performance and Evaluation of LISP Systems. The MIT Press.
1985

M.C. Sergio Garza Carranza 24


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 2.4

MANEJO DE LISTAS EN LISP

OBJETIVO.

El alumno conocerá el concepto de lista y su implementación en LISP, elaborará


programas utilizando listas para resolver problemas sencillos en LISP.

INTRODUCCIÓN.

Esta práctica aborda el tema 2.5 del programa de estudio, denominado Aplicaciones de las
listas. Se busca que el alumno conozca el concepto de listas en LISP, las principales
funciones de manejo de listas que incluye el lenguaje, y que practique la implementación
de listas mediante la elaboración de programas sencillos.

LISP es un lenguaje diseñado para el tratamiento de listas. En una lista se puede acceder
fácilmente a los elementos de la misma. Las listas se construyen internamente utilizando
“celdas cons”. Cada celda está formada por dos punteros: CAR y CDR.

Internamente una lista cualquiera (A B C) tiene la siguiente representación:

NIL → Símbolo especial que indica el final de la lista


CAR → nombre de la función que devuelve el primer elemento de la lista
CDR → nombre de la función que devuelve el resto de la lista

Las listas se representan como cero o más elementos entre paréntesis. Los elementos
pueden ser de cualquier tipo, incluidas las listas. Se debe usar quote con las listas, ya que
de otra forma Lisp las tomaría como una llamada a función. Veamos algunos ejemplos:

>’ (Mis 2 "ciudades")  (MIS 2 "CIUDADES")


>’ (La lista (a b c) tiene 3 elementos)  (LA LISTA (A B C) TIENE 3 ELEMENTOS)

M.C. Sergio Garza Carranza 25


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

También es posible construir listas usando la función LIST:

> (LIST ’mis (+ 4 2) "colegas")  (MIS 6 COLEGAS)

Algunas de las funciones de manipulación de listas más comunes son las siguientes:

(SETF lista ‘(a b (c d e) f (g h) i j k)) (A B (C D E) F (G H) I J K)


(LENGTH lista) 8
(THIRD lista) (C D E)
(CAR (CDR (CDR (CAR (CDR (CDR lista)))))) E
(CADR (CDADDR lista)) forma abreviada (máx. 4) E
(NTHCDR 4 lista) ((G H) I J K)
(LAST lista) (K)
(SUBST 'X 'A '(A B A C A D A E)) (X B X C X D X E)
(SUBST <nuevo> <viejo> <lista>) Substituye con <nuevo> todas
las apariciones de <viejo> en
<lista>

Funciones de mapeo sobre listas


Si se tiene una lista, y se desea realizar operaciones o modificaciones para cada elemento
de dicha lista, obteniendo otra de la misma longitud, se puede utilizar una función de
mapeo. MAPCAR es la más común de tales funciones. MAPCAR toma una función y una o
más listas, y aplica esa función a cada elemento de la lista, produciendo una nueva lista
resultante. Por ejemplo:

> (SETF lista '(1 2 3 4 5))


LISTA

> (DEFUN doble (n) (* n 2))


DOBLE

> (SETF lista (MAPCAR #'doble lista))


(2 4 6 8 10)

Función LAMBDA

Para no tener que definir funciones cada vez, existe la función "sin nombre" lambda, que
puede pasarse como argumento a MAPCAR, ahí mismo donde se define. Para el ejemplo
de la función doble, sería así:

(DEFUN doble (lista)

M.C. Sergio Garza Carranza 26


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

(MAPCAR #‘(LAMBDA (n) (* n 2)) lista)


)

Función MAPLIST

MAPLIST es similar a MAPCAR excepto que la función es aplicada a la lista completa y a


los sucesivos restos (cdr´s) de la lista, en lugar de a cada elemento individualmente.

Ejemplo:

>(MAPLIST #'(LAMBDA (x) (CONS ‘uno x)) '(a b c d))


>((UNO A B C D) (UNO B C D) (UNO C D) (UNO D))
>(MAPCAR #'(LAMBDA (x) (CONS 'uno (LIST x))) '(a b c d))
>((UNO A) (UNO B) (UNO C) (UNO D))

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software XLISP-PLUS versión 3.05 o más nueva.
3. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Resolver los siguientes ejemplos en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejemplos.

1. Definir una función que tenga por argumento una lista y devuelva el tercer
elemento de dicha lista.
2. Definir una función que tenga por argumento una lista y devuelva otra lista con el
primer y último elemento.
3. Escribir una función que reciba una lista de números y retorne una lista con una
sublista de los pares y otra sublista con los impares.
4. Definir una función que dados tres números X, Y y Z, devuelva una lista con los
números ordenados por orden creciente.
5. Defina una función que reciba una lista de n números y calcule el promedio.

M.C. Sergio Garza Carranza 27


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

Soluciones.

1. (DEFUN tercero (lista)


(THIRD lista)
)

2. (DEFUN pyu (lista)


(LIST (CAR lista)(CAR (LAST lista)))
)

3. (DEFUN pares-impares (l)


(SETF imp '())
(SETF par '())
(DOLIST (x l)
(if (ODDP x)
(SETF imp (CONS x imp))
(SETF par (CONS x par))
)
)
(LIST par imp)
)

4. (DEFUN ordena3 (x y z)
(SETF lo '())
(SETF lo (CONS (MAX x y z) lo))
(SETF lo (CONS (medio x y z) lo) )
(SETF lo (CONS (MIN x y z) lo))
)
(DEFUN medio (x y z)
(- (+ x y z) (MAX x y z) (MIN x y z))
)

5. (DEFUN promedio (lista)


(SETF lista2 (CONS '+ lista))
(SETF suma (EVAL lista2))
(SETF prom (/ suma (LENGTH lista)))
)

M.C. Sergio Garza Carranza 28


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplos resueltos.
5. Conclusiones

BIBILOGRAFÍA

• TOURETZKY, DAVID S. Common Lisp: A Gentle Introduction to Symbolic


Computation. Carnegie Mellon University, 1990.
• MCCARTHY, J. LISP 1.5 Programmer’s Manual. The MIT Press. 1962
• SEIBEL, P. Practical Common Lisp. USA: Apress. 2005.
• GABRIEL, RICHARD P. Performance and Evaluation of LISP Systems. The MIT Press.
1985

M.C. Sergio Garza Carranza 29


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 2.5

ARREGLOS EN LISP

OBJETIVO.

El alumno comprenderá el concepto de arreglos en LISP así como sus aplicaciones, e


Implementará programas que resuelvan problemas sencillos mediante el manejo de
arreglos.

INTRODUCCIÓN.

Para abordar el tema 2.6 del programa de estudio denominado Árboles, en esta práctica
es necesario introducir el concepto de arreglos para implementar árboles, se trata
también el concepto de conjunto, y se plantean programas que requieren su
implementación.

Los arreglos son estructuras de datos que pueden almacenar valores en posiciones de
memoria simples o multi-dimensionales, que son indexadas por uno o más enteros. Los
arreglos soportan un acceso muy rápido a los datos basado en índices de enteros. Se
crean arreglos empleando la función constructora MAKE-ARRAY y los elementos del
arreglo se refieren usando la función de acceso AREF. Se pueden establecer elementos
individuales en el arreglo usando SETF:

> (SET 'array (MAKE-ARRAY (LIST 3 3)))


#2A((NIL NIL NIL) (NIL NIL NIL) (NIL NIL NIL))

> (SETF (AREF array 0 0) "Uno")


"Uno"

> (SETF (AREF array 0 1) "Dos")


"Dos"

> (AREF array 0 0)


"Uno"

M.C. Sergio Garza Carranza 30


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

> (AREF array 0 1)


"Dos"

La función MAKE-ARRAY también admite varios argumentos de palabras clave optativos


para inicializar el arreglo en el momento de su creación. Uno de ellos es :INITIAL-
CONTENTS que permite establecer los valores iniciales:

> (MAKE-ARRAY '(4 2 3)


:INITIAL-CONTENTS
'(((a b c) (1 2 3))
((d e f) (3 1 2))
((g h i) (2 3 1))
((j k l) (0 0 0))))
#3A(((A B C) (1 2 3)) ((D E F) (3 1 2)) ((G H I) (2 3 1)) ((J K L) (0 0 0)))

Se trata de un arreglo de tres dimensiones: 4 x 2 x 3.

Observe la respuesta del intérprete al crear el arreglo: Comienza con las dimensiones #3A
(A es el tipo del arreglo) y luego los elementos como listas anidadas.

Árboles Binarios en LISP

En LISP, todos los datos en memoria se estructuran mediante pares conocidos como
nodos. Por ejemplo, los elementos a y b se almacenan en un nodo a b

Para acceder al elemento de la izquierda se utiliza CAR, y para acceder al elemento de la


derecha se utiliza CDR:

> (CAR ‘(a b))  a


> (CDR ‘(a b))  (b) Note que CDR devuelve también una lista

Ejemplo:
1
1
> (SETQ arbol ‘ (1 (2) 3))
(1 (2) 3)

2 3 2 3

NIL NIL

M.C. Sergio Garza Carranza 31


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

A la variable arbol se le asigna el arbol binario.


Por convención el elemento de la izquierda del nodo tendrá el valor y el elemento de la
derecha apuntará hacia otro nodo, o bien apunta a NIL.

Para acceder a la raíz usamos CAR:


> (CAR arbol)
1
Para acceder al nodo 2, primero usamos un (CDR arbol), que nos sitúa en el nodo que
contiene las direcciones de los nodos (2 . nil) y (3 . nil). Luego un CAR (que lo envuelve) nos
lleva al nodo (2 . nil). Por último un CAR devolverá el elemento 2.

Funciones sobre conjuntos


Un conjunto se define como una lista sin elementos repetidos. Por ejemplo, (A B C) es un
conjunto; pero, (A B A C) no lo es. Además, el orden de los elementos de un conjunto no
es esencial, por lo que (A B C) y (A C B) representan el mismo conjunto.

Función UNION. Devuelve la unión de dos conjuntos.


(UNION C1 C2)
Devuelve los elementos que están en C1 o C2
>(UNION ‘(A B C D) ‘(C D E F))
>(F E A B C D)

Función INTERSECTION. Devuelve la intersección de dos conjuntos.


(INTERSECTION C1 C2)
Devuelve los elementos que están en C1 y C2
>(INTERSECTION ‘(A B C D) ‘(C D E F))
>(D C)

MATERIAL Y EQUIPO.|

1. Computadora personal.
2. Software XLISP-PLUS versión 3.05 o más nueva.
3. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Resolver los siguientes ejemplos en forma individual.

M.C. Sergio Garza Carranza 32


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

2. Revisar los resultados y proponer mejoras.


3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejemplos.

1. Escribir una función que permita leer los elementos de una matriz de n x m.
2. Definir una función REDUCE-CONJUNTO que tome una lista y elimine los
elementos repetidos; es decir, que la convierta en conjunto. Por ejemplo,
(REDUCE-CONJUNTO ' (A B A C))  (B A C)
3. Definir un predicado CIGUALES que determine si dos conjuntos son iguales.
Recuerde que en un conjunto, el orden de los elementos no es esencial.
4. Definir una función que devuelva el número de elementos de un árbol dado como
argumento. (N-ELEM '(A (B C) (C (A)) E)) 6
5. Definir (PROFUNDIDAD L) que devuelva el número de niveles que existen en L; es
decir, el número de arcos de la raíz a la hoja más lejana. Por ejemplo,
(PROFUNDIDAD '(A (B C) (D (A)) E))  3

Soluciones.

1. (defun leematriz (n m)
(setf a (make-array n))
(dotimes (x n)
(setf (aref a x) (make-array m))
)
(dotimes (i n)
(dotimes (j m)
(format t "Elemento [ ~a , ~a ]:" (+ i 1) (+ j 1))
(setf (aref (aref a i) j) (read))
)))

2. (defun reduce-conjunto (l)


(cond ((atom l) l)
((member (car l) (cdr l))
(reduce-conjunto (cdr l)))
(t (cons (reduce-conjunto (car l))
(reduce-conjunto (cdr l))))))

3. (defun igual-conj (c1 c2)


(cond ((null c1) (null c2))
((member (car c1) c2)

M.C. Sergio Garza Carranza 33


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

(igual-conj (cdr c1) (remove (car c1) c2)))


(t ())))

4. (defun N-ELEM (l)


(length (linealiza l)))
(defun N-ELEM (l)
(cond ((null l) 0)
((atom l) 1)
((atom (car l)) (1+ (N-ELEM (cdr l))))
(t (+ (N-ELEM (car l))
(N-ELEM (cdr l)) ))))

5. (defun PROFUNDIDAD (l)


(cond ((atom l) 0)
(t (max (1+ (PROFUNDIDAD (car l)))
(PROFUNDIDAD (cdr l)) ))))

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplos resueltos.
5. Conclusiones

BIBILOGRAFÍA

• TOURETZKY, DAVID S. Common Lisp: A Gentle Introduction to Symbolic


Computation. Carnegie Mellon University, 1990.
• MCCARTHY, J. LISP 1.5 Programmer’s Manual. The MIT Press. 1962
• SEIBEL, P. Practical Common Lisp. USA: Apress. 2005.
• GABRIEL, RICHARD P. Performance and Evaluation of LISP Systems. The MIT Press.
1985

M.C. Sergio Garza Carranza 34


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 3.1

MAPA CONCEPTUAL DE LA ESTRATEGIA DE EVALUACIÓN PEREZOSA

OBJETIVO.

El alumno conocerá los fundamentos de la estrategia de evaluación perezosa, sus ventajas


y desventajas, y la diferencia con las estrategias de evaluación tradicionales. A través de
la elaboración de un mapa conceptual realizado mediante la herramienta de diseño Cmap
Tools.

INTRODUCCIÓN.

En esta práctica se aborda el tema 3.1 del programa de estudio, denominado La Estrategia
de Evaluación Perezosa. Además de reforzar los conceptos explicados en el aula, se busca
desarrollar las habilidades de análisis y síntesis así como el manejo de recursos de
cómputo como lo es la herramienta Cmap Tools para la elaboración de mapas
conceptuales.

Evaluación Impaciente vs. Perezosa

En el modelo de evaluación de los lenguajes funcionales, el usuario introduce una


expresión que es evaluada por el sistema. La evaluación consiste en buscar
subexpresiones dentro de la expresión que puedan transformarse utilizando las funciones
predefinidas y las funciones definidas por el usuario. Cuando no es posible realizar más
transformaciones se dice que se ha alcanzado la forma normal.
Existen dos estrategias fundamentales de evaluación: evaluación aplicativa y evaluación
normal.
En la evaluación aplicativa, se eligen las subexpresiones más internas de la expresión,
mientras que en la evaluación normal, se eligen las subexpresiones más externas.

Supóngase que se definen las funciones


> cuad x = x * x
> prim (x,y) = x

M.C. Sergio Garza Carranza 35


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

Para evaluar prim (cuad 3,cuad 4)

Con evaluación aplicativa, se evalúan primero los argumentos, obteniendo la secuencia


prim (cuad 3, cuad 4)
= prim (3 * 3, cuad 4)
= prim (9, cuad 4)
= prim (9, 4 * 4)
= prim (9,16)
=9

Con evaluación normal, se evalúan primero las llamadas a la función, obteniendo:


prim (cuad 3, cuad 4)
= cuad 3
=3*3
=9

Como puede observarse, el primer esquema tarda más ya que puede haber argumentos
que no se utilizan en el resultado y, sin embargo, son evaluados.
Este tipo de modelo también se conoce como evaluación impaciente (del inglés eager) o
estricta. En casos extremos, si alguno de dichos argumentos produce un error (por
ejemplo, una división por cero), o no finaliza, el sistema no devolvería el resultado
adecuado.

Por ejemplo, al evaluar prim (cuad 3, 1/0)


Con evaluación aplicativa
prim (cuad 3, 1 / 0)
= prim (3 * 3, 1 / 0)
= prim (9, 1 / 0)
= Error, división por cero...
• Con evaluación normal, se obtiene
prim (cuad 3, 1 / 0)
= cuad 3
=3*3
=9
La estrategia de evaluación aplicativa también se conoce como llamada por valor (call by
value). Ya que se evalúan primero los argumentos de la función y se le pasan a la función
sus valores.
La estrategia de evaluación normal se conoce como llamada por nombre (call by name),
indicando que se pasan las expresiones, en lugar de sus valores. Dichas expresiones no son
evaluadas si no se necesita su valor.
En ocasiones, la llamada por nombre puede hacer que ciertas subexpresiones se evalúen
más de una vez. Por ejemplo:
cuad (5 + 2)

M.C. Sergio Garza Carranza 36


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

= (5+2) * (5 + 2)
= 7 * (5 + 2)
=7*7
= 49
La evaluación perezosa permite solucionar este problema mediante una reducción
basada en un grafo. Por ejemplo, para la expresión anterior se utilizaría la siguiente
secuencia
cuad (5 + 2)
= x * x donde x = 5 + 2
= x * x donde x = 7
= 49

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software Cmap Tools (o similar).
3. Proyector.
4. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Leer los apuntes, identificar las ideas o conceptos principales y escribirlos en


una lista.
2. Ordenar los conceptos desde el más general al más específico en orden
descendiente.
3. Desglosar los conceptos para ver si la idea principal puede ser dividida en dos o
más conceptos.
4. Usar líneas que conecten los conceptos, y escribir sobre cada línea una palabra
o enunciado que aclare porqué los conceptos están conectados entre sí.

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Mapa conceptual.
5. Conclusiones

BIBLIOGRAFÍA

M.C. Sergio Garza Carranza 37


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

• JOSÉ EMILIO LABRA GAYO. Programación Funcional. Recuperado de


www.di002.edv.uniovi.es
• GUSTAVO RAMIRO RIVADERA (2008). La Programación Funcional: Un Poderoso
Paradigma. Recuperado de www.ucasal.edu.ar

PRÁCTICA 4.1

MAPA CONCEPTUAL SOBRE LA LÓGICA DE PRIMER ORDEN

OBJETIVO.

El alumno identificará los conceptos básicos de la programación lógica y de la lógica de


primer orden. A través de la elaboración de un mapa conceptual realizado mediante la
herramienta de diseño Cmap Tools.

INTRODUCCIÓN.

Esta práctica consiste en una introducción a la unidad 4 del programa de estudios


denominada Fundamentos de la Programación Lógica, particularmente aborda los temas
4.1 y 4.2. Se busca consolidar los conceptos explicados en el aula, desarrollar las
habilidades de análisis y síntesis así como reforzar el manejo de recursos de cómputo
como la herramienta Cmap Tools para la elaboración de mapas conceptuales.

La Programación Lógica fue propuesta por Kowalski en 1974, y facilita la tarea de


programación liberando al programador al hacer una optimización de las dos
componentes básicas de un algoritmo: Lógica y Control.
Consiste en la aplicación del conocimiento sobre lógica para el diseño de lenguajes de
programación y se ha convertido en el pilar de una nueva generación de lenguajes de
programación. Junto con la programación funcional forma parte de lo que se conoce
como programación declarativa.
Mientras que en los lenguajes tradicionales se intenta resolver un problema mediante
sentencias, en la programación lógica se trabaja de forma descriptiva, estableciendo
relaciones, y no indicando un cómo sino un qué hacer. Es decir el algoritmo que se quiera
diseñar se construye especificando un conocimiento en un lenguaje formal y para
resolverlo se uso la inferencia o control que actúa sobre aquel.
Su principal uso se basa en las aplicaciones de inteligencia artificial como: sistemas
expertos, demostración automática y reconocimiento de lenguaje natural, entre otras.
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.

M.C. Sergio Garza Carranza 38


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

La lógica proposicional sólo puede representar hechos acerca del mundo. La lógica de
primer orden describe un mundo que consta de objetos y propiedades (o predicados) de
esos objetos. Una función es una relación en la cual sólo hay un valor para un objeto dado.

Ejemplos:
Objetos: gente, casas, números, planetas,...
Relaciones: progenitor, hermano-de, mayor-que,...
Propiedades: rojo, pequeño, primo,...
Funciones: padre-de, uno-más-que….

La lógica de primer orden es universal porque puede expresar cualquier cosa que pueda
ser programada.

Sintaxis y semántica

La lógica de primer orden tiene sentencias como la lógica proposicional y además, tiene
términos, que representan objetos. Para construir términos se usan símbolos constantes,
variables y funciones; y para construir sentencias, se utilizan cuantificadores y predicados.

Símbolos constantes: A, B, C, 1, Juan,...

Cada símbolo constante nombra a exactamente un objeto en el mundo, no todos los


objetos necesitan tener nombres y algunos pueden tener más de un nombre.

Símbolos predicado: Vecino, Hermano,...

Un símbolo predicado se refiere a una relación particular en el modelo. Por ejemplo,


Hermano; dado que Hermano es un símbolo de relación binaria, la relación a que se
refiere debe ser también binaria, es decir, debe darse o fallar entre pares de objetos.

Símbolos de función: Coseno, Padre_de, Pierna_izquierda_de

Una relación funcional relaciona un objeto a exactamente otro único objeto. El último
elemento en la tupla es el valor de la función para los otros elementos. Por Ejemplo:
Padre_de (María, José).

Términos

Un término es una expresión lógica que se refiere a un objeto. Los símbolos constantes
son términos. Los términos también se pueden construir a partir de símbolos de funciones
y símbolos de constantes, ej., Padrede (Juan).

M.C. Sergio Garza Carranza 39


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

La semántica formal de los términos es la siguiente: Una interpretación especifica una


relación funcional referida por el símbolo función y objetos referidos por los símbolos
constantes. En consecuencia, un término función se refiere al objeto n+1 en una tupla
cuyos primeros n elementos son aquellos referidos por los argumentos de la función.

Sentencias atómicas

Una sentencia atómica está formada por un símbolo predicado seguido por una lista entre
paréntesis de términos, por ejemplo, Hermano (Roberto, Juan) indica que el objeto
referido por Roberto es el hermano del objeto referido por Juan.

Las sentencias atómicas pueden tener argumentos que son términos complejos: Casado
(Padrede (Roberto), Madrede (Juan))

Sentencias complejas

Podemos usar conectores lógicos para construir sentencias más complejas. La semántica
de éstas es la misma usada en lógica proposicional.

Ejemplos:

Hermano (Roberto, Juan) ∧ Hermano (Juan, Roberto) es verdad en el caso en que Juan es
hermano de Roberto y Roberto es hermano de Juan.

Mayor (Juan, 30) ∨ Menor (Juan, 30) es verdad cuando Juan es mayor de 30 o es menor
que 30.

Cuantificadores

Nos permiten expresar propiedades de colecciones de objetos. Hay dos cuantificadores en


lógica de primer orden: universal y existencial.

Cuantificación universal (∀)

Usando esta cuantificación podemos decir cosas tal como, “Todos los hámsteres son
mamíferos." ∀x Hamster(x) ⇒Mamifero(x)

En consecuencia, una sentencia ∀x Φ(x) es verdad en un modelo solo si Φ es verdad para


todos los objetos en el modelo.

Notar la diferencia entre ∀x Hamster(x)⇒Mamifero(x) y ∀x Hamster(x)∧Mamifero(x)

Las afirmaciones universales son verdad si son verdad para cada individuo en el mundo. Se
pueden pensar como una conjunción infinita.

M.C. Sergio Garza Carranza 40


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

Cuantificación existencial ∃x

Realiza afirmaciones acerca de al menos algún objeto. Para decir, por ejemplo que
Mancha tiene una hermana que es un hamster, escribimos ∃x Hermana(x,mancha) ∧
Hamster(x)

∃x P es verdad si P es verdad para algún objeto en el mundo. Se puede pensar como una
disyunción infinita.

Cuantificadores anidados

Se pueden realizar afirmaciones muy complejas si se anidan cuantificadores. Sin mezclar


tipos de cuantificadores, podemos decir cosas como

∀x,y Progenitor(x,y) ⇒ Hijo(y,x)

También podemos mezclar cuantificadores, ∀x∃y Buenopara(x,y) “Todos somos buenos


para alguna cosa"

Conexiones entre ∀ y ∃

Hay una íntima conexión entre los dos cuantificadores. Para ver esto, considerar la
sentencia ∀x ¬Gusta(x,LideresDecepcionantes)

“Para todo x, x no gusta de los líderes decepcionantes."

Otra forma de decir esto es, “No existe un x que guste de los líderes decepcionantes.“
¬∃x Gusta(x,LideresDecepcionantes)

Esto es verdad en general porque ∀ es una conjunción sobre todos los objetos y ∃ es una
disyunción sobre todos los objetos.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. Software Cmap Tools (o similar).
3. Proyector.

M.C. Sergio Garza Carranza 41


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

4. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Leer los apuntes, identificar las ideas o conceptos principales y escribirlos en


una lista.
2. Ordenar los conceptos desde el más general al más específico en orden
descendiente.
3. Desglosar los conceptos para ver si la idea principal puede ser dividida en dos o
más conceptos.
4. Usar líneas que conecten los conceptos, y escribir sobre cada línea una palabra
o enunciado que aclare porqué los conceptos están conectados entre sí.

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Mapa conceptual.
5. Conclusiones

BIBLIOGRAFÍA

• JOSÉ A. ALONSO JIMÉNEZ. Apuntes de Universidad de Sevilla. Temas de Lógica


informática (2014-15). Recuperado de www.cs.us.es/~jalonso/cursos/li/temas.html
• JULIAN, P. ALPUENTE, M. Programación Lógica. Teoría y Práctica. Pearson Prentice
Hall. 2007.

M.C. Sergio Garza Carranza 42


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 4.2

INVESTIGACIÓN SOBRE LAS DIFERENTES VERSIONES DE PROLOG.

OBJETIVO.

El alumno conocerá las principales versiones del lenguaje PROLOG, e identificará las
ventajas y desventajas de cada versión.

INTRODUCCIÓN.

Esta práctica corresponde a la unidad 4 del programa de estudio, denominada


Fundamentos de la Programación Lógica. Debido a que los temas siguientes se explicarán
utilizando el lenguaje de programación PROLOG, en esta práctica se investigan diferentes
versiones del lenguaje, para conocer las principales características de cada una y
seleccionar la que mejor se acomode a nuestras necesidades y recursos.

El lenguaje de programación PROLOG (“PROgrammation en LOGique”) fue creado por


Alain Colmerauer y sus colaboradores alrededor de 1970 en la Universidad de Marsella,
Francia. Uno de los principales protagonistas de su desarrollo y promoción fue Robert
Kowalski de la Universidad de Edimburgo. Las investigaciones de Kowalski proporcionaron
el marco teórico, mientras que los trabajos de Colmerauer dieron origen al actual lenguaje
de programación, construyendo el primer interprete Prolog.

PROLOG es un lenguaje de programación para ordenadores que se basa en el lenguaje de


la Lógica de Primer Orden y que se utiliza para resolver problemas en los que entran en
juego objetos y relaciones entre ellos.

ESTRUCTURA DE UN PROGRAMA

El hecho de programar en Prolog consiste en dar a la computadora un Universo finito en


forma de hechos y reglas, proporcionando los medios para realizar inferencias de un
hecho a otro. A continuación, si se hacen las preguntas adecuadas, Prolog buscará las
respuestas en dicho Universo y las presentará en la pantalla.

La programación en Prolog consiste en:

M.C. Sergio Garza Carranza 43


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

• Declarar algunos HECHOS sobre los objetos y sus relaciones.


• Definir algunas REGLAS sobre los objetos y sus relaciones.
• Hacer PREGUNTAS sobre los objetos y sus relaciones.

Programa Prolog: Conjunto de afirmaciones (hechos y reglas) representando los


conocimientos que poseemos en un determinado dominio o campo de nuestra
competencia.

Ejecución del programa: Demostración de un Teorema en este Universo, es decir,


demostración de que una conclusión se deduce de las premisas (afirmaciones previas).

La estrategia de resolución particular que utiliza Prolog es una forma de resolución de


entrada lineal (árbol de búsqueda estándar). Para la búsqueda de cláusulas alternativas
para satisfacer el mismo objetivo, Prolog adopta una estrategia de primero hacia abajo
(recorrido del árbol en profundidad). Por todo esto, el orden de las cláusulas (hechos y
reglas) de un determinado procedimiento es importante en Prolog, ya que determina el
orden en que las soluciones serán encontradas, e incluso puede conducir a fallos en el
programa.

Las preguntas son las herramientas que tenemos para recuperar la información desde
Prolog. Al hacer una pregunta a un programa lógico queremos determinar si esa pregunta
es consecuencia lógica del programa. Prolog considera que todo lo que hay en la Base de
Datos es verdad, y lo que no, es falso. De manera que si Prolog responde “yes” es que ha
podido demostrarlo, y si responde “no” es que no lo ha podido demostrar (no debe
interpretarse como “falso” si no que con lo que Prolog conoce no puede demostrar su
veracidad).

Cuando se hace una pregunta a Prolog, éste efectuará una búsqueda por toda la Base de
Datos intentando encontrar hechos que coincidan con la pregunta. Dos hechos
“coinciden” (se pueden unificar) si sus predicados son el mismo (se escriben de igual
forma) y si cada uno de los respectivos argumentos son iguales entre sí.

Cuando a Prolog se le hace una pregunta con una variable, dicha variable estará
inicialmente no instanciada. Prolog entonces recorre la Base de Datos en busca de un
hecho que empareje con la pregunta: los símbolos de predicado y el número de
argumentos sean iguales, y emparejen los argumentos. Entonces Prolog hará que la
variable se instancie con el argumento que esté en su misma posición en el hecho. Prolog
realiza la búsqueda por la Base de Datos en el orden en que se introdujo. La conjunción y
el uso de variables pueden combinarse para hacer preguntas más complejas.

M.C. Sergio Garza Carranza 44


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PREDICADOS

Se utilizan para expresar propiedades de los objetos, (predicados monádicos), y relaciones


entre ellos, (predicados poliádicos). En Prolog se denominan hechos.

Debemos tener en cuenta que:

• Los nombres de todos los objetos y relaciones deben escribirse con letras
minúsculas.
• Primero se escribe la relación o propiedad (predicado) y los objetos se escriben
separándolos mediante comas y encerrados entre paréntesis (argumentos.)
• Al final del hecho debe ir un punto (".").

Las variables se utilizan para representar objetos cualesquiera del Universo u objetos
desconocidos en ese momento, es decir, son las incógnitas del problema. Se
diferencian de los átomos en que empiezan siempre con una letra mayúscula o con el
signo de subrayado (_). Para trabajar con objetos desconocidos cuya identidad no nos
interesa, podemos utilizar la variable anónima (_).

Una variable está instanciada cuando existe un objeto determinado representado por
ella. Y está no instanciada cuando todavía no se sabe lo que representa la variable.
Explícitamente Prolog no utiliza los símbolos de cuantificación para las variables, pero
implícitamente sí lo están. En general, todas las variables que aparecen están
cuantificadas universalmente, aunque ya no escribamos explícitamente el
cuantificador.

Si las fórmulas atómicas de un programa lógico contienen variables, el significado de


estas es:

• Las variables que aparecen en los hechos están cuantificadas universalmente ya


que en una cláusula todas las variables que aparecen están cuantificadas
universalmente de modo implícito.
• Las variables que aparecen en la cabeza de las reglas (átomos afirmados) están
cuantificadas universalmente.
• Las variables que aparecen en el cuerpo de la regla pero no en la cabeza, están
cuantificadas existencialmente.

CONECTIVAS LÓGICAS

Las conectivas que se utilizan en la Lógica de Primer Orden son: conjunción,


disyunción, negación e implicación.

M.C. Sergio Garza Carranza 45


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

La conjunción, “y”, se representa poniendo una coma entre los objetivos “,” y
consiste en objetivos separados que Prolog debe satisfacer, uno después de otro: X , Y.
Cuando se le da a Prolog una secuencia de objetivos separados por comas, intentará
satisfacerlos por orden, buscando objetivos coincidentes en la Base de Datos. Para
que se satisfaga la secuencia se tendrán que satisfacer todos los objetivos.
La disyunción, “o”, tendrá éxito si se cumple alguno de los objetivos que la componen.
Se utiliza un punto y coma “;” colocado entre los objetivos: X ; Y. La disyunción lógica
también la podemos representar mediante un conjunto de sentencias alternativas, es
decir, poniendo cada miembro de la disyunción en una cláusula aparte.
La negación lógica no puede ser representada explícitamente en Prolog, sino que se
representa implícitamente por la falta de aserción: “no”, tendrá éxito si el objetivo X
fracasa. No es una verdadera negación, en el sentido de la Lógica, sino una negación
“por fallo”. Se representa con el predicado predefinido not o con \+.
La implicación o condicional, sirve para significar que un hecho depende de un grupo
de otros hechos. En español solemos utilizar las palabras “si ... entonces ...”.
En Prolog se usa el símbolo “:-” para representar lo que llamamos una regla:

cabeza_de_la_regla :- cuerpo_de_la_regla.

La cabeza describe el hecho que se intenta definir; el cuerpo describe los objetivos
que deben satisfacerse para que la cabeza sea cierta. Otra forma de verla es como
una implicación lógica “al revés” o “hacia atrás”:

P  Q en prolog sería : Q :- P

Ejemplos

Conjunción de predicados
le_gusta_a(clara,jorge), le_gusta_a(clara,chocolate).

Disyunción de predicados
le_gusta_a(clara,jorge); le_gusta_a(jorge,clara).

Negación de predicados
not(le_gusta_a(clara,jorge)).

Condicional: REGLAS
novios(X,Y) :- le_gusta_a(X,Y), le_gusta_a(Y,X).
hermana_de(X,Y) :- mujer(X), es_padre_de(P,X), es_madre_de(M,X), es_padre_de(P,Y),
es_madre_de(M,Y).

Disyunción con ; y con diferentes cláusulas


es_hijo_de(X,Y) :- (es_padre_de(Y,X) ; es_madre_de(Y,X)).

M.C. Sergio Garza Carranza 46


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

es_hijo_de(X,Y) :- es_padre_de(Y,X).
es_hijo_de(X,Y) :- es_madre_de(Y,X).

MATERIAL Y EQUIPO.

1. Computadora personal con acceso a internet.


2. Proyector.
3. Material y apuntes vistos en clase.

METODOLOGÍA.

1. Investigar la versión de PROLOG designada por el maestro.


2. Explicar y mostrar al grupo las características principales de la versión.
3. Explicar el entorno de desarrollo y la forma de escribir un programa.
4. Realizar un programa sencillo a manera de ejemplo.

SUGERENCIAS DIDÁCTICAS.

• Formar equipos de 2 o 3 alumnos.


• Realizar una lista de las versiones más comunes de PROLOG y sortearlas entre los
equipos.
• Hacer que los equipos expongan al grupo su investigación y proponer un debate en
el que “defiendan” su versión asignada.

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Características de la versión de PROLOG
5. Ventajas y desventajas.
6. Programa de ejemplo.
7. Conclusiones

BIBLIOGRAFÍA

• BRATKO. Prolog Programming for Artificial Intelligence. Addison Wesley. 1991.


• STERLING & Shapiro. The art de Prolog. MIT. 1994.

M.C. Sergio Garza Carranza 47


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

• TOLEDO, PACHECO & ESCRIG. El Lenguaje de Programación PROLOG. Universidad


Jaume I de Castellón. 2001. Recuperado de http://ics.uji.es/

PRÁCTICA 4.3

CLÁUSULAS DE HORN EN PROLOG.

OBJETIVO.

El alumno conocerá y describirá las clausulas de Horn y resolución SLD, para identificar
reglas de inferencia lógica y emplearlas en la representación del conocimiento.

INTRODUCCIÓN.

En esta práctica corresponde a la unidad 4 del programa de estudios y se abordan los


temas del 4.3 al 4.6. Se busca consolidar los conceptos explicados en el aula, desarrollar
las habilidades de análisis y síntesis así como reforzar el manejo del lenguaje de
programación PROLOG realizando ejemplos con clausulas de Horn y Resolución SLD.

CLÁUSULA DE HORN

En programación lógica una cláusula de Horn es una secuencia de literales que contiene
como máximo un literal positivo. Se llama así en honor a Alfred Horn, el primero en
señalar la importancia de estas cláusulas en 1951.
La sintaxis de una cláusula de Horn en PROLOG tiene el siguiente aspecto:
hija (A, B) :- mujer (A), padre (B,A).
que podría leerse así: "A es hija de B si A es mujer y B es padre de A".

En términos lógicos representa la siguiente implicación:

(mujer (A) ∧ padre (B , A) )→ hija (A , B)


Por definición de implicación se obtiene la siguiente cláusula de Horn:

¬mujer(A) ∨ ¬padre(B , A) ∨ hija(A , B)

Existen dos tipos de cláusulas de Horn:

• Las cláusulas determinadas (definite clauses), o «cláusulas de Horn con cabeza»


son las que sólo tienen un literal positivo:

M.C. Sergio Garza Carranza 48


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

(¬p 1 ¬p 2 ... ¬p k q) (p 1 p 2 ... p k q)

Caso particular son las no tienen más que ese literal positivo, que representan
«hechos» , es decir, conocimiento factual.

• Los objetivos determinados (definite goals), o «cláusulas de Horn sin cabeza» son
las que no tienen ningún literal positivo:

(¬p 1 ¬p 2 ... ¬p ) k ¬(p 1 p 2 ... p) k

En este caso, las fórmulas atómicas p1,p2,...,pk son inconsistentes, es decir no es


posible que sean todas verdaderas. Provienen de la negación de conclusiones que
el sistema deductivo debe obtener mediante resolución y refutación.

RESOLUCIÓN SLD (Selection-rule driven Linear resolution for Definite clauses)

La Resolución Lineal con función de Selección para Cláusulas Definidas, es un caso


particular de la resolución general, donde:

• Los resolventes son siempre objetivos (cláusulas sin cabeza).


• Los programas son conjuntos de cláusulas de Horn definidas, como hechos y reglas.
• Hay una función de selección que selecciona un átomo a quien aplicar resolución.

EJEMPLO
Representación de un grafo mediante hechos.

arco(a, b) .
arco(a, c) .
arco(b, d) .
arco(c, d) .
arco(c, e) .
arco(d, e) .

La relación de conexión entre nodos (caminos) puede expresarse mediante las reglas:

M.C. Sergio Garza Carranza 49


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

camino(X,Y ) :- X=Y.
camino(X,Y ) :- arco(X, Z), camino(Z,Y ).

La lectura de estas dos reglas es:


• hay un camino de un nodo a otro, si son el mismo
• hay un camino de un nodo X a otro Y si existe un nodo Z tal que hay arco entre X y
Z, y hay camino entre Z y Y.

Ahora, se podría plantear un objetivo, entendiendo los hechos y las reglas que hemos
escrito como premisas podríamos plantear una conclusión y tratar de mostrar la validez
de la argumentación.

Por ejemplo, podemos plantear los objetivos (o preguntas):


? arco(b, d).
? camino(a, d).
? camino(a,X).
? camino(e,Y ).
? camino(X,Y ).
? camino(X, b), camino(X, d).

Los dos primeros son objetivos cerrados porque no contienen variables, mientras que los
restantes son objetivos abiertos.

Todas las variables lógicas en de una clausula están cuantificadas universalmente de


forma implícita. Por ejemplo, en la clausula:

camino(X,Y ) ← arco(X, Z), camino(Z,Y )

implícitamente tenemos:

∀X.∀Y .∀Z.(camino(X,Y ) ← arco(X, Z), camino(Z,Y ))

Esta sentencia es lógicamente equivalente a:

∀X.∀Y .(camino(X,Y ) ← ∃Z.(arco(X, Z), camino(Z,Y )))

Es decir, las variables que sólo aparecen a la derecha de la cláusula están localmente
afectadas de una cuantificación existencial. Se dice que son variables existenciales o extra
o locales. Interpretarlas existencialmente facilita la lectura de la cláusula: “Para todo X y
todo Y , hay un camino entre X e Y si existe Z tal que hay arco de X a Z y hay camino entre
Z e Y”

M.C. Sergio Garza Carranza 50


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

MATERIAL Y EQUIPO.

1. Computadora personal.
2. SWI-PROLOG o similar.
3. Material y apuntes vistos en clase.

METODOLOGÍA

1. Resolver el siguiente ejercicio en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejercicio.
Considere el árbol genealógico de la figura, y formalice los hechos en PROLOG de la forma:
progenitor(nombre, nombre).

Formalice las reglas necesarias para definir los siguientes


parentescos:
Padre(X,Y)
Hijo(X,Y)
Abuelo(X,Y)
Hermanos(X,Y)
Tío(X,Y)
Primos(X,Y)
Ancestro(X,Y)

Solución:

progenitor(juan,jose).
progenitor(juan,saul).
progenitor(juan,omar).
progenitor(jose,alan).
progenitor(jose,abel).
progenitor(saul,ciro).
progenitor(alan,luis).
progenitor(ciro,blas).
progenitor(luis,hugo).
M.C. Sergio Garza Carranza 51
Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

progenitor(luis,raul).
progenitor(blas,rene).
progenitor(hugo,adan).
progenitor(adan,ivan).

padre(X,Y):-progenitor(X,Y).
hijo(X,Y):-padre(Y,X).
abuelo(X,Y):-padre(X,Z),padre(Z,Y).
nieto(X,Y):-abuelo(Y,X).
hermanos(X,Y):-padre(Z,X),padre(Z,Y),not(X=Y).
primos(X,Y):-padre(Z,X),padre(W,Y),hermanos(Z,W).
tio(X,Y):-padre(Z,Y),hermanos(X,Z).
ancestro(X,Y):-padre(X,Y).
ancestro(X,Y):-padre(X,Z),ancestro(Z,Y).

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplo resuelto
5. Conclusiones

BIBLIOGRAFÍA

• BRATKO. Prolog Programming for Artificial Intelligence. Addison Wesley. 1991.


• STERLING & Shapiro. The art de Prolog. MIT. 1994.
• JULIAN, P., Alpuente, M. Programación Lógica. Teoría y Práctica. Pearson Prentice
Hall. 2007.

M.C. Sergio Garza Carranza 52


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 4.4

CONSULTA DE UNA BASE DE CONOCIMIENTOS.

OBJETIVO.

El alumno implementará una base de conocimientos en PROLOG, y conocerá las formas de


acceso a la misma, a través del desarrollo de una aplicación de consulta.

INTRODUCCIÓN.

En esta práctica se abordan los temas 4.7 y 4.8 del programa de estudios. Se busca
reforzar la capacidad de análisis y síntesis del estudiante, el manejo del lenguaje PROLOG,
y el concepto de base de conocimientos, a través de la realización de un programa de
consultas en PROLOG.

Una base de conocimientos en PROLOG es un conjunto de hechos y reglas que expresan


cierto conocimiento expresado en lógica de primer orden.

MODIFICACIÓN DE LA BASE DE CONOCIMIENTOS

PROLOG cuenta con una serie de predicados predefinidos que nos permiten manipular la
Base de Conocimientos consultando, añadiendo, eliminando o modificando cláusulas.

Adición de bases de conocimiento externas.


En PROLOG los archivos se utilizan principalmente para almacenar programas y no
perderlos al apagar la computadora. Si queremos que PROLOG lea nuevas cláusulas de un
archivo que hemos preparado previamente, podemos utilizar los predicados consult y
reconsult. Esto es conveniente cuando tenemos que trabajar con programas de tamaño
considerable y no queremos teclear cada vez todas las cláusulas. Así, podremos crear el
programa con un editor de textos y guardarlo para posteriores usos, con la ventaja de que
lo podremos modificar y ampliar en cualquier momento.

consult(Archivo)
El predicado predefinido consult añade las cláusulas existentes en el archivo de nombre
Archivo a la base de conocimientos de PROLOG, al final de las ya existentes, sin destruir las

M.C. Sergio Garza Carranza 53


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

anteriores. Como argumento pasamos un átomo con el nombre del archivo del que
queremos leer las cláusulas.

Recordemos que un átomo está formado por letras, dígitos y el carácter subrayado. Si
queremos que contenga otros caracteres (los dos puntos «:» para la unidad, la barra
invertida «\» para el directorio o el punto «.» para la extensión) deberemos encerrarlo
entre comillas simples.

reconsult(Archivo)
El predicado predefinido reconsult actúa como el consult excepto que, de existir cláusulas
para un mismo predicado (nombre y aridad), las nuevas sustituyen a las existentes.

Se suele utilizar para la corrección de errores mientras se está realizando el programa, ya


que de esta manera la nueva versión sustituye a la anterior errónea. También es
interesante cuando queremos asegurarnos que se utilizan las cláusulas que vamos a leer, y
no otras posibles con el mismo nombre que tuviera el sistema de alguna consulta anterior.

Por defecto, SWI-PROLOG asume la extensión «.pl» y Prolog-2 toma la extensión «.pro».
Pero esto dependerá del sistema PROLOG utilizado y se puede personalizar.

SWI-PROLOG no tiene un predicado reconsult, ya que al consultar un archivo ya


almacenado, automáticamente es reconsultado.

Manipulación de la base de conocimientos


Existen también en PROLOG otros predicados predefinidos que podemos utilizar para ver
(listing), añadir (assert) o quitar (retract y abolish) cláusulas de nuestra base de
conocimientos:

listing(Predicado)
Todas las cláusulas que tienen como predicado el átomo al que está instanciada la
variable Predicado son mostradas por el archivo de salida activo (por defecto la pantalla).

El predicado de aridad 0 listing (sin parámetro) muestra todas las cláusulas de la Base de
Conocimientos.

asserta(Clausula) y assertz(Clausula)
Estos predicados permiten añadir nuevas cláusulas a la base de conocimientos.

El predicado asserta la añade al principio (letra «a») y assertz la añade al final (letra «z»)
de cualquier otra cláusula del mismo tipo que exista en la base de conocimientos.

M.C. Sergio Garza Carranza 54


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

En todos los casos, Clausula debe estar previamente instanciada a una cláusula. Dicha
cláusula queda incorporada a la base de conocimientos y no se pierde aunque se haga
reevaluación.

retract(Clausula) y retractall(Clausula)
Este predicado nos permite eliminar una cláusula de nuestra base de conocimientos.

Clausula debe estar instanciada y se quitará la primera cláusula de la base de


conocimientos que empareje con ella. Si se resatisface el objetivo, se irán eliminando,
sucesivamente, las cláusulas que coincidan. Con retractall se eliminarán todas.

abolish(Predicado/Aridad) y abolish(Predicado,Aridad)
Se utiliza para retirar de la Base de Conocimientos todas las cláusulas del predicado
Predicado. Debe estar identificado completamente el predicado: nombre y aridad.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. SWI-PROLOG o similar.
3. Material y apuntes vistos en clase.

METODOLOGÍA

1. Resolver el siguiente ejercicio en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejercicio.

Elabore una base de conocimientos en PROLOG que exprese los siguientes hechos:

le_gusta_a(carlos,ana).
le_gusta_a(carlos,futbol).
le_gusta_a(carlos,informática).
le_gusta_a(ana,cine).
le_gusta_a(ana,informática).

Escriba en PROLOG las siguientes preguntas y registre su resultado.


a) ¿Le gusta Ana a Carlos?
b) ¿Qué le gusta a Ana?
c) ¿Carlos y Ana se gustan mutuamente?

M.C. Sergio Garza Carranza 55


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

d) ¿Qué le gusta tanto a Carlos como a Ana?


e) ¿A quienes les gusta el futbol o el cine?

Soluciones.

a) ? le_gusta_a(carlos,ana).
True

b) ? le_gusta_a(ana,X).
X=cine <N>
X=informática <N>
False

c) ? le_gusta_a(carlos,ana) , le_gusta_a(ana,carlos).
False

d) ? le_gusta_a(carlos,X) , le_gusta_a(ana,X).
X=informática <N>
False

e) ? le_gusta_a(X,futbol) ; le_gusta_a(X,cine).
X=carlos <N>
X=ana <N>
False

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplo resuelto
5. Conclusiones

BIBLIOGRAFÍA

M.C. Sergio Garza Carranza 56


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

• BRATKO. Prolog Programming for Artificial Intelligence. Addison Wesley. 1991.


• STERLING & Shapiro. The art de Prolog. MIT. 1994.
• JULIAN, P., Alpuente, M. Programación Lógica. Teoría y Práctica. Pearson Prentice
Hall. 2007.

PRÁCTICA 4.5
LISTAS EN PROLOG.

OBJETIVO.

El alumno conocerá el concepto de listas y su implementación en PROLOG, y construirá un


programa que resuelva un problema real mediante listas.

INTRODUCCION.

En esta práctica se aborda el tema 4.9 del programa de estudios, denominado


Programación lógica con números, listas y árboles. Se busca reforzar la capacidad de
análisis y síntesis del estudiante, el manejo del lenguaje PROLOG, y el concepto de listas, a
través de la realización de un programa que implemente listas en PROLOG.

Una lista en PROLOG se divide en dos partes:


• Cabeza. Es el primer elemento de la lista. Puede ser un átomo o una lista.
• Cola. Es el resto de los elementos de una lista, es de nuevo una lista.

Ejemplos:
1. L= [perro, gato, ratón, queso]
a) cabeza= perro
b) cola= [gato, ratón, queso]

2. L= [[perro, gato], [ratón, queso]]


a) cabeza= [perro, gato]
b) cola= [[ratón, queso]]
3. L= [perro]
a) cabeza=perro
b) cola= [] lista vacía
4. L= []

M.C. Sergio Garza Carranza 57


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

a) cabeza= NO
b) cola= [] lista vacía

Manejo del contenido de las listas

En esta sección se verá el uso de las listas para determinar la existencia de un elemento en
la lista e incluso el uso de recursividad.
En primer lugar, la existencia de un elemento en la lista se puede verificar con una regla
como: pertenece (E, L) :- L= [E|_], que dice que el elemento E pertenece a la lista L si L se
puede hacer teniendo una lista cuya cabeza sea E y cualquier cola, incluso la lista vacía.
Pero esto solamente nos asegura la pertenencia de la cabeza de la lista, y no si un
elemento está dentro de ella. Para esto se necesita una segunda cláusula recursiva:
pertenece (E, [_|T] ) :- pertenece (E,T). Es decir “un elemento E pertenece a una lista
compuesta de cualquier cabeza y una cola T, si ese mismo elemento E es la cabeza del
resto de la lista T”.
Así se tiene el siguiente programa en PROLOG que verifica la pertenencia de un elemento
en una lista:
pertenece (E,L) :- L=[E|_].
pertenece( E,[_|T] ) :- pertenece(E,T).

Unión de listas

Si se desea unir las listas [a,b,c] y [d,e,f] para obtener la lista [a,b,c,d,e,f], una manera de
hacerlo es:
agregar([],L,L).
agregar([X|L1],L2,[X|L3]):-agregar(L1,L2,L3).

Al realizar la consulta agegar([a,b,c],[d,e,f],L), obtendremos la respuesta


L = [a, b, c, d, e, f].

Obtención del enésimo elemento de una lista

La obtención del enésimo elemento de una lista se puede lograr eliminando


recursivamente n elementos de una lista, la variable E controla el número de elementos
que se han eliminado. Cuando R=1, entonces X se asigna al enésimo elemento.

enesimo(X,1,[X|_]).

M.C. Sergio Garza Carranza 58


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

enesimo(X,N,[_|L]):-R is N-1, enesimo(X,R,L).

Así en la consulta enésimo(X,3,[a,b,c,d]), se obtiene la respuesta X=c.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. SWI-PROLOG o similar.
3. Material y apuntes vistos en clase.

METODOLOGÍA

1. Resolver los siguientes ejercicios en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejercicios.

1. Consideremos la siguiente base de conocimientos:


perros(pastor_aleman, [juli, rocky, pancho]).
perros(san_bernardo, [master, beethoven, tosco]).
perros(french_poodle, [figaro, piojo, chicho]).
Utilizando el predicado member, defina una regla para determinar si un perro es de
determinada raza.
Ejemplo:
? pastor_aleman(rocky).
True
?san_bernardo(piojo).
False
2. Escribir un predicado en Prolog que permita obtener el enésimo elemento de una lista
dada L.
Ejemplo:
?enesimo(X,3,[a,b,c,d]).
X=c
?enesimo(X,5,[a,b,c,d]).
false
3. Escribir un predicado en Prolog que permita eliminar un elemento X de una lista dada L.

M.C. Sergio Garza Carranza 59


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

Ejemplo:
?elimina(b,[a,b,c,d,e],L).
L=[a,c,d,e]
?elimina(f,[a,b,c,d,e],L).
false

Soluciones.
1.
perros(pastor_aleman, [juli, rocky, pancho]).
perros(san_bernardo, [master, beethoven, tosco]).
perros(french_poodle, [figaro, piojo, chicho]).

pastor_aleman(P):-perros(pastor_aleman, L), member(P,L).


san_bernardo(P):-perros(san_bernardo,L),member(P,L).
french_poodle(P):-perros(french_poodle,L), member(P,L).

2.
enesimo(X,1,[X|R]).
enesimo(X,N,[P|R]):-C is N-1, enesimo(X,C,R).

3.
elimina(X,[X|R],R).
elimina(X,[P|R],[P|R2]):- elimina(X,R,R2).

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplo resuelto
5. Conclusiones

BIBLIOGRAFÍA

• VÁZQUEZ, GÓMEZ, MATUS Y MÍINJAREZ. Introducción a los lenguajes PROLOG y


LISP ,IPN 1999
• STERLING & Shapiro. The art de Prolog. MIT. 1994.

M.C. Sergio Garza Carranza 60


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 4.6

ÁRBOLES EN PROLOG.

OBJETIVO.

El alumno definirá el concepto de árbol e implementará un programa en PROLOG que realice


búsquedas en un árbol.

INTRODUCCIÓN.

En esta práctica se aborda el tema 4.9 del programa de estudios, denominado


Programación lógica con números, listas y árboles. Se busca reforzar la capacidad de
análisis y síntesis del estudiante, el manejo del lenguaje PROLOG, y el concepto de árbol, a
través de la realización de un programa que implemente árboles de búsqueda en PROLOG.

Árboles binarios.

Un árbol binario es un grafo dirigido acíclico, en el cual cada nodo posee como máximo
dos sucesores y un solo predecesor. Se puede representar en PROLOG utilizando un
predicado de tres argumentos de la forma: arbol (Raiz, Arbol_Izq, Arbol_Der).

Raíz
Árbol_Der a

Árbol_Izq
b c

d e f

g h i

M.C. Sergio Garza Carranza 61


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

La estructura del árbol anterior podría representarse en PROLOG como:

arbol (a, arbol (b, arbol (d, #, arbol (g, #, #)), arbol (e, #, #)), arbol (c, #, arbol (f, arbol
(h,#,#), arbol (i,#,#))))

El siguiente programa recibe como argumento un término y determina si es un árbol


binario válido.

arbolbin(nill).
arbolbin(arbol(R,HI,HD)):-arbolbin(HI),arbolbin(HD).

Ejemplos:
a

?arbolbin(arbol(a, nill,nill)).

>True.

b c

?arbolbin(arbol(a, arbol(b,nill,nill), arbol(c,nill,nill))).

>True.

Para calcular la altura de un árbol binario, se puede utilizar el siguiente programa:

altura(nill,-1).
altura(arbol(R,HI,HD),A):-altura(HI,AHI),
altura(HD,AHD),
MA is max(AHI,AHD),
A is MA+1.

Ejemplos:
?- altura(arbol(a,nill,nill),A).

>A = 0.

M.C. Sergio Garza Carranza 62


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

?- altura(arbol(a, arbol(b,nill,nill), arbol(c, arbol(d,nill,nill),nill)),A).

>A = 2.

MATERIAL Y EQUIPO.

1. Computadora personal.
2. SWI-PROLOG o similar.
3. Material y apuntes vistos en clase.

METODOLOGÍA

1. Resolver los siguientes ejercicios en forma individual.


2. Revisar los resultados y proponer mejoras.
3. Seleccionar el trabajo más destacado para que sea expuesto frente al grupo.

Ejercicios.

1. Elabore un programa que cuente la cantidad de elementos que tiene un árbol


dado.
2. Elabore un programa que determine si un elemento pertenece a un árbol.
3. Elabore un programa que cuente el número de hojas de un árbol.

Soluciones.

1. cuantos(arbol(A,nil,nil),1):-!.
cuantos(arbol(A,X,nil),N):-cuantos(X,K),N is 1 + K.
cuantos(arbol(A,nil,X),N):-cuantos(X,K),N is 1 + K.
cuantos(arbol(A,X,Y),N):-cuantos(X,K),cuantos(Y,T), N is 1 + K + T.

2. perteneceA(arbol(_A,_X,_Y),_A):-!.
perteneceA(arbol(_A,X,_Y),B):-perteneceA(X,B),!.
perteneceA(arbol(_A,_X,Y),B):-perteneceA(Y,B),!.

3. cuentaHoja(arbol(_R,nil,nil),1):-!.
cuentaHoja(arbol(_R,Hi,nil),S):-cuentaHoja(Hi,S).
cuentaHoja(arbol(_R,nil,Hd),S):-cuentaHoja(Hd,S).
cuentaHoja(arbol(_R,Hi,Hd),S):-cuentaHoja(Hi,S1),cuentaHoja(Hd,S2),S is S1+S2.

M.C. Sergio Garza Carranza 63


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplo resuelto
5. Conclusiones

BIBLIOGRAFÍA

• VÁZQUEZ, GÓMEZ, MATUS Y MÍINJAREZ. Introducción a los lenguajes PROLOG y


LISP ,IPN 1999
• STERLING & Shapiro. The art de Prolog. MIT. 1994.

M.C. Sergio Garza Carranza 64


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

PRÁCTICA 4.7

PREDICADOS METALÓGICOS

OBJETIVO.

El alumno comprenderá los conceptos de predicados metalógicos y la manipulación de términos


en PROLOG.

INTRODUCCIÓN.

En esta práctica se aborda el tema 4.11 del programa de estudios denominado


Manipulación de términos. Predicados metalógicos. Se busca que el alumno se familiarice
con los principales predicados metalógicos que contiene el lenguaje PROLOG, así como
con los predicados especiales para la manipulación de términos. Mediante la investigación
en equipos y la exposición de clase, se busca fortalecer las habilidades de análisis y
síntesis, expresión oral y el manejo de recursos de cómputo.

Los predicados metalógicos permiten controlar el algoritmo de resolución facilitando la


meta-programación, que consiste en construir programas que manipulan otros programas
proporcionando una mayor expresividad al lenguaje.
La principal función de los predicados metalógicos es interrogar al sistema acerca del
estado actual del proceso de resolución.

El conjunto de predicados metalógicos disponible depende en general del dialecto


PROLOG utilizado, los más usuales son los siguientes:

nonvar(X) Es cierto cuando X es una variable instanciada.


var(X) Es cierto cuando X es una variable sin instanciar.
atom(X) Es cierto cuando X está instanciada a un valor que es un átomo.
number(X) Es cierto cuando X está instanciada a un valor que es un numero.
integer(X) Es cierto cuando X está instanciada a un valor que es un numero entero.
float(X) Es cierto cuando X está instanciada a un valor que es un numero real.
atomic(X) Es cierto cuando X está instanciada a un valor que es un átomo o un
numero.

Igualdad de términos
M.C. Sergio Garza Carranza 65
Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

La igualdad de términos puede determinarse de diferentes formas. La diferencia clave


estriba en si tiene lugar o no la unificación de variables en los términos. El operador “=” es
la propia unificación. Esto es, se unifican las variables de los términos que se comparan.
Sin embargo, eloperador “==” no unifica las variables de los términos que se comparan.
Por tanto, una variable (no ligada) sólo será igual a sí misma.

T1 = T2 Es cierto si T1 y T2 pueden unificarse.


T1 \= T2 Es cierto si T1 y T2 no pueden unificarse.
T1 == T2 Es cierto si T1 y T2 son idénticos, es decir, se unifican sin que haya ligaduras de
variables.
T1 \== T2 Es cierto si T1 y T2 no son idénticos.

Entrada / Salida
Los sistemas PROLOG poseen predicados predefinidos para la entrada y salida. Los más
comunes son:

read(X) Lee un término y lo unifica con X (el término debe terminar en punto).
write(T) Escribe el término T (en particular, write(‘texto’) para escribir texto).
display(T) Escribe el término T (sin expandir los operadores)

MATERIAL Y EQUIPO.

1. Computadora personal.
2. SWI-PROLOG o similar.
3. Material y apuntes vistos en clase.

METODOLOGÍA
1. Investigar los predicados metalógicos y de manupulación de términos explicados
en clase.
2. Elaborar un programa que utilice algunos de los predicados explicados en clase.
3. Exponer frente al grupo el programa realizado.

RESULTADOS

El reporte del alumno deberá contener lo siguiente:

1. Nombre de la práctica.
2. Objetivo.
3. Definiciones.
4. Código fuente y ejemplo resuelto
5. Conclusiones

M.C. Sergio Garza Carranza 66


Manual de Prácticas de Programación Lógica y Funcional I.T. de Nuevo Laredo

BIBLIOGRAFÍA

• VÁZQUEZ, GÓMEZ, MATUS Y MÍINJAREZ. Introducción a los lenguajes PROLOG y


LISP ,IPN 1999
• STERLING & Shapiro. The art de Prolog. MIT. 1994.

M.C. Sergio Garza Carranza 67

Você também pode gostar