los lenguajes WHILE y LOOP
X2 := X1;
while X2 ≠ 0 do X1 := X1 + 1;
X2 := X2 – 1 od
índice de materias
• introducción histórica
• modelos de cálculo
• • lenguajes lenguajes WHILE WHILE y y LOOP LOOP
• funciones µ-recursivas
• teorema de equivalencia
• indexaciones y universalidad
• problemas no resolubles
sintaxis, sem
sintaxis, semáántica yntica y capacidad expresiva capacidad expresiva
veremos:
- sintaxis
- semántica informal - semántica formal
WHILE y LOOP están basados en el bucle indefinido y el bucle definido
?
WHILE LOOP
15
sintaxis del lenguaje WHILE
identificadores
X1 , X2 , X3 , ... , Xi , ...
instrucciones de asignación código
Xi := Xj secuencia finita no vacía de
Xi := Xi + 1 instrucciones separadas
Xi := Xi − 1 ( 0 − 1 = 0 ) por ";"
Xi := 0
instrucción de control programa
bucle indefinido: (n, p, código)
while Xi ≠ 0 do (cabecera) p ≥ n
código (cuerpo) ambos naturales
od (cola)
Nota: el índice de anidamiento siempre es finito
ejemplo de programa WHILE
• Ejemplo 1:
Sea el programa WHILE (1, 2, código) con código:
X2 := X1 ;
while X2 ≠ 0 do X1 := X1 + 1 ; X2 := X2 – 1 od
ejemplo de programa WHILE
• Ejemplo 2:
Sea el programa WHILE (1, 1, código) con código:
X1 := X1 + 1 ; while X1 ≠ 0 do
X1 := X1 od
• trabaja sólo con naturales
• no hay instrucciones de entrada ni de salida
• para un programa (n, p, código)
– n variables de entrada: X1 , X2 , ... , Xn – 1 variable de salida: X1
– p variables de uso: X1 , X2 , ... , Xp con p ≥ n
• las variables que no son de entrada se inicializan implícitamente a cero
• una única función (que puede ser parcial) de NNn en NN se puede asociar a cada programa
semántica informal del
lenguaje WHILE
ejemplo de programa WHILE
• Semántica del programa del ejemplo 1:
Sea el programa WHILE (1, 2, código) con código:
X2 := X1 ;
while X2 ≠ 0 do X1 := X1 + 1 ; X2 := X2 – 1 od
Este programa tiene una variable de entrada (X1), usa dos
variables (X1 , X2), y X2 se inicializa implícitamente a cero.
Calcula: f(n)= 2n ∀n∈NN
ejemplo de programa WHILE
• Semántica del programa del ejemplo 2:
Sea el programa WHILE (1, 1, código) con código:
X1 := X1 + 1 ; while X1 ≠ 0 do
X1 := X1 od
Este programa tiene una variable de entrada (X1), que es la única que usa.
Calcula: f(n)= ↑ ∀n∈NN
(función que siempre diverge)
versión etiquetada de un programa WHILE
Dado un programa WHILE (n, p, código) lo escribimos de manera que cada línea contenga una de las siguientes cosas:
• una instrucción de asignación
• una cabecera de (bucle) while: while Xi ≠ 0 do
• una cola de (bucle) while: od Además:
• numeramos las líneas consecutivamente empezando por el 1
• tras una cabecera de while ponemos el número que le ha correspondido a su cola
• tras una cola de while ponemos el número que le ha correspondido a su cabecera
semántica formal del lenguaje WHILE
ejemplo de programa WHILE
• Versión etiquetada del programa WHILE del ejemplo 1 Sea el programa WHILE Q = (1, 2, código) con código
1: X2 := X1 ;
2: while X2 ≠ 0 do :5 3: X1 := X1 + 1 ;
4: X2 := X2 – 1
5: od :2
concepto de configuración de un programa WHILE
• sea Q = (n, p, código) un programa WHILE, con líneas numeradas de 1 a f , una configuración de Q es una (p+1)-tupla (s, x) con s∈{1, 2, 3,…, f, f +1} y x∈ N N
p• una configuración es inicial si s=1 y x
n+1= … = x
p= 0
• una configuración es final si s = f +1
• C
Qdenota al conjunto de las configuraciones de Q
ejemplos de configuraciones
Sea el programa WHILE Q = (1, 2, código) con código 1: X2 := X1 ;
2: while X2 ≠ 0 do :5 3: X1 := X1 + 1 ;
4: X2 := X2 – 1
5: od :2
(1,3,5) es configuración, no inicial y no final (1,5,0) es configuración, inicial y no final (6,8,3) es configuración final, y no inicial (2,2,2) es configuración, no inicial y no final (0,3,5) no es configuración
concepto de cálculo en un paso
Sea Q = (n, p, código) un programa WHILE, con líneas numeradas de 1 a f .
Diremos que la configuración c
1=(s, x) se transforma
en la configuración c
2=(t, y) en un paso de cálculo
(representado por c
1 Qc
2) sii
concepto de cálculo en un paso (para la asignación )
< (s, x) Q (t, y) >
• Si s: “asignación” aparece en la versión etiquetada de Q , entonces
– t = s + 1
–
– yr = xr para todo r tal que 1 ≤ r ≤ p y r ≠ i
−
=
+
=
=
=
−
= +
1 :
es
"
asignación
"
si
1 :
es
"
asignación
"
si
: es
"
asignación
"
si
0 : es
"
asignación
"
si
1 1 0
i i
i i
j i
i
i i
j i
X X
X X
X X
X
x x y x
concepto de cálculo en un paso (para el bucle )
< (s, x) Q (t, y) >
• Si s: while Xi ≠≠≠≠ 0 do :s’ aparece en la versión etiquetada de Q , entonces
– y = x
– si xi ≠ 0 entonces t = s + 1 – si xi = 0 entonces t = s’ + 1
• Si s: od :s’ aparece en la versión etiquetada de Q , entonces – y = x
– si xi ≠ 0 entonces t = s’ + 1 ( xi está en la cabecera s’ )
– si xi = 0 entonces t = s + 1
ejemplos de cálculo en un paso
Sea el programa WHILE Q = (1, 2, código) con código 1: X2 := X1 ;
2: while X2 ≠ 0 do :5 3: X1 := X1 + 1 ;
4: X2 := X2 – 1
5: od :2
¿ (1, 2, 0) Q (1, 2, 2) ? ¿ (1, 2, 0) Q (2, 2, 2) ?
¿ (3, 4, 6) Q (4, 5, 6) ? ¿ (2, 6, 0) Q (6, 6, 0) ?
(1, 6, 0) Q ? (2, 3, 7) Q ? (5, 4, 2) Q ? (5, 8, 0) Q ?
extendemos el “cálculo en un paso”
función siguiente configuración
• sea Q = (n, p, codigo) un programa WHILE y C
Qel conjunto de todas las configuraciones de Q
• la función siguiente SIG
Q: N
p+1→N
p+1es
¬∃
∨
= ∉
' /'
si
' si
) '
( c c C c c c
c c
c c SIG
Q Q
Q Q
siguiente para el programa Q ya visto
>
=
∧
=
≠
∧
=
=
−
= +
=
∧
=
≠
∧
=
=
=
=
5
si )
(
0 5
si )
6 (
0 5
si )
3 (
4
si )
1 5
(
3
si )
1 4
(
0 2
si )
6 (
0 2
si )
3 (
1
si )
2 (
0
si )
(
) (
a a,b,c
c a
,b,c
c a
,b,c
a ,b,c
a ,c
,b
c a
,b,c
c a
,b,c
a ,b,b
a a,b,c
a, b, c
SIG
Qfunción cálculo de un programa
(configuración alcanzada tras i pasos)
• sea Q = (n, p, c) un programa WHILE, con líneas numeradas de 1 a f , la función cálculo del
programa Q es la función CAL
Q: N
p+1→N
p+1• CAL
Q(a, i) = (t, b) , siendo a∈N
py (1, a)
Qc
1 Qc
2 Q…
Qc
i= (t, b) el cálculo de Q en i pasos, que comienza con valores a de las variables que usa el programa (las de no entrada inicializadas)
• se define recursivamente en función de SIG
Q>
−
= =
0 si
)) 1 ,
( (
0 si
) , 1 ) (
,
( SIG CAL a i i
i i a
a CAL
Q Q Q
ejemplo de función cálculo
• dado el programa Q ya visto, encontrar el valor de CAL
Q(6, 0, 4)
solución:
(1, 6, 0)
Q(2, 6, 6)
Q(3, 6, 6)
Q(4, 7, 6)
Q(5, 7, 5)
CAL
Q(6, 0, 4) = (5, 7, 5)
función complejidad temporal
(nº de pasos de un programa, según la entrada)
• sea Q = (n, p, código) un programa WHILE, con líneas numeradas de 1 a f , la función complejidad temporal de Q es la función T
Q: N
n→N
siendo x ∈N
n, 0 un vector de p−n ceros y π
1p+1la función proyección de la primera componente de un vector de p+1 componentes
( µj ≡ el menor j tal que)] 1 ))
, 0 , ( (
[ )
(x = j 1 +1 CAL x j = f +
TQ
µ π
p Qejemplo de función complejidad temporal
• dado el programa Q ya visto, determinar la complejidad temporal
solución:
(1, a, 0)
Q(2, a, a)
Q(3, a, a)
Q
(4, a+1, a)
Q(5, a+1, a−1)
Q(3, a+1, a−1)
Q
(4, a+2, a−1)
Q(5, a+2, a−2)
Q(3, a+2, a−2)
· · · Q
(3, 2a−1, 1)
Q
(4, 2a, 1)
Q(5, 2a, 0)
Q(6, 2a, 0)
T
Q(a) = 3a+2
concepto de función calculada por un programa WHILE
• sea Q = (n, p, código) un programa WHILE, la función calculada f
Q: N N
n→ N se define por N
siendo x ∈N
ny 0 un vector de p−n ceros
expresado informalmente: dados unos valores para las variables de entrada (x), se inicializan a cero las demás variables, se realizan pasos de cálculo hasta alcanzar una configuración final, y se toma como resultado la segunda componente
(variable X1); si no es posible alcanzar tal configuración final, entonces el programa no acaba para esos valores de entrada, y la función está indefinida (diverge)
))) (
, 0 , ( (
)
(x 2 1 CAL x T x
fQ =
π
p+ Q Qla clase de funciones WHILE-calculables
• F
n(WHILE) es el conjunto de todas las funciones f: N
n→N tales que existe un programa WHILE, con n variables de entrada, que calcula f
• F(WHILE) es la unión de todas las F
n(WHILE) , para n≥0
• si f∈F(WHILE) diremos que f es una función
WHILE-calculable
ejercicios de WHILE-calculabilidad
Demostrar (dando programa y funciones SIG , CAL , T y f ) que cada una de las siguientes funciones es WHILE-calculable:
- suma
- resta ( x − y = 0 si x < y )
- valor absoluto de la resta ( x − y si x ≥ y , y − x si x < y ) - signo ( 0 si x = 0 , 1 si x > 0 )
- complementario del signo ( 0 si x > 0 , 1 si x = 0 ) - producto
- función que siempre diverge
- la función identidad de N en N N N
- función constante C
kj: N N
k→ N , C N
kj(x) = j ∀x∈N N
klenguaje WHILE ampliado
• utilización de denominaciones libres para las
variables de entrada y para la variable de salida (hay que especificar cuáles son de entrada y cuál es de
salida)
• permitiremos en el lenguaje ampliado incluir
instrucciones de asignación cuyo miembro de la derecha implica la activación de otras funciones while-calculables (macroinstrucción)
• inclusión de líneas de comentarios
una función en WHILE ampliado es WHILE-calculable
ejemplo de WHILE ampliado
Ejemplo de “denominaciones libres” y de “comentario”:
Entradas: dato
Salida: doble (* = 2 × dato *) Código:
doble := dato ;
while dato ≠ 0 do
doble := doble + 1 ; dato := dato – 1 od
ejemplo de WHILE ampliado
Ejemplo de “activación de funciones while-calculables”.
Sea el programa doble = (1, 2, código) con código X2 := X1 ;
while X2 ≠ 0 do X1 := X1 + 1 ; X2 := X2 – 1 od
Sea el programa (macroprograma) exp = (1, 2, código) con código X2 := X2 + 1 ;
while X1 ≠ 0 do
X2 :=:= doble( X:=:= 2) ; ←←←← macroinstrucción X1 := X1 – 1
od ;
X1 := X2 ( exp calcula f(n)=2n )
conversión a WHILE:
variables y comentarios
• un programa con denominaciones libres para las variables se convierte en un programa WHILE haciendo las siguientes transformaciones:
– reemplazar la primera variable de entrada por X1 , la segunda por X2 , …, la n-ésima por Xn
– reemplazar la variable de salida por Xn+1
– reemplazar las variables de uso interno, según su orden de aparición por Xn+2 , …
– añadir al final del código resultante la instrucción X1 := Xn+1
• los comentarios se eliminan sin efecto para el código
ejemplo de conversión a WHILE
Entradas: dato
Salida: doble (* 2×dato *) Código:
doble := dato ; while dato ≠ 0 do
doble := doble + 1 ; dato := dato − 1
od
(1, 2, código-doble) código-doble:
X
2:= X
1;
while X
1≠ 0 do
X
2:= X
2+ 1 ; X
1:= X
1− 1 od ;
X
1:= X
2conversión a WHILE:
macroinstrucciones
• las macroinstrucciones se eliminan como sigue
– sea la macroinstrucción Xi := f ( Xj1 , …, Xjn ) , donde f es calculada por el programa (n, p, código)
– sea Q un macroprograma que usa q variables en el cual aparece la macroinstrucción anterior, la expansión PQ de la macroinstrucción en Q da lugar a:
Xq+1 := Xj1 ; Xq+2 := Xj2 ; … Xq+n := Xjn ; Xq+n+1 := 0 ; Xq+n+2 := 0 ; … Xq+p := 0 ;
“el código de P sustituyendo Xi por Xq+i , con 1 ≤ i ≤ p ” Xi := Xq+1
• cada macroinstrucción se expande independientemente
ejemplo de conversión a WHILE
exp = (1, 2, cod)
cod: X2 := X2 + 1 ; while X1 ≠ 0 do
X2 :=:=:=:= doble( X2 ) ; X1 := X1 − 1
od ;
X1 := X2 doble = (1, 2, cod) cod: X2 := X1 ;
while X2 ≠ 0 do X1 := X1 + 1 ; X2 := X2 − 1 od
exp = (1, 4, cod) cod: X2 := X2 + 1 ;
while X1 ≠ 0 do X3 :=:= X:=:= 2 ; X4 :=:= 0 ;:=:=
X4 :=:= X:=:= 3 ;
while X4 ≠≠≠≠ 0 do X3 :=:= X:=:= 3 + 1 ; X4 :=:= X:=:= 4 −−−− 1 od ;X2 :=:= X:=:= 3 ;
X1 := X1 − 1 od ;
X1 := X2
lenguaje WHILE ampliado
• Podemos combinar variables libres y macroinstrucciones
Ejemplo:
Entradas: x, y
Salida: prod (* = x × y *) Código:
while y ≠ 0 do
prod := suma(prod, x) ; y := y – 1
od
lenguaje WHILE ampliado
• Para las macroinstrucciones relativas a funciones conocidas y con representación infija, estándar en matemáticas, usaremos dicha representación
Así, las macros se escribirán
z := suma(x,y) z := x + y z := resta(x,y) z := x
−
yz := producto(x,y) z := x × y
z := exp(x) z := 2x
• Permitiremos más de una función while-calculable en una macroinstrucción
p.e.: z := x + ( x × (z - y))
ejemplos con WHILE ampliado
Demostrar que las siguientes funciones son while-calculables:
— máximo ( max(x,y) )
— diferencia en valor absoluto ( | x - y | )
— igualdad ( igualdad(x,y) , o bien x=y ) (calcula 1 si son iguales, 0 si son distintos)
— potencia ( x y )
soluciones: — potencia:
— max(x,y) := ( x – y ) + y Entradas: x, y
— | x - y | := ( x – y ) + ( y - x ) Salida: z
— igualdad(x,y) := csg( | x - y | ) Código:
( csg ≡ complemento del signo) z := z + 1 ;
while y ≠ 0 do z := z × x ; y := y – 1 od
composición de funciones
sean f y g dos funciones de N en N N , ambas N while-calculables; la composición de ellas g
°f
también es una función while-calculable
sea (1, p
f, Q) el programa while que calcula f : N N → N N y (1, p
g, R) el programa que calcula g: N N → N, el N
siguiente macroprograma calcula g
°f Entrada: x
Salida: y Código:
x := f(x) ;
y := g(x)
capacidad expresiva de WHILE:
estructuras de control
do x times od S
z := x;
while z ≠ 0 do S z := z − 1
od
(* z es una nueva variable *)if x ≠ 0 then S fi
y := sg (x);
do y times od S
(* y es una nueva variable *)
if x ≠ 0 then S else T fi
y := sg (x);
z := csg(x);
do y times od S
do z times
od T
capacidad expresiva de WHILE:
expresiones booleanas
C E
CX = Y 1 − [(Y − X) + (X − Y)]
X > Y (X − Y) − [(X − Y) − 1]
X < Y (Y − X) − [(Y − X) − 1]
C
1∨ C
2sg(E
C1+ E
C2) C
1∧ C
2(E
C1+ E
C2) − 1
¬C 1 − E
Cwhile C do od S
z := E
C;
while z ≠ 0 do S z := E
C;
od
para cualquier condición booleana C existe una expresión EC
tal que si la condición es verdadera toma el valor 1 y si es falsa toma el valor 0
capacidad expresiva de WHILE:
expresiones con funciones
do f(x) times S od w := f(x); do w times S od
while f(x) ≠ 0 do S od w := f(x); while w ≠ 0 do S; w := f(x) od if f(x) ≠ g(x) then S1 w := |f(x)–g(x)|; if w ≠ 0 then S1 else S2 fi
else S2 fi
if f(x) ≠ 0 then S fi w := f(x); if w ≠ 0 then S fi
siendo f y g funciones de N en N N while-calculables y S , SN 1
y S2 códigos, permitiremos escribir instrucciones de la forma:
instrucción expansión
sintaxis del lenguaje LOOP
identificadores
X1 , X2 , X3 , ... , Xi , ...
instrucciones de asignación código
Xi := Xj secuencia finita no vacía de
Xi := Xi + 1 instrucciones separadas
Xi := Xi − 1 ( 0 − 1 = 0 ) por ";"
Xi := 0
instrucción de control programa
bucle definido: (n, p, código)
do Xi times (cabecera) p ≥ n
código (cuerpo) ambos naturales
od (cola)
Nota: el índice de anidamiento siempre es finito
clase de funciones LOOP-calculables
• F
n(LOOP) es el conjunto de las funciones f: N
n→ N tales que existe un programa LOOP, con n variables de entrada, que calcula f
• F(LOOP) es la unión de todas las F
n(LOOP) , para todo n ≥ 0
• si f∈F(LOOP) decimos que f es una función
LOOP-calculable
lenguajes LOOP
i• para cada i ≥ 0 , se define el lenguaje LOOP
icomo el sublenguaje de LOOP formado por los programas que tiene nivel de anidamiento de bucles a lo sumo i
• F(LOOP
i) es la clase de funciones calculadas por programas LOOP
i• si una función pertenece a una clase, entonces
pertenece a todas las que están por encima de ella
F(LOOP
0) ⊂ F(LOOP
1) ⊂ F(LOOP
2) ⊂ … ⊂ F(LOOP)
¿cómo son los programas escritos en LOOP0 y las funciones de F(LOOP0) ?