Calculo de Programas
Calculo de Programas
Calculo de Programas
alculo
de
Programas
Javier Blanco
Silvina Smith
Damian Barsotti
e-mail: {blanco|smith|damian}@famaf.unc.edu.ar
7 de abril de 2008
Indice general
Prefacio
VII
1. Preliminares
1.1. Resoluci
on de ecuaciones . . . . . . . .
1.2. Resoluci
on de desigualdades . . . . . .
1.3. Que se puede aprender de una torta?
1.4. Expresiones aritmeticas . . . . . . . .
1.5. Sustituci
on . . . . . . . . . . . . . . .
1.6. Igualdad y regla de Leibniz . . . . . .
1.7. Funciones . . . . . . . . . . . . . . . .
1.8. Breve descripci
on de lo que sigue . . .
1.9. Ejercicios . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
3
6
8
11
12
13
18
19
20
2. L
ogica proposicional
2.1. Introducci
on . . . . . . . . . . . . . . . . . . . .
2.2. Expresiones Booleanas . . . . . . . . . . . . . . .
2.3. Tablas de verdad . . . . . . . . . . . . . . . . . .
2.4. Tautologas y contradicciones . . . . . . . . . . .
2.5. Lenguaje y l
ogica . . . . . . . . . . . . . . . . . .
2.6. Negaci
on, conjunci
on y disyunci
on en el lenguaje
2.7. Implicaci
on y equivalencia . . . . . . . . . . . . .
2.8. An
alisis de razonamientos . . . . . . . . . . . . .
2.9. Resoluci
on de acertijos l
ogicos . . . . . . . . . . .
2.10. Ejercicios . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
23
26
27
30
30
31
33
35
36
37
3. C
alculo proposicional
3.1. Sistemas formales .
3.2. La equivalencia . .
3.3. La negaci
on . . . .
3.4. La discrepancia . .
3.5. La disyunci
on . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
41
42
45
47
47
48
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
i
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
INDICE GENERAL
ii
3.6. La conjunci
on . . . . . . . . .
3.7. La implicaci
on . . . . . . . .
3.8. La consecuencia . . . . . . . .
3.9. Generalizaci
on del formato de
3.10. Ejercicios . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
demostracion
. . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
50
52
54
55
57
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
59
59
62
64
66
67
68
69
5. C
alculo de predicados
5.1. Predicados . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2. El cuantificador universal . . . . . . . . . . . . . . . . . .
5.3. El cuantificador existencial . . . . . . . . . . . . . . . . .
5.4. Propiedades de las cuantificaciones universal y existencial
5.5. Aplicaciones del c
alculo de predicados . . . . . . . . . . .
5.6. Algunas conclusiones . . . . . . . . . . . . . . . . . . . . .
5.7. Dios y la l
ogica . . . . . . . . . . . . . . . . . . . . . . . .
5.8. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
73
74
75
79
82
84
86
87
90
6. Expresiones cuantificadas
6.1. Introducci
on . . . . . . . . . . . . . . . . . . . . .
6.2. Revisi
on de la sustituci
on y la regla de Leibniz . .
6.3. Reglas generales para las expresiones cuantificadas
6.4. Cuantificadores aritmeticos . . . . . . . . . . . . .
6.5. Expresiones cuantificadas para conjuntos . . . . . .
6.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
. 94
. 97
. 98
. 101
. 103
. 104
7. El formalismo b
asico
7.1. Funciones . . . . . . . . . . . . . . . .
7.2. Definiciones y expresiones . . . . . . .
7.3. Reglas para el c
alculo con definiciones
7.4. Definiciones locales . . . . . . . . . . .
7.5. An
alisis por casos . . . . . . . . . . . .
7.6. Pattern Matching . . . . . . . . . . . .
7.7. Tipos . . . . . . . . . . . . . . . . . .
7.8. Tipos b
asicos . . . . . . . . . . . . . .
7.9. Tuplas . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4. Aplicaciones del c
alculo proposicional
4.1. An
alisis de argumentaciones . . . . . .
4.2. Resoluci
on de acertijos l
ogicos . . . . .
4.3. La funci
on piso . . . . . . . . . . . . .
4.4. Igualdad indirecta . . . . . . . . . . .
4.5. La funci
on techo . . . . . . . . . . . .
4.6. M
aximo y mnimo . . . . . . . . . . .
4.7. Ejercicios . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
107
107
109
110
112
112
114
115
116
117
INDICE GENERAL
iii
7.10. Listas . . . . . . . . . . . . . . . . . .
7.10.1. Constructores de listas . . . . .
7.10.2. Operaciones sobre listas . . . .
7.10.3. Propiedades de las operaciones
7.11. Ejercicios . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
117
118
119
120
121
8. Modelo computacional
8.1. Introducci
on . . . . . . . . . . . . . . . . . . .
8.2. Valores . . . . . . . . . . . . . . . . . . . . . . .
8.3. Forma normal . . . . . . . . . . . . . . . . . . .
8.4. Evaluaci
on . . . . . . . . . . . . . . . . . . . .
8.5. Un modelo computacional m
as eficiente . . . .
8.6. Nociones de eficiencia de programas funcionales
8.7. Problema de la forma normal . . . . . . . . . .
8.8. Ejercicios . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
125
125
126
128
130
133
136
137
138
9. El proceso de construcci
on de programas
141
9.1. Especificaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
9.2. Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
9.3. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
10.Inducci
on y recursi
on
10.1. Inducci
on matem
atica . . . . . . .
10.2. Inducci
on generalizada . . . . . . .
10.3. Equivalencia entre los principios de
10.4. Ejercicios . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
157
158
163
165
165
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
167
167
169
170
172
176
184
programas funcionales
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
185
185
191
197
. . . . . .
. . . . . .
induccion
. . . . . .
11.T
ecnicas elementales para la programaci
on
11.1. Definiciones recursivas . . . . . . . . . . . .
11.2. Reemplazo de constantes por variables . . .
11.3. Modularizaci
on . . . . . . . . . . . . . . . .
11.4. Uso de tuplas . . . . . . . . . . . . . . . . .
11.5. Generalizaci
on por abstracci
on . . . . . . .
11.6. Ejercicios . . . . . . . . . . . . . . . . . . .
12.Ejemplos de derivaci
on
12.1. Ejemplos numericos
12.2. Ejemplos con listas .
12.3. Ejercicios . . . . . .
de
. .
. .
. .
.
.
.
.
.
.
INDICE GENERAL
iv
13.Ejemplos con segmentos
13.1. B
usqueda de un segmento . . . . . . . .
13.2. Problema de los parentesis equilibrados
13.3. Problema del segmento de suma mnima
13.4. Ejercicios . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
199
199
203
207
212
14.Especificaciones implcitas
14.1. Aritmetica de precisi
on arbitraria . . . . . .
14.2. Especificaciones implcitas . . . . . . . . . .
14.3. Revisi
on del ejemplo . . . . . . . . . . . . .
14.4. Especificaciones implcitas con invariante de
14.5. Ejercicios . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
representacion
. . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
213
213
217
218
222
224
15.Recursi
on final
15.1. Ejemplos de funciones recursivas finales
15.2. Recursi
on lineal y recursi
on final . . . .
15.3. Recursi
on final para listas . . . . . . . .
15.4. Ejercicios . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
227
231
233
237
240
16.La programaci
on imperativa
16.1. Estados y predicados . . . . . . . . . . . . . . . . . . . . . . . . . .
16.2. El transformador de predicados wp . . . . . . . . . . . . . . . . . .
16.3. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
243
243
246
247
17.Definici
on de un lenguaje de programaci
on
17.1. Skip . . . . . . . . . . . . . . . . . . . . . .
17.2. Abort . . . . . . . . . . . . . . . . . . . . .
17.3. Asignaci
on . . . . . . . . . . . . . . . . . .
17.4. Concatenaci
on o composici
on . . . . . . . .
17.5. Alternativa . . . . . . . . . . . . . . . . . .
17.6. Repetici
on . . . . . . . . . . . . . . . . . . .
17.7. Ejercicios . . . . . . . . . . . . . . . . . . .
249
249
250
250
253
253
256
260
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
imperativo
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
18.Introducci
on al c
alculo de programas imperativos
263
18.1. Derivaci
on de ciclos . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
18.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
19.T
ecnicas para determinar invariantes
19.1. Tomar terminos de una conjunci
on . .
19.2. Reemplazo de constantes por variables
19.3. Fortalecimiento de invariantes . . . . .
19.4. Problemas con los bordes . . . . . . .
19.5. Ejercicios . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
267
267
275
279
283
288
INDICE GENERAL
20.Recursi
on final y programaci
on imperativa
291
20.1. Programas imperativos sobre listas . . . . . . . . . . . . . . . . . . 295
20.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
21.Busca y ordenaci
on
21.1. Busca lineal . . . . . . . . . . . . . . . . .
21.2. Multiconjuntos . . . . . . . . . . . . . . .
21.3. Listas y multiconjuntos . . . . . . . . . .
21.4. Especificaci
on del problema de ordenacion
21.5. Ordenamiento por inserci
on . . . . . . . .
21.6. Ordenamiento por selecci
on . . . . . . . .
21.7. Quick-sort . . . . . . . . . . . . . . . . . .
21.8. Merge-sort . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
301
301
302
304
306
307
309
310
311
A. Operadores booleanos
313
315
Bibliografa
319
vi
INDICE GENERAL
Prefacio
Existen diversas maneras de introducir los conceptos y tecnicas elementales
de programaci
on. Dos maneras bastante exploradas y que han dado lugar a materiales did
acticos muy buenos son la de construccion sistematica de programas
imperativos [Dij76, Gri81, DF88, Kal90, Bac03] y la de programacion funcional
[Tho96, Fok96, Hoo89, Bir98]. En este libro nos basaremos en ambas, tratando de
mostrar que si bien los paradigmas de programacion y los modelos computacionales son diferentes, a la hora de desarrollar programas las tecnicas usadas se parecen
m
as y se complementan. M
as a
un, es posible usar el paradigma funcional (el cual
es m
as abstracto) en el desarrollo de programas imperativos. No se explotan en
este libro todas las posibilidades de ambos paradigmas (por ejemplo, se usan muy
poco las funciones de alto orden en programacion funcional y no se usan los procedimientos y las funciones imperativas) sino que se trata de usar un n
ucleo mnimo
que sea suficiente para resolver una familia interesante de problemas, pudiendo
enfocarnos as en los metodos de resoluci
on de problemas.
Este libro comenz
o a escribirse usando las notas tomadas por Silvina Smith de
las clases dictadas por Javier Blanco a partir de 1998 y se ha ido modificando y
extendiendo desde entonces. Luego se sum
o Damian Barsotti quien reviso todo el
material y produjo varios captulos nuevos. Ademas de en la Universidad Nacional
de C
ordoba, versiones preliminares de este libro se usan en la Universidad Nacional
de Ro Cuarto y en la Universidad Nacional de Rosario. Esperamos que a partir
de esta edici
on esta manera de introducir la programacion se extienda a otras
instituciones educativas.
vii
viii
PREFACIO
Captulo 1
Preliminares
We must not, however, overlook the fact that human calculation
is also an operation of nature, but just as trees do not represent or
symbolize rocks our thoughts even if intended to do so do not
necesarily represent trees and rocks (. . . ) Any correspondence between
them is abstract.
Alan Watts:Tao, the watercourse way
La programaci
on es una actividad que ofrece desafos intelectuales interesantes,
en la cual se combinan arm
onicamente la creatividad y el razonamiento riguroso.
Lamentablemente no siempre es ense
nada de esta manera. Muchos cursos de introducci
on a la programaci
on se basan en el metodo de ensayo y error. Las construcciones de los lenguajes de programaci
on son presentadas solo operacionalmente, se
estudia un conjunto de ejemplos y se espera resolver problemas nuevos por analoga, a
un cuando estos problemas sean radicalmente diferentes de los presentados.
Se asume a priori que los programas desarrollados con este metodo tendran errores
y se dedica una buena parte del tiempo de programacion a encontrarlos y corregirlos. Es as que esta ingrata tarea se denomina eufemsticamente debugging, es decir
eliminaci
on de los bichos del progama, como si estos bichos hubieran entrado al
programa involuntariamente infectando al programa sano. En este libro hablaremos simplemente de errores introducidos en el proceso de programacion. En los
libros de ingeniera del software se suele dedicar un considerable tiempo a explicar
la actividad de correcci
on de errores, y se le asigna un peso muy relevante en el
proceso de desarrollo de programas. Sin embargo, pese a todos los esfuerzos que
se hagan, nunca se puede tener una razonable seguridad de que todos los errores
hayan sido encontrados o de que alguna de las reparaciones de errores viejos no
haya introducido otros nuevos (el llamado efecto Hydra en [BEKV94]).
1
CAPITULO 1. PRELIMINARES
DE ECUACIONES
1.1 RESOLUCION
1.1 Resoluci
on de ecuaciones
Como ya mencionamos en la secci
on anterior, la logica matematica es una
herramienta indispensable para el desarrollo de programas. Para comenzar ejemplificando el tipo de presentaci
on de la l
ogica que vamos a usar en este libro,
comenzaremos aplic
andola a una clase de problemas mas simple y conocida como
es el de la resoluci
on de ecuaciones aritmeticas.
En los libros de texto de matem
atica utilizados en las escuelas secundarias, la
resoluci
on de ecuaciones es presentada en general como un proceso mecanico el
cual consiste en despejar la inc
ognita. Sumado a esto, la logica suele ser ense
nada como un objeto de estudio separado y no como una herramienta para resolver
estos problemas matem
aticos. Es as que, el proceso mecanico de despejar la inc
ognita es poco comprendido por los alumnos debido en gran medida a la falta
de un formalismo notacional claro y uniforme. En particular, los casos especiales
en los cuales una ecuaci
on admite infinitas o ninguna solucion son tratados como
anomalas. Adem
as, cuando se introducen ecuaciones con soluciones m
ultiples el
mecanismo notacional debe adaptarse o directamente dejarse de lado.
A continuaci
on presentaremos una serie de ejemplos de resolucion de ecuaciones
utilizando la l
ogica como herramienta, no solo para resolverlas si no tambien para
comprender y justificar los resultados obtenidos.
Ejemplo 1.1
Supongamos que se nos propone resolver la siguiente ecuacion lineal:
3x+1=7
Pensemos primero en el significado de esta ecuacion. Esta constituida por dos
expresiones aritmeticas unidas por un smbolo de igualdad. La presencia de la
igualdad induce a pensar que toda la ecuacion tiene cierto valor de verdad, es
decir que ser
a verdadera o falsa. Pero, la ecuacion tal cual esta escrita, no tiene un
valor de verdad fijo. La presencia de la variable x indica que el valor de verdad de
la ecuaci
on depender
a del valor que tome esta variable. Para algunos valores sera
verdadera y para otros ser
a falsa. Por ejemplo, si x toma el valor 1 la ecuacion es
falsa, pero si x es igual a 2 la misma es verdadera. La resolucion de la ecuacion
consiste en identificar el conjunto de valores de x para los cuales la ecuacion es
verdadera. La manera usual de hacer esto es obtener otra ecuacion equivalente a la
primera pero suficientemente simple como para que el conjunto de soluciones sea
visible de manera inmediata. Introduciremos a traves de este ejemplo el formato
de demostraci
on que luego usaremos en todo el libro.
CAPITULO 1. PRELIMINARES
4
3x+1=7
{ restamos 1 a cada termino }
3x=6
{ dividimos por 3 cada termino }
x=2
En la demostraci
on, las leyes de la aritmetica aseguran la correcion de cada
paso, esto es que cada una de las sucesivas ecuaciones tiene el mismo conjunto de
soluciones o, dicho de otra manera, son verdaderas para los mismos valores de x.
Como resultado de la demostraci
on podemos afirmar que el valor de verdad
(verdadero o falso) de la primera ecuaci
on, para un x fijo, es el mismo que el de la
u
ltima, para el mismo valor de x. O lo que es lo mismo, el conjunto de valores de
x para los cuales la ecuaci
on 3 x + 1 = 7 es verdadera, es exactamente el mismo
para los que la ecuaci
on x = 2 es verdadera. De esto u
ltimo se desprende que
el u
nico valor para la variable x que hace verdadera la ecuacion 3 x + 1 = 7 es
2. Llamaremos al conjunto de valores que hace verdadera una ecuacion como el
conjunto de soluciones de esa ecuaci
on.
Observaci
on: El tama
no de los pasos de una derivacion dependera del objetivo
de la demostraci
on que se este realizando. En este caso, se esta presentando de
manera detallada la resoluci
on de una ecuacion lineal, por lo cual los pasos son
particularmente detallados. Si se est
a trabajando por ejemplo en la derivacion de
programas, donde el enf
asis est
a en otro lado, la demostracion precedente puede
abreviarse como
3x+1=7
{ aritmetica }
x=2
donde se asume que el lector de la demostracion puede comprender el paso sin
ning
un problema. De todas maneras frente a la duda conviene ser lo mas explcito
posible.
Ejemplo 1.2
Consideremos la resoluci
on de la siguiente ecuacion:
3 x + 1 = 3 (x + 1) 2
{ disributiva }
3x+1=3x+32
{ aritmetica }
3x+1=3x+1
DE ECUACIONES
1.1 RESOLUCION
{ reflexividad de la igualdad }
T rue
Usamos la palabra T rue para denotar la proposicion que siempre es verdadera,
independientemente de los valores de las variables que se esten usando. Esto significa que para cualquier valor de la variable x la ecuacion es verdadera o, dicho de
otro modo, que el conjunto de soluciones de la u
ltima ecuacion es el de todos los
enteros (o naturales, o reales, seg
un como se haya planteado el problema). Por lo
tanto, como resultado de la demostraci
on, el conjunto de soluciones de la ecuacion
3 x + 1 = 3 (x + 1) 2 es el de todos los n
umeros enteros.
Ejemplo 1.3
Consideremos ahora la resoluci
on de la siguiente ecuacion:
3 x + 1 = 3 (x + 1)
{ disributiva }
3x+1=3x+3
{ restamos 3 x en cada miembro }
1=3
{ igualdad de enteros }
F alse
Simetricamente al ejemplo anterior, la proposicion F alse es la que es falsa para
cualquier valor de x. Se dice en este caso que la ecuacion no tiene solucion o equivalentemente que su conjunto de soluciones es vaco. Por lo tanto, como resultado
de la demostraci
on, el conjunto de soluciones de la ecuacion 3 x + 1 = 3 (x + 1)
es vaco, o directamente, no tiene soluci
on.
Ejemplo 1.4
Resolveremos ahora la siguiente ecuaci
on cuadratica
x (x 2) = 3 (x 2)
{ restamos 3 (x 2) a ambos terminos }
x (x 2) 3 (x 2) = 0
{ distributiva }
(x 3) (x 2) = 0
{ producto igual a 0: a b = 0 a = 0 b = 0 }
x3=0x2=0
{ sumamos 3 al primer termino y 2 al segundo }
x=3x=2
CAPITULO 1. PRELIMINARES
1.2 Resoluci
on de desigualdades
A continuci
on veremos el uso de la misma notacion para resolver desigualdades.
Nos vamos a concentrar en obtener la validez de desigualdades que contengan races
cuadradas. Como veremos, utilizando el f
ormalismo logico, esta tarea se resuelve
de manera muy simple, mostrando la potencia que tiene esta herramienta.
Ejemplo 1.6
Supongamos que queremos determinar si el n
umero 2+ 7 es menor que 3+ 5
sin usar una calculadora. Notemos, que
ambas
expresiones
no dependen de ninguna
variable, con lo cual la desigualdad 2 + 7 < 3 + 5 posee un valor de verdad
fijo (verdadero o falso). La idea es aprovechar las propiedades de las desigualdades
y transformar la expresi
on a resolver en una mas simple cuyo valor de verdad sea
inmediato.
DE DESIGUALDADES
1.2 RESOLUCION
2+
7<
3+
A partir de la demostraci
on vemos que la formula 2 + 7 < 3 + 5 tiene
el mismo
ormula F alse, por lo tanto no es el caso que
valor
deverdad que la f
2 + 7 < 3 + 5.
Podramos haber intentado probar que ambos terminos de la desigualdad anterior son iguales o que el primero es mayor que el segundo (estos son los u
nicos
casos posibles restantes). Dado que todas las propiedades usadas preservan tanto
la relaci
on de menor, la de igualdad como
la de mayor,
la demostracion puede facilmente adaptarse para mostrar que 2 + 7 > 3 + 5 es equivalente a 224 > 9
lo cual es obviamente cierto. De la misma forma, para el caso de la igualdad llegaremos a un resultado negativo ya que no se cumple 224 = 9. Con ello logramos
obtener cual es la relaci
on que hay entre los dos terminos.
CAPITULO 1. PRELIMINARES
1.3 Qu
e se puede aprender de una torta?
Presentaremos ahora un ejemplo para aclarar los conceptos. El mismo esta
tomado de E.W.Dijkstra [Dij89] donde la solucion se atribuye a A.Blokhuis. La
idea de presentar los inconvenientes del razonamiento por ensayo y error usando
este ejemplo est
a inspirada en una discusi
on similar en [Coh90].
Problema: En una torta circular se marcan N puntos sobre el contorno y luego
se trazan todas las cuerdas posibles entre ellos. Se supone que nunca se cortan
m
as de dos cuerdas en un mismo punto interno. Cuantas porciones de torta se
obtienen?
Antes de seguir leyendo, resuelva el problema de la torta.
Analizaremos los casos N=1, N=2, N=3, etc., tratando de inferir una formulaci
on v
alida para N arbitrario:
Si N=1, obtenemos 1 pedazo. Si N=2, obtenemos 2 pedazos.
N
umero de puntos
N
umero de porciones
1
1
2
2
Avancemos un poco m
as. Si N=3, obtenemos 4 pedazos. Para tratar de tener
m
as informaci
on tomamos N=4 y obtenemos 8 pedazos.
N
umero de puntos
N
umero de porciones
1
1
2
2
3
4
4
8
5
16
Para estar m
as seguros probemos con el caso N=6, para el cual deberamos
hallar N=32.
N
umero de puntos
1 2
N
umero de porciones 1 2
3
4
4
8
5
16
6
31
2
2
3
4
4
8
5
16
6
31
7
57
CAPITULO 1. PRELIMINARES
10
n
umero de porciones agregadas al agregar una cuerda
= { cuerdas dividen porciones en dos }
n
umero de porciones cortadas por la cuerda
= { una porci
on se divide por un segmento de cuerda }
n
umero de segmentos de la cuerda agregada
= { los segmentos son determinados por puntos de interseccion internos }
1 + n
umero de puntos de intersecci
on internos sobre la cuerda
Una vez que tenemos este resultado podemos calcular en cuanto se incrementa
el n
umero de porciones si se agregan c cuerdas.
n
umero de porciones agregadas al agregar c cuerdas
= { resultado anterior y el hecho que cada punto de interseccion interno es
compartido por exactamente dos cuerdas }
c + total de puntos de intersecci
on internos en las c cuerdas.
Dado que si comenzamos con 0 puntos tenemos una porcion (toda la torta) y
agregar c cuerdas nos incrementa el n
umero en c + (total de puntos de interseccion
internos), si definimos
f = n
umero de porciones
c = n
umero de cuerdas
p = n
umero de puntos de intersecci
on internos
hemos deducido que
f =1+c+p
En este punto hemos podido expresar el problema original en teminos de la
cantidad de cuerdas y de puntos de interseccion internos. Falta expresar ahora
1.4 EXPRESIONES ARITMETICAS
11
= { un punto de intersecci
on interna cada 4 puntos en la circunferencia }
N
N
1+
+
2
4
= {
algebra }
1+
N 4 6N 3 + 23N 2 18N
24
componentes m
as elementales. Estos
tuvieron ademas un tama
no adecuado. Otro
factor importante fue la precisi
on; cada paso puede verse como una manipulacion
de f
ormulas, en este caso aritmeticas.
CAPITULO 1. PRELIMINARES
12
1.5 Sustituci
on
Sean E y F dos expresiones y sea x una variable. Usaremos la notacion
E(x := F )
para denotar la expresi
on que es igual a E donde todas las ocurrencias de x han
sido reemplazadas por (F ). Cuando los parentesis agregados a F sean innecesarios
nos tomaremos la libertad de borrarlos sin avisar. Por ejemplo,
13
(x + y)(y := 2 z) = (x + (2 z)) = x + 2 z
Es posible sustituir simult
aneamente una lista de variables por una lista de
expresiones de igual longitud. Esto no siempre es equivalente a realizar ambas
sustituciones en secuencia. Por ejemplo:
(x + z)(x, z := z + 1, 4) = z + 1 + 4
mientras que
(x + z)(x := z + 1)(z := 4) = (z + 1 + z)(z := 4) = 4 + 1 + 4
Tomaremos como convenci
on que la sustitucion tiene precedencia sobre cualquier otra operaci
on, por ejemplo
x + z(x, z := z + 1, 4) = x + (z(x, z := z + 1, 4)) = x + 4
N
otese que sustituir una variable que no aparece en la expresion es posible y
no tiene ning
un efecto.
Frecuentemente se usar
a el smbolo x para denotar una secuencia no vaca
de variables distintas. Si entonces F denota una secuencia de expresiones de la
misma longitud que x, la expresi
on E(x := F ) denotara la expresion E donde
se han sustituido simult
aneamente las ocurrencias de cada elemento de x por su
correpondiente expresi
on en F .
Sustituci
on y evaluaci
on. Es importante no confundir una sustitucion, la cual
consiste en el reemplazo de variables por expresiones (obteniendo as nuevas expresiones) con una evaluaci
on, la cual consiste en dar un valor a una expresion a
partir de un estado dado (es decir, de asumir un valor dado para cada una de las
variables de la expresi
on).
14
CAPITULO 1. PRELIMINARES
todo estado posible produce el valor T rue. Si su evaluacion en todo estado posible
produce el valor F alse la expresi
on ser
a falsa (o equivalente a la expresion F alse).
Notar, como en el primer ejemplo de la seccion 1.1, la existencia de expresiones
que no son verdaderas ni falsas. En estos casos la expresion en cuestion se evaluara
a distintos valores seg
un el estado considerado, por lo que no se podra asignar un
valor de verdad a la misma.
Observaci
on: De lo dicho anteriormente, debe quedar claro la diferencia entre
una expresi
on y un valor. Una expresi
on es una entidad de caracter sintactico.
Su definici
on puede expresarse de manera puramente formal dando la manera de
construirla y su precedencia, como se hizo con las expresiones aritmeticas en la
secci
on 1.4. Pero el concepto de valor asociado a una expresion solo tiene sentido
si partimos de un estado dado. Esta diferencia conceptual entre una expresion y
su valor ya fue establecida en la secci
on 1.1, al referirnos al conjunto de soluciones
de una ecuaci
on aritmetica. Este conjunto contiene justamente los estados para
los cuales la ecuaci
on se eval
ua al valor T rue. Sin este conjunto la ecuacion por si
sola no tiene nesesariamente un valor.
Observaci
on: Tambien debe quedar claro que existen expresiones que tienen el
mismo valor independiente del estado. Este es el caso de las desigualdes tratadas
en la secci
on 1.2, o las expresiones T rue, F alse, 1 = 2 o x x.
Observaci
on: Se habr
a podido observar tambien que hemos usado indistintamente la notaci
on T rue y F alse para indicar los valores y las expresiones que denotan
los mismos. Tambien suceder
a lo mismo para expresiones aritmeticas que tienen
asociado directamente un valor, como por ejemplo 1, 2, 3 (esta asociacion
ser
a discutida en el captulo 8). El lector podra discernir cuando se este hablando
de uno u otro concepto seg
un el contexto en el que se este hablando.
Una forma alternativa de demostrar que dos expresiones son iguales sin tener
que recurrir a su evaluaci
on en cualquier estado posible es aplicar leyes conocidas
para ese tipo de expresiones (como vimos con las leyes de la aritmetica en las
secciones 1.1 y 1.2) y las leyes de la igualdad. Esta manera es mas u
til cuando
se quiere razonar con expresiones. Si las leyes caracterizan la igualdad (es decir
que dos expresiones son iguales si y s
olo si pueden demostrarse iguales usando las
leyes), puede pensarse a estas como la definicion de la igualdad.
La igualdad es una relaci
on de equivalencia, o sea que satisface las leyes de
reflexividad, simetra y transitividad. La reflexividad nos da un axioma del cual
partir (o al cual llegar) en una demostraci
on de igualdad, la simetra permite
razonar hacia adelante o hacia atr
as indistintamente, mientras que la transitividad permite descomponer una demostraci
on en una secuencia de igualdades mas
simples.
15
X=Y
E(x := X) = E(x := Y )
X=X
(X = Y ) = (Y = X)
X=Y , Y =Z
X=Z
X=Y
E(x := X) = E(x := Y )
Leibniz:
CAPITULO 1. PRELIMINARES
16
Axioma 1.2 (Asociatividad)
P
P (x := X)
17
CAPITULO 1. PRELIMINARES
18
1.7 Funciones
Una funci
on es una regla para computar un valor a partir de otro u otros. Por
ejemplo, la funci
on que dado un n
umero lo eleva al cubo se escribe usualmente en
matem
atica como
f (x) = x3
Para economizar parentesis (y por otras razones que quedaran claras mas adelante) usaremos un punto para denotar la aplicacion de una funcion a un argumento; as la aplicaci
on de la funci
on f al argumento x se escribira f.x. Por otro lado,
para evitar confundir el predicado de la igualdad (=) con la definicion de funciones,
.
usaremos un smbolo ligeramente diferente: = . Con estos cambios notacionales la
funci
on que eleva al cubo se escribir
a como
.
f.x = x3
Si ahora quiere evaluarse esta funci
on en un valor dado, por ejemplo en (el
valor) 2 obtenemos
DE LO QUE SIGUE
1.8 BREVE DESCRIPCION
19
f.2
= { aplicaci
on de f }
23
= { aritmetica }
8
Puede notarse que el primer paso justificado como aplicacion de f es simplemente una sustituci
on de la variable x por la constante 2 en la expersion que
define a f . Esto puede hacerse para cualquier expresion, no necesariamente para
constantes. Por ejemplo
f.(z + 1)
= { aplicaci
on de f }
(z + 1)3
= { aritmetica }
z3 + 3 z2 + 3 z + 1
La aplicaci
on de funciones a argumentos puede definirse entonces usando sustituci
on. Si se tiene una funci
on f definida como
.
f.x = E
para alguna expresi
on E, entonces la aplicacion de f a una expresion cualquiera
X estar
a dada por
f.X = E(x := X)
La idea de sustituci
on de iguales por iguales (regla de Leibniz) y la de funcion
est
an ntimamente ligadas, por lo cual puede postularse la siguiente regla (derivada
de la regla usual de Leibniz y la definici
on de aplicacion de funciones), la cual
llamaremos, para evitar la proliferaci
on de nombres, regla de Leibniz:
X=Y
f.X = f.Y
Las funciones ser
an uno de los conceptos esenciales de este libro. Volveremos
sobre ellas en el captulo 7.
CAPITULO 1. PRELIMINARES
20
de otras
areas. Esto
hace a las demostraciones muy faciles de leer. Puede parecer exagerado poner tanto enfasis en cuestiones de estilo, pero dada la cantidad
de manipulaciones formales que es necesario realizar cuando se programa, estas
cuestiones pueden significar el exito o no de un cierto metodo de construccion de
programas.
Las manipulaciones formales de smbolos son inevitables en la programacion,
dado que un programa es un objeto formal construido usando reglas muy precisas. Cuando se usa el metodo de ensayo y error no se evitan las manipulaciones
formales, simplemente se realizan usando como u
nica gua cierta intuicion operacional. Esto no s
olo vuelve m
as difcil la construccion de dichos programas, sino
que atenta contra la comprensi
on y comunicacion de los mismos, a
un en el caso
en que estos sean correctos. La misma noci
on de correccion es difcil de expresar
si no se tiene alguna manera formal de expresar las especificaciones.
En lo que sigue del libro se presentar
a un formalismo que permite escribir especificaciones y programas y demostrar que un programa es correcto respecto de
una especificaci
on dada. Este formalismo estara basado en un estilo ecuacional
de presentar la l
ogica matem
atica usual. Se dispondra de un repertorio de reglas
explcitas para manipular expresiones, las cuales pueden representar tanto especificaciones como programas. El hecho de limitarse a un conjunto predeterminado de
reglas para razonar con los programas no ser
a necesariamente una limitacion para
construirlos. Lo que se consigue con esto es acotar las opciones en las derivaciones,
lo cual permite que sea la misma forma de las especificaciones la que nos gue en
la construcci
on de los programas. Por otro lado, al explicitar el lenguaje que se
usar
a para construir y por lo tanto para expresar los programas y las demostraciones, se reduce el ancho de banda de la comunicacion, haciendo que sea mas
f
acil comprender lo realizado por otro programador y convencerse de la correccion
de un programa dado.
Concluimos esta secci
on con una cita pertinente.
It is an error to believe that rigor in the proof is an enemy of
simplicity. On the contrary, we find confirmed in numerous examples
that the rigorous method is at the same time the simpler and the more
easily comprehended. The very effort of rigor forces us to discover simpler methods of proof. It also frequently leads the way to methods which
are more capable of development than the old methods of less rigor.
David Hilbert
1.9 Ejercicios
Ejercicio 1.1
Resolver las siguientes ecuaciones:
2x+3=5
1.9 EJERCICIOS
21
2x+3=2x
Ejercicio 1.2
Simplificar la expresi
on (n + 1)2 n2 de manera que no aparezcan potencias.
Ejercicio 1.3
CAPITULO 1. PRELIMINARES
22
Ejercicio 1.8
Realizar las siguientes sustituciones eliminando los parentesis innecesarios.
1. (x + 2)(x := 6)
2. (x + 2)(x := x + 6)
3. (x x)(x := z + 1)
4. (x + z)(y := z)
5. (x (z + 1))(x := z + 1)
Ejercicio 1.9
Realizar las siguientes sustituciones simult
aneas eliminando los parentesis innecesarios.
1. (x + y)(x, y := 6, 3 z)
2. (x + 2)(x, y := y + 5, x + 6)
3. (x (y z))(x, y := z + 1, z)
4. (x + y)(y, x := 6, 3 z)
5. (x (z + 1))(x, y, z := z, y, x)
Ejercicio 1.10
Realizar las siguientes sustituciones eliminando los parentesis innecesarios.
1. (x + 2)(x := 6)(y := x)
2. (x + 2)(x := y + 6)(y := x 6)
3. (x + y)(x := y)(y := 3 z)
4. (x + y)(y := 3 z)(x := y)
5. (x (z + 1))(x, y, z := z, y, x)(z := y)
6. (4 x x + 4 y x + y y)(x, y := y, x)(y := 3)
Ejercicio 1.11
Demostrar las siguientes desigualdades.
1. X max X + Y max Y (X + Y ) max (X + Y )
2. (X + Z) max (Y + Z) + (X Z) max (Y Z) X + Y
Ejercicio 1.12
Definir el valor absoluto en terminos del m
aximo y demostrar la desigualdad triangular:
|X| + |Y | |X + Y |
Captulo 2
L
ogica proposicional
Who did you pass on the road? the King went on, holding out his
hand to the Messenger for some hay.
Nobody, said the Messenger.
Quite right, said the King: this young lady saw him too. So of
course Nobody walks slower than you.
I do my best, the Messenger said in a sullen tone. Im sure nobody
walks much faster than I do!.
He cant do that, said the King, or else hed have been here first.
However, now youve got your breath, you may tell us what happened
in the town.
Lewis Carroll: Through the Looking-Glass
2.1 Introducci
on
Se suele definir a la l
ogica como el estudio de los metodos y principios usados
para distinguir los razonamientos correctos de los incorrectos. En este sentido, la
l
ogica estudia b
asicamente la forma de estos razonamientos, y determina si un
razonamiento es v
alido o inv
alido pero no si la conclusion de este es verdadera o
no. Lo u
nico que la l
ogica puede afirmar de un razonamiento correcto es que si se
parti
o de premisas verdaderas la conclusi
on sera verdadera, pero en el caso que
alguna de las premisas sea falsa nada se sabra del valor de verdad de la conclusion.
Uno de los conceptos b
asicos de l
ogica es el de proposici
on. Suele definirse una
proposici
on como una sentencia declarativa de la cual puede decirse que es verdadera o falsa. As se las distingue de otros tipos de oraciones como las interrogativas,
23
CAPITULO 2. LOGICA
PROPOSICIONAL
24
exclamativas o imperativas, dado que de una pregunta, una exlamacion o una orden no puede decirse que sea verdadera o falsa: su funcion en el lenguaje no es
postular o establecer hechos.
En los textos de l
ogica suele distinguirse entre una oracion o sentencia y su
significado, reserv
andose la palabra proposici
on para este u
ltimo. Por ejemplo
Est
a lloviendo afuera.
Afuera est
a lloviendo.
ser
an consideradas como dos oraciones diferentes pero no se las distinguira como
proposiciones, dado que su significado es obviamente el mismo.
Otro ejemplo usual de diferentes oraciones que dan lugar a la misma proposicion
es el de las oraciones en diferentes idiomas, por ejemplo
Llueve.
Il pleut.
It rains.
Het regent.
ser
an consideradas iguales como proposiciones.
Por supuesto que la relaci
on entre oraciones y proposiciones es un fenomeno
complejo el cual involucra, entre otras cosas, temas tan controversiales como la
noci
on de sem
antica del lenguaje natural. No avanzaremos mas en este punto,
qued
andonos con una noci
on prete
orica de significado.
Las proposiciones ser
an usadas esencialmente en razonamientos. Entendemos
por razonamiento a un conjunto de proposiciones de las cuales se afirma que una
de ellas se deriva de las otras. En este sentido, un razonamiento no es cualquier
conjunto de proposiciones sino que tiene una estructura. La conclusi
on de un razonamiento es una proposici
on que se deriva de las otras, llamadas premisas. Se
supone que las premisas sirven como justificacion o evidencia de la conclusion. Si
el razonamiento es v
alido, no puede aceptarse la verdad de las premisas sin aceptar
tambien la validez de la conclusi
on.
Ejemplos de razonamientos v
alidos
Como es usual escribimos las premisas una debajo de la otra, luego trazamos
una raya, la cual podra leerse como por lo tanto o luego y debajo de ella
escribimos la conclusi
on.
Ejemplo 2.1
El primero es uno de los m
as usados a lo largo de la historia de la logica.
Todos los hombres son mortales.
S
ocrates es hombre.
S
ocrates es mortal
2.1 INTRODUCCION
25
Ejemplo 2.2
El siguiente razonamiento tiene premisas falsas, pero la forma es correcta: si fueran
ciertas las premisas debera serlo tambien la conclusion. Esta forma de razonamiento recibe el nombre de silogismo en la l
ogica clasica.
Las ara
nas son mamferos.
Los mamferos tienen seis patas.
Las ara
nas tienen seis patas.
Ejemplo 2.3
En los captulos siguientes veremos c
omo puede mostrarse la validez de un razonamiento. Este u
ltimo ejemplo de razonamiento correcto es mas simple en este sentido
que los anteriores, dado que las herramientas teoricas necesarias para demostrarlo
son m
as elementales.
Si tuviera pelo sera feliz.
No soy feliz.
No tengo pelo.
26
CAPITULO 2. LOGICA
PROPOSICIONAL
27
sint
acticas. Estas expresiones denotan respectivamente los valores de verdad T rue
y F alse, por lo cual se usa la misma palabra para ambos. Los u
nicos valores a los
cuales las expresiones booleanas pueden evaluar en un estado dado seran tambien
T rue y F alse.
No presentamos aqu una definici
on inductiva completa de las formulas booleanas, dado que esta definici
on no presenta ninguna dificultad siendo analoga a la
de expresiones aritmeticas dada en el captulo precedente. Queda dicha definicion
como ejercicio elemental para el lector.
q
pq
T rue T rue
F alse T rue
T rue T rue
F alse F alse
pq pq
T rue T rue
T rue F alse
F alse T rue
T rue T rue
p q p q p 6 q
T rue T rue F alse
F alse F alse T rue
F alse F alse T rue
T rue F alse F alse
Ejemplo 2.6
Las tablas de verdad ser
an u
tiles entre otras cosas para evaluar expresiones booleanas en un estado dado. Por ejemplo, la evaluacion de la expresion
p q p
en el estado {(p, T rue}, (q, T rue)} puede calcularse de la siguiente manera: si q es
verdadera, en la tabla del puede verse que q es falsa. Luego, en la tabla del
28
CAPITULO 2. LOGICA
PROPOSICIONAL
se ve que cuando alguno de los argumentos es falso (en este caso q), entonces la
conjunci
on es falsa. Por u
ltimo, en la tabla de se ve que si el primer argumento
(el antecedente) es falso, la implicaci
on es verdadera, no importa cual sea el valor
de verdad del segundo argumento (llamado el consecuente).
Describiremos ahora sucintamente los operadores considerados. Mas adelante
los usaremos para interpretar oraciones del lenguaje natural y consideraremos los
aspectos m
as sutiles o controversiales de c
omo usar la logica matematica para
razonar acerca de argumentos presentados en el lenguaje corriente.
Equivalencia. El operador simbolizar
a la igualdad de valores de verdad.
Puede por lo tanto usarse tambien el operador usual de la igualdad para
este caso. Sin embargo, ambos operadores tendran propiedades distintas,
dado que, como es usual, la igualdad m
ultiple se interpreta como conjuntiva, es decir que si se escribe a = b = c se interpreta como a = b y
b = c, mientras que la equivalencia es asociativa, es decir que a b c
se usar
a para referirse equivalentemente a (a b) c o a a (b c).
Otra diferencia esencial es la precedencia asociada a ambos operadores.
La del = es m
as alta que la de cualquier operador logico, mientras que la
de la equivalencia es la m
as baja. Esto es comodo para evitar parentesis.
Por ejemplo, la transitividad de la igualdad (con un T rue redundante, es
cierto) podra escribirse como
a = b b = c a = c T rue
lo cual es mucho m
as simple que la expresion con todos los parentesis
(((a = b) (b = c)) (a = c)) T rue
Negaci
on. El operador representa la negacion usual.
Discrepancia. El operador 6 es la negacion de la equivalencia. Tendra para
expresiones booleanas el mismo significado que el operador 6=, pero tambien tendr
a las mismas diferencias que la igualdad con la equivalencia. En
algunos libros de l
ogica se lo suele llamar disyunci
on exclusiva u operador
xor, dado que es verdadero cuando exactamente uno de sus argumentos
lo es.
Disyunci
on. El operador representar
a el o usual del lenguaje. Se lo suele
llamar disyunci
on inclusiva, dado que es verdadera cuando alg
un argumento lo es.
Conjunci
on. El operador representa el y del lenguaje, dado que es cierto
s
olo cuando ambos argumentos lo son.
29
Implicaci
on. El operador es uno de los mas controversiales respecto de su
relaci
on con el lenguaje. La expresion p q sera verdadera en todos los
casos excepto cuando p sea verdadera y q falsa. Este operador captura
la idea de consecuencia l
ogica. De la tabla de verdad se desprende uno
de los hechos que resulta menos intuitivo, que es que de falso se puede
deducir cualquier cosa.
Consecuencia. El operador es el converso de , en el sentido de que son
equivalentes p q con q p. Se introduce en nuestras expresiones
debido a su utilidad en el proceso de construccion de demostraciones.
Definici
on 2.1 (Precedencia)
Para cada operador nuevo se definir
a tambien la precedencia la cual nos permite
eliminar parentesis. Por ejemplo, si el operador tiene precedencia sobre el operador , entonces puede escribirse X Y Z para indicar (X Y ) Z; en cambio
en la expresi
on X (Y Z) no pueden eliminarse los parentesis sin cambiar su
sentido.
Los operadores l
ogicos tendr
an la siguiente precedencia:
1. (la precedencia m
as alta).
2. y .
3. y .
4. y 6.
Por ejemplo, la f
ormula
((p q) r) ((p r) (q r))
puede simplificarse como
p q r (p r) (q r)
Uso de las tablas de verdad. Las tablas de verdad pueden usarse para calcular
los posibles valores de verdad de expresiones mas complejas. Un estado estara
descripto por una fila y el valor asociado a una expresion en ese estado sera el
valor en esa fila y en la columna de la f
ormula. Por ejemplo:
30
CAPITULO 2. LOGICA
PROPOSICIONAL
p
q
r
T rue T rue T rue
T rue T rue F alse
T rue F alse T rue
T rue F alse F alse
F alse T rue T rue
F alse T rue F alse
F alse F alse T rue
F alse F alse F alse
q
p q
F alse F alse
F alse F alse
T rue T rue
T rue T rue
F alse F alse
F alse F alse
T rue F alse
T rue F alse
p q r
T rue
T rue
T rue
F alse
T rue
T rue
T rue
T rue
2.5 Lenguaje y l
ogica
La l
ogica matem
atica surgi
o como una manera de analizar los razonamientos
escritos en lenguaje natural. Los operadores presentados en la seccion anterior
fueron pensados como contrapartidas formales de operadores del lenguaje. Si se
tiene cierto cuidado puede traducirse una proposicion escrita en lenguaje natural
a lenguaje simb
olico. Esta traducci
on nos permitira dos cosas: por un lado resolver
uedades del lenguaje natural; por otro, manipular y analizar las expresiones
ambig
as obtenidas usando las herramientas de la l
ogica. Algunas de esas herramientas
ser
an introducidas en las secciones que siguen.
CONJUNCION
Y DISYUNCION
EN EL LENGUAJE
2.6 NEGACION,
31
La idea b
asica de traducci
on consiste en identificar las proposiciones elementales de un enunciado dado y componerlas usando los operadores booleanos asociados a los conectivos del lenguaje que aparecen en el enunciado. Los conectivos
del lenguaje ser
an traducidos a su interpretacion obvia, aunque veremos algunas
sutilezas de dicha traducci
on.
Por ejemplo, la oraci
on
Hamlet defendi
o el honor de su padre pero no la felicidad de su madre
o la suya propia.
puede analizarse como compuesta de b
asicamente tres proposiciones elementales:
p: Hamlet defendi
o el honor de su padre.
q: Hamlet defendi
o la felicidad de su madre.
r: Hamlet defendi
o su propia felicidad.
Usando estas variables proposicionales puede traducirse la proposicion como
p (q r)
N
otese que la palabra pero se traduce como una conjuncion (dado que afirma
ambas componentes). Por otro lado la disyuncion usada es inclusiva, dado que
podra haber defendido la felicidad de su madre, la propia o ambas.
2.6 Negaci
on, conjunci
on y disyunci
on en el lenguaje
La operaci
on de negaci
on aparece usualmente en el lenguaje insertando un
no en la posici
on correcta del enunciado que se quiere negar; alternativamente,
puede anteponerse la frase es falso que o la frase no se da el caso que o hacer
construcciones sint
acticas algo m
as complejas. Por ejemplo el enunciado
Todos los unicornios son azules.
puede negarse de las siguientes maneras:
No todos los unicornios son azules.
No se da el caso de que todos los unicornios sean azules.
Es falso que todos los unicornios sean azules.
Algunos unicornios no son azules.
CAPITULO 2. LOGICA
PROPOSICIONAL
32
Y EQUIVALENCIA
2.7 IMPLICACION
33
Un ejemplo de disyunci
on exclusiva es:
El consejero del emperador pertenece a la nobleza o al pueblo.
donde se interpreta que no puede pertenecer a ambos a la vez. Esta proposicion se
simboliza como
p 6 q
donde las proposiciones elementales son
p: El consejero del emperador pertenece a la nobleza.
q: El consejero del emperador pertenece al pueblo.
En latn existen dos palabras diferentes para la disyuncion inclusiva y exclusiva.
La palabra vel se usa para la disyunci
on inclusiva mientras que para la exclusiva
se usa la palabra aut. El smbolo usado en logica para la disyuncion proviene
precisamente de la inicial de la palabra latina.
2.7 Implicaci
on y equivalencia
La implicaci
on l
ogica suele representarse en el lenguaje natural con la construcci
on si . . . entonces . . . Es uno de los conectivos sobre los que menos acuerdo hay
y al que m
as alternativas se han propuesto. Casi todo el mundo esta de acuerdo
en que cuando el antecedente p es verdadero y el consecuente q es falso, entonces
p q es falsa. Por ejemplo, el caso de la afirmacion
Si se reforman las leyes laborales entonces bajara el desempleo.
Sin embargo existen ciertas dudas acerca del valor de verdad (o del significado
l
ogico) de frases como
Si dos m
as dos es igual a cinco, entonces yo soy el Papa.
Para la l
ogica cl
asica que estamos presentando aqu, la frase anterior es verdadera
(mirando la tabla de verdad del , vemos que si ambos argumentos son falsos
entonces la implicaci
on es verdadera).
Normalmente se usa una implicaci
on con un consecuente obviamente falso como
una manera elptica de negar el antecedente. Por ejemplo decir
Si la economa mejor
o con esos ajustes, yo soy Gardel.
es una manera estilizada de decir que la economa no mejoro con esos ajustes.
Otra forma de representar la implicaci
on (y la consecuencia) en el lenguaje es a
traves de las palabras suficiente y necesario. Por ejemplo la siguiente proposicion:
Es suficiente que use un preservativo para no contagiarme el sida
CAPITULO 2. LOGICA
PROPOSICIONAL
34
2.8 ANALISIS
DE RAZONAMIENTOS
35
2.8 An
alisis de razonamientos
En la secci
on 2.1 se presentaron ejemplos de razonamientos en lenguaje natural.
Ya estamos en condiciones de analizar la validez de algunas formas de razonamiento.
Hemos dicho que un razonamiento es v
alido si cada vez que todas las premisas
sean verdaderas la conclusi
on tambien tiene que serlo. Una forma de analizar un
razonamiento, entonces, es traducirlo a expresiones booleanas y analizar el caso
en el cual todas las premisas son verdaderas. Si se tiene el siguiente razonamiento
(ya traducido a expresiones booleanas):
p0
..
.
pn
q
el mismo se considera v
alido si siempre que p0 , . . . , pn sean todas verdaderas entonces tambien lo es q. Dada las tablas de verdad de la conjuncion y de la implicacion,
esto ocurre si y s
olo si la siguiente f
ormula es una tautologa:
p0 . . . pn q
Por caso, el razonamiento del pelado que no es feliz (ejemplo 2.4) puede traducirse como
p: Tengo pelo.
q: Soy feliz.
pq
q
p
Se puede ahora comprobar la validez del razonamiento contruyendo la tabla de
verdad asociada.
p
T rue
T rue
F alse
F alse
q
pq
T rue T rue
F alse F alse
T rue T rue
F alse T rue
q
(p q) q
F alse
F alse
T rue
F alse
F alse
F alse
T rue
T rue
p
(p q) q p
F alse
T rue
F alse
T rue
T rue
T rue
T rue
T rue
CAPITULO 2. LOGICA
PROPOSICIONAL
36
pq
q
T rue T rue
F alse F alse
T rue T rue
F alse T rue
p
(p q) p
q
(p q) p q
F alse
F alse
F alse
T rue
F alse
F alse
T rue
T rue
T rue
T rue
F alse
F alse
T rue
T rue
T rue
T rue
M
as a
un, mirando la tabla de verdad es posible saber cuando las premisas son
verdaderas y la conclusi
on es falsa. En este caso, cuando p es falsa y q es verdadera,
o volviendo a nuestro ejemplo, cuando tenemos un pelado feliz.
Si bien este metodo para analizar razonamientos es efectivo para razonamientos
con pocas variables proposicionales, a medida que la cantidad de variables crece,
el tama
no de las tablas de verdad crece de manera exponencial (hay 2n filas en
una tabla de verdad con n variables proposicionales). Esta limitacion practica al
uso de tablas de verdad no ocurre s
olo para analizar razonamientos, pero en este
caso es m
as obvio el problema dado que en los razonamientos suelen ser necesarias
una gran cantidad de variables proposicionales.
En los captulos siguientes veremos metodos alternativos para resolver la validez
de razonamientos y de expresiones booleanas en general, los cuales son a veces
mucho m
as cortos que las tablas de verdad.
2.9 Resoluci
on de acertijos l
ogicos
Haremos ahora una visita a la isla de los caballeros y los pcaros. Esta isla
est
a habitada solamente por estos dos tipos de gente. Los caballeros tienen la
particularidad de que s
olo dicen la verdad y los pcaros mienten siempre.
Ejemplo 2.7
Tenemos dos personas, A y B habitantes de la isla. A hace la siguiente afirmacion:
Al menos uno de nosotros es un pcaro. Que son A y B?
La soluci
on de este problema es bastante simple. Supongamos que A es un
pcaro. Luego la afirmaci
on hecha es falsa, y por lo tanto ninguno de ellos podra
2.10 EJERCICIOS
37
2.10 Ejercicios
Ejercicio 2.2
Evaluar las siguientes expresiones en el estado {(p, T rue), (q, F alse), (r, F alse)}.
1. (p q) r
2. (p q) r
3. p (q r)
4. p (q r)
5. (p q) r
6. (p q) r
7. p (q r)
8. p q r
Ejercicio 2.3
Escribir las tablas de verdad para las siguientes expresiones, determinando los
casos en los cuales sean tautologas o contradicciones.
1. (p q) q
2. (p q) q
3. (p 6 q) (p q)
4. p (q p)
CAPITULO 2. LOGICA
PROPOSICIONAL
38
5. (p 6 p) 6 p
6. (p q) p
7. q p (q p) q
8. (p p p) p
Ejercicio 2.4
En la isla de los pcaros y los caballeros, A dice O bien yo soy un pcaro o bien B
es un caballero Que son A y B?
Ejercicio 2.5
Traducir los siguientes razonamientos presentados en lenguaje natural al calculo
proposicional y analizar su validez.
1. Si el presidente entiende las protestas de la gente entonces si quiere ser reelegido cambiar
a su poltica. El presidente quiere ser reelegido. Luego, si el
presidente entiende las protestas de la gente, entonces cambiara su poltica.
2. Si el presidente entiende las protestas de la gente entonces si quiere ser reelegido cambiar
a su poltica. El presidente cambiara su poltica. Luego, si el
presidente entiende las protestas de la gente, entonces quiere ser reelegido.
3. Si el gobernador quiere mejorar su imagen, o bien mejora su poltica social
o bien gasta m
as en publicidad. El gobernador no mejora su poltica social.
Luego, si el gobernador quiere mejorar su imagen, entonces gastara mas en
publicidad.
4. Si el gobernador quiere mejorar su imagen, o bien mejora su poltica social
o bien gasta m
as en publicidad. El gobernador mejoro su poltica social.
Luego, si el gobernador quiere mejorar su imagen, entonces no gastara mas
en publicidad.
5. Si la ciudadana romana hubiera sido una garanta de los derechos civiles,
los romanos habran gozado de libertad religiosa. Si los romanos hubieran
gozado de libertad religiosa, entonces no se habra perseguido a los primeros
cristianos. Pero los primeros cristianos fueron perseguidos. Por consiguiente,
la ciudadana romana no puede haber sido una garanta de los derechos
civiles.
6. Si la descripci
on bblica de la cosmogona es estrictamente correcta, el Sol no
fue creado hasta el cuarto da. Y si el Sol no fue creado hasta el cuarto da,
no puede haber sido la causa de la sucesi
on del da y la noche durante los tres
primeros das. Pero o bien la Biblia usa la palabra da en un sentido diferente
al aceptado corrientemente en la actualidad, o bien el Sol debe haber sido
2.10 EJERCICIOS
39
la causa de la sucesi
on del da y la noche durante los tres primeros das.
De esto se desprende que, o bien la descripcion bblica de la cosmogona no
es estrictamente correcta, o bien la palabra da es usada en la Biblia en un
sentido diferente al aceptado corrientemente en la actualidad.
7. Se est
a a favor de la pena de muerte por miedo al delito o por deseo de
venganza. Aquellos que saben que la pena de muerte no disminuye el delito no
est
an a favor de la pena de muerte por miedo al delito. Por lo tanto aquellos
que est
an a favor de la pena de muerte no saben que esta no disminuye el
delito o tienen deseo de venganza.
40
CAPITULO 2. LOGICA
PROPOSICIONAL
Captulo 3
C
alculo proposicional
One philosopher was shocked when Bertrand Russell told him that
a false proposition implies any proposition. He said you mean that
from the statement that two plus two equals five it follows that you
are the Pope? Russell replied yes. The philosopher asked, Can you
prove this? Russell replied Certainly, and contrieved the following
proof on the spot:
1. Suppose 2 + 2 = 5.
2. Substracting two from both sides of the equation, we get 2 = 3.
3. Transposing, we get 3 = 2.
4. Substracting one from both sides, we get 2 = 1
Now, the Pope and I are two. Since two equals one, then the Pope
and I are one. Hence I am the Pope.
Raymond Smullyan:What Is the Name of This Book?
En este captulo se presenta una alternativa a las evaluaciones (tablas de verdad) para razonar con expresiones booleanas. En los captulos precedentes se determinaba si una f
ormula era una tautologa construyendo su tabla de verdad;
ahora en cambio se usar
an metodos algebraicos para demostrar que una expresion
dada es un teorema. Esta manera de trabajar presenta una buena alternativa a las
tablas de verdad, dado que estas pueden ser extremadamente largas si el n
umero
de variables es grande, en cambio una demostracion puede ser mucho mas corta.
La tabla de verdad se construye de manera mecanica, a diferencia de la demostraci
on para la cual es necesario desarrollar cierta habilidad en la manipulacion
41
42
CAPITULO 3. CALCULO
PROPOSICIONAL
sint
actica de f
ormulas (y a
un as no puede garantizarse que se encontrara una demostraci
on). Por otro lado, la manipulaci
on sintactica de formulas suele tener mas
aplicaciones y es una de las habilidades requeridas mas importantes a la hora de
construir programas de computadora.
Con este fin introduciremos un sistema para construir demostraciones que involucren expresiones de la l
ogica proposicional. El estilo utilizado se conoce como
c
alculo proposicional . Este c
alculo est
a orientado a la programacion, por lo cual
provee herramientas para el manejo efectivo de formulas logicas de tama
no considerable.
La necesidad de este c
alculo se fue haciendo cada vez mas notoria a medida
que se desarrollaba el c
alculo de programas. Pueden encontrarse ya sus primeros
elementos en el trabajo de E.W. Dijkstra y W.H.J. Feijen [DF88]. Una exposicion
completa figura en [DS90] y en [GS93]. Puede consultarse tambien [Coh90], donde
la exposici
on es m
as elemental.
43
el c
alculo estar
a constituido por un conjunto de axiomas, los cuales iran introduciendose paulatinamente, y un conjunto de reglas de inferencia. A diferencia de
otros sistemas formales para la l
ogica proposicional, nuestro calculo da un lugar
fundamental al conectivo de equivalencia l
ogica, por lo cual las reglas de inferencia
usadas ser
an esencialmente las de Leibniz, transitividad y sustitucion.
El sistema formal bajo consideraci
on consta de los siguientes elementos:
Alfabeto. Las expresiones booleanas las cuales constituiran la sintaxis de
nuestro c
alculo se construir
an usando el siguiente alfabeto:
constantes: Las constantes T rue y F alse que se usaran para denotar
los valores verdadero y falso respectivamente.
variables: Un conjunto infinito. Se usaran tpicamente las letras p, q, r
como variables proposicionales.
operadores unarios: negaci
on .
equivalencia
disyuncion
conjuncion
operadores binarios:
discrepancia 6
implicacion
consecuencia .
signos de puntuaci
on: Parentesis ( y ).
F
ormulas. Las expresiones bien formadas o formulas del calculo proposicional
ser
an las que se puedan construir de acuerdo a las siguientes prescripciones:
1. Las variables proposicionales y las constantes son formulas.
2. Si E es una f
ormula, entonces (E) tambien lo es.
3. Si E y F son f
ormulas y es un operador binario (, , etc.),
entonces (E F ) tambien es una formula.
4. S
olo son f
ormulas las construidas con las tres reglas precedentes.
Reglas de inferencia. Las reglas de inferencia usadas seran algunas de las
ya presentadas para la igualdad. En este caso, la equivalencia logica entre
expresiones booleanas satisfar
a las propiedades de la igualdad:
CAPITULO 3. CALCULO
PROPOSICIONAL
44
Transitividad:
Leibniz:
Sustituci
on:
P Q, Q R
P R
P Q
E(r := P ) = E(r := Q)
P
P (q := R)
donde P , Q, R y E son f
ormulas booleanas arbitrarias. De aqu en adelante usaremos letras may
usculas para denotar expresiones , diferenciandolas
as de las variables.
Axiomas. Los axiomas del c
alculo se introduciran gradualmente. El calculo
proposicional tal como se presenta aqu no aspira a la minimalidad en el
n
umero de reglas de inferencia y axiomas, dado que uno de los principales
objetivos de dicho c
alculo es su uso para realizar demostraciones reales y
no ser meramente un objeto de estudio en s mismo, como generalmente
ocurre. Si se usan un mnimo de axiomas y de reglas de inferencia, las
demostraciones de teoremas elementales resultan en general demasiado
largas.
En el captulo siguiente se ver
an algunas aplicaciones basicas del calculo proposicional. Su principal aplicaci
on es la derivacion y verificacion de programas, lo
cual se desarrollar
a en los captulos subsiguientes.
Un formato c
omodo para demostraciones (usando las reglas de inferencia ya
presentadas) es el que usamos en el captulo 1 para demostrar igualdades. Primero
definimos un teorema como generado por las siguientes reglas:
1. un axioma es un teorema,
2. la conclusi
on de una regla de inferencia cuyas premisas son teoremas (ya
demostrados) es un teorema,
3. una expresi
on booleana que se demuestra equivalente (ver mas adelante) a
un teorema es tambien un teorema.
Nuestro formato de demostraci
on consistir
a en general de una serie de pasos de
equivalencia desde la expresi
on a demostrar hasta llegar a un axioma. Cada paso
de demostraci
on estar
a justificado por una aplicacion de la regla de Leibniz, y el
teorema final se seguir
a por aplicaci
on de la regla de transitividad al igual que lo
hicimos en el captulo 1.
Una generalizaci
on usada usualmente en l
ogica e indispensable para cualquier
c
alculo que pretenda ser u
til, es que los pasos de demostracion puedan ser, ademas
3.2 LA EQUIVALENCIA
45
3.2 La equivalencia
La equivalencia, que denotaremos con el smbolo , se define como el operador
binario que satisface los siguientes axiomas:
Axioma 3.1 (Asociatividad)
((p q) r) (p (q r))
Axioma 3.2 (Conmutatividad)
pqqp
Axioma 3.3 (Neutro)
p T rue p
La asociatividad permite la omisi
on de parentesis. Por ejemplo: el tercer axioma debera haberse escrito como (p T rue) p. La asociatividad permite interpretarla en cada caso particular de la forma mas conveniente. Como ademas es
conmutativa, consideraremos tambien irrelevante el orden de los terminos en una
equivalencia. Por ejemplo, podemos usar el u
ltimo axioma para reemplazar p p
por T rue.
La reflexividad de la equivalencia puede demostrarse como sigue:
Teorema 3.4 (Reflexividad)
pp
n
Demostracio
pp
{ 3.3 aplicado a la primera p }
(p T rue) p
CAPITULO 3. CALCULO
PROPOSICIONAL
46
3.3 LA NEGACION
47
Metateorema 3.6
Dos teoremas cualesquiera son equivalentes.
3.3 La negaci
on
La negaci
on, que denotaremos con el smbolo , es el operador unario que
cumple los siguientes axiomas:
Axioma 3.7 (Negaci
on y equivalencia)
(p q) p q
Adem
as, definimos la constante F alse con el siguiente axioma
Axioma 3.8
F alse T rue
La negaci
on tiene mayor precedencia que cualquier otro operador del calculo.
A partir de los axiomas se pueden demostrar los siguientes teoremas (se deja como
ejercicios para el lector):
Teorema 3.9 (Doble negaci
on)
p p
Teorema 3.10 (Contrapositiva)
p F alse p
3.4 La discrepancia
La discrepancia es el operador que satisface el siguiente axioma:
Axioma 3.11 (Definici
on de 6)
p 6 q (p q)
La precedencia de la discrepancia es la misma que la de la equivalencia. A
partir de este axioma se pueden demostrar los siguientes teoremas:
Teorema 3.12 (Asociatividad)
((p 6 q) 6 r) (p 6 (q 6 r))
Teorema 3.13 (Conmutatividad)
(p 6 q) (q 6 p)
Teorema 3.14 (Asociatividad mutua)
p (q 6 r) (p q) 6 r
CAPITULO 3. CALCULO
PROPOSICIONAL
48
3.5 La disyunci
on
La disyunci
on, que denotaremos con el smbolo , es un operador binario de
mayor precedencia que la equivalencia, es decir que pq r debe entenderse como
(p q) r. Este operador est
a definido por los siguientes axiomas:
Axioma 3.18 (Asociatividad)
(p q) r p (q r)
Axioma 3.19 (Conmutatividad)
pq qp
3.5 LA DISYUNCION
49
CAPITULO 3. CALCULO
PROPOSICIONAL
50
3.6 La conjunci
on
La conjunci
on, que denotaremos con el smbolo , es un operador binario con
la misma precedencia que la disyunci
on, lo cual hace necesario el uso de parentesis
en las expresiones que involucran a ambos operadores. Por ejemplo: no es lo mismo
(p q) r que p (q r). Esto nos dice que no podemos escribir p q r, pues esta
expresi
on no est
a asociada de manera natural a ninguna de las dos anteriores. Se
introducir
a un u
nico axioma para definir conjuncion.
Axioma 3.26 (Regla dorada)
pq pq pq
La regla dorada aprovecha fuertemente la asociatividad de la equivalencia. En
principio, la interpretaramos como
p q (p q p q),
pero nada nos impide hacer otras interpretaciones, por ejemplo
(p q p) (q p q), o bien
(p q p q) p q, o bien, usando la conmutatividad de la equivalencia,
(p q) (p q p q), etcetera.
La regla dorada ser
a de gran utilidad para demostrar propiedades de la conjunci
on y la disyunci
on, dado que provee una relacion entre ambas.
Teorema 3.27 (Asociatividad)
p (q r) (p q) r
n
Demostracio
p (q r)
{ regla dorada, interpretada como p q (p q p q) }
p (q r) p (q r)
{ regla dorada, dos veces1 }
p q r q r p (q r q r)
{ axioma 3.21 }
pq r qr pq pr pqr
{ axiomas 3.2, 3.1 }
(p q p q) r (p r q r p q r)
{ axioma 3.21 }
(p q p q) r (p q p q) r
1 De
ahora en m
as no explicitaremos la interpretaci
on, a menos que lo juzguemos necesario.
3.6 LA CONJUNCION
51
{ regla dorada }
(p q) r (p q) r
{ regla dorada }
(p q) r
Teorema 3.28 (Conmutatividad)
pq qp
Teorema 3.29 (Idempotencia)
ppp
Teorema 3.30 (Neutro)
p T rue p
n
Demostracio
p T rue
{ regla dorada }
p T rue p T rue
{ teorema 3.24 }
p T rue T rue
{ p p; T rue es neutro de }
p
La disyunci
on es distributiva con respecto a la equivalencia por definicion. La
conjunci
on no lo es. Veamos:
(p q) (p r)
{ regla dorada en cada miembro }
pq pq pr pr
{ conmutatividad de }
pq r pq pr p
{ distributividad de con respecto a }
p q r p (q r) p
{ asociatividad de }
(p (q r) p (q r)) p
{ regla dorada }
(p (q r)) p
CAPITULO 3. CALCULO
PROPOSICIONAL
52
3.7 La implicaci
on
La implicaci
on, que denotaremos con el smbolo , es el operador binario que
precede a la equivalencia, pero es precedido por la disyuncion (y por lo tanto
tambien por la conjunci
on).
Para definirlo alcanza con el siguiente axioma:
Axioma 3.34
pq pq q
Teorema 3.35
pp
n
Demostracio
pp
3.7 LA IMPLICACION
53
{ axioma 3.34 }
ppp
y este resultado es el axioma 3.20.
Teorema 3.36
p q p q
n
Demostracio
pq
{ definici
on de }
pq q
{ p F alse p }
p q F alse q
{ 3.21 }
(p F alse) q
{ p F alse p }
p q
Teorema 3.37
(p q) p q
Teorema 3.38
p T rue
Teorema 3.39
pq p
Teorema 3.40
ppq
Teorema 3.41 (Transitividad)
(p q) (q r) (p r)
Un axioma que ser
au
til es la siguiente version axiomatica de la regla de Leibniz:
Axioma 3.42 (Leibniz)
e = f E(z := e) = E(z := f )
CAPITULO 3. CALCULO
PROPOSICIONAL
54
La forma de este axioma es diferente a la de los anteriores, ya que no es estrictamente hablando una expresi
on booleana sino un esquema, dado que para
cada E diferente ser
a un axioma diferente. Alternativamente, podra demostrarse
el axioma de Leibniz como un metateorema de nuestro calculo de predicados. La
demostraci
on puede hacerse por inducci
on en la estructura de E.
Si bien este axioma est
a inspirado en la regla de Leibniz su significado es
diferente, dado que la regla de Leibniz dice que si dos expresiones son iguales en
cualquier estado entonces sustituir esas expresiones en una expresion dada tambien
producir
a expresiones iguales en cualquier estado. El axioma de Leibniz dice, en
cambio, que si dos expresiones son iguales en un estado dado, entonces sustituirlas
en una expresi
on dada producir
a expresiones iguales en ese estado.
Una diferencia importante con la regla de Leibniz es que la recproca del axioma no es cierta (mientras que la recproca de la regla para nuestro lenguaje de
expresiones booleanas y aritmeticas es v
alida). El siguiente contraejemplo muestra
que para el axioma no es este el caso.
Ejemplo 3.1
Tomemos como E a la expresi
on T rue z. Luego se da que
E(z := T rue) = E(z := F alse)
dado que ambos son verdaderos, pero obviamente T rue 6= F alse.
En el caso de la regla de inferencia de Leibniz, se puede pensar que la recproca es v
alida dado que se supone una cuantificacion sobre todas las expresiones
posibles.
3.8 La consecuencia
La consecuencia es el operador dual de la implicacion. La denotaremos con el
smbolo . Es un operador binario que tiene la misma precedencia que la implicaci
on y que satisface:
Axioma 3.43
pq pq p
Puede ahora demostrarse f
acilmente que
Teorema 3.44
pqqp
A partir de este teorema pueden dualizarse las propiedades de la implicacion.
En las secciones siguientes permitiremos usar la implicacion o la consecuencia
como nexo en las demostraciones (pero no ambas en la misma demostracion). Esto
se justifica con la transitividad de estos operadores.
3.9 GENERALIZACION
55
negaci
on
disyunci
on y conjuncion
implicaci
on y consecuencia
equivalencia y discrepancia
3.9 Generalizaci
on del formato de demostraci
on
Se desea tener en el c
alculo de predicados una herramienta poderosa para
resolver problemas concretos. Los principales problemas a resolver provienen del
c
alculo formal de programas. Tanto para estos problemas como para los tratados
en el pr
oximo captulo, es c
omodo disponer de un formato de demostracion mas
laxo.
Para fijar ideas, comenzaremos con una derivacion matematica que involucra
desigualdades adem
as de igualdades [BvW08].
Ejemplo 3.2
Sean m y n dos enteros positivos tales que m > n entonces m2 n2 > 3.
Para demostrar este resultado, dado que m y n son enteros positivos se satisface
que m + n 3 (esto se deduce de que n 1 y m 2). Por otro lado, es obvio que
m n 1. Calculemos ahora
m2 n 2
= { diferencia de cuadrados }
(m + n) (m n)
{ propiedades de m y n }
31
= { aritmetica }
3
En el ejemplo, se aplica en uno de los pasos una desigualdad. Dado que la igualdad la implica y que es transitiva el resultado final se deduce de esta demostracion.
Hay que tener en cuenta, sin embrago, que el reemplazo de iguales por iguales, la
regla de Leibniz, no es siempre v
alida para las desigualdades. En este caso s, dado
CAPITULO 3. CALCULO
PROPOSICIONAL
56
3.10 EJERCICIOS
57
3.10 Ejercicios
Ejercicio 3.1
(Largo) Construir las tablas de verdad para todos los axiomas introducidos en este
captulo.
Ejercicio 3.2
(Muy largo) Demostrar todos los teoremas enunciados en este captulo.
Ejercicio 3.3
Demostrar que F alse es neutro para la disyuncion:
p F alse p
Ejercicio 3.4
Demostrar que F alse es absorbente para la conjuncion:
p F alse F alse
Ejercicio 3.5
Demostrar las leyes de absorci
on:
p (p q) p
p (p q) p
Ejercicio 3.6
Demostrar las leyes de absorci
on:
p (p q) p q
p (p q) p q
Ejercicio 3.7
Demostrar:
p (q p) p q
Ejercicio 3.8
Demostrar:
1. La conjunci
on distribuye con respecto a la conjuncion:
p (q r) (p q) (p r) .
2. La conjunci
on distribuye con respecto a la disyuncion:
p (q r) (p q) (p r) .
CAPITULO 3. CALCULO
PROPOSICIONAL
58
3. La disyunci
on es distributiva con respecto a la conjuncion:
p (q r) (p q) (p r) .
4. En general, la conjunci
on no es distributiva con respecto a la equivalencia,
pero cuando la cantidad de signos es par, s lo es:
s (p q r) s p s q s r .
Ejercicio 3.9
Demostrar:
1. p q p.
2. p (q r) p q r.
3. La implicaci
on distribuye con respecto a la equivalencia.
p (q r) p q p r.
4. Doble implicaci
on. (p q) (q p) p q
5. Contrarecproca. p q q p
6. p q p q p
7. (p q r) (p q r)
8. Modus ponens. p (p q) q
9. Transitividad. (p q) (q r) (p r)
10. Monotona. (p q) (p r q r)
11. Monotona. (p q) (p r q r)
Ejercicio 3.10
Demostrar:
p (p q) p q
p (q p) p
p (p q) T rue
p (q p) q p
T rue p p
p F alse p
F alse p T rue
Captulo 4
Aplicaciones del c
alculo
proposicional
Mi unicornio azul por fin te encontre. . .
Leo Masliah. La recuperaci
on del unicornio
La l
ogica es una herramienta fundamental para resolver problemas. En ciencias
de la computaci
on nos permite construir especificaciones y programas. Si bien la
inform
atica ha dado un gran impulso para el desarrollo de la logica, sobre todo en
su uso como herramienta concreta, la l
ogica se sigue usando para decidir acerca
de la validez de los razonamientos y para proveer soluciones a problemas diversos,
como por ejemplo la construcci
on de circuitos digitales combinatorios.
En este captulo se presentar
an algunas aplicaciones elementales del calculo
proposicional: an
alisis de argumentos l
ogicos y resolucion de problemas de ingenio.
Por u
ltimo veremos un ejemplo de uso del estilo de calculo proposicional para
problemas matem
aticos. Las definiciones de piso y techo y varias de sus propiedades
est
an inspiradas en el libro de Roland Backhouse [Bac03]. La presentacion del
m
aximo y mnimo usando propiedades universales seg
un nuestro conocimiento
apareci
o por primera vez en el artculo de Wim Feijen [Fei90].
4.1 An
alisis de argumentaciones
En el captulo 2 se usaron las tablas de verdad para comprobar la validez de
ciertas formas de razonamiento. Si bien ese metodo es efectivo, cuando crece el
n
umero de variables proposicionales su costo se vuelve prohibitivo, dado que el
59
CAPITULO 4. APLICACIONES DEL CALCULO
PROPOSICIONAL
60
tama
no de las tablas de verdad crece exponencialemente. Para el caso de razonamientos con dos premisas como los presentados en ese captulo el metodo es
adecuado, dado que el n
umero de variables proposicionales es muy peque
no. Sin
embargo, cuando se quieren analizar razonamientos de la vida real es conveniente
recurrir a metodos sint
acticos, es decir a la manipulacion de formulas sin interpretaci
on sem
antica. En el primer ejemplo consideraremos un razonamiento con seis
variables proposicionales, lo cual hubiera dado lugar a una tabla de verdad con 64
filas.
Ejemplo 4.1
Considerese la siguiente argumentaci
on (adaptada del libro [Cop73]):
Si Dios fuera incapaz de evitar el mal no sera omnipotente; si no
quisiera hacerlo sera malevolo. El mal s
olo puede existir si Dios no puede o no quiere impedirlo. El mal existe. Si Dios existe, es omnipotente
y no es malevolo. Luego, Dios no existe.
Para representarlo en el c
alculo proposicional elegimos letras proposicionales
para cada una de las proposiciones elementales en el razonamiento, luego encontramos las f
ormulas que representan las proposiciones mas complejas y mostramos
que efectivamente la f
ormula asociada a la conclusion se deduce formalmente de
las f
ormulas asociadas a las premisas.
Se ve que si uno se expresa con precisi
on, la argumentacion precedente no es
en si misma un razonamiento sino un teorema a ser demostrado.
Elegimos las siguientes letras proposicionales:
q: Dios quiere evitar el mal.
c: Dios es capaz de evitar el mal.
o: Dios es omnipotente.
m: Dios es malevolo.
e: El mal existe.
d: Dios existe.
Las premisas se expresan de la siguiente manera:
1. c o
2. q m
3. e q c
4. e
4.1 ANALISIS
DE ARGUMENTACIONES
61
5. d o m
Y la conclusi
on obviamente es:
d
Una demostraci
on de la correcci
on de este razonamiento es la siguiente:
d
{ premisa 5, contrarecproca (ejercicio 3.9) }
(m o)
{ de Morgan }
m o
{ premisa 1, 2, monotona dos veces }
q c
{ premisa 3 }
e
{ premisa 4 }
T rue
Hemos demostrado entonces que asumiendo que todas las premisas son validas,
T rue d, lo cual es lo mismo que afirmar d dado que T rue es neutro a
izquierda de una implicaci
on (como ya se demostro en el captulo anterior).
Ejemplo 4.2
Considerese el siguiente argumento cuya forma se denomina dilema en la logica
cl
asica [Cop73]. Si bien en este caso la tabla de verdad podra haber sido construida
(tiene s
olo 16 filas), la demostraci
on sint
actica es mas corta y elegante.
Si el general era leal, habra obedecido las ordenes, y si era inteligente las habra comprendido. O el general desobedecio las ordenes o
no las comprendi
o. Luego, el general era desleal o no era inteligente.
Elegimos las siguientes letras proposicionales:
l: El general es leal.
o: El general obedece las
ordenes.
i: El general es inteligente.
c: El general comprende las
ordenes.
62
4.2 Resoluci
on de acertijos l
ogicos
En esta secci
on usaremos el c
alculo de predicados para la resolucion de acertijos
l
ogicos. La mayor economa de este c
alculo nos permite encontrar soluciones mas
elegantes a problemas como los planteados en 2.9. Veremos primero soluciones
sint
acticas a dichos problemas los cuales fueron resueltos usando (implcitamente)
tablas de verdad.
Ejemplo 4.3
Tenemos dos personas, A y B, habitantes de la isla de caballeros y pcaros. A hace
la siguiente afirmaci
on: Al menos uno de nosotros es un pcaro. Que son A y B?
Si tomamos las proposiciones elementales
a: A es un caballero
b: B es un caballero
DE ACERTIJOS LOGICOS
4.2 RESOLUCION
63
64
4.3 La funci
on piso
El estilo de c
alculo proposicional con el cual estamos trabajando es particularmente c
omodo para trabajar con problemas matematicos. En las proximas secciones trabajaremos con propiedades de algunas funciones matematicas las cuales
aparecen en varios problemas de programaci
on.
Definici
on 4.1
Dado un n
umero real x se define la funci
on piso (o parte entera) aplicada a x como
el entero que satisface, para todo entero n, la siguiente propiedad:
b c : 7 Int
n bxc n x
Habra que mostrar que esta propiedad es suficiente para definir una funcion, es
decir que bxc est
a definida de manera u
nica para cada x. Esto quedara demostrado
por la propiedad 4.1.
Propiedad 4.1
Instanciando n en la definici
on de piso con el entero bxc, obtenemos la siguiente
propiedad:
bxc x
Propiedad 4.2
Instanciando ahora x en la definici
on de piso con n (que es tambien un real),
obtenemos la siguiente propiedad:
n bnc
Propiedad 4.3
De las dos propiedades anteriores se sigue que para todo entero n
bnc = n
PISO
4.3 LA FUNCION
65
Propiedad 4.4
Podemos usar tambien la propiedad contrapositiva de la equivalencia (teorema 3.16)
y el hecho que p q q < p para obtener la siguiente propiedad para todo n
entero:
bxc < n x < n
Esta propiedad puede pensarse como una definicion alternativa de la funcion piso.
Propiedad 4.5
Instanciando n con el entero bxc+1 en la propiedad anterior, obtenemos la siguiente
propiedad:
x < bxc + 1
Propiedad 4.6
De las propiedades anteriores puede deducirse que para todo x real
bxc x < bxc + 1
y por lo tanto puede verse que la funcion piso es efectivamente una funcion
cuya definici
on alternativa podra ser
b c : 7 Int
n = bxc n x < n + 1
66
TECHO
4.5 LA FUNCION
67
{ aritmetica }
knx
{ definici
on de piso }
k n bxc
{ aritmetica }
k bxc + n
4.5 La funci
on techo
De manera dual puede definirse la funcion techo, la cual dado un n
umero real
devuelve el menor entero mayor o igual que aquel.
Definici
on 4.2
Dado un n
umero real x se define la funci
on techo aplicada a x como el entero que
satisface, para todo entero m, la siguiente propiedad:
d e : 7 Int
dxe n x n
La funci
on techo tiene propiedades duales a la funcion piso (ver ejercicio 4.3)
Ejemplo 4.6 (Redondeo [Bac03])
En algunos lenguajes de programaci
on s
olo se dispone de la funcion piso y en
algunos casos hace falta usar tambien la funcion techo (por ejemplo para redondear
al entero m
as cercano). Resolveremos el problema para n
umeros racionales. Es
decir, dados dos enteros a y b se propone encontrar enteros p y q tales que
l m
a
p
=
q
b
Antes de seguir leyendo, recomendamos a los lectores intentar resolver el problema.
Para encontrar de manera sistem
atica los enteros p y q, procederemos usando la
igualdad indirecta. Tomemos un k entero arbitrario y partiendo de la desigualdad
lam
k
b
intentaremos llegar a traves de equivalencias logicas a una desigualdad similar pero
donde la expresi
on de la derecha sea una aplicacion de la funcion piso en lugar de
techo. Por la regla de igualdad indirecta, podremos entonces encontrar p y q con
la propiedad deseada.
68
a
b
{ desigualdad de enteros }
k 1 < ab
{ definici
on de techo, contrapositiva }
k1<
a
b
a+b1
b
{ definici
on de piso }
a+b1
k
b
De esta manera conseguimos una definici
on de la funcion techo en terminos de
la funci
on piso para n
umeros racionales. Si bien es requerido que el denominador
sea positivo, esto no es un problema dado que todo racional puede escribirse de
esa manera sin mayores inconvenientes.
4.6 M
aximo y mnimo
En esta secci
on presentamos una definici
on para el maximo (y dualmente para
el mnimo) en un estilo similar al usado para las funciones piso y techo. El tipo
de propiedad usado para definir estos operadores es conocido como propiedad
universal, e involucra la existencia y unicidad de cierto operador. En la seccion 1.7
introdujimos axiomas para el m
aximo y demostramos propiedades u
tiles en un
estilo ecuacional m
as c
omodo que los an
alisis por casos. Aqu demostraremos (o
propondremos como ejercicios) que todos esos axiomas son consecuencias de la
definici
on universal del m
aximo.
Definici
on 4.3
Dados dos n
umeros a y b se define el operador de m
aximo de ambos como el
n
umero que satisface, para todo n
umero n del mismo tipo que a y b, la siguiente
propiedad:
max : N um N um 7 N um
a max b n a n b n
4.7 EJERCICIOS
69
Los axiomas presentados en 1.7 pueden todos derivarse usando esta regla (ejercicio 4.8).
Demostraremos una propiedad esperable del maximo la cual no puede derivarse
f
acilmente a partir de los axiomas:
Propiedad 4.7
x max y = x x max y = y
x max y = x x max y = y
{ antisimetra de }
(x max y x x x max y) (x max y y y x max y)
{ axioma 1.5 }
(x max y x T rue) (x max y y T rue)
{ c
alculo proposicional, def. de m
aximo }
(x x y x) (x y y y)
{ reflexividad de , c
alculo proposicional }
xyy x
{ tricotoma }
T rue
4.7 Ejercicios
Ejercicio 4.1
Analizar los razonamientos del ejercicio 2.5 usando las herramientas introducidas
en esta secci
on.
Ejercicio 4.2
Utilizando el c
alculo proposicional, resolver los siguientes acertijos, donde A y B
son habitantes de la isla de los caballeros y los pcaros.
1. Nos encontramos con dos personas, A y B. A dice Al menos uno de nosotros
es un pcaro Que son A y B?
2. A dice Yo soy un pcaro o B es un caballero Que son A y B?
3. A dice Yo soy un pcaro pero B no Que son A y B?
4. Dos personas se dicen del mismo tipo si son ambas caballeros o ambas pcaros.
Tenemos tres personas, A, B y C. A y B dicen lo siguiente
A: B es un pcaro.
CAPITULO 4. APLICACIONES DEL CALCULO
PROPOSICIONAL
70
2. b xc = b bxcc
3. bbxcc = bxc
4. dbxce = bxc
Ejercicio 4.5
Que est
a mal en la siguiente demostraci
on (n, k enteros, 0 < n y x real)?
k bn xc
{ definici
on de piso }
k nx
{ aritmetica }
k
n
{ definici
on de piso }
k
n
bxc
{ aritmetica }
k n bxc
4.7 EJERCICIOS
71
{ aritmetica }
m
n
<k+1
{ definici
on de piso, contrapositiva }
bm
nc<k+1
{ aritmetica }
bm
nck
m
Por lo tanto, por igualdad indirecta vale que b m
n c = d n e.
Ejercicio 4.7
Definir una regla de desigualdad indirecta analoga a la de igualdad indirecta. Demostrarla. Usarla para demostrar que para cualquier par de reales a y b, vale que
bac + bbc ba + bc
Ejercicio 4.8
Demostrar los axiomas del m
aximo presentados en 1.7 a partir de la definicion 4.6.
Ejercicio 4.9
Demostrar que
bx min yc = bxc min byc
72
Captulo 5
C
alculo de predicados
(a) Socrates is a man.(b) All men are mortal.(c) All men are Socrates. That means all men are homosexuals.
Woody Allen:Love and Death
Si bien el c
alculo proposicional nos permitio analizar cierto tipo de razonamientos y resolver acertijos l
ogicos, su poder expresivo no es suficiente para comprobar
la validez de algunos razonamientos muy simples. Un caso paradigmatico es el de
los silogismos, tratados en la secci
on 2.1. Uno de los ejemplos considerados fue el
siguiente.
Las vacas son mamferos.
Hay animales que no son mamferos.
Hay animales que no son vacas.
Si quisieramos analizar este razonamiento usando el calculo proposicional nos
quedara claramente una forma invalida; cada premisa y como la conclusion seran
proposiciones elementales distintas,
vm: Las vacas son mamferos.
am: Hay animales que no son mamferos.
av: Hay animales que no son vacas.
y el razonamiento sera vm am av, el cual no es verdadero.
Para poder demostrar la validez de este tipo de razonamientos va a ser necesario disponer de herramientas que permitan analizar la estructura interna de las
proposiciones elementales.
73
CAPITULO 5. CALCULO
DE PREDICADOS
74
5.1 Predicados
El c
aculo proposicional desarrollado en el captulo 3 nos permitio razonar sobre
una clase restringida de expresiones booleanas denominadas f
ormulas proposicionales. Estas fueron construidas a partir de constantes (T rue y F alse), variables y
operadores booleanos ( , , , etc.). Por lo tanto, la expresividad de la logica
estuvo restringida a sentencias que puedan ser modeladas con estas formulas. Ya
vimos algunos ejemplos de expresiones booleanas mas generales en el captulo 1.
All, se utilizaron expresiones booleanas conjuntamente con expresiones aritmeticas.
En este captulo desarrollaremos el c
alculo de predicados. Este nos permitira
razonar sobre una clase m
as extensa y expresiva de expresiones booleanas. De
manera general, una f
ormula del c
alculo de predicados es una formula proposicional
en donde algunas variables booleanas pueden ser reemplazadas por:
Predicados, los cuales son funciones booleanas (el concepto de funcion fue
introducido en 1.7) cuyos argumentos pueden ser expresiones no booleanas.
Ejemplos de predicados son igual. (xy). 4 y mayor. 2+x. y. Los nombres
de funci
on (por ejemplo igual mayor) son llamados smbolos de predicados.
A menudo tambien se usa en los predicados la notacion infija como a < b o
a max b.
Los argumentos de los predicados pueden ser expresiones de distintos tipos.
En el captulo 1 vimos esto para el caso particular de las expresiones aritmeticas. De esta forma los argumentos pueden tener variables no necesariamente
booleanas. Estos argumentos se denominan terminos.
Cuantificaci
on universal y existencial, como se vera mas adelante en este
captulo.
Dado un conjunto de smbolos de predicado, el c
alculo puro de predicados tendr
a como axiomas y reglas de inferencia las del calculo proposicional (ya vistos en
el captulo 3) y las de las cuantificaciones. En este calculo, los smbolos de predicado no estar
an interpretados (excepto para la igualdad = ). Esto quiere decir
que se har
a abstracci
on de su significado, y la logica no brindara reglas especficas
para manipularlos. Por ejemplo, para razonar sobre la sentencia dada en la introducci
on, deberemos tener los smbolo de predicado es vaca y es mamif ero. Una
f
ormula posible ser
a entonces es vaca es mamif ero. m, pero no se daran las
reglas para deducir que esta f
ormula es verdadera. A pesar de esta restriccion, el
c
alculo nos permitir
a razonar sobre sentencias, sin tener en cuenta el significado
de los smbolos de predicados.
Por otro lado, cuando se quiera trabajar en una teora determinada (por ejemplo la aritmetica) se introducir
an axiomas que expresen las propiedades que deben
satisfacer las operaciones y predicados que aparecen en el lenguaje.
75
Esta
surge cuando se formaliza la noci
on de para todo x; por ejemplo, cuando
uno dice en matem
atica
2 n es par, con n entero.
lo que en realidad est
a diciendo es
Para todos los n enteros, 2 n es par.
Esta misma afirmaci
on se escribe usando nuestra notacion de la siguiente manera:
hn : n Z : par.(2 n)i
(5.1)
donde n Z es T rue si y s
olo si n es entero, y par.n es T rue si y solo si n es
un entero par.
Lo que se ha indicado aqu es el significado (semantica) que modela el comportamiento formal (sint
actico) de la cuantificacion universal. Una vez que se
presentan los axiomas, uno puede trabajar sin preocuparse por el significado de
cada expresi
on utilizada, siempre que se manipulen usando las reglas exactamente
como han sido especificadas.
El formato general de una cuantificaci
on universal es el siguiente:
hvar. de cuantificaci
on : rango : terminoi
donde rango y termino son predicados los cuales toman como argumento a n
es decir, que pueden devolver s
olo los valores T rue o F alse (ejemplo: n 2 es
una tal expresi
on; para cada n es verdadera o falsa, en cambio n2 no lo es). Si
en el rango figura el predicado constante T rue, lo omitiremos para ahorrar tinta,
lo cual queda expresado en el siguiente axioma:
Axioma 5.1
hx : : f.xi hx : T rue : f.xi
Uno de los axiomas m
as importantes es el que da significado al rango, el cual
llamaremos Intercambio entre rango y termino:
Axioma 5.2
hx : r.x : f.xi hx : : r.x f.xi
Usando el ejemplo de m
as arriba, este axioma nos dice que es lo mismo escribir
Para todos los n enteros, 2n es par que Para todos los n, si n es entero entonces
2 n es par.
Dado que el cuantificador universal es una generalizacion de la conjuncion,
algunas propiedades de esta pasan al primero. Por ejemplo, la Distributividad de
con :
CAPITULO 5. CALCULO
DE PREDICADOS
76
Axioma 5.3
X hx : : f.xi hx : : X f.xi, siempre que x no ocurra en X.
y la Distributividad con con (o bien Regla del Termino):
Axioma 5.4
hx : : f.xi hx : : g.xi hx : : f.x g.xi
Estos dos axiomas han sido enunciados para el caso que el rango sea exactamente T rue, pero para el caso de la distributividad con el podemos demostrar
que vale en general para cualquier rango, es decir:
Teorema 5.5
X hx : r.x : f.xi hx : r.x : X f.xi, donde x no ocurre en X
X hx : r.x : f.x)
{ Intercambio entre rango y termino }
X hx : : r.x f.x)
{ Caracterizaci
on de : p q p q aplicado al termino }
X hx : : r.x f.x)
{ Distributividad de con (x no ocurre en X) }
hx : : X r.x f.x)
{ Conmutatividad de , Caracterizaci
on de }
hx : : r.x X f.x)
{ Intercambio entre rango y termino }
hx : r.x : X f.x)
El teorema que sigue formaliza la idea de que cuantificar universalmente sobre una uni
on de elementos es equivamente a cuantificar sobre cada uno de los
conjuntos (no importa si no son disjuntos).
Teorema 5.6
Partici
on de rango.
hx : r.x : f.x) hx : s.x : f.x) hx : r.x s.x : f.x)
hx : r.x : f.x) hx : s.x : f.x)
{ Intercambio entre rango y termino y Caracterizacion , dos veces }
hx : : r.x f.x) hx : : s.x f.x)
{ Distributividad de con }
hx : : (r.x f.x) (s.x f.xi
77
{ Distributividad de con }
1
CAPITULO 5. CALCULO
DE PREDICADOS
78
{ Absorbente del }
hx : T rue x = Y : f.xi
{ Partici
on de rango }
79
{ Caracterizaci
on , Intercambio entre rango y termino en x }
hx : : hy : x = y : r.y f.xii
{ Rango unitario (del y, obvio con el otro no se puede) }
hx : : r.x f.xi
{ Caracterizaci
on , Intercambio entre rango y termino en x }
hx : r.x : f.xi
Aplicado a nuestro primer ejemplo, afirma que es exactamente lo mismo decir
Para todos los n enteros, 2 n es par que decir Para todos los x enteros, 2 x es
par, y asimismo reemplazando x por cualquier otra variable. Por esa razon, a las
variables de cuantificaci
on se las denomina variables bobas, porque lo u
nico que
hacen es indicar que se cuantifica, pero (por ejemplo) no pueden ser reemplazadas
por un valor. No tiene sentido decir
h10 : enteros.10 : par.10i
que se obtiene reemplazando n por 10 en 5.1 (Para todo 10 ya suena bastante
ridculo). Otro ejemplo de variable boba es el dado por las variables de derivacion:
para decir integral de f , uno escribe
Z
Z
f (x)dx
f (y)dy
y es lo mismo, pero no tiene sentido decir
Z
f (5)d5.
CAPITULO 5. CALCULO
DE PREDICADOS
80
donde rango y termino son predicados los cuales toman como argumento a n.
Daremos s
olo un axioma para el cuantficador existencial el cual lo relaciona
con el cuantificador universal.
Axioma 5.12
hx : r.x : f.xi hx : r.x : f.xi
Teorema 5.13
hx : : f.xi hx : T rue : f.xi
Uno de los axiomas m
as importantes es el que da significado al rango, el cual
llamaremos Intercambio entre rango y termino:
Teorema 5.14
hx : r.x : f.xi hx : : r.x f.xi
Usando el ejemplo de m
as arriba, este axioma nos dice que es lo mismo escribir
Para todos los n enteros, 2n es par que Para todos los n, si n es entero entonces
2 n es par.
Dado que el cuantificador universal es una generalizacion de la conjuncion,
algunas propiedades de esta pasan al primero. Por ejemplo, la Distributividad de
con :
Teorema 5.15
X hx : : f.xi hx : : X f.xi, siempre que x no ocurra en X.
y la Distributividad con con (o bien Regla del Termino):
Teorema 5.16
hx : : f.xi hx : : g.xi hx : : f.x g.xi
Estos dos axiomas han sido enunciados para el caso que el rango sea exactamente T rue, pero para el caso de la distributividad con el podemos demostrar
que vale en general para cualquier rango, es decir:
Teorema 5.17
X hx : r.x : f.xi hx : r.x : X f.xi, donde x no ocurre en X
X hx : r.x : f.x)
{ Intercambio entre rango y termino }
X hx : : r.x f.x)
{ Caracterizaci
on de : p q p q aplicado al termino }
X hx : : r.x f.x)
{ Distributividad de con (x no ocurre en X) }
hx : : X r.x f.x)
81
{ Conmutatividad de , Caracterizacion de }
hx : : r.x X f.x)
{ Intercambio entre rango y termino }
hx : r.x : X f.x)
El teorema que sigue formaliza la idea de que cuantificar universalmente sobre una uni
on de elementos es equivamente a cuantificar sobre cada uno de los
conjuntos (no importa si no son disjuntos).
Teorema 5.18
Partici
on de rango.
hx : r.x : f.x) hx : s.x : f.x) hx : r.x s.x : f.x)
hx : r.x : f.x) hx : s.x : f.x)
{ Intercambio entre rango y termino y Caracterizacion , dos veces }
hx : : r.x f.x) hx : : s.x f.x)
{ Distributividad de con }
hx : : (r.x f.x) (s.x f.xi
{ Distributividad de con }
hx : : (r.x s.x) f.xi
{ de Morgan }
hx : : (r.x s.x) f.xi
{ Caracterizaci
on e Intercambio entre rango y termino }
hx : r.x s.x : f.xi
Aplicando este teorema a nuestro ejemplo (5.1), podemos tomar r.n igual a n
es un entero positivo o cero, s.n igual a n es un entero negativo y obtenemos
la equivalencia entre
Para todos los n enteros, 2 n es par.
y
Para todos los n enteros positivos o cero 2 n es par y para todos los
n enteros negativos 2 n es par
Esto funciona ya que decir r.n s.n (n es un entero positivo o cero o n es un
entero negativo) es una forma de decir n es un entero.
El axioma de Rango unitario dice que si hay un u
nico x posible, digamos X,
decir que algo vale para todos los x equivale a decir que vale para ese ejemplo:
CAPITULO 5. CALCULO
DE PREDICADOS
82
Teorema 5.19
hx : x = Y : f.xi f.Y
CAPITULO 5. CALCULO
DE PREDICADOS
84
5.5 APLICACIONES DEL CALCULO
DE PREDICADOS
85
letras proposicionales para representar proposiciones atomicas, sino que analizaremos la estructura de estas proposiciones usando predicados y cuantificadores los
cuales permiten expresar relaciones que exceden al calculo proposicional.
Tomemos primero un ejemplo que puebla casi todos los libros de logica clasica.
Todos los hombres son mortales.
Socrates es hombre
Socrates es mortal
Para modelar este razonamiento es necesario introducir predicados que describen las categoras necesarias as tambien como una constante (para representar al
individuo Socrates).
H.x: x es hombre.
M.x: x es mortal.
s: Socrates.
El razonamiento puede codifcarse entonces como sigue:
h x : : H.x M.x i
H.s
M.s
Ahora podemos traducir este razonamiento a la implicacion correspondiente
(recordemos que tenemos que ver que no se da el caso de que las premisas puedan
ser verdaderas y la conclusi
on falsa. Luego demostramos que esa implicacion es un
teorema (del c
alculo de predicados).
h x : : H.x M.x i H.s M.s
{ instanciaci
on }
h x : : H.x M.x i (H.s M.s) H.s M.s
{ modus ponens }
h x : : H.x M.x i H.s M.s M.s
{ debilitamiento }
T rue
Un tipo de razonamientos que tuvo gran popularidad y fue considerado el
paradigma de los razonamientos v
alidos es el de los silogismos. Estos son ejemplos
de razonamientos correctos a los cuales Aristoteles pesaba que se podan recudcir
todos. Si bien se sabe que no es as, estos constituyen un ejemplo interesante para
trabajar nuestros metodos. Mostraremos que esencialmente todas las formas de
silogismos correctos (diesiseis) se reducen a variantes menores de dos formas, las
cuales demostraremos correctas.
La primera forma a considerar es la que tiene dos premisas universales y conclusi
on tambien universal. El siguiente razonamiento es un ejemplo de esta:
CAPITULO 5. CALCULO
DE PREDICADOS
86
Las ara
nas son mamferos.
Los mamferos tienen seis patas.
Las ara
nas tienen seis patas.
La forma de este silogismo puede esquematizarse como sigue:
h x : : a.x m.x i
h x : : m.x s.x i
h x : : a.x s.x i
Demostraremos ahora la implicaci
on asociada a este razonamiento. Para ello
partiremos de la conjunci
on de las premisas y llegaremos a la conclusion.
h x : : a.x m.x i h x : : m.x s.x i
{ regla del termino }
h x : : (a.x m.x) (m.x s.x) i
{ transitividad (usando la monotona del y del }
h x : : a.x s.x i
Consideremos el ejemplo que abre esta seccion
Las vacas son mamferos.
Hay animales que no son mamferos.
Hay animales que no son vacas.
El cual puede esquematizarse como sigue:
h x : : v.x m.x i
h x : : a.x m.x i
h x : : a.x v.x i
La demostrac
on de correcci
on la dejamos como ejercicio para el lector (sugerimos distribuir la conjunci
on con el existencial y luego aplicar la instanciacion
adecuada y la contrarecproca).
5.7 DIOS Y LA LOGICA
87
C
omo puede determinarse si una conclusi
on es consecuencia de un conjunto
de premisas, y de ser as c
omo puede demostrarse que lo es?
Para el caso de la l
ogica proposicional, esta pregunta puede resolverse con
relativa facilidad. Se construye la tabla de verdad para la formula asociada el
razonamiento pertinente y puede afirmarse usando el teorema de completitud
que es una tautologa si y s
olo si la conclusion es consecuencia de las premisas.
Para el caso de la l
ogica de predicados en cambio no existe ning
un metodo
mec
anico para decidir si una conclusion puede deducirse de un conjunto de
premisas. La teora de la computaci
on o computabilidad demuestra que un
tal algoritmo no puede existir.
Que caractersticas de las estrucuturas del mundo y del lenguaje y de las
relaciones entre palabras, cosas y pensamientos hacen posible el razonamiento
deductivo?
Esta pregunta no est
a a
un resuelta de manera satisfactoria y existen numerosas teoras que proponen posibles respuestas. Los ejemplos que hemos
considerado en este libro sugieren que la relacion entre lenguaje y mundo no
es arbitraria en su totalidad y que cierta estructura del lenguaje refleja cierta
estructura del mundo. Las constantes de nuestra logica puede pensarse que
denotan objetos, los predicados relaciones o propiedades. Sin embargo como
se establece esta relaci
on de denotacion es a
un un misterio.
5.7 Dios y la l
ogica
En la historia de la filosofa se registra una cantidad considerable de intentos
de demostraciones de la existencia de Dios. Si bien hoy son consideradas por los
l
ogicos como meras falacias, algunas de ellas a
un son ense
nadas en las escuelas
religiosas. Una de estas demostraciones tiene a
un cierto interes desde el punto
de vista de la l
ogica, pese a haber sido quiza el argumento mas veces refutado en
la historia. Es el llamado Argumento Ontol
ogico de San Anselmo de Canterbury
(1033-1109). La primera refutaci
on fue realizada por un monje llamado Gaunilo
quien fue contemporaneo con San Anselmo (aunque no canonizado).
La demostraci
on es presentada de varias formas. En los siguientes dos parrafos,
hay dos demostraciones diferentes;
Y entonces, O Se
nor, dado que has dado entendimiento a la fe, dame
el entendimento - siempre que tu sepas que es bueno para mi - de que
tu existes, tal como nosotros creemos, y que tu eres lo que nosotros
creemos que eres. Creemos que eres un ser del cual nada mayor puede
ser pensado. O podra ser que no haya tal ser, dado que el insensato ha
dicho en su coraz
on No hay Dios (Psalmo 14.1; 53:1). Pero cuando
el mismo insensato oye lo que digo - Un ser del cual nada mayor
88
CAPITULO 5. CALCULO
DE PREDICADOS
puede ser pensado el entiende lo que escucha, y lo que entiende esta
en su entendimiento a
un si no entiende que esto exista. Porque una
cosa es que un objeto este en el entendimiento y otra cosa entender
que este exista. Cuando un pintor considera de antemano lo que va a
pintar ya lo tiene en su entendimiento, pero el no supone que lo que
a
un no ha pintado ya existe. Pero una vez que lo ha pintado ambas
cosas ocurren: est
a en su entendimiento y tambien entiende que lo que
ha producido existe. A
un el insensato, entonces, debe estar convencido
de que un ser del cual nada mayor puede ser pensado existe al menos
en su entendimiento, dado que cuando oye esto lo entiende y aquello
que se entiende est
a en el entendimiento. Sin embargo es claro que
aquello de lo cual nada mayor puede ser pensado no puede existir solo
en el entendimiento. Porque si realmente esta solo en el entendimiento,
puede ser pensado que existe en realidad y esto sera a
un mayor. Por
lo tanto, si aquello de lo cual nada mayor puede ser pensado esta solo
en el entendimiento, esa misma cosa de la cual nada mayor puede ser
pensado es una cosa de la cual algo mayor puede ser pensado. Pero
obviamente esto es imposible. Sin ninguna duda, por lo tanto, existe
tanto en el entendimiento como en la realidad, algo de lo cual nada
mayor puede ser pensado.
Dios no puede ser pensado como inexistente. Y ciertamente el existe
de manera tan verdadera que no puede ser pensado como inexistente.
Dado que puede ser pensado algo que existe lo cual no puede ser pensado como inexistente, y esto es mayor que aquello que puede ser pensado
como no existente. Entonces si aquello de lo cual nada mayor puede ser
pensado, puede ser pensado como inexistente, esa misma cosa de la cual
nada mayor puede ser pensado no es algo de lo cual nada mayor pueda
ser pensado. Pero esto es contradictorio. Luego, hay verdaderamente
un ser del cual nada mayor puede ser pensado - luego ciertamente no
puede ni siquiera pensarse que no exista.
5.7 DIOS Y LA LOGICA
89
La conclusi
on sacada de la primer premisa necesita una suposicion adicional
de que es efectivamente posible pensar un ser el cual no puede ser pensado como
inexistente.
El argumento enunciado en el primer parrafo puede ser parafraseado como
sigue:
Premisa 1: Podemos concebir un ser del cual nada mayor puede ser concebido.
Premisa 2: Aquello que es concebido esta en el entendimiento de quien lo concibe.
Premisa 3: Aquello que existe en el entendimiento de alguien y tambien en la
realidad es mayor que algo que s
olo existe en el entendimiento.
Por lo tanto Un ser concebido tal que ninguno mayor puede ser pensado debe
existir tanto en la realidad como en el entendimiento.
Premisa 4: Dios es un ser del cual nada mayor puede ser pensado.
Conclusi
on: Dios existe en la realidad.
Quinientos a
nos despues, una versi
on del mismo argumento fue propuesta por
Descartes. Puede resumirse la esencia de esta nueva version y de algunas de las
anteriores en lo siguiente. Descartes define a dios como un ser que tiene todas
las propiedades (al menos las propiedades buenas). Luego, tiene entre ellas la
propiedad de la existencia. Luego, dios existe.
Las objeciones a estos argumentos son variadas. Basicamente la de Gaunilo
y posteriormente de Kant se basan en la idea de que la existencia no es una
propiedad. Otra objeci
on que puede hacerse al argumento de San Anselmo (que
Descartes se esmera en rechazar en la Meditaciones Metafsicas) es que en ning
un
lado se prueba la unicidad de Dios, y puede claramente haber mas de un ser con
esas propiedades. Siguiendo esta lnea de argumentacion puede tambien probarse
la existencia de otras cosas, por ejemplo de una isla perfecta (muchos pueden
imaginarse una isla de la cual ninguna mejor pueda ser pensada).
Vamos a presentar ahora una demostracion de que existe un unicornio la cual se
basa en la misma idea y ver una de las objeciones mas contundentes al argumento
ontol
ogico hecha por Raymond Smullyan en [Smu78].
En lugar de demostrar que existe un unicornio, vamos a demostrar la proposici
on posiblemente m
as fuerte de que existe un unicornio existente (la cual obviamente implica que existe un unicornio). Por la ley del tercero excludo, tenemos
solamente dos posibilidades:
1. Un unicornio existente existe.
2. Un unicornio existente no existe.
CAPITULO 5. CALCULO
DE PREDICADOS
90
La segunda posibilidad es obviamente contradictoria, dado que ningun ser existente puede no existir. De la misma manera que un unicornio azul tiene que ser
necesariamente azul (aunque se haya perdido), un unicornio existente necesariamente tiene que existir. Luego, la primera proposicion es verdadera.
La objeci
on de Kant es aplicable a esta demostracion, pero tambien puede verse
una confusi
on m
as elemental en el uso de la palabra un. En algunos contextos
un significa todos y en otros significa al menos uno. Por ejemplo, en un gato
es un felino estamos diciendo que cualquier gato es un felino, mientras que en un
gato se comi
o el pescado nos estamos refiriendo a un gato en particular, el cual
existe y adem
as se comi
o nuestra cena. En la demostracion de la existencia de un
unicornio, estamos confundiendo ambos usos de la palabra un. En la demostracion
usamos un en el primer sentido. En este caso la conclusion es verdadera, dado
que obviamente todo unicornio existente existe, pero la confusion viene de leer la
conlusi
on usando la palabra un en el segundo sentido. Si interpretaramos as a
la palabra un la demostraci
on no sera correcta, dado que en ese caso la primera
proposici
on sera falsa (como por ejemplo decir un unicornio azul se me perdio)
y la segunda verdadera (no existe ningun unicornio, existente o no). Esta misma
objeci
on puede aplicarse al argumento ontol
ogico de San Anselmo y Descartes. Lo
u
nico que est
an demostrando es que todo dios que satisficiera las propiedades de
la definici
on de Descartes obviamente existira.
Para finalizar, presentamos una objeci
on de Borges en un cuento llamado
sugerentemente Argumentum Ornithologicum.
Cierro los ojos y veo una bandada de p
ajaros. La vision dura un segundo
o acaso menos; no se cuantos p
ajaros vi. Era definido o indefinido su
n
umero? El problema involucra es de la existencia de Dios. Si Dios
existe, el n
umero es definido, porque Dios sabe cuantos pajaros vi. Si
Dios no existe, el n
umero es indefinido, porque nadie pudo llevar la
cuenta. En tal caso, vi menos de diez p
ajaros (digamos) y mas de uno,
pero no vi nueve, ocho, siete, seis, cinco, cuatro, tres o dos pajaros, Vi
un n
umero entre diez y uno que no es nueve, ocho, siete, seis, cinco,
etcetera. Ese n
umero entero es inconcebible; ergo, Dios existe.
5.8 Ejercicios
Ejercicio 5.1
1. h x : r.x : p.x i h x : : r.x i.
2. h x : : r.x i h x : r.x : p.x i.
3. h x : : p.x i (x :: q.x) h x : : p.x q.x i
4. h x : p.x : q.x i h x : q.x : r.x i (x : q.x : p.x r.x)
5.8 EJERCICIOS
91
92
CAPITULO 5. CALCULO
DE PREDICADOS
7. Probar que el siguiente razonamiento es valido: Todos los polticos son
corruptos y mentirosos. Existen polticos in
utiles. Luego, existen corruptos
in
utiles.
8. Analizar los siguientes razonamientos, traduciendo cada paso a notacion logica, y descubrir el paso en el cual fallan, pero destacando aquellos pasos que
est
an bien.
a) Ning
un matem
atico ha logrado cuadrar el crculo. Luego, nadie que
haya cuadrado el crculo es matem
atico. Por lo tanto, todos los que han
cuadrado el crculo son no-matem
aticos. Entonces, ciertamente, algunos
de los que han cuadrado el circulo son no-matematicos. Luego, alg
un
no-matem
atico ha cuadrado el crculo.
b) Es verdad que ning
un unicornio esta en mi casa. Luego, es falso que
todos los unicornios esten en mi casa. Por lo tanto, es verdad que algunos
unicornios no est
an en mi casa. Con lo que concluimos que existe alg
un
unicornio.
Ejercicio 5.3
Demostrar la siguiente versi
on generalizada del metateorema del testigo.
Si k 6 (F V.P F V.Q F V.R) entonces h i : R : P i Q si y solo si P (i :=
k) Q es un teorema.
Captulo 6
Expresiones cuantificadas
CHEREA: . . . Jai le go
ut et la besoin de la securite. La plupart
des hommes sont comme moi. Ils sont incapables de vivre dans un
univers o`
u la pensee la plus bizarre peut en une seconde entrer dans la
realite. . .
CALIGULA: La securite et la logique ne vont pas ensemble
Albert Camus:Caligula
Una notaci
on muy u
til usada en matematica es la que nos permite aplicar
operaciones una secuencia de expresiones las cuales dependen de alguna variable.
Ejemplos paradigm
aticos de esta notaci
on son la sumatoria y la productoria, as
tambien como la definici
on de conjuntos por comprension o las cuantificaciones en
l
ogica las cuales fueron analizadas en el captulo precedente.
Por ejemplo, es usual escribir expresiones como
n1
X
2i+1
i=0
94
forma
1 + 3 + + 2 (n 1) + 2 n
N
otese sin embargo la ventaja de usar la sumatoria respecto de la expresion con
los puntos suspensivos, dado que esta u
ltima no estara bien definida si por ejemplo
n es 0 o 1. Usualmente en matem
atica se asume que el lector puede discernir estos
casos sin inconvenientes. Sin embargo estas ambig
uedades son mas perniciosas en
el desarrollo formal de programas dado que las expresiones son mas complejas y
es por lo tanto importante tener m
as cuidado con los casos lmite. Por otro lado,
como se ver
a en este captulo, pueden proverse reglas explcitas para el manejo de
expresiones del estilo de la sumatoria, las cuales nos aseguran la correccion de las
operaciones realizadas con ellas y, m
as importante a
un, nos ayudaran a encontrar
programas a partir de especificaciones escritas usando estas expresiones. Por otro
lado, vamos a generalizar este mecanismo de definicion de expresiones a cualquier
operador binario asociativo y conmutativo. Esto permite que las reglas provistas
se apliquen a un conjunto grande de expresiones, las cuales seran suficientes para
especificar casi todos los problemas presentados en este libro.
Lo esencial de este mecanismo para nuestros fines es que provee reglas para
realizar c
alculos de manera suficientemente simple. Sumado esto a que la mayor
parte de las reglas son generales para cualquier operador binario (por supuesto
que tambien hay algunas reglas especficas), hace que el calculo presentado en este
libro pueda aspirar a ser un metodo eficiente para el desarrollo de programas. Los
lectores podr
an juzgar por si mismos acerca de la validez de esta afirmacion. Diferentes versiones de c
alculos que usan expresiones cuantificadas pueden encontrarse
en [GS93, DF88, DS90, Kal90, Coh90].
6.1 Introducci
on
En diversos contextos -aritmetica, l
ogica, teora de conjuntos, lenguajes de
programaci
on, etc.- aparece cierta noci
on de cuantificacion, entendiendos por esto
al uso de variables formales con un alcance delimitado explcitamente las cuales
pueden usarse para construir expresiones dependientes de estas pero solo dentro
de ese alcance.
Se propondr
a una notaci
on unificada para estas expresiones. Esta notacion
debe tener en cuenta al operador con el cual se cuantifica (en nuestro ejemplo la
suma), las variables que van a usarse para crear las expresiones (i en el ejemplo),
el rango de variaci
on de estas variables (0 i < n) y la expresion dependiente
de las variables que define los terminos de la cuantificacion (en nuestro ejemplo
2 i + 1).
Una expresi
on cuantificada ser
a entonces de la siguiente forma:
h i : R : T i ,
6.1 INTRODUCCION
95
96
DE LA SUSTITUCION
Y LA REGLA DE LEIBNIZ
6.2 REVISION
97
Ejemplo 6.1
Consideremos la expresi
on
P
E =ik+h i :0i<n: 2i+1i
luego, F V.E = {i, k, n} y BV.E = {i}.
6.2 Revisi
on de la sustituci
on y la regla de Leibniz
Las variables ligadas tienen su alcance delimitado de manera explcita y ligadas
a una variable de cuantificaci
on. Si se cambian ambas por un nombre fresco (que
no aparezca dentro del alcance), el significado de la expresion no cambiara, como
lo ejemplifica la siguiente igualdad:
P
P
h i :0i<n: 2i+1i=h j :0j <n: 2j+1i
Debe tenerse cuidado sin embargo con las colisiones de nombres, dado que si
por ejemplo se reemplaza a i por n nos da una expresion la cual es obviamente
diferente de las anteriores (en particular sera siempre igual a 0, sin importar el
valor de n en el estado).
P
h n :0n<n: 2n+1i
para extender la sustituci
on a expresiones cuantificadas a traves del siguiente
axioma:
Axioma 6.1 (Sustituci
on para expresiones cuantificadas)
V.y (V.x F V.E) =
h y : R : T i (x := E) = h y : R(x := E) : T (x := E) i
La condici
on sobre las variables es necesaria para evitar las colisiones de nombres. Si la condici
on no se cumple, es necesario renombrar la variable de cuantificaci
on. Esto se ver
a en la secci
on siguiente, axioma 6.10.
Regla de Leibniz
El objetivo de la regla de Leibniz es permitir el reemplazo de iguales por iguales.
Sin embargo, con su formulaci
on actual, esto no siempre es posible cuando aparecen expresiones cuantificadas. Por ejemplo, es esperable que aplicando la regla de
Leibniz pueda deducirse que
P
P
h i : 0 i < n : 2 i + 1 i = h i : 0 i < n : 2 (i + 1) 1 i
98
X=Y
E(x := X) = E(x := Y )
100
entonces:
h i : R : x T i = x h i : R : T i
An
alogamente, si es distributivo a derecha con respecto a y se cumple al
menos una de las condiciones anteriores, entonces:
h i : R : T x i = h i : R : T i x
Axioma 6.9 (Regla de anidado)
Cuando hay m
as de una variable cuantificada y el rango de especificacion es
una conjunci
on de predicados, uno de los cuales es independiente de alguna de
las variables de cuantificaci
on, la expresi
on cuantificada puede reescribirse de la
siguiente manera:
h i, j : R.i S.i.j : T.i.j i = h i : R.i : h j : S.i.j : T.i.j i i
Axioma 6.10 (Regla de cambio de variable)
Si V.j (F V.R F V.T ) = pueden renombrarse las variables
h i : R : T i = h j : R(i := j) : T (i := j) i
Puede tambien escribirse usando una referencia explcita a i
h i : R.i : T.i i = h j : R.j : T.j i
Todas estas reglas pueden particularizarse, refiriendose a operadores concretos.
Es lo que haremos en adelante, con los operadores mas usuales.
Teorema 6.11 (Regla de cambio de variable)
Si f es una funci
on que tenga inversa (sea biyectiva) en el rango de especificaci
on y j es una variable que no aparece en R ni en T , las variables cuantificadas
pueden renombrarse como sigue:
h i : R.i : T.i i = h j : R.(f.j) : T.(f.j) i
La inversa en el rango considerado se denotara con f 1 . La propiedad de ser
inversa puede escribirse como
Comenzamos la demostraci
on con la expresion mas complicada
h j : R.(f.j) : T.(f.j) i
= { Rango unitario (introducci
on de la cuantificacion sobre i) }
h j : R.(f.j) : h i : i = f.j : T.i i i
6.4 CUANTIFICADORES ARITMETICOS
101
= { Anidado }
h i, j : R.(f.j) i = f.j : T.i i
= { Leibniz }
h i, j : R.i i = f.j : T.i i
= { Anidado }
h i : R.i : h j : i = f.j : T.i i i
= { Inversa }
i : R.i : j : j = f 1 : T.i
= { Rango unitario, j 6 F V.T }
h i : R.i : T.i i
Teorema 6.12 (Separaci
on de un t
ermino)
h i : 0 i < n : T.i i = T.0 h i : 0 i < n : T.(i + 1) i
Teorema 6.13 (Separaci
on de un t
ermino)
h i : 0 i < n : T.i i = h i : 0 i < n : T.i i T.n
102
M
aximo y mnimo
Otros operadores aritmeticos que resultan de gran utilidad para especificar
programas son Max y Min (ver la definici
on en la seccion 1.6, ejercicio 1.7).
Pueden tomarse las siguientes propiedades como definiciones de las versiones
cuantificadas del m
aximo y del mnimo:
z = hMax i : R.i : F.i i h i : R.i : z = F.i i h i : R.i : F.i z i
z = hMin i : R.i : F.i i h i : R.i : z = F.i i h i : R.i : z F.i i
Una consecuencia de estas propiedades es la siguiente:
F.x = hMax i : R.i : F.i i R.x h i : R.i : F.i F.x i
F.x = hMin i : R.i : F.i i R.x h i : R.i : F.x F.i i
Ninguno de los dos operadores tiene un neutro en los enteros. Por conveniencia,
extenderemos los enteros con dos constantes que denotaremos con y , las
cuales ser
an, por definici
on, neutros para el mnimo y el maximo respectivamente.
Las operaciones aritmeticas usuales no estar
an definidas para estas constantes. En
103
determinados casos es posible elegir otros elementos neutros. Por ejemplo, cuando
se usa el operador de m
aximo para n
umeros naturales es posible tomar al 0 como
neutro.
Se deja como ejercicio para el lector el enunciado de todas las reglas para la
cuantificaci
on de los operadores Max y Min.
Operador de conteo
Hasta aqu hemos mencionado u
nicamente cuantificadores que provienen de
un operador conmutativo y asociativo. Pero tambien es posible definir nuevos
104
6.6 Ejercicios
Ejercicio 6.3
Sea un cuantificador asociado a un operador conmutativo y asociativo. Probar
la siguiente regla de eliminaci
on de una dummy (Z no depende de i ni de j):
h i, j : i = Z R.i.j : T.i.j i h j : R.Z.j : T.Z.j i
Ejercicio 6.4
Demostrar:
h x, y : x = y : P.x.y i h x : : P.x.x i
Ejercicio 6.5
Probar que la implicaci
on es distributiva con respecto al cuantificador universal:
h i : R.i : Z T.i i Z h i : R.i : T.i i
Ejercicio 6.6
Existe otra notaci
on muy usual para la cuantificacion universal y existencial que
suprime el rango de cuantificaci
on de forma explcita:
6.6 EJERCICIOS
105
Cuantificador universal
(i . P )
Cuantificador existencial (i . P )
Su equivalencia con la notaci
on que ya conocemos puede ser expresada (gracias
a las reglas de intercambio) por las siguientes equivalencias:
(i . P )
hi : : P i
(i . P )
hi : : P i
h i : R : T i (i . R T )
h i : R : T i (i . R T )
Demostrar
(i . P ) (i . P )
y que en nuestra notaci
on en general no se cumple
hi : R : T i hi : R : T i .
Ejercicio 6.7
Demostrar la siguiente relaci
on entre el m
aximo y el mnimo:
hMin i : R.i : F.i i = hMax i : R.i : F.i i
Ejercicio 6.8
El cuantificador aritmetico N no est
a definido en base a un operador subyacente
sino a traves de la cuantificaci
on de la suma:
. P
hN i : R.i : T.i i = h i : R.i T.i : 1 i
1. Enunciar y demostrar la regla de particion de rango para N .
2. Idem con la regla del rango vaco.
P
3. Probar: h i : R.i T.i : k i = k hN i : R.i : T.i i
Ejercicio 6.9
[Kal90] Suponiendo que:
P
(i) x = h i : R.i : f.i i
(ii) R.i 6 i = N para cualquier i
calcular una expresi
on libre de cuantificadores que sea equivalente a
P
h i : R.i i = N : f.i i
Ejercicio 6.10
[Kal90] Suponiendo que:
106
Captulo 7
El formalismo b
asico
41. Nada se edifica sobre la piedra, todo
sobre la arena, pero nuestro deber es edificar
como si fuera piedra la arena.
Jorge Luis Borges:
Fragmentos de un evangelio ap
ocrifo
En este captulo definiremos una notacion simple y abstracta que nos permitir
a escribir y manipular programas. Esta notacion, que llamaremos el formalismo
b
asico, se basa en la programaci
on funcional (ver por ej. [Bir98, Tho96]), y puede
pensarse como que representa la esencia de esta. Al mismo tiempo, esta notacion
es mucho m
as simple que la mayora de los lenguajes de programacion y es suficientemente rica para expresar de manera sencilla programas funcionales. Por
otro lado, las reglas que nos permiten manipularlas son explcitas y mantienen el
estilo del c
alculo de predicados y de las expresiones cuantificadas, lo cual permite
integrarlas arm
onicamente en el proceso de construccion de programas.
Varias de estas ideas est
an inspiradas en la tesis de doctorado [Hoo89].
7.1 Funciones
Las funciones ser
an uno de los conceptos esenciales en los cuales se basa el
formalismo b
asico. Como ya indicamos en el captulo 1, la notacion usual para la
aplicaci
on de funciones en matem
atica, f (x) no sera adecuada, por lo cual usaremos
un operador explcito para la aplicaci
on de funciones, el cual escribiremos como
un punto.
107
CAPITULO 7. EL FORMALISMO BASICO
108
En matem
atica es usual hablar de la funci
on f.x tal que . . . , para referirse a la
funci
on f (en cuya definici
on se usa probablemente la variable x). En matematica
esto no suele traer problemas dado que las funciones son raramente usadas como
valores ellas mismas, pero en nuestro caso debemos distinguir claramente entre la
funci
on f y la aplicaci
on de esta al valor x escrito como f.x.
La regla b
asica para la aplicaci
on de funciones es la regla de sustitucion de
iguales por iguales, que llamamos regla de Leibniz, la cual ya fue presentada en
el captulo 1. Usando expresiones cuantificadas podemos expresar esta regla como
sigue.
h f, x, y : : x = y f.x = f.y i
El operador de aplicaci
on de funciones tiene la maxima precedencia, es decir que
para cualquier otro operador vale
f.x y = (f.x) y
El valor de f.x puede ser a su vez otra funcion, la cual puede ser aplicada a
otro valor, por ejemplo, (f.x).y. Supondremos que el operador de aplicacion asocia
a izquierda, esto es
f.x.y = (f.x).y
y para todos los fines puede pensarse a una tal f como una funcion de dos argumentos.
Veamos ahora un ejemplo de aplicaci
on de la regla de Leibniz.
Ejemplo 7.1
Supongamos que existe una funci
on f : N at 7 N at con la siguiente propiedad:
p primo x, y N at,
f.p = 1
f.(x y) = f.x + f.y
p racional
{ definici
on de racional }
D
E
x, y : : p = xy
109
{a
lgebra }
x, y : : p y 2 = x2
{ regla de Leibniz }
x, y : : f.(p y 2 ) = f.x2
{ propiedad de f }
h x, y : : f.p + f.y + f.y = f.x + f.x i
{
algebra, f.p = 1 }
h x, y : : 1 + 2 f.y = 2 f.x i
{ n
umeros pares e impares son diferentes }
F alse
Por lo tanto,
p es irracional.
CAPITULO 7. EL FORMALISMO BASICO
110
booleanas:
F alse, T rue, (3 = 2)
numericas:
de caracteres:
8, z, ,
f.x = E
donde las variables en x pueden ocurrir en E. Si la secuencia de variables x es vaca
.
(es decir si la definici
on es de la forma f = E) se dira que f es una constante. Si
f ocurre en E se dice que la definici
on es recursiva .
Es esencial notar aqu que usamos un signo ligeramente diferente al signo igual
para las definiciones. Esto nos permitir
a distinguir una definicion (las cuales seran
nuestros programas) de una propiedad. Las reglas de plegado/desplegado de la
secci
on 7.3 mostrar
an que el signo de definici
on y el signo igual estan ntimamente
relacionados.
Dado un conjunto de definiciones, es posible usar los nombres definidos para
formar expresiones. Por ejemplo:
.
Son definiciones: pi = 3.1416
.
cuadrado.x = x x
.
area.r = pi cuadrado.r
Son expresiones:
pi
pi cuadrado.(3 5)
area.15
7.3 REGLAS PARA EL CALCULO
CON DEFINICIONES
111
La reglas b
asicas para manejar expresiones en un contexto de definiciones dado
son las reglas de plegado y desplegado (en ingles, folding y unfolding). Estas
dos reglas son una la inversa de la otra.
.
Si se tiene la definici
on f.x = E, entonces para cualquier expresion A,
f.A = E(x := A)
donde la expresi
on E(x := A) denota a la expresion E en la que toda aparicion del
nombre x es reemplazado sint
acticamente por la expresion A. Si x es una secuencia
de variables, entonces A tambien debe serlo y debe tener la misma longitud. En
tal caso, la sustituci
on se realiza de manera simultanea. Por ejemplo:
(x + y)(x, y := cuadrado.y, 3) = cuadrado.y + 3
La regla de desplegado consiste en reemplazar f.A por E(x := A), mientras que
la de plegado consiste en reemplazar E(x := A) por f.A. En los calculos que
realizaremos, frecuentemente diremos s
olo definicion de f entendiendose si es
plegado o desplegado a partir del contexto.
Es importante no confundir una funcion con su definicion. Una funcion es
un valor abstracto, mientras que una definicion es una entidad sintactica. Es as
.
.
que las definiciones f.x = 2 x y g.x = x + x definen la misma funcion, por
lo cual es verdadero que f = g. La regla que nos permite mostrar esto es la de
extensionalidad (la cual no debe ser confundida con la regla de Leibniz).
h f, g : : h x : : f.x = g.x i f = g i
Como ejemplo consideremos la composicion de funciones (para la cual usaremos
el smbolo ), cuya definici
on es:
() : (B 7 C) 7 (A 7 B) 7 (A 7 C)
.
(f g).x =
f.(g.x)
N
otese que estamos usando notaci
on infija para el operador de composicion.
Usaremos la convenci
on de que dado un operador infijo la funcion de dos variables asociada se escribir
a con el operador entre parentesis. En este sentido vale la
igualdad ().f.g = f g y por lo tanto la definicion del operador de composicion
podra escribirse en la notaci
on introducida incialmente como sigue:
() : (B 7 C) 7 (A 7 B) 7 (A 7 C)
.
().f.g.x =
f.(g.x)
En esta definci
on es m
as claro que tanto f y g como x son solo parametros en
la definici
on de .
CAPITULO 7. EL FORMALISMO BASICO
112
raiz1.a.b.c =
(b sqrt.disc)/(2 a)
.
|[disc = b2 4 a c]|
En la definici
on de raiz1, que calcula la menor raz de la ecuacion ax2 + bx + c = 0,
se incluye la variable disc, la cual est
a localmente definida, es decir, disc solo tiene
sentido dentro de la definici
on de raiz1. En particular, en este caso la definicion
de disc hace referenecia a nombres (b, a, c) que solo tienen sentido dentro de la
definici
on de raiz1.
En caso de haber m
as de una definici
on local separaremos las mismas con
comas, dentro de los corchetes.
Las definiciones locales pueden servir para mejorar la legibilidad de un programa pero tambien para mejorar la eficiencia, como veremos mas adelante.
7.5 An
alisis por casos
Un mecanismo muy u
til para construir expresiones y por lo tanto para definir
funciones es el an
alisis por casos. Cuando se usa esta construccion, el valor de la
expresi
on puede depender de los valores de verdad de ciertas expresiones booleanas
que la componen. En general, una expresi
on E puede tomar la siguiente forma
7.5 ANALISIS
POR CASOS
113
E = ( B0 E0
B1 E1
..
.
Bn En
)
donde las Bi son expresiones boolenas y las Ei son expresiones del mismo tipo que
E.
Se entiende que el valor de E ser
a el valor de alguna Ei tal que Bi es cierta.
Esta construcci
on es indispensable en la definicion de algunas funciones, por
ejemplo:
.
max.a.b
( ab
ba
)
b
a
Las condiciones booleanas reciben el nombre de guardas o protecciones (preferimos conservar la palabra guarda usada como un neologismo, del ingles guard).
Esta expresi
on tomar
a valores de acuerdo al valor de a y b. Si bien las guardas no
son disjuntas, esto no significa que la funcion pueda comportarse de manera diferente en dos evaluaciones, sino que no es relevante para demostrar que el programa
satisface alguna especificaci
on dada, cu
al de las dos guardas se elige en el caso que
ambas sean verdaderas. Esto puede dar cierta libertad a la hora de implementar
un programa escrito en nuestro formalismo en un lenguaje de programacion.
Ejemplo 7.2
La funci
on factorial puede definirse por casos como sigue
f ac.n
( n=0
n=
6 0
)
1
n f ac.(n 1)
Regla para an
alisis por casos: Existe una regla que permite manipular expresiones que incluyen an
alisis por casos. Sea por ejemplo una expresion con dos
alternativas
E = ( B0 E0
B1 E1
)
y supongamos que queremos demostrar que E satisface la propiedad P , esto es
P.E. Para ello es suficiente con demostrar la conjuncion de las siguientes
B0 B1
CAPITULO 7. EL FORMALISMO BASICO
114
B0 P.E0
B1 P.E1
El primer punto requiere que al menos una de la guardas sea verdadera, mientras
que el segundo y el tercero nos piden que, suponiendo la guarda verdadera, podamos probar el caso correspondiente. Esto nos da un metodo de demostracion (y
por lo tanto de derivaci
on de programas) que sera explotado mas adelante.
Ejemplo 7.3
Para definir la regla de rango unitario para el cuantificador numerico N es necesario
introducir una funci
on n definida por casos:
n : Bool 7 N um
.
n.b =
(
b
b
)
1
0
7.7 TIPOS
115
f ac.0 = 1
.
f ac.(n + 1) = (n + 1) f ac.n
Es importante notar que el pattern sirve no solo para distinguir los casos sino
tambien para tener un nombre en el cuerpo de la definicion (en este caso n) el cual
refiera a la componente del pattern (en este caso el n
umero anterior).
Otros patterns posibles para los naturales podran ser por ejemplo 0, 1 y n + 2,
lo cual estara asociado a tres guardas, dos que consideran los casos en que el
argumento es 0
o 1 y uno para el caso en que el n
umero considerado es 2 o mas.
As una defininici
on de la forma
.
f.0 = E0
.
f.1 = E1
.
f.(n + 2) = E2
se traduce a an
alisis por casos como
f.n
( n=0
n=1
n2
)
E0
E1
E2 (n := n 2)
7.7 Tipos
Toda expresi
on tiene un tipo asociado. Hay tres tipos basicos, que son: N um,
que incluye todos los n
umeros; Bool, para los valores de verdad T rue y F alse; y
Char, para los caracteres. A toda expresi
on correcta se le puede asignar un tipo,
ya sea un tipo b
asico o un tipo compuesto, obtenido a partir de los tipos basicos.
Si a una expresi
on no se le puede asignar un tipo, la misma sera considerada
incorrecta.
Ejemplos:
5
h
cuadrado
es de tipo N um
es de tipo Char
es de tipo N um 7 N um
CAPITULO 7. EL FORMALISMO BASICO
116
7.8 Tipos b
asicos
Los tipos b
asicos de nuestra notaci
on de programas seran descriptos por las
expresiones can
onicas y las operaciones posibles entre elementos de ese tipo.
Tipo N um: Las expresiones can
onicas son las constantes (n
umeros). Las operaciones usadas para procesar los elementos de este tipo son: +, , , /, ,
con las propiedades usuales, y las funciones div y mod, que devuelven,
respectivamente, el cociente y el resto de la division entera de dos n
umeros
enteros.
Tipo Bool: Hay dos expresiones can
onicas para denotar los valores de verdad, que son T rue y F alse. Una funcion que retorna un valor de verdad
se denomina predicado. Los booleanos son importantes porque son el
resultado de los operadores de comparacion: =, 6=, >, <, , . Estos operadores se aplican no s
olo a n
umeros, sino tambien a otros tipos basicos
(Char, String, etc.), siempre y cuando los dos argumentos a comparar
tengan el mismo tipo. Es decir, cada operador de comparacion es una
funci
on polim
orfica de tipo A 7 A 7 Bool. Los booleanos se pueden
combinar usando los operadores l
ogicos , , , etc. con las propiedades
usuales.
Tipo Char: Constituido por todos los caracteres, que se denotan encerrados
entre comillas simples, por ejemplo: a, B, 7. Tambien incluye los caracteres de control no visibles, como el espacio en blanco, el return, etc..
Una secuencia de caracteres se denomina String y se denota encerrada
entre comillas dobles, por ejemplo: hola.
Ejercicio 7.2
Determinar las propiedades que tienen las funciones div y mod.
7.9 TUPLAS
117
7.9 Tuplas
Una manera de formar un nuevo tipo combinando los tipos basicos es tomar
estos de a pares. Por ejemplo: el tipo (N um, Char) consiste de todos los pares en
los que la primera componente es de tipo N um y la segunda de tipo Char. De la
misma manera, se pueden construir ternas, cuaternas, etc. En general, hablaremos
de tuplas. Los elementos can
onicos de una tupla son de la forma ( , , . . . , ), donde
cada una de las coordenadas es un elemento canonico del tipo correspondiente.
Ejemplo: podemos definir la funci
on raices, que devuelve las races de un polinomio
de segundo grado, de manera tal que el resultado sea un par, es decir,
raices : N um 7 N um 7 N um 7 (N um, N um) .
La noci
on de pattern matching puede extenderse al caso de tuplas de manera
natural. Por ejemplo, para definir una funcion f sobre ternas puede darse una
definici
on de la siguiente forma:
.
f.(x, y, z) = . . .
es m
as, hasta el momento es la u
nica manera de definir una funcion sobre tuplas.
Otra manera quiz
a menos elegante es tomar alg
un elemento de la tupla usando la
funci
on de indexaci
on que se define a continuacion.
Dada una n-upla, se supone definida la funcion
.i : (A0 . . . An ) 7 Ai
la cual satisface la propiedad
(a0 , . . . , an ).i = ai ,
0in .
Esta u
ltima ecuaci
on puede ser considerada su definicion (usando pattern matching).
Ejemplo 7.4
Los n
umeros racionales pueden ser representados por pares de numeros enteros.
La funci
on que suma dos racionales puede ser definida como:
SumRat : (N um, N um) 7 (N um, N um) 7 (N um, N um)
SumRat.(a, b).(c, d) = (a d + b c , b d)
7.10 Listas
Una lista (o secuencia) es una colecci
on de valores ordenados, los cuales deben
ser todos del mismo tipo. Las listas pueden ser finitas o infinitas (en este curso solo
consideraremos listas finitas). Cuando son finitas, se las denota entre corchetes, con
sus elementos separados por comas.
CAPITULO 7. EL FORMALISMO BASICO
118
Ejemplos: [0, 1, 2, 3]
7.10.1
Constructores de listas
lista vaca.
2.
7.10 LISTAS
119
En general, los programas funcionales usan solo los dos primeros constructores.
Los tipos de estos constructores son:
[]
: [A]
: A 7 [A] 7 [A]
Las operaciones sobre listas pueden definirse por pattern matching en estos dos
constructores, o equivalentemente dando su definicion para el caso vaco y no vaco
(considerado c
omo agregar un elemento por la izquierda).
Proposici
on 7.1
Sean x, y de tipo A y xs, ys de tipo [A]. Entonces
(x xs) = (y ys) x = y xs = ys.
7.10.2
Hay cinco operaciones fundamentales sobre listas, que son las siguientes:
concatenar :
+
+ : [A] 7 [A] 7 [A]
El operador +
+ toma dos listas del mismo tipo y devuelve una lista del
mismo tipo, que consiste en las dos anteriores, puestas una inmediatamente despues de la otra. Si xs e ys son listas del mismo tipo, la concatenacion
de ambas se denota xs ++ ys.
Ejemplos: [0, 1] ++ [2, 3] = [0, 1, 2, 3]
[0, 1, 2] ++ [ ] ++ [3] = [0, 1, 2, 3]
[0, 1] ++ [1, 2] = [0, 1, 1, 2]
longitud :
# : [A] 7 A
: [A] 7 N um 7 [A]
CAPITULO 7. EL FORMALISMO BASICO
120
: [A] 7 N um 7 [A]
tirar n :
indexar :
[0, 1, 2, 3].2 = 2
[4, 5, 6].0 = 4
[4, 5, 6].3 indefinido
7.10.3
A continuaci
on enumeramos algunas de las propiedades mas importantes que
poseen los operadores definidos en la secci
on anterior. Algunas propiedades usan
.
el smbolo de definici
on (=) en vez de la igualdad. Por la regla de fold/unfold,
estas definiciones son tambien igualdades. N
otese que todas las operaciones pueden
definirse por pattern matching sobre los constructores de listas.
concatenar
.
[ ] ++ ys = ys
.
(x xs) ++ ys = x (xs ++ ys)
(xs ++ ys) ++ zs = xs ++ (ys ++ zs)
(xs ++ ys).i =
)
(xs ++ ys) = [ ] xs = [ ] ys = [ ]
longitud
#[ ]
7.11 EJERCICIOS
121
.
#(xs ++ ys) =
#(xsn)
#(xsn)
#xs + #ys
= n min #xs
= (#xs n) max 0
tomar n
xs0
[]
[ ]n = [ ]
.
(x xs)(n + 1) = x (xsn)
tirar n
xs0
= xs
.
[ ]n = [ ]
.
(x xs)(n + 1) = xsn
indexar
(x xs).0
= x
.
(x xs).(n + 1) = xs.n
7.11 Ejercicios
Ejercicio 7.3
Definir la funci
on sgn : Int Int que dado un n
umero devuelve 1, 0 o 1 en caso
que el n
umero sea positivo, cero o negativo respectivamente.
Ejercicio 7.4
Definir una funci
on abs : Int Int que calcule el valor absoluto de un n
umero.
Ejercicio 7.5
Definir el predicado bisiesto : N at Bool que determina si un a
no es bisiesto,
Recordar que los a
nos bisiestos son aquellos que son divisibles por 4 pero no por
100, a menos que tambien lo sean por 400. Por ejemplo 1900 no es bisiseto pero
2000 s lo es.
Ejercicio 7.6
Definir los predicados equi e isoc que toman tres n
umeros los cuales representan
las longitudes de los lados de un tri
angulo y determinan respectivamente si dicho
tri
angulo es equil
atero o is
oceles.
CAPITULO 7. EL FORMALISMO BASICO
122
Ejercicio 7.7
Definir la funci
on edad : (N at, N at, N at) (N at, N at, N at) Int que dadas
dos fechas indica los a
nos transcurridos entre ellas. Por ejemplo
edad.(20, 10, 1968).(30, 4, 1987) = 18
Ejercicio 7.8
En un prisma rectangular, llamemos h a la altura, b al ancho y d a la profundidad.
Completar la siguiente definici
on del
area del prisma:
area.h.b.d =
donde frente, lado y arriba son las caras frontal, lateral y superior del prisma
respectivamente.
Ejercicio 7.9
Definir la funci
on raices, que devuelve las races de un polinomio de segundo grado.
Ejercicio 7.10
Suponer el siguiente juego: m jugadores en ronda comienzan a decir los n
umeros
naturales consecutivamente. Cuando toca un m
ultiplo de 7 o un n
umero con alg
un
dgito igual a 7, el jugador debe decir pip en lugar del n
umero. Se pide: encontrar
un predicado que sea T rue cuando el jugador debe decir pip y F alse en caso
contrario. Resolver el problema para 0 n 9999.
Ayuda: definir una funci
on unidad, que devuelva la cifra de las unidades de un
n
umero. Idem con las decenas, etc.; para ello usar las funciones div y mod.
Ejercicio 7.11
Reescribir la siguiente definici
on usando an
alisis por casos:
.
f.0 = 1
.
f.(n + 1) = f.n + 2 n + 1
Ejercicio 7.12
Reescribir la siguiente definici
on usando an
alisis por casos:
.
g.x.0 = 1
.
g.x.(2 n + 1) = x g.x.(2 n)
.
g.x.(2 n + 2) = g.(x x).(n + 1)
Ejercicio 7.13
Definir las siguientes funciones:
1. hd : [A] 7 A devuelve el primer elemento de una lista (hd es la abreviatura
de head).
7.11 EJERCICIOS
123
124
Captulo 8
Modelo computacional
8.1 Introducci
on
En el captulo anterior definimos una notacion abstracta para razonar sobre
programas llamada formalismo b
asico. Como se pudo ver, este lenguaje hace referencia a los mismos y sirve para escribirlos y manipularlos. Consecuentemente se
estableci
o una relaci
on entre lenguaje y programas pero tratando de abstraer algunas de sus caractersticas con la finalidad de simplificar la concepcion que tenemos
de ellos y poder as razonar con entidades mas simples de tipo matematico. Esto
facilita el proceso de desarrollo de programas a partir de especificaciones (como
se ver
a en captulos siguientes) abstrayendo nociones que podran perjudicar el
correcto desarrollo de esta labor.
Entre estas nociones est
an las que posibilitan una interpretacion de las expresiones como programas ejecutables. Este tipo de interpretacion es denominada
interpretaci
on operacional o modelo computacional asociado al formalismo y consiste en definir formalmente los pasos elementales de ejecucion de un programa
hasta llegar al resultado final. De esta forma se describe como los programas se
ejecutan, en vez de analizar simplemente el resultado de esta ejecucion.
La interpretaci
on operacional se utiliza mayormente como gua para implementar el lenguaje en la computadora (en la forma de compiladores e interpretes) y
para probar que esta implementaci
on es correcta. Ademas, sirve para analizar la
complejidad de funciones definidas en el formalismo basico y para obtener algunos
resultados te
oricos referentes al mismo (en la seccion 8.7 se vera un ejemplo de
estos resultados). Estas interpretaciones no son u
tiles para demostrar la correccion
total de los programas ya que habra que analizar todos los pasos elementales de
ejecuci
on para cada uno de los elementos del dominio de la funcion.
125
126
De todas formas, como se vio en el captulo anterior es posible entender y utilizar el formalismo sin tener que recurrir a este tipo de interpretaciones. Es decir que,
para el desarrollo de programas, no hace falta conocer el modelo computacional
asociado al formalismo.
Esto no significa que el formalismo no permita una interpretacion operacional.
Podra suceder que nuestro lenguaje sea tan abstracto que no permita ser implementado en una computadora. Al contrario, el formalismo desarrollado permite
este tipo de interpretaciones y sobre este t
opico tratara este captulo. De todas
formas, es posible y conveniente utilizar el formalismo libre de estas connotaciones
al momento de desarrollar programas.
8.2 Valores
En el formalismo b
asico, como en matem
atica, una expresion es utilizada para
representar (denotar ) un valor. Una expresi
on puede denotar distintos tipos de
valores, como ser n
umeros, listas, pares, funciones, etc.
Como hemos mencionado en la secci
on 7.2, es importante distinguir entre un
valor y su representaci
on por medio de expresiones. Sea la funcion cuadrado :
N um N um definida como:
.
cuadrado.x = x x
Las expresiones cuadrado.(3 5), cuadrado.15 y 225 denotan (todas) el n
umero doscientos veinticinco pero ninguna (inclusive la expresion 225) es este valor.
Todas ellas son representaciones concretas del valor abstracto doscientos veinticinco.
Lo mismo sucede con otros tipos de valores.
booleanos: Las expresiones
- F alse T rue
- F alse F alse
- T rue
- F alse,
denotan el valor booleano falso.
pares: Las expresiones
- (cuadrado.3 5, 4)
- ((225, 2 + 2), T rue).0
- (225, 4)
8.2 VALORES
127
128
129
pares: (E0 , E1 )
donde E0 y E1 son expresiones canonicas.
listas: [E0 , , En1 ], donde n 0 y E0 , , En1 son expresiones canonicas.
Notar que aqu tambien definimos a la lista vaca ([ ]) como una expresion
can
onica cuando n = 0.
Notemos que no hemos incluido en el ejemplo expresiones canonicas que representen funciones. Matem
aticamente hablando, los valores de tipo funcion pueden
ser vistas como reglas que asocian cada elemento de un conjuntos de valores con
un u
nico elemento de otro conjunto. Uno puede encontrar varias expresiones que
representan esta relaci
on, pero no vamos a elegir a una expresion como la expresi
on
can
onica de estos valores.
Otros valores tampoco tienen expresi
on canonica. Por ejemplo, el n
umero
no tiene una representaci
on decimal finita. Uno puede escribir la expresion que
denota este valor mediante la expansi
on decimal de , dgito por dgito, pero en el
formalismo b
asico todas las expresiones son finitas. Por lo tanto no se puede elegir
la expresi
on can
onica del valor .
Hasta ahora hemos visto valores que no tienen expresion canonica (funciones,
n
umero ). Tambien puede suceder que una expresion no tenga forma normal. Por
ejemplo dada la definici
on de funci
on:
.
inf = inf + 1
(8.1)
La expresi
on inf (de tipo n
umero) no tiene forma normal dado que puede demostrarse que su valor es diferente al de cualquier forma normal.
Sea n la forma normal que representa el mismo valor que la expresion inf (n
es la forma normal de inf ). Esta relaci
on implica que la expresion n = inf es
cierta. Adem
as, como n es la representaci
on decimal de un n
umero (ya que es una
forma normal) se cumple n . Suponiendo esto (sera nuestra hipotesis) podemos
demostrar:
n
= { hip
otesis }
inf
= { definici
on de inf }
inf + 1
= { hip
otesis }
n+1
130
1
0
1
0 = 1 (inverso multiplicativo de 0)
0
Sea n la forma normal que representa el mismo n
umero que 01 . Esta relacion
1
implica que la expresi
on n = 0 es cierta. Ademas, como n es una forma normal,
n . Suponiendo esto:
0
= { elemento neutro de la multiplicaci
on en
RynR}
0n
= { conmutabilidad de la multiplicaci
on en R y n
R}
n0
= { hip
otesis }
1
0
0
= { inverso multiplicativo de 0 }
1
En consecuencia concluimos que 0 = 1. Razonando por el absurdo n no puede
ser la forma normal de 01 y por lo tanto esta expresion no tiene forma normal.
8.4 Evaluaci
on
A partir de todo lo dicho, la ejecuci
on de un programa sera el proceso de
encontrar su forma normal. Veamos entonces mas detenidamente el proceso de
b
usqueda de expresiones can
onicas que hacen las computadoras.
Una computadora eval
ua una expresi
on (o ejecuta un programa) buscando
su forma normal y mostrando este resultado. Con los lenguajes funcionales las
computadoras alcanzan este objetivo a traves de m
ultiples pasos de reducci
on de
las expresiones para obtener otra equivalente mas simple. El sistema de evaluacion
dentro de una computadora est
a hecho de forma tal que cuando ya no es posible
reducir la expresi
on es porque se ha llegado a la forma normal (ver figura 8.1).
Podemos ver el proceso que ejecuta este sistema como una forma particular del
c
alculo de nuestro formalismo b
asico en la cual siempre se usa la regla de desplegado en las definiciones. Consideremos la reduccion de la expresion cuadrado.(3 5):
cuadrado.(3 5)
= { aritmetica }
cuadrado.15
8.4 EVALUACION
expresin
131
posible reducir?
no
forma normal
132
= { definici
on de inf }
inf + 1
= { definici
on de inf }
(inf + 1) + 1
= { asociatividad de la suma }
inf + (1 + 1)
= { aritmetica }
inf + 2
= { definici
on de inf }
(inf + 1) + 2
= { asociatividad de la suma }
inf + (1 + 2)
= { aritmetica }
inf + 3
= { definici
on de inf }
(inf + 1) + 3
EFICIENTE
8.5 UN MODELO COMPUTACIONAL MAS
133
= { definici
on de inf }
K.3.((inf + 1) + 2)
Obviamente este proceso no termina. Pero ahora elijamos las subexpresion de mas
afuera:
K.3.inf
= { definici
on de K }
3
Y con esta estrategia de reducci
on el proceso s termina.
Afortunadamente existe un resultado teorico (demostrado para el calculo lambda, un c
alculo te
orico de funciones en el cual el formalismo basico esta basado)
que avala estas pruebas.
Teorema 8.1
Si la forma can
onica existe, la estrategia de reduccion que siempre elige la
subexpresi
on de m
as afuera y m
as a la izquierda, conduce a la misma.
En otras palabras, si nuestro modelo computacional usa esta estrategia, se
arribar
a a la forma normal, siempre que ella exista. El orden (mas afuera y mas a
la izquierda) de reducci
on se denomina orden normal de reduccion.
En los ejemplos donde no se pudo lograr la convergencia a una forma normal
se utiliz
o la estrategia que siempre elige la subexpresion de mas adentro y mas a
la izquierda. Este orden de reducci
on se denomina orden aplicativo.
134
= { aritmetica }
9 (cuadrado.3)
= { definici
on de cuadrado }
9 (3 3)
= { aritmetica }
99
= { aritmetica }
81
EFICIENTE
8.5 UN MODELO COMPUTACIONAL MAS
135
Una forma de solucionar este problema es cambiando nuestro modelo computacional para que cuando el sistema deba desplegar funciones que tengan este tipo
de definici
on se utilicen definiciones locales. As, por ejemplo, manteniendo la estrategia de reducci
on normal, la expresi
on cuadrado.(cuadrado.3) se podra haber
evaluado de esta forma:
cuadrado.(cuadrado.3)
= { definici
on de cuadrado }
xx
Jx = cuadrado.3K
= { definici
on de cuadrado }
xx
Jx = 3 3K
= { aritmetica }
xx
Jx = 9K
= { definici
on local }
99
= { aritmetica }
81
y de esta forma solo desplegamos dos veces la funcion cuadrado.
Este modelo computacional, que se basa en la estrategia de reduccion normal
agregando los mecanismos necesarios para que se pueden compartir subexpresiones, se denomina generalmente en la literatura modelo computacional lazy con
evaluaci
on call-by-need.
Como ya dijimos en la introducci
on de este captulo, la definicion formal del
modelo computacional sirve, entre otras cosas, para calcular la complejidad de las
funciones definidas en nuestro formalismo. Es as que, si nuestra implementacion
del lenguaje est
a realizada en base al modelo lazy, puede suceder que funciones
definidas con variables repetidas, sean m
as eficientes. En nuestro ejemplo la defi.
nici
on de cuadrado = x x tiene la variable x repetida con lo cual las expresiones
que instancien las mismas, ser
an reducidas solo una vez en este modelo, como ya
se ha visto.
Este modelo es el que se utiliza en la mayora de las implementaciones de los
lenguajes funcionales puros como por ejemplo Haskell [Has06]. Por lo general es
implementado representando las expresiones como un grafo, denominado grafo de
reducci
on. Para m
as informaci
on sobre implementacion de lenguajes funcionales
ver [JL91].
136
f ac.0 = 1
.
f ac.(n + 1) = (n + 1) f ac.n
resulta
T f ac .0 = 1
T f ac .(n + 1) = 1 + T f ac .n
f.0 = 0
.
f.(n + 1) = f.n + g.n
|[g.i = X i ]|
137
T g.0 = 1
T g.(n + 1) = 1 + T g.n
T f.0 = 1
= 2 + n + T f.n
Se puede demostrar que si se define
T f.n =
n (n + 3)
2
(8.2)
nf.P
nf.P
inf
0
138
8.8 Ejercicios
Ejercicio 8.1
Mostrar los pasos de reducci
on hasta llegar a la forma normal de la expresion:
2 cuadrado.(head.[2, 4, 5, 6, 7, 8])
1. utilizando el orden de reducci
on aplicativo.
2. utilizando el orden de reducci
on normal.
Ejercicio 8.2
Dada la definici
on:
.
linf = 1 . linf
mostrar los pasos de reducci
on hasta llegar a la forma normal de la expresion:
head.linf
1. utilizando el orden de reducci
on aplicativo.
2. utilizando el orden de reducci
on normal.
Comparar ambos resultados.
Ejercicio 8.3
Dada la definici
on:
.
f.x.0 = x
.
f.x.(n + 1) = cuadrado.(f.x.n)
mostrar los pasos de reducci
on hasta llegar a la forma normal de la expresion:
f.2.3
1. utilizando la estrategia de reducci
on normal, sin utilizar definiciones locales.
2. utilizando el modelo computacional lazy con evaluacion call-by-need.
Comparar ambos resultados.
Ejercicio 8.4
Dadas las definiciones
cond : Bool 7 A 7 A
.
cond.p.x.y =
(
p
2
p
)
x
y
8.8 EJERCICIOS
139
f ac : N um 7 N um
.
f ac.n =
cond.(n = 0).1.(n f ac.(n 1))
mostrar los pasos de reduci
on de la expresion
f ac.2
1. utilizando el orden de reducci
on aplicativo.
2. utilizando el modelo computacional lazy.
Responder a la pregunta:
Java y ejecuto el programa?
140
Captulo 9
El proceso de construcci
on
de programas
Un coup de des jamais nabolira le hasard.
Stephane Mallarme: Un Coup de Des
142
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
Problema
Programa
Informal
Poco detallado
Formal
Muy detallado
143
Problema
Especificacion formal
Informal
Poco detallado
Formal
Poco detallada
Formal
Programa
Muy detallado
144
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
9.1 Especificaciones
En un sentido general podemos definir una especificacion como una descripci
on formal de la tarea que un programa tiene que realizar. Un slogan usado con
referencia a las especificaciones es que estas responden a la pregunta que hace el
programa? mientras que el programa mismo, usualmente llamado la implementaci
on, reponde a la pregunta c
omo se realiza la tarea?
En el libro [BEKV94] se presenta a una especificacion como un contrato entre
el programador y el potencial usuario. Este contrato establece de manera precisa cu
al es el comportamiento del producto que el programador debe proveer al
usuario. Usualmente las especificaciones dicen que si el programa se ejecuta para
un valor de un conjunto dado, el resultado satisfara una cierta propiedad. Una
de las consecuencias de dicho contrato es que el usuario se compromete a usar el
programa s
olo para valores en ese conjunto predeterminado y el programador a
asegurar que el programa producir
a un resultado satisfactorio. En principio si el
usuario ingresa al programa datos que no estan en el conjunto de datos aceptables, el comportamiento del programa puede ser cualquiera sin con ello violar el
contrato establecido por la especificaci
on.
En el contexto de nuestro formalismo b
asico podemos ser mas precisos al definir el concepto de especificaci
on. Diremos simplemente que una especificaci
on
es un predicado sobre el espacio de valores. En general estaremos especificando
funciones, que como ya dijimos, son valores como cualesquiera otros. La tarea de
programaci
on de un problema especificado por un predicado dado puede describirse ahora simplemente como encontrar un valor (una funcion) que satisfaga dicho
predicado.
En este libro no nos encargaremos de cualquier clase de problema, pues algunos
son triviales y otros demasiado complejos o definidos muy vagamente.
Tomemos por ejemplo el problema de construir un sistema para la administraci
on de los alumnos de una materia. A primera vista parece un problema facil,
pero si se examina el problema con un poco mas de detalle puede notarse que su
formulaci
on es demasiado imprecisa. Si se da ese enunciado a ocho programadores
diferentes, es probable que se obtengan ocho soluciones a problemas diferentes. No
resolveremos problemas formulados de manera tan vaga.
Consideremos un problema m
as especfico. Dado el conjunto de los alumnos de
un curso se pide obtener el alumno con el segundo promedio mas alto. Este problema parece mucho m
as simple, pero a
un quedan varias cuestiones por resolver. Por
ejemplo, puede ser que dicho alumno no exista (en caso de que todos los alumnos
del curso tengan el mismo promedio) o que haya mas de uno. Si nos quedamos solo
con el enunciado informal, la soluci
on para estos casos vuelve a quedar librada al
criterio del programador.
9.1 ESPECIFICACIONES
145
En lo que resta del captulo usaremos las herramientas introducidas anteriormente para escribir especificaciones precisas. Para ello interpretaremos las formulas
del c
alculo de predicados y las expresiones cuantificadas como es usual y construiremos con ellas y con el formalismo b
asico las especificaciones formales. Esto nos
permitir
a resolver las ambig
uedades en la formulacion de los problemas. Por supuesto, siempre queda la pregunta de si la especificacion formal construida efectivamente expresa el enunciado del problema a resolver. Esta pregunta es inevitable
y es bueno responderla de manera completa lo mas temprano posible en el proceso
de construcci
on de programas. Por otro lado, no siempre una especificacion puede
ser satisfecha por un programa o la construccion de este puede ser muy costosa o
su ejecuci
on muy ineficiente. En estos casos es necesario cambiar la especificacion.
Ejemplo 9.1
El presente ejemplo ha sido adaptado de uno de [BEKV94]. El usuario propone al
programador el problema de calcular la raz cuadrada de un n
umero real dado.
Primer intento. El programador, conociendo el dominio del algebra, propone
resolver el problema s
olo para reales que no sean negativos. El usuario acepta la
propuesta por lo cual el contrato entre ambos (la especificacion) queda establecido
como sigue:
El programador se compromete a construir una funcion sqrt, tal que
sqrt : N um 7 N um
x : 0 x : (sqrt.x)2 = x
Puede pensarse a la especificaci
on como una ecuacion a resolver donde la incognita es sqrt, es decir, el problema es encontrar una funcion sqrt tal que se satisfaga
la especificaci
on. N
otese que esta funci
on no necesariamente es u
nica, en particular
en este ejemplo, dado que hay por lo menos dos soluciones posibles para la raz
cuadrada de un n
umero estrictamente positivo. Esto da lugar a que haya infinitas
soluciones para el problema planteado (dado que puede en principio elegirse para
que valores la raz ser
a positiva y para cuales negativa).
Una forma estilizada de escribir la misma especificacion es separar la precondici
on de la postcondici
on. La primera condicion habla de las restricciones que
determinan los datos aceptables, mientras que la segunda establece las propiedades que satisfar
a el resultado. Nuestro ejemplo podra escribirse como sigue.
sqrt : N um 7 N um
pre: 0 x
post: (sqrt.x)2 = x
146
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
N
otese que la cuantificaci
on de la variable x queda implcita. Esto sera una
pr
actica usual. En general se supondr
a que las variables que aparecen como argumentos de la funci
on especificada est
an cuantificadas universalmente. La especificaci
on original puede entonces escribirse tambien simplemente como
sqrt : N um 7 N um
0 x (sqrt.x)2 = x
Segundo intento. Un fen
omeno usual es que el programador por alguna raz
on no pueda satisfacer la especificaci
on acordada. Por ejemplo, puede descubrir
cuando est
a intentando resolver el problema que el sistema de computo en el cual
va a implementar su programa s
olo maneja aproximaciones finitas a los n
umeros
irracionales, por lo que es imposible encontrar por ejemplo una solucion exacta de
sqrt.2. El problema es que la especificaci
on requiere que la solucion sea exacta.
Dada esta situaci
on, el programador tiene que cambiar el contrato con el usuario,
quien probablemente no va a sentirse satisfecho, a
un en el caso usual en que el
usuario es el mismo programador. Una posible especificacion es
sqrt : N um 7 N um
pre: 0 x
post: |(sqrt.x)2 x| <
donde es una constante a ser negociada.
Escrita de esta manera, es obvio que la especificacion es mas favorable para
el programador, en el sentido de que la postcondicion es mas debil y por lo tanto
mas f
acil de satisfacer. Si se escribe la especificacion como
sqrt : N um 7 N um
0 x |(sqrt.x)2 x| <
queda claro que la especificaci
on realizada en el primer intento implica logicamente
a esta.
Cambios en la especificaci
on
Como se vio en el ejemplo anterior, frecuentemente es necesario modificar las
especificaciones. En este caso la especificaci
on fue debilitada, es decir se escribio
otra especificaci
on la que requera menos del programa. La forma de debilitarla
fue debilitar la postcondici
on. Otra forma de debilitar una especificacion es fortaleciendo la precondici
on, es decir permitiendo que el programa pueda ser solo usado
con un conjunto m
as chico de valores de entrada. Por ejemplo, podemos poner
9.1 ESPECIFICACIONES
147
como requisito que los argumentos para sqrt sean cuadrados perfectos (con lo cual
es posible encontrar valores exactos para la raz cuadrada). La especificacion de
esta (no demasiado u
til) funci
on sera:
sqrt : N um 7 N um
pre: y : y N at : y 2 = x
post:(sqrt.x)2 = x
Como contrapartida, a veces es necesario fortalecer la especificacion. Esto ocurre en general dado que el usuario puede darse cuenta que necesita un programa
con mejores propiedades que el anterior, o poder usarlo para un conjunto de datos
de entrada m
as amplio que el que haba pensado. En el ejemplo de la raz cuadrada, puede por ejemplo requerirse que el resultado sea siempre positivo, con lo
cual se est
a fortaleciendo la postcondici
on y por lo tanto la especificacion como un
todo, pudiendo escribirse como sigue.
sqrt : N um 7 N um
0 x |(sqrt.x)2 x| < 0 sqrt.x
Ejemplo 9.2
Consideremos ahora la especificaci
on de una funcion que calcule el segundo mejor
promedio de un curso. La manera m
as simple de construir esta especificacion es
usando un par de especificaciones auxiliares que expresen cual es el mayor promedio
y cu
al es el conjunto de aquellos estudiantes que tienen este promedio.
maxProm : {Alumno} 7 N um
mejProm : {Alumno} 7 {Alumno}
maxProm.A = hMax a : a A : prom.a i
mejProm.A = {a : a A prom.a = maxProm.A : a}
La especificaci
on de la funci
on requerida es ahora:
segProm : {Alumno} 7 {Alumno}
segProm.A = {a : a A prom.a = maxProm.(A \ mejProm.A) : a}
donde estamos suponiendo que la funcion prom nos da el promedio de un
alumno dado.
Las funciones maxProm y mejProm son funciones auxiliares que se usan para
especificar la funci
on requerida segProm, y no es en principio necesario contruir
148
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
9.2 Ejemplos
Dado que no existen reglas de aplicaci
on general para la especificacion de problemas, incluimos en esta secci
on algunos ejemplos. La clave esta en saber expresar
los problemas planteados en lenguaje coloquial de manera concisa, usando un lenguaje formal.
Escribiremos el problema a especificar entre comillas. Cabe aclarar que con
frecuencia los problemas pueden especificarse de diversas maneras, por lo que no
deben tomarse las especificaciones dadas a continuacion como las u
nicas posibles.
Ejemplo 9.3
Dados x 0 e y > 0 enteros, calcular el cociente y el resto de la division entera
de x por y.
El algoritmo de divisi
on en los enteros nos asegura la existencia de un u
nico
entero q cociente de la divisi
on entera de x por y y un u
nico entero r resto de esta
divisi
on. Estos n
umeros est
an caracterizados por las propiedades x = q y + r y
0 r < y. Por lo tanto, una funci
on que resuelva este problema puede especificarse
como sigue
divMod .x.y : N at N at (N at N at)
x 0 y > 0 divMod .x.y = (q, r) (x = q y + r 0 r < y)
9.2 EJEMPLOS
149
Ejemplo 9.4
Dado un entero x 0, sqrtInt.x es la raz cuadrada entera de x.
La raz cuadrada entera de un n
umero esta definida como el mayor entero
positivo cuyo cuadrado es menor o igual que el n
umero en cuestion. Esto puede
expresarse en lenguaje formal de la siguiente manera:
sqrtInt : N um 7 N um
0 x sqrtInt.x = Max z : 0 z z 2 x : z
alternativamente, puede evitarse el cuantificador maximo de la siguiente manera.
sqrtInt : N um 7 N um
0 x 0 sqrtInt.x (sqrInt.x)2 x x < (sqrtInt.(x) + 1)2 )
Ejemplo 9.5
Sea xs una lista no vaca de enteros. m es el mnimo de xs.
m : N um
m = hMin i : 0 i < #xs : xs.i i
Otra especificaci
on posible se obtiene al describir con mas detalle lo que significa
mnimo:
m : N um
h i : 0 i < #xs : xs.i m i h i : 0 i < #xs : xs.i = m i
Una manera m
as usual es definir una funcion que tome a la lista como parametro (no como en el caso previo en el cual la constante m esta especificada solo
para una lista particular xs). Consideramos la funcion minlist que dada una lista
cualquiera devuelve el valor mnimo de la lista
minlist : [N um] 7 N um
minlist.xs = hMin i : 0 i < #xs : xs.i i
N
otese que en esta u
ltima especificacion la variable xs esta implcitamente
cuantificada (no as en el caso anterior, en el cual era una constante)
150
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
Ejemplo 9.6
Sea xs una lista no vaca. Todos los elementos de xs son iguales.
Una manera de especificar este problema es expresar la condicion de igualdad
de todos los elementos diciendo que deben ser iguales dos a dos:
h i : 0 i < #xs : h j : 0 j < #xs : xs.i = xs.j i i
Pero tambien podramos expresar que todos son iguales diciendo que cada uno
de ellos es igual a uno fijo, por ejemplo, el primero (sabemos que existe pues
suponemos que la lista no es vaca):
h i : 0 i < #xs : xs.i = xs.0 i
Ejemplo 9.7
Sea xs una lista de enteros. xs est
a ordenada en forma creciente.
Si una lista est
a ordenada en forma creciente, cada elemento debe ser mayor
que el anterior:
h i : 0 < i < #xs : xs.i > xs.(i 1) i
Notar que fue necesario excluir el cero del rango de cuantificacion, para que el
termino este siempre definido.
Tambien puede especificarse este problema expresando la relacion de desigualdad correspondiente entre cualquier par de ndices:
h i : 0 i < #xs : h j : i < j < #xs : xs.i < xs.j i i
Ejemplo 9.8
La funci
on f : Int 7 [N um] 7 Bool determina si el k-esimo elemento de la lista
xs aloja el mnimo valor de xs.
Notemos que la funci
on f debe aplicarse a dos argumentos, una lista y un
entero que indica una posici
on en la lista. Para que la evaluacion tenga sentido, el
entero debe estar comprendido en el rango que corresponde al tama
no de la lista.
Entonces podemos escribir:
f : N um 7 [N um] 7 Bool
f.k.xs = (0 k < #xs xs.k = hMin i : 0 i < #xs : xs.i i)
o bien
f : N um 7 [N um] 7 Bool
f.k.xs = (0 k < #xs h i : 0 i < #xs : xs.k xs.i i)
9.2 EJEMPLOS
151
Ejemplo 9.9
La funci
on minout : [N at] 7 N at selecciona el menor natural que no esta en xs.
La funci
on minout extrae el mnimo de un conjunto, por lo que resulta claro
que la especificaci
on usar
a el cuantificador Min. El conjunto del cual se extrae el
mnimo deber
a especificarse en el rango de la cuantificacion:
minout : [N at] 7 N at
minout.xs = hMin i : 0 i h j : 0 j < #xs : xs.j 6= i i : i i
Ejemplo 9.10
La funci
on lmax : [A] 7 N um calcula la longitud del maximo intervalo de la
forma [0..k] que verifica xs.i = 0 para todo i [0..k].
Podemos dar una especificaci
on similar a la del ejemplo anterior:
lmax : [A] 7 N um
lmax.xs = hMax k : 0 k #xs h i : 0 i < k : xs.i = 0 i : k i
Esto tambien se puede escribir usando listas en lugar del entero k:
lmax : [A] 7 N um
lmax.xs = hMax as, bs
: xs = as ++ bs h i : 0 i < #as : xs.i = 0 i : #as i
Ejemplo 9.11
Dada una lista de n
umeros, la funci
on P determina si alg
un elemento de la lista
es igual a la suma de todos los anteriores a el.
Evidentemente, la funci
on P debe tomar como argumento una lista y devolver un booleano. El problema se puede especificar facilmente con la ayuda del
cuantificador existencial y de la suma:
P : [N um] 7 Bool
P
P.xs = h i : 0 i < #xs : xs.i = h j : 0 j < i : xs.j i i
Ejemplo 9.12
Dado un polinomio p(x) = an xn + an1 xn1 + . . . + a1 x + a0 , la funcion ev realiza
la evaluaci
on del polinomio en un valor dado de la variable independiente.
152
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
En principio, la funci
on ev se aplica a dos argumentos, el polinomio p(x) y el
punto en el que se desea evaluarlo. Para especificar la funcion debemos, entonces, elegir una manera adecuada de representar el polinomio. Como un polinomio
queda unvocamente determinado por sus coeficientes, una posibilidad es formar
con dichos coeficientes una lista: xs = [a0 , a1 , . . . , an1 , an ]. Mas a
un, cada lista de
enteros puede pensarse como la lista de coeficientes de un polinomio. As, podemos
especificar ev como:
ev : [N um] 7 N um 7 Bool
P
ev.xs.y =
i : 0 i < #xs : xs.i y i
Ejemplo 9.13
Dada una lista de booleanos, la funci
on bal debe indicar si en la lista hay igual
cantidad de elementos T rue que F alse.
El cuantificador aritmetico N nos permite contar la cantidad de T rue y de
F alse que hay en la lista. Lo que nos interesa es el resultado de la comparacion
de estas dos cantidades:
bal : [Bool] 7 Bool
bal.xs = (hN i : 0 i < #xs : xs.i = T rue i =
hN i : 0 i < #xs : xs.i = F alse i)
o equivalentemente
bal : [Bool] 7 Bool
bal.xs = (hN i : 0 i < #xs : xs.i i = hN i : 0 i < #xs : xs.i i)
Ejemplo 9.14
Dada una lista xs de booleanos, la funci
on balmax debe indicar la longitud del
m
aximo segmento de xs que satisface bal.
Dada una lista xs, un segmento de ella es una lista cuyos elementos estan en xs,
en el mismo orden y consecutivamente. Por ejemplo: si xs = [2, 4, 6, 8], entonces
[2, 4], [4, 6, 8], [ ], son segmentos, mientras que [4, 2] o [2, 6, 8] no lo son.
En problemas como este, suele ser conveniente expresar la lista como una concatenaci
on. Si escribimos xs = as ++ bs ++ cs, entonces as, bs y cs son segmentos
de xs, por lo que podemos usarlos para expresar las condiciones que necesitamos
que se satisfagan. Observemos que de los tres mencionados, el mas general es bs,
puesto que as necesariamente comienza en la posicion cero de xs, mientras que cs
termina necesariamente en la u
ltima posici
on de xs. El segmento bs puede estar en
9.3 EJERCICIOS
153
cualquier parte, pues tanto as como cs pueden ser vacos. Parece razonable, pues,
usar bs para especificar el problema. Ademas de pedir que sea segmento, necesitamos que satisfaga bal; esto debe figurar en el rango. En el termino debemos poner
lo que nos interesa de cada elemento considerado en el rango, esto es, la longitud.
Como queremos obtener la m
axima longitud, usamos el cuantificador Max. As,
podemos especificar el problema de la siguiente manera:
balmax : [Bool] 7 N um
balmax.xs = hMax bs : h as, cs : : xs = as ++ bs ++ cs i bal.bs : #bs i
o equivalentemente (pero m
as simple)
balmax : [Bool] 7 N um
balmax.xs = hMax as, bs, cs : xs = as ++ bs ++ cs bal.bs : #bs i
9.3 Ejercicios
Ejercicio 9.1
Expresar en lenguaje formal las oraciones entre comillas:
1. Dado un entero N > 0: x es el mayor entero que vale a lo sumo N y es una
potencia de 2.
2. Dado un conjunto B: si B no es vaco, x es el mayor elemento de B; en caso
contrario, x es igual a 0.
Ejercicio 9.2
Sea xs una lista no vaca, con elementos enteros. Expresar en lenguaje formal:
1. Suponiendo que #xs > 1 y que existen al menos dos valores distintos en xs:
x es el segundo valor m
as grande de xs. (Ejemplo: si xs = [3, 6, 1, 7, 6, 4, 7],
debe resultar x = 6).
2. s es la suma de los elementos de xs.
3. Dado un entero X: n es la cantidad de veces que X aparece en xs.
4. Todos los valores de xs son distintos.
5. Si el 1 est
a en xs, entonces tambien el 0 esta en xs.
6. p es el producto de todos los valores positivos de xs.
7. Dado un entero x: p es un booleano cuyo valor de verdad coincide con el de
la afirmaci
on x xs.
154
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
Ejercicio 9.3
Sea xs una lista no vaca, con elementos booleanos, tal que al menos un elemento
de xs es T rue. Expresar en lenguaje formal:
1. n es el menor entero tal que xs.n T rue.
2. n indica la posici
on del u
ltimo elemento de la lista que es equivalente a
T rue
Ejercicio 9.4
Sea xs una lista no vaca. Expresar las siguientes especificaciones en lenguaje
com
un:
1. h i : 0 i < N N #xs : xs.i 0 i
2. h i : 0 < i < N N #xs : xs.(i 1) < xs.i i
3. h i : 0 i < N N #xs : xs.i = 0 i
4. h p, q : 0 p 0 q p + q = N 1 N #xs : xs.p = xs.q i
Ejercicio 9.5
Sea xs una lista no vaca.
1. Especificar: xs es creciente.
2. Especificar y demostrar: si xs escreciente, entonces el primer elemento es el
menor.
Ejercicio 9.6
Especificar las siguientes funciones:
1. f : [N um] 7 Bool
f.xs determina si xs contiene igual cantidad de elementos pares que impares.
2. cp : [N um] 7 N um
cp.xs determina la cantidad de n
umeros pares que contiene xs.
3. g : N um 7 [N um] 7 Bool
g.k.xs determina si el k-esimo elemento de xs aloja el maximo valor de xs.
4. h : N um 7 [N um] 7 Bool
h.k.xs determina si el k-esimo elemento de xs aloja la primera ocurrencia
del m
aximo valor de xs.
5. nonulo : [N um] 7 Bool
nonulo.xs es T rue si y s
olo si xs no contiene elementos nulos.
9.3 EJERCICIOS
155
k
creciente
2. Dado un n
umero natural x, los elementos de xs verifican:
(i) 0
k
x
(ii) 0
=x
k
>x
156
DE PROGRAMAS
CAPITULO 9. EL PROCESO DE CONSTRUCCION
Captulo 10
Inducci
on y recursi
on
Induction. Letre aime est desire parce quun autre ou dautres ont
montre au sujet quil est desriable: tout special quil soit, le desir amoureux se decouvre par induction.
Roland Barthes:Fragments dun discourse amoureux
Y RECURSION
158
10.1 Inducci
on matem
atica
El dominio inductivo m
as familiar es el de los n
umeros naturales. El principio de inducci
on asociado a este dominio se conoce con el nombre de inducci
on
matem
atica. Sea por ejemplo la proposici
on
n (n + 1)
2
Una manera usual de demostrar que P es cierta para todo n
umero natural
es demostrar que vale P.0 y que suponiendo que vale para un n
umero natural n
dado, entonces tambien vale para el siguiente (n+1). Esta u
ltima afirmacion puede
escribirse como
P.n : h i : 0 i n : i i =
h n : 0 n : P.n P.(n + 1) i
(10.1)
Ahora, si ambas cosas son ciertas, puede verse como construir una demostraci
on de P para un n
umero N dado: La demostracion de P.0 es trivial. Usando la
propiedad (10.1) e instanciaci
on con n = 0 puede demostrarse por Modus Ponens
y P.0 que vale P.1. Luego, instanciando (10.1) con n = 1, puede demostrarse de
manera an
aloga P.2, etcetera, hasta llegar a P.N . Si tenemos suficiente tiempo y
ganas, no importa cuan grande sea N , se llegara en alg
un momento.
El principio de inducci
on, el cual podra plantearse como un metateorema,
permite inferir a partir de P.0 y de (10.1) que vale P para todo n
umero natural.
Consideremos de nuevo el ejemplo. Demostraremos primero el caso base P.0.
P.0
{ instanciaci
on }
P
0 (0 + 1)
h i :0i0: ii=
2
{ aritmetica }
P
0
h i :i=0: ii=
2
{ rango unitario, aritmetica }
0=0
{ reflexividad de = }
T rue
Demostraremos ahora el caso inductivo, suponiendo P.n valida demostraremos P.(n + 1).
P.(n + 1)
MATEMATICA
10.1 INDUCCION
159
{ instanciaci
on }
P
(n + 1) ((n + 1) + 1)
h i :0in+1: ii=
2
{ aritmetica }
P
(n + 1) (n + 2)
h i :0ini=n+1: ii=
2
{ partici
on de rango }
P
P
(n + 1) (n + 2)
h i :0in: ii+h i :i=n+1: ii=
2
{ rango unitario }
P
(n + 1) (n + 2)
h i :0in: ii+n+1=
2
{ suponemos P.n (hip
otesis inductiva), Leibniz }
n (n + 1)
(n + 1) (n + 2)
+n+1=
2
2
{ aritmetica }
n (n + 1) + 2 (n + 1)
(n + 1) (n + 2)
=
2
2
{ aritmetica }
T rue
El formato de demostraci
on puede hacerse mas (o menos) economico, como se
ilustrar
a a continuaci
on. El interes en estos formatos no esta solo en la elegancia y
la consiguiente facilidad para comprender o realizar las demostraciones, sino que
tambien se van a usar estos formatos para construir nuevos objetos (en general
funciones) los cuales van a satisfacer ciertas propiedades predeterminadas. La demostraci
on (inductiva) de que el objeto construido satisfara estas propiedades se
construye paso a paso junto con el objeto. Para ejemplificar esto introduciremos
primero una definici
on formal del principio de induccion.
Con la notaci
on que estamos usando, el principio de induccion puede escribirse
de la siguiente manera:
h i : 0 i : P.i i
{ inducci
on }
P.0 h j : 0 j : P.j P.(j + 1) i
En el contexto de nuestro formalismo basico el principio de induccion se usara
de dos maneras: para demostrar que una definicion recursiva dada satisface cierta
definici
on explcita, o -inversamente- para encontrar una definicion recursiva correspondiente a una definici
on explcita dada. Veamos esto con un ejemplo.
Sea f definida recursivamente por
Y RECURSION
160
f.0 = 0
.
f.(i + 1) = f.i + 2 i + 1
Queremos demostrar que f satisface la propiedad i : i N at : f.i = i2 .
La primera demostraci
on va a usar el principio de induccion en su forma cruda.
i : i N at : f.i = i2
{ inducci
on }
2
f.0 = 0 j : j N at : (f.j = j 2 f.(j + 1) = (j + 1)2 )
{
algebra }
f.0 = 0 j : j N at : (f.j = j 2 f.(j + 1) = j 2 + 2 j + 1)
{ Leibniz (axioma) }
f.0 = 0 j : j N at : (f.j = j 2 f.(j + 1) = f.j + 2 j + 1)
{ (p q) q, monotona }
f.0 = 0 h j : j N at : f.(j + 1) = f.j + 2 j + 1 i
{ definici
on de f }
T rue
Como se vio en el primer ejemplo, en los problemas que usan induccion, suele
separarse el caso base del resto. Lo anterior podra escribirse de la siguiente
manera:
Caso base
f.0 = 02
{
algebra }
f.0 = 0
{ definici
on de f }
T rue
Resto
f.(i + 1) = (i + 1)2
{
algebra }
f.(i + 1) = i2 + 2 i + 1
{ hipotesis inductiva }
f.(i + 1) = f.i + 2 i + 1
{ definicion de f }
T rue
Obviamente sera necesario demostrar un metateorema que indique como reconstruir una demostraci
on pura a partir de la anterior. No vamos a demostrarlo
aqu, dejando para el lector interesado esta tarea. Para el ejemplo considerado la
traducci
on realizada es obvia.
MATEMATICA
10.1 INDUCCION
161
Una forma m
as compacta de escribir esta demostracion es evitar repetir el lado
izquierdo de la igualdad en cada paso, dado que este no cambia. La demostracion
quedar
a por lo tanto de la siguiente forma:
Caso base
Paso inductivo
f.0
f.(i + 1)
= { definici
on de f }
= { definicion de f }
f.i + 2 i + 1
0
= {
algebra }
= { hipotesis inductiva }
i2 + 2 i + 1
= { algebra }
(i + 1)2
i : i N at : f.i = i2
Obviamente, existe una forma trivial de encontrar una funcion que satisfaga la
especificaci
on:
f.x = x x
Si bien es inmediato que esta definici
on satisface la especificacion y que adem
as es una definici
on extremadamete eficiente, a modo de ejemplo trataremos de
encontrar una definici
on recursiva de f . Para hacer esto, algunos de los pasos de
derivaci
on (en general los primeros) van a usar la especificacion como si fuera
cierta. En realidad lo que se quiere construir es, ademas del programa, una demostraci
on de que efectivamente el programa satisface dicha especificacion. Puede
pensarse por analoga que una especificaci
on de una funcion f es una ecuacion a
resolver con inc
ognita f . Luego el proceso de derivacion consistira en despejar f
Y RECURSION
162
para saber que valor toma (obviamente puede tener varias soluciones posibles). El
proceso de despejar nos asegura que si ahora reemplazamos el valor obtenido en
la ecuaci
on original tendremos un enunciado verdadero. Veamos esto a traves del
ejemplo.
Caso base
Paso inductivo
f.0
f.(i + 1)
= { especificaci
on de f }
02
= { especificacion de f }
(i + 1)2
= {
algebra }
= { algebra }
i2 + 2 i + 1
= { hipotesis inductiva }
f.i + 2 i + 1
f.0 = 0
.
f.(i + 1) = f.i + 2 i + 1
(la cual es casualmente la funci
on con la cual comenzamos el ejemplo) se satisface
la propiedad requerida. Lo que acabamos de hacer se llama derivaci
on de programa, dado que hemos construido un programa que satisface la especificacion
y la demostraci
on de que lo hace. Para ver esto u
ltimo, notese que es inmediato
c
omo recuperar la tercera demostraci
on por induccion de que la funcion f satisface
la propiedad requerida, simplemente invirtiendo la demostracion, poniendo en el
segundo paso el u
ltimo (y como justificaci
on en lugar de especificacion de f se
pone definici
on de f o regla de desplegado para f ) y como conclusion el segundo
paso de la derivaci
on. En general el primer paso de una derivacion sera la propiedad que finalmente se quiere que la funci
on cumpla. En ejemplos mas complejos
el formato de derivaci
on puede ser ligeramente diferente
En general, nos concentraremos en el problema de la derivacion de programas m
as que en la verificaci
on de los mismos. Veamos otro ejemplo sencillo de
derivaci
on: sea f ac una funci
on que satisface la propiedad
Q
h n : n N at : f ac.n = h i : 0 < i n : i i i ,
es decir, f ac calcula el factorial de un n
umero. Se desea una definicion recursiva
GENERALIZADA
10.2 INDUCCION
163
de f ac.
Caso base
Paso inductivo
f ac.0
f ac.(n + 1)
= { especificaci
on de f }
Q
h i :0<i0: ii
= { especificacion de f }
Q
h i :0<in+1: ii
= { rango vaco }
= { particion de rango }
Q
h i :0<in: ii
Q
h i :n<in+1: ii
= { hipotesis inductiva;
unitario }
f ac.n (n + 1)
rango
f ac.0 = 1
.
f ac.(n + 1) = (n + 1) f ac.n
10.2 Inducci
on generalizada
Existe una generalizaci
on natural del principio de induccion matematica la
cual consiste en usar para demostrar el caso inductivo P.(n + 1) no solo P.n sino
tambien P.i, con 0 i < n. La justificaci
on de que demostrando esta propiedad
(m
as debil) y el caso base implica que P vale para todo natural es la misma que
para la inducci
on presentada antes, dado que al demostrar P.(n + 1) ya tenemos
demostrados todos los anteriores, no s
olo P.n. Afortunadamente ambos principios
de inducci
on son equivalentes como se vera en la seccion 10.3, la cual puede ser
salteada en una primera lectura.
El principio de inducci
on generalizada puede formularse como sigue
h i : 0 i : P.i i
{ inducci
on }
h j : 0 j : h k : 0 k < j : P.k i P.j i
N
otese que no hace falta separar el caso base, dado que esta implcito en el
rango vaco del cuantificador interno para el caso n = 0.
Ejercicio 10.1
Demostrar que el principio de inducci
on generalizada es equivalente al siguiente
Y RECURSION
164
h i : 0 i : P.i i
{ inducci
on }
f ib.0 = 0
.
f ib.1 = 1
.
f ib.(n + 2) = f ib.n + f ib(n + 1)
Esta sucesi
on tiene propiedades muy interesantes, algunas de las cuales se presentan en los ejercicios. Vamos a demostrar ahora una muy simple:
h n : 0 n : f ib.n < 2n i
Dada la definici
on de f ib, parece conveniente considerar dos casos base, cuando
n = 0 y cuando n = 1. El caso inductivo podra entonces considerarse para n 2.
Ejercicio 10.2
Demostrar que el principio de inducci
on generalizada es equivalente al siguiente
h i : 0 i : P.i i
{ inducci
on }
P.0 P.1 h j : 0 j : h k : 0 k j + 1 : P.k i P.(j + 2) i
Los dos casos base se dejan como ejercicio (facil) para el lector. Consideremos el
caso inductivo (usaremos inducci
on generalizada). Sea P.n la proposicion f ib.n
2n . Vamos a partir de f ib.(n + 2) y llegar a 2n+2 .
f ib.(n + 2)
= { definici
on de f ib }
f ib.n + f ib.(n + 1)
< { hip
otesis inductiva (P.n) ,
algebra }
2n + f ib.(n + 1)
< { hip
otesis inductiva (P.(n + 1)) ,
algebra }
2n + 2n+1
< { la exponenciaci
on es creciente }
2n+1 + 2n+1
= {
algebra }
2n+2
10.3 EQUIVALENCIA ENTRE LOS PRINCIPIOS DE INDUCCION
165
n
n
1+ 5
1 5
donde =
y=
.
2
2
Ejercicio 10.4
Determinar cual es el error del siguiente razonamiento el cual demuestra que un
grupo cualquiera de gatos est
a compuesto solo por gatos negros.
La demostraci
on es por inducci
on en el n
umero de gatos de un
grupo dado. Para el caso de 0 gatos el resultado es inmemdiato, dado
que obviamente todo gato del grupo es negro. Consideremos ahora un
grupo de n + 1 gatos. Tomemos un gato cualquiera del grupo. El grupo
de los gatos restantes tiene n gatos, y por hipotesis inductiva son todos
negros. Luego tenemos n gatos negros y uno que no sabemos a
un de
que color es. Intecambiemos ahora el gato que sacamos con uno del
grupo, el cual sabemos que es negro. Luego tenemos un gato negro y
un grupo de n gatos. Por hip
otesis inductiva los n gatos son negros,
pero como el que tenemos aparte tambien es negro, entonces tenemos
que los n + 1 gatos son negros.
Ejercicio 10.5
Determinar cual es el error del siguiente razonamiento el cual demuestra que en
un grupo cualquiera de personas si una es comunista luego todas lo son.
Lo vamos a demostrar por induccion en el n
umero de personas del
grupo. El caso de 0 personas es trivialmente cierto (el antecedente de
la implicaci
on es falso). Para un grupo de 1 persona tambien es inmediato, dado que si esta persona es comunista se satisface el consecuente
de la implicaci
on y si no lo es entonces el antecedente es falso. Tomemos un grupo de n + 2 personas en el cual asumimos que alguna es
comunista (en caso contrario la implicacion vale trivialmente), con n
mayor o igual a cero. Sacamos una persona cualquiera del grupo. Si
esta persona es comunista, entonces la intercambiamos con cualquier
otra del grupo para asegurarnos de que en el grupo de n + 1 personas
haya al menos una que sea comunista. Luego, por hipotesis inductiva
tenemos un grupo de n + 1 personas todas comunistas y una afuera
Y RECURSION
166
de la cual no conocemos a
un sus simpatas polticas. Intercambiamos
entonces a esta persona con cualquiera de los que ya sabemos que son
comunistas, y nos queda un grupo de n + 1 personas de las cuales todas
menos una son comunistas. Por hip
otesis inductiva entonces tienen que
ser todas comunistas, y como la que est
a aparte tambien lo es, entonces
son todos comunistas.
Ejercicio 10.6
Demuestre usando ideas an
alogas a las de los dos ejercicios anteriores que si en
un grupo de personas hay dos con la misma cantidad de pelos en la cabeza, luego
todas las personas en el grupo tienen la misma cantidad de pelos en la cabeza.
Ejercicio 10.7
Principio de las casillas. Demostrar que dados xs : [N at] y M : N at, M > 0,
P
h i : 0 i < #xs : xs.i i < M h i : 0 i < #xs : xs.i #xs M i
Ejercicio 10.8
Sean xs : [N at] y M : N at. Demostrar:
1. h i : 0 i < #xs : xs.i M i hMax i : 0 i < #xs : xs.i i M
2. h i : 0 i < #xs : xs.i M i hMin i : 0 i < #xs : xs.i i M
Ejercicio 10.9
Demostrar que las siguientes proposiciones son equivalentes:
1. h n : n 0 : P.n i P.0 h n : n 0 : P.n P.(n + 1) i
2. h n : n 0 : P.n i h n : n 0 : P.n h i : 0 i < n : P.i i i
3. Dado S N at,
hx : x 0 : x S i hx : x 0 : x S hy : 0 y < x : y
/ Sii
Ejercicio 10.10
Torres de Hanoi. Se tienen tres postes -0, 1 y 2- y n discos de distinto tama
no. En
la situaci
on inicial se encuentran todos los discos ubicados en el poste 0 en forma
decreciente seg
un el tama
no (el m
as grande en la base).
El problema consiste en llevar todos los discos al poste 2, con las siguientes
restricciones:
(i) Se puede mover s
olo un disco por vez (el que esta mas arriba en alg
un poste).
(ii) No se puede apoyar un disco sobre otro de menor tama
no.
Sea B = {0, 1, 2}. Definir una funci
on f : B 7 B 7 B 7 N at 7 [(B, B)] tal
que f.a.b.c.n calcule la secuencia de movimientos para llevar n discos del poste a
al poste c, pasando por el poste b.
Ejemplo: f.0.1.2.2 = [(0, 1), (0, 2), (1, 2)]
Captulo 11
T
ecnicas elementales para la
programaci
on
The Road goes ever on and on
Down from the door where it began.
Now far ahead the road has gone,
And I must follow, if I can,
Pursuing it with eager feet,
Until it joins some larger way
Where many paths and errands meet.
And wither then? I cannot say.
J.R.R.Tolkien:
The Lord of the Rings
169
= { hip
otesis inductiva }
x + sum.xs
El paso de separaci
on de un termino es un lema ya demostrado el cual consiste
en la aplicaci
on sucesiva de partici
on de rango, rango unitario y cambio de variables
para volver a obtener un rango del tipo de la hipotesis inductiva.
A partir de esta derivaci
on hemos obtenido el siguiente programa para sum.
sum : [N um] 7 N um
.
sum.[ ] = 0
.
sum.(x . xs) =
x + sum.xs
P
Consideremos el siguiente problema: dados N y X, calcular
i : 0 i < N : Xi .
Una forma de abordar este problema es usar la tecnica de reemplazo de constantes por variables. El objetivo es cambiar el problema original por uno mas
general, que luego se resolver
a de la manera en que hemos trabajado en la seccion
anterior.
Las constantes que aparecen en nuestro problema son 0, N y X, y cualquiera
de ellas puede ser reemplazada por una variable, dando lugar a una nueva especificaci
on del problema:
Si reemplazamos la constante N por la variable n, la nueva especificacion es
P
n : n N at : f.n =
i : 0 i < n : Xi
()
y la soluci
on del problema estar
a dada por f.N .
Si reemplazamos la constante 0 por la variable n, la nueva especificacion es
P
n : n N at : f.n =
i : n i < N : Xi
y la soluci
on del problema estar
a dada por f.0.
Si reemplazamos la constante X por la variable x, la nueva especificacion es
P
x : x IR : f.x =
i : 0 i < N : xi
y la soluci
on del problema estar
a dada por f.X.
La ventaja de las dos primeras frente a la tercera es que al variar n sobre los
naturales es posible aplicar el principio de induccion.
Trabajemos con la primera. Tratemos de encontrar una definicion recursiva de
f:
P
i : 0 i < 0 : Xi
= { rango vaco }
0
Paso inductivo (n + 1)
f.(n + 1)
= { especificaci
on () }
P
i : 0 i < n + 1 : Xi
= { c
alculo de predicados }
P
i : 0 i < n n i < n + 1 : Xi
= { partici
on de rango; (n i < n + 1) (i = n) }
P
P
i : 0 i < n : Xi +
i : i = n : Xi
= { hip
otesis inductiva y rango unitario }
f.n + X n
Por lo tanto, una definici
on recursiva de f es
f : N um 7 N um
.
f.0 = 0
.
f.(n + 1) =
f.n + X n
Si el lenguaje de programaci
on permite calcular X n , hemos terminado. En caso
contrario, es necesario desarrollar un programa para el calculo de X n .
11.3 Modularizaci
on
En algunas ocasiones, como en el ejemplo que se acaba de analizar, la solucion
del problema original requiere la soluci
on de un sub-problema. En estos casos
suele ser conveniente no atacar ambos problemas simultaneamente, sino por modulos, cada uno de los cuales debe ser independiente de los demas. Esta tecnica se
denomina modularizaci
on. En el ejemplo anterior, si modularizamos, podemos
escribir la definici
on recursiva de f de la siguiente manera:
11.3 MODULARIZACION
171
f : N um 7 N um
.
f.0 = 0
.
f.(n + 1) =
f.n + g.n
.
|[g.i = X i ]|
La independencia de m
odulos significa que una vez resuelta g, debe quedar
resuelta f . Derivemos la funci
on g:
Caso base (n = 0)
g.0
= { especificaci
on de g }
X0
= {
algebra }
1
Paso inductivo (n + 1)
g.(n + 1)
= { especificaci
on de g }
X (n+1)
= {
algebra }
X Xn
= { hip
otesis inductiva }
X g.n
Es decir,
g : N um 7 N um
.
g.0 = 1
.
g.(n + 1) =
X g.n
Teniendo una definici
on explcita de g, el problema inicial queda resuelto.
La definici
on recursiva de una funci
on puede no ser u
nica. En nuestro ejemplo,
una forma diferente de dividir el rango conduce a otra definicion recursiva de f .
Veamos:
f.(n + 1)
P
i : 0 i < n + 1 : Xi
= { c
alculo de predicados }
P
i : 0 i < 1 1 i < n + 1 : Xi
= { partici
on de rango }
P
P
i : 1 i < n + 1 : Xi
i : i = 0 : Xi +
= { rango unitario }
P
X0 +
i : 1 i < n + 1 : Xi
= { reemplazando i por j+1 }
P
X0 +
j : 1 j + 1 < n + 1 : X j+1
= {
algebra }
P
1+
j : 0 j < n : X Xj
= { distributividad de * con respecto a + }
P
1+X
j : 0 j < n : Xj
= { hip
otesis inductiva }
1 + X f.n
Por lo tanto otra definici
on recursiva de f es
f : N um 7 N um
.
f.0 = 0
.
f.(n + 1) =
1 + X f.n
173
La evaluaci
on de este programa para un numero n realiza un n
umero de reducciones que crece exponencialmente con n. Esto implica que ya para n
umeros
chicos se vuelve impracticable su evaluaci
on. La ineficiencia radica en que en el
caso inductivo se eval
ua dos veces por separado la funcion f ib. La evaluacion del
segundo sumando f ib.(n + 1) va a calcular, entre otras cosas, f ib.n, pero este valor
va a ser recalculado por el primer sumando. Este fenomeno hace que muchos valores se calculen un gran n
umero de veces. La tecnica de tuplas se basa en la idea
de calcular ambos sumandos a la vez evitando as repetir calculos. Esta mejora
permite reducir dr
asticamente la complejidad de este programa.
Usando la tecnica de tuplas se especifica
g : N at 7 (N at, N at)
g.n = (f ib.n, f ib.(n + 1))
.
Obviamente puede definirse a esta funcion como g.n = (f ib.n, f ib.(n + 1))
pero no habramos ganado nada en eficiencia. Calcularemos ahora una definicion
recursiva directa para g. N
otese que es f
acil definir ahora f ib como g.0, el primer
elemento del par.
El caso base es simple.
Caso base (n = 0)
g.0
= { especificaci
on de g }
(f ib.0, f ib.1)
= { definici
on de f ib }
(0, 1)
El caso inductivo requiere m
as cuidado
Paso inductivo (n + 1)
g.(n + 1)
= { especificaci
on de g }
(f ib.(n + 1), f ib.(n + 2))
= { definici
on de f ib }
(f ib.(n + 1), f ib.n + f ib.(n + 1))
en este punto de la derivaci
on vemos el motivo de la ineficiencia de la definicion
original en la repetici
on del c
alculo de f ib.(n + 1). Para evitar esta ineficiencia
hacemos uso de definiciones locales que nos permiten reemplazar repetidas veces
un valor. N
otese que el uso de pattern matching da lugar a una definicion muy
f
acil de leer.
175
h : N um 7 (N um, N um)
h.n = (f.n, g.n)
Derivamos ahora de manera an
aloga al caso de fibonacci una definicion recursiva para h
Caso base (n = 0)
h.0
= { especificaci
on de h }
(f.0, g.0)
= { definici
on de f y g }
(0, 1)
Paso inductivo (n + 1)
h.(n + 1)
= { especificaci
on de h }
(f.(n + 1), g.(n + 1))
= { definici
on de f y g }
(f.n + g.n, X g.n)
= { introducimos a, b }
(a + b, X b)
.
|[a = f.n
.
b = g.n]|
= { igualdad de pares }
(a + b, X b)
.
|[(a, b) = (f.n, g.n)]|
= { hip
otesis inductiva }
(a + b, X b)
.
|[(a, b) = h.n]|
Por lo tanto
h : N um 7 (N um, N um)
.
h.0 = (0, 1)
.
h.(n + 1) =
(a + b, X b)
.
|[(a, b) = h.n]|
11.5 Generalizaci
on por abstracci
on
Una tecnica muy poderosa es la generalizaci
on por abstracci
on (por algunos autores llamada inmersi
on). Esta tecnica sera usada para distintos objetivos en
este curso. En este captulo la utilizaremos como un medio para resolver una derivaci
on cuando la hip
otesis inductiva no puede aplicarse de manera directa. La idea
consiste en buscar una especificaci
on m
as general uno de cuyos casos particulares
sea la funci
on en cuesti
on. Para encontrar la generalizacion adecuada se introducen
par
ametros nuevos los cuales servir
an para dar cuenta de las subexpresiones que
no permiten aplicar la hip
otesis inductiva en la derivacion original
Ejemplo 11.4
Consideremos un predicado que determina si todas las sumas parciales de una lista
son mayores o iguales a cero. La especificaci
on esta dada por:
P : [N um] 7 Bool
P.xs h i : : 0 i < #xs : sum.(xsi) 0 i
El caso base es simple y lo dejamos como ejercicio para el lector (el resultado
es T rue por rango vaco del cuantificador).
Calculamos el caso inductivo.
Paso inductivo (x . xs)
P.(x . xs)
= { especificaci
on de P }
h i : 0 i < #(x . xs) : sum.((x . xs)i) 0 i
= { definici
on de # }
h i : 0 i < 1 + #xs : sum.((x . xs)i) 0 i
= { separaci
on de un termino }
sum.((x . xs)0) 0 h i : 0 i < #xs : sum.((x . xs)(i + 1) 0 i
= { definici
on de}
sum.[ ] 0 h i : 0 i < #xs : sum.(x . (xsi)) 0 i
POR ABSTRACCION
11.5 GENERALIZACION
177
= { definici
on de sum }
0 0 h i : 0 i < #xs : x + sum.(xsi) 0 i
En este punto notamos que podra aplicarse la hipotesis inductiva de no ser
por la x que esta sumando. No parece haber ninguna forma de eliminar esta x por
lo cual se propone derivar la definici
on de una funcion generalizada Q especificada
como sigue.
Q : N um 7 [N um] 7 Bool
Q.n.xs h i : 0 i < #xs : n + sum.(xsi) 0 i
Esta nueva especificaci
on esta inspirada en la u
ltima expresion de la derivacion
de P . Sin embargo a partir de saber como resolver P en terminos de Q puede
olvidarse la derivaci
on de P y y realizar la de Q de manera independiente, pese
a que esta ser
a en general similar a la anterior. Que esta nueva derivacion pueda
llevarse adelante depender
a de las propiedades del dominio en cuestion (en este
caso los n
umeros, en particular la asociatividad de la suma) y puede no llegar a
buen puerto o tener que volver a generalizarse a su vez. La programacion es una
actividad creativa y esto se manifiesta en este caso en la eleccion de las posibles
generalizaciones.
Lo primero que puede determinarse antes de comenzar la derivacion del nuevo
predicado Q es si este efectivamente generaliza a P . Esto puede determinarse a
partir de la especificaci
on dado que P.xs = Q.0.xs debido a que 0 es el neutro de
la suma. Puede entonces definirse
.
P.xs = Q.0.xs
y derivar directamente Q
Calculamos el caso base.
Caso base (xs = [ ])
Q.n.[ ]
= { especificaci
on de Q }
h i : 0 i < #[ ] : n + sum.([ ]i) 0 i
= { definici
on de # }
h i : 0 i < 0 : n + sum.([ ]i) 0 i
= { rango vaco }
T rue
Calculamos ahora el caso inductivo.
P
Volvamos a considerar la especificaci
on n : n N at : f.n =
i : 0 i < n : Xi
para el primer caso.
POR ABSTRACCION
11.5 GENERALIZACION
179
f.(2 n)
= { especificaci
on de f }
P
i : 0 i < 2 n : Xi
= { partici
on de rango }
P
P
i : n i < 2 n : Xi
i : 0 i < n : Xi +
= { reemplazando i n + i en el segundo termino }
P
P
i : n n + i < 2 n : X n+i
i : 0 i < n : Xi +
= {
algebra }
P
P
i : 0 i < n : Xn Xi
i : 0 i < n : Xi +
= { distributividad de * con respecto a + }
P
i : 0 i < n : Xi + Xn
i : 0 i < n : Xi
= {
algebra }
(1 + X n )
i : 0 i < n : Xi
= { hip
otesis inductiva }
(1 + X n ) f.n
Hasta aqu hemos logrado escribir f.(2 n) = (1 + X n ) f.n, pero a
un nos
queda X n en la expresi
on. Para su c
alculo no podemos usar la funcion g obtenida
anteriormente (p
ag. 170), pues su costo es lineal, lo que hara imposible que el
costo total resultara logartmico. M
as adelante veremos un ejemplo que muestra
como definir una funci
on para el c
alculo de la exponencial con costo logartmico.
Probemos con una partici
on diferente del rango.
f.(2 n)
= { especificaci
on de f }
P
i : 0 i < 2 n : Xi
= { partici
on de rango }
P
P
i : 0 i < 2 n i par : X i +
i : 0 i < 2 n i impar : X i
= { reemplazando i 2i en el primer termino e i 2i+1 en el segundo
}
P
P
i : 0 2 i < 2 n : X 2i +
i : 0 2 i + 1 < 2 n : X 2i+1
= {
algebra }
P
P
i : 0 i < n : X 2i +
i : 0 i < n : X X 2i
= { distributividad de * con respecto a + }
P
i : 0 i < n : X 2i + X
i : 0 i < n : X 2i
P
(1 + X)
i : 0 i < n : X 2i
= {
algebra }
E
DP
i
i : 0 i < n : (X 2 )
(1 + X)
Aqu nos encontramos con un problema, dado que no podemos aplicar la hip
otesis inductiva, pues no aparece X sino X 2 . Esto puede solucionarse otra vez
generalizando la funci
on f . La idea es definir una funcion que dependa de ciertos
par
ametros, de manera tal que f sea un caso particular de la nueva funcion (para
ciertos valores fijos de los
par
ametros).
P
Sea g especificada por x, n : : g.x.n =
i : 0 i < n : xi . La funcion
g introduce el par
ametro x. f es un caso particular de g que se obtiene cuando el
par
ametro x toma el valor fijo X, pues g.X.n = f.n.
Usando el razonamiento anterior donde simplemente se reemplaza X por x es
posible obtener una definici
on recursiva para el caso par de g.
g.x.(2 n)
= { especificaci
on de g }
P
i : 0 i < n : xi
= { demostraci
on anterior }
E
DP
i
i : 0 i < n : (x2 )
(1 + x)
.
Aqu podramos aplicar hip
otesis inductiva obteniendo g.x.(2 n) = (1 + x)
g.(x x).n. Pero para hacerlo tenemos que garantizar que el segundo parametro de
g a la derecha de la definici
on sea menor que este mismo parametro a la izquierda, o
sea n < 2n (ver inducci
on generalizada en seccion 10.2). Esto es cierto u
nicamente
si n > 0. Por lo tanto falta encontrar la definicion de g para el caso baso n = 0.
Ejercicio: Derivar la definici
on de g para el caso base.
Todava falta encontrar una definici
on de g para el caso en que el parametro
sea impar.
g.x.(2 n + 1)
= { especificaci
on de g }
P
i : 0 i < 2 n + 1 : xi
= { reemplazando i i + 1 }
P
i : 0 i + 1 < 2 n + 1 : xi+1
POR ABSTRACCION
11.5 GENERALIZACION
181
= {
algebra }
P
i : 1 i < 2 n : xi+1
= { separaci
on del termino }
P
1+
i : 0 i < 2 n : xi+1
= {
algebra }
P
1+
i : 0 i < 2 n : x xi
= { distributividad de * con respecto a + }
P
1+x
i : 0 i < 2 n : xi
= { hip
otesis inductiva }
1 + x g.x.(2 n)
Por lo tanto, una posible definici
on de g sera
g : N um 7 N um 7 N um
.
g.x.0 = 0
.
g.x.(2 n) = (1 + x) g.(x x).n
.
g.x.(2 n + 1) = 1 + x g.x.(2 n)
si n > 0
o utilizando an
alisis por casos
g : N um 7 N um 7 N um
.
g.x.n =
( n=0 0
n 6= 0 ( n mod 2 = 0
n mod 2 = 1
)
)
Es claro que el costo de calcular g (y consecuentemente el de f ) resulta logartmico, pues cuando el segundo argumento es par (2 n), la recursividad nos lleva
a evaluar g en un par de argumentos tal que el segundo de ellos es exactamente
la mitad del segundo argumento original (n), mientras que cuando el segundo argumento es impar (2 n + 1), la recursividad nos lleva a evaluar g en un par de
argumentos tal que el segundo de ellos es par (2 n).
Ejercicio: demostrar que el costo de g es logartmico (depende basicamente de
log2 n).
e.x.(2 k + 1)
= { especificacion de e }
x2k+1
= {
algebra }
= { algebra }
k 2
x (xk )
= {
algebra }
= { algebra }
(x )
xk xk
= { hip
otesis inductiva }
e.x.k e.x.k
= { introducci
on de a }
aa
|[a = e.x.k]|
x xk xk
= { hipotesis inductiva
}
x e.x.k e.x.k
= { introduccion de a }
xaa
|[a = e.x.k]|
(x2 )
POR ABSTRACCION
11.5 GENERALIZACION
183
= { hip
otesis inductiva }
e.x2 .k
= {
algebra }
e.(x x).k
y sabiendo como calcular la exponencial con exponente par, podemos usar esta
definici
on para el caso impar, pues
e.x.(2 k + 1)
= { especificaci
on de e }
x2k+1
= {
algebra }
x x2k
= { c
alculo anterior }
x e.(x x).k
Con lo cual podemos dar la siguiente definicion recursiva para el calculo de la
exponencial:
e : N um 7 N at 7 N um
.
e.x.0 = 1
.
n 6= 0 e.x.n =
( n mod 2 = 0 e.(x x).(n div 2)
2
n mod 2 = 1 x e.(x x).((n 1) div 2)
)
Finalmente, podemos usar an
alisis por casos para dar una definicion de e.x.n
v
alida para todo n:
e : N um 7 N at 7 N um
.
e.x.n =
( n=0 1
2
n 6= 0 ( n mod 2 = 0 e.(x x).(n div 2)
2 n mod 2 = 1 x e.(x x).((n 1) div 2)
)
)
11.6 Ejercicios
Ejercicio 11.1
Especificar y derivar la funci
on iguala : [A] 7 A 7 Bool que verifica si todos los
elementos de una lista son iguales a un valor dado.
Ejercicio 11.2
Sea m : [Int] 7 Int la funci
on que devuelve el mnimo elemento de una lista de
enteros. Obtener una definici
on recursiva para m.
Ejercicio 11.3
Calcular la funci
on que eleva un n
umero natural al cubo usando solo sumas. La
especificaci
on es la obvia: f.x = x3 . Sugerencia: usar induccion, modularizacion
varias veces y luego tecnica de tuplas para mejorar la eficiencia.
Ejercicio 11.4
Calcular la funci
on de Fibolucci especificada como sigue:
f : N at 7 N at
P
f.n = h i : 0 i < n : f ib.i f ib.(n i) i
Ejercicio 11.5
Sea f la funci
on que resuelve el problema de las torres de Hanoi (ver seccion 10.4,
ejercicio 10.10). Calcular una definici
on recursiva para la funcion t : B 7 B 7
B 7 N at 7 ([(B, B)], [(B, B)], [(B, B)]) tal que
t.a.b.c.n = (f.a.b.c.n, f.b.c.a.n, f.c.b.a.n)
Sugerencia: calcular t.a.b.c.0, t.a.b.c.1 y t.a.b.c.(n + 2).
Captulo 12
Ejemplos de derivaci
on de
programas funcionales
No sabas que para abrir un aujerito hay que ir sacando la tierra
y tir
andola lejos?
Julio Cortazar: Rayuela
DE PROGRAMAS FUNCIONALES
186CAPITULO 12. EJEMPLOS DE DERIVACION
ev : N um 7 [N um] 7 N um
P
ev.xs.y =
i : 0 i < #xs : xs.i y i
Ahora estamos en condiciones de derivar una definicion recursiva para ev, haciendo inducci
on en la lista de coeficientes del polinomio.
Caso base
ev.[ ].y
= { especificaci
on de ev; #[ ] = 0 }
P
i : 0 i < 0 : [ ].i y i
= { rango vaco }
0
Paso inductivo
ev.(x . xs).y
= { especificaci
on de ev; #(x . xs) = 1 + #xs }
P
i : 0 i < 1 + #xs : (x . xs).i y i
= { partici
on de rango }
P
P
i : 1 i < 1 + #xs : (x . xs).i y i
i : 0 i < 1 : (x . xs).i y i +
= { rango unitario; i i + 1 en el segundo termino }
P
(x . xs).0 y 0 +
i : 1 i + 1 < 1 + #xs : (x . xs).(i + 1) y i+1
= {
algebra; definici
on de indexar }
P
x+
i : 0 i < #xs : xs.i y y i
= { distributividad de con respecto a + }
P
x+y
i : 0 i < #xs : xs.i y i
= { hip
otesis inductiva }
x + y ev.xs.y
Por lo tanto una definici
on recursiva para ev es:
ev : N um 7 [N um] 7 N um
.
ev.[ ].y = 0
.
ev.(x . xs).y =
x + y ev.xs.y
12.1 EJEMPLOS NUMERICOS
187
X1
i!
i0
i :0i<N :
1
i!
P
f.n =
i :0i<n:
1
i!
P
i : 0 i < 0 : i!1
= { rango vaco }
0
DE PROGRAMAS FUNCIONALES
188CAPITULO 12. EJEMPLOS DE DERIVACION
Paso inductivo
f.(n + 1)
= { especificaci
on de f }
P
i :0i<n+1:
1
i!
= { partici
on de rango }
P
P
i :ni<n+1:
i : 0 i < n : i!1 +
1
i!
= { hip
otesis inductiva; rango unitario }
f.n +
1
n!
12.1 EJEMPLOS NUMERICOS
189
Paso inductivo
h.(n + 1)
= { especificaci
on de h }
(f.(n + 1), g.(n + 1))
= { definici
on de f y g }
1
(f.n +
, (n + 1) g.n)
g.n
= { introducimos a, b }
1
(a + , (n + 1) b)
b
|[(a, b) = (f.n, g.n)]|
= { hip
otesis inductiva }
1
(a + , (n + 1) b)
b
|[(a, b) = h.n]|
De esta manera, h queda definida recursivamente por:
h : N um 7 (N um, N um)
.
h.0 = (0, 1)
1
.
h.(n + 1) = (a + , (n + 1) b)
b
|[(a, b) = h.n]|
o bien, usando an
alisis por casos,
h : N um 7 (N um, N um)
.
h.n =
( n = 0 (0, 1)
1
2 n 6= 0 (a + , n b)
b
|[(a, b) = h.(n 1)]|
)
Ejemplo 12.3 (b
usqueda lineal)
Dada f : N at 7 Bool y suponiendo h n : 0 n : f.n i, encontrar el mnimo
natural x tal que f.x. La expresi
on que especifica este natural es la siguiente
hMin i : 0 i f.i : i i
DE PROGRAMAS FUNCIONALES
190CAPITULO 12. EJEMPLOS DE DERIVACION
El metodo a usar para resolver este problema es el de reemplazo de constantes
por variables. La u
nica constante que puede ser reemplazada es 0.
Consideramos una funci
on g : N at 7 N at (suponiendo f ya dada) especificada
como
g.n = hMin i : n i f.i : i i
Obviamente se encuentra el valor requerido aplicando g al valor 0.
Para poder hacer inducci
on la u
nica informacion que tenemos sobre f es que
f.N vale para alg
un N , por lo tanto, podemos trabajar usando induccion (generalizada) sobre N n haciendo an
alisis por casos.
g.n
= { especificaci
on de g }
hMin i : n i f.i : i i
= { partici
on de rango }
hMin i : n = i f.i : i i min hMin i : n + 1 i f.i : i i
= { Leibniz }
hMin i : n = i f.n : i i min hMin i : n + 1 i f.i : i i
= { hip
otesis inductiva }
hMin i : n = i f.n : i i min g.(n + 1)
Ahora se hace necesario un an
alisis por casos de acuerdo al valor de f.n.
El caso en que el predicado es cierto va a transformarse en el caso base de la
funci
on.
= { caso f.n }
hMin i : n = i : i i min g.(n + 1)
= { rango unitario }
n min g.(n + 1)
= { n g.(n + 1) }
n
El caso en que es falso ser
a el caso inductivo.
= { caso f.n }
hMin i : n = i F alse : i i min g.(n + 1)
191
= { rango vaco }
+ min g.(n + 1)
= { neutro del min }
g.(n + 1)
La definici
on de g quedar
a entonces como
g : N um 7 N um
.
g.n =
( f.n n
2
f.n g.(n + 1)
)
DE PROGRAMAS FUNCIONALES
192CAPITULO 12. EJEMPLOS DE DERIVACION
Caso base (xs = [ ])
P.[ ]
{ especificaci
on de P ; #[ ] = 0 }
h i : 0 i < 0 : [ ].i = sum.([ ]i) i
{ rango vaco }
F alse
Paso inductivo (x . xs)
P.(x . xs)
{ especificaci
on de P ; definici
on de # }
h i : 0 i < 1 + #xs : (x . xs).i = sum.((x . xs)i) i
{ separaci
on de un termino }
(x . xs).0 = sum.(x . xs)0
h i : 0 i < #xs : (x . xs).(i + 1) = sum.((x . xs)(i + 1)) i
{ definiciones de . y de}
x = sum.[ ] h i : 0 i < #xs : xs.i = sum.x . (xsi) i
{ definici
on de sum }
x = 0 h i : 0 i < #xs : xs.i = x + sum.(xsi) i
La presencia de x dentro del termino de la cuantificacion existencial hace que
no podamos aplicar la hip
otesis inductiva, por lo que es necesario generalizar la
funci
on P .
Sea
Q.n.xs h i : 0 i < #xs : xs.i = n + sum.(xsi) i
La funci
on Q es efectivamente una generalizacion de P , pues P.xs = Q.0.xs.
Derivemos ahora una definici
on recursiva para Q.
Caso base (xs = [ ])
Q.n.[ ]
{ especificaci
on de Q; #[ ] = 0 }
h i : 0 i < 0 : [ ].i = n + sum.([ ]i) i
{ rango vaco }
F alse
193
DE PROGRAMAS FUNCIONALES
194CAPITULO 12. EJEMPLOS DE DERIVACION
en la lista. Sean ct y cf las funciones que cuentan la cantidad de T rue y de
F alse respectivamente. Podemos especificar f
acilmente estas funciones utilizando
el cuantificador de conteo N (p
ag. 103):
ct : [Bool] 7 N um
ct.xs = hN i : 0 i < #xs : xs.i i
cf : [Bool] 7 N um
cf.xs = hN i : 0 i < #xs : xs.i i
La funci
on bal puede especificarse entonces por:
bal : [Bool] 7 N um
bal.xs (ct.xs = cf.xs)
A fin de simplificar la derivaci
on de una definicion recursiva para bal, derivemos
en primer termino propiedades de las funciones ct y cf . Como de costumbre,
haremos inducci
on en la longitud de la lista.
Caso base
ct.[ ]
= { especificaci
on de ct; definici
on de # }
hN i : 0 i < 0 : [ ].i i
= { rango vaco }
0
Paso inductivo
ct.(x . xs)
= { especificaci
on de ct; definici
on de # }
hN i : 0 i < 1 + #xs : (x . xs).i i
= { partici
on de rango }
hN i : i = 0 : (x . xs).i i + hN i : 1 i < 1 + #xs : (x . xs).i i
= { i i + 1 en el segundo termino }
hN i : i = 0 : (x . xs).i i + hN i : 1 i + 1 < 1 + #xs : (x . xs).(i + 1) i
195
= {
algebra; propiedad de indexar }
hN i : i = 0 : (x . xs).i i + hN i : 0 i < #xs : xs.i i
= { hip
otesis inductiva }
hN i : i = 0 : (x . xs).i i + ct.xs
El primer termino es 1 si x es T rue y 0 si x es F alse. Por lo tanto, la funcion
ct satisface:
ct : [Bool] 7 N um
.
ct.[ ] = 0
.
ct.(T rue .xs) =
1 + ct.xs
.
ct.(F alse .xs) =
ct.xs
An
alogamente se demuestra que la funcion cf satisface:
cf : [Bool] 7 N um
.
cf.[ ] = 0
.
cf.(T rue .xs) =
cf.xs
.
cf.(F alse .xs) =
1 + cf.xs
Ejercicio: Derivar la funci
on cf .
Derivemos ahora una definici
on recursiva para la funcion bal.
Caso base
bal.[ ]
{ especificaci
on de bal }
ct.[ ] = cf.[ ]
{ propiedad de ct y cf }
T rue
Las propiedades de ct y cf nos inducen a derivar el paso inductivo haciendo
un an
alisis por casos, seg
un el valor del primer elemento de la lista.
bal.(T rue .xs)
{ especificaci
on de bal }
ct.(T rue .xs) = cf.(T rue .xs)
{ propiedad de ct y cf }
1 + ct.xs = cf.xs
DE PROGRAMAS FUNCIONALES
196CAPITULO 12. EJEMPLOS DE DERIVACION
Del mismo modo se obtiene bal.(F alse .xs) (ct.xs = 1 + cf.xs). Como no es
posible aplicar la hip
otesis inductiva, debemos generalizar la funcion y comenzar
a derivar nuevamente a partir de la generalizacion. Sea:
g : N um 7 [Bool] 7 N um
g.k.xs (k + ct.xs = cf.xs)
La funci
on g es efectivamente una generalizacion de bal, pues bal.xs = g.0.xs.
Derivemos, entonces, una definici
on recursiva para g.
gbal.k.[ ]
{ especificaci
on de gbal }
k + ct.[ ] = cf.[ ]
{ propiedad de ct y cf }
k=0
caso inductivo cuando la lista comienza con T rue.
g.k.(T rue .xs)
{ especificaci
on de g }
k + ct.(T rue .xs) = cf.(T rue .xs)
{ propiedad de ct y cf }
k + 1 + ct.xs = cf.xs
{ hip
otesis inductiva }
g.(k + 1).xs
El caso en que la lista comience con F alse es analogo y se deja como ejercicio.
Por lo tanto, una definici
on recursiva para g es:
g : N um 7 [Bool] 7 N um
.
g.k.[ ] = k = 0
.
g.k.(T rue .xs) = g.(k + 1).xs
.
g.k.(F alse .xs) =
g.(k 1).xs
12.3 EJERCICIOS
197
12.3 Ejercicios
Ejercicio 12.1 (lista de iguales)
Derivar una definici
on recursiva para la funcion iguales : [A] 7 Bool que determina si los elementos de una lista dada son todos iguales entre s.
Ejercicio 12.2 (lista creciente)
Derivar una definici
on recursiva para la funcion creciente : [Int] 7 Bool que determina si los elementos de una lista de enteros estan ordenados en forma creciente.
Ejercicio 12.3
Derivar una definici
on recursiva para la funcion f : Int 7 [N um] 7 Bool que
determina si el k-esimo elemento de una lista de n
umeros aloja el mnimo valor de
la misma..
Ejercicio 12.4 (funci
on minout)
Derivar una definici
on recursiva para la funcion minout : [N at] 7 N at que, dada una lista de naturales, selecciona el menor natural que no esta en la misma
(sugerencia: usar b
usqueda lineal).
Ejercicio 12.5
Derivar una definici
on recursiva para la funcion P : [N um] 7 Bool que, dada una
lista de naturales, determina si alg
un elemento de la lista es igual a la suma de
todos los otros elementos de la misma.
Ejercicio 12.6
Derivar una definici
on recursiva para la funcion f especificada como sigue:
f : [N um] 7 [N um] 7 N um
f.xs.ys = hMin i, j : 0 i < #xs 0 j < #ys : |xs.i ys.j| i
Ejercicio 12.7
Derivar una funci
on recursiva a partir de la siguiente especificacion
J K : [N at] 7 N at
P
JxsK = h i : 0 i < #xs : xs.i (i + 1)! i
El costo de calcular la funci
on debe ser lineal en la longitud de la lista.
Ayuda: Para encontrar la funci
on va a haber que generalizar la funcion. Si no
encuentra una generalizaci
on que resuelva el problema intente con la siguiente:
JxsKm =
DP
(i+m)!
m!
DE PROGRAMAS FUNCIONALES
198CAPITULO 12. EJEMPLOS DE DERIVACION
Ejercicio 12.8
Derivar una funci
on recursiva a partir de la siguiente especificacion
J K : [N at] 7 N at
DP
i : 0 i < #xs : xs.i
JxsK =
1
(i+2)!
Captulo 13
13.1 B
usqueda de un segmento
El siguiente ejemplo es de un predicado que se define inductivamente sobre dos
listas.
Se especifica el predicado P que determina si una lista es un segmento de otra
de la siguiente manera
P : [A] 7 [A] 7 Bool
P.xs.ys = h as, bs : : ys = as ++ xs ++ bs i
Para resolver esta funci
on puede estructurarse la derivacion inductiva de varias
maneras. La m
as simple (aunque no necesariamente la mas corta) es considerar los
cuatro casos posibles (vaca-vaca, vaca - no vaca, etc). Dado que la lista vaca es
segmento de cualquier otra lista, analizaremos primero el caso en que xs sea vaca
para cualquier valor posible de ys
199
200
Caso base (xs = [ ])
P.[ ].ys
= { especificaci
on de P }
h as, bs : : ys = as ++ [ ] ++ bs i
= { def. de ++ }
h as, bs : : ys = as ++ bs i
= { partici
on de rango (as = [ ] y as 6= [ ]) }
h as, bs : as = [ ] : ys = as ++ bs i h as, bs : as 6= [ ] : ys = as ++ bs i
= { anidado; rango unitario }
h bs : : ys = [ ] ++ bs i h as, bs : as 6= [ ] : ys = as ++ bs i
= { def. de ++ }
h bs : : ys = bs i h as, bs : as 6= [ ] : ys = as ++ bs i
= { intercambio }
h bs : ys = bs : T rue i h as, bs : as 6= [ ] : ys = as ++ bs i
= { rango unitario }
T rue h as, bs : as 6= [ ] : ys = as ++ bs i
= { absorbente para el }
T rue
El pr
oximo paso ser
a encontrar un definici
on inductiva para el caso xs distinto
de lista vaca. Para ello volveremos a aplicar induccion pero sobre la lista ys.
El caso base es como sigue
Caso (x . xs, ys = [ ])
P.(x . xs).[ ]
= { especificaci
on de P }
h as, bs : : [ ] = as ++ (x . xs) ++ bs i
= { igualdad de listas }
h as, bs : : [ ] = as [ ] = (x . xs) [ ] = bs i
= { igualdad de listas }
h as, bs : : [ ] = as F alse [ ] = bs i
= { rango vaco }
F alse
El caso inductivo ser
a
13.1 BUSQUEDA
DE UN SEGMENTO
Caso (x . xs, y . ys)
P.(x . xs).(y . ys)
= { especificaci
on de P }
h as, bs : : y . ys = as ++ (x . xs) ++ bs i
= { partici
on de rango (as = [ ] y as 6= [ ]) }
h as, bs : as = [ ] : y . ys = as ++ (x . xs) ++ bs i
h as, bs : as 6= [ ] : y . ys = as ++ (x . xs) ++ bs i
= { anidado; rango unitario }
h bs : : y . ys = [ ] ++ (x . xs) ++ bs i
h as, bs : as 6= [ ] : y . ys = as ++ (x . xs) ++ bs i
= { reemplazo as a . as (v
alido por as 6= [ ]) }
h bs : : y . ys = [ ] ++ (x . xs) ++ bs i
h a, as, bs : a . as 6= [ ] : y . ys = (a . as) ++ (x . xs) ++ bs i
= { def. ++ ; igualdad de listas (a . as 6= [ ] T rue) }
h bs : : y . ys = (x . xs) ++ bs i
h a, as, bs : : y . ys = (a . as) ++ (x . xs) ++ bs i
= { igualdad de listas }
h bs : : y = x ys = xs ++ bs i
h a, as, bs : : y = a ys = as ++ (x . xs) ++ bs i
= { distributiva del con el }
x = y h bs : : ys = xs ++ bs i
h a, as, bs : : y = a ys = as ++ (x . xs) ++ bs i
= { intercambio }
x = y h bs : : ys = xs ++ bs i
h a, as, bs : y = a : ys = as ++ (x . xs) ++ bs i
= { anidado; rango unitario }
x = y h bs : : ys = xs ++ bs i
h as, bs : : ys = as ++ (x . xs) ++ bs i
= { modularizaci
on; hip
otesis inductiva }
(y = x Q.xs.ys) P.(x . xs).ys
Donde el predicado Q queda especificado por
Q : [A] 7 [A] 7 Bool
Q.xs.ys = h bs : : ys = xs ++ bs i
201
202
N
otese que el predicado Q es m
as simple que P y que su especificacion podra
leerse en terminos informales como Q.xs.ys determina si xs es un segmento inicial
de ys.
Derivaremos entonces una definici
on recursiva para Q. El patron recursivo usado ser
a similar al usado para P .
Caso base (xs = [ ])
Q.[ ].ys
= { especificaci
on de P }
h bs : : ys = [ ] ++ bs i
= { def. de ++ }
h bs : : ys = bs i
= { intercambio }
h bs : ys = bs : T rue i
= { termino constante }
T rue
El caso base cuando la primera lista no es vaca sera entonces
Caso (x . xs, ys = [ ])
Q.(x . xs).[ ]
= { especificaci
on de P }
h bs : : [ ] = (x . xs) ++ bs i
= { igualdad de listas }
h bs : : [ ] = (x . xs) [ ] = bs i
= { igualdad de listas }
h bs : : F alse [ ] = bs i
= { intercambio, rango vaco }
F alse
y el caso inductivo sobre ys ser
a
Caso (x . xs, y . ys)
Q.(x . xs).(y . ys)
= { especificaci
on de P }
h bs : : y . ys = (x . xs) ++ bs i
13.2 PROBLEMA DE LOS PARENTESIS
EQUILIBRADOS
203
= { definici
on de ++ }
h bs : : y . ys = x . (xs ++ bs) i
= { igualdad de listas }
h bs : : y = x ys = xs ++ bs i
= { distributiva del con el }
y = x h bs : : ys = xs ++ bs i
= { hip
otesis inductiva }
y = x Q.xs.ys
El programa completo queda entonces
P : [N um] 7 [N um] 7 Bool
Q : [N um] 7 [N um] 7 Bool
.
P.[ ].ys = T rue
.
P.(x . xs).[ ] = F alse
.
P.(x . xs).(y . ys) =
(x = y Q.xs.ys) P.(x . xs).ys
.
Q.[ ].ys = T rue
.
Q.(x
.
xs).[ ] = F alse
.
Q.(x . xs).(y . ys) =
x = y Q.xs.ys
Nota: La funci
on derivada implementa un algoritmo de b
usqueda de cadenas cuyo costo es el producto de las longitudes de las listas. Los algoritmos de b
usqueda
de cadenas han sido muy estudiados. Algunos tienen costo proporcional a la longitud del texto sobre el que se quiere buscar pero utilizan estructuras intermedias
para lograrlo (tablas, aut
omatas, etc.). Para una rese
na de los mas conocidos ver
[Wik08].
204
N
otese la similitud de este problema con el de la lista balanceada (la expresion
matem
atica puede pensarse como una lista de caracteres). En este caso, ademas de
plantear que la cantidad de elementos de cada clase sea la misma, debemos exigir
tambien que en todo momento la cantidad de parentesis izquierdos sea mayor o
igual que la cantidad de parentesis derechos ledos.
La forma de resolver el problema es similar a la del ejemplo 12.5. Sean abr y
cie las funciones que cuentan la cantidad de parentesis izquierdos (abren) y derechos (cierran), respectivamente. Podemos especificar estas funciones de la siguiente
manera:
abr : [Char] 7 N um
abr.xs = hN i : 0 i < #xs : xs.i = (0 i
cie : [Char] 7 N um
cie.xs = hN i : 0 i < #xs : xs.i = )0 i
La definici
on inductiva de estas funciones es facil de calcular y se deja como
ejercicio.
abr : [Char] 7 N um
.
abr.[ ] = 0
.
0
abr.(( .xs) =
1 + abr.xs
.
0
abr.() . xs) =
abr.xs
cie : [Char] 7 N um
.
cie.[ ] = 0
.
cie.((0 .xs) =
cie.xs
.
cie.()0 . xs) =
1 + cie.xs
La funci
on pareq que resuelve el problema puede especificarse como sigue
pareq : [Char] 7 Bool
pareq.xs h i : 0 i < #xs : abr.(xsi) cie.(xsi)i abr.xs = cie.xs
o bien usando el estilo de segmentos
13.2 PROBLEMA DE LOS PARENTESIS
EQUILIBRADOS
205
pareq : [Char] 7 Bool
pareq.xs h as, bs : xs = as ++ bs : abr.as cie.asi abr.xs = cie.xs
Usaremos esta u
ltima especificaci
on. Derivemos ahora una definicion recursiva
para la funci
on pareq.
Caso base (xs = [ ])
pareq.[ ]
{ especificaci
on de pareq }
h as, bs : [ ] = as ++ bs : abr.as cie.as i abr.[ ] = cie.[ ]
{ definici
on de ++ ; propiedad de abr y cie }
h as, bs : [ ] = as ++ bs as = [ ] bs = [ ] : abr.as cie.as i 0 = 0
{ anidado; rango unitario;
algebra; calculo proposicional }
h bs : [ ] = bs : abr.[ ] cie.[ ] i
{ rango unitario; definici
on de abr y cie }
T rue
Para el paso inductivo analizaremos el caso en que el primer elemento de la
lista sea un parentesis abierto.
Paso inductivo ((0 .xs)
pareq.((0 .xs)
{ especificaci
on de pareq }
h as, bs : (0 .xs = as ++ bs : abr.as cie.as i abr.((0 .xs) = cie.((0 .xs)
{ partici
on de rango (as = [ ] y as 6= [ ]) }
h as, bs : (0 .xs = as ++ bs as = [ ] : abr.as cie.as i
h as, bs : (0 .xs = as ++ bs as 6= [ ] : abr.as cie.as i
abr.((0 .xs) = cie.((0 .xs)
{ anidado; rango unitario; igualdad de listas }
h bs : (0 .xs = bs : abr.[ ] cie.[ ] i
h as, bs : (0 .xs = as ++ bs as 6= [ ] : abr.as cie.as i
abr.((0 .xs) = cie.((0 .xs)
{ definici
on de abr y cie }
h bs : (0 .xs = bs : 0 0 i
h as, bs : (0 .xs = as ++ bs as 6= [ ] : abr.as cie.as i
abr.((0 .xs) = cie.((0 .xs)
206
{ termino constante; c
alculo proposicional }
h as, bs : (0 .xs = as ++ bs as 6= [ ] : abr.as cie.as i
abr.((0 .xs) = cie.((0 .xs)
{ reemplazo as a . as (v
alido por as 6= [ ]) }
h a, as, bs : (0 .xs = (a . as) ++ bs a . as 6= [ ] : abr.(a . as) cie.(a . as) i
abr.((0 .xs) = cie.((0 .xs)
{ anidado; rango unitario; igualdad de listas }
h as, bs : xs = as ++ bs : abr.((0 .as) cie.((0 .as) i
abr.((0 .xs) = cie.((0 .xs)
{ propiedad de abr y cie }
h as, bs : xs = as ++ bs : 1 + abr.as cie.as i
1 + abr.xs = cie.xs
Con esto hemos llegado a un punto donde resulta imposible aplicar la hipotesis
inductiva. Probemos generalizar la funci
on. Sea:
g : N um 7 [Char] 7 Bool
g.k.xs h as, bs : xs = as ++ bs : k + abr.as cie.as i k + abr.xs = cie.xs
Es claro que g generaliza a pareq, pues g.0.xs = pareq.xs. Derivemos una
definici
on recursiva para g.
Caso base (xs = [ ])
g.k.[ ]
{ razonamiento an
alogo al anterior }
k=0
Paso inductivo (( . xs)
g.k.(( . xs)
{ especificaci
on de g }
h as, bs : ( . xs = as ++ bs : k + abr.as cie.as i
k + abr.(( . xs) = cie.(( . xs)
{ razonamiento an
alogo al anterior }
h bs : ( . xs = bs : k + abr.[ ] cie.[ ] i
h as, bs : xs = as ++ bs : k + abr.(( . as) cie.(( . as) i
k + abr.(( . xs) = cie.(( . xs)
207
{ rango unitario;
algebra; propiedad de abr y cie }
k 0 h as, bs : xs = as ++ bs : k + abr.(( . as) cie.(( . as) i
k + abr.(( . xs) = cie.(( . xs)
{ propiedad de abr y cie }
k 0 h as, bs : xs = as ++ bs : k + 1 + abr.as cie.as i
k + 1 + abr.xs = cie.xs
{ hip
otesis inductiva }
k 0 g.(k + 1).xs
El caso ) . xs es simetrico.
Ejercicio: Derivar el caso ) . xs.
Finalmente, podemos dar la siguiente definicion recursiva para la funcion g:
g : N um 7 [Char] 7 Bool
.
g.k.[ ] = (k = 0)
.
g.k.(( . xs) = k 0 g.(k + 1).xs
.
g.k.() . xs) =
k 0 g.(k 1).xs
208
209
210
= { rango unitario }
hMin cs : x . xs = [ ] ++ cs : sum.[ ] i
min hMin b, bs, cs : x . xs = (b . bs) ++ cs (b . bs) 6= [ ] : sum.(b . bs) i
= { termino constante; definici
on de sum.[ ] }
0 min hMin b, bs, cs : x . xs = (b . bs) ++ cs (b . bs) 6= [ ] : sum.(b . bs) i
= { definici
on de ++ ; definici
on de igualdad de listas }
0 min hMin b, bs, cs : x . xs = b . (bs ++ cs) : sum.(b . bs) i
= { definici
on de igualdad de listas }
0 min hMin b, bs, cs : x = b xs = bs ++ cs : sum.(b . bs) i
= { anidado; rango unitario }
0 min hMin bs, cs : xs = bs ++ cs : sum.(x . bs) i
= { definici
on de sum }
0 min hMin bs, cs : xs = bs ++ cs : x + sum.bs i
= { distributividad de + con respecto a min (el rango es no vaco) }
0 min (x + hMin bs, cs : xs = bs ++ cs : sum.bs i)
= { hip
otesis inductiva }
0 min (x + g.xs)
Por lo tanto,
g : [N um] 7 N um
.
g.[ ] = 0
.
g.(x . xs) =
0 min (x + g.xs)
De esta manera, tenemos f.(x . xs) = 0 min (x + g.xs) min f.xs. Pero f.xs
0 xs (si todos los elementos de la lista son positivos, el mnimo se obtiene con
la lista vaca), por lo que resulta:
f : [N um] 7 N um
.
f.[ ] = 0
.
f.(x . xs) =
(x + g.xs) min f.xs
Ejercicio: Probar que el costo de calcular g es lineal y el de f es cuadratico.
A
un podemos reducir el costo en el c
alculo de la funcion f . Para lograrlo,
usemos la tecnica de tuplas: postulemos h.xs = (f.xs, g.xs) y busquemos una
definici
on recursiva para h.
211
212
13.4 Ejercicios
Ejercicio 13.1 (cantidad de apariciones de un segmento)
Especificar y derivar la funci
on que calcula la cantidad de apariciones de un segmento.
Ayuda: Ver como se especific
o y deriv
o el ejemplo de la seccion 13.1.
Ejercicio 13.2
Derivar una definici
on recursiva para la funci
on l especificada como sigue:
l : [Char] 7 [Char] 7 Bool
l.xs.ys = h as, bs, c, cs : xs = as ++ bs ys = as ++ (c . cs) : bs = [ ] bs.0 < c i
decir en palabras cuando vale l.xs.ys.
Ejercicio 13.3 (contar la)
Derivar una funci
on recursiva cantla : String 7 N um tal que, dada una cadena
de caracteres, devuelva la cantidad de apariciones de la subcadena la. El costo
de evaluar la misma debe ser lineal en el tama
no de la cadena.
Ejercicio 13.4
Derivar una funci
on recursiva maxiguala : [A] 7 A 7 N um especificada como
maxiguala : [A] 7 A 7 N um
maxiguala.xs.y = hMax as, bs, cs : xs = as ++ bs ++ cs iguala.bs.y : #bs i
donde iguala es la funci
on a derivar en el ejercicio 11.1. El costo de la funcion
resultado debe ser lineal en el tama
no de la lista.
Ayuda: Para obtener costo lineal puede ser necesario utilizar la tecnica de uso de
tuplas.
Ejercicio 13.5 (m
axima longitud de iguales)
Derivar la funci
on especificada como
maxigual : [A] 7 N um
maxigual.xs.y = hMax as, bs, cs : xs = as ++ bs ++ cs iguales.bs : #bs i
donde iguales es la funci
on derivada en el ejercicio 12.1.
La funci
on obtenida debe tener costo lineal.
Ayuda: Para obtener costo lineal puede ser necesario utilizar la tecnica de uso de
tuplas.
Captulo 14
Especificaciones implcitas
Estas ambig
uedades, redundancias y deficiencias recuerdan las que
el doctor Franz Kuhn atribuye a cierta enciclopedia china que se titula
Emporio celestial de conocimientos benevolos. En sus remotas paginas
est
a escrito que los animales se dividen en (a) pertenecientes al Emperador, (b) embalsamados, (c) amaestrados, (d) lechones, (e) sirenas,
(f) fabulosos, (g) perros sueltos, (h) incluidos en esta clasificacion, (i)
que se agitan como locos, (j) innumerables, (k) dibujados con un pincel
finsimo de pelo de camello, (l) etcetera, (m) que acaban de romper el
jarr
on (n) que de lejos parecen moscas.
Jorge Luis Borges: El Idioma analtico de John Wilkins
En esta secci
on veremos un ejemplo de derivacion de programas que nos introducir
a a una nueva tecnica para obtener algoritmos.
14.1 Aritm
etica de precisi
on arbitraria
Un problema com
un que se presenta cuando utilizamos algunos lenguajes de
programaci
on es el de poder manipular n
umeros enteros de gran magnitud. Por
213
214
P
JxsKB =
i : 0 i < #xs : xs.i B i
la cual, dada una lista de n
umeros, devuelve el que representa en la base B
(con B > 1). Este tipo de funciones suelen denominarse funci
on de abstracci
on
y relaciona los valores concretos con los abstractos que queremos representar (en
nuestro caso listas y n
umeros respectivamente).
La funci
on tiene algunas propiedades que van a ser de utilidad al momento de
encontrar las operaciones sobre las representaciones. Vamos a mencionar algunas
de ellas, dejando al lector demostrarlas como ejercicio.
Propiedades
P1 : J[ ]KB = 0
ARBITRARIA
14.1 ARITMETICA
DE PRECISION
215
P2 : Jx . xsKB = x + B JxsKB
= { especificaci
on de }
J[ ]KB + JysKB
= { P1 }
0 + JysKB
= {
algebra }
JysKB
con lo cual tenemos un problema ya que no obtenemos una definicion para []ys
de la forma
[ ] ys =
si no una para J[ ] ysKB .
Olvidemos por un momento esta cuesti
on y sigamos derivando los otros casos.
Caso base (ys = [ ])
Jxs [ ]KB
= { especificaci
on de }
JxsKB + J[ ]KB
= { P1 }
JxsKB + 0
= {
algebra }
JxsKB
216
Hip
otesis inductiva: Jxs ysKB = JxsKB + JysKB
Paso inductivo (x . xs, y . ys)
Jx . xs y . ysKB
= { especificaci
on de }
Jx . xsKB + Jy . ysKB
= { P2 }
x + B JxsKB + y + B JysKB
= { hip
otesis inductiva }
(x + y) + B Jxs ysKB
= { P2 }
= JysKB
= JxsKB
= J(x + y) . (xs ys)KB
(14.1)
217
218
f.X = E 0 .X
se va a cumplir su especificaci
on implcita g.(f.X) = E.X y con ello encontramos
la funci
on que est
abamos buscando.
14.3 Revisi
on del ejemplo
En el ejemplo inicial vimos como obtener la suma de dos n
umeros de precision
arbitraria representados como listas. Las listas contenan en orden, los dgitos del
n
umero en una base dada. Pero hemos olvidado un detalle; la especificacion que
dimos del operador no dice nada acerca que los dgitos del resultado deben
estar entre 0 y la base. Una forma de hacerlo es definir un predicado IB
IB .xs = h i : 0 i < #xs : 0 xs.i < B i
el cual requiere para su validez que todos los elementos de la lista se encuentren
entre 0 y B 1. Con el mismo podemos especificar el operador como
: [N um] 7 [N um] 7 [N um]
Jxs ysKB = JxsKB + JysKB IB .(xs ys)
y con ello requerimos que el resultado de la operacion cumpla IB .
Notemos que esta nueva especificaci
on es mas fuerte que la anterior (agrega un
termino conjuntivo). Podramos debilitarla un poco solicitando que los parametros
xs y ys verifiquen el predicado IB :
: [N um] 7 [N um] 7 [N um]
IB .xs IB .ys
Jxs ysKB = JxsKB + JysKB IB .(xs ys)
DEL EJEMPLO
14.3 REVISION
219
220
= { por demostraci
on anterior }
J(x + y) . (xs ys)KB
Como vemos para este caso dejaremos la misma definicion de obtenida
anteriormente, ya que la condici
on x+y < B asegura que los dgitos estan acotados
por la base.
Veamos el segundo caso
Caso: x + y B
Paso inductivo (x . xs, y . ys)
Jx . xs y . ysKB
= { por demostraci
on anterior }
(x + y) + B (JxsKB + JysKB )
= { aritmetica }
(x + y B) + B + B (JxsKB + JysKB )
= { aritmetica }
= { definici
on de J KB }
= { hip
otesis inductiva }
= { hip
otesis inductiva }
(x + y B) + B (J[1] xs ysKB )
= { P2 }
J(x + y B) . ([1] xs ys)KB
Por lo tanto
Jx . xs y . ysKB = J(x + y B) . ([1] xs ys)KB
DEL EJEMPLO
14.3 REVISION
221
{ Leibniz }
x . xs y . ys = (x + y B) . ([1] xs ys)
Nota: En la demostraci
on anterior se aplico dos veces hipotesis inductiva. En
ambas se hizo inducci
on completa sobre la longitud de la concatenacion de las dos
listas par
ametros del operador .
Ejercicio: Comprobar con esta hip
otesis inductiva que la derivacion es correcta.
A partir de las demostraciones anteriores hemos encontrado una nueva definici
on del operador :
: [N um] 7 [N um] 7 [N um]
.
[ ] ys = ys
.
xs [ ] = xs
.
x . xs y . ys =
( x + y < B (x + y) . (xs ys)
2 x + y B (x + y B) . ([1] xs ys)
)
Falta ahora demostrar que este resultado cumple el predicado IB suponiendo
que lo cumplen los par
ametros. Los casos bases son triviales y se dejan como
ejercicios para el lector. El caso inductivo tendra dos casos al igual que la derivacion
anterior y se utilizar
a la misma hip
otesis inductiva que en la u
ltima derivacion.
Para el caso x + y B tendremos
Suposiciones: IB .(x . xs), IB .(y . ys)
Caso: x + y B
Paso inductivo (x . xs, y . ys)
IB .(x . xs y . ys)
{ definici
on de }
I.((x + y B) . ([1] xs ys))
{ definici
on de IB }
h i : 0 i < #((x + y B) . ([1] xs ys)) :
0 ((x + y B) . ([1] xs ys)).i < B i
{ definici
on de #; partici
on de rango; rango unitario }
0x+yB <B
h i : 0 < i < #([1] xs ys) + 1 : 0 ((x + y B) . ([1] xs ys)).i < B i
222
14.4 ESPECIFICACIONES IMPLICITAS CON INVARIANTE DE REPRESENTACION223
suficiente para poder aplicar la funci
on a los parametros y es una condicion necesaria del resultado de la misma. Por esto mismo su nombre; es una condicion que
se cumple en los par
ametros y en el resultado, o sea que se mantiene invariante al
aplicar la funci
on.
Para simplificar la notaci
on escribiremos I.X en vez de la cuantificacion universal sobre la lista de par
ametro. Con ello la especificacion quedara como
I.X
g.(f.X) = E.X I.(f.X)
Para obtener una definici
on de la funci
on incognita f trabajaremos como usualmente hemos hecho cuando queremos demostrar implicaciones. Supondremos valido I.X y trabajaremos con cada termino de la conjuncion (del lado derecho de
la implicaci
on) por separado.
El primer termino de la es g.(f.X) = E.X y tiene la forma de una especificacion
implcita. Por lo tanto repetiremos la metodologa vista para las mismas aunque
suponiendo que el invariante de representacion se cumple para los parametros.
Suposici
on: I.X
g.(f.X) = E.X
{ Por derivaci
on suponiendo I.X }
g.(f.X) = g.(E 0 .X)
{ Leibniz }
f.X = E 0 .X
Como sucedi
o con las especificaciones implcitas, ya tenemos un candidato a
definici
on de la funci
on f . Pero todava no demostramos que esta definicion cumple
el invariante. Solo demostramos
I.X (f.X = E 0 .X g.(f.X) = E.X)
o lo que es lo mismo (por c
alculo proposicional)
f.X = E 0 .X I.X g.(f.X) = E.X .
(14.2)
(14.3)
224
14.5 Ejercicios
Ejercicio 14.1
Derivar el operador multiplicaci
on de enteros de precision arbitraria. La especificaci
on del mismo es la siguiente:
: [N um] 7 [N um] 7 [N um]
IB .xs IB .ys
Jxs ysKB = JxsKB JysKB IB .(xs ys)
Ejercicio 14.2
Derivar la funci
on convB que dado un n
umero mayor o igual a cero, devuelve su
representaci
on en base B. Esto es
convB : N um 7 [N um]
JconvB .nKB = n IB .(convB .n)
Nota: La funci
on convB est
a definida como la inversa a derecha de la funcion
de abstracci
on J KB . En particular, esto quiere decir que la funcion J KB es sobreyectiva pero no necesariamente inyectiva. En caso que no lo sea buscar algunos
contraejemplos en que la funci
on evaluada en distintos valores devuelva como resultado el mismo n
umero.
Ejercicio 14.3
Rehacer el ejemplo de la secci
on 14.3 generalizando el operador con la funcion
definida como
g : N um 7 [N um] 7 [N um] 7 [N um]
IB .xs IB .ys
Jg.k.xs.ysKB = k + JxsKB + JysKB IB .(g.k.xs.ys)
14.5 EJERCICIOS
225
xs ys = g.0.xs.ys
entonces satisface su especificaci
on.
Ejercicio 14.4
Los n
umeros representados en el ejemplo de aritmetica de precision arbitraria son
siempre positivos. Una forma de implementar ademas los negativos es cambiando
ligeramente la representaci
on de los n
umeros:
J K : (Bool, [N um]) 7 N um
B
P
J(s, xs)KB = ( s
i : 0 i < #xs : xs.i B i
P
2 s
i : 0 i < #xs : xs.i B i
)
Esto es, si el booleano s es verdadero el n
umero sera positivo y en caso contrario
negativo.
A partir de esta nueva funci
on de abstraccion especificar y derivar las operaciones de suma, resta y multiplicaci
on de enteros de precision arbitraria.
Ejercicio 14.5 (Notaci
on factorial)
En el ejercicio 12.7 se plante
o el problema de evaluar un n
umero entero positivo
representado en su notaci
on factorial. La funcion de abstraccion fue planteada
como:
J K : [N at] 7 N at
P
JxsK = h i : 0 i < #xs : xs.i (i + 1)! i
Adem
as, los n
umeros as representados cumplen con el siguiente invariante de
representaci
on:
I.xs = h i : 0 i < #xs : 0 xs.i i + 1 i
esto es, los dgitos deben ser n
umeros positivos menores o iguales al numero cuyo
factorial los multiplica.
Algunos ejemplos de n
umeros en esta representacion son:
J[0, 1]K
=
J[1, 1, 1]K =
J[1, 2, 3]K =
2
9
23
J[1, 2]K
= 5
J[0, 2, 1]K
= 10
J[0, 0, 0, 1]K = 24
226
Captulo 15
Recursi
on final
Unwin, cansado, lo detuvo.
- No multipliques los misterios - le dijo -. Estos
deben ser simples. Recuerda la carta robada de Poe,
recuerda el cuarto cerrado de Zangwill.
- O complejos - replico Dunraven -. Recuerda el universo
Jorge Luis Borges:
Abenjac
an el Bojar muerto en su laberinto
Existen algunos tipos de definiciones recursivas que gozan de buenas propiedades. Uno de los esquemas recursivos m
as importantes es el llamado de recursion
final, o recursi
on a la cola (en ingles, tail recursion). Una de las propiedades importantes de dicho esquema es que las funciones as definidas pueden traducirse
f
acilmente a programas iterativos. M
as a
un, la prueba de correccion del programa
iterativo puede obtenerse a partir de la definicion recursiva de la funcion.
Diremos que una funci
on es recursiva final si es posible definirla explcitamente de la siguiente manera:
H : A 7 B
.
FINAL
CAPITULO 15. RECURSION
228
N
otese el abuso de notaci
on implcito en la funcion g. Si, por ejemplo, H es una
funci
on de dos par
ametros, en realidad har
an falta dos funciones -sean estas g0 , g1 (o una funci
on que devuelva pares), quedando entonces la definicion explcita de
la siguiente manera:
.
t.x > 0
t.(g.x) < t.x
Ejemplo 15.1
La funci
on mcd (m
aximo com
un divisor) se puede definir, para x, y > 0, como una
recursi
on final:
mcd.x.y
(
2
)
x=yx
x 6= y mcd.(max.x.y min.x.y).(min.x.y)
229
t.x.y
= { definici
on de t }
x+y
= { definicion de t }
max.x.y min.x.y + min.x.y
> { x, y > 0 }
= { algebra }
max.x.y
< { x, y > 0 }
x+y
= { definicion de t }
t.x.y
Ejemplo 15.2
La definici
on recursiva de fac que hemos dado en captulos anteriores,
.
fac.0 = 1
.
fac.(n + 1) = (n + 1) fac.n
no es recursiva final (por la aparici
on del factor n + 1).
Muchas funciones recursivas pueden expresarse como recursivas finales. Una
forma de lograrlo es usar la tecnica de generalizacion por abstraccion de la funcion.
Veamos c
omo hacerlo con la funci
on fac:
Sea gfac especificada por
h m, n : : gfac.m.n = m fac.n i
Es claro que gfac generaliza a fac, pues fac.n = gfac.1.n. Tratemos, pues, de dar
una definici
on recursiva final de gfac.
Caso base
gfac.m.0
= { especificaci
on de gfac }
m fac.0
= { definici
on de fac }
m1
= {
algebra }
m
Paso inductivo
gfac.m.(n + 1)
= { especificacion de gfac }
m fac.(n + 1)
= { definicion de fac }
m ((n + 1) fac.n)
= { algebra }
(m (n + 1)) fac.n
= { hipotesis inductiva }
gfac.(m (n + 1)).n
FINAL
CAPITULO 15. RECURSION
230
Por lo tanto,
gfac.m.0 = m
gfac.m.(n + 1) = gfac.(m (n + 1)).n
que es recursiva final, pues puede escribirse con el esquema descripto al comienzo
del captulo:
gfac.m.n = ( n = 0 m
2n=
6 0 gfac.(m n).(n 1)
)
La principal dificultad que se presenta al buscar una definicion recursiva final
de una funci
on, es determinar la funci
on generalizada a partir de la cual se derivara
la expresi
on recursiva final. Si bien no vamos a dar reglas generales para encontrar
esta expresi
on, el problema puede generalmente resolverse usando la tecnica de
generalizaci
on por abstracci
on.
Ejemplo 15.3
Dar una definici
on recursiva final de la funci
on especificada por:
g.x.n =
i : 0 i < n : xi
En la secci
on 11.5 dimos una definici
on recursiva para g:
g.x.0 = 0
g.x.(2 n + 1) = 1 + x g.x.(2 n)
Observando la definici
on de g, vemos que su forma general es la siguiente:
cuando el segundo argumento es par, el valor asignado es un m
ultiplo de g, mientras
que cuando el segundo argumento es impar, el resultado es un m
ultiplo de g mas
una constante. Esto sugiere proponer una funcion generalizada de la siguiente
forma:
h.z.y.x.n = z + y g.x.n
Tratemos ahora de dar una definici
on recursiva final de h.
Caso base (n = 0)
h.z.y.x.0
= { especificaci
on de h }
z + y g.x.0
231
= { definici
on de g }
z+y0
= {
algebra }
z
Paso inductivo (n = 2k, k > 0)
h.z.y.x.(2 k)
= { especificaci
on de h }
z + y g.x.(2 k)
= { definici
on de g, k > 0 }
z + y (1 + x) g.(x x).k
= {
algebra }
z + (y (1 + x)) g.(x x).k
= { hip
otesis inductiva }
h.z.(y (1 + x)).(x x).k
Por lo tanto,
h.z.y.x.0 = z
h.z.y.x.(2 k) = h.z.(y (1 + x)).(x x).k
si k > 0
FINAL
CAPITULO 15. RECURSION
232
LINEAL Y RECURSION
FINAL
15.2 RECURSION
233
hP.b.n.(x . xs)
hP.b.n.[ ]
= { definicion de hP }
= { especificaci
on de hP }
b gP.n.(x . xs)
b gP.n.[ ]
= { definicion de gP }
= { definici
on de gP }
b x = n gP.n.xs
b F alse
= { hipotesis inductiva }
= { c
alculo proposicional }
hP.(b x = n).n.xs
15.2 Recursi
on lineal y recursi
on final
Un esquema m
as general que la recursi
on final es el de recursion lineal. En este
esquema, la referencia recursiva aparece a lo sumo una vez (en cada posible rama).
Diremos que una funci
on es recursiva lineal si es posible definirla explcitamente como
F : A 7 B
234
FINAL
CAPITULO 15. RECURSION
F.x = ( b.x f.x
2 b.x h.x F.(g.x)
)
donde puede ser cualquier operador.
La funci
on h es -estrictamente hablando- innecesaria (se puede evitar redefiniendo el operador ), pero facilita el enunciado de las propiedades de la definicion.
Nuevamente, se supone la existencia de una funcion de cota t : A 7 Int de
iguales propiedades que en el caso de la recursion final.
Ejemplo 15.6
La funci
on fac es recursiva lineal, puesto que puede expresarse de la siguiente
manera:
fac.n = ( n = 0 1
2 n=
6 0 n fac.(n 1)
)
Las funciones f , g y h que aparecen en la definicion de funcion recursiva lineal
son en este caso las siguientes:
f.n = 1 n
g.n = n 1
h.n = n
y el operador es la multiplicaci
on.
El teorema que sigue es la generalizaci
on de la derivacion hecha en el ejemplo
del c
alculo del factorial a una funci
on recursiva lineal arbitraria.
Teorema 15.1
Toda funci
on recursiva lineal (de la forma de arriba) en la cual el operador es
asociativo y tiene neutro a izquierda se puede expresar como una funcion recursiva
final.
Demostraci
on:
Sea F una funci
on recursiva lineal y sea G especificada por h y, x : : G.y.x = y F.x i.
La funci
on G es una generalizaci
on de F , pues F.x = G.e.x, donde e es el elemento
neutro a izquierda del operador . Veamos que G es recursiva final realizando un
LINEAL Y RECURSION
FINAL
15.2 RECURSION
235
an
alisis por casos:
Caso (b.x)
Caso (b.x)
G.y.x
G.y.x
= { especificacion de G }
= { especificaci
on de G }
y F.x
y F.x
= { b.x }
= { b.x }
y f.x
y (h.x F.(g.x))
= { es asociativo }
(y h.x) F.(g.x)
= { hipotesis inductiva }
G.(y h.x).(g.x)
G.z.m.0 = z
G.z.m.(n + 1) = G.(m z).(m + 1).n
Entonces
G.(f.m).m.n = f.(m + n)
FINAL
CAPITULO 15. RECURSION
236
Notar que G es recursiva final. El teorema dice que cualquier funcion definida
con el esquema de f se puede expresar como una recursiva final; mas a
un, nos
brinda la definici
on explcita de dicha funci
on recursiva final.
Demostraci
on del teorema: hacemos induccion sobre n.
Paso inductivo
Caso base (n = 0)
G.(f.m).m.(n + 1)
G.(f.m).m.0
= { definici
on de G }
f.m
= {
algebra }
f.(m + 0)
= { definicion de G }
G.(m f.m).(m + 1).n
= { definicion de f }
G.(f.(m + 1)).(m + 1).n
= { hipotesis inductiva }
f.((m + 1) + n)
= { algebra }
f.(m + (n + 1))
Corolario 15.3
Con f y G definidas como en el teorema, G.c.0.n = f.n
El teorema y su corolario resultan u
tiles para encontrar funciones recursivas
finales que permiten calcular funciones definidas con el esquema de la funcion f
del teorema. Lo u
nico que se requiere es identificar la constante c y el operador .
Ejemplo 15.8
Consideremos nuevamente la funci
on fac, definida por
fac.0 = 1
fac.(n + 1) = (n + 1) fac.n
Para escribirla como recursiva final usando el u
ltimo teorema, debemos identificar c y en este caso. Claramente, c = 1. Con hay que ser cuidadosos, pues
el primer factor en la expresi
on de fac.(n + 1) no es n. Para responder al esquema
de la funci
on f del teorema debemos considerar definido por x y = (x + 1) y.
Entonces la funci
on G debe ser
G.z.m.0 = z
G.z.m.(n + 1) = G.((m + 1) z).(m + 1).n
y el teorema asegura que
G.(fac.m).m.n = fac.(m + n)
237
15.3 Recursi
on final para listas
Cuando se definen funciones sobre listas, el requisito de asociatividad del operador usado para definir la funci
on es innecesariamente estricto. En esta seccion
presentamos un teorema para obtener definiciones recursivas finales a partir de
definiciones recursivas lineales que no requiere que el operador sea asociativo. A
cambio, es necesario introducir una nueva funcion en el enunciado del teorema. Se
trata de la funci
on rev, que invierte el orden de los elementos de una lista:
rev.[ ] = [ ]
rev.(x . xs) = (rev.xs) / x
Antes de enunciar el teorema, estudiemos un ejemplo. La funcion sum que
hemos usado en secciones anteriores es recursiva lineal:
sum.[ ] = 0
sum.(x . xs) = x + sum.xs
Se desea una expresi
on recursiva final que permita calcular sum. Como ya
hemos hecho antes, primero planteamos una generalizacion de la funcion y luego
buscamos una definici
on recursiva final de la generalizacion. Sea
G.y.xs = y + sum.xs
La funci
on G generaliza a sum, pues sum.xs = G.0.xs. Busquemos ahora una
expresi
on recursiva final para G.
Caso base (xs = [ ])
G.y.[ ]
= { especificaci
on de G }
y + sum.[ ]
= { definici
on de sum }
y+0
= {
algebra }
y
Esto es,
FINAL
CAPITULO 15. RECURSION
238
G.y.xs = ( xs = [ ] y
2 xs =
6 [ ] G.(y + xs.0).(xs1)
)
Para encontrar la definici
on recursiva final de G hemos usado la asociatividad
del operador +. Supongamos ahora que queremos dar una definicion recursiva
final de sum sin usar la asociatividad del operador +. Notemos que al poner
G.y.xs = y + sum.xs, en y vamos acumulando sumas parciales (interpretacion
operacional). Tratemos de expresar esto:
h xs, ys, y : y = sum.ys : G.y.xs = sum.(xs ++ ys) i
Trabajemos ahora a partir de esta especificacion.
Caso base (xs = [ ])
G.y.[ ]
= { especificaci
on de G }
sum.([ ] ++ ys)
= { propiedad de +
+ }
sum.ys
= { y = sum.ys }
y
239
en la derivaci
on. La conmutatividad del operador no es estrictamente necesaria,
como se ver
a en el siguiente resultado.
El ejemplo que acabamos de analizar se puede generalizar mediante el siguiente
Teorema 15.4
Sean
f.[ ] = c
f.(x . xs) = x f.xs
G.z.[ ] = z
G.z.(x . xs) = G.(x z).xs
Entonces
G.(f.ys).xs = f.(rev.xs ++ ys).
Demostraci
on del teorema:
Caso base (xs = [ ])
G.(f.ys).[ ]
= { definici
on de G }
f.ys
= { propiedad de +
+ }
f.([ ] ++ ys)
= { definici
on de rev }
f.(rev.[ ] ++ ys)
Observaci
on: La funci
on G del teorema anterior es recursiva final.
Corolario 15.5
Con f y G como en el teorema, G.c.xs = f.(rev.xs)
El teorema y su corolario son particularmente u
tiles cuando la funcion f que
se desea calcular es independiente del orden de los elementos de la lista a la cual
se aplica, pues en este caso rev.xs = xs, de donde resulta f.xs = G.c.xs, es decir,
el teorema nos indica como obtener una definicion recursiva final para el calculo
de f .
240
FINAL
CAPITULO 15. RECURSION
15.4 Ejercicios
Ejercicio 15.1
Sea P : [Int] 7 Bool la funci
on que determina si en una lista de enteros hay alg
un
elemento que es igual a la suma de todos los demas. Dar una definicion recursiva
final para P .
Ejercicio 15.2
Dar una definici
on recursiva final para el problema del calculo de una aproximacion
de la constante matem
atica e (ver secci
on 12.2).
Ejercicio 15.3
Dar una definici
on recursiva final para el problema de la lista balanceada (ver
secci
on 12.5).
Ejercicio 15.4
Dar una definici
on recursiva final para el problema de los parentesis equilibrados
(ver ejemplo 13.2).
Ejercicio 15.5
Una lista de enteros se denomina esferulada si cumple las siguientes dos condiciones:
15.4 EJERCICIOS
(i) La suma de cualquier segmento inicial es no negativa.
(ii) La suma de sus elementos es 0.
Se pide:
1. Especificar esf : [Int] 7 Bool.
2. Derivar una funci
on recursiva que resuelva esf .
3. Calcular una definici
on recursiva final para esf .
241
242
FINAL
CAPITULO 15. RECURSION
Captulo 16
La programaci
on imperativa
I fear those big words, Stephen said, which make us so unhappy.
James Joyce: Ulysses
A partir de ahora cambiaremos el modelo de computacion subyacente, y por
lo tanto el formalismo para expresar los programas. Esto no significa que todo
lo hecho hasta ahora no nos sea u
til en lo que sigue. La utilidad puede verse al
menos en dos aspectos. El primero es que la experiencia adquirida en el calculo de
programas, y la consecuente habilidad para el manejo de formulas, seguira siendo
esencial en este caso, mostrando as que pese a sus diferencias la programacion
funcional y la imperativa tienen bastantes cosas en com
un. El segundo se vera en
los captulos finales y es un metodo para obtener programas imperativos a partir
de programas funcionales (recursivos finales o de cola).
A diferencia de la primera parte, el material aqu presentado esta cubierto
en numerosos libros cuya consulta se aconseja a los lectores [Dij76, Gri81, DF88,
Kal90, Coh90].
244
IMPERATIVA
CAPITULO 16. LA PROGRAMACION
245
246
IMPERATIVA
CAPITULO 16. LA PROGRAMACION
Si las ternas {P } S {Q} y {P } S {R} son validas, entonces ejecutar S comenzando en un estado que satisface P , termina en un estado que satisface Q y tambien
R, i.e. satisface Q R. Recprocamente, si la terna {P } S {Q R} es valida, entonces ejecutar S comenzando en un estado que satisface P , termina en un estado
que satisface Q R, es decir, satisface tanto a Q como a R.
{P } S {Q} {P } S {R} {P } S {Q R}
Si las ternas {P } S {Q} y {R} S {Q} son validas, entonces ejecutar S comenzando en un estado que satisface o bien P o bien R, i.e. P R, termina en un
estado que satisface Q, por otro lado, si cada vez que se comienza con un estado
que satisface P R al terminar vale Q, entonces a fortiori (fortalecimiento de la
condici
on) vale que comenzando en un estado que satisface P (o R) al terminar
valdr
a Q.
{P } S {Q} {R} S {Q} {P R} S {Q}
16.3 EJERCICIOS
247
16.3 Ejercicios
Ejercicio 16.1
Dadas las siguientes propiedades del transformador de predicados wp,
Exclusi
on de milagros: [wp.S.f alse f alse]
Conjuntividad:
[wp.S.(P Q) wp.S.P wp.S.Q]
1. Demostrar monotona: [(P Q) (wp.S.P wp.S.Q)].
2. Usando la monotona de wp, demostrar: {Q} S {A}(A R) {Q} S {R}.
Ejercicio 16.2
Usando las propiedades de wp.S.Q, demostrar las reglas de la seccion16.1.
248
IMPERATIVA
CAPITULO 16. LA PROGRAMACION
Captulo 17
Definici
on de un lenguaje de
programaci
on imperativo
And while I thus spoke, did there not cross your mind some thought
of the physical power of words? Is not every word an impulse on the
air?
Edgar Allan Poe: The power of words
En esta secci
on veremos una serie de comandos que definen un lenguaje de
programaci
on imperativo b
asico. Para cada uno de ellos se dara la respectiva precondici
on m
as debil y se mostrar
an ejemplos de su funcionamiento.
17.1 Skip
La sentencia skip no tiene ning
un efecto sobre el estado valido antes de su
ejecuci
on (no lo modifica). La utilidad de una instruccion que no hace nada se
entender
a m
as adelante, pero podemos adelantar que sera tan u
til como lo es el 0
en el
algebra.
Queremos caracterizar la sentencia skip usando ternas de Hoare. Comencemos
estudiando wp.skip.Q. Claramente, el predicado mas debil P tal que {P } skip {Q}
es Q, pues lo mnimo necesario para asegurar el estado final Q cuando no se hace
nada es tener Q como estado inicial. Por lo tanto, la precondicion mas debil del
comando skip con respecto a un predicado es dicho predicado:
[wp.skip.Q Q]
249
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
250CAPITULO 17. DEFINICION
Esto podra inducirnos a caracterizar skip usando la terna {Q} skip {Q} como
axioma, pero como ya hemos visto que es posible reforzar la precondicion, daremos
una caracterizaci
on m
as general en terminos de una equivalencia:
{P } skip {Q} [P Q]
Ejemplo 17.1
El programa
|[var x : Int
{x 1}
skip
{x 0}
]|
es correcto, puesto que [x 1 x 0].
17.2 Abort
La instrucci
on abort est
a especificada por
{P } abort {Q} [P F alse]
El programa abort representa un programa erroneo. La semantica dice que no
existe ning
un estado en el cual abort pueda ejecutarse y terminar.
En terminos de la precondici
on m
as debil, tenemos
[wp.abort.Q F alse]
17.3 Asignaci
on
La asignaci
on se usa, como su nombre lo indica, para asignar valores a variables.
La sintaxis es
x := E
donde x es una lista de variables separadas por comas y E es una lista de expresiones de la misma longitud, tambien separadas por comas, tal que la nesima
expresi
on es del mismo tipo que la nesima variable de x. El efecto de la sentencia
x := E es reemplazar el valor de x por el de E. Ejemplos de asignaciones son:
x := x + 1
x, y := x 2, x + y
y, p := y/2, T rue
17.3 ASIGNACION
251
Ejemplo 17.2
Si P = (x 0 x y), entonces:
P (y := z + w) = (x 0 x z + w)
P (x := x + 1) = (x + 1 0 x + 1 y)
P (k := 3) = P, pues k no aparece en P.
Tambien es posible realizar sustituciones simultaneas. Por ejemplo: si P es
el predicado (x y), entonces P (x, y := q, z + w) = (q z + w). Hay que
tener presente que la sustituci
on simult
anea puede no ser equivalente a varias
sustituciones sucesivas. Por ejemplo P (x, y := y, x) = (y x), pero P (x :=
y)(y := x) = (y y)(y := x) = (x x).
Cuando la expresi
on E contiene una variable que en P esta siendo usada como
variable de cuantificaci
on (dummy), hay que renombrar esta variable en P antes
de realizar la sustituci
on.
Ejemplo 17.3
Si P = (x < y ( j : : f.j < y)), entonces para hacer P (y := y + j) primero es
necesario renombrar la variable j del cuantificador universal:
P = (x < y ( k : : f.k < y))
P (y := y + j) = (x < y + j ( k : : f.k < y + j))
Volvamos ahora a la asignaci
on. Analicemos en primer lugar wp.(x := E).Q.
Lo mnimo que se requiere para que el predicado Q sea valido luego de efectuar la
asignaci
on x := E, es el predicado Q(x := E). En otras palabras, la precondicion
m
as debil de una asignaci
on con respecto a un predicado es
[wp.(x := E).Q Q(x := E)]
Entonces, para que la terna {P } x := E {Q} sea correcta, el predicado P debe
ser m
as fuerte que el predicado Q(x := E). De esta manera, la asignacion esta
especificada por
{P } x := E {Q} [P Q(x := E)]
Asumiremos que en E s
olo se admitir
an expresiones bien definidas, sino habra
que agregar el predicado def.E (que es T rue solo si la expresion E esta bien
definida) en el segundo miembro de la implicacion: {P } x := E {Q} [P
def.E Q(x := E)].
N
otese que la expresi
on x := E del miembro izquierdo es una sentencia valida
de nuestro lenguaje de programaci
on, mientras que la del miembro derecho es una
operaci
on sint
actica la cual se aplica a expresiones logicas, por lo tanto no son
iguales.
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
252CAPITULO 17. DEFINICION
Ejemplo 17.4
Encontrar E tal que se satisfaga {T rue} x, y := x + 1, E {y = x + 1}
[T rue (y = x + 1)(x, y := x + 1, E)]
{ (T rue R) R }
[(y = x + 1)(x, y := x + 1, E)]
{ sustituci
on en predicados }
[E = x + 1 + 1]
{ aritmetica }
[E = x + 2]
Esto es, cualquier expresi
on E que valga lo mismo que x+2 es valida; en particular,
podemos tomar E = x + 2.
Notemos que la definici
on de wp.(x := E).Q nos permite escribir
{P } x := E {Q} [P wp.(x := E).Q]
De aqu que una forma pr
actica de derivar las expresiones que se deben usar en las
asignaciones es comenzar la derivaci
on analizando wp.(x := E).Q y usar en alg
un
momento de la misma la validez de P .
Ejemplo 17.5
Desarrollar un programa que satisfaga q = a c w = c2 a, q := a+c, E {q = a c}.
wp.(a, q := a + c, E).(q = a c)
{ definici
on de wp }
(q = a c)(a, q := a + c, E)
{ sustituci
on en predicados }
E = (a + c) c
{ aritmetica }
E = a c + c2
{ precondici
on (aqu se usa la validez de P ) }
E =q+w
A veces, programas que son aparentemente diferentes (por su sintaxis) son en
realidad equivalentes en cuanto a los cambios de estados que producen. Esto motiva
la siguiente definici
on:
Definici
on 17.1
Dos programas S y T se dicen equivalentes (S=T) si solo si h Q : : wp.S.Q wp.T.Q i.
Ejercicio 17.1
Usando la definici
on de equivalencia de programas, demostrar:(x := x) = skip.
O COMPOSICION
17.4 CONCATENACION
253
17.4 Concatenaci
on o composici
on
La concatenaci
on permite describir secuencias de acciones. La ejecucion de dos
sentencias S y T , una a continuaci
on de la otra, se indicara separando las mismas
con punto y coma:
S; T
siendo la de la izquierda la primera que se ejecuta.
La precondici
on m
as debil de la concatenacion S; T con respecto a un predicado
Q se obtiene tomando primero la precondicion mas debil de T con respecto a
Q (wp.T.Q) y luego la precondici
on m
as debil de S con respecto a este u
ltimo
predicado:
[wp.S; T.Q wp.S.(wp.T.Q)]
Para demostrar {P } S; T {Q} hay que encontrar un predicado intermedio R
que sirva como postcondici
on de S y como precondicion de T :
{P } S; T {Q} existe R tal que {P } S {R} {R} T {Q}
Ejemplo 17.6
El programa
|[var x, y : Int
{x > y}
y := y + 1; x := x + 1
{x > y}
]|
es correcto, puesto que R = {x y} es un predicado intermedio valido.
Ejercicio 17.2
Usando la definici
on de equivalencia de programas, demostrar:
(a) S; skip = S y skip; S = S (es decir, skip es el elemento neutro de la concatenaci
on).
(b) S; abort = abort y abort; S = abort
17.5 Alternativa
Los comandos vistos hasta el momento solo permiten derivar programas muy
simples. Un comando que ampla notablemente las posibilidades de desarrollar
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
254CAPITULO 17. DEFINICION
programas es el que permite una alternativa. La sintaxis es
if
2
..
.
B0 S0
B1 S1
2
fi
Bn Sn
if
2
..
.
B0 S0
B1 S1
2
fi
Bn Sn
{Q}
[P (B0 B1 . . . Bn )]
{P B0 } S0 {Q}
{P B1 } S1 {Q}
..
.
{P Bn } Sn {Q}
La implicaci
on P (B0 B1 . . . Bn ) es necesaria para asegurarse que el
programa no es err
oneo (contiene un abort), mientras que {P Bi } Si {Q} asegura
que ejecutar Si cuando se satisface P Bi conduce a un estado que satisface Q,
es decir, cualquiera que sea la guarda verdadera, ejecutar el respectivo comando
conduce al estado final deseado.
Asumiremos que las expresiones Bi est
an todas bien definidas, de otra manera
habra que agregar esta condici
on en el segundo miembro: [P def.B0 def.B1
. . . def Bn (B0 B1 . . . Bn )].
En cuanto a la precondici
on m
as debil de la alternativa con respecto a un
predicado Q, notemos que lo mnimo requerido es que alguna de las guardas Bi
sea verdadera y que cada una de ellas sea m
as fuerte que la precondicion mas debil
del respectivo Si con respecto a Q:
wp.if.Q = (B0 B1 . . . Bn ) (B0 wp.S0 .Q) . . . (Bn wp.Sn .Q)
17.5 ALTERNATIVA
255
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
256CAPITULO 17. DEFINICION
{ T rue elemento neutro de }
xY
{ y = Y por precondici
on }
xy
Esto nos dice que en caso de valer x y, ejecutar skip conduce a un estado
que satisface la postcondici
on. En otras palabras, x y es candidato a ser una
guarda, bajo la cual el comando a ejecutar es skip.
Hasta aqu hemos demostrado [P (y x) wp.(x := y).Q] y [P (x y)
wp.skip.Q], lo que nos conduce a proponer el siguiente programa:
if
2
fi
y x x := y
x y skip
17.6 Repetici
on
La lista de comandos se completa con una sentencia que permitira la ejecucion
repetida de una acci
on (ciclo). La sintaxis es
do
2
..
.
B0 S0
B1 S1
2 Bn Sn
od
donde para todo 0 i n, Bi es una expresi
on booleana llamada guarda y Si es
una instrucci
on.
El ciclo funciona de la siguiente manera: mientras haya guardas equivalentes a
T rue, se elige (de alguna manera) una de ellas y se ejecuta la instruccion correspondiente; luego vuelven a evaluarse las guardas. Esto se repite hasta que ninguna
guarda sea T rue. Si desde un principio ninguna guarda es T rue, el ciclo equivale
a un skip.
La especificaci
on de la repetici
on es
17.6 REPETICION
{P }
do
2
..
.
B0 S0
B1 S1
257
{Q}
2 Bn Sn
od
[P B0 B1 . . . Bn Q]
{P B0 } S0 {P }
{P B1 } S1 {P }
..
.
{P Bn } Sn {P }
el ciclo termina
La implicaci
on P B0 B1 . . . Bn Q asegura el cumplimiento
de la postcondici
on cuando ninguna guarda es verdadera, es decir, cuando el ciclo
termina, mientras que {P Bi } Si {P } asegura que ejecutar Si cuando se satisface
P Bi conduce a un estado que satisface P , lo cual es necesario para que tenga
sentido volver a evaluar las guardas. La condicion adicional el ciclo termina es
necesaria porque de otra manera el programa podra ejecutarse indefinidamente,
lo cual es ciertamente indeseable. M
as adelante formalizaremos esta condicion.
Asumiremos que las expresiones Bi est
an todas bien definidas, de otra manera
habra que agregar esta condici
on en el segundo miembro.
Un predicado P que satisface {P Bi } Si {P } recibe el nombre de invariante.
La mayor dificultad de la programaci
on imperativa consiste en la determinacion
de invariantes (notemos que esto es de vital importancia para el armado del ciclo).
Hay varias tecnicas para determinar invariantes, que analizaremos mas adelante.
Por ahora, intentaremos comprender el funcionamiento de los ciclos suponiendo
que ya se ha determinado el invariante.
Ejemplo 17.8 (M
aximo Com
un Divisor)
Desarrollar un algoritmo para calcular el maximo com
un divisor entre dos enteros
positivos.
El programa tendr
a la siguiente especificacion:
|[var x, y : Int
con X, Y : Int
{X > 0 Y > 0 x = X y = Y }
S
{x = mcd.X.Y }
]|
Para derivar S, recordemos las propiedades del mcd:
(1) mcd.x.x = x
(2) mcd.x.y = mcd.y.x
(3) x > y mcd.x.y = mcd.(x y).y
y > x mcd.x.y = mcd.x.(y x)
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
258CAPITULO 17. DEFINICION
Postulamos el siguiente invariante: {P : x > 0 y > 0 mcd.x.y = mcd.X.Y }
(notemos que la precondici
on implica P , es decir, P es un predicado que efectivamente vale al comienzo de S).
Derivemos ahora el ciclo, usando la propiedad (3):
P x>y
{ reemplazando P }
x > 0 y > 0 mcd.x.y = mcd.X.Y x > y
{ propiedad (3) }
x > 0 y > 0 mcd.(x y).y = mcd.X.Y x > y x
{
algebra }
x y > 0 y > 0 mcd.(x y).y = mcd.X.Y
{ sustituci
on en predicados }
P (x := x y)
Hemos demostrado que eligiendo como guarda x > y y como instruccion x := xy,
luego de ejecutar la acci
on sigue valiendo P , es decir, {P x > y} x := x y {P }
es correcto. An
alogamente, partiendo de P y > x se arriba a P (y := y x). As,
obtenemos el ciclo
|[var x, y : Int
con X, Y : Int
{X > 0 Y > 0 x = X y = Y }
do x > y x := x y
2 y > x y := y x
od
{x = mcd.X.Y }
]|
Observemos que si x = y el ciclo equivale a un skip, lo cual es correcto por
propiedad (1) del mcd. En otras palabras, (P (x > y) (y > x)) {x =
mcd.X.Y }.
Hasta este punto, hemos demostrado lo que se conoce como correcci
on parcial
del ciclo. Esto es: suponiendo que el ciclo termina, demostrar x
(i) (P B0 B1 . . . Bn ) Q
(ii) {P Bi } Si {P } 0 i n
Ahora bien, a
un no podemos asegurar que el programa derivado sea completamente correcto, pues no hemos demostrado que el ciclo termina. Esta prueba se
conoce como correcci
on total y consiste en encontrar una funcion t : Estados 7
17.6 REPETICION
259
{P }
do B0 S0 {Q}
2 B1 S1
..
.
2 Bn Sn
od
[P B0 B1 . . . Bn Q]
{P Bi } Si {P } 0 i n
Existe t : Estados 7 Int tal que
(i) [P (B0 B1 . . . Bn ) t 0]
(ii) {P Bi t = T } Si {t < T } 0 i n
do
od
B0 B1
if B0 S0
2 B1 S1
fi
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
260CAPITULO 17. DEFINICION
El enunciado del ejercicio resulta u
til, pues no todos los lenguajes de programaci
on admiten ciclos con varias guardas.
17.7 Ejercicios
Ejercicio 17.5
En cada uno de los siguientes casos, determinar la precondicion mas debil wp para
que el programa sea correcto. Suponer que las variables x, y, z, q, r son de tipo
Int, las variables i, j son de tipo N at y las variables a, b son de tipo Bool.
1. {wp} x := 8 {x = 8}
2. {wp} x := 8 {x 6= 8}
3. {wp} x := 8 {x = 7}
4. {wp} x := x + 2; y := y 2 {x + y = 0}
5. {wp} x := x + 1; y := y 1 {x y = 0}
6. {wp} x := x + 1; y := y 1 {x + y + 10 = 0}
7. {wp} z := z y; x := x 1 {z y x = c}
8. {wp} x, z, y := 1, c, d z xy = cd
9. {wp} i, j := i + i, j; j := j + i {i = j}
10. {wp} x := (x y) (x + y) x + y 2 = 0
11. {wp} q, r := q + 1, r y {q y + r = x}
12. {wp} a := a b; b := a b; a := a b {(a B) (b A)}
Ejercicio 17.6 (tomado de J. L. A. van de Snepscheut [vdS93])
En cada uno de los siguientes casos, determinar el predicado Q mas fuerte para
que el programa sea correcto. Suponer que las variables x, y son de tipo Int.
1. {x = 10} x := x + 1 {Q}
2. x2 > 45 x := x + 1 {Q}
3. {x 10} x := x 10 {Q}
4. {0 x < 10} x := x2 {Q}
5. x3 = y x := |x| {Q}
17.7 EJERCICIOS
261
Ejercicio 17.7
Calcular expresiones E tales que:
1. {A = q B + r} q := E; r := r B {A = q B + r}
2. {x y + p q = N } x := x p; q := E {x y + p q = N }
Ejercicio 17.8
Demostrar: {x = A y = B} x := x y; y := x + y; x := y x {x = B y = A}
Ejercicio 17.9
Demostrar que los siguientes programas son correctos. En todos los casos x, y : Int
y a, b : Bool.
1.
{T rue}
if x 1 x := x + 1
2 x 1 x := x 1
fi
{x 6= 1}
3.
{T rue}
x, y := y y, x x
if x y x := x y
2 x y y := y x
fi
{x 0 y 0}
5.
{N 0}
x := 0
do x 6= N x := x + 1
od
{x = N }
2.
{T rue}
if x y skip
2 x y x, y := y, x
fi
{x y}
4.
{T rue}
if a b a := a
2 a b b := b
fi
{a b}
6.
{N 0}
x, y := 0, 0
do x 6= 0 x := x 1
2 y 6= N x, y := N, y + 1
od
{x = 0 y = N }
Ejercicio 17.10
Suponiendo que el programa de la izquierda es correcto, demostrar que el de la
derecha tambien lo es, es decir, siempre se puede lograr que el if sea determinstico
(s
olo una guarda verdadera).
{P } if B0 S0 {Q}
2 B1 S1
fi
{P } if B0 B1 S0 {Q}
2 B1
S1
fi
Ejercicio 17.11
Demostrar que el siguiente programa es equivalente a Skip:
do F alse S
od
DE UN LENGUAJE DE PROGRAMACION
IMPERATIVO
262CAPITULO 17. DEFINICION
Ejercicio 17.12
Demostrar las siguientes implicaciones:
1. {P }
{P }
if B S
S
fi
{Q}
{Q}
2.
3..
{P }
if B0
2 B1
fi
{Q}
S0
S1
{P }
if
2
2
fi
{Q}
B0
B1
B2
S0
S1
S2
{P }
if
B0
2 B0
fi
{Q}
{P }
if
B0
2 B0
S0
S1
S0
if
2
fi
B1 S1
B2 S2
fi
{Q}
Captulo 18
Introducci
on al c
alculo de
programas imperativos
The Road goes ever on and on
Down from the door where it began.
Now far ahead the road has gone,
And I must follow, if I can,
Pursuing it with weary feet,
Until it joins some larger way
Where many paths and errands meet.
And wither then? I cannot say.
J.R.R.Tolkien:
The Lord of the Rings
18.1 Derivaci
on de ciclos
El teorema de invariancia proporciona las condiciones necesarias para demostrar que un ciclo es correcto. Ahora bien, como desarrollar un ciclo a partir de la
263
AL CALCULO
{P B} S {P }
{P B t = T } S {t < T }
{P } do B S od {P B}
P t 0 B
Supongamos ahora que el problema a resolver esta especificado por una precondici
on general R y una postcondici
on general Q. Comencemos por la postcondicion:
si se cumplen
{P } do B S od {P B}
P B Q
entonces, por debilitamiento de la postcondicion, se cumple
{P } do B S od {Q}
En otras palabras, si Q es la postcondici
on del problema, el invariante P y la
guarda B deben elegirse de tal manera que P B Q.
Consideremos ahora la precondici
on: como P debe valer al inicio del ciclo,
debemos derivar un programa S 0 tal que {R} S 0 {P }, proceso que se conoce como
inicializaci
on. De esta manera, tenemos
{R} S 0 {P }
{P } do B S od {Q}
y concatenando ambos, tenemos un programa con precondicion R y postcondicion
Q, como dese
abamos.
Concentremonos ahora en el desarrollo del ciclo propiamente dicho, es decir, {P } do B
S od {P B}, donde P es el invariante. Por el teorema de invariancia, S debe
satisfacer
{P B} S {P }
{P B t = T } S {t < T }
En este punto del desarrollo, tanto el invariante P como la guarda B han sido
determinados, por lo que no hay nada que agregar a la primera condicion. Pero
en la segunda condici
on interviene la cota t, que a
un no ha sido determinada.
El pr
oximo paso es, entonces, elegir la funci
on variante, lo cual debe hacerse de
manera tal de satisfacer lo requerido por el teorema de invariancia, es decir, debe
18.2 EJERCICIOS
265
18.2 Ejercicios
Ejercicio 18.1
Derivar dos programas que calculen r = X Y a partir de cada una de las siguientes
definiciones de la funci
on exponencial:
(a) exp(x, y) = ( y = 0 1
2 y 6= 0 x exp(x, y 1)
)
(b) exp(x, y) = ( y = 0 1
2 y 6= 0 ( y mod 2 = 0 exp(x x, y div 2)
2 y mod 2 = 1 x exp(x, y 1)
)
)
Dise
nar los dos programas a partir de:
Precondici
on R:
{x = X y = Y x 0 y 0}
Postcondici
on Q: {r = X Y }
Invariante P :
{y 0 r xy = X Y }
Para cada programa usar una de las definiciones. Tener en cuenta las mismas
a la hora de decidir la manera de achicar la cota.
AL CALCULO
Postcondici
on Q: {0 < k n
n < 2 k j : 0 <j : k = 2j }
Invariante P :
{0 < k n j : 0 < j : k = 2j }
Captulo 19
T
ecnicas para determinar
invariantes
In many of the more relaxed civilizations on the
Outer Eastern Rim of the Galaxy, the Hitchhikers
Guide has already suplanted the great
Encyclopedia Galactica as the standard repository
of all knowledge and wisdom, for though it has many
omissions and contains much that is apocryphal, or at
least wildly inaccurate, it scores over the older, more
pedestrian work in two important respects.
First, it is slighty cheaper; and second it has
the words DONT PANIC inscribed in large friendly
letters on its cover.
Douglas Adams
The Hitchhiker Guide to the Galaxy
19.1 Tomar t
erminos de una conjunci
on
En algunas ocasiones la postcondici
on es una conjuncion, digamos Q = Q0 Q1 ,
o puede reescribirse como tal. En estos casos, la implicacion P B Q puede
267
268
asegurarse f
acilmente tomando como P a uno de los terminos de la conjuncion y
como B a la negaci
on del otro: P = Q0 y B = Q1 .
Ejemplo 19.1 (Divisi
on entera)
Dados dos n
umeros, hay que encontrar el cociente y el resto de la division entera
entre ellos.
Para enteros x 0 e y > 0, el cociente q y el resto r de la division entera de x
por y est
an caracterizados por x = q y + r 0 r r < y. Por lo tanto, debemos
derivar un programa S que satisfaga
|[var x, y, q, r : Int
{R : x 0 y > 0}
S
{Q : x = q y + r 0 r r < y}
]|
(precondicion)
(postcondicion)
La poscondici
on es una conjunci
on de 3 terminos. El primero de ellos, x =
q y + r, debe ser v
alido en todo momento, ya que en cualquier paso intermedio
de una divisi
on se verifica que el cociente obtenido hasta el momento multiplicado
por el divisor m
as el resto que se tiene en ese momento es igual al dividendo. El
termino 0 r tambien debe valer en todo momento, puesto que la division no
admite restos negativos. El termino restante, r < y, no es necesariamente valido
en todo momento de la divisi
on; m
as a
un, s
olo se verifica al completar la misma.
Por ello elegimos como invariante {P : x = q y + r 0 r}. La guarda
es la negaci
on del resto de la conjunci
on, es decir (r < y), de donde resulta
{B : r y}.
El pr
oximo paso es establecer el invariante inicialmente. Como en P intervienen
q y r, que no aparecen en la precondici
on R, la inicializacion debe consistir en una
asignaci
on de valores a estas variables. Debemos elegir, pues, expresiones enteras
E y F tales que R wp.(q, r := E, F ).P .
wp.(q, r := E, F ).P
{ definici
on de wp y P }
(x = q y + r 0 r)(q, r := E, F )
{ sustituci
on en predicados }
x=Ey+F 0F
{ precondici
on y E, F : Int }
E =0F =x
Hasta aqu tenemos:
|[var x, y, q, r : Int
269
{R : x 0 y > 0}
q, r := 0, x
{P : x = q y + r 0 r}
do r y S od
{Q : x = q y + r 0 r r < y}
]|
El paso siguiente es determinar la cota t. Sabemos que el decrecimiento de
t debe asegurar que la guarda sea falsa en alg
un momento. Como la guarda es
r y, esto se lograra haciendo decrecer r o haciendo crecer y; pero lo segundo
no es factible, por lo que elegimos lo primero. Como funcion variante, tomamos
t.r = r.
Lo u
nico que resta es derivar el cuerpo del ciclo. El analisis que hemos efectuado para determinar la cota nos indica que r debe decrecer. Postulemos, entonces, ejecutar q, r := E, r k y determinemos los valores adecuados de E
y k, teniendo en cuenta que debemos mantener el invariante, es decir, se debe
satisfacer {P B} (q, r := E, r k) {P }. Esto queda garantizado demostrando
P B wp.(q, r := E, r k).P .
wp.(q, r := E, r k).P
{ definici
on de wp }
(x = q y + r 0 r)(q, r := E, r k)
{ sustituci
on en predicados }
x = E y + (r k) 0 r k
{ P y aritmetica }
qy+r =Ey+rkk r
{ aritmetica }
k
E =q+ k r
y
Como E debe ser entero, k debe ser m
ultiplo de y. Ademas, k debe ser positivo,
para que t decrezca. Podemos elegir, entonces, cualquier m
ultiplo positivo de y.
Continuemos la derivaci
on:
k
k r
y
{ Elegimos k = y, el menor m
ultiplo positivo de y }
E=q+
E =q+1y r
{ y r por B }
E =q+1
270
271
272
E =q+d0<ddy r
{
algebra }
E =q+d1ddy r
{ suponiendo 1 d d y r }
E =q+d
Esto nos permite escribir
|[var x, y, q, r, d : Int
{R : x 0 y > 0}
q, r := 0, x
{P : x = q y + r 0 r}
do r y S0 ; q, r := q + d, r d y od
{Q : x = q y + r 0 r r < y}
]|
donde S0 consiste en determinar d tal que 1 d d y r. Mas a
un, para evitar
la multiplicaci
on d y dentro del ciclo, podemos mantener invariante dd = d y.
De esta manera, debemos derivar el siguiente algoritmo:
273
|[var x, y, q, r, d, dd : Int
{R : x 0 y > 0}
q, r := 0, x
{P : x = q y + r 0 r}
do r y S1 ; q, r := q + d, r dd od
{Q : x = q y + r 0 r r < y}
]|
donde S1 consiste en calcular d y dd tales que 1 d d y r dd = d y. Para
derivar S1 , llamemos
R0 : 1 d
R1 : d y r
R2 : dd = d y
Lo que buscamos es el m
aximo valor de d que satisface R0 R1 , lo cual equivale
a buscar el mnimo valor de d tal que r < (d + 1) y. Como ademas sabemos que
existe un d que satisface esta condici
on, podramos pensar en resolver el problema
usando busca lineal.
Ejercicio: Determinar d usando busca lineal.
Sin embargo, esta soluci
on no es eficiente, pues cada repeticion tendra costo
lineal. Para disminuir el costo, debemos encontrar una manera de incrementar d
m
as r
apido que linealmente. Pidamos, por ejemplo, que d sea una potencia de 2:
R3 : d es potencia de 2
Notemos que al pedir esto estamos tomando una decision de dise
no, pues estamos restringiendo los candidatos a d; pero no es una restriccion tan drastica como
la que hicimos al tomar d = 1 (k = y).
Adem
as, pediremos que d sea la m
axima potencia de 2 posible, lo que -debido
on m
as:
a R1 - da lugar a una restricci
R4 : r < 2 d y
En otras palabras, S1 tiene como postcondicion RR = R0 R1 R2 R3 R4
y su precondici
on es P r y.
Derivemos ahora S1 a partir de su especificacion. Aprovechando que la postcondici
on es una conjunci
on, intentemos derivar un ciclo. El primer paso es elegir
el invariante. Claramente, tanto R0 como R3 deben formar parte del invariante,
pues contienen informaci
on acerca de d que no debe ser cambiada. Lo mismo ocunico termino de la conjuncion que dice algo acerca de dd.
rre con R2 , que es el u
De las otras dos, s
olo una puede usarse en la guarda, debiendo la otra quedar en
el invariante. Eligiendo R4 para la guarda (la eleccion es arbitraria), obtenemos
274
invariante: P P : R0 R1 R2 R3
guarda:
BB : R4
Ahora debemos inicializar d y dd de manera tal que {P r y} d, dd :=
E, F {P P }.
Ejercicio: Probar que la inicializaci
on d, dd := 1, y es corrrecta.
Hasta este punto, tenemos
{P r y}
d, dd := 1, y
{P P }
do r 2 d y SS od
{RR}
Nos resta derivar SS. Lo u
nico que podemos hacer para lograr que la guarda
sea falsa en alg
un momento es incrementar d. Por lo tanto, elegimos como cota
t.r.d = r d. Como la variable dd depende del valor de d, tambien sera necesario
modificarla. En otras palabras, proponemos como SS la asignacion d, dd := E, F .
Ahora bien, como esta asignaci
on debe mantener el invariante (en particular d debe
ser una potencia de 2) la forma obvia de modificar d es d := d2 y consecuentemente
tambien habr
a que hacer dd := dd 2. Probemos que esto es correcto, es decir, que
{P P BB} d, dd := 2 d, 2 dd {P P }:
wp.(d, dd := 2 d, 2 dd).P P
{ definici
on de wp y P P }
(1 d d y r dd = d y k : k 0 : d = 2k )(d, dd := 2 d, 2 dd)
{ sustituci
on en predicados }
1 2 d 2 d y r 2 dd = 2 d y k : k 0 : 2 d = 2k
{ aritmetica, definici
on de BB }
1 2 d BB dd = d y k : k 0 : d = 2k1
{ d 1 por P P }
1 2 d BB dd = d y k : k 1 : d = 2k1
{ aritmetica }
1 d BB dd = d y k : k 0 : d = 2k
{ definici
on de P P }
P P BB
275
276
277
una cl
ausula indicando el rango para la variable recientemente introducida. En
nuestro caso, debemos pedir
P
invariante: P : x = h i : 0 i < n : a.i i 0 n N
guarda:
B : n 6= N
Observar que el refuerzo del invariante permitira tomar como guarda n < N .
De aqu en m
as, la derivaci
on se desarrolla del modo acostumbrado. El paso
siguiente es inicializar de manera tal de asegurar {R}inicializaci
on{P }.
Ejercicio: Probar que la inicializaci
on n, x := 0, 0 es correcta.
Como cota elegimos la funci
on t.n = N n. El cuerpo del ciclo consistira,
pues, en incrementar el valor de n. Naturalmente, una modificacion en el valor de n
producir
a una modificaci
on en el valor de x, pues este depende de n. Probemos con
un incremento de n en una unidad. Debemos encontrar, entonces, una expresion
E tal que P B wp.(n, x := n + 1, E).P :
P
wp.(n, x := n + 1, E).(x = h i : 0 i < n : a.i i 0 n N )
{ definici
on de wp }
P
E = h i : 0 i < n + 1 : a.i i 0 n + 1 N
{ partici
on de rango y P }
P
E = h i : 0 i < n : a.i i + a.n 0 n < N
{ por P y B }
E = x + a.n 0 n < N
Por lo tanto, arribamos al siguiente programa:
|[con N : Int; a : array [0, N ) of Int
var x : Int
n, x := 0, 0
do n 6= N x, n := x + a.n, n + 1 od
]|
Ejercicio: Derivar el programa tomando como invariante lo que resulta al reemplazar en la postcondici
on la constante 0 por la variable n.
Ejemplo 19.5 (Exponenciaci
on de enteros)
Dados dos enteros no negativos A y B, calcular AB (suponer, para simplificar,
00 = 1).
La especificaci
on del programa es:
278
En la postcondici
on aparecen las constantes A y B. Podramos pensar en reemplazar s
olo una de ellas o bien ambas a la vez por una variable, es decir, los
candidatos a invariante son: r = Ax , r = xB , r = xy . El segundo es inadecuado,
dado que no podemos hacer inducci
on sobre x. El tercero es una generalizacion
del primero. Tomemos, pues, el primero.
r = Ax x = B Q, de donde resulta que la guarda del ciclo debe ser
(x = B). Reforcemos el invariante agregando un rango para x:
invariante: P : r = Ax 0 x B
guarda:
B : x 6= B
Ejercicio: Probar que la inicializaci
on x, r := 0, 1 es correcta.
La cota es t.x = B x, que decrecer
a mediante un incremento de la variable
x, el cual, a su vez, producir
a una modificaci
on de la variable r. Nuevamente, el
incremento natural es en una unidad. Busquemos E tal que P B wp.(x, r :=
x + 1, E).P :
wp.(x, r := x + 1, E).(r = Ax 0 x B)
{ definici
on de wp }
E = Ax+1 0 x + 1 B
{
algebra }
E = Ax A 0 x < B
{ por P y B }
E =rA
De esta manera, el programa buscado es
|[con A, B : Int
var r : Int
x, r := 0, 1
do x 6= B x, r := (x + 1), r A od
]|
Ejercicio: Despues de leer la secci
on 19.3, resuelva el problema tomando como
invariante r = xy .
279
CAPITULO 19. TECNICAS
PARA DETERMINAR INVARIANTES
280
s
olo sumas. Por ello, introducimos una nueva variable que representa este valor y
fortalecemos el invariante agregando un termino que mantenga la invariancia de
la nueva variable:
P : P0 P 1 P 2 ,
donde
P2 : y = 3n2 + 3n + 1 .
Ejercicio: Probar que la inicializaci
on x, y, n := 0, 1, 0 es correcta.
wp.(x, y, n := E, F, n + 1).(P0 P2 )
{ def. de wp }
E = (n + 1)3 F = 3(n + 1)2 + 3(n + 1) + 1
{ aritmetica }
E = n3 + 3n2 + 3n + 1 F = 3n2 + 6n + 3 + 3n + 3 + 1
{ por P }
E = x + y F = y + 6n + 6
Aplicando nuevamente la misma estrategia, introducimos z = 6n + 6 y fortalecemos el invariante:
P : P0 P 1 P2 P3 ,
donde
P3 : z = 6n + 6 .
Ejercicio: Determinar la inicializaci
on correcta.
Con una derivaci
on an
aloga a la anterior, se obtiene finalmente el siguiente
programa:
|[ con N : Int; var x, y, z : Int;
{N 0}
x, y, z, n := 0, 1, 6, 0
{P0 P1 P2 P3 }
do n 6= N x, y, z, n := x + y, y + z, z + 6, n + 1 od
{x = N 3 }
]|
281
P1 : 0 n N ,
CAPITULO 19. TECNICAS
PARA DETERMINAR INVARIANTES
282
P1
0nN
283
284
285
{ P0 y anidado }
E = r max hMax q : q = n + 1 : hMax p : 0 p q : sum.p.q i i
P
|[sum.p.q = h i : p i < q : A.i i]|
{ rango unitario }
E = r max hMax p : 0 p n + 1 : sum.p.(n + 1) i
P
|[sum.p.q = h i : p i < q : A.i i]|
{ introducimos u = hMax p : 0 p n + 1 : sum.p.(n + 1) i (*) }
E = r max u
|[u = hMax p : 0 p n + 1 : sum.p.(n + 1) i
P
sum.p.q = h i : p i < q : A.i i]|
Ahora bien, para poder asignar r := r max u, la expresion para u debera
formar parte del invariante (pues debe ser valida cada vez que se inicie el ciclo),
lo cual nos induce a fortalecer el invariante agregando
P2 : u = hMax p : 0 p n : sum.p.n i.
Con la definici
on de P2 dada, resulta (*)=P2 (n := n + 1). As, la asignacion
n, r := n+1, r max u es correcta (uno puede convencerse recomenzando el computo
de wp, pero ahora incluyendo P2 , es decir, calculando E tal que (P0 P1 P2 n 6=
N ) wp.(n, r := n + 1, E).(P0 P1 P2 )).
Pero para poder hacer r := r max u es necesario haber calculado antes u
(m
as precisamente, necesitamos calcular P2 (n := n + 1)). Por otra parte, tambien
es necesario inicializar u de manera de satisfacer el invariante P0 P1 P2 . La
inicializaci
on adecuada es u := 0. As, tenemos:
|[con N : Int, A : array[0, N ) of Int
var r, u : Int
{R : N 0}
n, r, u := 0, 0, 0
{P : P0 P1 P2 }
do n 6= N S0 ; n, r := n + 1, r max u od
{Q : r = hMax p, q : P
0 p q N : sum.p.q i
|[sum.p.q = h i : p i < q : A.i i]|
]|
donde S0 consistir
a en calcular u. Notemos que luego de ejecutar S0 , debe satisfacerse P2 (n := n+1), que es precondici
on necesaria para la asignacion r := r max u.
Buscamos, entonces, una expresi
on E tal que (P0 P1 P2 n 6= N ) wp.(u :=
E).(P2 (n := n + 1)).
wp.(u := E).(P2 (n := n + 1))
286
287
P1
0nN
CAPITULO 19. TECNICAS
PARA DETERMINAR INVARIANTES
288
P1
P2
0<nN
19.5 Ejercicios
Ejercicio 19.1
Calcular un programa que, dados dos enteros positivos x e y, devuelva en una
variable el mnimo com
un m
ultiplo de ambos.
Ayuda: el mnimo com
un m
ultiplo de dos enteros positivos se puede especificar
por:
mcm.x.y = hMin n : 1 n n mod x = 0 n mod y = 0 : n i
19.5 EJERCICIOS
289
Ejercicio 19.2
Sea N 0.
1. Derivar un programa que calcule el menor entero x que satisface x3 + x N .
2. Derivar un programa que calcule el mayor entero x que satisface x3 + x N .
Ejercicio 19.3
Sea A un arreglo de enteros.
1. Derivar un programa que determine si todos los elementos de A son positivos.
2. Derivar un programa que determine si alg
un elemento de A es positivo.
Ejercicio 19.4
Derivar un programa que guarde en una variable el maximo elemento de un arreglo
de enteros.
Ejercicio 19.5
Derivar un programa que calcule la cantidad de elementos pares de un arreglo de
enteros.
Ejercicio 19.6
Derivar un programa para la siguiente especificacion:
|[con M : Int, A : array[0, M ) of Int
var r : Int
{R : M 1}
S
{r = hN p, q : 0 p < q < M : A.p A.q 0 i}
]|
Ejercicio 19.7
Derivar un programa para la siguiente especificacion:
|[con N : Int, A : array[0, N ) of Int
var r : Int
{R : N 1}
S
{r = Max p, q : 0 p < q < N : (A.p A.q)2 }
]|
Ejercicio 19.8
Derivar un programa para la siguiente especificacion:
|[con N : Int, A : array[0, N ) of Int
var r : Int
290
{R : N 1}
S
{r h p, q : 0 p < q < N : A.p A.q 8 i}
]|
Sugerencia: Escribir la postcondici
on usando el operador de mnimo.
Captulo 20
Recursi
on final y
programaci
on imperativa
Still round the corner there may wait
A new road or a secret gate;
And though I oft have passed them by,
A day will come at last when I
Shall take the hidden paths that run
West of the Moon, East of the Sun.
J.R.R.Tolkien:
The Lord of the Rings
FINAL Y PROGRAMACION
IMPERATIVA
292CAPITULO 20. RECURSION
Supongamos que el problema consiste en determinar H.X para cierto valor
X. Observemos el esquema repetitivo de c
alculo de una funcion recursiva final:
mientras no ocurre b.x, se sigue aplicando la funcion (variando los argumentos,
claro est
a). En alg
un momento la condici
on b.x se verifica, con lo cual el computo de
la funci
on finaliza simplemente con la asignacion H.x = f.x. Este es precisamente
el esquema que hemos descripto para los ciclos. Por lo tanto, para calcular H.X
debemos derivar un ciclo.
La postcondici
on del problema puede expresarse por medio de una variable que
guarda el valor que se desea calcular:
{Q : r = H.X}
En primer lugar, debemos elegir el invariante. Ya hemos dicho que este es un
punto clave en la derivaci
on de un ciclo. La t
actica en este caso consiste en elegir
{P : H.x = H.X}
La validez del invariante al comienzo del ciclo se establece con la inicializacion
obvia x := X.
Antes de determinar la guarda, observemos nuevamente que la evaluacion de
H finalizar
a cuando ocurra b.x (para el x que haya quedado determinado), en cuyo
caso el valor asignado a H.x ser
a f.x. Pero como el invariante debe mantenerse,
debe valer H.x = H.X. Adem
as, al finalizar el computo debe verificarse tambien
r = H.X. Por lo tanto, al finalizar el programa debera satisfacerse r = f.x. Esto
nos induce a escribir como u
ltima instrucci
on del programa la asignacion a la
variable r del valor f.x:
|[var x : [tipo adecuado]
var r : [tipo adecuado]
{R}
x := X
{P : H.x = H.X}
S
{f.x = H.X}
r := f.x
{Q : r = H.X}
]|
Ahora debemos derivar S con precondicion P (invariante) y postcondicion
{f.x = H.X}. Como P b.x f.x = H.X, la guarda debe ser b.x. Y para
mantener el invariante, lo que debemos hacer en caso de satisfacerse la guarda es
asignarle a x el valor g.x. As, obtenemos:
|[var x : [tipo adecuado]
var r : [tipo adecuado]
293
{R}
x := X
{P : H.x = H.X}
do b.x x := g.x od
{f.x = H.X}
r := f.x
{Q : r = H.X}
]|
Para garantizar terminaci
on, debemos encontrar una funcion entera t, acotada
inferiormente, que decrezca en cada paso de la aplicacion de H, es decir, una
funci
on t tal que
b.x t.(g.x) < t.x
b.x t.x > 0
Si la funci
on H est
a bien definida (termina), esta funcion necesariamente tiene
que existir.
Ejemplo 20.1
Obtener un programa que calcule la suma de los dgitos de la representacion en
base 10 de un n
umero natural.
La funci
on
f.x
( x=00
2 x 6= 0 x mod 10 + f.(x div 10)
)
devuelve, para cada natural x representado en base 10, la suma de sus dgitos. Pero
f no es recursiva final, por lo que primero debemos transformarla en una funcion
de este tipo.
Sea H.y.x = y +f.x, donde y y x son naturales. H generaliza a f , pues H.0.x =
f.x. Busquemos una definici
on recursiva final para H. Como H involucra a f ,
estudiemos por separado los casos x = 0 y x 6= 0:
FINAL Y PROGRAMACION
IMPERATIVA
294CAPITULO 20. RECURSION
Caso (x 6= 0)
Caso (x = 0)
H.y.x
H.y.x
= { especificaci
on de H }
y + f.x
= { especificacion de H }
y + f.x
= { definici
on de f }
= { definicion de f }
y+0
= { aritmetica }
= { asociatividad de + }
podemos usar el programa para calcular H. Entonces, si lo que deseamos es calcular f.X, evaluamos H.0.X simplemente sustituyendo en el programa derivado
anteriormente:
|[var x, y : N at
y, x := 0, X
{P : H.y.x = H.0.X}
do x 6= 0 y, x := y + x mod 10, x div 10 od
{y = H.0.X}
r := y
{Q : r = H.0.X}
]|
295
h.[ ] = (0, 0)
|[(a, b) = h.xs]|
Usando el teorema de recursi
on final para listas, obtuvimos la siguiente definici
on (seci
on 15.3):
h.xs = G.(0, 0).xs
donde
G.(a, b).xs = ( xs = [ ] (a, b)
2 xs =
6 [ ] G.((xs.0 + b) min a, 0 min (xs.0 + b)).(xs1)
)
Primero supondremos que el lenguaje imperativo posee primitivas que permiten
el manejo de listas. De esta manera, la implementacion es inmediata usando el
teorema que nos permite construir programas imperativos a partir de funciones
recursivas finales.
En este caso el invariante ser
a
P : G.(a, b).ys = G.(0, 0).xs
El programa se calcula f
acilmente como sigue:
|[var ys : [Int]
var a, b, r : Int
FINAL Y PROGRAMACION
IMPERATIVA
296CAPITULO 20. RECURSION
{R}
a, b, ys := 0, 0, xs
{P : G.(a, b).ys = G.(0, 0).xs}
do ys 6= [ ]
a, b, ys := (ys.0 + b) min a, 0 min (ys.0 + b), ys1
od
{(a, b) = G.(0, 0).xs}
r := a
{Q : a = f.xs}
]|
Dado que en la mayora de los lenguajes de programacion imperativos no se
dispone de un manejo de listas tan simple, mostramos ahora como pueden implementarse programas sobre listas usando arreglos. Para esto volveremos a usar el
concepto de funci
on de abstracci
on. Esta funcion se usara para definir la manera
en que un arreglo (y una o dos variables enteras) representaran una lista dada.
Las operaciones sobre listas ser
an entonces implementadas como funciones en la
representaci
on, que conmuten con la funci
on de abstraccion de la manera en que se
detallar
a a continuaci
on. Esta tecnica puede en principio usarse para cualquier tipo de datos, no necesariamente para listas. Es por esto que en la definicion general
no hace falta referirse explcitamente a estas.
Dada una definici
on recursiva final H : A 7 B,
H.x = ( b.x f.x
2 b.x H.(g.x)
)
consideramos una funci
on de abstracci
on
[[ ]] : A0 7 A
y funciones
b : A0 7 Bool
f : A0 7 B
7 A0
g : A0
que satisfacen, para y A0 ,
b.y b.[[y]]
f .y = f.[[y]]
[[g.y]] = g.[[y]]
297
Se necesita tambien una constante X 0 (el valor inicial) que represente al valor
inicial abstracto, esto es [[X 0 ]] = X, siendo X el valor en el que se desea evaluar
la funci
on H. Entonces, el c
alculo de H puede implementarse como un programa
imperativo como sigue:
|[var y : A0
y := X 0
{P : H.[[y]] = H.X}
do b.y y := g.y od
{f .y = H.X}
r := f .y
{Q : r = H.X}
]|
Volvamos al ejemplo del segmento de suma mnima. Hemos dicho que la implementaci
on de las listas se har
a a traves del uso de arreglos. Definimos la siguiente
funci
on de abstracci
on:
[[A, i]] = [A.k | k [i..N 1]]
donde A es un arreglo. Por ejemplo, Si A es el arreglo [2,4,6,8,10], entonces
[[A, 2]] es la lista [6,8,10].
Si ys es la lista [[A, i]], tenemos las siguientes equivalencias:
(ys = [ ])
(i N )
ys.0 = A.i
(ys := ys1) (i := i + 1)
Escribamos ahora el programa imperativo para el problema del segmento de
suma mnima usando arreglos:
|[con N = #xs : N at
var a, b, i : Int
var A : array[0..N ) of Int
{[[A, 0]] = xs}
a, b, i := 0, 0, 0
{P : G.(a, b).[[A, i]] = G.(0, 0).xs}
do i 6= N
a, b, i := (A.i + b) min a, 0 min (A.i + b), i + 1
od
{(a, b) = G.(0, 0).xs}
r := a
{Q : a = f.xs}
]|
FINAL Y PROGRAMACION
IMPERATIVA
298CAPITULO 20. RECURSION
Observar que la guarda usada en el ciclo, i 6= N , es equivalente a la desigualdad
i < N , puesto que se comienza el programa con la asignacion i := 0 y en el cuerpo
del ciclo se incrementa el valor de esta variable en 1.
Resulta instructivo comparar este programa con el que se obtuvo en la seccion
19.2 al estudiar el problema del segmento de suma maxima, el cual es completamente an
alogo al problema resuelto m
as arriba.
Ejemplo 20.3 (El problema de los par
entesis equilibrados)
En la secci
on 13.2 derivamos la siguiente definicion recursiva para la funcion que
permite resolver el problema:
g : N um 7 [Char] 7 Bool
g.k.[ ] = (k = 0)
g.k.(( . xs) = k 0 g.(k + 1).xs
g.k.() . xs) = k 0 g.(k 1).xs
A partir de la misma, se puede derivar la siguiente funcion recursiva final:
G : Bool 7 N um 7 [Char] 7 Bool
G.b.k.[ ] = b k = 0
G.b.k.(( . xs) = G.(k 0).(k + 1).xs
G.b.k.() . xs) = G.(k 0).(k 1).xs
Ejercicio: Derivar la funci
on recursiva final anterior.
Escribamos ahora un programa imperativo para el computo de esta funcion
usando el modelo del comienzo del captulo y suponiendo que el lenguaje imperativo permite manejar listas.
La funci
on H.X del modelo es G. T rue .0.XS, por lo cual el invariante es
{G.b.k.xs = G. T rue .0.XS}. As, tenemos
|[var b : Bool, k : Int, xs : String
b, k, xs := T rue, 0, XS
{G.b.k.xs = G. T rue .0.XS}
do xs 6= [ ]
if xs.0 = ( b, k, xs := b k 0, k + 1, xs1
xs.0 = ) b, k, xs := b k 0, k 1, xs1
fi
od
{xs = [ ] G.b.k.xs = G. T rue .0.XS}
r := b k = 0
20.2 EJERCICIOS
299
{r = G. T rue .0.XS}
]|
Ejercicio: Probar que el valor asignado a r es equivalente a pareq.XS (definicion
de pareq en secci
on 13.2).
Implementando las listas por medio de arreglos a traves de la funcion de abstracci
on que definimos antes,
[[A, i]] = [A.k | k [i..N 1]],
podemos escribir el programa en lenguaje imperativo con arreglos:
|[con N = #XS : N at
|[var b : Bool, k, i : Int
var A : array[0..N ) of Char
{[[A, 0]] = XS}
b, k, i := T rue, 0, 0
{P : G.b.k.[[A, i]] = G. T rue .0.XS}
do i 6= N
if A.i = ( b, k, i := b k 0, k + 1, i + 1
A.i = ) b, k, i := b k 0, k 1, i + 1
fi
od
{(i = N G.b.k.[[A, i]] = G. T rue .0.XS}
r := b k = 0
{r = G. T rue .0.XS}
]|
20.2 Ejercicios
Ejercicio 20.1
Escribir programas imperativos para cada uno de los siguientes problemas, cuya
derivaci
on se realiz
o en el captulo 12. En un primer paso, suponer que el lenguaje
dispone de primitivas para el manejo de listas; luego implementar las listas usando
arreglos.
1. Evaluaci
on de un polinomio.
2. C
alculo de una aproximaci
on de la constante matematica e.
3. Problema de la lista balanceada.
4. Problema del m
aximo segmento balanceado.
FINAL Y PROGRAMACION
IMPERATIVA
300CAPITULO 20. RECURSION
Captulo 21
Busca y ordenaci
on
B
usqueda: mas fino que busca.
Ni el poema de Borges, ni el libro
de Baroja se titulan La b
usqueda
Adolfo Bioy Casares:
Diccionario del Argentino Exquisito
En esta secci
on analizaremos algunos metodos para la busca y ordenacion (en
ingles, searching and sorting) en estructuras lineales (por ejemplo, listas o funciones
con dominio en los naturales).
CAPITULO 21. BUSCA Y ORDENACION
302
La funci
on g generaliza a f , pues f.P = g.0.P . Trabajemos ahora con g:
g.n.P
= { especificaci
on de g }
hMin i : n i P.i : i i
= { divisi
on de rango }
hMin i : i = n P.i : i i min hMin i : n + 1 i P.i : i i
= { anidado en el primer parentesis }
hMin i : i = n : hMin j : P.i : i i i min hMin i : n + 1 i P.i : i i
= { rango unitario }
hMin j : P.n : n i min hMin i : n + 1 i P.i : i i
Analicemos por casos, seg
un el valor de verdad de P.n:
si P.n
si P.n
n min hMin i : n + 1 i P.i : i i
= {
algebra }
hMin i : n + 1 i P.i : i i
= { hipotesis inductiva }
g.(n + 1).P
( P.n 7 n
2 P.n 7 g.(n + 1).P
)
21.2 Multiconjuntos
Para especificar el problema de ordenar una lista de n
umeros (o, en general,
de cualquier conjunto totalmente ordenado) intoduciremos la nocion de multiconjuntos, enunciando algunas de las propiedades que nos seran de utilidad.
Los multiconjuntos (en ingles, multisets o bags) son una generalizacion de los
conjuntos, pues si bien no consideran el orden de sus elementos, s tienen en cuenta
la multiplicidad de los mismos. Alternativamente, un multiconjunto puede pensarse
como una funci
on del dominio de valores sobre el cual esta definido en los naturales,
21.2 MULTICONJUNTOS
303
CAPITULO 21. BUSCA Y ORDENACION
304
Propiedades de las operaciones:
]B =B]=B
( es el elemento neutro de ])
B]C =C ]B
(] es conmutativo)
A ] (B ] C) = (A ] B) ] C
B ] B 6= B
(] es asociativo)
(] no es idempotente)
(B \ {a}).a = ( a B 7 B.a 1
2 a 6 B 7 0
)
(B ] C) \ {a} = ( a B 7 B \ {a} ] C
2 a C 7 C \ {a} ] B
2 a 6 B a 6 C 7 B ] C
)
Comprensi
on de multiconjuntos
El operador de uni
on de multiconjuntos es asociativo y conmutativo, por lo que
puede formarse una expresi
on cuantificada con el. De manera analoga al caso de
los conjuntos, puede definirse una notaci
on para multiconjuntos por comprension,
peo es necesario ser bastante cuidadoso para evitar los errores y las definiciones
inconsistentes.
Se define el principio de comprensi
on para multiconjuntos como sigue
*x|x B P.x+ = h ] x : x B P.x : B.x *x+ i
Es necesario multiplicar cada multiconjunto unitario por su multiplicidad original para evitar perderla. Visto como funci
on, se puede definir la comprension de
multicionjuntos como sigue
*x|x B P.x + .z = n(P.z) B.x
Es decir, si ei z satisface P entonces queda con la misma multiplicidad que en
B (n(P.z) es igual a uno) y en caso contrario queda cero.
305
xs = [ ]
(x B [[xs]] = B \ *x+)
min.B = a a B h b : b B : a b i
i : Bag.A 7 nat 7 Bag.A
multiconjunto:
CAPITULO 21. BUSCA Y ORDENACION
306
Ejercicio 21.1
(a) Definirp yp, donde p es un predicado.
(b) Probar las siguientes propiedades: i =
B0 =
(c) Enunciar propiedades similares a las del ejercicio anterior para la funcion.
21.4 Especificaci
on del problema de ordenaci
on
Con la ayuda de las funciones [[ ]] y L, podemos expresar el hecho de tener una
lista ordenada de la siguiente manera:
h xs : : sort.xs = L.[[xs]] i
Dado B 6= , querramos encontrar x y xs tales que L.B = x . xs.
Teorema 21.1
B 6= L.B = min.B . L.(B \ *min.B+)
Demostraci
on: recordando que [[L.B]] = B y que ord.(L.B), y asumiendo
B 6= ,
L.B = x . xs
{ definici
on de L }
[[x . xs]] = B ord.(x . xs)
{ definici
on de ord y lema }
x B [[xs]] = B \ *x + h y : y [[x . xs]] : x y i ord.xs
{ definici
on de L }
{ definici
on de min }
21.5 ORDENAMIENTO POR INSERCION
307
Demostraci
on:
L.(Bi) ++ L.(Bi)
= { ejercicio anterior }
(L.B)i ++ (L.B)i
= { propiedad deypara listas }
L.B
Paso inductivo
sort.[ ]
sort.(x . xs)
= { especificaci
on de sort }
L.[[[ ]]]
= { definici
on de [[ ]] }
L.
= { definici
on de L }
[]
= { especificacion de sort }
L.[[x . xs]]
= { definicion de L }
L.({x} ] [[xs]])
= { introducimos
f | ord.ys f.y.ys =
L.(*y + ][[ys]]) }
f.x.[[xs]]
= { ord.ys [[ys]] = [[L.[[ys]]]]
}
f.x.(L.[[xs]])
= { hipotesis inductiva }
f.x.(sort.xs)
CAPITULO 21. BUSCA Y ORDENACION
308
funci
on f :
Caso base
f.x.[ ]
= { especificaci
on de f }
L.(*x + ][[[ ]]])
= { definici
on de [[ ]] }
L. * x+
= { definici
on de L }
[x]
Paso inductivo
f.x.(y . ys)
= { especificacion de f }
L.(*x + ][[y . ys]])
= { definicion de [[ ]] }
L.(*x + ] * y + ][[ys]])
= { introducimos B = *x + ] *
y + ][[ys]] }
L.B
= { propiedad de L }
min.B . L.(B \ *min.B+)
= { definici
on de min }
= { x min y = x }
Caso (x > y)
min.B . L.(B \
*min.B+)
x . L.(B \ *x+)
= { x min y = y }
x . L.(*y + ][[ys]])
= { def. de B }
x . (y . ys)
= { hipotesis
inductiva }
y . f.x.ys
= { def. de B }
y . L.(B \ *y+)
y . L.(*x + ][[xs]])
21.6 ORDENAMIENTO POR SELECCION
f.x.[ ]
f.x.(y . ys)
=
=
309
[x]
( x y 7 x . (y . ys)
2 x > y 7 y . f.x.ys
)
CAPITULO 21. BUSCA Y ORDENACION
310
= { propiedad de +
+ }
21.7 Quick-sort
Los metodos de ordenamiento por inserci
on y por seleccion son de costo cuadr
atico. Es posible demostrar (no lo haremos) que para ordenar una lista usando
s
olo comparaciones, basta con n log n operaciones. El Quick-sort es un metodo de
costo n2 en el peor caso, sin embargo su costo promedio es n log n. De hecho, suele
ser m
as r
apido que otros metodos cuyo costo en el peor caso es n log n.
En lneas generales, el metodo quick-sort funciona de la siguiente manera: se
toma x que este en la lista, se ordenan la sublista de los elementos que son menores
o iguales que x y la sublista de los elementos mayores que x, y finalmente se
concatenan estas dos sublistas ordenadas.
El metodo se deriva de la propiedad
L.B
(L.B)i ++ (L.B)i
= L.(Bi) ++ L.(Bi)
Dado x B, sea i0 = hMin i : x Bi : min.(Bi) i. Entonces
L.(B(i0 1)) ++ [x] ++ L.(Bi0 )
est
a ordenada, pues es igual a
L.(Bi) ++ L.(Bi)
21.8 MERGE-SORT
311
Ejercicio 21.5
Demostrar que las listas anteriores son efectivamente iguales.
Dentro del quick-sort hay varias versiones, seg
un como se elija el x en la lista.
Si elegimos el primero de la lista a ordenar, tenemos:
quicksort.[ ] = [ ]
quicksort.(x . xs) = quicksort.[y | y xs, y < x] ++
(x . quicksort.[y | y xs, y x])
Notar que si se ingresa una lista ya ordenada, el metodo hara (#xs)2 operaciones, es decir, ser
a de costo cuadr
atico.
Otra estrategia para seleccionar un x en la lista a ordenar consiste en elegir 3
elementos de la lista y quedarse con el del medio. En este caso el metodo recibe el
nombre de mean-sort.
21.8 Merge-sort
Un metodo de ordenamiento de listas con costo n log n en el peor caso es el
merge-sort. Consiste en lo siguiente: se parte la lista a ordenar en dos, se ordena
cada una de las partes y luego se arma una lista ordenada a partir de las dos
sublistas ordenadas que se obtuvieron.
Veamos primero como definir recursivamente la funcion merge que, dadas dos
listas ordenadas, produce una sola lista ordenada:
ord.xs ord.ys merge.xs.ys = L.([[xs]] ] [[ys]])
Para ello vamos a necesitar una propiedad:
L.(B ] C)
= { definici
on de L }
min.(B ] C) . L.(B ] C) \ {min.(B ] C)}
= { introducimos m = min.(B ] C) }
m . L.
( m B 7 (B \ {m}) ] C
2 m C 7 B ] (C \ {m})
)
|[m = min.(B ] C)]|
CAPITULO 21. BUSCA Y ORDENACION
312
|[b = min.B
c = min.C]|
Caso (ys = [ ])
merge.[ ].ys
merge.xs.[ ]
= { especificaci
on de merge }
L.[[ys]]
= { ys est
a ordenada }
ys
= { especificacion
merge }
de
L.[[xs]]
= { xs esta ordenada }
xs
Ap
endice A
Operadores booleanos
La siguiente tabla, extrada de [Kal90], resume algunas de las propiedades
importantes que involucran a los operadores booleanos definidos en la seccion 5.
En todos los casos, P , Q y R son predicados.
Idempotencia:
P P P
P P P
Conmutatividad:
P QQP
P QQP
(P Q) (Q P )
Asociatividad:
(P Q) R P (Q R)
(P Q) R P (Q R)
(P Q) R P (Q R)
Distributividad:
P (Q R) (P Q) (P R)
P (Q R) (P Q) (P R)
P (Q R) P Q P R
Absorci
on:
P (P Q) P
P (P Q) P
Reglas verdadero-falso:
P
P
P
P
Leyes de Morgan:
(P Q) P Q
(P Q) P Q
T rue P
F alse F alse
T rue T rue
F alse P
313
APENDICE
A. OPERADORES BOOLEANOS
314
Equivalencia:
P P
P P T rue
P P F alse
Implicaci
on:
P Q P Q
P QP QP
P QP QQ
P P Q
P QP
F alse P
P T rue
T rue P P
P F alse P
Negaci
on:
P P
P P F alse
P P T rue
(P Q) P Q
Ap
endice B
316
APENDICE
B. SOBRE LAS IMPLEMENTACIONES
y x z := x
x y z := y
y x z := x
x < y z := y
yx
then
else{x < y}
z := x
z := y
fi
5. En la mayora de los lenguajes de progrmacion no se dispone de asignacion
m
ultiple. En esos casos, esta puede implementarse usando una secuencia de
asignaciones simples. A veces es necesario usar variables auxiliares, siendo
317
recomendable entonces demostrar que la secuencia de asignaciones tiene la
misma sem
antica que la asignaci
on m
ultiple, dado que un error de este tipo
es en general difcil de encontrar. Por ejemplo la asignacion m
ultiple
S0 : x, y := 2 y, x + y
puede ser implementada por el programa
S1 : x0 := x
; x := 2 y
; y := x0 + y
pero no por
S2 : x := 2 y
; y := x + y
Ejercicio: Demostrar que S0 es equivalente (cuando no se considera el valor
de x0 ) a S1 pero no a S2
6. Existen opiniones divididas acerca de la utilidad de usar nombres mnemotecnicos para las variables. En este trabajo hemos preferido usar nombres
cortos, lo cual vuelve m
as cortos los calculos. A veces un nombre mnemotecnico en un programa ayuda a reconocer de que variable se esta hablando
pero si no est
a definido con precisi
on puede confundir mas que ayudar (que
significa por ejemplo la variable prod?). En el caso en que s este definido precisamente, la mnemotecnia se vuelve innecesaria. Aparentemente, los
nombres mnemotecnicos aparecieron en los programas artesanales pero se
vuelven superfluos cuando el programa es derivado formalmente.
318
APENDICE
B. SOBRE LAS IMPLEMENTACIONES
Bibliografa
[Bac03]
Roland Backhouse. Program Construction: Calculating Implementations from Specifications. John Wiley & Sons, Inc., New York, NY,
USA, 2003.
[BvW08]
[Coh90]
E. Cohen. Programming in the 1990s. An Introduction to the Calculation of Programs. Texts and Monographs in Computer Science.
Springer Verlag, 1990.
[Cop73]
[DF88]
[Dij76]
[Dij89]
[DS90]
E.W. Dijkstra and C.S. Scholten. Predicate Calculus and Program Semantics. Texts and Monographs in Computer Science. Springer Verlag,
1990.
[Fei90]
320
BIBLIOGRAFIA
[Fok96]
[Gib94]
[Gri81]
[GS93]
[Has06]
[Hoa69]
[Hoo89]
[JL91]
[Kal90]
[Knu69]
D.E. Knuth. The Art of Computer Programming, Volume 2, Seminumerical Algorithms. Addison-Wesley, 1969.
[Par90]
[Smu78]
[Tho96]
[vdS93]
[Wik08]
Wikipedia. String searching algorithm wikipedia, the free encyclopedia, 2008. [Online; accessed 11-March-2008].