Logo Studenta

2.3.2. Ejemplo Motivador Consideremos el método count que aparece en la parte izquierda de la Figura 2.4. El método recibe un número entero, ini...

2.3.2. Ejemplo Motivador Consideremos el método count que aparece en la parte izquierda de la Figura 2.4. El método recibe un número entero, inicializa un contador a “0” (ver bytecodes 0 y 1) y ejecuta un bucle que incrementa el contador en uno en cada iteración (bytecode 5), hasta que el valor llega al valor del argumento de entrada (la condición se chequea en los bytecodes 2, 3 y 4). El método devuelve el valor del contador en los bytecodes 7 y 8. Para decompilar el método count, evaluamos parcialmente el intérprete de la Figura 2.3 respecto al bytecode del método count empezando por el átomo main(count,[N],I), donde N representa el argumento de entrada y I el valor de retorno (es decir, la cima de la pila al final de la computación). En la Figura 2.6 se muestra (una versión reducida de) uno de los árboles SLD que da lugar a una decompilación efectiva del método count, y al que nos referiremos posteriormente. Para simplificar la comprensión, aparte del átomo de entrada main/3, solo mostramos los átomos correspondientes al predicado execute/2, pues es el único predicado recursivo del programa. Aśı, cada flecha en el árbol se corresponde realmente con varios pasos de derivación. Nótese que, algunas de las operaciones dentro del cuerpo de cada regla del predicado step, pueden quedar residuales al necesitar da- tos no conocidos en tiempo de EP. La regla de computación utilizada por el operador de desplegado es capaz de residualizar llamadas que no estén suficientemente instanciadas, y seleccionar aśı átomos del objetivo que no sean necesariamente los de más a la izquierda de forma segura [7], en par- ticular, se seleccionarán llamadas a átomos execute/2. Representaremos estas llamadas residuales como etiquetas asociadas a las ramas del árbol. Utilizando el HEm original Consideremos primero un evaluador parcial que utiliza el HEm para controlar la terminación tanto en el control local como en el global. Co- mo puede verse en la figura, el valor del PC “2” se corresponde con la entrada del bucle. Aplicando el HEm, la evaluación contiene una subse- cuencia de átomos de esta forma: execute(st(fr(count, 2, [], [N, 0]), []), Sf), execute(st(fr(count, 2, [], [N, 1]), []), Sf), execute(st(fr(count, 2, [], [N, 2]), []), Sf ), . . ., la cual aparece marcada en la figura con rectángulos de ĺınea dis- continua. Dicha secuencia se corresponde con las sucesivas iteraciones con- secutivas del bucle, en las cuales el control vuelve a la cabeza de éste (ver el valor 2 en el valor del PC del estado), y el valor del contador (variable de la segunda posición de la lista) se va incrementando de uno en uno. Esta secuencia puede crecer de forma infinita, pues el HEm no la detecta como potencialmente peligrosa (ver “∞ (with E)” en la figura). Esto ocurre de- bido al uso que hace el intérprete del operador de Prolog is/2, rompiéndose aśı la propiedad de finitud de signatura que se cumple en los programas lógicos puros. Para obtener una decompilación de calidad, es necesario que el valor del contador (variable local 1) sea filtrado, pero no aśı el del PC. Como vemos en la figura, esto requiere parar la derivación cuando aparezca el átomo execute(st(fr(count, 2, [], [N, 1]), []), Sf) (marcado como (1) ET (2)), y gene- ralizarlo con respecto al átomo anterior encerrado en el rectángulo con ĺınea discontinua, resultando aśı el átomo execute(st( fr(count, 2, [], [N, X]), []), Sf).