Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Computacion 1 Logica Resolucion de Problemas Algoritmos y Programas MC Graw Hill
Computacion 1 Logica Resolucion de Problemas Algoritmos y Programas MC Graw Hill
COMPUTACION I
Lógica, resolución de problemas,
algoritmos y programas
FUNDAMENTOS DE INFORMÁTICA FUNDAMENTOS DE PROGRAMACIÓN
Lógica, resolución de problemas, Algoritmos y estructura de datos
programas y computadoras (Segunda edición)
DAVID K. GARNICK
Bowdoin College
Traducción:
Revisión técnica:
v
UNIVERSIDAD NACIONAL ABIERTA
N° de Rfig¡~tl'O .....2.Q.,§.9..5.../t.:.f¿..-::t -~
Centro de ReQursos Múltiples
e.t. METROPOLITANO
ISBN: 84-481-2545-2
Depósito legal: M. 40.896-1999
I vi
Contenido
Prólogo . v
Nota del editor . vi
~j~:ciciOf~~~·~·I.~.~.~~.~ ..:::::::;::;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
51
52
3.2. Razonamiento con proposIcIOnes . 54
3.2.1. Equivalencia . 54
3.2.2. Propiedades de la equivalencia .. 55
3.2.3. Reglas de inferencia: La idea de demostración . 58
3.2.4. Estrategias de demostración . 61
3..2.5 Resolución de problemas de la vida real . 65
EJercIcIos . 66
3.3. Lógica de predicados . 69
3.3.1. Los cuantificadores universal y existencial .. 71
3.3.2. Otros cuantificadores . 76
3.3.3. Variables libres y ligadas . 76
3.4. Predicados y programas . 77
3.4.1. El estado de un cálculo .. 77
3.4.2. Cuantificadores y programación: bucles . 78
3.5. Razonamiento con predicados: prueba por inducción .. 81
~j::::~~~s.::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::~::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
86
3.6. 86
Capítulo 4. Problemas algorítmicos y su solución . 89
~I;r~~~~o.~.~.:.~~~~~.~.~.~ . :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
90
4.1. 93
4.2. Definición de problemas y descripción de algoritmos . 93
4.2.1. Los estados inicial y final de un algoritmo: entrada y salida . 93
4.2.2. Los estados intermedios de un cálculo: introducción de variables . 95
vii
viii Contenido
~~e:~~~j~S~ig~;ft~'i'~~"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
97
4.3. 98
4.3.1. Sintaxis y semántica . 100
4.3.2. Repetición y bucles: inicialización, invarianza y terminación . 103
4 ..3.3 Tres visiones de la misma solución al problema .. 108
EjercIcIos , 111
4.4. Más problemas algorítmicos .. 112
4.4.1. Cálculo de a" .. 113
4.4.2. Contar palabras de un texto . 116
I 4.4.3.. . Representación del problema de Las Tres-en-Raya .. 121
EjercIcIOs . 126
4.5. Resumen . 130
Capítulo 5. Resolución de problemas algorítmicos . 131
5.1. Necesitamos una metodología . 131
5.1.1. Generalidades sobre el método MAPS .. 132
5.2. Construcción de software para su reutilización: la rutina .. 134
5.2.1. Encapsulamiento de rutinas para la reutilización. Abstracción procedimental .. 134
5.2.2. Identificación de rutinas nuevas y definición de sus abstracciones .. 140
5.2.3. Funciones recursivas: Una alternativa a la repetición .. 144
5.2.4. Aprendizaje de rutinas ya existentes: Bibliotecas y características de los lenguajes 146
5.2.5. Selección y reutilización de tipos de datos y estructuras .. 147
5.2.6. A.rr~~s de ,cadenas de carac~eres .. 149
5.2.7 TlplÍlcaclon fuerte y coerclOn . 150
EjerCICIos . 152
5.3. Resolución de un problema utilizando la metodología MAPS .. 156
5.3.1. El diálogo .. 156
5.3.2. Las especificaciones . 158
t~:c·iciO;a ~.~.~~~~~~~.:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
159
.. 161
5.4. Definiciones de abstracciones: unificación de rutinas viejas con ideas nuevas .. 162
5.4.1. Reutilización de rutinas .. 163
5.4.2. Utilización de la creatividad para diseñar nuevas rutinas .. 166
5.4.3. Utilización del conocimiento del dominio en el diseño de rutinas nuevas . 167
5.5. Terminación del caso de estudio .. 169
5.5.1. Coditicación .. 169
5.5.2. Prueba y veriticación .. 171
5.5.3. Presentación . 171
5.6. Resumen . 173
Ejercicios . 174
Capítulo 6. Robustez y prueba de los algoritmos . 177
6.1.
6.2.
..
g~~~~~~~n ~ ~~~~~.~e.~ .:::::::::::::::::::::::::::::::::::::::::::::::::::::::
Resolución de problemas de procesamiento de texto, utilizando MAPS: Criptografía ..
178
182
182
6.3. R~sol.u~ión de problemas gráticos utilizando MAPS: el Juego de la Vida . 187
EjerCICIOs . 196
6.4. Garantía de la robustez. Diseño de casos de prueba .. 196
6.4.1. Ejemplo: Prueba de un procedimiento o función completos .. 197
6.4.2. Ejemplo: Prueba de un programa completo . 202
6.5. Garantía de corrección: verificación de programas .. 203
6.5.1. Tableau de demostración . 203
6.5.2. La regla de inferencia de la asignación .. 206
6.5.3. Reutilización de las reglas de inferencia de la lógica . 209
6.5.4. Reglas para las condicionales .. 209
6.5.5. Verificación de bucles . 212
6.5.6. Verificación formal frente a verificación informal de programas .. 216
6.6. Resumen .. 217
Ejercicios . 218
Capítulo 1. Algoritmos y programas .. 221
1.1. Los sistemas de procesamiento de la información .. 222
Contenido ix
304
3.6. Escritura de algoritmos/programas 304
3.6.1. Cabecera del programa o algoritmo 304
3.6.2. Declaración de variables 305
3.6.3. Declaración de constantes numéricas 305
3.6.4. Declaración de constantes y variables carácter 306
3.6.5. Comentarios 307
3.6.6. Estilo de escritura de algoritmos/programas 308
A~\Ív~d.ades de programación resueltas . 313
EjercIcIOs 3 15
Capítulo 4. Introducción a la programación estructu rada 316
4. l. Técnicas de programación 316
4.2. Programación modular 317
4.2.1. Tamaño de los módulos 318
4.2.2. Implementación de los módulos 319
4.3. Programación estructurada 319
4.3.1. Recursos abstractos 319
4.3.2. Diseño descendente (top-dow n) 320
4.3.3. Teorema de la programación estructurada: estructuras básicas 320
4.4. Estructura secuencial 324
4.5. Estructuras selectivas 324
4.5.1. Alternativa simple (si-entonces / if-then) 325
4.5.2. Alternativa doble (si-entonces-si_no / if-then-else) 331
4.5.3. Alternat.i~a múltiple (según-sea, caso de / case) 337
4.6. Estructuras repettttvas 340
4.6.1 . Estructura mientras (<<while») 345
4.6.2. Estructura repetir (<<repeab» 348
4.6.3. Estructura desde/para (<<for») 352
4.6.4. Salidas internas de los bucles 358
4.7. Estructuras de decisión anidadas 362
4.8. Estructuras repetitivas anidadas 364
4.9. La instrucción ir_a (<<goto») 365
A.ctiv.i~ades de programación resueltas 380
EjercIcIOs 381
Referencias bibliográficas 383
Capítulo 5. Subpro gramas (subalgoritmos): procedimientos y funciones 384
5.1. Introducción a subalgoritmos o subprogramas 386
5.2. Funciones 387
5.2.1. Declaración de funciones 388
5.2.2. Invocación a las funciones 393
5.3. Procedimientos (subrutinas) 394
~.3.1. Sustitución de argumentos/parámetros 398
5.4. Ambito: variables locales y globales 401
5.5. Comunicación con subprogramas: pa<¡o de parámetros 402
5.5.1. Paso de parámetros 403
5.5.2. Paso por valor 404
5.5.3. Paso por referencia 405
5.5.4. Comparaciones de los métodos de paso de parámetros 407
5.5.5: Síntesis de. la.transmisión de ~arámetros 410
5.6. FuncIOnes y procedimientos como parametros 412
5.7. Los efectos laterales 412
5.7.1. En procedimientos 413
5.7.2. En funciones 414
5.8. Recursión (recursividad) 417
A.ctiv.id.ades de programación resueltas 422
EjercIcIos
CAPíTULO 2
CONJUNTOS Y FUNCIONES
En este capítulo introducimos las nociones matemáticas básicas sobre los con-
juntos y las funciones, junto con su notación. Estas nociones son fundamenta-
les para la disciplina de la informática. Más adelante veremos cómo los con-
juntos y funciones se entremezclan con las nociones claves de la informática y
su aplicación. Estos conceptos y notaciones se utilizarán a lo largo de todo el
texto. (Algunos lectores encontrarán estas materias familiares. Sin embargo,
esta presentación tiene como objetivo reorientar estas ideas, quizá familiares,
hacia aquellas partes de la informática en que se utilizan.)
¿En qué forma se relacionan los conjuntos y funciones con la informática?
Generalmente, podemos considerar un programa para una computadora,
como la realización de una función o como una correspondencia entre dos
conjuntos: la entrada del programa que representa un elemento particular del
dominio de la función, y la salida que representa el resultado de aplicar la
función a dicha entrada. Introduciremos esta idea en este capítulo, ejercitándo-
la en las prácticas de laboratorio que le acompañan. En los Capítulos 4, 5 Y6
afianzaremos este concepto, ejercitándonos en la programación y mediante la
discusión exhaustiva de programas. Los conjuntos y las funciones están tam-
bién íntimamente relacionados con la propia computadora como dispositivo.
Así, podemos decir que una computadora es una máquina que realiza una fun-
ción determinada, cuando ejecuta un programa que realiza, paso a paso, dicha
función. También se insiste en esta idea en las prácticas de laboratorio que
acompañan a este capítulo. También, en el Capítulo 7, insistiremos sobre este
concepto al estudiar la estructura de las computadoras.
Algunos conjuntos son especialmente importantes para la programación y
para las computadoras. Por ejemplo, los números enteros y reales, los valores
booleanos, los caracteres que encontramos en el teclado de la computadora (el
conjunto de caracteres ASCII) y las «cadenas» * construidas con esos caracte-
* N. del T.: De las diversas traducciones que suelen realizarse de la palabra inglesa «string»,
hemos preferido la acepción «cadena» o «cadena de caracteres», que serán utilizadas de forma
indistinta.
Compu tación l. Lógica, resoluc ión de problem as, algoritm os
y progra mas
2
todos ellos
res, representan conjuntos que son esenciales para la informática;
progra mación y las compu tadora s moder-
están incluidos en los lenguajes de
la corresp ondenc ia que existe en progra ma-
nas. En este capítulo estudiaremos
concep to de «tipo~~. Alguna s funcion es resulta n
ción entre estos conjun tos y el
funcion es
de vital import ancia en programación. Entre ellas se incluyen las
expone nciales y logarít micas, y funcion es que se repre-
discretas, la{> funciones
sentan mediante series finitas.
en des-
Estudiaremos todas ellas en este capítulo, ponien do especial interés
tacar por qué son importantes para la informática.
2.1. CONJUNTOS
números.
En la vida cotidia na son corrientes las colecciones de objetos o
as de nuestra clase, la colecci ón de
Podem os pensar en la colección de person
vil, o la colecci ón de los nombr es
dígitos y letras de la matrícula de un automó
erto ü'Hare de Chicag o. Estas colecci ones,
de aerolíneas que vuelan al aeropu
ción
en el lenguaje matemático, reciben el nombr e de conjuntos. Una descrip
más precisa la podemos realiza r de la forma siguien te.
Esta notación requiere una variable al comienzo, una barra vertical y, al final,
una descripción de los elementos. Con esta notación, la Ecuación 2.6 se lee «el
conjunto de los x tales que x es un número entero entre 1 y 100, ambos
inclusive». Claramente, este ejemplo describe el mismo conjunto de la Ecua-
ción 2.5. La Ecuación 2.7 es otro ejemplo de esta alternativa para la descrip-
ción de conjuntos:
Ejemplos de elementos del conjunto definido por la Ecuación 2.7 son los si-
guientes:
Por ejemplo, la cardinalidad del conjunto definido por la Ecuación 2.3 es 26.
Existen cuatro conjuntos que tienen una importancia especial, tanto para la
informática como para las matemáticas:
Los tres primeros son infinitos, mientras que el último es finito y tiene cardina-
lidad n. Por ejemplo, el conjunto Z2 = {O, 1} tiene cardinalidad 2; el conjunto
Z10 = {O, 1, ..., 9} tiene cardinalidad 10.
al
bl
Definición. Supongamos que tenemos una lista de variables Xl' X 2 ' .oo, X n
cuyos tipos están definidos por los conjuntos 51' 52' oo., Sm respectivamente.
os y progra mas
6 Compu tación l. Lógica, resoluc ión de problem as, algoritm
es S2' y así
Supóngase que el valor de Xl es SI E SI' el valor de X2 S2 E
los
representa el estado de las variables xl' X 2 , ..., X w El conjun to de todos
e espacio de estados de esas
estados postbles de Xl' X 2 , ..., X n recibe el nombr
variables.
Esta import ante noción se ilustra en los Ejemplos del 2.1 al 2.3:
Ejemplo 2.1. Supon gamos que un progra ma de compu tadora tiene dos
tipo el
variables i y j, utilizadas como contadores. Ambas tienen como
podría
conjun to de los números naturales. El estado inicial del progra ma
ser:
i=O y j=O
Ejemplo 2.2. Si los pixels contro lados por un progra ma son Xl' X 2' ...,
XIOOOOOO, un estado de ese progra ma tendría
1 millón de entrad as, una por
cada variable. Por ejemplo, la expresión
Xl = on y X2 = off y y XIOOOOOO on
X
O
-3,1
e
e
y
y
0, junto con z =
J2 junto con z = 1
°
n. 1789
X = -1 e y "2 Junto con z
ma,
Frecuentemente, es de gran ayuda visualizar el estado de un progra
. Por ejempl o, los puntos de la Figura 2.2 están repre-
como puntos del espacio
de la Figu-
sentados los dos estados del Ejemplo 2.1. La gráfica tridimensional
marcad o el
ra 2.2b representa el espacio estado del Ejemplo 2.3, donde se ha
Cuand o en un
punto correspondiente a uno de los estados del programa.
produc e es como si
progra ma las variables cambia n de estado, el efecto que se
nos desplazáramos de un punto a otro del espacio de estados .
Conjuntos y funciones 7
7 ~""---r-..---r---..-....-....,
y
61--+--+......,f-+--+~r-;
51--+--+......,f-+--+-+--I
41--t--+-+-+-+-+--;
31--+--+""",'--+--+-+--1
.;.- x
21-+--+---1'--+--+-+--1
o t-Jf-+-+-+--+-t-+--
- 1 L..-.J----L_.1.--L---J,_.L---.J z
-1 O 2 3 4 5 6
a) b)
x:= 1.0
/
/1I
I
I
I
I
;-+----x
La Figura 2.4 representa tres diagramas de Venn, en los que las áreas
sombreadas representan la unión, la intersección y la diferencia.
b)
e)
AnB {1, 3, 5}
A u B {-3, -1,1,3,5,7, 9}
A \ B p, 9}
Como ejemplo adicional, supóngase que
AnB {n2 }
AuB {plp es un polinomio de la forma n 2 + bn + e,
donde b = O o e = O}
A \ B {plp es un polinomio de la forma n 2 + bn, donde b "# O}
al bl
\ Asociatividad u -simplificación
A n (B n C) == (A n B) n C A uA == A
A u (B u C) == (A u B) u C Au<p==A
AuV==V
Distributividad
A n (B u C) == (A n B) u (A n C)
A u (B n C) == (A u B) n (A u C)
Ejemplo 2.9. Si A = {sls es una cadena sobre {O, 1} que comienza por 1},
entonces A' = {E} U {sls es una cadena sobre {O, 1} que comienza por 1}.
En este caso, el símbolo E simboliza la cadena vacía que no contiene ningún
carácter. La notación {E} significa «el conjunto que tiene un solo elemen-
to», que es la cadena vacía. El conjunto vacío <p, por el contrario, no
contiene ninguna cadena.
Ejemplo 2.11. Sea U = {ulu es cualquier cadena sobre el alfabeto {O, 1},
incluida la cadena vacía E}. Entonces U es el conjunto universal de varios
conjuntos definidos sobre el mismo alfabeto, tales como S = {E, 0,1,00,01,
10, 11} Y T = {O, 01, 001, 0001, oO.}. Obsérvese que ni S es subconjunto de T,
ni T lo es de S. En la mayoría de los casos, el conjunto universal sobre el
que se definen conjuntos de cadenas particulares es tan evidente que no
suele mencionarse explícitamente.
Ejemplo 2.12. Supóngase que tenemos los dos conjuntos de cadenas si-
guientes:
Ejercicios
a) ; := 2;
j .- ; ;
b) ; .- ; + 1;
j .- j + 2;
e) j .- j + 1 r.
; .- i + 1 r.
j .-
j + ; r.
2.2. Expresar en notación de conjunto los descritos mediante las frases si-
guientes:
2.3. °
SeaA = {(x, y)lx ~ e y ~ O} Y B = {(x, y)lx ~ 1 e y ~ 1}. Identificar
cada uno de los conjuntos siguientes sobre el plano xy, sombreando el
área apropiada.
a) A n B
b) A u B
e) A \ B
d) B ~A
e) A'
2.4. Supóngase que s y t son cadenas sobre el alfabeto {a, b, ..., z}. Es posible
definir eoneat (s, t> como la cadena que resulta de poner t a conti-
nuación de s (concatenar). Por ejemplo, si s = abe y t = xy, entonces
eoneat(s,t) = abexy. Del mismo modo, si S y Tson conjuntos de
este tipo de cadenas, podemos definir eoneat (S, T) como el conjunto
de todas las cadenas, que resultan de concatenar una cadena arbitraria s
de S, y otra t de T. Supongamos, por ejemplo, que S = {e, x, xy,
xyy}, y T = {e, y, yx, yxx}. Se pide encontrar cada uno de los
conjuntos siguientes:
a) eoneat (S, T>
b) eoneat(T ,S)
e) S u T
d) S n T
e) S \ T
f) T \ S
2.5. Supongamos que S y T son conjuntos de cadenas. Encontrar dos ejem-
plos de parejas S y T, tales que eoneat(S, T> = S u T.
2.6. Dibujar un diagrama de Venn para los conjuntos A y B, Ysombrear las
partes correspondientes a los conjuntos siguientes:
a) (A' n B') u (A n B)
b) (A u BY u (A \ B)
2.7. ¿Cuántas cadenas de longitud 2 ó menor existen sobre el alfabeto (O, I)?
2.8. Decir cuáles de las afirmaciones siguientes son verdaderas y cuáles
falsas.
a) {2, 3, 4} u {2, 4, 5, 6} = {2, 3,4, 5, 6}
b) {2, 3, 5} n {2, 4, 5, 6} e {2, 3, 6}
e) {3, 4, 6, 8} \ {2, 4, 7, 8} ::J {3}
d) (<(> n {3, 5, 7, 8}) u {3, 7} = {3, 5, 7, 8}
e) {2, 3, 5} = {5, 2, 3, 2}
f) {2, 4, 5} e {I, 2, 4, 5, 6}
g) {3, 4, 5} e {I, 2,4, 5, 6}
h) {I, 2, 6} ::J {I, 2,4,5, 6}
i) «> e {2, 5}
Conjuntos y funciones 15
S {1, 2, 3, 4, 5}
T {xlO < x < 10 Y x es impar}
U Z16
2.2. FUNCIONES
1 2
2 5
3 10
4 17
Esta es una función que relaciona los enteros de la primera columna con
los correspondientes de la segunda. Si quisiéramos extender la función, no
sería dificil deducir que la quinta fila constaría de los pares 5 y 26. Es decir,
existe un criterio, sugerido por las cuatro filas de la función, que permite
generalizarla para cualquier número de valores.
1 2
2 5
1 7
3 2
2 6
16 Computación ,. Lógica, resolución de problemas, algoritmos y programas
Los valores no-ambiguos -es decir, que a cada valor de la primera columna lc
correspondA uno de la segunda-, son básicos para la idea de función.
La Figura 2.7 muestra dos funciones más, en este caso utilizando un gráfico
en lugar de una tabla. Obsérvese que en la Figura 2.7a cada valor de x se
corresponde con uno de y, y de la misma forma, cada uno de y se corresponde
con uno de x. En la Figura 2.7b cada x se corresponde con uno de y; sin
embargo, para un mismo y existen más de un valor de x. Para poder trabajar
con funciones es necesario definir el concepto de forma más precisa. Clarifique-
mos algunas de las ideas acerca de la correspondencia presentadas en los
ejemplos.
y y
a) b)
7
y 6
5
4
3
x 2
O
-1
-1 O 2 3 4 5 6
al b)
Ixl x cuando x ? O
- x cuando x < O
Conjuntos y funciones 19
_ _ _ _ _ _ _ _.......,.... x
y y
(-3,3) • .(3,3)
(-2,2). • (2,2)
(-1,1) • • (1,1)
a) b)
Ejemplo 2.19. Lafunción suelo l_x_lse define como el mayor entero menor
o igual que x. Esta función tiene como dominio a R y como rango a Z. Por
tanto, si x = n.d¡d 1 d 3 ... (donde n es un entero y di cualquier dígito), enton-
ces l_x_1 = n cuando x ~ 0, o x es un entero, y l_x_1 = n - 1 en caso
contrario. Por tanto, para números reales positivos, la función l_x_1 es el
Compu tación l. Lógica, resoluc ión de problem as, algoritm os
y progra mas
20
negati-
resultado de eliminar la parte decimal de x, y para números reales
elimin ar la parte deci-
vos que no sean ya enteros, l_x_1 es el resultado de
muestr a en la Figura 2.11.
mal y restarle uno. La gráfica de esta función se
I-x-j que se define como el
Una función muy relacionada es la función techo
calcula elimin ando la parte decima l
menor entero mayor o igual que x. Se
dole uno. Las funcion es suelo y techo
de x, y Isi x no fuera entero, sumán
i-
también se conocen como funciones mayor entero y menor entero, respect
vamente.
utili-
La función valor absoluto puede calcularse en Pascal, directamente,
variabl e o expres ión del
zando la expresión abs (x), donde x puede ser una
es suelo y techo no tienen una
tipo rea lo; ntege r. Sin embargo, las funcion
runC< x)
analogía exacta en Pascal. La función más próxim a es la función t
ión de tipo rea l en integer eliminan-
que convierte cualquier variable o expres
(3.14 ) = 3,ytru nC<- 3.14) = -3.
do los decimales. Por tanto, trunc
a, una
Hemos visto cómo se pueden definir funciones utilizando una fórmul
conjun to de pares ordena dos. Las
gráfica xy, una tabla de dos columnas y un
funciones pueden definirse de varias formas alterna tivas.
definir las
Definición recursiva de funciones. Algunas veces es conveniente
ferenci arse reci-
funciones en términos de sí mismas. Esta capacidad de autorre
reciben el nombr e de
be el nombr e de recursión, y las funciones así definidas
funciones recursivas.
•,, ,
:-2
I
'-1 O ,1 '2 :3 x
n f(n)
~ _ . _ ~
O 1
1 4
2 7
3 10
n f(n)
O O
1 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
22 Computación ,. Lógica, resolución de problemas, algoritmos y programas
read(x);
n := o;
whi le x >= 1.0 do
begin
x:=x/2.0;
n := n + 1
end;
Ejercicios
d)
e)
{(x,
{(l,
y)lx ~ ° e y = x}
a), (2, b), (3, a), (4, b), (5, e)}
f) {(l, a), (2, b), (1, e), (2, d), (3, e)}
g) {(l, e), (2, d), (3, e), (4, b), (5, a)}
n
d) Ixl para x = -1,0,1, -49,5 Y 6".
2.15. Marcar un punto en la gráfica (i, j) de la Figura 2.8b, para cada uno de
los estados marcados con A y B, en el segmento de programa siguiente.
; := 1;
j := 1;
(estado A}
;:=;+1;
j:=j+1;
{estado B}
y y
al bl
p(a) e
p(b) a
p(c) d
p(d) b
x y
a.~ • a
b •
• b
~
c.~ • e
d • ------+~ •d
f
Figura 2.13. Una función f que no es uno-a-uno, por lo que no tiene inversa.
uno,
Ejemplo 2.24. El Ejemplo 2.23, puesto que p es una función uno-a-
, p - puede definir se de la forma siguien te:
tiene inversa. Esta inversa 1,
p-l(a) b
p-l(b) d
p-l(e) a
p- l(d) e
cubrir
Obsérvese que p-l(p(a )) = p-l(e) = a. De forma general, para
x X, P- (p(x) = x. Análo-
cualqu ier función invertible p : X -+ Y, y cada E 1
ord ( , O' ) = 48
ord('A ') =-65
ord( '=') = 61
ord ( , a') = 97
ondien -
Una lista comple ta de los caracte res ASCII y sus ordina les corresp
tes puede encont arse en el Apénd ice A.
uni-
El propós ito de la función ord es definir un esquem a de codificación
del teclado . Este esquem a lo utilizan
forme para represe ntar los caracte res
La existen-
todos los constru ctores de software y hardw are de compu tadora s.
mbio fácil de inform ación entre distinto s
cia de este estánd ar permit e el interca
tipos de compu tadora s.
uno; si
Obsérvese que, para ser eficaz, la función o rd tiene que ser uno-a-
a una forma
un código estuvie ra asigna do a dos caracte res distintos, no existirí
ificar el código . Puesto que es una función uno-a- uno, la
consistente de descod
ter). Si n
función ord tiene en Pascal su inversa, denom inada eh r (por Charac
r del teclado
es un entero en el interva lo 0-127, entonc es eh r (n) es el carácte
corresp ondien te del entero. Por ejemplo:
ehr(48 ) = 'O'
ehr(65 ) = 'A'
ehr(61 ) = '='
eh r (97) = 'a'
Conjuntos V funciones 27
Obsérvese que, puesto que ord y chr son inversas, una de la otra, se verifica:
chr<ord<x» =x y ord<chr<n» =n
ABCDEFGHIJKLMNOPGRSTUVWXYZ
JSATERNICFHPLUGWVYDZOMXGBK
Las funciones exponenciales y logarítmicas son dos clases de funciones con una
importancia tal en la informática, que es necesario estudiarlas cuidadosamente.
Comencemos por la función exponencial.
x Z'
-2 1/4
-1 1/2
O 1
1 2 x
2 4
3 8
4 16
Estimemos cuánto arroz debía dar el rey al individuo. Antes de ello, recorde-
mos algunas propiedades algebraicas de las funciones exponenciales. Las cua-
tro funciones que necesitamos son las siguientes:
2m 2m 2m +" (2.8)
m 2m -"
2 /2" (2.9)
(2 m )" 2m" (2.10)
2m!" = .::12 m (2.11 )
(2.12)
(2.13)
debe ser
de 2, y = log2 x significa que x
obtener y. Si x es una potencia ifica que
r 1. Por ejemplo, log2 16 = 4 sign
dividido por 2 y veces, par a obtene (2.14) a
16 debe ser dividido por 2 cua tro
veces par a obt ene r 1. Las Ecuaciones ica.
rítm
(2.18) describen algunas propied
ades adicionales de la [unción loga
(2.14)
log2 1 O
(2.15)
log2 2 1
(2.16)
log2 mn log2 m + log2 n
(2.17)
log2 (m/n) log2 m - log2 n
(2.18)
n
log2 (m ) n log2 m
loga-
depende del hecho de que la función
La verificación de esas expresiones Ecu acio nes (2.1 4)
l. Abajo verificamos las
rítmica es la inversa de la exponencia ficación de las restantes.
veri
a (2.16), dejando par a el lector la x. Entonces
4) sup ong amo s que log2 1 =
Par a verificar la Ecuación (2.1
5), sea log2 x = x.
ficar la Ecuación (2.1
2x = 1, por lo que x = O. Par a veri Par a verificar la Ecuación (2.16), sea
= 1.
Entonces 2 = 2, resultando x x y
X
Y • Por tan to, nm = 2 + , y
onc es m = 2x
y n = 2
x = log2 m e y = log2 n. Ent = log2
bin and o ambas, obtenemos log2 mn
por tan to, x + y = log2 (mn). Com
m + log2 n.
Conjuntos y funciones 33
Ejercicios
2.18. Una alternativa en criptografia para el cifrado de César es la utilización
de una clave de codificación, que consiste en un patrón que se repite e
°
indica al descodificador a qué distancia a la derecha en el alfabeto se
encuentra la letra correcta. Por ejemplo, A significa «desplaza letras»;
B significa «desplaza 1 letra», y así sucesívamente. Por tanto, si la clave
de codificación es ABCDABC..., el mensaje (en inglés) FOURSCO-
REANDSEVEN se codificaría FPWRTEOSGAOFSFXEO. Invertir el
proceso para el mensaje codificado (también en inglés) OIVOCGIO-
PASPIB. ¿Es este esquema una función de caracteres uno-a-uno? ¿Es
una función uno-a-uno de cadenas de caracteres?
n
a) i~l i 1 + 2 + 3 + ... + (n - 1) + n.
n
b) i~ 3i O + 3 + 6 + 9 + '" + 3(n - 1) + 3n.
n
e) L
i= 1
(3i + 2) 5 + 8 + 11 + .. , + (3n - 1) + (3n + 2).
1 + 2 + 3 + ." + (n - 2) + (n - 1).
e) i~ i 2 + 3 + 4 + ... + (n - 1) + n.
n
f) i~ i(3i + 2) = 5 + 16 + 33 + ... + (n - 1)(3n - 1) + n(3n + 2).
Conjuntos y funciones 35
n
I f(i)
i=m
= f(m) + f(m + 1) + ... + f(n) (2.19)
n
)'
L....J
a·I = a1 + a2 + .,. + an (2.20)
j= l
Propiedades de las series finitas. Las Ecuaciones (2.21) a (2.24) reflejan algunas
propiedades básicas de las sumas utilizando la notación sigma.
¡=1
I a¡ al (2.21)
n n
¡= 1
I a¡ al + ¡~a¡ (2.22)
n n~l
¡= 1
I a¡ an + I
¡= 1
a¡ (2.23)
n m n
¡= 1
I a¡ I
¡= 1
a¡ + I
¡=m+l
a¡ SI 1 ~m < n (2.24)
I
j= 1
e en donde e es una constante (2.25)
n n
I
¡= 1
(f(i) e I
i= l
f(i) (2.26)
36 Computación ,. Lógica, resolución de problemas, algoritmos y programas
n n n
I
j= 1
(f(0 + g(i)) i~ f(O + j~ g(i) (2.27)
n n n
I
j= 1
(fU) - g(i)) I
j= 1
f(i)
j=l
I g(i) (2.28)
n
i~ (f(i + 1) - f(i)) = f(n + 1) - f(l) (2.29)
donde podemos ver que todos los términos entre f(n + 1) y f(l) se cancelan
mutuamente, por lo que el resultado seráf(n + 1) - f(l).
1 + 2 + 3 + ... + (n - 1) + n
Existe una anécdota interesante sobre esta serie. Cad Friedrich Gaus (1777-
1855) fue uno de los matemáticos más destacados del siglo XIX. Cuando era
joven le enviaron a un internado, más conocido por su estricta disciplina que
por su calidad académica. Como castigo, él y sus compañeros deberían realizar
el ejercicio de sumar los 100 primeros enteros. Apenas el profesor había enun-
ciado el problema, Gauss levantó su mano dando la respuesta correcta. Gauss
había descubierto una forma sencilla de sumar la serie aritmética para n =
100. Gauss escribió la suma horizontalmente en orden creciente, y debajo
escribió la misma suma, pero en orden decreciente, haciendo después la suma
término a término:
1 + 2 + 3 + + 99 + 100
+ 100 + 99 + 98 + + 2 + 1
101 + 101 + 101 + + 101 + 101
Conjuntos y funciones 37
Gauss pudo observar que el resultado era la mitad de 101 x 100, o 5050. El
profesor de Gauss reconoció que el muchacho tenía un gran talento para las
matemáticas, y recomendó a su padre que lo enviara a un colegio en el que
pudiera sacar mejor partido de su capacidad. De hecho, podemos utilizar el
método abreviado de Gauss para sumar series en general:
1 + 2 + 3 + + (n 1) + n
+ n + (n 1) + (n 2) + + 2 + 1
(n + 1) + (n + 1) + (n + 1) + + (n + 1) + (n + 1)
n
n(n + 1)(2n + 1)
i~1 i2
6
(2.31 )
n
n 2 (n + 1)2
I
i= 1
i
3
4
(2.32)
n
I 2i 2n+ 1 _
1 (2.33)
i= 1
Las Ecuaciones (2.30) a (2.32) se las conoce con el nombre de p-series por ser de
la forma:
n
I
i= 1
iP
20 20 6
20(21) 6(7)
i~i i~1 JI -2- 2
210 - 21 189
V progra mas
38 Compu tación ,. Lógica, resoluc ión de problem as, algoritm os
2.3. SUMARIO
conjun-
En este capítulo se han introducido algunas ideas fundamentales sobre
mayor ía de estas nocion es tienen directa se
tos y funciones. Como se sugirió, la
ática. En este libro utilizar emos los con-
importantes aplicaciones en la inform
que esta
ceptos de conjun to y función siempre que sea necesario. Veremos
y exacta, produc e grande s benefic ios en la solu-
notación matemática, concisa
áticos, sean los propio s proble mas de natura leza
ción de problemas inform
tienen un
matem ática o no. Las propiedades de los conjuntos y las funciones
lo 3, y en el
gran paralelismo con las de la lógica, como veremos en el Capítu
tanto, un conoci-
diseño de compu tadora s, como se verá en el Capítu lo 7. Por
import ancia en el
miento profundo de los conjun to y las funciones es de vital
estudio de la disciplina informática.
Ejercicios
o
d) i~ a¡
13 5
b) i~ 2i(i + 1) f) ¡~ (2¡ + 1)
12 5
e) ¿ 3¡2
¡=6
g) i~ ¡2
10 O
d)
k~5 2k h) ¿1 a¡
i=
ítu-
es recursiva, según se vio en el Cap
Obsérvese que la definición ante rior ino s de una o
nen una pro pos ició n en térm
lo 2. Es decir, las reglas 3 y 4 defi con stru idas util i-
cuales pue den hab er sido
más pro pos icio nes ya existentes, las ten
ame nte. Sin emb arg o, deb ido a que exis
zan do las reglas 3 y 4, Y así sucesiv 1 y 2, que no util izan
s util izan do las reglas
pro pos icio nes elementales form ada algo es
nici ón, el pro ces o par a dete rmi nar si
la pal abr a proposición en la defi es dec ir, la defi nici ón no
reglas, no es infinito;
una pro pos ició n, util izan do estas
es circular. ipu -
os con el cálculo pro pos icio nal, man
Por el mo men to, cua ndo trab ajem pos ició en
n
ntar emo s sim bol izar nin gun a pro
laremos sólo var iabl es y no inte las varia-
mos formas de inte rpre taci ón de
particular. Má s ade lant e intr odu cire diseño de
el mu ndo de la pro gra mac ión y del
bles, que son de gra n util idad en
las com put ado ras.
Lógica 43
Equivalente
Símbolo Significado
en castellano
no Negación
V o Disyunción
/\ y Conjunción
=> implica Implicación
-= si y solo si Eq uivalencia
p
q
c-· p)
(p v q)
(p v (q v r»
(p =o> (q v (r =o> (p ~ q»»
Una línea de razonamiento similar sirve para demostrar que el sexto ejem-
plo es una proposición:
(p)
(p q) p)
I ~ (p)
44 Computación ,. Lógica, resolución de problemas, algoritmos y programas
((p v p) /\ r) o bien,
(p v (q /\ r))
tanto por ((p 1\ q) 1\ r) como mediante (p 1\ (q 1\ r)). En la Sección 3.2 se verá que
ambas expresiones lógicas son equivalentes, y que pueden eliminarse los parén-
tesis, quedando, por tanto, la expresión p 1\ q 1\ r. En la frase anterior, la prime-
ra coma equivale al operador 1\.
El operador v puede tener en castellano dos significados ligeramente dife-
rentes, por ·10 que es necesario distinguirlo. En la frase:
(DSvMD) =>
(((VAA 1\ VAD) v (L/VA 1\ L/VD» 1\ "" FRA 1\ TF)
p q pvq
P q pAq
P ~p
a) b)
p q p=q p q p<:o>q
e) d)
Figura 3.2. Tablas de verdad para proposICiones: (a) Negación; (b) conjun-
ción; (e) implicación; (d) equivalencia.
p q pvq ~p (p v q) = ~p
p q (p v q) = ~p
p q pvq
verdadero verdadero
falso verdadero verdadero
falso falso falso
Ejemplo 3.5. La proposición (p /\ q) => (r v (p => s)) podría tener una tabla
de verdad completa de 16 líneas. Sin embargo, utilizando condiciones «da
igual» podemos reducir su tamaño a cinco lineas, tal y como se muestra
debajo:
3.1.3. Tautologías
Esto confirma algo intuitivo: es imposible para una proposición ser simul-
táneamente verdadera y falsa. Igualmente, p v '" p es una tautología.
p pv ~p
p q ~p ~q ~(P/\q) (~pv~q)
Ejercicios
f) x - y = o.
g) ¿Por qué es azul el cielo?
h) La hipotenusa es el lado más corto de un triángulo rectángulo.
p => "-'q)
(p V « "-' p) /\ q))
(p => p) /\ « "-' q) => q)
3.6. Demostrar que '" (p v q) y ("-' P /\ "-' q) tienen la misma tabla de verdad.
3.2.1. Equivalencia
Considérese la proposición (p /\ q) V (p /\ "-' q), cuya tabla de verdad se mues-
tra abajo:
p q (p /\ q) V (p /\ ~q)
Los valores de la última columna de la tabla son exactamente los mismos que
los de la columna de la p; por tanto, podemos decir que (p /\ q) V (p /\ '" q) es en
cierta manera equivalente a p. Por tanto, si en alguna situación nos encontra-
mos con (p /\ q) V (p /\ '" q) podemos sencillamente reemplazarla por p.
En cuanto empezamos a razonar con proposiciones, se ve la necesidad de
simplificar proposiciones complejas. Nuestro propósito ahora será el de definir
qué significa que dos proposiciones sean equivalentes, y el ver cómo esta equi-
valencia permite simplificar expresiones complejas.
Definición. 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.
Lógica 55
Conmutatividad' Asociatividad
pAq == qAP P A (q A r) == (p A q) A r
pv q == qvp p v (q v r) == (p v q) v r
Obsérvese que muchas de estas expresiones tienen una paralela en las que
fueron estudiadas para los conjuntos (véase Tabla 2.1). Además, muchas de
estas propiedades tienen también una análoga en la aritmética. Así, las propie-
dades conmutativa, asociativa y distributiva permiten la simplificación de ex-
presiones aritméticas. De una forma similar la asociatividad, conmutatividad y
distributividad introducidas en la Tabla 3.2 permiten la simplificación de pro-
posiciones lógicas.
Estas propiedades se utilizan de diversas maneras. Por ejemplo, la conmu-
tatividad se utiliza para reordenar las proposiciones y así poder realizar otras
simplificaciones. La asociatividad permite la eliminación de paréntesis. Por
ejemplo, puesto que p /\ (q /\ r) == (p /\ q) /\ r, de forma equivalente es posible
escribir p /\ q /\ r. Las leyes de la distributividad permiten la factorización de las
proposiciones. Esta leyes totalmente equivalente a la ley aritmética que permi-
te escribir 3 x 5 + 3 x 7 = 3 x (5 + 7). Las leyes de Morgan son de gran
utilidad cuando se trabaja con expresiones que incluyen negaciones. La ley de
la implicación permite escribir expresiones equivalentes a la implicación, pero
utilizando sólo v, /\ Y "'.
Antes de utilizar las leyes de la equivalencia es necesario convencerse de
que son correctas. Para ello es suficiente construir una tabla de verdad para
cada lado de la equivalencia y verificar que ambas tablas son idénticas. De-
mostraremos lo anterior para la ley de la implicación, dejando el resto como
ejercicio.
1. (p => q) /\ (p => r)
2. (- p v q) /\ ( - P v r) Ley de implicación
3. '" p v (q /\ r) Distributividad
4. p => (q /\ r) Ley de la implicación
Donde puede observarse que la proposición del paso 2 resulta de la del paso 1,
tras la aplicación de la ley de la implicación. La del paso 3 se obtiene de la
del '2 aplicando la distributividad, y la del 4 se obtiene de la del 3 por la ley de
la implicación. El Ejemplo 3.10 es más complicado:
1. 5x + 1 = 3x + 2 1. 5x + 1 = 3x + 2
2.2x=1 2. (5x + 1) - 1 = (3x + 2) - 1
3. x = 1/2 3. 5x + (1 - 1) = 3x + (2 - 1)
4. 5x + O = 3x + 1
5. 5x = 3x + 1
6. 5x - 3x = (3x + 1) - 3x
7. (5 - 3)x = (1 + 3x) - 3x
8. 2x = 1 + (3x - 3x)
9. 2x = 1 + (3 - 3)x
10. 2x = 1 + Ox
58 Computación ,. Lógica, resolución 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
La sencilla prueba del ejemplo 3.12 muestr a que p => p es una tautolo
gía.
Podría mos demos trar esto utilizando una tabla de verdad, pero represe
nta una
buena oportu nidad para introdu cir la notació n y estilo de las demos
traciones.
Ejemplo 3.12. Demos trar p => p:
1. [p]
2. p 1
3. p => p =>-introducción, 1, 2
=-introducción ~-introducción
[p] p=q
-q-- q=p
p=q p~q
=-eliminación ~-eliminación
::!L
~p
~ -eliminación
falso
p
/\ -introducción
p
v -introducción
-q- -p- -q-
P/\q pvq pvq
/\ -eliminación v -eliminación
P/\q P/\q [p] [q]
-p- -q-
pv q r r
r
versátiles que las tablas de verdad, puesto que las tablas de verdad son inmane-
jables cuando analizamos las proposiciones de más de tres o cuatro variables, y
además no aportan ninguna base para razonar con proposiciones de forma
deductiva.
Podemos autoconvencernos, de forma intuitiva, de que las reglas de infe-
rencia tienen sentido. Por ejemplo, la regla de la 1\ -introducción nos dice que si
hllmos demostrado que p y q son tautologías en dos pasos anteriores cuales-
quiera de la demostración, en el paso actual podemos concluir que p 1\ q es una
tautología. De forma similar, la regla de la ==>-eliminación (conocida familiar-
mente como modus ponens), simplemente establece que, si en un paso anterior
hemos demostrado que p ==> q y que p es una tautología, en el paso actual
podemos concluir que q es una tautología.
En las demostraciones procederemos paso a paso para conseguir, en cada
uno de ellos, una nueva tautología que nos acerque más a nuestra meta -la
últíma proposición de la prueba--. Justificaremos cada paso realizado, bien en
la utilización de una regla de equivalencia (mediante la sustitución de una
parte derecha de una expresión de la Tabla 2.3, por una parte izquierda, o vi-
ceversa), bien mediante la utilización de una regla de inferencia. Adicionalmen-
te a lo anterior, es preciso desarrollar estrategias de demostración; es decir, mé-
todos de realizar demostraciones que puedan ser de utilidad en diferentes
situaciones. Estas situaciones se dan no sólo en la lógica, sino también en
varias aplicaciones de la informática, las matemáticas y la ciencia en general.
En esta sección se estudian algunas estrategias básicas para demostrar que una
proposición es una tautología, mediante la utilización de las propiedades de la
equivalencia y las reglas de inferencia.
1. [p] Suposición
2. [q] Suposición
3. p 1
4. q => p =>-introducción, 2, 3
5. p ==> (q => p) =>-introducción, 1, 4
tración será la propia p ~ q. Esta estrategia fue utilizada en los Ejemplos 3.12
y 3.13.
Utilización del modus ponens. Supongamos que alguien dice: «Si abres la
jaula, se escapará el tigre» y supongamos que yo abro la jaula. La conclusión
seguramente será, por modus ponens, que el tigre escapará. Análogamente, si
oimos a alguien decir: «Si representan Nuestra Ciudad, compraré entradas», y
descubrimos que están representando Nuestra Ciudad, podemos concluir que
esa persona comprará entradas. En el Ejemplo 3.14 podemos ver cómo se
utiliza el modus ponens en una demostración.
1. ((p ~ q) 1\ (r ~ p) 1\ r) Suposición
2. r ~ p 1\ -eliminación, 1
3. r 1\ -eliminación, 1
4. p Modus ponens, 2, 3
5. p ~ q 1\ -eliminación, 1
6. q Modus ponens, 4, 5
7. ((p ~ q) 1\ (r ~ p) 1\ r) ~ q ~-introducción, 1,6
1. Suposición
2. A -eliminación, 1
3. A -eliminación, 1
4. [p] Suposición
5. q Modus ponens, 2
6. "'q 3
1- falso '" -eliminación 5, 6
8. '" P '" -introducción, 4
9. ((p ~q)A "'q) ~ ",p ~-introducción, 1, 8
6. r
7. P~ r
8. (p ~ q) ~ (p ~ r)
9. (p ~ (q ~ r)) ~ ((p ~ q) ~ (p ~ r))
(La justificación de los distintos pasos de la demostración se dejan al lector
como ejercicio.)
Utilización de la bicondicionalidad en las demostraciones. Para demostracio-
nes de proposiciones de la forma p ~ q, una estrategia que suele ser eficaz es
demostrar primero que p ~ q y después que q ~ p, utilizando posteriormente
la regla de la ~-introducción como último paso de la demostración.
Ejemplo 3.18. Para demostrar que (p ~ q) ~ ('" p v q), primero se de-
muestra que (p ~ q) ~ ('" p ~ q) es una tautología (pasos 1-13), y poste-
riormente se demuestra que ('" p v q) ~ (p ~ q) es una tautología (pasos
14-22). Finalmente, se aplica la regla de la ~-introducción como último
paso de la demostración. 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. ['" p v q] Suposición
2. ["'p] Suposicion
3. [p] Suposición
4. pA ",p A-introducción, 2, 3
5. falso '" -introducción, 4
6. q '" -eliminación, 5
7. p~q ~-introducción, 3, 6
8. [q] Suposición
pro gra mas
ón de prob lem as, algo ritm os y
64 Com puta ción l. Lógica, reso luci
Ejemplo 3.20. Los deseos son caballos, a condición de que los caballos
no vuelen. También, los mendigos no cabalgan, a condición 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 imposibi-
lidad 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 introdu-
cir variables que representen cada una de las proposiciones básicas que
contiene. Como suele ser habitual en problemas de la vida real, como es
este, las frases constituyen un pequeño jeroglífico que hay que descifrar.
En cualquier caso, supongamos que introducimos las variables siguientes:
W Los deseos son caballos
HF Los caballos vuelan
BRD Los mendigos cabalgan
BRCH Los mendigos son ricos
Es posible representar las cinco frases de que consta el problema origi-
nal mediante las proposiciones siguientes, respectivamente:
1. -HF ~ W
2. - W ~ - BRD
3. - (BRD /\ - W) ~ HF
4. - ( - HF v - BRD) ~ - BRCH
5. BRD
Utilizándolas igual que utilizaríamos suposiciones en una demostración
ordinaria, es posible escribir la serie de inferencias siguiente, haciendo
referencia la última a la variable BRCH que es la que nos interesa:
6. W Modus tollens, 2, 5
7. -BRDv W ~ HF Leyes de Morgan, 3
8. -BRDv W v-introducción, 6
9. HF Modus ponens, 7, 8
10. BRD/\HF /\-introducción, 5, 9
11. (HF /\ BRD) ~ - BRCH Leyes de Morgan, 4
12. -BRCH Modus ponens, 10, 11
Con lo que se demuestra que los mendigos no son ricos.
66 Computación /. Lógica, resolución de problemas, algoritmos y programas
Ejercicios
3.7. Utilizar tablas de verdad para demostrar que las expresiones siguientes
son equivalencias.
a) p v (q /\ r) == (p v q) /\ (p V r)
b) ~(pvq) == ~p/\ ~q
c) p => q == ~(p /\ "'-'q)
d) p v falso == p
e) p /\ verdadero == p
f) P /\ (p V q) == p
p q p nand q
"'pvp
verdadero
68 Computación l. Lógica, resolución de problemas, algoritmos y programas
3.15. Desarrollar una demostración para cada una de las tautologías siguien-
tes, utilizando reglas de inferencia.
a) «p => r) 1\ (r => q)) => (p => q)
b) «p v q) 1\ (p => s) 1\ (q => s)) => S
3.16. En la isla Paradoja, todos sus residentes pertenecen a uno de dos clanes.
Los miembros de uno de los dos clanes siempre dicen la verdad, mien-
tras que los del otro siempre mienten. Un visitante de la isla Paradoja se
encuentra con tres nativos. Einstein, Planck y Bohr. Einstein dice: «o
bien Bohr o bien yo pertenecemos a un clan distinto de los otros dos.»
¿A qué clan pertenece Bohr? *
* Adaptado del libro de GEORGE J. SUMMERS, titulado The Great Book C?f Mind Teasers and
Mind Puzzles, Ed. Sterling Publishing Co., Nueva York, 1986.
Lógica 69
que Bridget. ¿Cuál de las tres (si es que existe) pide siempre lo mismo
después de cenar?
no es más
Esta notaci ón puede ser la denom inada «lógica de predicados», que
icional presen tada en las Seccio nes 3.1
que una extensión de la lógica propos
ce la notació n básica de la lógica de predica -
y 3.2. En esta sección se introdu
necesa rias para trabaja r con ella y utilizar la en la
dos, junto con las nociones
descripción de los estados de los progra mas.
formas
Las descripciones de entrad a y salida anteriores no son más que
predic ado
relajadas 'de predicados. De forma intuitiva, podem os consid erar un
inado valor,
como una frase que incluye variables, las cuales, al tener un determ
convierten la frase en una proposición.
ti-
Definición. Un predicado es un aserto constit uido por consta ntes aritmé
y los valores lógicos verdad ero y
cas y boolea nas (números enteros, reales
operac iones aritmét icas (=, *, etc.);
falso); variables aritméticas y booleanas,
lógicos
operaciones relacionales ( <, ~, >, ~, =, i=, E, etc.) y operad ores
valor verdad ero o falso depend iendo de los
(1\, v, ~, etc.), que tiene el
estados de sus variables.
expresiones
En Pascal, este tipo de predicados se conocen con el nombr e de
booleanas, y tienen gran cantida d de usos en progra mación .
preci-
En la Sección 3.1 se definió la sintaxis de las proposiciones de forma
sin embarg o, en su lugar,
sa. Podría mos hacer lo mismo con los predicados;
expresiones
utilizaremos nuestros conocimientos y experiencia con ese tipo de
alment e álgebra y progra ma-
en otros campo s de las matemáticas~especi
idos sobre propos iciones . Comence-
ción- junto con los conocimientos adquir
mos destac ando que cualquier proposición es tambié n un predica do.
Las
Ejemplo 3.22. Las proposiciones siguientes son tambié n predicados.
expresiones equivalentes en Pascal se muestr an a la derech a.
x < 10 x < 10
i 2 + / = 25 i*i + j*j = 25
al < a 2 1\a 2 < a 3 (a[1] < a([2]) and (a[2] < a[3])
necesario
Obsérvese en el tercer predic ado del Ejemplo 3.22 que, aunque no es
ntar el predica do, si 10 es en la expres ión en
utilizar paréntesis para represe
es debido a que los operad ores 1\ y v tienen menor
Pascal equivalente. Esto
priorid ad que los operad ores relacio nales «, ~, >, etc.). Sin embarg o, en
operad ores
Pascal, los operad ores and y or tienen una priorid ad mayor que los
para conse-
relacionales «, ~, >, etc.) en una expresión booleana. Por ello,
sis *.
guir una interpr etación equivalente, es necesaria la utilización de parénte
Las expresiones siguientes no son predicados:
i + 1
y2 < 10 i=
x := x + 1
se el
* Para una mayor información sobre las expresiones booleanas en Pascal, consúlte
manual de laborato rio.
Lógica 71
a) {(i, j) I i < j}
b) {(i,j) I i 2 + / = 25)}
c) {(a o, al' a 2) I a o = máx(a 1 , a2)}
d) {(Si' S2) / Sl es un prefijo para S2}
e) {(i, j) I i < j v j = O}
f) {(i, j) I i 2 + / = 25 1\ j > 2}
Debido a que expresiones como «para cada», «para todo», «para cada
uno» aparecen con frecuencia en matemáticas y lógica, todos ellos se simboli~
zan de forma abreviada con el símbolo V, denominado cuantificador universal.
En el ejemplo, podemos escribir la frase:
V R(i) : P(i)
'(a, bl
--r----------- x
Figura 3.3. Representación gráfica del
predicado V (j, j) E R: i < a /\ j < b.
d) En una lista A = (el' e2, 000' en) los elementos hasta elj-ésimo, excluido
él mismo, están colocados en orden creciente (véase Figura 3.4)0
(1 3 5 6 7 9 2 8 4)
I
e,
I
ej
Vi:i<i+l
74 Computación l. Lógica, resolución de problemas, algoritmos y programas
V R(i) : P(i)
f) Existe una frase en este texto con al menos una falta de ortografía.
2 30
Supon gamos tambié n que todos los a¡ son distintos. Es posible expres
ar todo
lo anterio r como:
que no están ligadas son libres. (Veremos que la misma distinción entre varia-
bles libres y ligadas existe entre variables globales y locales, respectivamente,
cuando definamos procedimientos y funciones en programación.)
Considérese la expresión
Una forma posible de comprobar esto sería escribir una larguísima instrucción
condicional, asignando a la variable booleana vá l ; do el valor verdadero o
falso:
válido:=true;
if e[1] <= O
then válido:=false;
if e[2] <= O
then válido:=false;
if e[30] <= O
then válido:=false;
válido:=true;
for i :=1 to 30 do
jf e[i] <= O
then vá l i do :=fa lse;
vál ido:=false;
for i :=1 to 30 do
ife[i]=O
then válido:=true;
Ejemplo 3.29. La frase «El número de elementos de la lista A = (el' ez' ...,
e30 ) cuyo valor es cero», puede reescribirse como Num i E {l, ..., 30}: e¡ = O.
El programa siguiente comienza con la suposición de que no existen en A
elementos que cumplan esta condición. Posteriormente, se corrige metódi-
camente la suposición (añadiendo 1 a la variable contador numero), cada
vez que se encuentre un cero en la lista.
número:=O
for i :=1 to 30 do
ife[i]=O
then número:=número+1;
Ejercicios
3.18. Evaluar los predicados siguientes, en cada uno de los estados 1 y 11:
(1) i = O 1\ j = 1 1\ k = - 1 (JI) i = - 1 1\ j = 1 1\ k = O
80 Computación l. Lógica, resolución de problemas, algoritmos y programas
a) i< lO/\j< 10
b) -1 < j :::; i
e) i + j > k
d) i3 = / = p
3.19. Evaluar cada uno de los predicados siguientes. Supóngase, en todos los
casos, que el dominio es N.
a) Vi: i < i + 1 h) Vi 3j : i - j = O
b) Vi: i2 < i i) 3i Vj : i - j = O
e) Vi, j : i 2 + / > O j) Mio i E {1, ..., 6} : (i2 - 6i) = 3
d) 3i: i 2 = 5i - 6 k) Vi 3j : i x j = O
e) 3i, j : i2 + j2 :::; 25 l) Sum i E {l, , lO} : i - 5
f) Vi 3j : j = O m) Prod i E {l, , n} : i
g) Max i E {l, ..., lOO} : i + 2 = 101
3.20. Supóngase que se define un tablero de ajedrez como {(i, j)ll :::; i :::;
:::; 8 /\ 1 :::; j :::; 8}. Supongamos que el par (1, 1) define el cuadrado de
la esquina inferior izquierda del tablero, la casilla es negra, y las blancas
ocupan inicialmente las dos filas inferiores del tablero. Sea p una fun-
ción que asigna a cada casilla del tablero el nombre de la pieza que está
sobre ella. Así, si la casilla (4, 7) está vacía, escribiremos p(4, 7) = vacía;
si la casilla (1, 5) contiene el rey blanco, escribiremos p(l, 5) = RB.
Escribir predicados para describir las frases siguientes:
a) La reina blanca ha sido capturada.
b) Las negras conservan sus alfiles.
e) Una torre blanca está en la misma fila que la reina negra.
d) Un peón blanco está atacando al rey blanco.
e) Una torre blanca está atacando a la reina negra.
f) Un alfil negro está atacando al rey negro.
columna
fila 1 2 3
2
xO
3
X
e)
Escribir un predicado que describa todos los estados en que las X
pueden ganar, en la columna de enmedio; es decir, todos los estados en
que las X ocupan dos casillas de la segunda columna y la otra casilla
está vacía.
d) Escribir un predicado cuantificado, que describa la imposibilidad de
que las X ganen en la segunda columna.
e) Escribir otro que describa la imposibilidad de las X de ganar en cada
columna.
f) Escribir un predicado que describa la imposibilidad de que ganen las X.
Tabla 3.4. Reglas de inferen cia para predica dos cuantif icados
V-introducción V-eliminación
R-=P V R(i): P(i)
V R(i): P(i) R(i o) -= P(i o)
3-introducción 3-eliminación
V R(i): P(i) 3 R(O: P(i)
~3 R(i): ~P(i) ~ V R(i): ~ P(i)
Supongamos que se quiere demos trar que todos los enteros pares mayore
s
que 2 no son primos. En este caso, R es el predicado:
y P es el predicado:
i no es primo
inducción tiene también una relación muy estrecha con el concepto matemático
de funciones recursivas (como se vio en el Capítulo 2) y una gran aplicación en la
resolución de problemas y en programación (véase Capítulo 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.
P(l)
P(l) ~ P(2)
P(2) ::::- P(3)
Combinando las dos primeras líneas es posible concluir, utilizando modus po-
nens, que P(2) es válido. Combinando la veracidad de P(2) con la tercera línea, es
de nuevo posible concluir que P(3) es verdadero. Es posible continuar de esta
forma indefinidamente hasta demostrar que Vi E {l, 2, oo.}: P(n) es válido.
Ejemplo 3.30. Supongamos que St; desea probar por inducción que Vn > o:
n n(n + 1)
j~l j = 2 . Consideremos los dos casos:
84 Computación l. Lógica, resolución de problemas, algoritmos y programas
n
n(n + 1)
Caso base. Demostrar que Lj 2
j= 1
" i( i + 1) i ~1 . (i + 1)((i + 1) + 1)
¿j= ~ ¿J
j=l 2 j=l 2
i+ 1 i
¿j L j + (i + 1) Propiedad de L
j= 1 j=l
i
i(i + 1) i(i + 1)
2
+ (i + 1) Suponiendo L j =
2
j= 1
i(i + 1) 2(i + 1)
+ 2 Aritmética
2
(i + 1)((i + 1) + 1)
Aritmética
2
A primera vista, puede parecer que la inducción matemática es una forma circu-
lar de razonamiento. Sin embargo, lo que está realizándose es, en alguna medida,
un «razonamiento hipotético». Lo que decimos es «Supongamos que P(n) es
cierto. ¿Podemos deducir de ello que P(n + 1) también lo es?». Esto no demues-
tra la validez de P(n + 1), sino sólo que P(n) implica P(n + 1). Considérese de
nuevo la analogía con la ascensión de la escalinata. En realidad, lo que estamos
diciendo es «Supongamos que nos encontramos en el n-ésimo escalón, ¿puedo
desde aquí ir al siguiente?». Esto no supone afirmar que sepamos llegar al
n-ésimo escalón, sino que estando en él somos capaces de alcanzar el n + l-ésimo.
Es la combinación de las capacidades de saltar de uno al siguiente, y la de
alcanzar el primer escalón (es decir, probar P(I)), lo que permite alcanzar el n-
ésimo.
1 r
RHS = = 1, para r =1= 1
1 - r
1 - rn+1
RHS + r n+1
1 - r
1 - r n+2
1 - r
3.6. RESUMEN
En este capítulo hemos estudiado los fundamentos de la lógica, prestando espe-
cial atención a su utilización en la informática. La lógica proposicional, la equi-
valencia y las demostraciones se han revelado como inestimables herramientas
en la resolución de problemas. El cálculo de predicados tiene una utilización
directa en Pascal, en forma de expresiones booleanas. Se han introducido méto-
dos deductivos de demostración, incluida la inducción, útiles para el estudio del
diseño de programas y la verificación, que se verán en capítulos posteriores.
Ejercicios
3.24. Demostrar que la suma de los n primeros números impares es n 2 •
n
(Nota: nA
i=O
i significa A o n Al n ... n A n)
L
n
n(n + 1)(2n + 1)
b) ¡2
i=O 6
n
n2 (n + 1?
c) L ¡3
4
i=O
CAPíTULO 4
PROBLEMAS ALGORíTMICOS
V SU SOL UCi ÓN
n una
Definición. Un algoritmo es una lista de instrucciones que realiza
de un proces o que garant iza que resuelve
descripción paso a paso y precisa
pertene zca a un tipo determ inado, y que termin a
cualqu ier proble ma que
después de que se hayan llevado a cabo un númer o finito de pasos.
mas, o
Los algoritmos se escriben o diseñan con el propós ito de resolver proble
más exactamente, proble mas algorít micos.
tual o
Definición. Un problema algorítmico es cualquier problema, concep
práctico, cúya solución puede expres arse median te un algorit mo.
tanto den-
En la vida cotidia na encont ramos muchos proble mas algoritmicos,
especia lizado de la inform ática. Por ejem-
tro como fuera del campo altame nte
prepar ar pollo a la cazado ra constit uye un
plo, una determ inada receta para
ma genera l de prepar ar pollo a la cazado ra es
algoritmo, mientras que el proble
o. En la Tabla 4.1 se presen tan alguno s ejem-
el proble ma algoiítmico asociad
plos comunes de algoritmos y de proble mas algorítmicos.
existen
Para cada proble ma algorítmico como «cursar una licenciatura»,
utilizar se como solució n. Por ejem-
varios algoritmos alternativos que pueden
ingenie ría en inform ática, seguirá un
plo, un alumn o que desee cursar una m-
en el que desee licenci arse en ciencia s medioa
algoritmo muy diferente que
bientales o en filosofía.
alcs
En cualquier caso, los algoritmos de la Tabla 4.1 exhiben las princip
ación
características señaladas en la definición: exactitud, efectividad y termin
tarse
garantizada. Cuand o se ejecutan determ inados algoritmos pueden comple
llevar mucho
en un pequeño intervalo de tiempo, mientras que otroS' pueden
Problemas algorítmicos y su solución 91
tiempo. Sin embargo, la ejecución de todos los algoritmos debe terminar. Por
ello, cualquier descripción paso a paso de un proceso que no termine, no es un
algoritmo. Por ejemplo, el proceso de escribir todos los números enteros posi-
tivos, uno a uno, no es un algoritmo, puesto que no terminaría nunca.
En la informática se asocia la noción de algoritmo con la de un proceso
que debe ser ejecutado por una computadora, en lugar de por una persona. En
princjpio, cualquier algoritmo que diseñemos para una computadora puede ser
realizado a mano (suponiendo que disponemos del tiempo necesario, una piza-
rra o suficiente papel). En realidad, encargamos a la computadora la ejecución
de los pasos que componen un algoritmo, porque es capaz de completarlo en
un tiempo mucho menor del que nosotros emplearíamos, y porque es menos
proclive a cometer errores que nosotros.
Sin embargo, no todos los algoritmos pueden ser ejecutados por computa-
doras. Las computadoras sólo pueden ejecutar algoritmos que se componen de
acciones individuales que pueden entender y realizar. Por ejemplo, la prepara-
ción 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 cuáles son las tareas que puede
realizar una computadora, de forma que diseñemos algoritmos que contengan
sólo ese tipo de tareas.
Como punto de partida, considérese el sencillo modelo computacional de la
Figura 4.1.
Procesador/
[ Teclado/Ratón
I
- - - - '--_M_em_o_ri_a_--..JI--- Pantalla de monitor
Ejercicio
,
4.2. DEFINICiÓN DE PROBLEMAS Y DESCRIPCiÓN
DE ALGORITMOS
{pre: ent rada = una expresión que describe todas las posibles entradas
del problema}
{post ent rada =0/\ sa l i da = una descripción de todas las salidas que
pueden darse para cada entrada}
Especificaciones
Figura 4.5. Una versión del problema del cálculo del promedio
anotada parcialmente.
Ejercicios
este
del prome dio para una lista de calificaciones arbitra ria. Considérese
una extens ión del proble ma CM. Ser muy genera l al
proble ma como
describir los pasos del proceso. ¿Que variable adicional es necesa ria?
Ejercicio
4.3. ¿Cuáles serían la precondición y poscondición del proceso del
4.2? Definir una lista sencilla y la salida corresp ondien te que daría el
algorit mo constru ido.
•
Listas. Este programa hace us\> del tipo L; s ta y sus operaciones relaciona-
das, que se resumen en la Figura 4.7. Los programadores pueden utilizar el
Problemas algorítmicos y su solución 101
B~
Entrada
RadLi sta
;::1:7.: :~"g3l
,,----..@
e List0 InserLista
DeleteLista
¡salida I GV
Figura 4.7. Resumen de las operaciones de Lista.
tipo Lis ta y sus operaciones, sin más que hacer la declaración uses Lis ta;
después de la cabecera del programa. (Las definiciones están ocultas al progra-
ma, aunque su utilización 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 número cada vez. Esto supone una ayuda inestimable para la resolución de
muchos problemas algorítmicos, 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:
(3 2 1 3)
Notas = (3 213)
que Leng-
del elemento devuelto. Así, por ejemplo, un caso posible podría ser
va el valor integ er 4, y Notas [3] devuelva el
htLis ta (Nota s) devuel
Lis ta
valor real 1. Una díscusión más comple ta de las operacíones sobre
torio. Es
mostra das en la Fígura 4.7, puede encont rarse en el manua l de labora
utilicen
conveniente repasa r esta discusión antes de constru ir progra mas que
listas.
asertos
Limitaciones del conjunto de caracteres ASCn. Cuand o se incorp oran
es necesa rio record ar las
y otros comentarios dentro del texto de un progra ma,
que es el estánd ar de los carac-
limitaciones del conjun to de caracteres ASCn,
ctores de
teres que se pueden codificar y que utilizan la mayor ía de los constru
de Americ an Standa rd Code for Infor-
compu tadora s. (ASCII es un acróni mo
conjun to de caracte res estánd ar, es posi-
mation lnterchange)*. Utilizando un
entre compu tadora s diferentes. (Como entre
ble la transferencia de información
res ASCII
Macin tosh y PCs de IBM, por ejemplo). La lista comple ta de caracte
y su. codifícación se incluye en el Apénd ice A.
les,
Los científicos suelen utilizar letras gríegas y otros símbolos especia
áticas o al
subíndices, superíndices, al escribir expresiones lógicas y matem
escribir asertos. En el proble ma de CM se utilizaron, por ejemplo, No t a Si' 0
los Capí-
y ~ estilo matemático, contin uando con la notació n convencional de
aparec er dentro de
tulos 2 y 3. Desgraciadamente, esos caracteres no pueden
conjun to de caracte res
un progra ma Pascal, por no estar incluidos dentro del
ma Pascal,
ASCII. Por ello, cuando convertimos un algorit mo en un progra
la sustitu ción de los símbolos
utilizamos un convenio de sustitución ASCn para
más comunes, como el de la Tabla 4.2.
Tabla 4.2. Sustitu tos ASCII para los símbol os matem áticos
Sustituto
Símbolo
Significado ASCII
matemátíco
bio de Información.
• N. del T.: Estánda r Americano de Codificación para el Intercam
Problemas algorítmicos y su solución 103
El concepto de bucle es uno de los más importantes de todos los que se utilizan
en el diseño de algoritmos. ¿Por qué necesitan bucles los programas? Existen
dos razones fundamentales:
1. Economía de las expresiones.
2. Impredecibilidad del tamaño de la entrada.
Ambas razones para la existencia de bucles se pueden comprender si analiza-
mos la situación siguiente: Supongamos que es necesario diseñar un algoritmo
que calcule S como la suma de seis calificaciones, dadas por las variables 91 a
96. Una forma de calcularlo sería realizando la declaración y secuencia de
instrucciones Pascal siguiente:
S := O;
8:=8+91;
8 := 8 + 92;
8 := 8 + 93;
8:=8+94 ;
8:=8+95;
8 := 8 + 96;
pueda
en el momento en que se escribe el programa, de forma que el progra ma
para cada valor particu lar de n, en el mome nto en que
calcular el valor de Sum
en una
el progra ma es ejecutado o, como dicen algunos, corrido. Es decir,
mismo
ejecución del programa, n puede valer 6, y en la siguiente ejecución del
progra ma 100, en otra quizá 1000.
an
Lo que ,necesitaremos es que el lenguaje aporte facilidades que permit
generalizaciones de dos tipos:
ió en la
La primera posibilidad la aporta el tipo Lis ta, tal y como se describ
ción de Pascal
sección anterior. La segunda capacidad la aporta la instruc
instruc ción, o grupo de
wh i l e, que permite ejecutar reiteradas veces una
cada repetic ión. Esto es
instrucciones, pero con interpretaciones diferentes en
cción que nos calcula ba la
lo que necesitamos para simplificar la torpe constru
suma de n valores.
Ilustremos estas capacidades por separado. Supongamos que se declara
91 a 96.
sólo una variable 9, del tipo Lis ta, en lugar de las seis variables de
ma origina l en la forma siguien te, sin
Entonces, es posible cambiar el progra
cambiar su significado:
varg: Lista;
5 := O;
5 :=5+g [1];
5 := 5 + g[2];
5 := 5 + g[3];
5:=5+ g[4];
5 := 5 + g[5];
5 :=5+g [6];
8 := O;
i := 1;
8:=8+ g[i];
i :=i+1 ;
8:=8+ g[i];
i := i + 1 ;
8:=8+ g[i];
i:=i+ 1;
'8 := 8 + g[i];
i:=i+ 1;
8:=8+ g[i];
i:=i+ 1;
8 ;= 8 + 9 [i];
i:=i+ 1;
Figura 4.8. Suma de seis elemen tos: un paso hacia la genera lización .
Instrucciones de inicialización
while b do
begin
s;s; ... ;5
end;
Por tanto, los requisitos para que un bucle sea controlado son que las instruc-
ciones de inicialización, la expresión booleana b y las instrucciones s; Si
... i s estén escritas de tal forma que: 1) se garantice la terminación del bucle;
y 2) se satisfaga la poscondición del bucle.
En nuestro ejemplo, las instrucciones de inicialización S : = O e ; : = 1, la
expresión booleana ; <= 6, Ylas instrucciones S : = S + 9 [ i] e ; : = ; + 1,
combinan y satisfacen estos requisitos. Es decir, nuestro ejemplo puede reescri-
birse como el bucle controlado de la Figura 4.11.
5 := O;
i := 1;
while i <~ 6 do
begin
5:=5+g[i];
i := i + 1
end¡
Para demos trar que esto es, sin duda, el invariante del bucle, debem
os
compr obar que cada valor de ; durant e la ejecución del bucle:
Antes
de la Estado Comprobación del invariante
iteración
Puesto que la quinta iteración no tiene lugar (se produce la salida del
wh i Le,
puesto que; <= n cambia a falso), el invariante conduce al cumplimiento
de la
poscondición al salir del bucle. Esto es,
Sum = Su.. j in (1, "."' i - 1}: Notas [j] /\ 1 <= i <~ n+1
prog ram as
ón de prob lem as, algo ritm os y
108 Com puta ción ,. Lógica, resoluci
y el invariante
1 <= ; <= n + 1
n {1, ... , ; - 1 }: Not as [j]
1\
Suro = SUII j ;
etívos en
de forma intencionada con dos obj
El cuerpo del bucle se ha diseñado
mente:
1. El cuerpo preserve el invaria
nte (valga verdadero).
sión hacia la terminación del bucle.
2. El cuerpo produzca una progre
do lo
hacer ni más ní menos que esto -to
En general, los bucles no tienen que
demás es irrelevante.
ma
4.3.3. Tres vision~s de la misma solución al proble
",.
les de
lta de la composición de tres nive
El pro gra ma de la Figura 4.6 resu la descripción del proceso, que describe
cal;
lenguaje distintos: el código en Pas ma; y
tell ano qué ocu rre en cad a pas o del proceso que describe el progra
en cas ceso.
antes y después de cad a paso del pro ir,
la especificación formal que aparece dec
nivel elevado de redundancia; es
Los tres niveles jun tos suponen un estilos diferentes -alg orí tmi co formal
tres
expresan los mismos conceptos en no) y declarativo formal (especificac
io-
ico info rma l (castella
(Pascal), algorítm
nes). de que una solución pro gra mad a
a un
Est a redundancia enfatiza el hecho ienc ias:
te par a tres tipos de aud
algoritmo se escribe simultáneamen
1. La computadora.
grama.
2. La gente que diseña y lee el pro del programa.
la cor recc ión
3. La gente que verifica
ado ra
nta el código en Pascal: la com put
La com put ado ra sólo tiene en cue ores hu-
realizar el proceso. Los programad
seguirá con exactitud el código al en
en Pascal, los comentarios escritos
manos se interesarán por el código quieren entender y desarrollar correc-
s si
castellano, y las pre y poscondicione
Problemas algorítm icos y su solució n 109
progra ll ca l cu laCM;
uses
Listas ;
var
Notas : Listas ;
i, n : intege r;
Sum, CM: real;
begin
WriteL n ('Intro ducir la lista de califi cacio nes:') ;
ReadL ista (Notas );
n := LongL ista(N otas);
if n > O then
begin
Sum := O;
i := 1 ;
while i <= n do
begin
Sum :=Sum +Nota s[i];
i := i + 1
end;
CM := Sum/n;
WriteL n( 'La CM de esas cal ificac iones es = " CM : 5
2)
end
end. (Calcul aCM}
Ejercicios
4.4. La lista siguiente contiene la lectura de las temperaturas diarias de una
semana de verano.
4.7. Escribir un bucle contro lado que satisfaga las especificaciones siguien
-
tes:
4.8. Escribir las instrucciones de Pascal que calculen el promedio de las siete
temperaturas de la lista del Ejercicio 4.4, asignando el valor a la varia-
ble TemProm. Dar las precondiciones y postcondiciones de esas instruc-
ciones, así como el invariante del bucle controlado que contienen.
var x, y: reaL;
m, n, p: ínteger;
begin
readln (x, m);
read (y);
read (n, p);
wríte (n, x);
wríteln (p);
wríteln (y, m);
end.
13.215
23.7
236575
354679
4.4.1. Cálculo de el
Desarrollemos un programa llamado Pot en c i a que calcule la b-ésima poten-
cia de a, o ab , donde a y b son enteros y el resultado un número real. Por
ejemplo, escrito como una función de Pascal Potencia(2,3) calcularia el
valor 2 3 = 8.
El\ la construcción de una solución, debemos precisar previamente no sólo
el resultado esperado, sino también el rango de enteros para los que el progra-
ma está bien definido; es decir, sus precondiciones. En particular, debemos
especificar que ciertas parejas de valores de a y b, tales como a = OY b = - 1,
deben ser excluidas, puesto que podrian conducirnos a errores computaciona-
les. (En este caso, Potenci a (0,1) representaría 0- 1 ó 1/0, que representa
una división con resultado indefinido). También debemos tener en cuenta las
limitaciones del lenguaje de programación en el que expresamos el algoritmo.
Por ejemplo, muchas versiones de Pascal restringen el rango de valores de los
enteros al rango - 215 ... 2 15 - 1. Si identificamos estos valores con Mi nlnt y
Maxlnt, respectivamente, entonces las precondiciones de Potencia pueden
descartar todos aquellos valores de a o b que conduzcan un resultado que
exceda a Minlnt o Maxlnt. Por ejemplo, a = 2 Y b = 16 darían como
resultado 216 , que sería un valor mayor que Maxlnt para muchas versiones
Pascal.
Teniendo presentes estas condiciones, las precondiciones y poscondiciones
siguiente podrían ser apropiadas para diseñar el programa de la potencia.
Definición ab = 1 if b O
if b > O
: ':/~av'~ ~'.:~ I if b < O
Lb-a es
En la construcción de una solución al problema, debemos tener en cuenta que
el valor de b, que gobierna el número de veces que se calcula a por a, es una
variable. Por tanto, cualquíer solución que calcule el producto de las bases
debe contener un bucle.
El diseño del bucle se ve facilitado si analizamos el caso en que b es
pequeño, y la varíable 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 número de iteraciones del bucle es b - 1.
114 Computación ,. Lógica, resolución de problemas, algoritmos y programas
1 P := a {P = a}
2 P := a;
P := P * a {P=a*a}
3 P := B;
P := P * a;
P := P * a {P=a*a*a}
4 P := B;
P := P * a;
P :=P*a;
P := P * a {P=a*a*a*a}
progra. Potencia;
{Este programa calcula la b-ésima potencia de a)
varP: real;
1I, b, i: i nteger;
begin
{Pre : ent rada = a b A (a <> O or a ~ O A b <> O)
b
A Mi nlnt <= a <= Maxlnt}
WriteLn( 'lntroduci r dos enteros a y b: ');
ReadLn(a,b);
i f b = O then
P := 1
else
begin
P := a;
i := 1;
while i <= abs(b) - 1 do
{i nv: P = a; A 1 <= i <= b)
begin
P := P * a;
i := i + 1
end;
if b < O then
P := 1/P
end;
WriteLn('Potencia(a,b) =',P);
{post: entrada = vacio A salida = a b )
end. {Potencia)
Los tipos numéricos integer y real se utilizan en casi todos los problemas
algorítmicos. Sin embargo, un gran número de problemas no se resolvería
adecuadamente con sólo esos dos tipos. Muchos problemas involucran a cade-
nas de caracteres ASCII, como datos, y su solución precisa la utilización de un
conjunto de operaciones características de este tipo de datos. La noción de
cadena en Pascal puede definirse de la forma siguiente:
En la Figura 4.1 hemos visto ejemplos de cadenas. Por ejemplo, todos los
mensajes como:
• N. del T.: Algunas implementaciones de Pascal incluyen entre los tipos incorporados el
tipo string. Por ello, cuando nos refiramos al concepto seguiremos hablando de «cadenas" de
caracteres y utilizaremos la palabra «slring" cuando hablemos del tipo.
Problemas algorítmicos y su solución 117
va .. s: st .. ing;
• N. del T.: En las Figuras 4.15 y 4.16 na se han traducido los nombres de las funciones.
pues son los mismos que suelen tener esas funciones en las implementaciones de Pascal. que
incluyen el tipo «string».
118 Computación ,. Lógica, resolución de problemas, algoritmos y programas
¡Input I 12
'Hello World!'
va .. s: St,;ng; 7
(
s := 'Hello World! ';
'Hello World!'
lnsert(', Ciao', s, 12)
1Output 1
Figura 4.16.
"
'Hello World, Ciao!'
esos
conoce r.
IMundo ! I
{pre: entrad a ~ 'c[1J c[2J .,. c[nJ' /\ n >= O 1-. cada c[iJ
es
un caráct er ASCII}
{post: entrad a ~ vacia /\ sal ida = número de palabr as de
la entrad a}
Un progra ma que resuelve este problema, utilizando la mayoria de
las funcio-
nes de la Figura 4.16, se muestra en la Figura 4.17.
Aunque los tipos numéricos y cadena de caracteres son la base de gran canti-
dad de problemas algorítmicos, no sirven para caracterizar aquellos problemas
que implican la representación de información gráfica. Este tipo de problemas
incluye la visualización y análisis de imágenes de rayos X, fotografías desde
satélites, tableros de ajedrez y otros tipos de tableros de juego, y otros tipos de
gráficos utilizados habitualmente en gestión comercial y en el cálculo científico.
Para ilustrar este tipo de problemas, consideremos el conocido juego de las
tres-en-raya. Supongamos que se nos pide que construyamos un algoritmo que
muestre los movimientos individuales del juego de las tres en raya, reflejando
cada movimiento (X o O) en un entramado rectangular de la pantalla de la
computadora.
Para poder resolver este tipo de problemas necesitamos un nuevo tipo de
datos y el correspondiente conjunto de operaciones asociadas, que permitan a
un programa dibujar y realizar transformaciones sobre un array* rectangular,
denominado ent ramado de celdas individuales. Cada celda puede rellenarse
de una de las cuatro formas siguientes: No (sin rellenar); Sí (rellena en gris); X o
O. En la Figura 4.18 se muestra un entramado de 3 x 3 celdas, las cuales
tienen valores particulares en la que las filas y columnas del entramado se han
numerado de la forma convencional. La celda de la fila 1, columna 2 es una X;
la celda en la fila 2, columna 1 es Sí; la celda de la fila 3, columna 3 es O; y las
seis celdas restantes son No.
El número de filas y columnas, así como el tamaño de cada celda, se
establece en el momento en que el programa lo crea. El tamaño de la celda se
mide en pixels, que son unidades gráficas de la pantalla de la computadora y
que no son divisibles en unidades más pequeñas. 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 posición en la pantalla de su esquina superior izquierda,
cuando se visualiza el entramado. La localización viene dada por un par de
• N. del T.: Aparece aqui por primera vez la palabra inglesa ARRAY. Como ocurriera con
string, esta palabra se ha traducido de muchas formas, en mi opinión todas ellas insatisfactorias.
Por ello prefiero, tanto en este punto como en ocurrencias posteriores, respetar el término inglés.
122 Computación l. Lógica, resolución de problemas, algoritmos y programas
Anclaje
3
o
Figura 4.18. Un entramado de 3 x 3 celdas y las situaciones de las mismas.
CellOn ~ole~
CellOff
CellX
Ce llO
TurnCellOn
TurnCellOff
TurnCellX
TurnCellO
• N. del T.: Seguiremos aquí el mísmo convenio entre tipo y objeto que utilizamos entre
cadena y slring.
Problem as algorítm icos y su solució n 123
StartG rids;
StopG rids;
TurnC ellX(d , 1, 2)
(10, ro;
(200,2~
for i := 1 to GridSize(d) do
TurnCeLLX(d, i, 2);
Donde se ha utilizado la variable integer i para recorrer todas las filas del
entrainado d, y se ha utilizado la función GridSize para obtener el número
total de filas y columnas del entramado d.
Finalmente, el grupo de operaciones CeLLOnCd, i, j), CeLLOffCd,
i, j), Ce LLX Cd, i, j) y Ce LLO Cd, i, j) pueden utilizarse para cono-
cer el estado de la celda de la fila i, columna j del entramado d. Por ejemplo,
si nuestro entramado d tuviera el aspecto del de la Figura 4.18, la función
CeLLOnCd, 1, 3) devolvería el valor faLse míentras que la operacíón
Ce LLX Cd, 1, 2) devolvería el valor t rue.
Con estas operaciones presentes podemos resolver el problema propuesto
al princípio de la sección. El programa de la Figura 4.21 controla el juego de
Las Tres-en-Raya, solicitando una alternancia de movímientos a dos jugado-
res, y redibuja la situación del juego en la parte gráfica de la pantalla.
program TresEnRaya;
uses Grids;
begin
{pre: una serie de movimientos de las Tres en Raya}
Ejercicios
4.14. Repetir el Ejercicio 4.13, pero cambiando el programa para que escriba
los n números en orden inverso. (Es decir, cada número es la mitad del
anterior.)
4.15. Escribir un programa que lea 25 enteros y que cuente cuántos de ellos
son negativos.
4.16. Escribir un programa que lea 100 enteros y que determine y escriba
cuántos de ellos son divisibles por 5.
Problem as algorítm icos V su solució n 127
,¡Cuidado!
4.18. ¿Qué hacen los fragmentos de progra ma siguientes? Es decir,
¿si in-
troduje ra y ejecutase en la compu tadora este progra ma, cuál seria
la
salida?
a) var
k, j, m: intege r;
n: real;
begin
k := 4;
j := 8;
m := 9;
n := m div j + k * 1.0 - m div j;
writel n ('n= " n)
end;
b) var
m, j: intege r;
begin
m :~ 4;
j := 1;
whi le (j < m) do
begin
j:=j+ 2;
m := m+ 1
end;
writel n ('m= ',m, Ij= " j)
end;
e) var
k, j: intege r;
begin
for k : = 1 to 10 do
begin
j := 10 - k;
i f (j <= 4) then
j := j - 1
end;
writel n ('j = " j, 'k= " k)
end;
ti) var
n, m: intege r;
begin
n := O;
m := 1;
128 Computación l. Lógica, resolución de problemas, algoritmos y programas
e) var
j, k, m: integer;
begin
k := O;
for j : = 1 to 3 do
for m := 1 to 4 do
k :=k+1;
writeln ('k= " k)
end;
f) uses
Lista;
var
k: Lista;
j: integer;
begin
k[1] :~ 1;
for j := 2 to 4 do
k[j] :~k[j-1]+j;
wri teL i sta (k)
end;
g) uses
Lista;
var
m: Lista;
j: integer;
begin
j := 1;
while (j <= 2) do
begin
m[j + 2] :~ j;
m[3-j] :=j;
j :~j+1;
end
WriteL i sta (m)
end;
4.20. Escribir un programa que cambie a cero todos los valores de una lista
que ocupen una posición impar y que sean impares. Es decir, si llama-
mos L a la lista, el programa debe examinar L[1 J, y si contiene un
Problemas algoritmicos y su solución 129
O! 1
n! n x (n - 1)1
4.25. Comprobar que el invariante del bucle del programa ContadorPa La-
bras es válido para la entrada del Ejercicio 4.24, analizándolo para
cada valor de i que provoca un cambio en npa Labras. Por ejemplo,
la primera interpretación del bucle ocurrirá cuando i = 6, Yse leería de
la forma siguiente:
'mayo 1992'
'2991 oyam'
4.28. Escribir un programa que calcule el coste total del franqueo postal de
una serie de envíos. Debe contener un bucle que lea la cantidad y precio
de cada envío y lo acumule al total. Después de que se haya introducido
el último elemento, el programa mostrará el coste total de la operación
y el número total de envíos realizados. El coste total deberá reflejar un
5 por 100 de impuestos. Asegúrese de incluir en el propio programa las
pre y. poscondiciones.
4.5. RESUMEN
El conocimiento puede ser de dos tipos. Conocemos algo por nosotros mismos,
o conocemos dónde podemos encontrar información sobre ello.
SAMUEL JOHNSON, 1775
* N. del T.: En el texto se respelará el acrónimo inglés MAPS (Methodology for Algorith-
mic Problem Solvíng), debido a que el autor pretende enfatizar la semejanza de la metodología con
el término Map o Mapping, que podría traducirse por correspondencia y que se utiliza amplia-
mente en la terminologia informática. Debido a que al traducirlo es imposible capturar este
concepto, respetamos el acrónimo original.
132 Computación l. Lógica, resolución de problemas, algoritmos V programas
Algunas rutinas son tan comunes que están incluidas en el lenguaje de progra-
mación Pascal para utilizarlas en los programas. Estas rutinas incluyen los
operadores numéricos (+, -, *, /, di v y mod); las expresiones aritméticas,
las estructuras de control (i f, wh i Le y f o r); los operadores de entrada,
salida y asignación (read, wri te y :=) y los operadores de cadenas (copy,
pos y Length). Se pucden añadir al lenguaje otras rutinas para manipular
listas (ReadL i s t a, Wri teL i s tal y entramados (Ma keGr i d, Gr i dS i ze y
TurnCeLLOn).
Existe una gran variedad de rutinas para diferentes dominios de la resolu-
ción de problemas. Varios de ellos se introducirán en este capitulo.
PromedioLista(L):
{pre: L= (e" e" """' en) 1\ n:i'a 1\ Vi E {1, """' n}:: e, es un número}
{post: n > a 1\ resultado = Sum i E {1, .""' n}: eJn
v n ~ a 1\ resul tado = a}
n :~ lengh\;l i sta(L);
if n > O then
begin
Sum :~ O;
i := 1;
while i <= n do
begin
Sum := Sum + l[i];
i := i + 1
end;
..esul tado := Sum/n;
end {if}
else
..esul tado := O
(post: n>OA resultado~Sum; E {1, "0' nI: eJn
v n = O /\ resu l tado = O}
end; (P .. omediolista)
prograll calculacM;
{esto es un programa que ca lcu la la CM de una seri e de una o más
calificaciones numéricas, cada una de ellas en el rango O.. 4,
que se introducirán por el teclado}
uses
Listas;
var
Notas: Listas;
CM: real;
function PromedioLista (L: Lista): real;
{Esta función calcula la media de los valores de una lista)
uses
Listas;
var
i, n: integer;
sum: real;
Resolución de problemas algorítmicos 139
begin
{pre: L = (e" e" ... , en) /\ n :;" O /\ Vi E {1, ••• , n}: /\ n :;" O /\
Vi E {1, ... , n}:: e; es un número}
n := LenghtL ista(L};
i1 n > O then
begin
Sum := O;
i := 1;
ilhile i <= n do
begin
Sum :~ Sum + L[i];
i := i + 1
end;
PromedioLista := Sum/n;
end {;t}
else
PromedioLista := O
{post: n > O /\ resu l tado = Su. i E {1, ... , n}: e;!n
v n = O /\ resu l tado = O}
end; {PromediLista}
begin
pre: entrada = (Notas" Notas" ..• , Notas n) /\ n > O /\
Vi E {1, ... , n} :Notas; E {O, ... , 4}}
CM := PromedioLista (Notas);
Salida
Entrada 2.25
(32 1 3)
llamarla Suma Lis t a y escribir sus especificaciones para una lista arbitra
ria L,
como las siguientes:
Figuré 5.5. Especi ficació n de la abstrac ción que suma los elemen tos
de una lista.
Figura 5.7. Especi ficacio nes de la abstrac ción Cuent aPaLa bras.
Existen otros muchos fragmentos de progra mas que tienen gran utilida
d y
que pueden ser convertidos con facilidad en rutinas. Otras cuatro
abstraccio-
nes simples pueden ser de utilidad en una gran variedad de problemas
algorit-
micos que procesan listas. Los dos primeros (Figura 5.8) encuen tran
el lugar
que ocupa (índice) el mayor y el menor elemento de los m primeros
elementos
de una lista L.
Figura 5.8. Especi ficació n para las abstrac ciones de MaxL i sta y Mi nL
i sta.
142 Computación ,. Lógica, resolución de problemas, algoritmos y programas
Intercambiar<L, j, k):
{pre: L = fe" e 2 , •• _, e j , • • _, e k , •• _, en) 1\ 1 ~ j, k ~ n}
{post: L = (e" e" ""., e., "."' e j , • • • , en)}
PosLista(x, Ll:
{pre: L = (e" e" ... , en) 1\ X es un número 1\ n ~ O}
{post: 3i E {1, .""' n}: X = e, 1\ resultado = i v Vi E {1, ... , n}:
X"" e, 1\ resul tado = O}
Figura 5.9. Especificación de las abstracciones Intercambi a r y PostL i sta.
~Ci"''''
~10
( PosLista(O.O,Ll
12l
~'".b;''''' 2, 9l
L = (2.5 6.00.3 5.7 2.1 1.3 1.0 5.9 4.40.0 0.3 2.2)
MaxLista(L, k) =1 si k = 1
~k si k> 1 y e k > eMaxListaCL, k - 1)
j := 1;
fOI" k := 2 to m do
{invVi E {1, """' k-1}: e[j] >=e[i] /\2<=k<~m+1}
i f L[k] > L[j] then
j := k;
Max :=j;
Invocación Devuelve
Sublista Invocación Comparación
de em > MaxLista(L, m- 1) el re-
MaxL i sta m de L activa
sultado
1 4 (2 5 4 3) 2 3>MaxLista(L,3) 2
2 3 (2 5 4) 3 4> MaxL ista(L, 2) 2
3 2 (2 5) 4 5>MaxLista(L,1) 2
4 1 (2) ninguno ninguno 1
ReadLista(L):
{pre: entrada = (e" e u ..• , en) cualquier secuencia A n;. D}
{post: ent rada = cua lqui er secuenci a A L = (e" e u ... , en)}
L[ i] :
{pre: L= (e" e u •.. , en) A 1 ~i ~n}
{post: e, es un número A resul tado = e i v e, no es un número A
resul tado = D}
5:=5+'1.5'
(donde s simboliza una variable cadena) son incorrectas. Del mismo modo,
podemos leer y almacenar en una lista una colección completa de números
reales, tanto de un archivo externo como desde el teclado, utilizando la opera-
ción ReadL; sta. Sin embargo, no podemos hacer lo mismo si queremos leer
y almacenar una colección de cadenas. Podemos utilizar un a r rayen lugar de
una lista para almacenar una colección de cadenas, pero carecemos de la
flexibilidad para leerlas y almacenarlas si no inventamos y construimos las
rutinas que tengan la capacidad funcional de ReadL; sta. Estas diferencias
están resumidas en la Figura 5.15, que muestra, en una especie de diagrama de
Venn, el solapamiento funcional que existe entre a r rays y Listas. El men-
saje básico de estos párrafos es que ninguna estructura de datos ofrece todas
las ventajas de otra sin acarrear algunas desventajas. Esta situación es típica en
la informática; los profesionales de la informática se refieren a ella como «el
compromiso y las consecuencias» de tomar una decisión.
El tipo cadena es el más básico de los tipos construidos con valores elemen-
tales, puesto que puede contener cualquier número de caracteres separados por
blancos u otros caracteres ASCII no imprimibles (caracteres de control, tales
como saltos de línea y tabuladores). Así, cualquier carácter es una cadena, pero
no cualquier cadena es un carácter; por ejemplo, el carácter a es una cadena,
pero la cadena Pepe no es un carácter. Continuando con esta línea de razona-
miento, c'lda dígito numérico es un carácter, pero un carácter individual no
tiene por qué ser un dígito numérico. Por ejemplo, el dígito 3 es un carácter,
pero el carácter x no es dígito numérico. Igualmente, si colocamos un número
entre comillas simples tendremos una cadena, pero no toda cadena es un
número. Así, I 3 . 5 I es una cadena, pero I 1v á n I no es un número.
Iván RET
cami nó RET
3 RET
ki Lómetros RET
hasta RET
eL RET
coLegio RET
a RET
una RET
veLocidad RET
de RET
2,5 RET
ki Lómetros RET
por RET
hora RET
RET
150 Computación l. Lógica, resolución de problemas, algoritmos y programas
Es posible declarar el tipo de array siguiente, y una variable del mismo que
permite almacenar cada palabra del texto:
type palabra = string[16];
ListaStrings = a ....ay[1 .. 100] of palab ..a;
va .. Frase: ListaSt .. ings;
LongitudFrase: integer;
Apala~ra: palab ..a;
valCs, r, código)
{pre: s es una cadena)
{post: r = valor real equivalente a s 1\ código = O si la coerción
se rea liza con éx ito
strCr, s);
{pre: r es un número real J
{post: s es la cadena equivalente a r)
roundCx);
{pre: x es un número rea l )
{post: resultado=lx+O.5J}
trunc(x) :
{pre: x es un número rea l)
(post: resultado = lxJ}
152 Computación l. Lógica, resolución de problemas, algoritmos y programas
Por tanto, si queremos tratar el i-ésimo elemento de una lista L como un entero,
debemos convertirlo explícitamente utilizando una de las rutinas round o
trunco Por ejemplo, la instrucción siguiente asigna la parte entera (ignorando
la parte decimal) del i -ésimo elemento de L a la variable in t ege r j.
j :~ truncCL[i]);
,
¿Por qué son tan necesarias y útiles la tipificación fuerte y la coerción?
Existen varias razones. Primero, los lenguajes fuertemente tipificados suelen ser
más efectivos que los débilmente tipificados como vehículos de enseñanza de
los principios de la programación, por el simple hecho de que sus compiladores
detectan un rango de errores más amplio, y sugieren la forma de corregirlos
antes de que se produzca la ejecución del programa. En algunas ocasiones, las
listas incluyen elementos de distintos tipos, por lo que el programa debe identi-
ficar 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 cronológicamente de valores pluviométricos de los meses del año.
Las listas como esta, en que cada valor numérico está precedido inmediata-
mente por un nombre descriptivo, reciben el nombre de listas con atributos.
L = (Enero 2,5
Septi embre 6,0
Febrero 4,4
Mayo 2,1
Junio 1,3
Novi embre 0,3
Diciembre 2,2
Julio 5,9
Marzo 0,3
Abril 5,7
Agosto 1,0
Octubre 0,0)
Ejercicios
b) program fn;
var
k: integer;
function nd (m: integer>: integer;
var
n: integer;
begin
nd := O;
n := m;
while n >= 1 do
begin
n := n div 10;
nd := nd + 1
end
end;
begin
whi le not eof do
begin
readln (k>;
writeln ('ans = " nd(k»
end
end.
5.2. Implementar la rutina SumL; s ta, definida en la Figura 5.5, como una
función de Pascal. Probar que la función puede reutilizarse para conse-
guir una implementación alternativa del procedimiento Promed i 0-
Lis t a, diferente a la de la Figura 5.1.
5.10. Escribir una función recursiva SumL i sta (L, n) que devuelva la suma
de los n primeros elementos de la lista L.
Fib(n) o para n O
1 para n 1
Fib(n - 1) + Fib(n 2) para n > 1
MyFun := n + MyFun<n - 1)
else
MyFun :~ MyFun<n - 1)
end;
5.15. La rutina PosL i sta (x, U es muy útil cuando queremos determinar
si una lista tiene elementos repetidos. Escribir un programa en Pascal
que, para una lista arbitraria de númcros L, utilice PosL i s ta para
ayudarnos a descubrir y escribir los números que aparezcan más de una
vez. Por ejemplo, la lista L = (1 2 3 5 4 1 5 1 ) hará que el programa
escriba las duplicidades siguientes:
1
5
PrimosRelativos<B, 9) = true
PrimosRelativos<B, 10) ~ false
5.19. Diseñar y escribir en Pascal una función que examine los n elementos
de una lista y devuelva t rue si los elementos están ordenados en orden
decreciente, y fa l se en caso contrario. La función se llamará Prueba
y tiene que tener un parámetro para el nombre de la lis ta, y otros
para el número de elementos n que deben examinarse. Escribir un pro-
grama de prueba que invoque a la función para establecer si trabaja
correctamente.
5.3.1. El diálogo
ENTRADA SALIDA
CEnero, Febrero
Marzo, Abri L
Mayo, Junio
JuL i o, Agosto
Septiembre, Octubre
Noviembre, Diciembre)
a) b)
Figura 5.17. Dos representaciones alternativas de la entrada para el problema
de la pluviometría. al Dos listas de entrada. b) La lista de los valores pluviomé-
tricos como única entrada.
5.3.3. La partición
Rutinas
Elementos de datos
{pre: entrada = (e" e" " .. , e,.) /\ Vi E {1, """' 12) e, es el valor
pluviométrico del i-ésimo mes del año}
Podemos observar que las cuatro rutinas deben colocarse en este orden
para que la poscondición quede satisfecha. En concreto, la lectura de los valo-
res pluviométricos debe preceder a todos los demás pasos. Por si mismo, el
primer paso provoca la satisfacción de la especificación entrada = 0 de la
poscondición. Del mismo modo, a continuación debe calcularse y escribirse el
valor promedio por dos razones: Primero, el promedio es necesario como
entrada (calilla precondición) del paso 3, donde necesitamos calcular y visuali-
zar los meses cuya pluviométria está por debajo del promedio, y del paso 4,
donde encontramos y visualizamos el(los) mes(es) con máximo valor pluviomé-
trico. Segundo, la poscondición del problema exige que los valores promedio,
máximo y mínimo de pluviometría deben mostrarse antes de que se produzcan
las salidas de los pasos 3 y 4. Finalmente, el paso 3 debe preceder al 4, puesto
que sus salidas respectivas deben realizarse en este orden según las poscondi-
ciones del problema.
Ejercicios
5.21. Escribir la salida que aparecería si mezclamos los dos bucles for de los
pasos 3 y 4, del problema de la pluviometría, en un solo bucle for que
contenga las dos selecciones ; f, ante la entrada ejemplo de la Figu-
ra S.17. Es decir, suponer que se mezclan los pasos 3 y 4 de la forma
siguiente:
R
R2 WriteL n( 'media = "
R
Rl if <O < m) and (m <= LengthL i sta(L» then
begin
j := 1
fOI" k := 2 to m do
i f L[k](2:)L[j] then
j := k;
end
else
j := O;
~Lista :y
~nLista ::J>
Figura 5.23. Creación de una rutina R por la adaptación de otra R1.
R Rl
i f (O < m) and (m <= LengthL i sta( L» then
begin
Max := 1 ; R2
IMin:=1;
for k :~ 2 to m do
begin
i f L[k] > L[Max] then
Max := k;
end
end
else
begin
Max:=O;
I Min :=0
end;
I
Figura 5.24. Creación de una rutina nueva R por mezcla de otras dos R1 y R2.
166 Computación l. Lógica, resolución de problemas, algoritmos y programas
En los casos en los que no existe ninguna rutina disponible, debemos emplear
nuestra creatividad para construir las abstracciones procedimentales apropia-
das. En el problema de la pluviometría tenemos que utilizar nuestra creativi-
dad para encontrar una solución a los pasos 3, que debe escribir los meses
cuya pluviometria está por debajo de la media, y el 4, que debe mostrar el(los)
mes(es) cuya pluviometria es la máxima.
Aparentemente, ambos pasos requieren utilizar el mismo tipo de estrategia
-una búsqueda dentro de la lista de pluviometrias para encontrar los valores
que cumplen una determinada propiedad-. El índice de la lista PLuv i ome-
tri a puede utilizarse para encontrar el nombre del mes correspondiente, en el
array Meses. Considerando el ejemplo de entrada de la Figura 5.17b, el pro-
medio de lecturas pluviométricas de esta entrada es de 2,64 lts/m 2 . El valor
pluviométrico para PLuviometria[1] es 2,5, que se encuentra por debajo
de la media. Por tanto, el paso 3 debe mostrar el valor de Me s e s [1] o Ene ro
como una de las salidas. Para encontrar todos los meses que satisfacen la
misma condición, es necesario explorar los doce valores pluviométricos. Esto
se consigue con el bucle siguiente:
sqrtCx ):
(pre: x>=O )
(post: result ~ y 1\ y2 ~ x)
Existe una forma alternativa de calcular raíces cuadradas que nos permite
esquivar el necesario conocimiento del dominio que supone el método de New-
ton. Sin embargo, esta alternativa nos obliga a conocer el dominio de las ca-
racterísticas más avanzadas de las bibliotecas de funciones estándar de Pascal.
En concreto, Pascal incorpora las funciones exp(x) y ln(x) que calcu-
lan las funciones eX y el logaritmo neperiano de x, respectivamente. Combinan-
do esta información con los conocimientos adquiridos en el Capítulo 2, pode-
mos obtener:
b In (a)
a
In (x 1/2) = 1/2 In x
o bien:
X'f2 = e1f2 In (xl
5.5.1. Codificación
En pocas palabras, la codificación es la traslación de la solución de un
proble-
ma algorítmico a un programa, junto con su documentación. En la
resolución
de un problema algorítmico, la mayoría del código se obtiene durant
e las
etapas de partición y abstracción. Por ejemplo, hemos completado la
codifica-
ción de los pasos 3 y 4, del problema de la pluviometria, en la búsque
da de
nuevas rutinas que sean apropi adas para ellos. También los pasos 1
y 2 están
prácticamente codificados; sabemos que pueden implementarse reutiliz
ando y
combinando rutinas de otros problemas ya existentes.
El proceso de codificación implica el juntar las partes de la solució
n al
problema, asegurándonos de que el resultado conjun to es coherente,
inteligi-
ble, y satisface las pre y poscondiciones originales. Cuand o codific
amos en
Pascal suele ser útil utilizar una plantilla como la siguiente:
progra m <nomb re>;
{Breve comen tario que descri ba el proble ma, la estruc
tura genera l de
la soluci ón, el autor y la fecha}
uses <Bibli otecas de las que se tomará n alguna s rutina
s>;
<Decl aració n de las variab les identi ficada s en el proces
ción> o de parti-
begin
{pre: <Preco ndició n del problem a>}
{Paso 1. <Desc ripción del primer paso de la partici ón>}
{Paso 2. <Desc ripción del segund o paso de la partic ión}
{post: <Posco ndicio nes del problem a>}
end.
program Pluviometrias;
{El programa calcula algunas caracteristicas Pluviométricas
a partir de datos mensuales. Diseñador: Allen Tucker, 30 de marzo
de 1990. Reutiliza las rutinas MaxLista, MinLista y PromedioLista.}
uses Listas, Herrami entasL i stas;
begin
{pre: entrada = (e" e" .. "' e,,) /\ Vi E {1, .•. , 12} e, es el valor
pluviométrico del i-ésimo mes del año}
Es posible compr obar que se introdu ce exacta mente una lista de doce
elemen-
tos con las instrucciones:
repeat
Write lnC'in troduc ir la lista de los 12 valore s pluvio
métric os
mensu ales: 1);
Readl istaCp luviom etrias) ;
until length listaC Pluvio metria s) = 12;
5.5.3. Presentación
sea leído por alguien no familiarizado con la solución obtenida, pero sí con la
metodología y el dominio al que pertenece el problema. Es decir, el texto del
programa ---con su documentación, estructura paso a paso, y pre y poscondi-
ciones- debe ser fácilmente legible por un colega profesional, como lo sería un
artículo del ABe para cualquier persona bien educada.
La presentación de una solución completa de un problema algorítmico
debe incluir, además del propio texto del programa, los elementos siguientes:
program Pluviometrias;
(El programa calcula algunas caracteristicas Pluviométricas
a partir de datos mensuales. Diseñador: Allen Tucker, 30 de marzo
de 1990. Reutiliza las rutinas MaxLista, MinLista y PromedioLista.)
uses Listas, HerramientasLi stas;
begin
{pre: entrada = (e" e" .•• , en) /\ Vi E {1, .• ",12) e, es el valor
pluviométrico del i-ésimo mes del año)
5.6. RESUMEN
En el Capítulo 4 introdujimos las técnicas y herramientas básicas para cons-
truir programas sencillos en Pascal a partir de sus especificaciones. En este
capítulo hemos aprendido cómo analizar un problema y a desarrollar su solu-
ción, identificando elementos del programa más pequeños (rutinas) y combi-
nándolas todas en un programa completo.
Aprendimos algo del proceso de abstracción y de su realización en Pascal.
La creación de rutinas que puedan ser reutilizadas, es una de las tareas funda-
mentales del proceso de resolución de problemas algoritmicos. Podemos reuti-
lizar rutinas y recombinarlas en cuatro formas fundamentales --empalmándo-
las, anidándolas, adaptándolas y mezclándolas durante el proceso de creación
de una solución a un problema nuevo. Fuera de estos limites, es preciso utilizar
la creatividad y el conocimiento del dominio. Los otros aspectos de la resolu-
ción de problemas algorítmicos son evidentes en la metodología MAPS --el
diálogo, la especificación, la partición, definición de abstracciones, codificación,
verificación y prueba, y presentación.
Pero entender no es lo mismo que hacer. Antes de proseguir con el libro,
tómese algún tiempo para diseñar y escribir programas para los problemas
174 Computación l. Lógica, resolución de problemas, algoritmos y programas
Ejercicios
5.23. Implementar una rutina del método de Newton para calcular raices
cuadradas en forma de función de Pascal, y que tenga Z + como domi-
nio y R como rango. Probar el resultado para diversos valores de x, y
compararlos con los resultados de utilizar la rutina de cálculo de raíces
cuadradas de la Sección 5.4.
5.24. Escribir el cuerpo del procedimiento In; e; al; za rMeses del progra-
ma de la Pluv;ometr;a.
5.25. Continuar con el diseño MAPS sobre los números romanos esbozado
en el Ejercicio 5.20; definir las abstracciones y codíficar el programa
completo. ¿Es posible utilizar abstracciones vistas previamente? ¿Qué
abstracciones nuevas es necesario introducir, y qué tipo de creatividad y
conocimiento del dominio es necesario utilizar para completarlo?
Entrada Salida
(3 1 2 4) 2,50
(2 ) 2,00
(2 3 3 3 3 3 3 2) 2,75
Un estudio cuidadoso del programa de la Figura 4.6 hace que nos plantee-
mos algunas dudas sobre lo que ocurre cuando las entradas no satisfacen las
especificaciones de las precondiciones. Por ejemplo, ¿qué ocurre si la entrada
es la lista vacia( )? ¿Qué ocurre si la lista de entrada contiene valores fuera del
intervalo {O, ..., 4}, como la lista de pluviometrías mensuales utilizadas en la
Figura 5.17b, utilizadas para un problema completamente distinto? ¿Qué ocu-
rre si la lista contiene algo distinto de números, 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 pro-
grama con varias entradas alternativas que no satisfacen las precondiciones, y
ver qué ocurre en cada caso. Observemos el cuerpo del programa Ca Lcu La CM
y analicemos cómo tratará cada uno de los distintos casos (véase Figura 6.1).
Este es un programa tan sencillo que resulta conveniente un análisis tan
directo. En el caso en que la lista de entrada esté vacia, no se satisface la
condición n > O, por lo que el programa no genera ninguna salida. Sin embar-
go, en el caso en que los valores de la entrada no estén en el intervalo {O, ..., 4},
el programa calcula sin problemas el promedio y escribe (erróneamente) el
valor de la CM, aunque algunas entradas numéricas no sean calificaciones
válidas, según las especificaciones.
Robustez y prueba de los algoritmos 179
begin
{pre: entrada ~ (Notas" Notas" . o., Notas,) 1\ n > O 1\
\;Ii E {1,
o ni: Notas, E {O, .•. , 4}}
•• ,
(31 hello 2)
°
la referencia a Notas[3] devuelve el valor para esta lista en concreto, por
lo que el valor promedio es, por tanto, 1,50.
Tenemos que destacar, por tanto, que el programa Ca Lcu LaCM es correcto
en el sentido de la definición anterior. Sin embargo, no es robusto.
1. Es correcto.
2. 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.
1. Es correcto.
2. 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.
Ejercicios
en el mensaje codificado
Etapa 1: El diálogo. Existen tan pocas dudas acerca de este problema, que
podemos estar tentados de abordar directamente el diseño. Sin embargo, es
necesario apuntar y resolver algunas cuestiones de detalle. Por ejemplo, ¿puede
contener el texto tanto letras mayúsculas como minúsculas, e incluso caracte-
res no alfabéticos? Presumiblemente la respuesta es si, y tales caracteres deben
aparecer en el mensaje descodificado tal y como aparecían en el mensaje origi-
nal. Por ejemplo, el blanco del mensaje codificado permanece igual en el men-
saje descodificado.
[pre: entrada = una serie de mensajes, siendo cada uno una secuencia
de caracteres c" ... , c n representando una codi fi cación uti Lizando
eL método de César
"post: saLida = una serie de textos descodificados de La forma
d" ... , d n en La que cada d, satisface La reLación c, ~ César(d,) /\c,
es un carácter aLfabético v para todo i en {1, ... , n): c, = di}
a d A D
b e B E
x a X A
Y b Y B
z e Z C
repeat
{Paso 1. Obtener eL mensaje. J
Descodificar(mensaje)
{pre: mensaje = C 1 , e 2 , •• _, en}
{post: resultado = d" d" •. "' dn 1\ para todo i in (1, "."' n):
di = Césarlnversa(c»)
Césarlnversa(c)
(pre: c es un carácter)
(post: resultado = d, Y bien d es alfabético 1\ CésarCd) = c or d no
es alfabético 1\ d = c)
program Criptografia;
{El programa descodifica una serie de mensajes y escribe cada uno
descodi fi cado; se supone que cada mensaje se ha codi fi cado
util izando la cifra de César.}
function CésarInversa
function Descodificar
Yar
mensaje, descodificado: string;
186 Computación l. Lógica, resolución de problemas, algoritmos y programas
begin
{pre: entrada ~ una serie de lineas, conteniendo cada una un mensaje
codifi cado}
repeat
{Paso 1. Obtener el mensaje}
WriteLn('Introducir en una sola linea un mensaje codificado, y');
WriteLn,( 'pulsar <RET> para terminar:');
ReadLn(mensaje);
Etapa 6: Prueba. Es útil probar este tipo de programas utilizando como entra-
da un texto almacenado en un archivo separado. De esta forma, no es necesa-
rio reescribir de forma tediosa el mensaje de entrada cada vez que se ejecute el
programa. Una sencilla alternativa al programa anterior, que permita utilizar
una variable archivo (tipo file), en el que se escribiría la entrada, y que condi-
ciona la terminacíón del programa a que se lea la marca de fin de fichero, se
obtendría con las modificaciones siguíentes. Previas al paso 1 habría que escri-
bir:
reset(ArchivoTexto, 'codificado,txt');
El paso 1 debería alterarse para que tome la entrada del archivo, en lugar de
tomarla desde el teclado, en la forma siguiente:
ReadLn(ArchivoTexto, mensaje);
WriteLn(mensaje);
a) b)
Etapa 2: Las especificaciones. Después del diálogo, podemos escribir las si-
guientes especificaciones para este problema:
{pre: entrada =n, X 1 , y" XZ' Y2' •• _, Xn , Yn , C" e Z' ••• , Cm /\ Cm = I q ' /\
n > O 1\ m > O pa ra todo i in {1, ... , n}: 1 ,;; Xii y; ,;; 8}
Donde las pulsaciones de teclas C" Cl' ••• , Cm-' sirve para proporcionar al
usuario el control de las transiciones entre una generación y la siguiente. Es
decir, el carácter (incluida la barra espaciadora) que se simboliza por c; indica
al programa que tiene que calcular la i -ésima generación, a partir de la
(i -1)-ésima y dibujarlas una alIado de la otra. Por tanto, en cada momento, el
programa debe mostrar las dos últimas generaciones calculadas, siendo la de la
derecha la más reciente. La primera generación, dada por las coordenadas x"
y" x 2 ' Yl' ••• , x n, Yn' se identifica con el nombre de generación 1 de la
secuenCia.
La Figura 6.3 muestra una generación 1 inicial (en el entramado del lado
izquierdo) y la generación 2, que se obtendría si se pulsa la tecla de continua-
ción (lee las celdas sombreadas, fila a fila, suponiendo que las filas y las colum-
nas estén numeradas del 1 al 8):
6364546475456
for i := 1 to 8 do
for j : = 1 to 8 do
case Vecinos<Gen1, i, j) of
{sobrevivir: poner a on la celda i, j de Gen2}
{nacimiento: poner a on la celda i, j de Gen2}
{muerte: poner a off la celda i, j de Gen2}
end
var
Gen1, Gen2: Grid;
control: char;
Gennumero: integer;
begin
{pre: entrada = n, X 1 , y" x2 ' Y2' ••• , x n, Yn, C 1 , e 2 , .... , Cm 1\ C lII = Iql A
n > O 1\ m> O pa ra todo i in {1, ••. , n}: 1 <:; x;, y; <:; 8}
Obsérvese que el paso 3 tiene dos partes alternativas. Una que se ejecuta al
calcular una generación par, y la otra al calcular una impar. Esto se obtiene
directamente de la idea de los «papeles invertibles» de los entramados Gen1 y
Gen2. La variable gennumero lleva la cuenta de la generación que se está
calculando y visualizando.
Las rutinas nuevas que se utilizan en este programa se muestran a conti-
nuación. La primera es la rutina 1 ni e; aL; za r, que se muestra en la Figu-
ra 6.5. Simplemente pone a on cada celda del entramado G que se indica por la
fila y columna.
a) b)
Ejercicio
a) b) e)
Tabla 6.2
(3 1 2 8) 4 4
(8 1 2 3) 4
(3 8 1 2) 4 2
(-1 ·2··3 -8) 4
(3 1 2 8) 3
(3 1 2 8) 2
(3 2 8)
Los dos primeros datos de pruebas son importantes porque el valor máximo
ocupa la última y primera posición de la lista. respectivamente. El tercer caso
también es importante. pues representa el caso típico que puede ocurrir---es
Robustez y prueba de 105 algoritmos 199
program conductor;
(Este programa conductor prueba eL procedimiento <p(x, y»}
{ut i Lizando un juego de pruebas como datos de ent rada}
(deL archivo <archivo juego pruebas>}
end;
beg;n
WrHeLn('Parámetros de entrada = " <x»;
<p(x, y»;
Wr; teLn(' Resul tado de p(x, y) =' , <y»;
read«arch;vo juego pruebas>, <x»;
end;
WrHeLn( 'F;nal de la prueba del proced;m;ento <p(x, y»')
end.
(3 1 2 8) 4
(8 1 2 3) 4
(3 8 1 2) 4
(-1 -2 -3 -8) 4
(3 1 2 8) 3
(3 1 2 8) 2
(3 1 2 8) 1
(-1 -2 hello -8) 4
() O
program Conductor;
{Este prog rama conductor prueba la fune; ón MaxU sta ut H ; zando un
juego de pruebas como datos de entrada del arch;vo juegopruebasmax}
varL: Lista;
m, j: intege r;
juegop ruebas max: text;
begin
WriteL n( 'Comie nza la prueba de la funció n MaxLi sta(L,
m)');
WriteL n('Intr oducir el nombre del archiv o del juego de
prueba s: ');
ReadL ista(U ;
while not eof(jue goprue basma x) do
begin
WriteL n( 'Lista de entrad a L ='); Write Lista( U;
Write (Intro ducir valor de m: '); ReadLn (m);
j := MaxLi sta(L, m);
WriteL n('Res ultado de MaxLi sta(L, m) ~ " j);
ReadL ista(U ;
end;
WriteL n('Fin al de la prueba de la funció n MaxLi sta(L,
m)
end.
Debemos probar los programas «de abajo a arriba». Es decir, debemos probar
todos los procedimientos y funciones antes de probar el programa que los
utiliza. Después de realizar esto, podemos proceder a la prueba del programa
completo en la misma forma en que probamos un procedimiento. Para cllo,
convertimos e' programa en una especie de autoconductor de si mismo, aña-
diéndole un bucle externo que lea sistemáticamente datos de entrada alternati-
vos desde un archivo externo que contenga un juego de pruebas, y después
prosiga con su ejecución normal, produciendo las salidas a todas las entradas
del juego de pruebas, en lugar de la salida de un único juego de datos.
Por ejemplo, considérese el programa Ca Lcu La CM, de la Figura 4.6, el cual
modificamos para ser más amigable (véase Sección 6.1). Para probar este pro-
grama, podemos convertirlo en el autoconductor que se muestra más abajo, y
ejecutarlo con los datos de el archivo que contiene varias listas de calificacio-
nes alternativas, en lugar de sólo una. El resultado de convertir este programa
en amigable y en un autoconductor, se muestra en la Figura 6.12. Para conver-
tirlo en autoconductor, basta con añadirle un bucle repea t abarcando las pre
y poscondiciones del programa. Esta modificación hace que el programa lea y
procese entradas hasta que lea una lista vacia 0, lo que señala el fin de las
ejecuciones de prueba.
program caLcuLaCM;
uses
Listas;
var
Notas: Listas;
i, n: integer;
Sum, CM: reaL;
entradaváLida: BooLean;
beyin
repeat
{pre: entrada = (Notas" Notas" ... , Notas") 1\ n> O
1\ \1'i E {1, .""' n}: Notas, E (O, .. "' 4}}
repeat
WriteLn ('Introducir La Lista de caLificaciones:');
ReadLista(Notas);
n :~ LongLista(Notas);
entradaváL ida :~ true;
for i : ~ 1 to n do
if not isNumeric(Notas[i] or Notas[i] < O) or (Notas[i] > 4) then
entradaváL ida := faLse;
until entradaváLida;
i f n > O then
beyin
Sum :~ O:
i := 1;
whi le i <= n do
begin
Sum := Sum + Notas[i];
Robustez y prueba de los algoritmos 203
i := i + 1
end
CM = Sum/n;
WriteLn('La CM de esas caLificaciones es=', CM: 5: 2)
end {i f}
{post entrada =0"
saLida=Sumi E {1, ... ,n}:Notas;ln}
untiL n ~ O;
end.
begin
(precondiciones}
{P,}, 5,; {P 2 }, 52; ••• ; {Pn}' Sn; {P n+,}
(poscondiciones}
end
begin
(pre: precondición)
5,;
(post: poscondición);
begin
{pre: entrada = n1, n2 /\ salida =0l
( @)
Read (x, y ) ; - - -
{ @
z:=x*y; ~
{ @Y
Write (z) - - - -
( )
{post: entrada =0/\ salida = n1 * n2
end.
begin
{pre: entrada ~ n1, n2 /\ salida =0} Jus! ¡Cica! iuus
~{entrada~n1, n2 } {A-eLiminación
QY Read (x, y);.. @
[entrada =0/\ x = n1 /\ y = n2 /\ x*y = n1*n2) i regla de la asignación,
® z:~x*y;.. @ aritmética,
/\-introducción}
{regla de la asignación,
{x = n1 /\ y = n2 /\ z = n1 *n2 /\ sa l i da = 0
® Write (z) .. @ A-eliminación,
/\-introducción}
{z = n1 *n2 /\ sa l i da = n1 *n2 } {regla de la asignación,
a) {P(e)} v := e { }
{P(e)} v := e {P(v)}
b) {entrada ~ n} Read(v) { }
[entrada ~ n} Read(v) {entrada = 0 /\ V = n}
e) [salida=0/\e=n} Write(e):}
[salida ~0 /\ e = n) Write(e) {salida = e}
Robustez y prueba de los algoritmos 207
{x*y~nl*n2}
z:=x*y;
{z=n1 *n2} {regLa de La asignación}
Lo único que hemos hecho, al realizar esta inferencia, ha sido poner z en todas
las ocurrencias de x * y en la proposición ya conocida P (x * y) para poder
obtener P (z >. Obsérvese que se ha marcado esta inferencia de la demostra-
ción, con una justificación situada a la derecha, para clarificar las razones de la
inferencia realizada. Esto es consistente con el estilo de las demostraciones de
la lógica.
Está claro que esta regla es fácilmente extensible para instrucciones Read y
Wr; te, con más de una variable, para las instrucciones ReadLn, Wr; tLn,
ReadL; sta y Wr; teL; sta, y así sucesivamente. Por simplicidad, no re-
cargaremos esta regla tratando de formalizarla para todas esas situaciones,
aunque la utilizaremos en nuestras demostraciones como si lo hubiéramos
hecho.
Como ejemplo adicional, consideremos la primera instrucción del progra-
ma de la Figura 6.14, para la que se cumple lo siguiente cuando razonamos
sobre ella:
{i ~ O]
i:=i+1;
{i > Ol {Regla de la asignación, aritmética}
Los programas incluyen otros tipos de instrucciones, aparte de las que asignan
valores a las variables. Cuando se pretenden escribir demostraciones sobre los
programas, es necesario conocer axiomas para poder razonar sobre selecciones
210 Computación l. Lógica, resolución de problemas, algoritmos V programas
a) ;P 1\ 6} 5 {Q) b) {P 1\ 6) 5, {Q }
PI\-6o>Q {P 1\ -6) 5, {Q )
{Pi i f 6 then 5 {Q) {Pi i f 6 then 5, el5e 5, {Q}
z := x;
i f x <~ y then
z :~ y
Q= {z = X 1\ X > y v z ~ y 1\ X <~ y)
Que es una manera más formal de describir la salida que deseamos para z. Las
inslrucciones de asignación y la selección condicional están en secuencia, por
lo que necesitamos utilizar, en el proceso de verificación, tanto la regla de la
asignación como la de la selección condicional. Por tanto, podemos comenzar
con lo siguiente:
I 1
, J
Z := x;
{z = x}
if x <~ y then
z := y
{x > y 1\ Z = X v X <= Y 1\ Z = y)
Para demostrar la validez del aserto anterior, consideramos los dos casos
x <= y Y~(x <= y) que, como sabemos por aritmética, son los únicos posibles.
Cuando x <= y la linea 1 es válida, puesto que se realizará la asignación
x : = y, y la regla de la asignación garantiza que z = y. La regla de la
/\ -introducción nos permite inferir z = y /\ X <= y, Yfinalmente, la regla de la
v -introducción nos permite inferir z = x /\ x > y v z = Y /\ X <= y. La línea 2
también es trivialmente válida, puesto que ~(x <= y) es fa Lso y fa Lso =o> p
es siempre válido para cualquier proposición p.
En el segundo caso, x > y, la segunda línea de la disyunción de arriba es
válida. Es decir, tanto ~(x <= y) (o equivalentemente, x> y) y z = x son
válidos, por lo que lo es su conjunción por la /\ -introducción. Pero
z =X /\ ~(x := y)
es equivalente a
z=x/\x>y
if x > y then
z := x
else
z := y
Q= {z = X /\ X > y v z = y /\ X <= y}
{verdadero}
i f x ) y then
z := x
else
z :~ y
: z = x /\ x > y v z ~ y /\ X <= y}
212 Computación l. Lógica, resolución de problemas, algoritmos V programas
Analicemos por separado cada una de las lineas de la disyunción, como hici-
mos en el ejemplo anterior. La línea 1 se corresponde con el caso en que x > y.
Utilizando la regla de la asignación, la propiedad de la identidad para el valor
verdadero y la 1\ -introducción, podemos poner lo siguiente:
{X>Y} z :~X(Z=XAX>Y}
sum := o;
i :~ 1;
while i <= 5 do
begin
5um := sum + i;
i:=i+1;
end
Las cinco ejecuciones del cuerpo del bucle pueden ser desplegadas de la mane-
ra siguiente:
sum : = sum + i;
i:=i+1;
Robustez y prueba de los algoritmos 213
sum : = sum + i;
i:=i+1;
suro : = sum + i;
i:=i+1;
sum : = sum + i;
i:=i+1;
sum := sum + i;
i:=i+1;
,
Recuérdese también de! Capitulo 4, que el invariante del bucle es un aserto
que es válido antes y después de cada repetición del bucle, incluidas la primera
y la última. El invariante para e! bucle de arriba es:
{sum = O 1\ i = 1 }
sum := sum + i;
i:=i+1;
{sum = O + 1 1\ i = 2}
sum := sum + i;
i:=i+1;
{sum = O + 1 + 2 1\ i = 3}
sum : = sum + i;
i:=i+1;
{sum = O + 1 + 2 + 3 1\ i = 4}
sum := sum + i;
i:=i+1;
{sum = O + 1 + 2 + 3+4 1\ i ~ 5}
sum := sum + i;
i:=i+1;
( sum = O + 1 + 2 + 3+ 4+5 1\ i = 6}
a) { i nv 1\ e} s {i nv}
{inv} while e do s {inv 1\ -e}
214 Computación l. Lógica, resolución de problemas, algoritmos y programas
b) (inv) s {inv}
{inv) repeat s until B {inv A B)
e) (inv A 1 ~ i ~ n} s {inv}
[ i nv) for i : = 1 to n do s {i nv A i = n + 1)
5Uro := o;
i :~ 1;
while i <= 5 do
{i nv: sum = Sum i E (1, ... , i - 1 ): i A 1 <~ i <= 6)
begin
sum := suro + i;
j:~i+1;
end
{sum = Sum i E {1, ... , i - 1 ): i A 1 <~ i <= 6 A -( i <= 5) )
sum :~ O;
i := 1;
repeat
(inv: sum= Sumi E [1, o •• , i -1): i A 1 <= i <~6}
sum := suro + i;
i:~i+1;
until i > 5
{sum = SUII j E {1, .. o, i - 1 }: j A 1 <~ i <= 6 A i > 5}
bucle wh; Le). De nuevo, podemos simplificar utilizando las reglas de la arit-
mética:
sum :~o;
for ; := 1 to 5 do
{ ; nv: sum ~ SumjE {1, ... , ; - 1 }: j /\ 1 <~ ; <= 6}
sum := sum + i;
{sum = Su. j E {1, •.. , ; - 1 }: j /\ 1 <= ; <= 6 /\ ; = 6}
sum := o;
for ; := 1 to 5 do
{; nv: SUm = Su", j E {1, ... , ; - 1}: j /\ 1 <= ; <= 6}
sum : ~ sum + 1;
Ahora tendremos que demostrar por, inducción, que tras una ejecución de
todo el cuerpo del bucle, se garantiza que:
donde ; , = ; + 1.
Podemos hacer esto examinando el efecto de las instrucciones sobre el
invariante original. Es decir, una simple ejecución de la instrucción sum :=
sum + 1 conduce a
6.6. RESUMEN
Ejercicios
a) { } e) { }
i := i + 1 Write(x>
{i > O} {saLida ~ 12)
b) {i ~ O} J) {i ~ 10}
i :~ i + 1 j :~ 25
{ } { }
e) {i+j=O} g) { }
i := i + 1; s :~ s + t ~ 1
j :~ j ~ 1 {O <= s)
{ }
d) {entrada ~ 4 7 5)
Read(x>
{ }
6.10. En cada una de las instrucciones siguientes, escribir el aserto que falta
(utilizando la regla de inferencia de la selección condicional) de forma
que éste sea válido.
a) { }
if a = 1 then b :~ a else b := a + 1
{b ~ 1}
Robustez y prueba de los algoritmos 219
b) {i=nAj=m}
H i = O then j := O else j := 1
{ }
e) {i = n A j = m}
i f i = O then j :~ O
{ }
Count := o;
Loe := O;
whi le Loe < Length(S) do
{inv: O <= Loe <= Length(S) A
Coun t = Num i E {1, ... , Lo e}: 'O' <= S[ i] <= '9')
begin
Loe :~Loe+1;
i f (S[Loe] >= 'O') and (S[Loe] <~ '9') then
Count := Count + 1
end¡