You are on page 1of 113

Contenido

Nota del editor

~~~~~I ~di~~':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::.::::::::::::: .....................................................


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

vi

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

Captulo 2.
2.1.

~~~~n~~': .:..~~.~~.i.~~~
2.1.1.

~n'

' ..
2.1.4.
2.1.5.

COMPUTACIN J. 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:
Thcker, A. B.; Bradley, W. J.; Cupper, R. D., Y Garnick, D. K.: Fundamentos de Informtica.
Lgica, resolucin de problemas, programas y computadoras. Madrid, McGrawcHiII. 1994.

2.2.

ariabks tipos estados ..........................................:::::::::::::::::::::::::::::::::::::::::::::::

[1~f~~~~;;;~fi;jiiffL:::~:L::::::::::::::. :. .: : : : : : .:-:':.: ': : .': : : : ': :.:.: : ': : : .: :

~,.2.3 ... Formas alternativas d~ definir fu~'~i'~'~'~~'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


2~~~.ICIO~~~~~~~~~~~~~~~~~~Y'f~~~i~~~'~i~~~~~~~::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

2.2.5. Fu~clOne~ boolean~. enteras, exponenciales y logartmicas ............................. .


~..2.6 ... Senes fimtas y funcIOnes relacionadas ................................................................ ::::

Joyanes AguiJar, L.: Fundamentos de programacin. Algoritmos y estructura de datos. Madrid,


McGraw-HiII. 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 J. Lgica, resolucin de problemas, algoritmos y programas comienza en el Captulo 2,
contina hasta el Captulo 6 (correspondientes a la obra de Thcker y otros) y finaliza en los Captulos 1 a 5 (pertenecientes al texto de Joyanes).

Relaciones entre conjuntos: los diagra;;;~~d~V~~~ .. .. .......... .


y
peraelones entre conjuntos ............................................. .
Propiedades de las operaciones entre cooJ'untos ................ :.................................... .
Conjuntos de cadenas de caracteres
.................................... .

Captmo

i~ rcic~ ~ JLtlj2>: : : : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : : : : : :i: : .: : : : : i: :'.: : :: :


3.1.1.
3.1.2.

Represe~?ciones de ~~ses en castellano utilizando la lgic~'p;~~~'i'~i'~~~i"::::::::::


EvaluaclOn de propoSIciones: Tablas de verdad ................. ..

3.1.3. Tautologas ...........................................................................::::::::::::::::::::::::::::::::::::


3.2.

Madrid, octubre de 1999

3.3.

1
4
4

8
10
1I
13
15
16

18
20

22

24

343328
38
38
41
41
44

47
51

rfi~~~~~~~~t~:::~~~~~a~::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

52

3.2.3.

58

Reftas de

inferenc~: La idea ~~'d~~~~i~~~i6~"'"''''''''''''''''''''''''''''''''''''''''''''''''''''

~.~:t . i~::~~!~~ ~~ ~:,~!~a~:~~ i~'~d~';~~i":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


e;f~~I~! p~~i~~d~~":::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ....................................................
3.3.1. Los cuantificadores universal y existencial
................................................... .

u~~2;222

3.5.

Razonamiento con predicados: prueba por induccin ........................................................... .

~iE~~:~~~~i~;=::::~:::::::::::~::::::::::::::::I::::::::t::::::::::::::::~::::::::::::::::::::::::::::::::::::::::
41
Al'
4:2: ~~i~~:s~:::~::::.~:~~:;~~::::~~:~~:~::~;;~~~;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Captulo ::6.

yUSOUCD ............................................................................... ..

4.2.1.
4.2.2.

Los estados !nicial y ~niIde un alg~ritmo: e~'t;~i~'y"~~id~"::::::::::::::::::::::::::::::::::


Los estados mtermedlOs de un clculo: introduccin de variables ......................... .

54
54
55
61
65
66

69
71

76
76

77
77

78
81

86
86
89'
90
93
93
93

95

vii
vi

viii

Contenido

4.3.

t~;.~~j~~~~~\~;;;;~si:;;~~::::::::::::::::::::::::::::::::::::::::::::::.::::::.:::::::::::::::::::::::::::::::::::::

4.3.2.
4.3.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.

Repeticin y bucles: inicializacin, nvarlanza y terminacIn ................................ .


Tres visiones de la misma solucin al problema .................................................... .

~~~c~~~~~~~~~ig~;ii~i~~~:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

4.4.1. Clculo de ab ........................................................................................................... .


4.4.2. Contar palabras de un texto ..................................................................................... .
4.4.3. Representacin del problema de Las Tres-en-Raya ................................................ .
Ejercicios ........................................................................... ,}.'r: ........................ ..................
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. Arrays de cadenas de caracteres .............................................................................. .

~j!~~iciO;~:.~~.~~~.i.~~.~~~~~.:..~~~~~~~~

.. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Resolucin de un problema utilizando la metodologa MAPS ............................................. .
5.3.1. El dilogo .................................................................................................... ,........... .
5.3.2.
Las especificaciones ................................................................................................ .

~j!~~iCiO~.:.~~~~~~.:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
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. Codificacin ............................................................................................................ .
5.5.2. Prueba y verificacin ............................................................................................... .
Presentacin ............................................................................................................. .
5.5.3.
Resumen ................................................................................................................................. .
Ejercicios .... " ................................... " ..................................................................................... .

Robustez y prueba de los algoritmos ..................................................... ;.......................... ..

~j~~~~~~~n..:..~~~~~~~~.. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Resolucin de problemas de procesamiento de texto, utilizando MAPS: Criptografa ....... ..

R~so~u~in de problemas grficos 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 ................................................................ .

Contenido
97
98
lOO
103
108
111
112

1.2.
1.3.

Concepto de algoritmo ........................................................................................................... .


1.2.1. Caractersticas de los algoritmos ............................................................................ .

113

116
121
126
130

131
131
132
134
134
140

1.4.

1.5.
1.6.

144

146
147
149
150
152
156
156
158
159
161
162
163
166
167
169
169
171
171
173
174
177

1.7.
1.8.

182

!:1~: Datos
g=~~~ tipo
r~Tc~!c~so~i~~~~~
j..:: ::: :::: ::::::: ::::: ::::::: ::::::::: :::::::::::: :::::: :::: :::
carcter y tipo cadena ............................................................................ .

1.4.3.

:!f~~tj,
.

1.~.2.3. Prioridad de los operadores en las expresiones lgicas .......................... .

1.8.2.
1.8.3.

Asignacin lgica ................................................................................................... ..


Asignacin de cadenas de caracteres ..................................................................... ..

r~'::'~~~:~i~t~';'=~ig~~~~::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1.8.1.
Asignacin aritmtica ............................................................................................. ..

~~i:~:~t~~:.~~p~~~~~~~~~~t~f~:~~.L:;;;:;:;;:;;:;:;:;;:;;;;:; ; ;:; ; L:;: ;:; ; ;; : ; ;:; :;:;:; ;:;:;: :; : :;:;: :


H: ~ ~l~ d~:~fi~ {~ : :;:]~;:~I~;"L~: : : :; ::; :;:; ; ;:;:;:;:; :;: ; :; ;:; :; : : :; :; ; ;: :; ;:.; ;:; :;:; :;

Captulo 2.

2.4.
2.5.

178
182
187
196
196
197
202
203
203
206
209
209
212
216
217
218
221
222

Datos, tipos de datos y operaciones primitivas ..................................................................... .

2.6.

La resolucin de problemas con computadoras y las herramientas de

progra~a~i~":

Resolucin dl problema mediante computadora .................................................................. .


Representacin grfica de los algoritmos .............................................................................. .
2.5.1.
Diagramas de flujo .................................................................................................. .
Diagramas de Nassi-Schneidennan (N-S) ................................................................... .

~bl~?~s~~~~~~~~~~~..~:.~:;~~ii~;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;:::

Captulo 3.

Estructura general de un programa ..................................................................... :... :::: .. ::::

!j f.E~j~:;~:~
3.4.2.
3.4.3.

..

Instrucciones de lectura de datos (entrada) ............................................................ ..


Instrucciones de escritura de resultados (salida) .................................................... ..

"tl:tffi~I~~~~;?,
3.5.5.

Interruptores ......................................................................................................... ..

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

Contenido
3.6.

Escritura de algoritmos/programas ....... :................................................................................ .


3.6.1. Cabecera del programa o algontmo ........................................................................ .
3.6.2. Declaracin de variables ............: ............................................................................ .
3.6.3. Declaracin de constantes num~ncas ...... ~............................................................... .
3.6.4.
Declaracin de constantes y vanables caracter ....................................................... .
3.6.5. Comentarios ............................................................................................................. .
3.6.6.
Estilo de escritura de algoritmos/programas .......................................................... ..
Actividades de programacin resueltas ............................................................................................ .
Ejercicios .......................................................................................................................................... .
Captulo 4.
Introduccin a la pro~~amacin estructurada ............. 1..\:................................................. ..

!:i: ~~~:~~~!~:~~?1~::6~~~~::::::::::::::::::::::::::::::::::::::::S:i:::::::::::::::::::::::::::::::::::::::::::: :
4.2.2.

4.3.
4.4.
4.5.

4.6.

4.7.
4.8.
4.9.

Implementacin de los mdulos .............................................................................. .

:~~.1~am~!~~r~~~~~~~~~0~

.. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
4.3.2.
Diseo descendente (top-down) ........................................ :.................................... ..
4.3.3. Teorema de la programacin estructurada: estructuras bSicas .............................. .
Estructura secuencial ............................................................................................................. .
Estructuras selectivas ............................................................................................................. .
4.5.1.
Alternativa simple (si-entonces / if-then) ............................................................... ..
4.5.2.
Alternativa doble (si-entonces-sLno I if-then-else) ............................................... ..
4.5.3.
Alternativa mltiple (segn-sea, caso de / case) .................................................... ..
Estructuras repetitivas ............................................................................................................ .
4.6.1.
Estructura mientras (<<while) ................................................. :.............................. ..
4.6.2.
Estructura repetir (<<repeat) .................................................................................... .
4.6.3.
Estructura desde/para (<<for) .................................................................................. .
4.6.4.
Salidas internas de los bucles ................................................................................. ..
Estructuras de decisin anidadas .......................................................................... ;............... ..
Estructuras repetitivas anidadas ............................................................................................. .
La instruccin ir_a (<<goto) .................................................................................................. .

~:E~~t::~::::::~i~~::~~:~~~?:~:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Captulo 5.
5.1.
5.2.
5.3.
5.4.
5.5.

5.6.
5.7.
5.8.

Subprogramas (subalgoritmos): procedimientos y funciones ........................................ ..


Introduccin a subalgoritmos o subprogramas ..................................................................... ..
Funciones ............................................................................................................................... .
5.2.1.
Declaracin de funciones ........................................................................................ .
5.2.2.
Invocacin a las funciones ...................................................................................... .
Procedimientos (subrutinas) .................................................................................................. .
5.3.1. Sustitucin de argumentos/parmetros .................................................................... .
mbito: variables locales y globales .........................................-............................................ .
Comunicacin con subprogramas: paso 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 p.armetros ......................................... ..
5.5.5. Sntesis de la transmisin de parmetros ................................................................ .
Funciones y procedimientos como parmetros ..................................................................... .
Los efectos laterales ............................................................................................................... .
5.7.1. En procedimientos ................................................................................................... .
5.7.2.
En funciones ............................................................................................................ .
Recursin (recursividad) ........................................................................................................ .

~j~t:~:~i~~e~.~~.:.~.~.~.~~~~~~~.~..~.~~~~~~~.. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

304
304
304
305
305
306
307
308
313
315
316
316

CAPTULO

CONJUNTOS V FUNCIONES

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

En este captulo introducimos las nociones matemticas bsicas sobre los con.
juntos y las funciones, junto con su notacin. Estas nociones son fundamenta.
les para la disciplina de la informtica. Ms adelante veremos cmo los con.
juntos 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 Y 6
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.

414
417

422

* 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.

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


Conjuntos y funciones

res, representan conjuntos que son esenciales para la informtica; todos ellos
estn incluidos en los lenguajes de programacin y las computadoras modernas. En este captulo estudiaremos la correspondencia que existe en programacin entre estos conjuntos y el concepto de tipo. Algunas funciones resultan
de vital importancia en programacin. Entre ellas se incluyen las funciones
discretas, las funciones exponenciales y logartmicas, y funciones que se representan mediante series finitas.
Estudiaremos todas ellas en este captulo, poniendo e~p.ecial inters en destacar por qu son importantes para la informtica.

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 deben satisfacer todos sus elementos, por ejemplo:
{xix es entero y 1 .; x .; lOO}

2.1.

CONJUNTOS

En la vida cotidiana son corrientes las colecciones de objetos o nmeros.


Podemos pensar en la coleccin de personas de nuestra clase, la coleccin de
dgitos y letras de la matrcula de un automvil, o la coleccin de los nombres
de aerolneas que vuelan al aeropuerto O'Hare de Chicago. Estas colecciones,
en el lenguaje matemtico, reciben el nombre de conjuntos. Una descripcin
ms precisa la podemos realizar de la forma siguiente.
Definicin. Un conjunto es cualquier coleccin bien definida de objetos. A

menudo, los objetos que forman un conjunto comparten alguna caracterstica en comn. Un elemento de un conjunto es cualquiera de los objetos
que lo constituyen. Se dice que un elemento de un conjunto pertenece a
dicho conjunto. Si S es un conjunto que contiene el elemento x, para expresar que x pertenece a S escribiremos x E S.
Una de las formas de describir un conjunto es encerrando los elementos que lo
componen entre corchetes {y}. Por ejemplo, el conjunto de los das laborables
de la semana se puede describir como:
{Lunes, Martes, Mircoles, Jueves, Viernes}

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}

X2

2x

.01n 2 -

100n - 3

8000y2 - 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.
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 <p.

(2.1)

{O, 1} es el conjunto de dgitos que se utiliza para escribir nmeros


binarios.

(2.2)

{a, b, c, ... , z} es el conjunto de letras minsculas del alfabeto.

(2.3)

{ +, -,

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

nmero naturales

(2.4)

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

los enteros

{xl- infinito < x < + infinito}

los nmeros reales

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

los enteros mdulos n

{l, 2, ... , 100} es el conjunto de nmeros enteros del 1 al 100, ambos


inclusive.

(2.7)

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

{O, 1,2, 3, 4, 5, 6, 7, 8, 9} es el conjunto cuyos elementos son los


dgitos decimales.

ms importantes.

(2.6)

Definicin.

Las Ecuaciones 2.1 a 2.7 son otros ejemplos de definicin de conjuntos:

*, /} es el conjunto de las cuatro operaciones aritmticas

(2.5)

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:

z,

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

Conjuntos y funciones

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

2.1.1.

Relaciones entre conjuntos: los diagramas de Venn

a)

El orden en que aparecen enumerados los elementos de un conjunto no tie~e


especial relevancia; adems, la duplicidad de elementos e~.'i'edundante. Es deCir,
{a, b, c} y {b, a, c, a} representan el mismo conjunto.' ,.
".
Es bastante habitual que los elementos de un conjunto sean tamblen 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:
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 slmbohza por A e B. SI A es
un subconjunto de B, decimos que B es un superconjunto de A y se simboliza
por A => B. Si se verifica que A # B, Y adems 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), Y el conjunto {O} es un subconjunto de A (y se denota
por {O} e A). Sera incorrecto decir que Oes 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 Ven n 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, .", 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).

b)

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 ' "., x"
cuyos tipos estn definidos por los conjuntos SI' S" "., S"' respectivamente.

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

Supngase que el valor de XI es SI E SI' el valor de x 2 es


sucesvamente. Entonces se dce que la expresin

S2 E S2'

Conjuntos y funciones

y as

representa el estado de las variables x" x 2 , ... , x.. El conjunto de todos los
estados posibles de XI' x 2 , ... , x n recibe el nombre espacio de estados de esas
variables.

1..

j2

"1

-3.1
L.-----r-_____
x

..

Esta importante nocin se ilustra en los Ejemplos del 2.1' al 2.3:


Ejemplo 2.1. Supongamos que un programa de computadora tiene dos
variables i y j, utilizadas como contadores. Ambas tienen como tipo el
conjunto de los nmeros naturales. El estado inicial del programa podra
ser:
i=O

j=O

i=5

Figura 2.2.

Representacin grfica del estado de un programa


espa~io de estados del Ejemplo 2.1. b) U~
estado del espacIO de estados del Ejemplo 2.3.

Ejemplo 2.2. Si los pixels controlados por un programa son XI' X , ... ,
2
XIOOOOOO, un estado de ese programa tendra 1 milln de entradas, una por
cada variable. Por ejemplo, la expresin
=

on

off

X2 =

x'oooooo

Ejemplo 2.3. Considrese un programa con tres variables, las tres del tipo
rea l (la analoga en programacin al conjunto R). Tres posibles estados
de este programa son:

x:= 1.0

Esta instruccin .asigna el valor de 1.0 a la variable x. Si no se ha realizado


nmguna restncclOn sobre las otras dos variables z e y, todo el plano X = 1 es el
conJunt~ de( J?oslbles estados de este programa, despus de que se ejecute la
aSlgnaclOn vease la FIgura 2.3).
y

O, junto con z = O

-3,1

J2 junto con z

n.
Y = 2 Junto con z

-1

. ~onsidrese un programa Con tres variables reales z, X e y (variable rea l


slgm Ica lo m!smO q~~ variable del tipo rea l). Supngase que el programa
conlIene una mstrucclOn de la forma

on

describe un posible estado del programa.

b)

a) Dos estados del

Un estado posterior podra ser

XI

/1

= 1
(

1789

Frecuentemente, es de gran ayuda visualizar el estado de un programa,


como puntos del espacio. Por ejemplo, los puntos de la Figura 2.2 estn representados los dos estados del Ejemplo 2.1. La grfica tridimensional de la Figura 2.2b representa el espacio estado del Ejemplo 2.3, donde se ha marcado el
punto correspondiente a uno de los estados del programa. Cuando en un
programa las variables cambian de estado, el efecto que se produce es como si
nos desplazramos de un punto a otro del espacio de estados.

"

:
:
I

I
I
1.1---1"'-_- x
z
Figura 2.3. El estado x = 1 en un programa
con tres variables reales z, x e y.

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


Conjuntos y funciones

2.1.3.

Operaciones entre conjuntos


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:

Considrense los conjuntos siguientes:

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


{l, 10, 100, 1000, 1O000}

A n B
AvB

T =

Los nmeros 1 y 10 son los nicos elementos que pertenecen 11 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 v 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 n 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.

A \ B

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

{7, 9}

Como ejemplo adicional, supngase que

+ bn, donde b es una constante real}


es un polinomio de la forma n' + c, donde c es una constante real}

{plp es un polinomio de la forma n'

{plp

Dos posi?les elementos ~el conjunto A seran n' + n y n' + 4,5n, mientras que
del B senan n - 3 y n + 7. Las sIgUIentes relacIOnes son ciertas:
A n B
A v B
A

\ B

{n'}

+ bn + c,
donde b = O o c = O}
{plp es un polinomio de la forma n' + bn, donde bolO}
{plp es un polinomio de la forma n'

El conjunto vaco q, es extremadamente til. Por ejemplo, si e es el conjunto de consonantes (excluida la y), y Vel 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.
al

bl
~------------~

Definicin. El complementario de un conjunto S es aquel conjunto S' al


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

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.

el
Figura 2.4.

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


conjuntos A y 8.

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 ;o, O e y.;o, O), YB = {(x, y)lx < O e y < O),
~ntonces A y B son dIsjuntos. Esto se Ilustra en la Figura 2.6, donde las
areas sombreadas representan los conjuntos A y B. Obsrvese que BolA'
puesto que A' = {(x, y Jlx < O o y < O).

,
10

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

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

AnB",BnA
AvB",BvA

A nA' '" <1>

Asociatividad

al

A n (B n
A v (B v

bl

u-simplificacin

e) '" (A n B) n e

e) '"

(A v B) v

AvA",A
Av<1>"'A

AvU",U

Figura 2.5. Representacin mediante diagramas de Venn de:


a) Conjuntos disjuntos. b) Conjuntos complementarios.

Distributividad
A n (B v C) '" (A n B) v (A n e)
A v (B n e) '" (A v B) n (A v el

Leyes de Morgan
y

n-simplificacin

(A n Bl' '" A' v B'


(A v Bl' '" A' n B'

AnA ",A
AnU",A
An<1>"'<1>

Propiedad de la negacin
(A')' '" A

Complementariedad

Ley de exclusin del trmino medio


A v A' =o U

2.1.5.

Figura 2.6. Conjuntos disjuntos.

2.1.4.

Propiedades de las operaciones entre conjuntos

Las operaciones aritmticas entre nmeros tienen determinadas propiedades,


como asocia ti vi dad, 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.

U' - 4l
<1>' '" U

Conjuntos de cadenas de caracteres

El tipo st r; n9 (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, a b, ba, bb J es el conjunto de todas
las posibles cadenas de dos elementos, construidas a partir del alfabeto
{a, b J.

* 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.

20

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


Conjuntos y funciones

resultado de eliminar la parte decimal de x, y para nmeros reales negativos que no sean ya enteros, l_x_1 es el resultado de eliminar la parte decimal y restarle uno. La grfica de esta funcin se muestra en la Figura 2.1!.
Una funcin muy relacionada es la funcin techo I-x-l que se define como el
menor entero mayor o igual que x. Se calcula eliminando la parte decimal
de x, y si x no fuera entero, sumndole uno. Las funciones suelo y techo
tambin se conocen como funciones mayor entero y menor entero, respectivamente.
_:
La funcin valor absoluto puede calcularse en Pascal, directamente, utilizando la expresin abs(x), donde x puede ser una variable o expresin del
tipo rea Lo; nteger. Sin embargo, las funciones suelo y techo no llenen una
analoga exacta en Pascal. La funcin ms prxima es la funcin t runc (x)
que convierte cualquier variable o expresin de tipo rea L en integer eliminando los decimales. Por tanto, trunC<3.14) = 3, y trunC<-3.14) = -3.

Ejemplo 2.20. Supongamos X


la forma siguiente:
f(n)

Definicin recursiva de funciones. Algunas veces es conveniente definir las


funciones en trminos de s mismas. Esta capacidad de autorreferenciarse recibe el nombre de recursin, y las funciones as definidas reciben el nombre de
funciones recursivas.

,
-2

'-1

1
2

4
7

10

Ejemplo 2.21. Considrese la funcin recursiva:

O
1
f(n -

1) + f(n -

2)

cuando
cuando
cuando

n
O
n = 1
n >

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

,,

n f(n)
-0--0-

'1

'2

:3

---'!--+---:---:--.;--

Figura 2.".

f(n)

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 sencillo, extrayendo el criterio de
la tabla para obtener la frmula equivalente f(n) = 3n + !.

f(n)
y

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
valo.r de f a partir del anterio~, no es necesario que conozcamos una regla
explICita 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
feO) = 1, despus lo utilizamos para calcular f(1) = 3 + f(0). Esto puede
hacerse repelldas veces, obtenindose la tabla siguiente:

Formas alternativas de definir funciones

Hemos visto cmo se pueden definir funciones utilizando una frmula, una
grfica xy, una tabla de dos columnas y un conjunto de pares ordenados. Las
funciones pueden definirse de varias formas alternativas.

cuando
cuando

1)

2.2.3.

N, Y que la funcinf(n) se define de

1
3 + f(n -

La funcin suelo l_x_l.

21

1
2
3
4
5
6
7

1
1
2
3
5
8
13
21

26

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


Conjuntos y funciones

Ejemplo 2.24. El Ejemplo 2.23, puesto que p es una funcin uno-a-uno,


tiene inversa. Esta inversa, p - 1, puede definirse de la forma siguiente:

p-'(b)

b
d

p-I(C)

p-'(d)

p-I(a)

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

Ejemplo 2.25. Las funciones uno-a-uno se emplean habitualmente en la


codificacin. El American Standard Code for Information Interchange (ASCII) define una equivalencia numrica entre O y 127 para cada carcter
regular o de control que puede ser pulsado en un teclado estndar de una
computadora. Esta funcin es uno-a-uno. y est incluida en lenguaje de
programacin Pascal con el nombre de o rd (por valor orddinal). Es decir,
para cada carcter que encontramos en el teclado, o rd(x) es un nmero
entero entre O y 127. Los valores ordinales de algunos caracteres familiares
del teclado se pueden ver debajo:
arde 'O') = 48
ord('A') ="65
arde '=') = 61
ord('a') =97

Una lista completa de los caracteres ASCII y sus ordinales correspondientes puede encontarse en el Apndice A.
El propsito de la funcin o rd es definir un esquema de codificacin uniforme para representar los caracteres del teclado. Este esquema lo utilizan
todos los constructores de software y hardware de computadoras. La existencia de este estndar permite el intercambio fcil de informacin entre distintos
tipos de computadoras.
Obsrvese que, para ser eficaz, la funcin ord tiene que ser uno-a-uno; si
un cdigo estuviera asignado a dos caracteres distintos, no existira una forma
consistente de descodificar el cdigo. Puesto que es una funcin uno-a-uno, la
funcin ord tiene en Pascal su inversa, denominada chr (por Character). Si n
es un entero en el intervalo 0-127, entonces chr(n) es el carcter del teclado
correspondiente del entero. Por ejemplo:
chr(48)
chr(6S)
chr(61)
chr(97)

'O'
'A'
= '='
= 'a'
=

ord(chr(n

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


Ejemplo 2.26.

Obsrvese que p-I(p(a ~ p-I(C) ~ a. De forma general, para cubrir


cualquier funcin invertible p: X -> Y, Y cada x E X, p-l(p(X) ~ x. Anlogamente, para cada y E Y, p(p-I(y ~ y.

27

La criptografia (codificacin de mensajes secretos) es un

~ea de la informtica que utiliza muchos de los principios que hemos


dlsculIdo. 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:


VHUJHDQW SHSSHUV ORQHOB KHDUWV FOXE EDQG

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:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
JSATERNICFHPLUGWVYDZOMXQBK

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 criptografia es un
campo de estudio excitante y que encierra grandes desafios. 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 elr la informtica son
finitos. Por ejemplo, el conjunto de caracteres ASCn 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; nteger en programacin es finito. Nociones complementarias
sobre el tipo; nteger se introducen en el manual de laboratorio.

Conjuntos y funciones

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 2 , 2 3 + 1,
X
x' - 5x, y as sucesivamente. La forma general de una funcin polinmica es:

As, si n

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.

2, a 2

al

O, Y a o

1, entonces p(x)

= 2X3 +

1.

Definicin. Sean X = Y = R, y sean j(x) = y La funcin f(x) recibe el


nombre de funcin exponencial con base 2.
0

Ejemplo 2.27. Supongamos que X = Z e Y = {verdadero, faLso}.


Sea j(x) = (O .;; x .;; 100). Entonces, j(1) = verdadero, j(102) =
faLso,J(-I) = faLso, y as sucesivamente. El dominio dejes el de los
enteros y el rango el conjunto {verdadero, faLso}.

3, a 3

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.

2.2.5. Funciones booleanas enteras, exponenciales


V logartmicas
Existen un conjunto de funciones especiales que aparecen con la suficiente
frecuencia en la informtica como para justificar un breve estudio.

29

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


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

2"

-2
-1

1/4
1/2
1
2
4
8
16

1
2
3
4

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 function por funcin asociativa, hashing por asociatividad, aunque
aqu no Jo hemos hecho.

34

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


Conjuntos y funciones

Series finitas y funciones relacionadas

2.2.6.

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


forma. Considrense las relaciones generales siguientes:

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 estimar la cantidad de tiempo y espacio que consumir el programa,
sin necesidad de ejecutarlo. Tales clculos suelen iml?/icar la suma de largas listas de nmeros o expresiones. Para facilitar tod6-~1l0, y otras expresiones relacionadas, se ha desarrollado la denominada notacin sigma. Esta notacin utiliza la letra griega ~ (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:

I f(i)
i=m

,:,

a = al

1=1

,
I= a,

+ 2 + 3 + ... +

(n -

1)

,~3i

o+

+ ... +

,~(3i + 2)

d)

.J,-,

e)

,:," i

f)

i= I

i(3i

2)

3(n -

1)

+ 8 + 11 + ... +

+ ... +

(n -

2)

(n -

+ ... +

(n -

1)

n.

16

33

f(n)

a2

+ ... +

an

(2.19)
(2.20)

+
1)

(3n -

3n.

(3n

+ ... +

(n -

+ 2).

1).

n(3n

(2.22)

11-1

a.

,~ a,

I= 1 a

I", e

1)(3n - 1)

:, a,

,~

,:, a,

,~

+ ... +

:, a,

(2.23)

"

I
I=m+

a,

SI

1 ,,-;; 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 igua"! 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.

,
e)

1)

(2.21)

a,

n.

,
b)

a,

I 1 a,

Ejemplo 2.34. A continuacin, se muestran varios ejemplos de notacin


s'gma:

f(m

Obsrvese la utilizacin de subndices en la Ecuacin (2.20). Este tipo de notacin suele utilizarse para diferencar los elementos de una lista, siendo a, el
primero, a 2 el segundo, y as sucesivamente. Utilizaremos a menudo esta idea
de lista en el diseo de programas.

i=

I== 1 i

.L

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.

a)

f(m)

Propiedades de las series finitas. Las Ecuaciones (2.21) a (2.24) reflejan algunas
propiedades bsicas de las sumas utilizando la notacin sigma.

20

"

35

+ 2).

I"

i= 1

cf(i)

en
e

donde e es una' constante

I"

i= 1

f(i)

(2.25)
(2.26)

36

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

"

L (I(i)

i= 1

+ g(i

L f(i) + i=L" 1 g(i)


i= 1

L (f(i)

i= 1

Conjuntos y funciones

- g(i

(2.27)

,~ f(i)

=1

g(i)

(2.28)

L (f(i

i= 1

1) - f(i = f(n

1) - f(1)

(2.29)

Es posible justificar estas ecuaciones haciendo las consideraciones siguientes:


En la Ecuacin (2.25), el lado izquierdo es el propio valor c sumado a s mismo
n veces. En la Ecuacin (2.26), el lado 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:
(1(2) - f(I

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

1) - f(n

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 re.comend 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:

+
+

(n

1)

+
+

+
1)
1)

(n

(n

+
+

,f:

+ ... +

(n -

1)

trmino a trmino:

99

101

,f:

n(n

1) +

(n

2
(n

+
1)

1
(n

1)

"

1)
(2.30)

+ 1)(2n +

1)
(2.31)

6
i3

n 2 (n

JI 2i

+ W

(2.32)

2n+ 1

(2.33)

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.

+ lOO

2 +

+
+
+

15

+
+

+
+

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

Existe una ancdota interesante sobre esta serie. Carl 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 lOO 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
1 +
2 +
3 +
+ 100 + 99 + 98 +
101 + 101 + 101 +

2)
1)

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):

n(n

Algunas series importantes para la informtica. No suele ser habitual la mode-

(n

1=1
n

3
(n

Puesto que hay n trminos en la suma, el resultado de la suma anterior puede escnbIrSe 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).

donde podemos ver que todos los trminos entre f(n + 1) Yf(l) se cancelan
mutuamente, por lo que el resultado serf(n + 1) - f(I).

37

1
101

20

,~

20

,f:

JI
JI
6

15(15 + 1) ,;,
120
2
20(21)
-2-

6(7)

210 - 21

189

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

54

e)

f)

3.6.

p ""'" (q 1\ -q ""'" p)
(p ""'" q) v (p =- - q)

Demostrar que - (p v q) y (- P 1\

3.2.

q)

tienen la misma tabla de verdad.

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.

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 =- q es bien (verdadero =- verdadero)
bien (falso =- falso) haciendo de p =- q una tautologa. Por el contrario,
supongamos ahora que p =- q es una tautologa, y que S es un estado en que p
es falso. Puesto que p =- 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.

Equivalencia

Tabla 3.2.

Considrese la proposicin (p 1\ q) V (p 1\
tra abajo:
p

verdadero
verdadero

verdadero

falso

falso
falso

falso

verdadero

q), cuya tabla de verdad se mues-

q) V (p

-q)

verdadero
verdadero

falso
falso

==
==

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.

Asociatividad

qAp
qvp

r)
pv(qAr)
p

(q

==

r)
(pvq)A(pvr)
(p

q)

(p

==

-(pvq)
-(pAq)

p=q

pvp

==

pV(pAq)

== verdadero

== P

==

pA
A

p v verdadero
pvfalso == p

==

(q=q)A(q=p)

Ley de la contradiccin

p v ....... p == verdadero

v -simplificacin

-pA-q
-pv-q

Identidad

Ley de la exclusin del trmino medio

==
==

Lcy de la bicondicionalidad

-pvq

Propiedad de la negacin
-(-p)

(pAq)Ar
(pvq)vr

Leyes de Morgan

==
==

Ley de la implicacin

==
==

pA(qAr)
pv(qvr)

Distributividad

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 1\ q) V (p 1\ - q) es en
cierta manera equivalente a p. Por tanto, si en alguna situacin nos encontramos con (p 1\ q) V (p 1\ - 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.

Propiedades de la equivalencia

Conmutatividad
pAq
pvq

(p

55

Teorema. Dos proposiciones p y q son equivalentes y lo simbolizamos


como p == q, si y slo si la proposicin p =- q es una tautologia.

RAZONAMIENTO CON PROPOSICIONES

En esta seccin se analizan algunos aspectos fundamentales del razonamiento


con proposiciones. En este contexto, razonamiento signific'a desarrollo. de nueva
informacin a partir de otra dada, expresada en formade 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.

Lgica

== falso

-simp1ificacin
pAP
.p

== P

Averdadero ==

p A falso == falso
pA(pvq) == p

58

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

11. 2x=1
12. (1/2)2x = 1/2
13. 1/2)2)x = 1/2
14. Ix = 1/2
15. x = 1/2

Lgica

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.1 I 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.

Simplificar la proposicin (p = (q /\ r

(q /\

s:

1. (p
(q /\r /\ (~p
(q /\ s
2. ( ~ p v (q /\r)) /\ (p V (q /\ s
3. ( ~ p v q) /\ ( ~ P v r) /\ (p V q) /\ (p V s)
4. ~P/\p)vq)/\(~pvr)/\(pvs)
5.

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

6.

q /\ (p

3.2.3.

/\ (~p

s)

= r) /\ (~p = 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. Seria deseable encontrar una metodologa que nos permitiera
afirmar cundo una determinada conclusin es vlida -es decir, si es o no una
tautologa- -. 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 operado-

res.

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

59

de demostracin es una extensin de la metodologa desarrollada para simplificar proposiciones. Sin embargo, las demostraciones contienen un ingrediente
adicional de gran importancia: se realiza una inferencia a partir de una suposicin. Las inferencias de una demostracin se realizan aplicando un reducido
conjunto de reglas de inferencia. Es decir, las reglas de inferencia permiten
obtener proposiciones a partir de otras, de las que se conocen si son verdaderas o se supone que lo son. Estas reglas se resumen en la Tabla 3.3.
Definicin. En el clculo proposicional, una demostracin es una secuencia de pasos que sirven para demostrar que una determinada Proposicin p
es una tautologa. Cada paso de la demostracin es bien una Proposicin
ya demostrada, bien una proposicin que se ha obtenido de otra anterior
utilizando una regla de inferencia, o bien una proposicin que se introduce
como suposicin para preparar un paso posterior. Este ltimo tipo de
proposiciones (suposicin) lo simbolizamos ponindolo entre corchetes
cuadrados [y]; todos los dems pasos se acompaan de una justificacin; y
el ltimo paso de la demostracin debe ser la propia p.
La sencilla prueba del ejemplo 3. I 2 muestra que p = p es una tautologa.
Podramos demostrar esto utilizando una tabla de verdad, pero representa una
buena oportunidad para introducir la notacin y estilo de las demostraciones.
Ejemplo 3.12.
1.

[p]

2.

3.

Demostrar p

p:

I
=-introduccin, 1, 2

La primera lnea contiene la suposicin [p]. Al comienzo de la demostracin,


podemos suponer 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 subsiguientes
pueda distinguirse del resto de la prueba. Puesto que suponemos 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 columna de la derecha de la demostracin como justificacin del paso realizado. A continuacin utilizamos la regla
de inferencia de la =-introduccin (sustituyendo p por q en la frmula 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 desarrollada por el matemtico alemn Gerhard Gentzen.


En ella se reflejan las reglas de inferencia que se IHilizan en el razonamiento
normal, y que constituyen las bases de la mayora de los estudios y aplicaciones de la lgica formal. Cada regla de la tabla tiene la forma:
p

60

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

Tabla 3.3. Reglas de inferencia


=>-introduccin

<=>-introduccin

p=q
q=p
p=q

[p]
~q-

p=q

<:>-eliminacin

=>-eliminacin

(modus ponens)
p=p
-p-

q
(modus rollens)
p=q

:::.!L
-p

p=q
p=q
[p]

ralso
-p
'" -eliminacin

/\ -introduccin
p

ralso

ralso
p

v-introduccin

~q

-p-

pAq

pvq

/\ -eliminacin

v-eliminacin

pAq

-q-

-q-

pvq

[p] [q]
pvq r r
r

La proposicin p que aparece encima de la lnea .indica un pa~o. anterior


(su osici u otro) que ya aparece en la demostraclOn. La proposlclOn q que
a ~rece dJ,ajo de la lnea puede obtenerse o s.er inferid~ .en el sIgUIente paso de
demostrai;in. As, la regla denominada =-mtroducclOn en las ,tablas permlle
realizar la inferencia p = q en cualquier paso de la demostraclOn, ~n la que p
a arece como suposicin y q como conclusin en un paso subsIgUIente.
p Una comparacin cuidadosa entre estas reglas y algunas de las proPI~dades
de la equivalencia que se muestran en la Tabla 3.2, pone d~ ~amfiesto a gunas
similitudes interesantes. Por ejemplo, la ley de la blc?ndlclOnal1ad d~daden
la tabla conduce directamente a las dos reglas de mfere~cI~ enomma as
=-introduccin y =-eliminacin de la Tabla 3.3. De forma slmlla~, la ley de la
la Tabla
32 conduce directamente a la regla
de mferencla
.. de
contra d ICClOn
.
.
.
t" de

.
.
SI'n
embargo
muchas
de
las
reglas
de
mferencla
no
lenen
1a '" e llmmacwn.
,
.'
nin n precedente, entre las propiedades de la eqUIvalencIa.
las reglas de inferencia pueden utilizarse como alternal1v~ a las tablas de
verdad en la demostracin de que una determinada proposlclon es una taut?loga. Sin embargo, como veremos ms adelante, las demostracIOnes son mas

1:

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 A -introduccin nos dice que si
hemos demostrado que p y q son tautologas en dos pasos anteriores cualesquiera de la demostracin, en el paso actual podemos concluir que p A 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
q y que p es una tautologa, en el paso actual
hemos demostrado que p
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
ltima 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.

'" -introduccin

p
- p

Lgica

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.
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.
Demostracin deductiva.

Demostrar que p

Ejemplo 3.13.

1.
2.
3.
4.

5.

[p]

q
(q

[q]
p
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-

62

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

Lgica

tracin ser la propia p


y 3.13.

q. Esta estrategia fue utilizada en los Ejemplos 3.12

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 pOdel)lOs ver cmo se
utiliza el modus ponens en una demostracin.
Ejemplo 3.14.

((p
q) /\ (r
r = p
r
p
p = q

1.

2.
3.
4.

5.

= p) M)

6.

7.

Demostrar que ((p

= q) /\ (r = p) /\ r) = q

((p

= q) /\ (r = p) /\ r) = q:

1.
2.
3.

[(p

Demostrar ((p

q)/\ ~q]

q
~p

= q) /\ ~ q) = ~ p

q) /\ ~ q)

~ p:

Suposicin
t\

~p

4.
5. ((p

-eliminacin, 1

/\ -eliminacin, 1
Modus tallens, 2, 3
=>-introduccin, 1, 4

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.
((p

= q) /\ ~ q) =Demostrar,
p:

[(p
p

3.
4.

~q

sin utilizar modus tallens, la proposicin

=q

q)/\ ~q]

5.
6.

~q

7.

falso
((p =q)/\ ~q)

-eliminacin, 1

Suposicin
Modus ponens, 2
3
~ -eliminacin 5, 6
~ -introduccin, 4
=-introduccin, 1, 8

~p

8.

9.

Suposicin
A -eliminacin,

[p]
q

~p

El ejemplo 3.17 es algo ms complicado.


Ejemplo 3.17.

Suposicin
A -eliminacin,
A -eliminacin,
Modus ponens, 2, 3
/\ -eliminacin, 1
Modus ponens, 4, 5
=-introduccin, 1,6

Utilizacin de la /\-eliminacin y modus tollens. En el Ejemplo 3.15 se desarrolla una demostracin utilizando una combinacin de las reglas de inferencia
/\ 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.

63

1.
2.

[p

Demostrar (p

= (q = rl]
[p

3.
4.
5.
6.
7.
8.
9. (p

= (q = r)) = ((p = q) = (p = r)):

= q]

[p]
q
q
r

=r

(p = q) = (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 de.
muestra que (p
q)
(~p
q) es una tautologa (pasos 1-13), y poste.
(p
q) es una tautologa (pasos
riormente se demuestra que (~p v q)
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.

[ ~pvq]
[ ~p]

[p]

4.

p/\

5.

falso
q

6.
7.
8.

p=q
[q]

~p

= =

Suposicin
Suposicion
Suposicin
/\-introduccin, 2, 3
~ -introduccin, 4
~ -eliminacin, 5
=-introduccin, 3, 6
Suposicin

64

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

Lgica

[p]
q

9.

la

11.
12.

13.
14.

p""'q
P "", q

(- p v q) "", (p "", q)
[p "", q]

15.

pv-p

[p]

16.
17.
18.
19.
20.
21.

q
-pvq
[_p]
-pvq
-pvq

22. (p"'" q) "", (_ p v q)


23.

(p"'" q)

=- (_ p v q)

Suposicin

8
"",-introduccin, 9, 10
v-eliminacin, 1, 2
"",-introduccin

Suposicin
Ley de exclusin del caso intermedio
Suposicin
.
Modus ponens, 14, .16 ..
v -introduccin, 17
Suposicin
v-introduccin, 19
v-eliminacin, 15, 16, 18, 19, 20
"",-introduccin, 14, 21
=--introduccin, 13, 22

Demostracin por contradiccin (reduccin al absurdo). La regla de inferencia


de la - -introduccin es la base de una importante estrategia de demostracin
conocida como demostracin por contradiccin. Una aplicacin tpica de esta
tcnica en las matemticas podra ser la siguiente: Sea T un tringulo de lados
2, 3 Y 4. Supongamos que queremos demostrar que T no es un tringulo
rectngulo. Si suponemos lo contrario, que Tes un tringulo rectngulo, podemos concluir por el teorema de Pitgoras que la longitud de la hipotenusa,
elevada al cuadrado, es igual a la suma de los cuadrados de los otros dos lados;
2
2
esto es, 2 + J2 = 4 Sin embargo, 4 + 9 ". 16. Esto conduce, utilizando la
eliminacin, al valor falso. Entonces, por la - -induccin, la hiptesis original
-T es un tringulo rectngulo-- es tambin falsa.
Supongamos que queremos demostrar que p "", q) A p) "", q es una tautologa. Supongamos que es falsa en cualquier caso -es decir, que la negacin es
una tautologa- y analicemos si esta suposicin nos conduce a una contradiccin. Esta es la estrategia seguida en el ejemplo 3.19.
Ejemplo 3.19.
1.

Demostrar p "", q) A p) "", q:

2.

[-(p""'q)Ap)""'q)]
-(-p"'" q)Ap)Vq)

3.
4.

p"'" q) A p)

-q

5.

(p"'" q)

6.

7.
8.

q
Falso

9.

p"'" q) A p) "", q

Suposicin
""'-eliminacin, 1

Ley de Morgan, A-eliminacin, 2


A-eliminacin, 2
A -eliminacin, 4
A -eliminacin, 4
Modus ponens, 5, 6
,...., -eliminacin, 3, 7
--introduccin, 1, 8

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
equivalencia, 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
-(BRDA -W)"", HF
-(-HFv -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.
9.

lO.
11.
12.

W
-BRDvW"", HF
-BRDv W
HF
BRDAHF
(HF A BRD) "", - BRCH
-BRCH

Modus tollens, 2, 5

Leyes de Morgan, 3
v-introduccin; 6
Modus ponens, 7, 8
A-introducCin, 5, 9
Leyes de Morgan, 4
Modus ponens, lO, 11

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

70

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

Esta notacin puede ser la denominada <<lgica de predicados, que no es ms


que una extensin de la lgica proposicional presentada en las Secciones 3.1
y 3.2. En esta seccin se introduce la notacin bsica de la lgica de predicados, junto con las nociones necesarias para trabajar con ella y utilizarla en la
descripcin de los estados de los programas.
Las descripciones de entrada y salida anteriores no son ms que formas
relajadas de predicados. De forma intuitiva, podemos considerar un predicado
como una frase que incluye variables, las cuales, al tener u1J:determinado valor,
convierten la frase en una proposicin.
.
Definicin. Un predicado es un aserto constituido por constantes aritmticas y booleanas (nmeros enteros, reales y los valores lgicos verdadero y
falso); variables aritmticas y booleanas, operaciones aritmticas (=, " etc.);
operaciones relacionales , <;, >, ;:" =, #, E, etc.) y operadores lgicos
(/\, v, ~, etc.), que tiene el valor verdadero o falso dependiendo de los
estados de sus variables.
En Pascal, este tipo de predicados se conocen con el nom bre de expresiones
booleanas, y tienen gran cantidad de usos en programacin.
En la Seccin 3.1 se defini la sintaxis de las proposiciones de forma precisa: Podramos hacer lo mismo con los predicados; sin embargo, en su lugar,
utIhzaremos nuestros conocimientos y experiencia con ese tipo de expresiones
en. otros campos de las matemticas --especialmente lgebra y programaCiOn- Junto con los conocimientos adquiridos sobre proposiciones. Comencemos destacando que cualquier proposicin es tambin un predicado.
Ejemplo 3.22. Las proposiciones siguientes son tambin predicados. Las
expresiones equivalentes en Pascal se muestran a la derecha.
x<lO
x<10
2 + / = 25
i *i + j * j ~ 25
a, < a 2 /\a 2 < a 3
(.[1] < .([2]) .nd (.[2] < .[3])
Obsrvese en el tercer predicado del Ejemplo 3.22 que, aunque no es necesario
utilizar parntesis para representar el predicado, si lo es en la expresin en
Pascal equivalente. Esto es debido a que los operadores /\ y v tienen menor
prioridad que los operadores relacionales , <;, >, etc.). Sin embargo, en
Pascal, los operadores and y or tienen una prioridad mayor que los operadores
relaCiOnales ( <, <;, >, etc.) en una expresin booleana. Por ello, para conseguir una interpretacin equivalente, es necesaria la utilizacin de parntesis '.
Las expresiones siguientes no son predicados:
+ 1
y2<1O#
x := x + 1

* Pra una mayor informacin sobre las expresiones booleanas en Pascal, consltese el
manual de laboratorio.

Lgica

71

i + 1 no e~. un pred!c~do, puesto que no tiene un valor lgico; simplemente es


una expreslOn antmetIca que tIene un valor numrico. y2 < 10 # podra serlo
si hubiera otra expresin a la derecha del smbolo #; pero, tal y como est~
escnta, carece de slgmficado. 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
valores, en un determmado estado, y calcular el resultado utilizando las leyes
de la aritmtica. As, x <.10 se evala a verdadero en el estado x = 1, Y a 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 satisfecho se
le denomina satisfaetible. Por ejemplo, el predicado x < 10 es satisfactible
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 ;:, O v i <; 1 es vlido, puesto que


es verda~ero 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 definicin
de conjuntos. Por ejemplo, en cada una de las definiciones siguientes, el
conjunto definido contiene todos los estados que satisfacen el predicado
que haya la derecha de la barra vertical. El apartado d utiliza cadenas de
caracteres como dominio; el dominio del resto de las variables es el conjunto de los nmeros naturales N.
a)
b)

e)
d)
e)

f)

3.3.1.

{(i,j)li<j}
{(i,j) I i 2 + / = 25)}
{tao, a" a 2 ) I a o = mx(a a 2 )}
{(S" S2) / S, es un prefijo "para S2}
{ti, j) I i < j v j = O}
{(j, j) I i 2 + j2 = 25 /\ 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

que es una permutacin de otra lista A, y que tiene la propiedad de que para
entre 1 y 29, ambos inclusive, e+ 1 <; e. Esta frase es la conjuncin de dos

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

72

Lgica

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.
~ ~ el, contiene 29 predicados de la forma ei+ 1 :( ei, uno por cada entero
entre el 1 y el 29. Es decir. sirve como abreviatura para el predicado

e, +,

(a, b)

Debido a que expresiones ~omo 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.
Vi E {l, 2,
29}: e+l :( ei

e, +, e,
~

---4------------------ x

como

Figura 3.3. Representacin grfica del


predicado V (i, J) E R: i < a A j < b.

o."

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 lo 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):

d)

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 e 2 , es distinto de 9.


Vi E{l. 2..... 21}: e, # 9

b)

Todos los ej entre em y en son nmeros positivos.


Vj

e)

{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 (i. j)

R: i < a /\ j < b

En una lista A = (e,. e 2 .... en) los elementos hasta elj-simo. excluido
l mismo. estn colocados en orden creciente (vase Figura 3.4).
Vi

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,) /\ P(i2) /\ .... donde i,. i2 .... simbolizan todos los valores de i que
satisfacen R.

73

(1

{l, 2, .,., j - 2}: e :( ei+ 1

4)

e,

Figura 3.4,

e)

Ejemplo de predicado.

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


VP. 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 . es un entero (como suele
ocurrir frecuentemente). es posible escribir:
Vi:i<i+

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

74

Lgica

De forma similar, siempre es posible escribir

75

La relacin entre ambos cuantificadores podemos encontrarla en la generalizacin de las leyes de Morgan siguiente:

V R(i) : P(i)
como Vi : R(i)

=;>

P(i). Por ejemplo

(Vi

{I, ... , 21}: e; #- 9)

es lo mismo que (Vi: 1 .;; i .;; 21

=;>

e;

#- 9).

El otro cuantificador de inters es el cuantificador existencial, simb?lizado


por 3. Su significado es existe, o bien. existe. al me.nos o para alg~n. Se
utiliza para abreviar mltiples ocurrencias de disyuncIOnes cuando vanos predicados similares estn relacionados con este operador.
Ejemplo 3.25. Las frases sig~ientes se acompaan con su representacin
abreviada utilizando el cuantificador eXistencial:
a)

Existe un elemento de la lista (e" e2 ,


3iE (l, ..., n -

b)

Los elementos de (e" e2 ,


3j

e)

... ,

I}:e; = O

(3.2)

Ejemplo 3.26.
a)

- 3i

{l, ..., ni: e;

+ b

b3

b)

- 3i

1\

(3.3)

-P(2)

(3.4)

O es equivalente a

Vi

-P(1) v -P(2)

A continuacin, se muestran dos ejemplos concretos:

R : i < O 1\ j < O

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

P(2)) -

1\

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

(l, ... , ni: e; #- O.

{I, ... , 21}: e; #- 9 es equivalente a

Existe alguna fila del tablero que no tiene ninguna pieza.


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

f)

- 3 R(i) : P(i) '" V R(i): - P(i)

-(P(I)

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


E

(3.1)

La Ecuacin (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 interpretacin similar: la frase no es cierto que algn i en
el dominio satisfat:e 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 Morgan, que
fueron introducidas anteriormente en este captulo. Tngase en cuenta que los
cuantificadores utilizados ahora representan abreviaturas de conjunciones y
disyunciones. Por ejemplo, las equivalencias siguientes son interpretaciones vlidas de las Ecuaciones (3.1) y (3.2), cuando el rango de i es el conjunto {l, 2}:

en) no estn todos en orden ascendente.

3 a, b, e #- O: a
e)

en) que es cero.

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

3 (i, j)
)

.. ,

- V R(i) : P(i) '" 3 R(i): - P(i)

Existe una frase en este texto con al menos una falta de ortografia.

Vi

(l, ... , 21):

e; =

9.

A menudo son necesarios ambos cuantificadores para expresar un Untco


predicado. Por ejemplo, supongamos que queremos expresar que, simblicamente, B = {e', e, ,.. , e30} es una permutacin de A = {el' e2 , .,., e30 }.
Supongamos tambin que todos los a; son distintos. Es posible expresar todo
lo anterior como:

3 una frase S en este texto: S tiene al menos una falta de ortografia.


perm (B, A) =

El cuantificador universal, al igual que el existencial, representa una notaci~


abreviada. Por ejemplo, 3 i E {I, ... , ni: e; = O es la notaclOn a~revlada de(e, = O) v (e 2 = O) v ... v (en = O). Es decir, al igual que el cuanttficador untversal
representa una forma abreviada de una secuenCia de operacIOnes and, el cuantificador existencial representa una forma abreViada de secuencias de oro

Vi

(I, ... , 30) 3j

{l, ... , 30)l

e; = ej'

Dicho en castellano, B es una permutacin de A, si para 'cada elemento e; 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).

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

76

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:
N um 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 Sumo que se
utiliz en la Seccin 2.4 (donde se simboliz mediante la letra griega ~). Prod
es similar a Sumo 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:
a)
b)
e)
d)
e)

3.3.3.

{O, .... 3}: i2 > i


Mio i E {O..... 3}: i 2 > i
Max i E {O, .... 3}: i 2 > i
Sum i E {O..... 3}: 2 - i
Prod i E {l, .... 4}: i 2 > i
Num i

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

Variables libres y ligadas

Comprese

Lgica

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

Vi

{l,

o ,

29}: ei+l :( ei

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

{m ....

ni: 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
corresp?ndencia entre predicados cuantificados y bucles de un programa. En
la secclOn 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:
;

:~

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


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

con la expresin cuantificada

77

:~

Tal predicado recibe el nombre de poseondicin de la instruccin i : = O.


Su~ngase que conocemos que. antes de la ejecucin de esta instruccin. las
vanables cumplen i > j A j > 10. El predicado anterior recibe el nombre de
precondiein, debido a que describe el conjunto de todos los estados que pueden darse antes de ejecutar la instruccin.
Definicin. Una poseondicin 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. Una preeondicin para esa instruccin o' grupo de instrucciones
es un predicado que describe el conjunto de estados en los que pueden esta;
todas la~ vanables del programa. inmediatamente antes de ejecutarse la
InstrucclOn o grupo de Instrucciones.

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.

79

Lgica

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

78

Para evitar problemas d.e escritura, en esta y en similares situaciones, es


posIble utthzar la l~strucclOn for 'para expresar la misma idea. Es posible
sustttUlr la sene de instruccIOnes If-then por el bucle siguiente:
vl ido:=true;
for i :~1 to 30 do
if e[i] <~O
then vlido:=false;

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 \fR(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 =(e l ,
e2 , ... , e30 ) Yqueremos conocer si todos los miembros de esta lista son positivos;
es decir, se quiere establecer si el predicado siguiente es vlido:
\f i E {1, ... , 30}: e,

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 contrano examinando los 30 casos de forma individual.
Puede se~Ulrse una estrategia de programacin similar, cuando se implem.enten 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 = (el' e2 , ... ,
e30 ) cuyo valor es cero, puede reescribirse como 3i E {1, ... , 30}: e, = O. Un
bucle para probar la vahdez del predIcado sera:
vlido:=false;
for i

i f (e[1]>0 and (e[2]>0) and ... and (e[30]>0)

then vLido:=true
else vlido:=faLse;

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


e30 ) cuyo valor escero, 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 nume ro), cada
vez que se encuentre un cero en la lista.
nmero:=Q
for i :~1 to 30 do
if e[i ]~O
then nmero:=nmero+1;

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


vlido:=true;
ife[1]<~0

then vlido:=false

to 30 do

then vl ido:=true;

> 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:

:~1

ife[i]~O

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


manual de laboratorio.

if e[2] <~ O
then vLido:=false
if e[30] <~ O
then vlido:=false;

Es decir, el predicado original no es vlido, SI es posible que uno o ms


elementos de la lista cumplan e, .:; O.

Ejercicios
3.18.

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


(1)

O /\ j

1 /\ k

(11)

1 /\ j

1 /\ k

82

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

Lgica

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-mtroducclOn y de a 3-elImmacin recuerdan a las leyes de Morgan (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 io de i, tambin es vlida R(io) =;. P(io)'
Tabla 3.4.

Reglas de inferencia para predicados cuantificados

V-introduccin

V-eliminacin

R"",P

V R(i): P(i)

V R(i): P(i)

R(io) "'" P(io)

3-eliminacin

3-introduccin

V R(i): P(i)

- 3 R(i): - P(i)

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

Supongamos que se quiere demostrar que todos los enteros pares mayores
que 2 no son primos. En este caso, R es el predicado:
i no un entero

1\

(i

> 2) 1\ 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 iD


representativo, que satisfaga R, y demostrando que tambin satisface P. As, la
prueba podra comenzarse:

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.
Caso base: Demostracin de P(l).
Paso de induccin: Demostracin de P(i)

Prueba por induccin. La validez de predicados que contienen cuantificadores,


puede muchas veces establecerse mediante el mtodo conocido por prueba por
induccin (o induccin). Este es un concepto tan importante para la programacin como para las matemticas. Es decir, los mtodos de demostracin inductivos se utilizan en la verificacin formal de programas (vase Captulo 6). La

=;.

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
cualquier i, entonces se demuestra la validez de P(l) =;. P(2) =;. .... Puesto que
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(l). 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, ...}: 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, ... }: P(i) =;. P(i + 1) es posible escribir las expresiones
siguientes, sin ms que sustituir i por diferentes nmeros enteros:

Sea iD cualquier entero par que verifique iD > 2.


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, concluimos que
todos los enteros pares mayores que 2 no son primos.

83

P(l)
P(l)

=;.

P(2)

=;.

P(2)
P(3)

Combinando las dos primeras lneas es posible concluir, utilizando modus poque 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 pol;ible continuar de esta
forma indefinidamente hasta demostrar que Vi E {l, 2, ... }: P(n) es vlido.
nens,

Ejemplo 3.30.
"

j~1 j

n(n

Supongamos que s~ desea probar por induccin que Vn > O:

+ 1)

2 ' ConSIderemos los dos casos:

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

84

Caso base, Demostrar que

n(n + 1)

RHS

I)((i

1)

1)

+1

j=l

1)

(i

Propiedad de

1)

r'

1 -

rl1+1

= --;---

1 -

1 -

(3.5)

Demostraremos que esto implica

+
+

(i

Suponiendo

1)

1)

2(i

+
1)((i

1)

1)

1)

r'

i(i

1)

Sumando r' + 1 a ambos lados de la ecuacin (3.5), obtenemos

Aritmtica
Aritmtica

,+1

LHS

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.

Demostrar que si O < 1 r < 1, entonces

Comencemos con n

O. Los lados izquierdo y derecho (LHS y RHS) de la

ecuacin anterior se convierten en:

,+1

r' +

rn+ 1

i=O

RHS

1 1
1

1 -

i=O

Ejemplo 3.31.

1, para r # 1

i=O

j= 1

2
(i

1, para r # O

,+1

j= 1

i(i

-=-;:

i(i

1 -

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.
j

Esto completara la demostracin del caso base, Supongamos ahora que

,.0

r'

85

i=O

Paso de induccin: Demostrar que


(i

LHS

j= 1

Lgica

r'

,11+ 1

rn+ 1

,11+2

i=O

Ejemplo 3.32. Supongamos que S es un conjunto finito que tiene n elementos. Demostrar mediante induccin que S tiene 2' subconjuntos.

Solucin. Denotemos por P(S) la coleccin de subconjuntos de S. Supongamos que n = O. Entonces, S = <p. Por tanto, P(S) = {<P} 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 2'
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'+1 y los que no-o Cada subconjunto {tI> ~2' ... , t,} es tambin un
subconjunto de T. Por tanto, por hiptesis de la induccin 2' subconjuntos
de Tno incluyen a t,+I' Cada subconjunto que incluye t'+1 puede considerarse como la unin de un subconjunto de {tI> t 2, ... , t,} con {t,+ 1}' Luego
existen 2' subconjuntos que incluyen t,+I' Por tanto, existen 2' + 2' = 2 x
x 2' = 2' + 1 subconjuntos.

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

86

Lgica

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


Sin incluir t n + ,

Incluyendo t n + ,

</>

{tn+ d
{ti' tn+d

{td

{t2}
{t"t 2 }
{t" 't 2 ,

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


definicin no recursiva:
Factorial (n) = 1 x 2 x ... x (n - 1) x n

3.26.

Supongamos que la funcin fIn) se define mediante la siguiente regla:


f(O) = 1
fIn + 1)

{t 2 , tn + ,}
{ti' .t 2 , t n+,}
. ,

2f(n) para todo n > O

Demostrar por induccin que fIn)

tn}

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


... , tn)' La lista de la derecha se ha construido haciendo la unin de cada uno
de los elementos de la lista de la derecha con {tn + ,}. Luego hay exactamente
2n elementos en cada lista.

3,27.

2".

Demostrar la generalizacin de la ley de Margan, siguiente:

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 cientifieo; 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.

(Nota:

"
U
A, significa Ao

u A, u ... u A.)

i=O

(Nota:

n"

A, significa Ao nA, n ... nA.)

i=O

3.28. Verificar las relaciones siguientes utilizando la induccin matemtica:

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.

a)

I:
i ==

b)

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)
1
Factorial (n) = n x Factorial (n -

N se define recursivamente de

1)

para

n > 1

(i(i

"

I:

j=O

e)

I:
i=O

-->

87

n(n

+ 1
n(n

l)(n + 2)
3

1)(2n + 1)
6

n 2 (n + 1)'
4

90

Computacin " Lgica, resolucin de problemas, algoritmos y programas

4.1.

ALGORITMOS V PROBLEMAS

Los conceptos de problemas algortmicos, algoritmos, lenguajes algortmicos y


comportamiento algortmico son fundamentales para la actividad de resolver
problemas con computadoras y, por tanto, para la disciplina de la informtica.
En consecuencia, necesitamos adquirir un conocimiento firme sobre lo que es
un algoritmo (y sobre lo que no es), y lo que es un problema algortmico, con
objeto de llevar a cabo de forma eficaz la actividad de re~o.lver problemas. La
definicin siguiente sirve como punto de partida para esta discusin,
Definicin. Un algoritmo es una lista de instrucciones que realizan una
descripcin paso a paso y precisa de un proceso que garantiza que resuelve
cualquier problema que pertenezca a un tipo determinado, y que termina
despus de que se hayan llevado a cabo un nmero finito de pasos.

Los algoritmos se escriben o disean con el propsito de resolver problemas, o


ms exactamente, problemas algortmicos,
Un problema algortmico es cualquier problema, conceptual o
prctico, cuya solucin puede expresarse mediante un algoritmo,

Definicin.

En la vida cotidiana encontramos muchos problemas algortmicos, tanto dentro como fuera del campo altamente especializado de la informtica, Por ejemplo, una determinada receta para preparar pollo a la cazadora constituye un
algoritmo, mientras que el problema general de preparar pollo a la cazadora es
el problema algoi'tmico asociado. En la Tabla 4.1 se presentan algunos ejemplos comunes de algoritmos y de problemas algortmicos.
Tabla 4,1,

Algunos algoritmos y problemas algortmicos

Algoritmo

Problema algoritmico

Conjunto de instrucciones para tejer un jersey


Un itinerario particular para recorrer el mundo
Un plan de trabajo para cursar una licenciatura

Tejer un jersey.

Dar la vuelta al mundo.


Cursar una licenciatura.

Para cada problema algortmico como cursar una licenciatura, existen


varios algoritmos alternativos que pueden utilizarse como solucin. Por ejemplo, un alumno que desee cursar una ingeniera en informtica, seguir un
algoritmo muy diferente que en el que desee licenciarse en ciencias medioambientales o en filosofia,
En cualquier caso, los algoritmos de la Tabla 4.1 exhiben las principales
caractersticas sealadas en la definicin: exactitud, efectividad y terminacin
garantizada. Cuando se ejecutan determinados algoritmos pueden completarse
en un pequeo intervalo de tiempo, mientras que otros- pueden llevar mucho

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 ent~ros positIvos, uno a uno, no es un algontmo, 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
pnnclplO, cualqUIer algontmo que diseemos para una computadora puede ser
reahzado a mano (supomendoque disponemos del tiempo necesario, una pizarra o sufiCIente papel). En reahdad, 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
prochve a cometer errores que nosotros.
Sin embargo, no todos los algoritmos pueden ser ejecutados por computadoras. Las c?~putadoras slo pueden ejecutar algoritmos que se componen de
aC,clOnes mdlvlduales que pueden entender y realizar. Por ejemplo, la preparaclon 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
f<;ahzar una computadora, de forma que diseemos algoritmos que contengan
solo ese tIpo de tareas,
Como punto de partida, considrese el sencillo modelo computacional de la
Figura 4.1.

L-_EN_T_R_A_D_A~~---+'I
Figura 4,1,

PROCESO

~---+'I

SALIDA

El modelo de computacin entrada-proceso-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 algontmo. En este caso, la entrada puede ser cualquier lista de valores
numricos dentro del rango O a 4. (O = suspenso, 1 = aprobado, 2 = notable,
3 = sobresahente, 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); y el
proceso es (una descnpcln 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 ,. Lgica, resolucin de problemas, algoritmos y programas

Paso
Paso
Paso
Paso
Paso

1. Obtener la lista de calificaciones.


2. Calcular n = nmero de notas de la lista.
3. Calcular Sum = la suma de las calificaciones de la lista.
4. Calcular CM = Sum/n.
5. Mostrar CM.

Cuando se escriben este tipo de descripciones de procesos, se realizan algunas suposiciones tcitas sobre el comportamiento del m?d~lo entrada-procesosalida de la Figura 4.1. La primera hiptesis es que el numero de cahficaclOnes
es indeterminado, aunque nunca infinito. La segunda hiptesis. es que p~ra
poder calcular cualquier cosa sobre las calificaciones, el algontmo 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 fislcamente 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 fisicamente separada del procesador en dispositiVOS como
el tecl~do el monitor o un archivo en disquete. Un diagrama de las unidades
de una co~putadora que se corresponde con el modelo entrada-proceso-salida
puede verse en la Figura 4.2.
Teclado/Ratn

Figura 4.2.

Procesador/

Memoria

1-----+ Pantalla de monitor

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 escntos. Por ejemplo, dlficllmente podramos realizar el Paso 5 sin haber realizado antes los pasos I 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 comp~tado
ra-. Por ejemplo, hemos asumido que la orden Mostrar (Paso 5) esta en el
repertorio de instrucciones de la computadora. Por tanto, siempre que s~ eJecute alguna instruccin que contenga la palabra Mostrar, la mformaclOn de
salida aparecer en el monitor, independientemente de cul sea .el paso que .la
contiene. (En este caso, mostrar aparece muy tarde. No eXiste mnguna restnccin 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 computador~s eJecuta.n las mstrucciones de una forma obediente, comenzando por la pnmera 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.

4.2.

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.

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 /. 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 podra 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 final. 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 precondicin 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 poscondicin del algoritmo (o post). Ambas suelen escribirse utilizando la notacin
convencional de la lgica, introducida en el Captulo 3:
{pre: entrada
del problema}

una expresin que describe todas las posibles entradas

{post entrada =01\ sa Lida = una descripcin de todas las salidas que
pueden darse para cada entrada}
Si denotamos por Notas, la primera calificacin de la lista, por Notas la
2
segunda, y as sucesivamente, la descripcin siguiente es una descripcin precisa del problema de la calificacin media, en forma de precondicin y poscondicin:

Problemas algortmicos y su solucin

Con objeto de enfatizar la e~trecha relacin existente entre la especificacin


de u~ al~ontmo y la descnpclOn del proceso correspondiente, encerramos la
descnpclOn del proceso entre la precondicin y la poscondicin, como se
muestra en la Figura 4.3.
{pr.e: entrada = (Notas" Notasz, o . " ' Notas )
n
AV, E {1, ... , n}:Notas, E {O, ... , 4})
Paso 1.
Paso 2.
Paso 3.
Paso 4.

n > O 1\

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 escrito 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 inicial 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.

1\

n> O

Obtener la lista de calificaciones


CaLcular n = nmero de notas de la lista
Calcular Sum = la suma de las calificaciones de la
l;
Calcular CM = Sum/n

Paso S. Mostrar CM

sta) ~;:c;:;
proceso

{post: entrada ~0A


salida ~ Sum i E {1, ... , n}:Notas;!n}

Especificaciolles

Figura 4.3.

4.2.2.
{pre: entrada = (Notas" Notasz, . "' Notas n )
Vi E {1, ... , n} :Notas, E {O, ... , 4}}
{post: entrada ~0A
salida ~ Sum i E {1, ... , n}:Notas;!n)

95

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 k)~ cambios que se producen en las propias entradas al incorporar v'alores mdlVlduales al proceso de clculo. Por ejemplo, en el algoritmo de CM los
valores intermedios se identifican por n (el nmero de calificaciones); Su~ (la
suma de calIficaCIOnes mdlVlduales, Notas" donde i = 1, "', n); y CM (el promedIO de notas resultante).
Estos valor~s intermedios se identifican simblicamente, puesto que es impOSible predeCirlos prevIamente a una ejecucin concreta del algoritmo. Por
ejemplo, una eJecuclOn 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, capturanos esta nocin de
valor varlable de la suma ulIlIzando 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
algontmo, pero cuyo valor no puede predeterminarse en el momento en
que se construye el proceso del algoritmo.

100

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


Problemas algortmicos y su solucin

{Paso 5. Se muestra CM}


WriteLn('La CM de esas calificaciones es =', CM : 5 : 2)
end [if]
{post entrada =01\
saLida = Su. ; E {1, o . " n}:Notas;ln}
end. {CalculaCM}

B~
Entrada

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 signifi.
cado 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:');

Qntegy

RadLi sta

Figura 4.6. 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 aqu
como comentarios entre corchetes, de forma que la correspondencia entre estos
casos y el grupo de instrucciones Pascal sea fcilmente identificable. La pre.
condicin, 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 correspon.
dencia entre el lenguaje de programacin (como vehculo para describir de
forma precisa el proceso algortmico) y la especificacin (como vehculo para
describir de forma precisa el problema lingstico a resolver).

Lengtt::hlista
Poslista

101

:----~~
Inserli sta

L; st~

DeleteLista

nombrelista [indiceJ

Salida

I+----

C--Rea';"i)

Figura 4.7. 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 progra.
ma, 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 proble.
ma CM, con el objetivo de almacenar una lista de calificaciones completa:
var Notas: lista;

El procedimiento Readl i sta (Notas) obtiene del dispositivo de entra.


da 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:
(32 1 3)

ReadLista (Notas);

La instruccin Wr i te ln indica al usuario qu tipo de entrada se pretende


obtener, y la instruccin Readli sta cumple la tarea de conseguir la lista de
enteros.
Listas. Este programa hace uSQ del tipo lis t a y sus operaciones relaciona.
das, que se resumen en la Figura 4.7. Los programadores pueden utilizar el

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


Notas

(3 2 1 3)

La funcin lenghtlista (Notas) devuelve el nmero de elementos


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

102

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


Problemas algortmicos y su solucin

del elemento devuelto. As, por ejemplo, un caso posible podra ser que LenghtLista (Notas) devuelva el valor integer 4, y Notas[3] devuelva el
valor real 1. Una discusin ms completa de las operaciones sobre Lis ta
mostradas en la Figura 4.7, puede encontrarse en el manual de laboratono. Es
conveniente repasar esta discusin antes de construir programas que utilicen
listas.
Limitaciones del conjunto de caracteres ASCII. Cuando se~ ncorporan asertos
y otros comentarios dentro del texto de un programa, es ne~esario recordar las
limitaciones del conjunto de caracteres ASCII, que es el estandar de los caracteres que se pueden codificar y que utilizan la mayora de los constructores de
computadoras. (ASCII es un acrnimo de American Standard Code for Infor
mation Interchange)* Utilizando un conjunto de caracteres estndar, es pOSI
ble la transferencia de informacin entre computadoras diferentes. (Como entre
Macintosh y PCs de IBM, por ejemplo). La lista completa de caracteres ASCII
y su codificacin se incluye en el Apndice A.
.
.
Los cientficos suelen utilizar letras griegas y otros slmbolos especiales,
subndices, superndices, al escribir expresiones lgicas y matemticas o al
escribir asertos. En el problema de CM se utilizaron, por ejemplo, Notas" 0
y ~ estilo matemtico, continuando con la notacin convencional de los Captulos 2 y 3. Desgraciadamente, esos caracteres no pueden aparecer dentro de
un programa Pascal, por no estar incluidos dentro del conjunto de caracteres
ASCII. Por ello, cuando convertimos un algoritmo en un programa Pascal,
utilizamos un convenio de sustitucin ASCII para la sustitucin de los smbolos
ms comunes, como el de la Tabla 4.2.
Tabla 4.2. Sustitutos ASCII para los smbolos matemticos
Smbolo
matemtico
Notas i

o}; o Sum
,;;
V
3
/\

V
E

Sustituto
ASCII

Significado

Seleccin del i-simo elemento de la lista


Conjunto vaco
Sumatoria
Menor o igual
Cuantificador universal
Cuantificador existencial
Conjuncin
Disyuncin
Pertenencia a conjunto

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 =0/\ n > O
Su. i {1, ... , n}: Notas,

4.3.2.

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


CM es el de bucle.
Definici6n. Un bucle es una secuencia de instrucciones que pueden ejecutarse O, 1 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:
Economa de las expresiones.
Impredecibilidad del tamao de la entrada.

1.

2.

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:
var 91, 92, 93, 94, 95, 96: real;

vaco

S
S
S
S
S
S
S

G=

para todo
existe
/\

or
in

N. del T.: Estndar Americano de Codificacin para el Intercambio de Informacin.

entrada = vacio 1\ n > O


Sum i in {1, ... , nJ: Notas[i]

Repeticin y bucles: inicializacin, invarianza


y terminacin

Notas[i]
Sum

103

:~

:~
:~
:~
:~
:~
:~

O;
S + 91;
S + 92;
S + 93;
S + 94;
S + 95;
S + 96;

Esta alternativa es absolutamente torpe. Si tuviramos q~e extender el problema mnimamente, y necesitsemos sumar 100 calificaciones, la eleccin realiza.'
da 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

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

104

en el momento en que se escribe el programa, de forma que el programa pueda


calcular el valor de Sum para cada valor particular de n, en el momento en que
el programa es ejecutado o, como dicen algun~s, ~orrido: Es .~eclf, en una
ejecucin del programa, n puede valer 6, y en la sigUIente eJecuclOn del mismo
.
..
.
programa 100, en otra quiz 1000.
Lo que necesitaremos es que el lenguaje aporte faCIlIdades que permitan
generalizaciones de dos tipos:

Problemas algortmicos y su solucin

105

S := O;
; := 1;
S:~S+g[i];

;:=;+1;
S

:~S+g[i];

;:=;+1;
S

:~S+g[i];

;:=1+1;
S:~S+g[i];

;:=1+1;

l.
2.

La posibilidad de asignar un umco nombre a una lista de nmeros


arbitrariamente larga.
.
.
La posibilidad de escribir instrucciones o grupos de mstrucclOnes que
puedan ser ejecutados reiteradas veces, pero que sean .su~cepllbles de
ser interpretados de una forma diferente en cada repellclOn.

La primera posibilidad la aporta el tipo Lista, tal y c~mo se d~scribi en la


seccin anterior. La segunda capaCidad la aporta la mstr~~clOn de Pascal
wh i l e, que permite ejecutar reiteradas veces una mstrucclOn,. ?, grupo de
instrucciones, pero con interpretaciones diferentes en ,~ada repellclOn, Esto es
lo que necesitamos para simplificar la torpe construcclOn que nos calculaba la
suma de n valores,
Ilustremos estas capacidades por separado, Supo~gam?s que se declara
slo una variable g, del tipo Lis ta, en lugar de las seis vanables de g1 a g6.
Entonces, es posible cambiar el programa original en la forma SigUIente, sm
cambiar su significado:
var g: Lista;
S := O;
S :~S+g[1];
S :~ S + g[2];
S:~S+g[3];
S:~

S:~
S:~

S + g[4];
S + g[5];
S + g[6];

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


S~

Su- i

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

haciendo una nica declaracin, en lugar de seis.


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

S:~S+g[i];

;:=;+1;
S:~S+g[i];

;:=1+1:
Figura 4.8.

Suma de seis elementos: un paso hacia la generalizacin.

Parec~ como si estuviramos retrocediendo, puesto que ahora tenemos que


escnblr ,:1 doble de mstrucciones, por lo que el nuevo mtodo parece una
locura. Sm embargo, cada pareja de instrucciones a partir de las dos primeras
es idntica:
whiLe b do

begin
5;5; ... ;5

end
Figura 4,9, Forma general de la instruccin whi le: b es una expresin booleana; s; s; ... ; s es cualquier secuencia de instrucciones en Pascal.
S:~S+g[i];

;:=;+1:

y la secuencia entera sigue satisfaciendo la poscondicin,


La instruccin wh i 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 condicin b,
Si el resultado de la evaluacin es verdadero, se ejecuta la secuencia s; S
. ; s una vez, La condicin b se vuelve a evaluar, y si el resultado
de ~uevo verd~dero, 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 termin~
la ejecucin del whi le,
Sin embargo, cuando utilizamos un bucle wh i l e, debemos tomar una serie
de, precauciones inicialesp~ra que ste se ejecute bajo conttoL Es decir, la ejecuclOn del bucl,: debe termmar despus de un nmero firlito de repeticiones, y
una vez termmado, debe satisfacerse la poscondici1, Por esta razn, a los
bucles suele denominrseles 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:
'

:s

106

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

Instrucciones de inicializacin
whi Le b do

begin
5;5; ... ;5
end;

Figura 4.10. Estructura general de un bucle controlado en Pascal.


Por tanto, los requisitos para que un bucle sea controla9-o son que las instrucciones de inicializacin, la expresin booleana b y las instrucciones s; s;
, , ,; 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 i : = 1, la
expresin booleana i <= 6, Y las instrucciones S : = S + 9 [ i] e i : = i + 1,
combinan y satisfacen estos requisitos. Es decir, nuestro ejemplo puede reescribirse como el bucle controlado de la Figura 4.11.
S := O;
i := 1;
while i <= 6 do

begin

Problemas algortmicos y su solucin

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


que fue diseado. Para conseguir este propsito se utiliza un tipo especial 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
guardan una relacin especial con los fragmentos de programas en los que
estn incluidos. El aserto siguiente es un invariante del bucle del programaCM.
{inv: Sum~Su. j in {1, ... , i -1): Notas[j]

; := i

+1

Figura 4.11. Suma de los seis elementos de una lista. Generalizacin.


Obsrvese que en la Figura 4.11 la condicin i <= 6 describe con exactitud la
condicin bajo la cual el bucle debe seguir repitindose, con objeto de conseguir 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 economa 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
wh i l e de la Figura 4.6) es prcticamente idntico al bucle wh i l e 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 restriccin 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

1 <~ i <~n+ 1)

Para demostrar que esto es, sin duda, el invariante del bucle, debemos
comprobar que cada valor de i durante la ejecucin del bucle:
1.
2.

S:~S+g[i];

end

107

S um es la suma de las i - 1 primeras calificaciones en la lista No t a s; y


El valor de i 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 correspondiente
del valor del invariante, puede sintetizarse de la forma siguiente:
Anles
de la

ESlado

Comprobacin del invariante

iteracin

Sum

""

~ Sum j ; n (1,
A1<~1<~5

Sum

.. ,,1}: Notas[j]

Sum

... ,
... ,

3
4

~ Sum j ; n (1,
A1<~2<~5
Sum ~ Sum j ; n (1,
A1<~3<~5

Sum j ; n (1,

A1<~4<~5

Sum

O): Notas[j]

2}: Notas[j]
3}: Notas[j]

Sum j ; n (1, .. " 4}: Notas[j]

A1<~5<~5

,
Puesto que la quinta iteracin no tiene lugar (se produce la salida del whi le,
puesto que i <= 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

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

108

que por s mismo acaba siendo:


Sum~SulI

in {1, ... , nI: Notas[iJ

Cuando el valor de ; alcanza n + 1.


Cul es la relacin entre el invariante del bucle y la secuencia de i~struc.
ciones s; s; ... ; s que constituyen el cuerpo del bucle? Es necesario que
estudiemos en nuestro ejemplo la relacin entre las instruc~ienes

Problemas algortmicos y su solucin

109

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


ficadores h~manos del prog~ama estarn interesados en el cdigo de Pascal, la
precondlclon, la poscondlclOn 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 computadora de la
parte en Pascal del programa que soluciona el problema CM.
progra. calculaCM
uses

Listas;

Sum := Sum + Notas[;];


; := ; + 1

va.
Notas: Li stas;
i, n : integer

y el invariante
Sum~

Su. j

Sum, CM : real;
begin

in {1, ... , i -1}: NotasU]" 1

<~

<~n+

El cuerpo del bucle se ha diseado de forma intencionada con dos objetivos en


mente:
1.

2.

El cuerpo preserve el invariante (valga verdadero).


El cuerpo produzca una progresin hacia la terminacin del bucle.

En general, los bucles no tienen que hacer ni ms ni menos que esto -todo lo
dems es irrelevante.

WriteLn ('Introducir la lista de calificaciones:

ReadLista (Notas);

I);

n := longLista(Notas)
ifn>Othen

begin
Sum := O;
i := 1;
whi le i <= n do

begin
Sum := Sum + Notas[; J;
; := ; + 1
end;
CM := Sum/n

4.3.3.

Tres visiones de la misma solucin al problema

El programa de la Figura 4.6 resulta de la composicin de tres niveles de


lenguaje distintos: el cdigo en Pascal; la descripcin del proceso, que deSCribe
en castellano qu ocurre en cada paso del proceso que deSCribe el programa; y
la especificacin formal que aparece antes y despus de cada paso del proceso.
Los tres niveles juntos suponen un nivel elevado de redundanCia; es deCIr,
expresan los mismos conceptos en tres estilos diferentes -algortmic~ for":lal
(Pascal), algortmico informal (castellano) y declarativo formal (especlficaclO'
nes).
..
Esta redundancia enfatiza el hecho de que una soluclOn programada a un
algoritmo se escribe simultneamente para tres tipos de audiencias:
1.

2.
3.

La computadora.
La gente que disea y lee el programa.
La gente que verifica la correccin del programa.

La computadora slo tiene en cuenta el cdigo en Pascal: la computadora


seguir con exactitud el cdigo al realizar el proceso. Los programadores hu
manos se interesarn por el cdigo en Pascal, los comentarios escritos en
castellano, y las pre y poscondiciones si quieren entender y desarrollar corree

WriteLn( ILa CM de esas calificaciones es

end
end. {CalculaCM}

= 1,

CM : 5 : 2)

Figura 4.12. El programa CM, desde el punto de vista de la computadora.


Los programadores noveles suelen confundir el punto de vista de la computadora con el del lector. Es decir, suelen presentar slo el programa como
solUCIn a un problema algortmico. Sin embargo, esta representacin, por s
mIsma, no es sufiCIente para la construccin y presentacin de programas
fiables.
. Cuando nos .compr?metemos en el proceso de resolver problemas algortmICOS, nuestra mtenclOn debe ser la de desarrollar programas comentados
completamente, de forma que estas anotaciones nos muestren la definicin del
problema original, y los sucesivos pasos que hemos segwido en su solucin.
Para el problema de CM, el programa completo es ms o menos como la
versin mostrada en la Figura 4.13.
'
,
program calculaCM
{esto es un programa que calcula la CM de una serie de una o ms

112

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

{post: SumPa res = La suma de todos los elementos de L con i n.di c~ par !\
SumImpar = la suma de todos los elementos de L con sub; nd, ce lmpar}

4.8. Escribir las instrucciones de Pascal que calculen el promedio de las si~te
temperaturas de la lista del Ejercicio 4.4, asignando el valor a la vanable TemProm. Dar las precondlclOnes y postcondlclOnes de esas lllStruCciones, as como el invariante del bucle controlado que conhenen.

4.9. Escribir las instrucciones en Pascal que cuenten el.llil.mero de

temper~

turas de la lista del Ejercicio 4.4, que estn por debajo de ,,:alor medIO
(TemProm) y dejen este valor en la variable ~ntera ndebaJ~. Escnblr
la precondicin y la poscondicin para esas lllstrucclOn~s.' aSI como. el
invariante del bucle que contienen. Estn esas precondlclOnes relacIOnadas con las poscondiciones del Ejercicio 4.8? Qu sU?lere esto .sobr~
el orden en que esos dos grupos de instrucciones debenan escnblfse SI
las ussemos para resolver el Ejercicio 4.4c?
4.10. Qu mostrara el siguiente fragmento de programa?:
var x, y: real;
m, n, p: integer;
begin
readln (x, m);
read (y);
read (n, p);
wri te (n, x);
writeln (p);
writeln (y, m);
end.

si se le suministrase la entrada siguiente:

Problemas algortmicos y su solucin

4.4.1.

(pre: a y b son enteros


!\

Minlnt ~ a b ;:;;;; Maxlnt}

(a;<O v a =0

b;<O)

(Post: result=a b }

Para los valores de a y b que satisfagan esta precondicin, el resultado ab


podra definirse como:
Definici6n

ab

if b

=aa ... a~

=~

if b > O
if b < O

Lb-a es

MS PROBLEMAS ALGORTMICOS

En esta seccin nos alejamos del ya familiar problema de CM, e introducimos


otros problemas algortmicos junto con sus solucio~es. Estos nuevos ejemplos
ilustran el conjunto de problemas que son s~~cepllbles de soluc~onarse ullhzando una computadora. Tambin nos serVlfan para ]~st~ar como los tres
estilos diferentes (descripcin en castellano de los pasos llldlVldual~s: especificaciones y otras aserciones, y codificacin en lenguaje Pascal) se ullhzan para
realizar una descripcin y resolucin completa del problema.

Clculo de ah

Desarrollemosb un programa llamado Potenci a que calcule la b-sima potencia de a, o a , donde a y b son enteros y el resultado un nmero real. Por
ejemplo,3 escrito como una funcin de Pascal Potencia(2,3) calculara el
valor 2 = 8..
En 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 = O Y b = - 1,
deben ser excluidas, puesto que podran conducirnos a errores computacionales. (En este caso, Potenci a (O, 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
15
enteros al rango - 2 ... 2 15 - 1. Si identificamos estos valores con Mi nlnt y
Maxlnt, respectivamente, entonces las precondiciones de Potenc i a pueden
descartar todos aquellos valores de a o b que conduzcan un resultado que
exceda a Mi nlnt o Maxlnt. Por ejemplo, a = 2 Y b = 16 daran como
resultado 2 '6 , 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.

13.215
23.7
2365 75
35 46 79

4.4.

113

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, cualquier 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 variable 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.

Problemas algortmicos y su solucin

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 ; -sima iteracin del bucle, donde 1 .::; ; .::; b, el valor de P
viene dado por
{ ; nv: P = a'

1 <= ; <= b}

Tabla 4.3. Resultados intermedios para el problema de la potencia

ClcuLo de a b

2
3
4

P
P
P
P
P
P
P
P
P
P

:= a
:= a;
:= P *
:= a;
:= P *
:= P *
:= 8;
:= P *
:= P *
:= P *

~ar~ valor~s inadecuados provoca un erro~ en tiempo de ejecucin; un mensaje


SImIlar a , nteger overf low aparecera en el momtor, y la ejecucin concluir repentinamente.

progra. Potencia;
{Este programa calcula la b-sima potencia de a}
var P: real;
a, b, i: integer;

begin

La salida del bucle se producir inmediatamente antes de la b-sima iteracin


(que nunca tendr lugar). Ahora; = b yel invariante se convierte por s mismo
en P = a b, que est bastante prximo de la poscondicin del problema.

Valor de b

115

P := 1
else
begin
P := ai

Poscondicin
{P

{Pre:entrada = a b 1\ (a <> O or a = O 1\ b <> O)


b
1\ Minlnt <= a <= Maxlnt}
Wri teLnC' Introduc; r dos enteros a y b: 1);
ReadLnCa,b) ;
i1 b = O then

a}

; nv:

{P=a*a}

P = a' A 1 <= ; <= b}


begin
p := P a;

do

i := ; + 1

end;

a;
a
a;
a;
a

; := 1;
while i <= abs(bl - 1

i f b < O then
P := 1/P

end;
WriteLnC'PotenciaCa,b) =',P);

{P=a *a *a *a}

Entonces, si utilizamos la variable; 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 algortmico, tales como el de la Potenc ; a 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 Potenci a, 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 ; a no puede ser comprobada explcitamente por el propio programa, puesto que la accin de calcular a b

{post: entrada

end. {PoteRe; a}

vacio

1\

salida = a b }

Figura 4.14. Un programa que calcula abo


La precondicin (a <> O v a = O 1\ b <> O) podra haberla comprobado explcitamente el programa Potenci 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 poscondiciones, pero de forma que resuelva un problema ms general (es decir,
de forma que haga algo incluso si alguien intrQl:!uce 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

Problemas algortmicos y su solucin

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 podra denominarse programacin pasiva, mientras que la segunda podra denominarse programacin defensiva. En un curso de programacin avanzado o de desarrollo profesional de software, siempre se prefiere la
estrategia 2 sobre la 1. Sin embargo, en un curso introductqrio, donde se estudian por primera vez otros conceptos fundamentales, suele'aceptarse temporalmente la estrategia 1. Este punto es importante y trascendehte. 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; nteger y rea l 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. U na 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 ( I ) 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:

117

Length

Pos

Figura 4.15.

Resumen de las operaciones sobre cadenas


y tipos involucrados *.

En el manua~ d,e laboratorio se realiza una discusin completa de estas


operaCIOnes, A,qUl solo da~emos unos pocos ejemplos que sirvan de ayuda ara
c?mprender como se ut~hzan las cadenas de caracteres en la resoluci~ de
a gunos problemas algontmlcos de manipulacin de textos
decl~:~~i:~c;i~:i~~~:a variable cadena, por ejemplo s, ba~ta con escribir la
var s: stri n9;

Ahor~, p~demos asignar valores a la variable utilizando la asignacin o los


proce 1m lentos Read o ReadLn, de la misma forma en ue lo hacam
los enteros o los reales, Por tanto, podemos escribir inst~cciones com~~ con
s

;=

'Hello World! I O Read(s)

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.

Para conseguir el efecto que se muestra en el centro de la Figura 4 16


~a figura 4.16 muestra el efecto de la utilizacin de varias de las 'op'eraciones. e as ca?enas, tales como Lenght, Pos, Copy, Insert, De lete
Wrl te'l ~bservese qu~ sus nombres son similares a los de las funciones qu~
maannIuPaUI ad alnbhstas (vease Flg. 4,7), Ms detalles pueden encontrarse en el
m
e a oratono,
La longitud de una cadena (valor de la funcin Lenah t)
. 1
el nm
d
"
es, slmp emente
er? e caracteres de que se compone, incluidos los blancos si nos d~
puntuaclOn y otros caracteres especiales del conjunt~ ASCII,
' g

* 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 string cuando hablemos del tipo.

'" N. del T.: En las Figuras 415 y 4 16


h
d'
pues son los mismos ue s
.
. no s~ an tra uCl.do los nombres de las funciones,
incluyen el tipo string~.
uelen tener esas funcIOnes en las Implementaciones de Pascal, que

'Introducir la lista de calificaciones'

118

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

I Input I
'Hello World!

Length(s)
1

ReadCs);

12

poses, w)
~v:a~r~s~:~s~t~r:,~n~g~;~~~~~~~__~~~. 7
'Hello Worldl'

Problemas algortmicos y su solucin

119

mente, se consideran elementos de la palabra a la que se aad


P
11
d
en. or e o, ca a
una de las cadenas siguientes son palabras:
esos

conocer.
'Mundo! '

Podemos escribir las precondiciones y poscondiciones que describen el probl


ema, como sIgue:
'Hello World! 1;
'Hello World!

'1 '

IOUtput I

Inserte', Ciaa', s, 12)

"

'Hello World, Ciaa!

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, '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 funcin 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( 1, 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, Insert(', adis,s,12), literalmente indica que se
debe crear un valor nuevo de tipo string para la variable s incrustrando el
valor' , adi s' en la cadena' Hello wor ld! " 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 castellana
comn. Los signos de puntuacin, tales como puntos y comas, y as sucesiva-

{pre: e~trada ~ 'c[1J c[2J '" c[nJ' A n >~ O A cada c[iJ es


un caracter ASCII}
{post: ent rada = vaca 1\. sa l ida = nmero de pa labras de la entrada}

Un programa que resuelve este problema, utilizando la mayora de las funciones de la FIgura 4.16, se muestra en la Figura 4.17.
program ContadorPalabras'

{El programa ~uenta el n~ero de palabras de una lnea de te t


muestra ,el computo resultante. Se entiende por palabra cua~ o~ y

Fuc~~:~i:e;:l}~~r ~:~~~r~~~~~~~~~~s/;~ebtl:;~iO~a ~uoen e:lt~ f::lc~~l ~~~~~

var s: stri ng;


i, npalabras: integer;
begin
{pre: e~trada ~ 'c[1J c[2J ... c[nJ'
un caracter ASCII}

n >~ O A cada c[iJ es

{Pas~ 1. O~~enemos el texto de entrada}


wr1tln( lntroducir una linea de texto seguida de <RET>'}
Read(s);
Writeln;
1 nse rt ( , 1, s, Lengh t (s) + 1) .
{s~ 'c[lJ c[2J '" c[nJ c[n+'1J' A c[n +1J ~" A n>~O}
{Paso 2. Contamos las palabras del texto}
~pa labras := O;

, .~ 1 .
whi le'i <+ Lengh(s) - 1 do
{inv: np.alabras = palabras contadas para s[l
.
beg,n
... , - 1 J
i f (Copy (s, i, 1) <> " ) and (Copy (s, i + 1, 1) =
npa labras := npa labras + 1 .
i:=i+1;
,
ende
{npalab~as = palabras contadas en s[1 .. n + 1])

1 <~ i

1')

<~

n + 1}

then

{Pas~ 3. Se,muestra el resultado de la cuenta}


wr1~eln( el nmer~ de palabras es', npalabras)
{post. entrada = vaCla 1\ salida = nmero de palabras d
ende {Contadorpalabras}
,e la entrada}

Figura 4.17.

Programa que cuenta el nmero de palabras


de una cadena de texto.

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

120

En el programa anterior, la variable npa Labras 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, u~a comprobacin sobre el final del texto de s. Es decir, el final del texto sera solo cuando
el carcter i -simo sea un blanco, y el i + 1-simo tambin. Este c?~vemo se
verifica para la palabra ms a la derecha de s; es decir, la mstrucclOn:
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 elImmados
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 k~ow I


de s. Ahora, el bucle de bsqueda del paso 2 comIenza con la vanable mdlce
i = 1:
s

1Whose woods these are 1 thi nk 1 know 1

Utilizamos la expresin Copy (s, i, 1) para selecci.onar e! i -simo, carcter de s y Copy (s, i + 1, 1) para seleCCIOnar el 1 + 1-eslmo. ASI, la
expresin combinada:
(Copy(s, i, 1) <>'

1)

and (Copy(s, i + 1,1)

11)

que busca si dentro de s el i -simo carcter es dis,tinto de blanco, a la vez que


el i + 1-simo s lo es. Obsrvese que esta condlclOn es exactamente ~erdadera
cuando se alcanza el final de una palabra, como en el caso en que 1 = 5:
s

1Whose woods these are 1 think 1 know1

Puesto que el contador npaLabras se incrementa slo al final de cada pala:


bra, registra apropiadamente el nmero de palabras de ~ en el devemr de 1
desde la primera posicin del texto hasta el SIgUIente, caracter al final del texto s. Esta posicin se establece ulIlIzando la expreslOn Lenght(s) - 1.

Problemas algortmicos y su solucin

121

As, el invariante del bucle se preserva. A la salida del bucle, el invariante se


convierte en una expresin sobre el valor final de npa Labras, necesaria para
que se satisfaga la poscondicin. Ningn otro valor nos satisfara!
Finalmente, obsrvese la similitud entre las operaciones de las cadenas y las
correspondientes de las lista~, viendo las Figuras 4.15 y 4.17, respectivamente.
Por ejemplo, la funcin de cadenas Lenght devuelve el nmero de caracteres
de una cadena, mientras que la LenghtL i 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, fotografias 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 entramado 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 esquin superior izquierda,
cuando se visualiza el entramado. La localizacin viene dada por un par de
* N. del T.: Aparece aqu 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

.. I. Lo'gica, resolucin de prob Iemas, algoritmos y programas


Computacwn
Problemas algorftmicos y su solucin

123

Sin embargo, al contrario de las listas y cadenas, necesitamos comenzar los


programas que utilizan estas facilidades grficas con la instruccin

Anclaje
} Tamao de la celda

= 20 pixels

StartGrids;

y finalizar el programa con la instruccin


StopGrids;

Figura 4.18.

Un entrama d o d e 3 x 3 celdas y las situaciones de las mismas.

coordenadas xy, teniendo la esquina superior izquierda de la pantalla las coordenadas (O, O).
. .
. nes que pueden utilizarse para
La Figura 4.19 muestra las dlstmtas operacl~dificar el estado de sus celdas.
crear entramados de varios tamao~ ~ t:~a p~demos utilizar esas operaciones
Si declaramos una vanable de tIpo
'. bl
para realizar transformaciones sobre la vana e.

La primera de ellas borra la pantalla y crea dos ventanas, una ventana grfica a
la izquierda y una de texto a la derecha. Todos los entramados que se creen en
el programa aparecern en la ventana grfica, mientras que los textos, entradas
y salidas lo harn en la ventana de texto. Los detalles sobre esas y otras
operaciones grficas se explican extensivamente en el manual de laboratorio.
Al contrario que las variables de tipo Lista o string, las variables del tipo
Gr i d se deben crear y dibujarse en la ventana grfica antes de asignar valores
a las celdas. Por ejemplo, si queremos crear el entramado d para que tenga 3
filas y columnas, con celdas de 20 pixels y anclado en la posicin (10, 10) de la
ventana grfica, escribiremos:
MakeGrid(d, 3, 10, 10, 20);

Inexistencia I Existencia

~;;;;..--

Ce LlOn <f>ole!9>
Ce llOff
Ce llX
Ce llO

Gri d

'-.:~------

GridSize

TurnCellOn
TurnCellOff
TurnCellX
TurnCellO

Esta instruccin crea el entramado d con la forma y tamao idnticos al


entramado de la Figura 4.18, pero teniendo todas sus celdas en blanco. El
resultado se muestra en la Figura 4.20.
Si queremos cambiar de aspecto alguna celda de d, utilizaremos las operaciones TurnCellOn, TurnCellX o TurnCellO. Por ejemplo,
TurnCeLLX(d, 1, 2)

coloca una X en la celda de la fila 1, columna 2. El resultado de esta accin


aparecer inmediatamente en la ventana grfica. Si queremos extender lo ante<[ntegy

(0, O)

Ventana grfica Ventana de texto

(10, 10)

Figura 4.19.

Resumen de las operaciones ms importantes.

(200,200J\
. entre tipo
.
.
os aqu el mismo convemo
y obj'eto que utilizamos entre
* N. del T.: ScgUlrem
cadena y string.

Figura 4.20.

Aspecto de la pantalla para salida grfica.

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

132

problemas grandes ocupa generalmente ms de una pgina de cdigo en Pascal. Segundo, los programas largos tienen, adems de su longitud, alguna otra
caracteristica 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 caractersticas: 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
algortmico!

5.1.1.

l.

Generalidades sobre el mtodo MAPS

En qu consiste esta metodologa de resolucin de problemas algortmicos?


La metodologia MAPS puede resumirse como la sucesin 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 poseo ndiciones 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

Resolucin de problemas algortmicos

133

que tanto las precondiciones como las poscondiciones son interna y mutuamente conSistentes.
Etapa 3: La divisin. Subdividir, de forma sistemtica, el proceso en una

coleccin de pasos diferentes. Repetir este proceso para cada paso hasta
que la subdivisin no tenga sentido. Identificar las relaciones de control
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. Documentar cada paso escribiendo
una breve descripcin de sus objetivos. Asignar un nombre apropiado a
cada nueva variable que incorporemos en cada paso, en funcin de cul
es su cometido.
Etapa 4: Definicin de abstracciones. Determinar cules de los pasos que

hemos utilizado haban sido, a su vez, usados en otra situacin, recolectar


las rutinas que se utilizaron en esa situacin y adaptarlas para reutilizarlas en la situacin presente. En muchos casos, esta tarea implica la construccin de una rutina nueva a partir de otras dos, o incluso construir
una nueva para una utilizacin ms especializada.
Etapa 5: Codificacin. Trasladar a Pascal cada paso individual de nuestra

solucin, identificando rutinas nuevas y reutilizando aquellas que resulten apropiadas para realizar cada paso individual. Conectar cada paso
utilizando la estructura de control apropiada (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 durante el paso 3 para cada
paso individual y las variables correspondientes.
Etapa 6: Prueba y verificacin. Probar o validar de forma sistemtica el

programa Pascal, hacindolo ejecutarse para un conjunto de valores de


entradas, que permita explorar todo el rango de valores permitido por las
precondiciones. Para cada ejecucin, comprobar que las salidas satisfacen
las poscondiciones. De forma alternativa, verificar cuando sea apropiado
alguno o todos los pasos del programa, utilizando tcnicas de demostracin formal.
Etapa 7: Presentacin. Aadir un comentario al comienzo del programa

para clarificar su propsito, escribir el nombre de los autores y la fecha, e


identificar la utilizacin de rutinas que fueron desarrolladas con otro
propsito (e incluso por otros programadores). Preparar 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 especficas. 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 visu_alizan 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 sera 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 nueva 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 reutilizado, 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.

1,

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, whi le y for); los operadores de entrada,
salida y asignacin (read, wri te y :=) y los operadores de cadenas (copy,
pos y length). Se pueden aadir al lenguaje otras rutinas para manipular
listas (ReadL i sta, WriteL i s tal y entramados (Ma keG ri d, Gr i dSi ze y
TurnCe llOn).
Existe una gran variedad de rutinas para diferentes dominios de la resolucin de problemas. Varios de ellos se introducirn en este captulo.

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

Resolucin de problemas algortmicos

135

fundamental para construir rutinas en Pascal es la denominada abstraccin


procedimemal. Siempre q~e hac~mos que una parte de un programa ya existent~ ,se co?vlerta e? una rutma, ~nmero enco~tramos (y definimos) su generalizaclOn mas apropIada, y despues la convertImos, de forma sistemtica en un
procedimiento o funcin de Pascal. Estdiese en el manual de laborat~rio 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:
l. Nombrar la abstraccin. Asignar un nombre que identifique claramente 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 emrada 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 programa existente para el
problema original.

Los pasos l y 2 reciben el nombre de especificacin de la rutina. Su resultado se


muestra en la forma encapsulada siguiente:
Nombre(parmetros)
{pre: expresin con las precondiciones de la rutina}
{post: expresin con las poscondiciones de la rutina}

El paso 3 unifica las especificaciones con el propio procedimiento o funcin de


Pascal, convirtindola en una unidad de programa 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:
= (Notas v Notas z, .. _, Notas) 1\ n > O 1\
V; E {1, ... , n}:Notas, E {O, ... , 4}}
"
{post: entrada ~0" saUda ~ Sum; E {1, ... , n} :Notas;!n}
{pre: entrada

Supongamos ahora que este programa es lo suficientemente importante 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 entrada 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. Cuando nos ponemos a resolver el

136

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


Resolucin de problemas algortmicos

problema observamos que parte de nuestro viejo programa CM puede utilizarse para encontrar la solucin. iNuestra 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 Promedi ol i sta es una buena eleccin, pues indica con claridad lo que
har la rutina. Para el paso 2a, parametrizacin de la eJ).trada 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 resu l 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= (el' el' ... , en) I\n~O" 'Vi E {1, ... , n}:: el es un nmero}
{post: n>O" resultado=Sum ; E {1, ... , n}: e/n
v n = O A resultado = O}

"

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, as 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 Promedi al i 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 Promediol i 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.l y 5.2 se
muestran ambas alternativas.

137

procedure Promediolista (l: lista; val" resultado: real);


uses
listas;

va.
i, n: integer;
sum: real;
begin
{pre: l= (e" e u ... ,
n:= Lenghtlista(l).
ifn>Othen
'
begin
Sum := O;
i := 1;
whi le i <= n do
begin
Sum :~ Sum

en)

n~O

'Vi

{1

)
' ... , n :: e i es un nmero}

+ L[i]'

i:=i+1
'
end;
resul tado := Surn/n
end {if)
,
etse
resul tado := O
{post: n > O A resultado = Sum "
v n = O 1\ resul tado = O}
end; {PromedioLista}

Figura 5.1.

'1
"

,n}:ei/n

Abstraccin de Promedi aL i s ta como un procedimiento.

f En ambas abstracciones hay que destacar algunas caractersticas. Si con;onta~os ambas con el programa original (vase Figura 4.6), a partir del cual
an SI o co~strU1da.s, podemos ver que todas las instrucciones de entrada
~a]da an SIdo su~tltU1das por referencias a los parmetros l y resultado E~
e~lr, a abstracclOn proc~dimental delega la tarea de hacer la entrada . la
~a~da al programa que utl]za la abstraccin resultante. De hecho el progrIma
e e summlstrar los. ~rgument~s apropiados para que sirvan de entrada al
Procelddlmlento,o funclOn, y debe Interpretar de forma apropiada la informacin
de sa I a que este le proporcIOne.
Podemos observar tambin que el fundamento lgico del programa ori inal se ha preservado. En el procedimiento Promediolista (Figura 51) g I
En el a
caso de I funclOn
., P rome. ,e
resultado
d'
l" se asocIa con un parmetro va r,
r ' 0..' s ta (FIgura 5.2), el resultado se asocia con el propio nombre de la
unclOn. Otras vana bIes declaradas en el programa original (Sum i
a~qU1er~n la,categora de v~riables locales dentro de la abstraccin, p~estoYq~~
a Ora solo tIenen un Interes local exclusivo para el clculo del promedio
h En la FIgura 5.2 se puede ob~ervar que el parmetro de salida resultado se
d: reefmPI~.zado por la aSlgnaclOn del promedio resuItallte al propio nombre
~ ~nc~on. -sta es la fon~a en que Pascal permite especificar el resultado
q~e ~ e evo ver ~na funclOn. En otras palabras, el procedimiento PromedlOl,.sta de la FIgura 5.1 y la funcin Promediolista de la Figura 52
son Identlcos.
'

138

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

function PromedioLista (l: Lista): real;


uses

var
i, n: integer;
sum: reaL;

begin
L = (el' el' ... , en) 1\ n? O /\ Vi E {1, , n}:
{1, . "' n}:: e, es un numero}

1\

O 1\

LenghtLista(l);
> O then

begin
Sum := O;
begin
:~

Pro~edioLista := Sum/n;

n ~ O 1\

"hi le ; <= n do
begin
Sum :~ Sum + L[i];
i := i + 1

{post: n>O" resultado = Su. ;


v n ~ O A resultado ~ O)
end; {PromediLista}

Su. i

{1, .. , n}: eJn

end; {PromediLista}

end {if)
else
PromedioL i sta := O
E

{1, ... , n}: eJn

Figura 5.2. Abstraccin de Promediolista como una funcin.

Comprobacin de la integridad de una abs~ra~cin. Ante.s, de utilizar una rutina


que ha sido abstrada en forma de procedImIento o funclOn, debemos,asegurarnos de que hemos realizado correctamente el proceso de abstracclOn. Como
mnimo, esto requiere reestructurar el programa original del que hemos p~rll
do para realizar la abstraccin, y comprobar que el programa sIgue sallsfaclendo las especificaciones originales con la abstraccin realizada. Para el ~rograma
de la calificacin media, esto puede realizarse como se muestra en la FIgura 5.3.

begin
pre: entrada = (Notas u Notas u .. , Notas n )
Vi E (1, ... , n) :Notas, E {O, ... , 4})

prograll 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;
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: rea l;

/\

n> O /\

{Paso 1. Obtenemos la lista de calificaciones}


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}
Wri teLn (' La CM de esas ca l i f i caci ones es =' , CM : 5 : 2)
end {H}
{post: entrada ~0A salida ~ Su .. i E {1, ... , n): NotasJn)
end. {CalculaCM}

Figura 5.3.

1"

1\

begin
Sum := O;
i := 1;

else
PromedioLista := O
{pos t: n > O /\ resu l tado
v n ~ O A resultado ~ O)

Sum + L[i];

+1

endo

.,'
,."

{1, o."' n}:

PromedioLista :=Sum/n;
end {it)

.,hi le ; <= n do
; := i

end;

; := 1;

Sum

139

begin
{pre: L = (e" el' .. "' en) 1\ n ~ O 1\ Vi
Vi E {1, .. , n}:: e; es un nmero}
n := Lenghtlista(l);
if n>O then

Listas;

{pre:
Vi E
n :=
if n

Resolucin de problemas algortmicos

Revisin del programa CM utilizando la funcin Promedi al 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


Promedi ol i sta (Notas, CM)

Lo importante aqu 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 Nota s, y a
visualizar el promedio de notas (pasos 1 y 5, respectivamente, del diseo origi-

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

140

Resolucin de problemas algortmicos

141

nal de la Seccin 4.1). A su vez, el programa ha transferido la responsabilidad


de calcular el promedio a la rutina Promediol i sta 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 ol i s ta 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
(3 2 1 3).

llamarla Sumal i sta y escribir sus especificaciones para una lista arbitraria l
'
como las SIgUientes:

5.2.2.

El programa Potenci a es otro candidato a convertirse en rutina, y podemos conve~tIrlo de programa ~ funcin con facilidad. De las especificaciones
de la SecclOn 4.4.1, la abstracclOn procedimental de Potenci a puede definirse
como en la FIgura 5.6:

Identificacin de rutinas nuevas y definicin


de sus abstracciones

Una destreza importante que se debe adquirir al resolver problemas algortmicos 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 -ilo importante es reconocer la
rutina, no su abstraccin!
En el Captulo 4 introdujimos algoritmos para resolver el problema CM,
para calcular a b , 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 Ca lculaCM (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 recaudacn obtenida en un evento deportivo.
Cmo sera el aspecto de una rutina que realice este proceso? Podramos

SumaLista(l):
{pre: L= (e 1, el' .. ".' e,,> 1\ n ~o 1\ Vi E {1, ... , n}:: e; es un nmero}
{post: result ~ Sum, E {1, ... , nJ: e;}
Figura 5.5.

Potencia(a, b):
{Pre: a y b son enteros
(Post: resultado ~ a b )
Figura 5.6.

Entrada
(3 2 1 3)

--~ 2.25

1\

(a

=1=

Ov a

O 1\ b f=- O)

J\

Minlnt ~ a b ~ Maxlnt}

Especificacin de la abstraccin de la funcin Potencia.

Considrese tambin la posibilidad de encapsular como una rutina el programa CuentaPa labras. De las especificaciones del Captulo 4, la abstraccin
de la FIgura 5.7 resulta evidente:
CuentaPalabras(s):
{pre: : ~ 'e [1] e [2] : .. e [n]' A n >~ a A eada e [i] es un ea reter ASe ll}
{post. resultado = numero de palabras en s}
Figura 5.7.

Salida

Especificacin de la abstraccin que suma los elementos


de una lista.

Especificaciones de la abstraccin CuentaPalabras.

Existen otros muchos fragmento.s de programas que tienen gran utilidad y


que pueden ser convertIdos con facIlIdad en rutmas. Otras cuatro abstracciones sImples pueden ser de utilidad en una gran variedad de problemas algortmICOS que ~rocesan lIstas. Los dos primeros (Figura 5.8) encuentran el lugar
que ocupa (lndIce) el mayor y el menor elemento de los m primeros elementos
de una lIsta L.
MaxLista(L, m):
{pre: L = (e" e~, """' en) n;3- O 1\ cada e; es un nmero}
{post: n>O 1\ V, E {1, """' n}: e j ;3-e; 1\ resultado= j v n =0
resul tado ~ a}

1\

MinLista(L, m):

{pre: L = (e 1 , e~, """' en) n;3- O 1\ cada e; es un nmero}


{post: n > O 1\ V, E {1, """' n}: e j ~e; 1\ resultado= j v n =0
resu l tado ~ a)

Figura 5.4.

Utilizacin de la funcin PromedioL i sta


en el programa CalculaCM.

Figura 5.8.

1\

Especificacin para las abstracciones de MaxLista y MinLista.

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.

,..

function MaxLista(L: Lista; m: integer): integer;


var j, k: integer;
begin
{pre: L = (e 1 , ez' """' e"" .""' en) 1\ n;?; O 1\ cada e j es un nmero}
if (O < n) and (m <~ LengthLista(L) then
begin
j := 1;
for k : ~ 2 to m do
{; nv: Vi E {1, ... , k - 1): e[ j] >~ e [i] A 2 <~ k <~ m + 1 )
if L[k] > L[j] then
j := k;
end
else
j := O;
MaxLista :=j;
{post: n > O 1\ 'Vi E {1, """' n}: e j ;?; el 1\ resultado = j v
n ~ O A resu l tado ~ O)
end;

Figura 5.12.

Abstraccin procedimental de MaxLista(L, m).

145

el ndice del elemento mayor de la sublista de L.


function MaxLista(L: Lista; m: integer): integer

begin
{p~e: L = (el' e u .. "' e m ,

" ' e ..)


1\ n;?: O 1\ cada e; es un nmero}
1f (O < n) and (m <~ LengthLista(L) then
i1 rn= 1 then
MaxL i sta := 1
else i f L[m] > L[MaxL i sta(L, m - 1) 1 then
MaxL i sta := m
else
MaxLista := MaxLista(l, m~ 1)
else

Funciones recursivas: Una alternativa:ci 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 MaxL i S tao 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 MaxL i sta se invoca
a s misma de forma recurrente, con los argumentos L y m - 1. As se activan
una serie completa de invocaciones a MaxL i sta, para poder determinar:

,.

Resolucin de problemas algortmicos

MaxLi sta := O;

{post: n > O 1\ Vi E {1, , n}: e j


n ~ O A resu l tado ~ O)

;:-:

1\

resultado

j v

end;

Figura 5.13.

Implementacin recursiva de la funcin MaxLista(L, m).

Para ilustrar la semntica (el significado) de las funciones recursivas, supongamos que se invoca a la funcin con MaxL i sta (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 ndice 2), se muestra en la Tabla 5.1.
Tabla 5.1.
Invocacin

de
MaxLista

1
2
3
4

4
3
2
1

Sublista
de L

Clculo de MaxLista(L, 4)

Invocacin
activa

(2 5 4 3)
2
(2 54)
3
(2 5)
4
(2)
ninguno

Comparacin

em >MaxLista(L,m-1)
3> MaxLista(L, 3)
4> MaxLista(L, 2)
5> MaxLista(L, 1 )
ninguno

Devuelve

el re-

sultado
2
2
2
1

Cada invocac!?n sucesiva a MaxL i s ta, comenzando por la primera, realiza una comparaclOn entre e m y el valor mximo de la sublista que contiene un
elemento menos, hasta que se realiza 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 list~ de longitud 1. El resultado se pasa a la invocacin 3, por lo que
M~xL, sta comp~ra los valores de e, Y e,. Puesto que , es mayor, la invocaClOn 3 devuelve el mdlce 2 a la llamada 2. La invocacin 2 compara los valores
de e, Y e 3 , determmando que e, es mayor, por lo que pasa a la invocacin 1 el
ndice 2. Aqu se realiza finalmente la comparacin e. > e" devolvindose el
valor 2 al programa que invoc la funcin.
Una forma grfica de ver el proceso de recursin es dibujando una estruc-

146

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

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; nteger y rea l de Pascal, junto con sus operaciones aritmticas y booleanas,
como +, -, <, =, y as sucesivamente. Tambin hemos utilizado el tipo
str;ng 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 ;nteger, real y str;ng.
Tambin hemos aprendido cosas sobre los tipos L; sta y Gr; d, contenidos en bibliotecas, junto con algunas de sus operaciones (ReadL; sta,
L[;], MakeGr;d, 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.

2~ ' ) MaxLista(L, 4)
(0

2~')MaXList(L,3)

(0

2~')MaXList(L, 2)
.

0"

1~

MaxList<L,n

o
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 manu~l 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 ~~ el ya famIlIar estilo de definicin procedimental que se introdujo en la
SecclOn 5.2.1.
ReadL ista(L):
{pre: .entrada = Ce 1 , e u :.", en) cua.lquier secuencia 1\ n ~ O}
{post. entrada = cualquler secuenCla J\ L = (e" e u .. "' en)}
L[ i 1 :
{pre: L = Ce 1 , ez' .. "' en) 1\ 1 ~ i .:;;:; n}
{post: el es un nmero 1\ resultado = el v e i no es un nmero

resultado

O}

WritelnCs" Su . . , sn):
{pre: entrada = cualquier secuencia 1\ Vi E {1, .. "' n}:
o una cadena}
{post: sal ida = cualquier secuencia s l ' s 2 " ' "
. s}
n

Si

1\

es un nmero

poses, t):
{pre: t = 't" tz, ... , tn' 1\ 5= '51' Su . , S .. ' 1\ n ~ O}
{~ost: 5= t j t 1+1... ti+II_1 (1:0;;;; ;:0;;;; i + m - 1:0;;;; n) es la ocurrencia ms a la
lzqulerda de s en t 1\ resultado = i v s no est en t 1\ resultado = O}

Aqu, la nocin cua lqu; er secuenc; a asociada a las rutinas ReadLi s ta y Wr ite l n significan, literalmente, cualquier secuencia de valores de
entrada o salida existentes en el momento en que las rutinas son ejecutadas. En
el c~so de ReadL~sta, l~ notacin entrada = (e" e" .. , en) cualqUler secuencla, slgmfica que existe una lista al principio de la secuencia
de entrad~, segUIda de una secuencia arbitraria de otros posibles valores (que
pue~e no Inc1.U1r mng~no). La utilizacin de cualquier secuencia en la especificaClOn de Wr1 teln, slgmfica que coloca la salida a la cola de todas las salidas
que se hayan generado antes de la ejecucin de la instruccin writeln.

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 rutmas. Tambin debemos ejercitarnos en ser cuidadosos cuando seleccionamos tipos de datos y estructuras para diferentes problemas con
los que estamos familiarizados.
. Hemo~ trabajado ya con los tipos numricos bsicos (rea le; nteger), el
lIpa strlng y con los IIpos Llsta y Array, que se 'utilizan para definir
estructuras lIneales sImples. Sabemos, por la experiencia adquirida, que las
operacIOnes par~ el lIpa rea l tambin pueden aplicarse, aunque con algunas
restncclOnes, al 1 nteger. Sabemos tambin que rutinas con nombre similares
para los tipos L; s t a y s t r; ng, tienen significados similares. Por ejemplo, la
rutma Pos (s, t), que devuelve la posicin donde aparece por primera vez la

148

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


Resolucin de problemas algortmicos

cadena t en la s, es totalmente anloga PosL i sta (x, L), que localiza el


elemento x en L. De forma similar, la referencia L[i J, que selecciona el elemento i -simo de la lista L, se utiliza en la misma forma para seleCCIOnar el
i -simo elemento de un array.
Sin embargo, existen sutiles diferencias entre esas alternativas. ~or ejemplo,
no podemos aplicar operadores aritmticos a valores tipo s t r, ng, aunque
stos tengan connotaciones numricas; instrucciones tales como:
5:=5+'1.5

(donde s simboliza una variable cadena) son inco~~ectas. Del mismo .modo,
podemos leer y almacenar en una lista una colecclOn completa de numeros
reales tanto de un archivo externo como desde el teclado, utIhzando la operacin ReadL i sta. Sin embargo, no podemos hacer lo mismo si queremos leer
y almacenar una coleccin de cadenas. Podemos utilizar un a r r a y en 1ugar 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 i 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 arrays y listas. El mensaje bsico de estos prrafos es que ninguna estructura de dato~ ofre~e todas
las ventajas de otra sin acarrear algunas desventajas. Esta sltuaclOn es tIplca en
la informtica; los profesionales de la informtica se refieren a ella como el
compromiso y las consecuencias de tomar una decisin .

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 c;dena
pero la cadena :epe no ~s un carcter. Continuando con esta lnea de razona~
miento, cada. dlgllo n~menco es. un carcter, pero un carcter individual no
tiene por que ser un dlglto numenco. Por ejemplo, el dgito 3 es un carcter
pero el carcter x no es dgito numrico. Igualmente, si colocamos un nmer;
e~tre comil!as simples tendremos una cadena, pero no toda cadena es un
numero. ASI, '3.5' es una cadena, pero' Ivn' no es un nmero.

5.2.6.

Arrays de cadenas de caracteres

Nos gustara extender l~ potencia y utilidad del tipo s tri ng incorporndolo


d~ntro de la Idea de l, sta. Esto nos permitira aplicar todas las rutinas de
l, stas, que nos son tan familiares, a listas de cadenas de caracteres en la
misma forma en que lo .hicimos en el Captulo 4 con las listas de rea les.
Puesto que el tipo stnng es ms general que el de integer o real es
esperable >Iue el tip~ lista de s tri ng sea de utilidad en una gama de problemas algontmlcos mas ampha que el de las listas de rea les.
Desgraciadamente, no podemos extender la idea de lis t a de esta forma.
Tenemos que Implementar las listas de cadenas utilizando arrays. El tipo
de elementos de un a rray puede .ser establecido arbitrariamente por el programador. Supongamos que escnblmos una frase como una lista de palabras
'
separadas entre s por saltos de lnea. La frase:
Ivn camin 3 kilmetros hasta el colegio a una velocidad de
2,5 ki lmetros por hora

Podra introducirse por el teclado en la forma siguiente:


Ivn RET

camin RET
3 RET
ki lmet ros RET
hasta RET
el RET
colegio RET
a RET
una RET

velocidad RET

Figura 5.15.

Diferencias entre listas, arrays, cadenas y nmeros.

149

de RET
2,5 RET
ki lmetros RET
por RET
hora RET
RET

150

Computacin ,. 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 ~ array[1 100] 01 palabra;
var Frase: listaStrings;

LongitudFrase: integer;
Apalabra: palabra;

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 frase e identificar el
nmero de palabras con la variable Longi tudPa labra, debemos disear el
cdigo que realice esta operacin. Es decir, el cdigo siguiente podra ser la
base de una abstraccin procedimental:
Long; tudFrase := O;
ReadLn<APalabral
while APalabra <> l' do
begin
Long; tudFrase := Long; tudFrase + 1;
Frase [long; tudFrase] := APa labra;
Readln<APalabral
end

'

De forma anloga, es posible implementar inserciones, eliminaciones y bsquedas de palabras aisladas utilizando abstracciones procedurales. De esta forma,
podemos manipular listas de palabras de la misma forma que manipulamos
listas de reaLes, posibilidad que es de gran utilidad en gran cantidad de
aplicaciones.

5.2.7.

Resolucin de problemas algortmicos

1.

151

La in~trucci~ i : = i + 1: del prog~ama Pot en e i a de la Figura 4,14,


una vanable numenca ---es decir, rea l o i nteger.
declarada como un string, la idea de utilizar su

nec~slta que 1 sea


SI 1 hubIera SIdo

~alor en .una operacin aritmtica, como una suma, sera incorrecta,

mcluso SI su valor pudiera ser interpretable como un nmero (por


ejemplo, la cadena 2 . 2 ').
2. La expresin Copy(s, i, 1) <> ", del programa ContarPalabras 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 tri ng, puesto que el resultado debe ser comparado (utilizando el operador < con
la cadena , .
3. La instruccin Tu r n Ce l L ( t a b Le ro, i, j), del programa de
las Tres-en-Raya. de l~ Figura 4.21, necesita que sus argumentos
sean de los tipos grld, lnteger e integer, respectivamente.
Supongamos que queremos reinterpretar un valor de un tipo como valor
de otro dIferente '-por ejemplo, interpretar la cadena' 2.5' como el nmero
real 2.,5-. Para hacer esto en un lenguaje fuertemente tipificado como Pascal,
necesItamos utlhzar una rutina especfica 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 estan defimdas 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 A cdigo
se realiza con xito
str(r, s);
{pre: r es un nmero real}
{post: s es la cadena equivalente a r}

O si la coercin

Tipificacin fuerte y coercin

,.

l""

j;1
lo,

Es complicado 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:

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 slempr~ que sea necesario como el real 1 O. Las rutinas siguientes convIerten un ,numero real en entero, bien redondendolo al entero ms prximo,
bIen truncando lo, respectivamente.
round(x);
{pre: x es un nmero rea l}
{post: resultado ~ lx + O.5J)
trunc(x):
{pre: x es un nmero real}
{post: resultado~lxJ}

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

152

Resolucin de problemas algortmicos

b)

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 tege r j.

153

progra .. fn;

var
k: integer
function nd (m: integer): integer;

var

n: integer;
begin
:~

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.

nd := O;
n := m"

while'n >= 1 do
begin
n:=ndiv10;
nd
end

:~

nd

+1

end"
begin'
whi le not eof do
begin
re~dln (k);

wrlteln ('ans

= "

nd(k

end

end.

5.2. Implementar la rutina SumL i sta definida en la FI'gura 55


f
.. d P I '
. ,como una
unClOn e asca. Prob~r que la funcin puede reutilizarse para con seg~Ir una lmplementaclOn alternativa del procedimiento Promedio-

L = (Enero 2,5

Septi embre 6,0


Febrero 4,4

Llsta, dIferente a la de la Figura 5.1.

Mayo 2,1

Junio 1,3
Novi embre 0,3
Di ei embre 2,2
Jul io 5,9
Marzo 0,3
Abril 5,7
Agosto 1,0
Octubre 0,0)

5.3.

~on~truir una funcin, a la que llamaremos MaxFactor que calcule


e maXImo factor de un entero n que sea menor ue l ' .
ejemplo, MaxFactor(100) = 50, MaxFactor~15e) ~OflO nM(po~
Factor(13) =1),
,yax

5.4. Supongamos que A, B Y C representan la longitud de los lados de un

,.,..

1
tnangulo. ConstrUIr una funcin que devuelva t rue si A By C
, s o n os
lados de un tringulo rectngulo.

>'

,..

"
1

Ejercicios
5.1.

5.5. ~n qu condiciones puede convertirse un procedimiento en una fun~lOn e~uRIvalente? En qu condiciones puede realizarse la operacin

Describir qu es lo que hacen los programas siguientes:


a)

function naoz (l: lista) : integer;


va.
i:integer;
begin
naoz := O;
for i :~ 1 to LengthLista(L) do
i f L[i] ~ 0,0 then
naoz := naoz + 1;
end;

Inversa.

azonar la respuesta.

5.6. Convertir el programa factorial del Ejercicio 4.22, en una funcin.


5.7.

~mp~m~n~ar como un procedimiento de Pascal la abstraccin Con.a r a a ra (s) de la Figura 5.7. Comprobar su integridad reutili~an~~lal P4ar(a. resoh:er el programa original que contaba palabras del
apI u o
vease FIgura 4.17).

Resolucin de problemas algortmicos

3.
5.19.

5.3.

157

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

156

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 false en caso contrario. La funcin se llamar Prueba
y tiene que tener un parmetro para el nombre de la l; sta, 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.

RESOLUCiN DE. UN PROBLEMA UTILIZANDO


LA METODOLOGIA 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 construir 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. As, 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. 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?
2. 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?

4.

En la salida, deben apare~er. los meses con pluviometra inferior al


promedIO, en. orden cronologlco, en orden de ndices pluviomtricos
relaltvos o, sImplemente, en el mi~mo orden en que aparecieron las
lecturas en la entrada? Es necesano escribir el valor medio di' d'
pluviomtrico?
e m Ice
pu;de ocurrir que ms de un mes tengan el valor pluviomtrico ms
alto. En ese caso, debe mostrar el algoritmo el nombre de todos eso
meses?
s

Tratando de clarificar lo anterior.' suele ser conveniente dar una muestra de la


entrada y de la sahda corres~ondlente del problema; una imagen vale ms que
mIl palabras! Los ejemplos sIrven para resolver de forma visual muchas de las
preguntas antenores, e mclus nos proporcionan pistas sobre cmo debemos
resolver el problema. En la FIgura 5.16, la entrada se presenta en una lista
senctlla, ~ el programa debe distinguir entre nombre de meses (entradas de la
hsta ~o~ mdlces Impares 1, 3, 5, ... ) Yvalores pluviomtricos (entradas de la lista
con mdlces pares 2, 4, 6, ... ).
SALIDA

ENTRADA

ESTADISTICAS PLUVIOMETRICAS

(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
Diciembre 2,2)

med; a = 2,64
mxima = 6,0
minima = 0,0
Meses por debajo de la med; a:
Enero

Marzo
Mayo
Junio
Agosto
Octubre
Noviembre
Diciembre
Mes(es) mxima:

Septiembre

Figura 5.16.

Ejemplo de entrada y salida para el problema


de la pluviometra.

Sin embargo, la entrada y salida para este problema pueden presentarse


de otras maneras. Dos alternativas razonables se muestran en la
FIgura 5.17. En una de las alternativas, la entrada se sUlJlinistra 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 pluvlOmetra estn suministrados en orden cronolgIco --es d~ctr, la pnmera entrada es el valor de enero, la segunda el de
febrero, y aSI sucesIvamente.
p~rfectamente

Resolucin de problemas algortmicos

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

158

(Enero, Febrero
Marzo, Abr l
Mayo, Junio

Jul io, Agosto


Septiembre, Octubre
Noviembre, Diciembre)

(2.5 4.4
0.3 5.7
2.1 1.3

2.5 4.4
0.3 5.7
2.1 1.3

,.-

5.9 1.0
6.0 0.0

5.9 1.0
6.0 0.0

0.3 2.2)

0.3 2.2)

b)

a)

-Figura 5.17. Dos representaciones alternativas d~ la entrada para el pro~lem.a


de la pluviometra. a) Dos listas de entrada. b) La lista de los valores pluvlometricos como nica entrada.

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
(m" m" ... , m,,) 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, debe ser generada de alguna forma por el programa en forma de un
array de doce posiciones). Es decir, el hecho de que m, = Febrero y que e, =
4,4 significa que el valor pluviomtrico de febrero es 4,4 Its/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 podra
no estar escrita con la misma precisin y brevedad.

5.3.3.
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 clanficar 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 siguiente:
{pre: entrada = (e" e u .. "' e, .. ) A 'Vi E {1, .. "' 12} e; es el valor
pluviomtrico del ;-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, el valor 4.4 lts/m' (el
valor pluviomtrico 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 satisfara la precondicin.
La poscondicin para este problema puede definirse de la forma siguiente:
{post: entrada ~0A saL ida ~ ESTADISTICAS PLUVIOMETRICAS
media ~ SUII i E (1, .. ,12): e/12
mxima = "ax ; E {1, ... , 12}: e;
minima = "in i E {1, .. "' 12}: el
Meses por deba j o de la med a:
{m;: e; < Su.i E (1, .. ,12): eJ12}
Mes (es) maX. ; ma:

{m,: e;

lIax i E {1, .. , 12): e i

1~j~12} }

159

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 los 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 p Luv i omet ra s) y a las
variables principales PLuvometraProm, MaxPLuviometra y MinPL uv i omet ra) 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 formall11ente (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.

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 subpasos. En nuestro ejemplo, los pasos 1 y 2 pueden ser subdivididos
nuevamente para clarificar sus objetivos individuales. .
Estas nuevas subdivisiones pueden verse en la Figra 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

Paso 1.2. Leer lista de valores pluviomtricos

Paso 2. Mostrar pluviometra promedio, mxima y mnima

Paso 2.1. Calcular y mostrar pluviometra 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

ReadL i S ta para el paso 1.2. Podemos combinar dos rutinas, Promedi 0Li sta 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 i s ta y WriteLn para el paso 2.2, y las rutinas Mi nL i sta y Wri 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 algortmicos, 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 RI Y R2
son dos rutinas ya existentes, el empalmado de ambas crea una rutina nueva R,
que se compone de RI 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 se 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 y: Learning to program: Learning to construct mechanisms and explanaCommunicarions of the ACM (septiembre 1986),29(9): 850.

tions~~,

Resolucin de problemas algortmicos

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

164

mismo. Obsrvese que se pierde la asignacin del valor promedio a la variable


PluviometraProm, que se realiz en el empalmamiento mostrado en la figura 2.21.

165

procedure MaxMinL;sta(L: Lista; var Max, Min: real);


R

if (O<m) and

Rl

(m<~

LengthLista(L

then

begin

Rl

PluviometraProm:= PromedioListaepluviometrias)

R2

WriteLnC 'media

j :~ 1
for k : = 2 to m do

ifjL~!]~\L[j]_
then
_

R
=

1, PluviometriaProm}

1.-:

end

else
j := O;

Figura 5.21.

Creacin de una rutina nueva R empalmando


las rutinas R1 y R2.

R2

WriteLn( 'media =

Rll

1,

promedioListaePluviometrias>!

Figura 5.22.

~XL ; sta

Creacin de una rutina nueva R por anidamiento


de R1 y R2.

:=y

~ ~nLista ::J:>
Figura 5.23.

------@

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

Adaptacin. Es posible crear una rutina nueva R adaptando otra Rl ya existente. Es decir, el propsito original de Rl puede ser ligeramente modificado,
generalizado o particularizado de forma que realice la funcin requerida por R.
Supongamos que adaptamos la rutina MaxL i sta (que encuentra la posicin
que ocupa el elemento mximo de una lista) para utilizarla como una rutina
Mi nL i sta (que encuentra la posicin que ocupa el elemento mnimo de una
lista). Qu necesitamos modificar en rutina MaxL i sta de forma que cumpla
las especificaciones de Mi n Li s t a? Es casi evidente que es necesario realizar
unas modificaciones mnimas, y el resultado se obtiene mucho ms rpida y
fcilmente que si la construyramos de cero. Las modificaciones se resumen en
la Figura 5.23.

if (O < m) and (m
begin

Mezcla. Se puede construir una rutina nueva R mediante la mezcla o entrelazamiento de los pasos individuales de otras Rl y R2 ya existentes. Esto se
muestra de forma abitracta en la Figura 5.24, donde se han mezclado los pasos
de la rutina MaxL i sta con los de la Mi nL i s ta, para obtener una nueva que
obtiene el valor mximo y mnimo en una nica pasada (bucle for) por la
lista, en lugar de dos.
Obsrvese que, en la Figura 5.24, hemos alterado la sintaxis y renombrado
algunas de las variables de las rutinas Ma xLi s t a y Mi n Lis t a originales, con
objeto de que la nueva rutina MaxMi nL i s ta devuelva dos valores en lugar de
uno. En una implementacin completa, la cabecera podra ser:

else

<~

LengthLista(L

then

Max := 1;

R2

IMin:-1;

for k

:~

begin

2 to m do

i f L[k] > L[Max] then


Max := k;
i f L[k] < L[Min] then
Min :~ k

end
end
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 /. Lgica, resolucin de problemas, algoritmos y programas


Resolucin de problemas algortmicos

Obsrvese, en la Figura 5.24, que las instrucciones for e i f sirven tanto


para el caso de la funcin MaxLista que para el de MinLista. Esto es as
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
Rl (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 dsponible, 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 pluviometra est por debajo de la media, y el 4, que debe mostrar el(los)
mes(es) cuya pluviometra es la mxima.
Aparentemente, ambos pasos requieren utilizar el mismo tipo de estrategia
-una bsqueda dentro de la lista de pluviometras para encontrar los valores
que cumplen una determinada propiedad-o El ndice de la lista P l uv i ometri apuede 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 ltsfm 2 . El valor
pluviomtrico para Pluvi omet r i a [1] es 2,5, que se encuentra por debajo
de la media. Por tanto, el paso 3 debe mostrar el valor de Meses[1] o Enero
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:

l'

"
"

!:::

1:, '
"
11" .' . .
'

{Paso 3. Mostrar meses que estn por debajo del promedio}


Wr; teln( 'Meses por debajo de la med a: I};
tor i := 1 to Lengthlista(Pluviometrias) do
if Pluviometras[i] < PluviometriaProm then
WriteLn(' " Meses[iJ);

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 teLn, 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:'};

167

fo~ i := 1 to LengthLista(Pluv;ometrias) do
1f Pluviometrias[i] = MaxPluviometra then
WriteLn(' " Mes(es)[i]>;

Obsrv~se que la solucin se ha conseguido adaptando la solucin del paso 3.


Est~ practica es habitual en la resolucin de problemas algortmicos d b
utilizarse siempre que parezca, intuitivamente, que dos pasos necesite~ ~I ';is=
mo tipo de proceso. Pueden mezclarse los pasos 3 y 4 en un bucle for nico
problema? No es el caso. Piense sobre lo que ocurrira si un
um~o bucle f o r tuviera las dos instrucciones i f de los pasos 3 y 4 de t
~cl.
nro

9ue resuelva el

5.4.3.

Utiliza.cin del conocimiento de dominio en el diseo


de rutinas nuevas

A lo largo de nuestra discusin sobre la resol~cin de problemas algortmicos,


hemos supuesto que se posee un cierto conocimiento sobre el dominio al que
pertenece el prob!ema. En probl~mas sencillos, como los que hemos visto hasta
el momento, el umco conOCimiento del dominio que se precisa es el de la
farmliandad con los rudimentos dcl lgebra y de la Lgica. Para poder construir soluc~ones a problemas ms avanzados, es necesario tener unos conocimlent?s mas profundos d~ntro del campo de la alta Matemtica, Informtica
Ciencias Natura!es, Ciencias Sociales, Lingstica, Economa o Comercio. '
. El Pascal estandar no incluye una rutina que calcule la raz cuadrada de un
numero: Supongamos que estamos trabajando con un problema que requiere
esta rutma. Por eJemplo, necesitamos calcular, adems del valor medio de unas
I~~turas pluvlometncas, su desviacin estndar. Este clculo precisa la utilizaclon de una rutma q~~ calcule la raz cuadrada de x, siendo x un valor no
~egatlvo. La construcclOn de esa rutina puede comenzarse con la especificacin
siguiente:
sqrt(x):
{pre: x >~ o }
(post: result ~ y

y'" x)

Donde se ha utilizado el smbolo ,., para resaltar el hecho de que la raz

cuadr~da de algu?os nmeros slo se puede calcular de forma aproximada.


Por ejemplo, la raIZ cuadrada de 2 es aproximadamente, con una precisin de
tres decimales, 1,414.
Un conodo mtodo de las matemticas para qlcular races cuadradas de
forma a;roxlmada es el mtodo de Newton. De hecho, el mtodo de Newton
es un. ?,eto~ g;neral par.a calcular las races qe ecuaciones, entre las que la
ec~aclOn y -. x es tan solo un caso particular. El mtodo de Newton es un
metodo iterativo que trabaja de la forma siguiente. Comenzamos con una
pnmera aproximacin al. valor esperado; por ejemplo, y = 1. La eleccin
particular de este valor mlclal es habitualmente indiferente para la efectividad

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

168

del mtodo. A partir de y calculamos un nuevo valor ms aproximado, y',


mediante la frmula:
y'

Tabla 5.2. Primeros pasos del clculo aproximado de


de Newton

1
1,5
1,41667
1,41422

(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)

In (ah)
e1n(a)

= a

Por lo que tenemos una forma simplificada de calcular la raz cuadrada de x.


Recurdese que es posible escribir la raz cuadrada de un nmero como x1/2.
Por lo que utilizando logaritmos:
In (x I/2 )

1/2 In x

Ahora, aplicando eX, que excribimos como exp (x), obtendremos:


exp (In (x I/2 ))

XI/2

el/2 In (x)

exp (1/2 In x)

ln(x

P~r l~ que la solucin que demos al problema algortmico estar fuertemente


m UI a por nuestro conOCImIento de la relacin del mismo y sus d' . l'
relaCIOnadas.
ISClp mas

5.5.

TERMINACiN DEL CASO DE ESTUDIO

Vo~viendo al caso de estudio, nos 9uedan por aplicar tres pasos de la metodologIa MAPS propuesta: codlficacIOn, verificacin y prueba, y presentacin.

}2 por el mtodo

Clculo de y'

2/1 = 2
2/1,5 = 1,33333
2/1,41667 = 1,41176

o bien:

y := exp<O,5

La aplicacin 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, suponendo 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 raz 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).

x/y

169

Que puede escribirse en Pascal como:

y + x/y
2

Estimacin (y)

Resolucin de problemas algortmicos

5.5.1.

Codificacin

En pocas, palabras, la codificacin es la traslacin de la solucin de un proble~a algont~ico a un p~og~ama, junto con su documentacin, En la resolucin
e un pro ema. algontmlCo, la mayora del cdigo se obtiene durante las
~~~as de partlcIOn y abstraccin. Por ejemplo, hemos completado la codificade lo~ pasos 3 y 4, del problema de la pluviometra, en la bs ueda de
nu~vas rutmas qu~ sean apropiadas para ellos. Tambin los pasos l ~ 2 estn
prac~.camednte c<;,dlficados; sabemos que pueden implementarse reutilizando y
com man o rutmas de otros problemas ya existentes,
El proceso de, codificacin implica el juntar las partes de la solucin al
problema,. asegurandonos de que el resultad? conjunto es coherente, inteli ible, yl satIsface
las
, .pre
. .y poscondlcIOnes onginales . C uan d o co d'fi
l lcamos gen
P
l
asca sue e ser utll utlhzar una plantilla como la siguiente:
program <nombre>;
{Breve
que describa el problema ' l a estructura general de
lcomentario
'6
l
a so UCl n, el autor y la fecha}
uses <Bi b l ; atecas de las que se toma rn algunas rut ; nas>.,
<.D,eclaracin de las variables identificadas en el proceso de partiClan>
begin
{pre: <Precondicin del problema>}
{Paso 1. <Descripcin del primer paso de la partic:jn>}
{Paso 2. <Descripcin del segundo paso de la particin}
{post: <Poscondi ci ones de l problema>}
end.

Figura 5.25. Plantilla de un programa escrito en Pascal.

170

, .
f in de problemas, algoritmos Y programas
Computacin l. Log/ca, reso uc

de la luviometria que hemos desarrollado,


5 26 En este programa se ha
Podemos codificar el programa l~'
utilizando como guia la plant!ll~?e L\ ~~ur~a ~ Lis t a y M; n L; S t a estn
supuesto que las rutinas Prome
tec~ denominada Herram;entasalmacenadas separadamente en la b~bh~ra manipulacin de listas de reales en
L; s tas, y otr~s operaCiOnes dIVersae :a construido el esqueleto del progr.ama,
la biblioteca L, stas. Una vez que s d
pletarse mediante su mserCiOn en
el cdigo de los pasos mdlVlduales pue e com
,_ .
los lugares apropiados.

,0. '.

program Pluviometrias;
tersticas pluviomtricas
{El programa calcula algunas ca.rac_ d r' Allen Tucker, 30 de marzo
a partir de datos mensuale~. Dlsen~.Ot~ MinLista Y PromedioLista.}
de 1990. Reutiliza las rutl~as Ma.x lS ,
uses L1 s tas , HerramientasLlstas,
type NombreMeses = array [ 1 .. 12] 01 string[10];
var Meses: NombreMeses;
PLuviometrias: Lista;
PLuviometriaProm: reaL;
MaxPluviometra: 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 mnimo de las lecturas}

begin
e ) 1\ Vi E {1, ... , 12} e; es el vaLor
{pre: entrada = (e l l .e '1.! : .. , 1'1. d lao}
pLuviomtrico deL l-eSlmo mes e
{Paso 1. Inicializar lista de meses Y pluviometrias}
{Paso 2. Mostrar pLuviometria prome d'la, ma'ximayminima}
{Paso 3. Mostrar meses por debajo del promedio}

Resolucin de problemas algortmicos

171

duzca los datos correctamente. Lo que hay que hacer se refleja en el esquema
del paso 1 siguiente:
{Paso 1. Inicializar lista de meses y pluviometrias}
InicializarMeses(Meses);
WriteLn(IIntroducir la lista de los 12 valores pluviomtricos mensuales: 1);
ReadLista(pluviometrias);

Donde es necesario disear la rutina In;c;al;zarMeses de forma que el


array Meses se inicialice adecuadamente con los nombre de los doce meses del
ao. Podemos aadir entradas protegidas (para el caso en que las precondiciones deban ser comprobadas explcitamente por el programa). Por ejemplo, en
vez de reducir el paso 1 a las instrucciones:
WriteLn('Introducir la lista de los 12 valores pluviomtricos
mensuales: 1);
ReadLista(Pluviometrias);

Es posible comprobar que se introduce exactamente una lista de doce elementos con las instrucciones:
repeat
WriteLn('introducir la lista de Los 12 valores pluviomtricos
mensuaLes: I};
ReadLista(pluviometras};
until LengthLista(Pluviometras} = 12;

El cdigo de los pasos 2 a 4 se ha completado en el programa de la Figura 5.27. Obsrvese que se ha omitido el cuerpo del procedimiento 1 n; c; al;za rMeses, que se deja como ejercicio.

{Paso 4. Mostrar mes(es) con pluviometria ms alta.}


l ida ~ ESTADlSTlCAS PLUVlOMETRICAS
{post: entrada -.0 A sa
12)' e./12
medi a = Sum 1 E {1, ... ,
..
mxima=Max i E {1, ... , 12}: e;
minima=Min i E {1, ... ,.12}. el
Meses por debaj.o de la med'~~}. e./12)
.
{m.:e.<Su.1E{1, ... ,

5.5.2.

Prueba y verificacin

Mes(es) max,ma:
{mj: ej=Max 1
end.

Figura 5.26.

{1

"

12}' e.

1,;; j,;; 12))

Plantilla en Pascal para el pro bl ema de la pLuviometra.

.
. . d I s asas de entrada de datos, es necesaPara completar la codlficacIOn e. o p
. s para que el usuario introrio que el programa emita los mensajes necesartO

El objetivo de la prueba y la verificacin es garantizar lo ms posible que la


solucin diseada es correcta y completa en todos sus extremos. Es decir, se
trata de poder asegurar que la ejecucin del programa, utilizando unos datos
de entrada permitidos por las precondiciones, producir un resultado consistente con las poscondiciones. Debido a que la prueba y verificacin son fundamentales en el proceso de resolucin de problemas algortmicos, se analizarn
en profundidad en el Captulo 6.

5.5.3.

Presentacin

Cuando la solucin a un problema algortmico ha sido desarrollada completamente, el programa debe ser suficientemente autodocumentado, para cuando

Resolucin de problemas algortmicos

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

172

{Paso 3. Mostrar meses por debajo del promedio}


WriteLn('Meses por debajo de la media:');
fori := 1 to LengthLista(Pluviometrias) do
if Pluviometrias[i] < PluviometriaProm then

sea ledo por alguien no familiarizado con la solucin obtenida, pero s con la
t dologa y el dominio al que pertenece el problema. Es decir, el texto ~~I
n:~ rama --con su documentacin, estructura paso a paso, y pre y posc'.JU 1~io;es- debe ser fcilmente legible por un colega profesIOnal, como lo sena un
artculo del ABe para cualquier persona bIen educada.
, .
La presentacin de una solucin completa de un problema al~or~tmlc~
debe incluir, adems del propio texto del programa, los elementos sIgUIentes.
,.'

,"

WriteLn('Meses[i]);
{Paso 4. Mostrar mes(es) con pluviometria ms alta.}
Writeln( 'Mes(es) mxima:')
tor i := 1 to LengthLi sta(Pluviometrias) do
if Pluviometras[i] = MaxPluviometria then
WriteLn(' " Meses[iJ);

'

Una introduccin escrita en castellano identificando 7l(1os) autor(es) y


que describa el problema, la solucin y algn aspecto musual o mnovador de la solucin.
.
Un
ejemplo
de
las
entradas
y
las
respectivas
salidas
obtemdas
en una o
2.
varias ejecuciones del programa.
.
.,
3. Un resumen de los resultados de la venficaclOn y/o prueba del programa , en los casos en que sea adecuada.

1.

program Pluv,iometras;
. '
.
{El programa calcula algunas caracteristlcas Pluvlom tncas
a artir de datos mensuales. Diseador: Allen Tucker, 30 de. ma~zo
d:1990. Reutiliza las rutinas MaxLsta, MinLista Y PromedloLlsta.}
uses Listas, HerramientasListas;

type NombreMeses ~ array[1, ,12] of string[10];


var Meses: NombreMeses;
pluvometras: Lista;
pluvometraProm: real;
MaxPluvometra: real;
MinPluviometra: real;

{LoS nombres de los 12 meses)


{Las 12 lecturas pluviomtricas)
{La media de las lecturas)
{Valor mximo de las lecturas)
{Valor mnimo de las lecturas}

begin
. {1
12) e es el valor
{pre: entrada = (el'.e u : .. , e u ) 1\ Vl_E
, ... ,
i
pluviomtrico del l-slmo mes del ano}
{Paso 1. Inicializar lista de meses Y pluviometras}
InicializarMeses(Meses)
.
.
WriteLn('lntroducir la lista de los 12 valores pluvlom tncos
mensuales:');
ReadLista(Pluviometras);
{Paso 2. Mostrar pluviometra promedio, ~xima y mnima}
WriteLn('ESTADISTICAS PLUVIOMETRICAS
pluviometriaProm := PromedioLista(Pluvlometrias);
WriteLn(' media = " PluviometraProm:5:2);
.
._
MaxPluviometria :=MaxLista(Pluviometras, LengthLlsta(PluvlOme

)?

trias;
, 5 2)
WriteLn(' mxima = " MaxPluviometrla::;
.
.
MinPluviometra :=MinLista(Pluviometras, LengthLlsta(PluvlOmetrias
.
)
WriteLn( I mnima = " MinPluviometrla:5:2

173

~0

A sa l i da ~ ESTADISTI CAS PLUVIOMETRICAS


{1, ,_" 12): e ,112
mxima = "ax ; E {1, .. "' 12}: el
minima="in i E {1, ... , 12}: e i
Meses por debajo de la media:
{m,: e, < Sum i E {1, ",,12): e/12)
Mes(es) mxima:
{m,: e,~"ax i E {1, ",,12): e,A1,;;j,;;12))
end.
{pos t: ent rada
med i a ~ Sum i

Figura 5,27,

El programa Pascal PLuv;ometr;as, compLeto.

En pocas palabras, la presentacin de la solucin a un problema debe hacese


lector ser,
de forma que un lector interesado sea capaz de comprenderla. El

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 algortmicos. 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 lmites, es preciso utilizar
la creatividad y el conocimiento del dominio. Los 0\fos 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

178

6.1.

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

CORRECCiN V ROBUSTEZ

,"

.'.." ,

{pre: entrada = (Notas" Notas u ... , Notas n )


1'; E {1, ... , n): Notas, E {O, ... ,4))

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 Ca lculaCM. del
Captulo 4. es correcto en este sentido. Es decir. para todas las entradas del
tipo (Notas!, Notas 2 ..... Notas,). 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
(3124)
(2)
(2 3 3 3 3 3 3 2)

179

begin

Qu significa que un programa sea correcto?

..

Robustez y prueba de los algoritmos

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 vaca( )? 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 lculaCM
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 vaca. 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.

1\

n > OA

{Paso 1. Obtenemos la lista de calificaciones}


WriteLn('Introducir la lista de calificaciones:I);
ReadLista(Notas);
{Paso 2. Calcular n o nmero de calificaciones en la lista}
n := LengthLista(Notas);

ifn>Othen

begin
{entrada =0/\ n>O}
{Paso 3. Calculamos Sum = la suma de las calificaciones de la lista}
Sum := O;
; := 1;
whi le ; <= n do
begin
Sum := Sum + Notas[i]:
; := ; + 1
end
end;
{Paso 40 Calculamos CM ~ Sum/n)
CM

Sum/n;

{Sum ~ Su. ;

{1, . o., n): Notas,

CM ~ Sum/n)

(Paso 5. Se muestra CM)


Writeln( 'La CM de esas calificaciones es

end {;t)
{post: entrada ~0A
sal;da ~ Sum; E (1,
end. {CalculaCM)

Figura 6.1.

= 1,

CM; 5 : 2)

n): NotasJn)

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) para i = 1,2 Y 4 son los nmeros 3.1 Y 2. respectivamente. Para el caso de i = 3 (donde la entrada es 'Notas = hello) se
producir un error? debe devolver la rutina algn valor especial. por ejemplo
O, 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 /. Lgica, resolucin de problemas, algoritmos y 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 l cu laCM es correcto
en el sentido de la definicin anterior. Sin embargo, no es robusto.

,." "
"~O

l" .

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 l cu 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 i sta de forma que ponga Li stError a true 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 > O, con una clusula e l se, de
forma que el programa escriba el mensaje de error apropiado cuando se presente como entrada una lista vaca. Podemos revisar el paso 1 de la forma
siguiente:
{Paso 1. Obtenemos la lista de calificaciones}
WriteLn(IIntroducir la Lista de calificaciones:');
ReadLista(Notas);
n:= LengthLista(Notas);
i1 ListError or (n = O) then
entradavlida :=false
else
begin
entradavLida := true;
for ; : = 1 to n do
H Notas[i] < O) o. (Notas[i] > 4) then

entradavlida := false;
end;
i f not ent radav l ; da then
WriteLn(lEntrada no vlida. Programa terminado!)
else begin

Robustez y prueba de los algoritmos

181

Donde la nueva variable booleana ent radav l i da indica si la entrada se


ajusta o no a los requisitos de la precondicin. El resto del programa quedara
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 caracterstica 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 Ca lcu laCM 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);
if ListError or (n = O) then
entradavlida :=false
else
begin
entradavlida!= true;
for i : = 1 to n do
i f Notas[i] < O) oc (Notas[i] > 4) then
entradavl ida := 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. Puesio 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 metodologia MAPS.

196

Computacin /. 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)

b)

Figura 6.9. 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 bien para entradas
correctas, sino que tambin se comportan elegantemente para un amplio

Robustez y prueba de los algoritmos

197

rango de entradas incorrectas~. 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 crtica 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 especficos 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 procedimie'lto 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

.. I. Lo'gica, resoluGn de problemas, algoritmos y programas


Computac/On

. d onos d e que~ en
aseguran
. cada caso, el resultado del procedimiento es consist te con sus poscondlclones.
.
. d'
en Puesto que es Imp
. osible
probar (odo.' los pOSibles valores
de' entra .d,cut.u
ten,
. T

os que seleccionar un subconjunto de ellos que sea slgm Icatlvo, y eJe. '
~rel~o ram~ e imprimir el resultado con cada uno de los elementos de ese
~u~COl~junto. Una forma bastante til de rcallzar este proceso ~s c~nstrlllr,.~n
. ro rama ('onductor. Se denomina as porque, hter~~mente. gU1~ la ,eJ.cc~~I~ln
~ i~presin de resultados del procedimiento o funclOn con. los v,tlores seleccIOnados para la prueba.
.
.
l. f
."
Ilustremos estas ideas construyendo un .luego de pruebas pa;a . ,1 un~1( n
MaxL i sta (vase Figura 5.12). Cul seria un conJunto de pru~b~s dPro~Jadol
..
un. conductor
pard estudJar e
para esta funClon,
y ca. mo. podemos dIsear
"
.<,
comport'lmiento de MaxL, sta frente a estos datos..
. .'
Los i~cgos de prueba pueden crecer rpid~lInente. Consl~~rc~l.~lS :1 nUl~~~ o
tot'\1 d~ posibles entradas vlidas quc podnamos construll pal ,\ 11.1 funelon
Ma~L i sta utilizando O l ms elementos. Supongamos que cada c omento es
, elrango
'
un entero en
--?" d. I 2" - 1, habrn?- I h ='(' 65.536 dlIStas diferentes
1 ""nt)O
de un solo elemento. El nmero de posibles listas dl,erentc.' , e 11 ee~~ (~
resulta astronmico ----seguramente excesIvo para tnclUlllds en un Juego de
pruebas.
.
l'Istas que PUC(I'n
ser P'\S'\
Pensemos un momento sobre algunas poslhles
t:,
.. , < das a M'axL i s tao y a lo que esperamos que MaxL i sta produzca como respuesta. En la Tabla 6.1 se ofrecen algunas eJemplos ohvlOs.
Tabla 6.2

Robustez y prueba de los algoritmos

decir, el valor mximo ocupa una posicin cualquiera entre el primero y el


ltimo elemento de la lista~-. El cuarto comprueba si MaxL i sta 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, debemos 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 podemos probar la
robustez y amigabilidad de MaxL i sta? Es decir, cmo se comportar MaxLista con entradas como la lista (-1, -2, hola, -8)? O ante un valor
de L, como 'hola' o 'asrtfadesr' 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 de 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; <a rch i va 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
sea 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.

Resultado esperado

(3 1 2 8)

(8 1 2 3)

(3 8 1 2)

(-12 -3 -8)

program conductor;
{Este programa conductor prueba el procedimiento <p(x, y}
{uti l ; zando un juego de pruebas como datos de ent rada}
{del archivo <archivo juego pruebas>}

(3 1 2 8)

begin

Parmetros de entrada L

procedure <p(x, y;

(3 1 2 8)

(3 1 2 8)

end

var <variables correspondientes a los parmetros>;


<archivo juego pruebas>: text;

Los dos primcros datos dc pruebas son il~porlanlcs ~orqllc el valor l~~x~~~~
ocupa la ltima y primera posicin de la lIsta. re~p~ctlvamcntc. :1 l~n.;~~ ~~~~s
tambin es importante. pucs represcnta el caso llplCO que puede OCUfllI
-

199

begin
WriteLn( 'Comienza la prueba del procedimiento <p(x, yI);
readarchivo juego pruebas, <x;
while not eofarchivo juego pruebas

do

200

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

begin

end;
d' .
( ) ')
WriteLn(IFinal de la prueba deL proce lmlento <p x, y>
end.

Estructura general de un conductOr de pruebas.

Supongamos que se quiere probar la funcin MaxL; sta utiliza?do un


programa conductor y el archivo de j uegopruebasmax que conttene 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)
()

201

va,. L: Lista;
m, j: integer;

WriteLn('Parmetros de entrada = , <x;


<p(x, y;
Wri teLn(' Resul tado de p(x, y) =1, <y;
readarchivo juego pruebas>, <x;

Figura 6.10.

Robustez y prueba de los algoritmos

4
4
4
4
3
2
1
4
O

juegopruebasmax: text;
begin
Wr; teLn( I Comienza la prueba de la funcin MaxLi sta(L, m)')
WriteLn( 'Introduci r el nombre del archivo del juego de pruebas!
ReadLista(L);
while not eof(juegopruebasmax) do
begin
WriteLn('Lista de entrada L =1); Writelista(L);
Write(lntroducir valor de m: '}; ReadLn(m);
j := MaxLista(L, m);
WriteLn('Resultadode MaxLista(L, m) = " j);
ReadLista(L);

1);

end;
WriteLn('Final de la prueba de la funcin MaxLista(L, m)
end.

La salida que produce este conductor cuando se le suministra el archivo j uegopruebasmax se muestra en la Figura 6.11.
Comienza la prueba de la funcin MaxLista(L, m)
Introducir el nombre del archivo del juego de pruebas:
milista
Lista de entrada L =
(3 1 2 8)

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 programa conductor prueba la funcin MaxLista utlllzando un
juego de pruebas como datos de entrada del archivo juegopruebasmax}
function MaxLista(L: Lista; m: integer): integer;
var j, k: integer;
begin
.
{pre: L = (e" el' ... , e m, , en) /\ n ~ O /\ cada e i es un numero}
H (O < n) and (m <~ LengthLista(L then
begin
j := 1;
for k :~ 2 to m do
{i nv: Vi E {1, .. , k - 1): e [j] >~ e [i] A 2 <~ k <~ m + 1 )
H L[k] > L[ il then
j := k;
end
else
j := O;

MaxLista := j;
(post: n > O 1\ Vi E {1, .""' n}: e j ~ e i
n = O 1\ resul tado = O}
end;

.
1\

resultado

1v

Introducir valor de m: 4
Resultado de MaxLista(L, m) = 4
Lista de entrada L=
(8 1 2 3)
Introducir valor de m: 4
ResuLtado de MaxLista(L, m) = 1
Lista de entrada L =
()

Introducir valor de m: O
Resultado de MaxLista(L, m) = O
Final de la prueba de la funcin MaxLista(L,

m)

Figura 6.11. Resultado de ejecutar el conductor de pruebas para


la funcin MaxL ista, con el archivo de entrada juegopruebasmax.

Como puede verse, la construccin y utilizacin de un conductor de pruebas es casi un proceso mecnico. Sin em bargo, cuando se utiliza con cuidado,
no slo nos permite descubrir errores ocultos, sino 'Iue nos sugiere formas de
conseguir que el programa sea ms robusto y amigable. Utilizar el procesamiento con un juego de datos desconocido puede conducirnos a resultados
sorprendentes! Sin embargo, es preferible realizar esos descubrimientos en el
momento de la prueba, que no despus. cuando se ha entregado el procedimiento a una persona desconocida para cualquier utilizacin.

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

202

.,~ ~

,,0,

l'! "

, !'

'.,

"

Debemos probar los programas de abajo a arriba. Es decir, debemos probar


todos los procedimientos y funciones antes de probar el programa que lo.s
utiliza Despus de realizar esto, podemos proceder a la pr~eba del programa
compl~to en la misma forma en que probamos un procedlmle~to .. Para e~lo,
convertimos el programa en una especie de autoconductor de SI mismo, anadindole un bucle externo que lea sistemticamente datos~e entrada alternat.lvos desde un archivo externo que contenga un juego de pruebas, y despues
prosiga con su ejecucin normal, produciendo las ~ahdas a todas las entradas
del 'ue o de pruebas en lugar de la salida de un UOlCO Juego de datos.
~o;ejemplo, con;idrese el progra~a Ca l c~ ~a CM, de la Figura 4.6, el cua~
modificamos para ser ms amigable (vease SecclOn 6.1). Para proba~ este pro
rama, adema s convertirlo en el autoconductor que se m~estra mas abaJO: ~
~'ecutarro con los datos de el archivo que contIene vanas hstas de cahficaclO
es alternativas, en lugar de slo una. El resultado de convertlT este programa
en amigable y en un autoconductor, se muestra en la Figura 6.12. Para cfnvertirio en autoconductor, basta con aadirle un bucle repeat abarcando as pre
y poscondiciones del programa. Esta modifica.cin hace que programadle~ y
procese entradas hasta que lea una lista vaCIa 0, lo que senala el fin e as
ejecuciones de prueba.

:1

progra. calculaCM
uses

Listas;

var
Notas: Li stas;
i, n: integer
Sum, CM: reaL;

entradavlida: Boolean;
begin
repeat
{pre: entrada

(Notas" Notas u
AV; E {1, " . , n}: Notas; E {O,
repeat.
WriteLn (lIntroduc1r la lista
ReadLista(Notas);
n := LongL i sta (Notas);
entradavl ida := true;
for i := 1 to n do
if not isNumeric(Notas[i] or
entradavlida := false;
until entradavlida;
if n>Othen
begin
Sum :~O:
i := 1;
while i <= n do
begin
Sum := Sum + Notas[;];
=

N t

... , o aSn
" . , 4})

1\

n > O

.
,)
de calificac10nes: ;

.
) h
Notas[1] < O) or (Notas[i] > 4 ten

203

i := ; + 1
end

Ejemplo: Prueba de un programa completo

6.4.2.

,.,"

Robustez y prueba de los algoritmos

CM = Sum/n
WriteLn('LaCMdeesascalificacioneses=',CM
end {; f}
{post entrada =0/\
salida = Sum ; E {1, ... , n}:Notas;ln}
untiln=O
end.

Figura 6.12.

6.5.

2)

Un autoconductor para la versin amigable del Ca lcu laCM.

GARANTA DE CORRECCiN: VERIFICACiN


DE PROGRAMAS

Como metodologa general, la verificacin de programas tiene como objetivo


la aplicacin de la lgica matemtica, para demostrar formalmente que el
programa incluido entre la precondicin y la poscondicin cumple esas especificaciones bajo cualquier circunstancia de ejecucin posible. En este sentido, la
verificacin 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 investigacin 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 demostracin 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
desviaciones, 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 lab/eau. Un comienzo de prueba del tab/eau, o tab/eau vaco, es un listado del programa con sus
precondiciones, poscondiciones y comentarios vacos antes y despus de cada

Robustez y prueba de los algoritmos

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

216

Ahora tendremos que demostrar por, induccin, que tras una ejecucin de
todo el cuerpo del bucle, se garantiza que:
5um

SU" j

{1, ... , ;

1}: j

1\

1 <= ;

<= 6

donde ; ' = ; + 1.
.
.
Podemos hacer esto examinando el efecto de las mstrucclones sobre el
invariante original. Es decir, una simple ejecucin de la instruccin sum : =
sum + 1 conduce a
sum ~ ; + Su.
~ Su .. j E
~ Su", j E
~ Su .. j E

E {1, ... , ; - 1}: j


{1, ... , ;}: j
{1, ... , (i + 1) -1}: j
{1, ... , ; , - 1 }: j

por reglas algebraicas sencillas. La instruccin ; : = ; + 1 conduce a


1 <= ; + 1 <= 6 == 1 <= ;

<= 6

puesto que el valor limitador de ; = 5 en elbucle for limita a 6 el ~~lor de


; ' . Luego, por induccin, se deduce que el mvanante del bucle es vahdo, 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 captul<;> ~eciben. habituallll:ent~ ,el
nombre de tcnicas de verificacin formal. Como es faclllmagmar, la aphcaclOn
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 h~n d~~arrollado
suficientemente las tcnicas de verificacin. El proceso de venficaclOn form~l
de programas est todava en la infancia -:-hace falta hacer mucho todavla
para que pueda utilizarse como una herramIenta que garanttce la robustez de
los programas.
.
Sin embargo, existen diferentes niveles de granulandad de programas, en
los que se puede aplicar las tcnicas de verificacin de programas. El proceso
de la verificacin informal parece aportar medIOs de argumentar, de forma
convincente sobre la correccin de los programas, eVItando muchos de los
inconvenientes de la demostracin lnea-a-lnea 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 CapItulo 3.
Es decir cuando simplificamos una expresin algebraica, no solemos enumerar
todos lds pasos que se siguen ni su justificacin formal en trminos de propie-

217

dades algebraicas bsicas (asociatividad, conmutatividd, etc.). En su lugar solemos saltarnos los pasos que son evidentes para el lector concentrndono~ slo
en aquellos esenciales y dificiles de comprender.
'
E,ste es el caso de l~ verificacin informal. En lugar de construir una demostr~clOn completa medIante una prueba tableau, nos centramos en los aspectos
mas complejOS del programa, y argumentamos en castellano sobre la forma en
que esa~ partes complejas satisfacen las especificaciones. As las nociones de
precondlcin, poscondicin e invariante juegan an un papel esencial en este
pr?ceso, pero las argumentaciones sobre la correccin del programa se realizan
mas mformalmente.

6.6.

RESUMEN

En. este .captulo se han presentado las nociones de correccin, robustez y


a~~llgablhdad de los programas. En el captulo se ha incidido sobre la utiliza-

cI<;>n de la estrategIa de resolucin de problemas MAPS, ilustrando su utilizaclon en la resolucin de un problema de tratamiento de textos, y otro grfico.
Hemos present~?o y desarrollado dos metodologas complementarias para
~segurar la ~orrecclOn y robustez de nuestros programas: prueba y verificacin.
Estas permIten desarrollar. buenos programas, aun a los ms escpticos, si
tte~en una mentahdad posItIva. Es evidente que tendremos que realizar un
anahsls acttvo de n,uestros propios diseos y los programas que resultan a
medIda que sean mas complejos los problemas que queremos resolver.
. El metodo 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
captul~, garantizan la ausen~ia de errores. A su vez, inciden en la importancia
de la loglca para la mformat~ca. Es decir, l~s principios de la lgica y las
demostr~cl.ones que se mtroduJer?n en el CapItulo 3, son la base notacional y
metodologl~a para la combmaclOn de precondiciones y poscondiciones en la
especlficaclOn de problemas, con las reglas de inferencia en la verificacin de
pr~gramas. Sin embargo, la verificacin tiene limitaciones prcticas, y es necesano que,las conozcamos bIen cuando tengamos que decidirnos entre prueba o
venflcaclOn de programas. En el Volumen TI de esta serie, veremos tcnicas de

prueba y verificacin adicionales.

You might also like