Vous êtes sur la page 1sur 4

Ejercicio: Una tabla de números enteros es ‘gaspariforme’ si las sumas parciales

de los elementos de la tabla son todas ellas positivas y la suma de todos sus
elementos es cero. El problema a resolver se especifica del modo siguiente:

t: tabla [1..N ] de entero;


b: booleano;
{P re ≡ t = T }
gaspariforme P
{P ost ≡ t = TP∧ b = ((∀ i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) ≥ 0)∧
∧( j : 1 ≤ j ≤ N : t[j]) = 0)}

El algoritmo que derives habrá de contar con una única composición itera-
tiva.

Solución: La tabla es ‘gaspariforme’ si las sumas parciales de los elementos de


la tabla son todas mayores o iguales a cero (positivos) y la suma de todos los
elementos es cero.
Veámoslo con un ejemplo, sea la tabla t definida para N = 5:
1 2 3 4 5
4 2 -6 3 -3
Tenemos que:

t[1] = 4 ≥ 0
t[1] + t[2] = 6 ≥ 0
t[1] + t[2] + t[3] = 0 ≥ 0
t[1] + t[2] + t[3] + t[4] = 3 ≥ 0
t[1] + t[2] + t[3] + t[4] + t[5] = 0 ≥ 0

Además, la suma de todos sus elementos es 0, tal y como indica la última


suma, y, por tanto, es gaspariforme. Obviamente, si una suma parcial es menor
que 0 la tabla ya no cumple la propiedad, o si la suma de todos sus elementos
no es igual a 0. Veámoslo con otros dos ejemplos:
1 2 3 4 5
4 2 -7 3 -2
Tenemos que:

t[1] + t[2] + t[3] = −1 < 0


t[1] + t[2] + t[3] + t[4] + t[5] = 0 ≥ 0

Mientras que para la siguiente tabla:


1 2 3 4 5
4 2 -6 3 1

Tenemos que:

1
t[1] + t[2] + t[3] + t[4] + t[5] = 4 6= 0

Si tomamos la P P {P ost ≡ t = T ∧ b =
postcondición de la especificación
((∀ i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) ≥ 0) ∧ ( P j : 1 ≤ j ≤ N : t[j]) = 0)},
tenemos que evaluar primero1Psi ∀ i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) ≥ 0
es cierto o no y segundo si ( j : 1 ≤ j ≤ N : t[j]) = 0 es cierto o no. Ası́,
podremos evaluar el valor de b que nos P indica si la tabla es gaspariforme.
Para resolver ∀ i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) ≥ 0 tenemos que
plantear una búsqueda para lo cual aplicamos la propiedad de equivalencia
∀ i : . . . : S ≡ ¬(∃ i : . . . : ¬S). Al aplicar esta propiedad a nuestro problema
queda lo siguiente: P
¬(∃i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) < 0)
Ya podemos aplicar el esquema de búsqueda al (∃ i : . . .):
• Definimos una variable de búsqueda a la que llamamos x de tipo entero
• El espacio de búsqueda, de 1 a N en la tabla t
• Sentido, creciente, de 1 a N .
Tenemos el siguiente esquema:

t: tabla [1..N ] de entero;


b: booleano;
{P re ≡ t = T }
var x: entero fvar
x := 1;
{Inv ≡ t = T ∧ ∀ i : 1 ≤ i < x : ¬A(t, i) ∧ 1 ≤ x ≤ N }
{cota ≡ N − x}
mientras x < N ∧ no A(t, x) hacer
x := x + 1
fmientras;
{Inv ∧ (A(t, x) ∨ (x = N ))}

¿Quién es A(t, i) en el invariante?


P
A(t, i) ≡ ( j : 1 ≤ j ≤ i : t[j]) < 0

¿Quién es A(t, x) en el algoritmo?


P
A(t, x) ≡ ( j : 1 ≤ j ≤ x : t[j]) < 0

La condición del bucle A(t, x) no se puede programar porque la expresión


P
j : 1 ≤ j ≤ x : t[j] no es programable directamente. Por lo tanto, se re-
fuerza el invariante con una nueva variable z de tipo entero igual a la expresin
que no se puede programar.
{Inv 0 ≡ t = T ∧∀ i : 1 ≤ i < x : ¬A(t, i)∧1 ≤ x ≤ N ∧z =
P
j : 1 ≤ j ≤ x : t[j]}

Procedemos a repasar el esquema siguiendo la derivación


1 Parapoder cumplir la especificación de hacerlo en una única iteración; de hecho, se podı́a
haber tomado la segunda parte de la postcondición y obtener una solución correcta también
pero que no cumple con lo que nos pide el problema.

2
• La condición de continuación anterior: x < N ∧ ¬A(t, x); quedará como:
(x < N ) ∧ ¬(z < 0), esto es (x < N ) ∧ (z ≥ 0)
P
• Inicialización. Si x = 1 entonces z = ( j : 1 ≤ j ≤ x : t[j]) = t[1] luego
se necesita la inicialización z := t[1]
• Restablecer. Tenemos que se cumple {Inv 0 ∧ B ≡P t = T ∧ ∀ i: 1 ≤ i <
x : ¬A(t, i) ∧ 1 ≤ x ≤ N ∧ (x < N ∧ z ≥ 0) ∧ z = j : 1 ≤ j ≤ x : t[j]}
y hay que ver como restablecer el invariante al realizar el avancePde x, es
decir (Inv 0 )xx+1 . Sustituyendo, tenemos que (Inv 0 )xx+1 ≡ . . . z = j: 1 ≤
j ≤ (x+1) : t[j] Si denotamos como zant al valor de z en {Inv 0 ∧ B} y como
znueva al valor de z con el avance de x, tenemos que znueva ← zant +t[x+1].
Todo lo demás se cumple porque el esquema de búsqueda tipo es correcto.

Con estos cambios, nos queda:

t: tabla [1..N ] de entero;


b: booleano;
{P re ≡ t = T }
var x, z: entero fvar
x := 1;
z := t[1];
{Inv 0 ≡ t = P T ∧ ∀ i : 1 ≤ i < x : ¬(A(t, i) < 0) ∧ 1 ≤ x ≤ N ∧
∧z = j : 1 ≤ j ≤ x : t[j]}
{cota ≡ N − x}
mientras x < N ∧ z ≥ 0 hacer
z := z + t[x + 1];
x := x + 1
fmientras;
{Inv 0 ∧ ((z < 0) ∨ (x = N ))}
Cuando termina de iterar, se cumple {Inv 0 ∧ ((z < 0) ∨ (x = N ))} y lo que
nos queda es comprobar el éxito de la búsqueda para ver cómoP asignamos el valor
a b. Cuando el bucle termina, sabemos por Inv 0 que z = j : 1 ≤ j ≤ x : t[j]
y por la condición de terminación ((z < P 0) ∨ (x = N )). P
Observa que b = ¬(∃ i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) < 0) ∧ ( j : 1 ≤
j ≤P N : t[j]) = 0). Por el esquema de bsqueda sabemos que ∃ i : 1 ≤ i ≤
NP: ( j : 1 ≤ j ≤ i : t[j]) < 0 es equivalente a A(t, x). Luego b = (¬(A(t, x)) ∧
( j : 1 ≤ j ≤ N : t[j]) = 0). Por el predicado Inv 0 , tenemos que A(t, x) ≡
(z <P0) y, de este modo, ¬(A(t, x)) ≡ (z ≥ 0). Pero si z ≥ 0 entonces x = N y
z= j : 1 ≤ j ≤ N : t[j], con x = N , ası́ que b = (z ≥ 0) ∧ (z = 0) y juntando
ambas expresiones da lugar a : b = (z = 0).
Finalmente, el algoritmo queda de la siguiente manera:

3
algoritmo gaspariforme;
t: tabla [1..N ] de entero;
b: booleano;
{P re ≡ t = T }
var x,z: entero fvar
x := 1;
z := t[1];
{Inv 0 ≡ t = P
T ∧ ∀ i : 1 ≤ i < x : ¬(A(t, i) < 0) ∧ 1 ≤ x ≤ N ∧
∧z = j : 1 ≤ j ≤ x : t[j]}
{cota ≡ N − x}
mientras x < N ∧ z ≥ 0 hacer
z := z + t[x + 1];
x := x + 1
fmientras;
{Inv 0 ∧ ((z < 0) ∨ (x = N ))}
b := (z = 0) P
{P ost ≡ t = TP∧ b = ((∀ i : 1 ≤ i ≤ N : ( j : 1 ≤ j ≤ i : t[j]) ≥ 0)∧
∧( j : 1 ≤ j ≤ N : t[j]) = 0)}
falgoritmo;

Vous aimerez peut-être aussi