Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CORRECCIÓN DE PROGRAMAS
EJERCICIOS
0. Especifique un programa que :
(a) Determine la suma de elementos de un arreglo de enteros dado.
(b) Determine el número de ocurrencias de en un arreglo dado.
(c) Dado un arreglo booleano que contenga un valor verdadero, fije en el menor
tal que
valga.
(d) Dado un arreglo booleano que contenga un valor verdadero, fije en ! el mayor
tal que
valga.
(e) Determine el número de valores distintos en arreglo de enteros dado.
(f) Determine una mayoría en el arreglo , dado que haya una. Una mayoría en un arreglo
que contenga "
elementos es un valor que ocurre mas de div veces. " #
(g) Dado que haya uno, determine el segundo valor mas largo de un arreglo de enteros
dado.
toda ejecución de & termina en un estado que satisface Q cuando se inicia en un estado
que satisface . &
Presentaremos ahora el lenguaje de comandos guardados de Dijkstra mediante una
“semántica axiomática” (es decir, una forma de entender el significado de un programa
basada en axiomas) expresada en términos de axiomas sobre la corrección de sus
comandos.
• 0-1
2/30547698;:=<>2 equivale a 1 ≡ 47698;:=< (ley del milagro excluido)
El comando =?>A@ B
El comando de asignación
Se escribe JKCML N donde O representa una secuencia finita de variables y N representa una
secuencia de expresiones (una por cada variable en O ) OKPMQ N evalúa las expresiones en N y
1
Un programa se llama determinístico cuando al iniciar con los mismos datos, todas las ejecuciones del programa dan
siempre los mismos resultados (p.e. siempre aborta, o siempre se queda en ciclo infinito, o siempre se detiene con los
mismos resultados. Existen programas que iniciando con los mismos datos producen resultados diferentes bajo diferentes
ejecuciones. Estos programas se llaman no-determinísticos.
Otro ejemplo: Solucionar para
en " Σ e23| ? J(henU W¡ f¢¤£¥
Para hallarlo tenemos que resolver para ¢ en ¥ ⇒ ¥ ¦UnU W¡ f¢J
2
Un predicado § se dice "más débil que" otro ¨ , si ¨ ⇒© es un teorema. La definición dual aplica al concepto “mas
fuerte que”.
≡ definición de , sustitución textual
!#"# $&% ('
Σ
)
≡ ruptura por
*+!#"# ,$% ('.-/$0'
Σ
≡ suponiendo
12-3$4'
EJERCICIOS
0. Determine el predicado más débil que satisfaga:
67
8-. 29;:<6
(i) 5 5
67
1 29;:<6
(ii) 5 ⋅ 5
67
1 =?>
(iii) 5 ⋅ ⋅ ⋅@2ABDCE@2F;G<H
(iv) CIH7@
JK1@A.LMCE@ N OPRQ S T/UQ2V;W<X
(v) YZX7Q
[\1Q ⋅Q ⋅Q=O?U ⋅Q2T]^YEQ _ O&PRQ S T/UQ2V;W<X
(vi) YZX7Q
[\1QT.`MYEQ=\1QT.`X
(vii) YZX7Q
[\)a+YEQ=\1aX
(viii) YZX7Q
[\1Q bdcfe UgYEQ=\1Q bdcfe UhX
(ix) YZX7QjiRk
[\8QT.`iRkjO`MYEQTjk2V;W<X
(x) YZX7QjiRk
[\8kT.`iRQjO`MYEQ2V;W<X
(xi) YZX7QjiRk
[\1k ⋅QjiRQ ⋅k#YEQTjk2V;W<X
(xii) YZXmln[\
l ≡ o/YRlpX
(xii) YZXmln[\
l ⇒ o3YRl ∨ o/X
1. Muestre que la ejecución de Q
[\1QT.` termina
El comando qjrsftvu
Ejemplo: Hallar la precondición mas débil tal que la ejecución >?*+( ; (*+:. ; .*+> logre
que (@+BA ∧ .@+DC sea verdad.
E
(@+A ∧ .6+FCHGI3 .*+:>J593 (*+.K593L>?*+0(K5
≡ M sust. textualN
E
(@+A ∧ >+DCHG3 (*+.K593L>?*+0(K5
≡ M sust. textualN
E
.@+A ∧ >+DCHG3L>?*+(K5
≡ M sust. textualN
E
.@+A ∧ (6+FCHG
EJERCICIOS
0. Determine el predicado más débil O que satisface:
(i) #O
&)(*+(QPSR9-<(*+0(QPSR7#T(6UDVW&
(ii) #O
&)(*+0( ⋅(X-<(*+0(QPSR7#T(6UDVW&
(iii) YZ
[)\]^0\Q_a`Xb<`]^0\ac`Xb<\]^\ac`BYT\@^0d ∧ e6f0g
h
(iv) ij
h)klfeXm<elfkBiTk@fn ∧ e@f0g
h
≡ ley de De Morgan
""
! ∨ ! ∀$&%('6)+$-,/./% "10
$ ⇒ 3240 $ 5
⇐ ∨ 7 ⇐
""
!
EJERCICIOS
1. 32 8 9 2 : 9 2 ; 2 8 9<32 : 9 2 ;
(la secuenciación es asociativa)
= >9 2 249 = 2 =
2. $ $ ( $ es la unidad de la secuenciación)
9 2 2-9
?@
3. ( es el anulador de la secuenciación)
= A9 = =
4. Muestre que $ $ es equivalente a $ .
2
5. Si es un programa determinístico que termina normalmente siempre, entonces
32?B 32/B
! ≡ ! para todo predicado .
2 " EF2
6. Probar que C 7*D C D ⇐ C 7*D if fi C D
Como do
od debería valer. Escogemos como predicado intermedio en la
secuencia: do
od es decir,
"!
if
"!
[]
do
od
fi
de donde se obtiene:
# "!
%$
'&
# "!
(
%$
# # #
(iii) do
od vuelve a dar lugar a %
$ ,
(
%$ y
(
(
%$ .
# #
Si podemos garantizar que la repetición termina
%$ y (
%$ bastan.
Formulamos estas condiciones para una repetición con dos guardas:
3
La semántica operacional es la forma clásica de describir el significado de un programa (el efecto de su ejecución)
mediante la composición de los efectos de los comandos que conforman dicho programa.
implican
do
[]
od
Solución:
BDCFE(G BJI
+H = do $<O' $*)P3Q$&R'
[] '4<O$ S'*)P3T'&R$
od
Hemos probado:
( , IJL , (
Lo cual implica (3.).
≡ X aritmética Y
JKMLON'P ≠ R)U
≡ X definición de ≠ Y
JK
P = R
⇒ X regla de Leibnitz y proposición (1.) de Z[\ Y
P]I^ Z[\ _
Hemos mostrado la corrección parcial del ciclo `baO[dcfeg\W`h es decir:
iBjlk `baO[dcfeg\W`Bh i"mk siempre y cuando nBolp"qbrOsdtfugvWqwdndxgyzrOq/p
¿Como mostrar la terminación del ciclo solución para qbrOsdtfugvWqw ?
do {|}~{1I{!"}
[] }|{~}12}!"{
od
Considere la función (del estado de ejecución de bO
dfgW ) I
≠ )
(1) Claramente:
⇒ aritmética
[]
[]
od
cumple es suficiente encontrar un predicado (invariante) y función límite !
tal que:
(0) "#
(1) %$'&)(*( ⇒
(2) %$+(-, ./01, .2 para 354768:9;9;9<8>=
(3) ?%@BACAEDGF1HJI
(4) KL%M+N-O P:MRQTSVU1W0X1O P2KYQTZ[U1W para PTS\]:O;O;O ]_^ donde N*N'Sa` b c deBfhg2fjilkm0n g/o
No olvidar que:
p'qsr ∀c kte ≤ g ≤ ulv>w;x;yz{0z |/} es otro compromiso de demostración subyacente.
HJI*K*KLNM O P @
Ejemplo: Siendo entero “al menos cero” A @CBED<F
y arreglo entero con subindices enG
y , variables enteras, considere los predicados:
Q R S;TVUXWZY []\ ^ _8`bacedgf d4hi_kj;l c3a`mXjnl f"op`<q
r s _8`5ah"d4t
u _;vVwXxZy z _*`bac,d{h{_|j;l c}a`<q
se desea solucionar el siguiente problema de programación:
~ r m r s m u5
_ “Incrementar h
~r en actualizando ”
Paso 2: (criterio de terminación) Escoja una función cota que satisfaga .
En otras palabras encuentre una función (así sea implicitamente) cuyo decremento
garantice la falsificación de la guarda del ciclo. Esto nos garantiza que el cuerpo del ciclo
no ejecutará indefinidamente.
!
Paso 3: Derive (el cuerpo del ciclo) de tal manera que satisfaga "#$! (es
%&')(*',+.-0/213$%4+657/21
decir, que preserve el invariante después de cada iteración) y a la vez,
(avance hacia terminación).
&
b) Terminación primero:
Paso 0: Encuentre una forma de establecer el predicado invariante inicialmente.
.3 < =
Paso 1: Encuentre una función 8:+ 9 +
;
adecuada al invariante elegido ( ). Proponga
(>< =
&
%&?'@(>< =A',+.- 8 136< =%4+.5 8 1 8& :9 +
;
subprogramas que decrementen . Encuentre guarda tal que :
C DFEGHGJIK>L EBMON7PRQTS
Paso 2: Continue realizando el Paso 1 hasta que:
` ≤U ≤X
\[G XdgUha
\ do U ≠ X → U Gcb Ujilk od
^ U b Xa
]|
Supongamos por ahora, que ningún parámetro tiene el mismo nombre que un resultado.
Entonces si es una función especificada como sigue:
ret
!
"
funct
" ##$&
Pre
Pos '%
%
Una llamada a ( sobre los datos ) * +-,,+) . que asigne los resultados a las variables / * +0,-,+/ !
responde al siguiente postulado:
" $21 3 * +-,,+3 . # 45) * +-,,+6) . 7%
" /';* 1 +3 ,* +,+,/ ,! +<3 #4 (8) * +,,+9) . :
. +6= * +,,+9= ! #4>) * +,,+9) . +/ * +,,+/ ! 7%
Continuando con el ejemplo anteriormente presentado, como la función division retorna dos
resultados es preciso invocarla de la siguiente manera:
? +@A#4>BCDCEBCE=98) * +6) F : donde ) * GH) F son expresiones aritméticas
Aplicando el postulado anterior, este comando satisface la siguiente especificación:
" 8 I J2KL5MHNOK0:P1QI+MR#4>) * +9) F 7%
?
" 8+I@A4T#4SM B⋅U;CDVCEB=W
CE=98) * +6) F :
LXKZY[=]\ZMA:P1QI+M+6U+6=#4>) * +9) F + ? +@^7_%
Con lo que se obtiene
" ) * J2KL`) F NOKZ%
? +@A#4SBCDCEBCE=98) * +6) F :
Diseño de Algoritmos Cap 2 52
Jaime A Bohórquez V
⋅
No es necesario que los argumentos sean variables: pueden ser expresiones. Por ejemplo si
los datos fuesen ⋅ e ,
(*),+.⋅ -0/2 1 "034!#
1 65*%7 $&⋅
) ' 98
/
⋅ 7:98 ⋅( + !;
< += 7:98>'
que se puede argumentar como ya se mostró.
Prescindimos ahora, de la suposición realizada un poco más arriba, de que ningún
parámetro tiene el mismo nombre que un resultado. En caso de que se empleen como
parámetros una o más de las variables que retornan los resultados, para relacionar y
distinguir entre sus valores iniciales y los que éstas adoptan después de la llamada, es
preciso hacer uso de variables de especificación (estáticas) que registren dichos valores
iniciales en la precondición.
Parámetros externos o contextuales
if 8BC
D : C
76 6 JI 6
[] 8 ≠ ED : F7 ⋅5 ./8 9G H 8 :LK H
;<
fi
IB 6
K ! : M. NAO ./82( ⋅ F7 P Q3R
ret S ;
T3U
= l sustituyendo m
En realidad, las ideas anteriormente expuestas aplican a toda clase de funciones recurrentes
sin que sea necesario enunciar explícitamente un postulado de corrección para ellas. Todo
lo que se debe tener en cuenta para el desarrollo de una prueba de corrección de una
función o procedimiento recurrente es, además de la aplicación de los postulados de
corrección para los comandos secuenciales involucrados (en particular para el comando de
Diseño de Algoritmos Cap 2 56
Jaime A Bohórquez V
selección), la aplicación de argumentos inductivos fundamentados en una relación bien
fundada que permita usar la especificación de sus invocaciones recurrentes como hipótesis
inductivas que apelan a los postulados de corrección que se establecieron para las llamadas
o invocaciones a comandos modulares (funciones o procedimientos).
el programa ;(<=?>@;(AB
La solución
E J
;(<=+U+;(AB GV;(;WH UNR , donde ;(; es un comando de función
para
que se apoya en N
es simplemente la asignación:
Oy como parámetros contextuales y que responde a la siguienterecurrente
X Y con N E AB
Z[ OE <
\\<] YJQQ NR^_ AB
Z[ C N ≥ ` T
especificación:
Verificamos la corrección de este código. En primer lugar, fijamos como función
límite para mostrar que la recurrencia de se apoya una relación bien fundada, y por
tanto, termina.
Note que
⇒ ≥
≡ definición de y
≤ !
≤ " ⇒ ≥
≡ aritmética
$#&%'
Y por tanto, la primera condición para la función cota se cumple. El resultado de la
siguiente demostración nos será útil:
∧ ≠
()
⇒ definición de y aritmética
( ≤
⇒ monotonía de ≤
( ≤
( ∧
(*( ≤ +
⇒ monotonía de ,*-. y aritmética
0/1
(32 ,*-. 4!
Procedemos a mostrar que la función cota cumple con su segunda condición, teniendo en
cuenta, que la única función de la variable 5 es la de guardar el valor /1
(32 ,*-. :
∧ ≠
()
⇒ resultado anterior
0/1
(32 *, -. 4!
⇒ aritmética
60/1
(32 ,*-. !7 ∧ 6!/1
(32 *, -.
⇒ definición de 8
6 :9 /1
(32 ,;-. =< ∧ 6 > 9 ? /1
(32 ,*- . =<
Mostramos ahora la corrección del caso no recurrente del comando de selección del cuerpo
de :
≡ sustituyendo
"#
↑ ! ∧ ↓ $ %!
⇐ regla de un punto
&')(
')(
Para continuar con la prueba de corrección del caso recurrente ( ≠ ) podemos hacer
uso de la corrección de las llamadas recurrentes (hipótesis de inducción):
*,+ .- / /465
1023
*87
25 7 9
0 0 ∧
(8,:(8;<=;> &?@?A ?@?A
0B! 0 <!
* ,
(8,:(. ,
&;<=;C + 5
∧ ∧
*D+ + E 5
∧
y entonces, basta demostrar los siguientes dos hechos:
*87 ')(F5
∧ ≠
' ;BJ
0 B! GHI
*,+ .- / /465
1023
y
*D+ + E 5
∧
,
( ;<,:( =;
↑ ↓
* 5
⇐ Regla de Leibnitz
+ E
EJERCICIOS
3. Especifique y escriba un programa recurrente que evalúe el número combinatorio:
m
⋅ . Calcúlelo evitando hacer uso de la función factorial, pues da
n
lugar a valores exageradamente altos. Búsque al menos dos soluciones distintas ambas
linealmente recurrentes.
4. Diseñe un programa recurrente que, dados dos naturales y , calcule de cuantas formas
diferentes se pueden seleccionar naturales no nulos, posiblemente repetidos que sumen
. Ayuda: Plantear una recurrencia múltiple, reservando una llamada recurrente para
contar las descomposiciones que incluyen algún , y otra para las que no contienen
ninguno.
5. El recorrido en inorden de un árbol binario puede dafirse como una secuencia que
comienza con los elementos del del recorrido en inorden del hijo izquierdo, continúa con
la raíz del árbol, y sigue con el recorrido en inorden del hijo derecho. Especificar
ecuacionalmente esta operación, y diseñar un programa recurrente que calcule el
recorrido de un árbol binario.