• Nenhum resultado encontrado

Aplica¸c˜ oes de Avalia¸c˜ ao Parcial

Esta se¸c˜ao apresenta aplica¸c˜oes da avalia¸c˜ao parcial de programas em diversas ´areas.

3.2.1 Engenharia de Software

Dois objetivos importantes na produ¸c˜ao de programas s˜ao geralmente conflitantes:

construir programas gen´ericos e modulares, facilitando o reuso de c´odigo e manu-ten¸c˜ao do mesmo;

construir programas os mais eficientes poss´ıveis.

O pre¸co de se utilizar m´odulos gen´ericos e fortemente independentes ´e geralmente a perda da eficiˆencia. Muito tempo pode ser gasto em chamadas de fun¸c˜oes, passagem de parˆametros, constru¸c˜ao de estruturas complexas para satisfazer ao formato independente das interfaces, testes de valores que na realidade s˜ao constantes etc.

Embora se espere que um compilador eficiente execute a “propaga¸c˜ao de constantes”

em tempo de compila¸c˜ao, isso nem sempre ´e verdade quando se trata de propaga¸c˜ao entre diferentes procedimentos. Al´em disso, a expans˜ao de loops (loop unrolling) baseada em dados constantes ´e ainda mais rara.

Avalia¸c˜ao parcial pode ser utilizada para minimizar o impacto negativo da modulari-dade sobre a eficiˆencia de programas. Mesmo n˜ao existindo dados est´aticos para servir de base para a especializa¸c˜ao, ´e poss´ıvel identificar v´arias estruturas est´aticas dentro de um programa, agrupar m´odulos dentro de um s´o, expandir chamadas de fun¸c˜oes, expandir loops dependentes de constantes etc. O resultado ´e um programa inadequado `a leitura ou modifica¸c˜ao, mas muito mais eficiente.

3.2.2 Parˆ ametros com Freq¨ encias de Varia¸ ao Diferentes

Avalia¸c˜ao parcial tamb´em pode ser de grande valia em situa¸c˜oes como a descrita a seguir:

uma fun¸c˜aof(x, y) deve ser computada para diversos pares diferentes (x, y);

o valor dex muda com menos freq¨uˆencia que o de y; e

uma parte significativa da computa¸c˜ao de f depende apenas dex.

Um exemplo onde as condi¸c˜oes acima s˜ao satisfeitas ´e o m´etodo usado em computa¸c˜ao gr´afica conhecido comoray tracing, para renderiza¸c˜ao de figuras. Esse m´etodo consiste em calcular o caminho de raios de luz entre v´arios pontos de uma cena que ser´a exibida.

O algoritmo geral recebe duas entradas, uma cena e um raio de luz. Na exibi¸c˜ao de uma figura, a cena, que ´e uma cole¸c˜ao de objetos de trˆes dimens˜oes, n˜ao ´e alterada enquanto a seq¨uˆencia de raios ´e tra¸cada. A avalia¸c˜ao parcial do algoritmo de ray tracing em rela¸c˜ao a uma cena espec´ıfica resulta em um procedimento eficiente para tra¸car raios para aquela cena [5]. O tempo gasto para se construir o algoritmo especializado ´e compensado pela eficiˆencia obtida, uma vez que o mesmo ser´a utilizado in´umeras vezes para diferentes raios.

Experiˆencias realizadas por Mogensen mostraram um ray tracer especializado que era de 8 a 12 vezes mais r´apido que o original [67].

3.2.3 Problemas de Natureza Interpretativa

Problemas que tenham natureza interpretativa constituem outra classe que pode se beneficiar imensamente da avalia¸c˜ao parcial. Esses problemas envolvem geralmente o uso de uma linguagem que permite ao usu´ario especificar o formato da entrada e parˆametros especiais. Alguns exemplos s˜ao: simula¸c˜ao de circuitos, redes neuronais, casamento de padr˜oes, problemas com entradas que s˜ao tabelas especificando transi¸c˜oes.

Simuladores de circuitos recebem a descri¸c˜ao de um circuito el´etrico como entrada, cons-troem equa¸c˜oes diferenciais que descrevem seu comportamento e usam m´etodos num´ericos para resolver essas equa¸c˜oes. A especializa¸c˜ao de um simulador geral em rela¸c˜ao a um circuito espec´ıfico gera um programa eficiente para esse circuito. Um ganho substancial em velocidade pode ser obtido [9].

O treinamento de redes neuronais geralmente ´e um processo muito caro, dispendendo um tempo longo de computa¸c˜ao. Do ponto de vista da avalia¸c˜ao parcial, esse problema ´e semelhante ao anterior: um simulador geral pode ser especializado em rela¸c˜ao a uma dada topologia de rede.

Um algoritmo de casamento de padr˜oes em textos recebe como entradas uma seq¨uˆencia de caracteres definindo um padr˜ao e um texto onde esse padr˜ao dever´a ser pesquisado. A avalia¸c˜ao parcial do algoritmo em rela¸c˜ao a um padr˜ao espec´ıfico resulta em um programa que implementa um autˆomato finito determin´ıstico que executa as a¸c˜oes necess´arias para a identifica¸c˜ao desse padr˜ao em qualquer texto. Uma experiˆencia interessante de Consel e Danvy mostra a gera¸c˜ao de um algoritmo equivalente ao m´etodo de Knuth, Morris e Pratt (KMP) a partir de algoritmo de casamento de padr˜oes ingˆenuo (for¸ca bruta) [23].

An´alise l´exica e sint´atica podem ser implementadas usando-se algoritmos que seguem tabelas de transi¸c˜oes. Essas tabelas associam, a um dado estado e um dado caractere de entrada, um novo estado e uma a¸c˜ao semˆantica correspondente. A especializa¸c˜ao desses algoritmos em rela¸c˜ao a tabelas espec´ıficas resulta na “compila¸c˜ao” da tabela diretamente para um c´odigo execut´avel, muito mais r´apido.

3.2.4 Compila¸ ao e Gera¸ ao de Compiladores

Finalmente, um dos usos mais importantes de avalia¸c˜ao parcial ´e na compila¸c˜ao e gera¸c˜ao de compiladores dirigida por semˆantica.

A semˆantica de uma linguagem de programa¸c˜aoLpode ser dada por um interpretador para programas escritos em L. A avalia¸c˜ao parcial de um interpretador em rela¸c˜ao a um programa espec´ıfico resulta na compila¸c˜ao desse programa para a linguagem dos programas produzidos pelo avaliador parcial. A avalia¸c˜ao parcial do pr´oprio avaliador em rela¸c˜ao a um interpretador espec´ıfico resulta em um compilador. A avalia¸c˜ao parcial do avaliador com respeito a si pr´oprio resulta em um gerador de compiladores.

Os conceitos envolvidos neste exemplo s˜ao um pouco mais complexos que os dos exem-plos anteriores, assim ser˜ao explicados em detalhe na Se¸c˜ao 3.5.