Está en la página 1de 225

,

COMPUTACION I
Lgica, resolucin de problemas,
algoritmos y programas
Lgica, resolucin de problemas,
programas y computadoras

FUNDAMENTOS DE PROGRAMACIN
Algoritmos y estructura de datos
(Segunda edicin)

ALLEN B. TUCKER

LUIS JOYANES AGUILAR

FUNDAMENTOS DE INFORMTICA

Bowdoin College

W. JAMES BRADLEY
Calvin College

Departamento de Lenguajes y Sistemas


Informticos y de Ingeniera de Software
Escuela Universitaria de Informtica
Universidad Pontificia de Salamanca en Madrid

ROBERT D. CUPPER
Allegheny College

DAVID K. GARNICK
Bowdoin College

Traduccin:

Manuel Ortega Ortiz de Apodaca


Universidad Europea de Madrid

Revisin tcnica:

Antonio Vaquero Snchez


Escuela Superior de Informtica
Universidad Complutense de Madrid

MADRID. BUENOS AIRES. CARACAS. GUATEMALA. LISBOA. MXICO


NUEVA YORK. PANAM. SAN JUAN. SANTAF DE BOGOT. SANTIAGO SAO PAULO
AUCKLAND. HAMBURGO LONDRES. MILN. MONTREAL NUEVA DElHI PARs
SAN FRANCISCO. SIDNEY SINGAPUR STo LOUIS TOKIO. TaRaNTa

Prlogo
\

En el pasado prximo, la Universidad Nacional Abierta ofreca, en el curso introductorio a la


Computacin, contenidos programticos que incluan elementos de la globalidad de temas que
comprende esta disciplina. Al abarcar tan amplio espectro se debilitaba el objetivo final del curso (resolver problemas algortmicos con la ayuda de la' computadora digital), el cual, en trminos prcticos, lo reflejaba la ponderacin de los objetivos evaluables de la asignatura.
Este nuevo texto delimita los temas tratados a los estrictamente necesarios para el cabal dominio del objetivo de aprendizaje general del curso, logrando tratar los temas de importancia con
mayor claridad, extensin y profundidad. Otros temas de la disciplina son trasladados en el diseo curricular a un curso introductorio en Informtica y a otros cursos posteriores de los ejes de
Computacin y Sistemas de Informacin de la carrera de Ingeniera de Sistemas.
El texto gua del nuevo curso, un esfuerzo editorial conjunto de la Universidad Nacional
Abierta y McGraw-Hill Interamericana de Venezuela, S. A., aglutina el tratamiento de temas que
van desde conjuntos y funciones, lgica, problemas algortmicos y su solucin, hasta la codificacin de estas soluciones en lenguajes computacionales de alto nivel, por autores de reconocida
trayectoria en la informtica y su enseanza, como son los profesores Allen B. Tucker y David
Garnick, del Bowdoin College; W. James Bradley, del Calvin College; Robert D. Cupper, del
Allegheny College, y Luis Joyanes Aguilar, de la Universidad Pontificia de Salamanca. Los contenidos son selectivamente tomados de los textos Fundamentos de Informtica, lgica, resolucin
de problemas, programas y computadoras, de los cuatro primeros autores, y Fundamentos de
Programacin, algoritmos y estructura de datos, del ltimo, con el objetivo de conformar un texto que cubra los requisitos especficos en trminos de contenidos, del nuevo Plan de Curso de la
asignatura Computacin I de la carrera de Ingeniera de Sistemas de la Universidad Nacional
Abierta, diseado por los profesores Edgar Blanco, NelIy Mendoza y Juana Marrero como Proyecto Especial del rea de Actualizacin de Cursos del Vicerrectorado Acadmico de la mencionada institucin.
DR. EOGAR BLANCO
ING. NELLY MENOOZA
ING. JUANA MARRERO

UNIVERSIDAD NACIONAL ABIERTA


Estudios Profesionales I
Computacin I (301)
Diseo de Instruccin
Edgar Blanco (UNA)
Juana Marrero (UNA)
NelIy Mendoza (UNA)

Especialista en evaluacin
Carmen Velsquez (UNA)

Coordinador de Ingeniera
de Sistemas
Dr. Luis Mrquez Gordones

UNIVERSIDAD NACIONAL ABIERTA


N de

Rfig~tl'O .....2.Q.,.9..5.../t.:.f..-::t -~

Centro de ReQursos Mltiples

e.t. METROPOLITANO
COMPUTACIN l. Lgica, resolucin de problemas, algoritmos y programas
No est permitida la reproduccin total o parcial de este libro, ni su tratamiento informtico, ni la transmisin de ninguna forma o por cualquier medio, ya sea electrnico,
mecnico, por fotocopia, por registro u otros mtodos, sin el permiso previo y por escrito de los titulares del Copyright.
DERECHOS RESERVADOS 2000, respecto a la primera edicin en espaol, por
McGRAW-HILL/INTERAMERICANA DE ESPAA, S. A. U.
Edificio Valrealty, 1." planta
Basauri, 17
28023 Aravaca (Madrid)
ISBN: 84-481-2545-2
Depsito legal: M. 40.896-1999
Compilado de las siguientes obras:
Allen B. Tucker; W. James Bradley; Robert D. Cupper, y David K. Garnick.
FUNDAMENTOS DE INFORMTICA. Lgica, resolucin de problemas, programas
y computadoras.
ISBN: 84-481-1875-8
DERECHOS RESERVADOS 1994, respecto a la primera edicin en espaol. por
McGRAW-HILUINTERAMERICANA DE ESPAA, S. A. U.
Luis Joyanes Aguilar. FUNDAMENTOS DE PROGRAMACIN. Algoritmos y estructura de datos (Segunda edicin).
ISBN: 84-481-0603-2
DERECHOS RESERVADOS 1996, respecto a la segunda edicin en espaol, por
McGRAW-H1LUINTERAMERICANA DE ESPAA, S. A. U.
Esta obra se termin de
Imprimir en junio del 2005
Litogrfica Ingramex
Centeno Nm. 162 - 1
Col. Granjas Esmeralda
Delegacin Iztapalapa
09810 Mxico, D.F.

Nota del editor

COMPUTACIN l. Lgica. resolucin de problemas, algoritmos y programas es una obra nacida de la unin de dos textos para atender a las necesidades de la Universidad Nacional Abierta.
Dichos textos son los siguientes:
Tucker, A. B.; Bradley, W. 1.; Cupper, R. D., Y Garnick, D. K.: Fundamentos de Informtica.
Lgica, resolucin de problemas, programas y computadoras. Madrid, McGraw-Hill. 1994.
Joyanes Aguilar, L.: Fundamentos de programacin. Algoritmos y estructura de datos. Madrid,
McGraw-Hill. 1996.
Se ha respetado el formato de ambas obras, de ah que el tamao y tipos de letra son distintos. Asimismo, se ha mantenido la numeracin de los captulos de cada libro. Por ello, COMPUTACIN I. Lgica. resolucin de problemas, algoritmos y programas comienza en el Captulo 2,
contina hasta el Captulo 6 (correspondientes a la obra de Tucker y otros) y finaliza en los Captulos 1 a 5 (pertenecientes al texto de Joyanes).

Madrid. octubre de 1999

vi

Contenido
Prlogo
Nota del editor

.
.

Captulo 2.
2.1.

.
.
.
.
..
..
.
.
.
.
.
.
.
.
..
.
.
.
.
.
.
.
.

Conjuntos y funciones
Conjuntos
2.1.1. Relaciones entre conjuntos: los diagramas de Venn
2.1.2.
Variables tipos y estados
2.1.3. Operaciones entre conjuntos
2.1.4. Propiedades de las operaciones entre conjuntos
2).5
Conjuntos de cadenas de caracteres
EJercIcIos
2.2. Funciones
2.2.1. Conceptos bsicos
2.2.2. Funciones continuas y discretas
2.2.3. Formas alternativas de definir funciones
Ejercicios
2.2.4. Funciones uno-a-uno y funciones inversas
2.2.5. Funciones booleanas, enteras, exponenciales y logartmicas
2..2.6.. . Series finitas y funciones relacionadas
EJerCICiOS
2.3. Sumario
Ejercicios
Captulo 3.
Lgica
:
3.1. Lgica proposicional
3.1.1. Representaciones de frases en castellano utilizando la lgica proposicional
3.1.2. Evaluacin de proposiciones: Tablas de verdad
3.2.

3.3.

3.4.
3.5.

3.6.
Captulo 4.
4.1.
4.2.

~j~:ciciOf~~~~I.~.~.~~.~ ..:::::::;::;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Razonamiento con proposIcIOnes


3.2.1. Equivalencia
3.2.2. Propiedades de la equivalencia
3.2.3. Reglas de inferencia: La idea de demostracin
3.2.4. Estrategias de demostracin
3..2.5
Resolucin de problemas de la vida real
EJercIcIos
Lgica de predicados
3.3.1.
Los cuantificadores universal y existencial
3.3.2. Otros cuantificadores
3.3.3.
Variables libres y ligadas
Predicados y programas
3.4.1. El estado de un clculo
3.4.2. Cuantificadores y programacin: bucles
Razonamiento con predicados: prueba por induccin

.
.
..
.
.
.
.
.
..
.
.
.
..
.
..

~j::::~~~s.::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::~::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Problemas algortmicos y su solucin

~I;r~~~~o.~.~.:.~~~~~.~.~.~ . :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Definicin de problemas y descripcin de algoritmos


4.2.1.
Los estados inicial y final de un algoritmo: entrada y salida
4.2.2.
Los estados intermedios de un clculo: introduccin de variables

.
.
.

vi
I

2
4
4
8
10
JI
13
15
16

18

20
22
24

28
34
33
38
38
41
41
44
47
51
52
54
54
55
58
61

65
66

69
71
76
76

77
77

78
81
86
86
89
90
93
93
93
95

vii

viii

Contenido

~~e:~~~j~S~ig~;ft~'i'~~"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

4.3.

4.4.

4.5.

Captulo 5.
5.1.
5.2.

5.3.

5.4.

5.5.

5.6.

Captulo 6.
6.1.
6.2.
6.3.
6.4.

6.5.

6.6.

Captulo 1.
1.1.

97
98

4.3.1.
Sintaxis y semntica
4.3.2.
Repeticin y bucles: inicializacin, invarianza y terminacin
Tres visiones de la misma solucin al problema
4 ..3.3
EjercIcIos
Ms problemas algortmicos
4.4.1.
Clculo de a"
4.4.2.
Contar palabras de un texto
4.4.3.. . Representacin del problema de Las Tres-en-Raya
EjercIcIOs
Resumen

.
.
..
,
..
..
.
..
.
.

Resolucin de problemas algortmicos

Necesitamos una metodologa


.
..
5.1.1.
Generalidades sobre el mtodo MAPS
Construccin de software para su reutilizacin: la rutina
..
5.2.1.
Encapsulamiento de rutinas para la reutilizacin. Abstraccin procedimental
..
5.2.2.
Identificacin de rutinas nuevas y definicin de sus abstracciones
..
5.2.3.
Funciones recursivas: Una alternativa a la repeticin
..
5.2.4.
Aprendizaje de rutinas ya existentes: Bibliotecas y caractersticas de los lenguajes
..
5.2.5.
Seleccin y reutilizacin de tipos de datos y estructuras
5.2.6.
A.rr~~s de ,cadenas de carac~eres
..
5.2.7
Tlpllcaclon fuerte y coerclOn
.
EjerCICIos
.
..
Resolucin de un problema utilizando la metodologa MAPS
5.3.1.
El dilogo
..
5.3.2.
Las especificaciones
.

t~:ciciO;a ~.~.~~~~~~~.:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

..
Definiciones de abstracciones: unificacin de rutinas viejas con ideas nuevas
5.4.1.
Reutilizacin de rutinas
5.4.2.
Utilizacin de la creatividad para disear nuevas rutinas
5.4.3.
Utilizacin del conocimiento del dominio en el diseo de rutinas nuevas
Terminacin del caso de estudio
5.5.1.
Coditicacin
5.5.2.
Prueba y veriticacin
5.5.3.
Presentacin
Resumen
Ejercicios
Robustez y prueba de los algoritmos

..

g~~~~~~~n ~ ~~~~~.~e.~

..
..
..
.
..
..
..
.
.
.

.:::::::::::::::::::::::::::::::::::::::::::::::::::::::

Resolucin de problemas de procesamiento de texto, utilizando MAPS: Criptografa


R~sol.u~in de problemas grticos utilizando MAPS: el Juego de la Vida
EjerCICIOs
Garanta de la robustez. Diseo de casos de prueba
6.4.1.
Ejemplo: Prueba de un procedimiento o funcin completos
6.4.2.
Ejemplo: Prueba de un programa completo
Garanta de correccin: verificacin de programas
6.5.1.
Tableau de demostracin
6.5.2.
La regla de inferencia de la asignacin
6.5.3.
Reutilizacin de las reglas de inferencia de la lgica
6.5.4.
Reglas para las condicionales
6.5.5.
Verificacin de bucles
6.5.6.
Verificacin formal frente a verificacin informal de programas
Resumen
Ejercicios

..
.
.
..
..
.
..
.
..
.
..
.
..
..
.

Algoritmos y programas

..

Los sistemas de procesamiento de la informacin

..

100
103
108
111
112
113
116
121
126

130
131
131

132
134

134
140

144
146

147
149

150
152
156

156
158
159
161
162
163

166
167
169
169

171
171
173
174
177
178

182
182

187
196
196

197
202
203
203
206
209
209
212

216
217

218
221
222

Contenido
1.2.

1.7.

Concepto de algoritmo
1.2.1. Caractersticas de los algoritmos
Los lenguajes de programacin
1.3.1. Instrucciones a la computadora
1.3.2. Lenguajes mquina
1.3.3. Lenguajes de bajo nivel
1.304.
Lenguajes de alto nivel
1.3.5. Traductores de lenguaje
\
1.3.5.1. Intrpretes
1.3.5.2. Compiladores
1.3.6. La compilacin y sus fases
Datos, tipos de datos y operaciones primitivas
104.1 . Datos numricos
104.2.
Datos lgicos (booleanos)
104.3. Datos tipo carcter y tipo cadena
Constantes y variables
Expresiones
1.6.1. Expresiones aritmticas
1.6.1.1. Reglas de prioridad
1.6.2.
Expresiones lgicas (booleanas)
1.6.2. l. Operadores de relacin
1.6.2.2. Operadores lgicos
. 1.?2.3. Prioridad de los operadores en las expresiones lgicas
FunClOnes mternas

1.8.

T.~~~era~~~~=c~~~~:~~~ti~~':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

1.3.

lA.

1.5.
1.6.

1.9.

1.8.2. Asignacin lgica


1.8.3. Asignacin de cadenas de caracteres
1.804. Conversin de tipo
Entrada y salida de informacin

.
.
.
.
.
.
.
.
..
.
..
..
.
.
.
.
.
..
.
.
..
..
..
.
.
..
..
..

~j~t;~t~':e~.~~.~~~.~.~~.~.~~~~~ ..~~.~~~~~~~ ..:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

La resolucin de problemas con computadoras y las herramientas de programacin .


La resolucin de problemas
.
Anlisis del problema
.
Diseo del algoritmo
.
2.3.1.
Escritura inicial del algoritmo
.
204. Resolucin del problema mediante computadora
.
2.5. Representacin grfica de los algoritmos
.
2.5.1. Diagramas de flujo
..
2.6. Diagramas de Nassi-Schneiderman (N-S)
.
2.7. Pseudocdigo
.
A.ctivid.ades de programacin resueltas
.
EJercIcIOs
.
Captulo 3.
Estructura general de un programa
.
3.1. Concepto de un programa
.
3.2. Partes constitutivas de un programa
.
3.3. Instrucciones y tipos de instrucciones
.
304. Tipos de instrucciones
.
304.1.
Instrucciones de asignacin
.
304.2.
Instrucciones de lectura de datos (entrada)
.
304.3.
Instrucciones de escritura de resultados (salida)
.
304.4.
Instrucciones de bifurcacin
.
3.5. Elementos bsicos de un programa
.
3.5.1. Bucles
..
3.5.2. Contadores
.
3.5.3. Acumulador
.
3.504.
Decisin o seleccin
.
3.5.5. Interruptores
.

Captulo 2.
2.1.
2.2.
2.3.

ix
224
225
226
227
227
228
229
230
230
231
231
233
233
235
235
236
237
238
240
242
242
244
245
246
247
248
249
249
249
251
251
257
259
260
260
261
263
265
266
266
276
278
279
284
287
287
288
289
290
290
291
292
292
293
294
296
299
300
301

Conten ido

Escritura de algoritmos/programas
3.6.1. Cabecera del programa o algoritmo
Declaracin de variables
3.6.2.
3.6.3. Declaracin de constantes numricas
Declaracin de constantes y variables carcter
3.6.4.
3.6.5. Comentarios
3.6.6. Estilo de escritura de algoritmos/programas
A~\v~d.ades de programacin resueltas .
EjercIcIOs
Introduccin a la programacin estructu rada
Captulo 4.
4. l. Tcnicas de programacin
4.2. Programacin modular
4.2.1. Tamao de los mdulos
4.2.2. Implementacin de los mdulos
4.3. Programacin estructurada
4.3.1. Recursos abstractos
4.3.2. Diseo descendente (top-dow n)
4.3.3. Teorema de la programacin estructurada: estructuras bsicas
4.4. Estructura secuencial
4.5. Estructuras selectivas
4.5.1. Alternativa simple (si-entonces / if-then)
4.5.2. Alternativa doble (si-entonces-si_no / if-then-else)
4.5.3. Alternat.i~a mltiple (segn-sea, caso de / case)
4.6. Estructuras repettttvas
4.6.1 . Estructura mientras (<<while)
4.6.2. Estructura repetir (<<repeab
4.6.3. Estructura desde/para (<<for)
4.6.4. Salidas internas de los bucles
4.7. Estructuras de decisin anidadas
4.8. Estructuras repetitivas anidadas
4.9. La instruccin ir_a (<<goto)
A.ctiv.i~ades de programacin resueltas
EjercIcIOs
Referencias bibliogrficas
Subpro gramas (subalgoritmos): procedimientos y funciones
Captulo 5.
5.1. Introduccin a subalgoritmos o subprogramas
5.2. Funciones
5.2.1. Declaracin de funciones
5.2.2. Invocacin a las funciones
5.3. Procedimientos (subrutinas)
Sustitucin de argumentos/parmetros
~.3.1.
5.4. Ambito: variables locales y globales
5.5. Comunicacin con subprogramas: pa<o de parmetros
5.5.1. Paso de parmetros
5.5.2. Paso por valor
5.5.3. Paso por referencia
5.5.4. Comparaciones de los mtodos de paso de parmetros
5.5.5: Sntesis de. la.transmisin de ~armetros
5.6. FuncIOnes y procedimientos como parametros
5.7. Los efectos laterales
5.7.1. En procedimientos
5.7.2. En funciones
5.8. Recursin (recursividad)
A.ctiv.id.ades de programacin resueltas
EjercIcIos
3.6.

304
304
304
305
305
306
307
308
313
3 15
316
316
317
318
319
319
319
320
320
324
324
325
331
337
340
345
348
352
358
362
364
365
380
381
383
384
386
387
388
393
394
398
401
402
403
404
405
407
410
412
412
413
414
417
422

CAPTULO

CONJUNTOS Y FUNCIONES

En este captulo introducimos las nociones matemticas bsicas sobre los conjuntos y las funciones, junto con su notacin. Estas nociones son fundamentales para la disciplina de la informtica. Ms adelante veremos cmo los conjuntos y funciones se entremezclan con las nociones claves de la informtica y
su aplicacin. Estos conceptos y notaciones se utilizarn a lo largo de todo el
texto. (Algunos lectores encontrarn estas materias familiares. Sin embargo,
esta presentacin tiene como objetivo reorientar estas ideas, quiz familiares,
hacia aquellas partes de la informtica en que se utilizan.)
En qu forma se relacionan los conjuntos y funciones con la informtica?
Generalmente, podemos considerar un programa para una computadora,
como la realizacin de una funcin o como una correspondencia entre dos
conjuntos: la entrada del programa que representa un elemento particular del
dominio de la funcin, y la salida que representa el resultado de aplicar la
funcin a dicha entrada. Introduciremos esta idea en este captulo, ejercitndola en las prcticas de laboratorio que le acompaan. En los Captulos 4, 5 Y6
afianzaremos este concepto, ejercitndonos en la programacin y mediante la
discusin exhaustiva de programas. Los conjuntos y las funciones estn tambin ntimamente relacionados con la propia computadora como dispositivo.
As, podemos decir que una computadora es una mquina que realiza una funcin determinada, cuando ejecuta un programa que realiza, paso a paso, dicha
funcin. Tambin se insiste en esta idea en las prcticas de laboratorio que
acompaan a este captulo. Tambin, en el Captulo 7, insistiremos sobre este
concepto al estudiar la estructura de las computadoras.
Algunos conjuntos son especialmente importantes para la programacin y
para las computadoras. Por ejemplo, los nmeros enteros y reales, los valores
booleanos, los caracteres que encontramos en el teclado de la computadora (el
conjunto de caracteres ASCII) y las cadenas * construidas con esos caracte-

* N. del T.: De las diversas traducciones que suelen realizarse de la palabra inglesa string,
hemos preferido la acepcin cadena o cadena de caracteres, que sern utilizadas de forma
indistinta.

y progra mas
Compu tacin l. Lgica, resoluc in de problem as, algoritm os

todos ellos
res, representan conjuntos que son esenciales para la informtica;
s modertadora
compu
las
y
macin
progra
estn incluidos en los lenguajes de
maprogra
en
existe
que
ia
ondenc
corresp
la
nas. En este captulo estudiaremos
n
resulta
es
funcion
s
Alguna
tipo~~.
de
to
concep
el
cin entre estos conjun tos y
es
funcion
de vital import ancia en programacin. Entre ellas se incluyen las
se repreque
es
funcion
y
micas,
logart
y
nciales
expone
discretas, la{> funciones
sentan mediante series finitas.
en desEstudiaremos todas ellas en este captulo, ponien do especial inters
tacar por qu son importantes para la informtica.

2.1.

CONJUNTOS

nmeros.
En la vida cotidia na son corrientes las colecciones de objetos o
n de
colecci
la
clase,
nuestra
de
as
Podem os pensar en la coleccin de person
es
nombr
los
de
n
colecci
la
o
vil,
dgitos y letras de la matrcula de un autom
ones,
colecci
Estas
o.
Chicag
de
'Hare
erto
de aerolneas que vuelan al aeropu
cin
en el lenguaje matemtico, reciben el nombr e de conjuntos. Una descrip
te.
siguien
forma
la
de
r
ms precisa la podemos realiza
objetos. A
Definicin. Un conjun to es cualquier coleccin bien definida de

rsmenudo, los objetos que forman un conjun to compa rten alguna caracte
objetos
los
de
tica en comn. Un elemento de un conjun to es cualquiera
ce a
que lo constituyen. Se dice que un elemento de un conjun to pertene
exprepara
x,
to
elemen
dicho conjunto. Si S es un conjun to que contiene el
sar que x pertenece a S escribiremos x E S.

tos que lo
Una de las formas de describir un conjun to es encerr ando los elemen
les
laborab
das
los
de
to
conjun
compo nen entre corchetes {y}. Por ejemplo, el
de la semana se puede describir como:
{Lunes, Martes, Mircoles, Jueves, Viernes}
tos:
Las Ecuaciones 2.1 a 2.7 son otros ejemplos de definicin de conjun
{O, 1, 2, 3,4, 5, 6, 7, 8, 9} es el conjun to cuyos elementos son los
dgitos decimales.
{O, 1} es el conjun to de dgitos que se utiliza para escribir nmeros
binarios.
{a, b, c, ..., z} es el conjun to de letras minsculas del alfabeto.
{+, -, *, /} es el conjunto de las cuatro operaciones aritmticas
ms importantes.
{1, 2, ..., 100} es el conjunto de nmeros enteros del 1 al 100, ambos
inclusive.

(2.1)
(2.2)
(2.3)
(2.4)
(2.5)

Conjuntos y funciones

Notacin. Obsrvese la utilizacin de la coma y los puntos suspensivos.


Las comas separan elementos individuales del conjunto, mientras que los
puntos suspensivos (...) denotan la repeticin de un patrn claramente establecido, como ocurre en las Ecuaciones 2.3 y 2.5.

Tambin podemos definir un conjunto, estableciendo las propiedades que debtln satisfacer todos sus elementos, por ejemplo:

{xix es entero y 1

lOO}

(2.6)

Esta notacin requiere una variable al comienzo, una barra vertical y, al final,
una descripcin de los elementos. Con esta notacin, la Ecuacin 2.6 se lee el
conjunto de los x tales que x es un nmero entero entre 1 y 100, ambos
inclusive. Claramente, este ejemplo describe el mismo conjunto de la Ecuacin 2.5. La Ecuacin 2.7 es otro ejemplo de esta alternativa para la descripcin de conjuntos:

{plp es un polinomio de grado 2}

(2.7)

Ejemplos de elementos del conjunto definido por la Ecuacin 2.7 son los siguientes:
x2

2x

+ 1

.01n 2

100n - 3

SOOOy2 - 67

Algunos conjuntos tienen un nmero finito de elementos, mientras que otros


tienen un nmero infinito de ellos. Por ejemplo, los conjuntos definidos por las
Ecuaciones 2.1 a 2.6 son finitos, mientras el conjunto definido por la Ecuacin 2.7 es infinito.
Definicin. Se denomina cardinalidad de un conjunto al nmero de elementos del que consta. El conjunto vaco es aquel que no contiene ningn
elemento y, por tanto, su cardinalidad es O. El conjunto vaco se simboliza
por {} o por </>.

Por ejemplo, la cardinalidad del conjunto definido por la Ecuacin 2.3 es 26.
Existen cuatro conjuntos que tienen una importancia especial, tanto para la
informtica como para las matemticas:
N

{O, 1, 2, 3, ...}

nmero naturales

{..., -3, -2, -1, 0,1,2,3, oo.}

los enteros

{xl- infinito < x < + infinito}

los nmeros reales

{O, 1, 2, ..., n - 1}

los enteros mdulos n

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

Los tres primeros son infinitos, mientras que el ltimo es finito y tiene cardinalidad n. Por ejemplo, el conjunto Z2 = {O, 1} tiene cardinalidad 2; el conjunto
Z10 = {O, 1, ..., 9} tiene cardinalidad 10.

2.1.1.

Relaciones entre conjuntos: los diagramas de Venn

El orden en 'que aparecen enumerados los elementos de un conjunto no tiene


especial relevancia; adems, la duplicidad de elementos es redundante. Es decir,
{a, b, e} y {b, a, e, a} representan el mismo conjunto.
Es bastante habitual que los elementos de un conjunto sean tambin miembros de otro diferentes. Por ejemplo, todos los elementos del conjunto V =
= {a, e, i, o, u} son tambin elementos del conjunto L = {a, b,
z}. La
definicin siguiente sirve para formalizar estos conceptos:
'00'

Definicin. Si dos conjuntos A y B contienen los mismos elementos, se dice


que son iguales y se simboliza escribiendo A = B. Si todos y cada uno de
los elementos de A tambin lo son de B, y se simboliza por A e B. Si A es
un subconjunto de B, decimos que B es un superconjunto de A y se simboliza
por A ::J B. Si se verifica que A i= B, Yadems A e B, entonces se dice que
A es un subconjunto propio de B. Si todos los elementos de un conjunto o de
una coleccin de conjuntos se obtienen de un conjunto comn, a este conjunto se le denomina conjunto universal.

Obsrvese la diferencia que existe entre elemento y subconjunto. Por ejemplo,


sea A = {O, 1, 2, 3, 4, 5, 6, 7}. Entonces el dgito O es un elemento de A
(simbolizado por OE A), yel conjunto {O} es un subconjunto de A (y se denota
por {O} e A). Sera incorrecto decir que O es un subconjunto de A, puesto que
no es un conjunto. De forma anloga, sera incorrecto decir que {O} es un
elemento de A.
Frecuentemente, se representan los conjuntos utilizando diagramas de
Venn (vase Fig. 2.1). Un diagrama de Venn es un dibujo en el que los conjuntos se representan como crculos etiquetados, dentro de una caja rectangular,
que representa el conjunto universal del que se dibujan los elementos.

2.1.2.

Variables tipos y estados

Dos nociones fundamentales de la informtica son las de variable y estado.


Una variable es un mecanismo de notacin que se toma prestado de las matemticas, que permite representar ideas complejas mediante un simple smbolo,
y que aporta concisin y precisin. Frecuentemente, leemos frases como: Representemos mediante x una letra del alfabeto. A continuacin, podemos
utilizar el smbolo x y entender de forma precisa lo que significa, puesto que se
ha definido anteriormente el smbolo, para representar la nocin de cualquier
elemento del conjunto L = {a, b, oo., z}. Cuando se utiliza de esta forma, x
recibe el nombre de variable, puesto que su valor puede variar entre diversas
alternativas (26 para ser exactos).

Conjuntos y funciones

al

bl

Figura 2.1. Diagramas de Venn. a) Dos conjuntos A y B que pueden


tener varios elementos comunes. b) La relacin A e B.

Definicin. Una variable es un smbolo que se asocia con un valor simple,


que de hecho puede ser un elemento de un conjunto bien definido. A lo
largo de los pasos que implican un clculo, el valor de una variable puede
cambiar de ser uno de los miembros del conjunto a ser otro distinto. El
conjunto sobre el que se define una variable recibe el nombre de tipo de la
variable.
Por ejemplo, la variable x que se ha definido anteriormente es del tipo L (o de
manera informal, del tipo letra).
Otra nocin fundamental en la informtica es la de estado. Por ejemplo, un
programa que juegue al ajedrez tiene muchos estados posibles -uno por cada
posible colocacin de las piezas sobre el tablero-o Un programa grfico debe
controlar millones de pixels [puntos de una pantalla de un monitor, cada
uno de los cuales puede estar iluminado (on) o no iluminado (ofl)]. Su estado,
en cada momento, es el valor on u off que tienen el milln de pixels. La nocin
de estado se puede definir ms formalmente de la forma siguiente:
Definicin. Supongamos que tenemos una lista de variables Xl' X 2 ' .oo, X n
cuyos tipos estn definidos por los conjuntos 51' 52' oo., Sm respectivamente.

os y progra mas
Compu tacin l. Lgica, resoluc in de problem as, algoritm

Supngase que el valor de Xl es SI E SI' el valor de


sucesivamente. Entonces se dice que la expresin

X2

es

S2 E

S2' y as

los
representa el estado de las variables xl' X 2 , ..., X w El conjun to de todos
esas
de
estados
de
espacio
e
estados postbles de Xl' X 2 , ..., X n recibe el nombr
variables.
Esta import ante nocin se ilustra en los Ejemplos del 2.1 al 2.3:
Supon gamos que un progra ma de compu tadora tiene dos
tipo el
variables i y j, utilizadas como contadores. Ambas tienen como
podra
conjun to de los nmeros naturales. El estado inicial del progra ma
ser:
Ejemplo 2.1.

i=O

j=O

j=6

Un estado posterior podra ser


i=5

Si los pixels contro lados por un progra ma son Xl' X 2' ...,
1 milln de entrad as, una por
XIOOOOOO, un estado de ese progra ma tendra
cada variable. Por ejemplo, la expresin

Ejemplo 2.2.

Xl =

on

X2 =

off

XIOOOOOO

on

describe un posible estado del progra ma.


del tipo
Ejemplo 2.3. Considrese un progra ma con tres variables, las tres
estados
s
posible
Tres
R).
to
conjun
al
macin
progra
rea l (la analoga en
de este progra ma son:
X
X
X

-3,1

-1

0, junto con z =
junto con z = 1
n.
1789
"2 Junto con z

J2

ma,
Frecuentemente, es de gran ayuda visualizar el estado de un progra
repreestn
2.2
Figura
la
de
puntos
los
o,
ejempl
Por
.
como puntos del espacio
de la Figusentados los dos estados del Ejemplo 2.1. La grfica tridimensional
o el
marcad
ra 2.2b representa el espacio estado del Ejemplo 2.3, donde se ha
un
en
o
Cuand
punto correspondiente a uno de los estados del programa.
si
como
es
e
produc
progra ma las variables cambia n de estado, el efecto que se
.
estados
nos desplazramos de un punto a otro del espacio de

Conjuntos y funciones
7

~""---r-..---r---..-....-....,

61--+--+......,f-+--+~r-;

51--+--+......,f-+--+-+--I
41--t--+-+-+-+-+--;

31--+--+""",'--+--+-+--1
21-+--+---1'--+--+-+--1

.;.-

o t-Jf-+-+-+--+-t-+-- 1

L..-.J----L_.1.--L---J,_.L---.J

-1

a)

b)

Figura 2.2. Representacin grfica del estado de un programa.


al Dos estados del espacio de estados del Ejemplo 2.1. bl Un
estado del espacio de estados del Ejemplo 2.3.

Considrese un programa con tres variables reales z, x e y (variable rea l


significa lo mismo que variable del tipo rea l). Supngase que el programa
contiene una instruccin de la forma
x:= 1.0
Esta instruccin asigna el valor de 1.0 a la variable x. Si no se ha realizado
ninguna restriccin sobre las otras dos variables z e y, todo el plano x = 1 es el
conjunto de posibles estados de este programa, despus de que se ejecute la
asignacin (vase la Figura 2.3).
y

/1I
I
I

;-+----x
z
Figura 2.3. El estado x = 1 en un programa
con tres variables reales z, x e y.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

2.1.3.

Operaciones entre conjuntos

Considrense los conjuntos siguientes:

s
T

{O, 1, 01, 10, 11, OO}


{l, 10, 100, 1000, 10000}

Los nmeros 1 y 10 son los nicos elementos que pertenecen a ambos conjuntos, pero existen entre S y T otros nueve elementos diferentes. Los conceptos de
interseccin, unin y diferencia de conjuntos nos ayudan a describir en diferentes maneras la existencia de elementos comunes entre conjuntos.
Definicin. Sean A y B dos conjuntos. La unin de A y B simbolizada por
A u B, es aquel conjunto cuyos elementos pertenecen como mnimo a uno
de los dos conjuntos, A o B. La interseccin de A y B, simbolizada por A (\ B,
es el conjunto que incluye aquellos elementos que pertenecen tanto a A como
a B. La diferencia (o complemento relativo) de A y B, simbolizado por A \ B, es
el conjunto que contiene aquellos elementos que estn en A, pero no en B.

La Figura 2.4 representa tres diagramas de Venn, en los que las reas
sombreadas representan la unin, la interseccin y la diferencia.

b)

e)

Figura 2.4.

Diagramas de Venn: a) Unin. b) Interseccin. e) Diferencia de dos


conjuntos A y 8.

Conjuntos V funciones

Es posible escribir algunos ejemplos adicionales, utilizando la notacin de


conjuntos. Sean a = {1, 3, 5, 7, 9}, Y B = {- 3, - 1, 1, 3, 5}. Las relaciones
siguientes son ciertas:

AnB
A u B
A \ B

{1, 3, 5}
{-3, -1,1,3,5,7, 9}

p, 9}

Como ejemplo adicional, supngase que


A = {plp es un polinomio de la forma n 2 + bn, donde b es una constante real}
B = {plp es un polinomio de la forma n 2 + e, donde e es una constante real}

Dos posibles elementos del conjunto A seran n 2 + n y n 2 + 4,5n, mientras que


del B seran n2 - 3 Y n2 + 7. Las siguientes relaciones son ciertas:

AnB
AuB
A \ B

{n2 }
{plp es un polinomio de la forma n 2 + bn + e,
donde b = O o e = O}
{plp es un polinomio de la forma n 2 + bn, donde b "# O}

El conjunto vaco <p es extremadamente til. Por ejemplo, si e es el conjunto de consonantes (excluida la y), y V el conjunto de vocales (incluida la y),
entonces e n V no contiene elementos.
Definicin. Decimos que dos conjuntos son disjuntos si su interseccin es
el conjunto vaco.

El complementario de un conjunto S es aquel conjunto Si al


que pertenecen todos los elementos del conjunto universal U, que no pertenecen aS.

Definicin.

Por ejemplo, si e y S representan el conjunto de consonantes y vocales, respectivamente, y U es el alfabeto completo, entonces C' = V Y V' = C. Es decir,
todas las letras que no son consonantes son vocales y viceversa. (Se ha supuesto que la letra y es una vocal). La Figura 2.5 ilustra los conceptos de conjuntos
disjuntos y complementarios utilizando diagramas de Venn.
Ejemplo 2.4. Supongamos que x e y son enteros. Sea S el espacio de
estados compuesto por todos los posibles pares de enteros (x, y). Si definimos los conjuntos A = {(x, y)lx ;?; Oe y ;?; O}, YB = {(x, y)lx < Oe y < O},
entonces A y B son disjuntos. Esto se ilustra en la Figura 2.6, donde las
reas sombreadas representan los conjuntos A y B. Obsrvese que B "# A'
puesto que A' = {(x, y Jlx < O o y < O}.

10

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

bl

al

Figura 2.5. Representacin mediante diagramas de Venn de:


al Conjuntos disjuntos. bl Conjuntos complementarios.

Figura 2.6.

2.1.4.

Conjuntos disjuntos.

Propiedades de las operaciones entre conjuntos

Las operaciones aritmticas entre nmeros tienen determinadas propiedades,


como asociatividad, conmutatividad, inversa, y as sucesivamente. Hacemos
uso de estas propiedades, de forma casi automtica, cuando simplificamos
ecuaciones algebraicas. Los conjuntos y sus operaciones tienen propiedades
similares, y las podemos utilizar para simplificar operaciones complejas entre
conjuntos. Las principales propiedades de las operaciones entre conjuntos se
resumen en la Tabla 2.1.

Conjuntos y funciones

11

Tabla 2.1. Propiedades y operaciones de los conjuntos. (A y B son conjuntos;


U es el conjunto universal sobre el que estn definidos A y B)
Conmutatividad

Ley de la contradiccin
A n A'

AnB==BnA
AuB==BuA

\ Asociatividad

== <p

u -simplificacin

A n (B n C)
A u (B u C)

==
==

(A n B) n C
(A u B) u C

A uA == A
Au<p==A
AuV==V

Distributividad
A n (B u C) == (A n B) u (A n C)
A u (B n C) == (A u B) n (A u C)

Leyes de Morgan
(A n B)'

==

A' u B '

(A u B)'

==

A' n B'

n-simplificacin
A nA == A
AnV==A
An<p==<p

Propiedad de la negacin
(A')'

Complementariedad

== A

Ley de exclusin del trmino medio


A u A'

2.1.5.

==

V'

<p

<P' == V

Conjuntos de cadenas de caracteres

El tipo s tri ng (cadena de caracteres) * es muy importante en informtica.


Informalmente, puede definirse una cadena como una secuencia de elementos contiguos, pertenecientes todos a un conjunto universal conocido como
alfabeto. A continuacin, se pueden ver algunos ejemplos de conjuntos cuyos
elementos son cadenas de caracteres.
Ejemplo 2.5. El conjunto {aa, ab, ba, bb} es el conjunto de todas
las posibles cadenas de dos elementos, construidas a partir del alfabeto

{a, b}.

* N. del T.: El tipo string es un tipo caracterstico de la mayora de los lenguajes de


programacin modernos. Sin embargo, al tratarse de un captulo dedicado a los conjuntos, traduciremos el trmino string al castellano. En captulos posteriores, en los que aparece el tipo como
perteneciente a un lenguaje de programacin, dejaremos el trmino sin traducir.

12

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Ejemplo 2.6. M = {abe, acb, bae, bca, eab, eba} es el conjunto


formado por todas las posibles colocaciones o permutaciones de las tres
letras a, b Y e. Obsrvese que existen seis permutaciones distintas.
Ejemplo 2.7. S = {O, 1,01,001, 100, 0100} es un conjunto de cadenas del
alfabeto {O, 1}. Existen otras muchas cadenas obtenidas de este alfabeto,
tales como {l, 10, 100, 1000, 10000}, Ylos propios {O, 1}. Es posible establecer restricc'iones a las cadenas. Por ejemplo, el conjunto {O, 1,01, 10, 11, OO}
es el conjunto de todas las cadenas del alfabeto {O, 1} que tienen longitud
1 2.
Ejemplo 2.8. F = {abed, abdc, aebd, aedb, adbe, adeb, baed,
bade, bead, beda, bdae, bdea, eabd, eadb, ebad, ebda,
edab, edba, dabe, daeb, dbae, dbea, deab, deba} es el conjunto de todas las permutaciones de las letras a, b y c. Esto puede escribirse
alternativamente como F = {plp es una permutacin de abed}. Obsrvese
que existen 24 permutaciones distintas.
Ejemplo 2.9. Si A = {sls es una cadena sobre {O, 1} que comienza por 1},
entonces A' = {E} U {sls es una cadena sobre {O, 1} que comienza por 1}.
En este caso, el smbolo E simboliza la cadena vaca que no contiene ningn
carcter. La notacin {E} significa el conjunto que tiene un solo elemento, que es la cadena vaca. El conjunto vaco <p, por el contrario, no
contiene ninguna cadena.
Ejemplo 2.10. Sea D el conjunto formado por todas las permutaciones de
abed, que terminan en d. Entonces D = { abed, aebd, bacd, bead,
cabd, ebad}. Si N = {plp es una permutacin de abed}, entonces D es
un subconjunto propio de N, por lo que la interseccin de D y N es el
propio conjunto D y la unin entre D y N es N.
Ejemplo 2.11. Sea U = {ulu es cualquier cadena sobre el alfabeto {O, 1},
incluida la cadena vaca E}. Entonces U es el conjunto universal de varios
conjuntos definidos sobre el mismo alfabeto, tales como S = {E, 0,1,00,01,
10, 11} Y T = {O, 01, 001, 0001, oO.}. Obsrvese que ni S es subconjunto de T,
ni T lo es de S. En la mayora de los casos, el conjunto universal sobre el
que se definen conjuntos de cadenas particulares es tan evidente que no
suele mencionarse explcitamente.
Ejemplo 2.12. Supngase que tenemos los dos conjuntos de cadenas siguientes:
A

{plp es una permutacin de la cadena abed,


que comienza por a}
{abed, abdc, acbd, aedb,adbe, adcb}

Conjuntos y funciones

13

{plp es una permutacin de la cadena abcd que termina en d}


{abcd, acbd, bacd, bcad, cabd, cbad}

Entonces las operaciones interseccin, unin y complemento relativo dan


origen a las cadenas siguientes:

{abcd,
{abcd,
bcad,
{abdc,

AnD
AuD
A \ D

acbd}
abdc, acbd, acdb, adbc, adcb, bacd,
cabd, cbad}
acdb, adbc, adcb}

Obsrvese que tanto A como D tienen seis miembros, mientras que A u B


tiene diez miembros, puesto que abcd y a cbd son elementos de ambos
conjuntos.

Ejercicios
2.1.

Supongamos que i = 1 Yj = 1 es el estado inicial. Describir el estado al


que se llega despus de realizar cada una de las asignaciones de los
apartados a) al e). Hacer una representacin bidimensional del plano
xy, y dibujar el punto que corresponde al estado inicial y a los distintos
estados a que conducen las asignaciones de los apartados a) al e).

a) ; := 2;
j
b)
e)

.- ; ;

.- ;
.-

2.2.

+ 1;

j .- j +
j .- j +
; .- i +
j
j +

2;
1 r.
1 r.
; r.

Expresar en notacin de conjunto los descritos mediante las frases siguientes:


a)

b)
e)
d)
e)

Las cadenas sobre el alfabeto {O, 1} de longitud menor o igual que


5, que contengan uno o dos ceros.
Los enteros pares.
El conjunto de todas las cadenas sobre el alfabeto {a, b, e} que
no contengan smbolos duplicados.
El conjunto de todas las permutaciones de la cadena 012.
El conjunto de todos los polinomios de grado 3 menor que tengan a x como un factor.

14

2.3.

Computacin /. Lgica, resolucin de problemas, algoritmos y programas

SeaA = {(x, y)lx ~ e y ~ O} Y B = {(x, y)lx ~ 1 e y ~ 1}. Identificar


cada uno de los conjuntos siguientes sobre el plano xy, sombreando el
rea apropiada.
a)
b)
e)
d)

e)

2.4.

A n B
A u B
A \ B
B ~A
A'

Supngase que s y t son cadenas sobre el alfabeto {a, b, ..., z}. Es posible
definir eoneat (s, t> como la cadena que resulta de poner t a continuacin de s (concatenar). Por ejemplo, si s = abe y t = xy, entonces
eoneat(s,t) = abexy. Del mismo modo, si S y Tson conjuntos de
este tipo de cadenas, podemos definir eoneat (S, T) como el conjunto
de todas las cadenas, que resultan de concatenar una cadena arbitraria s
de S, y otra t de T. Supongamos, por ejemplo, que S = {e, x, xy,
xyy}, y T = {e, y, yx, yxx}. Se pide encontrar cada uno de los
conjuntos siguientes:
eoneat (S, T>
eoneat(T ,S)
e) S u T
d) S n T
e) S \ T
f) T \ S
a)

b)

2.5.

Supongamos que S y T son conjuntos de cadenas. Encontrar dos ejemplos de parejas S y T, tales que eoneat(S, T> = S u T.

2.6.

Dibujar un diagrama de Venn para los conjuntos A y B, Ysombrear las


partes correspondientes a los conjuntos siguientes:
a)
b)

(A' n B') u (A n B)
(A u BY u (A \ B)

2.7. Cuntas cadenas de longitud 2 menor existen sobre el alfabeto (O, I)?
2.8.

Decir cules de las afirmaciones siguientes son verdaderas y cules


falsas.
a)

b)
e)
d)
e)

f)
g)
h)
i)

{2, 3,
{2, 3,
{3, 4,
(<(> n
{2, 3,
{2, 4,
{3, 4,
{I, 2,

4} u {2, 4, 5, 6} = {2, 3,4, 5, 6}


5} n {2, 4, 5, 6} e {2, 3, 6}
6, 8} \ {2, 4, 7, 8} ::J {3}
{3, 5, 7, 8}) u {3, 7} = {3, 5, 7, 8}
5} = {5, 2, 3, 2}
5} e {I, 2, 4, 5, 6}
5} e {I, 2,4, 5, 6}
6} ::J {I, 2,4,5, 6}

>

{2, 5}

Conjuntos y funciones

2.9.

15

Supngase que:

S
T
U

{1, 2, 3, 4, 5}
{xlO < x < 10 Y x es impar}
Z16

\ Escribir el conjunto de elementos de los conjuntos siguientes:


a)
b)

e)
2.10.

2.2.

S n T
(S u T)'
(S u T) \ S

Los conjuntos siguientes se han definido en forma de reglas. Reescribir


las definiciones en forma de lista de elementos.
N, x ::::; 10, Y x es par}

a)

{xix

b)

{plp es una permutacin de la cadena 012}

FUNCIONES

Un concepto fundamental para la informtica es el de funcin. En su forma


ms simple, unafunein es una tabla con dos columnas que indican una correspondencia entre los valores de la primera columna y los de la segunda.
Ejemplo 2.13. Considrese la tabla siguiente.

1
2
3
4

2
5
10
17

Esta es una funcin que relaciona los enteros de la primera columna con
los correspondientes de la segunda. Si quisiramos extender la funcin, no
sera dificil deducir que la quinta fila constara de los pares 5 y 26. Es decir,
existe un criterio, sugerido por las cuatro filas de la funcin, que permite
generalizarla para cualquier nmero de valores.
Ejemplo 2.14. La tabla siguiente es ligeramente diferente:
1
2

2
5

3
2

2
6

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

16

Puesto que en la columna de la derecha aparecen nmeros duplicados, esta


tabla no parece representar una relacin estable y fiable. Parece no ajustarse a ninguna regla gracias a la cual, a partir de un valor de la izquierda,
pueda calcularse el de la derecha.
Los valores no-ambiguos -es decir, que a cada valor de la primera columna lc
correspondA uno de la segunda-, son bsicos para la idea de funcin.
La Figura 2.7 muestra dos funciones ms, en este caso utilizando un grfico
en lugar de una tabla. Obsrvese que en la Figura 2.7a cada valor de x se
corresponde con uno de y, y de la misma forma, cada uno de y se corresponde
con uno de x. En la Figura 2.7b cada x se corresponde con uno de y; sin
embargo, para un mismo y existen ms de un valor de x. Para poder trabajar
con funciones es necesario definir el concepto de forma ms precisa. Clarifiquemos algunas de las ideas acerca de la correspondencia presentadas en los
ejemplos.
y

a)

b)

Figura 2.7. Dos representaciones grficas de funciones: al Cada x se corresponde con un y. bl Cada x se corresponde con una y, pero una misma y se
corresponde con varias x.

2.2.1.

Conceptos bsicos

Una funcin siempre se define utilizando dos conjuntos.


Definicin. Sean X e Y conjuntos. La notacin (x, y) donde x E X e y E Y,
recibe el nombre de par ordenado. El producto cartesiano de X e Y, simboli-

zado por X x Y, es el conjunto {(x, y)lx E X e y E Y}. Es decir, X x Yes el


conjunto de todos los pares ordenados (x, y) que verifican que x E X e y E Y.

Conjuntos y funciones

17

Ejemplo 2.15. Sea X = Y = R. Entonces, X x Yes el sistema y coordenadas xy que se muestra en la Figura 2.8a. Si 1 = J = Z, entonces 1 x J es el
conjunto de todos los puntos del plano cartesiano, cuyas coordenadas son
enteras. Los puntos de 1 x J son las intersecciones de las lneas verticales y
horizontales de la Figura 2.8b.

O
-1
-1

al

b)

Figura 2.8. Representacin grfica de: a) El producto cartesiano


de reales. b) El producto cartesiano de enteros.

Una funcin es un caso particular de producto cartesiano, es un conjunto de


pares en el que dos elementos distintos no pueden tener igual el primer elemento del par. De una manera formal, una funcin puede definirse.
Definicin. Sean X e Y dos conjuntos. Una funcin es un subconjunto f de
X x Y, tal que cada x E X se encuentra emparejado con uno, y slo un
elemento y E Y. El conjunto X recibe el nombre de dominio de la funcin!, e
y el de rango de f
En el contexto de una representacin tabular de las funciones podemos pensar
en el dominio como en la primera columna de la tabla, y en el rango como en
la segunda. La propia funcin es la correspondencia que existe entre los nmeros de las dos columnas. De una forma similar, cuando observamos una representacin grfica de una funcin, se puede identificar el eje x como el dominio
y el y como el rango, y la funcin con el conjunto de pares (x, y) que constituyen la grfica (por ejemplo, como se muestra en la Figura 2.7). En cualquier
caso, la nocin de que cada valor x slo puede tener un y asociado, resalta el
concepto de dependencia o estabilidad de la correspondencia.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

18

Ejemplo 2.16. Supongamos que X = {l, 2, 3, 4} e Y = {2, 4, 6, 8}.


Supongamos tambin que tenemos el conjunto de pares f = {(l, 2),
(2,4), (3, 6), (4, 8)}. Entonces f es una funcin; el conjunto {l, 2, 3, 4} es el
dominio; y {2, 4, 6, 8} su rango. Obsrvese que para cada x E X existe un
nico y E Y emparejado con l. Obsrvese tambin que esta correspondencia particular puede representarse mediante la regla y = 2x.
\

Supongamos de nuevo que X = {l, 2, 3, 4}, Yconsidrese el conjunto g = {(1,2),


(2, 4), (3, 6)}. En este caso, g no es una funcin con dominio X, puesto que
existen elementos de X para los que g no est definida. Aquellos conjuntos que
tienen todas las propiedades de las funciones, pero que no estn definidas
sobre todo el dominio, reciben el nombre de funciones parciales. Las funciones
parciales se utilizan a menudo en la informtica.
Aunque una funcin exige que cada x del dominio tenga un valor del
rango, y asociado con l, no es necesario que cada valor y del rango corresponda a un x. Por ejemplo, si X = Y = {l, 2, 3, 4}, Ydefinimos la funcin y = 4
para todo valor de X, entonces los valores 1, 2 Y 3 no se corresponden con
ninguno de X. Finalmente, sea h = {(l, 2), (2, 4), (3, 6), (1, 8), (4, lO)}. El
conjunto h no es tampoco una funcin, puesto que existe un valor de x que se
corresponde con dos valores distintos de y.
Los trminos siguientes suelen utilizarse al referirnos a funciones.
Definicin. Seafuna funcin con dominio X y rango Y. Se suele simbolizar
esta relacin como f: X ~ Y. Cuando se han especificado el dominio y el
rango, escribimos y = f(x) para simbolizar la relacin que f representa
entre cada elemento del dominio X, y el correspondiente del rango Y. En
esta notacin, x recibe el nombre de variable independiente. El conjunto de
pares {(x, f(x))lx E X Y f(x) E Y) se utiliza para definir la grfica de la
funcin!
Ejemplo 2.17. Si X = Y = R e y = f(x) = 2x - 1, x es la variable independiente, e y es la dependiente. La grfica de f se muestra en la Figura 2.9.

2.2.2.

Funciones continuas y discretas

Las funciones suelen caracterizarse dependiendo de si pueden visualizarse mediante una linea continua o no. Si no es posible, la funcin tiene huecos en
su representacin en el plano xy, y recibe el nombre de funcin discreta.
Ejemplo 2.18. Sea X = Y = R. La funcin valor absoluto, dada por y =

puede definirse mediante la regla

Ixl

x cuando x ? O
- x cuando x < O

Ixl

Conjuntos y funciones

_ _ _ _ _ _ _ _.......,....

Figura 2.9.

19

Grfica de la funcin ((x)

2x -

1.

La Figura 2.10a muestra la grfica de y = Ixl cuando el dominio y el rango


de la funcin es R (dando origen a una funcin continua). Si X = Y = Z, la
funcin es ligeramente diferente, como se muestra en la Figura 2.10b (una
funcin discreta).
y

y
(-3,3)

.(3,3)

(-2,2).

-----IlI'-----x
(0,0)

a)
Figura 2.10.

Grfica de y

(2,2)

(-1,1)

(1,1)

------+------x
(0,0)

b)
=

IxI.

a) Una funcin continua. b) Funcin discreta.

Ejemplo 2.19. Lafuncin suelo l_x_lse define como el mayor entero menor
o igual que x. Esta funcin tiene como dominio a R y como rango a Z. Por
tanto, si x = n.dd 1 d 3 ... (donde n es un entero y di cualquier dgito), entonces l_x_1 = n cuando x ~ 0, o x es un entero, y l_x_1 = n - 1 en caso
contrario. Por tanto, para nmeros reales positivos, la funcin l_x_1 es el

20

y progra mas
Compu tacin l. Lgica, resoluc in de problem as, algoritm os

negatiresultado de eliminar la parte decimal de x, y para nmeros reales


deciparte
la
ar
elimin
vos que no sean ya enteros, l_x_1 es el resultado de
2.11.
Figura
la
en
a
muestr
mal y restarle uno. La grfica de esta funcin se
el
como
define
se
que
I-x-j
Una funcin muy relacionada es la funcin techo
l
decima
parte
la
ando
elimin
calcula
menor entero mayor o igual que x. Se
techo
y
suelo
es
funcion
Las
uno.
dole
de x, y Isi x no fuera entero, sumn
itambin se conocen como funciones mayor entero y menor entero, respect
vamente.
utiliLa funcin valor absoluto puede calcularse en Pascal, directamente,
del
in
expres
o
e
variabl
zando la expresin abs (x), donde x puede ser una
una
tienen
no
techo
y
suelo
es
tipo rea lo; ntege r. Sin embargo, las funcion
runC< x)
analoga exacta en Pascal. La funcin ms prxim a es la funcin t
eliminaninteger
en
l
rea
tipo
de
in
que convierte cualquier variable o expres
= -3.
3.14)
nC<3,ytru
=
)
(3.14
do los decimales. Por tanto, trunc

2.2.3.

Formas alternativas de definir funciones

a, una
Hemos visto cmo se pueden definir funciones utilizando una frmul
Las
dos.
ordena
pares
de
to
conjun
grfica xy, una tabla de dos columnas y un
tivas.
alterna
funciones pueden definirse de varias formas
definir las
Definicin recursiva de funciones. Algunas veces es conveniente
arse reciferenci
funciones en trminos de s mismas. Esta capacidad de autorre
e de
nombr
el
reciben
be el nombr e de recursin, y las funciones as definidas
funciones recursivas.
y

,,

:-2

'-1

Figura 2.11.

,1

,
'2

La funcin suelo

:3

I_x_l.

Conjuntos y funciones

21

Ejemplo 2.20. Supongamos X = Y = N, Y que la funcinf(n) se define de


la forma siguiente:

f(n)

1
3

+ f(n -

cuando
cuando

1)

n-O
n > O

\ Con la definicin conocemos un valor inicial para la funcin; es decir, su


valor cuando x = o. Mientras conozcamos cmo se puede calcular cada
valor de f a partir del anterior, no es necesario que conozcamos una regla
explcita para calcular f(n) directamente. Es decir, el valor de f(n) puede calcularse aplicando reiteradas veces la relacin de recurrencia a valores crecientes de n, comenzando por n = o. Por tanto, primero calculamos
f(O) = 1, despus lo utilizamos para calcular f(l) = 3 + f(O). Esto puede
hacerse repetidas veces, obtenindose la tabla siguiente:

n
O
1
2
3

f(n)
1
4

~ _ . _ ~

10

En algunas ocasiones es fcil deducir una frmula no-recursiva para calcular f(n) a partir de la recursiva, y en otros casos es muy dificil. Por ejemplo,
el caso del Ejemplo 2.20 es relativamente senciJIo, extrayendo el criterio de
la tabla para obtener la frmula equivalente f(n) = 3n + 1.
Ejemplo 2.21. Considrese la funcin recursiva:

f(n) = O
= 1
= f(n -

1)

+ f(n -

2)

cuando
cuando
cuando

n-O
n - 1
n > 1

Aplicando reiteradas veces la relacin de recurrencia se puede obtener la tabla:

f(n)

1
2
3
4

1
1
2
3

5
6

5
8

7
8

13
21

22

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

Esta funcin recibe el nombre de serie de Fibonacci. Es una funcin de gran


utilidad en diversas reas de las matemticas aplicadas. Sin embargo, es
dificil, sin un conocimiento ms profundo de las matemticas, encontrar
una forma de la funcin que la calcule directamente para cualquier valor
de n.
\

Utilizacin de un programa para definir una funcin. Las funciones pueden


definirse tambin utilizando un programa de computadora en el cual se describa cmo puede calcularse un valor de rango, utilizando un valor predeterminado del dominio. Formalmente, un programa de estas caractersticas recibe el
nombre de algoritmo. La construccin de algoritmos computacionales para
una gran variedad de funciones es el objetivo de los Captulos 4 al 6.
Ejemplo 2.22. Podemos definir un algoritmo como un conjunto bien definido de pasos, que transforman una entrada (de un conjunto de entradas
disponibles) en la salida correspondiente. Es decir, describe cmo calcular
el valor de una funcinf(x) para cada valor particular x del dominio. Por
ejemplo, la secuencia siguiente es un algoritmo (escrito en lenguaje Pascal)
que calcula los valores de la funcin n = Hog2n-l, donde x es un nmero
real arbitrario, mayor o igual que 1. En este caso, el valor de x es la entrada
del algoritmo, y el de n la salida de la funcin.
read(x);
n :=

o;

whi le x >= 1.0 do

begin
x:=x/2.0;
n := n + 1

end;

Cuando se utiliza un algoritmo para calcular una funcin, el conjunto de


entradas permitidas (en este caso R) se corresponde con el dominio de la
funcin; el conjunto de salidas (en este caso N) se corresponde con el rango; y
los pasos de que consta definen procedimentalmente la correspondencia existente entre cada valor del dominio y el correspondiente del rango. Otras formas de definir funciones (vase Ejemplo 1.11) no describen ningn proceso
particular, mediante el cual pueda calcularse la funcin. Los programas controlan el proceso.

Ejercicios
2.11.

Cules de los conjuntos de pares ordenadores siguientes son funciones?


a)

b)
e)

{(1, 1), (1, n), (1, lOO)}


{el, 1),(3,7),(5,13),(4, 19)}
{( - 1, 1), (O, 1), (1, 1), (1, 1), (3, l)}

Conjuntos y funciones

d)
e)

f)
g)
2.12.

{(x,
{(l,
{(l,
{(l,

y)lx ~
e y = x}
a), (2, b), (3, a), (4, b), (5,

23

e)}

a), (2, b), (1, e), (2, d), (3, e)}


e), (2, d), (3, e), (4, b), (5, a)}

Determinar el dominio y el rango de cada una de las funciones siguientes:


h(x) = x mod 17, para x = 0, 16, 17, 32 Y 69. (La funcin mod
calcula el resto entero que resulta de la divisin del primer argumento por el segundo.)
b) b(x) = (-1:::;; x :::;; 10), para x = -2, -1,0,10 Y 15.
e) l_x_1 para x = 10, n, y -1,5.
n
d) Ixl para x = -1,0,1, -49,5 Y 6".

a)

2.13.

Definir las funciones que cumplan lo siguiente:


a)

b)

e)
d)

2.14.

Tome un entero positivo y calcule el resto despus de dividirlo


por 67.
Trunque un nmero real a la mitad de la dcima ms prxima (por
ejemplo, 19.567 quedara 19,5).
Asigne verdadero si el nmero es positivo, y falso si es cero
o negativo.
Crear una secuencia de valores para cada uno de los cuales es el
doble del anterior ms uno. El primero es 1.

Tabular unos pocos valores de las siguientes ecuaciones de recurrencia,


y deducir una expresin compacta para f
a) f(n)
3 para n
0, y f(n) = f(n - 1) + 5 para n > O.
b) f(n) = 1 para n = 0, y f(n) = 2f(n - 1) para n > O.

2.15.

Marcar un punto en la grfica (i, j) de la Figura 2.8b, para cada uno de


los estados marcados con A y B, en el segmento de programa siguiente.
; := 1;
j := 1;

(estado A}
;:=;+1;
j:=j+1;
{estado B}

2.16.

Considrese la funcin f(x) = (x mod 2 = O).


Cul es el dominio de esta funcin?
Cul es el rango?
e) Es una funcin parcial o total?

a)
b)

24

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

2.17.

La funcin Ancestros tiene como entrada un nmero de generacin, y


devuelve el nmero de ancestros que tuvo en todas las generaciones
precedentes, suponiendo que cada persona de cada generacin tiene
exactamente dos padres. Es decir, Ancestros(l) = 2, Ancentros(2) = 4, Y
as sucesivamente. En particular, Ancestros(O) = 1, suponiendo que cada
persona es ancestro de s mismo o s misma. Enunciar una definicin
re~ursiva para la funcin Ancestros.

2.2.4.

Funciones uno-a-uno y funciones inversas

Supongamos que f es una funcin con dominio X y rango Y. Entonces, como se


vio en la Figura 2.7b, a cada x le corresponde uno y slo un valor de y. Sin
embargo, cada valor de y puede corresponder a ms de un valor de x. Una
funcin de este tipo se representa en la Figura 2.12. Sin embargo, si quisiramos invertir el proceso, comenzando por y, el resultado obtenido no sera una
funcin correcta. Es decir, alguna y se correspondera con ms de un valor de
x, mientras que algunas de ellas no se corresponderan con ningn x. La
funcin de la Figura 2.12b es diferente ---en este caso podemos invertir el
proceso y seguimos obteniendo una funcin-o Esto es debido a que a cada x
le corresponde una y distinta. La definicin siguiente formaliza estas ideas.
Definicin. Sea f: X -+ y una funcin. La funcin f es una funcin unoa-uno si a cada x diferente le corresponde un y diferente para cada x E X e
y E Y. Se dice que dos conjuntos x e Y estn en una correspondencia unoa-uno si existe una funcin f: X -+ y que es uno-a-uno.

Ejemplo 2.23. Las funciones resultantes de permutaciones son ejemplos


clarificadores de las correspondencias uno-a-uno. Por ejemplo, considrese

....

_~

"",_ _...,

x
--..,~--f----- x

al
Figura 2.12.

bl

a) Funcin no-uno-a-uno. b) Funcin uno-a-uno.

Conjuntos y funciones

25

la cadena abcd y su permutacin bdac. Si hacemos X = Y = {a, b, e,


d} esta permutacin puede considerarse como una funcin definida como:

p(b)

e
a

p(c)
p(d)

d
b

p(a)

Es decir, p indica en qu posicin se deben colocar los diferentes elementos de


una cadena arbitraria de a, b, e y d. La funcin p es tambin una funcin
uno-a-uno, puesto que x diferentes se corresponden con y's distintos, y el rango
de p = {a, b, e, d} = y.
Definicin. Sea f : X --. Y una funcin uno-a-uno. Entonces f - 1 es una
funcin con dominio Y y rango X, que verifica que si y = f(x), entonces
x = f - 1 (y). La funcin f - 1 recibe el nombre de funcin inversa de f

No todas las funciones tienen inversa. Por ejemplo, supongamos X = Y =


= {a, b, c,d},yf(a) = b,f(b) = c,yf(c) =f(d) = d,como se muestra en
la Figura 2.13.

a.~
b

c.~

d ------+~

Figura 2.13.

Una funcin f que no es uno-a-uno, por lo que no tiene inversa.

Entonces, si la inversa de f existiera,f - 1 (d) tendra como valores asociados e y


d, lo que invalidara af -1 como una funcin legtima. Por tanto, para que una
funcin pueda tener inversa ha de ser una relacin uno-a-uno.

26

os y progra mas
Compu tacin ,. Lgica, resoluc in de problem as, algoritm

uno,
Ejemplo 2.24. El Ejemplo 2.23, puesto que p es una funcin uno-ate:
siguien
forma
la
de
se
definir
puede
1,
p
,
tiene inversa. Esta inversa
p-l(a)
p-l(b)

p-l(e)
p- l(d)

a
e

cubrir
Obsrvese que p-l(p(a )) = p-l(e) = a. De forma general, para
Anlox.
=
(p(x)
1
PX,
E
x
cualqu ier funcin invertible p : X -+ Y, y cada
gamente, para cada y E Y, p(p-l(y )) = y.
e en la
Ejemplo 2.25. Las funciones uno-a- uno se emplea n habitu alment
(ASange
Interch
ation
codificacin. El American Standa rd Code for Inform
r
carcte
cada
para
127
y
CII) define una equivalencia numr ica entre O
una
de
ar
estnd
teclado
un
en
regular o de contro l que puede ser pulsad o
je de
compu tadora . Esta funcin es uno-a- uno, y est incluid a en lengua
decir,
Es
l).
orddina
valor
(por
ord
de
e
progra macin Pascal con el nombr
nmer o
para cada carcte r que encont ramos en el teclado, o rd(x) es un
res
familia
res
caracte
s
alguno
de
les
ordina
entero entre O y 127. Los valores
:
debajo
del teclado se pueden ver
ord ( , O' )
ord('A ')
ord( '=')
ord ( , a')

= 48
=-65
= 61
= 97

ondien Una lista comple ta de los caracte res ASCII y sus ordina les corresp
A.
ice
Apnd
tes puede encont arse en el
uniEl props ito de la funcin ord es definir un esquem a de codificacin
utilizan
lo
a
esquem
Este
.
teclado
del
forme para represe ntar los caracte res
La existentodos los constru ctores de software y hardw are de compu tadora s.
distinto s
entre
acin
inform
de
fcil
mbio
cia de este estnd ar permit e el interca
tipos de compu tadora s.
uno; si
Obsrvese que, para ser eficaz, la funcin o rd tiene que ser uno-aa una forma
un cdigo estuvie ra asigna do a dos caracte res distintos, no existir
uno, la
uno-afuncin
una
es
que
Puesto
.
cdigo
el
ificar
consistente de descod
Si n
ter).
funcin ord tiene en Pascal su inversa, denom inada eh r (por Charac
teclado
del
r
es un entero en el interva lo 0-127, entonc es eh r (n) es el carcte
corresp ondien te del entero. Por ejemplo:
ehr(48 ) = 'O'
ehr(65 ) = 'A'
ehr(61 ) = '='
eh r (97) = 'a'

Conjuntos V funciones

27

Obsrvese que, puesto que ord y chr son inversas, una de la otra, se verifica:
chr<ord<x

=x

ord<chr<n

=n

Para cualquier entero entre O y 127, Y cualquier carcter del teclado.


\ Ejemplo 2.26. La criptografia (codificacin de mensajes secretos) es un
rea de la informtica que utiliza muchos de los principios que hemos
discutido. Por ejemplo, el cifrado de Csar, un esquema de codificacin en
el que cada letra de un mensaje es reemplazada por otra letra diferente del
alfabeto, la tercera letra detrs de ella. Entonces el mensaje:
SERGEANT PEPPERS LONEL y HEARTS CLUB BAND

se codifica en el cifrado de Csar como:


VHUJHDGW SHSSHUV ORGHOB KHDUWV FOXE EDGG

El cifrado de Csar es una permutacin de las letras del alfabeto, y por


tanto una funcin uno-a-uno, cuyos dominio y rango son el alfabeto de
letras maysculas. La descodificacin del lenguaje implica el descubrimiento de la funcin inversa a la que fue utilizada al cifrarlo.
La gran desventaja del cifrado de Csar es lo relativamente fcil que es
descodificarlo. Podemos construir un mtodo ms dificil de descodificar, utilizando una permutacin aleatoria y haciendo sustituciones en base a ella. Utilizando la tabla de sustitucin:
ABCDEFGHIJKLMNOPGRSTUVWXYZ
JSATERNICFHPLUGWVYDZOMXGBK

Permite codificar el mensaje:


SERGEANT PEPPERS LONELY HEARTS CLUB BAND
DEYNEJUZ WEWWEYD PGUEPB IEJYZD APOS SJUT

como

Si el mensaje cifrado es lo suficientemente largo, incluso un cifrado aleatorio


puede descodificarse contando el nmero de veces que aparece cada letra,
comparndola con el nmero de veces que aparece cada letra en un prrafo en
castellano. Algunos esquemas de encriptacin ms sofisticados emplean funciones de descodificacin que encriptan bloques de letras. La criptografa es un
campo de estudio excitante y que encierra grandes desafos. El concepto de
funcin uno-a-uno aporta un criterio preciso para definir la nocin de conjuntos que tienen el mismo nmero de elementos, y la nocin de tamao de un
conjunto.

28

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Definicin. Dos conjuntos A y B tienen el mismo nmero de elementos, si


estn en una correspondencia uno-a-uno. Un conjunto que est en una
correspondencia uno-a-uno con Zn para algn valor n natural, se dice que
tiene cardinalidad * n. Dicho conjunto tiene n elementos y recibe el nombre
de conjunto finito. Los conjuntos que no tienen cardinalidad n para ningn
valor de n, reciben el nombre de conjuntos infinitos.
\

La mayora de los conjuntos que nos encontraremos en la informtica son


finitos. Por ejemplo, el conjunto de caracteres ASCII del Ejemplo 2.25 tiene
cardinalidad 128. Incluso el conjunto de enteros que se utiliza en la informtica
es finito -para muchas computadoras, su cardinalidad es 2 16; es decir, 65.536.
Este es el tipo; nteger que utiliza el lenguaje de programacin Pascal, y que
difiere de la nocin matemtica del conjunto Z por razones evidentes. En
resumen, el rango de los enteros en matemticas es infinito, mientras que el
rango de los; ntege r en programacin es finito. Nociones complementarias
sobre el tipo; nteger se introducen en el manual de laboratorio.

2.2.5.

Funciones booleanas enteras, exponenciales


y logartmicas

Existen un conjunto de funciones especiales que aparecen con la suficiente


frecuencia en la informtica como para justificar un breve estudio.
Ejemplo 2.27. Supongamos que X = Z e Y = {verdadero, fa l so}.
Sea f(x) = (O ~ x ~ 100). Entonces, f(l) = verdadero, f(102) =
fa l so, f( - 1) = fa l so, y as sucesivamente. El dominio de f es el de los
enteros y el rango el conjunto {verdadero, falso}.

Este es un ejemplo de un importante conjunto de funciones, conocidas como


booleanas en honor del matemtico ingls George Boole (1815-1864), que sent las bases y comenz el desarrollo de la lgica simblica. Esta funciones
reciben tambin el nombre de predicados. Estudiaremos detenidamente los
predicados y la lgica en el Captulo 3.
Ejemplo 2.28. Sea b mod p el resto entero resultante de dividir el entero b
por el entero p. As, por ejemplo, 8 mod 3 = 2, 15 mod 5 = O, Y as
sucesivamente. Obsrvese que O ~ b mod p ~ p - 1. Si X = N, Y = Z23 y
h(b) = b mod 23, entonces h(46) = O, h(70) = 1, Y as sucesivamente.

* N. del T.: En castellano se suele utilizar el trmino cardinalidad o simplemente cardinal


de un conjunto.

Conjuntos y funciones

29

La funcin h es un ejemplo sencillo de una clase de funciones conocidas como


funciones hash*, que se suelen utilizar en programas de computadoras que
almacenan y recuperan informacin de archivos muy grandes.
Ejemplo 2.29. Otro tipo de funciones que aparecen frecuentemente en
informtica es la clase de funciones polinmicas, tales como x Z, 2x 3 + 1,
, x 5. - 5x, y as sucesivamente. La forma general de una funcin polinmIca es:
p(x) = a nx n + a n-l xn -

As, si n = 3, a 3

+ '" + a l x + a o

2, a z = al = O, ya o = 1, entonces p(x) = 2x 3 + 1.

Las funciones exponenciales y logartmicas son dos clases de funciones con una
importancia tal en la informtica, que es necesario estudiarlas cuidadosamente.
Comencemos por la funcin exponencial.
Definicin. Sean X = Y = R, Y seanf(x)
nombre de funcin exponencial con base 2.

2x La funcin f(x) recibe el

Puesto que 20 = 1 Y 2 -x = 1/2x , es posible tabular algunos valores de la


funcin exponencial y perfilar su grfica, que se muestra en la Figura 2.14.

Z'

-2
-1

1/4
1/2

O
1

2
3

2
4

8
16

Figura 2.14.

La funcin exponencial y su representacin grfica.

* N. del T.: Es extraordinariamente dificil traducir al castellano el trmino hash. Su


traduccin literal sera picadillo. Ms en consonancia con el concepto sera traducir hashtable
por tabla asociativa, hash functiom> por funcin asociativa, hashing por asodatividad, aunque
aqu no lo hemos hecho.

30

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

La principal caractersticas de la funcin exponencial es su crecimiento


rpido. Si la x se incrementa en 1, f(x) se dobla, puesto que 2x + 1 = 2 x 2x .
Los dos acertijos siguientes ilustran esta propiedad; el primero se debe a los
franceses y el segundo a los persas.
Ejemplo 2.30. Supongamos que tenemos un estanque en nuestra propiedad. En el estanque crecen nenfares, y hemos observado que la superficie
del estanque que recubren stos se dobla cada dia. Al principio, el crecimiento era pequeo, puesto que el rea que cubran era escaso. Sin embargo, si llegasen a cubrir todo el estanque, eliminaran todos los dems tipos
de vida en l. Despus de 29 das observamos que la mitad del estanque
est totalmente cubierto. Cuntos das nos quedan para poder salvar el
estanque? (La respuesta, por supuesto, es 1 da).
Ejemplo 2.31. Cierto individuo ofreci regalar al rey un precioso tablero
de ajedrez si el rey le daba a l un grano de trigo en la primera casilla, dos
granos sobre la segunda, cuatro sobre la tercera, y as sucesivamente hasta
que el tablero estuviera cubierto completamente. Pensando de forma superficial sobre lo que le pedan, el rey acept. El rey no tard mucho en caer en
la bancarrota.

Estimemos cunto arroz deba dar el rey al individuo. Antes de ello, recordemos algunas propiedades algebraicas de las funciones exponenciales. Las cuatro funciones que necesitamos son las siguientes:

2m +"

(2.8)

2 /2"

2m -"

(2.9)

(2 m )"

2m"

2m 2m
m

2m!" = .::12 m

(2.10)
(2.11 )

donde m y n son nmeros naturales (estas propiedades se verifican incluso si n


y m son reales, aunque nuestras aplicaciones slo requerirn el caso ms simple).
No es dificil verificar esas propiedades. En la Ecuacin (2.8), el lado izquierdo es el producto de m doses seguido del de n doses. El resultado es el producto de m + n doses. La verificacin de la Ecuacin (2.9) se obtiene de forma
anloga. La parte izquierda de la Ecuacin (2.10) es el producto de n copias de
2m; es decir, el producto de n copias de un producto de m doses. Por tanto, es el
producto de mn doses. Para verificar la Ecuacin (2.11), utilizamos la propiedad de que la Ecuacin (2.10) puede extenderse al caso en que m y n sean
nmeros racionales. Es decir, 2m !" puede escribirse como (2 m )l!", por lo que se
obtiene directamente la Ecuacin (2.11) utilizando el hecho de que 2 1!" =.::12.
Podemos ahora estimar la cantidad de granos de trigo que el donante del
tablero de ajedrez habra recibido si el rey hubiera sido capaz de cumplir el

Conjun tos y funcion es

31

compro miso. Consid eremos los primer os cuadra dos. En la casilla


1 habra que
deposi tar 1 (= 2) granos de trigo; en la casilla 2, 2 ( = 2 1) granos ; en
la casilla 3,
2
4 (= 2 ) granos; y as sucesivamente. As, el da 64 el individ uo
tendra
que
recibir 2 63 granos de trigo del rey. Pero:

Por tanto:

263
210
263

260 X 2 3 = (2 1 )6 X 23
1024 ~ 1000 = 10 3
(10 3)6 X 8 = 8 X 10 18

Si hacem os una estima cin de 50 granos de trigo por cada gramo


, esto es
aproxi madam ente igual a 1,6 x 10 11 tonelad as mtricas de trigo,
que excede
con creces la produc cin de arroz de todo el mundo .
La funcin exponencial es una funcin uno-a- uno; as, si Xl =f. x ,
2 entonc es
2" =f. 2". Su rango es el conjun to de nmer os reales no negativos. Por
tanto, si
restrin gimos el domin io al conjun to {x E Rlx > O}, entonc es el domin
io de la
funcin exponencial ser igual al rango (vase de nuevo la Figura
2.14). En este
caso, la funcin es invertible. La funcin inversa de una exponencial
recibe el
nombr e de funcin logartmica.

Definicin. Sea X = R e Y = {x E Rlx > O}. Seaf(x ) = 2x Enton ces'-l


recibe el nombr e de funcin logartmica en base 2 y se represe
nta por
log2(x).
Recurdese que una funcin y su inversa cumple n fU - 1 (x
= x y
f-IU( x = x. Esta relaci n nos conduc e a las ecuaci ones siguien
tes, que
relacio nan entre s ambas funciones:
(2.12)
(2.13)
Ejemplo 2.32. Puesto que 2 3 = 8,log 8 = 3. Es decir, 2 3 =
8 respon de a
2
la pregun ta: Qu obtend remos cuando elevamos el nmer o 2 al
cubo?.
Por el contra rio, log2 8 = 3 respon de a la pregun ta: A qu potenc
ia hay
que elevar 2 para obtene r 8?. Del mismo modo, tendrem os que log2
16 = 4,
Y log2 1024 = 10.

En la Figura 2.15 se muestr a la grfica de la funcin logartmica.


La principal
caracte rstica de la funcin expone ncial es su rpido crecimiento.
Por el contrario, la princip al caracte rstica de la funcin logart mica es su
crecimiento
lento. Obsrvese que log2 8 = 3 Y log2 16 = 4. Es decir, aadie
ndo
1 a x se
dobla 2x , mientr as que al doblar x slo se le aade 1 a log2 x.
Otra forma de compa rar las funciones exponencial y logartmica
es la siguiente: y = 2X significa que el nmer o 1 debe ser doblad o x
veces para

32

y prog ram as
n de prob lem as, algo ritm os
Com puta cin l. Lgica, reso luci

Figura 2.15.

La fun cin loga rtm ica.

debe ser
de 2, y = log2 x significa que x
obtener y. Si x es una potencia
ifica que
r 1. Por ejemplo, log2 16 = 4 sign
dividido por 2 y veces, par a obtene
(2.14) a
veces par a obt ene r 1. Las Ecuaciones ica.
16 debe ser dividido por 2 cua tro
rtm
ades adicionales de la [uncin loga
(2.18) describen algunas propied
log2 1

log2 2

(2.14)
(2.15)

log2 mn

log2 m + log2 n

(2.16)

log2 (m/n)

log2 m - log2 n

(2.17)

n
log2 (m )

n log2 m

(2.18)

logadepende del hecho de que la funcin


4)
La verificacin de esas expresiones
(2.1
nes
acio
Ecu
l. Abajo verificamos las
rtmica es la inversa de la exponencia ficacin de las restantes.
veri
a (2.16), dejando par a el lector la
x. Entonces
4) sup ong amo s que log2 1 =
(2.1
Par a verificar la Ecuacin
x = x.
log2
sea
5),
(2.1
ficar la Ecuacin
2x = 1, por lo que x = O. Par a veri Par a verificar la Ecuacin (2.16), sea
X
= 1.
x y
Entonces 2 = 2, resultando x
Y Por tan to, nm = 2 + , y
x
2
=
n
y
2
=
m
es
onc
x = log2 m e y = log2 n. Ent
= log2
bin and o ambas, obtenemos log2 mn
por tan to, x + y = log2 (mn). Com
m + log2 n.

Conjuntos y funciones

33

Ejemplo 2.33. logz 3 = 1,585 Y logz 5 = 2,322. Podemos utilizar esta


informacin para calcular las expresiones siguientes:
a)
b)

e)

logz 6 = logz (2 x 3) = logz 2 + logz 3 = 1 + 1,585 = 2,585


logz 1,6 = logz (8/5) = logz 8 - logz 5 = 3 - 2,322 = 0,678
logz 0,5 = logz (1/2) = logz 1 - 1 = - 1

Pascal incorpora las funciones exponencial y logartmica, pero en base e en


lugar de en base 2. Se simbolizan mediante exp y l n respectivamente. Es
decir, dado x para calcular en Pascal eX escribiremos la expresin exp(x).
Conocido x para calcular en Pascal loge x, escribiremos l n ( x). Para ms
detalles vase el manual de laboratorio.

Ejercicios
2.18.

Una alternativa en criptografia para el cifrado de Csar es la utilizacin


de una clave de codificacin, que consiste en un patrn que se repite e
indica al descodificador a qu distancia a la derecha en el alfabeto se
encuentra la letra correcta. Por ejemplo, A significa desplaza letras;
B significa desplaza 1 letra, y as sucesvamente. Por tanto, si la clave
de codificacin es ABCDABC..., el mensaje (en ingls) FOURSCOREANDSEVEN se codificara FPWRTEOSGAOFSFXEO. Invertir el
proceso para el mensaje codificado (tambin en ingls) OIVOCGIOPASPIB. Es este esquema una funcin de caracteres uno-a-uno? Es
una funcin uno-a-uno de cadenas de caracteres?

2.19.

Dibjense las grficas de las funciones siguientes. Supngase que el


dominio es R (excepto para el apartado e que es N).

a) 12xl
b) lx/3J
e)

logz (2x)
x

d) 2>+
x mod 7
Ilogz xl
rIxll
2.20. Simplificar las expresiones siguientes:
a) 3a x 3 -a
b) (2 Z)3
e)
f)
g)

e)

d)
e)

f)
g)

h)

27"/ 3
23/2 4

logz 4
log3 (1/27)
logz 2"
3 log3 (x + 1)

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

34

2.2.6.

Series finitas y funciones relacionadas

Los procesos acumulativos son frecuentes en la informtica. Por ejemplo, algunos programas repiten un determinado clculo. Cada repeticin consume
una cierta cantidad de tiempo y memoria. El programador tiene que ser capaz de esmar la cantidad de tiempo y espacio que consumir el programa,
sin necesidad de ejecutarlo. Tales clculos suelen implicar la suma de largas listas de nmeros o expresiones. Para facilitar todo ello, y otras expresiones relacionadas, se ha desarrollado la denominada notacin sigma. Esta notacin utiliza la letra griega L (sigma) para simbolizar la suma, un ndice que
define el intervalo de valores para los que se realiza la suma, y la funcin que
hay que sumar. Supongamos que se quiere escribir la suma de los 20 primeros
enteros, 1 + 2 + 3 + ... + 20, utilizando notacin sigma. Escribiremos
entonces:

Esto se lee, calcular la suma de los i enteros comprendidos entre 1 y 20,


ambos inclusive. El nmero 20 es el lmite superior y el 1 el lmite inferior,
siendo la variable i la variable ndice de la sumatoria.
Ejemplo 2.34.

A continuacin, se muestran varios ejemplos de notacin

sigma:
n

a)

i~l i

b)

i~ 3i

e)

1 + 2 + 3 + ... + (n - 1) + n.

O + 3 + 6 + 9 + '" + 3(n - 1) + 3n.

(3i

i= 1

2)

5 + 8 + 11 + .. , + (3n - 1) + (3n + 2).

1 + 2 + 3 + ." + (n - 2) + (n - 1).
n

e)

i~ i

f)

i~ i(3i

2 + 3 + 4 + ... + (n -

1) + n.

+ 2) = 5 + 16 + 33 + ... + (n - 1)(3n - 1) + n(3n + 2).

Conjuntos y funciones

35

De hecho, cualquier funcin de una variable ndice i, puede sumarse de esta


forma. Considrense las relaciones generales siguientes:
n

I f(i)
i=m

= f(m) + f(m + 1) + ... + f(n)

(2.19)

(2.20)

)'
aI
L....J
j=

a1

+ .,. +

a2

an

Obsrvese la utilizacin de subndices en la Ecuacin (2.20). Este tipo de notacin suele utilizarse para diferenciar los elementos de una lista, siendo al el
primero, a z el segundo, y as sucesivamente. Utilizaremos a menudo esta idea
de lista en el diseo de programas.
Propiedades de las series finitas. Las Ecuaciones (2.21) a (2.24) reflejan algunas
propiedades bsicas de las sumas utilizando la notacin sigma.
1

=1

(2.21)

al

al

+ ~a

an

= 1

(2.22)

n~l

= 1

= 1

(2.23)

= 1

= 1

=m+l

SI

~m

< n

(2.24)

Que se pueden justificar de la forma siguiente: En la Ecuacin (2.21) los lmites


inferior y superior son iguales, por lo que existir un nico trmino, el correspondiente al valor comn de los lmites. En la Ecuacin (2.22) el lado derecho
de la expresin es simplemente igual al izquierdo, con el primer trmino escrito
por separado. En la Ecuacin (2.23), el lado derecho es igual al izquierdo, pero
con el ltimo trmino escrito por separado. En la Ecuacin (2.24), el lado
derecho es igual al izquierdo separado en dos sumas -una hasta m, y otra
desde m + 1 hasta n.
Las Ecuaciones (2.25) a (2.29) resumen otras importantes propiedades adicionales de las sumas en series finitas.
n

j=

= 1

(2.25)

donde e es una constante

en

(f(i)

I
i=

f(i)
l

(2.26)

36

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas


n

j= 1

(f(0 + g(i))

i~ f(O + j~ g(i)

(fU) - g(i))

j= 1

j= 1

(2.27)

f(i)

g(i)

(2.28)

j=l

i~ (f(i

1) - f(i)) = f(n

1) - f(l)

(2.29)

Es posible justificar estas ecuaciones haciendo las consideraciones siguientes:


En la Ecuacin (2.25), dIado izquierdo es el propio valor c sumado a s mismo
n veces. En la Ecuacin (2.26), dIado derecho es igual al izquierdo, tras sacar c
factor comn de la suma. En la Ecuacin (2.27), el lado derecho es igual al
izquierdo, pero con los trminos reagrupados. La Ecuacin (2.28) se deja como
ejercicio. La Ecuacin (2.29) se conoce como las series telescpicas. El lado
izquierdo puede escribirse como:
(f(2) - f(l)) + (f(3) - f(2)) + ... + (f(n + 1) - f(n))

donde podemos ver que todos los trminos entre f(n + 1) y f(l) se cancelan
mutuamente, por lo que el resultado serf(n + 1) - f(l).
Algunas series importantes para la informtica. No suele ser habitual la mode-

lizacin de procesos acumulativos, como sumas finitas, utilizando notacin


sigma. Generalmente, es deseable encontrar una frmula que nos calcule el
resultado en funcin de los lmites inferior y superior. Se han obtenido estas
frmulas para algunas de las series ms comunes, y es conveniente memorizarlas.
Una de tales series, que se utiliza frecuentemente en la informtica, es la
serie aritmtica (tambin conocida como progresin aritmtica):
1

+ ... +

(n -

1)

Existe una ancdota interesante sobre esta serie. Cad Friedrich Gaus (17771855) fue uno de los matemticos ms destacados del siglo XIX. Cuando era
joven le enviaron a un internado, ms conocido por su estricta disciplina que
por su calidad acadmica. Como castigo, l y sus compaeros deberan realizar
el ejercicio de sumar los 100 primeros enteros. Apenas el profesor haba enunciado el problema, Gauss levant su mano dando la respuesta correcta. Gauss
haba descubierto una forma sencilla de sumar la serie aritmtica para n =
100. Gauss escribi la suma horizontalmente en orden creciente, y debajo
escribi la misma suma, pero en orden decreciente, haciendo despus la suma
trmino a trmino:
1 +
2 +
3 +
+ 100 + 99 + 98 +
101 + 101 + 101 +

+ 99 + 100
+ 2 + 1
+ 101 + 101

37

Conjuntos y funciones

Gauss pudo observar que el resultado era la mitad de 101 x 100, o 5050. El
profesor de Gauss reconoci que el muchacho tena un gran talento para las
matemticas, y recomend a su padre que lo enviara a un colegio en el que
pudiera sacar mejor partido de su capacidad. De hecho, podemos utilizar el
mtodo abreviado de Gauss para sumar series en general:
1

(n + 1)

+
2
+ (n
+ (n +

1)
1)

+
3
+ (n
+ (n +

2)
1)

+
+
+

+
+
+

1)

(n

2
(n

1)

+
+
+

1
(n

1)

Puesto que hay n trminos en la suma, el resultado de la suma anterior puede escribirse n(n + 1). Por tanto, la suma de la serie aritmtica original es
n(n + 1)/2, puesto que se ha sumado consigo misma para obtener la ltima
lnea. La forma compacta de la suma de esta serie, junto con la de otras tambin importantes, se muestran en las Ecuaciones (2.30) a (2.33).
n

i~l
i2

I
i= 1

1)

(2.30)

i~1

n(n

n(n

+ 1)(2n +

1)

(2.31 )

n 2 (n

1)2

(2.32)

I 2i
i= 1

2n+ 1

(2.33)

Las Ecuaciones (2.30) a (2.32) se las conoce con el nombre de p-series por ser de
la forma:
n

I
i=

iP

para algn valor de p. La Ecuacin (2.32) es un ejemplo de la que se conoce


como serie geomtrica o progresin geomtrica.
Ejemplo 2.35. A continuacin, se estudian dos ejemplos en los que se ve
cmo pueden utilizarse esas propiedades para calcular sumas de series.
15

i~1
20

i~i

20

i~1

JI

+ 0_

15(15
i

2
20(21)
-2-

6(7)

120
210 - 21

189

V progra mas
Compu tacin ,. Lgica, resoluc in de problem as, algoritm os

38

Considrese el proble ma discutido en el Ejemplo 2.31. Es


granos
posible utilizar la Ecuacin (2.33) para calcular el nmer o total de
te:
siguien
de arroz que se acumu laran en 64 das, de la forma

Ejemplo 2.36.

63
63
64
63
63
63
- 1.
Obsrvese que 264 = 2 X 2 = 2 + 2 , luego 2 - 1 = 2 + 2
263 .
fue
64
da
el
os
recibid
Recurdese que el nmero de granos de trgo
que la
Por tanto, el nmero de granos recibidos el da 64 era de uno ms
series
las
l,
genera
En
res!
anterio
das
suma de los recibidos en todos los
decir,
Es
rstica.
geomtricas tienen esta caracte

7, que es 1 menos que 8


1 + 2 + 4
1 + 2 + 4 + 8 = 15, que es 1 menos que 16
creciy as sucesivamente. Esto aporta otro punto de vista sobre el rpido
miento de las funciones exponenciales.

2.3.

SUMARIO

conjunEn este captulo se han introducido algunas ideas fundamentales sobre


se
directa
tienen
es
nocion
estas
de
a
mayor
tos y funciones. Como se sugiri, la
conlos
emos
utilizar
libro
este
En
tica.
importantes aplicaciones en la inform
que esta
ceptos de conjun to y funcin siempre que sea necesario. Veremos
la soluen
ios
benefic
s
grande
e
produc
exacta,
y
notacin matemtica, concisa
leza
natura
de
mas
proble
s
propio
los
sean
ticos,
cin de problemas inform
tienen un
matem tica o no. Las propiedades de los conjuntos y las funciones
3, y en el
lo
gran paralelismo con las de la lgica, como veremos en el Captu
conociun
tanto,
diseo de compu tadora s, como se ver en el Captu lo 7. Por
en el
ancia
import
miento profundo de los conjun to y las funciones es de vital
estudio de la disciplina informtica.

Ejercicios
2.21.

Desarr ollar cada una de las sumato rias siguientes:

Conjuntos y funciones

39

d)

2.22.

Expresar las series siguientes en notacin sigma:


a)
b)

e)
d)

e)

2.23. a)
b)

2.24.

i~

17 + 21 + 25 + ... + 65.
2 + 5 + 10 + 17 + .. , + 101.
La suma de los nmeros impares de O a 1000, inclusive.
La suma de los enteros positivos menores que 300 y que sean divisibles por 3.
La suma de las raices cuadradas de todos los enteros positivos
menores que 1000.
Justificar la Ecuacin (2.28).
Justificar que la suma de los n primeros nmeros impares es n 2

Calcular la suma de las expresiones desarrolladas en el Ejercicio 2.22.

2.25. Calcular las sumas siguientes:


25

a)

b)

i~ 2i(i + 1)

e)

32
=6

e)

~1

f)

g)

i~

h)

1 a

13

2.26.

2k

i=

Un programa de computadora ordena una lista L = (al' a 2, ..., a n ) en la


forma siguiente. Examina cada elemento de la lista, selecciona el mayor,
y lo intercambia con an0 A continuacin, repite el mismo proceso para la
sublista (a l ' a 2 , ... , a n _ 1)' El programa termina cuando slo quede a 1 en
la sublista.
a)

b)

2.27.

+ 1)

10

k~5

(2

12

d)

Utilizar notacin sigma para escribir una expresin que refleje el


nmero de exmenes realizados por el proceso.
Sumar la expresin.

En Nepal, el arroz se cultiva a menudo en terrazas formadas en las


laderas de las colinas. Una coleccin de estas terrazas, observadas a

40

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

vista de pjaro, se puede ver en la Figura 2.16. El cuarto de crculo


interior, correspondiente a la cima, no est cultivado. Movindonos
hacia abajo por la colina, los parterres se alternan con zonas escarpadas
no cultivadas. Supongamos que, para una determinada colina, el radio
del crculo de la cima es de 75 metros, y cada crculo concntrico de ah
hacia abajo tiene 50 metros. Supongamos que hay 10 parterres plantados.'
a)

b)

Utilizar la notacin sigma para escribir una expresin que refleje el


rea total cubierta por los parterres de arroz.
Calcular el rea total cubierta por parterres.

75

125

175

225

275

325

Metros

Figura 2.16. Panormica a vista de pjaro


de los parterres de Nepa!.

2.28.

Si comenzamos con una clula de levadura el da O, y al final de cada


da cada clula se divde en dos, cmo de grande ser la colona despus de n das?

CAPTULO

LGICA

La lgica est adquiriendo un papel cada vez ms preponderante en la informtica. De hecho, algunas personas llegan tan lejos como para afirmar que la
informtica no es ms que lgica aplicada. En este texto, la lgica tiene tres
distintas e importantes aplicaciones: se utiliza la lgica en programacin para
construir expresiones lgicas (Captulo 4); se utiliza la lgica para escribir pre y
poscondiciones y otros asertos que describen el comportamiento de los programas (Captulos 5 y 6); Yse utiliza la lgica como fundamento para el diseo de
las computadoras mismas (Captulo 7).
En las Secciones 3.1 y 3.2 se introduce la lgica proposicional, que es un
sistema para razonar y hacer clculos con proposiciones. La lgica proposicional naci entre los aos 1847 y 1854, fruto de los trabajos de George Boole.
Boole observ que exista una gran similitud entre las operaciones lgicas and
y or, y las operaciones aritmticas producto y suma. Boole desarroll un sistema para la manipulacin de expresiones lgicas, que era tan preciso para
manipular esas expresiones como la aritmtica para manipular nmeros.
En la Seccin 3.3 se extiende la nocin de lgica proposicional a otra ms
amplia, conocida como lgica de predicados. Esta extensin nos permite utilizar la lgica en informtica de una forma muy constructiva. Por ejemplo, la
utilizacin de los denominados cuantificadores lgicos est estrechamente relacionada con la idea de bucles en los programas.
Tambin se introducen las ideas de tautologa y demostracin. Estos conceptos sern revisados en el Captulo 6, en yuxtaposicin con los conceptos
paralelos de prueba y verificacin. Lgica y demostracin son tan fundamentales para la informtica como para otras disciplinas, tanto artsticas como cientficas; por tanto, este captulo ser til en otras reas diferentes.

3.1.

LGICA PROPOSICIONAL

La idea bsica de Boole fue la de analizar patrones de argumentaciones lgicas, utilizando smbolos para representar tanto aseveraciones simples como los

42

y pro gra mas


n de prob lem as, algo ritm os
Com puta cin l. Lgica, reso luci

de lgica
la lgica se con oce por el nom bre
pro pio s patr one s. Est a par te de
pos icio nal,
s lgica simblica). En lgica pro
proposicional (o en algu nos caso
e) o falso
r slo dos valores verdadero (tru
una frase (o proposicin) pue de tene
:
ejemplos tpicos de proposiciones
(false). Las ora cion es siguientes son
usa de
I
ulo issceles, que tiene una hip oten
El re a de un tri ngu lo rect ng
lon gitu d 2 es 1/2.
(1 3 5 7 6 4) son men ore s que 10.
Tod os los elem ento s de la lista
3 + 5 = 7.
enjum ps ove r the lazy dog est n pres
En la frase Th e qui ck bro wn fox
s.
letr as del alfa beto ingl
tes, al men os una vez, tod as las
ficacin
del Cal vin College, alca nz la cali
Nin gn alu mn o de info rm tica
de B + en el cur so de 1990.
precio las ante rior es, de una form a ms
Con obj eto de exp resa r frases com
3.1 se
la
Tab
a escribir pro pos icio nes . En la
pos isa, util izam os un estilo formal par
pro
ibir
lgicos que se util izan al escr
pre sen ta una lista de los operadores
ciones.
iendo
una exp resi n que se con stru ye sigu
Definicin. Un a proposicin es
las reglas siguientes:
(false) son pro pos icio nes .
Regla 1: Verdadero (true) y falso
ocido
o tipo sea {verdadero, falso} (con
Regla 2: Cua lqu ier variable cuy
pos ici n.
com o tipo boo lean o) es una pro
tam bin lo es ('" p).
Regla 3: Si p es una pro pos ici n,
/\ q),
nes, tam bin lo son (p v q), (p
Regla 4: Si p Y q son proposicio
(p => q), (p <=> q).
tues recursiva, segn se vio en el Cap
o
Obsrvese que la definicin ante rior
una
de
s
ino
nen una pro pos ici n en trm
iutil
lo 2. Es decir, las reglas 3 y 4 defi
idas
stru
con
cuales pue den hab er sido
ten
ms pro pos icio nes ya existentes, las
nte. Sin emb arg o, deb ido a que exis
ame
izan
zan do las reglas 3 y 4, Y as sucesiv
util
no
que
2,
y
1
s util izan do las reglas
pro pos icio nes elementales form ada
algo es
n, el pro ces o par a dete rmi nar si
nici
n no
la pal abr a proposicin en la defi
nici
defi
la
ir,
dec
es
reglas, no es infinito;
una pro pos ici n, util izan do estas
ipu es circular.
os con el clculo pro pos icio nal, man
Por el mo men to, cua ndo trab ajem
n
pos ici en
ntar emo s sim bol izar nin gun a pro
laremos slo var iabl es y no inte
las variamos formas de inte rpre taci n de
particular. M s ade lant e intr odu cire
diseo de
el mu ndo de la pro gra mac in y del
bles, que son de gra n util idad en
las com put ado ras.

Lgica

Tabla 3.1.

Los operadores lgicos

Equivalente
en castellano

Smbolo

no
o

V
/\

=>

implica
si y solo si

-=

43

Significado
Negacin
Disyuncin
Conjuncin
Implicacin
Eq uivalencia

Despus de ver algunos ejemplos de la aplicacin de estos operadores, estudiaremos otras interpretaciones.
Ejemplo 3.1. Si p, q y r son variables booleanas, entonces las siguientes
expresiones son proposiciones vlidas:
p
q

c- p)

(p v q)
(p v (q v

(p

=o>

(q v (r

=o>

(p

De las Reglas 2 y 3 puede deducirse, de forma inmediata, que las cuatro


primeras son expresiones. Para la quinta expresin puede aplicarse reiteradamente la cuarta regla, siguiendo los siguientes pasos:
p, q y r son proposiciones por la segunda regla.
(q v r) es una proposicin segn la regla 4.
(p v (q v
es una proposicin segn la regla 4.

Una lnea de razonamiento similar sirve para demostrar que el sexto ejemplo es una proposicin:
p, q y r son proposiciones por la segunda regla.
(p ~ q) es una proposicin segn la regla 4.
(r =o> (p ~ q es una proposicin segn la regla 4.
(q v (r =o> (p ~ q))) es una proposicin segn la regla 4.
(p =o> (q v (r =o> (p ~ q))) es una proposicin segn la regla 4.

Ejemplo 3.2.
(p)
(p q) p)
~ (p)

Las expresiones siguientes no son proposiciones:

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

44

Observando el Ejemplo 3.2, si somos estrictos en la aplicacin de las reglas,


los parntesis juegan un papel crucial en la determinacin de si una expresin es
una proposicin. Sin embargo, podemos prescindir de ellos siempre que el significado de la expresin est claro. Por ejemplo, podemos escribir '" p en lugar de
('" p), p v q en lugar de (p v q), y as sucesivamente.
Sin embargo, la eliminacin descuidada de los parntesis puede conducirnos a am~igedades. Por ejemplo, no est claro si p v q /\ r significa
((p v p) /\ r)
(p v (q /\ r))

o bien,

Para evitar estas ambigedades, se asignan prioridades a los operadores:


'" tiene la prioridad ms alta; /\ tiene la siguiente ms elevada; y v, =:> y ~
tienen sus prioridades por este mismo orden. De esta forma, la expresin
p v q /\ r siempre se debe interpretar como (p v (q /\ r)).

3.1.1.

Representacin de frases en castellano


utilizando la lgica proposicional

No siempre es posible representar cualquier frase arbitraria, de forma simblica, utilizando proposiciones o predicados. Es decir, muchas frases no son declarativas y, por tanto, no puede afirmarse que sean verdaderas o falsas. Por
ejemplo, cierra la puerta! es una orden, y fuiste a la clase de anatoma de
ayer, del profesor Davidson? es una pregunta. Sin embargo, existen gran cantidad de frases que pueden representarse como proposiciones y, ms an, que
pueden representarse como predicados. En informtica, la mayora de las cosas
que solemos querer representar simblicamente, no son ambiguas, tienen un
valor verdadero o falso, tambin no ambiguo y son expresables en forma de
proposicin o de predicado.
Obsrvese que en la lgica proposicional existen cinco operadores. De hecho, solamente es necesario uno; el resto pueden obtenerse a partir de ste
(vanse los ejercicios de la Seccin 3.2). La lengua castellana ofrece una gran
cantidad de formas para expresar la misma idea; as, al representar frases
mediante proposiciones evitaremos muchos matices del significado, centrando
nuestra atencin en la estructura lgica de las oraciones. Del mismo modo,
utilizaremos la misma estructura lgica para expresar diferentes giros en castellano. Por ejemplo, si representamos la frase Phogbound quiere ser senador
mediante la variable p, las oraciones siguientes pueden representarse ambas
mediante la proposicin '" p:
Phogbound no quiere ser senador.
No es verdad que Phogbound pretenda ser senador.
De forma similar es posible simbolizar las frases siguientes, como p /\ q si
realizamos una asignacin apopiada a las variables p y q:

Lgica

45

El nmero n es un nmero primo menor que 100.


10 ~ x ~ 100
Henry Higgins era un soltero recalcitrante, pero Eliza Doolitte conquist
su corazn.
Aunque haba sido un traficante de esclavos, John Newton termin siendo
un decidido oponente a la esclavitud.
I

La primera de las oraciones anteriores puede descomponerse en dos frases


-n es un nmero primo y n es menor que 100- aunque estn condensa-

das en una utilizando, segn es costumbre en el lenguaje coloquial. La segunda


tambin contiene dos frases ocultas, aunque en este caso el mtodo de sntesis
corresponde a las matemticas. En la tercera, el adverbio pero tiene en lgica
significado de la operacin y; introduce un matiz en la frase que no es necesario para la construccin de las proposiciones. En la cuarta frase, la proposicin
aunque indica la presencia de una y, a la vez que sirve para remarcar el contraste.
Podemos simbolizar la frase:
Algunos han nacido para la grandeza, algunos alcanzan la grandeza y
algunos soportan sobre s la grandeza
tanto por ((p 1\ q) 1\ r) como mediante (p 1\ (q 1\ r)). En la Seccin 3.2 se ver que
ambas expresiones lgicas son equivalentes, y que pueden eliminarse los parntesis, quedando, por tanto, la expresin p 1\ q 1\ r. En la frase anterior, la primera coma equivale al operador 1\.
El operador v puede tener en castellano dos significados ligeramente diferentes, por 10 que es necesario distinguirlo. En la frase:
Este banco proporcionar crdito a todo el que mantenga un saldo medio de
500 dlares o que tenga un certificado de depsito de ms de 5000 dlares.
El banco, evidentemente, no intenta excluir a aquellas personas que cumplan
simultneamente ambos requisitos. Por el contrario, podemos imaginar a un
padre diciendo: Puedes ir a la piscina o a la pista de patinaje, que quiere
decir que puede ir a uno u otro lugar, pero no a ambos. Mientras el banco
utiliza la o inclusiva que significa que ambas posibilidades son aceptables, el
padre utiliza la o exclusiva que significa que una de las dos posibilidades es
aceptable, pero no ambas a la vez.
En proposiciones como p => q, p recibe el nombre de antecedente y q el de
consecuente. Un ejemplo en castellano de una implicacin lgica es:
Si Phogbound resulta elegido, entonces estaremos apaados.
Aunque el adverbio entonces no suele incluirse en el lenguaje coloquial. Si
simbolizamos mediante p la frase Phogbound resulta elegido, y mediante q a
estaremos apaados, podemos representar toda la frase como p => q (que

IGIL.JIUIJIM...i.IISIIISlIILllj!IJ"".!lI!C,;aIllJIII..lI!I!d!ll!lll.. 1!lII!fIlI""""",_4-~'
\IIl,

46

Compu tacin ,. Lgica, resoluc in de problem as, algoritm os


y progra mas

significa p implica q). De forma alternativa, es posible reescribir esa


frase en

la forma

Estaremos apaados si Phogb ound resulta elegido,


aunque la frase anterio r puede seguir representndose de forma
simblica
como p => q.
Obsrvense las distintas utilizaciones que se hacen de la proposicin
si, en
las siguientes frases:
Compr ar entrad as si representan Nuestr o barrio.
Compr ar entrad as slo si representan Nuestr o barrio.
Si representamos mediante r la proposicin representan Nuestr o
barrio y
mediante s la proposicin comprar entradas, la primer a frase puede
representarse en la forma r =::> s. Cualqu ier person a que pronuncie esta frase
no est
afirmando nada acerca de lo que hara si se representase Maebeth. En
cambio,
la ltima frase tiene un significado ligeramente diferente, y que se
simboliza
mediante s => r. Esta frase puede rehacerse de la forma si compr
o entrad as,
entonces es que se representa Nuestr o barrio; en definitiva, que la
nica circunstancia que har que compre entrad as es que se est representando
Nuestr o
barrio; En estas circunstancias, se dice que la proposicin s =::>
r es la proposicin recproca de r =::> s.
Otra propie dad import ante de la implicacin p =::> q es que no es necesa
rio
supone r la existencia de causalidad entre p y q. Por ejemplo, cuando
decimos:
Si George toca bien la viola, entonces le seleccionarn para la orques
ta,
implcitamente asumimos que si George es elegido para tocar en la orques
ta, es
porque toca bien. La frase:
Si 1

+ 1

2, entonces el sol es el centro del sistema solar.

Tambin se simboliza por p => q que, desde el punto de vista de la


lgica, es
tan vlida como la afirmacin de George y la orquesta.
La causalidad es otra de las cosas que podemos expresar en lenguaje
natural, pero que no podemos expresar en el clculo proposicional.
La expresin p ~ q se utiliza para indicar que dos proposiciones
son
lgicamente equivalentes; es decir, que una implica la otra y vicever
sa. Un
ejemplo tpico es el siguiente:
Sea T un tringulo de lados a, b y e. Entonces a 2 + b 2 = e 2 slo si
T es un
tringulo rectngulo.
Si representamos por p a 2 + b 2 = e 2 , y por q T es un tringu
lo rectngulo, la frase a 2 + b2 = e 2 si y slo si T es un tringulo rectng
ulo

Lgica

47

se representa mediante P ~ q. Es decir, que son ciertas simultneamente


tanto P => q como q => p.
Ejemplo 3.3. Se pueden representar como proposiciones oraciones enteras. Veamos un ejemplo relativamente complicado: Si conseguimos
los contratos de Dynamic Systems o de Metadyne, van Alstyne o Liu
realizarn tanto el anlisis como el diseo; a Frederick no se le asignar
el diseo, y Thompson ser despedido. Para poder escribir la proposicin equivalente a esta frase, primero tenemos que asociar variables a
cada parte de la oracin.
DS
MD
VAA
L/VA
VAD
L/VD
FRA
TF

Conseguir el contrato de Dynamic Systems.


Conseguir el contrato de Metadyne.
Se le asigna el anlisis a van Alstyne.
Se le asigna el anlisis a van Liu.
Se le asigna el diseo a van Alstyne.
Se le asigna el diseo a Liu.
Se le asigna el anlisis a Frederick.
Thompson es despedido.

Con estas definiciones de variables, la oracin anterior puede representarse:


(DSvMD) =>
(((VAA

3.1.2.

1\

VAD) v (L/VA

1\

L/VD 1\

"" FRA 1\

TF)

Evaluacin de proposiciones: Tablas de verdad

Recurdese que en el Captulo 2 definamos el concepto de estado de una


variable. Esta nocin puede aplicarse tambin a las proposiciones.
Definicin. Sean PI' ..., Pn las variables de una proposicin. El estado de
esas variables PI' ..., Pn es el resultado de asignar los valores booleanos
verdadero o falso a cada una de ellas.
Por ejemplo, supongamos que tenemos la proposicin P v q. Puesto que la
proposicin consta slo de dos variables, cada una de las cuales puede tomar
slo dos valores posibles (verdadero o falso), existen slo cuatro posibles estados para las variables de la proposicin P v q. De forma alternativa, podemos
considerar la proposicin P v q como una funcin en dos variables P y q, con
dominio {verdadero, falso} x {verdadero, falso} y con rango {verdadero, falso}.
As, al contrario que las funciones con dominios infinitos (tales como N o R), la
funcin P v q tiene un dominio tan reducido que pueden tabularse sus valores
para todos los estados posibles de sus variables. Estas tablas reciben el nombre

Computacin /. Lgica, resolucin de problemas, algoritmos y programas

48

de tablas de verdad. La tabla de verdad de la funcin p v q se muestra en la


Figura 3.1.
p

pvq

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

verdadero
verdadero
verdadero
falso

Figura 3.1.

Tabla de verdad para la funcin pv q.

En la tabla, se puede apreciar que el valor de la funcin es verdadero siempre


que cualquiera de las variables, o ambas, valga verdadero; en caso contrario
valdr falso. Esta definicin de la funcin es consistente con nuestra idea intuitiva acerca de la disyuncin, que se ilustr en la Seccin 3.1.1. Supongamos
que las variables p y q representan las proposiciones siguientes:
p

Tenemos un saldo medio mayor de 500 $.


Tenemos un certificado de depsito de ms de 5000 $.

Entonces, la proposicin p v q vale verdadero, siempre que p y q, o ambas a la


vez, sean verdaderas; en otro caso (p v q) valdr falso.
Las tablas de verdad de las otras operaciones de la lgica proposicional,
pueden construirse de forma anloga. Estas tablas se muestran en la Figura 3.2.
La mayora de los valores de estas operaciones son consistentes con las ideas
intuitivas introducidas en la Seccin 3.1.1. Asi, la negacin siempre devuelve el
valor contrario al de la variable, y la conjuncin lgica slo se evala a verdadero cuando ambas variables valen verdadero simultneamente.
El operador implicacin precisa una discusin ms cuidadosa, sobre todo
en el caso en que p vale falso. Lo anterior, no es dificil de entender si consideramos el ejemplo siguiente:
Si representan Nuestro barrio, entonces comprar entradas.
La frase anterior se representa por p

~ q.

De hecho, si no se representa

Nuestro barrio, la variable p vale falso. Sin embargo, no est garantizado que
no queramos comprar entradas aunque no se represente Nuestro barrio; en su
lugar, podemos comprar entradas para Lnea de coros. Puesto que la falsedad

de p no garantiza la falsedad de q, podemos permitir que la proposicin resultante sea, en este caso, verdadera. (Otra justificacin para esta decisin se
presentar en la Seccin 3.2.4.)
La tablas de verdad se pueden construir para proposiciones de complejidad
arbitraria. Cuando una proposicin involucra a ms de un operador, la evaluacin de su valor se realiza siguiendo el orden de prioridad de los operadores.
Esto se ilustra en el Ejemplo 3.4.

Lgica

pAq

verdadero
falso
verdadero
falso

verdadero
falso
falso
falso

P
P

49

~p

verdadero
falso

verdadero
verdadero
falso
falso

falso
verdadero

a)

b)

p=q

p<:o>q

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

verdadero
falso
verdadero
verdadero

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

verdadero
falso
falso
verdadero

d)

e)

Figura 3.2.

Tablas de verdad para proposICiones: (a) Negacin; (b) conjuncin; (e) implicacin; (d) equivalencia.

= '"

Ejemplo 3.4. Para construir la tabla de verdad de (p v q)


p comenzamos por p y q; a continuacin, se deriva la tabla para cada subproposicin
(p v q) y ~ p, combinando finalmente los resultados utilizando la tabla de
verdad de la operacin =. Habitualmente se trabaja siempre de izquierda a
derecha, tal y como se muestra abajo:
p

pvq

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

verdadero
verdadero
verdadero
falso

~p

falso
falso
verdadero
verdadero

(p v q)

~p

falso
falso
verdadero
verdadero

Una forma alternativa de construir tablas de verdad es la de escribir la operacin una nica vez y colocar el resultado de la evaluacin de cada subproposicin debajo del operador correspondiente. Si lo hacemos as, debemos tener
cuidado de rellenar las columnas en el orden adecuado, como se muestra en la
tabla de verdad siguiente:
p

(p v q)

~p

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

verdadero
verdadero
verdadero
falso

falso
falso
verdadero
verdadero

falso
falso
verdadero
verdadero

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

50

En este caso, comenzamos rellenando las columnas de p y q; a continuacin, rellenamos la columna de (p v q); a continuacin, la de "-' p, y finalmente
la columna correspondiente a =>. La tabla de verdad de la proposicin completa se corresponde con los valores de la ltima columna obtenida, que no se
corresponde forzosamente con la columna de ms a la derecha.
El nmero de filas de una tabla de verdad crece exponencialmente con el
nmero de variables presentes en la proposicin. Es decir, si una proposicin
tiene una variable como, por ejemplo, "-' p, su tabla de verdad tiene dos filas.
Proposiciones con dos variables como p v q tienen tablas de verdad de cuatro
filas. Proposiciones de tres variables tendrn ocho filas, puesto que existen
2 3 = 8 formas diferentes de asignar los valores verdadero y falso a las tres
variables. En general, el tamao de una tabla de verdad con n variables ser de
2n filas. Por este motivo, si trabajamos con ms de cuatro o cinco variables, el
tamao de las tablas de verdad resulta inmanejable.
Una forma de acortar la longitud de las tablas de verdad es mediante la
bsqueda de condiciones da igual. Por ejemplo, cuando evaluamos la proposicin (p v p), si p vale falso, no importa lo que valga q; la proposicin se
evaluar a verdadero en cualquiera de los casos. Es decir, el valor de q es una
entrada da igual, y 10 denotaremos mediante un guin (-) en la columna
correspondiente de la tabla de verdad. Con esto, podemos reducir en uno el
nmero de filas de la tabla de verdad para p v q:
p

pvq

verdadero
falso
falso

verdadero
falso

verdadero
verdadero
falso

Utilizando esta tcnica, se pueden reducir de forma significativa el nmero de


lneas de las tablas de verdad de expresiones complejas, como se muestra en la
Figura 3.5.
Ejemplo 3.5. La proposicin (p /\ q) => (r v (p => s)) podra tener una tabla
de verdad completa de 16 lneas. Sin embargo, utilizando condiciones da
igual podemos reducir su tamao a cinco lineas, tal y como se muestra
debajo:
p

verdadero
verdadero
verdadero

falso
verdadero
verdadero
verdadero

falso
verdadero
falso
falso

(p 1\ q)

verdadero
falso

falso
falso
verdadero
verdadero
verdadero

=>

verdadero
verdadero
verdadero
verdadero
falso

(r v (p

=>

s))

verdadero
verdadero
falso

verdadero
verdadero
falso

Lgica

51

El proceso de construccin de tablas de verdad con entradas da igual


puede ser bastante complejo, tal y como sugiere el ejemplo. Cursos avanzados
en lgica yen diseo de circuitos tratan este tema ms cuidadosamente. Intuitivamente podemos ver que, si reducimos el nmero de filas en una tabla de
verdad, reduciremos tambin la complejidad de cualquier circuito representado por la proposicin. Esta es una de las actividades cruciales en el diseo de
l(ls computadoras modernas: un objetivo primordial es la minimizacin del
nmero de circuitos y, por tanto, la reduccin del costo de fabricacin de la
computadora. Estas ideas sern abordadas en el Captulo 7.

3.1.3.

Tautologas

Algunas proposciones se distinguen por el hecho de que son siempre verdaderas.


Es decir, cualquiera que sea la asignacin de valores a sus variables, siempre se
obtendr el valor verdadero en la ltima columna de la evaluacin de la proposicin. Formalmente, estas proposiciones reciben el nombre de tautologas.
Definicin. Una tautologa es una proposicin que se evala a verdadero
en cualquier estado; una contradiccin es una proposicin que se evala a
falso en cualquier estado.
Podemos comprobar si una proposicin es una tautologa sin ms que escribir
su tabla de verdad. Tambin existen otros mtodos para comprobar si una
proposicin compleja es o no una tautologa. Estos mtodos implican el desarrollo de demostraciones, y se estudiarn en la Seccin 3.2.3. Las demostraciones de la lgica juegan un papel trascendental en la informtica, por lo que les
dedicaremos un inters especial en este captulo.
Ejemplo 3.6. Para verificar que la proposicin (p 0= q) /\ p) 0= q es una
tautologa, podemos desarrollar su tabla de verdad y examinar la columna
ms a la derecha para comprobar que todas las entradas son verdadero.
p

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

((p

verdadero
falso
verdadero
verdadero

=;.

q) /\ p)

verdadero
falso
falso
falso

=;.

verdadero
verdadero
verdadero
verdadero

Ejemplo 3.7. La proposlcIOn' p /\ P es una contradiccin. Esto puede


verse en la tabla de verdad siguiente:
"V

verdadero
falso

falso
verdadero

falso
falso

52

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Esto confirma algo intuitivo: es imposible para una proposicin ser simultneamente verdadera y falsa. Igualmente, p v '" p es una tautologa.
pv

p
verdadero
falso

falso
verdadero

~p

verdadero
verdadero

La aseveracin de que p v '" p es una tautologa recbe el nombre de ley del


exclusin del caso intermedio. Es decir, para cualquier proporcin, ella misma o
su negacin deben ser cierta; no existe una tercera posibilidad. Esto significa que
algunas frases que son comunes en el lenguaje coloquial, como la frase que est
leyendo ahora es falsa, estn excluidas del clculo proposicional. Se han desarrollado otros modelos lgicos que no incluyen la ley de exclusin del caso
intermedio; estos modelos son de gran utilidad en el estudio de las bases de
datos. La ley de exclusin del trmino medio, junto con el hecho de que la
proposicin p 1\ "-' P es una contradiccin, nos indica que cualquier proposicin,
o es una tautologa o no lo es; no puede ser ambas cosas al mismo tiempo.
Ejemplo 3.8.
de verdad.

La proposicin '" (p 1\ q) Y ('" P v '" q) tienen la misma tabla

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

~p

falso
falso
verdadero
verdadero

~q

falso
verdadero
falso
verdadero

~(P/\q)

falso
verdadero
verdadero
verdadero

(~pv~q)

falso
verdadero
verdadero
verdadero

La aseveracin de que "-' (p 1\ q) Y ('" P v '" q) tienen la misma tabla de


verdad, constituye una de las tres aseveraciones que conjuntamente constituyen las denominadas Leyes de Margan. Estas leyes son muy tiles en la simplificacin de proposiciones compuestas, especialmente si contienen negaciones. La
segunda Ley de Morgan se analiza en el ejercicio 3.6.

Ejercicios
3.1.

Razonar cules de las frases siguientes constituyen una proposicin:


a)
b)
e)
d)

En esta pgina hay 512 palabras exactamente.


314159 es un nmero primo.
Xl

2x

13.

La edad del universo es de unos 17 billones de aos, aproximadamente.


e) Disparad al pianista.

Lgica

f)
g)
h)

3.2.

(p => (p /\ q))
((( "-' p)
q) /\ ( "-' r))
(p v ( "-' q)) /\ (p V q)) => p)

-=

Representar las frases siguientes, de forma simblica, utilizando proposiciones. Definir claramente qu significa cada variable.
a)
b)

e)
d)
e)

f)

3.4.

x - y = o.
Por qu es azul el cielo?
La hipotenusa es el lado ms corto de un tringulo rectngulo.

Construir las proposiciones siguientes a partir de variables, aplicando


una regla de la definicin en cada paso.
u)
h)
e)

3.3.

53

-l~x~l,-l~y~l

Aunque Manderson tena una mente fina y analtica y grandes riquezas, estaba incomprensiblemente loco.
Bien Trent estaba en Pars mientras Mabel estaba en Londres, bien
Trent estaba en Venecia mientras Mabel estaba en Pars.
Una definicin es recursiva slo si incluye un paso de inicializacin y
otro de induccin.
Siempre que Thomas y Dumars disparen bien, los Pistons ganarn, a
no ser que Rodman est lesionado y Laimber batee mal, en cuyo
caso los Pistons perdern.
Si el grupo de diseo cometiera un error, seran los principales responsables, y los dems tendran una responsabilidad secundaria; si el
grupo de programadores cometiera un error de codificacin, entonces el grupo de Ted o el de Louis sera el principal responsable; si el
error fuera de prueba, tanto el grupo de FouSen como el de Rita
seran los principales responsables.

De acuerdo con la definicin, cules de las siguientes son proposiciones


vlidas?
verdadero
(verdadero)
~P/\q

p => "-'q)
(p V "-' p) /\ q))
(p => p) /\ "-' q) => q)

3.5.

Construir las tablas de verdad de las proposiciones siguientes, utilizando


condiciones da igual siempre que resulte apropiado. Identificar las tautologas.
a)
b)
e)
d)

p => q) /\ p) => q
pp => r) /\ (q => ~r)) => (p /\ q)
p /\ (q V r) => S
(p =>q) /\ (q => r)) => (p => r))

54

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

e)

f)

((p => (q /\ "-'q)) => p)


(p => q) V (p <o:> '" q)

Demostrar que '" (p v q) y ("-' P /\ "-' q) tienen la misma tabla de verdad.

3.6.

3.2.

RAZONAMIENTO CON PROPOSICIONES


1

En esta seccin se analizan algunos aspectos fundamentales del razonamiento


con proposiciones. En este contexto, razonamiento significa desarrollo de nueva
informacin a partir de otra dada, expresada en forma de proposiciones (y
como predicados).
Es necesario desarrollar mtodos que permitan determinar cundo dos
proposiciones son equivalentes, de forma que una pueda ser sustituida por la
otra. Es tambin necesario encontrar una forma alternativa a las tablas de
verdad, para determinar cundo una proposicin arbitraria es una tautologa.
Finalmente, es necesario explorar cmo los mtodos de razonamiento pueden
ayudarnos a resolver problemas lgicos que estn planteados en castellano.
Todas estas tcnicas constituyen una preparacin necesaria para una fase posterior, en la que utilizaremos tcnicas de razonamiento para analizar varias
caractersticas de programas escritos en Pascal (Captulo 6) y en el diseo de
computadoras (Captulo 7).

3.2.1.

Equivalencia

Considrese la proposicin (p /\ q) V (p /\ "-' q), cuya tabla de verdad se muestra abajo:


p

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

(p /\ q) V (p /\

~q)

verdadero
verdadero
falso
falso

Los valores de la ltima columna de la tabla son exactamente los mismos que
los de la columna de la p; por tanto, podemos decir que (p /\ q) V (p /\ '" q) es en
cierta manera equivalente a p. Por tanto, si en alguna situacin nos encontramos con (p /\ q) V (p /\ '" q) podemos sencillamente reemplazarla por p.
En cuanto empezamos a razonar con proposiciones, se ve la necesidad de
simplificar proposiciones complejas. Nuestro propsito ahora ser el de definir
qu significa que dos proposiciones sean equivalentes, y el ver cmo esta equivalencia permite simplificar expresiones complejas.
Definicin. Se dice que dos proposiciones p y q son equivalentes si tienen
el mismo valor para cada estado. En otras palabras, p y q son equivalentes
si tienen la misma tabla de verdad.

Lgica

55

Por tanto, una forma de comprobar si dos proposiciones son equivalentes es


escribiendo su tabla de verdad. Existe otro mtodo que generalmente es ms
eficaz, basado en el siguiente teorema.
Teorema. Dos proposiciones p y q son equivalentes y lo simbolizamos
como p == q, si y slo si la proposicin p <:o> q es una tautologa.
El teorema no es dificil de probar. Primero, supongamos que p y q son
equivalentes. Entonces en cualquier estado ambas son bien verdaderas bien
falsas. Por tanto, en cualquier estado p <:o> q es bien (verdadero <:o> verdadero)
bien (falso <:o> falso) haciendo de p <:o> q una tautologa. Por el contrario,
supongamos ahora que p <:o> q es una tautologa, y que S es un estado en que p
es falso. Puesto que p <:o> q es una tautologa, q tiene que ser tambin falso.
Igualmente, si S es Un estado en que p es verdadero, entonces q tambin debe
serlo en ese estado.

3.2.2.

Propiedades de la equivalencia

La equivalencia tiene una serie de propiedades que se verifican para todas las
proposiciones, y que son de gran utilidad en varias aplicaciones de la lgica.
En la Tabla 3.2 se resumen las ms importantes.
Tabla 3.2.

Propiedades de la equivalencia

Conmutatividad'
pAq
pv q

==
==

Asociatividad

qAP
qvp

==
==

=q

==
==

(p A q) A r
(p v q) v r

pvp == p
p v verdadero == verdadero
p v falso == p
pV(pAq) == P

~pA ~q
~pv ~q

p<o>q==(q=q)A(q=p)

Identidad
p == p
Ley de la contradiccin
pA ~p

== verdadero

v -simplificacin

==
==

Ley de la bicondicionalidad

Ley de la exclusin del trmino medio


p v ~p

~(pAq)

~pvq

Propiedad de la negacin
~(~p)

~(pvq)

(p A q) V (p A r)
(p v q) A (p V r)

Ley de la implicacin
p

==
==

Leyes de Morgan

Distributividad
p A (q V r)
p v (q A r)

P A (q A r)
p v (q v r)

== falso

-simplificacin

== P
P A verdadero

pAp

==

p A falso == falso
p A(p V q) == p

56

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

Obsrvese que muchas de estas expresiones tienen una paralela en las que
fueron estudiadas para los conjuntos (vase Tabla 2.1). Adems, muchas de
estas propiedades tienen tambin una anloga en la aritmtica. As, las propiedades conmutativa, asociativa y distributiva permiten la simplificacin de expresiones aritmticas. De una forma similar la asociatividad, conmutatividad y
distributividad introducidas en la Tabla 3.2 permiten la simplificacin de proposiciones lgicas.
Estas propiedades se utilizan de diversas maneras. Por ejemplo, la conmutatividad se utiliza para reordenar las proposiciones y as poder realizar otras
simplificaciones. La asociatividad permite la eliminacin de parntesis. Por
ejemplo, puesto que p /\ (q /\ r) == (p /\ q) /\ r, de forma equivalente es posible
escribir p /\ q /\ r. Las leyes de la distributividad permiten la factorizacin de las
proposiciones. Esta leyes totalmente equivalente a la ley aritmtica que permite escribir 3 x 5 + 3 x 7 = 3 x (5 + 7). Las leyes de Morgan son de gran
utilidad cuando se trabaja con expresiones que incluyen negaciones. La ley de
la implicacin permite escribir expresiones equivalentes a la implicacin, pero
utilizando slo v, /\ Y "'.
Antes de utilizar las leyes de la equivalencia es necesario convencerse de
que son correctas. Para ello es suficiente construir una tabla de verdad para
cada lado de la equivalencia y verificar que ambas tablas son idnticas. Demostraremos lo anterior para la ley de la implicacin, dejando el resto como
ejercicio.
Ejemplo 3.9. Para demostrar que (p ~ q) == ('" p v q), podemos construir
sus tablas de verdad de la forma siguiente:
p

p=q

-pvq

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

verdadero
falso
verdadero
verdadero

verdadero
falso
verdadero
verdadero

(p

q)~(-pvq)

verdadero
verdadero
verdadero
verdadero

Simplificacin de proposiciones mediante la utilizacin de las propiedades de la


equivalencia. Centremos nuestra atencin en la simplificacin de proposiciones. Entendemos por simpllfzcacin el proceso de modificar una proposicin
para que resulte ms til a un determinado propsito, como el conseguir que
contenga menos variables y/o operadores que la proposicin original.
Para simplificar una proposicin, escribimos una serie de pasos numerados.
Cada paso se compone de una proposicin en la parte izquierda, y de una
referencia a una ley particular en la parte derecha. La proposicin de la izquierda es siempre equivalente a la del paso inmediatamente anterior, en virtud de la propiedad escrita en la derecha. Por ejemplo, supongamos que se
desea reducir la proposicin (p ~ q) v (p ~ r). En el paso 1 se escribe la
proposicin, y los pasos 2 al 4 contienen las proposiciones equivalentes.

Lgica

2.
3.

(p => q) /\ (p => r)
(- p v q) /\ ( - P v r)
'" p v (q /\ r)

4.

p => (q /\ r)

1.

57

Ley de implicacin
Distributividad
Ley de la implicacin

Donde puede observarse que la proposicin del paso 2 resulta de la del paso 1,
tras la aplicacin de la ley de la implicacin. La del paso 3 se obtiene de la
del '2 aplicando la distributividad, y la del 4 se obtiene de la del 3 por la ley de
la implicacin. El Ejemplo 3.10 es ms complicado:

Ejemplo 3.10. En el Ejercicio 3.5a se utiliz una tabla de verdad para


demostrar que la proposicin ((p => q) /\ p) => q es una tautologa. Pueden
utilizarse las propiedades de la equivalencia para demostrar de nuevo que
lo es. En este caso demostraremos que la proposicn anterior es equivalente a la proposicin simple verdadero.
1.
2.

3.
4.

5.
6.
7.
8.
9.
10.
11.

((p => q)/\p) => q


((-pvq)/\p) => q
(( - P /\ p) V (q /\ p)) => q
(falso v (q /\ p)) => q
(q /\ p) => q
- ((q /\ p) /\ - q)
- ((p /\ q) /\ - q)
- (p /\ (q /\ - q))

Ley de implicacin
Distritibutividad
Contradiccin
v -simplificacin
Ley de la implicacin
Conmutatividad
Asociatividad
Ley de la contradiccn
/\ -simplificacin
Negacin

-(p/\falso)
- falso
verdadero

El ejemplo 3.10 se ha desarrollado con excesivo detalle; cada propiedad se


ha aplicado en un paso separado. Cuando nos familiaricemos ms con estas
propiedades, ser posible abreviar los clculos. De hecho, es lo mismo que en
el caso del lgebra, donde nuestra familiaridad y costumbre en la manipulacin
de expresiones complejas nos permite la simplificacin mediante la aplicacin
de varias reglas a la vez. Como ejemplo, obsrvense las dos simplificaciones
siguientes:
1. 5x + 1 = 3x
2.2x=1
3. x = 1/2

1.
2.
3.

4.
5.
6.
7.
8.
9.
10.

5x + 1 = 3x + 2
(5x + 1) - 1 = (3x + 2) - 1
5x + (1 - 1) = 3x + (2 - 1)
5x + O = 3x + 1
5x = 3x + 1
5x - 3x = (3x + 1) - 3x
(5 - 3)x = (1 + 3x) - 3x
2x = 1 + (3x - 3x)
2x = 1 + (3 - 3)x
2x = 1 + Ox

58

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

11.
12.
13.
14.
15.

2x=1
(1/2)2x = 1/2
((1/2)2)x = 1/2
Ix = 1/2
x = 1/2

La simplificacin en tres pasos de la izquierda es lo habitual cuando se


conocen bien las propiedades de la aritmtica, mientras que la simplificacin
en 15 pasos es lo habitual en los aprendices del lgebra. Con este libro se
pretende alcanzar un conocimiento suficiente de la lgica, de manera que las
simplificaciones se parezcan ms a la de la izquierda, es decir, que se realicen
aplicando varias leyes en cada paso. Sin embargo, el conocimiento de las
propiedades en que se basan estos argumentos, es fundamental para entender
claramente el proceso realizado.
El ejemplo 3.11 muestra una serie de pasos ms corta, en la simplificacin
de la proposicin (p => (q /\ r)) /\ (~p => (q /\ s)). En ella q aparece como parte
del consecuente de dos condiciones diferentes, que estn conectados con el
operador /\. En la simplificacin se extrae q de ambas, de forma que la proposicin puede escribirs como la conjuncin de q con dos implicaciones.
Ejemplo 3.11.
1.

2.
3.
4.

3.2.3.

Simplificar la proposicin (p

(p => (q /\ r)) /\ ( ~ p => (q /\ s))


( ~ p v (q /\ r)) /\ (p V (q /\ s))
( ~ p v q) /\ ( ~ P v r) /\ (p V q) /\ (p V s)
(( ~ P /\ p) V q) /\ ( ~ P v r) /\ (p V s)

=>

(q /\ r)) /\ (~p => (q /\ s)):

Ley de la implicacin, negacin


Distributividad, asociatividad
Conmutatividad,
distributividad
Ley de la contradiccin
v -simplificacin
Ley de la implicacin

Reglas de inferencia: La idea de demostracin

Cuando se estudia la lgica, el primer objetivo es el de conseguir patrones de


razonamiento. Sera deseable encontrar una metodologa que nos permitiera
afirmar cundo una determinada conclusin es vlida -es decir, si es o no una
tautologa-o Sabemos que las tablas de verdad son un buen instrumento
cuando trabajamos con proposiciones sencillas, pero que resultan tediosas
cuando las proposiciones contienen ms de tres o cuatro variables u operadores.
Por tanto, pretendemos encontrar una metodologa alternativa que nos
permita llegar a conclusiones vlidas de una forma legtima. En dicha metodologa, denominada demostracin, el criterio de razonamiento consiste en el
encadenamiento de una serie de pasos o inferencias, cada una de las cuales es
encadenable con la siguiente de una manera justificable formalmente. El proceso

Lgica

59

de demos tracin es una extensin de la metodologa desarro llada para


simplificar proposiciones. Sin embarg o, las demostraciones contienen un
ingrediente
adicional de gran importancia: se realiza una inferen cia a partir de
una suposicin. Las inferencias de una demos tracin se realizan aplican
do un reducido
conjun to de reglas de inferencia. Es decir, las reglas de inferencia
permiten
obtene r proposiciones a partir de otras, de las que se conoce n si son
verdaderas o se supone que lo son. Estas reglas se resumen en la Tabla 3.3.
Definicin. En el clculo proposicional, una demost racin es
una secuencia de pasos que sirven para demos trar que una determ inada propos
icin p
es una tautologa. Cada paso de la demos tracin es bien una propos
icin
ya demos trada, bien una propos icin que se ha obteni do de otra
anterio r
utilizando una regla de inferencia, o bien una propos icin que se introdu
ce
como suposicin para prepar ar un paso posterior. Este ltimo
tipo de
proposiciones (suposicin) lo simbolizamos ponin dolo entre corche
tes
cuadra dos [y]; todos los dems pasos se acomp aan de una justific
acin; y
el ltimo paso de la demos tracin debe ser la propia p.

La sencilla prueba del ejemplo 3.12 muestr a que p => p es una tautolo
ga.
Podra mos demos trar esto utilizando una tabla de verdad, pero represe
nta una
buena oportu nidad para introdu cir la notaci n y estilo de las demos
traciones.
Ejemplo 3.12.
1.

2.
3.

Demos trar p

=>

p:

[p]
p
p => p

1
=>-introduccin, 1, 2

La primer a lnea contiene la suposicin [p]. Al comienzo de la demos


tracin,
podem os supone r cualquier cosa que creamos que puede llevarnos
a la conclusin.
La suposicin, junto con los pasos subsiguientes que se obtienen
de ellas,
suealen presentarse sangrados, de forma que la lgica de pasos subsigu
ientes
pueda distinguirse del resto de la prueba. Puesto que supone mos
que p es
verdadero, se puede deducir que p es verdadero, luego el paso 2 se obtiene
del 1
directamente. Colocamos un 1 en la colum na de la derecha de la
demos tracin como justificacin del paso realizado. A contin uacin utilizam
os la regla
de inferencia de la =>-introduccin (sustituyendo p por q en la frmul
a general
de la Tabla 3.3) con lo que se concluye en el paso 3 que p =>
p es una
tautologa.
La Tabla 3.3 fue desarro llada por el matem tico alemn Gerha rd Gentze
n.
En ella se reflejan las reglas de inferencia que se utilizan en el razona
miento
normal, y que constituyen las bases de la mayor a de los estudios
y aplicaciones de la lgica formal. Cada regla de la tabla tiene la forma:
p
q

60

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Tabla 3.3.
=-introduccin

[p]

Reglas de inferencia
~-introduccin

p=q
q=p

-q-p=q

p~q

=-eliminacin
(modus ponens)
p=p
-p-

~-eliminacin
p~q

p~q

p=q

q=p

~ -introduccin

(modus tollens)
p=q

::!L
~p

[p]

falso
~p

~ -eliminacin

falso
p

/\ -introduccin

v -introduccin

-qP/\q

-p-

/\ -eliminacin

v -eliminacin

P/\q

-p-

-q-

pvq

P/\q
-q-

pvq

[p] [q]

pv q

La propoSlclOn p que aparece encima de la lnea indica un paso anterior


(suposiciq u otro) que ya aparece en la demostracin. La proposicin q que
aparece debajo de la lnea puede obtenerse o ser iriferida en el siguiente paso de
la demostracin. Asi, la regla denominada =>-introduccin en las tablas permite
realizar la inferencia p => q en cualquier paso de la demostracin, en la que p
aparece como suposicin y q como conclusin en un paso subsiguiente.
Una comparacin cuidadosa entre estas reglas y algunas de las propiedades
de la equivalencia que se muestran en la Tabla 3.2, pone de manifiesto algunas
similitudes interesantes. Por ejemplo, la ley de la bicondicionalidad dada en
la tabla, conduce directamente a las dos reglas de inferencia denominadas
<=>-introduccin y <=>-eliminacin de la Tabla 3.3. De forma similar, la ley de la
contradiccin de la Tabla 3.2 conduce directamente a la regla de inferencia de
la ~ eliminacin. Sin embargo, muchas de las reglas de inferencia no tienen
ningn precedente, entre las propiedades de la equivalencia.
Las reglas de inferencia pueden utilizarse como alternativa a las tablas de
verdad en la demostracin de que una determinada proposicin es una tautologa. Sin embargo, como veremos ms adelante, las demostraciones son ms

Lgica

61

verstiles que las tablas de verdad, puesto que las tablas de verdad son inmanejables cuando analizamos las proposiciones de ms de tres o cuatro variables, y
adems no aportan ninguna base para razonar con proposiciones de forma
deductiva.
Podemos autoconvencernos, de forma intuitiva, de que las reglas de inferencia tienen sentido. Por ejemplo, la regla de la 1\ -introduccin nos dice que si
hllmos demostrado que p y q son tautologas en dos pasos anteriores cualesquiera de la demostracin, en el paso actual podemos concluir que p 1\ q es una
tautologa. De forma similar, la regla de la ==>-eliminacin (conocida familiarmente como modus ponens), simplemente establece que, si en un paso anterior
hemos demostrado que p ==> q y que p es una tautologa, en el paso actual
podemos concluir que q es una tautologa.
En las demostraciones procederemos paso a paso para conseguir, en cada
uno de ellos, una nueva tautologa que nos acerque ms a nuestra meta -la
ltma proposicin de la prueba--. Justificaremos cada paso realizado, bien en
la utilizacin de una regla de equivalencia (mediante la sustitucin de una
parte derecha de una expresin de la Tabla 2.3, por una parte izquierda, o viceversa), bien mediante la utilizacin de una regla de inferencia. Adicionalmente a lo anterior, es preciso desarrollar estrategias de demostracin; es decir, mtodos de realizar demostraciones que puedan ser de utilidad en diferentes
situaciones. Estas situaciones se dan no slo en la lgica, sino tambin en
varias aplicaciones de la informtica, las matemticas y la ciencia en general.

3.2.4.

Estrategias de demostracin

En esta seccin se estudian algunas estrategias bsicas para demostrar que una
proposicin es una tautologa, mediante la utilizacin de las propiedades de la
equivalencia y las reglas de inferencia.
Demostracin deductiva. Una demostracin deductiva es aquella en que se
utilizan las reglas de inferencia para deducir las conclusiones, despus de haber
realizado una o ms suposiciones para comenzar el proceso de demostracin.
El ejemplo 3.13 es un ejemplo sencillo.
Ejemplo 3.13.
1.

Demostrar que p ==> (q ==> p)

[p]

2.
3.
4.
5.

[q]
p

=>

p ==> (q => p)

Suposicin
Suposicin
1
=>-introduccin, 2, 3
=>-introduccin, 1, 4

Si se intenta demostrar que una proposicin de la forma p ==> q es una tautologa, es aconsejable comenzar suponiendo p y tratar de encontrar una serie de
pasos que nos conduzcan a q. Si lo conseguimos, el ltimo paso de la demos-

Computacin J. Lgica, resolucin de problemas, algoritmos y programas

62

~ q.

tracin ser la propia p

Esta estrategia fue utilizada en los Ejemplos 3.12

y 3.13.

Utilizacin del modus ponens. Supongamos que alguien dice: Si abres la


jaula, se escapar el tigre y supongamos que yo abro la jaula. La conclusin
seguramente ser, por modus ponens, que el tigre escapar. Anlogamente, si
oimos a alguien decir: Si representan Nuestra Ciudad, comprar entradas, y
descubrimos que estn representando Nuestra Ciudad, podemos concluir que
esa persona comprar entradas. En el Ejemplo 3.14 podemos ver cmo se
utiliza el modus ponens en una demostracin.
Demostrar que ((p

Ejemplo 3.14.

1.
2.

((p

q) 1\ (r

3.

r ~ p
r

4.
5.

p
p

6.

7.

((p

p) 1\ r)

q) 1\ (r

p) 1\ r)

q) 1\ (r

p) 1\ r)

q:

Suposicin
1\ -eliminacin,
1\ -eliminacin,
Modus ponens,
1\ -eliminacin,
Modus ponens,

1
1
2, 3
1
4, 5
~-introduccin, 1,6

Utilizacin de la I\-eliminacin y modus tollens. En el Ejemplo 3.15 se desarrolla una demostracin utilizando una combinacin de las reglas de inferencia
I\-eliminacin y modus ponens. Como en casos anteriores, se parte de suposiciones cuidadosamente elegidas y trabajamos deductivamente a partir de ellas.
Ejemplo 3.15.

1.
2.
3.
4.

[(p ~ q) 1\
p ~ q

5. ((p

Demostrar ((p

~ q) 1\ '" q) ~ '" p:

'" q]

Suposicin
1\ -eliminacin, 1
1\ -eliminacin, 1
Modus tollens, 2, 3
~-introduccin, 1, 4

'" P
'" P
~

q) 1\

'" q)

'" p

Utilizacin de la '" -eliminacin y de la '" -introduccin. La segunda regla de


'" -eliminacin dice que cuando partimos de una suposicin falsa cualquier
conclusin p es una tautologa. As, podemos realizar una argumentacin lgica muy sofisticada en la que una suposicin no vlida (no importa cmo de
nimia pueda ser sta) hace que todos nuestros razonamientos sean errneos.
Muchas argumentaciones pueden ser vlidas, tanto en cuanto no dependan de
suposiciones falsas.
Ejemplo 3.16.

Demostrar, sm utilizar modus tollens, la proposicin

((p ~ q) 1\ "'q) ~ p:

Lgica

1.
2.
3.
4.
6.

1'" P

8.
9.

Suposicin
A -eliminacin, 1
A -eliminacin, 1
Suposicin
Modus ponens, 2
3
'" -eliminacin 5, 6
'" -introduccin, 4
~-introduccin, 1, 8

[p]
q
"'q
falso

5.

((p

~q)A

"'q)

63

",p

El ejemplo 3.17 es algo ms complicado.


Ejemplo 3.17.

Demostrar (p

1.

[p ~ (q ~ r)]

2.
3.
4.

[p

5.

q~r

7.

P~
(p

(q

r))

((p

q)

(p

r)):

q]
[p]
q

6.

8.
9.

(p

q)

r
(p ~ r)

(q

r))

((p

q)

(p

r))

(La justificacin de los distintos pasos de la demostracin se dejan al lector


como ejercicio.)
Utilizacin de la bicondicionalidad en las demostraciones. Para demostraciones de proposiciones de la forma p ~ q, una estrategia que suele ser eficaz es
demostrar primero que p ~ q y despus que q ~ p, utilizando posteriormente
la regla de la ~-introduccin como ltimo paso de la demostracin.
Ejemplo 3.18. Para demostrar que (p ~ q) ~ ('" p v q), primero se demuestra que (p ~ q) ~ ('" p ~ q) es una tautologa (pasos 1-13), y posteriormente se demuestra que ('" p v q) ~ (p ~ q) es una tautologa (pasos
14-22). Finalmente, se aplica la regla de la ~-introduccin como ltimo
paso de la demostracin. La estrategia seguida en los pasos 1-11 para
demostrar que p ~ q puede realizarse suponiendo '" p (paso 2) o bien q
(paso 8).

1.
2.
3.
4.

['" p v q]

["'p]

[p]
pA ",p

5.

falso
q

6.
7.

p~q

8.

[q]

Suposicin
Suposicion
Suposicin
A-introduccin, 2, 3
'" -introduccin, 4
'" -eliminacin, 5
~-introduccin, 3, 6
Suposicin

pro gra mas


n de prob lem as, algo ritm os y
Com puta cin l. Lgica, reso luci

64

[p]
q
p= >q

9.

In

11.
p => q
12.
13. ( '" P v q) => (p

=>

q)

.[p => q]

14.

15.
16.
17.
18.
19.
20.
21.
22.
23.

pv "'p
[p]
q
"'p vq
["'p ]
'" p v q

(p
(p

"'p vq
q) =>

=>
=>

('" p v

q)

q) ~ ('" p v q)

Sup osic in
8
=>-introduccin, 9, 10
v-eliminacin, 1, 2
=>- in troduccin
Sup osic in
dio
Ley de exclusin del cas o inte rme
Sup osic in
Modus ponens, 14, 16
v -introduccin, 17
Sup osic in
v -introduccin, 19
20
v -eliminacin, 15, 16, 18, 19,
21
14,
n,
cci
=>-introdu
~-introduccin, 13, 22

a de inferencia
(reduccin al absurdo). La regl
Demostracin por contradiccin
ostr aci n
una imp orta nte estr ateg ia de dem
de la '" -int rod ucc in es la base de
de esta
ca
tpi
contradiccin. Un a apli cac in
con ocid a com o demostracin por
lado s
de
lo
ngu
ser la siguiente: Sea T un tri
lo
tcnica en las mat em tica s pod ra
ngu
tr
un
es
rem os dem ostr ar que T no
e2, 3 Y 4. Sup ong amo s que que
pod
,
ulo
ng
rect
io, que T es un tri ngu lo
,
usa
rect ng ulo. Si sup one mo s lo con trar
oten
hip
la
de
d
Pit gor as que la lon gitu
s;
mo s con clui r por el teor ema de
lado
dos
s
otro
los
de
igual a la sum a de los cua dra dos
elev ada al cua dra do, es
izan do la
2
2
o, 4 + 9 i= 16. Est o con duc e, util
2
esto es, 2 + 3 = 4 Sin emb arg
orig inal
s
tesi
hip
la
in,
es, por la '" -ind ucc
eliminacin, al valo r falso. Ent onc
es tam bin falsa.
-T es un tri ngu lo rec tn gul otau toostr ar que p => q) /\ p) => q es una
dem
os
rem
Sup ong amo s que que
neg aci n es
cua lqu ier cas o -es decir, que la
loga. Sup ong amo s que es falsa en
con trad icesta sup osic in nos con duc e a una
una tau tol og a- y ana lice mos si
a en el ejem plo 3.19.
cin. Est a es la estr ateg ia seg uid
Ejemplo 3.19.

Dem ostr ar p

1. ['" (p => q) /\ p) => q)]


2. ",(" ,p => q)/ \p) vq)
3. '" q
4. p => q) /\ p)
5. (p => q)
6.

7.
8.

q
Fal so
p => q) /\ p) => q

9.

=>

q) /\ p) => q:

Sup osic in
=>-eliminacin, 1
2
Ley de Mo rga n, /\-eliminacin,
/\-eliminacin, 2
/\ -eliminacin, 4
/\-eliminacin, 4
Modus ponens, 5, 6
'" -eliminacin, 3, 7
'" -introduccin, 1, 8

Lgica

3.2.5.

65

Resolucin de problemas de la vida real

La lgica y los mtodos de demostracin pueden utilizarse en una gran


variedad de problemas lgicos o problemas de la vida real, en los que puede
obtenerse informacin nueva, a partir de una pequea cantidad de informacin inicial. En los Ejemplos 3.20 y 3.21 se utilizan las propiedades de la
~quivalencia, las reglas de inferencia y las tcnicas de demostracin:

Ejemplo 3.20. Los deseos son caballos, a condicin de que los caballos
no vuelen. Tambin, los mendigos no cabalgan, a condicin de que los
deseos no sean caballos. Si se da el caso de que los mendigos cabalgan y
los deseos no sean equinos, entonces los caballos vuelan. Si la imposibilidad de los caballos para volar y la imposibilidad de los mendigos para
cabalgar no son alternativas, entonces los mendigos no son ricos. Pero
los mendigos cabalgan, son ricos los mendigos?
El primer paso para resolver problemas como este, es el de introducir variables que representen cada una de las proposiciones bsicas que
contiene. Como suele ser habitual en problemas de la vida real, como es
este, las frases constituyen un pequeo jeroglfico que hay que descifrar.
En cualquier caso, supongamos que introducimos las variables siguientes:
W
HF
BRD
BRCH

Los
Los
Los
Los

deseos son caballos


caballos vuelan
mendigos cabalgan
mendigos son ricos

Es posible representar las cinco frases de que consta el problema original mediante las proposiciones siguientes, respectivamente:
1.
2.
3.
4.

5.

-HF ~ W
- W ~ - BRD
- (BRD /\ - W) ~ HF
- ( - HF v - BRD) ~ - BRCH
BRD

Utilizndolas igual que utilizaramos suposiciones en una demostracin


ordinaria, es posible escribir la serie de inferencias siguiente, haciendo
referencia la ltima a la variable BRCH que es la que nos interesa:
6.

7.
8.

-BRDv W
-BRDv W
HF
BRD/\HF
(HF /\ BRD)
-BRCH

9.

10.
11.
12.

HF

- BRCH

Modus tollens, 2, 5
Leyes de Morgan, 3
v-introduccin, 6
Modus ponens, 7, 8
/\-introduccin, 5, 9
Leyes de Morgan, 4
Modus ponens, 10, 11

Con lo que se demuestra que los mendigos no son ricos.

66

Computacin /. Lgica, resolucin de problemas, algoritmos y programas

Ejemplo 3.2.1. Los martes, o Timson est en el cementerio o Agnes


est en la sacrista. No es posible encontrar a Timson en el cementerio
sin Stanley. Stanley slo abandona los martes el cementerio, cuando va
a pasear con Agnes. Si Hutchinson cometi el robo, Stanley no estaba
en el cementerio. El robo se produjo en martes. Pudo ser Hutchinson
el ladrn?
Utilicemos las variables siguientes:
Timson estaba en el cementerio
Agnes estaba en la sacrista
Stanley estaba en el cementerio
Hutchinson fue el ladrn
El robo fue en martes

p
q
s
h
u

Ahora es posible simbolizar el prrafo problema de la forma siguiente:


1.
2.
3.
4.
5.

=> (p V q)

p =>

Para poder deducir algo sobre la variable h, que es la que nos interesa,
podemos razonar de la manera siguiente:
6.
7.
8.

pvq
[q]

9.

q=>s

Modus ponens, 1, 5
Suposicin
Modus Tollens, 3, 7
=>-introduccin, 7, 8
v-eliminacin, 2, 6, 9
Modus tollens, 4, 10

10.

11.

~h

Por 10 que Hutchinson no fue el ladrn.

Ejercicios
3.7.

Utilizar tablas de verdad para demostrar que las expresiones siguientes


son equivalencias.
a)
b)

p v (q /\ r) == (p v q) /\ (p V r)
~(pvq)

==

~p/\ ~q

c) p => q == ~(p /\ "'-'q)


d) p v falso == p
e) p /\ verdadero == p
f) P /\ (p V q) == p

3.8.

Encontrar todas las correspondencias entre las propiedades de la equivalencia entre proposiciones (Tabla 3.2), y las propiedades de la equivalencia entre conjuntos (Tabla 2.1).

Lgica

3.9.

Simplificar las proposiciones siguientes, encontrando otra equivalente


con menos operadores y/o variables:
a)
b)

e)
d)
e)

3.10.

67

(pvq)/\("'pv"'q)
(p /\ q) V (p /\ '" q) V ( '" P /\ q)
p v ( '" P /\ q)
'" p ~ p

V ( '" P /\

'" q)

p ~ '" p
~

f)

((p /\ q)

g)

(p~(q/\"'q))~

p)

(p v q)
"'p

La funcin nand se define mediante la tabla de verdad siguiente:


p

p nand q

verdadero
verdadero
falso
falso

verdadero
falso
verdadero
falso

falso
verdadero
verdadero
verdadero

Demostrar que los operadores "', /\, V Y ~ pueden definirse utilizando


la funcin nand. Es decir, encontrar proposiciones construidas slo con
p's, q's y operadores nand cuyas tablas de verdad sean iguales a las de
'" p, p v q, P /\ q Y P ~ q, respectivamente.

3.11.

Justificar los pasos realizados en cada una de las demostraciones siguientes:


a) ((p ~ q) /\ (q ~ r)) ~ (p ~ r)
(( '" p v q) /\ ( '" q v r)) ~ ('" p v r)
'" (( '" p v q) /\ ('" q v r)) v ('" p v r)
( '" ( '" p v q) v '" ( '" q v r)) v ( '" p v r)
(p /\ '" q) V (q /\ '" r) v ( '" p v r)
((p /\ '" q) V '" p) v ((q /\ '" r) v r)
( '" p v (p /\ '" q)) v (r v (q /\ '" r))
(",pvp)/\("'pv ",q))v(rvq)/\(rv "'r))
verdadero /\ ( '" P v '" q) v (r v q) /\ verdadero
( '" p v '" q) v (r v q)
'" p v (q v '" q) v r
'" p v verdadero v r

verdadero
b)

(p~(q/\"'q))~ "'p
falso) ~ '" p

(p ~

'" (p /\ '" falso)

'" p

'" (p /\ verdadero) ~ '" p


~p ~ "'p
"'pvp

verdadero

68

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

3.12.

Demostrar que las proposiciones siguientes son tautologas, utilizando


reglas de equivalencia que las hagan equivalentes al valor verdadero:
a)

(-pvq)=>(qv-p)

b)
e)
d)
e)

(p => q)

f)
g)

h)

(-q => -p)

(p => - p) => - p

p v q) 1\ ""' p) => q
(p v q) 1\ (p => s) 1\ (q => s)) => S
p => q) 1\ (p => r)) => (p => q 1\ r)
p => q) 1\ (r => s)) => p v r) => (q V s))
p => q) 1\ (r => s) 1\ ( - q v s)) => ""' P V - r

313.

Utilizando reglas de inferencia, demostrar cada una de las tautologas


del Ejercicio 3.12.

3.14.

Dada la proposicin p v q) 1\ ""' p) => q.


a) Demostrar que es una tautologa, utilizando una tabla de verdad.
b) Demostrar que es equivalente a la oracin siguiente, si se realiza
una asignacin apropiada de variables a cada frase.
O los Red Sox son mejores que los A-es o los Piratas son
mejores que los Red. Los Red Sox no son mejores que los A-es. Por
tanto, los Piratas son mejores que los Red.
e) Demostrar que la proposicin es una tautologa, utilizando las
equivalencias y reglas de inferencia apropiadas. Ayuda: comenzar la
demostracin suponiendo que el lado derecho de la implicacin es
verdadero y concluirla utilizando la regla de la =>-introduccin.

3.15.

Desarrollar una demostracin para cada una de las tautologas siguientes, utilizando reglas de inferencia.
a)

p => r)

b)

p v q) 1\ (p

1\

(r => q)) => (p => q)


=> s) 1\

(q => s)) =>

3.16.

En la isla Paradoja, todos sus residentes pertenecen a uno de dos clanes.


Los miembros de uno de los dos clanes siempre dicen la verdad, mientras que los del otro siempre mienten. Un visitante de la isla Paradoja se
encuentra con tres nativos. Einstein, Planck y Bohr. Einstein dice: o
bien Bohr o bien yo pertenecemos a un clan distinto de los otros dos.
A qu clan pertenece Bohr? *

3.17.

Abigail, Bridget y Claudia cenan a menudo juntas. Despus de cenar


toman caf o t. Si Abigail pide caf, entonces Bridget pide lo mismo
que Claudia. Si Bridget pide caf, entonces Abigail pide lo contrario de
lo que pida Claudia. Si Claudia pide t, entonces Abigail pide lo mismo

* Adaptado del libro de GEORGE J. SUMMERS, titulado The Great Book C?f Mind Teasers and
Mind Puzzles, Ed. Sterling Publishing Co., Nueva York, 1986.

Lgica

69

que Bridget. Cul de las tres (si es que existe) pide siempre lo mismo
despus de cenar?

3.3.

LGICA DE PREDICADOS

La programacin puede considerarse como una actividad dirigida por un objetivo. ~s decir, el propsito de un programa puede describirse como la consecucin
de una tarea, que genera una salida de un determinado tipo. Por tanto, el punto
de partida en la construccin de un programa es la definicin de la salida que se
espera que produzca. Otra tarea a completar en la construccin de programas
est estrechamente relacionada con la anterior. Definir un conjunto de condiciones que describan todas las entradas posibles para las que el programa produzca
la salida deseada. Suele definirse primero la salida, porque describe el objetivo
del programa. Para entender esto, considrese el problema de encontrar todas
las posibles rutas para viajar en automvil desde Cleveland a Dretoit. Para
resolver este problema, no solemos analizar todas las carreteras que salen de
Cleveland y ver cules llegan a Detroit; lo normal es localizar Detroit y desde
ah ver slo cules son las posibles carreteras que llegan desde Cleveland.
Para el diseo de problemas, necesitamos un lenguaje muy preciso para
describir entradas y salidas. Por ejemplo, supongamos que queremos construir
un programa que reorganice una lista de 30 enteros, de forma que los deje en
orden descendente (a este proceso se le conoce vulgarmente como ordenacin).
Podemos describir, informalmente, las entradas y salidas de la forma siguiente:
Entrada = Cualquier lista de treinta enteros
Salida = Los 30 enteros originales, en orden descendente
Sin embargo, esta forma de descripcin suele no ser lo suficientemente precisa
para definir un problema. Por ejemplo, no se da un criterio para determinar
que los enteros estn en orden descendente. Esto puede parecer trivial, puesto
qe todos tenemos una idea clara de lo que esto significa. Esto es debido a que,
por la experiencia que compartimos, damos por hecho que conocemos esta
informacin. Sin embargo, una computadora no tiene estas ventajas, y en
algn punto del proceso de programacin tenemos que indicarle un mtodo
con el que determinar si la lista de enteros est ordenada en orden descendente
o no. Por tanto, una descripcin ms precisa es la siguiente:
Entrada
Salida

Cualquier lista A = (el' el' ..., e 30 ) de enteros.


Una lista B = (e', e~, ..., e30) permutacin de A para la que se
verifica que e+ 1 ~ e para cada entero i en el intervalo 1 al 29,
ambos inclusive.

Esta descripcin alternativa clarifica la relacin entre la entrada y la salida, y


aporta una definicin no ambigua de lo que significa en orden descendente.
Aunque nuestra segunda definicin es ms precisa que la primera, tambin
es ms prolija. Es, por tanto, necesario encontrar una notacin ms sinttica
para expresar los estados de entrada, salida y otros intermedios del programa.

70

y progra mas
Compu tacin l. Lgica, resoluc in de problem as, algoritm os

no es ms
Esta notaci n puede ser la denom inada lgica de predicados, que
nes 3.1
Seccio
las
en
tada
presen
icional
que una extensin de la lgica propos
predica
de
lgica
la
de
bsica
n
notaci
la
ce
y 3.2. En esta seccin se introdu
la
en
la
utilizar
y
ella
con
r
trabaja
para
rias
necesa
dos, junto con las nociones
descripcin de los estados de los progra mas.
formas
Las descripciones de entrad a y salida anteriores no son ms que
ado
predic
relajadas 'de predicados. De forma intuitiva, podem os consid erar un
valor,
inado
como una frase que incluye variables, las cuales, al tener un determ
convierten la frase en una proposicin.
tiDefinicin. Un predicado es un aserto constit uido por consta ntes aritm
y
ero
verdad
lgicos
valores
los
y
cas y boolea nas (nmeros enteros, reales
etc.);
*,
(=,
icas
aritmt
iones
operac
falso); variables aritmticas y booleanas,
lgicos
operaciones relacionales ( <, ~, >, ~, =, i=, E, etc.) y operad ores
de los
iendo
depend
falso
o
ero
verdad
valor
(1\, v, ~, etc.), que tiene el
estados de sus variables.
expresiones
En Pascal, este tipo de predicados se conocen con el nombr e de
.
booleanas, y tienen gran cantida d de usos en progra macin
preciEn la Seccin 3.1 se defini la sintaxis de las proposiciones de forma
lugar,
su
en
o,
embarg
sin
sa. Podra mos hacer lo mismo con los predicados;
expresiones
utilizaremos nuestros conocimientos y experiencia con ese tipo de
progra may
lgebra
e
alment
en otros campo s de las matemticas~especi
Comence.
iciones
propos
sobre
idos
cin- junto con los conocimientos adquir
do.
predica
un
n
tambi
es
mos destac ando que cualquier proposicin
Las
Ejemplo 3.22. Las proposiciones siguientes son tambi n predicados.
a.
derech
la
a
an
muestr
se
Pascal
en
expresiones equivalentes
x < 10
x < 10
i*i + j*j = 25
i 2 + / = 25
(a[1] < a([2]) and (a[2] < a[3])
al < a 2 1\a 2 < a 3
necesario
Obsrvese en el tercer predic ado del Ejemplo 3.22 que, aunque no es
in en
expres
la
en
es
10
si
do,
predica
el
ntar
utilizar parntesis para represe
menor
tienen
v
y
1\
ores
operad
los
que
a
debido
es
Pascal equivalente. Esto
o, en
embarg
Sin
etc.).
>,
~,
,
nales
relacio
ores
priorid ad que los operad
ores
operad
Pascal, los operad ores and y or tienen una priorid ad mayor que los
consepara
relacionales , ~, >, etc.) en una expresin booleana. Por ello,
sis *.
guir una interpr etacin equivalente, es necesaria la utilizacin de parnte
Las expresiones siguientes no son predicados:

+ 1
y2 < 10 i=
x := x + 1

se el
* Para una mayor informacin sobre las expresiones booleanas en Pascal, conslte
manual de laborato rio.

Lgica

71

i + 1 no es un predicado, puesto que no tiene un valor lgico; simple


mente es
una expresin aritmtica que tiene un valor numrico. y2 < 10 :1: podra
serlo,
si hubiera otra expresin a la derecha del smbolo :1:; pero, tal y como
est
escrita, carece de significado. La expresin x := x + 1 es una instruccin
vlida
en Pascal, pero no es una expresin que tenga un valor lgico.
Es posible evaluar un predicado reemplazando todas sus variables por
sus
valpres, en un determinado estado, y calcular el resultado utilizando
las leyes
de la aritmtica. As, x < 10 se evala a verdadero en el estado x = 1,
Ya falso
en el estado x = 11. Decimos que x = 1 es un estado que satisface el
predicado x < 10. A un predicado que posee estado en el que puede ser satisfec
ho, se
le denomina satisfactible. Por ejemplo, el predicado x < 10 es satisfac
tible,
mientras que el predicado 11 < 10 no es satisfactible.

Definicin.
vlido.

Un predicado que se satisface en cada estado se dice que es

Por ejemplo, si i es un entero, el predicado i ~ Ov i ~ 1 es vlido, puesto


que
es verdadero para cualquier valor de i. Por tanto, el concepto de validez
para
los predicados es como la nocin de tautologa para las proposiciones
.
Ejemplo 3.23. Los predicados se utilizan frecuentemente en la definic
in
de conjuntos. Por ejemplo, en cada una de las definiciones siguien
tes, el
conjunto definido contiene todos los estados que satsfacen el predic
ado
que haya la derecha de la barra vertical. El aparta do d utiliza cadena
s de
caracteres como dominio; el dominio del resto de las variables es el conjun
to de los nmeros naturales N.
a)
b)
c)
d)

e)
f)

3.3.1.

{(i, j) I i < j}
{(i,j) I i 2 + / = 25)}
{(a o, al' a 2) I a o = mx(a 1 , a2)}

{(Si' S2) / Sl es un prefijo para S2}


{(i, j) I i < j v j = O}
{(i, j) I i 2 + / = 25 1\ j > 2}

Los cuantificadores universal y existencial

Recurdese de un ejemplo anterior, que es posible describir la salida


de un
programa como una lista de la forma
B = (e', e, ..., e30)

que es una permutacin de otra lista A, y que tiene la propiedad de que


para i
entre 1 y 29, ambos inclusive, ej+ 1 ~ ej. Esta frase es la conjuncin
de dos

72

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

predicados. El primero, B es una permutacin de A, es un predicado con


treinta variables. El segundo, para cada i entre 1 y 29, ambos inclusive, ei+ 1
~ ~ ei, contiene 29 predicados de la forma ei + 1 ~ e, uno por cada entero
entre el 1 y el 29. Es decir, sirve como abreviatura para el predicado

Debido a que expresiones como para cada, para todo, para cada
uno aparecen con frecuencia en matemticas y lgica, todos ellos se simboli~
zan de forma abreviada con el smbolo V, denominado cuantificador universal.
En el ejemplo, podemos escribir la frase:
para cada i entre 1 y 29, ambos inclusive, ei+ 1
Vi E {1, 2, ..., 29}: e+ l ~ e;

ei

como

donde, a continuacin del smbolo V, aparece un predicado que indica el dominio de la variable i, y a continuacin de este otro predicado que indica 10 que
es verdadero cuando la variable toma valores en ese dominio.
De forma general, el predicado siguiente puede construirse con los predicados R(i) y P(i):
V R(i) : P(i)

Donde R(i) se utiliza para describir el dominio de i, y el predicado P(i) debe


satisfacer para todos los valores de i pertenecientes a su dominio, para que el
predicado V P(i) : R(i) resultante sea vlido -es decir, valga verdadero en todos
los casos-o Este tipo de predicados puede utilizarse para sintetizar conjunciones como P(i 1 ) 1\ P(i 2 ) 1\ ..., donde i l , i 2 . , simbolizan todos los valores de i que
satisfacen R.
Ejemplo 3.24. Cada una de las frases de abajo va seguida de su representacin como predicado, que utiliza el cuantificador universal:
a)

Cada elemento e de la lista desde el hasta e21 es distinto de 9.

Vi E{l, 2, oo., 21}: e


b)

Todos los ej entre em y en son nmeros positivos.


Vj

c)

=1=

{m, m

+ 1, ..., n}:

ej > O

El punto (a, b) est arriba y a la derecha de cada punto (i, j) de alguna


regin rectangular R del plano xy (vase Figura 3.3).
V (j, j)

R: i < a

1\

j < b

Lgica

73

y
'(a,

bl

--r----------- x
Figura 3.3. Representacin grfica del
predicado V (j, j) E R: i < a /\ j < b.

d)

En una lista A = (el' e2, 000' en) los elementos hasta elj-simo, excluido
l mismo, estn colocados en orden creciente (vase Figura 3.4)0
Vi

(1

{l, 2, .. o,j - 2}: e ~ e+l

4)

I
ej

e,

Figura 3.4.
e)

Ejemplo de predicado.

La proposicin P(p, q, r ) es una tautologa.


V p, q, r

{verdadero, falso}: P(p, q, r)

Obsrvese que no se realiza ninguna exigencia de. que las proposiciones


sean siempre verdaderas. El apartado e requiere algn comentario adicional:
P(p, q, r) es una proposicin; sin embargo, la frase la proposicin P(p, q, r) es
una tautologa puede reescribirse para todos y cada uno de los estados de
las variables p, q y r, P(p, q, r) es verdadera. Por tanto, con el cuantificador
universal, el aserto P(p, q, r) del apartado e vale verdadero en todos sus ocho
posibles estados.
Hay veces en que el cuantificador del predicado puede omitirse, si est
claro por el contexto -es decir, cuando el conjunto universal ha sido expresado con claridad-o Por ejemplo, si sabemos que i es un entero (como suele
ocurrir frecuentemente), es posible escribir:
Vi:i<i+l

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

74

De forma similar, siempre es posible escribir


V R(i) : P(i)

como Vi : R(i)

P(i). Por ejemplo

(Vi
es lo mismo que (Vi: 1

{l, ..., 2l}: e "1= 9)


21

e "1= 9).

El otro cuantificador de inters es el cuantificador existencial, simbolizado


por 3. Su significado es existe, o bien existe al menos o para algo. Se
utiliza para abreviar mltiples ocurrencias de disyunciones cuando varios predicados similares estn relacionados con este operador.

Ejemplo 3.25. Las frases siguientes se acompaan con su representacin


abreviada utilizando el cuantificador existencial:
a)

Existe un elemento de la lista (el' e 2 ,


3iE {l, ...,n -

b)

Los elementos de (el' e 2 ,


3j

e)

.,

en) que es cero.

l}:e

en) no estn todos en orden ascendente.

{l, ..., n - l}: ej + 1 > ej

Algn punto del conjunto del plano R, se encuentra en el tercer cuadrante.


3 (i, j)

R : i < O /\ j < O

d)

Existen enteros a b y e, distintos de cero, que verifican a 3 + b3

e)

Existe alguna fila del tablero que no tiene ninguna pieza.

c3

3 una fila R en el tablero: R no tiene piezas


f)

Existe una frase en este texto con al menos una falta de ortografa.
3 una frase S en este texto: S tiene al menos una falta de ortografa.

El cuantificador universal, al igual que el existencial, representa una notacin


abreviada. Por ejemplo, 3 i E {l, ..., n}: e = Oes la notacin abreviada de (el =
= O) v (e 2 = O) v ... v (en = O). Es decir, al igual que el cuantificador universal
representa una forma abreviada de una secuencia de operaciones and, el cuantificador existencial representa una forma abreviada de secuencias de oro

Lgica

75

La relacin entre ambos cuantificadores podem os encont rarla en la


generalizacin de las leyes de Morga n siguiente:
- V R{i) : P(i)

3 R{i): - P(i)

(3.1)

- 3 R(i) : P(i)

V R(i): - P(i)

(3.2)

La Ecuaci n (3.1) dice que la frase no es cierto que todos los es en


el dominio
satisfacen p es equivalente a para algn i del dominio, P es falso.
La Ecuacin (3.2) tiene una interpr etacin similar: la frase no es cierto que
algn i en
el domin io satisfa te P es equivalente a la frase para cada i en el
dominio, P
es falso.
Estas son generalizaciones de la versin simple de las leyes de Morga
n, que
fueron introdu cidas anterio rmente en este captulo. Tngase en cuenta
que los
cuantificadores utilizados ahora represe ntan abrevi aturas de conjun
ciones y
disyunciones. Por ejemplo, las equivalencias siguientes son interpr
etaciones vlidas de las Ecuaciones (3.1) y (3.2), cuando el rango de i es
el conjunto {1, 2}:

Ejemplo 3.26.
a)

3i

-(P(l) /\ P(2)) -

-P(I) v -P(2)

(3.3)

-(P(I) v P(2))

-P(I) /\ -P(2)

(3.4)

A continu acin, se muestr an dos ejemplos concretos:

{1, oo.,

O es equivalente a

n}: e =

Vi
b)

- 3i

{1, oo., 21}:

{l, .oo, n}:

:f. O.

:f. 9 es equivalente a

Vi

{1, oo., 21}:

e =

9.

A menud o son necesarios ambos cuantificadores para expres ar un


nico
predicado. Por ejemplo, supong amos que querem os expres ar que,
simblicamente, B = {e'}, e,
e~o} es una permu tacin de A = {el' e , .. , e }.
2
30
Supon gamos tambi n que todos los a son distintos. Es posible expres
ar todo
lo anterio r como:
OO"

perm (B, A) = Vi

{l, oo., 30} 3j

{1, oo., 30}: ei = ej'

Dicho en castellano, B es una permu tacin de A, si para cada elemen


to ei de B
existe un elemento idntico ej en A, aunque no necesariamente en
la misma
posicin (es decir, los ndices i y j no necesitan ser idnticos para
que e; = ej
sea verdadero).

76

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

3.3.2. Otros cuantificadores


En informtica suelen utilizarse otros cuantificadores junto con los dos anteriores, 3 y V. Estos cuantificadores pueden verse a continuacin:
Num R(i): P(i)
Mio R(i): P(i)
Max R(i): P(i)
Sum R(i): f(i)
Prod R(i): f(i)
Num R(i): P(i) da el nmero de valores de i en el rango determinado por R, que
satisfacen el predicado P. Mio devuelve el valor mnimo de la funcin f(i),
donde i est restringida al rango especificado por R. Max es similar a Mio,
pero devuelve el valor mximo. Tambin se ha visto la funcin Sum, que se
utiliz en la Seccin 2.4 (donde se simboliz mediante la letra griega L). Prod
es similar a Sum, pero simboliza el producto en lugar de la suma. (En matemticas suele simbolizarse el producto mediante la letra griega n.)
Ejemplo 3.27. Las expresiones siguientes muestran la utilizacin de estos
cuantificadores. El valor que resulta de evaluarlas aparece a la derecha:
{O, oo., 3}: i 2 > i
b) Mio i E {O, ..., 3}: i 2 > i
e) Max i E {O, oo., 3}: i2 > i
d) Sum i E {O, ..., 3}: i 2 - i
e) Prod i E {l, .oo, 4}: i 2 > i

a) Num

2
2
3

+ +

2 + 6 = 8
1 x 4 x 9 x 16 = 576

3.3.3. Variables libres y ligadas


Comprese

con la expresin cuantificada


Vi

{l, oo., 29}:

ei+l

e;

En la primera expresin, i est irrestringida; puede tomar cualquier valor en el


dominio que deseamos definir. En este caso, i recibe el nombre de variable
libre. Sin embargo, en el segundo caso, la variable i est restringida por el
cuantificador universal a tomar valores en un intervalo especfico. En este caso,
se dice que i es una variable ligada.
En general, todas las variables cuyos valores estn restringidos a un determinado dominio, por la aplicacin de un cuantificador, son ligadas; variables

Lgica

77

que no estn ligadas son libres. (Veremos que la misma distincin entre variables libres y ligadas existe entre variables globales y locales, respectivamente,
cuando definamos procedimientos y funciones en programacin.)
Considrese la expresin
Vi

{m, ..., n}: e :::;; K

En esta expresin, i es una variable ligada, mientras que m, n y K son libres.


Suele ser habitual la coexistencia de variables libres y ligadas.

3.4.

PREDICADOS V PROGRAMAS

En el Captulo 5, se utilizarn con frecuencia predicados para discutir sobre


programas y resolucin de problemas. La idea de predicado, que define exactamente las condiciones bajo las que debe ejecutarse un programa, es fundamental para los objetivos descritos en la frase anterior. Es tambin fundamental la
correspondencia entre predicados cuantificados y bucles de un programa. En
la seccin siguiente se introducen ambas ideas.

3.4.1.

El estado de un clculo

Supngase que en un programa de una computadora se tiene una instruccin


como la siguiente:
; := O

que asigna el valor O a la variable ;. Supngase tambin que el programa es


tan simple que slo utiliza las variables; y j. Es posible utilizar un predicado
para describir el estado del programa despus de la ejecucin de la instruccin
; := O

Tal predicado recibe el nombre de poscondicin de la instruccin ; : = O.


Supngase que conocemos que, antes de la ejecucin de esta instruccin, las
variables cumplen i > j 1\ j > 10. El predicado anterior recibe el nombre de
precondicin, debido a que describe el conjunto de todos los estados que pueden darse antes de ejecutar la instruccin.

Definicin. Una poscondicin de una instruccin o grupo de instrucciones


de un programa, es un predicado que describe el conjunto de todos los
estados en que estas instrucciones pueden terminar, despus de que sean
ejecutadas. U na precondicin para esa instruccin o grupo de instrucciones,
es un predicado que describe el conjunto de estados en los que pueden estar
todas las variables del programa, inmediatamente antes de ejecutarse la
instruccin o grupo de instrucciones.

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

78

Podemos pensar en la poscondicin como un predicado que describe el


conjunto objetivo o el propsito de nuestro programa. Obsrvese que, si se

considera una instruccin o conjunto de instrucciones como una funcin, la


precondicin representa su dominio, y la poscondicin su recorrido. Ms adelante, se ver cmo la precondicin y la poscondicin sirven de ayuda en la
construccin y verificacin de programas.

3.4.2.

Cuantificadores y programacin: bucles

Existe una estrecha correspondencia entre la utilizacin de cuantificadores en


lgica y la de bucles en programacin. Es decir, al igual que los cuantificadores
universal y de existencia permiten en la lgica abreviar una serie de tediosas
secuencias de operaciones /\ y v, los bucles sirven en programacin para
abreviar largas secuencias de instrucciones. Tendremos muchas ocasiones de
hacer traducciones entre esas dos formas de expresarse.
Es habitual tener que escribir instrucciones de programas que comprueben
si los predicados cuantificados VR(i): P(i) y 3R(i): P(i) son vlidos. Cuando el
rango de la variable i, expresada en R(i) es finito, esta prueba puede realizarse
utilizando un bucle for de Pascal. Supongamos que tenemos la lista A =(el'
e2 , ... , e30 ) Yqueremos conocer si todos los miembros de esta lista son positivos;
es decir, se quiere establecer si el predicado siguiente es vlido:
Vi

{l, ..., 30}: ei > O

Una forma posible de comprobar esto sera escribir una largusima instruccin
condicional, asignando a la variable booleana v l ; do el valor verdadero o
falso:
i f (e[1]>O and (e[2]>0> and .. and (e[30]>O>

then vlido:=true
eLse vlido:=false;

De forma alternativa, tras aplicar la ley de Morgan, podramos escribir:


vlido:=true;
if e[1] <= O
then vlido:=false;
if e[2] <= O
then vlido:=false;
if e[30] <= O

then vlido:=false;

Es decir, el predicado original no es vlido,


elementos de la lista cumplan ei ~ O.

SI

es posible que uno o ms

Lgica

79

Para evitar problemas de escritura, en esta y en similares situaciones, es


posible utilizar la instruccin for para expresar la misma idea. Es posible
sustituir la serie de instrucciones if-then por el bucle siguiente:
vlido:=true;
for i :=1 to 30 do
jf e[i] <= O
then v l i do :=fa lse;

Sencillamente, se ha utilizado un truco bastante comn en programacin: se ha


supuesto que el predicado es vlido para todos los valores del rango de i, y se
intenta demostrar lo contrario examinando los 30 casos de forma individual.
Puede seguirse una estrategia de programacin similar, cuando se implementen predicados como instrucciones, que involucren otros cuantificadores.
Ejemplos de esto pueden verse en los Ejemplos 3.28 y 3.29:
Ejemplo 3.28. El predicado Existe un nmero en la lista A = (e l' e2' ... ,
e 30 ) cuyo valor es cero, puede reescribirse como :Ji E {l, ..., 30}: e = O. Un
bucle para probar la validez del predicado sera:
vl ido:=false;
for i :=1 to 30 do
ife[i]=O
then vlido:=true;

Ejemplo 3.29. La frase El nmero de elementos de la lista A = (el' ez' ...,


e30 ) cuyo valor es cero, puede reescribirse como Num i E {l, ..., 30}: e = O.
El programa siguiente comienza con la suposicin de que no existen en A
elementos que cumplan esta condicin. Posteriormente, se corrige metdicamente la suposicin (aadiendo 1 a la variable contador numero), cada
vez que se encuentre un cero en la lista.
nmero:=O
for i :=1 to 30 do
ife[i]=O
then nmero:=nmero+1;

Una discusin ms detallada sobre el bucle for, puede encontrarse en el


manual de laboratorio.

Ejercicios
3.18.

Evaluar los predicados siguientes, en cada uno de los estados 1 y 11:


(1)

i = O 1\ j = 1 1\ k = - 1

(JI)

i = - 1 1\ j = 1 1\ k = O

80

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

a)
b)

e)
d)

3.19.

i< lO/\j< 10
-1 < j :::; i
i + j > k
i3 = / = p

Evaluar cada uno de los predicados siguientes. Supngase, en todos los


casos, que el dominio es N.
h) Vi 3j : i - j = O
Vi: i < i + 1
i) 3i Vj : i - j = O
Vi: i2 < i
j) Mio i E {1, ..., 6} : (i2 - 6i) = 3
Vi, j : i 2 + / > O
3i: i 2 = 5i - 6
k) Vi 3j : i x j = O
e) 3i, j : i2 + j2 :::; 25
l) Sum i E {l, , lO} : i - 5
f) Vi 3j : j = O
m) Prod i E {l, , n} : i
g) Max i E {l, ..., lOO} : i + 2 = 101
a)

b)
e)
d)

3.20.

Supngase que se define un tablero de ajedrez como {(i, j)ll :::; i :::;
:::; 8 /\ 1 :::; j :::; 8}. Supongamos que el par (1, 1) define el cuadrado de
la esquina inferior izquierda del tablero, la casilla es negra, y las blancas
ocupan inicialmente las dos filas inferiores del tablero. Sea p una funcin que asigna a cada casilla del tablero el nombre de la pieza que est
sobre ella. As, si la casilla (4, 7) est vaca, escribiremos p(4, 7) = vaca;
si la casilla (1, 5) contiene el rey blanco, escribiremos p(l, 5) = RB.
Escribir predicados para describir las frases siguientes:
a)
b)

e)
d)

e)
f)
3.21.

Identificar las variables libres y ligadas de las expresiones siguientes:


a)
b)
e)

3.22.

La reina blanca ha sido capturada.


Las negras conservan sus alfiles.
Una torre blanca est en la misma fila que la reina negra.
Un pen blanco est atacando al rey blanco.
Una torre blanca est atacando a la reina negra.
Un alfil negro est atacando al rey negro.

{O, oo., n} : i3 - i2 < 100


3i E N : "In E {1, .oo, i} : n 2 = i
(O:::; m :::; p) /\ (Vw E R : w < m /\ w2 < p)
Vi

Considrese la situacin del juego de las tres-en-raya descrita en el


dibujo. Supngase que la notacin s(i, j) = v significa que la cuadrcula
de la fila i y la columna j contienen el valor v (donde v puede ser una X,
una O o estar vaca).
a)
b)

Escribir un predicado que describa la situacin concreta del dibujo.


Escribir un predicado que describa el mejor movimiento que puedan realizar las O, a continuacin.

Lgica

fila

columna
1
2

81

xO

e)

Escribir un predicado que describa todos los estados en que las X


pueden ganar, en la columna de enmedio; es decir, todos los estados en
que las X ocupan dos casillas de la segunda columna y la otra casilla
est vaca.
d) Escribir un predicado cuantificado, que describa la imposibilidad de
que las X ganen en la segunda columna.
e) Escribir otro que describa la imposibilidad de las X de ganar en cada
columna.
f) Escribir un predicado que describa la imposibilidad de que ganen las X.
3.23.

Describir las situaciones siguientes, utilizando predicados y cuantificadores. Supngase que A = (el' e2, ..., e,,) es una lista de caracteres ASCII.
a)
b)

e)
d)
e)
f)
g)
h)
i)
j)
k)

l)

3.5.

Todos los caracteres de la lista son idnticos.


La letra x no est en la lista.
Algn carcter de la lista es la z.
La lista est ordenada alfabticamente, de menor a mayor.
No existen en la lista dos caracteres iguales.
Algn par de caracteres de la lista son iguales.
La letra y aparece exactamente dos veces en la lista.
La lista B = (b l , b2 , .., b,,) es una sublista de A.
La variable cont almacena el nmero de puntos y comas de la lista.
La lista B es idntica a la A.
La lista B es idntica a la A, excepto que algn cero de la lista ha sido
reemplazado por una letra o.
El nmero 3621 no es primo.

RAZONAMIENTO CON PREDICADOS:


PRUEBA POR INDUCCION

El razonamiento con predicados es similar al razonamiento con proposiciones,


puesto que existen tambin reglas de inferencia que gobiernan los pasos a seguir.
Frecuentemente, se asignan valores representativos a las variables de un predicado (convirtindolo en una proposicin) y se utilizan las reglas de inferencia para

82

Compu tacin ,. Lgica, resoluc in de problem as, algoritm os


y progra mas

proposiciones. Sin embargo, el razonamiento con predicados implica


algunas
reglas adicionales que se resumen en la Tabla 3.4.
Como sugiere la Tabla 3.4, las reglas de la 3-introduccin y de a 3-elimi
nacin recuerdan a las leyes de Morga n (vanse Ecuaciones (3.1) y (3.2)).
Las reglas
de la V-introduccin y de la V-eliminacin tambin son ampliamente
utilizadas
en las demostraciones. La primera indica que si es posible establecer
que R => P
es vlida, es posible afirmar, en un paso posterior de la demostracin
, que
tambin es' vlido V R(i): P(i). La segunda indica que si V R(i): P(i)
es vlida,
entonces para cada valor particular i de i, tambin es vlida R(io) =>
o
P(i o)'
Tabla 3.4.

Reglas de inferen cia para predica dos cuantif icados

V-introduccin
R-=P

V R(i): P(i)

3-introduccin
V R(i): P(i)
~3

R(i):

~P(i)

V-eliminacin
V R(i): P(i)
R(i o) -= P(i o)

3-eliminacin

3 R(O: P(i)
~ V R(i): ~ P(i)

Supongamos que se quiere demos trar que todos los enteros pares mayore
s
que 2 no son primos. En este caso, R es el predicado:
i no un entero /\ (i > 2) /\ i es par

y P es el predicado:
i no es primo

Es necesario ver que R => P es vlido. Esto se suele hacer seleccionando


un io
representativo, que satisfaga R, y demostrando que tambin satisface
P. As, la
prueba podra comenzarse:
Sea io cualquier entero par que verifique i > 2.
o
De la suposicin anterior concluimos que i no es primo (puesto que para
que un
nmero sea par, es necesario que sea divisible por 2). Por tanto, conclu
imos que
todos los enteros pares mayores que 2 no son primos.
Prueba por induccin. La validez de predicados que contienen cuantif
icadores,
puede muchas veces establecerse mediante el mtodo conocido por
prueba por
induccin (o induccin). Este es un concepto tan import ante
para la programacin como para las matemticas. Es decir, los mtodos de demostracin
inductivos se utilizan en la verificacin formal de programas (vase Captu
lo 6). La

Lgica

83

induccin tiene tambin una relacin muy estrecha con el concepto matemtico
de funciones recursivas (como se vio en el Captulo 2) y una gran aplicacin en la
resolucin de problemas y en programacin (vase Captulo 5).
Para demostrar la validez del predicado VR(n): P(n) en el caso especial en que
R(n) tiene la forma n E {l, 2, "'}' podemos considerar dos casos por separado.
Oaso base: Demostracin de P(l).
Paso de induccin: Demostracin de P(i) ::::- P(i

+ 1) para todo

i ~ 1.

El caso base, simplemente establece la validez de P para el valor inicial, i = 1. El


paso de induccin establece que, si podemos demostrar que P(i) ::::- P(i + 1), para
Puesto que
cualquier i, entonces se demuestra la validez de P(l) ::::- P(2) ::::P(l) es vlido, tambin lo ser P(2) [puesto que P(l) ::::- P(2)] y tambin lo ser
P(3) [puesto que P(2) ::::- P(3)], y as sucesivamente.
.
La idea de la induccin puede ilustrarse mediante una analoga. Supongamos que alguien quiere subir una escalinata. Slo sern necesarias dos fases para
describir el proceso -la fase de alcanzar el primer peldao y la de subir desde
un peldao hasta el siguiente-. Utilizando estas dos instrucciones es posible
subir cualquier escalinata, sin tener en cuenta cmo tenemos que situarnos en un
escaln determinado. Adems, estas dos acciones hacen irrelevante, para completar el proceso de induccin, lo larga que sea la escalera. El hecho de alcanzar
el primer escaln es equivalente a probar el caso base P(1). El hecho de saltar del
i-simo escaln al i + 1, es anlogo a probar el paso de induccin P(i) ~ P(i +
+ 1) para cada i ~ 1. La expresin Vn E {l, 2, oo.}: P(n) establece que P(n) es
verdadero para todo n, y es anlogo a la posibiliad de saltar de uno a otro
escaln de todas las escaleras.
Mientras no podamos utilizar una tabla de verdad para justificar el proceso
de induccin, podemos justificarlo utilizando el modus ponens y basndonos en
algunas propiedades de los nmeros naturales. Es decir, si sabemos que P(l) es
verdadero y que Vi E {l, 2, oo.}: P(i) ::::- P(i + 1) es posible escribir las expresiones
siguientes, sin ms que sustituir i por diferentes nmeros enteros:
oo

P(l)
P(l)

~ P(2)
P(2) ::::- P(3)

Combinando las dos primeras lneas es posible concluir, utilizando modus ponens, que P(2) es vlido. Combinando la veracidad de P(2) con la tercera lnea, es
de nuevo posible concluir que P(3) es verdadero. Es posible continuar de esta
forma indefinidamente hasta demostrar que Vi E {l, 2, oo.}: P(n) es vlido.
Ejemplo 3.30.
n

j~l j =

n(n

Supongamos que St; desea probar por induccin que Vn >


1)

. Consideremos los dos casos:

o:

84

Computacin l. Lgica, resolucin de problemas, algoritmos y programas


n

n(n

Lj

Caso base. Demostrar que

1)

j= 1

Paso de induccin: Demostrar que

"
i( i
j=

1)

j=l

i ~1

(i

+ 1)((i + 1) + 1)
2

j=l

El caso base es evidente si utilizamos la aritmtica. Es decir, 1 = 2/2. El paso


de induccin tampoco es muy dificil de probar, si se utilizan las propiedades
de las sumatorias finitas, introducidas en la Seccin 2.2.6.
i+ 1

j= 1

+ (i + 1)

Propiedad de L

j=l

i(i

+ 1)
2

i(i

+
2

(i

+ 1)

(i

Suponiendo

j= 1

1)

+ 1)

2(i

+
1)((i

+ 1) + 1)
2

i(i

+ 1)
2

Aritmtica
Aritmtica

A primera vista, puede parecer que la induccin matemtica es una forma circular de razonamiento. Sin embargo, lo que est realizndose es, en alguna medida,
un razonamiento hipottico. Lo que decimos es Supongamos que P(n) es
cierto. Podemos deducir de ello que P(n + 1) tambin lo es?. Esto no demuestra la validez de P(n + 1), sino slo que P(n) implica P(n + 1). Considrese de
nuevo la analoga con la ascensin de la escalinata. En realidad, lo que estamos
diciendo es Supongamos que nos encontramos en el n-simo escaln, puedo
desde aqu ir al siguiente?. Esto no supone afirmar que sepamos llegar al
n-simo escaln, sino que estando en l somos capaces de alcanzar el n + l-simo.
Es la combinacin de las capacidades de saltar de uno al siguiente, y la de
alcanzar el primer escaln (es decir, probar P(I)), lo que permite alcanzar el nsimo.
Ejemplo 3.31.

Demostrar que si O < 1 r < 1, entonces


n

i=O

1 - rn+1
ri = - - 1 - r

Comencemos con n = O. Los lados izquierdo y derecho (LHS y RHS) de la


ecuacin anterior se convierten en:

Lgica

LHS

rO

= 1, para

85

r =1= O

i=O

RHS =

1 - r

= 1, para

r =1= 1

E&to completara la demostracin del caso base. Supongamos ahora que


1 - rn+1
ri = ---1 - r

i=O

(3.5)

Demostraremos que esto implica


1 _ rn + 2

n+1

I
i=O

Sumando

r n+ 1

1 -

a ambos lados de la ecuacin (3.5), obtenemos


n+1

LHS

n+1

ri + rn + 1 =

i=O

RHS

ri

i=O

1 - rn+1
1 - r
1 - r n+2
1 -

r n+1

Ejemplo 3.32. Supongamos que S es un conjunto finito que tiene n elementos. Demostrar mediante induccin que S tiene 2n subconjuntos.
Solucin. Denotemos por P(S) la coleccin de subconjuntos de S. Supongamos que n = O. Entonces, S = <j>. Por tanto, P(S) = {<j>} y S tiene 1 (= 2)
subconjuntos. Este es el caso base para la prueba inductiva.
Supongamos ahora que cualquier conjunto S de n elementos tiene 2n
subconjuntos. Para probar el paso de induccin, sea T un conjunto arbitrario con n + 1 elementos.

Los subconjuntos de T pueden dividirse en dos grupos ~aquellos que incluyen a t n + 1 Ylos que no-o Cada subconjunto {t 1 , t 2 , , t n } es tambin un
subconjunto de T. Por tanto, por hiptesis de la induccin 2n subconjuntos
de T no incluyen a t n + l' Cada subconjunto que incluye t n + 1 puede considerarse como la unin de un subconjunto de {t l ' t 2' ... , tn } con {t n + 1}' Luego
existen 2n subconjuntos que incluyen t n + l' Por tanto, existen 2n + 2n = 2 x
x 2n = 2n + 1 subconjuntos.

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

86

Una forma de visualizar la demostracin es escribiendo la lista de subconjuntos siguiente:


Sin incluir tn +

Incluyendo t n +

4J
{td
{t 2 }

{tn+d

{ti' .t 2 }

{t l' .t 2 , t n + }

{ti' t 2 , oo., t n }

{t,"t 2 ,

{ti' t n + }
{t 2' t n + }

..,

t n, t n + }

La lista de la izquierda est construida con todos los subconjuntos de {tl' t 2 ,


..., t n ). La lista de la derecha se ha construido haciendo la unin de cada uno

de los elementos de la lista de la derecha con {t n + }. Luego hay exactamente


2n elementos en cada lista.
Obsrvese que, en contradiccin con su nombre, la demostracin por induccin implica razonamiento deductivo, en lugar de inductivo. El razonamiento
inductivo hace referencia a una tcnica habitual en la ciencia, denominada mtodo cientfico; este mtodo consiste en inferir principios generales a partir de casos
particulares. Por ejemplo, el astrnomo Kepler utiliz el razonamiento inductivo
para inferir las leyes del movimiento planetario a partir de un voluminoso conjunto de datos experimentales que haba recogido. Sin embargo, la induccin
matemtica sigue un tpico proceso deductivo -partiendo de axiomas, teoremas
previamente demostrados define nuevos teoremas utilizando reglas de inferencia.

3.6.

RESUMEN

En este captulo hemos estudiado los fundamentos de la lgica, prestando especial atencin a su utilizacin en la informtica. La lgica proposicional, la equivalencia y las demostraciones se han revelado como inestimables herramientas
en la resolucin de problemas. El clculo de predicados tiene una utilizacin
directa en Pascal, en forma de expresiones booleanas. Se han introducido mtodos deductivos de demostracin, incluida la induccin, tiles para el estudio del
diseo de programas y la verificacin, que se vern en captulos posteriores.

Ejercicios
3.24. Demostrar que la suma de los n primeros nmeros impares es n 2
3.25. Supongamos que la funcin Factorial: N
la forma siguiente:

Factorial (1)
Factorial (n) = n x Factorial (n -

N se define recursivamente de

1)

para

n > 1

Lgica

87

Demostrar por induccin, sobre n, que esta definicin es equivalente a la


definicin no recursiva:

Factorial (n)

3.26.

1 x 2 x ... x (n -

1) x n

Supongamos que la funcin f(n) se define mediante la siguiente regla:


f(O) = 1

f(n

+ 1)

2f(n) para todo n > O

Demostrar por induccin que f(n)

3.27.

2n

Demostrar la generalizacin de la ley de Margan, siguiente:

(Nota:

U A significa A o u

Al U ... U

A n)

;=0

(Nota:

nA

significa A o n Al n ... n A n)

i=O

3.28.

Verificar las relaciones siguientes utilizando la induccin matemtica:


n

a)

L (i(i

n(n

1)

i=O

b)

n(n

+ 1)(2n +
6

i=O

c)

L
i=O

n2 (n

+ 1)(n +

+
4

1?

1)

2)

CAPTULO

PROBLEMAS ALGORTMICOS
V SU SOL UCi N

El conjunto de problemas que son resolubles utilizando una compu tadora


es,
indudablemente, muy extenso. Muchos de estos problemas son de ndole
matemtica, y requieren la utilizacin de nmeros y la aplicacin de princip
ios
matemticos. Otros tienen naturaleza grfica, e implican la manipulacin
de
objetos grficos, tales como puntos, lneas, rectngulos y crculos. El
otro gran
grupo implica la manipulacin de textos en lengua castellana y, por
tanto,
implica la manipulacin de caracteres alfabticos y palabras como unidad
es de
informacin bsicas.
Muchos de los problemas que debemos resolver con computadoras, autnticamenteimportantes, fuerzan a la manipulacin conjunta de dos o tres
de los
dominios anteriores -mate mtica s, grficos y texto-- . Por ejemplo,
si utilizamos una compu tadora para resolver un problema que simula el juego
de las
tres en raya, no querremos slo visualizar la secuencia de movimientos
(describible como texto), sino que queremos ver en qu situacin se encuen
tra el
tablero en cada momento (descripcin grfica). Un estudio cuidadoso
de problemas algoritmicos debe incluir elementos de esos tres dominios,
bien por
separado, bien en combinacin con otro.
Existe una ventaja adicional si se estudian los problemas computaciona
les
de las matemticas, los grficos y los textos de forma conjunta: mucho
s de los
principios que se aprenden al estudiar una de estas reas, por ejempl
o las
matemticas, son tambin de aplicacin en las dems. Esto sugiere la existen
cia
de una serie subyacente y nica de principios, que gobiernan el compo
rtamiento de computadoras y programas. De hecho, estos principios dirigen
nuestra
forma de aborda r un problema cuando tratamos de resolverlo con una
computadora. Este conjunto de principios recibe el nombre de resolucin de problem
as
algortmicos. En este capitulo se introducen las ideas1undamentales
de la resolucin de problemas algortmicos, y se presentan una gran variedad de
problemas matemticos, grficos y de procesamiento de textos, que ilustra
n estas
ideas.

90

y program as
Compu tacin /. Lgica, resoluc in de problem as, algoritm os

4.1.

ALGORITMOS Y PROBLEMAS

micos y
Los conceptos de proble mas algortmicos, algoritmos, lenguajes algort
resolver
de
ad
activid
la
para
compo rtamie nto algortmico son fundamentales
tica.
inform
la
de
ina
discipl
la
para
proble mas con compu tadora s y, por tanto,
es
que
lo
sobre
firme
miento
conoci
un
En consecuencia, necesitamos adquir ir
con
mico,
algort
ma
proble
un
es
que
lo
y
un algorit mo (y sobre lo que no es),
mas. La
objeto de llevar a cabo de forma eficaz la activid ad de resolver proble
n.
discusi
esta
para
partida
de
punto
definicin siguiente sirve como
n una
Definicin. Un algoritmo es una lista de instrucciones que realiza
e
resuelv
que
iza
garant
que
o
proces
un
de
descripcin paso a paso y precisa
a
termin
que
y
inado,
determ
tipo
un
a
zca
pertene
cualqu ier proble ma que
despus de que se hayan llevado a cabo un nmer o finito de pasos.
mas, o
Los algoritmos se escriben o disean con el props ito de resolver proble
micos.
algort
ms exactamente, proble mas
tual o
Definicin. Un problema algortmico es cualquier problema, concep
mo.
algorit
un
te
median
arse
expres
prctico, cya solucin puede
tanto denEn la vida cotidia na encont ramos muchos proble mas algoritmicos,
Por ejemtica.
inform
la
de
lizado
especia
tro como fuera del campo altame nte
uye un
constit
ra
cazado
la
a
pollo
ar
prepar
plo, una determ inada receta para
ra es
cazado
la
a
pollo
ar
prepar
de
l
genera
ma
algoritmo, mientras que el proble
ejems
alguno
tan
presen
se
4.1
Tabla
la
En
o.
el proble ma algoitmico asociad
plos comunes de algoritmos y de proble mas algortmicos.
Tabla 4.1.

Alguno s algorit mos y proble mas algort micos

Algoritmo

Problem a algortmico

Conjun to de instrucciones para tejer un jersey


Un itinerario particu lar para recorre r el mundo
Un plan de trabajo para cursar una licenciatura

Tejer un jersey.
Dar la vuelta al mundo.
Cursar una licenciatura.

existen
Para cada proble ma algortmico como cursar una licenciatura,
ejemPor
n.
soluci
como
se
utilizar
varios algoritmos alternativos que pueden
un
seguir
tica,
inform
en
ra
ingenie
plo, un alumn o que desee cursar una
mmedioa
s
ciencia
en
arse
licenci
desee
que
el
en
algoritmo muy diferente que
bientales o en filosofa.
alcs
En cualquier caso, los algoritmos de la Tabla 4.1 exhiben las princip
acin
caractersticas sealadas en la definicin: exactitud, efectividad y termin
tarse
garantizada. Cuand o se ejecutan determ inados algoritmos pueden comple
mucho
llevar
en un pequeo intervalo de tiempo, mientras que otroS' pueden

Problemas algortmicos y su solucin

91

tiempo. Sin embargo, la ejecucin de todos los algoritmos debe terminar. Por
ello, cualquier descripcin paso a paso de un proceso que no termine, no es un
algoritmo. Por ejemplo, el proceso de escribir todos los nmeros enteros positivos, uno a uno, no es un algoritmo, puesto que no terminara nunca.
En la informtica se asocia la nocin de algoritmo con la de un proceso
que debe ser ejecutado por una computadora, en lugar de por una persona. En
princjpio, cualquier algoritmo que diseemos para una computadora puede ser
realizado a mano (suponiendo que disponemos del tiempo necesario, una pizarra o suficiente papel). En realidad, encargamos a la computadora la ejecucin
de los pasos que componen un algoritmo, porque es capaz de completarlo en
un tiempo mucho menor del que nosotros emplearamos, y porque es menos
proclive a cometer errores que nosotros.
Sin embargo, no todos los algoritmos pueden ser ejecutados por computadoras. Las computadoras slo pueden ejecutar algoritmos que se componen de
acciones individuales que pueden entender y realizar. Por ejemplo, la preparacin de pollo a la cazadora implica acciones como encender el horno o
deshuesar el pollo, tareas para las que una computadora est bastante mal
preparada. Por tanto, es necesario conocer bien cules son las tareas que puede
realizar una computadora, de forma que diseemos algoritmos que contengan
slo ese tipo de tareas.
Como punto de partida, considrese el sencillo modelo computacional de la
Figura 4.1.

ENTRADA

Figura 4.1.

I----~.I

PROCESO

----~.I

SALIDA

El modelo de computacin entrada-procesa-salida.

En este modelo, un proceso de clculo se compone de tres partes: una entrada,


un proceso y una salida. La entrada la constituyen un conjunto de informaciones que necesitan los pasos de que se compone el algoritmo para llevar a cabo
la tarea; el proceso contiene (una descripcin de) los pasos del algoritmo; finalmente, la salida la constituye el resultado que se obtiene ejecutando los pasos,
con los datos de entrada.
Por ejemplo, el procedimiento para calcular la calificacin media (CM) es
un algoritmo. En este caso, la entrada puede ser cualquier lista de valores
numricos dentro del rango Oa 4. (O = suspenso, 1 = aprobado, 2 = notable,
3 = sobresaliente, y 4 = matrcula de honor); la salida ser la media de esos
valores (es decir, el cociente entre la suma de todos y el nmero de valores); yel
proceso es (una descripcin de) el conjunto de pasos individuales que deben
seguirse para obtener el resultado. Ese conjunto de pasos puede resumirse en
un lenguaje-castellano descriptor de procesos, en la forma siguiente:

92

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Paso
Paso
Paso
Paso
Paso

1.
2.
3.
4.
5.

Obtener la lista de calificaciones.


Calcular n = nmero de notas de la lista.
Calcular Sum = la suma de las calificaciones de la lista.
Calcular CM = Sumn.
Mostrar CM.

Cuando se escriben este tipo de descripciones de procesos, se realizan algunas' suposiciones tcitas sobre el comportamiento del modelo entrada-procesosalida de la Figura 4.1. La primera hiptesis es que el nmero de calificaciones
es indeterminado, aunque nunca infinito. La segunda hiptesis es que para
poder calcular cualquier cosa sobre las calificaciones, el algoritmo necesita
obtenerlas primero ---es decir, trasladarlas fisicamente a la parte proceso del
modelo, desde la parte entrada del mismo.
Cuando se utiliza una computadora en la resolucin de este problema
algortmico, las instrucciones que contienen los pasos individuales, junto con
los valores numricos de Sum, n y CM se almacenan fisicamente en un lugar
llamado memoria, que se encuentra unido a la unidad central de procesamiento
(CPU o procesador) de la computadora. Toda la informacin de entrada o
salida, se encuentra fsicamente separada del procesador en dispositivos como
el teclado, el monitor o un archivo en disquete. Un diagrama de las unidades
de una computadora que se corresponde con el modelo entrada-proceso-salida
puede verse en la Figura 4.2.

Teclado/Ratn

Procesador/
- - - - '--_M_em_o_ri_a_--..JI--- Pantalla de monitor

Figura 4.2.

Computadora correspondiente al modelo.

La tercera suposicin que realizaremos es que los pasos de la descripcin


del proceso se realizarn en el orden en que estn escritos. Por ejemplo, difcilmente podramos realizar el Paso 5 sin haber realizado antes los pasos 1 al 4,
adems de ser improbable que hubiramos podido calcular la CM.
Nuestra cuarta suposicin es que cada uno de los pasos es eficaz ---es decir,
que contiene slo acciones del repertorio de las realizables por la computadora-. Por ejemplo, hemos asumido que la orden Mostrar (Paso 5) est en el
repertorio de instrucciones de la computadora. Por tanto, siempre que se ejecute alguna instruccin que contenga la palabra Mostrar, la informacin de
salida aparecer en el monitor, independientemente de cul sea el paso que la
contiene. (En este caso, mostrar aparece muy tarde. No existe ninguna restriccin del nmero de veces que mostrar puede estar en un proceso.)
Las cuatro suposiciones son ciertas, de hecho, para todos los algoritmos
que construimos para las computadoras. Las computadoras ejecutan las instrucciones de una forma obediente, comenzando por la primera y ejecutando
slo aquellas que le son inteligibles; es decir, instrucciones que describen tareas
dentro de su propio repertorio.

Problemas algortmicos y su solucin

93

Ejercicio
4.1.

Describir un problema algortmico que nos encontremos en la vida diaria, similar a los discutidos en la Seccin 4.1. Dar dos algoritmos alternativos para solucionar el problema.

,
4.2.

DEFINICiN DE PROBLEMAS Y DESCRIPCiN


DE ALGORITMOS

En la resolucin de problemas algortmicos, el nivel de precisin -tanto en la


descripcin del propio problema como en la solucin algortmica al mismodebe ser detallada y rigurosa. Por ejemplo, nuestra descripcin del algoritmo
de CM, de la Seccin 4.1, puede no ser lo suficientemente rigurosa para incorporarlo a una computadora. Es necesario un mayor nivel de detalle por dos
razones fundamentales:
El problema, sus limitaciones y su solucin deben describirse de forma
clara para el lector humano.
La solucin debe resolver completamente el problema -es decir, debe
aportar a la computadora toda la informacin necesaria para que produzca una salida correcta para todas las posibles variaciones de la entrada.
En el problema CM, la impresin en el proceso de descripcin deja sin responder la pregunta de cuntas puntuaciones constituirn la entrada. Existe un
nmero mximo de puntuaciones? Es posible suponer que siempre habr un
nmero de puntuaciones distinto de cero? Si no est permitida una entrada
consistente en cero puntuaciones, esto debera expresarse explcitamente. Sin
embargo, si se permite una entrada de cero puntuaciones, es necesario modificar la descripcin del proceso, de forma que evitemos la divisin por cero
(Paso 4), y que sea posible escribir el mensaje adecuado.
Esta breve discusin enfatiza sobre la necesidad de encontrar una manera
ms sinttica y formal de describir un problema algortmico y sus soluciones.
En el resto de esta seccin se introducen los rudimentos de un lenguaje de
descripcin de algoritmos. En la Seccin 4.3 se introducirn los rudimentos de
un lenguaje de descripcin de soluciones a problemas, y se demostrar que estos
dos tipos de lenguajes estn relacionados mutuamente.

4.2.1.

Los estados inicial y final de un algoritmo:


entrada y salida

Para formalizar el modelo de clculo entrada-procesa-salida, introduciremos


primero la nocin de estado de un algoritmo. Intuitivamente, podemos entender la idea de estado de un algoritmo como una especie de instantnea que
describe cmo estn las cosas inmediatamente despus (o antes) de que se haya

94

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

ejecutado un paso de un algoritmo. Por ejemplo, el estado del proceso descrito


en la Seccin 4.1 podria ser una instantnea de sus entradas, sus salidas y cada
una de sus variables Sum, n y CM en el instante particular en que cada uno de
los pasos, del 1 al 5, ha sido ejecutado.
Existen dos pasos de inters especial: el estado inicial y el fina!. El estado
inicial lo constituye una descripcin de la entrada, antes de que se ejecute el
primer paso del algoritmo y, por tanto, recibe el nombre de precondiein del
algoritmo (o pre). El estado final es una descripcin de las entradas y las salidas
despus de que se haya ejecutado el algoritmo, y reciben el nombre de poseondicin del algoritmo (o post). Ambas suelen escribirse utilizando la notacin
convencional de la lgica, introducida en el Capitulo 3:
{pre: ent rada = una expresin que describe todas las posibles entradas
del problema}
{post ent rada =0/\ sa l i da = una descripcin de todas las salidas que
pueden darse para cada entrada}
Si denotamos por Notas! la primera calificacin de la lista, por Notas z la
segunda, y as sucesivamente, la descripcin siguiente es una descripcin precisa del problema de la calificacin media, en forma de precondicin y poscondicin:
{pre: entrada = (Notas" Notas" .. "' Notas,> /\ n> O /\
\ti E {1, .. , n} :Notas, E (O, ... , 4))
{pos t: ent rada = 0 /\
salida = Sum i E {1, ... , n}:Notas,ln}

Obsrvese cmo se utiliza en la precondicin y la poscondicin el lenguaje de


la lgica de predicados, estudiado en el Captulo 3. Cuando utilizamos la
lgica de predicados de esta forma, se dice que realizamos asertos acerca de los
estados inicial y final del proceso.
El lenguaje de la lgica permite, en la expresin del estado de un clculo,
una concisin y precisin que no podemos alcanzar con el lenguaje castellano.
En el ejemplo, el estilo de descripcin no deja duda sobre la exclusin del caso
de que existan cero entradas en el problema de la CM. Por tanto, la solucin
algortmica a este problema no tiene que ocuparse de este caso.
El haber escrto entrada = 0 en la poscondicin significa que, al final del
proceso, la entrada estar vaca. Es decir, todas las entradas habrn sido ledas
por el proceso, pero no pueden ser ledas de nuevo. Esta peculiaridad de los
estados incial y final reflejan una forma peculiar de procesar la entrada y la
salida en una ejecucin del algoritmo. Es decir, el acto de obtener las entradas
consiste en una serie de pasos discretos, en los cuales: 1) un valor no puede ser
obtenido de nuevo despus de haberse obtenido una vez; y 2) los valores
individuales de la entrada se obtienen exactamente en el orden en el que se
introducen por el teclado.

Problemas algortmicos y su solucin

95

Con objeto de enfatizar la estrecha relacin existente entre la especificacin


de un algoritmo y la descripcin del proceso correspondiente, encerramos la
descripcin del proceso entre la precondicin y la poscondicin, como se
muestra en la Figura 4.3.
(pre: entrada = <Notas" Notas" .. "' Notas")
1\ \fi,E (1, ... , n) :Notas, E (O, ... ,4))
Paso
Paso
Paso
Paso
Paso

1.
2.
3.
4.
5.

1\

n> O

Obtener La Lista de caLificaciones


\ DescripCaLcuLar n = nmero de notas de La Lista
CaLcuLar Sum= La suma de Las caLificaciones de La Lista \ cin del
CaLcuLar CM ~ Sum/n
J proceso
Mostrar CM

{post: entrada ~01\


saL ida = Sum i E (1, ... , n} :Notas,ln}
Especificaciones

Figura 4.3.

4.2.2.

Unificacin de la descripcin de un proceso y su especificacin.

los estados intermedios de un clculo:


introduccin de variables

Los estados intermedios resultantes de cada paso intermedio de un clculo


pueden describirse tambin mediante asertos. Contrariamente al caso de la
precondicin y la poscondicin, en este caso es necesario considerar valores
intermedios que es necesario calcular para obtener los resultados finales, as
como los cambios que se producen en las propias entradas al incorporar valores individuales al proceso de clculo. Por ejemplo, en el algoritmo de CM, los
valores intermedios se identifican por n (el nmero de calificaciones); Sum (la
suma de calificaciones individuales, Notas;, donde i = 1, oo., n); y CM (el promedio de notas resultante).
Estos valores intermedios se identifican simblicamente, puesto que es imposible predecirlos previamente a una ejecucin concreta del algoritmo. Por
ejemplo, una ejecucin puede calcular el promedio de tres calificaciones (y por
tanto, n = 3), Y otra diferente puede calcular el promedio de 24 puntuaciones
(n = 24). La misma situacin es esperable para las propias puntuaciones o
para su suma, para diferentes ejecuciones. Por ello, capturamos esta nocin de
valor variable de la suma utilizando un nombre apropiado, como Sumo

Definicin. Una variable es un nombre simblico que se asocia con un


valor o serie de valores particulares, durante una ejecucin concreta de un
algoritmo, pero cuyo valor no puede predeterminarse en el momento en
que se construye el proceso del algoritmo.

96

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Por tanto, n, Sum y CM son variables del problema de la CM.


Podemos utilizar variables siempre que deseemos describir un estado intermedio de un clculo. Por ejemplo, es posible describir el aserto:
{ent rada

~ 0/\

Sum = Sum i

{1, .. , n l : Notas;

Para describir el estado de los clculos, despus de que se hayan completado


los pasos 1, 2 Y 3. Esto es una abreviatura de Se ha obtenido la entrada, el
tamao de la entrada (n) ha sido determinado, y se ha calculado la suma de los
n valores de entrada y se ha identificado este valor con la variable Sum.
Con objeto de localizar con precisin dentro del proceso dnde es cierto el
aserto, lo colocamos justo inmediatamente detrs del paso del algoritmo que lo
hace verdadero. Una versin aumentada de la descripcin del algoritmo del
proceso CM podria ser la siguiente:
Paso 1. Obtener la lista de cal i fi caciones
Paso 2. Calcular n ~ nmero de notas de la lista
Paso 3. Calcular Sum = la suma de las calificaciones de la lista
{entrada =0/\ Sum = Sum i

{1, .. , n} :Notas;}

Paso 4. Calcular CM = Sum/n


Paso 5. Mostrar CM

En general, se puede colocar un aserto entre dos pasos cualquiera de un clculo, y ste puede decir mucho o poco sobre el estado de los clculos en ese
momento del clculo. Lgicamente, si se colocan asertos antes del primer paso
y despus del ltimo, ambos deben ser consistentes con la precondicin y la
poscondicin, respectivamente. Por tanto, es posible colocar junto con la precondicin y la poscondicin un conjunto completo de asertos, con objeto de
clarificar la descripcin de los pasos de un algoritmo, tal y como se muestra en
la Figura 4.4.
En la prctica, el nivel de detalle que se muestra en la Figura 4.4 en los
asertos intermedios es excesivo, puesto que la mayora de la informacin puede
deducirse de un aserto prximo. Es decir, existe mucha informacin redundante en esta descripcin, lo que la hace intil. Por ejemplo, cada aparicin de
entrada = 0 en los asertos despus de los pasos del 2 al 4, puede eliminarse,
puesto que es redundante con la informacin que aparece en el aserto de detrs
del paso 1. De forma ms general, cualquier aserto intermedio puede eliminarse si su contenido es directamente deducible de un aserto vecino.
Una especificacin, descripcin de proceso y anotaciones intermedias ms
tiles se muestran en la Figura 4.5. El propsito para el que se utilizan los
asertos intermedios para ilustrar los pasos de un proceso es doble. Primero, los
asertos aportan informacin para cualquiera que necesite comprender el efecto
de los pasos individuales del proceso de clculo. Segundo, son un vehculo
eficaz en el proceso de verificacin de que ese conjunto de pasos resuelve
verdaderamente el problema original que se plante en forma de precondicin

Problemas algortmicos y su solucin

97

{pre: entrada = (Notas" Notas., . , Notas,) /\ n > O


/\ Vi E {1, ... , n} :Notas; E {O, " .. , 4}}
Paso 1. Obtener la lista de calificaciones
{entrada = 0} - - - - - - - - - - - - - - - - - - - - - - - - - - - ,
Paso 2. Calcular n ~ nmero de notas de la lista
{entrada =0/\ n > O}
Paso 3. Calcular Sum = la suma de las calificaciones de la lista
{entrada =0/\ Sum = Sum i E {1, ... , n} :Notas;}
Paso 4. Calcular CM = Sum/n
(entrada =0/\ Sum = Sum i E (1, .. "' n) :Notas, /\ CM = Sum/n} _
Paso 5. Mostrar CM
{post: entrada =0/\
sal ida = Sum i E {1, " .. , n} :Notas,!n}
A s e r los i n I e rme dio S _--'-----'-.-JL-'

Figura 4.4.

Introduccin de asertos intermedios en la descripcin


del algoritmo del problema CM.

y poscondicin. Obsrvese que existe una estrecha correspondencia entre esta


forma de describir los pasos de un algoritmo y el modelo original de entradaproceso-salida descrito en la Figura 4.1. Es decir, la precondicin se corresponde con la entrada, el paso del algoritmo describe el proceso, y la poscondicin
caracteriza la salida.
Ahora que podemos describir con ms precisin las transiciones entre estados en un proceso algortmico, en la Seccin 4.3 y posteriores trataremos de
conseguir un nivel de precisin comparable en el proceso de descripcin de los
pasos de que consta el propio algoritmo.
(pre: entrada = (Notas" Notas.,
, Notas,) /\ n > O
/\ Vi E (1, .. "' n) :Notas, E {O,
, 4}}
Paso 1. Obtener la lista de calificaciones
Paso 2. Calcular n = nmero de notas de la lista
(entrada =0/\ n > O)
Paso 3. Calcular Sum = la suma de las calificaciones de la lista
Paso 4. Calcular CM = Sum/n
(entrada =0/\ Sum ~ Sum i E (1, ... , n) :Notas; /\ CM = Sum/n}
Paso 5. Mostrar CM
(pos t: ent rada = 0 /\
salida = Su.. i E (1, ... , n) :Notas,!n}
Figura 4.5.

Una versin del problema del clculo del promedio


anotada parcialmente.

Ejercicios

4.2.

Describir en castellano el conjunto de pasos de un proceso algortmico


que calcule y muestre el conjunto de calificaciones que estn por encima

y program as
Compu tacin l. Lgica, resoluc in de problem as, algoritm os

98

este
del prome dio para una lista de calificaciones arbitra ria. Considrese
l al
genera
muy
Ser
CM.
ma
proble
del
in
extens
una
proble ma como
ria?
describir los pasos del proceso. Que variable adicional es necesa
Ejercicio
4.3. Cules seran la precondicin y poscondicin del proceso del
dara el
que
te
4.2? Definir una lista sencilla y la salida corresp ondien
algorit mo constru ido.

LENGUAJE ALGORTMICO

4.3.

descripcin
El conjun to de pasos individuales que, combinados, forman la
lingstico
estilo
comple ta de un proceso o algoritmo, deben escribirse con un
uado
inadec
medio
un
muy preciso. El castellano, por su propia natura leza, es
do
mostra
pasos,
cinco
de
para conseguir la precisin adecuada. El algorit mo
para
vago
iado
demas
es
en la Seccin 4.2 para calcular la calificacin media,
ser til.
en la
El tipo de lenguajes que tienen la suficiente precisin para ser tiles
leno
micos
algort
es
lenguaj
de
e
nombr
descripcin de algoritmos, reciben el
ano
castell
del
difieren
macin
progra
de
jes
guajes de programacin. Los lengua
en tres puntos esenciales:
s
Los lenguajes de progra macin tienen un vocabu lario y una sintaxi
algorit
ir
describ
pueden
slo
mas
muy limitados. Por tanto, los progra
de
micos)
algort
(no
tipos
otros
ir
describ
mos, y son inadecuados para
prosa.
s
2. El vocabu lario de un lenguaje de progra macin contiene slo aquello
realitipos de acciones bsicas que una compu tadora puede entend er y
las
zar, y no otras. Por ejemplo, un lenguaje de progra macin soport a
divin,
operaciones aritmticas habituales (suma, resta, multiplicaci
sin, comparacin); acciones propia s del procesamiento de texto, accioLas
nes de procesamiento de grficos y acciones de entrad a/salid a.
variay
s
mucha
son
r
acciones que una compu tadora no puede realiza
das -corre r, sacar de banda, recibir, sentir, hacer quiche y crear pinturas al leo- son algunas de las acciones que no se encuen tran dentro
de vocabulario de una compu tadora .
permite
3. La sintaxis de un lenguaje de progra macin es muy rgida, y no
te entre
cocien
del
clculo
el
o,
ejempl
Por
muchas variaciones de estilo.
tiva.
alterna
forma
existe
no
y
Sum/n
Sum y n se expresa como

1.

que
La descripcin de un proceso o algoritmo en un lenguaje de progra macin
ejecuson
mas
progra
Los
ma.
progra
de
e
difiere del castellano recibe el nombr
en castellatables por las compu tadora s, mientras que los algoritmos descritos
rse al
parece
para
os
disead
estn
macin
progra
de
no no. (Algunos lenguajes
idioma.
ingls, por lo que los progra mas escritos en l parece n estarlo en este
in
expres
El COBO L es uno de estos lenguajes. Sin embargo, la capaci dad de
.)
macin
en ingls no es posible alcanz arla en ningn lenguaje de progra

Problemas algortmicos y su solucin

99

Existen varios lenguajes de programacin entre los que podemos elegir


para describir algoritmos. Algunos estn diseados especialmente para la enseanza y el aprendizaje de los algoritmos, las computadoras y la resolucin de
problemas algortmicos. Pascal es un lenguaje de este tipo, y lo utilizaremos en
los ejemplos que pondremos a lo largo de este texto. Otros lenguajes de programacin populares son C, Modula-2, Ada, FORTRAN, COBOL, LISP,
ScheQ1e y ensambladores a nivel mquina. Introduciremos los lenguajes ensambladores en el Captulo 7. Algunos de los lenguajes mencionados antes son
bien conocidos por los programadores profesionales (como FORTRAN y COBOL), pero no son adecuados para el aprendizaje y la enseanza del proceso
de resolucin de problemas algortmicos.
Hasta el momento, nos hemos familiarizado con la sintaxis del Pascal,
gracias al manual de laboratorio adjunto. Por ello, no es difcil comprender
que el programa de la Figura 4.6 es una implementacin en este lenguaje del
problema CM, que habiamos descrito informalmente en castellano.
program caLcuLaCM;
{Esto es un programa que caLcuLa La CM de una serie de una o ms
caLificaciones numricas, cada una de eLLas en eL rango O.. 4,
que se introducirn por eL teclado}
uses
Listas;
val'

Notas: Li stas;
i,n:integer;
Sum, CM: rea L;
begin
{pre: entrada = (Notas" Notas" .. "' Notas")
1\ \1 i E {1, ... , n} : No t a s; E {O, ... , 4} }

1\

n> O

(Paso 1. Obtenemos La Lis ta de ca Lif i cac iones}


WriteLn ('Introducir La Lista de calificaciones: ');
ReadLista (Notas);
{Paso 2. CalcuLar n o nmero de caLificaciones en La lista)
n := LongL i sta(Notas);
i f n > O then
begin
{entrada ~01\ n > O}
{Paso 3. CalcuLamos Sum = La suma de Las caLificaciones de la Lista}
Sum := O:
i := 1 ;
whi le i <= n do
begin
Sum :~ Sum + Notas[i];
i

:~

+1

end
end;
{Paso 4. CaLcuLamos CM = Sum/n)
CM = Sum/n;
(Sum ~ SUII iE (1, ... , n) :Notas;

1\

CM = Sum/n}

100

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

{Paso 5. Se muestra CM}


WriteLn( 'La CM de esas calificaciones es
end [if]
{post entrada =01\
salida ~ SUIl i E {1, ... , n}:Notas,ln}
end. {CalculaCM}
Figurp 4.6.

=',

CM : 5 : 2)

Programa Pascal que se corresponde con la descripcin


de proceso de la Figura 4.5.

Los cinco pasos originales de la descripcin del proceso se incluyen aqui


como comentarios entre corchetes, de forma que la correspondencia entre estos
casos y el grupo de instrucciones Pascal sea fcilmente identificable. La precondicin, la poscondicin y los asertos intermedios tambin se ponen de
relieve mediante comentarios entre corchetes. Puesto que se han escrito como
comentarios de Pascal, el programa puede ser ejecutado en una computadora
directamente, sin necesidad de hacer ninguna modificacin.
El programa introduce algunos elementos nuevos que no se han tratado en
el manual de laboratorio. Los introduciremos en la seccin siguiente (para una
descripcin ms detallada, vase el manual de laboratorio). Para el propsito
de la discusin que nos ocupa, pondremos un nfasis especial en la correspondencia entre el lenguaje de programacin (como vehiculo para describir de
forma precisa el proceso algortmico) y la especificacin (como vehiculo para
describir de forma precisa el problema lingstico a resolver).

4.3.1. Sintaxis y semntica


El conjunto de instrucciones Pascal de la Figura 4.6 representa una implementacin del problema CM, en un lenguaje de programacin concreto. El significado de cada instruccin est definido de forma estricta, y trata de expresar de
una forma ms rigurosa el conjunto de pasos que componen el algoritmo,
originalmente expresado en castellano. Por ejemplo, la frase
Obtenemos la lista de calificaciones

que constituye el primer paso de la descripcin de la Figura 4.3, se convierte en


dos instrucciones de Pascal:
WriteLn ('Introducir la lista de calificaciones:');
ReadLista (Notas);

La instruccin Wr; te Ln indica al usuario qu tipo de entrada se pretende


obtener, y la instruccin ReadL; sta cumple la tarea de conseguir la lista de
enteros.
Listas. Este programa hace us\> del tipo L; s ta y sus operaciones relacionadas, que se resumen en la Figura 4.7. Los programadores pueden utilizar el

Problemas algortmicos y su solucin

B~
Entrada

RadLi sta

;::1:7.: :~"g3l
,,----..@
List0

salida

Figura 4.7.

101

InserLista
DeleteLista

oo.b.. " " , ["di ,,]

GV
Resumen de las operaciones de Lista.

tipo Lis ta y sus operaciones, sin ms que hacer la declaracin uses Lis ta;
despus de la cabecera del programa. (Las definiciones estn ocultas al programa, aunque su utilizacin se ha descrito cuidadosamente en el manual de
laboratorio.)
Un programa Pascal que incluye la unidad Lista est capacitado para
obtener, procesar y escribir listas completas de enteros, en lugar de trabajar con
un nmero cada vez. Esto supone una ayuda inestimable para la resolucin de
muchos problemas algortmicos, y la utilizaremos extensivamente en este texto.
Una variable que se declare como de tipo Lista, contendr una lista de
valores completa, como ocurre con la variable Notas declarada en el problema CM, con el objetivo de almacenar una lista de calificaciones completa:
var Notas: Li sta;

El procedimiento ReadL i sta (Notas) obtiene del dispositivo de entrada una lista de enteros, suponiendo que la lista est encerrada entre parntesis,
y se asigna su valor a la variable Notas. As, por ejemplo, si se teclea la
entrada:
(3 2 1 3)

El procedimiento ReadL i st (Notas) dejar la variable Notas en el estado


Notas =

(3

213)

La funcin LenghtLista (Notas) devuelve el nmero de elementos


que componen la lista, mientras que la expresin Nota s [i ] devuelve el valor
del i-simo elemento de la lista Notas. El entero i recibe el nombre de ndice

y progra mas
Compu tacin l. Lgica, resoluc in de problem as, algoritm os

102

que Lengdel elemento devuelto. As, por ejemplo, un caso posible podra ser
devuelva el
[3]
Notas
y
4,
er
integ
valor
el
va
htLis ta (Nota s) devuel
Lis ta
valor real 1. Una dscusin ms comple ta de las operacones sobre
Es
torio.
mostra das en la Fgura 4.7, puede encont rarse en el manua l de labora
utilicen
conveniente repasa r esta discusin antes de constru ir progra mas que
listas.
asertos
Limitaciones del conjunto de caracteres ASCn. Cuand o se incorp oran
ar las
record
rio
necesa
es
y otros comentarios dentro del texto de un progra ma,
caraclos
de
ar
estnd
el
es
que
limitaciones del conjun to de caracteres ASCn,
ctores de
teres que se pueden codificar y que utilizan la mayor a de los constru
Inforfor
Code
rd
Standa
an
Americ
de
compu tadora s. (ASCII es un acrni mo
posies
ar,
estnd
res
caracte
de
to
conjun
mation lnterchange)*. Utilizando un
entre
(Como
tes.
diferen
s
tadora
compu
entre
ble la transferencia de informacin
res ASCII
Macin tosh y PCs de IBM, por ejemplo). La lista comple ta de caracte
A.
ice
Apnd
el
en
y su. codifcacin se incluye
les,
Los cientficos suelen utilizar letras gregas y otros smbolos especia
al
o
ticas
subndices, superndices, al escribir expresiones lgicas y matem
0
Si'
a
t
No
escribir asertos. En el proble ma de CM se utilizaron, por ejemplo,
los Capy ~ estilo matemtico, contin uando con la notaci n convencional de
de
dentro
er
aparec
tulos 2 y 3. Desgraciadamente, esos caracteres no pueden
res
caracte
de
to
conjun
un progra ma Pascal, por no estar incluidos dentro del
ma Pascal,
ASCII. Por ello, cuando convertimos un algorit mo en un progra
smbolos
los
de
cin
sustitu
la
utilizamos un convenio de sustitucin ASCn para
ms comunes, como el de la Tabla 4.2.
Tabla 4.2.

Smbolo
matemtco

Nota Si

LO Sum
~

V
3

Sustitu tos ASCII para los smbol os matem ticos


Sustituto
ASCII

Significado
Seleccin del i-simo elemento de la lista
Conjun to vaco
Sumato ria
Menor o igual
Cuantificador universal
Cuantificador existencial
Conjuncin
Disyuncin
Pertenencia a conjunt o

Notas [;]
vaco
Sum
~

para todo
exste

or
n

bio de Informacin.
N. del T.: Estnda r Americano de Codificacin para el Intercam

Problemas algortmicos y su solucin

103

Utilizando las equivalencia de la tabla anterior, algunas de las expresiones


matemticas de la Figura 4.6, podran escribirse utilizando sustitutos ASCII
aceptables de la forma siguiente:
entrada =01\ n > O
8u.; E (1, ... , n): Notas,

4.3.2.

entrada = vac;o 1\ n > O


8um; ;n {1, .. "' n}: Notas[i]

Repeticin y bucles: inicializacin, invarianza


y terminacin

Un nuevo e importante concepto que encontramos en la solucin al problema


CM es el de bucle.
Definicin. Un bucle es una secuencia de instrucciones que pueden ejecutarse O, I un nmero finito de veces n.
El concepto de bucle es uno de los ms importantes de todos los que se utilizan
en el diseo de algoritmos. Por qu necesitan bucles los programas? Existen
dos razones fundamentales:
1.

2.

Economa de las expresiones.


Impredecibilidad del tamao de la entrada.

Ambas razones para la existencia de bucles se pueden comprender si analizamos la situacin siguiente: Supongamos que es necesario disear un algoritmo
que calcule S como la suma de seis calificaciones, dadas por las variables 91 a
96. Una forma de calcularlo sera realizando la declaracin y secuencia de
instrucciones Pascal siguiente:
val" 91,92,93,94,95,96: real;
S := O;
8:=8+91;
8 := 8 + 92;
8 := 8 + 93;
8:=8+94 ;
8:=8+95;
8 := 8 + 96;

Esta alternativa es absolutamente torpe. Si tuviramos que extender el problema mnimamente, y necesitsemos sumar 100 calificaciones, la eleccin realizada sera bastante poco brillante.
Bastante ms dificil, e incluso bordeando lo imposible, sera extender el
algoritmo para el caso en que el nmero de calificaciones fuera impredecible
(aunque finito); por ejemplo, n. Naturalmente, el valor de n no puede predecirse

y program as
Compu tacin l. Lgica, resoluc in de problem as, algoritm os

104

pueda
en el momento en que se escribe el programa, de forma que el progra ma
que
en
nto
mome
el
en
n,
de
lar
particu
valor
cada
para
calcular el valor de Sum
una
en
el progra ma es ejecutado o, como dicen algunos, corrido. Es decir,
mismo
ejecucin del programa, n puede valer 6, y en la siguiente ejecucin del
progra ma 100, en otra quiz 1000.
an
Lo que ,necesitaremos es que el lenguaje aporte facilidades que permit
generalizaciones de dos tipos:
La posibilidad de asignar un nico nombre a una lista de nmeros
arbitrariamente larga.
que
2. La posibilidad de escribir instrucciones o grupos de instrucciones
de
tibles
suscep
sean
que
puedan ser ejecutados reiteradas veces, pero
in.
repetic
cada
ser interpretados de una forma diferente en
1.

i en la
La primera posibilidad la aporta el tipo Lis ta, tal y como se describ
Pascal
de
cin
seccin anterior. La segunda capacidad la aporta la instruc
de
grupo
o
cin,
instruc
wh i l e, que permite ejecutar reiteradas veces una
es
Esto
in.
repetic
cada
instrucciones, pero con interpretaciones diferentes en
la
ba
calcula
nos
que
ccin
lo que necesitamos para simplificar la torpe constru
suma de n valores.
Ilustremos estas capacidades por separado. Supongamos que se declara
91 a 96.
slo una variable 9, del tipo Lis ta, en lugar de las seis variables de
te, sin
siguien
forma
la
en
l
origina
ma
Entonces, es posible cambiar el progra
cambiar su significado:
varg: Lista;

5 := O;
5 :=5+g [1];
5 := 5 + g[2];
5 := 5 + g[3];
5:=5+ g[4];
5 := 5 + g[5];
5 :=5+g [6];

Es decir, la poscondicin de la secuencia anterior seguir siendo:


5 = Sum i

{1, ... , 6}: g[ i]

haciendo una nica declaracin, en lugar de seis.


del
Pero las seis instrucciones ltimas son idnticas, a excepcin del valor
largo de
ndice de la referencia a la lista 9 [i ]; es decir, i varia entre 1 y 6 a lo
que
forma
las instrucciones. Con objeto de generalizar esas instrucciones de
recoque
i,
o
sean idnticas, necesitaremos introducir una variable, por ejempl
rra la secuencia de valores que se muestra en la Figura 4.8:

Problem as algortm icos y su soluc n

105

8 := O;
i := 1;
8:=8+ g[i];
i :=i+1 ;
8:=8+ g[i];
i := i + 1 ;
8:=8+ g[i];
i:=i+ 1;
'8 := 8 + g[i];
i:=i+ 1;
8:=8+ g[i];
i:=i+ 1;
8 ;= 8 + 9 [i];
i:=i+ 1;

Figura 4.8.

Suma de seis elemen tos: un paso hacia la genera lizacin .

Parece como si estuviramos retrocediendo, puesto que ahora tenemo


s que
escribir el doble de instrucciones, por lo que el nuevo mtodo parece
una
locura. Sin embargo, cada pareja de instrucciones a partir de las dos
primeras
es idntica:
whi le b do

begin
5; s; ... ; s
end
Figura 4.9. Forma genera l de la instruc cin wh i le: b es
una expres in booleana; s; s; . ; s es cualqu ier secuen cia de instruc ciones
en Pascal.
8:=8+ g[i];
i:=i+ 1;

y la secuencia entera sigue satisfaciendo la poscondicin.


La instruccin whi l e permite repetir el par de instrucciones seis veces.
Su
forma general se presenta en la Figura 4.9, y una descripcin ms
detallada
puede encontrarse en el manual de laboratorio.
Cuando se ejecuta una instruccin wh i l e, primero se evala la condic
in b.
Si el resultado de la evaluacin es verdadero, se ejecuta la secuencia
s;
.. ; s una vez. La condicin b se vuelve a evaluar, y si el resulta s;
do es
de nuevo verdadero, se vuelve a ejecutar la sentencia. Esta pareja de
acciones
se ejecutan reiteradamente, hasta que la condicin resulta evaluada
a falso,
momento en que se concluye la repeticin de las instrucciones y se
termina
la ejecucin del wh ; le.
Sin embargo, cuando utilizamos un bucle wh ; l e, debemos tomar una
serie
de precauciones inicia/espara que ste se ejecute bajo control. Es decir,
la ejecucin del bucle debe terminar despus de un nmero finito de repetic
iones, y
una vez terminado, debe satisfacerse la poscondicin. Por esta razn,
a los
bucles suele denominrse!es bucles controlados. La estructura de un bucle
controlado, que incluye tanto la inicializacin como la instruccin wh
i l e, se
muestra en la Figura 4.10:

106

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Instrucciones de inicializacin
while b do
begin
s;s; ... ;5
end;
Figura 4.10.

Estructura general de un bucle controlado en Pascal.

Por tanto, los requisitos para que un bucle sea controlado son que las instrucciones de inicializacin, la expresin booleana b y las instrucciones s; Si
... i s estn escritas de tal forma que: 1) se garantice la terminacin del bucle;
y 2) se satisfaga la poscondicin del bucle.
En nuestro ejemplo, las instrucciones de inicializacin S : = O e ; : = 1, la
expresin booleana ; <= 6, Ylas instrucciones S : = S + 9 [ i] e ; : = ; + 1,
combinan y satisfacen estos requisitos. Es decir, nuestro ejemplo puede reescribirse como el bucle controlado de la Figura 4.11.
5 := O;
i := 1;
while i <~ 6 do
begin
5:=5+g[i];
i := i + 1
end

Figura 4.11.

Suma de los seis elementos de una lista. Generalizacin.

Obsrvese que en la Figura 4.11 la condicin; <= 6 describe con exactitud la


condicin bajo la cual el bucle debe seguir repitindose, con objeto de conse
guir el equivalente a los seis pares de instrucciones como las que aparecen en la
versin original de la Figura 4.8.
Utilizando el mtodo de los bucles controlados, se ha conseguido una
generalidad y economia en las expresiones, que en otro caso habra sido dificil
de conseguir. Obsrvese que el paso 3 de la solucin al problema CM ( el bucle
whi le de la Figura 4.6) es prcticamente idntico al bucle whi le de la Figura
4.11. Los dos bucles difieren slo en la forma de las expresiones booleanas que
gobiernan el nmero de repeticiones del bucle, y en el nombre de las variables.
En la Figura 4.11, el bucle se repetir exactamente seis veces; mientras que en
el bucle original, el nmero de iteraciones viene determinado por n, o nmero
de calificaciones en la lista Notas. Gracias a la generalidad que nos aporta la
introduccin de la variable n, es posible resolver el problema CM. Sin n, la
solucin estara limitada a la que calcula el promedio de un nmero predeterminado de calificaciones. La permanencia de esta restrccin supondra una
situacin bastante insatisfactoria no slo para este problema, sino que no
satisfara los requisitos de generalidad exigidos a las soluciones algortmicas.
Invarianza de bucles. Un aspecto importante en el diseo de soluciones a
problemas mediante la utilizacin de bucles, es el poder garantizar que el bucle

Problem as algortm icos y su soluci n

107

termina, y que despus de esto se satisface exactamente la poscondicin


para la
que fue diseado. Para conseguir este props ito se utiliza un tipo especia
l de
aserto, llamado invariante del bucle (o simplemente invariante).
Informalmente, podemos pensar en el bucle como en un aserto sobre
el
estado de los clculos, que vale verdadero (es decir, que no vara)
antes y
despus de cada iteracin del bucle, mientras se est ejecutando. Es
habitual
diferenciar los invariantes de otro tipo de asertos de los programas,
porque
guarda n una relacin especial con los fragmentos de progra mas en
los que
estn incluidos. El aserto siguiente es un invariante del bucle del
programaCM .
(inv: Sum = Su.

in (1, """' i - 1}: Notas[ j] /\ 1 <= i <= n + 1}

Para demos trar que esto es, sin duda, el invariante del bucle, debem
os
compr obar que cada valor de ; durant e la ejecucin del bucle:
1.

2.

Sum es la suma de las i - 1 primeras calificaciones en la lista Not


a s; y
El valor de ; est comprendido siempre entre 1 y el valor que causa
la
terminacin del bucle.

Considrese el ejemplo en el que Notas = (3 2 1 3), por lo que n


= 4. El
estado antes de cada iteracin del bucle, y la comprobacin corresp
ondiente
del valor del invariante, puede sintetizarse de la forma siguiente:
Antes
de la
iteracin

Estado

S=O /\;=1 J\n= 4

S=3/ \;=2J \n=4

S=5J \;=3/ \n=4

S=6/ \i=4J \n=4

S=9J \i=5J \n=4

Comprobacin del invariante

Sum = Sum j ; n {1,


J\1< =1< =5
Sum= Sum j in {1,
/\1< =2< =5
Sum= Sum j in {1,
J\1< =3< =5
Sum = Sum j ; n {1,
J\1< =4< =5
Sum = Sum j in {1,
J\1< =5< =5

""., O}: No t a s [j]


.. , 1}: Notas [j]
. , 2}: Notas [j]
.. , 3}: No t a s [j]
.. , 4}: Notas [j]

Puesto que la quinta iteracin no tiene lugar (se produce la salida del
wh i Le,
puesto que; <= n cambia a falso), el invariante conduce al cumplimiento
de la
poscondicin al salir del bucle. Esto es,
Sum = Su.. j in (1, "."' i - 1}: Notas [j] /\ 1 <= i

<~

n+1

108

prog ram as
n de prob lem as, algo ritm os y
Com puta cin ,. Lgica, resoluci

que por s mismo acaba siendo:


Not a s [j]
Suro = Sum j ; n {1, ... , n}:

1.
rucCua ndo el valor de ; alcanza n +
nte del bucle y la secuencia de inst
aria
inv
el
e
entr
cin
rela
la
Cuill es
que
io
esar
nec
Es
yen el cuerpo del bucle?
ciones s; s; ... ; s que constitu
es
cion
relacin entre las instruc
estudiemos en nuestro ejemplo la
Suro := Suro + No tas [;]i
; := ; + 1

y el invariante
Suro =

SUII j ;

n {1, ... , ; - 1 }: Not as [j]

1\

1 <= ; <= n + 1

etvos en
de forma intencionada con dos obj
El cuerpo del bucle se ha diseado
mente:
nte (valga verdadero).
1. El cuerpo preserve el invaria
sin hacia la terminacin del bucle.
2. El cuerpo produzca una progre
do lo
hacer ni ms n menos que esto -to
En general, los bucles no tienen que
dems es irrelevante.

4.3.3.

Tres

vision~s

ma
de la misma solucin al proble

",.

les de
lta de la composicin de tres nive
El pro gra ma de la Figura 4.6 resu la descripcin del proceso, que describe
cal;
ma; y
lenguaje distintos: el cdigo en Pas
o del proceso que describe el progra
pas
a
cad
en
rre
ocu
qu
ano
tell
cas
ceso.
en
antes y despus de cad a paso del pro ir,
dec
la especificacin formal que aparece
nivel elevado de redundancia; es
Los tres niveles jun tos suponen un estilos diferentes -alg or tmi co formal
tres
ioexpresan los mismos conceptos en
no) y declarativo formal (especificac
tella
(cas
l
rma
info
ico
(Pascal), algortm
a un
nes).
de que una solucin pro gra mad a
Est a redundancia enfatiza el hecho
ias:
ienc
te par a tres tipos de aud
algoritmo se escribe simultneamen
1. La computadora.
grama.
2. La gente que disea y lee el pro del programa.
in
recc
cor
la
3. La gente que verifica
ado ra
nta el cdigo en Pascal: la com put
La com put ado ra slo tiene en cue
ores hurealizar el proceso. Los programad
en
seguir con exactitud el cdigo al
en Pascal, los comentarios escritos
manos se interesarn por el cdigo quieren entender y desarrollar correcs si
castellano, y las pre y poscondicione

Problemas algortm icos y su soluci n

109

tamente el cdigo y, posteriormente, ampliar o mejorar el programa.


Los verificadores humanos del progra ma estarn interesados en el cdigo de
Pascal, la
precondicin, la poscondicin y en los asertos intermedios mediante los
cuales
obtendrn una demostracin rigurosa de la correccin del programa.
En la Figura 4.12 se muestra lo que considerara la compu tadora
de la
parte en Pascal del progra ma que soluciona el problema CM.
progra ll ca l cu laCM;
uses
Listas ;
var
Notas : Listas ;
i, n : intege r;
Sum, CM: real;
begin
WriteL n ('Intro ducir la lista de califi cacio nes:') ;
ReadL ista (Notas );
n := LongL ista(N otas);
if n > O then
begin
Sum := O;
i := 1 ;

while i <= n do
begin
Sum :=Sum +Nota s[i];
i := i + 1
end;
CM := Sum/n;
WriteL n( 'La CM de esas cal ificac iones es = " CM : 5
end
end. (Calcul aCM}

Figura 4.12.

2)

El progra ma CM, desde el punto de vista de la compu tadora


.

Los programadores noveles suelen confundir el punto de vista de la


computado ra con el del lector. Es decir, suelen presentar slo el progra
ma como
solucin a un problema algortmico. Sin embargo, esta representacin
, por si
misma, no es suficiente para la construccin y presentacin de progra
mas
fiables.
Cuand o nos comprometemos en el proceso de resolver problemas algort
micos, nuestra intencin debe ser la de desarrollar programas comen
tados
completamente, de forma que estas anotaciones nos muestren la definic
in del
problema original, y los sucesivos pasos que hemos seguido en su
solucin.
Para el problema de CM, el progra ma completo es, ms o menos,
como la
versin mostra da en la Figura 4.13.
progra m calcula CM;
{esto es un program a que calcul a la CM de una serie de
una o ms

110

Computacin l. Lgica, resolucin de problemas, algoritmos y programas


calificaciones numricas, cada una de ellas en el rango O.. 4, que
se introducirn por el teclado}
uses
Listas;
var
Notas: Listas;
i, n : integer;
Sum, CM : real;
begin
'
{pre: entrada = (Notas" Notas" , Notas n ) /\ n > O
/\ Vi E {1, ... , n}:Notas; E {O, ... , 4}}
{Paso 1. Obtenemos la lista de calificaciones}
WriteLn('Introducir la lista de calificaciones');
ReadLista(Notas);
{Paso 2. Calcular n o nmero de calificaciones en la lista}
n := LongLista(Notas);
if n > O then
begin

{Paso 3. Calculamos Sum= la suma de las calificaciones de la lista}


Sum := O;
i := 1;
while i <= n do
begin
Sum := Sum + Notas[i J;
i := i + 1
end;
{Paso 4. Calculamos CM = Sum/n}
CM = Sum/n;
{Paso 5. Se muestra CM}
WriteLn('La CMde esas calificaciones es= "
end {if}
{post: entrada =0/\
salida = Su.. i E {1, ... , n}: Notas;!n}
end. {CalculaCM}

Figura 4.13.

CM

2)

El mismo programa, desde el punto de vista del lector


y del desarrollador.

La versin de la Figura 4.13 difiere de la versin de la Figura 4.6, en que


excluye los asertos intermedios. Estos asertos son tiles cuando el programa es
probado y verificado. La prueba y verificacin de programas se introduce
separadamente en el Captulo 6.

Problemas algortm icos y su soluci n

111

Ejercicios
4.4.

La lista siguiente contiene la lectura de las temperaturas diarias de una


semana de verano.
Temps = (78 62 71 73748 584) *

Cul es el ndice de la lista Tems, de la temperatura mxima de la


semana?
b) Cul es el valor de la temper atura mxima?
e) Cun tas temperaturas estuvieron por debajo del promedio semanal?
a)

4.5.

Supongamos que necesitamos escribir un progra ma que calcule, para


una lista de siete temperaturas como la del ejemplo anterior, todas
las
respuestas a las cuestiones de dicho ejemplo.
Escribir una precondicin que describa el conjun to de todas las
listas de entrad a vlidas para el programa.
b) Dar una poscondicin que describa, para las entrad as
vlidas, las
salidas que debe mostra r el programa.
e) Cul de todas las cuestiones precisa la utilizacin de un bucle para
que el progra ma pueda contestarla?
a)

4.6.

Debajo, se muestra un bucle contro lado que calcula la temperatura


mxima de una semana, y la deja en la variable Max.
Max := Temps [1]
i := 2;
while i <= Lenght Li sta (Temps ) do
i f Temps [i] > Max then
Max := Temps [i]

Trazar una ejecucin de los pasos de bucle, utilizando los valores de


Temp s del Ejercicio 4.4. Trazar significa escribir los valores
que
toman las variables ; y Max, en relacin a los valores de
Temps [; ], al comienzo de cada iteracin.
b) Despus de examinar esos valores y examinar el compo rtamie
nto
del bucle para cualquier lista de valores, escribir un invariante para
el bucle.
a)

4.7.

Escribir un bucle contro lado que satisfaga las especificaciones siguien


tes:
{pre: L ~ (e"

e" . , en) /\ n > O)

N. del T.: Expresadas en grados Farenheith.

112

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

{post: SumPares = La suma de todos Los eLementos de L con ndce par 1\


Sumlmpar = La suma de todos Los eLementos de L con subndice mpar}

4.8.

Escribir las instrucciones de Pascal que calculen el promedio de las siete


temperaturas de la lista del Ejercicio 4.4, asignando el valor a la variable TemProm. Dar las precondiciones y postcondiciones de esas instrucciones, as como el invariante del bucle controlado que contienen.

4.9.

Escribir las instrucciones en Pascal que cuenten el nmero de temperaturas de la lista del Ejercicio 4.4, que estn por debajo de valor medio
(TemProm) y dejen este valor en la variable entera ndebajo. Escribir
la precondicin y la poscondicin para esas instrucciones, asi como el
invariante del bucle que contienen. Estn esas precondiciones relacionadas con las poscondiciones del Ejercicio 4.8? Qu sugiere esto sobre
el orden en que esos dos grupos de instrucciones deberan escribirse si
las ussemos para resolver el Ejercicio 4.4c?

4.10. Qu mostraria el siguiente fragmento de programa?:


var x, y: reaL;
m, n, p: nteger;
begin
readln (x, m);
read (y);
read (n, p);
wrte (n, x);
wrteln (p);
wrteln (y, m);
end.

si se le suministrase la entrada siguiente:


13.215
23.7
236575
354679

4.4.

MS PROBLEMAS ALGORTMICOS

En esta seccin nos alejamos del ya familiar problema de CM, e introducimos


otros problemas algortmicos junto con sus soluciones. Estos nuevos ejemplos
ilustran el conjunto de problemas que son susceptibles de solucionarse utilizando una computadora. Tambin nos servirn para ilustrar cmo los tres
estilos diferentes (descripcin en castellano de los pasos individuales, especificaciones y otras aserciones, y codificacin en lenguaje Pascal) se utilizan para
realizar una descripcin y resolucin completa del problema.

Problemas algortmicos y su solucin

4.4.1.

Clculo de

113

el

Desarrollemos un programa llamado Pot en c i a que calcule la b-sima potencia de a, o ab , donde a y b son enteros y el resultado un nmero real. Por
ejemplo, escrito como una funcin de Pascal Potencia(2,3) calcularia el
valor 2 3 = 8.
El\ la construccin de una solucin, debemos precisar previamente no slo
el resultado esperado, sino tambin el rango de enteros para los que el programa est bien definido; es decir, sus precondiciones. En particular, debemos
especificar que ciertas parejas de valores de a y b, tales como a = OY b = - 1,
deben ser excluidas, puesto que podrian conducirnos a errores computacionales. (En este caso, Potenci a (0,1) representara 0- 1 1/0, que representa
una divisin con resultado indefinido). Tambin debemos tener en cuenta las
limitaciones del lenguaje de programacin en el que expresamos el algoritmo.
Por ejemplo, muchas versiones de Pascal restringen el rango de valores de los
enteros al rango - 215 ... 2 15 - 1. Si identificamos estos valores con Mi nlnt y
Maxlnt, respectivamente, entonces las precondiciones de Potencia pueden
descartar todos aquellos valores de a o b que conduzcan un resultado que
exceda a Minlnt o Maxlnt. Por ejemplo, a = 2 Y b = 16 daran como
resultado 216 , que sera un valor mayor que Maxlnt para muchas versiones
Pascal.
Teniendo presentes estas condiciones, las precondiciones y poscondiciones
siguiente podran ser apropiadas para disear el programa de la potencia.
{pre: a y b son enteros A (a", O v a
b
A Minlnt '" a '" Maxlnt}
{Pos t: resu l t = a b }

=OA

b '" O)

Para los valores de a y b que satisfagan esta precondicin, el resultado ab


podra definirse como:
Definicin

ab

=
:

if b

':/~av'~ ~'.:~ I

if b > O
if b < O

Lb-a es

En la construccin de una solucin al problema, debemos tener en cuenta que


el valor de b, que gobierna el nmero de veces que se calcula a por a, es una
variable. Por tanto, cualquer solucin que calcule el producto de las bases
debe contener un bucle.
El diseo del bucle se ve facilitado si analizamos el caso en que b es
pequeo, y la varable P = ab resultante se calcula en la forma de la Tabla 4.3.
De los casos de esta tabla podemos hacer las observaciones siguientes:
1.

El nmero de iteraciones del bucle es b - 1.

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

114

2.
3.

La inicializacin del bucle se realiza mediante la asignacin P : = a.


La instruccin que debe repetirse b -1 veces es la asignacin P := P * a.

Este ejemplo nos sugiere nuevas ideas sobre la naturaleza del invariante del
bucle. Esto es, de la i -sima iteracin del bucle, donde 1 ~ i ~ b, el valor de P
viene dado por

,
{; nv: P = a i

1 <= ; <= b}

La salida del bucle se producir inmediatamente antes de la b-sima iteracin


(que nunca tendr lugar). Ahora i = b Yel invariante se convierte por s mismo
en P = ab, que est bastante prximo de la poscondicin del problema.
Tabla 4.3.

Resultados intermedios para el problema de la potencia


CLcuLo de a b

VaLor de b
1
2

P
P
P
P
P
P
P
P
P
P

:= a
:= a;
:= P * a
:= B;
:= P * a;
:= P * a
:= B;
:= P * a;
:=P*a;
:= P * a

Poscond;c;n
{P

a}

{P=a*a}
{P=a*a*a}

{P=a*a*a*a}

Entonces, si utilizamos la variable i para controlar el nmero de iteraciones del bucle, tomar todos los valores del rango de enteros comprendidos
entre 1 y b ~ 1, para que el clculo de P sea correcto. Estas consideraciones
nos conducen al programa Pascal comentado, que se muestra en la Figura 4.14.
Quin comprueba las precondiciones? Cuando observamos la solucin a algn problema algoritmico, tales como el de la Potencia o el de la CM,
es normal preguntarse: de quin es responsabilidad comprobar el cumplimiento de las precondiciones?, del programa o del usuario del programa?
Nos gustara tener algn tipo de garanta operativa de que ninguna entrada
diferente de aquellas para las que fue diseado el programa se producir y
tendremos as garantizado que no se nos contaminar ni peligrar la integridad del programa.
Consideremos el programa Potencia, para el que la precondicin establece que, para algunos valores de a y b, el resultado a b puede estar fuera del
conjunto de valores enteros que la computadora puede reconocer. Desgraciadamente, esta precondicin del programa Potenc i a no puede ser comprobada explicitamente por el propio programa, puesto que la accin de calcular a b

Problemas algortmicos y su solucin

115

para valores inadecuados provoca un error en tiempo de ejecucin; un mensaje


similar a ; nteger overf Low aparecer en el monitor, y la ejecucin concluir repentinamente.
progra. Potencia;
{Este programa calcula la b-sima potencia de a)
varP: real;
1I, b, i: i nteger;
begin
{Pre : ent rada = a b A (a <> O or a ~ O A b <> O)
b
A Mi nlnt <= a <= Maxlnt}
WriteLn( 'lntroduci r dos enteros a y b: ');
ReadLn(a,b);
i f b = O then
P := 1
else
begin
P := a;
i := 1;
while i <= abs(b) - 1 do
{i nv: P = a; A 1 <= i <= b)
begin
P := P * a;
i := i + 1
end;
if b < O then
P := 1/P
end;
WriteLn('Potencia(a,b) =',P);
{post: entrada = vacio A salida = a b )
end. {Potencia)

Figura 4.14.

Un programa que calcula abo

La precondicin (a <> O v a = O b <> O) podra haberla comprobado explcitamente el programa Potenc; a, y emitido un mensaje de error
en el caso de ser violada. Sin embargo, esto no es as en el programa de la
Figura 4.14.
En general, debemos elegir entre dos extremos cuando tenemos que decidir
quin debe comprobar las precondiciones:
Estrategia 1. Disear el programa sin comprobar ninguna de las precondiciones; construir el programa conforme a las precondiciones y poscon-

diciones, pero de forma que resuelva un problema ms general (es decir,


de forma que haga algo incluso si alguien introduce entradas fuera del
rango de las precondiciones), en este caso, el usuario no se ofender si el
programa se utiliza para los propsitos especificados por las precondiciones.
Estrategia 2. Disear el programa de forma que compruebe todas aquellas precondiciones que sea posible comprobar, sin provocar una termi-

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

116

nacin anmala del mismo. Adoptar un convenio para devolver esta


informacin al usuario, si las entradas estn en desacuerdo con las precondiciones.
La estrategia 1 podria denominarse programacin pasiva, mientras que la segunda podra denominarse programacin defensiva. En un curso de programacin lVanzado o de desarrollo profesional de software, siempre se prefiere la
estrategia 2 sobre la 1. Sin embargo, en un curso introductorio, donde se estudian por primera vez otros conceptos fundamentales, suele aceptarse temporalmente la estrategia 1. Este punto es importante y trascendente. Lo analizaremos de nuevo en el Captulo 6, cuando discutamos las diferencias entre la
nocin de correccin de un programa, robustez y facilidad de uso.
No importa cul de las dos estrategias decidamos seguir, siempre debemos
introducir las precondiciones y poscondiciones como comentarios al principio
y al final del programa, respectivamente. Es decir, el lector humano no debe
tener nunca dudas de lo que hace el programa, aunque la propia computadora
no est totalmente informada de l.

4.4.2.

Contar palabras de un texto

Los tipos numricos integer y real se utilizan en casi todos los problemas
algortmicos. Sin embargo, un gran nmero de problemas no se resolvera
adecuadamente con slo esos dos tipos. Muchos problemas involucran a cadenas de caracteres ASCII, como datos, y su solucin precisa la utilizacin de un
conjunto de operaciones caractersticas de este tipo de datos. La nocin de
cadena en Pascal puede definirse de la forma siguiente:

Definicin. Una cadena es una secuencia finita de cero o ms caracteres


ASCII. Cuando se escribe una cadena en un programa Pascal, se encierra
entre comillas simples ( , ) para distinguirla de las instrucciones del programa que la rodean.
En la Figura 4.1 hemos visto ejemplos de cadenas. Por ejemplo, todos los
mensajes como:
'Introducir la lista de calificaciones'

son cadenas. Extendiendo el concepto, podemos declarar variables del tipo


cadena (s tri ng) * cuando queramos manipular valores de tipo cadena, en
lugar de valores numricos. Acompaando a la idea de cadena de caracteres,
estn una serie de funciones y procedimientos que sirven para manipularlas y
transformarlas. Esas funciones se resumen en la Figura 4.15.
N. del T.: Algunas implementaciones de Pascal incluyen entre los tipos incorporados el
tipo string. Por ello, cuando nos refiramos al concepto seguiremos hablando de cadenas" de
caracteres y utilizaremos la palabra slring" cuando hablemos del tipo.

Problemas algortmicos y su solucin

Figura 4.15.

117

Resumen de las operaciones sobre cadenas


y tipos involucrados*.

En el manual de laboratorio se realiza una discusin completa de estas


operaciones. Aqu slo daremos unos pocos ejemplos que sirvan de ayuda para
comprender cmo se utilizan las cadenas de caracteres en la resolucin de
algunos problemas algortmicos de manipulacin de textos.
Para declarar una variable cadena, por ejemplo s, basta con escribir la
declaracin siguiente:
va .. s: st .. ing;

Ahora podemos asignar valores a la variable utilizando la asignacin o los


procedimientos Read o ReadLn, de la misma forma en que lo hacamos con
los enteros o los reales. Por tanto, podemos escribir instrucciones como:
5:= 'Hello World!'; o Read(s);

Para conseguir el efecto que se muestra en el centro de la Figura 4.16.


La Figura 4.16 muestra el efecto de la utilizacn de varias de las operaciones de las cadenas, tales como Lenght, Pos, Copy, Insert, Delete y
Wri te. Obsrvese que sus nombres son similares a los de las funciones que
manipulaban listas (vase Fig. 4.7). Ms detalles pueden encontrarse en el
manual de laboratorio.
La longitud de una cadena (valor de la funcin Lengh t) es, simplemente,
el nmero de caracteres de que se compone, incluidos los blancos, signos de
puntuacin y otros caracteres especiales del conjunto ASCII.
N. del T.: En las Figuras 4.15 y 4.16 na se han traducido los nombres de las funciones.
pues son los mismos que suelen tener esas funciones en las implementaciones de Pascal. que
incluyen el tipo string.

118

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

Input

12

'Hello World!'
va .. s: St,;ng;

(
s := 'Hello World! ';
'Hello World!'

1Output 1

lnsert(', Ciao', s, 12)

"

'Hello World, Ciao!'

Figura 4.16.

Utilizacin de algunas operaciones de cadenas de caracteres.

La funcin Pos realiza una bsqueda en la cadena, de izquierda a derecha,


tratando de encontrar la primera ocurrencia de otra cadena. As, si escribimos
Pos (s, I W' ) preguntamos por el ndice o posicin de la primera ocurrencia
empezando por la izquierda, de la cadena 'W'. Si la cadena no estuviera dentro
de s, la {uncin devolver el valor O.
La funcin Copy selecciona una subcadena de la cadena argumento, definida por el valor de la posicin inicial y la longitud. As, Copy( s, 1,1) selecciona la subcadena de s que comienza en la posicin 1 y que tiene una longitud 1. Como se trata de una funcin, Copy devuelve un resultado de tipo
string,

aunque no altera para nada la cadena original s. La nica forma en que

s podra quedar modificada, sera mediante una subsiguiente asignacin a s,


del resultado de la funcin Copy, como ocurre en la instruccin siguiente:
s := Copy(', adis' ,12);

Finalmente, la funcin Insert crea una cadena ms larga mediante la


insercin o incrustracin, de una cadena dentro de otra, a partir de una determinada posicin. As, Inserte I , adi s ,s, 12), literalmente indica que se
debe crear un valor nuevo de tipo string para la variable s incrustrando el
valor " adis' en la cadena I Hello world! " que es el antiguo valor de s.
Para ilustrar estas ideas, considrese el problema de construir un programa
que tenga como entrada una cadena s, y que cuente el nmero de palabras de
la entrada.
Por simplicidad, supongamos que una palabra es una secuencia de caracteres distintos del blanco, tengan o no significado dentro de la lengua castel1ana
comn. Los signos de puntuacin, tales como puntos y comas, y as sucesiva-

Problem as algortm icos y su soluci n

119

mente, se consideran elementos de la palabr a a la que se aaden. Por


ello, cada
una de las cadenas siguientes son palabras:
esos
conoce r.
IMundo !

Podemo$ escribir las precondiciones y poscondiciones que describen


el problema, como sIgue:
{pre: entrad a ~ 'c[1J c[2J .,. c[nJ' /\ n >= O 1-. cada c[iJ
es
un carct er ASCII}
{post: entrad a ~ vacia /\ sal ida = nmero de palabr as de
la entrad a}

Un progra ma que resuelve este problema, utilizando la mayoria de


las funciones de la Figura 4.16, se muestra en la Figura 4.17.
progra m Contad orPala bras;
(El program a cuenta el nmero de palabr as de una linea
de texto, y
muestr a el cmput o resul tanteo Se entien de por palabr
a cualqu ier
secuen cia de caract eres distin tos del blanco , que est
preced ido por
el comien zo del texto o un blanco , y que termin a con el
final del texto
o un blanco )
var s: string ;
i, npalab ras: intege r;
begin
{pre: entrad a = 'c[1J c[2J ... c[nJ' 1-. n >= O 1-. cada c[iJ
es
un carct er ASCII}
{Paso 1. Obtene mos el texto de entrad a}
writln (' introd uci runa linea de texto seguid a de <RET>
'}
Read(s );
Writel n;
Insert (" ,s,Len ght<s) + 1);
(s = 'c[1J c[2J '" c[nJ c[n + 1J' 1-. c[n + 1J = " /\ n >~
O)
{Paso 2. Contam os las palabr as del texto}
npalab ras := O;
i := 1;
while i <+ Lengh( s) - 1 do
{inv: npala bras~ palab rasco ntada spara s[1... i-1JI.1<=i <=n+ 1)
begin
i f (Copy( s, i, 1) <>' ') and (Copy( s, i + 1,1) =' ') then
npalab ras :~ npalab ras + 1;
i:=i+ 1;
end;
(npala bras = palabr as contad as en s[1 ... n + 1J)
(Paso 3. Se muestr a el resulta do de la cuenta )
writel n('el nmero de palabr as es', npalab ras)
{post: entrad a = vacia 1-. sal ida = nmero de palabr as de
la entrad a}
end. (Conta dorPal abras)
Figura 4.17.

Progra ma que cuenta el nmer o de palabra s


de una cadena de texto.

120

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

En el programa anterior, la variable npa Lab r a s indica el nmero de palabras


en el texto de entrada, mientras que n simboliza su longitud.
El corazn del programa es el bucle whi Le, donde se realiza una comprobacin sobre el final del texto de s. Es decir, el final del texto ser slo cuando
el carcter i -simo sea un blanco, y el i + 1-simo tambin. Este convenio se
verifica para la palabra ms a la derecha de s; es decir, la instruccin:
1

Insert<' " s, Length<s) + 1);

Introduce un carcter adicional a la derecha de s. Los casos en los que el valor


de entrada de s termine con un carcter distinto del blanco, son eliminados
previamente a la entrada del bucle que cuenta.
Consideremos la cadena de entrada:
'Whose woods these are 1 thi nk 1 know .

Tras completarse el paso 1 del programa ContadorPa Labras, la variable s


queda con el valor:
5=

'Whose woods these are 1 think 1 know. '

Obsrvese que el blanco adicional se ha insertado dentro de la palabra I know I


de s. Ahora, el bucle de bsqueda del paso 2 comienza con la variable ndice
i = 1:
s

I Whose

woods these are 1 thi nk 1 know.1

Utilizamos la expresin Copy(s, i, 1) para seleccionar el ;-simo carcter de s y Copy(s, i + 1, 1) para seleccionar el i + 1-simo. As, la
expresin combinada:
<CoPY<s, i,

1)

<>' ') and <copy<s, i +

1,1)

=' ')

que busca si dentro de s el i -simo carcter es distinto de blanco, a la vez que


el i + 1-simo s lo es. Obsrvese que esta condicin es exactamente verdadera
cuando se alcanza el final de una palabra, como en el caso en que i = 5:
s

IWhose

woods these are 1 think 1 know.1

Puesto que el contador npaLabras se incrementa slo al final de cada palabra, registra apropiadamente el nmero de palabras de s en el devenir de i
desde la primera posicin del texto hasta el siguiente carcter al final del texto s. Esta posicin se establece utilizando la expresin Lenght (s) - 1.

Problemas algortmicos y su solucin

121

As, el nvarante del bucle se preserva. A la salida del bucle, el invariante se


converte en una expresn sobre el valor final de npa labras, necesara para
que se satisfaga la poscondicn. Nngn otro valor nos satisfara!
Fnalmente, obsrvese la similitud entre las operaciones de las cadenas y las
correspondientes de las listas, viendo las Figuras 4.15 y 4.17, respectivamente.
Por ejemplo, la funcin de cadenas Lenght devuelve el nmero de caracteres
de Uljla cadena, mientras que la LenghtL; sta devuelve el nmero de elementos de una lista. Esta similitud es de gran ayuda cuando queremos recordar el
nombre de las funciones, cuando queremos resolver otros problemas algortmicos que utilizan listas y cadenas de caracteres.

4.4.3.

Representacin del problema de Las Tres-en-Raya

Aunque los tipos numricos y cadena de caracteres son la base de gran cantidad de problemas algortmicos, no sirven para caracterizar aquellos problemas
que implican la representacin de informacin grfica. Este tipo de problemas
incluye la visualizacin y anlisis de imgenes de rayos X, fotografas desde
satlites, tableros de ajedrez y otros tipos de tableros de juego, y otros tipos de
grficos utilizados habitualmente en gestin comercial y en el clculo cientfico.
Para ilustrar este tipo de problemas, consideremos el conocido juego de las
tres-en-raya. Supongamos que se nos pide que construyamos un algoritmo que
muestre los movimientos individuales del juego de las tres en raya, reflejando
cada movimiento (X o O) en un entramado rectangular de la pantalla de la
computadora.
Para poder resolver este tipo de problemas necesitamos un nuevo tipo de
datos y el correspondiente conjunto de operaciones asociadas, que permitan a
un programa dibujar y realizar transformaciones sobre un array* rectangular,
denominado ent ramado de celdas individuales. Cada celda puede rellenarse
de una de las cuatro formas siguientes: No (sin rellenar); S (rellena en gris); X o
O. En la Figura 4.18 se muestra un entramado de 3 x 3 celdas, las cuales
tienen valores particulares en la que las filas y columnas del entramado se han
numerado de la forma convencional. La celda de la fila 1, columna 2 es una X;
la celda en la fila 2, columna 1 es S; la celda de la fila 3, columna 3 es O; y las
seis celdas restantes son No.
El nmero de filas y columnas, as como el tamao de cada celda, se
establece en el momento en que el programa lo crea. El tamao de la celda se
mide en pixels, que son unidades grficas de la pantalla de la computadora y
que no son divisibles en unidades ms pequeas. Cada celda del entramado de
la Figura 4.18 es de 20 pixels de ancha y otros 20 de larga. El anclaje de un
entramado es la posicin en la pantalla de su esquina superior izquierda,
cuando se visualiza el entramado. La localizacin viene dada por un par de
N. del T.: Aparece aqui por primera vez la palabra inglesa ARRAY. Como ocurriera con
string, esta palabra se ha traducido de muchas formas, en mi opinin todas ellas insatisfactorias.
Por ello prefiero, tanto en este punto como en ocurrencias posteriores, respetar el trmino ingls.

122

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Anclaje

3
} Tamao de la celda

20 pixels

~~--i

o
Figura 4.18.

Un entramado de 3 x 3 celdas y las situaciones de las mismas.

coordenadas xy, teniendo la esquina superior izquierda dc la pantalla las coordenadas (O, O).
La Figura 4.19 muestra las distintas operaciones que pueden utilizarse para
crcar entramados de varios tamaos y para modificar cl estado de sus celdas.
Si declaramos una-variable dc tipo Grid*, podemos utilizar esas opcraciones
para realizar transformaciones sobre la variable.

CellOn ~ole~
CellOff
CellX
Ce llO

TurnCellOn
TurnCellOff
TurnCellX
TurnCellO

Figura 4.19.

Resumen de las operaciones ms importantes.

N. del T.: Seguiremos aqu el msmo convenio entre tipo y objeto que utilizamos entre
cadena y slring.

Problem as algortm icos y su soluci n

123

Sin embargo, al contra rio de las listas y cadenas, necesitamos comen


zar los
progra mas que utilizan estas facilidades grficas con la instruccin
StartG rids;

y finalizar el progra ma con la instruccin


StopG rids;

La primer a de ellas borra la pantal la y crea dos ventanas, una ventan


a grfica a
la izquierda y una de texto a la derecha. Todos los entram ados que
se creen en
el progra ma aparec ern en la ventan a grfica, mientras que los textos,
entrad as
y salidas lo harn en la ventan a de texto. Los detalles sobre
esas y otras
operaciones grficas se explican extensivamente en el manual de labora
torio.
Al contra rio que las variables de tipo Lista o string, las variables
del tipo
Gr ; d se deben crear y dibujarse en la ventan a grfica antes de asigna
r valores
a las celdas. Por ejemplo, si queremos crear el entram ado d para que
tenga 3
filas y columnas, con celdas de 20 pixels y anclad o en la posicin (10,
10) de la
ventan a grfica, escribiremos:
MakeG rid(d, 3,10, 10,20 );

Esta instruccin crea el entram ado d con la forma y tamao idntic


os al
entram ado de la Figura 4.18, pero teniendo todas sus celdas en
blanco. El
resultado se muestra en la Figura 4.20.
Si queremos cambia r de aspecto alguna celda de d, utilizaremos las
operaciones TurnC eLLOn , TurnC ellX o TurnC eL LO. Por ejemplo,
TurnC ellX(d , 1, 2)

coloca una X en la celda de la fila 1, column a 2. El resultado de


esta accin
aparec er inmedi atamen te en la ventan a grfica. Si queremos extend
er lo ante-

(O, O)

(10,

Ventana grfica Ventana de texto

ro;
(200,2~

Figura 4.20.

Aspect o de la pantall a para salida grfica .

124

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

rior de forma que todas las celdas de la columna 2 contengan X, podemos


escribir el bucle siguiente:
for i := 1 to GridSize(d) do
TurnCeLLX(d, i, 2);

Donde se ha utilizado la variable integer i para recorrer todas las filas del
entrainado d, y se ha utilizado la funcin GridSize para obtener el nmero
total de filas y columnas del entramado d.
Finalmente, el grupo de operaciones CeLLOnCd, i, j), CeLLOffCd,
i, j), Ce LLX Cd, i, j) y Ce LLO Cd, i, j) pueden utilizarse para conocer el estado de la celda de la fila i, columna j del entramado d. Por ejemplo,
si nuestro entramado d tuviera el aspecto del de la Figura 4.18, la funcin
CeLLOnCd, 1, 3) devolvera el valor faLse mentras que la operacn
Ce LLX Cd, 1, 2) devolvera el valor t rue.
Con estas operaciones presentes podemos resolver el problema propuesto
al princpio de la seccin. El programa de la Figura 4.21 controla el juego de
Las Tres-en-Raya, solicitando una alternancia de movmientos a dos jugadores, y redibuja la situacin del juego en la parte grfica de la pantalla.
program TresEnRaya;
uses Grids;
const ancLajex = 20; {coordenadas x e y}
ancLajey = 20; {deL tabLero en La pantaLLa}
var tabLero: Grid;
movimiento: integer; {movimiento que se debe mostrar}
i, j: integer;
{fila y columna del movimiento}
begin
{pre: una serie de movimientos de las Tres en Raya}
{Paso 1. Inicializamos eL tabLero y eL juego}
StartGrids;
MakeGrid(tablero, 3, ancLajex, anclajey, 40)
movimiento :~ 1;
{Paso 2. Alternancia de movimientos entre x e y}
repeat
writeLn(' introduci r fila y columna del siguiente movimiento');
writeLn('(O O significa eL finaL deL juego): ');
read(i); read(j);
i f i > j then
begin
i f movi mi ento mod 2 ~ 1 then
TurnCeLLX(tabLero, i, j) {Los movimientos impares son de X}
else
TurnCe LLO( tabLero, i, j) {Los movimi entos pares son de O}
end;
movimiento := movimiento + 1;
unti l i = O;

Problemas algortmicos V su solucin

125

{post: entrada ~ vaca /\


sa l da = una representaci 6n gr f i ca de estos movi mi entos sobre
un tablero de las Tres-en-Raya}
end. {TresEnRaya}
Figura 4.21.

Programa que controla Las Tres-en-Raya.

En el programa, dos jugadores alternan sus movimientos. Cada movimiento viene dado por un nmero de fila ;, y uno en columna j, donde los
jugadores desean colocar una X o un O. La primera persona que juega es X. El
control del juego y la determinacin del ganador se encuentra totalmente en
manos de los jugadores. Cuando un jugador introduce O O (dos ceros), el
programa terminar el juego. Un ejemplo de una secuencia de movimientos y
de los tableros resultantes se muestra en la Figura 4.22.
La variable mov; mi ento juega un papel trascendental en la simulacin.
Almacena el nmero de jugada que est a punto de realizarse, en cada repeticin del bucle del paso 2. Movimientos de nmeros impares (siempre que
mov; mi ento mod 2 = 1) el programa coloca una X en la posicin (;, j)
del tablero. Un nmero impar de movimiento coloca un O en la posicin del
tablero.

Introducir fi la y columna del siguiente movimiento


(O O significa el final del juego):
12
Introducir fi la y columna del siguiente movimiento
(O O significa el final del juego):
1 3
Introducir fila y columna del siguiente movimiento
(O O significa el final del juego):
3 2
Figura 4.22.

Serie de tres movimientos de Las Tres-en-Raya.

Aunque el programa anterior no sea una implementacin excesivamente


satisfactoria del juego de las tres-en-raya, sirve para ilustrar alguna de las
operaciones grficas bsicas que acompaan al tipo Gr; d, Y su utilizacin
como ayuda en la visualizacin de la salida de cierto tipo de problemas algoritmicos.
Existen varias razones por las que este programa no representa una simulacin totalmente satisfactoria del juego de las tres-en-raya. En primer lugar,
obsrvese que el programa permite a un jugador borrar el movimiento del
otro, sin ms que especificar la misma casilla. Segundo, el programa no analiza
si un jugador accidentalmente introduce un nmero de fila o de columna
errneo, tal como 4 7. Tercero, el programa no tiene ningn conocimiento de
la situacin del juego. Es decir, no puede reconocer un movimiento tras el que

126

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

gane X o gane Y, o queden empatados (lo que es bastante habitual en este


juego). Cuarto, el programa no est preparado para ser uno de los dos jugadores, realizando movimientos inteligentes en respuesta a los que realice una
persona jugando con la pieza opuesta.
La primera y segunda de las carencias son fciles de solucionar. Sin embargo, la tercera y la cuarta requieren la introduccin de fragmentos de algoritmos
ms sofisticados, que corresponderan al rea de la informtica conocida como
inteligencia artificial. Es decir, cdigo que permitiera a la computadora simular
la inteligencia humana, aunque fuera de forma muy limitada.
Hemos investigado un pequeo nmero de algoritmos, y las herramientas
del lenguaje Pascal que sirven para su realizacin en una computadora. Hemos
utilizado varios tipos de datos, tales como el integer, real, string, lista y grids; y
varios tipos de instrucciones que incluyen la asignacin, la seleccin condicional, los bucles y la E/S. Tras estudiar estas herramientas y ejemplos, y tras
haber trabajado con el manual de laboratorio, el lector habr conseguido
desarrollar una cierta facilidad en el diseo y escritura de programas pequeos
en Pascal. Con los Ejemplos 4.11 a 4.27 conseguir algo ms de prctica.
Recuerde que el aprendizaje del diseo de programas, como el aprender a tocar
un instrumento, requiere no slo estudio terico, sino mucha prctica. Cuando
ejecute sus programas en una computadora, sea paciente e intntelo de nuevo;
recuerde que pocos programas funcionan bien la primera vez. Conseguir
mayores xitos si lo tiene en cuenta!

Ejercicios
4.11.

Escribir un programa en Pascal que escriba S1, si la variable K es un


entero positivo impar (como 1, 3, 5, ...) Y NO en caso contrario.

4.12.

Escribir un programa que asigne a m el valor absoluto de n, sin utilizar


la funcin de Pascal que da el valor absoluto.

4.13.

Escribir un programa Pascal que escriba la secuencia de n nmeros, en


la que cada trmino se obtiene de doblar el valor del anterior, siendo n
la entrada. (Es decir, cada nmero en la secuencia es el doble del anterior.)

4.14.

Repetir el Ejercicio 4.13, pero cambiando el programa para que escriba


los n nmeros en orden inverso. (Es decir, cada nmero es la mitad del
anterior.)

4.15.

Escribir un programa que lea 25 enteros y que cuente cuntos de ellos


son negativos.

4.16.

Escribir un programa que lea 100 enteros y que determine y escriba


cuntos de ellos son divisibles por 5.

Problem as algortm icos V su soluci n

4.17.

127

Escribir un fragmento de progra ma que realice lo siguiente:


Poner x a x + A si x es negativo;
Poner x a x + A + B si x es cero; o
Poner x a x + A + B + e si x es positivo.

,Cuidado!
4.18. Qu hacen los fragmentos de progra ma siguientes? Es decir,
si introduje ra y ejecutase en la compu tadora este progra ma, cul seria
la
salida?
a)

var
k, j, m: intege r;
n: real;
begin
k := 4;
j := 8;
m := 9;
n := m div j + k * 1.0 - m div j;
writel n ('n= " n)
end;

b)

var
m, j: intege r;
begin
m :~ 4;
j := 1;
whi le (j < m) do
begin
j:=j+ 2;
m := m+ 1
end;
writel n ('m= ',m, Ij= " j)
end;

e)

var
k, j: intege r;
begin
for k : = 1 to 10 do
begin
j := 10 - k;
i f (j <= 4) then
j := j - 1
end;
writel n ('j = " j, 'k= "
end;

ti)

var
n, m: intege r;
begin
n := O;
m := 1;

k)

128

Computacin l. Lgica, resolucin de problemas, algoritmos y programas


whi le (m <= 101) do
begin
n := n + 1;
m := m + 5
end;
writeln ('n= " n)
end;

e)

f)

var
j, k, m: integer;
begin
k := O;
for j : = 1 to 3 do
for m := 1 to 4 do
k :=k+1;
writeln ('k= " k)
end;
uses

Lista;
var
k: Lista;
j: integer;
begin
k[1] :~ 1;
for j := 2 to 4 do
k[j] :~k[j-1]+j;
wri teL i sta (k)
end;

g)

uses

Lista;
var
m: Lista;
j: integer;
begin
j := 1;
while (j <= 2) do
begin
m[j + 2] :~ j;
m[3-j] :=j;
j :~j+1;
end
WriteL i sta (m)
end;

4.19.

Trazar la ejecucin del programa Po t ene i a para las entradas 5 y - 4,


escribiendo los valores de las variables a, b, P e i, antes de que se
ejecute cada iteracin.

4.20.

Escribir un programa que cambie a cero todos los valores de una lista
que ocupen una posicin impar y que sean impares. Es decir, si llamamos L a la lista, el programa debe examinar L[1 J, y si contiene un

Problemas algoritmicos y su solucin

129

valor impar, poner L [1] a O. Lo mismo debe hacer para L [3] ,


L[S],
, mientras que deben descartarse los elementos L[2],
L[4],
.
4.21.

Escribir un programa que escriba los 11 primeros nmeros de Fibonacci. Los nmeros de Fibonacci son 1, 1, 2, 3, 5, 8, 13, ...

4.22.

Escribir un programa que calcule el factorial de un entero n (denotado


por ni). Recurdese que la definicin de n! es:
O!
n!

1
n x (n -

1)1

4.23.

Disear y escribir un programa en Pascal que lea un determinado texto,


y calcule y escriba el nmero de ocurrencias de la subcadena I and' .

4.24.

Trazar la ejecucin del programa ContadorPa Labras de la Figura


4.17, mostrando los valores de las variables i y npa Labras durante su
ejecucin, con el texto de entrada siguiente:
'Able was 1 ere 1 saw Elba .

4.25.

Comprobar que el invariante del bucle del programa ContadorPa Labras es vlido para la entrada del Ejercicio 4.24, analizndolo para
cada valor de i que provoca un cambio en npa Labras. Por ejemplo,
la primera interpretacin del bucle ocurrir cuando i = 6, Yse leera de
la forma siguiente:
{npalabras = 1 para 'Able' /\ 1 <= 6

4.26.

<~

26)

Escribir un programa en Pascal que lea un texto y lo invierta y escriba.


Es decir, si la entrada del programa es:
'mayo 1992'

la salida del programa debe ser:


'2991 oyam'

4.27.

Refinar el programa de las Tres-en-Raya, de forma que prevea el


que un jugador coloque una X o una O en una casilla ya ocupada.
Cuando esto ocurra, el programa debe avisar al jugador, de forma corts, que debe hacer un movimiento alternativo y registrar un nuevo
movimiento.

130

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

4.28.

Escribir un programa que calcule el coste total del franqueo postal de


una serie de envos. Debe contener un bucle que lea la cantidad y precio
de cada envo y lo acumule al total. Despus de que se haya introducido
el ltimo elemento, el programa mostrar el coste total de la operacin
y el nmero total de envos realizados. El coste total deber reflejar un
5 por 100 de impuestos. Asegrese de incluir en el propio programa las
pre y. poscondiciones.

4.5.

RESUMEN

En este captulo se han introducido las ideas de problema algoritmico y de su


solucin correspondiente. Se ha hecho especial hincapi en la importancia de
especificar con precisin el problema en forma de precondicin y poscondicin. Tambin se ha introducido la idea de invariante de un bucle y su utilizacin en un programa. Se comenz con algunos sencillos problemas matemticos, para seguir con problemas de procesamiento de textos y manipulacin de
grficos, proponiendo y discutiendo su solucin en Pascal.
Este captulo es una base importante para los Captulos 5 y 6. En el Captulo 5 se introduce la metodologa MAPS, que es una metodologa sistemtica
para la resolucin de problemas algortmicos, y que puede utilizarse en la
resolucin de una amplia gama de problemas dentro de esas tres reas. La
metodologa MAPS incide especialmente en la utilizacin de las ideas fundamentales introducidas en el Captulo 4 -precondiciones, poscondiciones, bucles, invariantes, listas, cadenas, entramados y sus operaciones asociadas. En el
Captulo 6 se introduce una tcnica que permite asegurar la correccin de los
programas en Pascal que construimos al solucionar problemas algortmicos.

CAPTULO

RESOLUCiN
DE PROBLEMAS ALGORTMICOS

El conocimiento puede ser de dos tipos. Conocemos algo por nosotros mismos,
o conocemos dnde podemos encontrar informacin sobre ello.
SAMUEL JOHNSON, 1775

En el Captulo 4 nos concentramos en la construccin de programas relativamente cortos, que resolvan problemas bastante sencillos. Enfatizamos en la
necesidad de realizar especificaciones claras, estableciendo los principales pasos del algoritmo y trasladando esos pasos a instrucciones Pascal ejecutables.
En este proceso nos familiarizamos con los tipos de datos bsicos (i nteger,
reaL y booLean) y con otros algo ms complejos (Listas, strings y
gri ds), junto con sus operaciones asociadas. Tambin desarrollamos algunos
programas sencillos para ilustrar el gran nmero de problemas con una solucin algoritmica. Estos programas son una muestra de la denominada programacin en pequea escala.
Sin embargo, para poder resolver problemas algoritmicos ms extensos y
complejos, necesitamos proveernos de un conjunto de tcnicas de resolucin de
problemas ms robustas. Es decir, la programacin en gran escala requiere
la utilizacin de una metodologa unificada y robusta que pueda utilizarse de
manera fiable en una variada rea de aplicaciones. Una Metodologa de Resolucin de Problemas Algortmicos *, MAPS, se desarrollar e ilustrar en este
capitulo.

5.1.

NECESITAMOS UNA METODOLOGA

Los problemas de la programacn en gran escala difieren de los de la pequea


escala en tres aspectos. Primero, un programa que representa una solucin a

* N. del T.: En el texto se respelar el acrnimo ingls MAPS (Methodology for Algorithmic Problem Solvng), debido a que el autor pretende enfatizar la semejanza de la metodologa con
el trmino Map o Mapping, que podra traducirse por correspondencia y que se utiliza ampliamente en la terminologia informtica. Debido a que al traducirlo es imposible capturar este
concepto, respetamos el acrnimo original.

132

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

problemas grandes ocupa generalmente ms de una pgina de cdigo en Pascal. Segundo, los programas largos tienen, adems de su longitud, alguna otra
caracterstica que los hace ms complejos. Tercero, las soluciones para problemas ms complicados se expresa mejor si se utiliza una sistemtica que si se
escribe directamente el cdigo que se nos ocurre. Es necesario que los primeros
pasos describan el problema y que el algoritmo resultante sea fruto de un
diseo, fruto de una sistemtica paso a paso. De hecho, en muchos casos, la
solucin a un problema grande es el resultado del trabajo de un grupo de
trabajo numeroso ms que de una sola persona.
Las soluciones a los problemas grandes comparten con las de los pequeos
tres caracteristicas: legibilidad, eficiencia y correccin. Legibilidad significa que
cualquiera que conozca el lenguaje Pascal y el dominio al que pertenece el
problema, es capaz de entender el problema y el programa sin ms que leer
cuidadosamente el programa y los comentarios que le acompaan, independientemente de lo largo que sea el programa o lo complejo que sea el problema. La eficiencia es deseable porque los recursos informticos son relativamente costosos, y las aplicaciones deben intentar minimizarlos. La
correccin significa que todas las ejecuciones del programa deben conducir
a resultados vlidos para cualquier entrada permitida por las especificaciones
del programa.
Estas tres caractersticas de los problemas complejos tienden a dotarlos de
una identidad dual. En un extremo, la legibilidad de los programas permite
que stos constituyan una explicacin de la solucin a problemas algortmicos
para un lector interesado. En el otro extremo, la eficiencia y fiabilidad de los
programas les permite ser un mecanismo a travs del cual la computadora
puede ser utilizada para resolver problemas. En la construccin de programas
utilizando la metodologa MAPS, siempre tendremos en mente esta doble
identidad de los programas. i El proceso de codificacin de un programa en
Pascal es slo una parte de la complicada tarea de resolver un problema
algoritmico!

5.1.1.

Generalidades sobre el mtodo MAPS

En qu consiste esta metodologa de resolucin de problemas algortmicos?


La metodologa MAPS puede resumrse como la sucesn de las etapas siguientes:
Etapa 1: El dilogo. Comprender el problema. Leer el enunciado del
problema. Hacer preguntas sobre las caractersticas de la entrada y la
salida y sus limitaciones, hasta tener completamente claro el problema.
Etapa 2: Las especificaciones. Construir las especificaciones a partir de
nuestro conocimiento del enunciado del problema. Escribir pre y poscondiciones que sean completas y consistentes. Es decir, asegurarse de que
las precondiciones cubren todas (y slo esas) las posibles entradas, que
las poscondiciones definen la salida para todas las posibles entradas, y

Resolu cin de problem as algortm cos

133

que tanto las precondiciones como las poscondiciones son interna y


mutuamente consistentes.
Etapa 3: La divisin. Subdividir, de forma sistemtica, el proces
o en una

coleccin de pasos diferentes. Repetir este proceso para cada paso hasta
que la subdivisin no tenga sentido. Identificar las relaciones de contro
l
entre los distintos pasos. Es decir, qu paso debe preceder a cul?,
qu
pasos son parte de otro ms complejo?, qu pasos deben repetirse
dentro de un bucle?, y asi sucesivamente. Docum entar cada paso escribi
endo
una breve descripcin de sus objetivos. Asignar un nombr e apropi ado
a
cada nueva variable que incorporemos en cada paso, en funcin de
cul
es su cometido.

Etapa 4: Definicin de abstracciones. Determ inar cules de los


pasos que

hemos utilizado habian sido, a su vez, usados en otra situacin, recolec


tar
las rutinas que se utilizaron en esa situacin y adapta rlas para reutiliz
arlas en la situacin presente. En muchos casos, esta tarea implica la construccin de una rutina nueva a partir de otras dos, o incluso constru
ir
una nueva para una utilizacin ms especializada.

Etapa 5: Codificacin. Trasla dar a Pascal cada paso individual


de nuestra

solucin, identificando rutinas nuevas y reutilizando aquellas que resulten apropi adas para realizar cada paso individual. Conec tar cada
paso
utilizando la estructura de control apropi ada (bucles, invocaciones a
procedimientos, secuencias de instrucciones, selecciones condicionales,
etc.)
de una forma compatible con lo diseado en el paso 3. Respetar como
comentarios toda la informacin generada durant e el paso 3 para
cada
paso individual y las variables correspondientes.

Etapa 6: Prueba y verificacin. Probar o validar de forma sistem


tica el

progra ma Pascal, hacindolo ejecutarse para un conjun to de valores


de
entradas, que permita explorar todo el rango de valores permitido por
las
precondiciones. Para cada ejecucin, compr obar que las salidas satisfac
en
las poscondiciones. De forma alternativa, verificar cuando sea apropi
ado
alguno o todos los pasos del programa, utilizando tcnicas de demos
tracin formal.

Etapa 7: Presentacin. Aadir un comentario al comienzo del


progra ma
para clarificar su propsito, escribir el nombre de los autore s y la fecha,
e

identificar la utilizacin de rutinas que fueron desarrolladas con


otro
propsito (e incluso por otros programadores). Prepar ar un listado
del
programa, junto con un listado de algunas ejecuciones de prueba.

En este captulo se ilustran cada una de las etapas de la metodologa


MAPS.
Definamos previamente la idea de rutina, tal y como se considera en
la resolucin de problemas algortmicos, junto con el mtodo de Pascal para
empaquetarlas, de forma que stas sean reutilizables convenientemente.

134

5.2.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

CONSTRUCCiN DE SOFTWARE PARA


SU REUTILIZACiN: LA RUTINA

En el Captulo 4, y en el manual de laboratorio, se han presentado algunos


procedimientos y programas cortos que realizan tareas especificas. Por ejemplo, un programa calcula el valor promedio de una lista de enteros, otro
calcula una potencia entera de un nmero, un tercero localiza el mximo de
una lista, y otros cuentan las palabras de un texto o visualizan una secuencia
de jugadas del juego de Las Tres-en-Raya.
Tuvimos que realizar un gran esfuerzo, porque desarrollamos esos problemas partiendo de la nada. Es evidente que, para problemas ms complejos,
tendremos que hacer un esfuerzo mayor si los resolvemos tambin partiendo
de la nada. Existe alguna alternativa? Seguramente no queremos seguir resolviendo problemas si no podemos beneficiarnos de la experiencia adquirida al
resolver otros problemas.
Si encontramos un problema que para solucionarlo podemos utilizar partes
de otros previamente resueltos, el no hacerlo y desarrollar una solucin desde
el principio seria un gran despilfarro de tiempo. Nuestro tiempo y energa
estarn utilizados de una forma ms eficaz si somos capaces de reutilizar soluciones ya conocidas cuando sean necesarias. La correccin de la solucin nucva ser ms fcil de establecer, puesto que la de uno de sus componentes ya lo
fue anteriormente.
Un algoritmo o parte de l, que parcialmente puede ser rcutilizado, recibe
el nombre de rutina. Una buena parte del tiempo empleado en resolver problemas se utiliza en identificar rutinas y en reutilizarlas en forma apropiada.
Definicin. Una rutina es una parte de un algoritmo que puede reutilizarse
en otros contextos de resolucin de problemas algortmicos.
Algunas rutinas son tan comunes que estn incluidas en el lenguaje de programacin Pascal para utilizarlas en los programas. Estas rutinas incluyen los
operadores numricos (+, -, *, /, di v y mod); las expresiones aritmticas,
las estructuras de control (i f, wh i Le y f o r); los operadores de entrada,
salida y asignacin (read, wri te y :=) y los operadores de cadenas (copy,
pos y Length). Se pucden aadir al lenguaje otras rutinas para manipular
listas (ReadL i s t a, Wri teL i s tal y entramados (Ma keGr i d, Gr i dS i ze y
TurnCeLLOn).
Existe una gran variedad de rutinas para diferentes dominios de la resolucin de problemas. Varios de ellos se introducirn en este capitulo.

5.2.1.

Encapsulamiento de rutinas para la reutilizacin.


Abstraccin procedimental

Cmo podemos almacenar o encapsular rutinas de forma que puedan ser


reutilizadas con posterioridad en la resolucin de otros problemas? Un mtodo

Resolu cin de problem as algoritm icos

135

fundamental para construir rutinas en Pascal es la denominada abstrac


cin
procedimental. Siempre que hacemos que una parte de un progra ma
ya existente se convierta en una rutina, primero encontramos (y definimos) su genera
lizacin ms apropiada, y despus la convertimos, de forma sistemtica,
en un
procedimiento o funcin de Pascal. Estdiese en el manual de labora
torio los
detalles de cmo utilizar y crear los procedimientos y funciones de Pascal
antes
de continuar con el captulo.
La 'abstraccin procedimental es un proceso que consta de tres etapas:
1. Nomb rar la abstraccin. Asignar un nombre que identifique claram
ente el algoritmo que representar el algoritmo resultante.
2. Redefinir las precondiciones y poscondiciones del problema, de
forma
que su solucin pueda implementarse como un procedimiento o funcin
.
a) Parametrizar la entrada y la salida. Reemplazar (partes de) entrada = y salida = en las especificaciones por el o los parmetros
apropiados, que jueguen el mismo papel que las especificaciones a
las que sustituyen en el problema original.
b) Generalizar los tipos. Examinar las entradas, las salidas y los
parmetros para determinar si es posible extenderlos o generalizarlos,
de forma que la solucin construida pueda servir para un conjunto
ms amplio de problemas.
3. Implementar la abstraccin como un procedimiento o funcin
, bien
partiendo de cero, bien convirtiendo un progra ma existente para
el
problema original.
Los pasos 1 y 2 reciben el nombre de especificacin de la rutina. Su resulta
do se
muestra en la forma encapsulada siguiente:
Nombr e(parm etros>
(pre: expres in con las precon dicion es de la rutina )
(post: expres in con las poscon dicion es de la rutina )

El paso 3 unifica las especificaciones con el propio procedimiento o funcin


de
Pascal, convirtindola en una unidad de progra ma reutilizable.
Para ilustrar lo anterior, considrese el problema de la CM que se resolvi

en el Captulo 4. Sus especificaciones se definieron, originalmente, en


la Figura 4.3 de la forma siguiente:
(pre: entrad a = (Notas" Notas " "."' Notas > 1\ n > O 1\
n
'Vi E {1, .""' n} :Notas E (O, "."' 4})
(post: entrad a =0/\ salida = Sum i E (1, .. , n):No tasJn}

Supongamos ahora que este progra ma es lo suficientemente import ante


para
asignarle la categora de rutina. Quiz porque estemos trabajando en
un problema ms complejo que tiene por objetivo calcular qu mes del ao
tiene el
mayor promedio de lluvia cada por da. La entrad a de este problema
podra
ser una serie de listas, una por cada uno de los 12 meses del ao, que
contengan la cantidad de lluvia cada cada da. Cuand o nos ponemos a resolve
r el

136

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

problema observamos que parte de nuestro viejo programa CM puede utilizarse para encontrar la solucin. Nuestra solucin de promediado acaba de
alcanzar el rango de rutina!
Pero, antes de reutilizar nuestro programa debemos convertirlo en un procedimiento o funcin equivalente; es decir, debemos aplicar los tres pasos de la
abstraccin procedimental a su definicin. Para el paso 1, la eleccin del nombre Promed; al,; sta es una buena eleccin, pues indica con claridad lo que
har la rutina. Para el paso 2a, parametrizacin de la entrada y la salida,
incluimos el parmetro l, en lugar de la entrada, para simbolizar la lista de
valores de la que deseamos calcular el promedio, y el parmetro resuL tado
en lugar de la salida, indicando as que el promedio resultante se devolver al
contexto del programa en que se utilice, en lugar de visualizarse por la pantalla. Para el paso 3, generalizacin del tipo, cambiamos nuestra rutina de promediado para que trabaje sobre nmeros en un intervalo apropiado, y no slo
en el rango de O a 4 original.
Por tanto, los pasos 1 y 2 de la abstraccin procedimental del problema
CM conducen a las especificaciones revisadas siguientes:
PromedioLista(L):
{pre: L= (e" e" """' en) 1\ n:i'a 1\ Vi E {1, """' n}:: e, es un nmero}
{post: n > a 1\ resultado = Sum i E {1, .""' n}: eJn
v n ~ a 1\ resul tado = a}

En el paso 3, en la abstraccin procedimental, convertimos el programa CM


original en un procedimiento o funcin de Pascal que satisfaga las especificaciones revisadas. La eleccin entre un procedimiento y una funcin depender
de la forma en que se vaya a utilizar la rutina, asi como de ciertas restricciones
que plantea el lenguaje Pascal en la codificacin de procedimientos y funciones. Por ejemplo, debe devolver la rutina un nico resultado o debe devolver
varios? Si slo tiene que devolver un resultado se suele preferir una funcin; si
los resultados a devolver son varios, entonces se utilizar un procedimiento. En
otras palabras, invocaremos a la abstraccin resultante como si de una instruccin separada se tratase (lo que sugiere la codificacin de un procedimiento) o, por el contrario, la invocaremos como una funcin utilizndola dentro
de una expresin aritmtica ms larga (lo que requiere la codificacin de una
funcin)?
Consideremos la abstraccin Promed; al; s ta que estamos construyendo. Si la vamos a invocar como una instruccin, debemos codificarla como un
procedimiento Pascal, con todos los parmetros de salida de la cabecera identificados con el prefijo varo (Para ms detalles sobre la sintaxis de los procedimientos de Pascal, y sobre los parmetros var, consltese el manual de laboratorio.) Por el contrario, si se va a invocar como una funcin Promed; ol; sta,
debe implementarse como una funcin de Pascal. En este caso, todos los parmetros deben incluirse en la cabecera de la definicin, excepto el resultado, que
se identifica con el propio nombre de la funcin. En las Figuras 5.1 y 5.2 se
muestran ambas alternativas.

Resolucin de problemas algortmicos

137

p..ocedu.. e P.. omediolista (l: Lista; va .. resultado: reaL);


uses
Listas;
va ..
i, n: integer;
sum: rea l;
begin
(pre: l= (e" e"
e o ) A n;'O A Vi E (1, ... , ni:: e i es un nme .. o}
n :~ lengh\;l i sta(L);
if n > O then
begin
Sum :~ O;
i := 1;
while i <= n do
begin
Sum := Sum + l[i];
i := i + 1
end;
..esul tado := Sum/n;
end {if}
else
..esul tado := O
(post: n>OA resultado~Sum; E {1, "0' nI: eJn
v n = O /\ resu l tado = O}
end; (P .. omediolista)
o

Figura 5.1.

Abstraccin de Promedi ol; sta como un procedimiento.

En ambas abstracciones hay que destacar algunas caracteristicas. Si confrontamos ambas con el programa original (vase Figura 4.6), a partir del cual
han sido construidas, podemos ver que todas las instrucciones de entrada y
salida han sido sustituidas por referencias a los parmetros l y resultado. Es
decir, la abstraccin procedimental delega la tarea de hacer la entrada y la
salida al programa que utiliza la abstraccin resultante. De hecho, el programa
debe suministrar los argumentos apropiados para que sirvan de entrada al
procedimiento o funcin, y debe interpretar de forma apropiada la informacin
de salida que ste le proporcione.
Podemos observar tambin que el fundamento lgico del programa original se ha preservado. En el procedimiento Promediolista (Figura 5.1), el
resultado se asocia con un parmetro varo En el caso de la funcin Promedi ol i st a (Figura 5.2), el resultado se asocia con el propio nombre de la
funcin. Otras variables declaradas en el programa original (Sum, i y n)
adquieren la categoria de variables locales dentro de la abstraccin, puesto que
ahora slo tienen un inters local exclusivo para el clculo del promedio.
En la Figura 5.2 se puede observar que el parmetro de salida resultado se
ha reemplazado por la asignacin del promedio resultante al propio nombre
de la funcin. Esta es la forma en que Pascal permite especificar el resultado
que debe devolver una funcin. En otras palabras, el procedimiento Promediolista de la Figura 5.1 y la funcin Promediolista de la Figura 5.2
son idnticos.

138

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

function PromedioLista (L: Lista): real;


uses
Listas;
var
i, n: integer;
sum: rea l;
begin
{pre: L ~ (e" e" .. , en) /\ n '" O /\ Vi E {1, . , n}: /\ n '" 0/\
Vi E {1, ... , ni:: e, es un nmero}
n := LenghtLista(L);
i f n > O then
begin
Sum := O;
i := 1;
while i <= n do
begin
Sum:=Sum+L[i];
i := i + 1
end;
PromedioLista := Sum/n;
end {if}
else
PromedioLista := O
{post: n > O /\ resultado = SUII i E {1, .. , ni: eJn
v n = O /\ resultado = O}
end; {PromediLista}

Figura 5.2. Abstraccin de Promedi ol i sta como una funcin.


Comprobacin de la integridad de una abstraccin. Antes de utilizar una rutina
que ha sido abstrada en forma de procedimiento o funcin, debemos asegurarnos de que hemos realizado correctamente el proceso de abstraccin. Como
mnimo, esto requiere reestructurar el programa original del que hemos partido para realizar la abstraccin, y comprobar que el programa sigue satisfaciendo las especificaciones originales con la abstraccin realizada. Para el programa
de la calificacin media, esto puede realizarse como se muestra en la Figura 5.3.
prograll calculacM;
{esto es un programa que ca lcu la la CM de una seri e de una o ms
calificaciones numricas, cada una de ellas en el rango O.. 4,
que se introducirn por el teclado}
uses
Listas;
var
Notas: Listas;
CM: real;
function PromedioLista (L: Lista): real;
{Esta funcin calcula la media de los valores de una lista)
uses
Listas;
var
i, n: integer;
sum: real;

Resolucin de problemas algortmicos

139

begin
{pre: L = (e" e" ... , en) /\ n :;" O /\ Vi E {1, , n}: /\ n :;" O /\
Vi E {1, ... , n}:: e; es un nmero}
n := LenghtL ista(L};
i1 n > O then
begin
Sum := O;
i := 1;
ilhile i <= n do
begin
Sum :~ Sum + L[i];
i := i + 1
end;
PromedioLista := Sum/n;
end {;t}
else
PromedioLista := O
{post: n > O /\ resu l tado = Su. i E {1, ... , n}: e;!n
v n = O /\ resu l tado = O}
end; {PromediLista}
begin
pre: entrada = (Notas" Notas" .. , Notas n) /\ n > O /\
Vi E {1, ... , n} :Notas; E {O, ... , 4}}
{Paso 1 . Obtenemos la lista de ca l ;ti cac iones}
WriteLn ('Introducir la lista de calificaciones:');
ReadLista (Notas);
{Nota: Los pasos del 2 al 4 del programa CM original se realizan ahora
invocando a la funcin PromedioLista}
CM :~ PromedioLista (Notas);
{Paso 5. Se muestra CM}
WriteLn ('La CM de esas cal ificaciones es =', CM : 5 : 2)
end{if}
{post: entrada ~01\ salida ~ Sum i E {1, .. "' n}: Notas;!n}
end. {CalculaCM}

Figura 5.3.

Revisin del programa CM utilizando la funcin Promedi ol i sta.

La revisin de la Figura 5.3 podr perfectamente haber utilizado el procedimiento en lugar de la funcin. En este caso, la instruccin
CM := PromedioLista (Notas);

debe sustituirse por la invocacin equivalente al procedimiento


PromedioLista (Notas, CM)

Lo importante aqui no es si se utiliza un procedimiento o una funcin, sino la


estructura del programa resultante. En concreto, obsrvese que el programa ha
reducido su responsabilidad a la de obtener la lista de entrada Notas, y a
visualizar el promedio de notas (pasos 1 y 5, respectivamente, del diseo origi-

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

140

nal de la Seccin 4.1). A su vez, el programa ha transferido la responsabilidad


de calcular el promedio a la rutina Promedi oL i s ta recin creada. Para
poder hacer esto, el programa necesita suministrar a la rutina una lista de
nmeros (en este caso la variable Notas). El programa tiene que asignar el
resultado devuelto por Promedi oLi sta a la variable CM, de forma que su
responsabilidad frente a la salida est cubierta. El proceso completo puede
observarse "en la Figura 4.5, donde se ha supuesto que la lista de entrada es
<32 1 3).

5.2.2.

Identificacin de rutinas nuevas y definicin


de sus abstracciones

Una destreza importante que se debe adquirir al resolver problemas algoritmicos es la de reconocer rutinas cuando aparecen en contextos de resolucin de
problemas diferentes. Una vez identificada la rutina, puede ser abstrada con
facilidad en forma de procedimiento o funcin -lo mportante es reconocer la
rutina, no su abstraccin!
En el Captulo 4 introdujimos algoritmos para resolver el problema CM,
para calcular ab , y para contar el nmero de palabras de una cadena de texto.
Trate de identificar las rutinas que incluyen. Algunas de ellas saltan a la vista.
Por ejemplo, consideremos el clculo de la suma de los elementos de una lista
de enteros arbitraria, que est incluido dentro del programa CaLcuLaCM (y
tambin dentro de Promedi oL i sta). Calcular la suma de los elementos de
una lista es seguramente una rutina, puesto que puede ser til en una gran
variedad de problemas, tales como el de calcular el balance de un libro de
contabilidad o totalizar la recaudacin obtenida en un evento deportivo.
Cmo sera el aspecto de una rutina que realice este proceso? Podramos

Entrada
(32 1 3)

Figura 5.4.

Salida
2.25

Utilizacin de la funcin Pramedi al i sta


en el programa CaLcuLaCM.

Resolu cin de problem as algortm icos

141

llamarla Suma Lis t a y escribir sus especificaciones para una lista arbitra
ria L,
como las siguientes:
Suma Lis t a CLl :
{pre: L= Ce" e" ... , e,) /\ n;:,O /\ Vi E {1, ... , n):: e,
es un nmero )
{post: result = Sum i E {1, ... , n): ed
Figur 5.5.

Especi ficaci n de la abstrac cin que suma los elemen tos


de una lista.

El progra ma Pot ene i a es otro candid ato a convertirse en rutina,


y podemos convertirlo de progra ma a funcin con facilidad. De las especif
icaciones
de la Seccin 4.4.1, la abstraccin procedimental de Poten e i a puede
definirse
como en la Figura 5.6:
Potenc iaCa, b):
{Pre: a y b son entero s /\ Ca '1' O v a = 0/\ b '1' O) /\ Minlnt
'" a b
{Post: resulta do = a b )
Figura 5.6.

'"

Maxlnt )

Especi ficaci n de la abstrac cin de la funcin Poten cia.

Considrese tambin la posibilidad de encaps ular como una rutina


el programa Cuen taPal abras . De las especificaciones del Capitu lo 4, la
abstraccin
de la Figura 5.7 resulta evidente:
Cuenta Palabr asCs):
{pre: s ~ 'c[1] c[2] .. c[n]' /\ n >= O /\ cada c[i] es un carct
er ASCII)
{post: resulta do = nmero de palabr as en s)
Figura 5.7.

Especi ficacio nes de la abstrac cin Cuent aPaLa bras.

Existen otros muchos fragmentos de progra mas que tienen gran utilida
d y
que pueden ser convertidos con facilidad en rutinas. Otras cuatro
abstracciones simples pueden ser de utilidad en una gran variedad de problemas
algoritmicos que procesan listas. Los dos primeros (Figura 5.8) encuen tran
el lugar
que ocupa (ndice) el mayor y el menor elemento de los m primeros
elementos
de una lista L.
MaxLis taCL, m):
{pre: L = Ce" e" ... , e,) n;:' O /\ cada e es un nmero )
{pos t: n > O /\ Vi E {1, ... , n): e j ;:, e, /\ i resu l tado = j v
n = O /\
resul tado = O)
MinLis taCL, m):
{pre: L = (e 1 , el' .. _, en) n ~ O 1\ cada e, es un nmero }
{pos t: n > O /\ Vi E {1, .. , n}: e j ' " e /\ resu l t ado = j v
n
i
resul tado = O)
Figura 5.8.

O /\

Especi ficaci n para las abstrac ciones de MaxL i sta y Mi nL


i sta.

142

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

La tercera abstraccin intercambia o permuta dos elementos de una lista L La


cuarta busca en una lista L y determina si un determinado valor x est o no
dentro de la lista, devolviendo su posicin (si es Hue existe). Las especificaciones para ambos se pueden ver en la Figura 5.9:
Intercambiar<L, j, k):
{pre: L = fe" e 2 , _, e j , _, e k , _, en) 1\ 1
{post: L = (e" e" ""., e., "."' e j , , en)}

j, k

PosLista(x, Ll:
{pre: L = (e" e" ... , en) 1\ X es un nmero 1\ n ~ O}
{post: 3i E {1, .""' n}: X = e, 1\ resultado = i v Vi
X"" e, 1\ resul tado = O}

Figura 5.9.

n}

{1, ... , n}:

Especificacin de las abstracciones Intercambi a r y PostL i sta.

Estas abstracciones precisan algunos comentarios. Consideremos la lista de


la Figura 5.10. Aqu podemos ver que L contiene 12 nmeros, representando
cada uno un valor pluviomtrico mensual expresado en litros por m 2 Por
ejemplo, L[1] representa 2,5 litros por m 2 en el mes de enero. L[2] representa 4,4 litros por m 2 en el mes de febrero, y as sucesivamente.
As, la rutina Mi n Lis t a ( L, 7) busca el valor pluviomtrico mnmo de
los siete primeros meses del ao, y devuelve el ndce 3. La rutina MaxL i sta (L, 12) busca el valor mxmo de los doce de la lista L, devolviendo el
valor 9. PostLista(O.O, L) busca la existencia en L del valor especfico
0.0, y devuelve el valor 10, que indica su posicin en la lista. Finalmente, la
rutina Intercambiar(L, 2, 9) intercambia o permuta los elementos segundo y noveno de la lista L, como se indica mediante los valores subrayados
en la parte baja de la Figura 5.10.
9

~Ci"''''
~'".b;'''''

~10
12l

( PosLista(O.O,Ll

2, 9l

L = (2.5 6.00.3 5.7 2.1 1.3 1.0 5.9 4.40.0 0.3 2.2)

Figura 5.10.

Ilustracin de las rutinas MaxL i sta, Mi nL i sta,


Intercambiar y PosLista.

Resolucin de problemas algortmicos

143

Veamos la implementacin de una de esas rutinas, Ma xLi s t a ( L, m)


como un ejercicio adicional de la abstraccin procedimental. La Figura 5.11
contiene algunas observaciones adicionales sobre una lista arbitraria:

al ir incrementando los valores del indice k entre 1 y m. Para una lista de


longitud 1, su valor mximo slo puede ser el valor e,. Para k = 2, MaxL ista (L, 2) es el ndice del mayor de los valores e, o e 2 , Y si k = 3, MaxL i sta(L, 3) es el ndice del mayor entre e 3 Y eM.xList.(L, 2) --es decir, el ndice
del mayor de e 3 Y (el mayor de e, Y e 2 ). Este razonamiento puede continuarse
hasta llegar finalmente a que Ma xLi s t a (L, m) es el ndice del mayor de e m,
e m -"
, e" Y por tanto de toda la lista e m, e m _"
, e 2 Y e,. (Los
lectores observadores se habrn percatado de que esta expresin es un ejemplo
de relacin de recurrencia, como las que se introdujeron en el Captulo 2.)
MaxLista(L, k) =1
~k

= MaxL i sta(L, k -

1)

si

k = 1

si

k> 1 y e k >
k> 1 y e k ::::;:

si

eMaxListaCL, k -

1)

eJIIIUListaCL, k - 1)

Figura 5.11. Valores de MaxLi sta (L, k) al variar el ndice k.


Las consideraciones anteriores sugieren la estrategia de implementacin
iterativa siguiente, para calcular el ndice j del valor mximo de la sublista de
L que contiene m elementos:
j := 1;
k := 2 to m do

fOI"

{invVi E {1, """' k-1}: e[j] >=e[i]


i f L[k] > L[j] then

/\2<=k<~m+1}

j := k;

Max :=j;

Obsrvese que el invariante refleja nuestro razonamiento informal sobre cmo


debe calcularse el valor de MaxLista(L, i) para cada valor de i en el
intervalo i, ... , m. Cuando finaliza el bucle, el ndice j sealar el elemento
mayor de la sublista L[1, ... , m]. Esto se deduce de la interpretacin del
valor final del invariante
{inv: Vi

{1, ... , m}: e[j] >= e[i]}

puesto que k = m + 1 al terminar.


Hemos terminado prcticamente la codificacin del cuerpo de la funcin
MaxL i sta, si exceptuamos la instruccin condicional, o guarda, que debe

144

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

aadirse para comprobar que se satisfacen las precondiciones. Esto se muestra


en la Figura 5.12, donde se presenta una abstraccin procedimental completa
de la funcin MaxL i s tao Obsrvese que la implementacin elegida devuelve el
valor O siempre que no se satisface la precondicin. Para esta funcin, este
valor es el equivalente a resultado <<indefinido.

5.2.3.

Funciones recursivas: Una alternativa a la repeticin

En el Captulo 2 vimos que las funciones matemticas pueden definirse utilizando una relacin de recurrencia, o recursivamente. Esta idea ha sido trasladada al lenguaje Pascal, de forma que ste nos permite definir funciones recursivas. El hecho de que la funcin MaxL i sta fuera originalmente concebida de
forma recursiva no es, por tanto, ninguna traba para su traslacin a una
funcin de Pascal. Es decir, podemos escribir una funcin Pascal que incluya la
relacin de recurrencia original. Este tipo de funciones de Pascal reciben el
nombre de funciones recursivas. En la Figura 5.13 puede verse una implementacin recursiva de la funcin MaxLista. La funcin refleja directamente la
relacin de recurrencia de la Figura 5.11.
Podemos ver que la relacin de recurrencia original se ha codificado en
Pascal utilizando una serie de instrucciones i f anidadas. El efecto de la iteracin se consigue en la tercera instruccin i f de la serie, donde los aspectos
recursivos de la funcin han sido subrayados. La funcin Ma xLi s ta se invoca
a s misma de forma recurrente, con los argumentos L y m - 1. As se activan
una serie completa de invocaciones a Ma xLi s t a, para poder determinar:
function MaxLista(L: Lista; m: integer): integer;
var j, k: integer;
begin
{pre: L = (e" ez, .. _, e lll , _ , en) 1\ n ~ O /\ cada e i es un nmero}
i f (O < n) and (m
LengthLista(L then
begin
j :~ 1;
for k := 2 to m do
{i nv: \li E {1, ... , k - 1 }: e [j] >= e [i] 1\ 2 <= k <~ m + 1 }
i f L[k] > L[j] then
j := k;
end
else
j := O;
MaxLi sta := j;
{pos t: n > O 1\ \1 i E {1, ... , n}: e j ? e, 1\ resu l tado = j v
n = O 1\ resul tado = O}
end;

<=

Figura 5.12.

Abstraccin procedimental de MaxLi sta (L,

m).

Resolucin de problemas algortmicos

145

el ndice del elemento mayor de la sublista de L.


function MaxLista(L: Lista; m: integer): integer;
begin
{pre: L ~ (e" e" ... , e., ""., e o ) /\ n;, O /\ cada e, es un nmero}
i f (O<n) and (m<=LengthLista(L then
i f m = 1 then
MaxLi sta := 1
else if L[m] > L[MaxLista(L, m - 1 )] then
MaxL i sta := m
else
MaxL i sta :~ MaxLi sta (L, m - 1)
else
MaxL i sta :~ O;
{post: n > O /\ Vi E {1, .""' n}: e j ;, e, /\ resul tado = j v
n = O /\ resul tado = O)
end;

Figura 5.13.

Implementacin recursiva de la funcin MaxLista(L,

m).

Para ilustrar la semntica (el signfcado) de las funciones recursivas, supongamos que se nvoca a la funcn con Ma xLi S t a ( L, 4), siendo L = (2 5
4 3 8 6). La secuencia de eventos que se producen en el proceso de clculo
para calcular el resultado (que es el ndce 2), se muestra en la Tabla 5.1.
Tabla 5.1.

Invocacin
de
MaxL i sta m
1

2
3
4

4
3
2
1

Sublista
de L

Clculo de MaxLista(L, 4)

Invocacin
activa

(2 5 4 3)
2
(2 5 4)
3
(2 5)
4
(2)
ninguno

Comparacin
em > MaxLista(L, m- 1)

Devuelve
el resultado

3>MaxLista(L,3)
4> MaxL ista(L, 2)
5>MaxLista(L,1)
ninguno

2
2
2
1

Cada nvocacin sucesiva a MaxL i sta, comenzando por la primera, realiza una comparacin entre e m y el valor mxmo de la sublista que contiene un
elemento menos, hasta que se realza una invocacin para la que la longitud de
la lista es 1. (En este caso, esto ocurre en la cuarta invocacin). En ese momento se devuelve el resultado, que confirma que e, es siempre el mximo valor de
la lista de longitud 1. El resultado se pasa a la invocacin 3, por lo que
MaxL i s ta compara los valores de e, Yez. Puesto que e z es mayor, la invocacin 3 devuelve el ndce 2 a la llamada 2. La invocacin 2 compara los valores
de e z Ye 3 , determinando que e z es mayor, por lo que pasa a la nvocacin 1 el
ndce 2. Aqu se realiza finalmente la comparacin e 4 > ez' devolvindose el
valor 2 al programa que nvoc la funcin.
Una forma grfica de ver el proceso de recursn es dibujando una estruc-

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

146

tura arborescente que muestre los caminos de invocacin, argumentos pasados


y resultados devueltos. En la Figura 5.14 se muestra una estructura de este
tipo.

5.2.4.

Aprendizaje de rutinas ya existentes: Bibliotecas


y caractersticas de los lenguajes

Muchas de las rutinas que nos sirven de ayuda en el proceso de resolucin de


problemas, o estn incluidas en el lenguaje de programacin, o han sido desarrolladas por otros programadores y son suministradas en forma de bibliotecas
y rutinas utilizables. Por ejemplo, hemos utilizado los tipos elementales; n t eger y rea L de Pascal, junto con sus operaciones aritmticas y booleanas,
como +, -, <, =, y as sucesivamente. Tambin hemos utilizado el tipo
string y algunas de las rutinas de utilidad (Length, Pos, Insert, DeLete, y as sucesivamente). Otras caractersticas del lenguaje, como Read o
ReadLn, tienen una utilidad ms general, puesto que pueden aplicarse a un
gran variedad de tipos como el integer, reaL y string.
Tambin hemos aprendido cosas sobre los tipos Li s ta y Gr id, contenidos en bibliotecas, junto con algunas de sus operaciones (ReadLista,
L[i], MakeGrid, y as sucesivamente). Si no se nos hubieran suministrado
esas rutinas, tendramos que haberlas construido de la nada, antes de ponernos
a resolver muchos problemas algortmicos interesantes.

Figura 5.14.

Estructura de la invocacin recursiva de MaxLista(L, 4>El nmero de la invocacin est dentro de un crculo; las flechas
descendentes simbolizan argumentos y las ascendentes resultados.

Resolucin de problemas algortmicos

147

En el manual de laboratorio puede encontrarse una discusin ms detallada sobre esos tipos y otros de Pascal igualmente tiles, junto con sus rutinas
relacionadas. Las definiciones siguientes de algunas de estas rutinas estn escritas en el ya familiar estilo de definicin procedimental que se introdujo en la
Seccin 5.2.1.
ReadLista(L):
{pre: entrada = (e" e u .. , en) cualquier secuencia A n;. D}
{post: ent rada = cua lqui er secuenci a A L = (e" e u ... , en)}
L[ i] :

{pre: L= (e" e u .. , en) A 1 ~i ~n}


{post: e, es un nmero A resul tado = e i v e, no es un nmero
resul tado = D}
Writeln(s" Su . , sn):
{pre: entrada = cualquier secuencia A Vi E {1, . , ni:
o una cadena}
{post: salida = cualquier secuencia s" s" .... , sn}

Si

es un nmero

poses, t):
{pre: t = 't 1 , t z , __ , t n l A S = '$" 52' _, Srw l / \ n ~ O}
{post: 5= t,t<+, ... t'...._1 (1 ~ i ~ i + m - 1 ~ n) es la ocurrencia ms a la
izquierda de s en t A resultado = i v s no est en t A resultado = D}

Aqu, la nocin cua lqui er secuenci a asociada a las rutinas ReadLis t a y Wr i te l n significan, literalmente, cualquier secuencia de valores de
entrada o salida existentes en el momento en que las rutinas son ejecutadas. En
el caso de ReadL i sta, la notacin entrada = (e" el' . , en) cua lquier secuencia, significa que existe una lista al principio de la secuencia
de entrada, seguida de una secuencia arbitraria de otros posibles valores (que
puede no incluir ninguno). La utilizacin de cualquier secuencia en la especificacin de wr i te l n, significa que coloca la salida a la cola de todas las salidas
que se hayan generado antes de la ejecucin de la instruccin wr i te l n.

5.2.5.

Seleccin y reutilizacin de tipos de datos y estructuras

Sabemos ya que es importante para su reutilizacin la identificacin y encapsulamiento de rutinas. Tambin debemos ejercitarnos en ser cuidadosos cuando seleccionamos tipos de datos y estructuras para diferentes problemas con
los que estamos familiarizados.
Hemos trabajado ya con los tipos numricos bsicos (rea le i nteger), el
tipo string y con los tipos Lista y Array, que se utilizan para definir
estructuras lineales simples. Sabemos, por la experiencia adquirida, que las
operaciones para el tipo rea l tambin pueden aplicarse, aunque con algunas
restricciones, al i nteger. Sabemos tambin que rutinas con nombre similares
para los tipos Lis ta y s tri ng, tienen significados similares. Por ejemplo, la
rutina Pos (s, t), que devuelve la posicin donde aparece por primera vez la

148

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

cadena t en la s, es totalmente anloga PosL;sta(x, U, que localiza el


elemento x en L. De forma similar, la referencia L[; J, que selecciona el elemento ; -simo de la lista L, se utiliza en la misma forma para seleccionar el
;-simo elemento de un array.
Sin embargo, existen sutiles diferencias entre esas alternativas. Por ejemplo,
no podemos aplicar operadores aritmticos a valores tipo s t r; ng, aunque
stos teng;m connotaciones numricas; instrucciones tales como:
5:=5+'1.5'

(donde s simboliza una variable cadena) son incorrectas. Del mismo modo,
podemos leer y almacenar en una lista una coleccin completa de nmeros
reales, tanto de un archivo externo como desde el teclado, utilizando la operacin ReadL; sta. Sin embargo, no podemos hacer lo mismo si queremos leer
y almacenar una coleccin de cadenas. Podemos utilizar un a r rayen lugar de
una lista para almacenar una coleccin de cadenas, pero carecemos de la
flexibilidad para leerlas y almacenarlas si no inventamos y construimos las
rutinas que tengan la capacidad funcional de ReadL; sta. Estas diferencias
estn resumidas en la Figura 5.15, que muestra, en una especie de diagrama de
Venn, el solapamiento funcional que existe entre a r rays y Listas. El mensaje bsico de estos prrafos es que ninguna estructura de datos ofrece todas
las ventajas de otra sin acarrear algunas desventajas. Esta situacin es tpica en
la informtica; los profesionales de la informtica se refieren a ella como el
compromiso y las consecuencias de tomar una decisin.

Figura 5.15.

Diferencias entre l; stas, arrays, cadenas y nmeros.

Resolucin de problemas algoritmicos

149

El tipo cadena es el ms bsico de los tipos construidos con valores elementales, puesto que puede contener cualquier nmero de caracteres separados por
blancos u otros caracteres ASCII no imprimibles (caracteres de control, tales
como saltos de lnea y tabuladores). As, cualquier carcter es una cadena, pero
no cualquier cadena es un carcter; por ejemplo, el carcter a es una cadena,
pero la cadena Pepe no es un carcter. Continuando con esta lnea de razonamiento, c'lda dgito numrico es un carcter, pero un carcter individual no
tiene por qu ser un dgito numrico. Por ejemplo, el dgito 3 es un carcter,
pero el carcter x no es dgito numrico. Igualmente, si colocamos un nmero
entre comillas simples tendremos una cadena, pero no toda cadena es un
nmero. As, I 3 . 5 I es una cadena, pero I 1v n I no es un nmero.

5.2.6.

Arrays de cadenas de caracteres

Nos gustara extender la potencia y utilidad del tipo st r; ng incorporndolo


dentro de la idea de l; sta. Esto nos permitira aplicar todas las rutinas de
l; s ta s, que nos son tan familiares, a listas de cadena s de caracteres en la
misma forma en que lo hicimos en el Captulo 4 con las listas de rea les.
Puesto que el tipo string es ms general que el de integer o real, es
esperable que el tipo lista de s tri ng sea de utilidad en una gama de problemas algortmicos ms amplia que el de las listas de rea les.
Desgraciadamente, no podemos extender la idea de lis ta de esta forma.
Tenemos que implementar las listas de cadenas utilizando arrays. El tipo
de elementos de un array puede ser establecido arbitrariamente por el programador. Supongamos que escribimos una frase como una lista de palabras,
separadas entre s por saltos de lnea. La frase:
Ivn camin 3 ki Lmetros hasta eL coLegio a una veLocidad de
2,5 ki Lmetros por hora

Podra introducirse por el teclado en la forma siguiente:


Ivn RET
cami n RET
3 RET

ki Lmetros RET
hasta RET
eL RET
coLegio RET
a RET
una RET
veLocidad RET
de RET
2,5 RET

ki Lmetros RET
por RET
hora RET
RET

150

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Es posible declarar el tipo de array siguiente, y una variable del mismo que
permite almacenar cada palabra del texto:
type palabra = string[16];
ListaStrings = a ....ay[1 .. 100] of palab ..a;
va .. Frase: ListaSt .. ings;
LongitudFrase: integer;
Apala~ra: palab ..a;

La definicin anterior permite manipular frases de 100 palabras o menos,


conteniendo cada palabra 16 caracteres o menos (lo que es una suposicin
bastante razonable para el lenguaje cotidiano). La terminacin de la frase se
sealiza con dos saltos de lnea sucesivos (RET RET).
Si queremos leer una serie de cadenas en la variable f rase e identificar el
nmero de palabras con la variable Long; tudPa labra, debemos disear el
cdigo que realice esta operacin. Es decir, el cdigo siguiente podra ser la
base de una abstraccin procedimental:
LongitudFrase := o;
ReadLn(APalabra)
whi le APa lab ..a <> ' , do
begin
LongitudFrase := LongitudFrase + 1;
Frase[LongitudFrase] := APalabra;
ReadLn(APalabra)
end

De forma anloga, es posible implementar inserciones, eliminaciones y bsquedas de palabras aisladas utilzando abstracciones procedurales. De esta forma,
podemos manipular listas de palabras de la misma forma que manipulamos
l; s tas de rea l es, posibilidad que es de gran utilidad en gran cantidad de
aplcaciones.

5.2.7. Tipificacin fuerte y coercin


Es complcado cambiar de tipos dentro del lenguaje Pascal, porque el lenguaje
obliga a los programadores a hacer distinciones explcitas entre los valores del
tipo string, char, real e integer, dependiendo de la rutina concreta
(procedimiento o funcin) utilizada y del contexto sintctico en el que se utiliza. Esta caracterstica de los lenguajes de programacin recibe el nombre de
tipificacin fuerte.

Definicin. Un lenguaje de programaclOn es fuertemente-tipificado si el


tipo de cada variable y constante que interviene en cada instruccin individual est restringida explcitamente al tipo de clculo en el que se utiliza.
Los ejemplos de tipificacin fuerte pueden encontrarse en los programas del
Captulo 4:

Resolucin de problemas algortmicos

1.

2.

3.

151

La instruccin i : = i + 1, del programa Po t en c i a de la Figura 4.14,


necesita que i sea una variable numrica --es decir, rea lo i nteger.
Si i hubiera sido declarada como un string, la idea de utilizar su
valor en una operacin aritmtica, como una suma, sera incorrecta,
incluso si su valor pudiera ser interpretable como un nmero (por
ejemplo, la cadena '2.2 ').
La expresin Copy(s, i, 1) <> ", del programa ContarPaLabra s de la Figura 4.17, precisa que s sea una cadena y que i sea un
entero. La propia Copy debe devolver un valor de tipo s t ri ng, puesto que el resultado debe ser comparado (utilizando el operador < con
la cadena ' '.
La instruccin Tu r n Ce LL( t a b Le ro, i, j), del programa de
las Tres-en-Raya de la Figura 4.21, necesita que sus argumentos
sean de los tipos grid, integer e integer, respectivamente.

Supongamos que queremos reinterpretar un valor de un tipo como valor


de otro diferente -por ejemplo, interpretar la cadena '2.5 I como el nmero
real 2,5--. Para hacer esto en un lenguaje fuertemente tipificado como Pascal,
necesitamos utilizar una rutina especifica que convierta el valor de tipo string
en uno de tipo real. Este es el papel de la rutina de Pascal Val (vase Seccin
5.2.6). La utilizacin de una rutina de este tipo recibe el nombre de coercin. La
coercin en la direccin opuesta le permite la funcin s t r. Las rutinas siguientes estn definidas en Turbo Pascal para permitir la coercin entre reales y
cadenas:
valCs, r, cdigo)
{pre: s es una cadena)
{post: r = valor real equivalente a s 1\ cdigo = O si la coercin
se rea liza con x ito
strCr, s);
{pre: r es un nmero real J
{post: s es la cadena equivalente a r)

Pascal realiza la coercin directa entre reales y enteros. Los enteros no


necesitan ser convertidos explcitamente a los reales equivalentes, puesto que se
pueden considerar un subconjunto de ellos. Por ejemplo, el entero 1 se interpreta siempre que sea necesario como el real 1 O. Las rutinas siguientes convierten un nmero real en entero, bien redondendolo al entero ms prximo,
bien truncndolo, respectivamente.
roundCx);
{pre: x es un nmero rea l )
{post: resultado=lx+O.5J}
trunc(x) :
{pre: x es un nmero rea l)
(post: resultado = lxJ}

152

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Por tanto, si queremos tratar el i-simo elemento de una lista L como un entero,
debemos convertirlo explcitamente utilizando una de las rutinas round o
trunco Por ejemplo, la instruccin siguiente asigna la parte entera (ignorando
la parte decimal) del i -simo elemento de L a la variable in t ege r j.
j

:~

truncCL[i]);
,

Por qu son tan necesarias y tiles la tipificacin fuerte y la coercin?


Existen varias razones. Primero, los lenguajes fuertemente tipificados suelen ser
ms efectivos que los dbilmente tipificados como vehculos de enseanza de
los principios de la programacin, por el simple hecho de que sus compiladores
detectan un rango de errores ms amplio, y sugieren la forma de corregirlos
antes de que se produzca la ejecucin del programa. En algunas ocasiones, las
listas incluyen elementos de distintos tipos, por lo que el programa debe identificar tanto los tipos como los valores de cada elemento. La lista siguiente
incluye algunos datos en los que cadenas y reales se alternan en una serie no
ordenada cronolgicamente de valores pluviomtricos de los meses del ao.
Las listas como esta, en que cada valor numrico est precedido inmediatamente por un nombre descriptivo, reciben el nombre de listas con atributos.
L = (Enero 2,5
Septi embre 6,0
Febrero 4,4
Mayo 2,1
Junio 1,3
Novi embre 0,3
Diciembre 2,2
Julio 5,9
Marzo 0,3
Abril 5,7
Agosto 1,0
Octubre 0,0)

Ejercicios

5.1.

Describir qu es lo que hacen los programas siguientes:


a)

function nooz (L: lista) : integer;


val'
i: i nteger;
begin
nooz := O;
for i := 1 to LengthLista(L) do
i f L[i] =0,0 then
nooz := nooz + 1;
end;

Resolucin de problemas algortmicos

b)

153

program fn;
var
k: integer;
function nd (m: integer>: integer;
var
n: integer;
begin
nd := O;
n := m;
while n >= 1 do
begin
n := n div 10;
nd := nd + 1
end
end;
begin
whi le not eof do
begin
readln (k>;
writeln ('ans = " nd(k
end
end.

5.2. Implementar la rutina SumL; s ta, definida en la Figura 5.5, como una
funcin de Pascal. Probar que la funcin puede reutilizarse para conseguir una implementacin alternativa del procedimiento Promed i 0Lis t a, diferente a la de la Figura 5.1.
5.3. Construir una funcin, a la que llamaremos MaxFactor, que calcule
el mximo factor de un entero n, que sea menor que el propio n (por
ejemplo, MaxFactor(100) = 50, MaxFactor(15) = 5, Y Max-

Factor(13) = 1).
5.4.

Supongamos que A, B Y C representan la longitud de los lados de un


tringulo. Construir una funcin que devuelva t rue si A, B YC son los
lados de un tringulo rectngulo.

5.5.

En qu condiciones puede convertirse un procedimiento en una funcin equivalente? En qu condiciones puede realizarse la operacin
inversa? Razonar la respuesta.

5.6.

Convertir el programa factorial del Ejercicio 4.22 en una funcin.

5.7. Implementar como un procedimiento de Pascal la abstraccin ContarPalabraCs) de la Figura 5.7. Comprobar su integridad reutilizndola para resolver el programa original que contaba palabras del
Captulo 4 (vase Figura 4.17).

154

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

5.8.

Ilustrar el comportamiento de la implementacin recursiva de MaxLista(L, m) (Figura 5.8), mostrando la secuencia de invocaciones y
resultados devueltos, cuando L = (6 5 4 3 2 1) Y m = 6. Existe
alguna reduccin en el nmero de invocaciones que son precisas cuando
el mximo valor ocupar el primer lugar de la lista? Razonarlo.

5.9.

Reesdribir la funcin siguiente, pero reemplazando el bucle far por


uno whi Le equivalente; es decir, quc conduzca al mismo resultado.
Escribir pre y poscondiciones que describan el resultado. En qu medida es esta funcin similar a la operacin Mi nL i sta (Figura 5.8)?
type ArrayLista = array[1 .. 255] of real;
function IndiceDelMenor<UnArray: ArrayLista; n: integer):
integer;
(devuelve el indice del menor de los elementos de un array de
longi tud n}
var IndiceDelMenorPorAhora: integer;
begin
Indi ceDelMenorPorAhora := 1;
for i ;= 2 to n do
i f UnArray[i] < UnArray[Indi ceDelMenorPorAhora] then
Indi ceDe lMenorPorAhora :~ i;
Indi ceDe lMenor := Indi ceDe lMenorPorAhora;
end;

5.10.

Escribir una funcin recursiva SumL i sta (L, n) que devuelva la suma
de los n primeros elementos de la lista L.

5.11.

a)

Escribir la funcin recursiva Fib(n) que calcule para el entero n el


n-simo nmero de Fibonacci, que se define de la forma siguiente:
Fib(n)

o
1

Fib(n -

1) + Fib(n

para
para
2) para

n
n

n >

Dibujar la representacin grfica de la cadena de invocaciones


cuando se invoca con F i b (4).
e) Reescribir la funcin, pero sin utilizar recurrencias; es decir, utilizando un bucle en lugar de llamadas recursivas.

b)

5.12.

a)

Describir en castellano qu hace la funcin siguiente.


function MyFun (n: integer): integer;
begin
i f n ~ O then
MyFun := O
else i f n mod 2 = O then

Resolucin de problemas algortmicos


MyFun := n

+ MyFun<n

155

- 1)

else
MyFun

:~

MyFun<n - 1)

end;

b)

Escribir las pre y poscondiciones de la funcin My Fun.

5.13.

Utillzando una linea de razonamiento similar a la utilizada para implementar MaxL i sta (L, m), desarrollar una implementacin de la funcin Mi n Lis t a definida en la Seccin 5.2.2. Si la implementacin contiene un bucle, incluir la descripcin del invariante del bucle.

5.14.

Realizar la abstraccin procedimental de la rutina PosLista(x, U,


definida en la Seccin 5.2.2, y escribir en Pascal una funcin no recursiva de la abstraccin.

5.15.

La rutina PosL i sta (x, U es muy til cuando queremos determinar


si una lista tiene elementos repetidos. Escribir un programa en Pascal
que, para una lista arbitraria de nmcros L, utilice PosL i s ta para
ayudarnos a descubrir y escribir los nmeros que aparezcan ms de una
vez. Por ejemplo, la lista L = (1 2 3 5 4 1 5 1 ) har que el programa
escriba las duplicidades siguientes:
1
5

Describir un problema algortmico de la vida cotidiana en que sea de


utilidad una rutina que localice duplicidades.
5.16.

Escribir una implementacin recursiva de la funcin PosL i sta.

5.17.

Escribir la funcin Primos Re La t i vos que tenga dos enteros n y m


como argumentos, y devuelva el valor booleano t rue, si y slo si m y n
no tienen ningn divisor comn ms que 1. Por ejemplo,
PrimosRelativos<B, 9) = true
PrimosRelativos<B, 10) ~ false

puesto que 8 y 10 tiene un divisor comn que es 2.


5.18.

Escribir una funcin que devuelva el valor t r ue si el primer elemento


de una Lis ta es mayor que el resto de elementos. La funcin se llamar EsMayor y tendr un solo parmetro, que designar a la lista. Escribir un programa de prueba que invoque a la funcin para establecer si
trabaja correctamente.

156

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

5.19.

Disear y escribir en Pascal una funcin que examine los n elementos


de una lista y devuelva t rue si los elementos estn ordenados en orden
decreciente, y fa l se en caso contrario. La funcin se llamar Prueba
y tiene que tener un parmetro para el nombre de la lis ta, y otros
para el nmero de elementos n que deben examinarse. Escribir un programa de prueba que invoque a la funcin para establecer si trabaja
correctamente.

5.3.

RESOLUCIN DE UN PROBLEMA UTILIZANDO


LA METODOLOGA MAPS

Ya estamos en condiciones de utilizar nuestro mtodo de resolucin de problemas (MAPS) y utilizarlo en un caso concreto, desde el principio hasta el final.
Durante todo el proceso enfatizaremos la importacia de identificar y reutilizar
rutinas en una forma creativa. Una de las caractersticas destacables de MAPS
es que no slo sirve como gua en la resolucin de problemas particulares, sino
que en este proceso se van creando rutinas que el programador podr reutilizar en la resolucin de otros problemas ms complejos.

5.3.1.

El dilogo

El problema que vamos a resolver es el de construr un algoritmo que tenga


como entrada una lista de valores pluviomtricos, y escriba los meses cuyos
valores pluviomtricos estn por debajo de la media, el valor pluviomtrico
ms alto y ms bajo de cada mes, y el mes que dio el valor pluviomtrico ms
alto.
Nuestra primera reaccin ante la explicacin anterior es que es muy vaga.
Es decir, se han omitido muchos detalles. Necesitamos mucha ms informacin
antes de pasar a la etapa siguiente en la resolucin del problema. Esto es muy
tpico en la resolucin de problemas; no es buen proceder el admitir especificaciones ambiguas y realizar preguntas que dejen sin clarificar algunos detalles.
Los resolutores de problemas inteligentes preguntan primero sobre las cuestiones que necesiten ser clarificadas, antes de proceder a la bsqueda de una
solucin. Asi, debemos tener un dilogo con la persona que nos presenta el
problema, hasta que consigamos tener un conocimiento preciso del mismo.
Para el problema que nos ocupa, algunas cosas que deberamos preguntar
podran ser las siguientes:
1.

2.

Cmo se nos presentar la entrada? Cronolgicamente por meses?


Por valores pluviomtricos? Consistir la entrada en una o dos listas? Estarn los meses explcitamente representados en la entrada, o se
presentar las lecturas nicamente organizadas en orden cronolgico?
Cul es un valor vlido de pluviometra? Es decir, un valor pluviomtrico puede ser cualquier nmero real no negativo?, existe un valor
mximo para las lecturas?

Resolucin de problemas algortmicos

3.

4.

157

En la salida, deben aparecer los meses con pluviometria inferior al


promedio, en orden cronolgico, en orden de indices pluviomtricos
relativos o, simplemente, en el mismo orden en que aparecieron las
lecturas en la entrada? Es necesario escribir el valor medio del indice
pluviomtrico?
Puede ocurrir que ms de un mes tengan el valor pluviomtrico ms
alto? En ese caso, debe mostrar el algoritmo el nombre de todos esos
rbeses?

Tratando de clarificar lo anterior, suele ser conveniente dar una muestra de la


entrada y de la salida correspondiente del problema; una imagen vale ms que
mil palabras! Los ejemplos sirven para resolver de forma visual muchas de las
preguntas anteriores, e incluso nos proporcionan pistas sobre cmo debemos
resolver el problema. En la Figura 5.16, la entrada se presenta en una lista
sencilla, y el programa debe distinguir entre nombre de meses (entradas de la
lista con ndices impares 1, 3, 5, ...) Yvalores pluviomtricos (entradas de la lista
con ndices pares 2, 4, 6, ...).
ENTRADA

SALIDA

(Enero 2,5
Febrero 4,4
Marzo 0,3
Abril 5,7
Mayo 2,1
Junio 1,3
Julio 5,9
Agosto 1,0
Septiembre 6,0
Octubre 0,0
Novi embre 0,3
Di c i embre 2,2)

Figura 5.16.

ESTADISTICAS PLUVIOMETRICAS
medi a = 2,64
mxima = 6,0
minima = 0,0
Meses por debajo de la media:
Enero
Marzo
Mayo
Junio
Agosto
Octubre
Noviembre
Diciembre
Mes(es) mxima:
Septiembre

Ejemplo de entrada y salida para el problema


de la pluviometra.

Sin embargo, la entrada y salida para este problema pueden presentarse


perfectamente de otras maneras. Dos alternativas razonables se muestran en la
Figura 5.17. En una de las alternativas, la entrada se suministra en dos listas en
lugar de en una; en la otra, la entrada se presenta sin los nombres de los meses.
En este caso, el programa debe generar los nombres de los doce meses y
suponer que los valores de pluviometra estn suministrados en orden cronolgico --es decir, la primera entrada es el valor de enero, la segunda el de
febrero, y as sucesivamente.

158

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

CEnero, Febrero
Marzo, Abri L
Mayo, Junio
JuL i o, Agosto
Septiembre, Octubre
Noviembre, Diciembre)
2.5 ~.4
0.3 5.7

0.3 5.7

2.1 1.3

2.1 1.3

C2.5 4.4

5.9 1.0

5.9 1.0

6.0 0.0

6.0 0.0

0.3 2.2)

0.3 2.2)

a)

b)

Figura 5.17. Dos representaciones alternativas de la entrada para el problema


de la pluviometra. al Dos listas de entrada. b) La lista de los valores pluviomtricos como nica entrada.

5.3.2.

Las especificaciones

Supongamos que la Figura 5.17b muestra la organizacin de la entrada que


espera el programa, y la Figura 5.16 la de la salida. Podemos entonces construir de una forma ms precisa las especificaciones del programa, es decir, las
precondiciones y postcondiciones. Estas especificaciones servirn para clarificar los detalles de la solucin al problema, que desarrollaremos en pasos siguientes. La precondicin para el problema de la pluviometra puede expresarse de la forma siguente:
{pre: entrada = Ce" e" .. , e ,2 ) /\ Vi E {1, ... ,12) e i es eL vaLor
pLuviomtrico deL i-simo mes deL ao)

As, si se suministrase al programa la entrada particular de la Figura 5.l7b, se


satisfara esta precondicin; el programa asignara a e z el valor 4.4 Its/m 2 (el
valor pluviomtrco de febrero), y as sucesivamente. Sin embargo, el lector se
percatar de que, si la entrada se suministrase en una de las otras formas
alternativas, no se satisfaria la precondicin.
La poscondicin para este problema puede definirse de la forma siguiente:
{post: entrada =0/\ saLida = ESTADIsnCAS PLUVIOMETRICAS
media = Sum i E {1,
,12): e i /12
m x i ma ~ Max i E {1,
, 12): e i
minima = Min i E {1,
,12): e i
Meses por debajo de La media:
{m;: e; < Su.i E {1, ... ,12): e,l12)
MesCes) ma><ima:
[mi: e j = Max iE (1, ... ,12): e i /\ 1o;;jo;;12))

Resolucin de problemas algoritmicos

159

En este caso, la especificacin de entrada describe la forma general y la esencia


de la misma, y la especificacin de salida la relacin que deben guardar entrada y salida. Por ejemplo, podemos ver que son necesarias dos listas -una lista
(mi' ml' ..., miz) con los doce meses del ao y una lista con los doce valores
pluviomtricos. A la vista de esto, debe existir algn tipo de paralelismo entre
ambas listas. (Obsrvese que, aunque la lista de meses no se suministra como
entrada, deb~ ser generada de alguna forma por el programa en forma de un
array de doce posiciones). Es decir, el hecho de que m2 = Febrero y que e 2 =
4,4 significa que el valor pluviomtrico de febrero es 4,4 lts/m 2 .
Por tanto, la solucin al problema puede describirse en trminos de aquellos meses cuyo valor pluviomtrico guarda alguna relacin con el mximo,
mnimo y valor pluviomtrico medio. En este caso, la notacin de la lgica es
especialmente til, pues permite expresar las especificaciones de forma breve y
precisa. Una descripcin en castellano de las mismas entradas y salidas podria
no estar escrita con la misma precisin y brevedad.

5.3.3.

La particin

Muchos objetivos o pasos de este problema son evidentes, si nos ponemos


a pensar sobre el problema y sus especificaciones. Inicialmente, nuestra solucin debe generar la lista con los nombres de los meses y obtener de la
entrada la lista de valores pluviomtricos. Tambin nuestra solucin necesita
calcular el valor medio, el mximo y mnimo de los valores pluviomtricos.
Necesitar escribir Jos nombres de aquellos meses cuyo valor pluviomtrico
est por debajo de la media, as como el(los) mes(es) que tengan el mximo
de valor pluviomtrico.
La solucin a este problema puede ser dividida, inicialmente, en las cuatro
rutinas y cinco elementos de datos que se muestran en la Figura 5.18. Hemos
hecho dos cosas importantes en esta etapa inicial del proceso de particin;
hemos identificado las principales rutinas que sern necesarias, y hemos asignado nombre a las listas principales (meses y pLuv;ometr;as) y a las
variables principales PLuv;ometr;aProm, MaxPLuv;ometr;a y M;nPLuv;ometria) que precisa la solucin.
Recapacitemos ahora acerca de dos nuevos elementos del proceso de resolucin de problemas -la relacin secuencial entre rutinas y la posibilidad de
utilizar rutinas ya conocidas como ayuda para la construccin de la solucin al
problema que nos ocupa-o Podemos determinar informalmente el secuenciamiento de los eventos descritos en la Figura 5.18 (simplemente pensando en
qu debe ocurrir primero, qu segundo, etc.), o formalmente (escribiendo pre
y poscondiciones para cada rutina que hayamos identificado, u ordenarlas
lgicamente segn el contexto que imponen las especificaciones del problema principal). Un anlisis informal conduce al orden inicial descrito en la
Figura 5.19, junto con las especificaciones del programa original, ocupando su
lugar.

160

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Rutinas
Mostrar meses
por debajo
del promedio

Inicializar
lista de meses
y pluviometras

Mostrar pluviometra
promedio. mxima
y mnima

Mostrar mes(es)
con pluviometra
ms alta

Elementos de datos
Meses
Pluviometrias
PluviometriaPorm
MaxPluviometria
MinPluviometria

Figura 5.18.

Un array de doce nombre de meses.


Una lista de doce lecturas de valores pluviomtricos.
El valor medio de las lecturas.
El valor mximo de pluviometra de los doce meses.
El valor mnimo de pluviometra de los doce meses.

Particin en rutinas y elementos de datos para el problema


de la pluviometra.

{pre: entrada = (e" e" " .. , e,.) /\ Vi E {1, """' 12) e, es el valor
pluviomtrico del i-simo mes del ao}
Paso 1. Inicializar lista de meses y pluviometras

Paso 2. Mostrar pluviometra promedio, mxima y mnima

Paso 3. Mostrar meses por debajo del promedio

Paso 4. Mostrar el(los) mes(es) con pluviometra ms alta

{post: entrada =0/\ salida = ESTAOfSnCAS PLUVIOMIOTRICAS


media = Sum i E {1,
, 12): e;l12
mxima = Max i E {1,
, 12): e,
minima = Min i E {1,
, 12): e,
Meses por debajo de la media:
{m j : e j < SUII i E {1, ... , 12): e ;l12}
Mes(es) mxima:
(m;: e; ~ Sum i E (1, """' 12): e;l12}

Figura 5.19.

Orden inicial y especificaciones para el problema


de los valores pluviomtricos.

Resolucin de problemas algortmicos

161

Podemos observar que las cuatro rutinas deben colocarse en este orden
para que la poscondicin quede satisfecha. En concreto, la lectura de los valores pluviomtricos debe preceder a todos los dems pasos. Por si mismo, el
primer paso provoca la satisfaccin de la especificacin entrada = 0 de la
poscondicin. Del mismo modo, a continuacin debe calcularse y escribirse el
valor promedio por dos razones: Primero, el promedio es necesario como
entrada (calilla precondicin) del paso 3, donde necesitamos calcular y visualizar los meses cuya pluviomtria est por debajo del promedio, y del paso 4,
donde encontramos y visualizamos el(los) mes(es) con mximo valor pluviomtrico. Segundo, la poscondicin del problema exige que los valores promedio,
mximo y mnimo de pluviometra deben mostrarse antes de que se produzcan
las salidas de los pasos 3 y 4. Finalmente, el paso 3 debe preceder al 4, puesto
que sus salidas respectivas deben realizarse en este orden segn las poscondiciones del problema.

Ejercicios
5.20.

Supngase que se utiliza la metodologa MAPS para disear un programa que lea un nmero expresado en cifras romanas, y que muestre su
valor en nmeros arbigos. En las etapas de dilogo y especificacin, se
ha establecido que la entrada ser una cadena de letras maysculas del
conjunto (1, V, X, L, C, D, M). Recuerde que los valores de esos digitos
romanos son 1, S, 10, SO, 100, SOO, 1000, respectivamente. Se ha decidido
tambin que los digitos en la entrada estarn en orden no creciente de
valores; es decir, el nmero arbigo 4 se escribir como el numeral UU
(en lugar de IV). Con estas hiptesis, escribir detalladamente las especificaciones y realizar la fase de particin de la metodologa MAPS.

5.21.

Escribir la salida que aparecera si mezclamos los dos bucles for de los
pasos 3 y 4, del problema de la pluviometra, en un solo bucle for que
contenga las dos selecciones ; f, ante la entrada ejemplo de la Figura S.17. Es decir, suponer que se mezclan los pasos 3 y 4 de la forma
siguiente:
WriteLn('Meses por debajo de La media');
WriteLn( 'Mes(es) mxima:');
for i := 1 to LenghtLista(Pluviometras) then
begin
i f Pluviometrias[i] < PLuvometriaProm then
WriteLn('
" Meses[i]);
i f Pluvometras[i] = PluviometraProm then
WriteLn('
" Meses[i]);
end;

5.22.

Escribir un invariante para el bucle del paso 3 del problema de la


pluviometra.

162

5.4.

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

DEFINICiN DE ABSTRACCIONES: UNIFICACiN


DE RUTINAS VIEJAS CON IDEAS NUEVAS

Hemos definido y desarrollado la solucin al problema de la pluviometra,


hasta un punto en que es posible evaluar el esfuerzo necesario para solucionar
cada una de sus partes. Es decir, debemos decidir qu pasos deben ser subdivididos en subpasQs. En nuestro ejemplo, los pasos 1 y 2 pueden ser subdivididos
nuevamente para clarificar sus objetivos individuales.
Estas nuevas subdivisiones pueden verse en la Figura 5.20. En la figura
podemos ver que se ha subdividido el paso 1 en dos subpasos 1.1 y 1.2, que
asignan la lista de nombre de meses y leen la lista de pluviometras, respectivamente. El paso 3 tiene tres componentes: el paso 2.1 calcula y escribe el valor
pluviomtrico medio; el paso 2.2 calcula y escribe el valor pluviomtrico mximo; y el paso 2.3 calcula y escribe el valor pluviomtrico mnimo. Obsrvese
que los subpasos diseados se han secuenciado apropiadamente, con objeto de
satisfacer el orden de las dos listas, y el que especifica la poscondicin para las
salidas. Este cuidado, que puede parecer excesivo para un problema tan simple,
se hace ms importante cuanto ms complejo es el problema a resolver.
Paso 1. Inicializar lista de meses y pluviometra

Paso 1.1. Asignar lista de meses

L
Paso 1.2. Leer lista de valores pluviomtricos

Paso 2. Mostrar pluviometra promedio, mxima y minima

Paso 2.1. Calcular y mostrar pluviometria media

Paso 2.2. Calcular y mostrar pluviometra mxima

Paso 2.3. Calcular y mostrar pluviometra mnima

Figura 5.20.

Particin adicional de los pasos 1 y 2 del problema


de la pluviometra.

Hemos de continuar subdividiendo y secuenciando los pasos individuales


hasta que cada subpaso sea reconocible con claridad como una rutina, sea
resoluble mediante la combinacin de otras existentes (conocidas), o pueda ser
resuelto directamente creando una rutina nueva. Podemos ver que es necesario
desarrollar una rutina nueva para el paso 1.1. Podemos utilizar la rutina

Resolucin de problemas algortmicos

163

ReadLista para el paso 1.2. Podemos combinar dos rutinas, Promed;oLista y WriteLn para resolver el paso 2.1 (el clculo del promedio y la
visualizacin del resultado son dos acciones separadas, y por tanto deben
realizarlas rutinas diferentes). De forma similar, podemos combinar las rutinas
MaxL; sta y Wri teLn para el paso 2.2, y las rutinas Mi nL i sta y Wr; teLn
para el paso 2.3.
Ni el paso 3 ni el 4 parecen resolubles mediante la aplicacin directa ni la
combinacin de rutinas. No hemos visto hasta ahora ninguna rutina que resuelva directamente problemas como ste, y tenemos que crear una solucin
nueva para cada uno de los casos. Sin embargo, en la mayora de las situaciones
de resolucin de problemas algoritmicos, los diseadores de software emplean
ms tiempo combinando o reutilizando rutinas que crendolas nuevas desde el
principio. Es decir, el proceso de resolucin de problemas algortmicos tiende a
cumplir la regla 90 por 100 de transpiracin y 10 por 100 de inspiracin.
Apliquemos la <<transpiracin (Seccin 5.4.1) y la inspiracin (Seccin 5.4.2).

5.4.1.

Reutilizacin de rutinas

Como hemos dividido suficientemente el problema original, de forma que podemos tratar cada parte de forma independiente, debemos explorar la presencia de rutinas conocidas o viejas entre los pasos individuales. Por cierto,
algunas rutinas que son conocidas para unos resolutores de problemas, son
desconocidas para otros. Por ello, no debe descorazonarse si desconoce algunas rutinas con las que otros parecen estar muy familiarizados. Estamos aprendiendo un lenguaje nuevo, y nuestro vocabulario crecer con la experiencia.
Existen cuatro mecanismos que podemos utilizar para adaptar o reutilizar
rutinas ya existentes para propsitos nuevos: empalmndolas, anidndolas,
adaptndolas y mezclndolas *.
Empalmado. Es el mtodo ms sencillo de crear rutinas nuevas. Si Rl Y R2
son dos rutinas ya existentes, el empalmado de ambas crea una rutina nueva R,
que se compone de R 1 seguida secuencialmente de R2. Por ejemplo, en el
problema de la pluviometra. Las cuatro rutinas (pasos del 1 al 4) son empalmadas para formar una rutina nueva como es la solucin al problema. De la
misma forma, las rutinas PromedioLista y WriteLn se empalman para
construir la solucin al paso 2.1, como se ilustra en la Figura 5.21.
Anidamiento. Tambin se puede construir una rutina nueva anidando una
rutina R 1 ya existente de otra R2. El anidamiento se produce cuando utilizamos una rutina como argumento de la invocacin a un procedimiento, o
cuando la colocamos dentro de una instruccin condicional o dentro de un
bucle. Esto sc ilustra en la figura 5.22, donde el clculo del promedio de
pluviometra, ha sido anidado dentro del propio proceso de visualizacin del

* E. SOLOWA v: {<Lcarning to program: Learning to construct rncchanisms and cxplanations". Curnrnunicatians al the ACM (septiembre 1986), 29(9): 850.

164

Compu tacin ,. Lgica, resoluc in de problem as, algoritm os


y progra mas

mismo. Obsrvese que se pierde la asignacin del valor prome dio a la


variable
PluviometraProm, que se realiz en el empalmamiento mostra do en
la figura 2.21.
Rl

Pluvio metria Prom: = Prome dioLis ta(Plu viome trias>

R2

WriteL n( 'media = " Pluvio metria Prom>

Figura 5.21.

Creaci n de una rutina nueva R empal mando


las rutinas R1 y R2.

R2

WriteL n( 'media = "

R11
Figura 5.22.

Prome dioLis ta(Pluv iometr ias>!

Creaci n de una rutina nueva R por anidam iento


de R1 y R2.

Adaptacin. Es posible crear una rutina nueva R adaptando otra R1


ya existente. Es decir, el propsito original de Rl puede ser ligeramente modifi
cado,
generalizado o particularizado de forma que realice la funcin requer
ida por R.
Supongamos que adapta mos la rutina MaxL i s ta (que encuentra la
posicin
que ocupa el elemento mximo de una lista) para utilizarla como una
rutina
Mi n Lis t a (que encuentra la posicin que ocupa el elemento mnim
o de una
lista). Qu necesitamos modificar en rutina MaxL i sta de forma que
cumpla
las especificaciones de Mi nL i sta? Es casi evidente que es necesario
realizar
unas modficaciones mnimas, y el resultado se obtiene mucho ms
rpda y
fcilmente que si la construyramos de cero. Las modificacones se resume
n en
la Figura 5.23.
Mezcla. Se puede constr uir una rutina nueva R mediante la mezcla
o entrelazamiento de los pasos individuales de otras Rl y R2 ya exstentes.
Esto se
muestra de forma ablitracta en la Figura 5.24, donde se han mezclado
los pasos
de la rutina MaxL i sta con los de la Mi nL i sta, para obtene r una
nueva que
obtiene el valor mximo y mnimo en una nica pasada (bucle f o
r) por la
lista, en lugar de dos.
Obsrvese que, en la Figura 5.24, hemos alterado la sintaxs y renom
brado
algunas de las variables de las rutinas MaxL i sta y Mi nL i sta origina
les, con
objeto de que la nueva rutina MaxM i nL i s ta devuelva dos valores en
lugar de
uno. En una implementacin completa, la cabecera podra ser:

Resolucin de problemas algortmicos

165

pl"ocedul"e MaxMinLista(L: Lista; val" Max, Min: reaL);


R

if <O < m) and (m <= LengthL i sta(L

Rl

then

begin
j := 1
fOI" k := 2 to m do
i f L[k](2:)L[j] then
j := k;
end
else
j := O;

~Lista

:y

~nLista
Figura 5.23.

::J>

Creacin de una rutina R por la adaptacin de otra R1.

Donde los parmetros por referencia Max y Mi n se utilizan directamente en la


obtencin de los resultados; la variable j utilizada para este propsito en la
Figura 5.23 no es necesaria en esta versin.
R

Rl
i f (O < m) and (m <= LengthL i sta( L

begin
Max := 1 ;

then

R2

IMin:=1;

for k :~ 2 to m do
begin
i f L[k] > L[Max] then
Max := k;
if

L~~~ ~~L~Min]

then

end
end
else
begin
Max:=O;

I Min :=0
end;

Figura 5.24.

Creacin de una rutina nueva R por mezcla de otras dos R1 y R2.

166

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Obsrvese, en la Figura 5.24, que las instrucciones fa r e i f sirven tanto


para el caso de la funcin MaxL i sta que para el de Mi nL i sta. Esto es asi
porque la forma lgica de implementar ambas rutinas es la misma. En la
Figura 5.24 se han marcado esas instrucciones como originarias de la rutina
R l (en lugar de por R2), pero esto es indiferente en la ilustracin de la mezcla.

5.4.2.

Utilizacin de la creatividad para disear nuevas rutinas

En los casos en los que no existe ninguna rutina disponible, debemos emplear
nuestra creatividad para construir las abstracciones procedimentales apropiadas. En el problema de la pluviometra tenemos que utilizar nuestra creatividad para encontrar una solucin a los pasos 3, que debe escribir los meses
cuya pluviometria est por debajo de la media, y el 4, que debe mostrar el(los)
mes(es) cuya pluviometria es la mxima.
Aparentemente, ambos pasos requieren utilizar el mismo tipo de estrategia
-una bsqueda dentro de la lista de pluviometrias para encontrar los valores
que cumplen una determinada propiedad-. El ndice de la lista PLuv i ometri a puede utilizarse para encontrar el nombre del mes correspondiente, en el
array Meses. Considerando el ejemplo de entrada de la Figura 5.17b, el promedio de lecturas pluviomtricas de esta entrada es de 2,64 lts/m 2 . El valor
pluviomtrico para PLuviometria[1] es 2,5, que se encuentra por debajo
de la media. Por tanto, el paso 3 debe mostrar el valor de Me s e s [1] o Ene ro
como una de las salidas. Para encontrar todos los meses que satisfacen la
misma condicin, es necesario explorar los doce valores pluviomtricos. Esto
se consigue con el bucle siguiente:
{Paso 3. Mostrar meses que estn por debajo deL promedio}
WriteLn('Meses por debajo de La media: '};
for i := 1 to LengthLista(PLuviometrias) do
i f PLuviometrias[i] < PLuviometriaProm then
WriteLn(' " Meses[i]);

Obsrvese que, a pesar de haber utilizado la creatividad, la solucin al paso 3


combina algunas rutinas ya familiares mediante el empalmado y el anidamiento. Por ejemplo, una referencia a un elemento del array Meses se ha anidado
dentro de una rutina Wri teLn que, a su vez, est anidada dentro de una
rutina que incluye un bucle foro La propia rutina del for est, a su vez,
empalmada con otra rutina Wr i te Ln, para completar el paso 3.
Tras haber completado el paso 3, podemos intentar utilizar la misma estrategia para resolver el 4, del que sospechamos que se puede resolver en la misma
forma. Obsrvese que el valor mximo de pluviometra puede darse para ms
de un mes. En el caso peor, los 12 meses pueden tener el mismo valor pluviomtrico, por lo que la salida debe mostrarlos todos como salida del paso 4!
{Paso 4. Muestra eL(Los) mes(es) con vaLor mximo de PLuviometria)
WriteLn( 'Mes(es) Mxima:'};

Resolu cin de problem as algortm icos

167

for i := 1 to Length ListaC Pluvio metria s) do


i f PLuvi ometri as[i] = Maxpl uviome tria then
WriteL nC' " MesCe s)[i]);

Obsrvese que la solucin se ha conseguido adapta ndo la solucin del


paso 3.
Esta prctica es habitual en la resolucin de problemas algortmicos,
y debe
utilizarse siempre que parezca, intuitivamente, que dos pasos necesit
en el mismo tipo de 'proceso. Pueden mezclarse los pasos 3 y 4 en un bucle
for nico
que resuelva el problema? No es el caso. Piense sobre lo que ocurrir
a si un
nico bucle f or tuviera las dos instrucciones ; f de los pasos 3 y
4 dentro
de l.

5.4.3.

Utilizacin del conocimiento de dominio en el diseo


de rutinas nuevas

A lo largo de nuestra discusin sobre la resolucin de problemas algorit


micos,
hemos supuesto que se posee un cierto conocimiento sobre el domin
io al que
pertenece el problema. En problemas sencillos, como los que hemos visto
hasta
el momento, el nico conocimiento del dominio que se precisa es
el de la
familiaridad con los rudimentos del lgebra y de la Lgica. Para poder
construir soluciones a problemas ms avanzados, es necesario tener unos
conocimientos ms profundos dentro del campo de la alta Matemtica, Inform
tica,
Ciencias Naturales, Ciencias Sociales, Lingstica, Economa o Comer
cio.
El Pascal estnd ar no incluye una rutina que calcule la raz cuadra da
de un
nmero. Supongamos que estamos trabaja ndo con un problema que
requiere
esta rutina. Por ejemplo, necesitamos calcular, adems del valor medio
de unas
lecturas pluviomtricas, su desviacin estndar. Este clculo precisa
la utilizacin de una rutina que calcule la raz cuadra da de x, siendo x un
valor no
negativo. La construccin de esa rutina puede comenzarse con la especif
icacin
siguiente:
sqrtCx ):
(pre: x>=O )
(post: result

1\

y2 ~ x)

Donde se ha utilizado el simbolo ~ para resaltar el hecho de que


la raiz
cuadra da de algunos nmeros slo se puede calcular de forma aproxi
mada.
Por ejemplo, la raz cuadra da de 2 es aproximadamente, con una precisi
n de
tres decimales, 1,414.
Un conocido mtodo de las matemticas para calcular races cuadra
das de
forma aproxi mada es el mtodo de Newton. De hecho, el mtodo de
Newton
es un mtodo general para calcular las races de ecuaciones, entre
las que la
ecuacin y = x 2 es tan slo un caso particular. El mtodo de Newto
n es un
mtodo iterativo que trabaja de la forma siguiente. Comenzamos
con una
primera aproximacin al valor esperado; por ejemplo, y = 1. La
eleccin
particular de este valor inicial es habitualmente indiferente para la efectiv
idad

168

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

del mtodo. A partir de y calculamos un nuevo valor ms aproximado, y',


mediante la frmula:
y'

y + x/y
2

La apliqcin reiterada de esta frmula crea una serie de valores candidatos


que converge rpidamente hacia el valor de la raz cuadrada de x. Por ejemplo,
en la Tabla 5.2 se muestran los valores obtenidos, suponiendo x = 2 Y asumiendo un valor inicial de y = 1. As, utilizando el mtodo de Newton, podemos construir una rutina que calcule el valor aproximado de una raiz cuadrada, simplemente escribiendo un bucle que realice las aproximaciones sucesivas
de y' a y, y que termine cuando se haya alcanzado un grado de precisin
adecuado (por ejemplo, una diferencia de 0,0001).
Tabla 5.2.

Primeros pasos del clculo aproximado de


de Newton

Estimacin (y)
1
1,5
1,41667
1,41422

)2 por el

mtodo

Clculo de y'

x/y
2/1 = 2
2/1,5 = 1,33333
2/1,41667 = 1,41176

(1 + 2)/2 = 1,5
(1,5 + 1,33333)/2 = 1,41667
(1,41176 + 1,41667)/2 = 1,41422

Existe una forma alternativa de calcular races cuadradas que nos permite
esquivar el necesario conocimiento del dominio que supone el mtodo de Newton. Sin embargo, esta alternativa nos obliga a conocer el dominio de las caractersticas ms avanzadas de las bibliotecas de funciones estndar de Pascal.
En concreto, Pascal incorpora las funciones exp(x) y ln(x) que calculan las funciones eX y el logaritmo neperiano de x, respectivamente. Combinando esta informacin con los conocimientos adquiridos en el Captulo 2, podemos obtener:
b In (a)
a

Por lo que tenemos una forma simplificada de calcular la raiz cuadrada de x.


Recurdese que es posible escribir la raz cuadrada de un nmero como X 1 / 2 .
Por lo que utilizando logaritmos:
In (x 1/2) = 1/2 In x
Ahora, aplicando eX, que excribimos como exp (x), obtendremos:
exp (In

1 2
(X / )

= exp (1/2 In x)

Resolu cin de problem as algortm icos

169

o bien:
X'f2

e1f2 In (xl

Que puede escribirse en Pascal como:


y

:~

exp(O, 5

* ln(x

Por lo que 1<1 solucin que demos al problema algoritmico estar fuertem
ente
influida por nuestro conocimiento de la relacin del mismo y sus discipl
inas
relacionadas.

5.5.

TERMINACiN DEL CASO DE ESTUDIO

Volviendo al caso de estudio, nos quedan por aplicar tres pasos de la


metod ologa MAPS propuesta: codficacin, verificacin y prueba, y presen
tacin.

5.5.1.

Codificacin

En pocas palabras, la codificacin es la traslacin de la solucin de un


problema algortmico a un programa, junto con su documentacin. En la
resolucin
de un problema algortmico, la mayora del cdigo se obtiene durant
e las
etapas de particin y abstraccin. Por ejemplo, hemos completado la
codificacin de los pasos 3 y 4, del problema de la pluviometria, en la bsque
da de
nuevas rutinas que sean apropi adas para ellos. Tambin los pasos 1
y 2 estn
prcticamente codificados; sabemos que pueden implementarse reutiliz
ando y
combinando rutinas de otros problemas ya existentes.
El proceso de codificacin implica el juntar las partes de la soluci
n al
problema, asegurndonos de que el resultado conjun to es coherente,
inteligible, y satisface las pre y poscondiciones originales. Cuand o codific
amos en
Pascal suele ser til utilizar una plantilla como la siguiente:
progra m <nomb re>;
{Breve comen tario que descri ba el proble ma, la estruc
tura genera l de
la soluci n, el autor y la fecha}
uses <Bibli otecas de las que se tomar n alguna s rutina
s>;

<Decl araci n de las variab les identi ficada s en el proces


o de particin>
begin
{pre: <Preco ndici n del problem a>}
{Paso 1. <Desc ripcin del primer paso de la partici n>}
{Paso 2. <Desc ripcin del segund o paso de la partic in}
{post: <Posco ndicio nes del problem a>}
end.
Figura 5.25.

Plantill a de un progra ma escrito en Pascal.

170

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Podemos codificar el programa de la pluviometra que hemos desarrollado,


utilizando como gua la plantilla de la Figura 5.26. En este programa se ha
supuesto que las rutinas PromedioLista, MaxLista y MinLista estn
almacenadas separadamente en la biblioteca denominada HerramientasLis t a s, y otras operaciones diversas para manipulacin de listas de reales en
la biblioteca Listas. Una vez que se ha construido el esqueleto del programa,
el cdigo de lbS pasos individuales puede completarse mediante su insercin en
los lugares apropiados.

program Pluviometrias;
{El programa calcula algunas caracteristicas Pluviomtricas
a partir de datos mensuales. Diseador: Allen Tucker, 30 de marzo
de 1990. Reutiliza las rutinas MaxLista, MinLista y PromedioLista.}
uses Listas, Herrami entasL i stas;
type NombreMeses = array [1 . 12] of string[10];
val' Meses: NombreMeses;
Pluviometrias: Lista;
PluviometriaProm: real;
MaxPluviometria: real;
MinPluviometria: real;

{Los nombres de los 12 meses}


{Las 12 lecturas pluviomtricas}
{La medi a de las lecturas}
{Valor mximo de las lecturas}
{Valor minimo de las lecturas}

begin
{pre: entrada = (e" e" .. "' e,,) /\ Vi E {1, .. , 12} e, es el valor
pluviomtrico del i-simo mes del ao}
{Paso 1. Inicializar lista de meses y pluviometrias}
{Paso 2. Mostrar pluviometria promedio, mxima y minima}
{Paso 3. Mostrar meses por debajo del promedio}
{Paso 4. Mostrar mes(es) con pluviometria ms alta.}
{post: entrada =0/\ salida = ESTADISTICAS PLUVIOMETRICAS
media = Sum i E {1, .. "' 12}: e,/12
m xi ma = Max i E {1,
, 12}: e,
minima = Min i E {1,
, 12}: e,
Meses por debajo de la media:
{m;: e J < Su. i E {1, ... , 12}: e,l12}
Mes(es) mxima:
{m;: e j ~ Max i E {1, ... , 12}: e, /\ 1,; j,; 12})
end.

Figura 5.26.

Plantilla en Pascal para el problema de la pluviometria.

Para completar la codificacin de los pasos de entrada de datos, es necesario que el programa emita los mensajes necesarios para que el usuario intro

Resolu cin de problem as algoritm icos

171

duzca los datos correctamente. Lo que hay que hacer se refleja en


el esquema
del paso 1 siguiente:
{Paso 1. Inicia lizar lista de meses y pluvio metria s}
Inicial izarMe sesCM eses);
Writel nC'Int roduci r la lista de los 12 valore s pluvio
mtric os mensuales :' );
Readl ista(p luviom etrias) ;

Donde es necesario disear la rutina In; c; aL; za rMese s de forma


que el
array Meses se inicialice adecua damen te con los nombr e de los doce
meses del
ao. Podem os aadir entrad as protegidas (para el caso en que las prccon
diciones deban ser compr obadas explcitamente por el programa). Por
ejemplo, en
vez de reducir el paso 1 a las instrucciones:
Writel nC'Int roduci r la lista de los 12 valore s pluvio
mtric os
mensu ales:') ;
Readli staCPl uviom etrias) ;

Es posible compr obar que se introdu ce exacta mente una lista de doce
elementos con las instrucciones:
repeat
Write lnC'in troduc ir la lista de los 12 valore s pluvio
mtric os
mensu ales: 1);
Readl istaCp luviom etrias) ;
until length listaC Pluvio metria s) = 12;

El cdigo de los pasos 2 a 4 se ha comple tado en el progra ma


de la Figura 5.27. Obsrvese que se ha omitido el cuerpo del proced imient o In;
c; aL;za rMese s, que se deja como ejercicio.

5.5.2.

Prueba y verificacin

El objetivo de la prueba y la verificacin es garant izar lo ms posible


que la
solucin diseada es correc ta y comple ta en todos sus extremos.
Es decir, se
trata de poder asegur ar que la ejecucin del progra ma, utilizando
unos datos
de entrad a permitidos por las precondiciones, produc ir un resulta
do consistente con las poscondiciones. Debido a que la prueba y verificacin
son fundamentales en el proceso de resolucin de problemas algortmicos, se
analiza rn
en profun didad en el Captu lo 6.

5.5.3.

Presentacin

Cuand o la solucin a un proble ma algortmico ha sido desarro llada


completamente, el progra ma debe ser suficientemente autodo cumen tado, para
cuando

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

172

sea ledo por alguien no familiarizado con la solucin obtenida, pero s con la
metodologa y el dominio al que pertenece el problema. Es decir, el texto del
programa ---con su documentacin, estructura paso a paso, y pre y poscondiciones- debe ser fcilmente legible por un colega profesional, como lo sera un
artculo del ABe para cualquier persona bien educada.
La presentacin de una solucin completa de un problema algortmico
debe incluir, adems del propio texto del programa, los elementos siguientes:
1.

2.
3.

Una introduccin escrita en castellano identificando el(1os) autor(es) y


que descrba el problema, la solucin y algn aspecto inusual o innovador de la solucin.
Un ejemplo de las entradas y las respectivas salidas obtenidas en una o
varias ejecuciones del programa.
Un resumen de los resultados de la verificacin y/o prueba del programa, en los casos en que sea adecuada.

program Pluviometrias;
(El programa calcula algunas caracteristicas Pluviomtricas
a partir de datos mensuales. Diseador: Allen Tucker, 30 de marzo
de 1990. Reutiliza las rutinas MaxLista, MinLista y PromedioLista.)
uses Listas, HerramientasLi stas;
type NombreMeses = array[1 .. 12] of string[10];
var Meses: NombreMeses;
Pluviometrias: Lista;
PluviometriaProm: real;
MaxPluviometria: real;
MinPluviometria: real;

(Los nombres de los 12 meses)


(Las 12 lecturas pluviomtricas)
{La media de las lecturas}
(Valor mximo de las lecturas)
(Valor minimo de las lecturas)

begin
{pre: entrada = (e" e" . , en) /\ Vi E {1, . ",12) e, es el valor
pluviomtrico del i-simo mes del ao)
{Paso 1. Inicializar lista de meses y pluviometrias)
InicializarMeses(Meses)
WriteLn('Introducir la lista de los 12 valores pluviomtricos
mensuales:');
ReadLista(Pluviometrias);
(Paso 2. Mostrar pluviometria promedio, mxima y minima)
WriteLn('ESTADISTICAS PLUVIOMETRICAS');
PluviometriaProm := PromedioLista(Pluviometrias);
WriteLn(' media = " PluviometriaProm:5:2);
MaxPluviometria :=MaxLista(Pluviometrias, LengthLista(Pluviometrias;
WriteLn(' mxima = " MaxPluviometria:5:2);
MinPluviometria :~ MinLista(Pluviometrias, LengthLista(Pluviometrias;
WriteLn(' minima = " MinPluviometria:5:2);

Resolucin de problemas algortmicos

173

(Paso 3. Mostrar meses por debajo deL promedio)


WriteLn( 'Meses por debajo de La media:');
for i :~ 1 to LengthLista(PLuviometrias) do
if PLuviometrias[i] < PLuviometriaProm then
WriteLn('Meses[i]);
{Paso 4. Mostrar mes(es) con pLuviometria ms aLta.)
WriteLn( 'Mes(es) mxima:');
fQr i := 1 to LengthL ista(PLuviometrias) do
if PLuviometrias[i] = MaxPLuviometria then
WriteLn(' " Meses[i]);
{post: entrada ~01\ saLida = ESTADISnCAS PLUVIOMETRICAS
media = Sum i E {1, , . ,12): e,l12
mxima = "ax i E (1, .. ",12): e i
minima = "in i E (1, ." ,,12): e i
Meses por debajo de La media:
{mj: e j < Sum i E {1, .. "' 12): e,l 12 )
Mes(es) mxima:
(m j : e j ~ "ax i E (1, """,12): eiI\1~j~12))
end.

Figura 5.27.

El programa Pascal PLuviometras, compLeto.

En pocas palabras, la presentacin de la solucin a un problema debe hacese


de forma que un lector interesado sea capaz de comprenderla. El lector ser,
por el momento, su profesor, pero en un futuro podra ser cualquier otro
resolutor de problemas profesional (programador o analista) al que se le asigne
la tarea de revisar o extender la solucin al problema en cuestin.

5.6.

RESUMEN

En el Captulo 4 introdujimos las tcnicas y herramientas bsicas para construir programas sencillos en Pascal a partir de sus especificaciones. En este
captulo hemos aprendido cmo analizar un problema y a desarrollar su solucin, identificando elementos del programa ms pequeos (rutinas) y combinndolas todas en un programa completo.
Aprendimos algo del proceso de abstraccin y de su realizacin en Pascal.
La creacin de rutinas que puedan ser reutilizadas, es una de las tareas fundamentales del proceso de resolucin de problemas algoritmicos. Podemos reutilizar rutinas y recombinarlas en cuatro formas fundamentales --empalmndolas, anidndolas, adaptndolas y mezclndolas durante el proceso de creacin
de una solucin a un problema nuevo. Fuera de estos limites, es preciso utilizar
la creatividad y el conocimiento del dominio. Los otros aspectos de la resolucin de problemas algortmicos son evidentes en la metodologa MAPS --el
dilogo, la especificacin, la particin, definicin de abstracciones, codificacin,
verificacin y prueba, y presentacin.
Pero entender no es lo mismo que hacer. Antes de proseguir con el libro,
tmese algn tiempo para disear y escribir programas para los problemas

174

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

propuestos en los ejercicios siguientes. Asegrese de aplicar correctamente las


tcnicas del mtodo MAPS.

Ejercicios
5.23.

Implementar una rutina del mtodo de Newton para calcular raices


cuadradas en forma de funcin de Pascal, y que tenga Z + como dominio y R como rango. Probar el resultado para diversos valores de x, y
compararlos con los resultados de utilizar la rutina de clculo de races
cuadradas de la Seccin 5.4.

5.24.

Escribir el cuerpo del procedimiento In; e; al; za rMeses del programa de la Pluv;ometr;a.

5.25.

Continuar con el diseo MAPS sobre los nmeros romanos esbozado


en el Ejercicio 5.20; definir las abstracciones y codficar el programa
completo. Es posible utilizar abstracciones vistas previamente? Qu
abstracciones nuevas es necesario introducir, y qu tipo de creatividad y
conocimiento del dominio es necesario utilizar para completarlo?

5.26.

Disear e implementar un sistema de manipulacin de informacin de


una pequea compaa. El programa deber leer un archivo del personal, en el que cada empleado tiene su nmero y sueldo anual. Disear
un programa que realice un informe. Disear el formato del informe
cuidadosamente; cada elemento debe estar etiquetado cuidadosamente.
Para poder probar el programa, suponer que la compaia tiene 25 empleados y disear un archivo de empleados sencillo, consistente en nmeros de empleados y su sueldo anual. En el informe, mostrar lo siguiente:
a)
b)

La nmina anual de la empresa, los sueldos anuales mximo, minimo y medio.


Un apartado de la misma informacin para los rangos de salarios
siguientes (en dlares):
< sueldo < 15.000

15.000
20.000
30.000
45.000

< sueldo < 20.000


< sueldo < 30.000
< sueldo < 45.000
< sue ldo

(Es decir, el nmero de trabajadores de cada intervalo, junto con los


sueldos mximo, mnimo y medio de cada intervalo.)
5.27.

Desarrollar un diseo basado en la metodologa MAPS, para un gestor


de apuestas mltiples en las carreras de caballos. Antes de cada carrera,
el usuario debe introducir la apuesta que realice, dando el nmero del

Resolucin de problemas algortmicos

175

caballo y el valor de la apuesta. Tras la campana de ltima apuesta, el


programa debe calcular y visualizar la relacin de las apuestas sobre
cada caballo, que se calcula dividiendo el valor total de las apuestas
sobre todos los caballos por la cantidad total apostada a cada caballo.
Por ejemplo, en una carrera con tres caballos, el total de apuestas para
el nmero 1 fueron 100 dlares; para el nmero 2, 150 dlares; y 250
dlares Pllra el nmero 3. Las relaciones para el ejemplo anterior sern
5 a 1 para el primero, 5 a 3,33 para cl segundo, y 2 a 1 para el tercero.
No es necesario implementar todo el programa, sino slo el diseo
(pasos de MAPS del 1 al 4).

CAPTULO

ROBUSTEZ Y PRUEBA
DE LOS ALGORITMOS

Todo lo que pueda funcionar mal, lo har.


MURPHY

La disciplina de resolver problemas algortmicos puede resultar cruel. El diseador no slo debe cuidar que el programa funcione correctamente para las
entradas que se ajustan a las especificaciones, sino que debe cuidar que el
programa responda adecuadamente cuando se encuentre entradas incorrectas
o inesperadas. Asi, el resolutor de problemas se convierte rpidamente en un
escptico sobre la infalibilidad de los programas que pretenden resolver un
problema. Invariablemente, siempre que oimos en el laboratorio he encontrado el ltimo error!, sabemos que despus comprobar que slo era el
penltimo.
Es posible resolver problemas complejos y disear un software que tenga
una fiabilidad alta? Es decir, cmo podemos asegurar que nuestros programas, que son el producto final de nuestra metodologia de resolucin de problemas algoritmicos (MAPS), detecten combinaciones de entradas inesperadas, y
aun as trabajen de forma correcta y predecible?
En este captulo analizamos estas cuestiones de diferentes formas. Primero,
definimos las nociones complementarias de correccin, robustez y amigabilidad. Segundo, ilustramos la aplicacin de estas ideas en dos situaciones diferentes: una que involucra el procesamiento de textos, y otra que involucra el
tratamiento de grficos. En ambos casos utilizamos la metodologa de resolucin de problemas MAPS, lo que nos servir para afianzarnos en su conocimiento para utilizarla en otro tipo de problemas algortmicos. Tercero, introducimos una estrategia para disear datos de prueba, y una metodologa de
prueba sistemtica que aporta un grado de confianza sobre la correccin y
robustez del programa mayor que si se utilizan pruebas aleatorias. Cuarto,
introducimos la nocin complementaria de verificacin formal y mostramos
que est estrechamente relacionada con el lenguaje de la lgica y los procesos
de demostracin que fueron presentados en el Capitulo 3. Como veremos, las
tcnicas de verificacin y prueba pueden combinarse para crear una serie de
mtodos que aseguren la calidad y fiabilidad del software.

178

6.1.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

CORRECCiN V ROBUSTEZ

Qu significa que un programa sea correcto?

Definicin. Un programa es correcto si, para cualquier entrada que satisfaga la precondicin, termina generando una salida que satisface sus poscondiciones. De forma anloga, un procedimiento (o funcin) es correcto si,
para todos los posibles valores de los parmetros de entrada que satisfacen
las precondiciones, termina y, adems, los parmetros de salida (resultados)
satisfacen las poscondiciones.
Por ejemplo, el programa que calcula la calificacin media CaLcuLaCM, del
Capitulo 4, es correcto en este sentido. Es decir, para todas las entradas del
tipo (Notas!' Notas 2 , .. , Notas n), donde n > O y cada Notas, es un nmero en
el intervalo {O, ..., 4} el programa calcula y escribe la calificacin media y
termina. A continuacin, se demuestran algunas entradas y sus correspondientes salidas, para diferentes ejecuciones del programa.

Entrada
(3

1 2 4)

(2 )

(2 3 3 3 3 3 3 2)

Salida

2,50
2,00
2,75

Un estudio cuidadoso del programa de la Figura 4.6 hace que nos planteemos algunas dudas sobre lo que ocurre cuando las entradas no satisfacen las
especificaciones de las precondiciones. Por ejemplo, qu ocurre si la entrada
es la lista vacia( )? Qu ocurre si la lista de entrada contiene valores fuera del
intervalo {O, ..., 4}, como la lista de pluviometras mensuales utilizadas en la
Figura 5.17b, utilizadas para un problema completamente distinto? Qu ocurre si la lista contiene algo distinto de nmeros, como la lista de los doce
nombres de meses de la Figura 5.17a?
Una posible alternativa para responder a esas preguntas es correr el programa con varias entradas alternativas que no satisfacen las precondiciones, y
ver qu ocurre en cada caso. Observemos el cuerpo del programa Ca Lcu La CM
y analicemos cmo tratar cada uno de los distintos casos (vase Figura 6.1).
Este es un programa tan sencillo que resulta conveniente un anlisis tan
directo. En el caso en que la lista de entrada est vacia, no se satisface la
condicin n > O, por lo que el programa no genera ninguna salida. Sin embargo, en el caso en que los valores de la entrada no estn en el intervalo {O, ..., 4},
el programa calcula sin problemas el promedio y escribe (errneamente) el
valor de la CM, aunque algunas entradas numricas no sean calificaciones
vlidas, segn las especificaciones.

Robustez y prueba de los algoritmos

begin
{pre: entrada ~ (Notas" Notas" . o., Notas,)
\;Ii E {1,
ni: Notas, E {O, .. , 4}}
o

1\

179

n > O 1\

{Paso 1. Obtenemos la lista de calificaciones}


WriteLn( 'Introducir la lista de calificaciones:');
ReadLista(Notas);
{Pas6 2. Calcular n o nmero de calificaciones en la lista}
n:~ LengthLista(Notas);
i f n > O then
begin
{ent rada = 0 A n>O}
{Paso 3. Calculamos Sum = la suma de las calificaciones de la lista}
Sum := O;
i :~ 1;
while i <= n do
begin
Sum := Sum + Notas[i];
i := i + 1
end
end;
{Paso 4. Calculamos CM = Sum/n}
CM = Sum/n;
{Sum = Su. i E {1, ... , n}: Notas,

1\

CM

Sum/nj

{Paso 5. Se muestra CM}


WriteLn('La CM de esas calificaciones es
end {if}
{pos t: ent rada = 0 1\
salida = SUII i E {1, o , n}: Notas,!n}
end. {CalculaCM}

Figura 6.1.

~',

CM

5: 2)

Cuerpo del programa CalculaCM.

Finalmente, consideremos el caso en que la entrada no es completamente


numrica:
(31 hello 2)

Cmo trate el programa esta entrada depender de cmo manipule la rutina


ReadL i s ta las entradas no numricas. Es decir, los valores obtenidos por
ReadLista<Notas) parai = 1,2y4sonlosnmeros3,1 y2,respectivamente. Para el caso de i = 3 (donde la entrada es Notas = heL Lo) se
producir un error?, debe devolver la rutina algn valor especial, por ejemplo
0, cuando se introduzca un valor no numrico? Obsrvese que simplemente
analizando las pre y poscondiciones de la rutina ReadL i s ta (vase Apndice C), no se contesta a esta pregunta, puesto que stas estn enunciadas para
entradas vlidas. Sin embargo, ejecutando el programa podemos descubrir que

180

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

la referencia a Notas[3] devuelve el valor para esta lista en concreto, por


lo que el valor promedio es, por tanto, 1,50.
Tenemos que destacar, por tanto, que el programa Ca Lcu LaCM es correcto
en el sentido de la definicin anterior. Sin embargo, no es robusto.
Definicin, Se dice que un programa es robusto si rene las dos condiciones siguientes:
1.
2.

Es correcto.
Para todas las entradas que no satisfacen las precondiciones, el
programa termina y produce una salida que refleja el hecho de que
ha ocurrido un error en la entrada.

Seguramente, el programa Ca Lcu LaCM no es robusto, aunque seguramente es


correcto. En general, la creacin de software robusto es ms complicada que la
creacin de software correcto. Ms an, la robustez es una caracterstica deseable para el software de computadoras, sobre todo si va a ser manipulado por
gente no familiarizada con los detalles del diseo, o que son proclives a cometer ocasionalmente errores cuando escriben la entrada.
Cmo es posible robustecer el programa de la Figura 6.1? Es necesario
hacer dos cambios bsicos. Primero, es preciso revisar el procedimiento
ReadL; s ta de forma que ponga L; s tError a t rue siempre que aparezca
un dato no numrico en la lista de entrada. El paso 1 del programa debe
explorar especficamente la correccin de cada calificacin (es decir, que sea un
valor numrico dentro del conjunto {O, ..., 4}). Segundo, es necesario completar
la instruccin condiciorral que compruebe si n > 0, con una clusula e Lse, de
forma que el programa escriba el mensaje de error apropiado cuando se presente como entrada una lista vaca. Podemos revisar el paso l de la forma
siguiente:
(Paso 1. Obtenemos la lista de calificaciones}
WriteLn( 'Introducir la lista de calificaciones:');
ReadLista(Notas);
n := LengthLista(Notas);
i f Li stError o .. (n = O) then
entradavlida := false
else
begin
entradavl ida :~ true;
for i : = 1 to n do
i f Notas[i] < O) o .. (Notas[i] > 4) then
entradavlida := false;
end;
i f not ent radav l i da then
WriteLn('Entrada no vlida. Programa terminado')
else begin

Robustez y prueba de los algoritmos

181

Donde la nueva variable booleana ent radav L; da indica si la entrada se


ajusta o no a los requisitos de la precondicin. El resto del programa quedaria
de la forma original, salvo que la comprobacin de si n > O puede ser eliminada (puesto que se ha incorporado el paso 1 de esta nueva versin).
Una tercera caracteristica que es valorable en un programa es la de la
amigabilidad. Es decir, es deseable un programa que no slo identifique los
errores de entrada, sino que, a ser posible, realice avisos constructivos al
usuario sobre cmo tiene que escribir sta para que se ajuste a las especificaciones.
Definicin. Se dice que un programa es amigable si rene los requisitos
siguientes:
1.

2.

Es correcto.
Para todas las entradas que no se ajusten a las precondiciones, el
programa indica el tipo de error de entrada y concede al usuario la
oportunidad de corregirlo y continuar.

Cmo podemos convertir el programa CaLcuLaCM en un programa amigable? Podemos revisar el paso 1 en la forma siguiente:
{Paso 1. Obtenemos la lista de calificaciones}
repeat
WriteLn('Introducir La lista de calificaciones:');
ReadLista(Notas);
n := LengthLista(Notas);
i f ListError 01' (n = O) then
entradavl ida ;= false
else
begin
entradavl ida := true;
for i : ~ 1 to n do
if Notas[i] <O) 01' (Notas[i] > 4) then
entradavlida := false;
end;
until entradavlida;

Esta entrada es ms constructiva que la anterior, porque permite al usuario


mltiples oportunidades de reintroducir la lista de calificaciones. Es decir, el
programa contina en el bucle del paso 1 hasta que se introducen las calificaciones apropiadas, tras lo cual pueden ser ejecutados los pasos del 2 al 5.
Asegurarse de que un programa es correcto, robusto y amigable es una
tarea dura. Ello implica la aplicacin cuidadosa de tcnicas de prueba de
programas intrnsecas a la metodologa MAPS. Puesto que esta actividad es
tan crucial en la resolucin de problemas algortmicos, hacemos hincapi en
ella en las Secciones 6.2 y 6.3, donde resolvemos dos problemas muy diferentes
utilizando la metodologa MAPS.

182

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Ejercicios
6.1. Es correcto el programa de las Tres-en-Raya de la Figura 4.21? Es
robusto? Justificar la respuesta.
6.2.

Mostrar cmo puede modificarse el problema de las Tres-en-Raya


para que sea m~ amigable.

6.3.

a)

Revisar la precondicin del programa de las Tres-en-Raya, de


forma que describa exactamente cul movimiento es legal y cul no.
b) Considerando esta revisin, qu cambios adicionales pueden realizarse para hacer el programa ms robusto?

6.4. Es correcto el programa ContarPalabras de la Figura 4.17? Es


robusto? Justificarlo.
6.5.

6.2.

Mostrar la forma en que se puede alterar el programa ContarPalabras para hacerlo amigable.

RESOLUCiN DE PROBLEMAS DE PROCESAMIENTO


DE TEXTO UTILIZANDO MAPS: CRIPTOGRAFA

Las computadoras se han utilizado desde la Segunda Guerra Mundial para


ayudarnos en la resolucin de problemas criptogrficos, que requieren descubrir el esquema de codificacin, o cifrado, que subyace en un mensaje codificado. En el Captulo 2 presentamos un ejemplo del conocido mtodo Csar de
cifrado que convirti el mensaje
SERGEANT PEPPERS LONEL y HEARTS CLUB BANO

en el mensaje codificado
VHUJHOQW SHSSHUV ORQHOB KHOUWV FOXE EOQG

Aqu, el esquema de codificacin subyacente consiste en reemplazar cada letra


por la que ocupa tres posiciones posteriores en el alfabeto. En la prctica,
se utilizan otros esquemas de codificacin ms elaborados, y el descubrimiento
tanto del cifrado como del mensaje original puede ser una tarea bastante
complicada.
En nuestro caso, el problema es mucho ms sencillo: dada una serie de
mensajes codificados segn el mtodo Csar, descodificar cada uno y escribir el
texto del mensaje ya descodificado. Por tanto, para el mensaje codificado que
se muestra arriba, la salida debera ser SERGEANT PEPPERS LONEL y
HEARTS CLUB BAND.

Robustez V prueba de

105

algoritmos

183

Etapa 1: El dilogo. Existen tan pocas dudas acerca de este problema, que
podemos estar tentados de abordar directamente el diseo. Sin embargo, es
necesario apuntar y resolver algunas cuestiones de detalle. Por ejemplo, puede
contener el texto tanto letras maysculas como minsculas, e incluso caracteres no alfabticos? Presumiblemente la respuesta es si, y tales caracteres deben
aparecer en el mensaje descodificado tal y como aparecan en el mensaje original. Por ejemplo, el blanco del mensaje codificado permanece igual en el mensaje descodificado.
Etapa 2: Las especificaciones. Las especificaciones para este problema pueden
establecerse de la forma siguiente:
[pre: entrada = una serie de mensajes, siendo cada uno una secuencia
de caracteres c" ... , c n representando una codi fi cacin uti Lizando
eL mtodo de Csar
"post: saLida = una serie de textos descodificados de La forma
d" ... , d n en La que cada d, satisface La reLacin c, ~ Csar(d,) /\c,
es un carcter aLfabtico v para todo i en {1, ... , n): c, = di}

Donde Csa r (di) representa la codificacn Csar del; -simo carcter di


en el texto de salida. Esta codificacin se describe en la Tabla 6.1.
Tabla 6.1.

El

cifrado de Csar

Letra (1)

Csar (1)

Letra (1)

Csar (1)

a
b

A
B

D
E

a
b
e

A
B

Y
z

Y
Z

Etapa 3: La particin. El programa necesita ejecutar tres pasos principales


para cada mensaje que descodifica. En el paso dc entrada se obtendr el mensaje descodificado, a continuacin se har un paso de descodificacin y, finalmente, se realizar el paso de salida que escribe el programa ya descodificado.
Estos pasos se resumen de la forma siguiente:
repeat
{Paso 1. Obtener eL mensaje.

{Paso 2. Descodificar eL mensaje.)


{Paso 3. Escribir eL mensaje descodificado.)
until no existan ms mensajes para descodificar

184

Computacin ,. Lgica, resolucin de problemas, algoritmos y programas

Si acordamos que la longitud mxima de un mensaje est limitada a la


longitud mxima de un string de Pascal (255 caracteres en la mayora de las
implementaciones), entonces existe una pequea dificultad al implementar los
pasos de entrada y salida para este programa. Sin embargo, si pretendemos
ms generalidad, es necesario realizar algunas cuidadosas consideraciones sobre el almacenamiento y los requerimientos de codificacin de cada mensaje.
En esta solucin vamos a atenernos a la versin ms simple.
As, el programa tendr dos variables del tipo s tri n9 principales, la variable mensaje y la variable deseodi fi cado. La propia descodificacin
puede hacerse de dos maneras. Una forma es la de almacenar las letras del
alfabeto en un array, por ejemplo el array Csar, de forma que la descodificacin de una letra concreta Csa r [i] puede obtenerse directamente buscando
en Csar[i-3]. Si utilizamos esta estrategia, tendremos que tener cuidado
con las tres primeras letras del alfabeto. (Por qu?)
Otra forma de descodificar las letras del alfabeto es la de hacer operar
sobre el ordinal que corresponde a cada carcter en la tabla ASCII (vase el
Apndice A). Por ejemplo, el ordinal de la letra A es el 65, que se diferencia del
ordinal de la letra D (68) en tres unidades. As, si e es una letra del mensaje de
entrada, la funcin de Pascal ehr(ord(e)-3) devolver la letra codificada,
suponiendo de nuevo que e no es una de las tres primeras letras del alfabeto.
(Por qu?)
Etapa 4: Definicin de abstracciones. El paso 2 de este programa, la descodificacin del mensaje, puede considerarse como el anidamiento de dos rutinas. Es
decir, la funcin que calcula la inversa de la funcin de cifra de Csar (vase
Tabla 6.1) para una sola letra del alfabeto, puede anidarse dentro de otra que
analice uno a uno los caracteres que componen el mensaje codificado. La
ltima puede implementarse como un bucle for, mientras que la primera
puede implementarse como una funcin de Pascal a la que denominaremos
Csarlnversa(e), que toma un solo carcter como argumento y devuelve
como resultado el carcter descodificado. El anidamiento debe tener lugar,
puesto que esta operacin se realiza para todos los caracteres del mensaje.
Podemos definir las especificaciones de esas dos rutinas en la forma siguiente:
Descodificar(mensaje)
{pre: mensaje = C 1 , e 2 , _, en}
{post: resultado = d" d" . "' dn
di = Csarlnversa(c)

1\

para todo i in (1, "."' n):

Csarlnversa(c)
(pre: c es un carcter)
(post: resultado = d, Y bien d es alfabtico
es alfabtico 1\ d = c)

1\

CsarCd) = c or d no

Etapa 5. Codificacin. Las especificaciones anteriores pueden codificarse


como rutinas Pascal de la forma siguiente:

Robustez y prueba de los algoritmos

185

function Descodificar (mensaje: string): string;


yar
i: integer;
descodificado: string;
begin
{pre: mensaje = C 1 , C 2 , "' en}
descodificado := mensaje;
for i := 1 to Length(mensaje) do
descodifi cado[i] := CsarInyersa (mensa j e[i]);
Descodif i ca r : = descodi f i cado
{post: resultado=d" d" ... , do 1\ para todo i in {1, ... , ni:
di = CsarInversa(c i )}
end;
function Csar Inversa (c: char): char;
yar
d: char;
j: integer;
alpha: string;
begin
{pre: c es un carcter}
alpha := concat('abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
j := pos(c, alpha);
{busca c en el al fabeto}
case j of

O:
d := c;
1 .. 3:
d := alpha[23 + n;
4 .. 26:
d := alpha[j - 3];
27 .. 29:
d := alpha[23 + n;
30" .52:
d :~ alpha[j - 3J;
end;
Csar Inversa := d;
(post: resultado = d, Y bien d
or d no es al fabtico 1\ d = c}
end;

{no es alfabtico}
{descodifica a, b, c}
{descodifica d, e, .. "' z}
(descodifica A, B, C)
{descodifica D, E, ... , Z}
es alfabtico /\ Csar(d) = c

Teniendo todo lo anterior en mente, podemos escribir el esbozo de programa


siguiente:
program Criptografia;
{El programa descodifica una serie de mensajes y escribe cada uno
descodi fi cado; se supone que cada mensaje se ha codi fi cado
util izando la cifra de Csar.}
function CsarInversa
function Descodificar

Yar
mensaje, descodificado: string;

186

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

begin
{pre: entrada
codifi cado}

una serie de lineas, conteniendo cada una un mensaje

repeat
{Paso 1. Obtener el mensaje}
WriteLn('Introducir en una sola linea un mensaje codificado, y');
WriteLn,( 'pulsar <RET> para terminar:');
ReadLn(mensaje);
{Paso 2. Descodificar el mensaje.}
descodificado:~ Descodificar(mensaje);
{Paso 3. Escribir el mensaje descodificado.)
WriteLn('El mensaje descodificado es:');
WriteLn(descodificado);
unti l mensaje = "
{post: entrada ~ vacia
descodificado}

1\

salida

el correspondiente mensaje

Etapa 6: Prueba. Es til probar este tipo de programas utilizando como entrada un texto almacenado en un archivo separado. De esta forma, no es necesario reescribir de forma tediosa el mensaje de entrada cada vez que se ejecute el
programa. Una sencilla alternativa al programa anterior, que permita utilizar
una variable archivo (tipo file), en el que se escribira la entrada, y que condiciona la terminacn del programa a que se lea la marca de fin de fichero, se
obtendra con las modificaciones siguentes. Previas al paso 1 habra que escribir:
var Archi voTexto: text
reset(ArchivoTexto, 'codificado,txt');

El paso 1 debera alterarse para que tome la entrada del archivo, en lugar de
tomarla desde el teclado, en la forma siguiente:
ReadLn(ArchivoTexto, mensaje);
WriteLn(mensaje);

Finalmente, la condicin de terminacin del bucle repea t debe explorar el


final del archivo de entrada en la forma siguiente:
until not eof(Archi voTexto);

Es evidente que, separadamente, se debe preparar en la forma adecuada el


archivo cod i f i cado. t x t para que incluya los textos codificados antes de
ejecutar esta nueva versin del programa.

Robustez y prueba de los algoritmos

187

Etapa 7: Presentacin. La presentacin de la solucin a este problema requie-

re la realizacin de varias ejecuciones del programa, imprimiendo la salida


correspondiente a cada ejecucin. La combinacin de estas salidas con el texto
del programa, una breve exposicin escrita con el propsito del mismo, y una
explicacin con alguna caracterstica inusual (si la tiene), completarn la presentacin.

6.3.

RESOLUCiN DE PROBLEMAS GRFICOS UTILIZANDO


MAPS: EL JUEGO DE LA VIDA

El Juego de la Vda lo invent John H. Conway en 1970. Su propsito es


proporcionar una simulacin grfica sencilla de la variacin de poblacin a lo
largo de varias generaciones. El juego se juega en un entramado rectangular
que representa el mundo para una especie particular de organismo viviente
(personas, amebas, pollos u otros). En el entramado, cada celda sombreada
representa un organismo vivo, y la coleccn completa de celdas sombreadas la
poblacin viva en una generacin concreta. Por ejemplo, la Figura 6.2 muestra
una poblacin de seis pollos vivos en un mundo que puede albergar un total
de 64 en una generacin.

Figura 6.2.

Una generacin de seis pollos en el Juego de la Vida.

Cada nueva generacin de pollos se obtiene de la anterior siguiendo cuatro


reglas muy simples que regulan la supervivencia, muerte o nacimiento de cada
individuo. Estas reglas estn relacionadas solamente con el entorno fisico en
que vive el pollo -es decir, las condiciones de superpoblacin o la baja densidad de poblacin en la que se incluye el pollo-o Se define el entorno de una
celda del entramado, como el conjunto de celdas contiguas a ella. Las cuatro
reglas mencionadas son:
1.
2.

Supervivencia. Un pollo sobrevive hasta la siguiente generacin, si tiene dos o tres vecinos vivos en la generacin actual.
Nacimiento. Un pollo nacer en la generacin siguiente, si: a) no existe
en la generacin actual; y b) tiene exactamente tres vecinos vivos en la
generacin actual.

188

3.
4.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Un pollo morir en la generacin siguiente, si en


la actual tiene cero o un solo vecino.
Muerte por superpoblacin. Un pollo morir en la siguiente generacin, si en la actual tiene 4 o ms vecinos vivos.
Muerte por soledad.

Asi, si extendemos el ejemplo de la Figura 6.2 hasta la generacin siguiente,


nuestra poblacin de ppllos se transformar en la de la Figura 6.3.
Observamos, en la Figura 6.3b, que el pollo de abajo, a la izquierda, ha
muerto por soledad, mientras que dos pollos en la cruz han muerto por
superpoblacin. Los otros tres pollos de la cruz han sobrevivido porque tenan
tres vecinos en la generacin anterior. Finalmente, nacieron tres nuevos pollos
en celdas que estaban sin ocupar, y tenian exactamente tres vecinos en la
generacin anterior.

a)

b)

Figura 6.3. Dos primeras generaciones en el Juego de la Vida.


a) Seis pollos en la primera generacin. b) Seis en la segunda.

Despus de algunas pruebas, podemos concluir que la configuracin de pollos en cada generacin puede diferir de la precedente. El Juego de la Vida y
algunas derivaciones que presentan pequeas diferencas, han fascinado a matemticos y cientficos que los han estudiado detenidamente. Los cientficos han
estudiado la forma de aplicar este tipo de simulacones o tcnicas de modelizacin, como ayuda para comprender los cambios de poblacin en la vida real.
Sin embargo, el problema al que nos enfrentamos aqu es simplemente el de
construir un programa que, para una configuracin inicial sobre un entramado
de 8 x 8 celdas, muestre la secuencia de generaciones que siguen las reglas
sobre supervivencia, vida y muerte anteriores.
Etapa 1: El dilogo. Seguramente, nuestro programa debe proporcionar al
usuario una forma sencilla de describir la configuracin inicial de los pollos en
el entramado. Mientras no sea dificil generalizar el programa para que pueda
manipular entramados de cualquier tamao, esto no parece ser importante
para el programa, por lo que lo ignoraremos por el momento. Sin embargo, es
necesario incorporar algn mecanismo por el cual el usuario pueda controlar
el paso de las generaciones, e incluso parar el proceso.

Robustez y prueba de los algoritmos

189

Podemos considerar la entrada en dos etapas. Primero, el usuario introduce las filas y columnas de cada celda que estarn ocupadas por la primera
generacin de pollos. Segundo, el usuario introducir una serie de rdenes que
indicarn al programa si debe avanzar a la siguiente generacin, o bien terminar el juego.
La salida la constituyen una sucesin de grficos como los de la Figura 6.3.
La configuracin inicial se compone de un entramado, colocado a la izquierda,
con la distribucin inicial, y otro entramado vaco a la derecha. La segunda
imagen, que se visualiza ante la entrada por el usuario de la orden de progresar, estar constituida por un entramado a la izquierda con la configuracin
inicial, y el de la derecha con la distribucin obtenida en la segunda generacin. La tercera imagen, si se ordena, presentar a la segunda generacin a la
izquierda, y la tercera a la derecha, y asi sucesivamente.
Etapa 2: Las especificaciones. Despus del dilogo, podemos escribir las siguientes especificaciones para este problema:
{pre: entrada =n, X 1 , y" XZ' Y2' _, Xn , Yn ,
n > O 1\ m > O pa ra todo i in {1, ... , n}: 1 ,;;

C"
Xii

e Z' ,
y; ,;; 8}

Cm /\ Cm =

q ' /\

{post: salida = una serie de m- 1 imgenes del Juego de la Vida,


donde la pri mera imagen est determi nada por las n celdas
(x" y,>, (x" y,> , (X n, Yn>' y cada imagen sucesiva presenta
la i-sima generacin que se obtiene de la (i -1)-sima al aplicar
las reglas de nacimiento, supervivencia y muerte. El final del
juego lo provoca el usuario pulsando' 'q" (de' 'quit' '>')

Donde las pulsaciones de teclas C" Cl' , Cm-' sirve para proporcionar al
usuario el control de las transiciones entre una generacin y la siguiente. Es
decir, el carcter (incluida la barra espaciadora) que se simboliza por c; indica
al programa que tiene que calcular la i -sima generacin, a partir de la
(i -1)-sima y dibujarlas una alIado de la otra. Por tanto, en cada momento, el
programa debe mostrar las dos ltimas generaciones calculadas, siendo la de la
derecha la ms reciente. La primera generacin, dada por las coordenadas x"
y" x 2 ' Yl' , x n, Yn' se identifica con el nombre de generacin 1 de la
secuenCia.
La Figura 6.3 muestra una generacin 1 inicial (en el entramado del lado
izquierdo) y la generacin 2, que se obtendra si se pulsa la tecla de continuacin (lee las celdas sombreadas, fila a fila, suponiendo que las filas y las columnas estn numeradas del 1 al 8):
6364546475456

Etapa 3: La particin. Inmediatamente nos vienen a la cabeza varias ideas para


resolver este problema. Primero, ser til usar las facilidades de la abstraccin
Gri d. Segundo, ser til declarar dos variables del tipo Gri d; por ejemplo,
Gen1 (para el entramado de la izquierda) y Gen2 (para el de la derecha).

190

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

El programa deber incorporar tres pasos principales para simular el Juego


de la Vida. El primer paso debe inicializar los dos entramados Gen1 y Gen2,
leyendo la primera parte de la entrada, y sombreando las celdas de Gen1
apropiadas. El paso 2, simplemente leer del teclado la orden de si se debe
continuar a la siguiente generacin o terminar el juego. El paso 3 se encargar
de calcular la generacin actual a partir de la anterior, y de mostrar el resultado.
El secuenciamiento de esos tres pasos puede ser gobernado por la estructura iterativa que se muestra ms adelante. En ella, una instruccin wh i Le
controla el bucle, y cada repeticin de ste provoca el clculo de una nueva
generacin que resulta visualizada.
{Paso 1. Inicializar Gen1 y Gen2}
{Paso 2. Leer una orden de cont ro l}
while control <> 'q' do
begin
{Paso 3. Obtener y mostrar la generacin siguiente}
{Paso 4. Leer una orden de control}
end

Donde la variable de control se utiliza para almacenar el carcter que el


usuario pulsa en el teclado para indicar si se debe calcular y mostrar la prxima generacin. Por esta razn, el paso 4 es una repeticin del paso 2; es decir,
se necesita una orden distinta para iniciar el proceso y para cada repeticin
sucesIva.
El paso 1 primero crea los dos entramados con un tamao de celda apropiado, por ejemplo, 10 pixels, y coloca los entramados Gen1 y Gen2 en las
coordenadas apropiadas para que aparezcan uno al lado del otro. Este paso
tambin necesita inicializar la variable entera n seguida de n pares de enteros i
y j, en el rango 1 al 8 que designe la posicin inicial de la poblacin de la
generacin 1. A diferencia de la primera parte del paso 1, esta segunda parte
necesitar ser abstraida como un procedimiento -que podramos llamar
Ini ciaL izar.
El paso 2 es prcticamente inmediato. Puede construirse simplemente incluyendo una instruccin Read que asigne el carcter de la tecla pulsada a la
variable control. El paso 3 es el ms complejo del programa, por lo que se debe
subdividir en varias partes. Es decir, para el clculo y visualizacin de una
nueva generacin, primero debemos borrar el entramado que contendr la
generacin siguiente (Gen2 o Gen1, dependiendo de cul de los dos contiene
la generacin actual), y a continuacin determinar para cada celda en esa
generacin cul est viva y cul no. El acto de borrar un entramado puede
abstraerse bajo el nombre de Bor ra rG r i d. La determinacin de la configuracin de la prxima generacin puede abstraerse bajo el nombre Si gui enteGeneracin.

Robustez y prueba de los algoritmos

191

El procedimiento SiguienteGeneracin puede subdividirse a su vez


en partes, puesto que para cada celda debe contarse el nmero de vecinos vivos
que tiene. Abstraeremos esa tarea con la funcin Vec i nos. El procedure
NuevaGene ra c in puede construirse anidando la funcin Vec i nos dentro
de un bucle que examine por separado cada celda de la generacin actual.
Puede utilizarse una instruccin case (vase el manual de laboratorio para
ms detalles sobre esta funcin) para discriminar entre si las cuatro reglas del
nacimiento, supervivencia y muerte. Por tanto, el paso 3 tendr la estructura
de control siguiente, suponiendo que Gen1 es la generacin actual, y Gen2 la
siguiente:
{Paso 3. Obtener y mostrar la generacin siguiente}
BorrarGrid<Gen2);
SiguienteGeneracin<Gen1, Gen2);

El procedimiento S; gui enteGenerac i n tiene la siguiente estructura


cuando se aplica al clculo de Gen 2 a partir de Gen1:
for i := 1 to 8 do
for j : = 1 to 8 do
case Vecinos<Gen1, i, j) of
{sobrevivir: poner a on la celda i, j de Gen2}
{nacimiento: poner a on la celda i, j de Gen2}
{muerte: poner a off la celda i, j de Gen2}
end

Donde se han establecido informalmente las distintas alternativas para evitar


detalles innecesarios para este paso.
Obsrvese que los papeles de Gen1 y Gen2 sern los opuestos cuando se
produzca el cambio de poblacin siguiente de la generacin 2 a la 3. Es decir,
para la generacin 3 habr que borrar el entramado Gen1 y recalcular sus
celdas a partir de los valores actuales de Gen2. Por tanto, para valores impares del nmero de generacin (1, 3, 5, Yasi sucesivamente), el entramado Gen1
mostrar la nueva generacin, y para valores pares (2, 4, 6, ..., etc.). Este papel
lo jugar Gen2. Debido a esta alternancia de papeles, Gen1 y Gen2 deben ser
parmetros en la implementacin de las rutinas BorrarGri d, Si gui enteGeneracin y Vecinos.
Paso 4: Definicin de abstracciones. A continuacin, resumimos las abstracciones nuevas ms importantes que son necesarias para este programa:
procedure Inicializar<var G: Grid);
{pre: entrada = n, x" y" X 2 , Y2' -, xn , Yn }
{post: todas las celdas de G que corresponden a los pares de enteros
Xi' Yi se ponen a on, para todo i in 1, .. "' n, A entrada = vacia}
procedure BorrarGrid<var A: Grid);
{post: todas las celdas del Grid A se ponen a off}

192

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

function Vecinos(G: Grid: i, j: integer): integer;


{post: resultado ~ el nmero de vecinos vivos de la celda i, j
del grid G}
procedure SiguienteGeneracin(A: Grid; var B: Grid);
{post: entramado B = nueva generacin de celdas vivas, calculadas
del entramado A uti l izando las cuatro reglas de nacimiento,
supervivenci a,Y muerte}

El resto de las abstracciones pueden implementarse directamente a partir de


los procedimientos y funciones generales disponibles para los entramados.
Etapa 5: Codificacin. El cdigo de este programa se muestra en varios fragmentos. El cuerpo principal del programa puede verse en la Figura 6.4. Es
bastante autoexplicativo, puesto que se ha obtenido a partir de las etapas
previas de la metodologa MAPS.
program vi da;
uses
Grids;
var
Gen1, Gen2: Grid;
control: char;
Gennumero: integer;
begin
{pre: entrada = n, X 1 , y" x2 ' Y2' , x n, Yn, C 1 , e 2 , .... ,
n > O 1\ m> O pa ra todo i in {1, . , n}: 1 <:; x;, y; <:; 8}

Cm 1\ C lII =

Iql

{Paso 1. Inicializar Gen1 y Gen2}


WriteLn( 'El juego de la Vida');
StarsGrids;
SetUpGrid(Gen1, 8,10,10, 10};
SetUpGrid(Gen2, 8, 120, 10, 10};
Inicializar(Gen1);
{Paso 2. Leer una orden de control}
gennmero:= 1; {lleva el control del nmero de generacin}
WriteLn( 'pulsar <RET> para ver la generacin', gennumero + 1 :3);
WriteLn( 'pulsar "q" para terminar');
Read(control);
while control <> 'q' do
begin
{Paso 3. Calcula y visualiza la generacin siguiente}
i f gennumero IIOd 2 = 1 then
begin
BorrarGrid(Gen2); {las generaciones pares en el grid derecho}
SiguienteGeneracin(Gen1, Gen2);
end
else
begin
BorrarGrid (Gen1 ); {las generaciones impares en el gri d i zqui erdo}
SiguienteGeneracin(Gen2, Gen1);
end;

Robustez y prueba de los algoritmos

193

{Paso 4. Leer una orden de cont ro l )


gennmero + 1;
WriteLn( 'pulsar <RET> para ver la generacin', gennumero + 1 :3);
WriteLn( 'pulsar' 'q" para terminar');
Read(controL> ;
end
{post: salida = una serie de m-1 imgenes del Juego de la Vida,
donde la primera imagen est determinada por las n celdas
(x" y,), (x" y,) , (x n , Yn)' y cada imagen sucesiva presenta
la i-sima generacin que se obtiene de la (i - 1)-sima al aplicar
las reglas de nacimiento, supervivencia y muerte. El final del
juego lo provoca el usuario pulsando 'q' (de 'quit').)
end

Figura 6.4. Cuerpo del programa principal del programa Vi da.

Obsrvese que el paso 3 tiene dos partes alternativas. Una que se ejecuta al
calcular una generacin par, y la otra al calcular una impar. Esto se obtiene
directamente de la idea de los papeles invertibles de los entramados Gen1 y
Gen2. La variable gennumero lleva la cuenta de la generacin que se est
calculando y visualizando.
Las rutinas nuevas que se utilizan en este programa se muestran a continuacin. La primera es la rutina 1 ni e; aL; za r, que se muestra en la Figura 6.5. Simplemente pone a on cada celda del entramado G que se indica por la
fila y columna.
procedure Ini c i a l i zar (val' G: Gr i d);
val'
k, n, i, j: integer;
begin
{pre: entrada =0, x" y" X Z, Y2'
Xn , Yn }
Writeln('Introducir el nmero n de celdas inicialmente vivas:');
Read(n);
Writeln(' Introducir una serie n de pares de enteros');
Writeln('indicando cada uno las coordenadas x, y de una celda
vi va. ' );
for k :~ 1 to n do
begin
repeat
read(i, P;
until (1 <= i ) and (i <= GridSize(G and
(1 <= j) and (j <= GridSize(G;
TurnCellOn(G, i, j);
end;
{post: todas las celdas de G que corresponden a los pares de enteros
Xi' Yi se ponen a on para todo i in 1, .. , n /\ entrada = vaca)
a

Figura 6.5.

La ruti na 1n i e i a l iza r.

194

Compu tacin l. Lgica, resoluc in de problem as, algoritm os


y progra mas

Adems, obsrvese que el procedimiento Inici aLiza r lee reitera


damen te
pares de enteros i, j hasta que el par represente una celda vlida
del entramado G. Es decir, si i o j estuvieran fuera de rango de filas y column
as de G, el
par se vuelve a leer. Esto es un ejemplo de la construccin de
progra mas
robustos y amigables.
'
La segund a rutina, 80 r ra rG r id, realiza la sencilla tarea de poner
a off
todas y cada una de las celdas del entram ado G. Esto se muestr a
en la Figura 6.6.
p ..ocedu ..e Bo.... a .. Gr-id (va .. A: Grid);
(post: todas las celdas del Gr-id A se ponen a off}
va"
i,j:in tege .. ;
begin
fa .. i := 1 to Gr-idS ize(A) do
fo .. j := 1 to GridSi ze(A) do
Tu .. nCellO fHA, i, j)
end;

Figura 6.6.

La rutina Borra rGrid.

La rutina Vec i nos, de la Figura 6.7, cuenta el nmer o de vecinos


vivos
para la celda i, j del entram ado G. Obsrvese que se considera
vecina a
cualqu ier celda viva a la que se acceda directamente desde la celda
i, j por
uno de sus cuatro lados, o por una de sus cuatro esquinas. Por
tanto, cada
celda puede tener como mxim o ocho vecinas. Sin embarg o, las celdas
que se
encuen tran en los bordes del entram ado G tienen menos de ocho vecinos
. Por
ejemplo, la celda 1,1 no tiene ms que tres vecinos, y la celda 1,2
no tiene
ms que cinco. Para asegurarnos de que la rutina calcula valores
correctos
para esos casos, debemos saber que la rutina Ce LLOn (k, L>, que
se suministra con el tipo Grid, devuelve el valor faLse siempre que el par
k, L no se
corres ponda con una celda de G. Por ejemplo, si k = O o L = O Ce
LLOn (k,
L) = fa Ls e. Podem os cercior arnos de esto viendo
la especificacin de la
rutina CeL LOn (vase Apndice D).
functi on Vecino s(G: grid; i, j: intege r): intege r;
var
k, l, con t: i nt ege r;
begin
cont := O;
for k : = i - 1 to i + 1 do
for l := j - 1 to j + 1 do
if CellOn (G, k, l) and not ((k ~ i) and (L = j then
cont := cont + 1;
Vecino s := cont
: post: resul tado = eL nmero de vecino s vivos de la celda
i, j del grid G:

Figura 6.7.

La rutina Vecin os.

Robustez V prueba de los algoritmos

195

Finalmente, la rutina Si gui enteGeneraci n (vase Fig. 6.8) calcula las


celdas vivas para la siguiente generacin del entramado B, a partir de la generacin actual del entramado A. Incluye una interpretacin detallada de las
cuatro reglas de supervivencia, nacimiento y muerte.
Etapa 6: Prueba. Para probar este programa suficientemente, necesitamos
disear una serie de asos de prueba, que no slo prueben el Juego de la Vida
para unas configuraciones iniciales inusuales, sino tambin otras que suministren datos de entrada no vlidos. Queremos asegurar que nuestro programa es
tan robusto como correcto. Un paso inicial es ejecutar el programa para una
entrada conocida, tal como la de la Figura 6.2. Producir el programa la
salida correcta para la generacin 2?, y para la 3 y sucesivas?
A continuacin, debemos probar el programa con otras entradas, especialmente aquellas que representan poblaciones con una evolucin fcil de predecir, tal como la que se muestra en la Figura 6.9. Esta configuracin es interesante porque prueba la correccin del programa cuando las celdas vivas
ocupan los bordes.
procedure SiguienteGeneracin (A: Grid; var B: Grid);
var
i, j, cont: integer;
begin
for i := 1 to GridSize(A) do
for j :~ 1 to GridSize(A) do
case Vecinos(A, i, j) of
{RegLa 1. Supervivencia}
2, 3:
if CeLLOn(A, i, j) then
TurnCeLLOn(B, i, j)
{RegLa 2. Nacimiento)
else i f (Nacimiento(A, i, j) = 3) and
(CeLlOff(A, i, j))
then TurnCellOn(B, i, j);
{Regla 3. Muerte por soLedad)
O, 1 :
i f CellOn(A, i, j) then
TurnCellOff<B, i, j);
{Regla 4. Muerte por superpobLacin}
4,5,6,7,8:
i f CeLLOn(A, i, j) then
TurnCeLLOff(B, i, j);
end
{post: entramado B =nueva generacin de ceLdas vivas, caLcuLadas
del entramado A utiLizando Las cuatro regLas de nacimiento,
supervi venci a y muerte}
end;

Figura 6.8.

La rutina SiguienteGeneracin.

Etapa 7: Presentacin. La presentacin del programa est completa cuando se


ha preparado un esbozo de su propsito general, junto con un listado del

196

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

propio programa y con las salidas de algunas ejecuciones como ejemplo. El


esbozo debe contener no slo un resumen de lo que hace el programa, sino
tambin de cmo trata las situaciones excepcionales, junto con otras limitaciones que el usuario se pueda encontrar.

a)
Figura 6.9.

b)

Un caso de prueba diferente para el Juego de la Vida.

a) Primera generacin. b) Segunda generacin.

Ejercicio
6.6. Obtener a mano las generaciones 2 y 3 para las generaciones iniciales
siguientes.

a)

6.4.

b)

e)

GARANTA DE LA ROBUSTEZ: DISEO DE CASOS


DE PRUEBA

La metodologa de resolucin de problemas MAPS proporciona una estructura que, si se manipula cuidadosamente, puede conducirnos a la obtencin de
programas robustos -programas que no slo funcionan ben para entradas
correctas, sino que tambin se comportan elegantemente para un amplio

Robustez y prueba de los algoritmos

197

rango de entradas incorrectas-o Una etapa fundamental de la metodologa


MAPS es la etapa 6, o etapa de prueba y verificacin. Esta es una etapa que, en
nuestro camino, puede que sea la ms critica de todo el proceso. Si un programa resulta no ser correcto como resultado de la aplicacin sistemtica de
mtodos de prueba y/o verificacin, todas las etapas anteriores de la metodologa MAPS habrn sido intiles. En las Secciones 6.4 y 6.5 introduciremos
mtodos esp::cificos para llevar a cabo en esta importante etapa de prueba y
verificacin. La discusin de estos temas concluye con una evaluacin comparativa de la utilizacin de ambos mtodos en la construccin del software.
Un conjunto ya clsico de tcnicas para asegurar la correccin, robustez y
amigabilidad de los programas, se incluye bajo el nombre genrico de prueba.
Las tcnicas de prueba han sido desarrolladas por diseadores e ingenieros del
software durante las ltimas dcadas.

Definicin. La prueba de un programa es la aplicacin sistemtica de casos


de prueba al programa, procedimiento o funcin, con el objetivo de detectar y corregir los errores (o fallos) del programa. Los casos de prueba
consisten en distintos conjuntos de valores de entrada, elegidos intencionadamente para analizar el comportamiento del programa bajo unas condiciones que pueden o no haber sido sugeridas por el diseador del programa. Conjuntamente, todos los datos que estn incluidos en esas pruebas
reciben el nombre de juego de pruebas.
El resultado de la prueba ofrece menores garantas que la de la verificacin. Es
decir, la prueba, por su naturaleza limitada, no asegura la ausencia de errores
-slo puede poner de manifiesto los errores presentes.
Para que sea eficaz, la prueba debe realizarse por una persona distinta a la
que construy el programa. Esto es importante, porque una persona ajena
puede ser bastante ms objetiva sobre el comportamiento del programa que la
persona que lo ha desarrollado.
Existen varias formas de disear juegos de prueba y de aplicarlas a un
programa o a un procedimiento concreto. Son necesarias estrategias de prueba
ms largas cuando se trata de probar programas construidos con extensos
conjuntos de instrucciones, que cuando tratamos de probar casos de estudio.
En esta seccin nos concentraremos en el diseo y aplicacin de mtodos de
prueba rigurosos para programas relativamente pequeos, dejando para el
Volumen II de esta serie los mtodos de prueba del software de gran escala.

6.4.1.

Ejemplo: Prueba de un procedimiento o funcin


completos

Cuando desarrollamos una abstraccin procedimental para un problema bien


definido, o para una rutina, es necesario probarla ejecutando el procedimiento
suministrndole una amplia gama de valores a los parmetros de entrada, y

198

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

asegurndonos de que, en cada caso. el resultado del procedimicnto es consistente con sus poscondiciones.
Puesto que es imposible probar (odos los posibles valores de entrada. tendremos que seleccionar un subconjunto de ellos que sea significativo, y ejecutar
el programa e imprimir el resultado con cada uno de los elementos de ese
subconjunto. U na forma bastante til de realizar este proceso es construir un
programa cO/lductor. Se denomina as porque, literalmente. guia la ejecucin
e impresin de resultados del procedimiento o funcin con los valores seleccionados para la prueba.
Ilustremos estas ideas construyendo un juego de pruebas para la funcin
MaxL i sta (vase Figura 5.12). Cul seria un conjunto de pruebas apropiado
para esta funcin, y cmo podemos disear un conductor para estudiar el
comportamiento de MaxL i sta frente a estos datos?
Los juegos de prueba pueden crecer rpidamente. Consideremos el nmero
total de posibles entradas vlidas que podramos construir para la funcin
MaxL i sta, utilizando O ms elementos. Supongamos que cada elemento es
un entcro en el rango - 2':; al 2':; - 1, habrn 2\6 = 65.536 listas diferentes
de un solo elemento. El nmero de posibles listas diferentes de /l elementos
resulta astronmico --seguramente excesivo para incluirlas en un juego de
pruebas.
Pensemos un momento sobre algunas posibles listas que pueden ser pasadas a MaxLista. y a lo que esperamos que MaxLista produzca como respuesta. En la Tabla 6.2 se ofrecen algunas ejemplos obvios.
Tabla 6.2
Parmetros de entrada L

Resultado esperado

(3 1 2 8)

(8 1 2 3)

(3 8 1 2)

(-1 23 -8)

(3 1 2 8)

(3 1 2 8)

(3

2 8)

Los dos primeros datos de pruebas son importantes porque el valor mximo
ocupa la ltima y primera posicin de la lista. respectivamente. El tercer caso
tambin es importante. pues representa el caso tpico que puede ocurrir---es

Robustez y prueba de 105 algoritmos

199

decir, el valor mximo ocupa una posicin cualquiera entre el primero y el


ltimo elemento de la lista--. El cuarto comprueba si MaxL i s ta trabaja
correctamente con valores negativos. Los tres ltimos son importantes, puesto
que restringen el valor de m forzando a la funcin a buscar el mximo en una
sublista.
Pero, qu otras cosas deben introducirse en un juego de pruebas~ Evidentemente, debem9s asegurarnos de que la lista vaca ( ) devuelva el valor O.
Qu hacer con los otros incontables casos que se nos pueden presentar?
Cmo presentar a MaxL i sta un subconjunto de esos casos que nos asegure
que el procedimiento hace lo que debe? As mismo, cmo podcmos probar la
robustez y amigabilidad de Ma xLi s ta? Es decir, cmo se comportar Ma xLista con entradas como la lista (-1, -2, hoLa, -8)? ante un valor
de L, como I hoLa I o I asrtfadesr I o 3332123442 que no sean una
lista? Debemos aadir todos esos casos a nuestro juego de pruebas para determinar cmo responde MaxL i sta.
Por tanto, debemos ser muy selectivos al disear los juegos de prueba
para un procedimiento. Slo debemos incluir en los juegos de pruebas aquellas
entradas que representen a un gran nmero de casos posibles. Es conveniente
almacenar aparte nuestro juego de pruebas en un archivo de disco, de forma
que no necesitemos reescribirlo cada vez que queramos probar el procedimiento.
En la Figura 6.10 se muestra la estructura general dc un conductor de
pruebas. En la notacin utilizada <p (x, y) > simboliza a un procedimiento p
con parmetros de entrada x y parmetros de salida y; <archivo juegos
prueba> simboliza al archivo del que se pueden obtener los juegos de prueba.
Esta estructura es fcilmente adaptable para el caso en que lo que deseemos
sca probar una funcin f (x) en lugar de un procedimiento p (x, y); en este
caso la variable y se identifica con la salida de la funcin, la instruccin <p (x,
y se sustituye por y := f(x) en el conductor de la Figura 6.10, y los
comentarios se modifican para indicar que se prueba una funcin en lugar de
un procedimiento.
program conductor;
(Este programa conductor prueba eL procedimiento <p(x, y}
{ut i Lizando un juego de pruebas como datos de ent rada}
(deL archivo <archivo juego pruebas>}
procedure <p(x, y;
begin
end;
var <variabLes correspondientes a Los parmetros>;
<archivo juego pruebas>: text;
begin
WriteLn(' Comi enza La prueba deL procedimi ento <p(x, y');
readarchivo juego pruebas, <x;
while not eofarchivo juego pruebas do

200

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

beg;n
WrHeLn('Parmetros de entrada = " <x;
<p(x, y;
Wr; teLn(' Resul tado de p(x, y) =' , <y;
readarch;vo juego pruebas>, <x;
end;
WrHeLn( 'F;nal de la prueba del proced;m;ento <p(x, y')
end.
Figura 6.10.

Estructura general de un conductor de pruebas.

Supongamos que se quiere probar la funcin MaxL; sta utilizando un


programa conductor y el archivo de juegopruebasmax que contiene las
listas siguientes:
(3 1 2 8)
(8 1 2 3)
(3 8 1 2)
(-1 -2 -3 -8)
(3 1 2 8)
(3 1 2 8)
(3 1 2
8)
(-1 -2 hello -8)
()

4
4
4
4

3
2
1
4
O

Los enteros que aparecen a la derecha no estn almacenados en el archivo,


sino que son escritos por el usuario cuando el conductor se lo solicita. El
programa conductor siguiente podra ser eficaz:
program Conductor;
{Este prog rama conductor prueba la fune; n MaxU sta ut H ; zando un
juego de pruebas como datos de entrada del arch;vo juegopruebasmax}
function MaxUsta(L: Usta; m: integer): integer;
val' j, k: ;nteger;
begin
{pre: L = (e 1 , e 2 , _, e m, _, en) A n ~ O 1\ cada e i es un nmero}
i f (O < n) and (m <= LengthUsta(L then
begin
j := 1;
for k := 2 to m do
{; nv: v; E {1, ... , k - 1 }: e [j] >= e [;] /\ 2 <= k <= m + 1 }
if L[k] > L[j] then
j := k;
end
else
j := O;
MaxUsta := j;
( pos t: n > O /\ v; E {1, ... , n}: e j ;;O e, /\ re su l tado = j v
n = 0/\ resul tado = O}
end;

Robust ez y prueba de los algoritm os

201

varL: Lista;
m, j: intege r;
juegop ruebas max: text;
begin
WriteL n( 'Comie nza la prueba de la funci n MaxLi sta(L,
m)');
WriteL n('Intr oducir el nombre del archiv o del juego de
prueba s: ');
ReadL ista(U ;
while not eof(jue goprue basma x) do
begin
WriteL n( 'Lista de entrad a L ='); Write Lista( U;
Write (Intro ducir valor de m: '); ReadLn (m);
j := MaxLi sta(L, m);
WriteL n('Res ultado de MaxLi sta(L, m) ~ " j);
ReadL ista(U ;
end;
WriteL n('Fin al de la prueba de la funci n MaxLi sta(L,
m)
end.

La salida que produce este conduc tor cuando se le suministra el archivo


j uegopru ebasm ax se muestra en la Figura 6.11.
Comien za la prueba de la funci n MaxLi sta(L, m)
Introd ucir el nombre del archiv o del juego de prueba s:
milist a
Lista de entrad a L =
(3 1 2 8)
Introd ucir valor de m: 4
Result ado de MaxLi sta(L, m) = 4
Lista de entrad a L =
(8 1 2 3)
Introd ucir valor de m: 4
Resul tado de MaxLi sta(L, ro) = 1

i.. i sta de entrad a L =

O
Int roduci r va lar de ro: O
Result ado de MaxLi sta(L, ro) = O
Final de la prueba de la funci n MaxLi sta(L, ro)

Figura 6.11. Result ado de ejecuta r el conduc tor de prueba


s para
la funcin MaxL ista, con el archivo de entrada juegop ruebas
max.

Como puede verse, la construccin y utilizacin de un conduc tor de


pruebas es casi un proceso mecnico. Sin embargo, cuando se utiliza con
cuidado,
no slo nos permite descubrir errores ocultos, sino que nos sugiere
formas de
conseguir que el progra ma sea ms robust o y amigable. j Utilizar el
procesamiento con un juego de datos desconocido puede conducirnos a
resutados
sorprendentes! Sin embargo, es preferible realizar esos descubrimien
tos en el
momento de la prueba, que no despus, cuando se ha entregado el
procedimiento a una persona desconocida para cualquier utilizacin.

202

6.4.2.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Ejemplo: Prueba de un programa completo

Debemos probar los programas de abajo a arriba. Es decir, debemos probar


todos los procedimientos y funciones antes de probar el programa que los
utiliza. Despus de realizar esto, podemos proceder a la prueba del programa
completo en la misma forma en que probamos un procedimiento. Para cllo,
convertimos e' programa en una especie de autoconductor de si mismo, aadindole un bucle externo que lea sistemticamente datos de entrada alternativos desde un archivo externo que contenga un juego de pruebas, y despus
prosiga con su ejecucin normal, produciendo las salidas a todas las entradas
del juego de pruebas, en lugar de la salida de un nico juego de datos.
Por ejemplo, considrese el programa Ca Lcu La CM, de la Figura 4.6, el cual
modificamos para ser ms amigable (vase Seccin 6.1). Para probar este programa, podemos convertirlo en el autoconductor que se muestra ms abajo, y
ejecutarlo con los datos de el archivo que contiene varias listas de calificaciones alternativas, en lugar de slo una. El resultado de convertir este programa
en amigable y en un autoconductor, se muestra en la Figura 6.12. Para convertirlo en autoconductor, basta con aadirle un bucle repea t abarcando las pre
y poscondiciones del programa. Esta modificacin hace que el programa lea y
procese entradas hasta que lea una lista vacia 0, lo que seala el fin de las
ejecuciones de prueba.
program caLcuLaCM;
uses
Listas;
var
Notas: Listas;
i, n: integer;
Sum, CM: reaL;
entradavLida: BooLean;
beyin
repeat
{pre: entrada = (Notas" Notas"
1\ \1'i E {1, .""' n}: Notas, E (O,
repeat
WriteLn ('Introducir La Lista
ReadLista(Notas);
n :~ LongLista(Notas);
entradavL ida :~ true;
for i : ~ 1 to n do
if not isNumeric(Notas[i] or
entradavL ida := faLse;
until entradavLida;
i f n > O then
beyin
Sum :~ O:
i := 1;
whi le i <= n do
begin
Sum := Sum + Notas[i];

... , Notas")

1\

n> O

.. "' 4}}
de caLificaciones:');

Notas[i] < O) or (Notas[i] > 4) then

Robustez y prueba de los algoritmos

203

i := i + 1
end
CM = Sum/n;

WriteLn('La CM de esas caLificaciones es=', CM: 5: 2)


end {i f}

{post entrada =0"


saLida=Sumi E {1, ... ,n}:Notas;ln}
untiL n ~ O;
end.

Figura 6.12.

6.5.

Un autoconductor para la versin amigable del CaLcuLaCM.

GARANTA DE CORRECCiN: VERIFICACiN


DE PROGRAMAS

Como metodologa general, la verficacn de programas tene como objetvo


la aplcacn de la lgca matemtica, para demostrar formalmente que el
programa incluido entre la precondicn y la poscondicin cumple esas especificaciones bajo cualquier circunstanca de ejecucin posible. En este sentido, la
verificacn formal es un logro relativamente nuevo en el rea del software.
Pienso que es importante tener unos conocimientos bsicos de la verificacin
formal, sus mtodos y sus objetivos. De todas formas, esta materia est en un
punto de corte de la investigacn en informtica. La verificacin de programas proporciona a los lectores un punto de vista alternativo sobre la correccin de los programas, que pone de manifiesto uno de los mayores defectos de
las tcnicas de prueba clsicas: stas nunca garantizan la correccin.
El estilo de verificacin que utilizaremos es informal, resaltando los fundamentos ms que explicando el proceso de demostracn con mucho detalle.
Partimos de la hiptesis de que las propiedades algebraicas de los nmeros,
con las que estamos familiarizados, se preservan cuando se utilizan los nmeros en programacin. Sabemos que es una restriccin bastante fuerte. Sabemos, por ejemplo, que en los nmeros -reales o enteros- no tiene una representacin exacta en los programas Pascal. Sabemos tambin que, en
matemticas, las operaciones entre reales y enteros siempre producen resultados exactos, mientras que en computacin se introducen a veces pequeos
errores. Para el propsito de esta introduccin, ignoraremos estas pequeas
desviacones, con objeto de simplificar la presentacin de la verificacin y
centrarnos en los principios y en la metodologa.

6.5.1.

Tableau de demostracin

Para verificar un programa, desarrollamos una prueba del tableau. Un comienzo de prueba del tableau, o tableau vaco, es un listado del programa con sus
precondiciones, poscondiciones y comentarios vacios antes y despus de cada

204

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

instruccin, tal y como se muestra en la Figura 6.13. El objetivo de la verificacin es rellenar este tableau con asertos vlidos. Cada instruccin del programa debe preceder y seguir a un aserto, y debemos demostrar, siguiendo una
lnea sistemtica de razonamiento, que la instruccin conduce de una situacin
que satisface el aserto que le precede al que le sigue, partiendo de otros cuya
validez ya ha sido demostrada. As, la verificacin de un programa es un
proceso en el que se desarrollan una serie de asertos (y razonamientos que les
acompaan) en una forma similar al de las demostraciones de la lgica (como
vimos en el Captulo 3). El resultado de este proceso se denomina demostracin
de la correccin del programa, o simplemente demostracin.
El proceso por el que descubrimos sistemticamente la validez de los asertos que componen una prueba, se le denomina razonamiento sobre programas.
Podemos definir esas ideas ms formalmente como sigue:
Definicin. Una demostracin es un conjunto de asertos P1 , Pu ... ,
Pr>+1' que, cuando se insertan sucesivamente entre las instrucciones 51' Su
, sn en un tableau vaco, dan origen a la siguiente prueba de tableau:
begin
(precondiciones}
{P,}, 5,; {P 2 }, 52;
(poscondiciones}
end

{Pn}' Sn; {P n+,}

Donde los asertos siguientes son vlidos (es decir, tautologas):


1.
2.
3.

precondi ciones =<> P,


{P;}, s,, (P '+1} para todo i en (1, . , n}
P0+' =<>poscondi ciones

La notacin {P;} s; {P H1} quiere decir que, respecto de la ; -sima instruccin del programa, si P; es vlido antes de la ejecucin de S;, el aserto
P H1 ser vlido despus de la ejecucin de s;. En otras palabras, Pi y P H1
son, respectivamente, precondicin y poscondicin de la instruccin s;.
Supongamos que tenemos el programa y el tableau vaco de la Figura 6.14. Es
decir, queremos demostrar la correccin del programa que se ha diseado para
calcular y escribir el resultado del producto de dos nmeros cualquiera n 1 Yn 2 .
Para completar la demostracin, necesitamos descubrir y justificar los asertos p 1 al P4 del tableau, uno a uno, hasta rellenarlo. El resultado se muestra en
la Figura 6.15. Las justificaciones que aparecen en la columna de la derecha de
la Figura 6.15 son el resultado de aplicar equivalencias lgicas y reglas de
inferencia a la secuencia de instrucciones de Pascal. Algunas de esas justificaciones (por ejemplo, aritmticas) se basan en las hiptesis comunes que se
suelen realizar en la aritmtica. Otras (por ejemplo, A -introduccin) se han
tomado de las reglas de inferencia de la lgica (vase Captulo 3). Otras (por

Robustez y prueba de los algoritmos

205

begin
(pre: precondicin)
5,;

(post: poscondicin);

Figura 6.13.

Aspecto inicial de una prueba de tableau: el tableau vaco.

ejemplo, la regla de la asignacin) reflejan las propiedades de algunas instrucciones de Pascal (vanse Secciones 6.5.2 a 6.5.5), y las estudiaremos en este
captulo.
La demostracin completa del tableau refleja el estilo de las demostraciones
de la lgica, tal como se vio en el Captulo 3.

begin
{pre: entrada = n1, n2 /\ salida =0l

@)
Read (x, y ) ; - - -

{
z:=x*y;

{
Write
( )

@
@Y

(z) - - - -

{post: entrada =0/\ salida = n1


end.

Figura 6.14.

n2

Tableau vaco para un sencillo programa de tres instrucciones.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

206

6.5.2.

La regla de inferencia de la asignacin

Al igual que otros mtodos de demostracin, la verificacin de programas


utiliza los axiomas y las reglas de inferencia. Las reglas de inferencia son
generalizaciones sobre el comportamiento de determinados tipos especificos de
instrucciones de los programas en Pascal. Estas reglas aportan mtodos con
los que derivar asertos nuevos, a partir de otros existentes, para algunas instrucciones especficas.
begin
{pre: entrada

n1, n2 /\ salida =0}

Jus! Cica! iuus

~{entrada~n1, n2

QY

}
Read (x, y);..
@
[entrada =0/\ x = n1 /\ y = n2 /\ x*y = n1*n2)

z:~x*y;..

{x = n1 /\ y = n2 /\ z = n1 *n2 /\ sa l i da = 0
Write (z) ..
@
{z = n1 *n2 /\ sa l i da = n1 *n2 }

~ n1

i regla de la asignacin,
aritmtica,
/\-introduccin}
{regla de la asignacin,
A-eliminacin,
/\-introduccin}
{regla de la asignacin,
/\-el iminacin}
{/\-eliminacin,
/\-introduccin}

{post: entrada =0/\ salida

{A-eLiminacin

* n2 }

Figura 6.15. Prueba del tableau completa


para un programa sencillo.

En la verificacin formal de programas, el sistema de inferencias, y concretamente las reglas de inferencia, son mucho ms complicadas que las que se
han presentado aqu. Consideremos cuatro reglas de inferencia bsicas para los
programas: la regla de la asignacin, la regla de los procedimientos, la regla de
las condicionales y la regla de los bucles.
Definicin. La regla de inferencia de la asignacin.
a)

{P(e)} v :=

e { }

{P(e)} v := e {P(v)}

b)

e)

{entrada

n} Read(v) { }

[entrada

n} Read(v) {entrada = 0 /\

V =

n}

[salida=0/\e=n} Write(e):}
[salida

~0

/\ e = n) Write(e) {salida = e}

Robustez y prueba de los algoritmos

207

El apartado a) de esta regla dice que si una proposicin es vlida para el


estado de una expresin e (la satisface) antes de que la instruccin de
asignacin v : = e sea ejecutada. Podemos inferir que la misma proposicin es vlida para la variable y despus de la ejecucin de la asignacin.
Los apartados b) y e) simplemente destacan el hecho de que las instrucciones Read y Wr; te producen el mismo efecto que la asignacin. En la
instruccin .Read, el origen del valor para la asignacin es el flujo de
entrada, y el receptor la variable v. En la instruccin Wr; te, el origen del
valor es la expresin e, y el destino el propio flujo de salida. Ms concretamente, el apartado b) significa que la instruccin Read retira un valor n del
flujo de entrada, y se lo asigna a la variable v. El apartado e) indica que la
instruccin Wri te(e) aade una copia del valor n, que actualmente es el
resultado de evaluar la expresin e, al flujo de salida. Esto no es ms que
una formalizacin directa de lo que ya conociamos de la actuacin de
Read y Wr; te en nuestros programas.
Por ejemplo, en el programa de la Figura 6.14, supongamos que lo nico
que conocemos antes de la ejecucin de la instruccin de asignacin z : = x * y,
es que los valores de x e y son dos nmeros n1 y n2. Por las reglas de la
aritmtica, tambin sabemos que x * y = n1 * n2. Podemos utilizar estos
conocimientos en la forma siguiente:
{x*y~nl*n2}

z:=x*y;
{z=n1 *n2}

{regLa de La asignacin}

Lo nico que hemos hecho, al realizar esta inferencia, ha sido poner z en todas
las ocurrencias de x * y en la proposicin ya conocida P (x * y) para poder
obtener P (z >. Obsrvese que se ha marcado esta inferencia de la demostracin, con una justificacin situada a la derecha, para clarificar las razones de la
inferencia realizada. Esto es consistente con el estilo de las demostraciones de
la lgica.
Est claro que esta regla es fcilmente extensible para instrucciones Read y
Wr; te, con ms de una variable, para las instrucciones ReadLn, Wr; tLn,
ReadL; sta y Wr; teL; sta, y as sucesivamente. Por simplicidad, no recargaremos esta regla tratando de formalizarla para todas esas situaciones,
aunque la utilizaremos en nuestras demostraciones como si lo hubiramos
hecho.
Como ejemplo adicional, consideremos la primera instruccin del programa de la Figura 6.14, para la que se cumple lo siguiente cuando razonamos
sobre ella:
{ent rada ~ n1, n2)
Read(x, y);
{
}

20S

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

La parte b) de la regla de la asignacin nos permite escribir la inferencia


siguiente:
(entrada = n1, n2]
Read(x, y);
{entrada =0/\ x = n1 /\ y

n2}

{regla de la asignacin}

Lo que justifica formalmente que se les asignan valores a x e y, utilizando la


instruccin Read, y los valores son eliminados, simultneamente, del flujo de
entrada.
De forma similar, podemos razonar sobre la instruccin Wr i te, de la
Figura 6.14, utilizando el apartado e) de la regla de asignacin. Comencemos
con:
{z = n1 * n2 /\ sal ida =0}
Wr ite (z);
{

Lo ms importante de esta inferencia es que z debe tener el valor n1 * n2,


para que dicho valor pueda aparecer en el flujo de salida. Podemos escribir
esta conclusin formalmente utilizando la regla de la asignacin de la forma
siguiente:
{z = n1 * n2 /\ sal ida =0}
Write(z);
{salida=n1 *n2}

{regla de la asignacin}

El razonamiento sobre programas siempre requiere que utilicemos activamente nuestros conocimientos sobre aritmtica, aunque no reflejemos los detaHes de este conocimiento durante el proceso de la demostracin. Aqui presentamos otro ejemplo. Supongamos que sabemos que el valor de la variable i es
no negativo, inmediatamente antes de que se ejecute la asignacin i := i + 1
en un programa. Cmo nos puede ayudar la regla de la asignacin a razonar
acerca de esto? Formalmente comenzamos con:
{i ~ O]
i:=i+1;
{i > Ol

{Regla de la asignacin, aritmtica}

Si analizamos detenidamente los detaHes de esta asignacin, descubriremos


que si i ?> O, antes de la asignacin, entonces ; + 1 ?> 1. As, para utlizar la
regla de la asignacin identificamos las variables v e i + 1 con la expresin e,
y el aserto P (e) con i + 1 ?> 1. Por todo ello, podemos inferir P (v) o i ?> O.
Aplicando de nuevo las reglas de la aritmtica, podemos reescribir el aserto
slo en trminos de la variable i, lo que nos conduce a i > O.

Robustez y prueba de los algoritmos

6.5.3.

209

Reutilizacin de las reglas de inferencia de la lgica

Cuando escribimos la demostracin de un programa, adems de las reglas que


definen el comportamiento del programa y la aritmtica, utilizamos las reglas
de inferencia de la lgica que estudiamos en el Capitulo 3. Esas reglas nos
permiten mover los asertos a lo largo del programa, lo que permite utilizarlos para escribir nuevas inferencias en otros puntos del programa. Por tanto,
podemos conseguir una lnea de razonamiento coherente que incluya a todo el
programa, desde el principio hasta el final.
Para ilustrarlo, consideremos el programa de la Figura 6.15. Obsrvese
cmo se utiliza la regla de la asignacin para construir ciertas partes de los
asertos del P1 al P4' Pero, qu ocurre con sus interconexiones? Por ejemplo,
cmo justificar la migracin del aserto ent rada = 0 desde P2 , donde se
origina, saltndose P3 y P4' Yapareciendo finalmente en la poscondicin donde
se necesita para que la prueba est completa? Aunque la regla de la asignacin
no nos permite realizar esta migracin, las reglas de inferencia de la lgica, s.
El primer paso de la demostracin de la Figura 6.15 contiene el aserto P1
{ent rada = n1, n2}

que se infiere de la precondicin, utilizando la /\ -eliminacin


{ent rada

= n1, n2 " sa l i da = 0}

La derivacin de P2 es el resultado de la combinacin de tres pasos diferentes:


la regla de la asignacin, las propiedades de la aritmtica, y la regla de inferencia de la 1\ -introduccin. En concreto, la proposicin x*y = n1 *n2
aparece en P2 como preparacin para la derivacin de los asertos P3 de P2
y

S2'

Las reglas de la /\ -introduccin y de la /\ -eliminacin se utilizan tambin


a lo largo de la prueba. Sin embargo, esas reglas de inferencia deben aplicarse
con cuidado cuando el predicado que se va a aadir viene de una posicin
distante del programa. Por ejemplo, considrese la reintroduccin del aserto
sa l i da = 0 en la proposicin P3 despus de haber desaparecido de las proposiciones P 1 y P2 . Esto es posible hacerlo si en el programa no se han ejecutado
instrucciones que invaliden este predicado: es decir, alguna instruccin Wr i te
(o, de forma equivalente, alguna aplicacin del apartado e) de la regla de
asignacin) entre la ltima posicin en que el predicado era vlido y la instruccin donde se reintroduce.

6.5.4.

Reglas para las condicionales

Los programas incluyen otros tipos de instrucciones, aparte de las que asignan
valores a las variables. Cuando se pretenden escribir demostraciones sobre los
programas, es necesario conocer axiomas para poder razonar sobre selecciones

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

210

condicionales (instrucciones i f), invocaciones a procedimientos y funciones


sobre bucles. Existen reglas de inferencia que son aplicables a estas instrucciones.
Definicin. La regla de inferencia de la seleccin condicional.
a)

;P

1\

6}

b)

{Q)

PI\-6o>Q

{Pi i f 6 then 5 {Q)

{P

1\

6)

{P

1\

-6)

5,

{Q }

5,

{Q )

{Pi i f 6 then 5, el5e 5, {Q}

El apartado a) permite inferir la validez de Q tras la ejecucin de la seleccin condicional, si podemos inferirla independientemente de cul alternativa se haya seguido -en una tanto, P como B son verdaderas, y se ejecuta
la instruccin s; y en la otra, B es falso, y P Q es tambin vlido-o El
apartado b) es simplemente una extensin del a), en la que se establece la
validez de q, independientemente de cul de los dos caminos alternativos se
haya seguido -ejecucin de S1 (cuando B es ve rdade ro), o la de S2
(cuando B es fa Lso).

Consideremos las asignaciones y seleccin condicional siguientes, que se


han diseado para asignar a la variable z el mayor de los valores x o y:
z := x;
i f x <~ y then
z :~ y

Para verificar esto, tenemos que establecer la validez del aserto Q:


Q=

{z =

1\

> y v z

1\

X <~

y)

Que es una manera ms formal de describir la salida que deseamos para z. Las
inslrucciones de asignacin y la seleccin condicional estn en secuencia, por
lo que necesitamos utilizar, en el proceso de verificacin, tanto la regla de la
asignacin como la de la seleccin condicional. Por tanto, podemos comenzar
con lo siguiente:
I

:= x;
{z = x}
if x <~ y then
Z

z := y

{x > y

1\ Z

<= Y 1\

= y)

Utilizando la regla de la asignacin, podemos identificar P como z = x (la


validez de P se deduce de la linea anterior a l y de la regla de la asignacin), y
B como x <= y. Por tanto, tendremos que demostrar ahora la validez del

211

Robustez y prueba de los algoritmos

aserto Q para completar la demostracin. Sustituyendo por B, P Y


valores en la regla de la seleccin, obtendremos:
{z ~
{z =

X /\ X
X /\

<= y} z : = y (z
<= y) "'" z ~ X

sus

~ X /\ X

~(x

/\ X

> y v z = y /\ X <= y) /\
> y v z = y /\ X <= YJ

Para demostrar la validez del aserto anterior, consideramos los dos casos
x <= y Y~(x <= y) que, como sabemos por aritmtica, son los nicos posibles.
Cuando x <= y la linea 1 es vlida, puesto que se realizar la asignacin
x : = y, y la regla de la asignacin garantiza que z = y. La regla de la
/\ -introduccin nos permite inferir z = y /\ X <= y, Yfinalmente, la regla de la
v -introduccin nos permite inferir z = x /\ x > y v z = Y /\ X <= y. La lnea 2
tambin es trivialmente vlida, puesto que ~(x <= y) es fa Lso y fa Lso =o> p
es siempre vlido para cualquier proposicin p.
En el segundo caso, x > y, la segunda lnea de la disyuncin de arriba es
vlida. Es decir, tanto ~(x <= y) (o equivalentemente, x> y) y z = x son
vlidos, por lo que lo es su conjuncin por la /\ -introduccin. Pero
z

=X

/\ ~(x

:=

y)

es equivalente a
z=x/\x>y

por lo que la lnea 2 completa tiene la forma de un aserto de tipo p =o> P V q,


que es vlido por la v -introduccin. La lnea 1 tambin es trivialmente vlida,
puesto que x <= y es fa Lso. Esto completa la justificacin para el aserto Q.
Considrese la alternativa siguiente para asignar a z el mayor de los valores de x e y:
if x > y then

z := x
else
z := y

Para demostrar esto, es necesario establecer de nuevo la validez del aserto Q:


Q=

{z =

X /\ X

> y v z = y /\

<= y}

Utilizaremos de nuevo la regla de inferencia de la seleccin condicional, junto


con otras reglas de inferencia apropiadas, la aritmtica e identidades. Comenzamos con un tableau de prueba parcial:
{verdadero}
i f x ) y then

z := x
else
z :~ y
: z = x /\ x > y v z

y /\

<= y}

212

Computacin l. Lgica, resolucin de problemas, algoritmos V programas

Identificamos B como x> y, 5, como z := x, 52 como z := y, y P como


verdadero (esto es lo mismo que decir que no nos importa cul era el valor
que tenian esas variables antes de ejecutar la seleccin condicional). Asi, la
parte b) de la regla de la seleccin tomaria la forma siguiente, de la que debemos demostrar su validez para establecer la propia validez de Q:
{verdadero A x ~ y} z := x {z = X A X > y v z = y A X <= y} A
{verdadero A ~(X > y)} z := y{ z = X A X > y v z = y A X <= y}

Analicemos por separado cada una de las lineas de la disyuncin, como hicimos en el ejemplo anterior. La lnea 1 se corresponde con el caso en que x > y.
Utilizando la regla de la asignacin, la propiedad de la identidad para el valor
verdadero y la 1\ -introduccin, podemos poner lo siguiente:
{X>Y} z :~X(Z=XAX>Y}

Por lo que, utilizando la v -introduccin, es posible validar la lnea I con la


hiptesis de que x > y. La linea 2 cubre el caso alternativo en el que suponemos que x <= y. Es posible establecer la validez de la lnea 2 siguiendo
razonamientos similares a los que se utilizaron con la 1.

6.5.5.

Verificacin de bucles

Para verificar un bucle de un programa es necesario realizar dos operaciones


independientes: debemos encontrar y justificar sus asertos asociados, y debemos verificar por induccin su invariante.
Recurdese, del Captulo 4, que es posible explicar lo que hace un bucle
desplegndolo. Es decir, si reescribimos el bucle como una secuencia de
ocurrencias del cuerpo del bucle, podemos deducir con exactitud qu clase de
generalizacin representa el bucle. Considrese el bucle wh i l e de la Figura 6.16, que suma los enteros del 1 al 5.
sum := o;
i :~ 1;
while i <= 5 do

begin
5um := sum

+ i;

i:=i+1;

end
Figura 6.16.

Un bucle wh i Le sencillo.

Las cinco ejecuciones del cuerpo del bucle pueden ser desplegadas de la manera siguiente:
sum : = sum + i;

i:=i+1;

Robustez y prueba de los algoritmos


sum : = sum

213

+ i;

i:=i+1;
suro : = sum + i;

i:=i+1;
sum : = sum + i;

i:=i+1;
sum := sum + i;

i:=i+1;

Recurdese tambin de! Capitulo 4, que el invariante del bucle es un aserto


que es vlido antes y despus de cada repeticin del bucle, incluidas la primera
y la ltima. El invariante para e! bucle de arriba es:
{inv: sum=Su. j

{1, .. , i -1}: j

1\

1 <= i <=6)

Es posible comprobar que este invariante es verdadero, tanto antes como


despus de cada repeticin del bucle wh; Le. En particular, el bucle explica
cada uno de los pasos individuales de la expansin del bucle siguiente:
{sum = O 1\ i = 1 }
sum := sum + i;
i:=i+1;
{sum = O + 1 1\ i =
sum := sum + i;
i:=i+1;
{sum = O + 1 + 2 1\
sum : = sum + i;
i:=i+1;
{sum = O + 1 + 2 +
sum := sum + i;
i:=i+1;
{sum = O + 1 + 2 +
sum := sum + i;
i:=i+1;
( sum = O + 1 + 2 +

2}
i = 3}
3

1\

i = 4}

3+4

1\

3+ 4+5

5}

1\

i = 6}

Otro aspecto importante de la verificacin de bucles es demostrar que terminan. Es decir, estamos interesados slo en bucles controlados, bucles que terminan despus de un nmero de pasos finito, independientemente del estado de
las variables en el momento en que empieza su ejecucin. Existen tres reglas de
inferencia diferentes para describir la condicin de terminacin de un bucle,
una por cada tipo de bucle existente. Cada una de estas variantes utiliza el
invariante y la presuncin de terminacin de forma diferente.
Definicin. La regla de inferencia de los bucles.
a)

{ i nv

1\

e} s {i nv}

{inv} while

e do s {inv

1\

-e}

214

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

b)

(inv) s {inv}
{inv) repeat s until B {inv

e)

(inv

B)

1 ~ i ~ n} s {inv}

[ i nv) for i : = 1 to n do s {i nv

n + 1)

La parte a) de la regla dice que si {i nv !\ B} s {i nv} es vlido para una


nica ejecucin del cuerpo del bucle s, entonces {i nv} whi le B do s
{; nv !\ ~B} es vlido para el bucle completo. Obsrvese que la condicin
de terminacin del bucle (~B) est incluida en la expresin de forma
explicita. Los apartados b) y e) son similares, aunque se aplican a los otros
dos tipos de bucles de Pascal.
Reconsideremos el bucle whi le de la Figura 6.16. La regla del bucle nos
permite inferir los asertos siguientes, en los que B es la expresin i <= 5.
:= o;
i :~ 1;
while i <= 5 do
{i nv: sum = Sum i
begin
sum := suro + i;
5Uro

(1, ... , i - 1 ): i

<~

i <= 6)

j:~i+1;

end
{sum

Sum i

{1, ... , i - 1 ): i

<~

i <= 6

A -(

i <= 5) )

Este ltimo aserto puede simplificarse a


{sum

Sum i

{1,

5}: i

.,

i = 6)

utilizando reglas elementales de la aritmtica.


Observando las formas de la regla de los apartados b) y e), podemos ver
que la relacin entre el invariante y la condicin de terminacin son ligeramente diferentes, y reflejan con exactitud el significado de los bucles repeat y
foro Por ejemplo, si reescribimos el bucle de la Figura 6.16 en forma de bucle
repeat, la regla del bucle nos dar lo siguiente:
sum :~ O;
i := 1;
repeat
(inv: sum= Sumi E [1,
sum := suro + i;

i -1):

1 <= i

<~6}

i <= 6

i:~i+1;

until i > 5
{sum = SUII j

{1, ..

o,

i - 1 }: j

<~

i > 5}

Donde la condicin B es ahora; > 5, que especifica la condicin para que el


bucle termine (en lugar de la condicin para que contine, como pasaba en el

Robustez V prueba de los algoritmos

215

bucle wh; Le). De nuevo, podemos simplificar utilizando las reglas de la aritmtica:
{ s um =

SUI!

{1, ... , S}: j /\ ;

6}

Finalmente, reescribiremos el bucle de la Figura 6.16 como un bucle for.


Podemos ver de nuevo que la regla para este bucle alternativo genera los
asertos siguientes:
sum

:~o;

for ; := 1 to 5 do
{ ; nv: sum ~ Sumj

E {1, ... , ; - 1 }: j /\ 1 <~ ; <= 6}


sum := sum + i;
{sum = Su. j E {1, .. , ; - 1 }: j /\ 1 <= ; <= 6 /\ ; = 6}

donde el ltimo aserto se simplifica de nuevo a


{ sum

= Sum j

{1, ... , S}: j /\ ; = 6}

Utilizacin de la induccin en la verificacin del invariante. Hasta ahora, hemos admitido la validez del invariante del bucle muy informalmente. Es decir,
hemos supuesto que el invariante es, sin ninguna duda, vlido para el bucle
que describe. Sin embargo, cuando verificamos un programa, debemos escrutar
la correccin de todos los invariantes del bucle. Cmo podemos hacer esto?
Puesto que cada iteracin del bucle sigue a una iteracin anterior, podemos
utilizar el mtodo de la induccin que se introdujo en el Capitulo 3.
Aqui, la base de la induccin es el nmero ;, de la iteracin del bucle
que se va a ejecutar. Concretamente, es necesario demostrar: 1) Que el invariante se satisface antes de la primera interacin; y 2) Que la satisfaccin
del bucle despus de las ; - 1 primeras iteraciones (es decir, antes de la
; -sima iteracin) garantizan la satisfaccin del invariante despus de la iteracin; -sima (es decir, antes de la iteracin ; + 1). Consideremos de nuevo
el bucle siguiente:
sum :=

o;

for ; := 1 to 5 do
{; nv: SUm = Su", j E {1, ... , ; - 1}: j /\ 1 <= ; <= 6}
sum : ~ sum

+ 1;

Antes de la primera iteracin del bucle; = 1 Y sum = O, por lo que se ve


fcilmente que el invariante se satisface en este caso. Supongamos ahora que el
invariante se satisface despus de ; - 1 iteraciones, para algn ; = 2, 3,
... , 6. Es decir, supongamos que:
sum

Sum j

{1, ... , ; - 1 }: j /\ 1 <= ; <= 6

216

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

Ahora tendremos que demostrar por, induccin, que tras una ejecucin de
todo el cuerpo del bucle, se garantiza que:
sum = SUII j E

(1, ... , ;' - 1 ): j

1\

1 <= ; , <= 6

donde ; , = ; + 1.
Podemos hacer esto examinando el efecto de las instrucciones sobre el
invariante original. Es decir, una simple ejecucin de la instruccin sum :=
sum + 1 conduce a
sum

= ; + Sum j E (1, ... , ; - 1 ): j


= Sum j E (1,
, ;): j
= Sum j E (1,
, (; + 1 ) - 1 } :

SUII

(1,

, ; , - 1 ): j

por reglas algebraicas sencillas. La instruccin; :=;


1 <= ; + 1 <= 6 '" 1 <= ;'

<~

+1

conduce a

puesto que el valor limitador de ; = 5 en el bucle for limita a 6 el valor de


; , . Luego, por induccin, se deduce que el invariante del bucle es vlido, lo
que completa la verificacin del bucle.

6.5.6.

Verificacin formal frente a verificacin informal


de programas

Las tcnicas que se han introducido en este captulo reciben habitualmente el


nombre de tcnicas de verificacin formal. Como es fcil imaginar, la aplicacin
de las tcnicas de verificacin formal a un programa razonablemente largo se
convierte rpidamente en algo inabarcable. Adicionalmente, existe una amplia
gama de problemas de programacin para los que no se han desarrollado
suficientemente las tcnicas de verificacin. El proceso de verificacin formal
de programas est todava en la infancia -hace falta hacer mucho todava
para que pueda utilizarse como una herramienta que garantice la robustez de
los programas.
Sin embargo, existen diferentes niveles de granularidad de programas, en
los que se puede aplicar las tcnicas de verificacin de programas. El proceso
de la verificacin i'!formal parece aportar medios de argumentar, de forma
convincente, sobre la correccin de los programas, evitando muchos de los
inconvenientes de la demostracin lnea-a-linea de los mtodos formales. Este
proceso es similar al que se sigue en Matemticas, en la demostracin de un
teorema, o en una simplificacin algebraica, tal como se vio en el Captulo 3.
Es decir, cuando simplificamos una expresin algebraica, no solemos enumerar
todos los pasos que se siguen ni su justificacin formal en trminos de propie-

Robustez y prueba de los algoritmos

217

dades algebraicas bsicas (asociatividad, conmutatividd, etc.). En su lugar, solemos saltarnos los pasos que son evidentes para el lector, concentrndonos slo
en aquellos esenciales y dificiles de comprender.
Este es el caso de la verificacin informal. En lugar de construir una demostracin completa mediante una prueba tableau, nos centramos en los aspectos
ms complejos del programa, y argumentamos en castellano sobre la forma en
que esas partes complejas satisfacen las especificaciones. As, las nociones de
precondicin, poscondicin e invariante juegan an un papel esencial en este
proceso, pero las argumentaciones sobre la correccin del programa se realizan
ms informalmente.

6.6.

RESUMEN

En este captulo se han presentado las nociones de correCClOn, robustez y


amigabilidad de los programas. En el captulo se ha incidido sobre la utilizacin de la estrategia de resolucin de problemas MAPS, ilustrando su utilizacin en la resolucin de un problema de tratamiento de textos, y otro grfico.
Hemos presentado y desarrollado dos metodologas complementarias para
asegurar la correccin y robustez de nuestros programas: prueba y verificacin.
stas permiten desarrollar buenos programas, aun a los ms escpticos, si
tienen una mentalidad positiva. Es evidente que tendremos que realizar un
anlisis activo de nuestros propios diseos y los programas que resultan a
medida que sean ms complejos los problemas que queremos resolver.
El mtodo de prueba que se ha estudiado en este captulo aporta herramientas que nos permiten adquirir una mayor confianza sobre la correccin de
los programas. Aunque el proceso de prueba no garantiza la inexistencia de
errores, nos ayuda a adquirir confianza en la validez de nuestras soluciones. La
prueba es uno de los fundamentos pragmticos en el campo de la garantizacin de la calidad del software.
Cuando es posible aplicar los mtodos de verificacin estudiados en este
capitulo, garantizan la ausencia de errores. A su vez, inciden en la importancia
de la lgica para la informtica. Es decir, los principios de la lgica y las
demostraciones que se introdujeron en el Captulo 3, son la base notacional y
metodolgica para la combinacin de precondiciones y poscondiciones en la
especificacin de problemas, con las reglas de inferencia en la verificacin de
programas. Sin embargo, la verificacin tiene limitaciones prcticas, y es necesario que las conozcamos bien cuando tengamos que decidirnos entre prueba o
verificacin de programas. En el Volumen JI de esta serie, veremos tcnicas de
prueba y verificacin adicionales.

Computacin l. Lgica, resolucin de problemas, algoritmos y programas

218

Ejercicios
6.7.

Verificar los siguientes grupos de instrucciones, rellenando la precondicin o poscondicin que falta, utilizando la regla de inferencia de la
asignacin:
a) { }

e)

{ }
Write(x>
{saLida ~ 12)

{i ~ O}
i :~ i + 1
{ }

J)

{i ~ 10}
j :~ 25

{i+j=O}
i := i + 1;
j :~ j ~ 1
{ }

g)

i := i + 1
{i > O}
b)

e)

{entrada
Read(x>

d)

{ }

{ }
s :~ s + t
{O <= s)

4 7 5)

{ }

6.8.

Verificar el bucle siguiente, utilizando la regla de inferencia para bucles,


incluyendo una demostracin (por induccin) del invariante.
{L~

(e[1], e[2], .. " e[m], . , e[n]>)

j := 1;
k := 2;

whi le k <= m do
{inv: para todo i in {1, ... , k
if L[k] < L[j] then
j := k;
Min := j

1): e[j] <= e[i] /\ 2

<~

k <= m + 1}

6.9.

Escribir un bucle controlado utilizando una instruccin for o una


repeat y que sea equivalente al bucle del Ejercicio 6.8. Encontrar el
invariante y verificar el bucle resultante.

6.10.

En cada una de las instrucciones siguientes, escribir el aserto que falta


(utilizando la regla de inferencia de la seleccin condicional) de forma
que ste sea vlido.
a)

if a = 1 then b

{b

1}

:~

a else b := a + 1

Robustez y prueba de los algoritmos


b)

{i=nAj=m}
H i = O then j := O else j := 1
{ }

e)

{i = n A j = m}
i f i = O then j

:~

219

{ }

6.11.

Confrontar los procesos de prueba y verificacin como garantes de la


correccin, robustez y amigabilidad de los programas. Qu ventajas
tiene cada uno? Cules son las desventajas? Para el problema de la
Pluviometria del Captulo 5, cul de los dos procesos parece ser
ms adecuado y por qu?

6.12.

Verificar el invariante del segmento de programa siguiente, suponiendo


que s = R2D2 I . Escribir los valores de las variables Count y Loe en
cada iteracin de bucle.
Count := o;
Loe := O;
whi le Loe < Length(S) do
{inv: O <= Loe <= Length(S) A
Coun t = Num i E {1, ... , Lo e}: 'O' <= S[ i] <= '9')
begin
Loe :~Loe+1;
i f (S[Loe] >= 'O') and (S[Loe] <~ '9') then
Count := Count + 1
end

6.13.

Encontrar el invariante del bucle de la funcin siguiente:


function EstaOrdenada (A: Lista): Soolean;
var i: i nteger
begin
EstaOrdenada := true;
for i := 1 to LengthLista(A) -1 do
i f A[ i] > A[i + 1] t hen
EstaOrdenada := false
end

También podría gustarte