Você está na página 1de 4

Máxima diferencia

Construye una función recursiva para la especificación siguiente

const N≥ 2 fconst
tipo vec = tabla [1..N] de entero; ftipo
funcion maxima diferencia(t: vec) dev r: entero;
{P re ≡ verdadero }
{P ost ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ N } }
ffuncion

Debes dar: i) la especificación de la función inmersora; ii) los parámetros de la primera


llamada a la función (la llamada desde máxima diferencia a la función inmersora); iii) la
función limitadora; y iv) obviamente, el cuerpo de la función inmersora (que puede re-
querir alguna otra inmersión adicional).

Solución:

Como el enunciado no indica un método especı́fico para obtener la solución, podemos


intentar abordar el problema bien por el método del reforzamiento de la precondición o
por el método de debilitamiento de la postcondición. Para este problema, parece más
apropiado el debilitamiento de la postcondición.

Dada la postcondición P ost ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ N } debilitamos


este predicado mediante la sustitución de la constante N por una nueva variable x. Ası́
obtenemos:

r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} ∧ 1 ≤ x ≤ N

No es conveniente que el dominio del cuantificador ’max’, es decir 1 ≤ i < j ≤ x se


haga conjunto vacı́o (esto sucede cuando x = 1) puesto que su elemento neutro es −∞.
Además, hay que fijarse que N ≥ 2. Ası́ que, ajustamos el rango de x. El predicado nos
queda:

r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} ∧ 2 ≤ x ≤ N

Con esto ya podemos empezar definiendo la primera función inmersora:

funcion i maxima diferencia(t: vec, x: entero) dev r: entero;


{P ≡ 2 ≤ x ≤ N }
{Q ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} }
ffuncion

Ahora, nos fijamos en la primera llamada:

Observamos que Q ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} es exáctamente P ost ≡ r =


max{t[i] − t[j] : 1 ≤ i < j ≤ N } cuando x = N . Luego ya tenemos la equivalencia entre
la función inmersora y la ’sumergida’:

1
const N≥ 2 fconst
tipo vec = tabla [1..N] de entero; ftipo

funcion i maxima diferencia(t: vec, x: entero) dev r: entero;


{P ≡ 2 ≤ x ≤ N }
{Q ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} }
ffuncion

funcion maxima diferencia(t: vec) dev r: entero;


{P re ≡ verdadero }
r:= i maxima diferencia(t, N);
dev r
{P ost ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ N } }
ffuncion
Observa cómo funciona la primera llamada. Cuando se llama a i maxima diferencia(t,
N), su precondición es P [t ← t, x ← N ] ≡ 2 ≤ N ≤ N , se cumple!. La llamada es
correcta, ası́ que cuando termine de ejercutarse la función, se cumple su postcondición
devolviendo en r el resultado, Q[r ← r, t ← t, x ← N ] ≡ P ost. Ahora, ya nos podemos
concentrar en resolver el cuerpo de la función inmersora, para lo cual tenemos que iden-
tificar el caso trivial y el caso no-trivial. Recuerda que el método determina una función
recursiva no-final. Definimos la variable r′ , de tipo entero, para recoger el resultado de la
llamada en el caso no-trivial:

Caso trivial. En la primera llamada x = N , luego el caso trivial puede ser x = 2. En


ese caso debemos saber calcular directamente el resultado. Haciendo x = 2 en la post-
condición Q, obtenemos:

r = max{t[i] − t[j] : 1 ≤ i < j ≤ 2} = max{t[i] − t[j] : i = 1 ∧ j = 2} = t[1] − t[2].

Caso no-trivial. Si el caso trivial es x = 2, su caso contrario es x ̸= 2, como en la


precondición P , 2 ≤ x ≤ N , entonces 2 < x. En el caso no-trivial se plantea la llamada
recursiva, r′ := i maxima diferencia(t, expresion para x). Como la función debe terminar,
la expresión para x debe hacer decrecer su valor, ası́ se puede proponer x − 1. Además,
x sirve como función limitadora. Lo que tenemos hasta ahora es:
funcion i maxima diferencia(t: vec, x: entero) dev r: entero;
{P ≡ 2 ≤ x ≤ N } {limitadora: x}
var r’: entero fvar
si x= 2 → r:= t[1]-t[2]
[] 2< x → r’:=i maxima diferencia(t, x-1);
{ P [x ← x − 1] ≡ 2 ≤ x − 1 ≤ N }
{ Q[r ← r′ , x ← x − 1] ≡ r′ = max{t[i] − t[j] : 1 ≤ i < j ≤ x − 1} }
r:= expresion para calcular el resultado
fsi;
dev r
{Q ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} }
ffuncion

2
Cómo calculamos la expresión para el resultado deseado r en la postcondición Q?. En

r tenemos la máxima diferencia entre las parejas t[i] − t[j] definidas a partir del conjunto
de ı́ndices {1 ≤ i < j ≤ x − 1}. Pero r en Q, debe contener la máxima diferencia entre
las parejas t[i] − t[j] definidas a partir del conjunto de ı́ndices {1 ≤ i < j ≤ x}. Observa
lo siguiente: {1 ≤ i < j ≤ x} = {1 ≤ i < j ≤ x − 1} ∪ {1 ≤ i < x}. El último conjunto
se obtiene cuando j = x.

Sea max() la operación que calcula el máximo entre dos número enteros. El razon-
amiento anterior conduce a que,

max{t[i] − t[j] : 1 ≤ i < j ≤ x} =


max(max{t[i] − t[j] : 1 ≤ i < j ≤ x − 1}, max{t[i] − t[x] : 1 ≤ i < x})

Por lo tanto,

r ←max(r′ , max{t[i] − t[x] : 1 ≤ i < x}), operando,


r ←max(r′ , max{t[i] : 1 ≤ i < x} − t[x])

La primera inmersión nos queda ası́,

funcion i maxima diferencia(t: vec, x: entero) dev r: entero;


{P ≡ 2 ≤ x ≤ N } {limitadora: x}
var r’: entero fvar
si x= 2 → r:= t[1]-t[2]
[] 2< x → r’:=i maxima diferencia(t, x-1);
r←max(r’, max{t[i] : 1 ≤ i < x}- t[x])
fsi;
dev r
{Q ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} }
ffuncion

No podemos programar la función y tenemos que decidir si max{t[i] : 1 ≤ i < x} lo


calculamos como inmersión de resultados o parámetros en una segunda inmersón de la
función. Recordemos que en la primera llamada x = N , luego la expresión max{t[i] : 1 ≤
i < x} no tiene un valor trivial en la primera llamada. Esto sugiere una inmersión de
resultados. La segunda inmersión de la función queda de la siguiente manera, después de
razonar cúanto vale s cuando x = 2, y cómo se calcula s en la postcondición Q′ a partir
del valor obtenido para s′ en la llamada recursiva del caso no trivial:

funcion ii maxima diferencia(t: vec, x: entero) dev r, s: entero;


{P ′ ≡ 2 ≤ x ≤ N } {limitadora: x}
var r’, s’: entero fvar
si x= 2 → r:= t[1]-t[2]; s:= t[1]
[] 2< x → ⟨r’,s’⟩:=ii maxima diferencia(t, x-1);
s:= max(s’, t[x-1]);
r:= max(r’, s-t[x])
fsi;
dev ⟨r,s⟩

3
{Q′ ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} ∧ s = max{t[i] : 1 ≤ i < x} }
ffuncion

El resultado final queda expresado de la siguiente forma cuando juntamos todas las
inmersiones y la función sumergida original:

const N≥ 2 fconst
tipo vec = tabla [1..N] de entero; ftipo

funcion maxima diferencia(t: vec) dev r: entero;


{P re ≡ verdadero }
funcion i maxima diferencia(t: vec, x: entero) dev r: entero;
{P ≡ 2 ≤ x ≤ N }
funcion ii maxima diferencia(t: vec, x: entero) dev r, s: entero;
{P ′ ≡ P } {limitadora: x}
var r’, s’: entero fvar
si x= 2 → r:= t[1]-t[2]; s:= t[1]
[] 2< x → ⟨r’,s’⟩:=ii maxima diferencia(t, x-1);
s:= max(s’, t[x-1]);
r:= max(r’, s-t[x])
fsi;
dev ⟨r,s⟩
{Q′ ≡ Q ∧ s = max{t[i] : 1 ≤ i < x} }
ffuncion
var s: entero fvar
⟨r,s⟩:= ii maxima diferencia(t, x);
dev r
{Q ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ x} }
ffuncion
r:= i maxima diferencia(t, N);
dev r
{P ost ≡ r = max{t[i] − t[j] : 1 ≤ i < j ≤ N } }
ffuncion

Você também pode gostar